openmagic 0.10.0 → 0.11.0
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/cli.js +176 -188
- package/dist/cli.js.map +1 -1
- package/dist/toolbar/index.global.js +39 -22
- package/dist/toolbar/index.global.js.map +1 -1
- package/package.json +2 -3
package/dist/cli.js
CHANGED
|
@@ -31,134 +31,7 @@ function validateToken(token) {
|
|
|
31
31
|
return token === sessionToken;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
// src/proxy.ts
|
|
35
|
-
var gunzipAsync = promisify(gunzip);
|
|
36
|
-
var inflateAsync = promisify(inflate);
|
|
37
|
-
var brotliAsync = promisify(brotliDecompress);
|
|
38
|
-
function createProxyServer(targetHost, targetPort, serverPort) {
|
|
39
|
-
const proxy = httpProxy.createProxyServer({
|
|
40
|
-
target: `http://${targetHost}:${targetPort}`,
|
|
41
|
-
ws: true,
|
|
42
|
-
selfHandleResponse: true
|
|
43
|
-
});
|
|
44
|
-
const token = getSessionToken();
|
|
45
|
-
proxy.on("proxyRes", (proxyRes, req, res) => {
|
|
46
|
-
const contentType = proxyRes.headers["content-type"] || "";
|
|
47
|
-
const isHtml = contentType.includes("text/html");
|
|
48
|
-
if (!isHtml) {
|
|
49
|
-
res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);
|
|
50
|
-
proxyRes.pipe(res);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
collectBody(proxyRes).then((body) => {
|
|
54
|
-
const toolbarScript = buildInjectionScript(serverPort, token);
|
|
55
|
-
if (body.includes("</body>")) {
|
|
56
|
-
body = body.replace("</body>", `${toolbarScript}</body>`);
|
|
57
|
-
} else if (body.includes("</html>")) {
|
|
58
|
-
body = body.replace("</html>", `${toolbarScript}</html>`);
|
|
59
|
-
} else {
|
|
60
|
-
body += toolbarScript;
|
|
61
|
-
}
|
|
62
|
-
const headers = { ...proxyRes.headers };
|
|
63
|
-
delete headers["content-length"];
|
|
64
|
-
delete headers["content-encoding"];
|
|
65
|
-
delete headers["transfer-encoding"];
|
|
66
|
-
delete headers["content-security-policy"];
|
|
67
|
-
delete headers["content-security-policy-report-only"];
|
|
68
|
-
delete headers["x-content-security-policy"];
|
|
69
|
-
delete headers["etag"];
|
|
70
|
-
delete headers["last-modified"];
|
|
71
|
-
res.writeHead(proxyRes.statusCode || 200, headers);
|
|
72
|
-
res.end(body);
|
|
73
|
-
}).catch(() => {
|
|
74
|
-
try {
|
|
75
|
-
res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);
|
|
76
|
-
res.end();
|
|
77
|
-
} catch {
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
proxy.on("error", (err, _req, res) => {
|
|
82
|
-
if (res instanceof http.ServerResponse && !res.headersSent) {
|
|
83
|
-
const toolbarScript = buildInjectionScript(serverPort, token);
|
|
84
|
-
res.writeHead(502, { "Content-Type": "text/html" });
|
|
85
|
-
res.end(
|
|
86
|
-
`<html><body style="font-family:system-ui;padding:40px;background:#1a1a2e;color:#e0e0e0;">
|
|
87
|
-
<h2 style="color:#e94560;">OpenMagic \u2014 Cannot connect to dev server</h2>
|
|
88
|
-
<p>Could not reach <code>${targetHost}:${targetPort}</code></p>
|
|
89
|
-
<p style="color:#888;">Make sure your dev server is running, then refresh this page.</p>
|
|
90
|
-
<p style="color:#666;font-size:13px;">${err.message}</p>
|
|
91
|
-
${toolbarScript}
|
|
92
|
-
</body></html>`
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
const server = http.createServer((req, res) => {
|
|
97
|
-
if (req.url?.startsWith("/__openmagic__/")) {
|
|
98
|
-
handleToolbarAsset(req, res, serverPort);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
proxy.web(req, res);
|
|
102
|
-
});
|
|
103
|
-
server.on("upgrade", (req, socket, head) => {
|
|
104
|
-
if (req.url?.startsWith("/__openmagic__")) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
proxy.ws(req, socket, head);
|
|
108
|
-
});
|
|
109
|
-
return server;
|
|
110
|
-
}
|
|
111
|
-
async function collectBody(stream) {
|
|
112
|
-
const rawBuffer = await new Promise((resolve3, reject) => {
|
|
113
|
-
const chunks = [];
|
|
114
|
-
stream.on("data", (chunk) => chunks.push(chunk));
|
|
115
|
-
stream.on("end", () => resolve3(Buffer.concat(chunks)));
|
|
116
|
-
stream.on("error", reject);
|
|
117
|
-
});
|
|
118
|
-
const encoding = (stream.headers["content-encoding"] || "").toLowerCase();
|
|
119
|
-
if (!encoding || encoding === "identity") {
|
|
120
|
-
return rawBuffer.toString("utf-8");
|
|
121
|
-
}
|
|
122
|
-
try {
|
|
123
|
-
let decompressed;
|
|
124
|
-
if (encoding === "gzip" || encoding === "x-gzip") {
|
|
125
|
-
decompressed = await gunzipAsync(rawBuffer);
|
|
126
|
-
} else if (encoding === "deflate") {
|
|
127
|
-
decompressed = await inflateAsync(rawBuffer);
|
|
128
|
-
} else if (encoding === "br") {
|
|
129
|
-
decompressed = await brotliAsync(rawBuffer);
|
|
130
|
-
} else {
|
|
131
|
-
return rawBuffer.toString("utf-8");
|
|
132
|
-
}
|
|
133
|
-
return decompressed.toString("utf-8");
|
|
134
|
-
} catch {
|
|
135
|
-
return rawBuffer.toString("utf-8");
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
function handleToolbarAsset(_req, res, _serverPort) {
|
|
139
|
-
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
140
|
-
res.end("Not found");
|
|
141
|
-
}
|
|
142
|
-
function buildInjectionScript(serverPort, token) {
|
|
143
|
-
return `
|
|
144
|
-
<script data-openmagic="true">
|
|
145
|
-
(function() {
|
|
146
|
-
if (window.__OPENMAGIC_LOADED__) return;
|
|
147
|
-
window.__OPENMAGIC_LOADED__ = true;
|
|
148
|
-
window.__OPENMAGIC_CONFIG__ = {
|
|
149
|
-
wsPort: ${serverPort},
|
|
150
|
-
token: "${token}"
|
|
151
|
-
};
|
|
152
|
-
var script = document.createElement("script");
|
|
153
|
-
script.src = "http://127.0.0.1:${serverPort}/__openmagic__/toolbar.js";
|
|
154
|
-
script.dataset.openmagic = "true";
|
|
155
|
-
document.body.appendChild(script);
|
|
156
|
-
})();
|
|
157
|
-
</script>`;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
34
|
// src/server.ts
|
|
161
|
-
import http2 from "http";
|
|
162
35
|
import { readFileSync as readFileSync3, existsSync as existsSync3 } from "fs";
|
|
163
36
|
import { join as join3, dirname as dirname2 } from "path";
|
|
164
37
|
import { fileURLToPath } from "url";
|
|
@@ -1508,24 +1381,25 @@ async function handleLlmChat(params, onChunk, onDone, onError) {
|
|
|
1508
1381
|
}
|
|
1509
1382
|
|
|
1510
1383
|
// src/server.ts
|
|
1384
|
+
var VERSION = "0.11.0";
|
|
1511
1385
|
var __dirname = dirname2(fileURLToPath(import.meta.url));
|
|
1512
|
-
function
|
|
1513
|
-
|
|
1386
|
+
function attachOpenMagic(httpServer, roots) {
|
|
1387
|
+
function handleRequest(req, res) {
|
|
1388
|
+
if (!req.url?.startsWith("/__openmagic__/")) return false;
|
|
1514
1389
|
if (req.url === "/__openmagic__/toolbar.js") {
|
|
1515
1390
|
serveToolbarBundle(res);
|
|
1516
|
-
return;
|
|
1391
|
+
return true;
|
|
1517
1392
|
}
|
|
1518
1393
|
if (req.url === "/__openmagic__/health") {
|
|
1519
1394
|
res.writeHead(200, {
|
|
1520
1395
|
"Content-Type": "application/json",
|
|
1521
1396
|
"Access-Control-Allow-Origin": "*"
|
|
1522
1397
|
});
|
|
1523
|
-
res.end(JSON.stringify({ status: "ok", version:
|
|
1524
|
-
return;
|
|
1398
|
+
res.end(JSON.stringify({ status: "ok", version: VERSION }));
|
|
1399
|
+
return true;
|
|
1525
1400
|
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
});
|
|
1401
|
+
return false;
|
|
1402
|
+
}
|
|
1529
1403
|
const wss = new WebSocketServer({
|
|
1530
1404
|
server: httpServer,
|
|
1531
1405
|
path: "/__openmagic__/ws"
|
|
@@ -1552,7 +1426,7 @@ function createOpenMagicServer(proxyPort, roots) {
|
|
|
1552
1426
|
return;
|
|
1553
1427
|
}
|
|
1554
1428
|
try {
|
|
1555
|
-
await handleMessage(ws, msg, state, roots
|
|
1429
|
+
await handleMessage(ws, msg, state, roots);
|
|
1556
1430
|
} catch (e) {
|
|
1557
1431
|
sendError(ws, "internal_error", e.message, msg.id);
|
|
1558
1432
|
}
|
|
@@ -1561,9 +1435,9 @@ function createOpenMagicServer(proxyPort, roots) {
|
|
|
1561
1435
|
clientStates.delete(ws);
|
|
1562
1436
|
});
|
|
1563
1437
|
});
|
|
1564
|
-
return {
|
|
1438
|
+
return { wss, handleRequest };
|
|
1565
1439
|
}
|
|
1566
|
-
async function handleMessage(ws, msg, state, roots
|
|
1440
|
+
async function handleMessage(ws, msg, state, roots) {
|
|
1567
1441
|
switch (msg.type) {
|
|
1568
1442
|
case "handshake": {
|
|
1569
1443
|
const payload = msg.payload;
|
|
@@ -1583,12 +1457,13 @@ async function handleMessage(ws, msg, state, roots, _proxyPort) {
|
|
|
1583
1457
|
id: msg.id,
|
|
1584
1458
|
type: "handshake.ok",
|
|
1585
1459
|
payload: {
|
|
1586
|
-
version:
|
|
1460
|
+
version: VERSION,
|
|
1587
1461
|
roots,
|
|
1588
1462
|
config: {
|
|
1589
1463
|
provider: config.provider,
|
|
1590
1464
|
model: config.model,
|
|
1591
|
-
hasApiKey: !!config.apiKey
|
|
1465
|
+
hasApiKey: !!config.apiKey,
|
|
1466
|
+
apiKeys: config.apiKeys || {}
|
|
1592
1467
|
}
|
|
1593
1468
|
}
|
|
1594
1469
|
});
|
|
@@ -1614,12 +1489,20 @@ async function handleMessage(ws, msg, state, roots, _proxyPort) {
|
|
|
1614
1489
|
}
|
|
1615
1490
|
case "fs.write": {
|
|
1616
1491
|
const payload = msg.payload;
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1492
|
+
if (!payload?.path || payload.content === void 0) {
|
|
1493
|
+
sendError(ws, "invalid_payload", "Missing path or content", msg.id);
|
|
1494
|
+
break;
|
|
1495
|
+
}
|
|
1496
|
+
const writeResult = writeFileSafe(payload.path, payload.content, roots);
|
|
1497
|
+
if (!writeResult.ok) {
|
|
1498
|
+
sendError(ws, "fs_error", writeResult.error || "Write failed", msg.id);
|
|
1499
|
+
} else {
|
|
1500
|
+
send(ws, {
|
|
1501
|
+
id: msg.id,
|
|
1502
|
+
type: "fs.written",
|
|
1503
|
+
payload: { path: payload.path, ok: true }
|
|
1504
|
+
});
|
|
1505
|
+
}
|
|
1623
1506
|
break;
|
|
1624
1507
|
}
|
|
1625
1508
|
case "fs.list": {
|
|
@@ -1636,16 +1519,18 @@ async function handleMessage(ws, msg, state, roots, _proxyPort) {
|
|
|
1636
1519
|
case "llm.chat": {
|
|
1637
1520
|
const payload = msg.payload;
|
|
1638
1521
|
const config = loadConfig();
|
|
1639
|
-
const
|
|
1640
|
-
|
|
1522
|
+
const provider = payload.provider || config.provider || "openai";
|
|
1523
|
+
const apiKey = config.apiKeys?.[provider] || config.apiKey || "";
|
|
1524
|
+
const providerMeta = MODEL_REGISTRY?.[provider];
|
|
1525
|
+
if (!apiKey && !providerMeta?.local) {
|
|
1641
1526
|
sendError(ws, "config_error", "API key not configured", msg.id);
|
|
1642
1527
|
return;
|
|
1643
1528
|
}
|
|
1644
1529
|
await handleLlmChat(
|
|
1645
1530
|
{
|
|
1646
|
-
provider
|
|
1531
|
+
provider,
|
|
1647
1532
|
model: payload.model || config.model || "gpt-4o",
|
|
1648
|
-
apiKey
|
|
1533
|
+
apiKey,
|
|
1649
1534
|
messages: payload.messages,
|
|
1650
1535
|
context: payload.context
|
|
1651
1536
|
},
|
|
@@ -1669,8 +1554,11 @@ async function handleMessage(ws, msg, state, roots, _proxyPort) {
|
|
|
1669
1554
|
payload: {
|
|
1670
1555
|
provider: config.provider,
|
|
1671
1556
|
model: config.model,
|
|
1672
|
-
hasApiKey: !!config.apiKey,
|
|
1673
|
-
roots: config.roots || roots
|
|
1557
|
+
hasApiKey: !!(config.apiKeys?.[config.provider || ""] || config.apiKey),
|
|
1558
|
+
roots: config.roots || roots,
|
|
1559
|
+
apiKeys: Object.fromEntries(
|
|
1560
|
+
Object.entries(config.apiKeys || {}).map(([k]) => [k, true])
|
|
1561
|
+
)
|
|
1674
1562
|
}
|
|
1675
1563
|
});
|
|
1676
1564
|
break;
|
|
@@ -1680,7 +1568,15 @@ async function handleMessage(ws, msg, state, roots, _proxyPort) {
|
|
|
1680
1568
|
const updates = {};
|
|
1681
1569
|
if (payload.provider !== void 0) updates.provider = payload.provider;
|
|
1682
1570
|
if (payload.model !== void 0) updates.model = payload.model;
|
|
1683
|
-
if (payload.apiKey !== void 0
|
|
1571
|
+
if (payload.apiKey !== void 0 && payload.provider) {
|
|
1572
|
+
const existing = loadConfig();
|
|
1573
|
+
const apiKeys = { ...existing.apiKeys || {} };
|
|
1574
|
+
apiKeys[payload.provider] = payload.apiKey;
|
|
1575
|
+
updates.apiKeys = apiKeys;
|
|
1576
|
+
updates.apiKey = payload.apiKey;
|
|
1577
|
+
} else if (payload.apiKey !== void 0) {
|
|
1578
|
+
updates.apiKey = payload.apiKey;
|
|
1579
|
+
}
|
|
1684
1580
|
saveConfig(updates);
|
|
1685
1581
|
send(ws, {
|
|
1686
1582
|
id: msg.id,
|
|
@@ -1699,11 +1595,7 @@ function send(ws, msg) {
|
|
|
1699
1595
|
}
|
|
1700
1596
|
}
|
|
1701
1597
|
function sendError(ws, code, message, id) {
|
|
1702
|
-
send(ws, {
|
|
1703
|
-
id: id || "error",
|
|
1704
|
-
type: "error",
|
|
1705
|
-
payload: { code, message }
|
|
1706
|
-
});
|
|
1598
|
+
send(ws, { id: id || "error", type: "error", payload: { code, message } });
|
|
1707
1599
|
}
|
|
1708
1600
|
function serveToolbarBundle(res) {
|
|
1709
1601
|
const bundlePaths = [
|
|
@@ -1730,14 +1622,124 @@ function serveToolbarBundle(res) {
|
|
|
1730
1622
|
"Content-Type": "application/javascript",
|
|
1731
1623
|
"Access-Control-Allow-Origin": "*"
|
|
1732
1624
|
});
|
|
1733
|
-
res.end(`
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1625
|
+
res.end(`(function(){var d=document.createElement("div");d.style.cssText="position:fixed;bottom:20px;right:20px;background:#1a1a2e;color:#e94560;padding:16px 24px;border-radius:12px;font-family:system-ui;font-size:14px;z-index:2147483647;box-shadow:0 4px 24px rgba(0,0,0,0.3);";d.textContent="OpenMagic: Toolbar bundle not found.";document.body.appendChild(d);})();`);
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
// src/proxy.ts
|
|
1629
|
+
var gunzipAsync = promisify(gunzip);
|
|
1630
|
+
var inflateAsync = promisify(inflate);
|
|
1631
|
+
var brotliAsync = promisify(brotliDecompress);
|
|
1632
|
+
function createProxyServer(targetHost, targetPort, roots) {
|
|
1633
|
+
const proxy = httpProxy.createProxyServer({
|
|
1634
|
+
target: `http://${targetHost}:${targetPort}`,
|
|
1635
|
+
ws: true,
|
|
1636
|
+
selfHandleResponse: true
|
|
1637
|
+
});
|
|
1638
|
+
const token = getSessionToken();
|
|
1639
|
+
proxy.on("proxyRes", (proxyRes, req, res) => {
|
|
1640
|
+
const contentType = proxyRes.headers["content-type"] || "";
|
|
1641
|
+
const isHtml = contentType.includes("text/html");
|
|
1642
|
+
if (!isHtml) {
|
|
1643
|
+
res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);
|
|
1644
|
+
proxyRes.pipe(res);
|
|
1645
|
+
return;
|
|
1646
|
+
}
|
|
1647
|
+
collectBody(proxyRes).then((body) => {
|
|
1648
|
+
const toolbarScript = buildInjectionScript(token);
|
|
1649
|
+
if (body.includes("</body>")) {
|
|
1650
|
+
body = body.replace("</body>", `${toolbarScript}</body>`);
|
|
1651
|
+
} else if (body.includes("</html>")) {
|
|
1652
|
+
body = body.replace("</html>", `${toolbarScript}</html>`);
|
|
1653
|
+
} else {
|
|
1654
|
+
body += toolbarScript;
|
|
1655
|
+
}
|
|
1656
|
+
const headers = { ...proxyRes.headers };
|
|
1657
|
+
delete headers["content-length"];
|
|
1658
|
+
delete headers["content-encoding"];
|
|
1659
|
+
delete headers["transfer-encoding"];
|
|
1660
|
+
delete headers["content-security-policy"];
|
|
1661
|
+
delete headers["content-security-policy-report-only"];
|
|
1662
|
+
delete headers["x-content-security-policy"];
|
|
1663
|
+
delete headers["etag"];
|
|
1664
|
+
delete headers["last-modified"];
|
|
1665
|
+
res.writeHead(proxyRes.statusCode || 200, headers);
|
|
1666
|
+
res.end(body);
|
|
1667
|
+
}).catch(() => {
|
|
1668
|
+
try {
|
|
1669
|
+
res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);
|
|
1670
|
+
res.end();
|
|
1671
|
+
} catch {
|
|
1672
|
+
}
|
|
1673
|
+
});
|
|
1674
|
+
});
|
|
1675
|
+
proxy.on("error", (err, _req, res) => {
|
|
1676
|
+
if (res instanceof http.ServerResponse && !res.headersSent) {
|
|
1677
|
+
const toolbarScript = buildInjectionScript(token);
|
|
1678
|
+
res.writeHead(502, { "Content-Type": "text/html" });
|
|
1679
|
+
res.end(
|
|
1680
|
+
`<html><body style="font-family:system-ui;padding:40px;background:#1a1a2e;color:#e0e0e0;">
|
|
1681
|
+
<h2 style="color:#e94560;">OpenMagic \u2014 Cannot connect to dev server</h2>
|
|
1682
|
+
<p>Could not reach <code>${targetHost}:${targetPort}</code></p>
|
|
1683
|
+
<p style="color:#888;">Make sure your dev server is running, then refresh this page.</p>
|
|
1684
|
+
<p style="color:#666;font-size:13px;">${err.message}</p>
|
|
1685
|
+
${toolbarScript}
|
|
1686
|
+
</body></html>`
|
|
1687
|
+
);
|
|
1688
|
+
}
|
|
1689
|
+
});
|
|
1690
|
+
let omHandle = null;
|
|
1691
|
+
const server = http.createServer((req, res) => {
|
|
1692
|
+
if (omHandle && omHandle(req, res)) return;
|
|
1693
|
+
proxy.web(req, res);
|
|
1694
|
+
});
|
|
1695
|
+
const om = attachOpenMagic(server, roots);
|
|
1696
|
+
omHandle = om.handleRequest;
|
|
1697
|
+
server.on("upgrade", (req, socket, head) => {
|
|
1698
|
+
if (req.url?.startsWith("/__openmagic__")) return;
|
|
1699
|
+
proxy.ws(req, socket, head);
|
|
1700
|
+
});
|
|
1701
|
+
return server;
|
|
1702
|
+
}
|
|
1703
|
+
async function collectBody(stream) {
|
|
1704
|
+
const rawBuffer = await new Promise((resolve3, reject) => {
|
|
1705
|
+
const chunks = [];
|
|
1706
|
+
stream.on("data", (chunk) => chunks.push(chunk));
|
|
1707
|
+
stream.on("end", () => resolve3(Buffer.concat(chunks)));
|
|
1708
|
+
stream.on("error", reject);
|
|
1709
|
+
});
|
|
1710
|
+
const encoding = (stream.headers["content-encoding"] || "").toLowerCase();
|
|
1711
|
+
if (!encoding || encoding === "identity") {
|
|
1712
|
+
return rawBuffer.toString("utf-8");
|
|
1713
|
+
}
|
|
1714
|
+
try {
|
|
1715
|
+
let decompressed;
|
|
1716
|
+
if (encoding === "gzip" || encoding === "x-gzip") {
|
|
1717
|
+
decompressed = await gunzipAsync(rawBuffer);
|
|
1718
|
+
} else if (encoding === "deflate") {
|
|
1719
|
+
decompressed = await inflateAsync(rawBuffer);
|
|
1720
|
+
} else if (encoding === "br") {
|
|
1721
|
+
decompressed = await brotliAsync(rawBuffer);
|
|
1722
|
+
} else {
|
|
1723
|
+
return rawBuffer.toString("utf-8");
|
|
1724
|
+
}
|
|
1725
|
+
return decompressed.toString("utf-8");
|
|
1726
|
+
} catch {
|
|
1727
|
+
return rawBuffer.toString("utf-8");
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
function buildInjectionScript(token) {
|
|
1731
|
+
return `
|
|
1732
|
+
<script data-openmagic="true">
|
|
1733
|
+
(function() {
|
|
1734
|
+
if (window.__OPENMAGIC_LOADED__) return;
|
|
1735
|
+
window.__OPENMAGIC_LOADED__ = true;
|
|
1736
|
+
window.__OPENMAGIC_TOKEN__ = "${token}";
|
|
1737
|
+
var s = document.createElement("script");
|
|
1738
|
+
s.src = "/__openmagic__/toolbar.js";
|
|
1739
|
+
s.dataset.openmagic = "true";
|
|
1740
|
+
document.body.appendChild(s);
|
|
1741
|
+
})();
|
|
1742
|
+
</script>`;
|
|
1741
1743
|
}
|
|
1742
1744
|
|
|
1743
1745
|
// src/detect.ts
|
|
@@ -1914,7 +1916,7 @@ process.on("uncaughtException", (err) => {
|
|
|
1914
1916
|
process.exit(1);
|
|
1915
1917
|
});
|
|
1916
1918
|
var childProcesses = [];
|
|
1917
|
-
var
|
|
1919
|
+
var VERSION2 = "0.11.0";
|
|
1918
1920
|
function ask(question) {
|
|
1919
1921
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
1920
1922
|
return new Promise((resolve3) => {
|
|
@@ -2026,7 +2028,7 @@ function formatDevServerLine(line) {
|
|
|
2026
2028
|
return chalk.dim(` \u2502 ${trimmed}`);
|
|
2027
2029
|
}
|
|
2028
2030
|
var program = new Command();
|
|
2029
|
-
program.name("openmagic").description("AI-powered coding toolbar for any web application").version(
|
|
2031
|
+
program.name("openmagic").description("AI-powered coding toolbar for any web application").version(VERSION2).option("-p, --port <port>", "Dev server port to proxy", "").option(
|
|
2030
2032
|
"-l, --listen <port>",
|
|
2031
2033
|
"Port for the OpenMagic proxy",
|
|
2032
2034
|
"4567"
|
|
@@ -2036,7 +2038,7 @@ program.name("openmagic").description("AI-powered coding toolbar for any web app
|
|
|
2036
2038
|
).option("--no-open", "Don't auto-open browser").option("--host <host>", "Dev server host", "127.0.0.1").action(async (opts) => {
|
|
2037
2039
|
console.log("");
|
|
2038
2040
|
console.log(
|
|
2039
|
-
chalk.bold.magenta(" \u2728 OpenMagic") + chalk.dim(` v${
|
|
2041
|
+
chalk.bold.magenta(" \u2728 OpenMagic") + chalk.dim(` v${VERSION2}`)
|
|
2040
2042
|
);
|
|
2041
2043
|
console.log("");
|
|
2042
2044
|
let targetPort;
|
|
@@ -2085,28 +2087,20 @@ program.name("openmagic").description("AI-powered coding toolbar for any web app
|
|
|
2085
2087
|
);
|
|
2086
2088
|
const config = loadConfig();
|
|
2087
2089
|
saveConfig({ ...config, roots, targetPort });
|
|
2088
|
-
|
|
2090
|
+
generateSessionToken();
|
|
2089
2091
|
let proxyPort = parseInt(opts.listen, 10);
|
|
2090
|
-
while (await isPortOpen(proxyPort)
|
|
2092
|
+
while (await isPortOpen(proxyPort)) {
|
|
2091
2093
|
proxyPort++;
|
|
2092
2094
|
if (proxyPort > parseInt(opts.listen, 10) + 100) {
|
|
2093
|
-
console.log(chalk.red(" Could not find
|
|
2095
|
+
console.log(chalk.red(" Could not find an available port."));
|
|
2094
2096
|
process.exit(1);
|
|
2095
2097
|
}
|
|
2096
2098
|
}
|
|
2097
|
-
const
|
|
2098
|
-
const { httpServer: omServer } = createOpenMagicServer(companionPort, roots);
|
|
2099
|
-
omServer.listen(companionPort, "127.0.0.1", () => {
|
|
2100
|
-
});
|
|
2101
|
-
const proxyServer = createProxyServer(
|
|
2102
|
-
targetHost,
|
|
2103
|
-
targetPort,
|
|
2104
|
-
companionPort
|
|
2105
|
-
);
|
|
2099
|
+
const proxyServer = createProxyServer(targetHost, targetPort, roots);
|
|
2106
2100
|
proxyServer.listen(proxyPort, "127.0.0.1", async () => {
|
|
2107
2101
|
console.log("");
|
|
2108
2102
|
console.log(
|
|
2109
|
-
chalk.bold.green(`
|
|
2103
|
+
chalk.bold.green(` Proxy running at \u2192 `) + chalk.bold.underline.cyan(`http://localhost:${proxyPort}`)
|
|
2110
2104
|
);
|
|
2111
2105
|
console.log("");
|
|
2112
2106
|
await healthCheck(proxyPort, targetPort);
|
|
@@ -2123,16 +2117,10 @@ program.name("openmagic").description("AI-powered coding toolbar for any web app
|
|
|
2123
2117
|
});
|
|
2124
2118
|
}
|
|
2125
2119
|
});
|
|
2126
|
-
proxyServer.on("upgrade", (req, socket, head) => {
|
|
2127
|
-
if (req.url?.startsWith("/__openmagic__")) {
|
|
2128
|
-
omServer.emit("upgrade", req, socket, head);
|
|
2129
|
-
}
|
|
2130
|
-
});
|
|
2131
2120
|
const shutdown = () => {
|
|
2132
2121
|
console.log("");
|
|
2133
2122
|
console.log(chalk.dim(" Shutting down OpenMagic..."));
|
|
2134
2123
|
proxyServer.close();
|
|
2135
|
-
omServer.close();
|
|
2136
2124
|
process.exit(0);
|
|
2137
2125
|
};
|
|
2138
2126
|
process.on("SIGINT", shutdown);
|