import type { ExtensionContext } from "@earendil-works/pi-coding-agent"; import { extractMessageText, truncateText } from "./messages.ts"; import { parseEnabled, parseKittyVisibility, parseMessageMax, parseMessageSource, parseMinDurationMs, parseNotificationAction, } from "./parsers.ts"; import { renderTemplate } from "./template.ts"; import type { NotificationRuntimeValues, NotifyConfig } from "./types.ts"; const DEFAULT_TITLE = "π - {project}"; const DEFAULT_BODY = "{message}"; export function getConfig( ctx: ExtensionContext | undefined, startedAt: number | undefined, messages: unknown[] | undefined, runtime: NotificationRuntimeValues, now = Date.now(), ): NotifyConfig { const durationMs = startedAt === undefined ? 0 : Math.max(0, now - startedAt); const messageMax = parseMessageMax(process.env.PI_NOTIFY_MESSAGE_MAX); const userMessage = truncateText(extractMessageText(messages, "user"), messageMax); const assistantMessage = truncateText(extractMessageText(messages, "assistant"), messageMax); const messageSource = parseMessageSource(process.env.PI_NOTIFY_MESSAGE_SOURCE); const selectedMessage = messageSource === "user" ? userMessage : messageSource === "assistant" ? assistantMessage : ""; const message = selectedMessage || "Ready for input"; const toolErrorCount = Math.max(0, runtime.toolErrorCount ?? 0); const values = { user_message: userMessage, assistant_message: assistantMessage, message, status: toolErrorCount > 0 ? `ready · ${toolErrorCount} tool error${toolErrorCount === 1 ? "" : "s"}` : "ready", status_icon: toolErrorCount > 0 ? "⚠" : "✓", tool_error_count: String(toolErrorCount), }; return { enabled: parseEnabled(process.env.PI_NOTIFY_ENABLED), title: renderTemplate(process.env.PI_NOTIFY_TITLE || DEFAULT_TITLE, ctx, durationMs, values), body: renderTemplate(process.env.PI_NOTIFY_BODY || DEFAULT_BODY, ctx, durationMs, values), durationMs, minDurationMs: parseMinDurationMs(process.env.PI_NOTIFY_MIN_SECONDS), notificationId: runtime.notificationId, visibility: parseKittyVisibility(process.env.PI_NOTIFY_VISIBILITY), action: parseNotificationAction(process.env.PI_NOTIFY_ACTION), soundCommand: process.env.PI_NOTIFY_SOUND_CMD?.trim() || undefined, }; } export function shouldNotify(config: NotifyConfig, enabledOverride?: boolean): boolean { return (enabledOverride ?? config.enabled) && config.durationMs >= config.minDurationMs; }