mirror of
https://github.com/mvschwarz/openrig.git
synced 2026-11-07 05:56:21 -10:00
rig provider switch --account-home and --clear-account-home select or clear an existing Pi seat's account home through a confirmed successor with a fresh conversation and handover; an unconfirmed or failed switch leaves the old account and state intact, and the selection survives restart, resume, restore and daemon restart (migration 151 keeps switch history and creates or copies no credentials). The chosen directory must already hold a readable auth.json, which the runner links into the seat's managed agent directory; env-only accounts and wrappers that create credentials later are outside this path, and an existing seat-local login or unmanaged auth link is preserved through the confirmed switch. Selected accounts load a Node preload that points only their auth-lock operations at the chosen account's auth.json.lock pathname, even when that auth.json is a symlink, and removes its own NODE_OPTIONS entry before Pi starts tools; outside the managed target it does nothing. A Node-hosted launch wrapper that execs Pi can consume the preload, so that Pi gets no shared-auth lock and keeps its native per-seat lock; compiled Pi and wrappers that discard NODE_OPTIONS are likewise not covered. Contributed by seanmcn; requested in #2629.
27 lines
1.8 KiB
TypeScript
27 lines
1.8 KiB
TypeScript
import { expect, it } from "vitest";
|
|
import { createDb } from "../src/db/connection.js";
|
|
import { migrate } from "../src/db/migrate.js";
|
|
import { ALL_MIGRATIONS } from "../src/db/all-migrations.js";
|
|
import { piAccountSwitchesSchema } from "../src/db/migrations/151_pi_account_switches.js";
|
|
|
|
it("retains an interrupted runtime switch when upgrading to Pi-capable switches", () => {
|
|
const db = createDb();
|
|
try {
|
|
migrate(db, ALL_MIGRATIONS.filter(migration => migration.name !== piAccountSwitchesSchema.name));
|
|
db.exec("INSERT INTO rigs (id, name) VALUES ('rig', 'upgrade'); INSERT INTO nodes (id, rig_id, logical_id) VALUES ('seat', 'rig', 'dev.build');");
|
|
const insert = db.prepare(`INSERT INTO seat_runtime_switches
|
|
(id, node_id, canonical_session, staging_session, predecessor_pane, predecessor_generation, successor_generation, from_runtime, to_runtime, reason, plan_json, deadline_at)
|
|
VALUES (?, 'seat', 'build@upgrade', ?, '%0', 'before', ?, 'codex', ?, 'allowance', '{}', '2026-11-03T03:00:00Z')`);
|
|
insert.run("old", "staging-old", "after-old", "claude-code");
|
|
const before = db.prepare("SELECT * FROM seat_runtime_switches WHERE id = 'old'").get();
|
|
migrate(db, ALL_MIGRATIONS);
|
|
expect(db.prepare("SELECT * FROM seat_runtime_switches WHERE id = 'old'").get()).toEqual(before);
|
|
expect(() => insert.run("duplicate", "staging-new", "after-new", "pi")).toThrow();
|
|
db.exec("UPDATE seat_runtime_switches SET phase = 'abandoned' WHERE id = 'old'");
|
|
insert.run("pi", "staging-new", "after-new", "pi");
|
|
expect(db.prepare("SELECT to_runtime FROM seat_runtime_switches WHERE id = 'pi'").get()).toEqual({ to_runtime: "pi" });
|
|
migrate(db, ALL_MIGRATIONS);
|
|
expect(db.pragma("foreign_key_check")).toEqual([]);
|
|
} finally { db.close(); }
|
|
});
|