{"version":3,"file":"notification.mjs","names":[],"sources":["../../src/schemas/notification.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis';\nimport { type Static, Type } from 'typebox';\nimport { Check } from 'typebox/value';\n\n/** Provider-owned Cordis service for caller-authored notification requests. */\nexport const DOOM_NOTIFICATION_SERVICE = 'doom/notification';\n/** Custom session entry type used to publish normalized notification data. */\nexport const DOOM_NOTIFICATION_ENTRY_TYPE = 'doom-notification';\nexport const DOOM_NOTIFICATION_ENTRY_VERSION = 1 as const;\nexport const MAX_DOOM_NOTIFICATION_TITLE_CHARACTERS = 128;\nexport const MAX_DOOM_NOTIFICATION_SUBTITLE_CHARACTERS = 256;\nexport const MAX_DOOM_NOTIFICATION_BODY_CHARACTERS = 4_096;\n\nexport const DoomNotificationLevelSchema = Type.Union([\n  Type.Literal('info'),\n  Type.Literal('warning'),\n  Type.Literal('error'),\n]);\nexport type DoomNotificationLevel = Static<typeof DoomNotificationLevelSchema>;\n\nexport const DoomNotificationRequestSchema = Type.Object(\n  {\n    title: Type.Optional(Type.String({ minLength: 1, maxLength: MAX_DOOM_NOTIFICATION_TITLE_CHARACTERS })),\n    subtitle: Type.Optional(Type.String({ minLength: 1, maxLength: MAX_DOOM_NOTIFICATION_SUBTITLE_CHARACTERS })),\n    body: Type.String({ minLength: 1, maxLength: MAX_DOOM_NOTIFICATION_BODY_CHARACTERS }),\n    level: Type.Optional(DoomNotificationLevelSchema),\n  },\n  { additionalProperties: false },\n);\nexport type DoomNotificationRequest = Static<typeof DoomNotificationRequestSchema>;\n\nconst NormalizableDoomNotificationRequestSchema = Type.Object(\n  {\n    title: Type.Optional(Type.String()),\n    subtitle: Type.Optional(Type.String()),\n    body: Type.String(),\n    level: Type.Optional(DoomNotificationLevelSchema),\n  },\n  { additionalProperties: false },\n);\n\nexport const DoomNotificationEntryDataSchema = Type.Object(\n  {\n    version: Type.Literal(DOOM_NOTIFICATION_ENTRY_VERSION),\n    title: Type.String({ maxLength: MAX_DOOM_NOTIFICATION_TITLE_CHARACTERS }),\n    subtitle: Type.String({ maxLength: MAX_DOOM_NOTIFICATION_SUBTITLE_CHARACTERS }),\n    body: Type.String({ minLength: 1, maxLength: MAX_DOOM_NOTIFICATION_BODY_CHARACTERS }),\n    level: DoomNotificationLevelSchema,\n  },\n  { additionalProperties: false },\n);\nexport type DoomNotificationEntryData = Static<typeof DoomNotificationEntryDataSchema>;\n\n/** Generic outbound notification seam. The provider owns delivery and lifecycle. */\nexport interface DoomNotificationService {\n  readonly generation: string;\n  request(request: DoomNotificationRequest): void | Promise<void>;\n}\n\ndeclare module '@deepseek-ai/cordis' {\n  interface Context {\n    'doom/notification': DoomNotificationService;\n  }\n}\n\nfunction replaceControlCharacters(text: string): string {\n  return Array.from(text, (character) => {\n    const codePoint = character.codePointAt(0);\n    return codePoint !== undefined && (codePoint < 0x20 || codePoint === 0x7f) ? ' ' : character;\n  }).join('');\n}\n\nfunction normalizeText(text: string, maximum: number): string | undefined {\n  const normalized = replaceControlCharacters(text).replace(/\\s+/gu, ' ').trim();\n  if (!normalized) return undefined;\n\n  let truncated = '';\n  for (const character of normalized) {\n    if (truncated.length + character.length > maximum) break;\n    truncated += character;\n  }\n  return truncated;\n}\n\n/** Normalize caller-owned notification text into a validated request. */\nexport function normalizeDoomNotificationRequest(request: unknown): DoomNotificationRequest | undefined {\n  if (!Check(NormalizableDoomNotificationRequestSchema, request)) return undefined;\n\n  const body = normalizeText(request.body, MAX_DOOM_NOTIFICATION_BODY_CHARACTERS);\n  if (!body) return undefined;\n  const title = request.title && normalizeText(request.title, MAX_DOOM_NOTIFICATION_TITLE_CHARACTERS);\n  const subtitle = request.subtitle && normalizeText(request.subtitle, MAX_DOOM_NOTIFICATION_SUBTITLE_CHARACTERS);\n  const normalized = {\n    body,\n    ...(title ? { title } : {}),\n    ...(subtitle ? { subtitle } : {}),\n    ...(request.level ? { level: request.level } : {}),\n  };\n  return Object.freeze(normalized);\n}\n\n/** Builds normalized, versioned data for a Doom notification session entry. */\nexport function createDoomNotificationEntryData(request: unknown): DoomNotificationEntryData | undefined {\n  const normalized = normalizeDoomNotificationRequest(request);\n  if (!normalized) return undefined;\n  return Object.freeze({\n    version: DOOM_NOTIFICATION_ENTRY_VERSION,\n    title: normalized.title ?? '',\n    subtitle: normalized.subtitle ?? '',\n    body: normalized.body,\n    level: normalized.level ?? 'info',\n  });\n}\n\nexport function isDoomNotificationRequest(value: unknown): value is DoomNotificationRequest {\n  return Check(DoomNotificationRequestSchema, value);\n}\n\nexport function isDoomNotificationEntryData(value: unknown): value is DoomNotificationEntryData {\n  return Check(DoomNotificationEntryDataSchema, value);\n}\n\nexport function readDoomNotificationService(context: Context): DoomNotificationService | undefined {\n  return context.get(DOOM_NOTIFICATION_SERVICE) as DoomNotificationService | undefined;\n}\n\nexport function requireDoomNotificationService(context: Context): DoomNotificationService {\n  const service = readDoomNotificationService(context);\n  if (!service) throw new Error('Doom notification is unavailable. Load a notification provider.');\n  return service;\n}\n"],"mappings":"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"}