create-egregore 0.21.0-runtime-mvp.21 → 0.21.0-runtime-mvp.22

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.21
2
+ // egregore-launcher-version: 0.21.0-runtime-mvp.22
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.21";
38
+ const VERSION = "0.21.0-runtime-mvp.22";
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");
@@ -2499,20 +2499,33 @@ function formatTelemetryLines(status) {
2499
2499
  function upgradeStatus(inst, { fetch = false } = {}) {
2500
2500
  const args = ["status"]; if (fetch) args.push("--fetch");
2501
2501
  const r = runUpgrade(inst, args);
2502
- if (!r || r.status !== 0 || !r.stdout) return null;
2503
- try { return JSON.parse(r.stdout); } catch { return null; }
2502
+ if (!r || r.status !== 0 || !r.stdout) {
2503
+ const detail = String((r && (r.stderr || r.stdout)) || "Runtime status probe failed")
2504
+ .trim().split("\n")[0];
2505
+ return { status: "unavailable", failure: { message: detail } };
2506
+ }
2507
+ try { return JSON.parse(r.stdout); } catch {
2508
+ return { status: "unavailable", failure: { message: "Runtime status returned an unreadable response" } };
2509
+ }
2504
2510
  }
2505
2511
 
2506
2512
  function upgradeStatusAsync(inst, cb) {
2507
2513
  const bridge = resolveUpgradeBridge(inst);
2508
- if (!bridge) return cb(null);
2509
- let buf = "";
2514
+ if (!bridge) return cb({ status: "unavailable", failure: { message: "No Runtime update engine is installed" } });
2515
+ let buf = ""; let err = "";
2510
2516
  try {
2511
- const child = spawn("bash", [bridge.script, "status"], { cwd: inst.path, stdio: ["ignore", "pipe", "ignore"], env: { ...process.env, ...bridge.env } });
2517
+ const child = spawn("bash", [bridge.script, "status"], { cwd: inst.path, stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, ...bridge.env } });
2512
2518
  child.stdout.on("data", (d) => { buf += d; });
2513
- child.on("close", () => { try { cb(JSON.parse(buf)); } catch { cb(null); } });
2514
- child.on("error", () => cb(null));
2515
- } catch { cb(null); }
2519
+ child.stderr.on("data", (d) => { err += d; });
2520
+ child.on("close", (code) => {
2521
+ if (code === 0) {
2522
+ try { cb(JSON.parse(buf)); return; } catch {}
2523
+ }
2524
+ const detail = String(err || buf || "Runtime status probe failed").trim().split("\n")[0];
2525
+ cb({ status: "unavailable", failure: { message: detail } });
2526
+ });
2527
+ child.on("error", (error) => cb({ status: "unavailable", failure: { message: error.message } }));
2528
+ } catch (error) { cb({ status: "unavailable", failure: { message: error.message } }); }
2516
2529
  }
2517
2530
 
2518
2531
  // Local retrieval health for the settings surface. Package-update state,
@@ -2632,6 +2645,7 @@ const UPGRADE_STATUS_LABEL = {
2632
2645
  active: "active",
2633
2646
  cancelled: "cancelled",
2634
2647
  "rolled-back": "rolled back",
2648
+ unavailable: "unavailable",
2635
2649
  };
2636
2650
 
2637
2651
  // Settings-row truth for the Runtime update line. The row must say outright
@@ -2645,6 +2659,7 @@ function runtimeUpdateRowValue(st, candidate) {
2645
2659
  if (candidate && candidate !== v) return `${v} active ${YELLOW}· update available ${candidate}${RESET}`;
2646
2660
  return `${GREEN}${v} active${RESET}${candidate ? `${DIM} · up to date${RESET}` : ""}`;
2647
2661
  }
2662
+ if (st.status === "unavailable") return `${YELLOW}update unavailable${RESET}`;
2648
2663
  if (st.status === "ready-to-activate") return `${GREEN}${upgradeSummary(st)}${RESET}`;
2649
2664
  if (st.status === "failed" || st.status === "interrupted") return `${YELLOW}${upgradeSummary(st)}${RESET}`;
2650
2665
  if (st.status === "preparing" || st.status === "pending") return `${DIM}${upgradeSummary(st)}${RESET}`;
@@ -2685,7 +2700,7 @@ function formatUpgradeLines(inst, st, { candidate = "", retrieval = null } = {})
2685
2700
  if (d.candidate_digest) lines.push(`Package digest: sha256 ${String(d.candidate_digest).slice(0, 16)}…`);
2686
2701
  // A recorded failure only needs attention while the transaction is stuck
2687
2702
  // on it; once a later prepare succeeds the line would contradict "ready".
2688
- if (d.failure && d.failure.message && (d.status === "failed" || d.status === "interrupted")) {
2703
+ if (d.failure && d.failure.message && (["failed", "interrupted", "unavailable"].includes(d.status))) {
2689
2704
  lines.push(`Attention: ${d.failure.message}`);
2690
2705
  }
2691
2706
  if (d.rollback_version && d.status !== "none") lines.push(`Rollback target: ${d.rollback_version}`);
@@ -2760,6 +2775,7 @@ async function cmdSettingsRuntime(inst, args) {
2760
2775
  const st = upgradeStatus(inst, { fetch: fetchFlag });
2761
2776
  if (st === null) { process.stderr.write("Runtime update state is unavailable for this egregore.\n"); process.exitCode = 1; return; }
2762
2777
  emit(st);
2778
+ if (st.status === "unavailable") process.exitCode = 1;
2763
2779
  if (action === "review" || (st.status !== "active" && st.status !== "none")) {
2764
2780
  process.stdout.write("\nWhat stays:\n");
2765
2781
  for (const s of UPGRADE_STAYS) process.stdout.write(` · ${s}\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-egregore",
3
- "version": "0.21.0-runtime-mvp.21",
3
+ "version": "0.21.0-runtime-mvp.22",
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": {
@@ -6,7 +6,12 @@ set -euo pipefail
6
6
  # legacy Local instances create opaque local IDs once. Network failure remains
7
7
  # non-fatal to startup and is retried next session.
8
8
 
9
- ROOT="$(cd "$(dirname "$0")/.." && pwd)"
9
+ RUNTIME_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
10
+ # A launcher-carried bridge runs outside the selected instance. Keep code
11
+ # rooted in the packaged Runtime while resolving and persisting identity in
12
+ # exactly the instance the launcher selected.
13
+ ROOT="${EGREGORE_INSTANCE_ROOT:-$RUNTIME_ROOT}"
14
+ ROOT="$(cd "$ROOT" && pwd)"
10
15
  CONFIG="$ROOT/egregore.json"
11
16
  STATE="$ROOT/.egregore-state.json"
12
17
 
@@ -34,7 +39,9 @@ case "${1:-ensure}" in
34
39
  resolved && exit 0
35
40
  mode="$(jq -r 'if (.mode // "local") == "connected" or (.api_url // "") != "" then "connected" else "local" end' "$CONFIG" 2>/dev/null || echo local)"
36
41
  if [ "$mode" = "local" ]; then
37
- EGREGORE_ROOT="$ROOT" python3 -m egregore_runtime.identity_cli initialize-local >/dev/null
42
+ EGREGORE_ROOT="$ROOT" \
43
+ PYTHONPATH="$RUNTIME_ROOT${PYTHONPATH:+:$PYTHONPATH}" \
44
+ python3 -m egregore_runtime.identity_cli initialize-local >/dev/null
38
45
  else
39
46
  api_url="$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null)"
40
47
  api_key="$(grep '^EGREGORE_API_KEY=' "$ROOT/.env" 2>/dev/null | cut -d= -f2-)"
@@ -58,7 +65,9 @@ case "${1:-ensure}" in
58
65
  --argjson organization "$control_plane" \
59
66
  --argjson roster "$roster" \
60
67
  '{organization:$organization,roster:$roster}' | \
61
- EGREGORE_ROOT="$ROOT" python3 -m egregore_runtime.identity_cli \
68
+ EGREGORE_ROOT="$ROOT" \
69
+ PYTHONPATH="$RUNTIME_ROOT${PYTHONPATH:+:$PYTHONPATH}" \
70
+ python3 -m egregore_runtime.identity_cli \
62
71
  reconcile-records >/dev/null
63
72
  fi
64
73
  resolved
@@ -28,13 +28,35 @@ _runtime() {
28
28
  python3 -m egregore_runtime.harness_cli "$@"
29
29
  }
30
30
 
31
+ _ensure_identity() {
32
+ # Pre-Runtime instances can predate stable organization identity. Resolve it
33
+ # through the existing verified Local/Connected migration before computing
34
+ # the instance-scoped upgrade key; never infer identity from path or slug.
35
+ if jq -e '
36
+ .org_id | type == "string" and length > 0
37
+ ' "$INSTANCE_ROOT/egregore.json" >/dev/null 2>&1; then
38
+ return 0
39
+ fi
40
+ EGREGORE_INSTANCE_ROOT="$INSTANCE_ROOT" \
41
+ PYTHONPATH="$SCRIPT_DIR${PYTHONPATH:+:$PYTHONPATH}" \
42
+ bash "$SCRIPT_DIR/bin/runtime-identity.sh" ensure
43
+ }
44
+
45
+ _run_upgrade() {
46
+ _ensure_identity || {
47
+ echo "Runtime update could not resolve this Egregore's stable identity." >&2
48
+ return 1
49
+ }
50
+ _runtime upgrade "$@"
51
+ }
52
+
31
53
  case "${1:-}" in
32
- status) shift; _runtime upgrade status "$@" ;;
33
- init) shift; _runtime upgrade init "$@" ;;
34
- prepare) shift; _runtime upgrade prepare "$@" ;;
35
- activate) shift; _runtime upgrade activate "$@" ;;
36
- cancel) shift; _runtime upgrade cancel "$@" ;;
37
- rollback) shift; _runtime upgrade rollback "$@" ;;
54
+ status) shift; _run_upgrade status "$@" ;;
55
+ init) shift; _run_upgrade init "$@" ;;
56
+ prepare) shift; _run_upgrade prepare "$@" ;;
57
+ activate) shift; _run_upgrade activate "$@" ;;
58
+ cancel) shift; _run_upgrade cancel "$@" ;;
59
+ rollback) shift; _run_upgrade rollback "$@" ;;
38
60
  team-sync) shift; _runtime team-sync "$@" ;;
39
61
  *)
40
62
  echo "usage: bash bin/runtime-upgrade.sh {status|init --candidate <version>|prepare|activate|cancel|rollback|team-sync}" >&2
@@ -6,7 +6,12 @@ set -euo pipefail
6
6
  # legacy Local instances create opaque local IDs once. Network failure remains
7
7
  # non-fatal to startup and is retried next session.
8
8
 
9
- ROOT="$(cd "$(dirname "$0")/.." && pwd)"
9
+ RUNTIME_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
10
+ # A launcher-carried bridge runs outside the selected instance. Keep code
11
+ # rooted in the packaged Runtime while resolving and persisting identity in
12
+ # exactly the instance the launcher selected.
13
+ ROOT="${EGREGORE_INSTANCE_ROOT:-$RUNTIME_ROOT}"
14
+ ROOT="$(cd "$ROOT" && pwd)"
10
15
  CONFIG="$ROOT/egregore.json"
11
16
  STATE="$ROOT/.egregore-state.json"
12
17
 
@@ -34,7 +39,9 @@ case "${1:-ensure}" in
34
39
  resolved && exit 0
35
40
  mode="$(jq -r 'if (.mode // "local") == "connected" or (.api_url // "") != "" then "connected" else "local" end' "$CONFIG" 2>/dev/null || echo local)"
36
41
  if [ "$mode" = "local" ]; then
37
- EGREGORE_ROOT="$ROOT" python3 -m egregore_runtime.identity_cli initialize-local >/dev/null
42
+ EGREGORE_ROOT="$ROOT" \
43
+ PYTHONPATH="$RUNTIME_ROOT${PYTHONPATH:+:$PYTHONPATH}" \
44
+ python3 -m egregore_runtime.identity_cli initialize-local >/dev/null
38
45
  else
39
46
  api_url="$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null)"
40
47
  api_key="$(grep '^EGREGORE_API_KEY=' "$ROOT/.env" 2>/dev/null | cut -d= -f2-)"
@@ -58,7 +65,9 @@ case "${1:-ensure}" in
58
65
  --argjson organization "$control_plane" \
59
66
  --argjson roster "$roster" \
60
67
  '{organization:$organization,roster:$roster}' | \
61
- EGREGORE_ROOT="$ROOT" python3 -m egregore_runtime.identity_cli \
68
+ EGREGORE_ROOT="$ROOT" \
69
+ PYTHONPATH="$RUNTIME_ROOT${PYTHONPATH:+:$PYTHONPATH}" \
70
+ python3 -m egregore_runtime.identity_cli \
62
71
  reconcile-records >/dev/null
63
72
  fi
64
73
  resolved
@@ -28,13 +28,35 @@ _runtime() {
28
28
  python3 -m egregore_runtime.harness_cli "$@"
29
29
  }
30
30
 
31
+ _ensure_identity() {
32
+ # Pre-Runtime instances can predate stable organization identity. Resolve it
33
+ # through the existing verified Local/Connected migration before computing
34
+ # the instance-scoped upgrade key; never infer identity from path or slug.
35
+ if jq -e '
36
+ .org_id | type == "string" and length > 0
37
+ ' "$INSTANCE_ROOT/egregore.json" >/dev/null 2>&1; then
38
+ return 0
39
+ fi
40
+ EGREGORE_INSTANCE_ROOT="$INSTANCE_ROOT" \
41
+ PYTHONPATH="$SCRIPT_DIR${PYTHONPATH:+:$PYTHONPATH}" \
42
+ bash "$SCRIPT_DIR/bin/runtime-identity.sh" ensure
43
+ }
44
+
45
+ _run_upgrade() {
46
+ _ensure_identity || {
47
+ echo "Runtime update could not resolve this Egregore's stable identity." >&2
48
+ return 1
49
+ }
50
+ _runtime upgrade "$@"
51
+ }
52
+
31
53
  case "${1:-}" in
32
- status) shift; _runtime upgrade status "$@" ;;
33
- init) shift; _runtime upgrade init "$@" ;;
34
- prepare) shift; _runtime upgrade prepare "$@" ;;
35
- activate) shift; _runtime upgrade activate "$@" ;;
36
- cancel) shift; _runtime upgrade cancel "$@" ;;
37
- rollback) shift; _runtime upgrade rollback "$@" ;;
54
+ status) shift; _run_upgrade status "$@" ;;
55
+ init) shift; _run_upgrade init "$@" ;;
56
+ prepare) shift; _run_upgrade prepare "$@" ;;
57
+ activate) shift; _run_upgrade activate "$@" ;;
58
+ cancel) shift; _run_upgrade cancel "$@" ;;
59
+ rollback) shift; _run_upgrade rollback "$@" ;;
38
60
  team-sync) shift; _runtime team-sync "$@" ;;
39
61
  *)
40
62
  echo "usage: bash bin/runtime-upgrade.sh {status|init --candidate <version>|prepare|activate|cancel|rollback|team-sync}" >&2
@@ -6,7 +6,12 @@ set -euo pipefail
6
6
  # legacy Local instances create opaque local IDs once. Network failure remains
7
7
  # non-fatal to startup and is retried next session.
8
8
 
9
- ROOT="$(cd "$(dirname "$0")/.." && pwd)"
9
+ RUNTIME_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
10
+ # A launcher-carried bridge runs outside the selected instance. Keep code
11
+ # rooted in the packaged Runtime while resolving and persisting identity in
12
+ # exactly the instance the launcher selected.
13
+ ROOT="${EGREGORE_INSTANCE_ROOT:-$RUNTIME_ROOT}"
14
+ ROOT="$(cd "$ROOT" && pwd)"
10
15
  CONFIG="$ROOT/egregore.json"
11
16
  STATE="$ROOT/.egregore-state.json"
12
17
 
@@ -34,7 +39,9 @@ case "${1:-ensure}" in
34
39
  resolved && exit 0
35
40
  mode="$(jq -r 'if (.mode // "local") == "connected" or (.api_url // "") != "" then "connected" else "local" end' "$CONFIG" 2>/dev/null || echo local)"
36
41
  if [ "$mode" = "local" ]; then
37
- EGREGORE_ROOT="$ROOT" python3 -m egregore_runtime.identity_cli initialize-local >/dev/null
42
+ EGREGORE_ROOT="$ROOT" \
43
+ PYTHONPATH="$RUNTIME_ROOT${PYTHONPATH:+:$PYTHONPATH}" \
44
+ python3 -m egregore_runtime.identity_cli initialize-local >/dev/null
38
45
  else
39
46
  api_url="$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null)"
40
47
  api_key="$(grep '^EGREGORE_API_KEY=' "$ROOT/.env" 2>/dev/null | cut -d= -f2-)"
@@ -58,7 +65,9 @@ case "${1:-ensure}" in
58
65
  --argjson organization "$control_plane" \
59
66
  --argjson roster "$roster" \
60
67
  '{organization:$organization,roster:$roster}' | \
61
- EGREGORE_ROOT="$ROOT" python3 -m egregore_runtime.identity_cli \
68
+ EGREGORE_ROOT="$ROOT" \
69
+ PYTHONPATH="$RUNTIME_ROOT${PYTHONPATH:+:$PYTHONPATH}" \
70
+ python3 -m egregore_runtime.identity_cli \
62
71
  reconcile-records >/dev/null
63
72
  fi
64
73
  resolved
@@ -28,13 +28,35 @@ _runtime() {
28
28
  python3 -m egregore_runtime.harness_cli "$@"
29
29
  }
30
30
 
31
+ _ensure_identity() {
32
+ # Pre-Runtime instances can predate stable organization identity. Resolve it
33
+ # through the existing verified Local/Connected migration before computing
34
+ # the instance-scoped upgrade key; never infer identity from path or slug.
35
+ if jq -e '
36
+ .org_id | type == "string" and length > 0
37
+ ' "$INSTANCE_ROOT/egregore.json" >/dev/null 2>&1; then
38
+ return 0
39
+ fi
40
+ EGREGORE_INSTANCE_ROOT="$INSTANCE_ROOT" \
41
+ PYTHONPATH="$SCRIPT_DIR${PYTHONPATH:+:$PYTHONPATH}" \
42
+ bash "$SCRIPT_DIR/bin/runtime-identity.sh" ensure
43
+ }
44
+
45
+ _run_upgrade() {
46
+ _ensure_identity || {
47
+ echo "Runtime update could not resolve this Egregore's stable identity." >&2
48
+ return 1
49
+ }
50
+ _runtime upgrade "$@"
51
+ }
52
+
31
53
  case "${1:-}" in
32
- status) shift; _runtime upgrade status "$@" ;;
33
- init) shift; _runtime upgrade init "$@" ;;
34
- prepare) shift; _runtime upgrade prepare "$@" ;;
35
- activate) shift; _runtime upgrade activate "$@" ;;
36
- cancel) shift; _runtime upgrade cancel "$@" ;;
37
- rollback) shift; _runtime upgrade rollback "$@" ;;
54
+ status) shift; _run_upgrade status "$@" ;;
55
+ init) shift; _run_upgrade init "$@" ;;
56
+ prepare) shift; _run_upgrade prepare "$@" ;;
57
+ activate) shift; _run_upgrade activate "$@" ;;
58
+ cancel) shift; _run_upgrade cancel "$@" ;;
59
+ rollback) shift; _run_upgrade rollback "$@" ;;
38
60
  team-sync) shift; _runtime team-sync "$@" ;;
39
61
  *)
40
62
  echo "usage: bash bin/runtime-upgrade.sh {status|init --candidate <version>|prepare|activate|cancel|rollback|team-sync}" >&2
@@ -6,7 +6,12 @@ set -euo pipefail
6
6
  # legacy Local instances create opaque local IDs once. Network failure remains
7
7
  # non-fatal to startup and is retried next session.
8
8
 
9
- ROOT="$(cd "$(dirname "$0")/.." && pwd)"
9
+ RUNTIME_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
10
+ # A launcher-carried bridge runs outside the selected instance. Keep code
11
+ # rooted in the packaged Runtime while resolving and persisting identity in
12
+ # exactly the instance the launcher selected.
13
+ ROOT="${EGREGORE_INSTANCE_ROOT:-$RUNTIME_ROOT}"
14
+ ROOT="$(cd "$ROOT" && pwd)"
10
15
  CONFIG="$ROOT/egregore.json"
11
16
  STATE="$ROOT/.egregore-state.json"
12
17
 
@@ -34,7 +39,9 @@ case "${1:-ensure}" in
34
39
  resolved && exit 0
35
40
  mode="$(jq -r 'if (.mode // "local") == "connected" or (.api_url // "") != "" then "connected" else "local" end' "$CONFIG" 2>/dev/null || echo local)"
36
41
  if [ "$mode" = "local" ]; then
37
- EGREGORE_ROOT="$ROOT" python3 -m egregore_runtime.identity_cli initialize-local >/dev/null
42
+ EGREGORE_ROOT="$ROOT" \
43
+ PYTHONPATH="$RUNTIME_ROOT${PYTHONPATH:+:$PYTHONPATH}" \
44
+ python3 -m egregore_runtime.identity_cli initialize-local >/dev/null
38
45
  else
39
46
  api_url="$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null)"
40
47
  api_key="$(grep '^EGREGORE_API_KEY=' "$ROOT/.env" 2>/dev/null | cut -d= -f2-)"
@@ -58,7 +65,9 @@ case "${1:-ensure}" in
58
65
  --argjson organization "$control_plane" \
59
66
  --argjson roster "$roster" \
60
67
  '{organization:$organization,roster:$roster}' | \
61
- EGREGORE_ROOT="$ROOT" python3 -m egregore_runtime.identity_cli \
68
+ EGREGORE_ROOT="$ROOT" \
69
+ PYTHONPATH="$RUNTIME_ROOT${PYTHONPATH:+:$PYTHONPATH}" \
70
+ python3 -m egregore_runtime.identity_cli \
62
71
  reconcile-records >/dev/null
63
72
  fi
64
73
  resolved
@@ -28,13 +28,35 @@ _runtime() {
28
28
  python3 -m egregore_runtime.harness_cli "$@"
29
29
  }
30
30
 
31
+ _ensure_identity() {
32
+ # Pre-Runtime instances can predate stable organization identity. Resolve it
33
+ # through the existing verified Local/Connected migration before computing
34
+ # the instance-scoped upgrade key; never infer identity from path or slug.
35
+ if jq -e '
36
+ .org_id | type == "string" and length > 0
37
+ ' "$INSTANCE_ROOT/egregore.json" >/dev/null 2>&1; then
38
+ return 0
39
+ fi
40
+ EGREGORE_INSTANCE_ROOT="$INSTANCE_ROOT" \
41
+ PYTHONPATH="$SCRIPT_DIR${PYTHONPATH:+:$PYTHONPATH}" \
42
+ bash "$SCRIPT_DIR/bin/runtime-identity.sh" ensure
43
+ }
44
+
45
+ _run_upgrade() {
46
+ _ensure_identity || {
47
+ echo "Runtime update could not resolve this Egregore's stable identity." >&2
48
+ return 1
49
+ }
50
+ _runtime upgrade "$@"
51
+ }
52
+
31
53
  case "${1:-}" in
32
- status) shift; _runtime upgrade status "$@" ;;
33
- init) shift; _runtime upgrade init "$@" ;;
34
- prepare) shift; _runtime upgrade prepare "$@" ;;
35
- activate) shift; _runtime upgrade activate "$@" ;;
36
- cancel) shift; _runtime upgrade cancel "$@" ;;
37
- rollback) shift; _runtime upgrade rollback "$@" ;;
54
+ status) shift; _run_upgrade status "$@" ;;
55
+ init) shift; _run_upgrade init "$@" ;;
56
+ prepare) shift; _run_upgrade prepare "$@" ;;
57
+ activate) shift; _run_upgrade activate "$@" ;;
58
+ cancel) shift; _run_upgrade cancel "$@" ;;
59
+ rollback) shift; _run_upgrade rollback "$@" ;;
38
60
  team-sync) shift; _runtime team-sync "$@" ;;
39
61
  *)
40
62
  echo "usage: bash bin/runtime-upgrade.sh {status|init --candidate <version>|prepare|activate|cancel|rollback|team-sync}" >&2