openmagic 0.4.0 → 0.6.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 CHANGED
@@ -71,6 +71,7 @@ function createProxyServer(targetHost, targetPort, serverPort) {
71
71
  });
72
72
  proxy.on("error", (err, _req, res) => {
73
73
  if (res instanceof http.ServerResponse && !res.headersSent) {
74
+ const toolbarScript = buildInjectionScript(serverPort, token);
74
75
  res.writeHead(502, { "Content-Type": "text/html" });
75
76
  res.end(
76
77
  `<html><body style="font-family:system-ui;padding:40px;background:#1a1a2e;color:#e0e0e0;">
@@ -78,6 +79,7 @@ function createProxyServer(targetHost, targetPort, serverPort) {
78
79
  <p>Could not reach <code>${targetHost}:${targetPort}</code></p>
79
80
  <p style="color:#888;">Make sure your dev server is running, then refresh this page.</p>
80
81
  <p style="color:#666;font-size:13px;">${err.message}</p>
82
+ ${toolbarScript}
81
83
  </body></html>`
82
84
  );
83
85
  }
@@ -894,6 +896,94 @@ var MODEL_REGISTRY = {
894
896
  keyPrefix: "gsk_",
895
897
  keyPlaceholder: "gsk_..."
896
898
  },
899
+ // ─── MiniMax ───────────────────────────────────────────────────
900
+ minimax: {
901
+ name: "MiniMax",
902
+ models: [
903
+ { id: "MiniMax-M2.7", name: "MiniMax M2.7", vision: true, context: 1048576, maxOutput: 16384 },
904
+ { id: "MiniMax-M2.7-highspeed", name: "MiniMax M2.7 Highspeed", vision: true, context: 1048576, maxOutput: 16384 },
905
+ { id: "MiniMax-M2.5", name: "MiniMax M2.5", vision: true, context: 1048576, maxOutput: 16384 },
906
+ { id: "MiniMax-M2.5-highspeed", name: "MiniMax M2.5 Highspeed", vision: true, context: 1048576, maxOutput: 16384 }
907
+ ],
908
+ apiBase: "https://api.minimax.chat/v1",
909
+ keyPrefix: "",
910
+ keyPlaceholder: "Enter MiniMax API key..."
911
+ },
912
+ // ─── Moonshot / Kimi ──────────────────────────────────────────
913
+ moonshot: {
914
+ name: "Kimi (Moonshot)",
915
+ models: [
916
+ {
917
+ id: "kimi-k2.5",
918
+ name: "Kimi K2.5",
919
+ vision: true,
920
+ context: 262144,
921
+ maxOutput: 16384,
922
+ thinking: {
923
+ supported: true,
924
+ paramName: "reasoning_effort",
925
+ paramType: "level",
926
+ levels: ["low", "medium", "high"],
927
+ defaultLevel: "medium"
928
+ }
929
+ },
930
+ {
931
+ id: "kimi-k2-thinking",
932
+ name: "Kimi K2 Thinking",
933
+ vision: false,
934
+ context: 262144,
935
+ maxOutput: 16384,
936
+ thinking: {
937
+ supported: true,
938
+ paramName: "reasoning_effort",
939
+ paramType: "level",
940
+ levels: ["low", "medium", "high"],
941
+ defaultLevel: "high"
942
+ }
943
+ }
944
+ ],
945
+ apiBase: "https://api.moonshot.cn/v1",
946
+ keyPrefix: "",
947
+ keyPlaceholder: "Enter Moonshot API key..."
948
+ },
949
+ // ─── Alibaba Qwen (DashScope) ────────────────────────────────
950
+ qwen: {
951
+ name: "Qwen (Alibaba)",
952
+ models: [
953
+ { id: "qwen3.5-plus", name: "Qwen 3.5 Plus", vision: true, context: 101e4, maxOutput: 16384 },
954
+ { id: "qwen-plus", name: "Qwen Plus", vision: false, context: 131072, maxOutput: 16384 },
955
+ { id: "qwen-max", name: "Qwen Max", vision: false, context: 131072, maxOutput: 16384 },
956
+ { id: "qwen-turbo", name: "Qwen Turbo", vision: false, context: 131072, maxOutput: 8192 }
957
+ ],
958
+ apiBase: "https://dashscope.aliyuncs.com/compatible-mode/v1",
959
+ keyPrefix: "",
960
+ keyPlaceholder: "Enter DashScope API key..."
961
+ },
962
+ // ─── Zhipu AI (GLM) ──────────────────────────────────────────
963
+ zhipu: {
964
+ name: "Zhipu AI (GLM)",
965
+ models: [
966
+ { id: "glm-5", name: "GLM-5", vision: true, context: 131072, maxOutput: 16384 },
967
+ { id: "glm-4.7", name: "GLM-4.7", vision: true, context: 131072, maxOutput: 16384 },
968
+ { id: "glm-4.6", name: "GLM-4.6", vision: true, context: 131072, maxOutput: 16384 },
969
+ { id: "glm-4.5", name: "GLM-4.5", vision: true, context: 131072, maxOutput: 16384 }
970
+ ],
971
+ apiBase: "https://open.bigmodel.cn/api/paas/v4",
972
+ keyPrefix: "",
973
+ keyPlaceholder: "Enter Zhipu API key..."
974
+ },
975
+ // ─── ByteDance Doubao ─────────────────────────────────────────
976
+ doubao: {
977
+ name: "Doubao (ByteDance)",
978
+ models: [
979
+ { id: "doubao-seed-2-0-pro", name: "Doubao Seed 2.0 Pro", vision: false, context: 131072, maxOutput: 16384 },
980
+ { id: "doubao-seed-2-0-lite", name: "Doubao Seed 2.0 Lite", vision: false, context: 131072, maxOutput: 8192 },
981
+ { id: "doubao-seed-2-0-code", name: "Doubao Seed 2.0 Code", vision: false, context: 131072, maxOutput: 16384 }
982
+ ],
983
+ apiBase: "https://ark.cn-beijing.volces.com/api/v3",
984
+ keyPrefix: "",
985
+ keyPlaceholder: "Enter Volcano Engine API key..."
986
+ },
897
987
  // ─── Ollama (Local) ───────────────────────────────────────────
898
988
  ollama: {
899
989
  name: "Ollama (Local)",
@@ -1360,7 +1450,12 @@ var OPENAI_COMPATIBLE_PROVIDERS = /* @__PURE__ */ new Set([
1360
1450
  "mistral",
1361
1451
  "xai",
1362
1452
  "ollama",
1363
- "openrouter"
1453
+ "openrouter",
1454
+ "minimax",
1455
+ "moonshot",
1456
+ "qwen",
1457
+ "zhipu",
1458
+ "doubao"
1364
1459
  ]);
1365
1460
  async function handleLlmChat(params, onChunk, onDone, onError) {
1366
1461
  const { provider, model, apiKey, messages, context } = params;
@@ -1419,7 +1514,7 @@ function createOpenMagicServer(proxyPort, roots) {
1419
1514
  "Content-Type": "application/json",
1420
1515
  "Access-Control-Allow-Origin": "*"
1421
1516
  });
1422
- res.end(JSON.stringify({ status: "ok", version: "0.4.0" }));
1517
+ res.end(JSON.stringify({ status: "ok", version: "0.6.0" }));
1423
1518
  return;
1424
1519
  }
1425
1520
  res.writeHead(404);
@@ -1477,7 +1572,7 @@ async function handleMessage(ws, msg, state, roots, _proxyPort) {
1477
1572
  id: msg.id,
1478
1573
  type: "handshake.ok",
1479
1574
  payload: {
1480
- version: "0.4.0",
1575
+ version: "0.6.0",
1481
1576
  roots,
1482
1577
  config: {
1483
1578
  provider: config.provider,
@@ -1803,6 +1898,11 @@ function checkDependenciesInstalled(cwd = process.cwd()) {
1803
1898
  }
1804
1899
 
1805
1900
  // src/cli.ts
1901
+ var origEmitWarning = process.emitWarning;
1902
+ process.emitWarning = function(warning, ...args) {
1903
+ if (typeof warning === "string" && warning.includes("util._extend")) return;
1904
+ return origEmitWarning.call(process, warning, ...args);
1905
+ };
1806
1906
  process.on("unhandledRejection", (err) => {
1807
1907
  console.error(chalk.red("\n [OpenMagic] Unhandled error:"), err?.message || err);
1808
1908
  console.error(chalk.dim(" Please report this at https://github.com/Kalmuraee/OpenMagic/issues"));
@@ -1813,7 +1913,7 @@ process.on("uncaughtException", (err) => {
1813
1913
  process.exit(1);
1814
1914
  });
1815
1915
  var childProcesses = [];
1816
- var VERSION = "0.4.0";
1916
+ var VERSION = "0.6.0";
1817
1917
  function ask(question) {
1818
1918
  const rl = createInterface({ input: process.stdin, output: process.stdout });
1819
1919
  return new Promise((resolve3) => {
@@ -1873,6 +1973,57 @@ function runCommand(cmd, args, cwd = process.cwd()) {
1873
1973
  }
1874
1974
  });
1875
1975
  }
1976
+ async function healthCheck(proxyPort, targetPort) {
1977
+ try {
1978
+ const controller = new AbortController();
1979
+ const timeout = setTimeout(() => controller.abort(), 5e3);
1980
+ const res = await fetch(`http://127.0.0.1:${proxyPort}/`, {
1981
+ signal: controller.signal,
1982
+ headers: { Accept: "text/html" }
1983
+ });
1984
+ clearTimeout(timeout);
1985
+ if (res.ok) {
1986
+ const text = await res.text();
1987
+ if (text.includes("__OPENMAGIC_LOADED__")) {
1988
+ console.log(chalk.green(" \u2713 Toolbar injection verified."));
1989
+ } else {
1990
+ console.log(chalk.yellow(" \u26A0 Page loaded but toolbar may not have injected (non-HTML response or CSP)."));
1991
+ }
1992
+ } else {
1993
+ console.log(
1994
+ chalk.yellow(` \u26A0 Dev server returned ${res.status}. Pages may have errors.`)
1995
+ );
1996
+ console.log(
1997
+ chalk.dim(" The toolbar will still appear on pages that load successfully.")
1998
+ );
1999
+ }
2000
+ } catch {
2001
+ console.log(
2002
+ chalk.yellow(" \u26A0 Could not verify proxy. The dev server may still be starting.")
2003
+ );
2004
+ console.log(
2005
+ chalk.dim(" Try refreshing the page in a few seconds.")
2006
+ );
2007
+ }
2008
+ console.log("");
2009
+ }
2010
+ function formatDevServerLine(line) {
2011
+ const trimmed = line.trim();
2012
+ if (!trimmed) return "";
2013
+ if (trimmed.startsWith("Error:") || trimmed.includes("ModuleNotFoundError") || trimmed.includes("Can't resolve")) {
2014
+ return chalk.red(` \u2502 ${trimmed}`);
2015
+ }
2016
+ if (trimmed.includes("EADDRINUSE") || trimmed.includes("address already in use")) {
2017
+ return chalk.red(` \u2502 ${trimmed}`) + "\n" + chalk.yellow(" \u2502 \u2192 Port is already in use. Stop the other process or use --port <different-port>");
2018
+ }
2019
+ if (trimmed.includes("EACCES") || trimmed.includes("permission denied")) {
2020
+ return chalk.red(` \u2502 ${trimmed}`) + "\n" + chalk.yellow(" \u2502 \u2192 Permission denied. Try a different port or check file permissions.");
2021
+ }
2022
+ if (trimmed.includes("Cannot find module") || trimmed.includes("MODULE_NOT_FOUND")) {
2023
+ return chalk.red(` \u2502 ${trimmed}`) + "\n" + chalk.yellow(" \u2502 \u2192 Missing dependency. Try running npm install.");
2024
+ }
2025
+ return chalk.dim(` \u2502 ${trimmed}`);
2026
+ }
1876
2027
  var program = new Command();
1877
2028
  program.name("openmagic").description("AI-powered coding toolbar for any web application").version(VERSION).option("-p, --port <port>", "Dev server port to proxy", "").option(
1878
2029
  "-l, --listen <port>",
@@ -1941,16 +2092,20 @@ program.name("openmagic").description("AI-powered coding toolbar for any web app
1941
2092
  targetPort,
1942
2093
  proxyPort + 1
1943
2094
  );
1944
- proxyServer.listen(proxyPort, "127.0.0.1", () => {
2095
+ proxyServer.listen(proxyPort, "127.0.0.1", async () => {
1945
2096
  console.log("");
1946
2097
  console.log(
1947
2098
  chalk.bold.green(` \u{1F680} Proxy running at \u2192 `) + chalk.bold.underline.cyan(`http://localhost:${proxyPort}`)
1948
2099
  );
1949
2100
  console.log("");
2101
+ await healthCheck(proxyPort, targetPort);
1950
2102
  console.log(
1951
2103
  chalk.dim(" Open the URL above in your browser to start.")
1952
2104
  );
1953
2105
  console.log(chalk.dim(" Press Ctrl+C to stop."));
2106
+ console.log(
2107
+ chalk.dim(" Errors below are from your dev server, not OpenMagic.")
2108
+ );
1954
2109
  console.log("");
1955
2110
  if (opts.open !== false) {
1956
2111
  open(`http://localhost:${proxyPort}`).catch(() => {
@@ -2095,14 +2250,14 @@ async function offerToStartDevServer(expectedPort) {
2095
2250
  let childExited = false;
2096
2251
  child.stdout?.on("data", (data) => {
2097
2252
  for (const line of data.toString().trim().split("\n")) {
2098
- if (line.trim()) process.stdout.write(chalk.dim(` \u2502 ${line}
2099
- `));
2253
+ const formatted = formatDevServerLine(line);
2254
+ if (formatted) process.stdout.write(formatted + "\n");
2100
2255
  }
2101
2256
  });
2102
2257
  child.stderr?.on("data", (data) => {
2103
2258
  for (const line of data.toString().trim().split("\n")) {
2104
- if (line.trim()) process.stdout.write(chalk.dim(` \u2502 ${line}
2105
- `));
2259
+ const formatted = formatDevServerLine(line);
2260
+ if (formatted) process.stdout.write(formatted + "\n");
2106
2261
  }
2107
2262
  });
2108
2263
  child.on("error", (err) => {