create-egregore 0.21.0-runtime-mvp.1 → 0.21.0-runtime-mvp.3

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.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // egregore-launcher-version: 0.21.0-runtime-mvp.1
2
+ // egregore-launcher-version: 0.21.0-runtime-mvp.3
3
3
  //
4
4
  // egregore — launch and browse Egregore instances from your terminal.
5
5
  // Installed by create-egregore. Reads ~/.egregore/instances.json.
@@ -35,7 +35,7 @@ const crypto = require("node:crypto");
35
35
  const { spawnSync, spawn } = require("node:child_process");
36
36
  const readline = require("node:readline");
37
37
 
38
- const VERSION = "0.21.0-runtime-mvp.1";
38
+ const VERSION = "0.21.0-runtime-mvp.3";
39
39
  const REGISTRY = path.join(os.homedir(), ".egregore", "instances.json");
40
40
  const DEFAULT_FILE = path.join(os.homedir(), ".egregore", "default");
41
41
  const UPDATE_CACHE_FILE = path.join(os.homedir(), ".egregore", "update-check.json");
@@ -2543,7 +2543,8 @@ const UPGRADE_STATUS_LABEL = {
2543
2543
  };
2544
2544
 
2545
2545
  function upgradeSummary(st) {
2546
- if (!st || st.status === "none") return "up to date";
2546
+ // "none" means no activation record — a first-time state, not freshness.
2547
+ if (!st || st.status === "none") return "no update staged";
2547
2548
  if (st.status === "active") return `${st.active_version || "?"} active`;
2548
2549
  return UPGRADE_STATUS_LABEL[st.status] || st.status;
2549
2550
  }
@@ -2565,7 +2566,8 @@ function formatUpgradeLines(inst, st, { candidate = "" } = {}) {
2565
2566
  lines.push(`Selected Egregore: ${inst.name || inst.slug} (${inst.slug || "?"})`);
2566
2567
  lines.push(`Location: ${inst.path}`);
2567
2568
  lines.push("");
2568
- lines.push(`Runtime: ${d.active_version || "unknown"} active`
2569
+ const activeLabel = d.active_version ? `${d.active_version} active` : "not yet activated here";
2570
+ lines.push(`Runtime: ${activeLabel}`
2569
2571
  + (d.candidate_version ? ` → candidate ${d.candidate_version}` : candidate ? ` → candidate ${candidate} available` : ""));
2570
2572
  lines.push(`Status: ${UPGRADE_STATUS_LABEL[d.status] || d.status}`);
2571
2573
  if (d.candidate_digest) lines.push(`Package digest: sha256 ${String(d.candidate_digest).slice(0, 16)}…`);
package/lib/setup.js CHANGED
@@ -1327,17 +1327,46 @@ function currentTemplatePath() {
1327
1327
  // # egregore-launcher-version: X.Y.Z (bash)
1328
1328
  // // egregore-launcher-version: X.Y.Z (node)
1329
1329
  function launcherVersion(contents) {
1330
- const m = contents.match(/egregore-launcher-version:\s*(\d+\.\d+\.\d+)/);
1330
+ // Capture the full stamp including any prerelease suffix. A prerelease-blind
1331
+ // regex made 0.21.0-runtime-mvp.1 and .2 both read as "0.21.0", so the
1332
+ // refresh treated the newer template as a local edit and refused to upgrade.
1333
+ const m = contents.match(/egregore-launcher-version:\s*(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)/);
1331
1334
  return m ? m[1] : null;
1332
1335
  }
1333
1336
 
1334
- // Return 1 if a > b, -1 if a < b, 0 if equal. Both are semver strings "x.y.z".
1337
+ // Return 1 if a > b, -1 if a < b, 0 if equal. Semver with prerelease rules:
1338
+ // a release outranks any prerelease of the same core; prerelease identifiers
1339
+ // compare dot-by-dot, numerically when both numeric.
1335
1340
  function compareVersions(a, b) {
1336
- const pa = a.split(".").map(Number);
1337
- const pb = b.split(".").map(Number);
1341
+ const splitOnce = (v) => {
1342
+ const i = v.indexOf("-");
1343
+ return i === -1 ? [v, ""] : [v.slice(0, i), v.slice(i + 1)];
1344
+ };
1345
+ const [coreA, preA] = splitOnce(a);
1346
+ const [coreB, preB] = splitOnce(b);
1347
+ const pa = coreA.split(".").map(Number);
1348
+ const pb = coreB.split(".").map(Number);
1338
1349
  for (let i = 0; i < 3; i++) {
1339
1350
  if (pa[i] !== pb[i]) return pa[i] > pb[i] ? 1 : -1;
1340
1351
  }
1352
+ if (!preA && !preB) return 0;
1353
+ if (!preA) return 1;
1354
+ if (!preB) return -1;
1355
+ const ia = preA.split(".");
1356
+ const ib = preB.split(".");
1357
+ for (let i = 0; i < Math.max(ia.length, ib.length); i++) {
1358
+ if (ia[i] === undefined) return -1;
1359
+ if (ib[i] === undefined) return 1;
1360
+ const na = /^\d+$/.test(ia[i]) ? Number(ia[i]) : NaN;
1361
+ const nb = /^\d+$/.test(ib[i]) ? Number(ib[i]) : NaN;
1362
+ if (!Number.isNaN(na) && !Number.isNaN(nb)) {
1363
+ if (na !== nb) return na > nb ? 1 : -1;
1364
+ } else if (Number.isNaN(na) !== Number.isNaN(nb)) {
1365
+ return Number.isNaN(na) ? 1 : -1;
1366
+ } else if (ia[i] !== ib[i]) {
1367
+ return ia[i] > ib[i] ? 1 : -1;
1368
+ }
1369
+ }
1341
1370
  return 0;
1342
1371
  }
1343
1372
 
@@ -1628,6 +1657,8 @@ async function installShellAlias(egregoreDir, ui) {
1628
1657
 
1629
1658
  module.exports = {
1630
1659
  install,
1660
+ launcherVersion,
1661
+ compareVersions,
1631
1662
  ghApi,
1632
1663
  acceptPendingInvitations,
1633
1664
  registerInstance,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-egregore",
3
- "version": "0.21.0-runtime-mvp.1",
3
+ "version": "0.21.0-runtime-mvp.3",
4
4
  "description": "Set up Egregore for your team in one command — installs the egregore launcher and your choice of Claude Code, Codex, or Pi.",
5
5
  "license": "MIT",
6
6
  "bin": {