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.
- package/assets/egregore-launcher.js +27 -11
- package/package.json +1 -1
- package/runtime/claude/bin/runtime-identity.sh +12 -3
- package/runtime/claude/bin/runtime-upgrade.sh +28 -6
- package/runtime/codex/bin/runtime-identity.sh +12 -3
- package/runtime/codex/bin/runtime-upgrade.sh +28 -6
- package/runtime/pi/bin/runtime-identity.sh +12 -3
- package/runtime/pi/bin/runtime-upgrade.sh +28 -6
- package/runtime/prime/bin/runtime-identity.sh +12 -3
- package/runtime/prime/bin/runtime-upgrade.sh +28 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// egregore-launcher-version: 0.21.0-runtime-mvp.
|
|
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.
|
|
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)
|
|
2503
|
-
|
|
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(
|
|
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", "
|
|
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("
|
|
2514
|
-
child.on("
|
|
2515
|
-
|
|
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 && (
|
|
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.
|
|
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
|
-
|
|
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"
|
|
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"
|
|
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;
|
|
33
|
-
init) shift;
|
|
34
|
-
prepare) shift;
|
|
35
|
-
activate) shift;
|
|
36
|
-
cancel) shift;
|
|
37
|
-
rollback) shift;
|
|
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
|
-
|
|
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"
|
|
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"
|
|
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;
|
|
33
|
-
init) shift;
|
|
34
|
-
prepare) shift;
|
|
35
|
-
activate) shift;
|
|
36
|
-
cancel) shift;
|
|
37
|
-
rollback) shift;
|
|
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
|
-
|
|
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"
|
|
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"
|
|
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;
|
|
33
|
-
init) shift;
|
|
34
|
-
prepare) shift;
|
|
35
|
-
activate) shift;
|
|
36
|
-
cancel) shift;
|
|
37
|
-
rollback) shift;
|
|
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
|
-
|
|
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"
|
|
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"
|
|
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;
|
|
33
|
-
init) shift;
|
|
34
|
-
prepare) shift;
|
|
35
|
-
activate) shift;
|
|
36
|
-
cancel) shift;
|
|
37
|
-
rollback) shift;
|
|
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
|