31300cc2a2
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>
44 lines
1.2 KiB
TypeScript
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;
|
|
}
|