@elsium-ai/cli 0.1.7 → 0.2.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 +54 -54
- package/package.json +2 -3
package/dist/cli.js
CHANGED
|
@@ -109,7 +109,7 @@ var init_errors = __esm(() => {
|
|
|
109
109
|
};
|
|
110
110
|
});
|
|
111
111
|
// ../core/src/utils.ts
|
|
112
|
-
import { randomBytes } from "crypto";
|
|
112
|
+
import { randomBytes } from "node:crypto";
|
|
113
113
|
function cryptoHex(bytes) {
|
|
114
114
|
return randomBytes(bytes).toString("hex");
|
|
115
115
|
}
|
|
@@ -489,7 +489,7 @@ var init_mock_provider = __esm(() => {
|
|
|
489
489
|
});
|
|
490
490
|
|
|
491
491
|
// ../testing/src/fixtures.ts
|
|
492
|
-
import { createHash } from "crypto";
|
|
492
|
+
import { createHash } from "node:crypto";
|
|
493
493
|
function hashMessages(messages) {
|
|
494
494
|
const content = messages.map((m) => `${m.role}:${m.content}`).join("|");
|
|
495
495
|
return createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
@@ -855,7 +855,7 @@ function formatEvalReport(result) {
|
|
|
855
855
|
const lines = [];
|
|
856
856
|
lines.push(`
|
|
857
857
|
Eval Suite: ${result.name}`);
|
|
858
|
-
lines.push(` ${"
|
|
858
|
+
lines.push(` ${"─".repeat(50)}`);
|
|
859
859
|
for (const r of result.results) {
|
|
860
860
|
const icon = r.passed ? "PASS" : "FAIL";
|
|
861
861
|
lines.push(` [${icon}] ${r.name} (${r.durationMs}ms)`);
|
|
@@ -867,7 +867,7 @@ function formatEvalReport(result) {
|
|
|
867
867
|
}
|
|
868
868
|
}
|
|
869
869
|
}
|
|
870
|
-
lines.push(` ${"
|
|
870
|
+
lines.push(` ${"─".repeat(50)}`);
|
|
871
871
|
lines.push(` Score: ${(result.score * 100).toFixed(1)}% | ${result.passed}/${result.total} passed | ${result.durationMs}ms`);
|
|
872
872
|
lines.push("");
|
|
873
873
|
return lines.join(`
|
|
@@ -875,7 +875,7 @@ function formatEvalReport(result) {
|
|
|
875
875
|
}
|
|
876
876
|
|
|
877
877
|
// ../testing/src/snapshot.ts
|
|
878
|
-
import { createHash as createHash2 } from "crypto";
|
|
878
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
879
879
|
function createSnapshotStore(existing) {
|
|
880
880
|
const snapshots = new Map;
|
|
881
881
|
if (existing) {
|
|
@@ -1053,8 +1053,8 @@ function createPromptRegistry() {
|
|
|
1053
1053
|
}
|
|
1054
1054
|
|
|
1055
1055
|
// ../testing/src/regression.ts
|
|
1056
|
-
import { mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
1057
|
-
import { dirname } from "path";
|
|
1056
|
+
import { mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
|
|
1057
|
+
import { dirname } from "node:path";
|
|
1058
1058
|
function makeEmptyResult(name) {
|
|
1059
1059
|
return {
|
|
1060
1060
|
name,
|
|
@@ -1212,7 +1212,7 @@ function createReplayPlayer(entriesOrJson) {
|
|
|
1212
1212
|
}
|
|
1213
1213
|
|
|
1214
1214
|
// ../testing/src/pinning.ts
|
|
1215
|
-
import { createHash as createHash3 } from "crypto";
|
|
1215
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
1216
1216
|
function sha256(input) {
|
|
1217
1217
|
return createHash3("sha256").update(input).digest("hex");
|
|
1218
1218
|
}
|
|
@@ -1362,8 +1362,8 @@ var init_src2 = __esm(() => {
|
|
|
1362
1362
|
});
|
|
1363
1363
|
|
|
1364
1364
|
// src/commands/cost.ts
|
|
1365
|
-
import { existsSync, readFileSync } from "fs";
|
|
1366
|
-
import { join } from "path";
|
|
1365
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
1366
|
+
import { join } from "node:path";
|
|
1367
1367
|
var COST_FILE = ".elsium/cost-report.json";
|
|
1368
1368
|
async function costCommand(args) {
|
|
1369
1369
|
const costPath = join(process.cwd(), COST_FILE);
|
|
@@ -1388,7 +1388,7 @@ async function costCommand(args) {
|
|
|
1388
1388
|
const data = JSON.parse(readFileSync(costPath, "utf-8"));
|
|
1389
1389
|
console.log(`
|
|
1390
1390
|
ElsiumAI Cost Report`);
|
|
1391
|
-
console.log(` ${"
|
|
1391
|
+
console.log(` ${"─".repeat(50)}`);
|
|
1392
1392
|
console.log(` Generated: ${data.timestamp}`);
|
|
1393
1393
|
console.log();
|
|
1394
1394
|
console.log(` Total Cost: $${data.totalCost.toFixed(6)}`);
|
|
@@ -1399,7 +1399,7 @@ async function costCommand(args) {
|
|
|
1399
1399
|
console.log();
|
|
1400
1400
|
if (Object.keys(data.byModel).length > 0) {
|
|
1401
1401
|
console.log(" By Model:");
|
|
1402
|
-
console.log(` ${"
|
|
1402
|
+
console.log(` ${"─".repeat(50)}`);
|
|
1403
1403
|
for (const [model, stats] of Object.entries(data.byModel)) {
|
|
1404
1404
|
console.log(` ${model}`);
|
|
1405
1405
|
console.log(` Cost: $${stats.cost.toFixed(6)}`);
|
|
@@ -1415,9 +1415,9 @@ async function costCommand(args) {
|
|
|
1415
1415
|
}
|
|
1416
1416
|
|
|
1417
1417
|
// src/commands/dev.ts
|
|
1418
|
-
import { spawn } from "child_process";
|
|
1419
|
-
import { existsSync as existsSync2 } from "fs";
|
|
1420
|
-
import { resolve } from "path";
|
|
1418
|
+
import { spawn } from "node:child_process";
|
|
1419
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
1420
|
+
import { resolve } from "node:path";
|
|
1421
1421
|
async function devCommand(args) {
|
|
1422
1422
|
const entryFile = args[0] ?? "src/index.ts";
|
|
1423
1423
|
const cwd = process.cwd();
|
|
@@ -1453,8 +1453,8 @@ async function devCommand(args) {
|
|
|
1453
1453
|
}
|
|
1454
1454
|
|
|
1455
1455
|
// src/commands/eval.ts
|
|
1456
|
-
import { existsSync as existsSync3 } from "fs";
|
|
1457
|
-
import { join as join2 } from "path";
|
|
1456
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
1457
|
+
import { join as join2 } from "node:path";
|
|
1458
1458
|
async function evalCommand(args) {
|
|
1459
1459
|
const evalFile = args[0];
|
|
1460
1460
|
if (!evalFile) {
|
|
@@ -1520,8 +1520,8 @@ async function evalCommand(args) {
|
|
|
1520
1520
|
}
|
|
1521
1521
|
|
|
1522
1522
|
// src/commands/init.ts
|
|
1523
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
1524
|
-
import { join as join3 } from "path";
|
|
1523
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
1524
|
+
import { join as join3 } from "node:path";
|
|
1525
1525
|
async function initCommand(args) {
|
|
1526
1526
|
const projectName = args[0] ?? "my-elsium-app";
|
|
1527
1527
|
const projectDir = join3(process.cwd(), projectName);
|
|
@@ -1608,7 +1608,7 @@ function packageJsonContent(projectName) {
|
|
|
1608
1608
|
devDependencies: {
|
|
1609
1609
|
"@elsium-ai/testing": "^0.1.0",
|
|
1610
1610
|
"@biomejs/biome": "^1.9.0",
|
|
1611
|
-
"
|
|
1611
|
+
"@types/node": "^22.0.0",
|
|
1612
1612
|
typescript: "^5.7.0",
|
|
1613
1613
|
vitest: "^3.0.0"
|
|
1614
1614
|
}
|
|
@@ -1624,7 +1624,7 @@ function tsconfigContent() {
|
|
|
1624
1624
|
strict: true,
|
|
1625
1625
|
esModuleInterop: true,
|
|
1626
1626
|
skipLibCheck: true,
|
|
1627
|
-
types: ["
|
|
1627
|
+
types: ["node"]
|
|
1628
1628
|
},
|
|
1629
1629
|
include: ["src", "evals", "test", "elsium.config.ts"]
|
|
1630
1630
|
}, null, 2)}
|
|
@@ -1647,7 +1647,7 @@ function biomeJsonContent() {
|
|
|
1647
1647
|
`;
|
|
1648
1648
|
}
|
|
1649
1649
|
function envExampleContent() {
|
|
1650
|
-
return `# Provider API keys
|
|
1650
|
+
return `# Provider API keys — add at least one
|
|
1651
1651
|
ANTHROPIC_API_KEY=your-anthropic-key-here
|
|
1652
1652
|
OPENAI_API_KEY=your-openai-key-here
|
|
1653
1653
|
`;
|
|
@@ -1703,8 +1703,8 @@ import { env } from '@elsium-ai/core'
|
|
|
1703
1703
|
|
|
1704
1704
|
export const mesh = createProviderMesh({
|
|
1705
1705
|
providers: [
|
|
1706
|
-
{ name: 'anthropic', config: { apiKey: env('ANTHROPIC_API_KEY') }
|
|
1707
|
-
{ name: 'openai', config: { apiKey: env('OPENAI_API_KEY') }
|
|
1706
|
+
{ name: 'anthropic', config: { apiKey: env('ANTHROPIC_API_KEY') } },
|
|
1707
|
+
{ name: 'openai', config: { apiKey: env('OPENAI_API_KEY') } },
|
|
1708
1708
|
],
|
|
1709
1709
|
strategy: 'fallback',
|
|
1710
1710
|
circuitBreaker: {
|
|
@@ -1919,19 +1919,19 @@ bun run dev
|
|
|
1919
1919
|
|
|
1920
1920
|
## Project structure
|
|
1921
1921
|
|
|
1922
|
-
- **src/agents/**
|
|
1923
|
-
- **src/tools/**
|
|
1924
|
-
- **src/policies/**
|
|
1925
|
-
- **src/gateway/**
|
|
1926
|
-
- **src/workflows/**
|
|
1927
|
-
- **evals/**
|
|
1928
|
-
- **test/**
|
|
1922
|
+
- **src/agents/** — Agent definitions with guardrails
|
|
1923
|
+
- **src/tools/** — Tool schemas validated by Zod
|
|
1924
|
+
- **src/policies/** — Policy sets (model allowlist, cost caps)
|
|
1925
|
+
- **src/gateway/** — Provider mesh with circuit breaker
|
|
1926
|
+
- **src/workflows/** — Multi-step workflows
|
|
1927
|
+
- **evals/** — Eval suites (quality + determinism)
|
|
1928
|
+
- **test/** — Unit tests with mock providers and replay
|
|
1929
1929
|
`;
|
|
1930
1930
|
}
|
|
1931
1931
|
|
|
1932
1932
|
// src/commands/prompt.ts
|
|
1933
|
-
import { existsSync as existsSync5, readFileSync as readFileSync3, readdirSync } from "fs";
|
|
1934
|
-
import { join as join4 } from "path";
|
|
1933
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, readdirSync } from "node:fs";
|
|
1934
|
+
import { join as join4 } from "node:path";
|
|
1935
1935
|
var PROMPTS_DIR = ".elsium/prompts";
|
|
1936
1936
|
function showHelp() {
|
|
1937
1937
|
console.log(`
|
|
@@ -1976,9 +1976,9 @@ function handleList(promptsPath) {
|
|
|
1976
1976
|
}
|
|
1977
1977
|
console.log(`
|
|
1978
1978
|
Registered Prompts (${prompts.size})`);
|
|
1979
|
-
console.log(` ${"
|
|
1979
|
+
console.log(` ${"─".repeat(50)}`);
|
|
1980
1980
|
for (const [name, versions] of prompts) {
|
|
1981
|
-
console.log(` ${name}
|
|
1981
|
+
console.log(` ${name} — ${versions.length} version(s): ${versions.join(", ")}`);
|
|
1982
1982
|
}
|
|
1983
1983
|
console.log();
|
|
1984
1984
|
}
|
|
@@ -1992,9 +1992,9 @@ function handleHistory(promptsPath, name) {
|
|
|
1992
1992
|
}
|
|
1993
1993
|
console.log(`
|
|
1994
1994
|
Prompt History: ${name} (${files.length} versions)`);
|
|
1995
|
-
console.log(` ${"
|
|
1995
|
+
console.log(` ${"─".repeat(50)}`);
|
|
1996
1996
|
for (const p of files) {
|
|
1997
|
-
console.log(` v${p.version}
|
|
1997
|
+
console.log(` v${p.version} — ${p.variables.length} variables: ${p.variables.join(", ") || "none"}`);
|
|
1998
1998
|
}
|
|
1999
1999
|
console.log();
|
|
2000
2000
|
}
|
|
@@ -2010,9 +2010,9 @@ function handleShow(promptsPath, name, version) {
|
|
|
2010
2010
|
console.log(`
|
|
2011
2011
|
Prompt: ${prompt.name} v${prompt.version}`);
|
|
2012
2012
|
console.log(` Variables: ${prompt.variables.join(", ") || "none"}`);
|
|
2013
|
-
console.log(` ${"
|
|
2013
|
+
console.log(` ${"─".repeat(50)}`);
|
|
2014
2014
|
console.log(prompt.content);
|
|
2015
|
-
console.log(` ${"
|
|
2015
|
+
console.log(` ${"─".repeat(50)}
|
|
2016
2016
|
`);
|
|
2017
2017
|
}
|
|
2018
2018
|
function printDiffLines(fromLines, toLines) {
|
|
@@ -2041,12 +2041,12 @@ function handleDiff(promptsPath, name, v1, v2) {
|
|
|
2041
2041
|
process.exit(1);
|
|
2042
2042
|
}
|
|
2043
2043
|
console.log(`
|
|
2044
|
-
Diff: ${name} v${v1}
|
|
2045
|
-
console.log(` ${"
|
|
2044
|
+
Diff: ${name} v${v1} → v${v2}`);
|
|
2045
|
+
console.log(` ${"─".repeat(50)}`);
|
|
2046
2046
|
printDiffLines(from.content.split(`
|
|
2047
2047
|
`), to.content.split(`
|
|
2048
2048
|
`));
|
|
2049
|
-
console.log(` ${"
|
|
2049
|
+
console.log(` ${"─".repeat(50)}
|
|
2050
2050
|
`);
|
|
2051
2051
|
}
|
|
2052
2052
|
async function promptCommand(args) {
|
|
@@ -2097,8 +2097,8 @@ async function promptCommand(args) {
|
|
|
2097
2097
|
}
|
|
2098
2098
|
|
|
2099
2099
|
// src/commands/trace.ts
|
|
2100
|
-
import { existsSync as existsSync6, readFileSync as readFileSync4, readdirSync as readdirSync2 } from "fs";
|
|
2101
|
-
import { join as join5 } from "path";
|
|
2100
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, readdirSync as readdirSync2 } from "node:fs";
|
|
2101
|
+
import { join as join5 } from "node:path";
|
|
2102
2102
|
var TRACES_DIR = ".elsium/traces";
|
|
2103
2103
|
function formatStatus(status) {
|
|
2104
2104
|
if (status === "ok")
|
|
@@ -2142,7 +2142,7 @@ function listTraces(tracesPath) {
|
|
|
2142
2142
|
}
|
|
2143
2143
|
console.log(`
|
|
2144
2144
|
Recent Traces (${files.length})`);
|
|
2145
|
-
console.log(` ${"
|
|
2145
|
+
console.log(` ${"─".repeat(60)}`);
|
|
2146
2146
|
for (const file of files) {
|
|
2147
2147
|
const data = JSON.parse(readFileSync4(join5(tracesPath, file), "utf-8"));
|
|
2148
2148
|
const root = data.find((s) => !s.parentId) ?? data[0];
|
|
@@ -2168,7 +2168,7 @@ function showTrace(tracesPath, traceId) {
|
|
|
2168
2168
|
console.log(`
|
|
2169
2169
|
Trace: ${traceId}`);
|
|
2170
2170
|
console.log(` Spans: ${spans.length}`);
|
|
2171
|
-
console.log(` ${"
|
|
2171
|
+
console.log(` ${"─".repeat(60)}`);
|
|
2172
2172
|
const roots = spans.filter((s) => !s.parentId);
|
|
2173
2173
|
for (const root of roots) {
|
|
2174
2174
|
printSpanTree(root, spans, 0);
|
|
@@ -2211,14 +2211,14 @@ function printSpanTree(span, allSpans, depth) {
|
|
|
2211
2211
|
}
|
|
2212
2212
|
|
|
2213
2213
|
// src/commands/xray.ts
|
|
2214
|
-
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
|
|
2215
|
-
import { join as join6 } from "path";
|
|
2214
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
|
|
2215
|
+
import { join as join6 } from "node:path";
|
|
2216
2216
|
var XRAY_FILE = ".elsium/xray-history.json";
|
|
2217
2217
|
async function xrayCommand(args) {
|
|
2218
2218
|
const flag = args[0];
|
|
2219
2219
|
if (flag === "--help" || flag === "-h") {
|
|
2220
2220
|
console.log(`
|
|
2221
|
-
ElsiumAI X-Ray
|
|
2221
|
+
ElsiumAI X-Ray — Inspect LLM calls
|
|
2222
2222
|
|
|
2223
2223
|
Usage:
|
|
2224
2224
|
elsium xray Show last call
|
|
@@ -2273,8 +2273,8 @@ async function xrayCommand(args) {
|
|
|
2273
2273
|
return;
|
|
2274
2274
|
}
|
|
2275
2275
|
console.log(`
|
|
2276
|
-
ElsiumAI X-Ray
|
|
2277
|
-
console.log(` ${"
|
|
2276
|
+
ElsiumAI X-Ray — ${toShow.length} call(s)`);
|
|
2277
|
+
console.log(` ${"─".repeat(60)}`);
|
|
2278
2278
|
for (const entry of toShow) {
|
|
2279
2279
|
printEntry(entry, showRaw);
|
|
2280
2280
|
}
|
|
@@ -2294,17 +2294,17 @@ function printEntry(entry, raw = false) {
|
|
|
2294
2294
|
Cost: $${entry.cost.totalCost.toFixed(6)}`);
|
|
2295
2295
|
if (raw) {
|
|
2296
2296
|
console.log(`
|
|
2297
|
-
|
|
2297
|
+
── Request ──
|
|
2298
2298
|
${entry.request.method} ${entry.request.url}
|
|
2299
2299
|
Headers: ${JSON.stringify(entry.request.headers, null, 4)}
|
|
2300
2300
|
Body: ${JSON.stringify(entry.request.body, null, 4)}
|
|
2301
2301
|
|
|
2302
|
-
|
|
2302
|
+
── Response ──
|
|
2303
2303
|
Status: ${entry.response.status}
|
|
2304
2304
|
Headers: ${JSON.stringify(entry.response.headers, null, 4)}
|
|
2305
2305
|
Body: ${JSON.stringify(entry.response.body, null, 4)}`);
|
|
2306
2306
|
}
|
|
2307
|
-
console.log(` ${"
|
|
2307
|
+
console.log(` ${"─".repeat(60)}`);
|
|
2308
2308
|
}
|
|
2309
2309
|
|
|
2310
2310
|
// src/cli.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elsium-ai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "CLI tool for ElsiumAI projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Eric Utrera <ebutrera9103@gmail.com>",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"templates"
|
|
21
21
|
],
|
|
22
22
|
"scripts": {
|
|
23
|
-
"build": "bun build ./src/cli.ts --outdir ./dist --target
|
|
23
|
+
"build": "bun build ./src/cli.ts --outdir ./dist --target node && bun x tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
24
24
|
"dev": "bun --watch src/cli.ts"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
"@elsium-ai/observe": "workspace:*"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"bun-types": "^1.3.0",
|
|
32
31
|
"typescript": "^5.7.0"
|
|
33
32
|
}
|
|
34
33
|
}
|