@przeprogramowani/10x-cli 1.27.0 → 1.29.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/README.md +10 -5
- package/dist/index.mjs +108 -48
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -309,13 +309,18 @@ releases and suggests running `10x sync`.
|
|
|
309
309
|
10x changelog --since 2026-10-01 --limit 50
|
|
310
310
|
```
|
|
311
311
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
312
|
+
The output starts with where the project stands (for example `This project is on
|
|
313
|
+
toolkit v2.59.2 (recorded by 10x sync on 2026-10-05) — 2 newer releases:`), then
|
|
314
|
+
lists releases newest first: `vX.Y.Z — <date>`, the release highlights as bullets,
|
|
315
|
+
and the changed skills, prompts, rules and config templates with a status mark
|
|
316
|
+
(`+` new, `~` changed, `-` removed, `>` renamed) and a one-line summary. Colours are
|
|
317
|
+
used only on an interactive terminal and respect `NO_COLOR`. Exit code is `0`
|
|
318
|
+
whether or not there are new releases; an invalid `--since`/`--limit` exits `2`, a
|
|
319
|
+
missing login `3`, and an account without course access `4`. Against
|
|
315
320
|
a backend that does not serve the changelog yet the command fails with
|
|
316
321
|
`changelog_unsupported` (exit `1`); `get` and `sync` keep working. JSON output
|
|
317
|
-
(`--json` or piped) is `{ baseline: { source, version?, date? },
|
|
318
|
-
entries }`, where `source` is `flag`, `sync`, `applied` or `none`.
|
|
322
|
+
(`--json` or piped) is `{ baseline: { source, version?, date?, recordedAt? },
|
|
323
|
+
newEntries, entries }`, where `source` is `flag`, `sync`, `applied` or `none`.
|
|
319
324
|
|
|
320
325
|
### `10x bench`
|
|
321
326
|
|
package/dist/index.mjs
CHANGED
|
@@ -3183,7 +3183,7 @@ var cac = (name = "") => new CAC(name);
|
|
|
3183
3183
|
// package.json
|
|
3184
3184
|
var package_default = {
|
|
3185
3185
|
name: "@przeprogramowani/10x-cli",
|
|
3186
|
-
version: "1.
|
|
3186
|
+
version: "1.29.0",
|
|
3187
3187
|
description: "Open-source CLI for 10xDevs course content",
|
|
3188
3188
|
repository: {
|
|
3189
3189
|
type: "git",
|
|
@@ -3929,7 +3929,7 @@ function isChangelogEntry(value) {
|
|
|
3929
3929
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
3930
3930
|
return false;
|
|
3931
3931
|
const e2 = value;
|
|
3932
|
-
if (e2["schemaVersion"] !==
|
|
3932
|
+
if (e2["schemaVersion"] !== 1)
|
|
3933
3933
|
return false;
|
|
3934
3934
|
if (typeof e2["version"] !== "string" || !e2["version"])
|
|
3935
3935
|
return false;
|
|
@@ -3939,6 +3939,8 @@ function isChangelogEntry(value) {
|
|
|
3939
3939
|
return false;
|
|
3940
3940
|
if (e2["model"] !== null && typeof e2["model"] !== "string")
|
|
3941
3941
|
return false;
|
|
3942
|
+
if (!Array.isArray(e2["highlights"]) || !e2["highlights"].every((h2) => typeof h2 === "string"))
|
|
3943
|
+
return false;
|
|
3942
3944
|
const artifacts = e2["artifacts"];
|
|
3943
3945
|
if (!artifacts || typeof artifacts !== "object" || Array.isArray(artifacts))
|
|
3944
3946
|
return false;
|
|
@@ -3948,7 +3950,7 @@ function isChangelogEntry(value) {
|
|
|
3948
3950
|
if (!item || typeof item !== "object")
|
|
3949
3951
|
return false;
|
|
3950
3952
|
const change = item;
|
|
3951
|
-
return typeof change["name"] === "string" && typeof change["status"] === "string" && CHANGELOG_STATUSES.includes(change["status"]);
|
|
3953
|
+
return typeof change["name"] === "string" && typeof change["status"] === "string" && CHANGELOG_STATUSES.includes(change["status"]) && (change["summary"] === null || typeof change["summary"] === "string");
|
|
3952
3954
|
});
|
|
3953
3955
|
});
|
|
3954
3956
|
}
|
|
@@ -4565,6 +4567,38 @@ function formatReleaseAt(iso, now = new Date) {
|
|
|
4565
4567
|
return `${absolute} (tomorrow)`;
|
|
4566
4568
|
return `${absolute} (in ${days} days)`;
|
|
4567
4569
|
}
|
|
4570
|
+
function colorsEnabled() {
|
|
4571
|
+
return process.env["NO_COLOR"] === undefined && process.stderr.isTTY === true;
|
|
4572
|
+
}
|
|
4573
|
+
var STYLE = {
|
|
4574
|
+
bold: "1",
|
|
4575
|
+
dim: "2",
|
|
4576
|
+
red: "31",
|
|
4577
|
+
green: "32",
|
|
4578
|
+
yellow: "33",
|
|
4579
|
+
cyan: "36"
|
|
4580
|
+
};
|
|
4581
|
+
function paint(style, text) {
|
|
4582
|
+
if (!colorsEnabled())
|
|
4583
|
+
return text;
|
|
4584
|
+
return `\x1B[${style}m${text}\x1B[0m`;
|
|
4585
|
+
}
|
|
4586
|
+
function wrapText(text, width, prefix, indent = " ".repeat(prefix.length)) {
|
|
4587
|
+
const lines = [];
|
|
4588
|
+
let line = prefix;
|
|
4589
|
+
let empty = true;
|
|
4590
|
+
for (const word of text.split(/\s+/).filter(Boolean)) {
|
|
4591
|
+
if (!empty && line.length + 1 + word.length > width) {
|
|
4592
|
+
lines.push(line);
|
|
4593
|
+
line = indent + word;
|
|
4594
|
+
} else {
|
|
4595
|
+
line += (empty ? "" : " ") + word;
|
|
4596
|
+
}
|
|
4597
|
+
empty = false;
|
|
4598
|
+
}
|
|
4599
|
+
lines.push(line);
|
|
4600
|
+
return lines;
|
|
4601
|
+
}
|
|
4568
4602
|
|
|
4569
4603
|
// src/commands/bench.ts
|
|
4570
4604
|
function registerBenchCommand(cli) {
|
|
@@ -4604,22 +4638,6 @@ function handleBenchError(ctx, status, code, error) {
|
|
|
4604
4638
|
}
|
|
4605
4639
|
outputError(ctx, code || "bench_failed", "Failed to load the leaderboard.", ExitCodes.ERROR, error ? `Server said: ${error}` : undefined);
|
|
4606
4640
|
}
|
|
4607
|
-
function colorsEnabled() {
|
|
4608
|
-
return process.env["NO_COLOR"] === undefined && process.stderr.isTTY === true;
|
|
4609
|
-
}
|
|
4610
|
-
var STYLE = {
|
|
4611
|
-
bold: "1",
|
|
4612
|
-
dim: "2",
|
|
4613
|
-
red: "31",
|
|
4614
|
-
green: "32",
|
|
4615
|
-
yellow: "33",
|
|
4616
|
-
cyan: "36"
|
|
4617
|
-
};
|
|
4618
|
-
function paint(style, text) {
|
|
4619
|
-
if (!colorsEnabled())
|
|
4620
|
-
return text;
|
|
4621
|
-
return `\x1B[${style}m${text}\x1B[0m`;
|
|
4622
|
-
}
|
|
4623
4641
|
function scoreStyle(percentage) {
|
|
4624
4642
|
if (percentage >= 90)
|
|
4625
4643
|
return STYLE.green;
|
|
@@ -5830,7 +5848,7 @@ function resolveManifestBaseline(ctx, projectRoot) {
|
|
|
5830
5848
|
const { profile, manifest } = found;
|
|
5831
5849
|
verbose(ctx, `using manifest in ${profile.manifestDir}/`);
|
|
5832
5850
|
if (manifest.toolkit)
|
|
5833
|
-
return { source: "sync", version: manifest.toolkit.version };
|
|
5851
|
+
return { source: "sync", version: manifest.toolkit.version, recordedAt: manifest.toolkit.recordedAt };
|
|
5834
5852
|
const applied = newestAppliedAt(manifest);
|
|
5835
5853
|
if (applied)
|
|
5836
5854
|
return { source: "applied", date: applied };
|
|
@@ -5854,6 +5872,9 @@ function handleChangelogError(ctx, status, code, error) {
|
|
|
5854
5872
|
if (code === "changelog_unsupported") {
|
|
5855
5873
|
outputError(ctx, code, "The 10x-toolkit API does not support the toolkit changelog yet.", ExitCodes.ERROR, "The changelog endpoint has not been deployed yet. Try again later; '10x sync' still updates your files.");
|
|
5856
5874
|
}
|
|
5875
|
+
if (status === 403) {
|
|
5876
|
+
outputError(ctx, "course_access_denied", "Your account has no active course access, so there is no toolkit changelog to show.", ExitCodes.FORBIDDEN);
|
|
5877
|
+
}
|
|
5857
5878
|
if (status === 401) {
|
|
5858
5879
|
outputError(ctx, "auth_required", "Your session is no longer valid.", ExitCodes.AUTH_REQUIRED, "Run '10x auth' to log in again.");
|
|
5859
5880
|
}
|
|
@@ -5862,48 +5883,87 @@ function handleChangelogError(ctx, status, code, error) {
|
|
|
5862
5883
|
}
|
|
5863
5884
|
outputError(ctx, code || "changelog_failed", error || "Failed to load the toolkit changelog.", ExitCodes.ERROR);
|
|
5864
5885
|
}
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5886
|
+
var day = (iso) => (iso ?? "").slice(0, 10);
|
|
5887
|
+
var plural = (n, word) => `${n} ${word}${n === 1 ? "" : "s"}`;
|
|
5888
|
+
function header(baseline, count) {
|
|
5889
|
+
const v3 = paint(STYLE.bold, baseline.version ?? "");
|
|
5869
5890
|
switch (baseline.source) {
|
|
5891
|
+
case "sync":
|
|
5892
|
+
return `This project is on toolkit ${v3} ${paint(STYLE.dim, `(recorded by 10x sync on ${day(baseline.recordedAt)})`)}${count ? ` — ${plural(count, "newer release")}:` : ""}`;
|
|
5870
5893
|
case "flag":
|
|
5871
|
-
return
|
|
5894
|
+
return baseline.version ? `Toolkit changes since ${v3}:` : `Toolkit changes since ${paint(STYLE.bold, day(baseline.date))}:`;
|
|
5895
|
+
case "applied":
|
|
5896
|
+
return `No toolkit version recorded in this project — showing changes since your last lesson apply (${day(baseline.date)}):`;
|
|
5897
|
+
case "none":
|
|
5898
|
+
return `No toolkit version recorded in this project — showing the latest ${plural(count, "release")}:`;
|
|
5899
|
+
}
|
|
5900
|
+
}
|
|
5901
|
+
function emptyMessage(baseline) {
|
|
5902
|
+
switch (baseline.source) {
|
|
5872
5903
|
case "sync":
|
|
5873
|
-
return "
|
|
5904
|
+
return "You're up to date — no toolkit changes since then.";
|
|
5905
|
+
case "flag":
|
|
5906
|
+
return `No toolkit changes since ${baseline.version ?? day(baseline.date)}.`;
|
|
5874
5907
|
case "applied":
|
|
5875
|
-
return
|
|
5908
|
+
return `No toolkit changes since ${day(baseline.date)}.`;
|
|
5876
5909
|
case "none":
|
|
5877
|
-
return "
|
|
5910
|
+
return "No toolkit changes published yet.";
|
|
5878
5911
|
}
|
|
5879
5912
|
}
|
|
5913
|
+
var MAX_WIDTH = 100;
|
|
5914
|
+
var CATEGORIES = [
|
|
5915
|
+
["skills", "Skills"],
|
|
5916
|
+
["prompts", "Prompts"],
|
|
5917
|
+
["rules", "Rules"],
|
|
5918
|
+
["configTemplates", "Config templates"]
|
|
5919
|
+
];
|
|
5920
|
+
var STATUS = {
|
|
5921
|
+
added: { mark: "+", style: STYLE.green, label: "new" },
|
|
5922
|
+
modified: { mark: "~", style: STYLE.yellow },
|
|
5923
|
+
removed: { mark: "-", style: STYLE.red, label: "removed" },
|
|
5924
|
+
renamed: { mark: ">", style: STYLE.cyan, label: "renamed" }
|
|
5925
|
+
};
|
|
5926
|
+
function renderEntry(entry, width) {
|
|
5927
|
+
const lines = [`${paint(STYLE.bold, paint(STYLE.cyan, entry.version))} ${paint(STYLE.dim, `— ${entry.releasedAt.slice(0, 10)}`)}`];
|
|
5928
|
+
for (const highlight of entry.highlights)
|
|
5929
|
+
lines.push(...wrapText(sanitize(highlight), width, " • "));
|
|
5930
|
+
for (const [category, label] of CATEGORIES) {
|
|
5931
|
+
const items = entry.artifacts[category];
|
|
5932
|
+
if (items.length === 0)
|
|
5933
|
+
continue;
|
|
5934
|
+
lines.push("", ` ${paint(STYLE.bold, label)}`);
|
|
5935
|
+
for (const item of items) {
|
|
5936
|
+
const status = STATUS[item.status];
|
|
5937
|
+
const suffix = status.label ? ` ${paint(STYLE.dim, `(${status.label})`)}` : "";
|
|
5938
|
+
lines.push(` ${paint(status.style, status.mark)} ${paint(STYLE.bold, sanitize(item.name))}${suffix}`);
|
|
5939
|
+
if (item.summary)
|
|
5940
|
+
lines.push(...wrapText(sanitize(item.summary), width, " "));
|
|
5941
|
+
}
|
|
5942
|
+
}
|
|
5943
|
+
return lines;
|
|
5944
|
+
}
|
|
5945
|
+
function pushSyncHint(lines, baseline) {
|
|
5946
|
+
if (baseline.source !== "none" && baseline.source !== "applied")
|
|
5947
|
+
return;
|
|
5948
|
+
lines.push("", paint(STYLE.dim, "Run 10x sync to record this project's toolkit version; 10x changelog will then show only what changed since."));
|
|
5949
|
+
}
|
|
5880
5950
|
function render(ctx, baseline, entries) {
|
|
5881
5951
|
if (ctx.json) {
|
|
5882
5952
|
output(ctx, "", { baseline, newEntries: entries.length, entries });
|
|
5883
5953
|
return;
|
|
5884
5954
|
}
|
|
5885
|
-
const lines = [];
|
|
5886
|
-
if (baseline.source === "none") {
|
|
5887
|
-
lines.push(`Latest toolkit changes (${describeSource(baseline)})`);
|
|
5888
|
-
} else {
|
|
5889
|
-
lines.push(`Toolkit changes since ${describeBaseline(baseline)} (${describeSource(baseline)})`);
|
|
5890
|
-
}
|
|
5891
|
-
lines.push("");
|
|
5892
5955
|
if (entries.length === 0) {
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
lines.push(`${entry.version} — ${entry.releasedAt.slice(0, 10)}`);
|
|
5899
|
-
lines.push("");
|
|
5900
|
-
lines.push(entry.markdown.trimEnd());
|
|
5901
|
-
});
|
|
5902
|
-
}
|
|
5903
|
-
if (baseline.source === "none") {
|
|
5904
|
-
lines.push("");
|
|
5905
|
-
lines.push("Run 10x sync to record your baseline.");
|
|
5956
|
+
const lines2 = baseline.source === "sync" ? [header(baseline, 0), emptyMessage(baseline)] : [emptyMessage(baseline)];
|
|
5957
|
+
pushSyncHint(lines2, baseline);
|
|
5958
|
+
output(ctx, lines2.join(`
|
|
5959
|
+
`), undefined);
|
|
5960
|
+
return;
|
|
5906
5961
|
}
|
|
5962
|
+
const width = Math.min(process.stderr.columns || 80, MAX_WIDTH);
|
|
5963
|
+
const lines = [header(baseline, entries.length)];
|
|
5964
|
+
for (const entry of entries)
|
|
5965
|
+
lines.push("", ...renderEntry(entry, width));
|
|
5966
|
+
pushSyncHint(lines, baseline);
|
|
5907
5967
|
output(ctx, lines.join(`
|
|
5908
5968
|
`), undefined);
|
|
5909
5969
|
}
|