@elnora-ai/cli 1.5.0 → 1.5.4
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 +100 -50
- 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.4" : 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";
|
|
@@ -134,7 +134,10 @@ function scrub(text) {
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
result = result.replace(SCRUB_KEY_VALUE_RE, "[REDACTED]");
|
|
137
|
-
result = result.replace(SCRUB_LONG_TOKEN_RE,
|
|
137
|
+
result = result.replace(SCRUB_LONG_TOKEN_RE, (match) => {
|
|
138
|
+
if (match.startsWith("elnora_live_")) return "[REDACTED]";
|
|
139
|
+
return /\d/.test(match) ? "[REDACTED]" : match;
|
|
140
|
+
});
|
|
138
141
|
return result;
|
|
139
142
|
}
|
|
140
143
|
function scrubData(obj) {
|
|
@@ -1293,14 +1296,15 @@ var VSCODE_DIR = join2(HOME, ".vscode");
|
|
|
1293
1296
|
var CODEX_DIR = join2(HOME, ".codex");
|
|
1294
1297
|
var MARKETPLACE_NAME = "elnora-plugins";
|
|
1295
1298
|
var MARKETPLACE_REPO = "Elnora-AI/elnora-plugins";
|
|
1299
|
+
var MARKETPLACE_GITHUB_URL = `https://github.com/${MARKETPLACE_REPO}`;
|
|
1296
1300
|
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
1301
|
function readJsonFile(path) {
|
|
1302
|
+
if (!existsSync2(path)) return {};
|
|
1300
1303
|
try {
|
|
1301
1304
|
return JSON.parse(readFileSync2(path, "utf-8"));
|
|
1302
|
-
} catch {
|
|
1303
|
-
|
|
1305
|
+
} catch (err) {
|
|
1306
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
1307
|
+
throw new Error(`Cannot parse JSON config at ${path}: ${reason}`);
|
|
1304
1308
|
}
|
|
1305
1309
|
}
|
|
1306
1310
|
function writeJsonFile(path, data) {
|
|
@@ -1756,8 +1760,27 @@ function addOpenCommand(program2) {
|
|
|
1756
1760
|
init_profiles();
|
|
1757
1761
|
|
|
1758
1762
|
// src/lib/setup/claude.ts
|
|
1763
|
+
import { spawn } from "node:child_process";
|
|
1759
1764
|
import { existsSync as existsSync5 } from "node:fs";
|
|
1760
|
-
function
|
|
1765
|
+
function runClaudeCli(args) {
|
|
1766
|
+
return new Promise((resolve, reject) => {
|
|
1767
|
+
const child = spawn("claude", args, {
|
|
1768
|
+
stdio: "inherit",
|
|
1769
|
+
shell: process.platform === "win32"
|
|
1770
|
+
});
|
|
1771
|
+
child.on("error", (err) => reject(err));
|
|
1772
|
+
child.on("close", (code) => {
|
|
1773
|
+
if (code === 0) {
|
|
1774
|
+
resolve();
|
|
1775
|
+
return;
|
|
1776
|
+
}
|
|
1777
|
+
const err = new Error(`claude ${args.join(" ")} exited with code ${code}`);
|
|
1778
|
+
err.code = code ?? -1;
|
|
1779
|
+
reject(err);
|
|
1780
|
+
});
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
async function setupClaude() {
|
|
1761
1784
|
if (!existsSync5(CLAUDE_DIR)) {
|
|
1762
1785
|
console.error(fail("Claude Code not found (~/.claude/ does not exist)"));
|
|
1763
1786
|
console.error("");
|
|
@@ -1765,34 +1788,40 @@ function setupClaude() {
|
|
|
1765
1788
|
return false;
|
|
1766
1789
|
}
|
|
1767
1790
|
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})`));
|
|
1791
|
+
try {
|
|
1792
|
+
await runClaudeCli(["plugin", "marketplace", "add", MARKETPLACE_GITHUB_URL]);
|
|
1793
|
+
} catch (err) {
|
|
1794
|
+
return reportClaudeCliError(err, "marketplace add");
|
|
1795
|
+
}
|
|
1796
|
+
try {
|
|
1797
|
+
await runClaudeCli(["plugin", "install", PLUGIN_ID]);
|
|
1798
|
+
} catch (err) {
|
|
1799
|
+
return reportClaudeCliError(err, "plugin install");
|
|
1800
|
+
}
|
|
1791
1801
|
console.error("");
|
|
1792
1802
|
console.error(" Elnora skills are now available in Claude Code.");
|
|
1793
1803
|
console.error(" Restart Claude Code if it's currently running.");
|
|
1794
1804
|
return true;
|
|
1795
1805
|
}
|
|
1806
|
+
function reportClaudeCliError(err, step) {
|
|
1807
|
+
const e = err;
|
|
1808
|
+
if (e?.code === "ENOENT") {
|
|
1809
|
+
console.error("");
|
|
1810
|
+
console.error(fail("`claude` not found on PATH"));
|
|
1811
|
+
console.error("");
|
|
1812
|
+
console.error(" Install Claude Code first: https://claude.ai/code");
|
|
1813
|
+
console.error(" Then from a fresh terminal, run:");
|
|
1814
|
+
console.error(` claude plugin marketplace add ${MARKETPLACE_GITHUB_URL}`);
|
|
1815
|
+
console.error(` claude plugin install ${PLUGIN_ID}`);
|
|
1816
|
+
return false;
|
|
1817
|
+
}
|
|
1818
|
+
console.error("");
|
|
1819
|
+
console.error(fail(`Setup step "${step}" failed`));
|
|
1820
|
+
console.error(" To retry manually:");
|
|
1821
|
+
console.error(` claude plugin marketplace add ${MARKETPLACE_GITHUB_URL}`);
|
|
1822
|
+
console.error(` claude plugin install ${PLUGIN_ID}`);
|
|
1823
|
+
return false;
|
|
1824
|
+
}
|
|
1796
1825
|
|
|
1797
1826
|
// src/lib/setup/codex.ts
|
|
1798
1827
|
import { existsSync as existsSync6 } from "node:fs";
|
|
@@ -1806,7 +1835,14 @@ function setupCodex(apiKey) {
|
|
|
1806
1835
|
return false;
|
|
1807
1836
|
}
|
|
1808
1837
|
console.error(ok("Codex CLI found"));
|
|
1809
|
-
|
|
1838
|
+
let config;
|
|
1839
|
+
try {
|
|
1840
|
+
config = readJsonFile(CODEX_MCP_FILE);
|
|
1841
|
+
} catch (err) {
|
|
1842
|
+
console.error(fail(err instanceof Error ? err.message : String(err)));
|
|
1843
|
+
console.error(" Repair or delete the file and retry.");
|
|
1844
|
+
return false;
|
|
1845
|
+
}
|
|
1810
1846
|
if (!config.mcpServers || typeof config.mcpServers !== "object") {
|
|
1811
1847
|
config.mcpServers = {};
|
|
1812
1848
|
}
|
|
@@ -1833,7 +1869,14 @@ function setupCursor(apiKey) {
|
|
|
1833
1869
|
return false;
|
|
1834
1870
|
}
|
|
1835
1871
|
console.error(ok("Cursor found"));
|
|
1836
|
-
|
|
1872
|
+
let config;
|
|
1873
|
+
try {
|
|
1874
|
+
config = readJsonFile(CURSOR_MCP_GLOBAL);
|
|
1875
|
+
} catch (err) {
|
|
1876
|
+
console.error(fail(err instanceof Error ? err.message : String(err)));
|
|
1877
|
+
console.error(" Repair or delete the file and retry.");
|
|
1878
|
+
return false;
|
|
1879
|
+
}
|
|
1837
1880
|
if (!config.mcpServers || typeof config.mcpServers !== "object") {
|
|
1838
1881
|
config.mcpServers = {};
|
|
1839
1882
|
}
|
|
@@ -1863,7 +1906,14 @@ function setupVscode(apiKey) {
|
|
|
1863
1906
|
return false;
|
|
1864
1907
|
}
|
|
1865
1908
|
console.error(ok("VS Code found"));
|
|
1866
|
-
|
|
1909
|
+
let config;
|
|
1910
|
+
try {
|
|
1911
|
+
config = readJsonFile(VSCODE_MCP_GLOBAL);
|
|
1912
|
+
} catch (err) {
|
|
1913
|
+
console.error(fail(err instanceof Error ? err.message : String(err)));
|
|
1914
|
+
console.error(" Repair or delete the file and retry.");
|
|
1915
|
+
return false;
|
|
1916
|
+
}
|
|
1867
1917
|
if (!config.servers || typeof config.servers !== "object") {
|
|
1868
1918
|
config.servers = {};
|
|
1869
1919
|
}
|
|
@@ -1885,11 +1935,11 @@ function setupVscode(apiKey) {
|
|
|
1885
1935
|
// src/commands/setup.ts
|
|
1886
1936
|
var PLATFORM_SETUP = {
|
|
1887
1937
|
claude: () => setupClaude(),
|
|
1888
|
-
cursor: (key) => setupCursor(key),
|
|
1889
|
-
vscode: (key) => setupVscode(key),
|
|
1890
|
-
codex: (key) => setupCodex(key)
|
|
1938
|
+
cursor: async (key) => setupCursor(key),
|
|
1939
|
+
vscode: async (key) => setupVscode(key),
|
|
1940
|
+
codex: async (key) => setupCodex(key)
|
|
1891
1941
|
};
|
|
1892
|
-
function runSetup(platforms, profileName) {
|
|
1942
|
+
async function runSetup(platforms, profileName) {
|
|
1893
1943
|
let apiKey;
|
|
1894
1944
|
const needsKey = platforms.some((p) => p !== "claude");
|
|
1895
1945
|
if (needsKey) {
|
|
@@ -1906,7 +1956,7 @@ function runSetup(platforms, profileName) {
|
|
|
1906
1956
|
let anyFailed = false;
|
|
1907
1957
|
for (const platform of platforms) {
|
|
1908
1958
|
const setupFn = PLATFORM_SETUP[platform];
|
|
1909
|
-
const success = setupFn(apiKey ?? "");
|
|
1959
|
+
const success = await setupFn(apiKey ?? "");
|
|
1910
1960
|
if (!success) anyFailed = true;
|
|
1911
1961
|
console.error("");
|
|
1912
1962
|
}
|
|
@@ -1916,27 +1966,27 @@ function runSetup(platforms, profileName) {
|
|
|
1916
1966
|
}
|
|
1917
1967
|
function addSetupCommand(program2) {
|
|
1918
1968
|
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(() => {
|
|
1969
|
+
setup.command("claude").description("Set up Claude Code (skills + MCP server)").action(async () => {
|
|
1920
1970
|
const opts = setup.opts();
|
|
1921
1971
|
console.error("");
|
|
1922
|
-
runSetup(["claude"], opts.profile);
|
|
1972
|
+
await runSetup(["claude"], opts.profile);
|
|
1923
1973
|
});
|
|
1924
|
-
setup.command("cursor").description("Set up Cursor (MCP server)").action(() => {
|
|
1974
|
+
setup.command("cursor").description("Set up Cursor (MCP server)").action(async () => {
|
|
1925
1975
|
const opts = setup.opts();
|
|
1926
1976
|
console.error("");
|
|
1927
|
-
runSetup(["cursor"], opts.profile);
|
|
1977
|
+
await runSetup(["cursor"], opts.profile);
|
|
1928
1978
|
});
|
|
1929
|
-
setup.command("vscode").description("Set up VS Code Copilot (MCP server)").action(() => {
|
|
1979
|
+
setup.command("vscode").description("Set up VS Code Copilot (MCP server)").action(async () => {
|
|
1930
1980
|
const opts = setup.opts();
|
|
1931
1981
|
console.error("");
|
|
1932
|
-
runSetup(["vscode"], opts.profile);
|
|
1982
|
+
await runSetup(["vscode"], opts.profile);
|
|
1933
1983
|
});
|
|
1934
|
-
setup.command("codex").description("Set up OpenAI Codex (MCP server)").action(() => {
|
|
1984
|
+
setup.command("codex").description("Set up OpenAI Codex (MCP server)").action(async () => {
|
|
1935
1985
|
const opts = setup.opts();
|
|
1936
1986
|
console.error("");
|
|
1937
|
-
runSetup(["codex"], opts.profile);
|
|
1987
|
+
await runSetup(["codex"], opts.profile);
|
|
1938
1988
|
});
|
|
1939
|
-
setup.action(() => {
|
|
1989
|
+
setup.action(async () => {
|
|
1940
1990
|
const opts = setup.opts();
|
|
1941
1991
|
console.error("");
|
|
1942
1992
|
const detected = detectPlatforms();
|
|
@@ -1955,11 +2005,11 @@ function addSetupCommand(program2) {
|
|
|
1955
2005
|
}
|
|
1956
2006
|
console.error("");
|
|
1957
2007
|
const platforms = installed.map((p) => p.name);
|
|
1958
|
-
runSetup(platforms, opts.profile);
|
|
2008
|
+
await runSetup(platforms, opts.profile);
|
|
1959
2009
|
});
|
|
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) => {
|
|
2010
|
+
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
2011
|
console.error("");
|
|
1962
|
-
runSetup(["claude"], opts.profile);
|
|
2012
|
+
await runSetup(["claude"], opts.profile);
|
|
1963
2013
|
});
|
|
1964
2014
|
}
|
|
1965
2015
|
|