fix(extension): guard ctx.ui.theme access for RPC mode (#121)

Theme proxy throws when accessed in RPC mode since initTheme() is
never called without a TUI. Wrap header rendering in try/catch so
the GSD extension loads cleanly in both TUI and RPC modes.

Closes #121

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lex Christopherson 2026-03-12 10:44:55 -06:00
parent 2a5c270bb0
commit f4b1d888d6

View file

@ -158,14 +158,19 @@ export default function (pi: ExtensionAPI) {
// ── session_start: render branded GSD header + remote channel status ──
pi.on("session_start", async (_event, ctx) => {
const theme = ctx.ui.theme;
const version = process.env.GSD_VERSION || "0.0.0";
// Theme access throws in RPC mode (no TUI) — header is decorative, skip it
try {
const theme = ctx.ui.theme;
const version = process.env.GSD_VERSION || "0.0.0";
const logoText = GSD_LOGO_LINES.map((line) => theme.fg("accent", line)).join("\n");
const titleLine = ` ${theme.bold("Get Shit Done")} ${theme.fg("dim", `v${version}`)}`;
const logoText = GSD_LOGO_LINES.map((line) => theme.fg("accent", line)).join("\n");
const titleLine = ` ${theme.bold("Get Shit Done")} ${theme.fg("dim", `v${version}`)}`;
const headerContent = `${logoText}\n${titleLine}`;
ctx.ui.setHeader((_ui, _theme) => new Text(headerContent, 1, 0));
const headerContent = `${logoText}\n${titleLine}`;
ctx.ui.setHeader((_ui, _theme) => new Text(headerContent, 1, 0));
} catch {
// RPC mode — no TUI, skip header rendering
}
// Notify remote questions status if configured
try {