@przeprogramowani/10x-cli 1.4.0 → 1.5.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.
Files changed (2) hide show
  1. package/dist/index.mjs +89 -5
  2. 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.4.0",
2274
+ version: "1.5.0",
2275
2275
  description: "Open-source CLI for 10xDevs course content",
2276
2276
  repository: {
2277
2277
  type: "git",
@@ -3822,6 +3822,68 @@ var PROFILES = {
3822
3822
  };
3823
3823
  var DEFAULT_TOOL = "claude-code";
3824
3824
 
3825
+ // src/lib/update-check.ts
3826
+ var NPM_REGISTRY_URL = "https://registry.npmjs.org/@przeprogramowani/10x-cli/latest";
3827
+ async function fetchLatestVersion(options = {}) {
3828
+ const timeoutMs = options.timeoutMs ?? 2000;
3829
+ const url = options.url ?? NPM_REGISTRY_URL;
3830
+ const controller = new AbortController;
3831
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
3832
+ try {
3833
+ const res = await fetch(url, {
3834
+ signal: controller.signal,
3835
+ headers: { Accept: "application/json", "User-Agent": "10x-cli" }
3836
+ });
3837
+ if (!res.ok) {
3838
+ return {
3839
+ ok: false,
3840
+ code: "http_error",
3841
+ error: `registry returned HTTP ${res.status}`
3842
+ };
3843
+ }
3844
+ const body = await res.json();
3845
+ if (typeof body.version !== "string" || body.version.length === 0) {
3846
+ return {
3847
+ ok: false,
3848
+ code: "parse_error",
3849
+ error: "registry payload missing 'version' field"
3850
+ };
3851
+ }
3852
+ return { ok: true, version: body.version };
3853
+ } catch (err) {
3854
+ const aborted = controller.signal.aborted;
3855
+ return {
3856
+ ok: false,
3857
+ code: aborted ? "timeout" : "network_error",
3858
+ error: err instanceof Error ? err.message : String(err)
3859
+ };
3860
+ } finally {
3861
+ clearTimeout(timer);
3862
+ }
3863
+ }
3864
+ function compareSemver(a2, b2) {
3865
+ const parse = (v2) => {
3866
+ const core = v2.split(/[-+]/)[0] ?? v2;
3867
+ const parts = core.split(".").map((p2) => {
3868
+ const n = Number.parseInt(p2, 10);
3869
+ return Number.isFinite(n) ? n : 0;
3870
+ });
3871
+ return [parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0];
3872
+ };
3873
+ const [a1, a22, a3] = parse(a2);
3874
+ const [b1, b22, b3] = parse(b2);
3875
+ if (a1 !== b1)
3876
+ return a1 < b1 ? -1 : 1;
3877
+ if (a22 !== b22)
3878
+ return a22 < b22 ? -1 : 1;
3879
+ if (a3 !== b3)
3880
+ return a3 < b3 ? -1 : 1;
3881
+ return 0;
3882
+ }
3883
+ function upgradeCommand() {
3884
+ return "npm install -g @przeprogramowani/10x-cli";
3885
+ }
3886
+
3825
3887
  // src/commands/doctor.ts
3826
3888
  var EX_CONFIG = 78;
3827
3889
  function registerDoctorCommand(cli) {
@@ -3836,7 +3898,7 @@ async function runDoctor(ctx) {
3836
3898
  checks.push(checkAuth());
3837
3899
  checks.push(await checkApiConnectivity());
3838
3900
  checks.push(checkConfigDirectory());
3839
- checks.push(checkCliVersion());
3901
+ checks.push(await checkCliVersion());
3840
3902
  checks.push(checkToolDirectory());
3841
3903
  const failed = checks.filter((c2) => c2.status === "fail").length;
3842
3904
  const passed = checks.filter((c2) => c2.status === "pass").length;
@@ -3985,13 +4047,35 @@ function checkConfigDirectory() {
3985
4047
  };
3986
4048
  }
3987
4049
  }
3988
- function checkCliVersion() {
4050
+ async function checkCliVersion() {
4051
+ const current = package_default.version;
4052
+ const latest = await fetchLatestVersion({ timeoutMs: 2000 });
4053
+ if (!latest.ok) {
4054
+ return {
4055
+ name: "version",
4056
+ label: "Version",
4057
+ status: "pass",
4058
+ message: `10x-cli ${current} (update check skipped).`,
4059
+ details: { version: current, lookup: { ok: false, code: latest.code } }
4060
+ };
4061
+ }
4062
+ const cmp = compareSemver(current, latest.version);
4063
+ if (cmp < 0) {
4064
+ return {
4065
+ name: "version",
4066
+ label: "Version",
4067
+ status: "warn",
4068
+ message: `10x-cli ${current} is behind latest ${latest.version}.`,
4069
+ hint: `Upgrade with '${upgradeCommand()}'.`,
4070
+ details: { version: current, latest: latest.version, outdated: true }
4071
+ };
4072
+ }
3989
4073
  return {
3990
4074
  name: "version",
3991
4075
  label: "Version",
3992
4076
  status: "pass",
3993
- message: `10x-cli ${package_default.version}.`,
3994
- details: { version: package_default.version }
4077
+ message: `10x-cli ${current} — up to date.`,
4078
+ details: { version: current, latest: latest.version, outdated: false }
3995
4079
  };
3996
4080
  }
3997
4081
  function checkToolDirectory() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@przeprogramowani/10x-cli",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Open-source CLI for 10xDevs course content",
5
5
  "repository": {
6
6
  "type": "git",