Files
shahondin1624 31300cc2a2 Include shared/ dir in repo (gitignore allowlist)
The previous commit referenced shared/ansi.ts, shared/format.ts, and
shared/ctx.ts but those files were filtered by the default-deny
.gitignore. Adding !/shared/ to the allowlist so the imports actually
resolve in a fresh clone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 00:05:38 +02:00

44 lines
1.2 KiB
TypeScript

/**
* Helpers for dealing with pi's ExtensionContext in the face of its
* "stale after session replacement or reload" semantics.
*
* Pi's ExtensionRunner throws when any captured ctx field is accessed after
* the runner has been torn down (on /quit, /reload, new session). This
* module provides a single guarded wrapper so every extension doesn't have
* to re-implement try/catch + null-on-shutdown patterns.
*/
/**
* Run `fn` with the given ctx, swallowing any "stale context" errors that
* occur when pi's runner has gone away between the event that captured ctx
* and the time we're now using it (TUI render timers, setInterval ticks,
* etc.). Returns `undefined` on failure.
*/
export function safely<T>(fn: () => T): T | undefined {
try {
return fn();
} catch {
return undefined;
}
}
/**
* Async variant of `safely`.
*/
export async function safelyAsync<T>(fn: () => Promise<T>): Promise<T | undefined> {
try {
return await fn();
} catch {
return undefined;
}
}
/** Minimal shape we rely on — avoids coupling every caller to ExtensionContext. */
export interface UiLike {
hasUI: boolean;
}
export function hasUI(ctx: UiLike | null | undefined): ctx is UiLike & { hasUI: true } {
return !!ctx && ctx.hasUI === true;
}