@przeprogramowani/10x-cli 1.10.0 → 1.11.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/index.mjs +244 -23
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2271,7 +2271,7 @@ var cac = (name = "") => new CAC(name);
|
|
|
2271
2271
|
// package.json
|
|
2272
2272
|
var package_default = {
|
|
2273
2273
|
name: "@przeprogramowani/10x-cli",
|
|
2274
|
-
version: "1.
|
|
2274
|
+
version: "1.11.0",
|
|
2275
2275
|
description: "Open-source CLI for 10xDevs course content",
|
|
2276
2276
|
repository: {
|
|
2277
2277
|
type: "git",
|
|
@@ -3521,6 +3521,248 @@ function handleLoginError(ctx, status, code, error) {
|
|
|
3521
3521
|
outputError(ctx, code || "auth_error", "Authentication failed.", ExitCodes.ERROR, error ? `Server said: ${error}` : undefined);
|
|
3522
3522
|
}
|
|
3523
3523
|
|
|
3524
|
+
// src/lib/bench-client.ts
|
|
3525
|
+
var DEFAULT_BENCH_BASE = "https://10xbench.ai";
|
|
3526
|
+
var PROD_HOSTNAME2 = "10xbench.ai";
|
|
3527
|
+
var DEV_HOSTNAMES2 = new Set(["localhost", "127.0.0.1"]);
|
|
3528
|
+
function resolveBenchBase() {
|
|
3529
|
+
const override = process.env["BENCH_BASE_URL"];
|
|
3530
|
+
if (!override)
|
|
3531
|
+
return DEFAULT_BENCH_BASE;
|
|
3532
|
+
let url;
|
|
3533
|
+
try {
|
|
3534
|
+
url = new URL(override);
|
|
3535
|
+
} catch {
|
|
3536
|
+
throw new Error(`BENCH_BASE_URL is not a valid URL: ${JSON.stringify(override)}`);
|
|
3537
|
+
}
|
|
3538
|
+
if (url.pathname !== "/" && url.pathname !== "") {
|
|
3539
|
+
throw new Error(`BENCH_BASE_URL must not include a path (got ${JSON.stringify(url.pathname)})`);
|
|
3540
|
+
}
|
|
3541
|
+
if (url.search !== "" || url.hash !== "") {
|
|
3542
|
+
throw new Error("BENCH_BASE_URL must not include a query string or fragment");
|
|
3543
|
+
}
|
|
3544
|
+
if (url.protocol === "https:" && url.hostname === PROD_HOSTNAME2) {
|
|
3545
|
+
return `${url.protocol}//${url.host}`;
|
|
3546
|
+
}
|
|
3547
|
+
if (url.protocol === "http:" && DEV_HOSTNAMES2.has(url.hostname)) {
|
|
3548
|
+
return `${url.protocol}//${url.host}`;
|
|
3549
|
+
}
|
|
3550
|
+
throw new Error(`BENCH_BASE_URL must be ${DEFAULT_BENCH_BASE} or http://localhost[:port] (got ${JSON.stringify(override)})`);
|
|
3551
|
+
}
|
|
3552
|
+
var SUPPORTED_LEADERBOARD_SCHEMA = 1;
|
|
3553
|
+
var LEADERBOARD_PATH = "/api/leaderboard.json";
|
|
3554
|
+
var DEFAULT_TIMEOUT_MS3 = 30000;
|
|
3555
|
+
function isLeaderboardResponse(value) {
|
|
3556
|
+
if (value === null || typeof value !== "object")
|
|
3557
|
+
return false;
|
|
3558
|
+
const v2 = value;
|
|
3559
|
+
return typeof v2.schemaVersion === "number" && typeof v2.generatedAt === "string" && typeof v2.totalModels === "number" && Array.isArray(v2.leaderboard);
|
|
3560
|
+
}
|
|
3561
|
+
async function fetchLeaderboard(options = {}) {
|
|
3562
|
+
const url = `${resolveBenchBase()}${LEADERBOARD_PATH}`;
|
|
3563
|
+
let response;
|
|
3564
|
+
try {
|
|
3565
|
+
response = await fetch(url, {
|
|
3566
|
+
method: "GET",
|
|
3567
|
+
headers: {
|
|
3568
|
+
accept: "application/json",
|
|
3569
|
+
"user-agent": "10x-cli"
|
|
3570
|
+
},
|
|
3571
|
+
signal: options.signal ?? AbortSignal.timeout(DEFAULT_TIMEOUT_MS3)
|
|
3572
|
+
});
|
|
3573
|
+
} catch (err) {
|
|
3574
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3575
|
+
return { ok: false, status: 0, code: "network_error", error: message };
|
|
3576
|
+
}
|
|
3577
|
+
const text = await response.text();
|
|
3578
|
+
if (!response.ok) {
|
|
3579
|
+
return {
|
|
3580
|
+
ok: false,
|
|
3581
|
+
status: response.status,
|
|
3582
|
+
code: `http_${response.status}`,
|
|
3583
|
+
error: response.statusText || "Leaderboard request failed."
|
|
3584
|
+
};
|
|
3585
|
+
}
|
|
3586
|
+
let parsed;
|
|
3587
|
+
try {
|
|
3588
|
+
parsed = JSON.parse(text);
|
|
3589
|
+
} catch {
|
|
3590
|
+
return {
|
|
3591
|
+
ok: false,
|
|
3592
|
+
status: response.status,
|
|
3593
|
+
code: "bench_unavailable",
|
|
3594
|
+
error: "The leaderboard endpoint returned a non-JSON response."
|
|
3595
|
+
};
|
|
3596
|
+
}
|
|
3597
|
+
if (!isLeaderboardResponse(parsed)) {
|
|
3598
|
+
return {
|
|
3599
|
+
ok: false,
|
|
3600
|
+
status: response.status,
|
|
3601
|
+
code: "bench_unavailable",
|
|
3602
|
+
error: "The leaderboard endpoint returned an unexpected shape."
|
|
3603
|
+
};
|
|
3604
|
+
}
|
|
3605
|
+
return {
|
|
3606
|
+
ok: true,
|
|
3607
|
+
status: response.status,
|
|
3608
|
+
data: parsed,
|
|
3609
|
+
responseHeaders: response.headers,
|
|
3610
|
+
rawBody: text
|
|
3611
|
+
};
|
|
3612
|
+
}
|
|
3613
|
+
|
|
3614
|
+
// src/lib/format.ts
|
|
3615
|
+
function formatReleaseAt(iso, now = new Date) {
|
|
3616
|
+
const date = new Date(iso);
|
|
3617
|
+
if (!Number.isFinite(date.getTime()))
|
|
3618
|
+
return iso;
|
|
3619
|
+
const absolute = date.toLocaleDateString("en-US", {
|
|
3620
|
+
year: "numeric",
|
|
3621
|
+
month: "long",
|
|
3622
|
+
day: "numeric",
|
|
3623
|
+
timeZone: "UTC"
|
|
3624
|
+
});
|
|
3625
|
+
const msPerDay = 24 * 60 * 60 * 1000;
|
|
3626
|
+
const startOfTarget = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
|
|
3627
|
+
const startOfNow = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
|
|
3628
|
+
const days = Math.round((startOfTarget - startOfNow) / msPerDay);
|
|
3629
|
+
if (days <= 0)
|
|
3630
|
+
return absolute;
|
|
3631
|
+
if (days === 1)
|
|
3632
|
+
return `${absolute} (tomorrow)`;
|
|
3633
|
+
return `${absolute} (in ${days} days)`;
|
|
3634
|
+
}
|
|
3635
|
+
|
|
3636
|
+
// src/commands/bench.ts
|
|
3637
|
+
function registerBenchCommand(cli) {
|
|
3638
|
+
cli.command("bench", "Show the 10xBench top-10 model leaderboard (10xbench.ai)").option("--limit <n>", "Show only the top N models").action(async (options) => {
|
|
3639
|
+
const ctx = resolveContext(options);
|
|
3640
|
+
await runBench(ctx, options);
|
|
3641
|
+
});
|
|
3642
|
+
}
|
|
3643
|
+
async function runBench(ctx, options) {
|
|
3644
|
+
const limit = parseLimit(ctx, options.limit);
|
|
3645
|
+
verbose(ctx, `fetching leaderboard from ${resolveBenchBase()}`);
|
|
3646
|
+
const result = await fetchLeaderboard();
|
|
3647
|
+
if (!result.ok) {
|
|
3648
|
+
handleBenchError(ctx, result.status, result.code, result.error);
|
|
3649
|
+
}
|
|
3650
|
+
const data = result.data;
|
|
3651
|
+
if (data.schemaVersion !== SUPPORTED_LEADERBOARD_SCHEMA) {
|
|
3652
|
+
outputError(ctx, "unsupported_schema", `The leaderboard now uses format version ${data.schemaVersion}, but this CLI only understands version ${SUPPORTED_LEADERBOARD_SCHEMA}.`, ExitCodes.ERROR, "Run 'npm install -g @przeprogramowani/10x-cli@latest' to update, or visit https://10xbench.ai.");
|
|
3653
|
+
}
|
|
3654
|
+
renderLeaderboard(ctx, data, limit);
|
|
3655
|
+
}
|
|
3656
|
+
function parseLimit(ctx, raw) {
|
|
3657
|
+
if (raw === undefined)
|
|
3658
|
+
return null;
|
|
3659
|
+
const n = typeof raw === "number" ? raw : Number.parseInt(raw, 10);
|
|
3660
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
3661
|
+
outputError(ctx, "invalid_limit", `'${raw}' is not a valid limit.`, ExitCodes.USAGE, "Pass a positive whole number, for example '10x bench --limit 5'.");
|
|
3662
|
+
}
|
|
3663
|
+
return n;
|
|
3664
|
+
}
|
|
3665
|
+
function handleBenchError(ctx, status, code, error) {
|
|
3666
|
+
if (status === 0) {
|
|
3667
|
+
outputError(ctx, "network_error", "Could not reach 10xbench.ai.", ExitCodes.ERROR, "Check your internet connection and run '10x bench' again.");
|
|
3668
|
+
}
|
|
3669
|
+
if (code === "bench_unavailable") {
|
|
3670
|
+
outputError(ctx, "bench_unavailable", "The 10xBench leaderboard is temporarily unavailable.", ExitCodes.ERROR, "Try again in a few minutes, or visit https://10xbench.ai directly.");
|
|
3671
|
+
}
|
|
3672
|
+
outputError(ctx, code || "bench_failed", "Failed to load the leaderboard.", ExitCodes.ERROR, error ? `Server said: ${error}` : undefined);
|
|
3673
|
+
}
|
|
3674
|
+
function colorsEnabled() {
|
|
3675
|
+
return process.env["NO_COLOR"] === undefined && process.stderr.isTTY === true;
|
|
3676
|
+
}
|
|
3677
|
+
var STYLE = {
|
|
3678
|
+
bold: "1",
|
|
3679
|
+
dim: "2",
|
|
3680
|
+
red: "31",
|
|
3681
|
+
green: "32",
|
|
3682
|
+
yellow: "33",
|
|
3683
|
+
cyan: "36"
|
|
3684
|
+
};
|
|
3685
|
+
function paint(style, text) {
|
|
3686
|
+
if (!colorsEnabled())
|
|
3687
|
+
return text;
|
|
3688
|
+
return `\x1B[${style}m${text}\x1B[0m`;
|
|
3689
|
+
}
|
|
3690
|
+
function scoreStyle(percentage) {
|
|
3691
|
+
if (percentage >= 90)
|
|
3692
|
+
return STYLE.green;
|
|
3693
|
+
if (percentage >= 60)
|
|
3694
|
+
return STYLE.yellow;
|
|
3695
|
+
return STYLE.red;
|
|
3696
|
+
}
|
|
3697
|
+
var BAR_WIDTH = 20;
|
|
3698
|
+
function scoreBar(percentage) {
|
|
3699
|
+
const clamped = Math.min(Math.max(percentage, 0), 100);
|
|
3700
|
+
const filled = Math.round(clamped / 100 * BAR_WIDTH);
|
|
3701
|
+
return "█".repeat(filled) + "░".repeat(BAR_WIDTH - filled);
|
|
3702
|
+
}
|
|
3703
|
+
function renderLeaderboard(ctx, data, limit) {
|
|
3704
|
+
const ranked = limit === null ? data.leaderboard : data.leaderboard.slice(0, limit);
|
|
3705
|
+
if (ctx.json) {
|
|
3706
|
+
output(ctx, "", {
|
|
3707
|
+
source: resolveBenchBase(),
|
|
3708
|
+
generatedAt: data.generatedAt,
|
|
3709
|
+
totalAttempts: data.totalAttempts,
|
|
3710
|
+
totalModels: data.totalModels,
|
|
3711
|
+
models: ranked.map((e2, i) => ({
|
|
3712
|
+
rank: i + 1,
|
|
3713
|
+
model: e2.modelName,
|
|
3714
|
+
modelBaseId: e2.modelBaseId,
|
|
3715
|
+
score: e2.averageScore,
|
|
3716
|
+
maxScore: e2.averageMaxScore,
|
|
3717
|
+
percentage: e2.averagePercentage,
|
|
3718
|
+
attempts: e2.attemptCount,
|
|
3719
|
+
environment: e2.agentEnvironment,
|
|
3720
|
+
averageCost: e2.averageCost
|
|
3721
|
+
}))
|
|
3722
|
+
});
|
|
3723
|
+
return;
|
|
3724
|
+
}
|
|
3725
|
+
if (ranked.length === 0) {
|
|
3726
|
+
output(ctx, "The leaderboard has no results yet.", undefined);
|
|
3727
|
+
return;
|
|
3728
|
+
}
|
|
3729
|
+
const names = ranked.map((e2) => sanitize(e2.modelName));
|
|
3730
|
+
const details = ranked.map((e2) => formatDetail(e2));
|
|
3731
|
+
const nameWidth = Math.max(...names.map((n) => n.length));
|
|
3732
|
+
const detailWidth = Math.max(...details.map((d2) => d2.length));
|
|
3733
|
+
const rankWidth = String(ranked.length).length;
|
|
3734
|
+
const lines = [];
|
|
3735
|
+
lines.push(paint(STYLE.bold, `10xBench — Top ${ranked.length} of ${data.totalModels} models`) + paint(STYLE.dim, ` (${data.totalAttempts} attempts scored)`));
|
|
3736
|
+
lines.push("");
|
|
3737
|
+
for (let i = 0;i < ranked.length; i++) {
|
|
3738
|
+
lines.push(formatRow(ranked[i], i + 1, names[i], details[i], rankWidth, nameWidth, detailWidth));
|
|
3739
|
+
}
|
|
3740
|
+
lines.push("");
|
|
3741
|
+
lines.push(paint(STYLE.dim, `Data as of ${formatReleaseAt(data.generatedAt)} — ${resolveBenchBase()}`));
|
|
3742
|
+
output(ctx, lines.join(`
|
|
3743
|
+
`), undefined);
|
|
3744
|
+
}
|
|
3745
|
+
function formatDetail(entry) {
|
|
3746
|
+
const score = `${entry.averageScore.toFixed(1)}/${entry.averageMaxScore.toFixed(0)}`;
|
|
3747
|
+
const runs = `${entry.attemptCount} run${entry.attemptCount === 1 ? "" : "s"}`;
|
|
3748
|
+
const cost = entry.averageCost === null || entry.averageCost === undefined ? "" : `, ~$${entry.averageCost.toFixed(2)}/run`;
|
|
3749
|
+
return `(${score}, ${runs}${cost})`;
|
|
3750
|
+
}
|
|
3751
|
+
function formatRow(entry, rank, name, detail, rankWidth, nameWidth, detailWidth) {
|
|
3752
|
+
const style = scoreStyle(entry.averagePercentage);
|
|
3753
|
+
const rankCell = String(rank).padStart(rankWidth);
|
|
3754
|
+
const nameCell = name.padEnd(nameWidth);
|
|
3755
|
+
const pctCell = `${entry.averagePercentage.toFixed(1)}%`.padStart(6);
|
|
3756
|
+
return [
|
|
3757
|
+
` ${paint(rank <= 3 ? STYLE.bold : STYLE.dim, rankCell)}`,
|
|
3758
|
+
rank <= 3 ? paint(STYLE.bold, nameCell) : nameCell,
|
|
3759
|
+
paint(style, scoreBar(entry.averagePercentage)),
|
|
3760
|
+
paint(style, pctCell),
|
|
3761
|
+
detail.padEnd(detailWidth),
|
|
3762
|
+
paint(STYLE.dim, sanitize(entry.agentEnvironment))
|
|
3763
|
+
].join(" ");
|
|
3764
|
+
}
|
|
3765
|
+
|
|
3524
3766
|
// src/commands/doctor.ts
|
|
3525
3767
|
import { existsSync as existsSync2, accessSync, constants } from "node:fs";
|
|
3526
3768
|
import { join as join2 } from "node:path";
|
|
@@ -3732,28 +3974,6 @@ function apiBaseUrl() {
|
|
|
3732
3974
|
return resolveApiBase();
|
|
3733
3975
|
}
|
|
3734
3976
|
|
|
3735
|
-
// src/lib/format.ts
|
|
3736
|
-
function formatReleaseAt(iso, now = new Date) {
|
|
3737
|
-
const date = new Date(iso);
|
|
3738
|
-
if (!Number.isFinite(date.getTime()))
|
|
3739
|
-
return iso;
|
|
3740
|
-
const absolute = date.toLocaleDateString("en-US", {
|
|
3741
|
-
year: "numeric",
|
|
3742
|
-
month: "long",
|
|
3743
|
-
day: "numeric",
|
|
3744
|
-
timeZone: "UTC"
|
|
3745
|
-
});
|
|
3746
|
-
const msPerDay = 24 * 60 * 60 * 1000;
|
|
3747
|
-
const startOfTarget = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
|
|
3748
|
-
const startOfNow = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
|
|
3749
|
-
const days = Math.round((startOfTarget - startOfNow) / msPerDay);
|
|
3750
|
-
if (days <= 0)
|
|
3751
|
-
return absolute;
|
|
3752
|
-
if (days === 1)
|
|
3753
|
-
return `${absolute} (tomorrow)`;
|
|
3754
|
-
return `${absolute} (in ${days} days)`;
|
|
3755
|
-
}
|
|
3756
|
-
|
|
3757
3977
|
// src/lib/tool-profile.ts
|
|
3758
3978
|
var SENTINEL_BEGIN = "<!-- BEGIN @przeprogramowani/10x-cli -->";
|
|
3759
3979
|
var SENTINEL_END = "<!-- END @przeprogramowani/10x-cli -->";
|
|
@@ -6297,6 +6517,7 @@ registerGetCommand(cli);
|
|
|
6297
6517
|
registerListCommand(cli);
|
|
6298
6518
|
registerSyncCommand(cli);
|
|
6299
6519
|
registerDoctorCommand(cli);
|
|
6520
|
+
registerBenchCommand(cli);
|
|
6300
6521
|
cli.help();
|
|
6301
6522
|
cli.version(package_default.version);
|
|
6302
6523
|
try {
|