{"version":3,"file":"profileIdentity.mjs","names":[],"sources":["../../src/schemas/profileIdentity.ts"],"sourcesContent":["import { type Static, Type } from 'typebox';\n\n/**\n * The custom session entry the runtime journals when the active profile's\n * persona identity changes.\n *\n * A profile has always been prompt text only, so a cockpit had nothing to show\n * for it beyond the profile name already published as footer status. This entry\n * carries the persona's display name and avatar so the transcript can attribute\n * each assistant message to the persona that produced it.\n *\n * It rides Pi's `entry_appended` frames on the road the agent-model projection\n * already uses, so any RPC client sees the change live and on replay without a\n * new protocol.\n *\n * Unlike the minor-mode, context, and agent-model projections, this entry is\n * NOT a projection: it is transcript, positioned in journal order. A cockpit\n * folding it must keep every occurrence rather than collapsing to the latest\n * one, because a message written before a switch keeps the identity it was\n * written under. Collapsing would rewrite history.\n */\nexport const DOOM_PROFILE_IDENTITY_ENTRY_TYPE = 'doom-profile-identity';\n\n/**\n * Ceiling on the encoded icon, counted on the finished `data:` URL rather than\n * the file, so one number bounds both the journal entry and the transport.\n *\n * An avatar renders at 32 CSS pixels. This much room is already generous, and\n * the cap exists because the entry is replayed with the transcript: an oversize\n * icon is dropped and the persona keeps its name, never failing a profile load.\n */\nexport const PROFILE_ICON_MAX_DATA_URL_LENGTH = 262_144;\n\nconst MAX_PROFILE_NAME_LENGTH = 128;\n\n/**\n * Image types allowed for a persona icon.\n *\n * Deliberately narrower than the cockpit's general media catalog: `image/svg+xml`\n * is excluded because an SVG rendered same-origin executes script, and the icon\n * path comes from user-authored persona front-matter. Do not reconcile this list\n * with the broader media type map.\n */\nexport const PROFILE_ICON_MIME_TYPES = ['image/png', 'image/jpeg', 'image/gif', 'image/webp'] as const;\nexport type ProfileIconMimeType = (typeof PROFILE_ICON_MIME_TYPES)[number];\n\nexport const ProfileIdentityProjectionSchema = Type.Object(\n  {\n    profile: Type.String({ minLength: 1, maxLength: MAX_PROFILE_NAME_LENGTH }),\n    name: Type.Optional(Type.String({ minLength: 1, maxLength: MAX_PROFILE_NAME_LENGTH })),\n    icon: Type.Optional(Type.String({ minLength: 1, maxLength: PROFILE_ICON_MAX_DATA_URL_LENGTH })),\n  },\n  { additionalProperties: false },\n);\n\n/** The persona a message was produced under: the profile name, plus optional display name and icon. */\nexport type ProfileIdentityProjection = Static<typeof ProfileIdentityProjectionSchema>;\n"],"mappings":"+BAqBA,MAAa,EAAmC,wBAUnC,EAAmC,OAYnC,EAA0B,CAAC,YAAa,aAAc,YAAa,YAAY,EAG/E,EAAkC,EAAK,OAClD,CACE,QAAS,EAAK,OAAO,CAAE,UAAW,EAAG,UAAW,GAAwB,CAAC,EACzE,KAAM,EAAK,SAAS,EAAK,OAAO,CAAE,UAAW,EAAG,UAAW,GAAwB,CAAC,CAAC,EACrF,KAAM,EAAK,SAAS,EAAK,OAAO,CAAE,UAAW,EAAG,UAAW,CAAiC,CAAC,CAAC,CAChG,EACA,CAAE,qBAAsB,EAAM,CAChC"}