@elnora-ai/cli 1.5.0 → 1.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +96 -49
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -25,7 +25,7 @@ var VERSION, PRODUCTION_BASE_URL, BASE_URL, AI_SERVER_URL, ENDPOINTS, DEFAULT_HE
25
25
  var init_config = __esm({
26
26
  "src/lib/config.ts"() {
27
27
  "use strict";
28
- VERSION = true ? "1.5.0" : process.env.npm_package_version ?? "0.0.0-dev";
28
+ VERSION = true ? "1.5.3" : process.env.npm_package_version ?? "0.0.0-dev";
29
29
  PRODUCTION_BASE_URL = "https://platform.elnora.ai/api/v1";
30
30
  BASE_URL = process.env.ELNORA_API_URL ?? PRODUCTION_BASE_URL;
31
31
  AI_SERVER_URL = process.env.ELNORA_AI_SERVER_URL ?? "https://platform.elnora.ai/ai-server";
@@ -1293,14 +1293,15 @@ var VSCODE_DIR = join2(HOME, ".vscode");
1293
1293
  var CODEX_DIR = join2(HOME, ".codex");
1294
1294
  var MARKETPLACE_NAME = "elnora-plugins";
1295
1295
  var MARKETPLACE_REPO = "Elnora-AI/elnora-plugins";
1296
+ var MARKETPLACE_GITHUB_URL = `https://github.com/${MARKETPLACE_REPO}`;
1296
1297
  var PLUGIN_ID = `elnora@${MARKETPLACE_NAME}`;
1297
- var LEGACY_PLUGIN_IDS = ["elnora@elnora-local", "elnora@elnora-ai"];
1298
- var LEGACY_MARKETPLACE_NAMES = ["elnora-local", "elnora-ai"];
1299
1298
  function readJsonFile(path) {
1299
+ if (!existsSync2(path)) return {};
1300
1300
  try {
1301
1301
  return JSON.parse(readFileSync2(path, "utf-8"));
1302
- } catch {
1303
- return {};
1302
+ } catch (err) {
1303
+ const reason = err instanceof Error ? err.message : String(err);
1304
+ throw new Error(`Cannot parse JSON config at ${path}: ${reason}`);
1304
1305
  }
1305
1306
  }
1306
1307
  function writeJsonFile(path, data) {
@@ -1756,8 +1757,27 @@ function addOpenCommand(program2) {
1756
1757
  init_profiles();
1757
1758
 
1758
1759
  // src/lib/setup/claude.ts
1760
+ import { spawn } from "node:child_process";
1759
1761
  import { existsSync as existsSync5 } from "node:fs";
1760
- function setupClaude() {
1762
+ function runClaudeCli(args) {
1763
+ return new Promise((resolve, reject) => {
1764
+ const child = spawn("claude", args, {
1765
+ stdio: "inherit",
1766
+ shell: process.platform === "win32"
1767
+ });
1768
+ child.on("error", (err) => reject(err));
1769
+ child.on("close", (code) => {
1770
+ if (code === 0) {
1771
+ resolve();
1772
+ return;
1773
+ }
1774
+ const err = new Error(`claude ${args.join(" ")} exited with code ${code}`);
1775
+ err.code = code ?? -1;
1776
+ reject(err);
1777
+ });
1778
+ });
1779
+ }
1780
+ async function setupClaude() {
1761
1781
  if (!existsSync5(CLAUDE_DIR)) {
1762
1782
  console.error(fail("Claude Code not found (~/.claude/ does not exist)"));
1763
1783
  console.error("");
@@ -1765,34 +1785,40 @@ function setupClaude() {
1765
1785
  return false;
1766
1786
  }
1767
1787
  console.error(ok("Claude Code found"));
1768
- const marketplaces = readJsonFile(CLAUDE_MARKETPLACES_FILE);
1769
- for (const old of LEGACY_MARKETPLACE_NAMES) {
1770
- delete marketplaces[old];
1771
- }
1772
- marketplaces[MARKETPLACE_NAME] = {
1773
- source: {
1774
- source: "github",
1775
- repo: MARKETPLACE_REPO
1776
- }
1777
- };
1778
- writeJsonFile(CLAUDE_MARKETPLACES_FILE, marketplaces);
1779
- console.error(ok(`Marketplace registered (GitHub: ${MARKETPLACE_REPO})`));
1780
- const settings = readJsonFile(CLAUDE_SETTINGS_FILE);
1781
- if (!settings.enabledPlugins || typeof settings.enabledPlugins !== "object") {
1782
- settings.enabledPlugins = {};
1783
- }
1784
- const plugins = settings.enabledPlugins;
1785
- for (const old of LEGACY_PLUGIN_IDS) {
1786
- delete plugins[old];
1787
- }
1788
- plugins[PLUGIN_ID] = true;
1789
- writeJsonFile(CLAUDE_SETTINGS_FILE, settings);
1790
- console.error(ok(`Plugin enabled (${PLUGIN_ID})`));
1788
+ try {
1789
+ await runClaudeCli(["plugin", "marketplace", "add", MARKETPLACE_GITHUB_URL]);
1790
+ } catch (err) {
1791
+ return reportClaudeCliError(err, "marketplace add");
1792
+ }
1793
+ try {
1794
+ await runClaudeCli(["plugin", "install", PLUGIN_ID]);
1795
+ } catch (err) {
1796
+ return reportClaudeCliError(err, "plugin install");
1797
+ }
1791
1798
  console.error("");
1792
1799
  console.error(" Elnora skills are now available in Claude Code.");
1793
1800
  console.error(" Restart Claude Code if it's currently running.");
1794
1801
  return true;
1795
1802
  }
1803
+ function reportClaudeCliError(err, step) {
1804
+ const e = err;
1805
+ if (e?.code === "ENOENT") {
1806
+ console.error("");
1807
+ console.error(fail("`claude` not found on PATH"));
1808
+ console.error("");
1809
+ console.error(" Install Claude Code first: https://claude.ai/code");
1810
+ console.error(" Then from a fresh terminal, run:");
1811
+ console.error(` claude plugin marketplace add ${MARKETPLACE_GITHUB_URL}`);
1812
+ console.error(` claude plugin install ${PLUGIN_ID}`);
1813
+ return false;
1814
+ }
1815
+ console.error("");
1816
+ console.error(fail(`Setup step "${step}" failed`));
1817
+ console.error(" To retry manually:");
1818
+ console.error(` claude plugin marketplace add ${MARKETPLACE_GITHUB_URL}`);
1819
+ console.error(` claude plugin install ${PLUGIN_ID}`);
1820
+ return false;
1821
+ }
1796
1822
 
1797
1823
  // src/lib/setup/codex.ts
1798
1824
  import { existsSync as existsSync6 } from "node:fs";
@@ -1806,7 +1832,14 @@ function setupCodex(apiKey) {
1806
1832
  return false;
1807
1833
  }
1808
1834
  console.error(ok("Codex CLI found"));
1809
- const config = readJsonFile(CODEX_MCP_FILE);
1835
+ let config;
1836
+ try {
1837
+ config = readJsonFile(CODEX_MCP_FILE);
1838
+ } catch (err) {
1839
+ console.error(fail(err instanceof Error ? err.message : String(err)));
1840
+ console.error(" Repair or delete the file and retry.");
1841
+ return false;
1842
+ }
1810
1843
  if (!config.mcpServers || typeof config.mcpServers !== "object") {
1811
1844
  config.mcpServers = {};
1812
1845
  }
@@ -1833,7 +1866,14 @@ function setupCursor(apiKey) {
1833
1866
  return false;
1834
1867
  }
1835
1868
  console.error(ok("Cursor found"));
1836
- const config = readJsonFile(CURSOR_MCP_GLOBAL);
1869
+ let config;
1870
+ try {
1871
+ config = readJsonFile(CURSOR_MCP_GLOBAL);
1872
+ } catch (err) {
1873
+ console.error(fail(err instanceof Error ? err.message : String(err)));
1874
+ console.error(" Repair or delete the file and retry.");
1875
+ return false;
1876
+ }
1837
1877
  if (!config.mcpServers || typeof config.mcpServers !== "object") {
1838
1878
  config.mcpServers = {};
1839
1879
  }
@@ -1863,7 +1903,14 @@ function setupVscode(apiKey) {
1863
1903
  return false;
1864
1904
  }
1865
1905
  console.error(ok("VS Code found"));
1866
- const config = readJsonFile(VSCODE_MCP_GLOBAL);
1906
+ let config;
1907
+ try {
1908
+ config = readJsonFile(VSCODE_MCP_GLOBAL);
1909
+ } catch (err) {
1910
+ console.error(fail(err instanceof Error ? err.message : String(err)));
1911
+ console.error(" Repair or delete the file and retry.");
1912
+ return false;
1913
+ }
1867
1914
  if (!config.servers || typeof config.servers !== "object") {
1868
1915
  config.servers = {};
1869
1916
  }
@@ -1885,11 +1932,11 @@ function setupVscode(apiKey) {
1885
1932
  // src/commands/setup.ts
1886
1933
  var PLATFORM_SETUP = {
1887
1934
  claude: () => setupClaude(),
1888
- cursor: (key) => setupCursor(key),
1889
- vscode: (key) => setupVscode(key),
1890
- codex: (key) => setupCodex(key)
1935
+ cursor: async (key) => setupCursor(key),
1936
+ vscode: async (key) => setupVscode(key),
1937
+ codex: async (key) => setupCodex(key)
1891
1938
  };
1892
- function runSetup(platforms, profileName) {
1939
+ async function runSetup(platforms, profileName) {
1893
1940
  let apiKey;
1894
1941
  const needsKey = platforms.some((p) => p !== "claude");
1895
1942
  if (needsKey) {
@@ -1906,7 +1953,7 @@ function runSetup(platforms, profileName) {
1906
1953
  let anyFailed = false;
1907
1954
  for (const platform of platforms) {
1908
1955
  const setupFn = PLATFORM_SETUP[platform];
1909
- const success = setupFn(apiKey ?? "");
1956
+ const success = await setupFn(apiKey ?? "");
1910
1957
  if (!success) anyFailed = true;
1911
1958
  console.error("");
1912
1959
  }
@@ -1916,27 +1963,27 @@ function runSetup(platforms, profileName) {
1916
1963
  }
1917
1964
  function addSetupCommand(program2) {
1918
1965
  const setup = program2.command("setup").description("Configure AI coding tools to use Elnora").option("--profile <name>", "API key profile to use", "default");
1919
- setup.command("claude").description("Set up Claude Code (skills + MCP server)").action(() => {
1966
+ setup.command("claude").description("Set up Claude Code (skills + MCP server)").action(async () => {
1920
1967
  const opts = setup.opts();
1921
1968
  console.error("");
1922
- runSetup(["claude"], opts.profile);
1969
+ await runSetup(["claude"], opts.profile);
1923
1970
  });
1924
- setup.command("cursor").description("Set up Cursor (MCP server)").action(() => {
1971
+ setup.command("cursor").description("Set up Cursor (MCP server)").action(async () => {
1925
1972
  const opts = setup.opts();
1926
1973
  console.error("");
1927
- runSetup(["cursor"], opts.profile);
1974
+ await runSetup(["cursor"], opts.profile);
1928
1975
  });
1929
- setup.command("vscode").description("Set up VS Code Copilot (MCP server)").action(() => {
1976
+ setup.command("vscode").description("Set up VS Code Copilot (MCP server)").action(async () => {
1930
1977
  const opts = setup.opts();
1931
1978
  console.error("");
1932
- runSetup(["vscode"], opts.profile);
1979
+ await runSetup(["vscode"], opts.profile);
1933
1980
  });
1934
- setup.command("codex").description("Set up OpenAI Codex (MCP server)").action(() => {
1981
+ setup.command("codex").description("Set up OpenAI Codex (MCP server)").action(async () => {
1935
1982
  const opts = setup.opts();
1936
1983
  console.error("");
1937
- runSetup(["codex"], opts.profile);
1984
+ await runSetup(["codex"], opts.profile);
1938
1985
  });
1939
- setup.action(() => {
1986
+ setup.action(async () => {
1940
1987
  const opts = setup.opts();
1941
1988
  console.error("");
1942
1989
  const detected = detectPlatforms();
@@ -1955,11 +2002,11 @@ function addSetupCommand(program2) {
1955
2002
  }
1956
2003
  console.error("");
1957
2004
  const platforms = installed.map((p) => p.name);
1958
- runSetup(platforms, opts.profile);
2005
+ await runSetup(platforms, opts.profile);
1959
2006
  });
1960
- program2.command("setup-claude").description("Set up Claude Code (alias for 'setup claude')").option("--profile <name>", "API key profile to use", "default").action((opts) => {
2007
+ program2.command("setup-claude").description("Set up Claude Code (alias for 'setup claude')").option("--profile <name>", "API key profile to use", "default").action(async (opts) => {
1961
2008
  console.error("");
1962
- runSetup(["claude"], opts.profile);
2009
+ await runSetup(["claude"], opts.profile);
1963
2010
  });
1964
2011
  }
1965
2012
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elnora-ai/cli",
3
- "version": "1.5.0",
3
+ "version": "1.5.3",
4
4
  "description": "Elnora AI Platform CLI",
5
5
  "type": "module",
6
6
  "bin": {