@myop/cli 0.1.45 → 0.1.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/myop-cli.js +1461 -1207
- package/dist/skills/myop-angular-host/SKILL.md +437 -0
- package/dist/skills/myop-cli/SKILL.md +147 -0
- package/dist/skills/myop-component/SKILL.md +112 -42
- package/dist/skills/myop-component/references/dev-workflow.md +74 -8
- package/dist/skills/myop-react-host/SKILL.md +407 -0
- package/dist/skills/myop-react-host/references/auto-generated-packages.md +70 -0
- package/dist/skills/myop-react-native-host/SKILL.md +438 -0
- package/dist/skills/myop-vue-host/SKILL.md +374 -0
- package/package.json +1 -1
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 wt = Object.defineProperty;
|
|
3
|
+
var St = (o, t, e) => t in o ? wt(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
|
|
4
|
+
var ye = (o, t, e) => St(o, typeof t != "symbol" ? t + "" : t, e);
|
|
5
|
+
import Y from "ora";
|
|
6
|
+
import { select as et, Separator as _e } from "@inquirer/prompts";
|
|
7
|
+
import { Command as vt, Option as me } from "commander";
|
|
8
|
+
import { execSync as X, spawn as xt } from "child_process";
|
|
9
|
+
import _, { join as Te } from "path";
|
|
10
|
+
import M, { readFileSync as $t } from "fs";
|
|
11
|
+
import He from "crypto";
|
|
12
|
+
import bt from "http";
|
|
13
|
+
import { URL as tt, URLSearchParams as ot } from "url";
|
|
14
|
+
import Ct from "open";
|
|
15
|
+
import nt from "os";
|
|
16
|
+
const Pt = `
|
|
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
|
+
}, st = {
|
|
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 = _.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
|
+
}, Mt = (o) => {
|
|
71
|
+
const t = _.join(v.executionPath, o);
|
|
72
|
+
console.info(`reading config file from: ${t}`);
|
|
73
|
+
const e = M.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
|
+
}, Ue = (o, t) => {
|
|
76
|
+
const e = _.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
|
+
M.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
|
+
}, it = {
|
|
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), Ue(v.options.configPath, v.myopConfig);
|
|
91
91
|
},
|
|
92
92
|
action: async () => {
|
|
93
93
|
}
|
|
94
|
-
},
|
|
94
|
+
}, rt = {
|
|
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), Ue(v.options.configPath, v.myopConfig);
|
|
100
100
|
},
|
|
101
101
|
action: () => {
|
|
102
102
|
}
|
|
103
|
-
},
|
|
103
|
+
}, Et = {
|
|
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
|
+
}, It = {
|
|
111
111
|
name: "🟢 Create new component",
|
|
112
112
|
value: "-",
|
|
113
113
|
disabled: "(not available yet)"
|
|
114
|
-
},
|
|
114
|
+
}, kt = {
|
|
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
|
+
}, Rt = {
|
|
123
123
|
name: "🔴 Create new flow",
|
|
124
124
|
value: "-",
|
|
125
125
|
disabled: "(not available yet)"
|
|
126
|
-
},
|
|
126
|
+
}, Tt = {
|
|
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
|
+
}, jt = [Tt, It, kt, Ot, Rt];
|
|
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,69 +219,69 @@ ${n}
|
|
|
219
219
|
</body>
|
|
220
220
|
</html>`;
|
|
221
221
|
}
|
|
222
|
-
function
|
|
222
|
+
function _t(o) {
|
|
223
223
|
return o.includes("esbuild") && o.includes("another platform");
|
|
224
224
|
}
|
|
225
|
-
function
|
|
225
|
+
function Nt(o) {
|
|
226
226
|
return o.includes("ERR_MODULE_NOT_FOUND") && o.includes("esbuild");
|
|
227
227
|
}
|
|
228
|
-
function
|
|
228
|
+
function At() {
|
|
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 Lt(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, d, h) => {
|
|
248
|
+
if (i) {
|
|
249
|
+
console.error("❌ npm install failed:", i.message), h && console.error(h), 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 at(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: d = !1,
|
|
262
|
+
onRetry: h
|
|
263
|
+
} = s, y = ((o == null ? void 0 : o.message) || "") + (t || "") + (e || "");
|
|
264
|
+
return !i && _t(y) ? (At(), await Lt(n) && h ? (console.log(`🔄 Retrying build...
|
|
265
|
+
`), h(), { handled: !0, hasTriedPlatformFix: !0, hasTriedInstall: d }) : { handled: !0, hasTriedPlatformFix: !0, hasTriedInstall: d }) : !d && Nt(y) ? (console.log("📦 Missing dependencies detected, running npm install..."), new Promise((c) => {
|
|
266
|
+
n("npm install", (l, C, u) => {
|
|
267
|
+
if (l) {
|
|
268
|
+
console.error("❌ Failed to install dependencies:", l.message), u && console.error(u), c({ handled: !0, hasTriedPlatformFix: i, hasTriedInstall: !0 });
|
|
269
269
|
return;
|
|
270
270
|
}
|
|
271
|
-
console.log("✅ Dependencies installed"),
|
|
271
|
+
console.log("✅ Dependencies installed"), h && h(), c({ handled: !0, hasTriedPlatformFix: i, hasTriedInstall: !0 });
|
|
272
272
|
});
|
|
273
|
-
})) : { handled: !1, hasTriedPlatformFix:
|
|
273
|
+
})) : { handled: !1, hasTriedPlatformFix: i, hasTriedInstall: d };
|
|
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
|
|
282
|
+
i = t.default.dirname(import.meta.url);
|
|
283
|
+
const d = t.default.join(i, "commands", "dev", "management-website"), h = o.default.readFileSync(t.default.join(d, "styles.css"), "utf-8"), y = o.default.readFileSync(t.default.join(d, "app.js"), "utf-8"), c = 9292, l = 9293;
|
|
284
|
+
let C = "./dist", u = !1, P = !1, g = !1, w = null;
|
|
285
285
|
const j = () => {
|
|
286
286
|
try {
|
|
287
287
|
const a = o.default.readdirSync(".").filter((r) => !r.endsWith(".html") || r.startsWith(".") ? !1 : o.default.statSync(r).isFile());
|
|
@@ -290,7 +290,7 @@ async function be() {
|
|
|
290
290
|
} catch {
|
|
291
291
|
}
|
|
292
292
|
return null;
|
|
293
|
-
},
|
|
293
|
+
}, k = () => {
|
|
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, (f) => {
|
|
304
304
|
});
|
|
305
|
-
},
|
|
306
|
-
let
|
|
307
|
-
|
|
308
|
-
const
|
|
305
|
+
}, p = /* @__PURE__ */ new Map(), E = v.program.getOptionValue("config") || "./myop.config.json";
|
|
306
|
+
let x, O, R = !1;
|
|
307
|
+
w = j();
|
|
308
|
+
const D = k();
|
|
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", O = r.componentName || r.name || null, R = r.HMR === !0, w && !D && (g = !0, R = !0, console.log(`📄 Single HTML file mode: ${w}`)), R && console.log("🔥 HMR enabled");
|
|
312
312
|
} catch (a) {
|
|
313
|
-
|
|
313
|
+
w && !D ? (g = !0, x = "DEV", O = t.default.basename(w, ".html"), R = !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 L = 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
|
+
}, T = 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(), ut = (a, r, m) => {
|
|
365
365
|
if (a.url.startsWith("/_hmr/")) {
|
|
366
|
-
const
|
|
366
|
+
const f = 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(f) || oe.set(f, /* @__PURE__ */ new Set()), oe.get(f).add(r), console.log(`🔌 HMR client connected: ${f}`), r.on("close", () => {
|
|
375
|
+
const I = oe.get(f);
|
|
376
|
+
I && (I.delete(r), I.size === 0 && oe.delete(f)), console.log(`🔌 HMR client disconnected: ${f}`);
|
|
377
377
|
}), r.on("error", () => {
|
|
378
|
-
const
|
|
379
|
-
|
|
378
|
+
const I = oe.get(f);
|
|
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", (f) => m += f), 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: f, distPath: S, componentName: $, htmlFile: I } = JSON.parse(m);
|
|
388
|
+
F.set(f, { path: S, name: $ || null, htmlFile: I || null });
|
|
389
|
+
const N = $ ? ` (${$})` : "";
|
|
390
|
+
console.log(`✅ Registered: ${f}${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 (f) {
|
|
408
|
+
r.writeHead(400), r.end(JSON.stringify({ error: f.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", (f) => m += f), a.on("end", () => {
|
|
414
414
|
try {
|
|
415
|
-
const { componentId:
|
|
416
|
-
|
|
417
|
-
const
|
|
418
|
-
id:
|
|
419
|
-
path:
|
|
420
|
-
name:
|
|
415
|
+
const { componentId: f } = JSON.parse(m);
|
|
416
|
+
F.delete(f), console.log(`❌ Unregistered: ${f}`), 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 (f) {
|
|
434
|
+
r.writeHead(400), r.end(JSON.stringify({ error: f.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", (f) => m += f), a.on("end", () => {
|
|
442
442
|
try {
|
|
443
|
-
const { componentId:
|
|
444
|
-
if (
|
|
445
|
-
console.log(`🔥 Notifying ${
|
|
446
|
-
const
|
|
447
|
-
|
|
443
|
+
const { componentId: f, html: S } = JSON.parse(m), $ = oe.get(f);
|
|
444
|
+
if ($ && $.size > 0) {
|
|
445
|
+
console.log(`🔥 Notifying ${$.size} HMR client(s) for: ${f}`);
|
|
446
|
+
const I = JSON.stringify({ type: "update", html: S }), N = Ye(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 (f) {
|
|
457
|
+
r.writeHead(400), r.end(JSON.stringify({ error: f.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:${c}`), f = m.pathname, S = f.split("/").filter((W) => W);
|
|
468
|
+
if (f.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 H = "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
|
+
H = re.origin, q = re.hostname || re.origin;
|
|
481
481
|
} catch {
|
|
482
|
-
|
|
482
|
+
H = 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
|
+
H = B.origin, q = B.hostname || B.origin;
|
|
488
488
|
} catch {
|
|
489
|
-
|
|
489
|
+
H = 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" ? (H = "localhost", q = "localhost (direct)") : (H = B, q = B.replace("::ffff:", ""));
|
|
494
494
|
}
|
|
495
|
-
const
|
|
495
|
+
const Oe = a.headers.referer || a.headers.referrer || H, 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: Oe,
|
|
501
|
+
origin: H,
|
|
502
|
+
originLabel: q
|
|
503
503
|
};
|
|
504
|
-
|
|
505
|
-
url:
|
|
506
|
-
label:
|
|
504
|
+
Q.has(H) || (Q.set(H, {
|
|
505
|
+
url: H,
|
|
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 Re =
|
|
521
|
-
Re.requestCount++,
|
|
520
|
+
const Re = Q.get(H);
|
|
521
|
+
Re.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", (H, q) => {
|
|
543
|
+
if (H) {
|
|
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 Oe = Me(q, W), he = `dev-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, Re = {
|
|
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: Oe
|
|
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
567
|
}), r.end(JSON.stringify(Re, 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((H) => H.text()).then((H) => {
|
|
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(H);
|
|
577
|
+
}).catch((H) => {
|
|
578
|
+
console.error(`❌ Proxy error: ${H.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 (f === "/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(c, l, h, 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" && R) {
|
|
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
|
+
}), Ge = () => new Promise((a, r) => {
|
|
652
|
+
const m = g ? t.default.resolve(T) : t.default.resolve(T, C), f = JSON.stringify({
|
|
653
|
+
componentId: x,
|
|
654
|
+
distPath: m,
|
|
655
|
+
componentName: O,
|
|
656
|
+
htmlFile: g ? 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(f)
|
|
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(f), $.end();
|
|
673
|
+
}), gt = () => new Promise((a, r) => {
|
|
674
|
+
const m = JSON.stringify({ componentId: x }), f = {
|
|
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(f, ($) => {
|
|
684
684
|
a();
|
|
685
685
|
});
|
|
686
|
-
|
|
687
|
-
}),
|
|
686
|
+
S.on("error", () => a()), S.write(m), S.end();
|
|
687
|
+
}), ft = (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 (!R) return a;
|
|
794
|
+
const m = ft(r);
|
|
795
|
+
return a.includes("</body>") ? a.replace("</body>", `${m}</body>`) : a.includes("</html>") ? a.replace("</html>", `${m}</html>`) : a + m;
|
|
796
|
+
}, Ye = (a) => {
|
|
797
|
+
const r = Buffer.from(a), m = r.length;
|
|
798
|
+
let f;
|
|
799
|
+
return m < 126 ? f = Buffer.concat([
|
|
800
|
+
Buffer.from([129, m]),
|
|
801
801
|
// FIN + text frame, length
|
|
802
802
|
r
|
|
803
|
-
]) :
|
|
803
|
+
]) : m < 65536 ? f = 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
|
+
]) : f = 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
|
+
]), f;
|
|
816
|
+
}, Ke = () => {
|
|
817
|
+
if (!R) return;
|
|
818
|
+
const a = g ? w : t.default.join(C, "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 (ke) {
|
|
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 f = JSON.stringify({
|
|
833
833
|
type: "update",
|
|
834
834
|
html: r
|
|
835
|
-
}),
|
|
836
|
-
|
|
835
|
+
}), S = Ye(f);
|
|
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
|
+
}), f = {
|
|
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(f, ($) => {
|
|
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
875
|
if (u) {
|
|
876
|
-
|
|
876
|
+
P = !0;
|
|
877
877
|
return;
|
|
878
878
|
}
|
|
879
879
|
u = !0, console.log(`
|
|
880
|
-
🔨 Building...`),
|
|
880
|
+
🔨 Building...`), e("npm run build", { maxBuffer: 10 * 1024 * 1024 }, async (r, m, f) => {
|
|
881
881
|
if (u = !1, r) {
|
|
882
|
-
const
|
|
883
|
-
...
|
|
882
|
+
const S = await at(r, m, f, e, {
|
|
883
|
+
...Ee,
|
|
884
884
|
onRetry: () => ge(a)
|
|
885
885
|
});
|
|
886
|
-
|
|
886
|
+
Ee = { ...Ee, ...S }, S.handled || (console.error("❌ Build failed:", r.message), f && console.error(f));
|
|
887
887
|
} else
|
|
888
|
-
console.log("✅ Build completed"),
|
|
889
|
-
|
|
888
|
+
console.log("✅ Build completed"), m && console.log(m), Ke(), a && a();
|
|
889
|
+
P && (P = !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
|
+
}, Qe = /* @__PURE__ */ new Set(), Ie = (a) => {
|
|
892
|
+
o.default.readdir(a, { withFileTypes: !0 }, (r, m) => {
|
|
893
|
+
r || (m.forEach((f) => {
|
|
894
|
+
const S = t.default.join(a, f.name);
|
|
895
|
+
if (f.isDirectory())
|
|
896
|
+
f.name !== "node_modules" && f.name !== "dist" && !f.name.startsWith(".") && Ie(S);
|
|
897
|
+
else if (f.isFile()) {
|
|
898
|
+
const $ = t.default.extname(f.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
|
+
}), Qe.has(a) || (Qe.add(a), o.default.watch(a, (f, 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}`), g ? Ke() : ge());
|
|
915
915
|
} catch {
|
|
916
916
|
}
|
|
917
917
|
}, 50);
|
|
918
918
|
})));
|
|
919
919
|
});
|
|
920
|
-
},
|
|
920
|
+
}, Ze = (a) => {
|
|
921
921
|
console.log(`
|
|
922
|
-
🔨 Component: ${
|
|
923
|
-
`), a && a()) : (ge(a),
|
|
922
|
+
🔨 Component: ${x}`), g ? (console.log("📄 No build needed (single HTML file mode)"), Ie(T), console.log(`👀 Watching ${w} for changes...`), console.log(`Press Ctrl+C to stop
|
|
923
|
+
`), a && a()) : (ge(a), Ie(T), console.log("👀 Watching .js, .css, and .html files for changes..."), console.log(`Press Ctrl+C to stop
|
|
924
924
|
`));
|
|
925
|
-
},
|
|
925
|
+
}, ht = () => 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, (f) => {
|
|
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
|
+
}), yt = () => new Promise((a) => {
|
|
939
|
+
const r = n.default.createServer((m, f) => {
|
|
940
|
+
if (f.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 : ""}`), f.writeHead(200), f.end(JSON.stringify({ success: !0, registered: Array.from(F.keys()) }));
|
|
948
|
+
} catch ($) {
|
|
949
|
+
f.writeHead(400), f.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: ${$}`), f.writeHead(200), f.end(JSON.stringify({ success: !0 }));
|
|
958
|
+
} catch ($) {
|
|
959
|
+
f.writeHead(400), f.end(JSON.stringify({ error: $.message }));
|
|
960
960
|
}
|
|
961
961
|
});
|
|
962
|
-
} else
|
|
962
|
+
} else m.method === "GET" && m.url === "/_list" ? (f.writeHead(200), f.end(JSON.stringify({ components: Array.from(F.entries()) }))) : (f.writeHead(404), f.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
|
-
}), ue.listen(
|
|
971
|
-
console.log(`📡 Main server running at http://localhost:${
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
path:
|
|
975
|
-
name:
|
|
976
|
-
htmlFile:
|
|
970
|
+
}), ue.listen(c, () => {
|
|
971
|
+
console.log(`📡 Main server running at http://localhost:${c}`);
|
|
972
|
+
const m = g ? t.default.resolve(T) : t.default.resolve(T, C);
|
|
973
|
+
F.set(x, {
|
|
974
|
+
path: m,
|
|
975
|
+
name: O,
|
|
976
|
+
htmlFile: g ? w : null
|
|
977
977
|
});
|
|
978
|
-
const
|
|
979
|
-
console.log(`✅ Registered component: ${
|
|
978
|
+
const f = O ? ` (${O})` : "";
|
|
979
|
+
console.log(`✅ Registered component: ${x}${f}`), console.log(`📡 Access at: http://localhost:${c}/view/${x}/`), a(!0);
|
|
980
980
|
});
|
|
981
981
|
});
|
|
982
982
|
});
|
|
983
983
|
let fe;
|
|
984
|
-
const
|
|
984
|
+
const qe = () => {
|
|
985
985
|
fe = setInterval(async () => {
|
|
986
|
-
await
|
|
987
|
-
⚠️ Server appears to be down, attempting to take over...`), await
|
|
986
|
+
await ht() || (clearInterval(fe), console.log(`
|
|
987
|
+
⚠️ Server appears to be down, attempting to take over...`), await yt() ? (console.log("✅ Successfully took over as server"), ke = !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 Ge(), console.log(`✅ Re-registered component: ${x}`), qe();
|
|
990
|
+
} catch (m) {
|
|
991
|
+
console.error("❌ Failed to re-register:", m.message);
|
|
992
992
|
}
|
|
993
993
|
}, 2e3)));
|
|
994
994
|
}, 3e3);
|
|
995
|
-
},
|
|
995
|
+
}, Xe = async () => {
|
|
996
996
|
console.log(`
|
|
997
997
|
|
|
998
|
-
🛑 Shutting down...`), fe && clearInterval(fe), await
|
|
998
|
+
🛑 Shutting down...`), fe && clearInterval(fe), await gt(), process.exit(0);
|
|
999
999
|
};
|
|
1000
|
-
process.on("SIGINT",
|
|
1001
|
-
let
|
|
1002
|
-
|
|
1000
|
+
process.on("SIGINT", Xe), process.on("SIGTERM", Xe);
|
|
1001
|
+
let ke = !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:${
|
|
1011
|
-
}),
|
|
1007
|
+
x = await L();
|
|
1008
|
+
const r = await Ge();
|
|
1009
|
+
console.log(`✅ Registered component: ${x}`), console.log(`📡 Access at: http://localhost:${c}/view/${x}/`), console.log(`📋 All registered components: ${r.registered.join(", ")}`), Ze(() => {
|
|
1010
|
+
process.env.MYOP_NO_BROWSER || b(`http://localhost:${c}/view/${x}/`);
|
|
1011
|
+
}), qe();
|
|
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", ut), Pe.listen(l, async () => {
|
|
1018
|
+
ke = !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
|
-
}), ue.listen(
|
|
1022
|
-
console.log(`📡 Main server running at http://localhost:${
|
|
1023
|
-
const a =
|
|
1024
|
-
|
|
1021
|
+
}), ue.listen(c, async () => {
|
|
1022
|
+
console.log(`📡 Main server running at http://localhost:${c}`), (x === "DEV" || x === "NEW") && (x = "DEV1");
|
|
1023
|
+
const a = g ? t.default.resolve(T) : t.default.resolve(T, C);
|
|
1024
|
+
F.set(x, {
|
|
1025
1025
|
path: a,
|
|
1026
|
-
name:
|
|
1027
|
-
htmlFile:
|
|
1026
|
+
name: O,
|
|
1027
|
+
htmlFile: g ? w : null
|
|
1028
1028
|
});
|
|
1029
|
-
const r =
|
|
1030
|
-
console.log(`✅ Registered component: ${
|
|
1031
|
-
process.env.MYOP_NO_BROWSER || b(`http://localhost:${
|
|
1029
|
+
const r = O ? ` (${O})` : "";
|
|
1030
|
+
console.log(`✅ Registered component: ${x}${r}`), console.log(`📡 Access at: http://localhost:${c}/view/${x}/`), Ze(() => {
|
|
1031
|
+
process.env.MYOP_NO_BROWSER || b(`http://localhost:${c}/view/${x}/`);
|
|
1032
1032
|
});
|
|
1033
1033
|
});
|
|
1034
1034
|
});
|
|
1035
1035
|
}
|
|
1036
|
-
const
|
|
1037
|
-
constructor(
|
|
1038
|
-
this.components =
|
|
1039
|
-
(
|
|
1036
|
+
const A = class A {
|
|
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(A.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,
|
|
1088
|
-
for (let
|
|
1089
|
-
const
|
|
1090
|
-
this.panelPositions.set(
|
|
1091
|
-
row:
|
|
1092
|
-
col:
|
|
1093
|
-
width:
|
|
1094
|
-
height:
|
|
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), d = 2, y = this.rows - d - 2, c = Math.floor(y / s);
|
|
1087
|
+
this.visibleLogLines = Math.max(2, c - 4), this.layout = { panelsPerRow: n, panelWidth: i, numRows: s, panelHeight: c }, this.panelPositions.clear();
|
|
1088
|
+
for (let l = 0; l < t; l++) {
|
|
1089
|
+
const C = this.components[l], u = Math.floor(l / n), P = l % n;
|
|
1090
|
+
this.panelPositions.set(C.name, {
|
|
1091
|
+
row: d + 1 + u * c,
|
|
1092
|
+
col: P * i + 1,
|
|
1093
|
+
width: i,
|
|
1094
|
+
height: c
|
|
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), d = Math.max(0, Math.min(i, s + e));
|
|
1114
|
+
d !== s && (this.scrollPos.set(t, d), 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 + j.length +
|
|
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 = A.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 += A.ESC.clearLine.slice(0, -1), process.stdout.write(A.ESC.moveTo(2, 1) + s);
|
|
1138
|
+
}
|
|
1139
|
+
renderPanel(t) {
|
|
1140
|
+
const e = A.C, n = A.STATUS, s = this.panelPositions.get(t);
|
|
1141
|
+
if (!s) return;
|
|
1142
|
+
const i = this.components.findIndex((L) => L.name === t), d = this.components[i], h = i === this.selectedPanel, y = this.statusKeys.get(t) || "initializing", c = n[y], l = e[c.color], C = this.logs.get(t) || [], u = this.scrollPos.get(t) || 0, P = s.width - 1, g = h ? e.cyan : e.gray, w = [], j = d.name.substring(0, P - 20);
|
|
1143
|
+
let k = `${g}┌─${e.reset} ${l}${c.icon}${e.reset} `;
|
|
1144
|
+
k += `${e.bold}${j}${e.reset} ${e.gray}─${e.reset} ${l}${c.label}${e.reset} `;
|
|
1145
|
+
const b = 5 + j.length + c.label.length + 3;
|
|
1146
|
+
k += `${g}${"─".repeat(Math.max(0, P - b))}┐${e.reset}`, w.push(A.ESC.moveTo(s.row, s.col) + k);
|
|
1147
|
+
const p = (d.path || "").substring(0, P - 6);
|
|
1148
|
+
let E = `${g}│${e.reset} ${e.dim}${p}${e.reset}`;
|
|
1149
|
+
E += " ".repeat(Math.max(0, P - p.length - 3)), E += `${g}│${e.reset}`, w.push(A.ESC.moveTo(s.row + 1, s.col) + E);
|
|
1150
|
+
const x = C.length, O = x > this.visibleLogLines ? `${u + 1}-${Math.min(u + this.visibleLogLines, x)}/${x}` : "";
|
|
1151
|
+
let R = `${g}├${"─".repeat(P - O.length - 4)}${e.reset}`;
|
|
1152
|
+
O && (R += `${e.dim}${O}${e.reset}`), R += `${g}${"─".repeat(2)}┤${e.reset}`, w.push(A.ESC.moveTo(s.row + 2, s.col) + R);
|
|
1153
|
+
const D = C.slice(u, u + this.visibleLogLines);
|
|
1154
|
+
for (let L = 0; L < this.visibleLogLines; L++) {
|
|
1155
|
+
const T = D[L];
|
|
1156
|
+
let J = `${g}│${e.reset}`;
|
|
1157
|
+
if (T) {
|
|
1158
|
+
let F = e.white;
|
|
1159
|
+
T.type === "success" ? F = e.green : T.type === "error" ? F = e.red : T.type === "warning" ? F = e.yellow : T.type === "hmr" ? F = e.magenta : T.type === "change" && (F = e.blue);
|
|
1160
|
+
const V = T.message.substring(0, P - 12);
|
|
1161
|
+
J += `${e.dim}${T.timestamp}${e.reset} ${F}${V}${e.reset}`;
|
|
1162
|
+
const te = P - T.timestamp.length - V.length - 2;
|
|
1163
|
+
J += " ".repeat(Math.max(0, te));
|
|
1164
1164
|
} else
|
|
1165
|
-
|
|
1166
|
-
|
|
1165
|
+
J += " ".repeat(P - 2);
|
|
1166
|
+
J += `${g}│${e.reset}`, w.push(A.ESC.moveTo(s.row + 3 + L, s.col) + J);
|
|
1167
1167
|
}
|
|
1168
|
-
|
|
1168
|
+
w.push(A.ESC.moveTo(s.row + 3 + this.visibleLogLines, s.col) + `${g}└${"─".repeat(P - 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 = A.C;
|
|
1172
|
+
process.stdout.write(A.ESC.clearScreen + A.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 = A.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(A.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(A.ESC.clearScreen + A.ESC.moveTo(1, 1) + A.ESC.showCursor);
|
|
1189
1189
|
}
|
|
1190
1190
|
};
|
|
1191
1191
|
// ANSI escape codes
|
|
1192
|
-
ye(
|
|
1193
|
-
moveTo: (
|
|
1192
|
+
ye(A, "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(A, "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(A, "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
|
|
1227
|
+
let Ne = A;
|
|
1228
|
+
async function Dt(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), d = [], h = (l) => {
|
|
1234
|
+
const C = process.platform;
|
|
1235
1235
|
let u;
|
|
1236
|
-
|
|
1236
|
+
C === "darwin" ? u = `open "${l}"` : C === "win32" ? u = `start "" "${l}"` : u = `xdg-open "${l}"`, e(u, () => {
|
|
1237
1237
|
});
|
|
1238
|
-
},
|
|
1239
|
-
|
|
1240
|
-
🛑 Shutting down all components...`),
|
|
1238
|
+
}, y = () => {
|
|
1239
|
+
i.clear(), console.log(`
|
|
1240
|
+
🛑 Shutting down all components...`), d.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",
|
|
1248
|
-
const
|
|
1249
|
-
for (let
|
|
1250
|
-
const
|
|
1251
|
-
|
|
1252
|
-
const
|
|
1253
|
-
cwd: n.default.resolve(
|
|
1247
|
+
process.on("SIGINT", y), process.on("SIGTERM", y);
|
|
1248
|
+
const c = process.argv[1];
|
|
1249
|
+
for (let l = 0; l < o.length; l++) {
|
|
1250
|
+
const C = o[l], u = C.name;
|
|
1251
|
+
i.setStatus(u, "⏳ Starting..."), i.log(u, `Starting in ${C.path}`);
|
|
1252
|
+
const P = t("node", [c, "dev"], {
|
|
1253
|
+
cwd: n.default.resolve(C.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 j =
|
|
1257
|
+
d.push(P);
|
|
1258
|
+
let g = "";
|
|
1259
|
+
P.stdout.on("data", (w) => {
|
|
1260
|
+
g += w.toString();
|
|
1261
|
+
const j = g.split(`
|
|
1262
1262
|
`);
|
|
1263
|
-
|
|
1264
|
-
for (const
|
|
1265
|
-
const b =
|
|
1266
|
-
b && (b.includes("Registered component") || b.includes("Registered:") ?
|
|
1263
|
+
g = j.pop() || "";
|
|
1264
|
+
for (const k of j) {
|
|
1265
|
+
const b = k.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "").trim();
|
|
1266
|
+
b && (b.includes("Registered component") || b.includes("Registered:") ? i.setStatus(u, "✅ Ready") : b.includes("Building...") || b.includes("Running initial build") ? i.setStatus(u, "🔨 Building...") : b.includes("Build completed") || b.includes("Build succeeded") ? i.setStatus(u, "✅ Ready") : b.includes("Build failed") ? i.setStatus(u, "❌ Build Error") : b.includes("File changed") ? (i.setStatus(u, "📝 Changed"), setTimeout(() => i.setStatus(u, "✅ Ready"), 1500)) : b.includes("Notifying") && b.includes("HMR") ? (i.setStatus(u, "🔥 HMR Update"), setTimeout(() => i.setStatus(u, "✅ Ready"), 1e3)) : b.includes("HMR client connected") && (i.setStatus(u, "🔥 HMR Connected"), setTimeout(() => i.setStatus(u, "✅ 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(u, b));
|
|
1267
1267
|
}
|
|
1268
|
-
}),
|
|
1269
|
-
const j =
|
|
1268
|
+
}), P.stderr.on("data", (w) => {
|
|
1269
|
+
const j = w.toString().split(`
|
|
1270
1270
|
`);
|
|
1271
|
-
for (const
|
|
1272
|
-
const b =
|
|
1273
|
-
b && (
|
|
1271
|
+
for (const k of j) {
|
|
1272
|
+
const b = k.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "").trim();
|
|
1273
|
+
b && (i.log(u, `⚠️ ${b}`), i.setStatus(u, "⚠️ Warning"));
|
|
1274
1274
|
}
|
|
1275
|
-
}),
|
|
1276
|
-
|
|
1277
|
-
}),
|
|
1275
|
+
}), P.on("exit", (w) => {
|
|
1276
|
+
w !== 0 && w !== null && (i.setStatus(u, `❌ Exited (${w})`), i.log(u, `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
|
+
h("http://localhost:9292");
|
|
1281
1281
|
}, 2e3);
|
|
1282
1282
|
}
|
|
1283
|
-
const
|
|
1283
|
+
const Ht = /* @__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: Dt
|
|
1287
|
+
}, Symbol.toStringTag, { value: "Module" })), Ae = _.join(nt.homedir(), ".myop"), pe = _.join(Ae, "credentials.json");
|
|
1288
|
+
function Ut() {
|
|
1289
|
+
M.existsSync(Ae) || M.mkdirSync(Ae, { recursive: !0, mode: 448 });
|
|
1290
1290
|
}
|
|
1291
|
-
function
|
|
1291
|
+
function Be() {
|
|
1292
1292
|
try {
|
|
1293
|
-
if (!
|
|
1293
|
+
if (!M.existsSync(pe))
|
|
1294
1294
|
return null;
|
|
1295
|
-
const o =
|
|
1295
|
+
const o = M.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 lt(o) {
|
|
1302
|
+
Ut();
|
|
1303
|
+
const t = {
|
|
1304
1304
|
...o,
|
|
1305
1305
|
savedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1306
1306
|
};
|
|
1307
|
-
|
|
1307
|
+
M.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 ct() {
|
|
1313
1313
|
try {
|
|
1314
|
-
return
|
|
1314
|
+
return M.existsSync(pe) && M.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 Bt(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 = Be();
|
|
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, Je = `http://localhost:${Se}/callback`, Jt = "myop-cli";
|
|
1333
|
+
function zt() {
|
|
1334
|
+
return He.randomBytes(32).toString("base64url");
|
|
1335
1335
|
}
|
|
1336
|
-
function
|
|
1337
|
-
return
|
|
1336
|
+
function Wt(o) {
|
|
1337
|
+
return He.createHash("sha256").update(o).digest("base64url");
|
|
1338
1338
|
}
|
|
1339
|
-
async function
|
|
1339
|
+
async function Vt() {
|
|
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: Jt,
|
|
1345
|
+
redirect_uris: [Je],
|
|
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: d, glow: h } = 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: ${d};
|
|
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: ${h};
|
|
1468
|
+
border: 1px solid ${d}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
|
|
1528
|
-
if (
|
|
1529
|
-
|
|
1522
|
+
function Gt(o) {
|
|
1523
|
+
return new Promise((t, e) => {
|
|
1524
|
+
const n = bt.createServer((s, i) => {
|
|
1525
|
+
const d = new tt(s.url, `http://localhost:${Se}`);
|
|
1526
|
+
if (d.pathname === "/callback") {
|
|
1527
|
+
const h = d.searchParams.get("code"), y = d.searchParams.get("state"), c = d.searchParams.get("error");
|
|
1528
|
+
if (c) {
|
|
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
|
-
|
|
1534
|
-
)), n.close(),
|
|
1533
|
+
c
|
|
1534
|
+
)), n.close(), e(new Error(`OAuth error: ${c}`));
|
|
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 (!h) {
|
|
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(h);
|
|
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 Yt(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 ot({
|
|
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: Je,
|
|
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 Kt(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 ot({
|
|
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 Qt(o) {
|
|
1605
|
+
var s, i, d;
|
|
1606
|
+
const t = await fetch(`${ae}/mcp`, {
|
|
1607
1607
|
method: "POST",
|
|
1608
1608
|
headers: {
|
|
1609
1609
|
"Content-Type": "application/json",
|
|
@@ -1619,184 +1619,184 @@ 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 = (d = (i = (s = e.result) == null ? void 0 : s.content) == null ? void 0 : i[0]) == null ? void 0 : d.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 Vt()).client_id, n = zt(), s = Wt(n), i = He.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 d = Gt(i), h = new tt(`${ae}/oauth/authorize`);
|
|
1639
|
+
h.searchParams.set("response_type", "code"), h.searchParams.set("client_id", e), h.searchParams.set("redirect_uri", Je), h.searchParams.set("code_challenge", s), h.searchParams.set("code_challenge_method", "S256"), h.searchParams.set("state", i), o.stop(), console.log(`
|
|
1640
|
+
🌐 Opening browser for authentication...`), console.log("If the browser does not open, visit:"), console.log(` ${h.toString()}
|
|
1641
|
+
`), await Ct(h.toString());
|
|
1642
|
+
const y = await d;
|
|
1643
1643
|
o.start("Exchanging authorization code...");
|
|
1644
|
-
const
|
|
1644
|
+
const c = await Yt(y, e, n);
|
|
1645
1645
|
o.text = "Getting user info...";
|
|
1646
|
-
const
|
|
1647
|
-
accessToken:
|
|
1648
|
-
refreshToken:
|
|
1649
|
-
expiresAt: new Date(Date.now() +
|
|
1650
|
-
clientId:
|
|
1651
|
-
userId:
|
|
1652
|
-
userEmail:
|
|
1646
|
+
const l = await Qt(c.access_token), C = {
|
|
1647
|
+
accessToken: c.access_token,
|
|
1648
|
+
refreshToken: c.refresh_token,
|
|
1649
|
+
expiresAt: new Date(Date.now() + c.expires_in * 1e3).toISOString(),
|
|
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 lt(C), o.succeed(`Authenticated as ${l.email}`), C;
|
|
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 dt() {
|
|
1660
|
+
const o = Be();
|
|
1661
1661
|
if (!o) {
|
|
1662
1662
|
console.log("Not currently logged in.");
|
|
1663
1663
|
return;
|
|
1664
1664
|
}
|
|
1665
|
-
|
|
1665
|
+
ct(), console.log(`✅ Logged out (was: ${o.userEmail})`);
|
|
1666
1666
|
}
|
|
1667
|
-
async function
|
|
1668
|
-
let o =
|
|
1667
|
+
async function ze() {
|
|
1668
|
+
let o = Be();
|
|
1669
1669
|
if (!o)
|
|
1670
1670
|
return console.log(`Not logged in. Starting authentication...
|
|
1671
1671
|
`), await de();
|
|
1672
|
-
if (!
|
|
1672
|
+
if (!Bt(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 Kt(
|
|
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
|
+
}, lt(o), t.succeed("Token refreshed"), o;
|
|
1687
1687
|
} catch {
|
|
1688
|
-
return
|
|
1688
|
+
return t.warn("Token refresh failed, please log in again"), ct(), 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
|
|
1698
|
-
function
|
|
1697
|
+
const ee = "@myop/cli", je = process.platform === "win32";
|
|
1698
|
+
function Zt() {
|
|
1699
1699
|
try {
|
|
1700
|
-
return
|
|
1700
|
+
return X("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 qt() {
|
|
1706
1706
|
try {
|
|
1707
|
-
return
|
|
1707
|
+
return X("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 Xt() {
|
|
1713
1713
|
try {
|
|
1714
|
-
const o =
|
|
1715
|
-
return
|
|
1714
|
+
const o = Zt().replace(/\/$/, ""), t = await fetch(`${o}/${ee}/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 eo(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, d = n[s] || 0;
|
|
1724
|
+
if (i > d) return 1;
|
|
1725
|
+
if (i < d) return -1;
|
|
1726
1726
|
}
|
|
1727
1727
|
return 0;
|
|
1728
1728
|
}
|
|
1729
|
-
async function
|
|
1730
|
-
const
|
|
1729
|
+
async function to(o) {
|
|
1730
|
+
const t = Y({
|
|
1731
1731
|
text: "Checking for updates...",
|
|
1732
1732
|
color: "cyan"
|
|
1733
|
-
}).start(),
|
|
1734
|
-
if (
|
|
1733
|
+
}).start(), e = await Xt();
|
|
1734
|
+
if (t.stop(), !e || eo(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 et({
|
|
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 ${
|
|
1755
|
+
const s = Y({
|
|
1756
|
+
text: `Updating ${ee} to v${e}...`,
|
|
1757
1757
|
color: "green"
|
|
1758
|
-
}).start(),
|
|
1758
|
+
}).start(), i = `npm install -g ${ee}@latest`, d = qt();
|
|
1759
1759
|
try {
|
|
1760
|
-
|
|
1760
|
+
X(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 ${d ? `install -g ${ee}@latest --prefix \\"${d}\\"` : `install -g ${ee}@latest`}' -Verb RunAs -Wait`;
|
|
1768
|
+
X(`powershell -Command "${l}"`, { stdio: "inherit" });
|
|
1769
1769
|
} else {
|
|
1770
|
-
const
|
|
1771
|
-
|
|
1770
|
+
const c = d ? `sudo npm install -g ${ee}@latest --prefix "${d}"` : `sudo ${i}`;
|
|
1771
|
+
X(c, { 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 ${ee}@latest (run as Administrator)` : `sudo npm install -g ${ee}@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 h = null;
|
|
1785
1785
|
try {
|
|
1786
|
-
let
|
|
1787
|
-
|
|
1788
|
-
const
|
|
1789
|
-
|
|
1786
|
+
let y;
|
|
1787
|
+
d ? y = je ? Te(d, "node_modules") : Te(d, "lib", "node_modules") : y = X("npm root -g", { encoding: "utf-8" }).trim();
|
|
1788
|
+
const c = Te(y, ee, "package.json"), l = $t(c, "utf-8");
|
|
1789
|
+
h = JSON.parse(l).version;
|
|
1790
1790
|
} catch {
|
|
1791
1791
|
}
|
|
1792
|
-
if (
|
|
1792
|
+
if (h === e)
|
|
1793
1793
|
return console.log(`
|
|
1794
1794
|
🔄 Restarting...
|
|
1795
|
-
`),
|
|
1795
|
+
`), xt(process.argv[0], process.argv.slice(1), {
|
|
1796
1796
|
stdio: "inherit",
|
|
1797
1797
|
shell: !0
|
|
1798
|
-
}).on("close", (
|
|
1799
|
-
process.exit(
|
|
1798
|
+
}).on("close", (c) => {
|
|
1799
|
+
process.exit(c || 0);
|
|
1800
1800
|
}), !0;
|
|
1801
1801
|
console.log(`
|
|
1802
1802
|
Please run myop again to use the new version.
|
|
@@ -1804,69 +1804,112 @@ Please run myop again to use the new version.
|
|
|
1804
1804
|
}
|
|
1805
1805
|
return !1;
|
|
1806
1806
|
}
|
|
1807
|
-
const
|
|
1807
|
+
const Le = _.join(nt.homedir(), ".myop"), De = _.join(Le, "preferences.json");
|
|
1808
|
+
function oo() {
|
|
1809
|
+
M.existsSync(Le) || M.mkdirSync(Le, { recursive: !0, mode: 448 });
|
|
1810
|
+
}
|
|
1811
|
+
function pt() {
|
|
1812
|
+
try {
|
|
1813
|
+
if (!M.existsSync(De))
|
|
1814
|
+
return {};
|
|
1815
|
+
const o = M.readFileSync(De, "utf8");
|
|
1816
|
+
return JSON.parse(o);
|
|
1817
|
+
} catch {
|
|
1818
|
+
return {};
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
function no(o) {
|
|
1822
|
+
oo();
|
|
1823
|
+
const e = { ...pt(), ...o };
|
|
1824
|
+
M.writeFileSync(De, JSON.stringify(e, null, 2), {
|
|
1825
|
+
mode: 384
|
|
1826
|
+
});
|
|
1827
|
+
}
|
|
1828
|
+
function so() {
|
|
1829
|
+
return pt().defaultOrganization || null;
|
|
1830
|
+
}
|
|
1831
|
+
function Fe({ id: o, name: t }) {
|
|
1832
|
+
no({ defaultOrganization: { id: o, name: t } });
|
|
1833
|
+
}
|
|
1834
|
+
async function io(o, t, e, n = {}) {
|
|
1835
|
+
var h, y, c;
|
|
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 d = (c = (y = (h = i.result) == null ? void 0 : h.content) == null ? void 0 : y[0]) == null ? void 0 : c.text;
|
|
1858
|
+
if (!d)
|
|
1859
|
+
throw new Error(`No content returned from ${e}`);
|
|
1860
|
+
return JSON.parse(d);
|
|
1861
|
+
}
|
|
1862
|
+
const ro = (o) => new Promise((t) => setTimeout(t, o)), ao = () => {
|
|
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
|
-
I.mkdirSync(e, { recursive: !0 });
|
|
1814
|
-
const t = I.readdirSync(o, { withFileTypes: !0 });
|
|
1815
|
-
for (const n of t) {
|
|
1816
|
-
const i = D.join(o, n.name), s = D.join(e, n.name);
|
|
1817
|
-
n.isDirectory() ? _e(i, s) : I.copyFileSync(i, s);
|
|
1818
|
-
}
|
|
1819
|
-
}, rt = (o) => {
|
|
1820
|
-
const e = qt();
|
|
1821
|
-
if (!I.existsSync(e))
|
|
1822
|
-
return console.info("Skills source directory not found, skipping skills installation"), !1;
|
|
1865
|
+
const t = _.dirname(o);
|
|
1866
|
+
return _.join(t, "skills");
|
|
1867
|
+
}, lo = (o) => {
|
|
1823
1868
|
try {
|
|
1824
|
-
const t =
|
|
1825
|
-
|
|
1826
|
-
const
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
for (const w of i) {
|
|
1831
|
-
const S = D.join(l, w), d = D.join("..", "..", ".agents", "skills", w);
|
|
1832
|
-
try {
|
|
1833
|
-
I.rmSync(S, { recursive: !0, force: !0 });
|
|
1834
|
-
} catch {
|
|
1835
|
-
}
|
|
1836
|
-
try {
|
|
1837
|
-
I.symlinkSync(d, S, "dir");
|
|
1838
|
-
} catch {
|
|
1839
|
-
_e(
|
|
1840
|
-
D.join(t, w),
|
|
1841
|
-
S
|
|
1842
|
-
);
|
|
1843
|
-
}
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
1846
|
-
return !0;
|
|
1847
|
-
} catch (t) {
|
|
1848
|
-
return console.info("Failed to install skills:", t.message), !1;
|
|
1869
|
+
const t = _.join(o, "package.json");
|
|
1870
|
+
if (!M.existsSync(t)) return [];
|
|
1871
|
+
const e = JSON.parse(M.readFileSync(t, "utf-8"));
|
|
1872
|
+
return Object.keys({ ...e.dependencies, ...e.devDependencies });
|
|
1873
|
+
} catch {
|
|
1874
|
+
return [];
|
|
1849
1875
|
}
|
|
1850
|
-
},
|
|
1876
|
+
}, We = async (o) => {
|
|
1877
|
+
const t = ao();
|
|
1878
|
+
if (!M.existsSync(t))
|
|
1879
|
+
return console.info("Skills source directory not found, skipping skills installation"), { success: !1 };
|
|
1880
|
+
try {
|
|
1881
|
+
const e = lo(o), n = ["myop-cli", "myop-component"], s = [
|
|
1882
|
+
{ deps: ["@myop/react", "react"], skill: "myop-react-host" },
|
|
1883
|
+
{ deps: ["@myop/vue", "vue"], skill: "myop-vue-host" },
|
|
1884
|
+
{ deps: ["@myop/angular", "@angular/core"], skill: "myop-angular-host" },
|
|
1885
|
+
{ deps: ["@myop/react-native", "react-native"], skill: "myop-react-native-host" }
|
|
1886
|
+
], i = s.filter(({ deps: c }) => c.some((l) => e.includes(l))).map(({ skill: c }) => c), d = s.flatMap(({ deps: c }) => c.filter((l) => e.includes(l)));
|
|
1887
|
+
i.length > 0 ? n.push(...i) : n.push(...s.map((c) => c.skill));
|
|
1888
|
+
const h = n.map((c) => `--skill ${c}`).join(" "), y = `npx -y skills add "${t}" ${h} --agent '*' --copy -y`;
|
|
1889
|
+
return X(y, { cwd: o, stdio: "pipe" }), { success: !0, detected: d, skillNames: n };
|
|
1890
|
+
} catch (e) {
|
|
1891
|
+
return console.info("Failed to install skills:", e.message), { success: !1 };
|
|
1892
|
+
}
|
|
1893
|
+
}, Ve = (o = ".", t = 3, e = 0) => {
|
|
1851
1894
|
const n = [];
|
|
1852
|
-
if (
|
|
1895
|
+
if (e > t) return n;
|
|
1853
1896
|
try {
|
|
1854
|
-
const
|
|
1855
|
-
for (const
|
|
1856
|
-
const
|
|
1857
|
-
if (
|
|
1858
|
-
if (
|
|
1897
|
+
const s = M.readdirSync(o, { withFileTypes: !0 });
|
|
1898
|
+
for (const i of s) {
|
|
1899
|
+
const d = _.join(o, i.name);
|
|
1900
|
+
if (i.isDirectory()) {
|
|
1901
|
+
if (i.name === "node_modules" || i.name === ".git" || i.name === "dist" || i.name.startsWith("."))
|
|
1859
1902
|
continue;
|
|
1860
|
-
n.push(...
|
|
1861
|
-
} else if (
|
|
1903
|
+
n.push(...Ve(d, t, e + 1));
|
|
1904
|
+
} else if (i.name === "myop.config.json")
|
|
1862
1905
|
try {
|
|
1863
|
-
const
|
|
1906
|
+
const h = M.readFileSync(d, "utf-8"), y = JSON.parse(h);
|
|
1864
1907
|
n.push({
|
|
1865
1908
|
path: o,
|
|
1866
|
-
configPath:
|
|
1867
|
-
name:
|
|
1868
|
-
componentId:
|
|
1869
|
-
config:
|
|
1909
|
+
configPath: d,
|
|
1910
|
+
name: y.name || y.componentName || _.basename(o),
|
|
1911
|
+
componentId: y.componentId || null,
|
|
1912
|
+
config: y
|
|
1870
1913
|
});
|
|
1871
1914
|
} catch {
|
|
1872
1915
|
}
|
|
@@ -1875,55 +1918,55 @@ const Xt = (o) => new Promise((e) => setTimeout(e, o)), qt = () => {
|
|
|
1875
1918
|
}
|
|
1876
1919
|
return n;
|
|
1877
1920
|
};
|
|
1878
|
-
|
|
1879
|
-
const
|
|
1880
|
-
const
|
|
1881
|
-
|
|
1882
|
-
}), console.info("📝 verbose mode on"),
|
|
1883
|
-
configPath:
|
|
1884
|
-
verbose:
|
|
1921
|
+
v.executionPath = process.cwd();
|
|
1922
|
+
const Ce = (o = !1) => {
|
|
1923
|
+
const t = v.program.getOptionValue("verbose");
|
|
1924
|
+
t || (console.info = () => {
|
|
1925
|
+
}), console.info("📝 verbose mode on"), v.options = {
|
|
1926
|
+
configPath: v.program.getOptionValue("config"),
|
|
1927
|
+
verbose: t
|
|
1885
1928
|
};
|
|
1886
1929
|
try {
|
|
1887
|
-
return
|
|
1888
|
-
} catch (
|
|
1930
|
+
return v.myopConfig = Mt(v.options.configPath), { configFound: !0 };
|
|
1931
|
+
} catch (e) {
|
|
1889
1932
|
if (o) {
|
|
1890
1933
|
console.info(`
|
|
1891
|
-
⚠️ failed read config file from ${
|
|
1934
|
+
⚠️ failed read config file from ${v.options.configPath}, trying to create new one`);
|
|
1892
1935
|
try {
|
|
1893
1936
|
const n = {
|
|
1894
1937
|
author: "@myop-cli",
|
|
1895
1938
|
flows: []
|
|
1896
1939
|
};
|
|
1897
|
-
return
|
|
1940
|
+
return Ue(v.options.configPath, n), v.myopConfig = n, { configFound: !0 };
|
|
1898
1941
|
} catch {
|
|
1899
|
-
return console.info("Error details :",
|
|
1942
|
+
return console.info("Error details :", e), { configFound: !1, error: e };
|
|
1900
1943
|
}
|
|
1901
1944
|
} else
|
|
1902
|
-
return console.info("Error details :",
|
|
1945
|
+
return console.info("Error details :", e), { configFound: !1, error: e };
|
|
1903
1946
|
}
|
|
1904
1947
|
};
|
|
1905
1948
|
[
|
|
1906
|
-
new
|
|
1907
|
-
...
|
|
1949
|
+
new _e(),
|
|
1950
|
+
...jt
|
|
1908
1951
|
];
|
|
1909
|
-
const
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1952
|
+
const co = "0.1.47";
|
|
1953
|
+
v.program = new vt();
|
|
1954
|
+
v.program.name("@myop/cli").description("Myop CLI - Remote UI Made Easy").version(co);
|
|
1955
|
+
v.program.addOption(new me("-c, --config <value>", "myop.config.json file location").default("./myop.config.json", "./myop.config.json"));
|
|
1956
|
+
v.program.addOption(new me("-h, --help", "Show helpful information"));
|
|
1957
|
+
v.program.addOption(new me("-v, --verbose", "Enables verbose output mode for the command-line interface (CLI)."));
|
|
1958
|
+
v.program.addOption(new me("--ci", "CI mode: print status info (version, config, auth) as JSON and exit without prompts"));
|
|
1959
|
+
v.program.addOption(new me("-m, --monorepo", "Monorepo mode: scan for all myop.config.json files in nested directories"));
|
|
1960
|
+
v.program.command("add").description("Install Myop assets").addArgument("type").addArgument("id").action((o, t) => {
|
|
1961
|
+
Ce(!0), console.info("adding ", o, t, v.options.configPath), o === "flow" && it._action(t), process.exit();
|
|
1919
1962
|
});
|
|
1920
|
-
|
|
1921
|
-
|
|
1963
|
+
v.program.command("remove").description("Remove Myop asset").argument("<type>", "Myop asset type").argument("<id>", "Asset id").action((o, t) => {
|
|
1964
|
+
Ce(), console.info("removing ", o, t, v.options.configPath), o === "flow" && rt._action(t), process.exit();
|
|
1922
1965
|
});
|
|
1923
|
-
|
|
1924
|
-
|
|
1966
|
+
v.program.command("install").description("Install Myop assets").action(async () => {
|
|
1967
|
+
Ce(), await st.action();
|
|
1925
1968
|
});
|
|
1926
|
-
|
|
1969
|
+
v.program.command("login").description("Authenticate with Myop platform").action(async () => {
|
|
1927
1970
|
try {
|
|
1928
1971
|
await de();
|
|
1929
1972
|
} catch (o) {
|
|
@@ -1931,218 +1974,102 @@ h.program.command("login").description("Authenticate with Myop platform").action
|
|
|
1931
1974
|
}
|
|
1932
1975
|
process.exit(0);
|
|
1933
1976
|
});
|
|
1934
|
-
|
|
1935
|
-
await
|
|
1977
|
+
v.program.command("logout").description("Clear stored credentials").action(async () => {
|
|
1978
|
+
await dt(), process.exit(0);
|
|
1936
1979
|
});
|
|
1937
|
-
|
|
1938
|
-
const o =
|
|
1980
|
+
v.program.command("whoami").description("Show current authenticated user").action(async () => {
|
|
1981
|
+
const o = $e();
|
|
1939
1982
|
o && o.email ? console.log(`Logged in as: ${o.email}`) : console.log("Not logged in. Run `myop login` to authenticate."), process.exit(0);
|
|
1940
1983
|
});
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1984
|
+
v.program.command("sync").description('[deprecated] Use "myop push" instead').option("--skip-build", "Skip the build step").action(async () => {
|
|
1985
|
+
console.log(`
|
|
1986
|
+
⚠️ "myop sync" is deprecated. Use "myop push" instead.
|
|
1987
|
+
`);
|
|
1988
|
+
const { execSync: o } = await import("child_process");
|
|
1989
|
+
try {
|
|
1990
|
+
o("node " + process.argv[1] + " push", { stdio: "inherit" });
|
|
1991
|
+
} catch {
|
|
1992
|
+
}
|
|
1993
|
+
process.exit(0);
|
|
1994
|
+
});
|
|
1995
|
+
v.program.command("push").description("Upload component to Myop platform").argument("[componentId]", "Component ID to push to (overrides myop.config.json)").action(async (o) => {
|
|
1996
|
+
var P, g, w, j, k, b;
|
|
1997
|
+
const t = v.program.getOptionValue("config") || "./myop.config.json";
|
|
1998
|
+
let e = {};
|
|
1999
|
+
if (M.existsSync(t))
|
|
1946
2000
|
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);
|
|
2001
|
+
e = JSON.parse(M.readFileSync(t, "utf-8"));
|
|
2002
|
+
} catch (p) {
|
|
2003
|
+
console.error(`⚠️ Failed to parse ${t}:`, p.message);
|
|
1953
2004
|
}
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
2005
|
+
o && (e.componentId = o);
|
|
2006
|
+
const n = e.name || e.componentName || _.basename(process.cwd());
|
|
2007
|
+
console.log(`
|
|
2008
|
+
📋 Component: ${n}`);
|
|
2009
|
+
let s = null, i = !1;
|
|
1957
2010
|
try {
|
|
1958
|
-
const
|
|
1959
|
-
|
|
2011
|
+
const p = JSON.parse(M.readFileSync("package.json", "utf-8"));
|
|
2012
|
+
i = !!(p.scripts && p.scripts.build);
|
|
1960
2013
|
} catch {
|
|
1961
2014
|
}
|
|
1962
|
-
if (!
|
|
1963
|
-
const
|
|
1964
|
-
(
|
|
2015
|
+
if (!i) {
|
|
2016
|
+
const p = M.readdirSync(".").filter(
|
|
2017
|
+
(E) => E.endsWith(".html") && !E.startsWith(".") && M.statSync(E).isFile()
|
|
1965
2018
|
);
|
|
1966
|
-
|
|
1967
|
-
}
|
|
1968
|
-
if (
|
|
1969
|
-
console.log(
|
|
1970
|
-
else if (
|
|
1971
|
-
const { exec:
|
|
1972
|
-
let
|
|
1973
|
-
const
|
|
1974
|
-
const
|
|
1975
|
-
|
|
1976
|
-
if (!
|
|
1977
|
-
|
|
2019
|
+
p.length === 1 && (s = p[0]);
|
|
2020
|
+
}
|
|
2021
|
+
if (s)
|
|
2022
|
+
console.log(` Single file: ${s} (skipping build)`);
|
|
2023
|
+
else if (i) {
|
|
2024
|
+
const { exec: p } = await import("child_process");
|
|
2025
|
+
let E = { hasTriedPlatformFix: !1, hasTriedInstall: !1 };
|
|
2026
|
+
const x = (R = !1) => new Promise((D) => {
|
|
2027
|
+
const L = Y(R ? "Retrying build..." : "Building project...").start();
|
|
2028
|
+
p("npm run build", { maxBuffer: 10 * 1024 * 1024 }, async (T, J, F) => {
|
|
2029
|
+
if (!T) {
|
|
2030
|
+
L.succeed("Build completed"), D(!0);
|
|
1978
2031
|
return;
|
|
1979
2032
|
}
|
|
1980
|
-
if (
|
|
1981
|
-
const
|
|
1982
|
-
if (
|
|
1983
|
-
const
|
|
1984
|
-
|
|
2033
|
+
if (L.fail("Build failed"), !E.hasTriedPlatformFix && !E.hasTriedInstall) {
|
|
2034
|
+
const V = await at(T, J, F, p, E);
|
|
2035
|
+
if (E = { ...E, ...V }, V.handled) {
|
|
2036
|
+
const te = await x(!0);
|
|
2037
|
+
D(te);
|
|
1985
2038
|
return;
|
|
1986
2039
|
}
|
|
1987
2040
|
}
|
|
1988
|
-
console.error(
|
|
2041
|
+
console.error(T.message), D(!1);
|
|
1989
2042
|
});
|
|
1990
2043
|
});
|
|
1991
|
-
await
|
|
2044
|
+
await x() || process.exit(1);
|
|
1992
2045
|
}
|
|
1993
|
-
const S = l || "./dist/index.html";
|
|
1994
|
-
t.existsSync(S) || (console.error(`❌ Error: ${S} not found`), console.log(" Make sure your build outputs to ./dist/index.html"), process.exit(1));
|
|
1995
2046
|
let d;
|
|
1996
|
-
|
|
1997
|
-
d =
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
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);
|
|
2047
|
+
if (s)
|
|
2048
|
+
d = s;
|
|
2049
|
+
else if (M.existsSync("./dist/index.html"))
|
|
2050
|
+
d = "./dist/index.html";
|
|
2051
|
+
else {
|
|
2052
|
+
const p = M.readdirSync(".").filter(
|
|
2053
|
+
(E) => E.endsWith(".html") && !E.startsWith(".") && M.statSync(E).isFile()
|
|
2054
|
+
);
|
|
2055
|
+
p.length === 1 ? d = 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
2056
|
}
|
|
2066
|
-
|
|
2057
|
+
const h = M.readFileSync(d, "utf-8");
|
|
2058
|
+
console.log(` File: ${d} (${(h.length / 1024).toFixed(1)} KB)`);
|
|
2067
2059
|
let y;
|
|
2068
2060
|
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
|
-
}
|
|
2061
|
+
y = await ze();
|
|
2062
|
+
} catch (p) {
|
|
2063
|
+
console.error("❌ Authentication failed:", p.message), process.exit(1);
|
|
2108
2064
|
}
|
|
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;
|
|
2065
|
+
const c = be();
|
|
2066
|
+
let l = Y("Uploading...").start(), C;
|
|
2133
2067
|
try {
|
|
2134
|
-
|
|
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;
|
|
2140
|
-
try {
|
|
2141
|
-
const P = await fetch(`${w}/mcp`, {
|
|
2068
|
+
const p = await fetch(`${c}/mcp`, {
|
|
2142
2069
|
method: "POST",
|
|
2143
2070
|
headers: {
|
|
2144
2071
|
"Content-Type": "application/json",
|
|
2145
|
-
Authorization: `Bearer ${
|
|
2072
|
+
Authorization: `Bearer ${y.accessToken}`
|
|
2146
2073
|
},
|
|
2147
2074
|
body: JSON.stringify({
|
|
2148
2075
|
jsonrpc: "2.0",
|
|
@@ -2151,55 +2078,55 @@ h.program.command("push").description("Upload component to Myop platform").actio
|
|
|
2151
2078
|
params: {
|
|
2152
2079
|
name: "upload_component",
|
|
2153
2080
|
arguments: {
|
|
2154
|
-
name:
|
|
2081
|
+
name: n,
|
|
2155
2082
|
componentId: e.componentId && e.componentId !== "DEV" ? e.componentId : void 0,
|
|
2156
2083
|
organization: e.organization || void 0
|
|
2157
2084
|
}
|
|
2158
2085
|
}
|
|
2159
2086
|
})
|
|
2160
2087
|
});
|
|
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
|
-
|
|
2088
|
+
if (!p.ok)
|
|
2089
|
+
throw new Error(`Server returned ${p.status}`);
|
|
2090
|
+
const E = await p.json();
|
|
2091
|
+
if (E.error)
|
|
2092
|
+
throw new Error(E.error.message);
|
|
2093
|
+
const x = (w = (g = (P = E.result) == null ? void 0 : P.content) == null ? void 0 : g[0]) == null ? void 0 : w.text;
|
|
2094
|
+
if (C = JSON.parse(x), !C.success)
|
|
2095
|
+
throw new Error(C.error);
|
|
2096
|
+
} catch (p) {
|
|
2097
|
+
l.fail("Failed to get upload URL"), console.error(" ", p.message), process.exit(1);
|
|
2171
2098
|
}
|
|
2172
2099
|
try {
|
|
2173
|
-
let
|
|
2174
|
-
const
|
|
2175
|
-
if (
|
|
2176
|
-
|
|
2100
|
+
let p;
|
|
2101
|
+
const E = C.curlCommand.match(/(?:"|\\")([^"\\]+(?:\\.[^"\\]*)*)(?:"|\\")$/);
|
|
2102
|
+
if (E)
|
|
2103
|
+
p = E[1];
|
|
2177
2104
|
else {
|
|
2178
|
-
const
|
|
2179
|
-
if (
|
|
2180
|
-
|
|
2105
|
+
const O = C.curlCommand.match(/(https:\/\/[^\s"\\]+)/);
|
|
2106
|
+
if (O)
|
|
2107
|
+
p = O[1];
|
|
2181
2108
|
else
|
|
2182
2109
|
throw new Error("Could not parse presigned URL");
|
|
2183
2110
|
}
|
|
2184
|
-
const
|
|
2111
|
+
const x = await fetch(p, {
|
|
2185
2112
|
method: "PUT",
|
|
2186
2113
|
headers: { "Content-Type": "text/html" },
|
|
2187
|
-
body:
|
|
2114
|
+
body: h
|
|
2188
2115
|
});
|
|
2189
|
-
if (!
|
|
2190
|
-
const
|
|
2191
|
-
throw new Error(`Upload failed: ${
|
|
2116
|
+
if (!x.ok) {
|
|
2117
|
+
const O = await x.text();
|
|
2118
|
+
throw new Error(`Upload failed: ${x.status} ${O}`);
|
|
2192
2119
|
}
|
|
2193
|
-
} catch (
|
|
2194
|
-
|
|
2120
|
+
} catch (p) {
|
|
2121
|
+
l.fail("Upload failed"), console.error(" ", p.message), process.exit(1);
|
|
2195
2122
|
}
|
|
2196
|
-
let
|
|
2123
|
+
let u;
|
|
2197
2124
|
try {
|
|
2198
|
-
const
|
|
2125
|
+
const p = await fetch(`${c}/mcp`, {
|
|
2199
2126
|
method: "POST",
|
|
2200
2127
|
headers: {
|
|
2201
2128
|
"Content-Type": "application/json",
|
|
2202
|
-
Authorization: `Bearer ${
|
|
2129
|
+
Authorization: `Bearer ${y.accessToken}`
|
|
2203
2130
|
},
|
|
2204
2131
|
body: JSON.stringify({
|
|
2205
2132
|
jsonrpc: "2.0",
|
|
@@ -2208,63 +2135,63 @@ h.program.command("push").description("Upload component to Myop platform").actio
|
|
|
2208
2135
|
params: {
|
|
2209
2136
|
name: "confirm_upload",
|
|
2210
2137
|
arguments: {
|
|
2211
|
-
uploadId:
|
|
2138
|
+
uploadId: C.uploadId
|
|
2212
2139
|
}
|
|
2213
2140
|
}
|
|
2214
2141
|
})
|
|
2215
2142
|
});
|
|
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
|
-
|
|
2143
|
+
if (!p.ok)
|
|
2144
|
+
throw new Error(`Server returned ${p.status}`);
|
|
2145
|
+
const E = await p.json();
|
|
2146
|
+
if (E.error)
|
|
2147
|
+
throw new Error(E.error.message);
|
|
2148
|
+
const x = (b = (k = (j = E.result) == null ? void 0 : j.content) == null ? void 0 : k[0]) == null ? void 0 : b.text;
|
|
2149
|
+
if (u = JSON.parse(x), !u.success)
|
|
2150
|
+
throw new Error(u.error);
|
|
2151
|
+
l.succeed("Pushed successfully");
|
|
2152
|
+
} catch (p) {
|
|
2153
|
+
l.fail("Confirmation failed"), console.error(" ", p.message), process.exit(1);
|
|
2227
2154
|
}
|
|
2228
|
-
if (
|
|
2229
|
-
e.componentId =
|
|
2155
|
+
if (u.isNewComponent || !e.componentId || e.componentId === "DEV") {
|
|
2156
|
+
e.componentId = u.componentId, e.organization = u.orgId, e.name || (e.name = u.componentName);
|
|
2230
2157
|
try {
|
|
2231
|
-
|
|
2232
|
-
} catch (
|
|
2233
|
-
console.log(`⚠️ Could not update ${
|
|
2158
|
+
M.writeFileSync(t, JSON.stringify(e, null, 2));
|
|
2159
|
+
} catch (p) {
|
|
2160
|
+
console.log(`⚠️ Could not update ${t}: ${p.message}`), console.log(` Add componentId: "${u.componentId}" manually`);
|
|
2234
2161
|
}
|
|
2235
2162
|
}
|
|
2236
2163
|
console.log(`
|
|
2237
|
-
${
|
|
2164
|
+
${u.componentName}`), console.log(` ${u.dashboardUrl}
|
|
2238
2165
|
`), process.exit(0);
|
|
2239
2166
|
});
|
|
2240
|
-
|
|
2241
|
-
var
|
|
2242
|
-
const
|
|
2167
|
+
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) => {
|
|
2168
|
+
var w, j, k;
|
|
2169
|
+
const e = v.program.getOptionValue("config") || "./myop.config.json";
|
|
2243
2170
|
let n = {};
|
|
2244
|
-
if (
|
|
2171
|
+
if (M.existsSync(e))
|
|
2245
2172
|
try {
|
|
2246
|
-
n = JSON.parse(
|
|
2173
|
+
n = JSON.parse(M.readFileSync(e, "utf-8"));
|
|
2247
2174
|
} catch {
|
|
2248
2175
|
}
|
|
2249
|
-
const
|
|
2250
|
-
(!
|
|
2251
|
-
const
|
|
2176
|
+
const s = o || n.componentId;
|
|
2177
|
+
(!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));
|
|
2178
|
+
const i = n.name || n.componentName || s;
|
|
2252
2179
|
console.log(`
|
|
2253
|
-
📥 Pulling: ${
|
|
2254
|
-
let
|
|
2180
|
+
📥 Pulling: ${i}`), console.log(` ID: ${s}`);
|
|
2181
|
+
let d;
|
|
2255
2182
|
try {
|
|
2256
|
-
|
|
2183
|
+
d = await ze();
|
|
2257
2184
|
} catch (b) {
|
|
2258
2185
|
console.error("❌ Authentication failed:", b.message), process.exit(1);
|
|
2259
2186
|
}
|
|
2260
|
-
const
|
|
2261
|
-
let
|
|
2187
|
+
const h = be(), y = Y("Fetching component...").start();
|
|
2188
|
+
let c;
|
|
2262
2189
|
try {
|
|
2263
|
-
const b = await fetch(`${
|
|
2190
|
+
const b = await fetch(`${h}/mcp`, {
|
|
2264
2191
|
method: "POST",
|
|
2265
2192
|
headers: {
|
|
2266
2193
|
"Content-Type": "application/json",
|
|
2267
|
-
Authorization: `Bearer ${
|
|
2194
|
+
Authorization: `Bearer ${d.accessToken}`
|
|
2268
2195
|
},
|
|
2269
2196
|
body: JSON.stringify({
|
|
2270
2197
|
jsonrpc: "2.0",
|
|
@@ -2272,75 +2199,286 @@ h.program.command("pull").description("Download component HTML from Myop platfor
|
|
|
2272
2199
|
method: "tools/call",
|
|
2273
2200
|
params: {
|
|
2274
2201
|
name: "get_component",
|
|
2275
|
-
arguments: { componentId:
|
|
2202
|
+
arguments: { componentId: s }
|
|
2276
2203
|
}
|
|
2277
2204
|
})
|
|
2278
2205
|
});
|
|
2279
2206
|
if (!b.ok)
|
|
2280
2207
|
throw new Error(`Server returned ${b.status}`);
|
|
2281
|
-
const
|
|
2282
|
-
if (
|
|
2283
|
-
throw new Error(
|
|
2284
|
-
const
|
|
2285
|
-
if (
|
|
2286
|
-
throw new Error(
|
|
2287
|
-
|
|
2208
|
+
const p = await b.json();
|
|
2209
|
+
if (p.error)
|
|
2210
|
+
throw new Error(p.error.message);
|
|
2211
|
+
const E = (k = (j = (w = p.result) == null ? void 0 : w.content) == null ? void 0 : j[0]) == null ? void 0 : k.text;
|
|
2212
|
+
if (c = JSON.parse(E), !c.success && !c.html)
|
|
2213
|
+
throw new Error(c.error || "No HTML content returned");
|
|
2214
|
+
y.succeed("Component fetched");
|
|
2288
2215
|
} catch (b) {
|
|
2289
|
-
|
|
2290
|
-
}
|
|
2291
|
-
let
|
|
2292
|
-
|
|
2293
|
-
const
|
|
2294
|
-
u && !
|
|
2295
|
-
const
|
|
2296
|
-
let
|
|
2297
|
-
if (
|
|
2298
|
-
name:
|
|
2299
|
-
componentId:
|
|
2216
|
+
y.fail("Failed to fetch component"), console.error(" ", b.message), process.exit(1);
|
|
2217
|
+
}
|
|
2218
|
+
let l = t.output;
|
|
2219
|
+
l || (M.existsSync("./dist/index.html") ? l = "./dist/index.html" : l = "./index.html");
|
|
2220
|
+
const C = c.htmlContent || c.html, u = _.dirname(l);
|
|
2221
|
+
u && !M.existsSync(u) && M.mkdirSync(u, { recursive: !0 }), M.writeFileSync(l, C), console.log(` Saved to: ${l} (${(C.length / 1024).toFixed(1)} KB)`);
|
|
2222
|
+
const P = M.existsSync(e);
|
|
2223
|
+
let g = !1;
|
|
2224
|
+
if (P ? ((!n.componentId || n.componentId === "DEV") && (n.componentId = s, g = !0), !n.name && c.name && (n.name = c.name, g = !0)) : (n = {
|
|
2225
|
+
name: c.name || _.basename(process.cwd()),
|
|
2226
|
+
componentId: s,
|
|
2300
2227
|
type: "html",
|
|
2301
2228
|
author: "@myop-cli",
|
|
2302
2229
|
HMR: !0
|
|
2303
|
-
},
|
|
2230
|
+
}, g = !0), g)
|
|
2304
2231
|
try {
|
|
2305
|
-
|
|
2232
|
+
M.writeFileSync(e, JSON.stringify(n, null, 2)), console.log(` ${P ? "Updated" : "Created"} ${e}`);
|
|
2306
2233
|
} catch (b) {
|
|
2307
|
-
console.log(` ⚠️ Could not write ${
|
|
2234
|
+
console.log(` ⚠️ Could not write ${e}: ${b.message}`);
|
|
2308
2235
|
}
|
|
2309
2236
|
console.log(`
|
|
2310
2237
|
✅ Pull completed!
|
|
2311
2238
|
`), process.exit(0);
|
|
2312
2239
|
});
|
|
2313
|
-
|
|
2314
|
-
const {
|
|
2315
|
-
let
|
|
2240
|
+
v.program.command("list").description("Browse and pull/push remote components").option("--org <orgId>", "Organization ID to use").action(async (o) => {
|
|
2241
|
+
const { search: t, select: e } = await import("@inquirer/prompts");
|
|
2242
|
+
let n;
|
|
2316
2243
|
try {
|
|
2317
|
-
|
|
2244
|
+
n = await ze();
|
|
2245
|
+
} catch (g) {
|
|
2246
|
+
console.error("Authentication failed:", g.message), process.exit(1);
|
|
2247
|
+
}
|
|
2248
|
+
const s = be(), i = (g, w) => io(s, n.accessToken, g, w);
|
|
2249
|
+
let d = Y("Loading organizations...").start(), h;
|
|
2250
|
+
try {
|
|
2251
|
+
const g = await i("list_organizations");
|
|
2252
|
+
if (h = g.organizations || g, !Array.isArray(h))
|
|
2253
|
+
throw new Error("Unexpected response from list_organizations");
|
|
2254
|
+
} catch (g) {
|
|
2255
|
+
d.fail("Failed to load organizations"), console.error(" ", g.message), process.exit(1);
|
|
2256
|
+
}
|
|
2257
|
+
h.length === 0 && (d.fail("No organizations found for this account"), process.exit(1)), d.stop();
|
|
2258
|
+
let y, c;
|
|
2259
|
+
if (o.org) {
|
|
2260
|
+
const g = h.find((w) => w.id === o.org || w._id === o.org);
|
|
2261
|
+
g || (console.error(`Organization "${o.org}" not found. Available:`), h.forEach((w) => console.log(` ${w.id || w._id} ${w.name}`)), process.exit(1)), y = g.id || g._id, c = g.name, Fe({ id: y, name: c });
|
|
2262
|
+
} else {
|
|
2263
|
+
const g = so();
|
|
2264
|
+
if (g && h.find((w) => (w.id || w._id) === g.id))
|
|
2265
|
+
y = g.id, c = g.name;
|
|
2266
|
+
else if (h.length === 1)
|
|
2267
|
+
y = h[0].id || h[0]._id, c = h[0].name, Fe({ id: y, name: c });
|
|
2268
|
+
else
|
|
2269
|
+
try {
|
|
2270
|
+
const w = await e({
|
|
2271
|
+
message: "Select an organization:",
|
|
2272
|
+
choices: h.map((j) => ({
|
|
2273
|
+
name: j.name,
|
|
2274
|
+
value: { id: j.id || j._id, name: j.name }
|
|
2275
|
+
}))
|
|
2276
|
+
});
|
|
2277
|
+
y = w.id, c = w.name, Fe({ id: y, name: c });
|
|
2278
|
+
} catch (w) {
|
|
2279
|
+
throw w.name === "ExitPromptError" && (console.log(`
|
|
2280
|
+
|
|
2281
|
+
👋 Goodbye!
|
|
2282
|
+
`), process.exit(0)), w;
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
console.log(` Using organization: ${c}`), d = Y("Loading components...").start();
|
|
2286
|
+
let l;
|
|
2287
|
+
try {
|
|
2288
|
+
const g = await i("list_components", { organizationId: y });
|
|
2289
|
+
if (l = g.components || g, !Array.isArray(l))
|
|
2290
|
+
throw new Error("Unexpected response from list_components");
|
|
2291
|
+
} catch (g) {
|
|
2292
|
+
d.fail("Failed to load components"), console.error(" ", g.message), process.exit(1);
|
|
2293
|
+
}
|
|
2294
|
+
d.stop(), l.length === 0 && (console.log(` No components found in this organization.
|
|
2295
|
+
`), process.exit(0)), console.log(` ${c} - ${l.length} component(s)
|
|
2296
|
+
`);
|
|
2297
|
+
const C = [];
|
|
2298
|
+
for (; ; ) {
|
|
2299
|
+
const g = `[Done - pull/push ${C.length} selected]`, w = "__done__", j = new Set(C.map((p) => p.id || p._id || p.componentId));
|
|
2300
|
+
let k;
|
|
2301
|
+
try {
|
|
2302
|
+
k = await t({
|
|
2303
|
+
message: "Search & select components:",
|
|
2304
|
+
source: (p) => {
|
|
2305
|
+
const E = (p || "").toLowerCase(), x = l.filter((R) => {
|
|
2306
|
+
const D = R.id || R._id || R.componentId;
|
|
2307
|
+
return j.has(D) ? !1 : E ? (R.name || "").toLowerCase().includes(E) : !0;
|
|
2308
|
+
}), O = [
|
|
2309
|
+
{ name: g, value: w }
|
|
2310
|
+
];
|
|
2311
|
+
for (const R of x) {
|
|
2312
|
+
const D = R.id || R._id || R.componentId, L = D ? D.substring(0, 8) + "..." : "";
|
|
2313
|
+
O.push({
|
|
2314
|
+
name: `${R.name} (${L})`,
|
|
2315
|
+
value: D
|
|
2316
|
+
});
|
|
2317
|
+
}
|
|
2318
|
+
return O;
|
|
2319
|
+
}
|
|
2320
|
+
});
|
|
2321
|
+
} catch (p) {
|
|
2322
|
+
throw p.name === "ExitPromptError" && (console.log(`
|
|
2323
|
+
|
|
2324
|
+
👋 Goodbye!
|
|
2325
|
+
`), process.exit(0)), p;
|
|
2326
|
+
}
|
|
2327
|
+
if (k === w)
|
|
2328
|
+
break;
|
|
2329
|
+
const b = l.find((p) => (p.id || p._id || p.componentId) === k);
|
|
2330
|
+
b && (C.push(b), console.log(` + ${b.name}`));
|
|
2331
|
+
}
|
|
2332
|
+
C.length === 0 && (console.log(` No components selected.
|
|
2333
|
+
`), process.exit(0));
|
|
2334
|
+
let u;
|
|
2335
|
+
try {
|
|
2336
|
+
u = await e({
|
|
2337
|
+
message: `${C.length} component(s) selected:`,
|
|
2338
|
+
choices: [
|
|
2339
|
+
{ name: "Pull selected", value: "pull" },
|
|
2340
|
+
{ name: "Push selected", value: "push" },
|
|
2341
|
+
{ name: "Cancel", value: "cancel" }
|
|
2342
|
+
]
|
|
2343
|
+
});
|
|
2344
|
+
} catch (g) {
|
|
2345
|
+
throw g.name === "ExitPromptError" && (console.log(`
|
|
2346
|
+
|
|
2347
|
+
👋 Goodbye!
|
|
2348
|
+
`), process.exit(0)), g;
|
|
2349
|
+
}
|
|
2350
|
+
u === "cancel" && (console.log(` Cancelled.
|
|
2351
|
+
`), process.exit(0));
|
|
2352
|
+
const P = (g) => g.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
2353
|
+
if (u === "pull") {
|
|
2354
|
+
console.log(`
|
|
2355
|
+
Pulling ${C.length} components...
|
|
2356
|
+
`);
|
|
2357
|
+
const g = await Promise.all(C.map(async (k) => {
|
|
2358
|
+
const b = k.id || k._id || k.componentId;
|
|
2359
|
+
try {
|
|
2360
|
+
const p = await i("get_component", { componentId: b }), E = P(k.name);
|
|
2361
|
+
M.mkdirSync(E, { recursive: !0 });
|
|
2362
|
+
const x = p.htmlContent || p.html;
|
|
2363
|
+
if (!x)
|
|
2364
|
+
throw new Error("No HTML content returned");
|
|
2365
|
+
return M.writeFileSync(_.join(E, "index.html"), x), M.writeFileSync(_.join(E, "myop.config.json"), JSON.stringify({
|
|
2366
|
+
name: k.name,
|
|
2367
|
+
componentId: b,
|
|
2368
|
+
organization: y,
|
|
2369
|
+
type: "html",
|
|
2370
|
+
author: "@myop-cli",
|
|
2371
|
+
HMR: !0
|
|
2372
|
+
}, null, 2)), { name: k.name, status: "ok", dir: E };
|
|
2373
|
+
} catch (p) {
|
|
2374
|
+
return { name: k.name, status: "failed", error: p.message };
|
|
2375
|
+
}
|
|
2376
|
+
}));
|
|
2377
|
+
let w = 0, j = 0;
|
|
2378
|
+
for (const k of g)
|
|
2379
|
+
k.status === "ok" ? (console.log(` \x1B[32m✔\x1B[0m ${k.name} -> ./${k.dir}/`), w++) : (console.log(` \x1B[31m✖\x1B[0m ${k.name} - ${k.error}`), j++);
|
|
2380
|
+
console.log(`
|
|
2381
|
+
Done! Pulled ${w} component${w !== 1 ? "s" : ""}.${j ? ` ${j} failed.` : ""}
|
|
2382
|
+
`);
|
|
2383
|
+
} else if (u === "push") {
|
|
2384
|
+
console.log(`
|
|
2385
|
+
Pushing ${C.length} components...
|
|
2386
|
+
`);
|
|
2387
|
+
const g = Ve(".", 3), w = await Promise.all(C.map(async (p) => {
|
|
2388
|
+
const E = p.id || p._id || p.componentId, x = g.find((O) => O.componentId === E);
|
|
2389
|
+
if (!x)
|
|
2390
|
+
return { name: p.name, status: "skipped", reason: "no local match" };
|
|
2391
|
+
try {
|
|
2392
|
+
let O;
|
|
2393
|
+
const R = x.path;
|
|
2394
|
+
if (M.existsSync(_.join(R, "dist", "index.html")))
|
|
2395
|
+
O = _.join(R, "dist", "index.html");
|
|
2396
|
+
else {
|
|
2397
|
+
const z = M.readdirSync(R).filter(
|
|
2398
|
+
(Q) => Q.endsWith(".html") && !Q.startsWith(".") && M.statSync(_.join(R, Q)).isFile()
|
|
2399
|
+
);
|
|
2400
|
+
if (z.length === 1)
|
|
2401
|
+
O = _.join(R, z[0]);
|
|
2402
|
+
else if (z.includes("index.html"))
|
|
2403
|
+
O = _.join(R, "index.html");
|
|
2404
|
+
else
|
|
2405
|
+
throw new Error("No HTML file found");
|
|
2406
|
+
}
|
|
2407
|
+
const D = M.readFileSync(O, "utf-8"), L = x.name || p.name, T = await i("upload_component", {
|
|
2408
|
+
name: L,
|
|
2409
|
+
componentId: E,
|
|
2410
|
+
organization: y
|
|
2411
|
+
});
|
|
2412
|
+
if (!T.success)
|
|
2413
|
+
throw new Error(T.error || "Upload request failed");
|
|
2414
|
+
let J;
|
|
2415
|
+
const F = T.curlCommand.match(/(?:"|\\")([^"\\]+(?:\\.[^"\\]*)*)(?:"|\\")$/);
|
|
2416
|
+
if (F)
|
|
2417
|
+
J = F[1];
|
|
2418
|
+
else {
|
|
2419
|
+
const z = T.curlCommand.match(/(https:\/\/[^\s"\\]+)/);
|
|
2420
|
+
if (z)
|
|
2421
|
+
J = z[1];
|
|
2422
|
+
else
|
|
2423
|
+
throw new Error("Could not parse presigned URL");
|
|
2424
|
+
}
|
|
2425
|
+
const V = await fetch(J, {
|
|
2426
|
+
method: "PUT",
|
|
2427
|
+
headers: { "Content-Type": "text/html" },
|
|
2428
|
+
body: D
|
|
2429
|
+
});
|
|
2430
|
+
if (!V.ok)
|
|
2431
|
+
throw new Error(`Upload failed: ${V.status}`);
|
|
2432
|
+
const te = await i("confirm_upload", {
|
|
2433
|
+
uploadId: T.uploadId
|
|
2434
|
+
});
|
|
2435
|
+
if (!te.success)
|
|
2436
|
+
throw new Error(te.error || "Confirmation failed");
|
|
2437
|
+
return { name: L, status: "ok" };
|
|
2438
|
+
} catch (O) {
|
|
2439
|
+
return { name: p.name, status: "failed", error: O.message };
|
|
2440
|
+
}
|
|
2441
|
+
}));
|
|
2442
|
+
let j = 0, k = 0, b = 0;
|
|
2443
|
+
for (const p of w)
|
|
2444
|
+
p.status === "ok" ? (console.log(` \x1B[32m✔\x1B[0m ${p.name}`), j++) : p.status === "skipped" ? (console.log(` \x1B[33m⊘\x1B[0m ${p.name} (${p.reason})`), k++) : (console.log(` \x1B[31m✖\x1B[0m ${p.name} - ${p.error}`), b++);
|
|
2445
|
+
console.log(`
|
|
2446
|
+
Done! Pushed ${j}${k ? `, skipped ${k}` : ""}${b ? `, ${b} failed` : ""}.
|
|
2447
|
+
`);
|
|
2448
|
+
}
|
|
2449
|
+
process.exit(0);
|
|
2450
|
+
});
|
|
2451
|
+
v.program.command("create").description("Create a new Myop HTML component and start dev server").action(async () => {
|
|
2452
|
+
const { input: o } = await import("@inquirer/prompts"), t = await import("fs"), n = (await import("path")).default.basename(process.cwd());
|
|
2453
|
+
let s;
|
|
2454
|
+
try {
|
|
2455
|
+
s = await o({
|
|
2318
2456
|
message: "Component name:",
|
|
2319
2457
|
default: n
|
|
2320
2458
|
});
|
|
2321
|
-
} catch (
|
|
2322
|
-
throw
|
|
2459
|
+
} catch (y) {
|
|
2460
|
+
throw y.name === "ExitPromptError" && (console.log(`
|
|
2323
2461
|
|
|
2324
2462
|
👋 Goodbye!
|
|
2325
|
-
`), process.exit(0)),
|
|
2463
|
+
`), process.exit(0)), y;
|
|
2326
2464
|
}
|
|
2327
|
-
(
|
|
2465
|
+
(t.existsSync("index.html") || t.existsSync("myop.config.json")) && (console.log(`
|
|
2328
2466
|
⚠️ 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:
|
|
2467
|
+
const i = {
|
|
2468
|
+
name: s,
|
|
2331
2469
|
componentId: "DEV",
|
|
2332
2470
|
type: "html",
|
|
2333
2471
|
author: "@myop-cli",
|
|
2334
2472
|
HMR: !0
|
|
2335
2473
|
};
|
|
2336
|
-
|
|
2337
|
-
const
|
|
2474
|
+
t.writeFileSync("myop.config.json", JSON.stringify(i, null, 2));
|
|
2475
|
+
const d = `<!DOCTYPE html>
|
|
2338
2476
|
<html lang="en">
|
|
2339
2477
|
<head>
|
|
2340
2478
|
<meta charset="UTF-8">
|
|
2341
2479
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
2342
2480
|
<meta name="myop:size" content='{"width":"100%","height":"100%"}'>
|
|
2343
|
-
<title>${
|
|
2481
|
+
<title>${s}</title>
|
|
2344
2482
|
<script type="myop/types">
|
|
2345
2483
|
// =========================================================================
|
|
2346
2484
|
// MYOP COMPONENT TYPE DEFINITIONS
|
|
@@ -2421,7 +2559,7 @@ h.program.command("create").description("Create a new Myop HTML component and st
|
|
|
2421
2559
|
</head>
|
|
2422
2560
|
<body>
|
|
2423
2561
|
<div id="app-root">
|
|
2424
|
-
<h1>${
|
|
2562
|
+
<h1>${s}</h1>
|
|
2425
2563
|
<p>Edit index.html to get started</p>
|
|
2426
2564
|
</div>
|
|
2427
2565
|
|
|
@@ -2450,31 +2588,139 @@ h.program.command("create").description("Create a new Myop HTML component and st
|
|
|
2450
2588
|
|
|
2451
2589
|
<script id="myop_preview">
|
|
2452
2590
|
window.myop_init_interface({
|
|
2453
|
-
title: '${
|
|
2591
|
+
title: '${s}',
|
|
2454
2592
|
description: 'Edit index.html to get started'
|
|
2455
2593
|
});
|
|
2456
2594
|
<\/script>
|
|
2457
2595
|
</body>
|
|
2458
2596
|
</html>`;
|
|
2459
|
-
|
|
2460
|
-
const
|
|
2597
|
+
t.writeFileSync("index.html", d);
|
|
2598
|
+
const h = await We(process.cwd());
|
|
2461
2599
|
console.log(`
|
|
2462
|
-
✅ Created ${
|
|
2600
|
+
✅ Created ${s}`), console.log(" index.html"), console.log(" myop.config.json"), h.success && console.log(" AI agent skills installed"), console.log(""), await xe();
|
|
2601
|
+
});
|
|
2602
|
+
v.program.command("dev").description("Start development server with file watching").action(xe);
|
|
2603
|
+
const mt = async () => {
|
|
2604
|
+
const o = process.cwd(), t = Y("Installing AI agent skills...").start(), e = await We(o);
|
|
2605
|
+
e.success ? (t.succeed("AI agent skills installed"), e.detected.length > 0 && console.log(` Detected: ${e.detected.join(", ")}`), console.log(` Skills: ${e.skillNames.join(", ")}`)) : t.fail("Failed to install skills"), process.exit(e.success ? 0 : 1);
|
|
2606
|
+
};
|
|
2607
|
+
v.program.command("skill").description("Install or update AI agent skills in the current directory").action(mt);
|
|
2608
|
+
v.program.command("train").description("Install or update AI agent skills in the current directory (alias for skill)").action(mt);
|
|
2609
|
+
v.program.command("mcp").description("Configure Myop MCP server for your AI coding assistant").action(async () => {
|
|
2610
|
+
const { select: o, confirm: t } = await import("@inquirer/prompts"), n = (await import("os")).homedir(), s = be() + "/mcp", i = [
|
|
2611
|
+
{
|
|
2612
|
+
name: "Claude Code",
|
|
2613
|
+
value: "claude",
|
|
2614
|
+
configPath: _.join(n, ".claude.json"),
|
|
2615
|
+
getEntry: () => ({ type: "http", url: s }),
|
|
2616
|
+
nextSteps: [
|
|
2617
|
+
"Restart Claude Code to pick up the new MCP config.",
|
|
2618
|
+
'Type /mcp to see all MCP servers and verify "myop" is listed.',
|
|
2619
|
+
'Select "Authenticate" next to myop — your browser will open',
|
|
2620
|
+
"to sign in with your Myop account (OAuth)."
|
|
2621
|
+
]
|
|
2622
|
+
},
|
|
2623
|
+
{
|
|
2624
|
+
name: "Cursor",
|
|
2625
|
+
value: "cursor",
|
|
2626
|
+
configPath: _.join(n, ".cursor", "mcp.json"),
|
|
2627
|
+
getEntry: () => ({ url: s }),
|
|
2628
|
+
nextSteps: [
|
|
2629
|
+
'Go to Cursor Settings > Tools & MCP to verify "myop" appears.',
|
|
2630
|
+
"A green dot means connected. Yellow means auth is needed —",
|
|
2631
|
+
'click "Connect" and your browser will open to sign in',
|
|
2632
|
+
"with your Myop account (OAuth).",
|
|
2633
|
+
"You can also click the refresh icon to reconnect after changes."
|
|
2634
|
+
]
|
|
2635
|
+
},
|
|
2636
|
+
{
|
|
2637
|
+
name: "Windsurf",
|
|
2638
|
+
value: "windsurf",
|
|
2639
|
+
configPath: _.join(n, ".codeium", "windsurf", "mcp_config.json"),
|
|
2640
|
+
getEntry: () => ({ url: s }),
|
|
2641
|
+
nextSteps: [
|
|
2642
|
+
"Open Cascade and click the hammer icon (top-right) to see MCP servers.",
|
|
2643
|
+
'Verify "myop" shows a green dot (connected).',
|
|
2644
|
+
'Click "Refresh" if needed. On first use, your browser will open',
|
|
2645
|
+
"to sign in with your Myop account (OAuth)."
|
|
2646
|
+
]
|
|
2647
|
+
},
|
|
2648
|
+
{
|
|
2649
|
+
name: "VS Code (GitHub Copilot)",
|
|
2650
|
+
value: "vscode",
|
|
2651
|
+
configPath: process.platform === "darwin" ? _.join(n, "Library", "Application Support", "Code", "User", "mcp.json") : process.platform === "win32" ? _.join(process.env.APPDATA || _.join(n, "AppData", "Roaming"), "Code", "User", "mcp.json") : _.join(n, ".config", "Code", "User", "mcp.json"),
|
|
2652
|
+
getEntry: () => ({ type: "http", url: s }),
|
|
2653
|
+
nextSteps: [
|
|
2654
|
+
"Requires VS Code 1.99+ and GitHub Copilot extension.",
|
|
2655
|
+
'Press Cmd+Shift+P / Ctrl+Shift+P > "MCP: List Servers"',
|
|
2656
|
+
'to verify "myop" is running. You can also see MCP tools',
|
|
2657
|
+
"via the Tools button in Copilot Chat (Agent mode).",
|
|
2658
|
+
"On first use, your browser will open to sign in",
|
|
2659
|
+
"with your Myop account (OAuth)."
|
|
2660
|
+
]
|
|
2661
|
+
}
|
|
2662
|
+
];
|
|
2663
|
+
console.log(`
|
|
2664
|
+
Configure Myop MCP server for your AI coding assistant.
|
|
2665
|
+
`);
|
|
2666
|
+
let d;
|
|
2667
|
+
try {
|
|
2668
|
+
d = await o({
|
|
2669
|
+
message: "Select your AI coding assistant:",
|
|
2670
|
+
choices: i.map((l) => ({ name: l.name, value: l.value }))
|
|
2671
|
+
});
|
|
2672
|
+
} catch (l) {
|
|
2673
|
+
throw l.name === "ExitPromptError" && (console.log(`
|
|
2674
|
+
|
|
2675
|
+
👋 Goodbye!
|
|
2676
|
+
`), process.exit(0)), l;
|
|
2677
|
+
}
|
|
2678
|
+
const h = i.find((l) => l.value === d);
|
|
2679
|
+
let y = {};
|
|
2680
|
+
try {
|
|
2681
|
+
const l = M.readFileSync(h.configPath, "utf-8");
|
|
2682
|
+
y = JSON.parse(l);
|
|
2683
|
+
} catch {
|
|
2684
|
+
}
|
|
2685
|
+
y.mcpServers || (y.mcpServers = {});
|
|
2686
|
+
const c = y.mcpServers.myop;
|
|
2687
|
+
if (c && c.url === s) {
|
|
2688
|
+
console.log(`
|
|
2689
|
+
Myop MCP is already configured for ${h.name}.`), console.log(` Config: ${h.configPath}`), console.log(`
|
|
2690
|
+
\x1B[1mNext steps:\x1B[0m`);
|
|
2691
|
+
for (const l of h.nextSteps)
|
|
2692
|
+
console.log(` ${l}`);
|
|
2693
|
+
console.log(""), process.exit(0);
|
|
2694
|
+
}
|
|
2695
|
+
if (c) {
|
|
2696
|
+
console.log(`
|
|
2697
|
+
Myop MCP is already configured (URL: ${c.url}).`);
|
|
2698
|
+
try {
|
|
2699
|
+
await t({ message: "Update to latest URL?", default: !0 }) || process.exit(0);
|
|
2700
|
+
} catch (l) {
|
|
2701
|
+
throw l.name === "ExitPromptError" && process.exit(0), l;
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
y.mcpServers.myop = h.getEntry(), M.mkdirSync(_.dirname(h.configPath), { recursive: !0 }), M.writeFileSync(h.configPath, JSON.stringify(y, null, 2)), console.log(`
|
|
2705
|
+
\x1B[32m✔\x1B[0m Myop MCP configured for ${h.name}`), console.log(` Config: ${h.configPath}`), console.log(` Server: ${s}`), console.log(`
|
|
2706
|
+
\x1B[1mNext steps:\x1B[0m`);
|
|
2707
|
+
for (const l of h.nextSteps)
|
|
2708
|
+
console.log(` ${l}`);
|
|
2709
|
+
console.log(""), process.exit(0);
|
|
2463
2710
|
});
|
|
2464
|
-
|
|
2465
|
-
const to = () => {
|
|
2711
|
+
const po = () => {
|
|
2466
2712
|
try {
|
|
2467
|
-
|
|
2713
|
+
X("git --version", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
2468
2714
|
} catch {
|
|
2469
2715
|
return { gitNotInstalled: !0 };
|
|
2470
2716
|
}
|
|
2471
2717
|
try {
|
|
2472
|
-
|
|
2718
|
+
X("git rev-parse --git-dir", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
2473
2719
|
} catch {
|
|
2474
2720
|
return { notARepo: !0 };
|
|
2475
2721
|
}
|
|
2476
2722
|
try {
|
|
2477
|
-
const o =
|
|
2723
|
+
const o = X("git diff --stat HEAD -- . 2>/dev/null || git diff --stat -- . 2>/dev/null", {
|
|
2478
2724
|
encoding: "utf-8",
|
|
2479
2725
|
stdio: ["pipe", "pipe", "pipe"]
|
|
2480
2726
|
}).trim();
|
|
@@ -2484,23 +2730,23 @@ const to = () => {
|
|
|
2484
2730
|
insertions: 0,
|
|
2485
2731
|
deletions: 0
|
|
2486
2732
|
};
|
|
2487
|
-
const
|
|
2488
|
-
`),
|
|
2733
|
+
const t = o.split(`
|
|
2734
|
+
`), e = t[t.length - 1], n = e.match(/(\d+) insertion/), s = e.match(/(\d+) deletion/), i = e.match(/(\d+) file/);
|
|
2489
2735
|
return {
|
|
2490
|
-
files:
|
|
2736
|
+
files: i ? parseInt(i[1]) : 0,
|
|
2491
2737
|
insertions: n ? parseInt(n[1]) : 0,
|
|
2492
|
-
deletions:
|
|
2738
|
+
deletions: s ? parseInt(s[1]) : 0
|
|
2493
2739
|
};
|
|
2494
2740
|
} catch {
|
|
2495
2741
|
return null;
|
|
2496
2742
|
}
|
|
2497
|
-
},
|
|
2498
|
-
var
|
|
2499
|
-
const
|
|
2743
|
+
}, ie = async (o = !1, t = !1) => {
|
|
2744
|
+
var l, C, u;
|
|
2745
|
+
const e = $e(), n = !!(e != null && e.email), s = ((l = v.myopConfig) == null ? void 0 : l.name) || ((C = v.myopConfig) == null ? void 0 : C.componentName), i = (u = v.myopConfig) == null ? void 0 : u.componentId, d = po();
|
|
2500
2746
|
console.log(`
|
|
2501
2747
|
┌─────────────────────────────────────────────────┐`), console.log("│ │"), console.log("│ Welcome to Myop CLI - Remote UI Made Easy │"), console.log("│ │"), console.log(`└─────────────────────────────────────────────────┘
|
|
2502
|
-
`), o &&
|
|
2503
|
-
const
|
|
2748
|
+
`), 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"}`), d != null && d.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")) : d != null && d.notARepo ? console.log(" Changes: Not a git repository") : d && (d.insertions > 0 || d.deletions > 0) ? console.log(` Changes: ${d.files} file${d.files !== 1 ? "s" : ""} | \x1B[32m+${d.insertions}\x1B[0m \x1B[31m-${d.deletions}\x1B[0m`) : d && console.log(" Changes: No uncommitted changes"), console.log("");
|
|
2749
|
+
const y = [
|
|
2504
2750
|
{
|
|
2505
2751
|
emoji: "🚀",
|
|
2506
2752
|
label: "Initialize new component",
|
|
@@ -2510,130 +2756,130 @@ const to = () => {
|
|
|
2510
2756
|
},
|
|
2511
2757
|
{
|
|
2512
2758
|
emoji: "🛠️ ",
|
|
2513
|
-
label:
|
|
2759
|
+
label: s ? `Start dev mode for "${s}"` : "Start dev mode",
|
|
2514
2760
|
value: "dev",
|
|
2515
2761
|
help: "Starts dev server with HMR for instant preview of changes",
|
|
2516
2762
|
disabled: o ? !1 : "(no config file)"
|
|
2517
2763
|
},
|
|
2518
2764
|
{
|
|
2519
2765
|
emoji: "📦",
|
|
2520
|
-
label:
|
|
2766
|
+
label: s ? `Push "${s}"` : "Push component",
|
|
2521
2767
|
value: "sync",
|
|
2522
2768
|
help: "Builds project & uploads dist/index.html to Myop",
|
|
2523
2769
|
disabled: o ? n ? !1 : "(login required)" : "(no config file)"
|
|
2524
2770
|
}
|
|
2525
|
-
].map((
|
|
2526
|
-
name:
|
|
2527
|
-
${
|
|
2528
|
-
value:
|
|
2529
|
-
disabled:
|
|
2771
|
+
].map((P) => ({
|
|
2772
|
+
name: t && !P.disabled ? `${P.emoji} ${P.label}
|
|
2773
|
+
${P.help}` : `${P.emoji} ${P.label}`,
|
|
2774
|
+
value: P.value,
|
|
2775
|
+
disabled: P.disabled
|
|
2530
2776
|
}));
|
|
2531
|
-
|
|
2532
|
-
new
|
|
2777
|
+
y.push(
|
|
2778
|
+
new _e(),
|
|
2533
2779
|
{
|
|
2534
|
-
name:
|
|
2535
|
-
Clears stored credentials from this machine` :
|
|
2536
|
-
Opens browser to authenticate with Myop` : n ? `🔓 Logout (${
|
|
2780
|
+
name: t && n ? `🔓 Logout (${e.email})
|
|
2781
|
+
Clears stored credentials from this machine` : t && !n ? `🔐 Login to Myop
|
|
2782
|
+
Opens browser to authenticate with Myop` : n ? `🔓 Logout (${e.email})` : "🔐 Login to Myop",
|
|
2537
2783
|
value: n ? "logout" : "login"
|
|
2538
2784
|
},
|
|
2539
2785
|
{
|
|
2540
|
-
name:
|
|
2786
|
+
name: t ? "📖 Hide help" : "📖 Show help",
|
|
2541
2787
|
value: "help"
|
|
2542
2788
|
},
|
|
2543
|
-
new
|
|
2789
|
+
new _e(),
|
|
2544
2790
|
{
|
|
2545
2791
|
name: "👋 Exit",
|
|
2546
2792
|
value: "exit"
|
|
2547
2793
|
}
|
|
2548
2794
|
);
|
|
2549
|
-
let
|
|
2795
|
+
let c;
|
|
2550
2796
|
try {
|
|
2551
|
-
|
|
2797
|
+
c = await et({
|
|
2552
2798
|
message: "What would you like to do?",
|
|
2553
|
-
choices:
|
|
2799
|
+
choices: y
|
|
2554
2800
|
});
|
|
2555
|
-
} catch (
|
|
2556
|
-
throw
|
|
2801
|
+
} catch (P) {
|
|
2802
|
+
throw P.name === "ExitPromptError" && (console.log(`
|
|
2557
2803
|
|
|
2558
2804
|
👋 Goodbye!
|
|
2559
|
-
`), process.exit(0)),
|
|
2805
|
+
`), process.exit(0)), P;
|
|
2560
2806
|
}
|
|
2561
|
-
switch (
|
|
2807
|
+
switch (c) {
|
|
2562
2808
|
case "init":
|
|
2563
|
-
await
|
|
2809
|
+
await fo();
|
|
2564
2810
|
break;
|
|
2565
2811
|
case "sync":
|
|
2566
2812
|
console.log(`
|
|
2567
|
-
|
|
2813
|
+
Pushing component...
|
|
2568
2814
|
`);
|
|
2569
|
-
const { execSync:
|
|
2815
|
+
const { execSync: P } = await import("child_process");
|
|
2570
2816
|
try {
|
|
2571
|
-
|
|
2817
|
+
P("node " + process.argv[1] + " push", { stdio: "inherit" });
|
|
2572
2818
|
} catch {
|
|
2573
2819
|
}
|
|
2574
|
-
await
|
|
2820
|
+
await ie(!0, t);
|
|
2575
2821
|
break;
|
|
2576
2822
|
case "dev":
|
|
2577
|
-
await
|
|
2823
|
+
await xe();
|
|
2578
2824
|
break;
|
|
2579
2825
|
case "login":
|
|
2580
2826
|
try {
|
|
2581
2827
|
await de(), console.log(`
|
|
2582
|
-
`), await
|
|
2583
|
-
} catch (
|
|
2584
|
-
console.error("Login failed:",
|
|
2828
|
+
`), await ie(o, t);
|
|
2829
|
+
} catch (g) {
|
|
2830
|
+
console.error("Login failed:", g.message), await ie(o, t);
|
|
2585
2831
|
}
|
|
2586
2832
|
break;
|
|
2587
2833
|
case "logout":
|
|
2588
|
-
await
|
|
2589
|
-
`), await
|
|
2834
|
+
await dt(), console.log(`
|
|
2835
|
+
`), await ie(o, t);
|
|
2590
2836
|
break;
|
|
2591
2837
|
case "help":
|
|
2592
|
-
await
|
|
2838
|
+
await ie(o, !t);
|
|
2593
2839
|
break;
|
|
2594
2840
|
case "exit":
|
|
2595
2841
|
process.exit(0);
|
|
2596
2842
|
}
|
|
2597
|
-
}, ve = ".myop-monorepo.json",
|
|
2843
|
+
}, ve = ".myop-monorepo.json", mo = () => {
|
|
2598
2844
|
try {
|
|
2599
|
-
const o =
|
|
2845
|
+
const o = M.readFileSync(ve, "utf-8");
|
|
2600
2846
|
return JSON.parse(o);
|
|
2601
2847
|
} catch {
|
|
2602
2848
|
return null;
|
|
2603
2849
|
}
|
|
2604
|
-
},
|
|
2850
|
+
}, uo = (o) => {
|
|
2605
2851
|
try {
|
|
2606
|
-
const
|
|
2852
|
+
const t = {
|
|
2607
2853
|
selectedComponents: o,
|
|
2608
2854
|
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
2609
2855
|
};
|
|
2610
|
-
|
|
2856
|
+
M.writeFileSync(ve, JSON.stringify(t, null, 2));
|
|
2611
2857
|
} catch {
|
|
2612
2858
|
}
|
|
2613
|
-
},
|
|
2614
|
-
const o =
|
|
2859
|
+
}, go = async () => {
|
|
2860
|
+
const o = $e(), t = !!(o != null && o.email);
|
|
2615
2861
|
console.log(`
|
|
2616
2862
|
┌─────────────────────────────────────────────────┐`), console.log("│ │"), console.log("│ Myop CLI - Monorepo Mode │"), console.log("│ │"), console.log(`└─────────────────────────────────────────────────┘
|
|
2617
2863
|
`);
|
|
2618
|
-
const
|
|
2619
|
-
|
|
2864
|
+
const e = Y("Scanning for components...").start(), n = Ve(".");
|
|
2865
|
+
e.stop(), n.length === 0 && (console.log(` ⚠️ No myop.config.json files found in this directory or subdirectories.
|
|
2620
2866
|
`), console.log(" Run `myop` without -m flag to initialize a single component.\n"), process.exit(0));
|
|
2621
|
-
const
|
|
2867
|
+
const s = mo(), i = (s == null ? void 0 : s.selectedComponents) || [], d = i.length > 0;
|
|
2622
2868
|
console.log(` Found ${n.length} component${n.length > 1 ? "s" : ""}:
|
|
2623
|
-
`), n.forEach((u,
|
|
2624
|
-
const
|
|
2625
|
-
console.log(` ${
|
|
2626
|
-
}), console.log(` User: ${
|
|
2627
|
-
const { checkbox:
|
|
2869
|
+
`), n.forEach((u, P) => {
|
|
2870
|
+
const g = u.componentId ? "✅" : "⚪", w = u.componentId ? u.componentId.substring(0, 8) + "..." : "(not pushed)";
|
|
2871
|
+
console.log(` ${g} ${u.name}`), console.log(` Path: ${u.path}`), console.log(` ID: ${w}`), console.log("");
|
|
2872
|
+
}), console.log(` User: ${t ? o.email : "Not logged in"}`), d && console.log(` 📋 Using saved selection from ${ve}`), console.log("");
|
|
2873
|
+
const { checkbox: h } = await import("@inquirer/prompts"), y = n.map((u) => ({
|
|
2628
2874
|
name: `${u.name} (${u.path})`,
|
|
2629
2875
|
value: u.path,
|
|
2630
|
-
checked:
|
|
2876
|
+
checked: d ? i.includes(u.path) : !0
|
|
2631
2877
|
}));
|
|
2632
|
-
let
|
|
2878
|
+
let c;
|
|
2633
2879
|
try {
|
|
2634
|
-
|
|
2880
|
+
c = await h({
|
|
2635
2881
|
message: "Select components to start in dev mode:",
|
|
2636
|
-
choices:
|
|
2882
|
+
choices: y
|
|
2637
2883
|
});
|
|
2638
2884
|
} catch (u) {
|
|
2639
2885
|
throw u.name === "ExitPromptError" && (console.log(`
|
|
@@ -2641,23 +2887,23 @@ Running sync...
|
|
|
2641
2887
|
👋 Goodbye!
|
|
2642
2888
|
`), process.exit(0)), u;
|
|
2643
2889
|
}
|
|
2644
|
-
|
|
2890
|
+
c.length === 0 && (console.log(`
|
|
2645
2891
|
⚠️ No components selected.
|
|
2646
|
-
`), process.exit(0)),
|
|
2892
|
+
`), process.exit(0)), uo(c), console.log(`
|
|
2647
2893
|
💾 Selection saved to ${ve}`);
|
|
2648
|
-
const
|
|
2649
|
-
console.log(`🚀 Starting dev mode for ${
|
|
2894
|
+
const l = n.filter((u) => c.includes(u.path));
|
|
2895
|
+
console.log(`🚀 Starting dev mode for ${l.length} component${l.length > 1 ? "s" : ""}...
|
|
2650
2896
|
`);
|
|
2651
|
-
const { monorepoDevCommand:
|
|
2652
|
-
await
|
|
2653
|
-
},
|
|
2654
|
-
const { input: o, select:
|
|
2655
|
-
let
|
|
2897
|
+
const { monorepoDevCommand: C } = await Promise.resolve().then(() => Ht);
|
|
2898
|
+
await C(l);
|
|
2899
|
+
}, fo = async () => {
|
|
2900
|
+
const { input: o, select: t } = await import("@inquirer/prompts"), e = await import("fs"), n = await import("path"), s = n.default.basename(process.cwd());
|
|
2901
|
+
let i, d;
|
|
2656
2902
|
try {
|
|
2657
|
-
|
|
2903
|
+
i = await o({
|
|
2658
2904
|
message: "Component name:",
|
|
2659
|
-
default:
|
|
2660
|
-
}),
|
|
2905
|
+
default: s
|
|
2906
|
+
}), d = await t({
|
|
2661
2907
|
message: "Component type:",
|
|
2662
2908
|
choices: [
|
|
2663
2909
|
{ name: "📄 HTML", value: "html", description: "Plain HTML/JS/CSS component" },
|
|
@@ -2666,23 +2912,23 @@ Running sync...
|
|
|
2666
2912
|
{ name: "🅰️ Angular", value: "angular", disabled: "(coming soon)" }
|
|
2667
2913
|
]
|
|
2668
2914
|
});
|
|
2669
|
-
} catch (
|
|
2670
|
-
throw
|
|
2915
|
+
} catch (c) {
|
|
2916
|
+
throw c.name === "ExitPromptError" && (console.log(`
|
|
2671
2917
|
|
|
2672
2918
|
👋 Goodbye!
|
|
2673
|
-
`), process.exit(0)),
|
|
2919
|
+
`), process.exit(0)), c;
|
|
2674
2920
|
}
|
|
2675
|
-
const
|
|
2676
|
-
name:
|
|
2677
|
-
type:
|
|
2921
|
+
const h = {
|
|
2922
|
+
name: i,
|
|
2923
|
+
type: d,
|
|
2678
2924
|
author: "@myop-cli",
|
|
2679
2925
|
HMR: !0
|
|
2680
|
-
},
|
|
2926
|
+
}, y = v.program.getOptionValue("config") || "./myop.config.json";
|
|
2681
2927
|
try {
|
|
2682
|
-
|
|
2683
|
-
✅ Created ${
|
|
2684
|
-
const
|
|
2685
|
-
name:
|
|
2928
|
+
e.writeFileSync(y, JSON.stringify(h, null, 2)), console.log(`
|
|
2929
|
+
✅ Created ${y}`);
|
|
2930
|
+
const c = {
|
|
2931
|
+
name: i.toLowerCase().replace(/\s+/g, "-"),
|
|
2686
2932
|
version: "1.0.0",
|
|
2687
2933
|
type: "module",
|
|
2688
2934
|
scripts: {
|
|
@@ -2693,7 +2939,7 @@ Running sync...
|
|
|
2693
2939
|
esbuild: "^0.24.0"
|
|
2694
2940
|
}
|
|
2695
2941
|
};
|
|
2696
|
-
|
|
2942
|
+
e.writeFileSync("package.json", JSON.stringify(c, 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
2943
|
import fs from 'fs';
|
|
2698
2944
|
import path from 'path';
|
|
2699
2945
|
|
|
@@ -2773,25 +3019,25 @@ fs.writeFileSync('dist/index.html', html);
|
|
|
2773
3019
|
console.log('✅ Built dist/index.html');
|
|
2774
3020
|
console.log(\` Bundled \${jsFiles.length} JS modules, \${cssFiles.length} CSS files\`);
|
|
2775
3021
|
`), console.log("✅ Created build.js");
|
|
2776
|
-
const
|
|
3022
|
+
const C = `<!DOCTYPE html>
|
|
2777
3023
|
<html lang="en">
|
|
2778
3024
|
<head>
|
|
2779
3025
|
<meta charset="UTF-8">
|
|
2780
3026
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
2781
|
-
<title>${
|
|
3027
|
+
<title>${i}</title>
|
|
2782
3028
|
<link rel="stylesheet" href="./src/styles/index.css">
|
|
2783
3029
|
</head>
|
|
2784
3030
|
<body>
|
|
2785
3031
|
<div id="app">
|
|
2786
|
-
<h1>${
|
|
3032
|
+
<h1>${i}</h1>
|
|
2787
3033
|
<p>Your Myop component is ready!</p>
|
|
2788
3034
|
</div>
|
|
2789
3035
|
<script type="module" src="./src/index.js"><\/script>
|
|
2790
3036
|
</body>
|
|
2791
3037
|
</html>
|
|
2792
3038
|
`;
|
|
2793
|
-
|
|
2794
|
-
const u = `// ${
|
|
3039
|
+
e.writeFileSync("index.html", C), console.log("✅ Created index.html");
|
|
3040
|
+
const u = `// ${i} - Entry Point
|
|
2795
3041
|
import { init } from './modules/app.js';
|
|
2796
3042
|
import { setupMyopInterface } from './modules/myop.js';
|
|
2797
3043
|
|
|
@@ -2800,16 +3046,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2800
3046
|
setupMyopInterface();
|
|
2801
3047
|
});
|
|
2802
3048
|
`;
|
|
2803
|
-
|
|
2804
|
-
const
|
|
3049
|
+
e.writeFileSync("src/index.js", u), console.log("✅ Created src/index.js");
|
|
3050
|
+
const P = `// ${i} - Main Application Logic
|
|
2805
3051
|
|
|
2806
3052
|
export function init() {
|
|
2807
|
-
console.log('${
|
|
3053
|
+
console.log('${i} loaded');
|
|
2808
3054
|
|
|
2809
3055
|
// Your component logic here
|
|
2810
3056
|
}
|
|
2811
3057
|
`;
|
|
2812
|
-
|
|
3058
|
+
e.writeFileSync("src/modules/app.js", P), console.log("✅ Created src/modules/app.js"), e.writeFileSync("src/modules/myop.js", `// Myop Interface - Communication with host app
|
|
2813
3059
|
|
|
2814
3060
|
export function setupMyopInterface() {
|
|
2815
3061
|
// Called when host app sends data to this component
|
|
@@ -2825,12 +3071,12 @@ export function setupMyopInterface() {
|
|
|
2825
3071
|
};
|
|
2826
3072
|
}
|
|
2827
3073
|
`), console.log("✅ Created src/modules/myop.js");
|
|
2828
|
-
const
|
|
3074
|
+
const w = `/* ${i} - Styles Entry Point */
|
|
2829
3075
|
/* Add your CSS imports here - they will be auto-bundled */
|
|
2830
3076
|
@import './main.css';
|
|
2831
3077
|
`;
|
|
2832
|
-
|
|
2833
|
-
const j = `/* ${
|
|
3078
|
+
e.writeFileSync("src/styles/index.css", w), console.log("✅ Created src/styles/index.css");
|
|
3079
|
+
const j = `/* ${i} - Main Styles */
|
|
2834
3080
|
|
|
2835
3081
|
* {
|
|
2836
3082
|
box-sizing: border-box;
|
|
@@ -2859,18 +3105,18 @@ p {
|
|
|
2859
3105
|
line-height: 1.5;
|
|
2860
3106
|
}
|
|
2861
3107
|
`;
|
|
2862
|
-
|
|
3108
|
+
e.writeFileSync("src/styles/main.css", j), console.log("✅ Created src/styles/main.css"), e.writeFileSync(".gitignore", `node_modules/
|
|
2863
3109
|
dist/
|
|
2864
3110
|
.temp-entry.js
|
|
2865
3111
|
.temp-styles.css
|
|
2866
3112
|
.DS_Store
|
|
2867
3113
|
`), console.log("✅ Created .gitignore");
|
|
2868
|
-
const b =
|
|
2869
|
-
b && console.log("✅ Installed AI agent skills");
|
|
2870
|
-
const
|
|
3114
|
+
const b = await We(process.cwd());
|
|
3115
|
+
b.success && console.log("✅ Installed AI agent skills");
|
|
3116
|
+
const p = await import("./index-DuEoKctW.js").then((x) => x.i), E = process.cwd();
|
|
2871
3117
|
try {
|
|
2872
|
-
await
|
|
2873
|
-
const
|
|
3118
|
+
await p.init({ fs: e, dir: E });
|
|
3119
|
+
const x = [
|
|
2874
3120
|
"myop.config.json",
|
|
2875
3121
|
"package.json",
|
|
2876
3122
|
"build.js",
|
|
@@ -2882,77 +3128,85 @@ dist/
|
|
|
2882
3128
|
"src/styles/index.css",
|
|
2883
3129
|
"src/styles/main.css"
|
|
2884
3130
|
];
|
|
2885
|
-
if (b) {
|
|
2886
|
-
const
|
|
3131
|
+
if (b.success) {
|
|
3132
|
+
const O = (R, D) => {
|
|
2887
3133
|
try {
|
|
2888
|
-
const
|
|
2889
|
-
for (const
|
|
2890
|
-
const
|
|
2891
|
-
|
|
3134
|
+
const L = e.readdirSync(R, { withFileTypes: !0 });
|
|
3135
|
+
for (const T of L) {
|
|
3136
|
+
const J = n.join(R, T.name), F = n.join(D, T.name);
|
|
3137
|
+
T.isDirectory() ? O(J, F) : x.push(F);
|
|
2892
3138
|
}
|
|
2893
3139
|
} catch {
|
|
2894
3140
|
}
|
|
2895
3141
|
};
|
|
2896
|
-
|
|
3142
|
+
try {
|
|
3143
|
+
const R = e.readdirSync(".", { withFileTypes: !0 });
|
|
3144
|
+
for (const D of R)
|
|
3145
|
+
if (D.isDirectory() && D.name.startsWith(".")) {
|
|
3146
|
+
const L = n.join(D.name, "skills");
|
|
3147
|
+
e.existsSync(L) && O(L, L);
|
|
3148
|
+
}
|
|
3149
|
+
} catch {
|
|
3150
|
+
}
|
|
2897
3151
|
}
|
|
2898
|
-
for (const
|
|
2899
|
-
await
|
|
2900
|
-
await
|
|
2901
|
-
fs:
|
|
2902
|
-
dir:
|
|
3152
|
+
for (const O of x)
|
|
3153
|
+
await p.add({ fs: e, dir: E, filepath: O });
|
|
3154
|
+
await p.commit({
|
|
3155
|
+
fs: e,
|
|
3156
|
+
dir: E,
|
|
2903
3157
|
message: "init",
|
|
2904
3158
|
author: { name: "myop-cli", email: "cli@myop.dev" }
|
|
2905
3159
|
}), console.log("✅ Initialized git repository");
|
|
2906
|
-
} catch (
|
|
2907
|
-
console.log("⚠️ Failed to initialize git repository:",
|
|
3160
|
+
} catch (x) {
|
|
3161
|
+
console.log("⚠️ Failed to initialize git repository:", x.message);
|
|
2908
3162
|
}
|
|
2909
3163
|
console.log(`
|
|
2910
3164
|
📦 Next steps:`), console.log(" 1. npm install"), console.log(" 2. npm run build"), console.log(` 3. myop sync
|
|
2911
|
-
`),
|
|
2912
|
-
} catch (
|
|
2913
|
-
console.error(`Failed to initialize component: ${
|
|
3165
|
+
`), v.myopConfig = h, await ie(!0);
|
|
3166
|
+
} catch (c) {
|
|
3167
|
+
console.error(`Failed to initialize component: ${c.message}`), process.exit(1);
|
|
2914
3168
|
}
|
|
2915
3169
|
};
|
|
2916
|
-
|
|
2917
|
-
if (
|
|
2918
|
-
await
|
|
3170
|
+
v.program.command("default", { isDefault: !0 }).action(async () => {
|
|
3171
|
+
if (v.program.getOptionValue("help") && (console.log(Pt), process.exit()), v.program.getOptionValue("monorepo")) {
|
|
3172
|
+
await go();
|
|
2919
3173
|
return;
|
|
2920
3174
|
}
|
|
2921
|
-
if (
|
|
2922
|
-
const
|
|
2923
|
-
let
|
|
3175
|
+
if (v.program.getOptionValue("ci")) {
|
|
3176
|
+
const h = await import("fs"), y = v.program.getOptionValue("config") || "./myop.config.json", c = v.program.version(), l = $e();
|
|
3177
|
+
let C = { found: !1 };
|
|
2924
3178
|
try {
|
|
2925
|
-
if (
|
|
2926
|
-
const
|
|
2927
|
-
|
|
3179
|
+
if (h.existsSync(y)) {
|
|
3180
|
+
const P = h.readFileSync(y, "utf-8"), g = JSON.parse(P);
|
|
3181
|
+
C = {
|
|
2928
3182
|
found: !0,
|
|
2929
|
-
path:
|
|
2930
|
-
name:
|
|
2931
|
-
componentId:
|
|
2932
|
-
organization:
|
|
3183
|
+
path: y,
|
|
3184
|
+
name: g.name || g.componentName || null,
|
|
3185
|
+
componentId: g.componentId || null,
|
|
3186
|
+
organization: g.organization || null
|
|
2933
3187
|
};
|
|
2934
3188
|
}
|
|
2935
|
-
} catch (
|
|
2936
|
-
|
|
3189
|
+
} catch (P) {
|
|
3190
|
+
C = { found: !1, error: P.message };
|
|
2937
3191
|
}
|
|
2938
3192
|
const u = {
|
|
2939
|
-
version:
|
|
2940
|
-
config:
|
|
3193
|
+
version: c,
|
|
3194
|
+
config: C,
|
|
2941
3195
|
auth: {
|
|
2942
|
-
loggedIn: !!(
|
|
2943
|
-
email: (
|
|
3196
|
+
loggedIn: !!(l != null && l.email),
|
|
3197
|
+
email: (l == null ? void 0 : l.email) || null
|
|
2944
3198
|
}
|
|
2945
3199
|
};
|
|
2946
3200
|
console.log(JSON.stringify(u, null, 2)), process.exit(0);
|
|
2947
3201
|
}
|
|
2948
|
-
let n =
|
|
3202
|
+
let n = Y({
|
|
2949
3203
|
text: "Loading Myop CLI...",
|
|
2950
3204
|
color: "green"
|
|
2951
3205
|
}).start();
|
|
2952
|
-
const
|
|
2953
|
-
await
|
|
2954
|
-
const
|
|
2955
|
-
await
|
|
3206
|
+
const s = Ce();
|
|
3207
|
+
await ro(500), n.stop();
|
|
3208
|
+
const i = v.program.version();
|
|
3209
|
+
await to(i) || await ie(s.configFound);
|
|
2956
3210
|
});
|
|
2957
|
-
|
|
2958
|
-
|
|
3211
|
+
v.program.parse(process.argv);
|
|
3212
|
+
v.program.opts();
|