export const ANON_NOTIFY_STATE_CHANNEL = "anon-notify:state"; export const ANON_NOTIFY_STATE_VERSION = 1 as const; export const ANON_NOTIFY_ACTIVATION_ENTRY_TYPE = "anon-notify:activation"; export const ANON_NOTIFY_ACTIVATION_VERSION = 1 as const; export interface AnonNotifyActivationRecordV1 { version: typeof ANON_NOTIFY_ACTIVATION_VERSION; active: boolean; } function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } function isAnonNotifyActivationRecordV1(value: unknown): value is AnonNotifyActivationRecordV1 { if (!isRecord(value) || Object.keys(value).length !== 2) return false; return value.version === ANON_NOTIFY_ACTIVATION_VERSION && typeof value.active === "boolean"; } export function createAnonNotifyActivationRecord(active: boolean): AnonNotifyActivationRecordV1 { return { version: ANON_NOTIFY_ACTIVATION_VERSION, active }; } export function readAnonNotifyActivation(entries: readonly unknown[]): boolean { for (let index = entries.length - 1; index >= 0; index -= 1) { const entry = entries[index]; if ( !isRecord(entry) || entry.type !== "custom" || entry.customType !== ANON_NOTIFY_ACTIVATION_ENTRY_TYPE ) continue; return isAnonNotifyActivationRecordV1(entry.data) ? entry.data.active : false; } return false; } export type SessionActivationStatus = "active" | "inactive" | "subagent-suppressed"; export type AnonNotifyExtensionStatus = "active" | "inactive" | "global-disabled" | "main-only" | "unavailable"; export interface AnonNotifyExtensionStateV1 { version: typeof ANON_NOTIFY_STATE_VERSION; sessionId: string; status: AnonNotifyExtensionStatus; sessionActive: boolean; servicesEnabled: boolean; tokenConfigured: boolean; } export interface AnonNotifyExtensionStateInput { sessionId: string; configLoaded: boolean; globallyEnabled: boolean; sessionSuppressed: boolean; sessionActive: boolean; tokenConfigured: boolean; } export function buildAnonNotifyExtensionState( input: AnonNotifyExtensionStateInput, ): AnonNotifyExtensionStateV1 { const status: AnonNotifyExtensionStatus = !input.configLoaded ? "unavailable" : input.sessionSuppressed ? "main-only" : !input.globallyEnabled ? "global-disabled" : input.sessionActive ? "active" : "inactive"; return { version: ANON_NOTIFY_STATE_VERSION, sessionId: input.sessionId, status, sessionActive: input.sessionActive, servicesEnabled: input.configLoaded && input.globallyEnabled && !input.sessionSuppressed && input.sessionActive, tokenConfigured: input.tokenConfigured, }; } /** In-memory projection of the current session's durable activation record. */ export class SessionActivation { private sessionId: string | undefined; private active = false; restore(sessionId: string, active: boolean): void { this.sessionId = sessionId; this.active = active; } enable(sessionId: string): void { this.sessionId = sessionId; this.active = true; } disable(sessionId?: string): void { if (sessionId === undefined || sessionId === this.sessionId) { this.active = false; } } isActive(sessionId: string | undefined): boolean { return Boolean(this.active && sessionId && sessionId === this.sessionId); } status(sessionId: string | undefined, suppressed: boolean): SessionActivationStatus { if (suppressed) return "subagent-suppressed"; return this.isActive(sessionId) ? "active" : "inactive"; } } export function sessionServicesEnabled( status: SessionActivationStatus, globallyEnabled: boolean, ): boolean { return globallyEnabled && status === "active"; }