@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.
- package/dist/cli.js +96 -49
- 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.
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|