@przeprogramowani/10x-cli 1.16.0 → 1.17.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 +85 -6
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -10173,7 +10173,7 @@ var cac = (name = "") => new CAC(name);
|
|
|
10173
10173
|
// package.json
|
|
10174
10174
|
var package_default = {
|
|
10175
10175
|
name: "@przeprogramowani/10x-cli",
|
|
10176
|
-
version: "1.
|
|
10176
|
+
version: "1.17.0",
|
|
10177
10177
|
description: "Open-source CLI for 10xDevs course content",
|
|
10178
10178
|
repository: {
|
|
10179
10179
|
type: "git",
|
|
@@ -11512,15 +11512,27 @@ async function runBenchKitInit(ctx, dirArg, options, deps = defaultDeps) {
|
|
|
11512
11512
|
const skills = syncDir(join4(scratch, skillSource), join4(targetDir, skillRootFor(toolId)), { overwrite: !repair });
|
|
11513
11513
|
installWorkflows(targetDir, { skipExisting: repair });
|
|
11514
11514
|
let baseRepo = null;
|
|
11515
|
+
let demoTasksPinned = 0;
|
|
11515
11516
|
if (!repair) {
|
|
11516
11517
|
const detected = await deps.detectBaseRepo(process.cwd());
|
|
11517
11518
|
if (detected !== null && resolve(detected.rootDir) !== targetDir) {
|
|
11518
|
-
|
|
11519
|
-
|
|
11520
|
-
|
|
11519
|
+
let repo = detected;
|
|
11520
|
+
const https = toHttpsUrl(detected.url);
|
|
11521
|
+
if (https !== null && await deps.remoteReachable(https)) {
|
|
11522
|
+
repo = { ...detected, url: https };
|
|
11523
|
+
verbose(ctx, `repo answers over https — using ${https} instead of SSH`);
|
|
11524
|
+
}
|
|
11525
|
+
if (await registerBaseRepo(join4(targetDir, "bench.config.yaml"), repo)) {
|
|
11526
|
+
baseRepo = repo;
|
|
11527
|
+
verbose(ctx, `registered base repo ${repo.name} (${repo.url})`);
|
|
11528
|
+
demoTasksPinned = await pinPlaceholderTasks(join4(targetDir, "tasks"), repo);
|
|
11529
|
+
if (demoTasksPinned > 0) {
|
|
11530
|
+
verbose(ctx, `pinned ${demoTasksPinned} demo task(s) to ${repo.headCommit.slice(0, 12)}`);
|
|
11531
|
+
}
|
|
11521
11532
|
}
|
|
11522
11533
|
}
|
|
11523
11534
|
}
|
|
11535
|
+
const runnerDeps = await installRunnerDependencies(ctx, deps, targetDir);
|
|
11524
11536
|
const manifest = {
|
|
11525
11537
|
templateVersion,
|
|
11526
11538
|
templateRef: requestedRef ?? "latest",
|
|
@@ -11543,6 +11555,8 @@ async function runBenchKitInit(ctx, dirArg, options, deps = defaultDeps) {
|
|
|
11543
11555
|
`Created a benchmark instance in '${targetDir}' from template ${templateVersion}.`,
|
|
11544
11556
|
`Agent skills installed for ${toolName} under ${skillRootFor(toolId)}/.`,
|
|
11545
11557
|
baseRepo === null ? "No product repo detected here — add your base repos to bench.config.yaml." : `Registered '${baseRepo.name}' (${baseRepo.url}) as the first base repo in bench.config.yaml.`,
|
|
11558
|
+
...demoTasksPinned > 0 ? [`Pinned the demo task to ${baseRepo?.headCommit.slice(0, 12)} (current HEAD of the base repo).`] : [],
|
|
11559
|
+
...runnerDeps === "failed" ? ["Runner dependencies did not install — run 'npm ci --prefix .bench-kit/runner' yourself."] : runnerDeps === "installed" ? ["Runner dependencies installed (.bench-kit/runner/node_modules)."] : [],
|
|
11546
11560
|
committed ? "Initialized a fresh git repository with an initial commit." : "Initialized a fresh git repository (initial commit skipped — commit the files yourself).",
|
|
11547
11561
|
"Next: wire up secrets, then run 'bench validate' before the first run."
|
|
11548
11562
|
];
|
|
@@ -11556,6 +11570,8 @@ async function runBenchKitInit(ctx, dirArg, options, deps = defaultDeps) {
|
|
|
11556
11570
|
skillRoot: skillRootFor(toolId),
|
|
11557
11571
|
filesCopied: copied + skills.added,
|
|
11558
11572
|
baseRepo,
|
|
11573
|
+
demoTasksPinned,
|
|
11574
|
+
runnerDeps,
|
|
11559
11575
|
gitInitialized: !repair,
|
|
11560
11576
|
committed
|
|
11561
11577
|
});
|
|
@@ -11623,9 +11639,11 @@ async function runBenchKitUpdate(ctx, dirArg, options, deps = defaultDeps) {
|
|
|
11623
11639
|
for (const file of SHARED_ROOT_FILES) {
|
|
11624
11640
|
addSync(shared, syncFile(join4(scratch, file), join4(targetDir, file)));
|
|
11625
11641
|
}
|
|
11642
|
+
const runnerDeps = await installRunnerDependencies(ctx, deps, targetDir);
|
|
11626
11643
|
output(ctx, [
|
|
11627
11644
|
`Updated the benchmark instance from template ${currentVersion} to ${newVersion}.`,
|
|
11628
11645
|
" .bench-kit/ replaced wholesale (runtime zone)",
|
|
11646
|
+
...runnerDeps === "failed" ? [" .bench-kit/runner/ npm ci FAILED — run 'npm ci --prefix .bench-kit/runner' yourself"] : runnerDeps === "installed" ? [" .bench-kit/runner/ dependencies reinstalled (npm ci)"] : [],
|
|
11629
11647
|
` .github/workflows/ ${describeSync(workflows)}`,
|
|
11630
11648
|
` ${`${skillRootFor(toolId)}/`.padEnd(23)}${describeSync(skills)} — proposal, review before committing`,
|
|
11631
11649
|
` ${SHARED_ROOT_FILES.join(", ").padEnd(23)}${describeSync(shared)} — proposal, review before committing`,
|
|
@@ -11641,6 +11659,7 @@ async function runBenchKitUpdate(ctx, dirArg, options, deps = defaultDeps) {
|
|
|
11641
11659
|
templateRef: updatedManifest.templateRef,
|
|
11642
11660
|
tool: toolId,
|
|
11643
11661
|
skillRoot: skillRootFor(toolId),
|
|
11662
|
+
runnerDeps,
|
|
11644
11663
|
zones: { benchKit: "replaced", workflows, skills, shared }
|
|
11645
11664
|
});
|
|
11646
11665
|
} finally {
|
|
@@ -11831,6 +11850,53 @@ async function registerBaseRepo(configPath, repo) {
|
|
|
11831
11850
|
writeFileSync3(configPath, doc.toString());
|
|
11832
11851
|
return true;
|
|
11833
11852
|
}
|
|
11853
|
+
function toHttpsUrl(url) {
|
|
11854
|
+
const scp = url.match(/^git@([^:/]+):(.+)$/);
|
|
11855
|
+
if (scp !== null)
|
|
11856
|
+
return `https://${scp[1]}/${scp[2]}`;
|
|
11857
|
+
const ssh = url.match(/^ssh:\/\/(?:[^@/]+@)?([^:/]+)(?::\d+)?\/(.+)$/);
|
|
11858
|
+
if (ssh !== null)
|
|
11859
|
+
return `https://${ssh[1]}/${ssh[2]}`;
|
|
11860
|
+
return null;
|
|
11861
|
+
}
|
|
11862
|
+
var PLACEHOLDER_COMMIT = /^0{40}$/;
|
|
11863
|
+
async function pinPlaceholderTasks(tasksDir, repo) {
|
|
11864
|
+
if (!existsSync4(tasksDir) || !/^[0-9a-f]{40}$/.test(repo.headCommit))
|
|
11865
|
+
return 0;
|
|
11866
|
+
const { parseDocument } = await Promise.resolve().then(() => __toESM(require_dist(), 1));
|
|
11867
|
+
let pinned = 0;
|
|
11868
|
+
for (const entry of readdirSync(tasksDir, { withFileTypes: true })) {
|
|
11869
|
+
if (!entry.isDirectory())
|
|
11870
|
+
continue;
|
|
11871
|
+
const taskYaml = join4(tasksDir, entry.name, "task.yaml");
|
|
11872
|
+
if (!existsSync4(taskYaml))
|
|
11873
|
+
continue;
|
|
11874
|
+
const doc = parseDocument(readFileSync3(taskYaml, "utf8"));
|
|
11875
|
+
if (doc.getIn(["repo"]) !== PLACEHOLDER_BASE_REPO)
|
|
11876
|
+
continue;
|
|
11877
|
+
const commit = doc.getIn(["commit"]);
|
|
11878
|
+
doc.setIn(["repo"], repo.name);
|
|
11879
|
+
if (typeof commit === "string" && PLACEHOLDER_COMMIT.test(commit)) {
|
|
11880
|
+
doc.setIn(["commit"], repo.headCommit);
|
|
11881
|
+
}
|
|
11882
|
+
writeFileSync3(taskYaml, doc.toString());
|
|
11883
|
+
pinned++;
|
|
11884
|
+
}
|
|
11885
|
+
return pinned;
|
|
11886
|
+
}
|
|
11887
|
+
async function installRunnerDependencies(ctx, deps, targetDir) {
|
|
11888
|
+
const runnerDir = join4(targetDir, ".bench-kit", "runner");
|
|
11889
|
+
if (!existsSync4(join4(runnerDir, "package.json")))
|
|
11890
|
+
return "skipped";
|
|
11891
|
+
verbose(ctx, "installing runner dependencies (npm ci in .bench-kit/runner)");
|
|
11892
|
+
const result = await deps.installRunnerDeps(runnerDir);
|
|
11893
|
+
if (!result.ok) {
|
|
11894
|
+
verbose(ctx, `npm ci failed (${result.error.trim().split(`
|
|
11895
|
+
`).pop() ?? ""})`);
|
|
11896
|
+
return "failed";
|
|
11897
|
+
}
|
|
11898
|
+
return "installed";
|
|
11899
|
+
}
|
|
11834
11900
|
async function freshGitInit(ctx, deps, dir, templateVersion) {
|
|
11835
11901
|
const init = await deps.runGit(["init"], dir);
|
|
11836
11902
|
if (!init.ok) {
|
|
@@ -11844,9 +11910,13 @@ async function freshGitInit(ctx, deps, dir, templateVersion) {
|
|
|
11844
11910
|
}
|
|
11845
11911
|
return true;
|
|
11846
11912
|
}
|
|
11847
|
-
function run(cmd, args, cwd) {
|
|
11913
|
+
function run(cmd, args, cwd, env) {
|
|
11848
11914
|
return new Promise((resolvePromise) => {
|
|
11849
|
-
const child = spawn(cmd, args, {
|
|
11915
|
+
const child = spawn(cmd, args, {
|
|
11916
|
+
cwd,
|
|
11917
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
11918
|
+
...env === undefined ? {} : { env: { ...process.env, ...env } }
|
|
11919
|
+
});
|
|
11850
11920
|
let stdout = "";
|
|
11851
11921
|
let stderr = "";
|
|
11852
11922
|
child.stdout?.on("data", (chunk) => {
|
|
@@ -11893,6 +11963,15 @@ var defaultDeps = {
|
|
|
11893
11963
|
return null;
|
|
11894
11964
|
return { rootDir, name: basename(rootDir), url, headCommit };
|
|
11895
11965
|
},
|
|
11966
|
+
async remoteReachable(url) {
|
|
11967
|
+
const result = await run("git", ["ls-remote", "--heads", url], undefined, {
|
|
11968
|
+
GIT_TERMINAL_PROMPT: "0"
|
|
11969
|
+
});
|
|
11970
|
+
return result.ok;
|
|
11971
|
+
},
|
|
11972
|
+
installRunnerDeps(runnerDir) {
|
|
11973
|
+
return run("npm", ["ci", "--no-audit", "--no-fund"], runnerDir);
|
|
11974
|
+
},
|
|
11896
11975
|
detectToolSignals(cwd) {
|
|
11897
11976
|
return detectTools(cwd);
|
|
11898
11977
|
},
|