@myop/cli 0.1.45 → 0.1.46
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 +1411 -1184
- package/dist/skills/myop-angular-host/SKILL.md +320 -0
- package/dist/skills/myop-component/SKILL.md +73 -6
- package/dist/skills/myop-component/references/dev-workflow.md +71 -6
- package/dist/skills/myop-react-host/SKILL.md +265 -0
- package/dist/skills/myop-react-host/references/auto-generated-packages.md +70 -0
- package/dist/skills/myop-react-native-host/SKILL.md +320 -0
- package/dist/skills/myop-vue-host/SKILL.md +263 -0
- package/package.json +1 -1
package/dist/myop-cli.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
var ye = (o,
|
|
5
|
-
import
|
|
6
|
-
import { select as
|
|
7
|
-
import { Command as
|
|
8
|
-
import { execSync as
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import { URL as
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
const
|
|
2
|
+
var St = Object.defineProperty;
|
|
3
|
+
var vt = (o, t, e) => t in o ? St(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
|
|
4
|
+
var ye = (o, t, e) => vt(o, typeof t != "symbol" ? t + "" : t, e);
|
|
5
|
+
import Y from "ora";
|
|
6
|
+
import { select as tt, Separator as Fe } from "@inquirer/prompts";
|
|
7
|
+
import { Command as xt, Option as me } from "commander";
|
|
8
|
+
import { execSync as ee, spawn as $t } from "child_process";
|
|
9
|
+
import O, { join as ke } from "path";
|
|
10
|
+
import C, { readFileSync as bt } from "fs";
|
|
11
|
+
import Ue from "crypto";
|
|
12
|
+
import Ct from "http";
|
|
13
|
+
import { URL as ot, URLSearchParams as nt } from "url";
|
|
14
|
+
import Pt from "open";
|
|
15
|
+
import st from "os";
|
|
16
|
+
const Mt = `
|
|
17
17
|
Usage: myop [OPTIONS] COMMAND [ARGS]...
|
|
18
18
|
|
|
19
19
|
A powerful command-line interface for managing your Myop projects.
|
|
@@ -47,7 +47,7 @@ Examples:
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
`,
|
|
50
|
+
`, v = {
|
|
51
51
|
program: null,
|
|
52
52
|
executionPath: "",
|
|
53
53
|
options: {
|
|
@@ -55,81 +55,81 @@ Examples:
|
|
|
55
55
|
verbose: !1
|
|
56
56
|
},
|
|
57
57
|
myopConfig: null
|
|
58
|
-
},
|
|
58
|
+
}, it = {
|
|
59
59
|
name: "📥 Install Myop generated dependencies",
|
|
60
60
|
value: "myopInstall",
|
|
61
61
|
description: "Fetch and generates Myop dependencies. flows including components, refs and props.",
|
|
62
62
|
action: async () => {
|
|
63
63
|
console.info("installing... ");
|
|
64
|
-
for (const o of
|
|
65
|
-
const
|
|
66
|
-
console.info(`Generate flow at ${
|
|
64
|
+
for (const o of v.myopConfig.flows) {
|
|
65
|
+
const t = O.join(v.executionPath, "/node_modules/@myop/flow-types/");
|
|
66
|
+
console.info(`Generate flow at ${t}`), console.info(`Generated flow at ${t}`);
|
|
67
67
|
}
|
|
68
68
|
process.exit();
|
|
69
69
|
}
|
|
70
|
-
},
|
|
71
|
-
const
|
|
72
|
-
console.info(`reading config file from: ${
|
|
73
|
-
const
|
|
70
|
+
}, Et = (o) => {
|
|
71
|
+
const t = O.join(v.executionPath, o);
|
|
72
|
+
console.info(`reading config file from: ${t}`);
|
|
73
|
+
const e = C.readFileSync(t, "utf8"), n = JSON.parse(e);
|
|
74
74
|
return console.info("config file loaded, ", n), n;
|
|
75
|
-
},
|
|
76
|
-
const
|
|
77
|
-
console.info(`writing config file to: ${
|
|
75
|
+
}, Be = (o, t) => {
|
|
76
|
+
const e = O.join(v.executionPath, o);
|
|
77
|
+
console.info(`writing config file to: ${e}`);
|
|
78
78
|
try {
|
|
79
|
-
const n = JSON.stringify(
|
|
80
|
-
|
|
79
|
+
const n = JSON.stringify(t, null, 2);
|
|
80
|
+
C.writeFileSync(e, n), console.info(`config file updated ${n}`);
|
|
81
81
|
} catch (n) {
|
|
82
|
-
throw console.info(`error ${n} while writing to ${
|
|
83
|
-
⚠️ Failed write config file to ${
|
|
82
|
+
throw console.info(`error ${n} while writing to ${e}, JSON: ${t}`), console.log(`
|
|
83
|
+
⚠️ Failed write config file to ${e}, for more info use verbose flag`), n;
|
|
84
84
|
}
|
|
85
|
-
},
|
|
85
|
+
}, rt = {
|
|
86
86
|
name: "🌟 Add flow definition to your project",
|
|
87
87
|
value: "addFlow",
|
|
88
88
|
description: "Adds flow to yours myop.config.json",
|
|
89
89
|
_action: (o) => {
|
|
90
|
-
|
|
90
|
+
v.myopConfig.flows.includes(o) || v.myopConfig.flows.push(o), Be(v.options.configPath, v.myopConfig);
|
|
91
91
|
},
|
|
92
92
|
action: async () => {
|
|
93
93
|
}
|
|
94
|
-
},
|
|
94
|
+
}, at = {
|
|
95
95
|
name: "🚫 Remove flow definition from your project",
|
|
96
96
|
value: "removeFlow",
|
|
97
97
|
description: "Removes flow to yours myop.config.json",
|
|
98
98
|
_action: (o) => {
|
|
99
|
-
|
|
99
|
+
v.myopConfig.flows = v.myopConfig.flows.filter((t) => t !== o), Be(v.options.configPath, v.myopConfig);
|
|
100
100
|
},
|
|
101
101
|
action: () => {
|
|
102
102
|
}
|
|
103
|
-
},
|
|
103
|
+
}, It = {
|
|
104
104
|
name: "👋 Quit",
|
|
105
105
|
value: "quit",
|
|
106
106
|
description: "Quit and continue coding.",
|
|
107
107
|
action: () => {
|
|
108
108
|
process.exit();
|
|
109
109
|
}
|
|
110
|
-
},
|
|
110
|
+
}, Rt = {
|
|
111
111
|
name: "🟢 Create new component",
|
|
112
112
|
value: "-",
|
|
113
113
|
disabled: "(not available yet)"
|
|
114
|
-
},
|
|
114
|
+
}, Tt = {
|
|
115
115
|
name: "🔵 Create new experience",
|
|
116
116
|
value: "-",
|
|
117
117
|
disabled: "(not available yet)"
|
|
118
|
-
},
|
|
118
|
+
}, Ot = {
|
|
119
119
|
name: "🟡 Create new skin",
|
|
120
120
|
value: "-",
|
|
121
121
|
disabled: "(not available yet)"
|
|
122
|
-
},
|
|
122
|
+
}, kt = {
|
|
123
123
|
name: "🔴 Create new flow",
|
|
124
124
|
value: "-",
|
|
125
125
|
disabled: "(not available yet)"
|
|
126
|
-
},
|
|
126
|
+
}, jt = {
|
|
127
127
|
name: "🆕 Define new custom Myop message",
|
|
128
128
|
value: "generateMyopMessage",
|
|
129
129
|
description: "️Help you creates the right structure for a new Myop message, including types and handlers.",
|
|
130
130
|
disabled: "(not available yet)"
|
|
131
|
-
},
|
|
132
|
-
function
|
|
131
|
+
}, _t = [jt, Rt, Tt, Ot, kt];
|
|
132
|
+
function Ft(o, t, e, n) {
|
|
133
133
|
return `<!DOCTYPE html>
|
|
134
134
|
<html lang="en">
|
|
135
135
|
<head>
|
|
@@ -137,7 +137,7 @@ function Rt(o, e, t, n) {
|
|
|
137
137
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
138
138
|
<title>Myop DevTools - localhost:${o}</title>
|
|
139
139
|
<style>
|
|
140
|
-
${
|
|
140
|
+
${e}
|
|
141
141
|
</style>
|
|
142
142
|
</head>
|
|
143
143
|
<body>
|
|
@@ -146,7 +146,7 @@ ${t}
|
|
|
146
146
|
<div class="toolbar-title">Myop DevTools</div>
|
|
147
147
|
<div class="toolbar-info">
|
|
148
148
|
<span><div class="status-dot"></div> localhost:${o}</span>
|
|
149
|
-
<span>Management: ${
|
|
149
|
+
<span>Management: ${t}</span>
|
|
150
150
|
</div>
|
|
151
151
|
</div>
|
|
152
152
|
|
|
@@ -219,70 +219,70 @@ ${n}
|
|
|
219
219
|
</body>
|
|
220
220
|
</html>`;
|
|
221
221
|
}
|
|
222
|
-
function
|
|
222
|
+
function Nt(o) {
|
|
223
223
|
return o.includes("esbuild") && o.includes("another platform");
|
|
224
224
|
}
|
|
225
|
-
function
|
|
225
|
+
function Lt(o) {
|
|
226
226
|
return o.includes("ERR_MODULE_NOT_FOUND") && o.includes("esbuild");
|
|
227
227
|
}
|
|
228
|
-
function
|
|
228
|
+
function Dt() {
|
|
229
229
|
console.error(`
|
|
230
230
|
❌ esbuild platform mismatch detected!`), console.error(" Your node_modules contains esbuild binaries for a different OS."), console.error(`
|
|
231
231
|
This usually happens when node_modules is copied between different`), console.error(` operating systems (e.g., Windows → Mac, or Mac → Linux).
|
|
232
232
|
`);
|
|
233
233
|
}
|
|
234
|
-
function
|
|
235
|
-
return new Promise((
|
|
234
|
+
function At(o) {
|
|
235
|
+
return new Promise((t) => {
|
|
236
236
|
console.log(`🔧 Attempting to fix: removing node_modules and reinstalling...
|
|
237
237
|
`);
|
|
238
238
|
const n = process.platform === "win32" ? "rmdir /s /q node_modules" : "rm -rf node_modules";
|
|
239
|
-
o(n, (
|
|
240
|
-
if (
|
|
241
|
-
console.error("❌ Failed to remove node_modules:",
|
|
239
|
+
o(n, (s) => {
|
|
240
|
+
if (s) {
|
|
241
|
+
console.error("❌ Failed to remove node_modules:", s.message), console.error(`
|
|
242
242
|
Please run manually:`), console.error(` \x1B[36m${n} && npm install\x1B[0m
|
|
243
|
-
`),
|
|
243
|
+
`), t(!1);
|
|
244
244
|
return;
|
|
245
245
|
}
|
|
246
246
|
console.log(" ✓ Removed node_modules"), console.log(` ⏳ Running npm install...
|
|
247
|
-
`), o("npm install", { maxBuffer: 10 * 1024 * 1024 }, (
|
|
248
|
-
if (
|
|
249
|
-
console.error("❌ npm install failed:",
|
|
247
|
+
`), o("npm install", { maxBuffer: 10 * 1024 * 1024 }, (i, c, u) => {
|
|
248
|
+
if (i) {
|
|
249
|
+
console.error("❌ npm install failed:", i.message), u && console.error(u), t(!1);
|
|
250
250
|
return;
|
|
251
251
|
}
|
|
252
252
|
console.log(` ✓ Dependencies reinstalled successfully!
|
|
253
|
-
`),
|
|
253
|
+
`), t(!0);
|
|
254
254
|
});
|
|
255
255
|
});
|
|
256
256
|
});
|
|
257
257
|
}
|
|
258
|
-
async function
|
|
258
|
+
async function lt(o, t, e, n, s = {}) {
|
|
259
259
|
const {
|
|
260
|
-
hasTriedPlatformFix:
|
|
261
|
-
hasTriedInstall:
|
|
262
|
-
onRetry:
|
|
263
|
-
} =
|
|
264
|
-
return !
|
|
265
|
-
`),
|
|
266
|
-
n("npm install", (
|
|
267
|
-
if (
|
|
268
|
-
console.error("❌ Failed to install dependencies:",
|
|
260
|
+
hasTriedPlatformFix: i = !1,
|
|
261
|
+
hasTriedInstall: c = !1,
|
|
262
|
+
onRetry: u
|
|
263
|
+
} = s, y = ((o == null ? void 0 : o.message) || "") + (t || "") + (e || "");
|
|
264
|
+
return !i && Nt(y) ? (Dt(), await At(n) && u ? (console.log(`🔄 Retrying build...
|
|
265
|
+
`), u(), { handled: !0, hasTriedPlatformFix: !0, hasTriedInstall: c }) : { handled: !0, hasTriedPlatformFix: !0, hasTriedInstall: c }) : !c && Lt(y) ? (console.log("📦 Missing dependencies detected, running npm install..."), new Promise((d) => {
|
|
266
|
+
n("npm install", (l, P, g) => {
|
|
267
|
+
if (l) {
|
|
268
|
+
console.error("❌ Failed to install dependencies:", l.message), g && console.error(g), d({ handled: !0, hasTriedPlatformFix: i, hasTriedInstall: !0 });
|
|
269
269
|
return;
|
|
270
270
|
}
|
|
271
|
-
console.log("✅ Dependencies installed"),
|
|
271
|
+
console.log("✅ Dependencies installed"), u && u(), d({ handled: !0, hasTriedPlatformFix: i, hasTriedInstall: !0 });
|
|
272
272
|
});
|
|
273
|
-
})) : { handled: !1, hasTriedPlatformFix:
|
|
273
|
+
})) : { handled: !1, hasTriedPlatformFix: i, hasTriedInstall: c };
|
|
274
274
|
}
|
|
275
|
-
async function
|
|
276
|
-
const o = await import("fs"),
|
|
277
|
-
let
|
|
275
|
+
async function xe() {
|
|
276
|
+
const o = await import("fs"), t = await import("path"), { exec: e } = await import("child_process"), n = await import("http"), { createHash: s } = await import("node:crypto");
|
|
277
|
+
let i;
|
|
278
278
|
if (import.meta.url.startsWith("file://")) {
|
|
279
|
-
const r = new URL(import.meta.url).pathname,
|
|
280
|
-
|
|
279
|
+
const r = new URL(import.meta.url).pathname, m = process.platform === "win32" && r.startsWith("/") ? r.slice(1) : r;
|
|
280
|
+
i = t.default.dirname(m);
|
|
281
281
|
} else
|
|
282
|
-
|
|
283
|
-
const
|
|
284
|
-
let
|
|
285
|
-
const
|
|
282
|
+
i = t.default.dirname(import.meta.url);
|
|
283
|
+
const c = t.default.join(i, "commands", "dev", "management-website"), u = o.default.readFileSync(t.default.join(c, "styles.css"), "utf-8"), y = o.default.readFileSync(t.default.join(c, "app.js"), "utf-8"), d = 9292, l = 9293;
|
|
284
|
+
let P = "./dist", g = !1, M = !1, f = !1, w = null;
|
|
285
|
+
const _ = () => {
|
|
286
286
|
try {
|
|
287
287
|
const a = o.default.readdirSync(".").filter((r) => !r.endsWith(".html") || r.startsWith(".") ? !1 : o.default.statSync(r).isFile());
|
|
288
288
|
if (a.length === 1)
|
|
@@ -290,7 +290,7 @@ async function be() {
|
|
|
290
290
|
} catch {
|
|
291
291
|
}
|
|
292
292
|
return null;
|
|
293
|
-
},
|
|
293
|
+
}, R = () => {
|
|
294
294
|
try {
|
|
295
295
|
const a = JSON.parse(o.default.readFileSync("package.json", "utf-8"));
|
|
296
296
|
return !!(a.scripts && a.scripts.build);
|
|
@@ -299,57 +299,57 @@ async function be() {
|
|
|
299
299
|
}
|
|
300
300
|
}, b = (a) => {
|
|
301
301
|
const r = process.platform;
|
|
302
|
-
let
|
|
303
|
-
r === "darwin" ?
|
|
302
|
+
let m;
|
|
303
|
+
r === "darwin" ? m = `open "${a}"` : r === "win32" ? m = `start "" "${a}"` : m = `xdg-open "${a}"`, e(m, (h) => {
|
|
304
304
|
});
|
|
305
|
-
},
|
|
306
|
-
let
|
|
307
|
-
|
|
308
|
-
const
|
|
305
|
+
}, p = /* @__PURE__ */ new Map(), E = v.program.getOptionValue("config") || "./myop.config.json";
|
|
306
|
+
let x, T, k = !1;
|
|
307
|
+
w = _();
|
|
308
|
+
const H = R();
|
|
309
309
|
try {
|
|
310
|
-
const a = o.default.readFileSync(
|
|
311
|
-
|
|
310
|
+
const a = o.default.readFileSync(E, "utf-8"), r = JSON.parse(a);
|
|
311
|
+
x = r.componentId || "DEV", T = r.componentName || r.name || null, k = r.HMR === !0, w && !H && (f = !0, k = !0, console.log(`📄 Single HTML file mode: ${w}`)), k && console.log("🔥 HMR enabled");
|
|
312
312
|
} catch (a) {
|
|
313
|
-
|
|
313
|
+
w && !H ? (f = !0, x = "DEV", T = t.default.basename(w, ".html"), k = !0, console.log(`📄 Single HTML file mode: ${w}`), console.log("🔥 HMR enabled")) : (console.error("❌ Error reading myop.config.json:", a.message), process.exit(1));
|
|
314
314
|
}
|
|
315
|
-
const
|
|
316
|
-
if (
|
|
317
|
-
return
|
|
315
|
+
const A = async () => {
|
|
316
|
+
if (x !== "DEV" && x !== "NEW")
|
|
317
|
+
return x;
|
|
318
318
|
try {
|
|
319
|
-
const r = ((await new Promise((
|
|
320
|
-
const
|
|
319
|
+
const r = ((await new Promise((S, $) => {
|
|
320
|
+
const I = {
|
|
321
321
|
hostname: "localhost",
|
|
322
|
-
port:
|
|
322
|
+
port: l,
|
|
323
323
|
path: "/_list",
|
|
324
324
|
method: "GET",
|
|
325
325
|
timeout: 1e3
|
|
326
|
-
},
|
|
327
|
-
let
|
|
328
|
-
|
|
326
|
+
}, N = n.default.request(I, (U) => {
|
|
327
|
+
let K = "";
|
|
328
|
+
U.on("data", (ne) => K += ne), U.on("end", () => {
|
|
329
329
|
try {
|
|
330
|
-
|
|
330
|
+
S(JSON.parse(K));
|
|
331
331
|
} catch {
|
|
332
|
-
|
|
332
|
+
S({ components: [] });
|
|
333
333
|
}
|
|
334
334
|
});
|
|
335
335
|
});
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}),
|
|
339
|
-
})).components || []).map(([
|
|
336
|
+
N.on("error", () => S({ components: [] })), N.on("timeout", () => {
|
|
337
|
+
N.destroy(), S({ components: [] });
|
|
338
|
+
}), N.end();
|
|
339
|
+
})).components || []).map(([S]) => S).filter((S) => S === "DEV" || S === "NEW" || /^DEV\d+$/.test(S) || /^NEW\d+$/.test(S));
|
|
340
340
|
if (r.length === 0)
|
|
341
341
|
return "DEV1";
|
|
342
|
-
const
|
|
343
|
-
if (
|
|
344
|
-
const
|
|
345
|
-
return
|
|
346
|
-
}).filter((
|
|
347
|
-
return `DEV${Math.max(...
|
|
342
|
+
const m = r.map((S) => {
|
|
343
|
+
if (S === "DEV" || S === "NEW") return 1;
|
|
344
|
+
const $ = S.match(/^DEV(\d+)$/), I = S.match(/^NEW(\d+)$/);
|
|
345
|
+
return $ ? parseInt($[1], 10) : I ? parseInt(I[1], 10) : 0;
|
|
346
|
+
}).filter((S) => S > 0);
|
|
347
|
+
return `DEV${Math.max(...m, 0) + 1}`;
|
|
348
348
|
} catch {
|
|
349
349
|
return "DEV1";
|
|
350
350
|
}
|
|
351
|
-
},
|
|
352
|
-
const r =
|
|
351
|
+
}, j = process.cwd(), J = (a) => {
|
|
352
|
+
const r = t.default.extname(a).toLowerCase();
|
|
353
353
|
return {
|
|
354
354
|
".html": "text/html",
|
|
355
355
|
".js": "text/javascript",
|
|
@@ -361,100 +361,100 @@ async function be() {
|
|
|
361
361
|
".svg": "image/svg+xml",
|
|
362
362
|
".ico": "image/x-icon"
|
|
363
363
|
}[r] || "application/octet-stream";
|
|
364
|
-
},
|
|
364
|
+
}, F = /* @__PURE__ */ new Map(), V = [], te = 50, z = [], Q = /* @__PURE__ */ new Map(), oe = /* @__PURE__ */ new Map(), gt = (a, r, m) => {
|
|
365
365
|
if (a.url.startsWith("/_hmr/")) {
|
|
366
|
-
const
|
|
366
|
+
const h = a.url.split("/_hmr/")[1], S = a.headers["sec-websocket-key"], $ = s("sha1").update(S + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64");
|
|
367
367
|
r.write(
|
|
368
368
|
`HTTP/1.1 101 Switching Protocols\r
|
|
369
369
|
Upgrade: websocket\r
|
|
370
370
|
Connection: Upgrade\r
|
|
371
|
-
Sec-WebSocket-Accept: ${
|
|
371
|
+
Sec-WebSocket-Accept: ${$}\r
|
|
372
372
|
\r
|
|
373
373
|
`
|
|
374
|
-
),
|
|
375
|
-
const
|
|
376
|
-
|
|
374
|
+
), oe.has(h) || oe.set(h, /* @__PURE__ */ new Set()), oe.get(h).add(r), console.log(`🔌 HMR client connected: ${h}`), r.on("close", () => {
|
|
375
|
+
const I = oe.get(h);
|
|
376
|
+
I && (I.delete(r), I.size === 0 && oe.delete(h)), console.log(`🔌 HMR client disconnected: ${h}`);
|
|
377
377
|
}), r.on("error", () => {
|
|
378
|
-
const
|
|
379
|
-
|
|
378
|
+
const I = oe.get(h);
|
|
379
|
+
I && I.delete(r);
|
|
380
380
|
});
|
|
381
381
|
}
|
|
382
|
-
},
|
|
382
|
+
}, Pe = n.default.createServer((a, r) => {
|
|
383
383
|
if (r.setHeader("Content-Type", "application/json"), a.method === "POST" && a.url === "/_register") {
|
|
384
|
-
let
|
|
385
|
-
a.on("data", (
|
|
384
|
+
let m = "";
|
|
385
|
+
a.on("data", (h) => m += h), a.on("end", () => {
|
|
386
386
|
try {
|
|
387
|
-
const { componentId:
|
|
388
|
-
|
|
389
|
-
const
|
|
390
|
-
console.log(`✅ Registered: ${
|
|
391
|
-
const
|
|
392
|
-
id:
|
|
393
|
-
path:
|
|
394
|
-
name:
|
|
387
|
+
const { componentId: h, distPath: S, componentName: $, htmlFile: I } = JSON.parse(m);
|
|
388
|
+
F.set(h, { path: S, name: $ || null, htmlFile: I || null });
|
|
389
|
+
const N = $ ? ` (${$})` : "";
|
|
390
|
+
console.log(`✅ Registered: ${h}${N} -> ${S}${I ? "/" + I : ""}`), r.writeHead(200), r.end(JSON.stringify({ success: !0, registered: Array.from(F.keys()) }));
|
|
391
|
+
const U = Array.from(F.entries()).map(([K, ne]) => ({
|
|
392
|
+
id: K,
|
|
393
|
+
path: ne.path,
|
|
394
|
+
name: ne.name
|
|
395
395
|
}));
|
|
396
|
-
|
|
396
|
+
z.forEach((K) => {
|
|
397
397
|
try {
|
|
398
|
-
|
|
398
|
+
K.write(`data: ${JSON.stringify({
|
|
399
399
|
type: "components",
|
|
400
|
-
components:
|
|
400
|
+
components: U
|
|
401
401
|
})}
|
|
402
402
|
|
|
403
403
|
`);
|
|
404
404
|
} catch {
|
|
405
405
|
}
|
|
406
406
|
});
|
|
407
|
-
} catch (
|
|
408
|
-
r.writeHead(400), r.end(JSON.stringify({ error:
|
|
407
|
+
} catch (h) {
|
|
408
|
+
r.writeHead(400), r.end(JSON.stringify({ error: h.message }));
|
|
409
409
|
}
|
|
410
410
|
});
|
|
411
411
|
} else if (a.method === "POST" && a.url === "/_unregister") {
|
|
412
|
-
let
|
|
413
|
-
a.on("data", (
|
|
412
|
+
let m = "";
|
|
413
|
+
a.on("data", (h) => m += h), a.on("end", () => {
|
|
414
414
|
try {
|
|
415
|
-
const { componentId:
|
|
416
|
-
|
|
417
|
-
const
|
|
418
|
-
id:
|
|
419
|
-
path:
|
|
420
|
-
name:
|
|
415
|
+
const { componentId: h } = JSON.parse(m);
|
|
416
|
+
F.delete(h), console.log(`❌ Unregistered: ${h}`), r.writeHead(200), r.end(JSON.stringify({ success: !0 }));
|
|
417
|
+
const S = Array.from(F.entries()).map(([$, I]) => ({
|
|
418
|
+
id: $,
|
|
419
|
+
path: I.path,
|
|
420
|
+
name: I.name
|
|
421
421
|
}));
|
|
422
|
-
|
|
422
|
+
z.forEach(($) => {
|
|
423
423
|
try {
|
|
424
|
-
|
|
424
|
+
$.write(`data: ${JSON.stringify({
|
|
425
425
|
type: "components",
|
|
426
|
-
components:
|
|
426
|
+
components: S
|
|
427
427
|
})}
|
|
428
428
|
|
|
429
429
|
`);
|
|
430
430
|
} catch {
|
|
431
431
|
}
|
|
432
432
|
});
|
|
433
|
-
} catch (
|
|
434
|
-
r.writeHead(400), r.end(JSON.stringify({ error:
|
|
433
|
+
} catch (h) {
|
|
434
|
+
r.writeHead(400), r.end(JSON.stringify({ error: h.message }));
|
|
435
435
|
}
|
|
436
436
|
});
|
|
437
437
|
} else if (a.method === "GET" && a.url === "/_list")
|
|
438
|
-
r.writeHead(200), r.end(JSON.stringify({ components: Array.from(
|
|
438
|
+
r.writeHead(200), r.end(JSON.stringify({ components: Array.from(F.entries()) }));
|
|
439
439
|
else if (a.method === "POST" && a.url === "/_hmr_notify") {
|
|
440
|
-
let
|
|
441
|
-
a.on("data", (
|
|
440
|
+
let m = "";
|
|
441
|
+
a.on("data", (h) => m += h), a.on("end", () => {
|
|
442
442
|
try {
|
|
443
|
-
const { componentId:
|
|
444
|
-
if (
|
|
445
|
-
console.log(`🔥 Notifying ${
|
|
446
|
-
const
|
|
447
|
-
|
|
443
|
+
const { componentId: h, html: S } = JSON.parse(m), $ = oe.get(h);
|
|
444
|
+
if ($ && $.size > 0) {
|
|
445
|
+
console.log(`🔥 Notifying ${$.size} HMR client(s) for: ${h}`);
|
|
446
|
+
const I = JSON.stringify({ type: "update", html: S }), N = Ke(I);
|
|
447
|
+
$.forEach((U) => {
|
|
448
448
|
try {
|
|
449
|
-
|
|
449
|
+
U.write(N);
|
|
450
450
|
} catch {
|
|
451
|
-
|
|
451
|
+
$.delete(U);
|
|
452
452
|
}
|
|
453
|
-
}), r.writeHead(200), r.end(JSON.stringify({ success: !0, notified:
|
|
453
|
+
}), r.writeHead(200), r.end(JSON.stringify({ success: !0, notified: $.size }));
|
|
454
454
|
} else
|
|
455
455
|
r.writeHead(200), r.end(JSON.stringify({ success: !0, notified: 0 }));
|
|
456
|
-
} catch (
|
|
457
|
-
r.writeHead(400), r.end(JSON.stringify({ error:
|
|
456
|
+
} catch (h) {
|
|
457
|
+
r.writeHead(400), r.end(JSON.stringify({ error: h.message }));
|
|
458
458
|
}
|
|
459
459
|
});
|
|
460
460
|
} else
|
|
@@ -464,90 +464,90 @@ Sec-WebSocket-Accept: ${v}\r
|
|
|
464
464
|
r.writeHead(403, { "Content-Type": "text/plain" }), r.end("Forbidden");
|
|
465
465
|
return;
|
|
466
466
|
}
|
|
467
|
-
const
|
|
468
|
-
if (
|
|
469
|
-
const
|
|
470
|
-
if (!
|
|
467
|
+
const m = new URL(a.url, `http://localhost:${d}`), h = m.pathname, S = h.split("/").filter((W) => W);
|
|
468
|
+
if (h.startsWith("/consume")) {
|
|
469
|
+
const W = m.searchParams.get("id");
|
|
470
|
+
if (!W) {
|
|
471
471
|
r.writeHead(400, { "Content-Type": "application/json" }), r.end(JSON.stringify({ error: "Component ID required. Use /consume?id=<componentId>" }));
|
|
472
472
|
return;
|
|
473
473
|
}
|
|
474
|
-
const
|
|
475
|
-
let
|
|
474
|
+
const G = F.get(W), Z = G ? G.path : null, ce = (se) => {
|
|
475
|
+
let D = "Unknown", q = "Unknown";
|
|
476
476
|
if (a.headers.referer || a.headers.referrer) {
|
|
477
|
-
const
|
|
477
|
+
const B = a.headers.referer || a.headers.referrer;
|
|
478
478
|
try {
|
|
479
|
-
const re = new URL(
|
|
480
|
-
|
|
479
|
+
const re = new URL(B);
|
|
480
|
+
D = re.origin, q = re.hostname || re.origin;
|
|
481
481
|
} catch {
|
|
482
|
-
|
|
482
|
+
D = B, q = B;
|
|
483
483
|
}
|
|
484
484
|
} else if (a.headers.origin)
|
|
485
485
|
try {
|
|
486
|
-
const
|
|
487
|
-
|
|
486
|
+
const B = new URL(a.headers.origin);
|
|
487
|
+
D = B.origin, q = B.hostname || B.origin;
|
|
488
488
|
} catch {
|
|
489
|
-
|
|
489
|
+
D = a.headers.origin, q = a.headers.origin;
|
|
490
490
|
}
|
|
491
491
|
else if (a.socket.remoteAddress) {
|
|
492
|
-
const
|
|
493
|
-
|
|
492
|
+
const B = a.socket.remoteAddress;
|
|
493
|
+
B === "::1" || B === "::ffff:127.0.0.1" ? (D = "localhost", q = "localhost (direct)") : (D = B, q = B.replace("::ffff:", ""));
|
|
494
494
|
}
|
|
495
|
-
const
|
|
495
|
+
const Te = a.headers.referer || a.headers.referrer || D, he = {
|
|
496
496
|
type: "request",
|
|
497
|
-
componentId:
|
|
497
|
+
componentId: W,
|
|
498
498
|
timestamp: Date.now(),
|
|
499
|
-
servedLocally:
|
|
500
|
-
referrer:
|
|
501
|
-
origin:
|
|
502
|
-
originLabel:
|
|
499
|
+
servedLocally: se,
|
|
500
|
+
referrer: Te,
|
|
501
|
+
origin: D,
|
|
502
|
+
originLabel: q
|
|
503
503
|
};
|
|
504
|
-
|
|
505
|
-
url:
|
|
506
|
-
label:
|
|
504
|
+
Q.has(D) || (Q.set(D, {
|
|
505
|
+
url: D,
|
|
506
|
+
label: q,
|
|
507
507
|
firstSeen: Date.now(),
|
|
508
508
|
requestCount: 0
|
|
509
|
-
}),
|
|
509
|
+
}), z.forEach((B) => {
|
|
510
510
|
try {
|
|
511
|
-
|
|
511
|
+
B.write(`data: ${JSON.stringify({
|
|
512
512
|
type: "origins",
|
|
513
|
-
origins: Array.from(
|
|
513
|
+
origins: Array.from(Q.values())
|
|
514
514
|
})}
|
|
515
515
|
|
|
516
516
|
`);
|
|
517
517
|
} catch {
|
|
518
518
|
}
|
|
519
519
|
}));
|
|
520
|
-
const
|
|
521
|
-
|
|
520
|
+
const Oe = Q.get(D);
|
|
521
|
+
Oe.requestCount++, z.forEach((B) => {
|
|
522
522
|
try {
|
|
523
|
-
|
|
523
|
+
B.write(`data: ${JSON.stringify({
|
|
524
524
|
type: "origins",
|
|
525
|
-
origins: Array.from(
|
|
525
|
+
origins: Array.from(Q.values())
|
|
526
526
|
})}
|
|
527
527
|
|
|
528
528
|
`);
|
|
529
529
|
} catch {
|
|
530
530
|
}
|
|
531
|
-
}),
|
|
531
|
+
}), V.push(he), V.length > te && V.shift(), z.forEach((B) => {
|
|
532
532
|
try {
|
|
533
|
-
|
|
533
|
+
B.write(`data: ${JSON.stringify(he)}
|
|
534
534
|
|
|
535
535
|
`);
|
|
536
536
|
} catch {
|
|
537
537
|
}
|
|
538
538
|
});
|
|
539
539
|
};
|
|
540
|
-
if (
|
|
541
|
-
const
|
|
542
|
-
o.default.readFile(
|
|
543
|
-
if (
|
|
544
|
-
console.log(`❌ File not found: ${
|
|
540
|
+
if (Z) {
|
|
541
|
+
const se = G.htmlFile ? t.default.join(Z, G.htmlFile) : t.default.join(Z, "index.html");
|
|
542
|
+
o.default.readFile(se, "utf-8", (D, q) => {
|
|
543
|
+
if (D) {
|
|
544
|
+
console.log(`❌ File not found: ${se}`), r.writeHead(404, { "Content-Type": "application/json" }), r.end(JSON.stringify({ error: "index.html not found" }));
|
|
545
545
|
return;
|
|
546
546
|
}
|
|
547
|
-
const
|
|
547
|
+
const Te = Me(q, W), he = `dev-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, Oe = {
|
|
548
548
|
item: {
|
|
549
|
-
name:
|
|
550
|
-
id:
|
|
549
|
+
name: W,
|
|
550
|
+
id: W,
|
|
551
551
|
consume_variant: [
|
|
552
552
|
{
|
|
553
553
|
id: he,
|
|
@@ -555,141 +555,141 @@ Sec-WebSocket-Accept: ${v}\r
|
|
|
555
555
|
loader: {
|
|
556
556
|
type: "HTMLLoader",
|
|
557
557
|
shadowRootMode: "localFrame",
|
|
558
|
-
HTML:
|
|
558
|
+
HTML: Te
|
|
559
559
|
}
|
|
560
560
|
}
|
|
561
561
|
]
|
|
562
562
|
}
|
|
563
563
|
};
|
|
564
|
-
console.log(`✅ Serving consume JSON for: ${
|
|
564
|
+
console.log(`✅ Serving consume JSON for: ${W}`), ce(!0), r.writeHead(200, {
|
|
565
565
|
"Content-Type": "application/json",
|
|
566
566
|
"Access-Control-Allow-Origin": "*"
|
|
567
|
-
}), r.end(JSON.stringify(
|
|
567
|
+
}), r.end(JSON.stringify(Oe, null, 2));
|
|
568
568
|
});
|
|
569
569
|
} else {
|
|
570
|
-
console.log(`📡 Proxying consume request to cloud.myop.dev for: ${
|
|
571
|
-
const
|
|
572
|
-
ce(!1), fetch(
|
|
570
|
+
console.log(`📡 Proxying consume request to cloud.myop.dev for: ${W}`);
|
|
571
|
+
const se = `https://cloud.myop.dev/consume${m.search}`;
|
|
572
|
+
ce(!1), fetch(se).then((D) => D.text()).then((D) => {
|
|
573
573
|
r.writeHead(200, {
|
|
574
574
|
"Content-Type": "application/json",
|
|
575
575
|
"Access-Control-Allow-Origin": "*"
|
|
576
|
-
}), r.end(
|
|
577
|
-
}).catch((
|
|
578
|
-
console.error(`❌ Proxy error: ${
|
|
576
|
+
}), r.end(D);
|
|
577
|
+
}).catch((D) => {
|
|
578
|
+
console.error(`❌ Proxy error: ${D.message}`), r.writeHead(502, { "Content-Type": "application/json" }), r.end(JSON.stringify({ error: "Failed to fetch from cloud.myop.dev" }));
|
|
579
579
|
});
|
|
580
580
|
}
|
|
581
581
|
return;
|
|
582
582
|
}
|
|
583
|
-
if (
|
|
583
|
+
if (h === "/events") {
|
|
584
584
|
r.writeHead(200, {
|
|
585
585
|
"Content-Type": "text/event-stream",
|
|
586
586
|
"Cache-Control": "no-cache",
|
|
587
587
|
Connection: "keep-alive",
|
|
588
588
|
"Access-Control-Allow-Origin": "*"
|
|
589
|
-
}),
|
|
590
|
-
const
|
|
591
|
-
id:
|
|
592
|
-
path:
|
|
593
|
-
name:
|
|
589
|
+
}), z.push(r);
|
|
590
|
+
const W = Array.from(F.entries()).map(([G, Z]) => ({
|
|
591
|
+
id: G,
|
|
592
|
+
path: Z.path,
|
|
593
|
+
name: Z.name
|
|
594
594
|
}));
|
|
595
595
|
r.write(`data: ${JSON.stringify({
|
|
596
596
|
type: "components",
|
|
597
|
-
components:
|
|
597
|
+
components: W
|
|
598
598
|
})}
|
|
599
599
|
|
|
600
600
|
`), r.write(`data: ${JSON.stringify({
|
|
601
601
|
type: "origins",
|
|
602
|
-
origins: Array.from(
|
|
602
|
+
origins: Array.from(Q.values())
|
|
603
603
|
})}
|
|
604
604
|
|
|
605
605
|
`), r.write(`data: ${JSON.stringify({
|
|
606
606
|
type: "requestLog",
|
|
607
|
-
log:
|
|
607
|
+
log: V
|
|
608
608
|
})}
|
|
609
609
|
|
|
610
610
|
`), a.on("close", () => {
|
|
611
|
-
const
|
|
612
|
-
|
|
611
|
+
const G = z.indexOf(r);
|
|
612
|
+
G !== -1 && z.splice(G, 1);
|
|
613
613
|
});
|
|
614
614
|
return;
|
|
615
615
|
}
|
|
616
|
-
if (
|
|
617
|
-
r.writeHead(200, { "Content-Type": "text/html" }), r.end(
|
|
616
|
+
if (S.length === 0) {
|
|
617
|
+
r.writeHead(200, { "Content-Type": "text/html" }), r.end(Ft(d, l, u, y));
|
|
618
618
|
return;
|
|
619
619
|
}
|
|
620
|
-
if (
|
|
620
|
+
if (S[0] !== "view") {
|
|
621
621
|
r.writeHead(404, { "Content-Type": "text/plain" }), r.end("Not found. Use /view/<componentId>/ to access components.");
|
|
622
622
|
return;
|
|
623
623
|
}
|
|
624
|
-
if (
|
|
624
|
+
if (S.length < 2) {
|
|
625
625
|
r.writeHead(400, { "Content-Type": "text/plain" }), r.end("Component ID required. Use /view/<componentId>/");
|
|
626
626
|
return;
|
|
627
627
|
}
|
|
628
|
-
const
|
|
629
|
-
if (!
|
|
630
|
-
r.writeHead(404, { "Content-Type": "text/plain" }), r.end(`Component not found: ${
|
|
628
|
+
const $ = S[1], I = F.get($);
|
|
629
|
+
if (!I) {
|
|
630
|
+
r.writeHead(404, { "Content-Type": "text/plain" }), r.end(`Component not found: ${$}`);
|
|
631
631
|
return;
|
|
632
632
|
}
|
|
633
|
-
const
|
|
634
|
-
console.log(`📥 Request: ${a.url} -> ${le}`), o.default.readFile(le, (
|
|
635
|
-
if (
|
|
633
|
+
const N = I.path, U = S.slice(2), K = I.htmlFile || "index.html", ne = U.length === 0 ? K : U.join("/"), le = t.default.join(N, ne);
|
|
634
|
+
console.log(`📥 Request: ${a.url} -> ${le}`), o.default.readFile(le, (W, G) => {
|
|
635
|
+
if (W) {
|
|
636
636
|
console.log(`❌ File not found: ${le}`), r.writeHead(404, { "Content-Type": "text/plain" }), r.end("Not Found");
|
|
637
637
|
return;
|
|
638
638
|
}
|
|
639
|
-
const
|
|
640
|
-
console.log(`✅ Serving: ${le} (${
|
|
641
|
-
let ce =
|
|
642
|
-
if (
|
|
643
|
-
const
|
|
644
|
-
ce = Me(
|
|
639
|
+
const Z = J(le);
|
|
640
|
+
console.log(`✅ Serving: ${le} (${Z})`);
|
|
641
|
+
let ce = G;
|
|
642
|
+
if (Z === "text/html" && k) {
|
|
643
|
+
const se = G.toString("utf-8");
|
|
644
|
+
ce = Me(se, $);
|
|
645
645
|
}
|
|
646
646
|
r.writeHead(200, {
|
|
647
|
-
"Content-Type":
|
|
647
|
+
"Content-Type": Z,
|
|
648
648
|
"Access-Control-Allow-Origin": "*"
|
|
649
649
|
}), r.end(ce);
|
|
650
650
|
});
|
|
651
|
-
}),
|
|
652
|
-
const
|
|
653
|
-
componentId:
|
|
654
|
-
distPath:
|
|
655
|
-
componentName:
|
|
656
|
-
htmlFile:
|
|
657
|
-
}),
|
|
651
|
+
}), Ye = () => new Promise((a, r) => {
|
|
652
|
+
const m = f ? t.default.resolve(j) : t.default.resolve(j, P), h = JSON.stringify({
|
|
653
|
+
componentId: x,
|
|
654
|
+
distPath: m,
|
|
655
|
+
componentName: T,
|
|
656
|
+
htmlFile: f ? w : null
|
|
657
|
+
}), S = {
|
|
658
658
|
hostname: "localhost",
|
|
659
|
-
port:
|
|
659
|
+
port: l,
|
|
660
660
|
path: "/_register",
|
|
661
661
|
method: "POST",
|
|
662
662
|
headers: {
|
|
663
663
|
"Content-Type": "application/json",
|
|
664
|
-
"Content-Length": Buffer.byteLength(
|
|
664
|
+
"Content-Length": Buffer.byteLength(h)
|
|
665
665
|
}
|
|
666
|
-
},
|
|
667
|
-
let
|
|
668
|
-
|
|
669
|
-
|
|
666
|
+
}, $ = n.default.request(S, (I) => {
|
|
667
|
+
let N = "";
|
|
668
|
+
I.on("data", (U) => N += U), I.on("end", () => {
|
|
669
|
+
I.statusCode === 200 ? a(JSON.parse(N)) : r(new Error(`Registration failed: ${I.statusCode}`));
|
|
670
670
|
});
|
|
671
671
|
});
|
|
672
|
-
|
|
673
|
-
}),
|
|
674
|
-
const
|
|
672
|
+
$.on("error", r), $.write(h), $.end();
|
|
673
|
+
}), ft = () => new Promise((a, r) => {
|
|
674
|
+
const m = JSON.stringify({ componentId: x }), h = {
|
|
675
675
|
hostname: "localhost",
|
|
676
|
-
port:
|
|
676
|
+
port: l,
|
|
677
677
|
path: "/_unregister",
|
|
678
678
|
method: "POST",
|
|
679
679
|
headers: {
|
|
680
680
|
"Content-Type": "application/json",
|
|
681
|
-
"Content-Length": Buffer.byteLength(
|
|
681
|
+
"Content-Length": Buffer.byteLength(m)
|
|
682
682
|
}
|
|
683
|
-
},
|
|
683
|
+
}, S = n.default.request(h, ($) => {
|
|
684
684
|
a();
|
|
685
685
|
});
|
|
686
|
-
|
|
687
|
-
}),
|
|
686
|
+
S.on("error", () => a()), S.write(m), S.end();
|
|
687
|
+
}), ht = (a) => `
|
|
688
688
|
<!-- MYOP HMR -->
|
|
689
689
|
<script>
|
|
690
690
|
(function() {
|
|
691
691
|
const componentId = '${a}';
|
|
692
|
-
const wsUrl = 'ws://localhost:${
|
|
692
|
+
const wsUrl = 'ws://localhost:${l}/_hmr/' + componentId;
|
|
693
693
|
let ws;
|
|
694
694
|
let reconnectAttempts = 0;
|
|
695
695
|
const maxReconnectAttempts = 10;
|
|
@@ -790,272 +790,272 @@ Sec-WebSocket-Accept: ${v}\r
|
|
|
790
790
|
})();
|
|
791
791
|
<\/script>
|
|
792
792
|
`, Me = (a, r) => {
|
|
793
|
-
if (!
|
|
794
|
-
const
|
|
795
|
-
return a.includes("</body>") ? a.replace("</body>", `${
|
|
796
|
-
},
|
|
797
|
-
const r = Buffer.from(a),
|
|
798
|
-
let
|
|
799
|
-
return
|
|
800
|
-
Buffer.from([129,
|
|
793
|
+
if (!k) return a;
|
|
794
|
+
const m = ht(r);
|
|
795
|
+
return a.includes("</body>") ? a.replace("</body>", `${m}</body>`) : a.includes("</html>") ? a.replace("</html>", `${m}</html>`) : a + m;
|
|
796
|
+
}, Ke = (a) => {
|
|
797
|
+
const r = Buffer.from(a), m = r.length;
|
|
798
|
+
let h;
|
|
799
|
+
return m < 126 ? h = Buffer.concat([
|
|
800
|
+
Buffer.from([129, m]),
|
|
801
801
|
// FIN + text frame, length
|
|
802
802
|
r
|
|
803
|
-
]) :
|
|
803
|
+
]) : m < 65536 ? h = Buffer.concat([
|
|
804
804
|
Buffer.from([129, 126]),
|
|
805
805
|
// FIN + text frame, extended length
|
|
806
|
-
Buffer.from([
|
|
806
|
+
Buffer.from([m >> 8, m & 255]),
|
|
807
807
|
// 16-bit length
|
|
808
808
|
r
|
|
809
|
-
]) :
|
|
809
|
+
]) : h = Buffer.concat([
|
|
810
810
|
Buffer.from([129, 127]),
|
|
811
811
|
// FIN + text frame, extended length
|
|
812
|
-
Buffer.from([0, 0, 0, 0,
|
|
812
|
+
Buffer.from([0, 0, 0, 0, m >> 24, m >> 16 & 255, m >> 8 & 255, m & 255]),
|
|
813
813
|
// 64-bit length
|
|
814
814
|
r
|
|
815
|
-
]),
|
|
816
|
-
},
|
|
817
|
-
if (!
|
|
818
|
-
const a =
|
|
815
|
+
]), h;
|
|
816
|
+
}, Qe = () => {
|
|
817
|
+
if (!k) return;
|
|
818
|
+
const a = f ? w : t.default.join(P, "index.html");
|
|
819
819
|
let r;
|
|
820
820
|
try {
|
|
821
|
-
const
|
|
822
|
-
r = Me(
|
|
823
|
-
} catch (
|
|
824
|
-
console.error("❌ Failed to read HTML for HMR:",
|
|
821
|
+
const m = o.default.readFileSync(a, "utf-8");
|
|
822
|
+
r = Me(m, x);
|
|
823
|
+
} catch (m) {
|
|
824
|
+
console.error("❌ Failed to read HTML for HMR:", m.message);
|
|
825
825
|
return;
|
|
826
826
|
}
|
|
827
|
-
if (
|
|
828
|
-
const
|
|
829
|
-
if (!
|
|
827
|
+
if (Re) {
|
|
828
|
+
const m = oe.get(x);
|
|
829
|
+
if (!m || m.size === 0)
|
|
830
830
|
return;
|
|
831
|
-
console.log(`🔥 Notifying ${
|
|
832
|
-
const
|
|
831
|
+
console.log(`🔥 Notifying ${m.size} HMR client(s)`);
|
|
832
|
+
const h = JSON.stringify({
|
|
833
833
|
type: "update",
|
|
834
834
|
html: r
|
|
835
|
-
}),
|
|
836
|
-
|
|
835
|
+
}), S = Ke(h);
|
|
836
|
+
m.forEach(($) => {
|
|
837
837
|
try {
|
|
838
|
-
|
|
838
|
+
$.write(S);
|
|
839
839
|
} catch {
|
|
840
|
-
|
|
840
|
+
m.delete($);
|
|
841
841
|
}
|
|
842
842
|
});
|
|
843
843
|
} else {
|
|
844
|
-
const
|
|
845
|
-
componentId:
|
|
844
|
+
const m = JSON.stringify({
|
|
845
|
+
componentId: x,
|
|
846
846
|
html: r
|
|
847
|
-
}),
|
|
847
|
+
}), h = {
|
|
848
848
|
hostname: "localhost",
|
|
849
|
-
port:
|
|
849
|
+
port: l,
|
|
850
850
|
path: "/_hmr_notify",
|
|
851
851
|
method: "POST",
|
|
852
852
|
headers: {
|
|
853
853
|
"Content-Type": "application/json",
|
|
854
|
-
"Content-Length": Buffer.byteLength(
|
|
854
|
+
"Content-Length": Buffer.byteLength(m)
|
|
855
855
|
},
|
|
856
856
|
timeout: 5e3
|
|
857
|
-
},
|
|
858
|
-
let
|
|
859
|
-
|
|
857
|
+
}, S = n.default.request(h, ($) => {
|
|
858
|
+
let I = "";
|
|
859
|
+
$.on("data", (N) => I += N), $.on("end", () => {
|
|
860
860
|
try {
|
|
861
|
-
const
|
|
862
|
-
|
|
861
|
+
const N = JSON.parse(I);
|
|
862
|
+
N.notified > 0 && console.log(`🔥 Notified ${N.notified} HMR client(s) via server`);
|
|
863
863
|
} catch {
|
|
864
864
|
}
|
|
865
865
|
});
|
|
866
866
|
});
|
|
867
|
-
|
|
868
|
-
}),
|
|
869
|
-
|
|
870
|
-
}),
|
|
867
|
+
S.on("error", () => {
|
|
868
|
+
}), S.on("timeout", () => {
|
|
869
|
+
S.destroy();
|
|
870
|
+
}), S.write(m), S.end();
|
|
871
871
|
}
|
|
872
872
|
};
|
|
873
|
-
let
|
|
873
|
+
let Ee = { hasTriedPlatformFix: !1, hasTriedInstall: !1 };
|
|
874
874
|
const ge = (a) => {
|
|
875
|
-
if (
|
|
876
|
-
|
|
875
|
+
if (g) {
|
|
876
|
+
M = !0;
|
|
877
877
|
return;
|
|
878
878
|
}
|
|
879
|
-
|
|
880
|
-
🔨 Building...`),
|
|
881
|
-
if (
|
|
882
|
-
const
|
|
883
|
-
...
|
|
879
|
+
g = !0, console.log(`
|
|
880
|
+
🔨 Building...`), e("npm run build", { maxBuffer: 10 * 1024 * 1024 }, async (r, m, h) => {
|
|
881
|
+
if (g = !1, r) {
|
|
882
|
+
const S = await lt(r, m, h, e, {
|
|
883
|
+
...Ee,
|
|
884
884
|
onRetry: () => ge(a)
|
|
885
885
|
});
|
|
886
|
-
|
|
886
|
+
Ee = { ...Ee, ...S }, S.handled || (console.error("❌ Build failed:", r.message), h && console.error(h));
|
|
887
887
|
} else
|
|
888
|
-
console.log("✅ Build completed"),
|
|
889
|
-
|
|
888
|
+
console.log("✅ Build completed"), m && console.log(m), Qe(), a && a();
|
|
889
|
+
M && (M = !1, ge());
|
|
890
890
|
});
|
|
891
|
-
},
|
|
892
|
-
o.default.readdir(a, { withFileTypes: !0 }, (r,
|
|
893
|
-
r || (
|
|
894
|
-
const
|
|
895
|
-
if (
|
|
896
|
-
|
|
897
|
-
else if (
|
|
898
|
-
const
|
|
899
|
-
if (
|
|
891
|
+
}, Ze = /* @__PURE__ */ new Set(), Ie = (a) => {
|
|
892
|
+
o.default.readdir(a, { withFileTypes: !0 }, (r, m) => {
|
|
893
|
+
r || (m.forEach((h) => {
|
|
894
|
+
const S = t.default.join(a, h.name);
|
|
895
|
+
if (h.isDirectory())
|
|
896
|
+
h.name !== "node_modules" && h.name !== "dist" && !h.name.startsWith(".") && Ie(S);
|
|
897
|
+
else if (h.isFile()) {
|
|
898
|
+
const $ = t.default.extname(h.name);
|
|
899
|
+
if ($ === ".js" || $ === ".css" || $ === ".html")
|
|
900
900
|
try {
|
|
901
|
-
const
|
|
902
|
-
|
|
901
|
+
const I = o.default.readFileSync(S, "utf-8");
|
|
902
|
+
p.set(S, I);
|
|
903
903
|
} catch {
|
|
904
904
|
}
|
|
905
905
|
}
|
|
906
|
-
}),
|
|
907
|
-
if (!
|
|
908
|
-
const
|
|
909
|
-
if (
|
|
910
|
-
const
|
|
906
|
+
}), Ze.has(a) || (Ze.add(a), o.default.watch(a, (h, S) => {
|
|
907
|
+
if (!S) return;
|
|
908
|
+
const $ = t.default.extname(S);
|
|
909
|
+
if ($ !== ".js" && $ !== ".css" && $ !== ".html") return;
|
|
910
|
+
const I = t.default.join(a, S);
|
|
911
911
|
setTimeout(() => {
|
|
912
912
|
try {
|
|
913
|
-
const
|
|
914
|
-
|
|
913
|
+
const N = o.default.readFileSync(I, "utf-8"), U = p.get(I);
|
|
914
|
+
N !== U && (p.set(I, N), console.log(`📝 File changed: ${I}`), f ? Qe() : ge());
|
|
915
915
|
} catch {
|
|
916
916
|
}
|
|
917
917
|
}, 50);
|
|
918
918
|
})));
|
|
919
919
|
});
|
|
920
|
-
},
|
|
920
|
+
}, qe = (a) => {
|
|
921
921
|
console.log(`
|
|
922
|
-
🔨 Component: ${
|
|
923
|
-
`), a && a()) : (ge(a),
|
|
922
|
+
🔨 Component: ${x}`), f ? (console.log("📄 No build needed (single HTML file mode)"), Ie(j), console.log(`👀 Watching ${w} for changes...`), console.log(`Press Ctrl+C to stop
|
|
923
|
+
`), a && a()) : (ge(a), Ie(j), console.log("👀 Watching .js, .css, and .html files for changes..."), console.log(`Press Ctrl+C to stop
|
|
924
924
|
`));
|
|
925
|
-
},
|
|
925
|
+
}, yt = () => new Promise((a) => {
|
|
926
926
|
const r = {
|
|
927
927
|
hostname: "localhost",
|
|
928
|
-
port:
|
|
928
|
+
port: l,
|
|
929
929
|
path: "/_list",
|
|
930
930
|
method: "GET",
|
|
931
931
|
timeout: 1e3
|
|
932
|
-
},
|
|
932
|
+
}, m = n.default.request(r, (h) => {
|
|
933
933
|
a(!0);
|
|
934
934
|
});
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
}),
|
|
938
|
-
}),
|
|
939
|
-
const r = n.default.createServer((
|
|
940
|
-
if (
|
|
941
|
-
let
|
|
942
|
-
|
|
935
|
+
m.on("error", () => a(!1)), m.on("timeout", () => {
|
|
936
|
+
m.destroy(), a(!1);
|
|
937
|
+
}), m.end();
|
|
938
|
+
}), wt = () => new Promise((a) => {
|
|
939
|
+
const r = n.default.createServer((m, h) => {
|
|
940
|
+
if (h.setHeader("Content-Type", "application/json"), m.method === "POST" && m.url === "/_register") {
|
|
941
|
+
let S = "";
|
|
942
|
+
m.on("data", ($) => S += $), m.on("end", () => {
|
|
943
943
|
try {
|
|
944
|
-
const { componentId:
|
|
945
|
-
|
|
946
|
-
const
|
|
947
|
-
console.log(`✅ Registered: ${
|
|
948
|
-
} catch (
|
|
949
|
-
|
|
944
|
+
const { componentId: $, distPath: I, componentName: N, htmlFile: U } = JSON.parse(S);
|
|
945
|
+
F.set($, { path: I, name: N || null, htmlFile: U || null });
|
|
946
|
+
const K = N ? ` (${N})` : "";
|
|
947
|
+
console.log(`✅ Registered: ${$}${K} -> ${I}${U ? "/" + U : ""}`), h.writeHead(200), h.end(JSON.stringify({ success: !0, registered: Array.from(F.keys()) }));
|
|
948
|
+
} catch ($) {
|
|
949
|
+
h.writeHead(400), h.end(JSON.stringify({ error: $.message }));
|
|
950
950
|
}
|
|
951
951
|
});
|
|
952
|
-
} else if (
|
|
953
|
-
let
|
|
954
|
-
|
|
952
|
+
} else if (m.method === "POST" && m.url === "/_unregister") {
|
|
953
|
+
let S = "";
|
|
954
|
+
m.on("data", ($) => S += $), m.on("end", () => {
|
|
955
955
|
try {
|
|
956
|
-
const { componentId:
|
|
957
|
-
|
|
958
|
-
} catch (
|
|
959
|
-
|
|
956
|
+
const { componentId: $ } = JSON.parse(S);
|
|
957
|
+
F.delete($), console.log(`❌ Unregistered: ${$}`), h.writeHead(200), h.end(JSON.stringify({ success: !0 }));
|
|
958
|
+
} catch ($) {
|
|
959
|
+
h.writeHead(400), h.end(JSON.stringify({ error: $.message }));
|
|
960
960
|
}
|
|
961
961
|
});
|
|
962
|
-
} else
|
|
962
|
+
} else m.method === "GET" && m.url === "/_list" ? (h.writeHead(200), h.end(JSON.stringify({ components: Array.from(F.entries()) }))) : (h.writeHead(404), h.end(JSON.stringify({ error: "Not found" })));
|
|
963
963
|
});
|
|
964
964
|
r.on("error", () => {
|
|
965
965
|
a(!1);
|
|
966
|
-
}), r.listen(
|
|
966
|
+
}), r.listen(l, () => {
|
|
967
967
|
console.log(`
|
|
968
|
-
🔄 Taking over as server...`), console.log(`📡 Management server on port ${
|
|
968
|
+
🔄 Taking over as server...`), console.log(`📡 Management server on port ${l}`), ue.on("error", () => {
|
|
969
969
|
r.close(), a(!1);
|
|
970
970
|
}), ue.listen(d, () => {
|
|
971
971
|
console.log(`📡 Main server running at http://localhost:${d}`);
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
path:
|
|
975
|
-
name:
|
|
976
|
-
htmlFile:
|
|
972
|
+
const m = f ? t.default.resolve(j) : t.default.resolve(j, P);
|
|
973
|
+
F.set(x, {
|
|
974
|
+
path: m,
|
|
975
|
+
name: T,
|
|
976
|
+
htmlFile: f ? w : null
|
|
977
977
|
});
|
|
978
|
-
const
|
|
979
|
-
console.log(`✅ Registered component: ${
|
|
978
|
+
const h = T ? ` (${T})` : "";
|
|
979
|
+
console.log(`✅ Registered component: ${x}${h}`), console.log(`📡 Access at: http://localhost:${d}/view/${x}/`), a(!0);
|
|
980
980
|
});
|
|
981
981
|
});
|
|
982
982
|
});
|
|
983
983
|
let fe;
|
|
984
|
-
const
|
|
984
|
+
const Xe = () => {
|
|
985
985
|
fe = setInterval(async () => {
|
|
986
|
-
await
|
|
987
|
-
⚠️ Server appears to be down, attempting to take over...`), await
|
|
986
|
+
await yt() || (clearInterval(fe), console.log(`
|
|
987
|
+
⚠️ Server appears to be down, attempting to take over...`), await wt() ? (console.log("✅ Successfully took over as server"), Re = !0) : (console.log("ℹ️ Another instance took over, re-registering..."), setTimeout(async () => {
|
|
988
988
|
try {
|
|
989
|
-
await
|
|
990
|
-
} catch (
|
|
991
|
-
console.error("❌ Failed to re-register:",
|
|
989
|
+
await Ye(), console.log(`✅ Re-registered component: ${x}`), Xe();
|
|
990
|
+
} catch (m) {
|
|
991
|
+
console.error("❌ Failed to re-register:", m.message);
|
|
992
992
|
}
|
|
993
993
|
}, 2e3)));
|
|
994
994
|
}, 3e3);
|
|
995
|
-
},
|
|
995
|
+
}, et = async () => {
|
|
996
996
|
console.log(`
|
|
997
997
|
|
|
998
|
-
🛑 Shutting down...`), fe && clearInterval(fe), await
|
|
998
|
+
🛑 Shutting down...`), fe && clearInterval(fe), await ft(), process.exit(0);
|
|
999
999
|
};
|
|
1000
|
-
process.on("SIGINT",
|
|
1001
|
-
let
|
|
1002
|
-
|
|
1000
|
+
process.on("SIGINT", et), process.on("SIGTERM", et);
|
|
1001
|
+
let Re = !1;
|
|
1002
|
+
Pe.on("error", async (a) => {
|
|
1003
1003
|
if (a.code === "EADDRINUSE") {
|
|
1004
1004
|
console.log(`
|
|
1005
1005
|
🔗 Connecting to existing dev server...`);
|
|
1006
1006
|
try {
|
|
1007
|
-
|
|
1008
|
-
const r = await
|
|
1009
|
-
console.log(`✅ Registered component: ${
|
|
1010
|
-
process.env.MYOP_NO_BROWSER || b(`http://localhost:${d}/view/${
|
|
1011
|
-
}),
|
|
1007
|
+
x = await A();
|
|
1008
|
+
const r = await Ye();
|
|
1009
|
+
console.log(`✅ Registered component: ${x}`), console.log(`📡 Access at: http://localhost:${d}/view/${x}/`), console.log(`📋 All registered components: ${r.registered.join(", ")}`), qe(() => {
|
|
1010
|
+
process.env.MYOP_NO_BROWSER || b(`http://localhost:${d}/view/${x}/`);
|
|
1011
|
+
}), Xe();
|
|
1012
1012
|
} catch (r) {
|
|
1013
1013
|
console.error("❌ Failed to register component:", r.message), process.exit(1);
|
|
1014
1014
|
}
|
|
1015
1015
|
} else
|
|
1016
1016
|
console.error("❌ Management server error:", a.message), process.exit(1);
|
|
1017
|
-
}),
|
|
1018
|
-
|
|
1019
|
-
🚀 Starting shared dev server...`), console.log(`📡 Management server on port ${
|
|
1017
|
+
}), Pe.on("upgrade", gt), Pe.listen(l, async () => {
|
|
1018
|
+
Re = !0, console.log(`
|
|
1019
|
+
🚀 Starting shared dev server...`), console.log(`📡 Management server on port ${l}`), ue.on("error", (a) => {
|
|
1020
1020
|
console.error("❌ Main server error:", a.message), process.exit(1);
|
|
1021
1021
|
}), ue.listen(d, async () => {
|
|
1022
|
-
console.log(`📡 Main server running at http://localhost:${d}`), (
|
|
1023
|
-
const a =
|
|
1024
|
-
|
|
1022
|
+
console.log(`📡 Main server running at http://localhost:${d}`), (x === "DEV" || x === "NEW") && (x = "DEV1");
|
|
1023
|
+
const a = f ? t.default.resolve(j) : t.default.resolve(j, P);
|
|
1024
|
+
F.set(x, {
|
|
1025
1025
|
path: a,
|
|
1026
|
-
name:
|
|
1027
|
-
htmlFile:
|
|
1026
|
+
name: T,
|
|
1027
|
+
htmlFile: f ? w : null
|
|
1028
1028
|
});
|
|
1029
|
-
const r =
|
|
1030
|
-
console.log(`✅ Registered component: ${
|
|
1031
|
-
process.env.MYOP_NO_BROWSER || b(`http://localhost:${d}/view/${
|
|
1029
|
+
const r = T ? ` (${T})` : "";
|
|
1030
|
+
console.log(`✅ Registered component: ${x}${r}`), console.log(`📡 Access at: http://localhost:${d}/view/${x}/`), qe(() => {
|
|
1031
|
+
process.env.MYOP_NO_BROWSER || b(`http://localhost:${d}/view/${x}/`);
|
|
1032
1032
|
});
|
|
1033
1033
|
});
|
|
1034
1034
|
});
|
|
1035
1035
|
}
|
|
1036
|
-
const
|
|
1037
|
-
constructor(
|
|
1038
|
-
this.components =
|
|
1039
|
-
(
|
|
1036
|
+
const L = class L {
|
|
1037
|
+
constructor(t) {
|
|
1038
|
+
this.components = t.map(
|
|
1039
|
+
(e) => typeof e == "string" ? { name: e, path: "", id: "" } : e
|
|
1040
1040
|
), this.logs = /* @__PURE__ */ new Map(), this.scrollPos = /* @__PURE__ */ new Map(), this.statuses = /* @__PURE__ */ new Map(), this.statusKeys = /* @__PURE__ */ new Map(), this.panelPositions = /* @__PURE__ */ new Map(), this.needsFullRedraw = !0, this.pendingUpdates = /* @__PURE__ */ new Set(), this.renderQueued = !1, this.startTime = Date.now(), this.visibleLogLines = 8, this.selectedPanel = 0;
|
|
1041
|
-
for (const
|
|
1042
|
-
this.logs.set(
|
|
1041
|
+
for (const e of this.components)
|
|
1042
|
+
this.logs.set(e.name, []), this.scrollPos.set(e.name, 0), this.statuses.set(e.name, "Initializing..."), this.statusKeys.set(e.name, "initializing");
|
|
1043
1043
|
this.cols = process.stdout.columns || 120, this.rows = process.stdout.rows || 30, process.stdout.on("resize", () => {
|
|
1044
1044
|
this.cols = process.stdout.columns || 120, this.rows = process.stdout.rows || 30, this.needsFullRedraw = !0, this.calculateLayout(), this.render();
|
|
1045
|
-
}), this.setupKeyboardInput(), process.stdout.write(
|
|
1045
|
+
}), this.setupKeyboardInput(), process.stdout.write(L.ESC.hideCursor), this.calculateLayout(), this.render(), this.uptimeInterval = setInterval(() => this.updateHeader(), 1e3);
|
|
1046
1046
|
}
|
|
1047
1047
|
setupKeyboardInput() {
|
|
1048
|
-
process.stdin.isTTY && (process.stdin.setRawMode(!0), process.stdin.resume(), process.stdin.setEncoding("utf8"), process.stdin.on("data", (
|
|
1048
|
+
process.stdin.isTTY && (process.stdin.setRawMode(!0), process.stdin.resume(), process.stdin.setEncoding("utf8"), process.stdin.on("data", (t) => {
|
|
1049
1049
|
var n;
|
|
1050
|
-
|
|
1051
|
-
const
|
|
1052
|
-
if (
|
|
1053
|
-
switch (
|
|
1050
|
+
t === "" && (this.clear(), process.exit());
|
|
1051
|
+
const e = (n = this.components[this.selectedPanel]) == null ? void 0 : n.name;
|
|
1052
|
+
if (e)
|
|
1053
|
+
switch (t) {
|
|
1054
1054
|
case "\x1B[A":
|
|
1055
|
-
this.scroll(
|
|
1055
|
+
this.scroll(e, -1);
|
|
1056
1056
|
break;
|
|
1057
1057
|
case "\x1B[B":
|
|
1058
|
-
this.scroll(
|
|
1058
|
+
this.scroll(e, 1);
|
|
1059
1059
|
break;
|
|
1060
1060
|
case "\x1B[C":
|
|
1061
1061
|
this.selectedPanel = (this.selectedPanel + 1) % this.components.length, this.needsFullRedraw = !0, this.render();
|
|
@@ -1064,57 +1064,57 @@ const N = class N {
|
|
|
1064
1064
|
this.selectedPanel = (this.selectedPanel - 1 + this.components.length) % this.components.length, this.needsFullRedraw = !0, this.render();
|
|
1065
1065
|
break;
|
|
1066
1066
|
case "\x1B[5~":
|
|
1067
|
-
this.scroll(
|
|
1067
|
+
this.scroll(e, -this.visibleLogLines);
|
|
1068
1068
|
break;
|
|
1069
1069
|
case "\x1B[6~":
|
|
1070
|
-
this.scroll(
|
|
1070
|
+
this.scroll(e, this.visibleLogLines);
|
|
1071
1071
|
break;
|
|
1072
1072
|
case "g":
|
|
1073
|
-
this.scrollPos.set(
|
|
1073
|
+
this.scrollPos.set(e, 0), this.queueUpdate(e);
|
|
1074
1074
|
break;
|
|
1075
1075
|
case "G":
|
|
1076
|
-
const
|
|
1077
|
-
this.scrollPos.set(
|
|
1076
|
+
const s = this.logs.get(e) || [];
|
|
1077
|
+
this.scrollPos.set(e, Math.max(0, s.length - this.visibleLogLines)), this.queueUpdate(e);
|
|
1078
1078
|
break;
|
|
1079
1079
|
}
|
|
1080
1080
|
}));
|
|
1081
1081
|
}
|
|
1082
1082
|
calculateLayout() {
|
|
1083
|
-
const
|
|
1083
|
+
const t = this.components.length, e = 38;
|
|
1084
1084
|
let n;
|
|
1085
|
-
this.cols >=
|
|
1086
|
-
const
|
|
1087
|
-
this.visibleLogLines = Math.max(2, d - 4), this.layout = { panelsPerRow: n, panelWidth:
|
|
1088
|
-
for (let
|
|
1089
|
-
const
|
|
1090
|
-
this.panelPositions.set(
|
|
1091
|
-
row:
|
|
1092
|
-
col:
|
|
1093
|
-
width:
|
|
1085
|
+
this.cols >= e * 3 + 4 ? n = Math.min(t, 3) : this.cols >= e * 2 + 2 ? n = Math.min(t, 2) : n = 1;
|
|
1086
|
+
const s = Math.ceil(t / n), i = Math.floor(this.cols / n), c = 2, y = this.rows - c - 2, d = Math.floor(y / s);
|
|
1087
|
+
this.visibleLogLines = Math.max(2, d - 4), this.layout = { panelsPerRow: n, panelWidth: i, numRows: s, panelHeight: d }, this.panelPositions.clear();
|
|
1088
|
+
for (let l = 0; l < t; l++) {
|
|
1089
|
+
const P = this.components[l], g = Math.floor(l / n), M = l % n;
|
|
1090
|
+
this.panelPositions.set(P.name, {
|
|
1091
|
+
row: c + 1 + g * d,
|
|
1092
|
+
col: M * i + 1,
|
|
1093
|
+
width: i,
|
|
1094
1094
|
height: d
|
|
1095
1095
|
});
|
|
1096
1096
|
}
|
|
1097
1097
|
}
|
|
1098
|
-
log(
|
|
1099
|
-
const
|
|
1098
|
+
log(t, e, n = "info") {
|
|
1099
|
+
const s = this.logs.get(t) || [], i = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
|
|
1100
1100
|
hour12: !1,
|
|
1101
1101
|
hour: "2-digit",
|
|
1102
1102
|
minute: "2-digit",
|
|
1103
1103
|
second: "2-digit"
|
|
1104
1104
|
});
|
|
1105
|
-
|
|
1105
|
+
e.includes("✅") || e.includes("completed") ? n = "success" : e.includes("❌") || e.includes("failed") ? n = "error" : e.includes("⚠") ? n = "warning" : e.includes("🔥") || e.includes("HMR") ? n = "hmr" : (e.includes("📝") || e.includes("changed")) && (n = "change"), s.push({ timestamp: i, message: e.replace(/[✅❌⚠🔥📝🔨]/g, "").trim(), type: n }), this.logs.set(t, s), s.length > this.visibleLogLines && this.scrollPos.set(t, s.length - this.visibleLogLines), this.queueUpdate(t);
|
|
1106
1106
|
}
|
|
1107
|
-
setStatus(
|
|
1107
|
+
setStatus(t, e) {
|
|
1108
1108
|
let n = "ready";
|
|
1109
|
-
const
|
|
1110
|
-
|
|
1109
|
+
const s = e.toLowerCase();
|
|
1110
|
+
s.includes("initializing") || s.includes("⏳") ? n = "initializing" : s.includes("starting") ? n = "starting" : s.includes("building") || s.includes("🔨") ? n = "building" : s.includes("ready") || s.includes("✅") ? n = "ready" : s.includes("changed") || s.includes("📝") ? n = "changed" : s.includes("hmr") ? n = "hmr_update" : s.includes("🔥") ? n = "hmr" : s.includes("error") || s.includes("❌") ? n = "error" : s.includes("warning") || s.includes("⚠") ? n = "warning" : (s.includes("stopped") || s.includes("exited")) && (n = "stopped"), this.statuses.set(t, e), this.statusKeys.set(t, n), this.queueUpdate(t);
|
|
1111
1111
|
}
|
|
1112
|
-
scroll(
|
|
1113
|
-
const n = this.logs.get(
|
|
1114
|
-
|
|
1112
|
+
scroll(t, e) {
|
|
1113
|
+
const n = this.logs.get(t) || [], s = this.scrollPos.get(t) || 0, i = Math.max(0, n.length - this.visibleLogLines), c = Math.max(0, Math.min(i, s + e));
|
|
1114
|
+
c !== s && (this.scrollPos.set(t, c), this.queueUpdate(t));
|
|
1115
1115
|
}
|
|
1116
|
-
queueUpdate(
|
|
1117
|
-
this.pendingUpdates.add(
|
|
1116
|
+
queueUpdate(t) {
|
|
1117
|
+
this.pendingUpdates.add(t), this.renderQueued || (this.renderQueued = !0, setImmediate(() => {
|
|
1118
1118
|
this.renderQueued = !1, this.flushUpdates();
|
|
1119
1119
|
}));
|
|
1120
1120
|
}
|
|
@@ -1123,80 +1123,80 @@ const N = class N {
|
|
|
1123
1123
|
this.fullRender(), this.needsFullRedraw = !1, this.pendingUpdates.clear();
|
|
1124
1124
|
return;
|
|
1125
1125
|
}
|
|
1126
|
-
for (const
|
|
1127
|
-
this.renderPanel(
|
|
1126
|
+
for (const t of this.pendingUpdates)
|
|
1127
|
+
this.renderPanel(t);
|
|
1128
1128
|
this.pendingUpdates.clear();
|
|
1129
1129
|
}
|
|
1130
1130
|
getUptime() {
|
|
1131
|
-
const
|
|
1132
|
-
return `${
|
|
1131
|
+
const t = Math.floor((Date.now() - this.startTime) / 1e3), e = Math.floor(t / 60), n = t % 60;
|
|
1132
|
+
return `${e}:${n.toString().padStart(2, "0")}`;
|
|
1133
1133
|
}
|
|
1134
1134
|
updateHeader() {
|
|
1135
|
-
const
|
|
1136
|
-
let
|
|
1137
|
-
|
|
1138
|
-
}
|
|
1139
|
-
renderPanel(
|
|
1140
|
-
const
|
|
1141
|
-
if (!
|
|
1142
|
-
const
|
|
1143
|
-
let
|
|
1144
|
-
|
|
1145
|
-
const b = 5 +
|
|
1146
|
-
|
|
1147
|
-
const
|
|
1148
|
-
let
|
|
1149
|
-
|
|
1150
|
-
const
|
|
1151
|
-
let
|
|
1152
|
-
|
|
1153
|
-
const
|
|
1154
|
-
for (let
|
|
1155
|
-
const
|
|
1156
|
-
let
|
|
1157
|
-
if (
|
|
1158
|
-
let
|
|
1159
|
-
|
|
1160
|
-
const
|
|
1161
|
-
|
|
1162
|
-
const
|
|
1163
|
-
|
|
1135
|
+
const t = L.C, e = Array.from(this.statusKeys.values()).filter((i) => i === "ready").length, n = this.components.length;
|
|
1136
|
+
let s = `${t.dim}📡${t.reset} http://localhost:9292 ${t.gray}|${t.reset} `;
|
|
1137
|
+
s += `${t.green}${e}${t.reset}/${n} ready ${t.gray}|${t.reset} `, s += `⏱ ${this.getUptime()} ${t.gray}|${t.reset} `, s += `Press ${t.yellow}Ctrl+C${t.reset} to stop`, s += L.ESC.clearLine.slice(0, -1), process.stdout.write(L.ESC.moveTo(2, 1) + s);
|
|
1138
|
+
}
|
|
1139
|
+
renderPanel(t) {
|
|
1140
|
+
const e = L.C, n = L.STATUS, s = this.panelPositions.get(t);
|
|
1141
|
+
if (!s) return;
|
|
1142
|
+
const i = this.components.findIndex((A) => A.name === t), c = this.components[i], u = i === this.selectedPanel, y = this.statusKeys.get(t) || "initializing", d = n[y], l = e[d.color], P = this.logs.get(t) || [], g = this.scrollPos.get(t) || 0, M = s.width - 1, f = u ? e.cyan : e.gray, w = [], _ = c.name.substring(0, M - 20);
|
|
1143
|
+
let R = `${f}┌─${e.reset} ${l}${d.icon}${e.reset} `;
|
|
1144
|
+
R += `${e.bold}${_}${e.reset} ${e.gray}─${e.reset} ${l}${d.label}${e.reset} `;
|
|
1145
|
+
const b = 5 + _.length + d.label.length + 3;
|
|
1146
|
+
R += `${f}${"─".repeat(Math.max(0, M - b))}┐${e.reset}`, w.push(L.ESC.moveTo(s.row, s.col) + R);
|
|
1147
|
+
const p = (c.path || "").substring(0, M - 6);
|
|
1148
|
+
let E = `${f}│${e.reset} ${e.dim}${p}${e.reset}`;
|
|
1149
|
+
E += " ".repeat(Math.max(0, M - p.length - 3)), E += `${f}│${e.reset}`, w.push(L.ESC.moveTo(s.row + 1, s.col) + E);
|
|
1150
|
+
const x = P.length, T = x > this.visibleLogLines ? `${g + 1}-${Math.min(g + this.visibleLogLines, x)}/${x}` : "";
|
|
1151
|
+
let k = `${f}├${"─".repeat(M - T.length - 4)}${e.reset}`;
|
|
1152
|
+
T && (k += `${e.dim}${T}${e.reset}`), k += `${f}${"─".repeat(2)}┤${e.reset}`, w.push(L.ESC.moveTo(s.row + 2, s.col) + k);
|
|
1153
|
+
const H = P.slice(g, g + this.visibleLogLines);
|
|
1154
|
+
for (let A = 0; A < this.visibleLogLines; A++) {
|
|
1155
|
+
const j = H[A];
|
|
1156
|
+
let J = `${f}│${e.reset}`;
|
|
1157
|
+
if (j) {
|
|
1158
|
+
let F = e.white;
|
|
1159
|
+
j.type === "success" ? F = e.green : j.type === "error" ? F = e.red : j.type === "warning" ? F = e.yellow : j.type === "hmr" ? F = e.magenta : j.type === "change" && (F = e.blue);
|
|
1160
|
+
const V = j.message.substring(0, M - 12);
|
|
1161
|
+
J += `${e.dim}${j.timestamp}${e.reset} ${F}${V}${e.reset}`;
|
|
1162
|
+
const te = M - j.timestamp.length - V.length - 2;
|
|
1163
|
+
J += " ".repeat(Math.max(0, te));
|
|
1164
1164
|
} else
|
|
1165
|
-
|
|
1166
|
-
|
|
1165
|
+
J += " ".repeat(M - 2);
|
|
1166
|
+
J += `${f}│${e.reset}`, w.push(L.ESC.moveTo(s.row + 3 + A, s.col) + J);
|
|
1167
1167
|
}
|
|
1168
|
-
|
|
1168
|
+
w.push(L.ESC.moveTo(s.row + 3 + this.visibleLogLines, s.col) + `${f}└${"─".repeat(M - 2)}┘${e.reset}`), process.stdout.write(w.join(""));
|
|
1169
1169
|
}
|
|
1170
1170
|
fullRender() {
|
|
1171
|
-
const
|
|
1172
|
-
process.stdout.write(
|
|
1173
|
-
const
|
|
1174
|
-
process.stdout.write(`${
|
|
1175
|
-
for (const
|
|
1176
|
-
this.renderPanel(
|
|
1171
|
+
const t = L.C;
|
|
1172
|
+
process.stdout.write(L.ESC.clearScreen + L.ESC.moveTo(1, 1));
|
|
1173
|
+
const e = " MYOP MONOREPO DEV ", n = Math.floor((this.cols - e.length) / 2);
|
|
1174
|
+
process.stdout.write(`${t.cyan}${"━".repeat(n)}${t.bold}${t.bgCyan}${t.black}${e}${t.reset}${t.cyan}${"━".repeat(this.cols - n - e.length)}${t.reset}`), this.updateHeader();
|
|
1175
|
+
for (const s of this.components)
|
|
1176
|
+
this.renderPanel(s.name);
|
|
1177
1177
|
this.renderFooter();
|
|
1178
1178
|
}
|
|
1179
1179
|
renderFooter() {
|
|
1180
|
-
const
|
|
1181
|
-
let n = `${
|
|
1182
|
-
n += `${
|
|
1180
|
+
const t = L.C, e = this.rows - 1;
|
|
1181
|
+
let n = `${t.gray}`;
|
|
1182
|
+
n += `${t.green}●${t.gray} Ready `, n += `${t.yellow}⟳${t.gray} Building `, n += `${t.magenta}⚡${t.gray} HMR `, n += `${t.red}✖${t.gray} Error `, n += `${t.dim}| ←→: select panel ↑↓: scroll PgUp/PgDn: page g/G: top/bottom${t.reset}`, process.stdout.write(L.ESC.moveTo(e, 1) + n);
|
|
1183
1183
|
}
|
|
1184
1184
|
render() {
|
|
1185
1185
|
this.needsFullRedraw = !0, this.queueUpdate("__full__");
|
|
1186
1186
|
}
|
|
1187
1187
|
clear() {
|
|
1188
|
-
this.uptimeInterval && clearInterval(this.uptimeInterval), process.stdin.isTTY && process.stdin.setRawMode(!1), process.stdout.write(
|
|
1188
|
+
this.uptimeInterval && clearInterval(this.uptimeInterval), process.stdin.isTTY && process.stdin.setRawMode(!1), process.stdout.write(L.ESC.clearScreen + L.ESC.moveTo(1, 1) + L.ESC.showCursor);
|
|
1189
1189
|
}
|
|
1190
1190
|
};
|
|
1191
1191
|
// ANSI escape codes
|
|
1192
|
-
ye(
|
|
1193
|
-
moveTo: (
|
|
1192
|
+
ye(L, "ESC", {
|
|
1193
|
+
moveTo: (t, e) => `\x1B[${t};${e}H`,
|
|
1194
1194
|
hideCursor: "\x1B[?25l",
|
|
1195
1195
|
showCursor: "\x1B[?25h",
|
|
1196
1196
|
clearScreen: "\x1B[2J",
|
|
1197
1197
|
clearLine: "\x1B[2K"
|
|
1198
1198
|
}), // Colors
|
|
1199
|
-
ye(
|
|
1199
|
+
ye(L, "C", {
|
|
1200
1200
|
reset: "\x1B[0m",
|
|
1201
1201
|
bold: "\x1B[1m",
|
|
1202
1202
|
dim: "\x1B[2m",
|
|
@@ -1211,7 +1211,7 @@ ye(N, "C", {
|
|
|
1211
1211
|
bgCyan: "\x1B[46m",
|
|
1212
1212
|
black: "\x1B[30m"
|
|
1213
1213
|
}), // Status configs
|
|
1214
|
-
ye(
|
|
1214
|
+
ye(L, "STATUS", {
|
|
1215
1215
|
initializing: { icon: "◔", color: "yellow", label: "Initializing" },
|
|
1216
1216
|
starting: { icon: "◑", color: "yellow", label: "Starting" },
|
|
1217
1217
|
building: { icon: "⟳", color: "yellow", label: "Building" },
|
|
@@ -1224,137 +1224,137 @@ ye(N, "STATUS", {
|
|
|
1224
1224
|
warning: { icon: "⚠", color: "yellow", label: "Warning" },
|
|
1225
1225
|
stopped: { icon: "■", color: "gray", label: "Stopped" }
|
|
1226
1226
|
});
|
|
1227
|
-
let Ne =
|
|
1228
|
-
async function
|
|
1229
|
-
const { spawn:
|
|
1230
|
-
name:
|
|
1231
|
-
path:
|
|
1232
|
-
id:
|
|
1233
|
-
})),
|
|
1234
|
-
const
|
|
1235
|
-
let
|
|
1236
|
-
|
|
1227
|
+
let Ne = L;
|
|
1228
|
+
async function Ht(o) {
|
|
1229
|
+
const { spawn: t, exec: e } = await import("child_process"), n = await import("path"), s = o.map((l) => ({
|
|
1230
|
+
name: l.name,
|
|
1231
|
+
path: l.path,
|
|
1232
|
+
id: l.componentId || ""
|
|
1233
|
+
})), i = new Ne(s), c = [], u = (l) => {
|
|
1234
|
+
const P = process.platform;
|
|
1235
|
+
let g;
|
|
1236
|
+
P === "darwin" ? g = `open "${l}"` : P === "win32" ? g = `start "" "${l}"` : g = `xdg-open "${l}"`, e(g, () => {
|
|
1237
1237
|
});
|
|
1238
|
-
},
|
|
1239
|
-
|
|
1240
|
-
🛑 Shutting down all components...`),
|
|
1238
|
+
}, y = () => {
|
|
1239
|
+
i.clear(), console.log(`
|
|
1240
|
+
🛑 Shutting down all components...`), c.forEach((l) => {
|
|
1241
1241
|
try {
|
|
1242
|
-
|
|
1242
|
+
l.kill("SIGTERM");
|
|
1243
1243
|
} catch {
|
|
1244
1244
|
}
|
|
1245
1245
|
}), setTimeout(() => process.exit(0), 500);
|
|
1246
1246
|
};
|
|
1247
|
-
process.on("SIGINT",
|
|
1247
|
+
process.on("SIGINT", y), process.on("SIGTERM", y);
|
|
1248
1248
|
const d = process.argv[1];
|
|
1249
|
-
for (let
|
|
1250
|
-
const
|
|
1251
|
-
|
|
1252
|
-
const
|
|
1253
|
-
cwd: n.default.resolve(
|
|
1249
|
+
for (let l = 0; l < o.length; l++) {
|
|
1250
|
+
const P = o[l], g = P.name;
|
|
1251
|
+
i.setStatus(g, "⏳ Starting..."), i.log(g, `Starting in ${P.path}`);
|
|
1252
|
+
const M = t("node", [d, "dev"], {
|
|
1253
|
+
cwd: n.default.resolve(P.path),
|
|
1254
1254
|
env: { ...process.env, FORCE_COLOR: "1", MYOP_NO_BROWSER: "1" },
|
|
1255
1255
|
stdio: ["ignore", "pipe", "pipe"]
|
|
1256
1256
|
});
|
|
1257
|
-
|
|
1258
|
-
let
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
const
|
|
1257
|
+
c.push(M);
|
|
1258
|
+
let f = "";
|
|
1259
|
+
M.stdout.on("data", (w) => {
|
|
1260
|
+
f += w.toString();
|
|
1261
|
+
const _ = f.split(`
|
|
1262
1262
|
`);
|
|
1263
|
-
|
|
1264
|
-
for (const
|
|
1265
|
-
const b =
|
|
1266
|
-
b && (b.includes("Registered component") || b.includes("Registered:") ?
|
|
1263
|
+
f = _.pop() || "";
|
|
1264
|
+
for (const R of _) {
|
|
1265
|
+
const b = R.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "").trim();
|
|
1266
|
+
b && (b.includes("Registered component") || b.includes("Registered:") ? i.setStatus(g, "✅ Ready") : b.includes("Building...") || b.includes("Running initial build") ? i.setStatus(g, "🔨 Building...") : b.includes("Build completed") || b.includes("Build succeeded") ? i.setStatus(g, "✅ Ready") : b.includes("Build failed") ? i.setStatus(g, "❌ Build Error") : b.includes("File changed") ? (i.setStatus(g, "📝 Changed"), setTimeout(() => i.setStatus(g, "✅ Ready"), 1500)) : b.includes("Notifying") && b.includes("HMR") ? (i.setStatus(g, "🔥 HMR Update"), setTimeout(() => i.setStatus(g, "✅ Ready"), 1e3)) : b.includes("HMR client connected") && (i.setStatus(g, "🔥 HMR Connected"), setTimeout(() => i.setStatus(g, "✅ Ready"), 1e3)), !b.includes("Watching") && !b.includes("Press Ctrl+C") && !b.includes("Starting shared") && !b.includes("Management server") && !b.includes("Main server") && !b.includes("Access at:") && !b.includes("No build needed") && i.log(g, b));
|
|
1267
1267
|
}
|
|
1268
|
-
}),
|
|
1269
|
-
const
|
|
1268
|
+
}), M.stderr.on("data", (w) => {
|
|
1269
|
+
const _ = w.toString().split(`
|
|
1270
1270
|
`);
|
|
1271
|
-
for (const
|
|
1272
|
-
const b =
|
|
1273
|
-
b && (
|
|
1271
|
+
for (const R of _) {
|
|
1272
|
+
const b = R.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "").trim();
|
|
1273
|
+
b && (i.log(g, `⚠️ ${b}`), i.setStatus(g, "⚠️ Warning"));
|
|
1274
1274
|
}
|
|
1275
|
-
}),
|
|
1276
|
-
|
|
1277
|
-
}),
|
|
1275
|
+
}), M.on("exit", (w) => {
|
|
1276
|
+
w !== 0 && w !== null && (i.setStatus(g, `❌ Exited (${w})`), i.log(g, `Process exited with code ${w}`));
|
|
1277
|
+
}), l < o.length - 1 && await new Promise((w) => setTimeout(w, 500));
|
|
1278
1278
|
}
|
|
1279
|
-
|
|
1280
|
-
|
|
1279
|
+
i.render(), setTimeout(() => {
|
|
1280
|
+
u("http://localhost:9292");
|
|
1281
1281
|
}, 2e3);
|
|
1282
1282
|
}
|
|
1283
|
-
const
|
|
1283
|
+
const Ut = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1284
1284
|
__proto__: null,
|
|
1285
|
-
devCommand:
|
|
1286
|
-
monorepoDevCommand:
|
|
1287
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
1288
|
-
function
|
|
1289
|
-
|
|
1285
|
+
devCommand: xe,
|
|
1286
|
+
monorepoDevCommand: Ht
|
|
1287
|
+
}, Symbol.toStringTag, { value: "Module" })), Le = O.join(st.homedir(), ".myop"), pe = O.join(Le, "credentials.json");
|
|
1288
|
+
function Bt() {
|
|
1289
|
+
C.existsSync(Le) || C.mkdirSync(Le, { recursive: !0, mode: 448 });
|
|
1290
1290
|
}
|
|
1291
|
-
function
|
|
1291
|
+
function Je() {
|
|
1292
1292
|
try {
|
|
1293
|
-
if (!
|
|
1293
|
+
if (!C.existsSync(pe))
|
|
1294
1294
|
return null;
|
|
1295
|
-
const o =
|
|
1295
|
+
const o = C.readFileSync(pe, "utf8");
|
|
1296
1296
|
return JSON.parse(o);
|
|
1297
1297
|
} catch (o) {
|
|
1298
1298
|
return console.info("Failed to read credentials:", o.message), null;
|
|
1299
1299
|
}
|
|
1300
1300
|
}
|
|
1301
|
-
function
|
|
1302
|
-
|
|
1303
|
-
const
|
|
1301
|
+
function ct(o) {
|
|
1302
|
+
Bt();
|
|
1303
|
+
const t = {
|
|
1304
1304
|
...o,
|
|
1305
1305
|
savedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1306
1306
|
};
|
|
1307
|
-
|
|
1307
|
+
C.writeFileSync(pe, JSON.stringify(t, null, 2), {
|
|
1308
1308
|
mode: 384
|
|
1309
1309
|
// Read/write for owner only
|
|
1310
1310
|
});
|
|
1311
1311
|
}
|
|
1312
|
-
function
|
|
1312
|
+
function dt() {
|
|
1313
1313
|
try {
|
|
1314
|
-
return
|
|
1314
|
+
return C.existsSync(pe) && C.unlinkSync(pe), !0;
|
|
1315
1315
|
} catch (o) {
|
|
1316
1316
|
return console.error("Failed to clear credentials:", o.message), !1;
|
|
1317
1317
|
}
|
|
1318
1318
|
}
|
|
1319
|
-
function
|
|
1319
|
+
function Jt(o) {
|
|
1320
1320
|
if (!o || !o.expiresAt)
|
|
1321
1321
|
return !0;
|
|
1322
|
-
const
|
|
1323
|
-
return Date.now() >
|
|
1322
|
+
const t = 5 * 60 * 1e3, e = new Date(o.expiresAt).getTime();
|
|
1323
|
+
return Date.now() > e - t;
|
|
1324
1324
|
}
|
|
1325
|
-
function
|
|
1326
|
-
const o =
|
|
1325
|
+
function $e() {
|
|
1326
|
+
const o = Je();
|
|
1327
1327
|
return o ? {
|
|
1328
1328
|
email: o.userEmail,
|
|
1329
1329
|
userId: o.userId
|
|
1330
1330
|
} : null;
|
|
1331
1331
|
}
|
|
1332
|
-
const ae = process.env.MYOP_MCP_URL || "https://mcp.myop.dev", Se = 19284,
|
|
1333
|
-
function
|
|
1334
|
-
return
|
|
1332
|
+
const ae = process.env.MYOP_MCP_URL || "https://mcp.myop.dev", Se = 19284, ze = `http://localhost:${Se}/callback`, zt = "myop-cli";
|
|
1333
|
+
function Wt() {
|
|
1334
|
+
return Ue.randomBytes(32).toString("base64url");
|
|
1335
1335
|
}
|
|
1336
|
-
function
|
|
1337
|
-
return
|
|
1336
|
+
function Vt(o) {
|
|
1337
|
+
return Ue.createHash("sha256").update(o).digest("base64url");
|
|
1338
1338
|
}
|
|
1339
|
-
async function
|
|
1339
|
+
async function Gt() {
|
|
1340
1340
|
const o = await fetch(`${ae}/oauth/register`, {
|
|
1341
1341
|
method: "POST",
|
|
1342
1342
|
headers: { "Content-Type": "application/json" },
|
|
1343
1343
|
body: JSON.stringify({
|
|
1344
|
-
client_name:
|
|
1345
|
-
redirect_uris: [
|
|
1344
|
+
client_name: zt,
|
|
1345
|
+
redirect_uris: [ze],
|
|
1346
1346
|
grant_types: ["authorization_code", "refresh_token"],
|
|
1347
1347
|
response_types: ["code"]
|
|
1348
1348
|
})
|
|
1349
1349
|
});
|
|
1350
1350
|
if (!o.ok) {
|
|
1351
|
-
const
|
|
1352
|
-
throw new Error(`Failed to register client: ${
|
|
1351
|
+
const t = await o.text();
|
|
1352
|
+
throw new Error(`Failed to register client: ${t}`);
|
|
1353
1353
|
}
|
|
1354
1354
|
return o.json();
|
|
1355
1355
|
}
|
|
1356
|
-
function we(o,
|
|
1357
|
-
const
|
|
1356
|
+
function we(o, t, e, n = null) {
|
|
1357
|
+
const s = {
|
|
1358
1358
|
success: `<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#4ade80" stroke-width="2">
|
|
1359
1359
|
<circle cx="12" cy="12" r="10"/>
|
|
1360
1360
|
<path d="M8 12l2.5 2.5L16 9"/>
|
|
@@ -1367,17 +1367,17 @@ function we(o, e, t, n = null) {
|
|
|
1367
1367
|
<path d="M12 2L2 22h20L12 2z"/>
|
|
1368
1368
|
<path d="M12 9v4M12 17h.01"/>
|
|
1369
1369
|
</svg>`
|
|
1370
|
-
},
|
|
1370
|
+
}, i = {
|
|
1371
1371
|
success: { accent: "#4ade80", glow: "rgba(74, 222, 128, 0.1)" },
|
|
1372
1372
|
error: { accent: "#f87171", glow: "rgba(248, 113, 113, 0.1)" },
|
|
1373
1373
|
warning: { accent: "#fbbf24", glow: "rgba(251, 191, 36, 0.1)" }
|
|
1374
|
-
}, { accent:
|
|
1374
|
+
}, { accent: c, glow: u } = i[o] || i.error;
|
|
1375
1375
|
return `<!DOCTYPE html>
|
|
1376
1376
|
<html lang="en">
|
|
1377
1377
|
<head>
|
|
1378
1378
|
<meta charset="UTF-8">
|
|
1379
1379
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1380
|
-
<title>myop-cli | ${
|
|
1380
|
+
<title>myop-cli | ${t}</title>
|
|
1381
1381
|
<style>
|
|
1382
1382
|
* {
|
|
1383
1383
|
margin: 0;
|
|
@@ -1432,7 +1432,7 @@ function we(o, e, t, n = null) {
|
|
|
1432
1432
|
h1 {
|
|
1433
1433
|
font-size: 20px;
|
|
1434
1434
|
font-weight: 500;
|
|
1435
|
-
color: ${
|
|
1435
|
+
color: ${c};
|
|
1436
1436
|
margin-bottom: 12px;
|
|
1437
1437
|
letter-spacing: -0.5px;
|
|
1438
1438
|
}
|
|
@@ -1464,8 +1464,8 @@ function we(o, e, t, n = null) {
|
|
|
1464
1464
|
display: inline-flex;
|
|
1465
1465
|
align-items: center;
|
|
1466
1466
|
gap: 8px;
|
|
1467
|
-
background: ${
|
|
1468
|
-
border: 1px solid ${
|
|
1467
|
+
background: ${u};
|
|
1468
|
+
border: 1px solid ${c}33;
|
|
1469
1469
|
border-radius: 4px;
|
|
1470
1470
|
padding: 10px 16px;
|
|
1471
1471
|
font-size: 12px;
|
|
@@ -1502,10 +1502,10 @@ function we(o, e, t, n = null) {
|
|
|
1502
1502
|
<body>
|
|
1503
1503
|
<div class="container">
|
|
1504
1504
|
<div class="icon">
|
|
1505
|
-
${
|
|
1505
|
+
${s[o] || s.error}
|
|
1506
1506
|
</div>
|
|
1507
|
-
<h1>${
|
|
1508
|
-
<p class="message">${
|
|
1507
|
+
<h1>${t}</h1>
|
|
1508
|
+
<p class="message">${e}</p>
|
|
1509
1509
|
${n ? `<div class="details"><code>Error:</code> ${n}</div>` : ""}
|
|
1510
1510
|
<div class="hint">
|
|
1511
1511
|
<span>Press</span>
|
|
@@ -1519,91 +1519,91 @@ function we(o, e, t, n = null) {
|
|
|
1519
1519
|
</body>
|
|
1520
1520
|
</html>`;
|
|
1521
1521
|
}
|
|
1522
|
-
function
|
|
1523
|
-
return new Promise((
|
|
1524
|
-
const n =
|
|
1525
|
-
const
|
|
1526
|
-
if (
|
|
1527
|
-
const
|
|
1522
|
+
function Yt(o) {
|
|
1523
|
+
return new Promise((t, e) => {
|
|
1524
|
+
const n = Ct.createServer((s, i) => {
|
|
1525
|
+
const c = new ot(s.url, `http://localhost:${Se}`);
|
|
1526
|
+
if (c.pathname === "/callback") {
|
|
1527
|
+
const u = c.searchParams.get("code"), y = c.searchParams.get("state"), d = c.searchParams.get("error");
|
|
1528
1528
|
if (d) {
|
|
1529
|
-
|
|
1529
|
+
i.writeHead(200, { "Content-Type": "text/html" }), i.end(we(
|
|
1530
1530
|
"error",
|
|
1531
1531
|
"Authentication Failed",
|
|
1532
1532
|
"Unable to complete the authentication process.",
|
|
1533
1533
|
d
|
|
1534
|
-
)), n.close(),
|
|
1534
|
+
)), n.close(), e(new Error(`OAuth error: ${d}`));
|
|
1535
1535
|
return;
|
|
1536
1536
|
}
|
|
1537
|
-
if (
|
|
1538
|
-
|
|
1537
|
+
if (y !== o) {
|
|
1538
|
+
i.writeHead(400, { "Content-Type": "text/html" }), i.end(we(
|
|
1539
1539
|
"warning",
|
|
1540
1540
|
"Security Error",
|
|
1541
1541
|
"State mismatch detected. This could indicate a CSRF attack. Please try authenticating again.",
|
|
1542
1542
|
"state_mismatch"
|
|
1543
|
-
)), n.close(),
|
|
1543
|
+
)), n.close(), e(new Error("State mismatch"));
|
|
1544
1544
|
return;
|
|
1545
1545
|
}
|
|
1546
|
-
if (!
|
|
1547
|
-
|
|
1546
|
+
if (!u) {
|
|
1547
|
+
i.writeHead(400, { "Content-Type": "text/html" }), i.end(we(
|
|
1548
1548
|
"error",
|
|
1549
1549
|
"Missing Authorization Code",
|
|
1550
1550
|
"No authorization code was received from the server.",
|
|
1551
1551
|
"missing_code"
|
|
1552
|
-
)), n.close(),
|
|
1552
|
+
)), n.close(), e(new Error("No authorization code"));
|
|
1553
1553
|
return;
|
|
1554
1554
|
}
|
|
1555
|
-
|
|
1555
|
+
i.writeHead(200, { "Content-Type": "text/html" }), i.end(we(
|
|
1556
1556
|
"success",
|
|
1557
1557
|
"Authentication Successful",
|
|
1558
1558
|
"You have been authenticated successfully. Return to the terminal to continue."
|
|
1559
|
-
)), n.close(),
|
|
1559
|
+
)), n.close(), t(u);
|
|
1560
1560
|
} else
|
|
1561
|
-
|
|
1561
|
+
i.writeHead(404), i.end("Not found");
|
|
1562
1562
|
});
|
|
1563
1563
|
n.listen(Se, () => {
|
|
1564
1564
|
console.info(`OAuth callback server listening on port ${Se}`);
|
|
1565
1565
|
}), setTimeout(() => {
|
|
1566
|
-
n.close(),
|
|
1566
|
+
n.close(), e(new Error("Authentication timed out"));
|
|
1567
1567
|
}, 5 * 60 * 1e3);
|
|
1568
1568
|
});
|
|
1569
1569
|
}
|
|
1570
|
-
async function
|
|
1570
|
+
async function Kt(o, t, e) {
|
|
1571
1571
|
const n = await fetch(`${ae}/oauth/token`, {
|
|
1572
1572
|
method: "POST",
|
|
1573
1573
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
1574
|
-
body: new
|
|
1574
|
+
body: new nt({
|
|
1575
1575
|
grant_type: "authorization_code",
|
|
1576
1576
|
code: o,
|
|
1577
|
-
client_id:
|
|
1578
|
-
redirect_uri:
|
|
1579
|
-
code_verifier:
|
|
1577
|
+
client_id: t,
|
|
1578
|
+
redirect_uri: ze,
|
|
1579
|
+
code_verifier: e
|
|
1580
1580
|
})
|
|
1581
1581
|
});
|
|
1582
1582
|
if (!n.ok) {
|
|
1583
|
-
const
|
|
1584
|
-
throw new Error(
|
|
1583
|
+
const s = await n.json();
|
|
1584
|
+
throw new Error(s.error_description || s.error || "Token exchange failed");
|
|
1585
1585
|
}
|
|
1586
1586
|
return n.json();
|
|
1587
1587
|
}
|
|
1588
|
-
async function
|
|
1589
|
-
const
|
|
1588
|
+
async function Qt(o, t) {
|
|
1589
|
+
const e = await fetch(`${ae}/oauth/token`, {
|
|
1590
1590
|
method: "POST",
|
|
1591
1591
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
1592
|
-
body: new
|
|
1592
|
+
body: new nt({
|
|
1593
1593
|
grant_type: "refresh_token",
|
|
1594
1594
|
refresh_token: o,
|
|
1595
|
-
client_id:
|
|
1595
|
+
client_id: t
|
|
1596
1596
|
})
|
|
1597
1597
|
});
|
|
1598
|
-
if (!
|
|
1599
|
-
const n = await
|
|
1598
|
+
if (!e.ok) {
|
|
1599
|
+
const n = await e.json();
|
|
1600
1600
|
throw new Error(n.error_description || n.error || "Token refresh failed");
|
|
1601
1601
|
}
|
|
1602
|
-
return
|
|
1602
|
+
return e.json();
|
|
1603
1603
|
}
|
|
1604
|
-
async function
|
|
1605
|
-
var
|
|
1606
|
-
const
|
|
1604
|
+
async function Zt(o) {
|
|
1605
|
+
var s, i, c;
|
|
1606
|
+
const t = await fetch(`${ae}/mcp`, {
|
|
1607
1607
|
method: "POST",
|
|
1608
1608
|
headers: {
|
|
1609
1609
|
"Content-Type": "application/json",
|
|
@@ -1619,180 +1619,180 @@ async function Vt(o) {
|
|
|
1619
1619
|
}
|
|
1620
1620
|
})
|
|
1621
1621
|
});
|
|
1622
|
-
if (!
|
|
1622
|
+
if (!t.ok)
|
|
1623
1623
|
throw new Error("Failed to get user info");
|
|
1624
|
-
const
|
|
1625
|
-
if (
|
|
1626
|
-
throw new Error(
|
|
1627
|
-
const n = (
|
|
1624
|
+
const e = await t.json();
|
|
1625
|
+
if (e.error)
|
|
1626
|
+
throw new Error(e.error.message);
|
|
1627
|
+
const n = (c = (i = (s = e.result) == null ? void 0 : s.content) == null ? void 0 : i[0]) == null ? void 0 : c.text;
|
|
1628
1628
|
if (n)
|
|
1629
1629
|
return JSON.parse(n);
|
|
1630
1630
|
throw new Error("Invalid response from whoami");
|
|
1631
1631
|
}
|
|
1632
1632
|
async function de() {
|
|
1633
|
-
const o =
|
|
1633
|
+
const o = Y("Starting authentication...").start();
|
|
1634
1634
|
try {
|
|
1635
1635
|
o.text = "Registering OAuth client...";
|
|
1636
|
-
const
|
|
1636
|
+
const e = (await Gt()).client_id, n = Wt(), s = Vt(n), i = Ue.randomBytes(16).toString("hex");
|
|
1637
1637
|
o.text = "Waiting for authorization...";
|
|
1638
|
-
const
|
|
1639
|
-
|
|
1640
|
-
🌐 Opening browser for authentication...`), console.log("If the browser does not open, visit:"), console.log(` ${
|
|
1641
|
-
`), await
|
|
1642
|
-
const
|
|
1638
|
+
const c = Yt(i), u = new ot(`${ae}/oauth/authorize`);
|
|
1639
|
+
u.searchParams.set("response_type", "code"), u.searchParams.set("client_id", e), u.searchParams.set("redirect_uri", ze), u.searchParams.set("code_challenge", s), u.searchParams.set("code_challenge_method", "S256"), u.searchParams.set("state", i), o.stop(), console.log(`
|
|
1640
|
+
🌐 Opening browser for authentication...`), console.log("If the browser does not open, visit:"), console.log(` ${u.toString()}
|
|
1641
|
+
`), await Pt(u.toString());
|
|
1642
|
+
const y = await c;
|
|
1643
1643
|
o.start("Exchanging authorization code...");
|
|
1644
|
-
const d = await
|
|
1644
|
+
const d = await Kt(y, e, n);
|
|
1645
1645
|
o.text = "Getting user info...";
|
|
1646
|
-
const
|
|
1646
|
+
const l = await Zt(d.access_token), P = {
|
|
1647
1647
|
accessToken: d.access_token,
|
|
1648
1648
|
refreshToken: d.refresh_token,
|
|
1649
1649
|
expiresAt: new Date(Date.now() + d.expires_in * 1e3).toISOString(),
|
|
1650
|
-
clientId:
|
|
1651
|
-
userId:
|
|
1652
|
-
userEmail:
|
|
1650
|
+
clientId: e,
|
|
1651
|
+
userId: l.userId,
|
|
1652
|
+
userEmail: l.email
|
|
1653
1653
|
};
|
|
1654
|
-
return
|
|
1655
|
-
} catch (
|
|
1656
|
-
throw o.fail(`Authentication failed: ${
|
|
1654
|
+
return ct(P), o.succeed(`Authenticated as ${l.email}`), P;
|
|
1655
|
+
} catch (t) {
|
|
1656
|
+
throw o.fail(`Authentication failed: ${t.message}`), t;
|
|
1657
1657
|
}
|
|
1658
1658
|
}
|
|
1659
|
-
async function
|
|
1660
|
-
const o =
|
|
1659
|
+
async function pt() {
|
|
1660
|
+
const o = Je();
|
|
1661
1661
|
if (!o) {
|
|
1662
1662
|
console.log("Not currently logged in.");
|
|
1663
1663
|
return;
|
|
1664
1664
|
}
|
|
1665
|
-
|
|
1665
|
+
dt(), console.log(`✅ Logged out (was: ${o.userEmail})`);
|
|
1666
1666
|
}
|
|
1667
|
-
async function
|
|
1668
|
-
let o =
|
|
1667
|
+
async function We() {
|
|
1668
|
+
let o = Je();
|
|
1669
1669
|
if (!o)
|
|
1670
1670
|
return console.log(`Not logged in. Starting authentication...
|
|
1671
1671
|
`), await de();
|
|
1672
|
-
if (!
|
|
1672
|
+
if (!Jt(o))
|
|
1673
1673
|
return o;
|
|
1674
1674
|
if (o.refreshToken) {
|
|
1675
|
-
const
|
|
1675
|
+
const t = Y("Refreshing access token...").start();
|
|
1676
1676
|
try {
|
|
1677
|
-
const
|
|
1677
|
+
const e = await Qt(
|
|
1678
1678
|
o.refreshToken,
|
|
1679
1679
|
o.clientId
|
|
1680
1680
|
);
|
|
1681
1681
|
return o = {
|
|
1682
1682
|
...o,
|
|
1683
|
-
accessToken:
|
|
1684
|
-
refreshToken:
|
|
1685
|
-
expiresAt: new Date(Date.now() +
|
|
1686
|
-
},
|
|
1683
|
+
accessToken: e.access_token,
|
|
1684
|
+
refreshToken: e.refresh_token,
|
|
1685
|
+
expiresAt: new Date(Date.now() + e.expires_in * 1e3).toISOString()
|
|
1686
|
+
}, ct(o), t.succeed("Token refreshed"), o;
|
|
1687
1687
|
} catch {
|
|
1688
|
-
return
|
|
1688
|
+
return t.warn("Token refresh failed, please log in again"), dt(), await de();
|
|
1689
1689
|
}
|
|
1690
1690
|
}
|
|
1691
1691
|
return console.log(`Session expired. Please log in again.
|
|
1692
1692
|
`), await de();
|
|
1693
1693
|
}
|
|
1694
|
-
function
|
|
1694
|
+
function be() {
|
|
1695
1695
|
return ae;
|
|
1696
1696
|
}
|
|
1697
|
-
const X = "@myop/cli",
|
|
1698
|
-
function
|
|
1697
|
+
const X = "@myop/cli", je = process.platform === "win32";
|
|
1698
|
+
function qt() {
|
|
1699
1699
|
try {
|
|
1700
|
-
return
|
|
1700
|
+
return ee("npm config get registry", { encoding: "utf-8" }).trim() || "https://registry.npmjs.org/";
|
|
1701
1701
|
} catch {
|
|
1702
1702
|
return "https://registry.npmjs.org/";
|
|
1703
1703
|
}
|
|
1704
1704
|
}
|
|
1705
|
-
function
|
|
1705
|
+
function Xt() {
|
|
1706
1706
|
try {
|
|
1707
|
-
return
|
|
1707
|
+
return ee("npm config get prefix", { encoding: "utf-8" }).trim();
|
|
1708
1708
|
} catch {
|
|
1709
1709
|
return null;
|
|
1710
1710
|
}
|
|
1711
1711
|
}
|
|
1712
|
-
async function
|
|
1712
|
+
async function eo() {
|
|
1713
1713
|
try {
|
|
1714
|
-
const o =
|
|
1715
|
-
return
|
|
1714
|
+
const o = qt().replace(/\/$/, ""), t = await fetch(`${o}/${X}/latest`);
|
|
1715
|
+
return t.ok ? (await t.json()).version : null;
|
|
1716
1716
|
} catch {
|
|
1717
1717
|
return null;
|
|
1718
1718
|
}
|
|
1719
1719
|
}
|
|
1720
|
-
function
|
|
1721
|
-
const
|
|
1722
|
-
for (let
|
|
1723
|
-
const
|
|
1724
|
-
if (
|
|
1725
|
-
if (
|
|
1720
|
+
function to(o, t) {
|
|
1721
|
+
const e = o.split(".").map(Number), n = t.split(".").map(Number);
|
|
1722
|
+
for (let s = 0; s < Math.max(e.length, n.length); s++) {
|
|
1723
|
+
const i = e[s] || 0, c = n[s] || 0;
|
|
1724
|
+
if (i > c) return 1;
|
|
1725
|
+
if (i < c) return -1;
|
|
1726
1726
|
}
|
|
1727
1727
|
return 0;
|
|
1728
1728
|
}
|
|
1729
|
-
async function
|
|
1730
|
-
const
|
|
1729
|
+
async function oo(o) {
|
|
1730
|
+
const t = Y({
|
|
1731
1731
|
text: "Checking for updates...",
|
|
1732
1732
|
color: "cyan"
|
|
1733
|
-
}).start(),
|
|
1734
|
-
if (
|
|
1733
|
+
}).start(), e = await eo();
|
|
1734
|
+
if (t.stop(), !e || to(e, o) <= 0)
|
|
1735
1735
|
return !1;
|
|
1736
1736
|
console.log(`
|
|
1737
|
-
📦 New version available: ${o} → ${
|
|
1737
|
+
📦 New version available: ${o} → ${e}
|
|
1738
1738
|
`);
|
|
1739
1739
|
let n;
|
|
1740
1740
|
try {
|
|
1741
|
-
n = await
|
|
1741
|
+
n = await tt({
|
|
1742
1742
|
message: "Would you like to update now?",
|
|
1743
1743
|
choices: [
|
|
1744
1744
|
{ name: "Yes, update now", value: !0 },
|
|
1745
1745
|
{ name: "No, continue with current version", value: !1 }
|
|
1746
1746
|
]
|
|
1747
1747
|
});
|
|
1748
|
-
} catch (
|
|
1749
|
-
throw
|
|
1748
|
+
} catch (s) {
|
|
1749
|
+
throw s.name === "ExitPromptError" && (console.log(`
|
|
1750
1750
|
|
|
1751
1751
|
👋 Goodbye!
|
|
1752
|
-
`), process.exit(0)),
|
|
1752
|
+
`), process.exit(0)), s;
|
|
1753
1753
|
}
|
|
1754
1754
|
if (n) {
|
|
1755
|
-
const
|
|
1756
|
-
text: `Updating ${X} to v${
|
|
1755
|
+
const s = Y({
|
|
1756
|
+
text: `Updating ${X} to v${e}...`,
|
|
1757
1757
|
color: "green"
|
|
1758
|
-
}).start(),
|
|
1758
|
+
}).start(), i = `npm install -g ${X}@latest`, c = Xt();
|
|
1759
1759
|
try {
|
|
1760
|
-
|
|
1760
|
+
ee(i, { stdio: "pipe" }), s.succeed(`Updated to v${e}`);
|
|
1761
1761
|
} catch {
|
|
1762
|
-
|
|
1762
|
+
s.stop(), console.log(`
|
|
1763
1763
|
🔐 Elevated permissions required.
|
|
1764
1764
|
`);
|
|
1765
1765
|
try {
|
|
1766
|
-
if (
|
|
1767
|
-
const
|
|
1768
|
-
|
|
1766
|
+
if (je) {
|
|
1767
|
+
const l = `Start-Process -FilePath 'cmd' -ArgumentList '/c npm ${c ? `install -g ${X}@latest --prefix \\"${c}\\"` : `install -g ${X}@latest`}' -Verb RunAs -Wait`;
|
|
1768
|
+
ee(`powershell -Command "${l}"`, { stdio: "inherit" });
|
|
1769
1769
|
} else {
|
|
1770
|
-
const d =
|
|
1771
|
-
|
|
1770
|
+
const d = c ? `sudo npm install -g ${X}@latest --prefix "${c}"` : `sudo ${i}`;
|
|
1771
|
+
ee(d, { stdio: "inherit" });
|
|
1772
1772
|
}
|
|
1773
1773
|
console.log(`
|
|
1774
|
-
✅ Updated to v${
|
|
1774
|
+
✅ Updated to v${e}`);
|
|
1775
1775
|
} catch {
|
|
1776
1776
|
console.log(`
|
|
1777
1777
|
❌ Update failed`);
|
|
1778
|
-
const
|
|
1778
|
+
const l = je ? `npm install -g ${X}@latest (run as Administrator)` : `sudo npm install -g ${X}@latest`;
|
|
1779
1779
|
console.log(`
|
|
1780
|
-
Please run manually: ${
|
|
1780
|
+
Please run manually: ${l}
|
|
1781
1781
|
`), process.exit(1);
|
|
1782
1782
|
}
|
|
1783
1783
|
}
|
|
1784
|
-
let
|
|
1784
|
+
let u = null;
|
|
1785
1785
|
try {
|
|
1786
|
-
let
|
|
1787
|
-
|
|
1788
|
-
const d =
|
|
1789
|
-
|
|
1786
|
+
let y;
|
|
1787
|
+
c ? y = je ? ke(c, "node_modules") : ke(c, "lib", "node_modules") : y = ee("npm root -g", { encoding: "utf-8" }).trim();
|
|
1788
|
+
const d = ke(y, X, "package.json"), l = bt(d, "utf-8");
|
|
1789
|
+
u = JSON.parse(l).version;
|
|
1790
1790
|
} catch {
|
|
1791
1791
|
}
|
|
1792
|
-
if (
|
|
1792
|
+
if (u === e)
|
|
1793
1793
|
return console.log(`
|
|
1794
1794
|
🔄 Restarting...
|
|
1795
|
-
`),
|
|
1795
|
+
`), $t(process.argv[0], process.argv.slice(1), {
|
|
1796
1796
|
stdio: "inherit",
|
|
1797
1797
|
shell: !0
|
|
1798
1798
|
}).on("close", (d) => {
|
|
@@ -1804,69 +1804,124 @@ Please run myop again to use the new version.
|
|
|
1804
1804
|
}
|
|
1805
1805
|
return !1;
|
|
1806
1806
|
}
|
|
1807
|
-
const
|
|
1807
|
+
const De = O.join(st.homedir(), ".myop"), Ae = O.join(De, "preferences.json");
|
|
1808
|
+
function no() {
|
|
1809
|
+
C.existsSync(De) || C.mkdirSync(De, { recursive: !0, mode: 448 });
|
|
1810
|
+
}
|
|
1811
|
+
function mt() {
|
|
1812
|
+
try {
|
|
1813
|
+
if (!C.existsSync(Ae))
|
|
1814
|
+
return {};
|
|
1815
|
+
const o = C.readFileSync(Ae, "utf8");
|
|
1816
|
+
return JSON.parse(o);
|
|
1817
|
+
} catch {
|
|
1818
|
+
return {};
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
function so(o) {
|
|
1822
|
+
no();
|
|
1823
|
+
const e = { ...mt(), ...o };
|
|
1824
|
+
C.writeFileSync(Ae, JSON.stringify(e, null, 2), {
|
|
1825
|
+
mode: 384
|
|
1826
|
+
});
|
|
1827
|
+
}
|
|
1828
|
+
function io() {
|
|
1829
|
+
return mt().defaultOrganization || null;
|
|
1830
|
+
}
|
|
1831
|
+
function _e({ id: o, name: t }) {
|
|
1832
|
+
so({ defaultOrganization: { id: o, name: t } });
|
|
1833
|
+
}
|
|
1834
|
+
async function ro(o, t, e, n = {}) {
|
|
1835
|
+
var u, y, d;
|
|
1836
|
+
const s = await fetch(`${o}/mcp`, {
|
|
1837
|
+
method: "POST",
|
|
1838
|
+
headers: {
|
|
1839
|
+
"Content-Type": "application/json",
|
|
1840
|
+
Authorization: `Bearer ${t}`
|
|
1841
|
+
},
|
|
1842
|
+
body: JSON.stringify({
|
|
1843
|
+
jsonrpc: "2.0",
|
|
1844
|
+
id: 1,
|
|
1845
|
+
method: "tools/call",
|
|
1846
|
+
params: {
|
|
1847
|
+
name: e,
|
|
1848
|
+
arguments: n
|
|
1849
|
+
}
|
|
1850
|
+
})
|
|
1851
|
+
});
|
|
1852
|
+
if (!s.ok)
|
|
1853
|
+
throw new Error(`Server returned ${s.status}`);
|
|
1854
|
+
const i = await s.json();
|
|
1855
|
+
if (i.error)
|
|
1856
|
+
throw new Error(i.error.message || "MCP error");
|
|
1857
|
+
const c = (d = (y = (u = i.result) == null ? void 0 : u.content) == null ? void 0 : y[0]) == null ? void 0 : d.text;
|
|
1858
|
+
if (!c)
|
|
1859
|
+
throw new Error(`No content returned from ${e}`);
|
|
1860
|
+
return JSON.parse(c);
|
|
1861
|
+
}
|
|
1862
|
+
const ao = (o) => new Promise((t) => setTimeout(t, o)), lo = () => {
|
|
1808
1863
|
let o = new URL(import.meta.url).pathname;
|
|
1809
1864
|
process.platform === "win32" && o.startsWith("/") && (o = o.slice(1));
|
|
1810
|
-
const
|
|
1811
|
-
return
|
|
1812
|
-
},
|
|
1813
|
-
|
|
1814
|
-
const
|
|
1815
|
-
for (const n of
|
|
1816
|
-
const
|
|
1817
|
-
n.isDirectory() ?
|
|
1818
|
-
}
|
|
1819
|
-
},
|
|
1820
|
-
const
|
|
1821
|
-
if (!
|
|
1865
|
+
const t = O.dirname(o);
|
|
1866
|
+
return O.join(t, "skills");
|
|
1867
|
+
}, He = (o, t) => {
|
|
1868
|
+
C.mkdirSync(t, { recursive: !0 });
|
|
1869
|
+
const e = C.readdirSync(o, { withFileTypes: !0 });
|
|
1870
|
+
for (const n of e) {
|
|
1871
|
+
const s = O.join(o, n.name), i = O.join(t, n.name);
|
|
1872
|
+
n.isDirectory() ? He(s, i) : C.copyFileSync(s, i);
|
|
1873
|
+
}
|
|
1874
|
+
}, Ve = (o) => {
|
|
1875
|
+
const t = lo();
|
|
1876
|
+
if (!C.existsSync(t))
|
|
1822
1877
|
return console.info("Skills source directory not found, skipping skills installation"), !1;
|
|
1823
1878
|
try {
|
|
1824
|
-
const
|
|
1825
|
-
|
|
1826
|
-
const n = [".claude", ".cursor", ".gemini", ".junie", ".agent"],
|
|
1827
|
-
for (const
|
|
1828
|
-
const
|
|
1829
|
-
|
|
1830
|
-
for (const
|
|
1831
|
-
const
|
|
1879
|
+
const e = O.join(o, ".agents", "skills");
|
|
1880
|
+
He(t, e);
|
|
1881
|
+
const n = [".claude", ".cursor", ".gemini", ".junie", ".agent"], s = C.readdirSync(t, { withFileTypes: !0 }).filter((i) => i.isDirectory()).map((i) => i.name);
|
|
1882
|
+
for (const i of n) {
|
|
1883
|
+
const c = O.join(o, i, "skills");
|
|
1884
|
+
C.mkdirSync(c, { recursive: !0 });
|
|
1885
|
+
for (const u of s) {
|
|
1886
|
+
const y = O.join(c, u), d = O.join("..", "..", ".agents", "skills", u);
|
|
1832
1887
|
try {
|
|
1833
|
-
|
|
1888
|
+
C.rmSync(y, { recursive: !0, force: !0 });
|
|
1834
1889
|
} catch {
|
|
1835
1890
|
}
|
|
1836
1891
|
try {
|
|
1837
|
-
|
|
1892
|
+
C.symlinkSync(d, y, "dir");
|
|
1838
1893
|
} catch {
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1894
|
+
He(
|
|
1895
|
+
O.join(e, u),
|
|
1896
|
+
y
|
|
1842
1897
|
);
|
|
1843
1898
|
}
|
|
1844
1899
|
}
|
|
1845
1900
|
}
|
|
1846
1901
|
return !0;
|
|
1847
|
-
} catch (
|
|
1848
|
-
return console.info("Failed to install skills:",
|
|
1902
|
+
} catch (e) {
|
|
1903
|
+
return console.info("Failed to install skills:", e.message), !1;
|
|
1849
1904
|
}
|
|
1850
|
-
},
|
|
1905
|
+
}, Ge = (o = ".", t = 3, e = 0) => {
|
|
1851
1906
|
const n = [];
|
|
1852
|
-
if (
|
|
1907
|
+
if (e > t) return n;
|
|
1853
1908
|
try {
|
|
1854
|
-
const
|
|
1855
|
-
for (const
|
|
1856
|
-
const
|
|
1857
|
-
if (
|
|
1858
|
-
if (
|
|
1909
|
+
const s = C.readdirSync(o, { withFileTypes: !0 });
|
|
1910
|
+
for (const i of s) {
|
|
1911
|
+
const c = O.join(o, i.name);
|
|
1912
|
+
if (i.isDirectory()) {
|
|
1913
|
+
if (i.name === "node_modules" || i.name === ".git" || i.name === "dist" || i.name.startsWith("."))
|
|
1859
1914
|
continue;
|
|
1860
|
-
n.push(...
|
|
1861
|
-
} else if (
|
|
1915
|
+
n.push(...Ge(c, t, e + 1));
|
|
1916
|
+
} else if (i.name === "myop.config.json")
|
|
1862
1917
|
try {
|
|
1863
|
-
const
|
|
1918
|
+
const u = C.readFileSync(c, "utf-8"), y = JSON.parse(u);
|
|
1864
1919
|
n.push({
|
|
1865
1920
|
path: o,
|
|
1866
|
-
configPath:
|
|
1867
|
-
name:
|
|
1868
|
-
componentId:
|
|
1869
|
-
config:
|
|
1921
|
+
configPath: c,
|
|
1922
|
+
name: y.name || y.componentName || O.basename(o),
|
|
1923
|
+
componentId: y.componentId || null,
|
|
1924
|
+
config: y
|
|
1870
1925
|
});
|
|
1871
1926
|
} catch {
|
|
1872
1927
|
}
|
|
@@ -1875,55 +1930,55 @@ const Xt = (o) => new Promise((e) => setTimeout(e, o)), qt = () => {
|
|
|
1875
1930
|
}
|
|
1876
1931
|
return n;
|
|
1877
1932
|
};
|
|
1878
|
-
|
|
1879
|
-
const
|
|
1880
|
-
const
|
|
1881
|
-
|
|
1882
|
-
}), console.info("📝 verbose mode on"),
|
|
1883
|
-
configPath:
|
|
1884
|
-
verbose:
|
|
1933
|
+
v.executionPath = process.cwd();
|
|
1934
|
+
const Ce = (o = !1) => {
|
|
1935
|
+
const t = v.program.getOptionValue("verbose");
|
|
1936
|
+
t || (console.info = () => {
|
|
1937
|
+
}), console.info("📝 verbose mode on"), v.options = {
|
|
1938
|
+
configPath: v.program.getOptionValue("config"),
|
|
1939
|
+
verbose: t
|
|
1885
1940
|
};
|
|
1886
1941
|
try {
|
|
1887
|
-
return
|
|
1888
|
-
} catch (
|
|
1942
|
+
return v.myopConfig = Et(v.options.configPath), { configFound: !0 };
|
|
1943
|
+
} catch (e) {
|
|
1889
1944
|
if (o) {
|
|
1890
1945
|
console.info(`
|
|
1891
|
-
⚠️ failed read config file from ${
|
|
1946
|
+
⚠️ failed read config file from ${v.options.configPath}, trying to create new one`);
|
|
1892
1947
|
try {
|
|
1893
1948
|
const n = {
|
|
1894
1949
|
author: "@myop-cli",
|
|
1895
1950
|
flows: []
|
|
1896
1951
|
};
|
|
1897
|
-
return
|
|
1952
|
+
return Be(v.options.configPath, n), v.myopConfig = n, { configFound: !0 };
|
|
1898
1953
|
} catch {
|
|
1899
|
-
return console.info("Error details :",
|
|
1954
|
+
return console.info("Error details :", e), { configFound: !1, error: e };
|
|
1900
1955
|
}
|
|
1901
1956
|
} else
|
|
1902
|
-
return console.info("Error details :",
|
|
1957
|
+
return console.info("Error details :", e), { configFound: !1, error: e };
|
|
1903
1958
|
}
|
|
1904
1959
|
};
|
|
1905
1960
|
[
|
|
1906
|
-
new
|
|
1907
|
-
...
|
|
1961
|
+
new Fe(),
|
|
1962
|
+
..._t
|
|
1908
1963
|
];
|
|
1909
|
-
const
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1964
|
+
const co = "0.1.46";
|
|
1965
|
+
v.program = new xt();
|
|
1966
|
+
v.program.name("@myop/cli").description("Myop CLI - Remote UI Made Easy").version(co);
|
|
1967
|
+
v.program.addOption(new me("-c, --config <value>", "myop.config.json file location").default("./myop.config.json", "./myop.config.json"));
|
|
1968
|
+
v.program.addOption(new me("-h, --help", "Show helpful information"));
|
|
1969
|
+
v.program.addOption(new me("-v, --verbose", "Enables verbose output mode for the command-line interface (CLI)."));
|
|
1970
|
+
v.program.addOption(new me("--ci", "CI mode: print status info (version, config, auth) as JSON and exit without prompts"));
|
|
1971
|
+
v.program.addOption(new me("-m, --monorepo", "Monorepo mode: scan for all myop.config.json files in nested directories"));
|
|
1972
|
+
v.program.command("add").description("Install Myop assets").addArgument("type").addArgument("id").action((o, t) => {
|
|
1973
|
+
Ce(!0), console.info("adding ", o, t, v.options.configPath), o === "flow" && rt._action(t), process.exit();
|
|
1919
1974
|
});
|
|
1920
|
-
|
|
1921
|
-
|
|
1975
|
+
v.program.command("remove").description("Remove Myop asset").argument("<type>", "Myop asset type").argument("<id>", "Asset id").action((o, t) => {
|
|
1976
|
+
Ce(), console.info("removing ", o, t, v.options.configPath), o === "flow" && at._action(t), process.exit();
|
|
1922
1977
|
});
|
|
1923
|
-
|
|
1924
|
-
|
|
1978
|
+
v.program.command("install").description("Install Myop assets").action(async () => {
|
|
1979
|
+
Ce(), await it.action();
|
|
1925
1980
|
});
|
|
1926
|
-
|
|
1981
|
+
v.program.command("login").description("Authenticate with Myop platform").action(async () => {
|
|
1927
1982
|
try {
|
|
1928
1983
|
await de();
|
|
1929
1984
|
} catch (o) {
|
|
@@ -1931,218 +1986,102 @@ h.program.command("login").description("Authenticate with Myop platform").action
|
|
|
1931
1986
|
}
|
|
1932
1987
|
process.exit(0);
|
|
1933
1988
|
});
|
|
1934
|
-
|
|
1935
|
-
await
|
|
1989
|
+
v.program.command("logout").description("Clear stored credentials").action(async () => {
|
|
1990
|
+
await pt(), process.exit(0);
|
|
1936
1991
|
});
|
|
1937
|
-
|
|
1938
|
-
const o =
|
|
1992
|
+
v.program.command("whoami").description("Show current authenticated user").action(async () => {
|
|
1993
|
+
const o = $e();
|
|
1939
1994
|
o && o.email ? console.log(`Logged in as: ${o.email}`) : console.log("Not logged in. Run `myop login` to authenticate."), process.exit(0);
|
|
1940
1995
|
});
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1996
|
+
v.program.command("sync").description('[deprecated] Use "myop push" instead').option("--skip-build", "Skip the build step").action(async () => {
|
|
1997
|
+
console.log(`
|
|
1998
|
+
⚠️ "myop sync" is deprecated. Use "myop push" instead.
|
|
1999
|
+
`);
|
|
2000
|
+
const { execSync: o } = await import("child_process");
|
|
2001
|
+
try {
|
|
2002
|
+
o("node " + process.argv[1] + " push", { stdio: "inherit" });
|
|
2003
|
+
} catch {
|
|
2004
|
+
}
|
|
2005
|
+
process.exit(0);
|
|
2006
|
+
});
|
|
2007
|
+
v.program.command("push").description("Upload component to Myop platform").argument("[componentId]", "Component ID to push to (overrides myop.config.json)").action(async (o) => {
|
|
2008
|
+
var M, f, w, _, R, b;
|
|
2009
|
+
const t = v.program.getOptionValue("config") || "./myop.config.json";
|
|
2010
|
+
let e = {};
|
|
2011
|
+
if (C.existsSync(t))
|
|
1946
2012
|
try {
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
console.log(`📋 Found config: ${f || "Unnamed component"}`), s.componentId && console.log(` Component ID: ${s.componentId}`);
|
|
1951
|
-
} catch (x) {
|
|
1952
|
-
console.error(`⚠️ Failed to parse ${e}:`, x.message);
|
|
2013
|
+
e = JSON.parse(C.readFileSync(t, "utf-8"));
|
|
2014
|
+
} catch (p) {
|
|
2015
|
+
console.error(`⚠️ Failed to parse ${t}:`, p.message);
|
|
1953
2016
|
}
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
2017
|
+
o && (e.componentId = o);
|
|
2018
|
+
const n = e.name || e.componentName || O.basename(process.cwd());
|
|
2019
|
+
console.log(`
|
|
2020
|
+
📋 Component: ${n}`);
|
|
2021
|
+
let s = null, i = !1;
|
|
1957
2022
|
try {
|
|
1958
|
-
const
|
|
1959
|
-
|
|
2023
|
+
const p = JSON.parse(C.readFileSync("package.json", "utf-8"));
|
|
2024
|
+
i = !!(p.scripts && p.scripts.build);
|
|
1960
2025
|
} catch {
|
|
1961
2026
|
}
|
|
1962
|
-
if (!
|
|
1963
|
-
const
|
|
1964
|
-
(
|
|
2027
|
+
if (!i) {
|
|
2028
|
+
const p = C.readdirSync(".").filter(
|
|
2029
|
+
(E) => E.endsWith(".html") && !E.startsWith(".") && C.statSync(E).isFile()
|
|
1965
2030
|
);
|
|
1966
|
-
|
|
1967
|
-
}
|
|
1968
|
-
if (
|
|
1969
|
-
console.log(
|
|
1970
|
-
else if (
|
|
1971
|
-
const { exec:
|
|
1972
|
-
let
|
|
1973
|
-
const
|
|
1974
|
-
const
|
|
1975
|
-
|
|
1976
|
-
if (!
|
|
1977
|
-
|
|
2031
|
+
p.length === 1 && (s = p[0]);
|
|
2032
|
+
}
|
|
2033
|
+
if (s)
|
|
2034
|
+
console.log(` Single file: ${s} (skipping build)`);
|
|
2035
|
+
else if (i) {
|
|
2036
|
+
const { exec: p } = await import("child_process");
|
|
2037
|
+
let E = { hasTriedPlatformFix: !1, hasTriedInstall: !1 };
|
|
2038
|
+
const x = (k = !1) => new Promise((H) => {
|
|
2039
|
+
const A = Y(k ? "Retrying build..." : "Building project...").start();
|
|
2040
|
+
p("npm run build", { maxBuffer: 10 * 1024 * 1024 }, async (j, J, F) => {
|
|
2041
|
+
if (!j) {
|
|
2042
|
+
A.succeed("Build completed"), H(!0);
|
|
1978
2043
|
return;
|
|
1979
2044
|
}
|
|
1980
|
-
if (
|
|
1981
|
-
const
|
|
1982
|
-
if (
|
|
1983
|
-
const
|
|
1984
|
-
|
|
2045
|
+
if (A.fail("Build failed"), !E.hasTriedPlatformFix && !E.hasTriedInstall) {
|
|
2046
|
+
const V = await lt(j, J, F, p, E);
|
|
2047
|
+
if (E = { ...E, ...V }, V.handled) {
|
|
2048
|
+
const te = await x(!0);
|
|
2049
|
+
H(te);
|
|
1985
2050
|
return;
|
|
1986
2051
|
}
|
|
1987
2052
|
}
|
|
1988
|
-
console.error(
|
|
2053
|
+
console.error(j.message), H(!1);
|
|
1989
2054
|
});
|
|
1990
2055
|
});
|
|
1991
|
-
await
|
|
2056
|
+
await x() || process.exit(1);
|
|
1992
2057
|
}
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
try {
|
|
2004
|
-
const x = await fetch(`${c}/mcp`, {
|
|
2005
|
-
method: "POST",
|
|
2006
|
-
headers: {
|
|
2007
|
-
"Content-Type": "application/json",
|
|
2008
|
-
Authorization: `Bearer ${d.accessToken}`
|
|
2009
|
-
},
|
|
2010
|
-
body: JSON.stringify({
|
|
2011
|
-
jsonrpc: "2.0",
|
|
2012
|
-
id: 1,
|
|
2013
|
-
method: "tools/call",
|
|
2014
|
-
params: {
|
|
2015
|
-
name: "upload_component",
|
|
2016
|
-
arguments: {
|
|
2017
|
-
name: s.name || s.componentName || i.default.basename(process.cwd()),
|
|
2018
|
-
componentId: s.componentId || void 0,
|
|
2019
|
-
organization: s.organization || void 0
|
|
2020
|
-
}
|
|
2021
|
-
}
|
|
2022
|
-
})
|
|
2023
|
-
});
|
|
2024
|
-
if (!x.ok)
|
|
2025
|
-
throw new Error(`Server returned ${x.status}`);
|
|
2026
|
-
const f = await x.json();
|
|
2027
|
-
if (f.error)
|
|
2028
|
-
throw new Error(f.error.message);
|
|
2029
|
-
const E = (j = (T = (C = f.result) == null ? void 0 : C.content) == null ? void 0 : T[0]) == null ? void 0 : j.text;
|
|
2030
|
-
if (u = JSON.parse(E), !u.success)
|
|
2031
|
-
throw new Error(u.error);
|
|
2032
|
-
$.succeed("Upload URL obtained");
|
|
2033
|
-
} catch (x) {
|
|
2034
|
-
$.fail("Failed to get upload URL"), console.error(" ", x.message), process.exit(1);
|
|
2035
|
-
}
|
|
2036
|
-
$ = V("Uploading component...").start();
|
|
2037
|
-
try {
|
|
2038
|
-
const x = t.readFileSync(S, "utf-8");
|
|
2039
|
-
let f;
|
|
2040
|
-
const E = u.curlCommand.match(/(?:"|\\")([^"\\]+(?:\\.[^"\\]*)*)(?:"|\\")$/);
|
|
2041
|
-
if (E)
|
|
2042
|
-
f = E[1];
|
|
2043
|
-
else {
|
|
2044
|
-
const B = u.curlCommand.match(/(https:\/\/[^\s"\\]+)/);
|
|
2045
|
-
if (B)
|
|
2046
|
-
f = B[1];
|
|
2047
|
-
else
|
|
2048
|
-
throw new Error("Could not parse presigned URL from: " + u.curlCommand);
|
|
2049
|
-
}
|
|
2050
|
-
console.info("Uploading to:", f.substring(0, 100) + "...");
|
|
2051
|
-
const L = await fetch(f, {
|
|
2052
|
-
method: "PUT",
|
|
2053
|
-
headers: {
|
|
2054
|
-
"Content-Type": "text/html"
|
|
2055
|
-
},
|
|
2056
|
-
body: x
|
|
2057
|
-
});
|
|
2058
|
-
if (!L.ok) {
|
|
2059
|
-
const B = await L.text();
|
|
2060
|
-
throw new Error(`Upload failed with status ${L.status}: ${B}`);
|
|
2061
|
-
}
|
|
2062
|
-
$.succeed("Component uploaded");
|
|
2063
|
-
} catch (x) {
|
|
2064
|
-
$.fail("Upload failed"), console.error(" ", x.message), x.cause && console.error(" Cause:", x.cause), process.exit(1);
|
|
2058
|
+
let c;
|
|
2059
|
+
if (s)
|
|
2060
|
+
c = s;
|
|
2061
|
+
else if (C.existsSync("./dist/index.html"))
|
|
2062
|
+
c = "./dist/index.html";
|
|
2063
|
+
else {
|
|
2064
|
+
const p = C.readdirSync(".").filter(
|
|
2065
|
+
(E) => E.endsWith(".html") && !E.startsWith(".") && C.statSync(E).isFile()
|
|
2066
|
+
);
|
|
2067
|
+
p.length === 1 ? c = p[0] : (console.error("❌ No HTML file found to upload."), console.log(" Expected: a single .html file in root or ./dist/index.html"), process.exit(1));
|
|
2065
2068
|
}
|
|
2066
|
-
|
|
2069
|
+
const u = C.readFileSync(c, "utf-8");
|
|
2070
|
+
console.log(` File: ${c} (${(u.length / 1024).toFixed(1)} KB)`);
|
|
2067
2071
|
let y;
|
|
2068
2072
|
try {
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
"Content-Type": "application/json",
|
|
2073
|
-
Authorization: `Bearer ${d.accessToken}`
|
|
2074
|
-
},
|
|
2075
|
-
body: JSON.stringify({
|
|
2076
|
-
jsonrpc: "2.0",
|
|
2077
|
-
id: 2,
|
|
2078
|
-
method: "tools/call",
|
|
2079
|
-
params: {
|
|
2080
|
-
name: "confirm_upload",
|
|
2081
|
-
arguments: {
|
|
2082
|
-
uploadId: u.uploadId
|
|
2083
|
-
}
|
|
2084
|
-
}
|
|
2085
|
-
})
|
|
2086
|
-
});
|
|
2087
|
-
if (!x.ok)
|
|
2088
|
-
throw new Error(`Server returned ${x.status}`);
|
|
2089
|
-
const f = await x.json();
|
|
2090
|
-
if (f.error)
|
|
2091
|
-
throw new Error(f.error.message);
|
|
2092
|
-
const E = (F = (b = (P = f.result) == null ? void 0 : P.content) == null ? void 0 : b[0]) == null ? void 0 : F.text;
|
|
2093
|
-
if (y = JSON.parse(E), !y.success)
|
|
2094
|
-
throw new Error(y.error);
|
|
2095
|
-
$.succeed("Upload confirmed");
|
|
2096
|
-
} catch (x) {
|
|
2097
|
-
$.fail("Confirmation failed"), console.error(" ", x.message), process.exit(1);
|
|
2098
|
-
}
|
|
2099
|
-
if (y.isNewComponent || !s.componentId) {
|
|
2100
|
-
s.componentId = y.componentId, s.organization = y.orgId, s.name || (s.name = y.componentName);
|
|
2101
|
-
try {
|
|
2102
|
-
t.writeFileSync(e, JSON.stringify(s, null, 2)), console.log(`
|
|
2103
|
-
📝 Updated ${e} with componentId`);
|
|
2104
|
-
} catch (x) {
|
|
2105
|
-
console.log(`
|
|
2106
|
-
⚠️ Could not update ${e}: ${x.message}`), console.log(` Please add componentId: "${y.componentId}" manually`);
|
|
2107
|
-
}
|
|
2073
|
+
y = await We();
|
|
2074
|
+
} catch (p) {
|
|
2075
|
+
console.error("❌ Authentication failed:", p.message), process.exit(1);
|
|
2108
2076
|
}
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
});
|
|
2112
|
-
h.program.command("push").description("Upload component to Myop platform").action(async () => {
|
|
2113
|
-
var $, u, y, C, T, j;
|
|
2114
|
-
const o = h.program.getOptionValue("config") || "./myop.config.json";
|
|
2115
|
-
let e = {};
|
|
2116
|
-
if (I.existsSync(o))
|
|
2117
|
-
try {
|
|
2118
|
-
e = JSON.parse(I.readFileSync(o, "utf-8"));
|
|
2119
|
-
} catch (P) {
|
|
2120
|
-
console.error(`⚠️ Failed to parse ${o}:`, P.message);
|
|
2121
|
-
}
|
|
2122
|
-
const t = e.name || e.componentName || D.basename(process.cwd());
|
|
2123
|
-
console.log(`
|
|
2124
|
-
📋 Component: ${t}`);
|
|
2125
|
-
let n;
|
|
2126
|
-
const i = I.readdirSync(".").filter(
|
|
2127
|
-
(P) => P.endsWith(".html") && !P.startsWith(".") && I.statSync(P).isFile()
|
|
2128
|
-
);
|
|
2129
|
-
i.length === 1 && !I.existsSync("./dist/index.html") ? n = i[0] : I.existsSync("./dist/index.html") ? n = "./dist/index.html" : i.length === 1 ? n = i[0] : (console.error("❌ No HTML file found to upload."), console.log(" Expected: a single .html file in root or ./dist/index.html"), process.exit(1));
|
|
2130
|
-
const s = I.readFileSync(n, "utf-8");
|
|
2131
|
-
console.log(` File: ${n} (${(s.length / 1024).toFixed(1)} KB)`);
|
|
2132
|
-
let l;
|
|
2133
|
-
try {
|
|
2134
|
-
l = await Ue();
|
|
2135
|
-
} catch (P) {
|
|
2136
|
-
console.error("❌ Authentication failed:", P.message), process.exit(1);
|
|
2137
|
-
}
|
|
2138
|
-
const w = Je();
|
|
2139
|
-
let S = V("Uploading...").start(), d;
|
|
2077
|
+
const d = be();
|
|
2078
|
+
let l = Y("Uploading...").start(), P;
|
|
2140
2079
|
try {
|
|
2141
|
-
const
|
|
2080
|
+
const p = await fetch(`${d}/mcp`, {
|
|
2142
2081
|
method: "POST",
|
|
2143
2082
|
headers: {
|
|
2144
2083
|
"Content-Type": "application/json",
|
|
2145
|
-
Authorization: `Bearer ${
|
|
2084
|
+
Authorization: `Bearer ${y.accessToken}`
|
|
2146
2085
|
},
|
|
2147
2086
|
body: JSON.stringify({
|
|
2148
2087
|
jsonrpc: "2.0",
|
|
@@ -2151,55 +2090,55 @@ h.program.command("push").description("Upload component to Myop platform").actio
|
|
|
2151
2090
|
params: {
|
|
2152
2091
|
name: "upload_component",
|
|
2153
2092
|
arguments: {
|
|
2154
|
-
name:
|
|
2093
|
+
name: n,
|
|
2155
2094
|
componentId: e.componentId && e.componentId !== "DEV" ? e.componentId : void 0,
|
|
2156
2095
|
organization: e.organization || void 0
|
|
2157
2096
|
}
|
|
2158
2097
|
}
|
|
2159
2098
|
})
|
|
2160
2099
|
});
|
|
2161
|
-
if (!
|
|
2162
|
-
throw new Error(`Server returned ${
|
|
2163
|
-
const
|
|
2164
|
-
if (
|
|
2165
|
-
throw new Error(
|
|
2166
|
-
const
|
|
2167
|
-
if (
|
|
2168
|
-
throw new Error(
|
|
2169
|
-
} catch (
|
|
2170
|
-
|
|
2100
|
+
if (!p.ok)
|
|
2101
|
+
throw new Error(`Server returned ${p.status}`);
|
|
2102
|
+
const E = await p.json();
|
|
2103
|
+
if (E.error)
|
|
2104
|
+
throw new Error(E.error.message);
|
|
2105
|
+
const x = (w = (f = (M = E.result) == null ? void 0 : M.content) == null ? void 0 : f[0]) == null ? void 0 : w.text;
|
|
2106
|
+
if (P = JSON.parse(x), !P.success)
|
|
2107
|
+
throw new Error(P.error);
|
|
2108
|
+
} catch (p) {
|
|
2109
|
+
l.fail("Failed to get upload URL"), console.error(" ", p.message), process.exit(1);
|
|
2171
2110
|
}
|
|
2172
2111
|
try {
|
|
2173
|
-
let
|
|
2174
|
-
const
|
|
2175
|
-
if (
|
|
2176
|
-
|
|
2112
|
+
let p;
|
|
2113
|
+
const E = P.curlCommand.match(/(?:"|\\")([^"\\]+(?:\\.[^"\\]*)*)(?:"|\\")$/);
|
|
2114
|
+
if (E)
|
|
2115
|
+
p = E[1];
|
|
2177
2116
|
else {
|
|
2178
|
-
const
|
|
2179
|
-
if (
|
|
2180
|
-
|
|
2117
|
+
const T = P.curlCommand.match(/(https:\/\/[^\s"\\]+)/);
|
|
2118
|
+
if (T)
|
|
2119
|
+
p = T[1];
|
|
2181
2120
|
else
|
|
2182
2121
|
throw new Error("Could not parse presigned URL");
|
|
2183
2122
|
}
|
|
2184
|
-
const
|
|
2123
|
+
const x = await fetch(p, {
|
|
2185
2124
|
method: "PUT",
|
|
2186
2125
|
headers: { "Content-Type": "text/html" },
|
|
2187
|
-
body:
|
|
2126
|
+
body: u
|
|
2188
2127
|
});
|
|
2189
|
-
if (!
|
|
2190
|
-
const
|
|
2191
|
-
throw new Error(`Upload failed: ${
|
|
2128
|
+
if (!x.ok) {
|
|
2129
|
+
const T = await x.text();
|
|
2130
|
+
throw new Error(`Upload failed: ${x.status} ${T}`);
|
|
2192
2131
|
}
|
|
2193
|
-
} catch (
|
|
2194
|
-
|
|
2132
|
+
} catch (p) {
|
|
2133
|
+
l.fail("Upload failed"), console.error(" ", p.message), process.exit(1);
|
|
2195
2134
|
}
|
|
2196
|
-
let
|
|
2135
|
+
let g;
|
|
2197
2136
|
try {
|
|
2198
|
-
const
|
|
2137
|
+
const p = await fetch(`${d}/mcp`, {
|
|
2199
2138
|
method: "POST",
|
|
2200
2139
|
headers: {
|
|
2201
2140
|
"Content-Type": "application/json",
|
|
2202
|
-
Authorization: `Bearer ${
|
|
2141
|
+
Authorization: `Bearer ${y.accessToken}`
|
|
2203
2142
|
},
|
|
2204
2143
|
body: JSON.stringify({
|
|
2205
2144
|
jsonrpc: "2.0",
|
|
@@ -2208,63 +2147,63 @@ h.program.command("push").description("Upload component to Myop platform").actio
|
|
|
2208
2147
|
params: {
|
|
2209
2148
|
name: "confirm_upload",
|
|
2210
2149
|
arguments: {
|
|
2211
|
-
uploadId:
|
|
2150
|
+
uploadId: P.uploadId
|
|
2212
2151
|
}
|
|
2213
2152
|
}
|
|
2214
2153
|
})
|
|
2215
2154
|
});
|
|
2216
|
-
if (!
|
|
2217
|
-
throw new Error(`Server returned ${
|
|
2218
|
-
const
|
|
2219
|
-
if (
|
|
2220
|
-
throw new Error(
|
|
2221
|
-
const
|
|
2222
|
-
if (
|
|
2223
|
-
throw new Error(
|
|
2224
|
-
|
|
2225
|
-
} catch (
|
|
2226
|
-
|
|
2227
|
-
}
|
|
2228
|
-
if (
|
|
2229
|
-
e.componentId =
|
|
2155
|
+
if (!p.ok)
|
|
2156
|
+
throw new Error(`Server returned ${p.status}`);
|
|
2157
|
+
const E = await p.json();
|
|
2158
|
+
if (E.error)
|
|
2159
|
+
throw new Error(E.error.message);
|
|
2160
|
+
const x = (b = (R = (_ = E.result) == null ? void 0 : _.content) == null ? void 0 : R[0]) == null ? void 0 : b.text;
|
|
2161
|
+
if (g = JSON.parse(x), !g.success)
|
|
2162
|
+
throw new Error(g.error);
|
|
2163
|
+
l.succeed("Pushed successfully");
|
|
2164
|
+
} catch (p) {
|
|
2165
|
+
l.fail("Confirmation failed"), console.error(" ", p.message), process.exit(1);
|
|
2166
|
+
}
|
|
2167
|
+
if (g.isNewComponent || !e.componentId || e.componentId === "DEV") {
|
|
2168
|
+
e.componentId = g.componentId, e.organization = g.orgId, e.name || (e.name = g.componentName);
|
|
2230
2169
|
try {
|
|
2231
|
-
|
|
2232
|
-
} catch (
|
|
2233
|
-
console.log(`⚠️ Could not update ${
|
|
2170
|
+
C.writeFileSync(t, JSON.stringify(e, null, 2));
|
|
2171
|
+
} catch (p) {
|
|
2172
|
+
console.log(`⚠️ Could not update ${t}: ${p.message}`), console.log(` Add componentId: "${g.componentId}" manually`);
|
|
2234
2173
|
}
|
|
2235
2174
|
}
|
|
2236
2175
|
console.log(`
|
|
2237
|
-
${
|
|
2176
|
+
${g.componentName}`), console.log(` ${g.dashboardUrl}
|
|
2238
2177
|
`), process.exit(0);
|
|
2239
2178
|
});
|
|
2240
|
-
|
|
2241
|
-
var
|
|
2242
|
-
const
|
|
2179
|
+
v.program.command("pull").description("Download component HTML from Myop platform").argument("[componentId]", "Component ID to pull (overrides myop.config.json)").option("-o, --output <path>", "Output file path (default: index.html or dist/index.html)").action(async (o, t) => {
|
|
2180
|
+
var w, _, R;
|
|
2181
|
+
const e = v.program.getOptionValue("config") || "./myop.config.json";
|
|
2243
2182
|
let n = {};
|
|
2244
|
-
if (
|
|
2183
|
+
if (C.existsSync(e))
|
|
2245
2184
|
try {
|
|
2246
|
-
n = JSON.parse(
|
|
2185
|
+
n = JSON.parse(C.readFileSync(e, "utf-8"));
|
|
2247
2186
|
} catch {
|
|
2248
2187
|
}
|
|
2249
|
-
const
|
|
2250
|
-
(!
|
|
2251
|
-
const
|
|
2188
|
+
const s = o || n.componentId;
|
|
2189
|
+
(!s || s === "DEV") && (console.error("❌ No component ID provided."), console.log(" Pass a component ID: myop pull <componentId>"), console.log(" Or ensure myop.config.json has a valid componentId."), process.exit(1));
|
|
2190
|
+
const i = n.name || n.componentName || s;
|
|
2252
2191
|
console.log(`
|
|
2253
|
-
📥 Pulling: ${
|
|
2254
|
-
let
|
|
2192
|
+
📥 Pulling: ${i}`), console.log(` ID: ${s}`);
|
|
2193
|
+
let c;
|
|
2255
2194
|
try {
|
|
2256
|
-
|
|
2195
|
+
c = await We();
|
|
2257
2196
|
} catch (b) {
|
|
2258
2197
|
console.error("❌ Authentication failed:", b.message), process.exit(1);
|
|
2259
2198
|
}
|
|
2260
|
-
const
|
|
2199
|
+
const u = be(), y = Y("Fetching component...").start();
|
|
2261
2200
|
let d;
|
|
2262
2201
|
try {
|
|
2263
|
-
const b = await fetch(`${
|
|
2202
|
+
const b = await fetch(`${u}/mcp`, {
|
|
2264
2203
|
method: "POST",
|
|
2265
2204
|
headers: {
|
|
2266
2205
|
"Content-Type": "application/json",
|
|
2267
|
-
Authorization: `Bearer ${
|
|
2206
|
+
Authorization: `Bearer ${c.accessToken}`
|
|
2268
2207
|
},
|
|
2269
2208
|
body: JSON.stringify({
|
|
2270
2209
|
jsonrpc: "2.0",
|
|
@@ -2272,75 +2211,286 @@ h.program.command("pull").description("Download component HTML from Myop platfor
|
|
|
2272
2211
|
method: "tools/call",
|
|
2273
2212
|
params: {
|
|
2274
2213
|
name: "get_component",
|
|
2275
|
-
arguments: { componentId:
|
|
2214
|
+
arguments: { componentId: s }
|
|
2276
2215
|
}
|
|
2277
2216
|
})
|
|
2278
2217
|
});
|
|
2279
2218
|
if (!b.ok)
|
|
2280
2219
|
throw new Error(`Server returned ${b.status}`);
|
|
2281
|
-
const
|
|
2282
|
-
if (
|
|
2283
|
-
throw new Error(
|
|
2284
|
-
const
|
|
2285
|
-
if (d = JSON.parse(
|
|
2220
|
+
const p = await b.json();
|
|
2221
|
+
if (p.error)
|
|
2222
|
+
throw new Error(p.error.message);
|
|
2223
|
+
const E = (R = (_ = (w = p.result) == null ? void 0 : w.content) == null ? void 0 : _[0]) == null ? void 0 : R.text;
|
|
2224
|
+
if (d = JSON.parse(E), !d.success && !d.html)
|
|
2286
2225
|
throw new Error(d.error || "No HTML content returned");
|
|
2287
|
-
|
|
2226
|
+
y.succeed("Component fetched");
|
|
2288
2227
|
} catch (b) {
|
|
2289
|
-
|
|
2290
|
-
}
|
|
2291
|
-
let
|
|
2292
|
-
|
|
2293
|
-
const
|
|
2294
|
-
|
|
2295
|
-
const
|
|
2296
|
-
let
|
|
2297
|
-
if (
|
|
2298
|
-
name: d.name ||
|
|
2299
|
-
componentId:
|
|
2228
|
+
y.fail("Failed to fetch component"), console.error(" ", b.message), process.exit(1);
|
|
2229
|
+
}
|
|
2230
|
+
let l = t.output;
|
|
2231
|
+
l || (C.existsSync("./dist/index.html") ? l = "./dist/index.html" : l = "./index.html");
|
|
2232
|
+
const P = d.htmlContent || d.html, g = O.dirname(l);
|
|
2233
|
+
g && !C.existsSync(g) && C.mkdirSync(g, { recursive: !0 }), C.writeFileSync(l, P), console.log(` Saved to: ${l} (${(P.length / 1024).toFixed(1)} KB)`);
|
|
2234
|
+
const M = C.existsSync(e);
|
|
2235
|
+
let f = !1;
|
|
2236
|
+
if (M ? ((!n.componentId || n.componentId === "DEV") && (n.componentId = s, f = !0), !n.name && d.name && (n.name = d.name, f = !0)) : (n = {
|
|
2237
|
+
name: d.name || O.basename(process.cwd()),
|
|
2238
|
+
componentId: s,
|
|
2300
2239
|
type: "html",
|
|
2301
2240
|
author: "@myop-cli",
|
|
2302
2241
|
HMR: !0
|
|
2303
|
-
},
|
|
2242
|
+
}, f = !0), f)
|
|
2304
2243
|
try {
|
|
2305
|
-
|
|
2244
|
+
C.writeFileSync(e, JSON.stringify(n, null, 2)), console.log(` ${M ? "Updated" : "Created"} ${e}`);
|
|
2306
2245
|
} catch (b) {
|
|
2307
|
-
console.log(` ⚠️ Could not write ${
|
|
2246
|
+
console.log(` ⚠️ Could not write ${e}: ${b.message}`);
|
|
2308
2247
|
}
|
|
2309
2248
|
console.log(`
|
|
2310
2249
|
✅ Pull completed!
|
|
2311
2250
|
`), process.exit(0);
|
|
2312
2251
|
});
|
|
2313
|
-
|
|
2314
|
-
const {
|
|
2315
|
-
let
|
|
2252
|
+
v.program.command("list").description("Browse and pull/push remote components").option("--org <orgId>", "Organization ID to use").action(async (o) => {
|
|
2253
|
+
const { search: t, select: e } = await import("@inquirer/prompts");
|
|
2254
|
+
let n;
|
|
2316
2255
|
try {
|
|
2317
|
-
|
|
2256
|
+
n = await We();
|
|
2257
|
+
} catch (f) {
|
|
2258
|
+
console.error("Authentication failed:", f.message), process.exit(1);
|
|
2259
|
+
}
|
|
2260
|
+
const s = be(), i = (f, w) => ro(s, n.accessToken, f, w);
|
|
2261
|
+
let c = Y("Loading organizations...").start(), u;
|
|
2262
|
+
try {
|
|
2263
|
+
const f = await i("list_organizations");
|
|
2264
|
+
if (u = f.organizations || f, !Array.isArray(u))
|
|
2265
|
+
throw new Error("Unexpected response from list_organizations");
|
|
2266
|
+
} catch (f) {
|
|
2267
|
+
c.fail("Failed to load organizations"), console.error(" ", f.message), process.exit(1);
|
|
2268
|
+
}
|
|
2269
|
+
u.length === 0 && (c.fail("No organizations found for this account"), process.exit(1)), c.stop();
|
|
2270
|
+
let y, d;
|
|
2271
|
+
if (o.org) {
|
|
2272
|
+
const f = u.find((w) => w.id === o.org || w._id === o.org);
|
|
2273
|
+
f || (console.error(`Organization "${o.org}" not found. Available:`), u.forEach((w) => console.log(` ${w.id || w._id} ${w.name}`)), process.exit(1)), y = f.id || f._id, d = f.name, _e({ id: y, name: d });
|
|
2274
|
+
} else {
|
|
2275
|
+
const f = io();
|
|
2276
|
+
if (f && u.find((w) => (w.id || w._id) === f.id))
|
|
2277
|
+
y = f.id, d = f.name;
|
|
2278
|
+
else if (u.length === 1)
|
|
2279
|
+
y = u[0].id || u[0]._id, d = u[0].name, _e({ id: y, name: d });
|
|
2280
|
+
else
|
|
2281
|
+
try {
|
|
2282
|
+
const w = await e({
|
|
2283
|
+
message: "Select an organization:",
|
|
2284
|
+
choices: u.map((_) => ({
|
|
2285
|
+
name: _.name,
|
|
2286
|
+
value: { id: _.id || _._id, name: _.name }
|
|
2287
|
+
}))
|
|
2288
|
+
});
|
|
2289
|
+
y = w.id, d = w.name, _e({ id: y, name: d });
|
|
2290
|
+
} catch (w) {
|
|
2291
|
+
throw w.name === "ExitPromptError" && (console.log(`
|
|
2292
|
+
|
|
2293
|
+
👋 Goodbye!
|
|
2294
|
+
`), process.exit(0)), w;
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
console.log(` Using organization: ${d}`), c = Y("Loading components...").start();
|
|
2298
|
+
let l;
|
|
2299
|
+
try {
|
|
2300
|
+
const f = await i("list_components", { organizationId: y });
|
|
2301
|
+
if (l = f.components || f, !Array.isArray(l))
|
|
2302
|
+
throw new Error("Unexpected response from list_components");
|
|
2303
|
+
} catch (f) {
|
|
2304
|
+
c.fail("Failed to load components"), console.error(" ", f.message), process.exit(1);
|
|
2305
|
+
}
|
|
2306
|
+
c.stop(), l.length === 0 && (console.log(` No components found in this organization.
|
|
2307
|
+
`), process.exit(0)), console.log(` ${d} - ${l.length} component(s)
|
|
2308
|
+
`);
|
|
2309
|
+
const P = [];
|
|
2310
|
+
for (; ; ) {
|
|
2311
|
+
const f = `[Done - pull/push ${P.length} selected]`, w = "__done__", _ = new Set(P.map((p) => p.id || p._id || p.componentId));
|
|
2312
|
+
let R;
|
|
2313
|
+
try {
|
|
2314
|
+
R = await t({
|
|
2315
|
+
message: "Search & select components:",
|
|
2316
|
+
source: (p) => {
|
|
2317
|
+
const E = (p || "").toLowerCase(), x = l.filter((k) => {
|
|
2318
|
+
const H = k.id || k._id || k.componentId;
|
|
2319
|
+
return _.has(H) ? !1 : E ? (k.name || "").toLowerCase().includes(E) : !0;
|
|
2320
|
+
}), T = [
|
|
2321
|
+
{ name: f, value: w }
|
|
2322
|
+
];
|
|
2323
|
+
for (const k of x) {
|
|
2324
|
+
const H = k.id || k._id || k.componentId, A = H ? H.substring(0, 8) + "..." : "";
|
|
2325
|
+
T.push({
|
|
2326
|
+
name: `${k.name} (${A})`,
|
|
2327
|
+
value: H
|
|
2328
|
+
});
|
|
2329
|
+
}
|
|
2330
|
+
return T;
|
|
2331
|
+
}
|
|
2332
|
+
});
|
|
2333
|
+
} catch (p) {
|
|
2334
|
+
throw p.name === "ExitPromptError" && (console.log(`
|
|
2335
|
+
|
|
2336
|
+
👋 Goodbye!
|
|
2337
|
+
`), process.exit(0)), p;
|
|
2338
|
+
}
|
|
2339
|
+
if (R === w)
|
|
2340
|
+
break;
|
|
2341
|
+
const b = l.find((p) => (p.id || p._id || p.componentId) === R);
|
|
2342
|
+
b && (P.push(b), console.log(` + ${b.name}`));
|
|
2343
|
+
}
|
|
2344
|
+
P.length === 0 && (console.log(` No components selected.
|
|
2345
|
+
`), process.exit(0));
|
|
2346
|
+
let g;
|
|
2347
|
+
try {
|
|
2348
|
+
g = await e({
|
|
2349
|
+
message: `${P.length} component(s) selected:`,
|
|
2350
|
+
choices: [
|
|
2351
|
+
{ name: "Pull selected", value: "pull" },
|
|
2352
|
+
{ name: "Push selected", value: "push" },
|
|
2353
|
+
{ name: "Cancel", value: "cancel" }
|
|
2354
|
+
]
|
|
2355
|
+
});
|
|
2356
|
+
} catch (f) {
|
|
2357
|
+
throw f.name === "ExitPromptError" && (console.log(`
|
|
2358
|
+
|
|
2359
|
+
👋 Goodbye!
|
|
2360
|
+
`), process.exit(0)), f;
|
|
2361
|
+
}
|
|
2362
|
+
g === "cancel" && (console.log(` Cancelled.
|
|
2363
|
+
`), process.exit(0));
|
|
2364
|
+
const M = (f) => f.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
2365
|
+
if (g === "pull") {
|
|
2366
|
+
console.log(`
|
|
2367
|
+
Pulling ${P.length} components...
|
|
2368
|
+
`);
|
|
2369
|
+
const f = await Promise.all(P.map(async (R) => {
|
|
2370
|
+
const b = R.id || R._id || R.componentId;
|
|
2371
|
+
try {
|
|
2372
|
+
const p = await i("get_component", { componentId: b }), E = M(R.name);
|
|
2373
|
+
C.mkdirSync(E, { recursive: !0 });
|
|
2374
|
+
const x = p.htmlContent || p.html;
|
|
2375
|
+
if (!x)
|
|
2376
|
+
throw new Error("No HTML content returned");
|
|
2377
|
+
return C.writeFileSync(O.join(E, "index.html"), x), C.writeFileSync(O.join(E, "myop.config.json"), JSON.stringify({
|
|
2378
|
+
name: R.name,
|
|
2379
|
+
componentId: b,
|
|
2380
|
+
organization: y,
|
|
2381
|
+
type: "html",
|
|
2382
|
+
author: "@myop-cli",
|
|
2383
|
+
HMR: !0
|
|
2384
|
+
}, null, 2)), { name: R.name, status: "ok", dir: E };
|
|
2385
|
+
} catch (p) {
|
|
2386
|
+
return { name: R.name, status: "failed", error: p.message };
|
|
2387
|
+
}
|
|
2388
|
+
}));
|
|
2389
|
+
let w = 0, _ = 0;
|
|
2390
|
+
for (const R of f)
|
|
2391
|
+
R.status === "ok" ? (console.log(` \x1B[32m✔\x1B[0m ${R.name} -> ./${R.dir}/`), w++) : (console.log(` \x1B[31m✖\x1B[0m ${R.name} - ${R.error}`), _++);
|
|
2392
|
+
console.log(`
|
|
2393
|
+
Done! Pulled ${w} component${w !== 1 ? "s" : ""}.${_ ? ` ${_} failed.` : ""}
|
|
2394
|
+
`);
|
|
2395
|
+
} else if (g === "push") {
|
|
2396
|
+
console.log(`
|
|
2397
|
+
Pushing ${P.length} components...
|
|
2398
|
+
`);
|
|
2399
|
+
const f = Ge(".", 3), w = await Promise.all(P.map(async (p) => {
|
|
2400
|
+
const E = p.id || p._id || p.componentId, x = f.find((T) => T.componentId === E);
|
|
2401
|
+
if (!x)
|
|
2402
|
+
return { name: p.name, status: "skipped", reason: "no local match" };
|
|
2403
|
+
try {
|
|
2404
|
+
let T;
|
|
2405
|
+
const k = x.path;
|
|
2406
|
+
if (C.existsSync(O.join(k, "dist", "index.html")))
|
|
2407
|
+
T = O.join(k, "dist", "index.html");
|
|
2408
|
+
else {
|
|
2409
|
+
const z = C.readdirSync(k).filter(
|
|
2410
|
+
(Q) => Q.endsWith(".html") && !Q.startsWith(".") && C.statSync(O.join(k, Q)).isFile()
|
|
2411
|
+
);
|
|
2412
|
+
if (z.length === 1)
|
|
2413
|
+
T = O.join(k, z[0]);
|
|
2414
|
+
else if (z.includes("index.html"))
|
|
2415
|
+
T = O.join(k, "index.html");
|
|
2416
|
+
else
|
|
2417
|
+
throw new Error("No HTML file found");
|
|
2418
|
+
}
|
|
2419
|
+
const H = C.readFileSync(T, "utf-8"), A = x.name || p.name, j = await i("upload_component", {
|
|
2420
|
+
name: A,
|
|
2421
|
+
componentId: E,
|
|
2422
|
+
organization: y
|
|
2423
|
+
});
|
|
2424
|
+
if (!j.success)
|
|
2425
|
+
throw new Error(j.error || "Upload request failed");
|
|
2426
|
+
let J;
|
|
2427
|
+
const F = j.curlCommand.match(/(?:"|\\")([^"\\]+(?:\\.[^"\\]*)*)(?:"|\\")$/);
|
|
2428
|
+
if (F)
|
|
2429
|
+
J = F[1];
|
|
2430
|
+
else {
|
|
2431
|
+
const z = j.curlCommand.match(/(https:\/\/[^\s"\\]+)/);
|
|
2432
|
+
if (z)
|
|
2433
|
+
J = z[1];
|
|
2434
|
+
else
|
|
2435
|
+
throw new Error("Could not parse presigned URL");
|
|
2436
|
+
}
|
|
2437
|
+
const V = await fetch(J, {
|
|
2438
|
+
method: "PUT",
|
|
2439
|
+
headers: { "Content-Type": "text/html" },
|
|
2440
|
+
body: H
|
|
2441
|
+
});
|
|
2442
|
+
if (!V.ok)
|
|
2443
|
+
throw new Error(`Upload failed: ${V.status}`);
|
|
2444
|
+
const te = await i("confirm_upload", {
|
|
2445
|
+
uploadId: j.uploadId
|
|
2446
|
+
});
|
|
2447
|
+
if (!te.success)
|
|
2448
|
+
throw new Error(te.error || "Confirmation failed");
|
|
2449
|
+
return { name: A, status: "ok" };
|
|
2450
|
+
} catch (T) {
|
|
2451
|
+
return { name: p.name, status: "failed", error: T.message };
|
|
2452
|
+
}
|
|
2453
|
+
}));
|
|
2454
|
+
let _ = 0, R = 0, b = 0;
|
|
2455
|
+
for (const p of w)
|
|
2456
|
+
p.status === "ok" ? (console.log(` \x1B[32m✔\x1B[0m ${p.name}`), _++) : p.status === "skipped" ? (console.log(` \x1B[33m⊘\x1B[0m ${p.name} (${p.reason})`), R++) : (console.log(` \x1B[31m✖\x1B[0m ${p.name} - ${p.error}`), b++);
|
|
2457
|
+
console.log(`
|
|
2458
|
+
Done! Pushed ${_}${R ? `, skipped ${R}` : ""}${b ? `, ${b} failed` : ""}.
|
|
2459
|
+
`);
|
|
2460
|
+
}
|
|
2461
|
+
process.exit(0);
|
|
2462
|
+
});
|
|
2463
|
+
v.program.command("create").description("Create a new Myop HTML component and start dev server").action(async () => {
|
|
2464
|
+
const { input: o } = await import("@inquirer/prompts"), t = await import("fs"), n = (await import("path")).default.basename(process.cwd());
|
|
2465
|
+
let s;
|
|
2466
|
+
try {
|
|
2467
|
+
s = await o({
|
|
2318
2468
|
message: "Component name:",
|
|
2319
2469
|
default: n
|
|
2320
2470
|
});
|
|
2321
|
-
} catch (
|
|
2322
|
-
throw
|
|
2471
|
+
} catch (y) {
|
|
2472
|
+
throw y.name === "ExitPromptError" && (console.log(`
|
|
2323
2473
|
|
|
2324
2474
|
👋 Goodbye!
|
|
2325
|
-
`), process.exit(0)),
|
|
2475
|
+
`), process.exit(0)), y;
|
|
2326
2476
|
}
|
|
2327
|
-
(
|
|
2477
|
+
(t.existsSync("index.html") || t.existsSync("myop.config.json")) && (console.log(`
|
|
2328
2478
|
⚠️ index.html or myop.config.json already exists in this directory.`), console.log(" Use `myop dev` to start the dev server for an existing component.\n"), process.exit(1));
|
|
2329
|
-
const
|
|
2330
|
-
name:
|
|
2479
|
+
const i = {
|
|
2480
|
+
name: s,
|
|
2331
2481
|
componentId: "DEV",
|
|
2332
2482
|
type: "html",
|
|
2333
2483
|
author: "@myop-cli",
|
|
2334
2484
|
HMR: !0
|
|
2335
2485
|
};
|
|
2336
|
-
|
|
2337
|
-
const
|
|
2486
|
+
t.writeFileSync("myop.config.json", JSON.stringify(i, null, 2));
|
|
2487
|
+
const c = `<!DOCTYPE html>
|
|
2338
2488
|
<html lang="en">
|
|
2339
2489
|
<head>
|
|
2340
2490
|
<meta charset="UTF-8">
|
|
2341
2491
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
2342
2492
|
<meta name="myop:size" content='{"width":"100%","height":"100%"}'>
|
|
2343
|
-
<title>${
|
|
2493
|
+
<title>${s}</title>
|
|
2344
2494
|
<script type="myop/types">
|
|
2345
2495
|
// =========================================================================
|
|
2346
2496
|
// MYOP COMPONENT TYPE DEFINITIONS
|
|
@@ -2421,7 +2571,7 @@ h.program.command("create").description("Create a new Myop HTML component and st
|
|
|
2421
2571
|
</head>
|
|
2422
2572
|
<body>
|
|
2423
2573
|
<div id="app-root">
|
|
2424
|
-
<h1>${
|
|
2574
|
+
<h1>${s}</h1>
|
|
2425
2575
|
<p>Edit index.html to get started</p>
|
|
2426
2576
|
</div>
|
|
2427
2577
|
|
|
@@ -2450,31 +2600,108 @@ h.program.command("create").description("Create a new Myop HTML component and st
|
|
|
2450
2600
|
|
|
2451
2601
|
<script id="myop_preview">
|
|
2452
2602
|
window.myop_init_interface({
|
|
2453
|
-
title: '${
|
|
2603
|
+
title: '${s}',
|
|
2454
2604
|
description: 'Edit index.html to get started'
|
|
2455
2605
|
});
|
|
2456
2606
|
<\/script>
|
|
2457
2607
|
</body>
|
|
2458
2608
|
</html>`;
|
|
2459
|
-
|
|
2460
|
-
const
|
|
2609
|
+
t.writeFileSync("index.html", c);
|
|
2610
|
+
const u = Ve(process.cwd());
|
|
2611
|
+
console.log(`
|
|
2612
|
+
✅ Created ${s}`), console.log(" index.html"), console.log(" myop.config.json"), u && console.log(" .agents/skills/ (AI agent skills)"), console.log(""), await xe();
|
|
2613
|
+
});
|
|
2614
|
+
v.program.command("dev").description("Start development server with file watching").action(xe);
|
|
2615
|
+
const ut = async () => {
|
|
2616
|
+
const o = process.cwd(), t = Y("Installing AI agent skills...").start(), e = Ve(o);
|
|
2617
|
+
e ? (t.succeed("AI agent skills installed"), console.log(" .agents/skills/ (master copy)"), console.log(" Symlinked to: .claude/, .cursor/, .gemini/, .junie/, .agent/")) : t.fail("Failed to install skills"), process.exit(e ? 0 : 1);
|
|
2618
|
+
};
|
|
2619
|
+
v.program.command("skill").description("Install or update AI agent skills in the current directory").action(ut);
|
|
2620
|
+
v.program.command("train").description("Install or update AI agent skills in the current directory (alias for skill)").action(ut);
|
|
2621
|
+
v.program.command("mcp").description("Configure Myop MCP server for your AI coding assistant").action(async () => {
|
|
2622
|
+
const { select: o, confirm: t } = await import("@inquirer/prompts"), n = (await import("os")).homedir(), s = be() + "/mcp", i = [
|
|
2623
|
+
{
|
|
2624
|
+
name: "Claude Code",
|
|
2625
|
+
value: "claude",
|
|
2626
|
+
configPath: O.join(n, ".claude.json"),
|
|
2627
|
+
getEntry: () => ({ type: "http", url: s }),
|
|
2628
|
+
restart: "Run /mcp in Claude Code to reload, or restart Claude Code."
|
|
2629
|
+
},
|
|
2630
|
+
{
|
|
2631
|
+
name: "Cursor",
|
|
2632
|
+
value: "cursor",
|
|
2633
|
+
configPath: O.join(n, ".cursor", "mcp.json"),
|
|
2634
|
+
getEntry: () => ({ url: s }),
|
|
2635
|
+
restart: "Restart Cursor or reload the window to activate."
|
|
2636
|
+
},
|
|
2637
|
+
{
|
|
2638
|
+
name: "Windsurf",
|
|
2639
|
+
value: "windsurf",
|
|
2640
|
+
configPath: O.join(n, ".codeium", "windsurf", "mcp_config.json"),
|
|
2641
|
+
getEntry: () => ({ url: s }),
|
|
2642
|
+
restart: "Restart Windsurf to activate."
|
|
2643
|
+
},
|
|
2644
|
+
{
|
|
2645
|
+
name: "VS Code (GitHub Copilot)",
|
|
2646
|
+
value: "vscode",
|
|
2647
|
+
configPath: process.platform === "darwin" ? O.join(n, "Library", "Application Support", "Code", "User", "mcp.json") : process.platform === "win32" ? O.join(process.env.APPDATA || O.join(n, "AppData", "Roaming"), "Code", "User", "mcp.json") : O.join(n, ".config", "Code", "User", "mcp.json"),
|
|
2648
|
+
getEntry: () => ({ type: "http", url: s }),
|
|
2649
|
+
restart: "Restart VS Code to activate. Requires GitHub Copilot."
|
|
2650
|
+
}
|
|
2651
|
+
];
|
|
2461
2652
|
console.log(`
|
|
2462
|
-
|
|
2653
|
+
Configure Myop MCP server for your AI coding assistant.
|
|
2654
|
+
`);
|
|
2655
|
+
let c;
|
|
2656
|
+
try {
|
|
2657
|
+
c = await o({
|
|
2658
|
+
message: "Select your AI coding assistant:",
|
|
2659
|
+
choices: i.map((l) => ({ name: l.name, value: l.value }))
|
|
2660
|
+
});
|
|
2661
|
+
} catch (l) {
|
|
2662
|
+
throw l.name === "ExitPromptError" && (console.log(`
|
|
2663
|
+
|
|
2664
|
+
👋 Goodbye!
|
|
2665
|
+
`), process.exit(0)), l;
|
|
2666
|
+
}
|
|
2667
|
+
const u = i.find((l) => l.value === c);
|
|
2668
|
+
let y = {};
|
|
2669
|
+
try {
|
|
2670
|
+
const l = C.readFileSync(u.configPath, "utf-8");
|
|
2671
|
+
y = JSON.parse(l);
|
|
2672
|
+
} catch {
|
|
2673
|
+
}
|
|
2674
|
+
y.mcpServers || (y.mcpServers = {});
|
|
2675
|
+
const d = y.mcpServers.myop;
|
|
2676
|
+
if (d && d.url === s && (console.log(`
|
|
2677
|
+
Myop MCP is already configured for ${u.name}.`), console.log(` Config: ${u.configPath}
|
|
2678
|
+
`), process.exit(0)), d) {
|
|
2679
|
+
console.log(`
|
|
2680
|
+
Myop MCP is already configured (URL: ${d.url}).`);
|
|
2681
|
+
try {
|
|
2682
|
+
await t({ message: "Update to latest URL?", default: !0 }) || process.exit(0);
|
|
2683
|
+
} catch (l) {
|
|
2684
|
+
throw l.name === "ExitPromptError" && process.exit(0), l;
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
y.mcpServers.myop = u.getEntry(), C.mkdirSync(O.dirname(u.configPath), { recursive: !0 }), C.writeFileSync(u.configPath, JSON.stringify(y, null, 2)), console.log(`
|
|
2688
|
+
\x1B[32m✔\x1B[0m Myop MCP configured for ${u.name}`), console.log(` Config: ${u.configPath}`), console.log(` Server: ${s}`), console.log(`
|
|
2689
|
+
${u.restart}
|
|
2690
|
+
`), process.exit(0);
|
|
2463
2691
|
});
|
|
2464
|
-
|
|
2465
|
-
const to = () => {
|
|
2692
|
+
const po = () => {
|
|
2466
2693
|
try {
|
|
2467
|
-
|
|
2694
|
+
ee("git --version", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
2468
2695
|
} catch {
|
|
2469
2696
|
return { gitNotInstalled: !0 };
|
|
2470
2697
|
}
|
|
2471
2698
|
try {
|
|
2472
|
-
|
|
2699
|
+
ee("git rev-parse --git-dir", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
2473
2700
|
} catch {
|
|
2474
2701
|
return { notARepo: !0 };
|
|
2475
2702
|
}
|
|
2476
2703
|
try {
|
|
2477
|
-
const o =
|
|
2704
|
+
const o = ee("git diff --stat HEAD -- . 2>/dev/null || git diff --stat -- . 2>/dev/null", {
|
|
2478
2705
|
encoding: "utf-8",
|
|
2479
2706
|
stdio: ["pipe", "pipe", "pipe"]
|
|
2480
2707
|
}).trim();
|
|
@@ -2484,23 +2711,23 @@ const to = () => {
|
|
|
2484
2711
|
insertions: 0,
|
|
2485
2712
|
deletions: 0
|
|
2486
2713
|
};
|
|
2487
|
-
const
|
|
2488
|
-
`),
|
|
2714
|
+
const t = o.split(`
|
|
2715
|
+
`), e = t[t.length - 1], n = e.match(/(\d+) insertion/), s = e.match(/(\d+) deletion/), i = e.match(/(\d+) file/);
|
|
2489
2716
|
return {
|
|
2490
|
-
files:
|
|
2717
|
+
files: i ? parseInt(i[1]) : 0,
|
|
2491
2718
|
insertions: n ? parseInt(n[1]) : 0,
|
|
2492
|
-
deletions:
|
|
2719
|
+
deletions: s ? parseInt(s[1]) : 0
|
|
2493
2720
|
};
|
|
2494
2721
|
} catch {
|
|
2495
2722
|
return null;
|
|
2496
2723
|
}
|
|
2497
|
-
},
|
|
2498
|
-
var
|
|
2499
|
-
const
|
|
2724
|
+
}, ie = async (o = !1, t = !1) => {
|
|
2725
|
+
var l, P, g;
|
|
2726
|
+
const e = $e(), n = !!(e != null && e.email), s = ((l = v.myopConfig) == null ? void 0 : l.name) || ((P = v.myopConfig) == null ? void 0 : P.componentName), i = (g = v.myopConfig) == null ? void 0 : g.componentId, c = po();
|
|
2500
2727
|
console.log(`
|
|
2501
2728
|
┌─────────────────────────────────────────────────┐`), console.log("│ │"), console.log("│ Welcome to Myop CLI - Remote UI Made Easy │"), console.log("│ │"), console.log(`└─────────────────────────────────────────────────┘
|
|
2502
|
-
`), o &&
|
|
2503
|
-
const
|
|
2729
|
+
`), o && s ? (console.log(` Component: ${s}`), i ? (console.log(` ID: ${i}`), console.log(` Dashboard: https://dashboard.myop.dev/dashboard/2.0/component/${i}`)) : console.log(" ID: (not yet pushed)")) : console.log(" Component: No myop.config.json found"), console.log(` User: ${n ? e.email : "Not logged in"}`), c != null && c.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")) : c != null && c.notARepo ? console.log(" Changes: Not a git repository") : c && (c.insertions > 0 || c.deletions > 0) ? console.log(` Changes: ${c.files} file${c.files !== 1 ? "s" : ""} | \x1B[32m+${c.insertions}\x1B[0m \x1B[31m-${c.deletions}\x1B[0m`) : c && console.log(" Changes: No uncommitted changes"), console.log("");
|
|
2730
|
+
const y = [
|
|
2504
2731
|
{
|
|
2505
2732
|
emoji: "🚀",
|
|
2506
2733
|
label: "Initialize new component",
|
|
@@ -2510,37 +2737,37 @@ const to = () => {
|
|
|
2510
2737
|
},
|
|
2511
2738
|
{
|
|
2512
2739
|
emoji: "🛠️ ",
|
|
2513
|
-
label:
|
|
2740
|
+
label: s ? `Start dev mode for "${s}"` : "Start dev mode",
|
|
2514
2741
|
value: "dev",
|
|
2515
2742
|
help: "Starts dev server with HMR for instant preview of changes",
|
|
2516
2743
|
disabled: o ? !1 : "(no config file)"
|
|
2517
2744
|
},
|
|
2518
2745
|
{
|
|
2519
2746
|
emoji: "📦",
|
|
2520
|
-
label:
|
|
2747
|
+
label: s ? `Push "${s}"` : "Push component",
|
|
2521
2748
|
value: "sync",
|
|
2522
2749
|
help: "Builds project & uploads dist/index.html to Myop",
|
|
2523
2750
|
disabled: o ? n ? !1 : "(login required)" : "(no config file)"
|
|
2524
2751
|
}
|
|
2525
|
-
].map((
|
|
2526
|
-
name:
|
|
2527
|
-
${
|
|
2528
|
-
value:
|
|
2529
|
-
disabled:
|
|
2752
|
+
].map((M) => ({
|
|
2753
|
+
name: t && !M.disabled ? `${M.emoji} ${M.label}
|
|
2754
|
+
${M.help}` : `${M.emoji} ${M.label}`,
|
|
2755
|
+
value: M.value,
|
|
2756
|
+
disabled: M.disabled
|
|
2530
2757
|
}));
|
|
2531
|
-
|
|
2532
|
-
new
|
|
2758
|
+
y.push(
|
|
2759
|
+
new Fe(),
|
|
2533
2760
|
{
|
|
2534
|
-
name:
|
|
2535
|
-
Clears stored credentials from this machine` :
|
|
2536
|
-
Opens browser to authenticate with Myop` : n ? `🔓 Logout (${
|
|
2761
|
+
name: t && n ? `🔓 Logout (${e.email})
|
|
2762
|
+
Clears stored credentials from this machine` : t && !n ? `🔐 Login to Myop
|
|
2763
|
+
Opens browser to authenticate with Myop` : n ? `🔓 Logout (${e.email})` : "🔐 Login to Myop",
|
|
2537
2764
|
value: n ? "logout" : "login"
|
|
2538
2765
|
},
|
|
2539
2766
|
{
|
|
2540
|
-
name:
|
|
2767
|
+
name: t ? "📖 Hide help" : "📖 Show help",
|
|
2541
2768
|
value: "help"
|
|
2542
2769
|
},
|
|
2543
|
-
new
|
|
2770
|
+
new Fe(),
|
|
2544
2771
|
{
|
|
2545
2772
|
name: "👋 Exit",
|
|
2546
2773
|
value: "exit"
|
|
@@ -2548,116 +2775,116 @@ const to = () => {
|
|
|
2548
2775
|
);
|
|
2549
2776
|
let d;
|
|
2550
2777
|
try {
|
|
2551
|
-
d = await
|
|
2778
|
+
d = await tt({
|
|
2552
2779
|
message: "What would you like to do?",
|
|
2553
|
-
choices:
|
|
2780
|
+
choices: y
|
|
2554
2781
|
});
|
|
2555
|
-
} catch (
|
|
2556
|
-
throw
|
|
2782
|
+
} catch (M) {
|
|
2783
|
+
throw M.name === "ExitPromptError" && (console.log(`
|
|
2557
2784
|
|
|
2558
2785
|
👋 Goodbye!
|
|
2559
|
-
`), process.exit(0)),
|
|
2786
|
+
`), process.exit(0)), M;
|
|
2560
2787
|
}
|
|
2561
2788
|
switch (d) {
|
|
2562
2789
|
case "init":
|
|
2563
|
-
await
|
|
2790
|
+
await fo();
|
|
2564
2791
|
break;
|
|
2565
2792
|
case "sync":
|
|
2566
2793
|
console.log(`
|
|
2567
|
-
|
|
2794
|
+
Pushing component...
|
|
2568
2795
|
`);
|
|
2569
|
-
const { execSync:
|
|
2796
|
+
const { execSync: M } = await import("child_process");
|
|
2570
2797
|
try {
|
|
2571
|
-
|
|
2798
|
+
M("node " + process.argv[1] + " push", { stdio: "inherit" });
|
|
2572
2799
|
} catch {
|
|
2573
2800
|
}
|
|
2574
|
-
await
|
|
2801
|
+
await ie(!0, t);
|
|
2575
2802
|
break;
|
|
2576
2803
|
case "dev":
|
|
2577
|
-
await
|
|
2804
|
+
await xe();
|
|
2578
2805
|
break;
|
|
2579
2806
|
case "login":
|
|
2580
2807
|
try {
|
|
2581
2808
|
await de(), console.log(`
|
|
2582
|
-
`), await
|
|
2583
|
-
} catch (
|
|
2584
|
-
console.error("Login failed:",
|
|
2809
|
+
`), await ie(o, t);
|
|
2810
|
+
} catch (f) {
|
|
2811
|
+
console.error("Login failed:", f.message), await ie(o, t);
|
|
2585
2812
|
}
|
|
2586
2813
|
break;
|
|
2587
2814
|
case "logout":
|
|
2588
|
-
await
|
|
2589
|
-
`), await
|
|
2815
|
+
await pt(), console.log(`
|
|
2816
|
+
`), await ie(o, t);
|
|
2590
2817
|
break;
|
|
2591
2818
|
case "help":
|
|
2592
|
-
await
|
|
2819
|
+
await ie(o, !t);
|
|
2593
2820
|
break;
|
|
2594
2821
|
case "exit":
|
|
2595
2822
|
process.exit(0);
|
|
2596
2823
|
}
|
|
2597
|
-
}, ve = ".myop-monorepo.json",
|
|
2824
|
+
}, ve = ".myop-monorepo.json", mo = () => {
|
|
2598
2825
|
try {
|
|
2599
|
-
const o =
|
|
2826
|
+
const o = C.readFileSync(ve, "utf-8");
|
|
2600
2827
|
return JSON.parse(o);
|
|
2601
2828
|
} catch {
|
|
2602
2829
|
return null;
|
|
2603
2830
|
}
|
|
2604
|
-
},
|
|
2831
|
+
}, uo = (o) => {
|
|
2605
2832
|
try {
|
|
2606
|
-
const
|
|
2833
|
+
const t = {
|
|
2607
2834
|
selectedComponents: o,
|
|
2608
2835
|
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
2609
2836
|
};
|
|
2610
|
-
|
|
2837
|
+
C.writeFileSync(ve, JSON.stringify(t, null, 2));
|
|
2611
2838
|
} catch {
|
|
2612
2839
|
}
|
|
2613
|
-
},
|
|
2614
|
-
const o =
|
|
2840
|
+
}, go = async () => {
|
|
2841
|
+
const o = $e(), t = !!(o != null && o.email);
|
|
2615
2842
|
console.log(`
|
|
2616
2843
|
┌─────────────────────────────────────────────────┐`), console.log("│ │"), console.log("│ Myop CLI - Monorepo Mode │"), console.log("│ │"), console.log(`└─────────────────────────────────────────────────┘
|
|
2617
2844
|
`);
|
|
2618
|
-
const
|
|
2619
|
-
|
|
2845
|
+
const e = Y("Scanning for components...").start(), n = Ge(".");
|
|
2846
|
+
e.stop(), n.length === 0 && (console.log(` ⚠️ No myop.config.json files found in this directory or subdirectories.
|
|
2620
2847
|
`), console.log(" Run `myop` without -m flag to initialize a single component.\n"), process.exit(0));
|
|
2621
|
-
const
|
|
2848
|
+
const s = mo(), i = (s == null ? void 0 : s.selectedComponents) || [], c = i.length > 0;
|
|
2622
2849
|
console.log(` Found ${n.length} component${n.length > 1 ? "s" : ""}:
|
|
2623
|
-
`), n.forEach((
|
|
2624
|
-
const
|
|
2625
|
-
console.log(` ${
|
|
2626
|
-
}), console.log(` User: ${
|
|
2627
|
-
const { checkbox:
|
|
2628
|
-
name: `${
|
|
2629
|
-
value:
|
|
2630
|
-
checked:
|
|
2850
|
+
`), n.forEach((g, M) => {
|
|
2851
|
+
const f = g.componentId ? "✅" : "⚪", w = g.componentId ? g.componentId.substring(0, 8) + "..." : "(not pushed)";
|
|
2852
|
+
console.log(` ${f} ${g.name}`), console.log(` Path: ${g.path}`), console.log(` ID: ${w}`), console.log("");
|
|
2853
|
+
}), console.log(` User: ${t ? o.email : "Not logged in"}`), c && console.log(` 📋 Using saved selection from ${ve}`), console.log("");
|
|
2854
|
+
const { checkbox: u } = await import("@inquirer/prompts"), y = n.map((g) => ({
|
|
2855
|
+
name: `${g.name} (${g.path})`,
|
|
2856
|
+
value: g.path,
|
|
2857
|
+
checked: c ? i.includes(g.path) : !0
|
|
2631
2858
|
}));
|
|
2632
2859
|
let d;
|
|
2633
2860
|
try {
|
|
2634
|
-
d = await
|
|
2861
|
+
d = await u({
|
|
2635
2862
|
message: "Select components to start in dev mode:",
|
|
2636
|
-
choices:
|
|
2863
|
+
choices: y
|
|
2637
2864
|
});
|
|
2638
|
-
} catch (
|
|
2639
|
-
throw
|
|
2865
|
+
} catch (g) {
|
|
2866
|
+
throw g.name === "ExitPromptError" && (console.log(`
|
|
2640
2867
|
|
|
2641
2868
|
👋 Goodbye!
|
|
2642
|
-
`), process.exit(0)),
|
|
2869
|
+
`), process.exit(0)), g;
|
|
2643
2870
|
}
|
|
2644
2871
|
d.length === 0 && (console.log(`
|
|
2645
2872
|
⚠️ No components selected.
|
|
2646
|
-
`), process.exit(0)),
|
|
2873
|
+
`), process.exit(0)), uo(d), console.log(`
|
|
2647
2874
|
💾 Selection saved to ${ve}`);
|
|
2648
|
-
const
|
|
2649
|
-
console.log(`🚀 Starting dev mode for ${
|
|
2875
|
+
const l = n.filter((g) => d.includes(g.path));
|
|
2876
|
+
console.log(`🚀 Starting dev mode for ${l.length} component${l.length > 1 ? "s" : ""}...
|
|
2650
2877
|
`);
|
|
2651
|
-
const { monorepoDevCommand:
|
|
2652
|
-
await
|
|
2653
|
-
},
|
|
2654
|
-
const { input: o, select:
|
|
2655
|
-
let
|
|
2878
|
+
const { monorepoDevCommand: P } = await Promise.resolve().then(() => Ut);
|
|
2879
|
+
await P(l);
|
|
2880
|
+
}, fo = async () => {
|
|
2881
|
+
const { input: o, select: t } = await import("@inquirer/prompts"), e = await import("fs"), n = await import("path"), s = n.default.basename(process.cwd());
|
|
2882
|
+
let i, c;
|
|
2656
2883
|
try {
|
|
2657
|
-
|
|
2884
|
+
i = await o({
|
|
2658
2885
|
message: "Component name:",
|
|
2659
|
-
default:
|
|
2660
|
-
}),
|
|
2886
|
+
default: s
|
|
2887
|
+
}), c = await t({
|
|
2661
2888
|
message: "Component type:",
|
|
2662
2889
|
choices: [
|
|
2663
2890
|
{ name: "📄 HTML", value: "html", description: "Plain HTML/JS/CSS component" },
|
|
@@ -2672,17 +2899,17 @@ Running sync...
|
|
|
2672
2899
|
👋 Goodbye!
|
|
2673
2900
|
`), process.exit(0)), d;
|
|
2674
2901
|
}
|
|
2675
|
-
const
|
|
2676
|
-
name:
|
|
2677
|
-
type:
|
|
2902
|
+
const u = {
|
|
2903
|
+
name: i,
|
|
2904
|
+
type: c,
|
|
2678
2905
|
author: "@myop-cli",
|
|
2679
2906
|
HMR: !0
|
|
2680
|
-
},
|
|
2907
|
+
}, y = v.program.getOptionValue("config") || "./myop.config.json";
|
|
2681
2908
|
try {
|
|
2682
|
-
|
|
2683
|
-
✅ Created ${
|
|
2909
|
+
e.writeFileSync(y, JSON.stringify(u, null, 2)), console.log(`
|
|
2910
|
+
✅ Created ${y}`);
|
|
2684
2911
|
const d = {
|
|
2685
|
-
name:
|
|
2912
|
+
name: i.toLowerCase().replace(/\s+/g, "-"),
|
|
2686
2913
|
version: "1.0.0",
|
|
2687
2914
|
type: "module",
|
|
2688
2915
|
scripts: {
|
|
@@ -2693,7 +2920,7 @@ Running sync...
|
|
|
2693
2920
|
esbuild: "^0.24.0"
|
|
2694
2921
|
}
|
|
2695
2922
|
};
|
|
2696
|
-
|
|
2923
|
+
e.writeFileSync("package.json", JSON.stringify(d, null, 2)), console.log("✅ Created package.json"), e.mkdirSync("src/modules", { recursive: !0 }), e.mkdirSync("src/styles", { recursive: !0 }), e.writeFileSync("build.js", `import * as esbuild from 'esbuild';
|
|
2697
2924
|
import fs from 'fs';
|
|
2698
2925
|
import path from 'path';
|
|
2699
2926
|
|
|
@@ -2773,25 +3000,25 @@ fs.writeFileSync('dist/index.html', html);
|
|
|
2773
3000
|
console.log('✅ Built dist/index.html');
|
|
2774
3001
|
console.log(\` Bundled \${jsFiles.length} JS modules, \${cssFiles.length} CSS files\`);
|
|
2775
3002
|
`), console.log("✅ Created build.js");
|
|
2776
|
-
const
|
|
3003
|
+
const P = `<!DOCTYPE html>
|
|
2777
3004
|
<html lang="en">
|
|
2778
3005
|
<head>
|
|
2779
3006
|
<meta charset="UTF-8">
|
|
2780
3007
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
2781
|
-
<title>${
|
|
3008
|
+
<title>${i}</title>
|
|
2782
3009
|
<link rel="stylesheet" href="./src/styles/index.css">
|
|
2783
3010
|
</head>
|
|
2784
3011
|
<body>
|
|
2785
3012
|
<div id="app">
|
|
2786
|
-
<h1>${
|
|
3013
|
+
<h1>${i}</h1>
|
|
2787
3014
|
<p>Your Myop component is ready!</p>
|
|
2788
3015
|
</div>
|
|
2789
3016
|
<script type="module" src="./src/index.js"><\/script>
|
|
2790
3017
|
</body>
|
|
2791
3018
|
</html>
|
|
2792
3019
|
`;
|
|
2793
|
-
|
|
2794
|
-
const
|
|
3020
|
+
e.writeFileSync("index.html", P), console.log("✅ Created index.html");
|
|
3021
|
+
const g = `// ${i} - Entry Point
|
|
2795
3022
|
import { init } from './modules/app.js';
|
|
2796
3023
|
import { setupMyopInterface } from './modules/myop.js';
|
|
2797
3024
|
|
|
@@ -2800,16 +3027,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2800
3027
|
setupMyopInterface();
|
|
2801
3028
|
});
|
|
2802
3029
|
`;
|
|
2803
|
-
|
|
2804
|
-
const
|
|
3030
|
+
e.writeFileSync("src/index.js", g), console.log("✅ Created src/index.js");
|
|
3031
|
+
const M = `// ${i} - Main Application Logic
|
|
2805
3032
|
|
|
2806
3033
|
export function init() {
|
|
2807
|
-
console.log('${
|
|
3034
|
+
console.log('${i} loaded');
|
|
2808
3035
|
|
|
2809
3036
|
// Your component logic here
|
|
2810
3037
|
}
|
|
2811
3038
|
`;
|
|
2812
|
-
|
|
3039
|
+
e.writeFileSync("src/modules/app.js", M), console.log("✅ Created src/modules/app.js"), e.writeFileSync("src/modules/myop.js", `// Myop Interface - Communication with host app
|
|
2813
3040
|
|
|
2814
3041
|
export function setupMyopInterface() {
|
|
2815
3042
|
// Called when host app sends data to this component
|
|
@@ -2825,12 +3052,12 @@ export function setupMyopInterface() {
|
|
|
2825
3052
|
};
|
|
2826
3053
|
}
|
|
2827
3054
|
`), console.log("✅ Created src/modules/myop.js");
|
|
2828
|
-
const
|
|
3055
|
+
const w = `/* ${i} - Styles Entry Point */
|
|
2829
3056
|
/* Add your CSS imports here - they will be auto-bundled */
|
|
2830
3057
|
@import './main.css';
|
|
2831
3058
|
`;
|
|
2832
|
-
|
|
2833
|
-
const
|
|
3059
|
+
e.writeFileSync("src/styles/index.css", w), console.log("✅ Created src/styles/index.css");
|
|
3060
|
+
const _ = `/* ${i} - Main Styles */
|
|
2834
3061
|
|
|
2835
3062
|
* {
|
|
2836
3063
|
box-sizing: border-box;
|
|
@@ -2859,18 +3086,18 @@ p {
|
|
|
2859
3086
|
line-height: 1.5;
|
|
2860
3087
|
}
|
|
2861
3088
|
`;
|
|
2862
|
-
|
|
3089
|
+
e.writeFileSync("src/styles/main.css", _), console.log("✅ Created src/styles/main.css"), e.writeFileSync(".gitignore", `node_modules/
|
|
2863
3090
|
dist/
|
|
2864
3091
|
.temp-entry.js
|
|
2865
3092
|
.temp-styles.css
|
|
2866
3093
|
.DS_Store
|
|
2867
3094
|
`), console.log("✅ Created .gitignore");
|
|
2868
|
-
const b =
|
|
3095
|
+
const b = Ve(process.cwd());
|
|
2869
3096
|
b && console.log("✅ Installed AI agent skills");
|
|
2870
|
-
const
|
|
3097
|
+
const p = await import("./index-DuEoKctW.js").then((x) => x.i), E = process.cwd();
|
|
2871
3098
|
try {
|
|
2872
|
-
await
|
|
2873
|
-
const
|
|
3099
|
+
await p.init({ fs: e, dir: E });
|
|
3100
|
+
const x = [
|
|
2874
3101
|
"myop.config.json",
|
|
2875
3102
|
"package.json",
|
|
2876
3103
|
"build.js",
|
|
@@ -2883,76 +3110,76 @@ dist/
|
|
|
2883
3110
|
"src/styles/main.css"
|
|
2884
3111
|
];
|
|
2885
3112
|
if (b) {
|
|
2886
|
-
const
|
|
3113
|
+
const T = (k, H) => {
|
|
2887
3114
|
try {
|
|
2888
|
-
const
|
|
2889
|
-
for (const
|
|
2890
|
-
const
|
|
2891
|
-
|
|
3115
|
+
const A = e.readdirSync(k, { withFileTypes: !0 });
|
|
3116
|
+
for (const j of A) {
|
|
3117
|
+
const J = n.join(k, j.name), F = n.join(H, j.name);
|
|
3118
|
+
j.isDirectory() ? T(J, F) : x.push(F);
|
|
2892
3119
|
}
|
|
2893
3120
|
} catch {
|
|
2894
3121
|
}
|
|
2895
3122
|
};
|
|
2896
|
-
|
|
3123
|
+
T(".agents/skills", ".agents/skills");
|
|
2897
3124
|
}
|
|
2898
|
-
for (const
|
|
2899
|
-
await
|
|
2900
|
-
await
|
|
2901
|
-
fs:
|
|
2902
|
-
dir:
|
|
3125
|
+
for (const T of x)
|
|
3126
|
+
await p.add({ fs: e, dir: E, filepath: T });
|
|
3127
|
+
await p.commit({
|
|
3128
|
+
fs: e,
|
|
3129
|
+
dir: E,
|
|
2903
3130
|
message: "init",
|
|
2904
3131
|
author: { name: "myop-cli", email: "cli@myop.dev" }
|
|
2905
3132
|
}), console.log("✅ Initialized git repository");
|
|
2906
|
-
} catch (
|
|
2907
|
-
console.log("⚠️ Failed to initialize git repository:",
|
|
3133
|
+
} catch (x) {
|
|
3134
|
+
console.log("⚠️ Failed to initialize git repository:", x.message);
|
|
2908
3135
|
}
|
|
2909
3136
|
console.log(`
|
|
2910
3137
|
📦 Next steps:`), console.log(" 1. npm install"), console.log(" 2. npm run build"), console.log(` 3. myop sync
|
|
2911
|
-
`),
|
|
3138
|
+
`), v.myopConfig = u, await ie(!0);
|
|
2912
3139
|
} catch (d) {
|
|
2913
3140
|
console.error(`Failed to initialize component: ${d.message}`), process.exit(1);
|
|
2914
3141
|
}
|
|
2915
3142
|
};
|
|
2916
|
-
|
|
2917
|
-
if (
|
|
2918
|
-
await
|
|
3143
|
+
v.program.command("default", { isDefault: !0 }).action(async () => {
|
|
3144
|
+
if (v.program.getOptionValue("help") && (console.log(Mt), process.exit()), v.program.getOptionValue("monorepo")) {
|
|
3145
|
+
await go();
|
|
2919
3146
|
return;
|
|
2920
3147
|
}
|
|
2921
|
-
if (
|
|
2922
|
-
const
|
|
2923
|
-
let
|
|
3148
|
+
if (v.program.getOptionValue("ci")) {
|
|
3149
|
+
const u = await import("fs"), y = v.program.getOptionValue("config") || "./myop.config.json", d = v.program.version(), l = $e();
|
|
3150
|
+
let P = { found: !1 };
|
|
2924
3151
|
try {
|
|
2925
|
-
if (
|
|
2926
|
-
const
|
|
2927
|
-
|
|
3152
|
+
if (u.existsSync(y)) {
|
|
3153
|
+
const M = u.readFileSync(y, "utf-8"), f = JSON.parse(M);
|
|
3154
|
+
P = {
|
|
2928
3155
|
found: !0,
|
|
2929
|
-
path:
|
|
2930
|
-
name:
|
|
2931
|
-
componentId:
|
|
2932
|
-
organization:
|
|
3156
|
+
path: y,
|
|
3157
|
+
name: f.name || f.componentName || null,
|
|
3158
|
+
componentId: f.componentId || null,
|
|
3159
|
+
organization: f.organization || null
|
|
2933
3160
|
};
|
|
2934
3161
|
}
|
|
2935
|
-
} catch (
|
|
2936
|
-
|
|
3162
|
+
} catch (M) {
|
|
3163
|
+
P = { found: !1, error: M.message };
|
|
2937
3164
|
}
|
|
2938
|
-
const
|
|
3165
|
+
const g = {
|
|
2939
3166
|
version: d,
|
|
2940
|
-
config:
|
|
3167
|
+
config: P,
|
|
2941
3168
|
auth: {
|
|
2942
|
-
loggedIn: !!(
|
|
2943
|
-
email: (
|
|
3169
|
+
loggedIn: !!(l != null && l.email),
|
|
3170
|
+
email: (l == null ? void 0 : l.email) || null
|
|
2944
3171
|
}
|
|
2945
3172
|
};
|
|
2946
|
-
console.log(JSON.stringify(
|
|
3173
|
+
console.log(JSON.stringify(g, null, 2)), process.exit(0);
|
|
2947
3174
|
}
|
|
2948
|
-
let n =
|
|
3175
|
+
let n = Y({
|
|
2949
3176
|
text: "Loading Myop CLI...",
|
|
2950
3177
|
color: "green"
|
|
2951
3178
|
}).start();
|
|
2952
|
-
const
|
|
2953
|
-
await
|
|
2954
|
-
const
|
|
2955
|
-
await
|
|
3179
|
+
const s = Ce();
|
|
3180
|
+
await ao(500), n.stop();
|
|
3181
|
+
const i = v.program.version();
|
|
3182
|
+
await oo(i) || await ie(s.configFound);
|
|
2956
3183
|
});
|
|
2957
|
-
|
|
2958
|
-
|
|
3184
|
+
v.program.parse(process.argv);
|
|
3185
|
+
v.program.opts();
|