@shadowob/shared
Advanced tools
| // src/constants/events.ts | ||
| var CLIENT_EVENTS = { | ||
| CHANNEL_JOIN: "channel:join", | ||
| CHANNEL_LEAVE: "channel:leave", | ||
| MESSAGE_SEND: "message:send", | ||
| MESSAGE_TYPING: "message:typing", | ||
| PRESENCE_UPDATE: "presence:update", | ||
| VOICE_JOIN: "voice:join", | ||
| VOICE_LEAVE: "voice:leave", | ||
| VOICE_STATE_UPDATE: "voice:state:update", | ||
| VOICE_TOKEN_RENEW: "voice:token:renew", | ||
| VOICE_HEARTBEAT: "voice:heartbeat" | ||
| }; | ||
| var SERVER_EVENTS = { | ||
| MESSAGE_NEW: "message:new", | ||
| MESSAGE_UPDATE: "message:update", | ||
| MESSAGE_DELETE: "message:delete", | ||
| MEMBER_TYPING: "member:typing", | ||
| MEMBER_JOIN: "member:join", | ||
| MEMBER_LEAVE: "member:leave", | ||
| PRESENCE_CHANGE: "presence:change", | ||
| REACTION_ADD: "reaction:add", | ||
| REACTION_REMOVE: "reaction:remove", | ||
| NOTIFICATION_NEW: "notification:new", | ||
| SERVER_APP_LIST_CHANGED: "server-app:list-changed", | ||
| VOICE_STATE: "voice:state", | ||
| VOICE_PARTICIPANT_JOINED: "voice:participant-joined", | ||
| VOICE_PARTICIPANT_LEFT: "voice:participant-left", | ||
| VOICE_PARTICIPANT_UPDATED: "voice:participant-updated", | ||
| VOICE_POLICY_UPDATED: "voice:policy-updated" | ||
| }; | ||
| // src/constants/limits.ts | ||
| var LIMITS = { | ||
| /** Max message content length (16KB — enough for detailed agent responses) */ | ||
| MESSAGE_CONTENT_MAX: 16e3, | ||
| /** Max username length */ | ||
| USERNAME_MAX: 32, | ||
| /** Min username length */ | ||
| USERNAME_MIN: 3, | ||
| /** Max display name length */ | ||
| DISPLAY_NAME_MAX: 64, | ||
| /** Max server name length */ | ||
| SERVER_NAME_MAX: 100, | ||
| /** Max channel name length */ | ||
| CHANNEL_NAME_MAX: 100, | ||
| /** Max thread name length */ | ||
| THREAD_NAME_MAX: 100, | ||
| /** Max file upload size (10MB) */ | ||
| FILE_UPLOAD_MAX_SIZE: 10 * 1024 * 1024, | ||
| /** Messages per page (cursor pagination) */ | ||
| MESSAGES_PER_PAGE: 50, | ||
| /** Max servers per user */ | ||
| SERVERS_PER_USER_MAX: 100, | ||
| /** Max channels per server */ | ||
| CHANNELS_PER_SERVER_MAX: 200, | ||
| /** Invite code length */ | ||
| INVITE_CODE_LENGTH: 8, | ||
| /** Password min length */ | ||
| PASSWORD_MIN: 8, | ||
| /** Max reactions per message per user */ | ||
| REACTIONS_PER_MESSAGE_MAX: 20 | ||
| }; | ||
| export { | ||
| CLIENT_EVENTS, | ||
| SERVER_EVENTS, | ||
| LIMITS | ||
| }; |
| // src/types/inbox.types.ts | ||
| var BUDDY_INBOX_TOPIC_PREFIX = "shadow:buddy-inbox:"; | ||
| var BUDDY_INBOX_DELIVERY_PERMISSION = "buddy_inbox:deliver"; | ||
| var BUDDY_INBOX_PLATFORM_PERMISSIONS = [BUDDY_INBOX_DELIVERY_PERMISSION]; | ||
| function isBuddyInboxPlatformPermission(value) { | ||
| return typeof value === "string" && BUDDY_INBOX_PLATFORM_PERMISSIONS.includes(value); | ||
| } | ||
| function buddyInboxTopic(agentId) { | ||
| return `${BUDDY_INBOX_TOPIC_PREFIX}${agentId}`; | ||
| } | ||
| function parseBuddyInboxAgentId(topic) { | ||
| if (!topic?.startsWith(BUDDY_INBOX_TOPIC_PREFIX)) return null; | ||
| const agentId = topic.slice(BUDDY_INBOX_TOPIC_PREFIX.length).trim(); | ||
| return agentId || null; | ||
| } | ||
| function isBuddyInboxTopic(topic) { | ||
| return parseBuddyInboxAgentId(topic) !== null; | ||
| } | ||
| var TASK_MESSAGE_CARD_STATUSES = [ | ||
| "queued", | ||
| "claimed", | ||
| "running", | ||
| "completed", | ||
| "failed", | ||
| "canceled", | ||
| "transferred" | ||
| ]; | ||
| var TERMINAL_TASK_MESSAGE_CARD_STATUSES = [ | ||
| "completed", | ||
| "failed", | ||
| "canceled", | ||
| "transferred" | ||
| ]; | ||
| var TASK_MESSAGE_CARD_STATUS_TRANSITIONS = { | ||
| queued: ["queued", "claimed", "running", "completed", "failed", "canceled"], | ||
| claimed: ["claimed", "running", "completed", "failed", "canceled"], | ||
| running: ["running", "completed", "failed", "canceled"], | ||
| completed: ["completed"], | ||
| failed: ["failed", "transferred"], | ||
| canceled: ["canceled"], | ||
| transferred: ["transferred"] | ||
| }; | ||
| function isTerminalTaskMessageCardStatus(status) { | ||
| return TERMINAL_TASK_MESSAGE_CARD_STATUSES.includes( | ||
| status | ||
| ); | ||
| } | ||
| function isTaskMessageCardStatus(value) { | ||
| return typeof value === "string" && TASK_MESSAGE_CARD_STATUSES.includes(value); | ||
| } | ||
| function canTransitionTaskMessageCardStatus(from, to) { | ||
| const allowed = TASK_MESSAGE_CARD_STATUS_TRANSITIONS[from]; | ||
| return allowed.includes(to); | ||
| } | ||
| function isRecord(value) { | ||
| return !!value && typeof value === "object" && !Array.isArray(value); | ||
| } | ||
| function isMessageReferenceCard(card) { | ||
| return card?.kind === "message_reference" && typeof card.title === "string" && isRecord(card.target) && typeof card.target.channelId === "string" && typeof card.target.messageId === "string"; | ||
| } | ||
| function getBuddyInboxTaskCards(message) { | ||
| const cards = message.metadata?.cards; | ||
| if (!Array.isArray(cards)) return []; | ||
| return cards.filter( | ||
| (card) => card?.kind === "task" && typeof card.id === "string" && isTaskMessageCardStatus(card.status) | ||
| ); | ||
| } | ||
| function hasBuddyInboxTaskCard(message) { | ||
| return getBuddyInboxTaskCards(message).length > 0; | ||
| } | ||
| function getBuddyInboxTaskStatuses(message) { | ||
| return getBuddyInboxTaskCards(message).map((card) => card.status); | ||
| } | ||
| function buildBuddyInboxViewMessages(messages, options) { | ||
| void options; | ||
| return [...messages]; | ||
| } | ||
| var DEFAULT_BUDDY_INBOX_ADMISSION_POLICY = { | ||
| defaultMode: "allow", | ||
| rules: [] | ||
| }; | ||
| function parseAdmissionMode(value, fallback) { | ||
| if (value === "allow" || value === "deny" || value === "first_time" || value === "every_time") { | ||
| return value; | ||
| } | ||
| if (value === void 0 || value === null) return fallback; | ||
| throw new Error("Invalid Buddy Inbox admission mode"); | ||
| } | ||
| function parseSubjectKind(value) { | ||
| if (value === "user" || value === "agent" || value === "server_app" || value === "system") { | ||
| return value; | ||
| } | ||
| throw new Error("Invalid Buddy Inbox admission subject kind"); | ||
| } | ||
| function parseOptionalString(value, field, maxLength) { | ||
| if (value === void 0 || value === null || value === "") return void 0; | ||
| if (typeof value !== "string" || value.length > maxLength) { | ||
| throw new Error(`Invalid Buddy Inbox admission ${field}`); | ||
| } | ||
| return value; | ||
| } | ||
| function normalizeBuddyInboxAdmissionPolicy(value) { | ||
| if (value === void 0 || value === null) return { ...DEFAULT_BUDDY_INBOX_ADMISSION_POLICY }; | ||
| if (!isRecord(value)) throw new Error("Invalid Buddy Inbox admission policy"); | ||
| const defaultMode = parseAdmissionMode(value.defaultMode, "allow"); | ||
| const rawRules = value.rules; | ||
| if (rawRules !== void 0 && !Array.isArray(rawRules)) { | ||
| throw new Error("Invalid Buddy Inbox admission rules"); | ||
| } | ||
| const rules = (rawRules ?? []).slice(0, 100).map((entry) => { | ||
| if (!isRecord(entry)) throw new Error("Invalid Buddy Inbox admission rule"); | ||
| return { | ||
| subjectKind: parseSubjectKind(entry.subjectKind), | ||
| subjectId: parseOptionalString(entry.subjectId, "subjectId", 160), | ||
| appKey: parseOptionalString(entry.appKey, "appKey", 120), | ||
| mode: parseAdmissionMode(entry.mode, defaultMode), | ||
| ...entry.approved === true ? { approved: true } : {}, | ||
| note: parseOptionalString(entry.note, "note", 500), | ||
| createdAt: parseOptionalString(entry.createdAt, "createdAt", 64), | ||
| updatedAt: parseOptionalString(entry.updatedAt, "updatedAt", 64) | ||
| }; | ||
| }); | ||
| return { defaultMode, rules }; | ||
| } | ||
| function buddyInboxAdmissionRuleKey(rule) { | ||
| return [rule.subjectKind, rule.subjectId ?? "", rule.appKey ?? ""].join(":"); | ||
| } | ||
| function parsePendingTask(value) { | ||
| if (!isRecord(value)) throw new Error("Invalid Buddy Inbox pending task"); | ||
| const title = parseOptionalString(value.title, "task.title", 180); | ||
| if (!title) throw new Error("Invalid Buddy Inbox pending task title"); | ||
| const body = parseOptionalString(value.body, "task.body", 8e3); | ||
| const priority = value.priority; | ||
| if (priority !== void 0 && priority !== "low" && priority !== "normal" && priority !== "medium" && priority !== "high") { | ||
| throw new Error("Invalid Buddy Inbox pending task priority"); | ||
| } | ||
| const idempotencyKey = parseOptionalString(value.idempotencyKey, "task.idempotencyKey", 240); | ||
| const source = isRecord(value.source) ? value.source : void 0; | ||
| const requirements = isRecord(value.requirements) ? value.requirements : void 0; | ||
| const outputContract = isRecord(value.outputContract) ? value.outputContract : void 0; | ||
| const privacy = isRecord(value.privacy) ? value.privacy : void 0; | ||
| const data = isRecord(value.data) ? value.data : void 0; | ||
| return { | ||
| title, | ||
| ...body ? { body } : {}, | ||
| ...priority ? { priority } : {}, | ||
| ...idempotencyKey ? { idempotencyKey } : {}, | ||
| ...source ? { source } : {}, | ||
| ...requirements ? { requirements } : {}, | ||
| ...outputContract ? { outputContract } : {}, | ||
| ...privacy ? { privacy } : {}, | ||
| ...data ? { data } : {} | ||
| }; | ||
| } | ||
| function normalizeBuddyInboxAdmissionPendingDeliveries(value) { | ||
| if (value === void 0 || value === null) return []; | ||
| if (!Array.isArray(value)) throw new Error("Invalid Buddy Inbox pending deliveries"); | ||
| return value.slice(0, 100).map((entry) => { | ||
| if (!isRecord(entry)) throw new Error("Invalid Buddy Inbox pending delivery"); | ||
| const id = parseOptionalString(entry.id, "pending.id", 80); | ||
| const serverId = parseOptionalString(entry.serverId, "pending.serverId", 160); | ||
| const channelId = parseOptionalString(entry.channelId, "pending.channelId", 160); | ||
| const agentId = parseOptionalString(entry.agentId, "pending.agentId", 160); | ||
| const mode = parseAdmissionMode(entry.mode, "first_time"); | ||
| if (mode !== "first_time" && mode !== "every_time") { | ||
| throw new Error("Invalid Buddy Inbox pending mode"); | ||
| } | ||
| if (!isRecord(entry.subject)) throw new Error("Invalid Buddy Inbox pending subject"); | ||
| if (!isRecord(entry.requestedBy)) throw new Error("Invalid Buddy Inbox pending requester"); | ||
| if (!id || !serverId || !channelId || !agentId) { | ||
| throw new Error("Invalid Buddy Inbox pending delivery identifiers"); | ||
| } | ||
| const requestedAt = parseOptionalString(entry.requestedAt, "pending.requestedAt", 64); | ||
| if (!requestedAt) throw new Error("Invalid Buddy Inbox pending requestedAt"); | ||
| return { | ||
| id, | ||
| serverId, | ||
| channelId, | ||
| agentId, | ||
| mode, | ||
| subject: { | ||
| kind: parseSubjectKind(entry.subject.kind), | ||
| id: parseOptionalString(entry.subject.id, "subject.id", 160), | ||
| appKey: parseOptionalString(entry.subject.appKey, "subject.appKey", 120), | ||
| label: parseOptionalString(entry.subject.label, "subject.label", 160) | ||
| }, | ||
| task: parsePendingTask(entry.task), | ||
| requestedBy: entry.requestedBy, | ||
| requestedAt, | ||
| updatedAt: parseOptionalString(entry.updatedAt, "pending.updatedAt", 64) | ||
| }; | ||
| }); | ||
| } | ||
| // src/types/message.types.ts | ||
| var MESSAGE_COPILOT_CONTEXT_METADATA_KEY = "copilotContext"; | ||
| var MESSAGE_AGENT_CHAIN_METADATA_KEY = "agentChain"; | ||
| function isBoundedMetadataString(value, maxLength, required = false) { | ||
| if (typeof value !== "string") return !required && value == null; | ||
| const trimmed = value.trim(); | ||
| return trimmed.length > 0 && trimmed.length <= maxLength; | ||
| } | ||
| function isMessageCopilotContext(value) { | ||
| if (!value || typeof value !== "object") return false; | ||
| const record = value; | ||
| return record.kind === "server_app_copilot" && isBoundedMetadataString(record.appKey, 120, true) && isBoundedMetadataString(record.serverAppId, 160) && isBoundedMetadataString(record.appId, 160) && isBoundedMetadataString(record.appName, 160) && isBoundedMetadataString(record.serverId, 160) && isBoundedMetadataString(record.serverSlug, 160) && isBoundedMetadataString(record.channelId, 160) && isBoundedMetadataString(record.channelKind, 40); | ||
| } | ||
| function buildMessageCopilotContextMetadata(context) { | ||
| return context && isMessageCopilotContext(context) ? { copilotContext: context } : void 0; | ||
| } | ||
| function isMessageAgentChainMetadata(value) { | ||
| if (!value || typeof value !== "object") return false; | ||
| const record = value; | ||
| const startedAt = record.startedAt; | ||
| return isBoundedMetadataString(record.agentId, 160, true) && typeof record.depth === "number" && Number.isInteger(record.depth) && record.depth >= 0 && record.depth <= 100 && Array.isArray(record.participants) && record.participants.length <= 100 && record.participants.every((participant) => isBoundedMetadataString(participant, 160, true)) && (startedAt == null || typeof startedAt === "number" && Number.isInteger(startedAt) && startedAt >= 0 || isBoundedMetadataString(startedAt, 64, true)) && isBoundedMetadataString(record.rootMessageId, 160); | ||
| } | ||
| function buildMessageAgentChainMetadata(agentChain) { | ||
| return agentChain && isMessageAgentChainMetadata(agentChain) ? { agentChain } : void 0; | ||
| } | ||
| function metadataRecord(value) { | ||
| return value && typeof value === "object" && !Array.isArray(value) ? value : null; | ||
| } | ||
| function metadataString(value) { | ||
| return typeof value === "string" && value.trim() ? value.trim() : null; | ||
| } | ||
| function isMessageCardStatus(value) { | ||
| return value === "queued" || value === "claimed" || value === "running" || value === "completed" || value === "failed" || value === "canceled" || value === "transferred"; | ||
| } | ||
| function parseBuddyInboxTaskRef(value) { | ||
| const record = metadataRecord(value); | ||
| if (!record) return void 0; | ||
| const messageId = metadataString(record.messageId); | ||
| const cardId = metadataString(record.cardId); | ||
| const channelId = metadataString(record.channelId); | ||
| const threadId = metadataString(record.threadId); | ||
| const title = metadataString(record.title); | ||
| if (!messageId || !cardId || !channelId) return void 0; | ||
| const extra = { ...record }; | ||
| delete extra.messageId; | ||
| delete extra.cardId; | ||
| delete extra.channelId; | ||
| delete extra.threadId; | ||
| delete extra.title; | ||
| return { | ||
| ...extra, | ||
| messageId, | ||
| cardId, | ||
| channelId, | ||
| threadId, | ||
| ...title ? { title } : {} | ||
| }; | ||
| } | ||
| function parseBuddyInboxTaskResultCard(value) { | ||
| const result = metadataRecord(value); | ||
| if (!result || result.kind !== "task_result") return null; | ||
| const taskMessageId = metadataString(result.taskMessageId); | ||
| const taskCardId = metadataString(result.taskCardId); | ||
| const status = result.status; | ||
| if (!taskMessageId || !taskCardId || !isMessageCardStatus(status)) return null; | ||
| const id = metadataString(result.id) ?? `task-result:${taskMessageId}:${taskCardId}:${status}`; | ||
| const version = typeof result.version === "number" && Number.isFinite(result.version) ? Math.max(1, Math.trunc(result.version)) : 1; | ||
| const title = metadataString(result.title) ?? metadataString(metadataRecord(result.sourceTask)?.title) ?? metadataString(metadataRecord(result.parentTask)?.title) ?? "Task result"; | ||
| const body = metadataString(result.body); | ||
| const idempotencyKey = metadataString(result.idempotencyKey); | ||
| const delivery = metadataString(result.delivery); | ||
| const createdAt = metadataString(result.createdAt); | ||
| const updatedAt = metadataString(result.updatedAt); | ||
| const sourceTask = parseBuddyInboxTaskRef(result.sourceTask); | ||
| const parentTask = parseBuddyInboxTaskRef(result.parentTask); | ||
| const data = metadataRecord(result.data); | ||
| const extra = { ...result }; | ||
| delete extra.id; | ||
| delete extra.kind; | ||
| delete extra.version; | ||
| delete extra.title; | ||
| delete extra.body; | ||
| delete extra.idempotencyKey; | ||
| delete extra.taskMessageId; | ||
| delete extra.taskCardId; | ||
| delete extra.status; | ||
| delete extra.delivery; | ||
| delete extra.createdAt; | ||
| delete extra.updatedAt; | ||
| delete extra.sourceTask; | ||
| delete extra.parentTask; | ||
| delete extra.data; | ||
| return { | ||
| ...extra, | ||
| id, | ||
| kind: "task_result", | ||
| version, | ||
| title, | ||
| taskMessageId, | ||
| taskCardId, | ||
| status, | ||
| ...body ? { body } : {}, | ||
| ...idempotencyKey ? { idempotencyKey } : {}, | ||
| ...delivery ? { delivery } : {}, | ||
| ...createdAt ? { createdAt } : {}, | ||
| ...updatedAt ? { updatedAt } : {}, | ||
| ...sourceTask ? { sourceTask } : {}, | ||
| ...parentTask ? { parentTask } : {}, | ||
| ...data ? { data } : {} | ||
| }; | ||
| } | ||
| function parseBuddyInboxTaskResultMetadata(metadata) { | ||
| const record = metadataRecord(metadata); | ||
| const cards = Array.isArray(record?.cards) ? record.cards : []; | ||
| for (const card of cards) { | ||
| const result = parseBuddyInboxTaskResultCard(card); | ||
| if (result) return result; | ||
| } | ||
| const custom = metadataRecord(record?.custom); | ||
| return parseBuddyInboxTaskResultCard(custom?.buddyInboxTaskResult); | ||
| } | ||
| function isMetadataRecord(value) { | ||
| return Boolean(value) && typeof value === "object" && !Array.isArray(value); | ||
| } | ||
| function isCommerceMessageCard(card) { | ||
| if (!isMetadataRecord(card)) return false; | ||
| const kind = card.kind; | ||
| return (kind === "offer" || kind === "product") && typeof card.id === "string" && typeof card.productId === "string" && typeof card.shopId === "string" && isMetadataRecord(card.snapshot) && isMetadataRecord(card.purchase); | ||
| } | ||
| function isPaidFileMessageCard(card) { | ||
| return isMetadataRecord(card) && card.kind === "paid_file" && typeof card.id === "string" && typeof card.fileId === "string" && isMetadataRecord(card.snapshot); | ||
| } | ||
| function isOAuthLinkMessageCard(card) { | ||
| return isMetadataRecord(card) && card.kind === "oauth_link" && typeof card.id === "string" && typeof card.appId === "string" && typeof card.title === "string" && typeof card.url === "string" && isMetadataRecord(card.action); | ||
| } | ||
| function getCommerceMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isCommerceMessageCard) : []; | ||
| } | ||
| function getPaidFileMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isPaidFileMessageCard) : []; | ||
| } | ||
| function getOAuthLinkMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isOAuthLinkMessageCard) : []; | ||
| } | ||
| // src/types/runtime-session.types.ts | ||
| var RUNTIME_SESSION_PET_REACTION_BY_STATE = { | ||
| idle: "idle", | ||
| running: "working", | ||
| streaming: "thinking", | ||
| tool_call: "working", | ||
| waiting_for_approval: "waiting", | ||
| blocked: "waiting", | ||
| completed: "success", | ||
| failed: "error", | ||
| stopped: "idle", | ||
| unknown: "idle" | ||
| }; | ||
| function runtimeSessionPetReactionForState(state) { | ||
| return RUNTIME_SESSION_PET_REACTION_BY_STATE[state] ?? "idle"; | ||
| } | ||
| function runtimeSessionSignalToPetReaction(signal) { | ||
| switch (signal) { | ||
| case "running": | ||
| return "working"; | ||
| case "streaming": | ||
| return "thinking"; | ||
| case "tool_call": | ||
| return "working"; | ||
| case "waiting_for_approval": | ||
| case "blocked": | ||
| return "waiting"; | ||
| case "completed": | ||
| return "success"; | ||
| case "failed": | ||
| return "error"; | ||
| case "stopped": | ||
| case "unknown": | ||
| return "idle"; | ||
| default: | ||
| return signal; | ||
| } | ||
| } | ||
| function runtimeSessionStateLooksActive(state) { | ||
| return state === "running" || state === "streaming" || state === "tool_call" || state === "waiting_for_approval" || state === "blocked"; | ||
| } | ||
| // src/types/user.types.ts | ||
| var USER_STATUSES = ["online", "idle", "dnd", "offline"]; | ||
| var BUDDY_PRESENCE_STATUSES = ["online", "busy", "idle", "dnd", "offline"]; | ||
| var BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS = 9e4; | ||
| function normalizeUserStatus(status) { | ||
| if (status === "online" || status === "idle" || status === "dnd" || status === "offline") { | ||
| return status; | ||
| } | ||
| return "offline"; | ||
| } | ||
| function normalizeBuddyPresenceStatus(status, options) { | ||
| if (options?.busy) { | ||
| return "busy"; | ||
| } | ||
| if (status === "busy") { | ||
| return "busy"; | ||
| } | ||
| return normalizeUserStatus(status); | ||
| } | ||
| function normalizePresenceStatus(status, options) { | ||
| return normalizeBuddyPresenceStatus(status, options); | ||
| } | ||
| function isBuddyHeartbeatActive(lastHeartbeat, options) { | ||
| if (!lastHeartbeat) return false; | ||
| const heartbeatMs = lastHeartbeat instanceof Date ? lastHeartbeat.getTime() : new Date(lastHeartbeat).getTime(); | ||
| if (!Number.isFinite(heartbeatMs)) return false; | ||
| const nowMs = options?.nowMs ?? Date.now(); | ||
| const thresholdMs = options?.thresholdMs ?? BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS; | ||
| return nowMs - heartbeatMs <= thresholdMs; | ||
| } | ||
| function normalizeBuddyRuntimePresenceStatus({ | ||
| userStatus, | ||
| agentStatus, | ||
| lastHeartbeat, | ||
| busy = false, | ||
| nowMs | ||
| }) { | ||
| if (busy || agentStatus === "busy") return "busy"; | ||
| if (agentStatus === "running") { | ||
| return isBuddyHeartbeatActive(lastHeartbeat, { nowMs }) ? "online" : "offline"; | ||
| } | ||
| const normalizedAgentStatus = normalizeBuddyPresenceStatus(agentStatus); | ||
| if (normalizedAgentStatus !== "offline") return normalizedAgentStatus; | ||
| return normalizeUserStatus(userStatus); | ||
| } | ||
| function resolvePresenceStatus({ | ||
| userStatus, | ||
| isBot, | ||
| agentStatus, | ||
| lastHeartbeat, | ||
| busy = false, | ||
| nowMs | ||
| }) { | ||
| if (busy) return "busy"; | ||
| if (isBot || agentStatus != null || lastHeartbeat != null) { | ||
| return normalizeBuddyRuntimePresenceStatus({ | ||
| userStatus, | ||
| agentStatus, | ||
| lastHeartbeat, | ||
| nowMs | ||
| }); | ||
| } | ||
| return normalizePresenceStatus(userStatus); | ||
| } | ||
| function getBuddyPresenceExpiresAt(lastHeartbeat, options) { | ||
| if (!lastHeartbeat) return null; | ||
| const heartbeatMs = lastHeartbeat instanceof Date ? lastHeartbeat.getTime() : new Date(lastHeartbeat).getTime(); | ||
| if (!Number.isFinite(heartbeatMs)) return null; | ||
| return new Date( | ||
| heartbeatMs + (options?.thresholdMs ?? BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS) | ||
| ).toISOString(); | ||
| } | ||
| function applyPresenceChangeToRuntime(current, update, options) { | ||
| const observedAt = update.observedAt ?? options?.observedAt ?? (/* @__PURE__ */ new Date()).toISOString(); | ||
| const userStatus = normalizeUserStatus(update.status); | ||
| const hasAgentPresence = current.isBot === true || current.agentStatus != null || current.lastHeartbeat != null || update.agentId != null || update.agentStatus !== void 0 || update.lastHeartbeat !== void 0; | ||
| if (!hasAgentPresence) return { userStatus }; | ||
| const agentStatus = update.agentStatus !== void 0 ? update.agentStatus : current.agentStatus ?? (userStatus === "online" ? "running" : null); | ||
| let lastHeartbeat = current.lastHeartbeat ?? null; | ||
| if (update.lastHeartbeat !== void 0) { | ||
| lastHeartbeat = update.lastHeartbeat; | ||
| } else if (userStatus === "online") { | ||
| lastHeartbeat = observedAt; | ||
| } else if (userStatus === "offline") { | ||
| lastHeartbeat = null; | ||
| } | ||
| return { userStatus, agentStatus, lastHeartbeat }; | ||
| } | ||
| export { | ||
| BUDDY_INBOX_TOPIC_PREFIX, | ||
| BUDDY_INBOX_DELIVERY_PERMISSION, | ||
| BUDDY_INBOX_PLATFORM_PERMISSIONS, | ||
| isBuddyInboxPlatformPermission, | ||
| buddyInboxTopic, | ||
| parseBuddyInboxAgentId, | ||
| isBuddyInboxTopic, | ||
| TASK_MESSAGE_CARD_STATUSES, | ||
| TERMINAL_TASK_MESSAGE_CARD_STATUSES, | ||
| TASK_MESSAGE_CARD_STATUS_TRANSITIONS, | ||
| isTerminalTaskMessageCardStatus, | ||
| isTaskMessageCardStatus, | ||
| canTransitionTaskMessageCardStatus, | ||
| isMessageReferenceCard, | ||
| getBuddyInboxTaskCards, | ||
| hasBuddyInboxTaskCard, | ||
| getBuddyInboxTaskStatuses, | ||
| buildBuddyInboxViewMessages, | ||
| DEFAULT_BUDDY_INBOX_ADMISSION_POLICY, | ||
| normalizeBuddyInboxAdmissionPolicy, | ||
| buddyInboxAdmissionRuleKey, | ||
| normalizeBuddyInboxAdmissionPendingDeliveries, | ||
| MESSAGE_COPILOT_CONTEXT_METADATA_KEY, | ||
| MESSAGE_AGENT_CHAIN_METADATA_KEY, | ||
| isMessageCopilotContext, | ||
| buildMessageCopilotContextMetadata, | ||
| isMessageAgentChainMetadata, | ||
| buildMessageAgentChainMetadata, | ||
| parseBuddyInboxTaskResultMetadata, | ||
| isCommerceMessageCard, | ||
| isPaidFileMessageCard, | ||
| isOAuthLinkMessageCard, | ||
| getCommerceMessageCards, | ||
| getPaidFileMessageCards, | ||
| getOAuthLinkMessageCards, | ||
| RUNTIME_SESSION_PET_REACTION_BY_STATE, | ||
| runtimeSessionPetReactionForState, | ||
| runtimeSessionSignalToPetReaction, | ||
| runtimeSessionStateLooksActive, | ||
| USER_STATUSES, | ||
| BUDDY_PRESENCE_STATUSES, | ||
| BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, | ||
| normalizeUserStatus, | ||
| normalizeBuddyPresenceStatus, | ||
| normalizePresenceStatus, | ||
| isBuddyHeartbeatActive, | ||
| normalizeBuddyRuntimePresenceStatus, | ||
| resolvePresenceStatus, | ||
| getBuddyPresenceExpiresAt, | ||
| applyPresenceChangeToRuntime | ||
| }; |
| // src/utils/index.ts | ||
| import { customAlphabet } from "nanoid"; | ||
| // src/utils/avatar-generator.ts | ||
| var COLORS = { | ||
| bg: [ | ||
| "transparent", | ||
| "#1e1f22", | ||
| "#313338", | ||
| "#5865F2", | ||
| "#23a559", | ||
| "#da373c", | ||
| "#f472b6", | ||
| "#3b82f6", | ||
| "#fbbf24", | ||
| "#a855f7", | ||
| "#1abc9c", | ||
| "#f39c12", | ||
| "#e74c3c" | ||
| ], | ||
| body: [ | ||
| "#2d2d30", | ||
| "#e8842c", | ||
| "#e8e8e8", | ||
| "#7a7a80", | ||
| "#d4a574", | ||
| "#6b8094", | ||
| "#f472b6", | ||
| "#c8d6e5", | ||
| "#3e2723", | ||
| "#bdc3c7", | ||
| "#ffb8b8" | ||
| ], | ||
| eyes: [ | ||
| "#f8e71c", | ||
| "#00f3ff", | ||
| "#4ade80", | ||
| "#60a5fa", | ||
| "#a855f7", | ||
| "#fbbf24", | ||
| "#f87171", | ||
| "#ffc0cb", | ||
| "#1dd1a1", | ||
| "#e056fd" | ||
| ], | ||
| pattern: ["#1a1a1c", "#ffffff", "#5a4a46", "#3d3d40", "#9a9aa0", "#d1ccc0", "#2d3436"] | ||
| }; | ||
| function getRandomElement(arr) { | ||
| return arr[Math.floor(Math.random() * arr.length)]; | ||
| } | ||
| function generateRandomCatConfig() { | ||
| return { | ||
| bg: getRandomElement(COLORS.bg), | ||
| bgPattern: getRandomElement(["none", "dots", "stripes", "grid", "stars"]), | ||
| body: getRandomElement(COLORS.body), | ||
| pattern: getRandomElement([ | ||
| "none", | ||
| "tabby", | ||
| "tuxedo", | ||
| "siamese", | ||
| "calico", | ||
| "bicolor" | ||
| ]), | ||
| patternColor: getRandomElement(COLORS.pattern), | ||
| eyeColor: getRandomElement(COLORS.eyes), | ||
| expression: getRandomElement([ | ||
| "smile", | ||
| "open", | ||
| "flat", | ||
| "sad", | ||
| "surprised", | ||
| "kawaii", | ||
| "winking", | ||
| "smirk" | ||
| ]), | ||
| decoration: getRandomElement([ | ||
| "none", | ||
| "glasses", | ||
| "blush", | ||
| "scar", | ||
| "flower", | ||
| "fish", | ||
| "headband" | ||
| ]) | ||
| }; | ||
| } | ||
| function renderCatSvg(config) { | ||
| const { bg, bgPattern, body, pattern, patternColor, eyeColor, expression, decoration } = config; | ||
| const stroke = "#1a1a1c"; | ||
| let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">`; | ||
| if (bg && bg !== "transparent") { | ||
| svg += `<rect width="100" height="100" fill="${bg}" rx="20" />`; | ||
| const pColor = `rgba(255,255,255,0.15)`; | ||
| const cleanBg = bg.replace("#", ""); | ||
| if (bgPattern === "dots") { | ||
| svg += `<pattern id="p-${cleanBg}-dots" x="0" y="0" width="10" height="10" patternUnits="userSpaceOnUse"><circle cx="2" cy="2" r="2" fill="${pColor}"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-dots)" rx="20" />`; | ||
| } else if (bgPattern === "stripes") { | ||
| svg += `<pattern id="p-${cleanBg}-str" x="0" y="0" width="12" height="12" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="12" stroke="${pColor}" stroke-width="4"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-str)" rx="20" />`; | ||
| } else if (bgPattern === "grid") { | ||
| svg += `<pattern id="p-${cleanBg}-grid" width="16" height="16" patternUnits="userSpaceOnUse"><path d="M 16 0 L 0 0 0 16" fill="none" stroke="${pColor}" stroke-width="1"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-grid)" rx="20" />`; | ||
| } else if (bgPattern === "stars") { | ||
| svg += `<pattern id="p-${cleanBg}-star" width="20" height="20" patternUnits="userSpaceOnUse"><path d="M10,2 L12,8 L18,8 L13,12 L15,18 L10,14 L5,18 L7,12 L2,8 L8,8 Z" fill="${pColor}" transform="scale(0.5) translate(5,5)"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-star)" rx="20" />`; | ||
| } | ||
| } | ||
| svg += `<ellipse cx="50" cy="85" rx="30" ry="6" fill="rgba(0,0,0,0.2)"/>`; | ||
| svg += `<path d="M22,45 C15,22 28,18 34,22 C38,25 40,38 40,38" fill="${body}" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>`; | ||
| svg += `<path d="M78,45 C85,22 72,18 66,22 C62,25 60,38 60,38" fill="${body}" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>`; | ||
| svg += `<path d="M26,38 C22,26 29,24 33,26 C35,28 36,34 36,34" fill="#ffb8b8" opacity="0.8"/>`; | ||
| svg += `<path d="M74,38 C78,26 71,24 67,26 C65,28 64,34 64,34" fill="#ffb8b8" opacity="0.8"/>`; | ||
| svg += `<ellipse cx="50" cy="58" rx="38" ry="30" fill="${body}" stroke="${stroke}" stroke-width="2.5"/>`; | ||
| if (pattern === "tabby") { | ||
| svg += `<path d="M50,30 L50,40 M42,32 L46,39 M58,32 L54,39" stroke="${patternColor}" stroke-width="3" stroke-linecap="round" opacity="0.7"/>`; | ||
| svg += `<path d="M18,55 L26,57 M20,62 L27,62" stroke="${patternColor}" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/>`; | ||
| svg += `<path d="M82,55 L74,57 M80,62 L73,62" stroke="${patternColor}" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/>`; | ||
| } else if (pattern === "tuxedo") { | ||
| svg += `<path d="M50,56 C30,68 28,88 50,88 C72,88 70,68 50,56" fill="${patternColor}" opacity="0.95"/>`; | ||
| svg += `<ellipse cx="50" cy="65" rx="16" ry="12" fill="${patternColor}" opacity="0.95"/>`; | ||
| } else if (pattern === "siamese") { | ||
| svg += `<ellipse cx="50" cy="62" rx="20" ry="16" fill="${patternColor}" opacity="0.6"/>`; | ||
| } else if (pattern === "calico") { | ||
| svg += `<path d="M25,40 Q35,30 45,45 Q35,55 25,40" fill="${patternColor}" opacity="0.8"/>`; | ||
| svg += `<path d="M75,45 Q65,60 55,50 Q65,35 75,45" fill="#e8842c" opacity="0.8"/>`; | ||
| } else if (pattern === "bicolor") { | ||
| svg += `<path d="M12,58 Q30,30 50,40 Q60,70 50,88 Q12,88 12,58 Z" fill="${patternColor}" opacity="0.8"/>`; | ||
| } | ||
| if (decoration === "blush") { | ||
| svg += `<ellipse cx="28" cy="62" rx="5" ry="3" fill="#ff7675" opacity="0.7"/>`; | ||
| svg += `<ellipse cx="72" cy="62" rx="5" ry="3" fill="#ff7675" opacity="0.7"/>`; | ||
| } | ||
| if (decoration === "scar") { | ||
| svg += `<path d="M28,42 L40,52 M30,48 L35,43 M34,51 L39,46 M32,53 L37,48" stroke="#d63031" stroke-width="1.5" stroke-linecap="round"/>`; | ||
| } | ||
| const drawEye = (cx, cy, lookDir = 0) => { | ||
| if (expression === "kawaii") { | ||
| return `<path d="M${cx - 8},${cy} Q${cx},${cy - 8} ${cx + 8},${cy} Q${cx},${cy - 3} ${cx - 8},${cy}" fill="${eyeColor}" stroke="${stroke}" stroke-width="1.5"/><circle cx="${cx + lookDir}" cy="${cy - 2}" r="3" fill="white"/><circle cx="${cx - 3 + lookDir}" cy="${cy}" r="1" fill="white"/>`; | ||
| } else if (expression === "winking" && cx > 50) { | ||
| return `<path d="M${cx - 7},${cy + 2} Q${cx},${cy - 4} ${cx + 7},${cy + 2}" fill="none" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round"/>`; | ||
| } else if (expression === "surprised") { | ||
| return `<circle cx="${cx}" cy="${cy}" r="8" fill="white" stroke="${stroke}" stroke-width="1.5"/><circle cx="${cx}" cy="${cy}" r="3" fill="${eyeColor}"/>`; | ||
| } else { | ||
| return `<circle cx="${cx}" cy="${cy}" r="7.5" fill="${eyeColor}" stroke="${stroke}" stroke-width="1.5"/><circle cx="${cx - 2 + lookDir}" cy="${cy - 2}" r="2.5" fill="white"/><circle cx="${cx + 2 + lookDir}" cy="${cy + 1}" r="1" fill="white"/>`; | ||
| } | ||
| }; | ||
| if (expression === "smirk") { | ||
| svg += `<path d="M26,50 L42,50" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round"/>`; | ||
| svg += drawEye(66, 52, 2); | ||
| } else { | ||
| svg += drawEye(34, 52, 0); | ||
| svg += drawEye(66, 52, 0); | ||
| } | ||
| if (decoration === "glasses") { | ||
| svg += `<circle cx="34" cy="52" r="11" fill="rgba(255,255,255,0.2)" stroke="#2d3436" stroke-width="2.5"/>`; | ||
| svg += `<circle cx="66" cy="52" r="11" fill="rgba(255,255,255,0.2)" stroke="#2d3436" stroke-width="2.5"/>`; | ||
| svg += `<path d="M45,50 Q50,48 55,50" fill="none" stroke="#2d3436" stroke-width="2.5" stroke-linecap="round"/>`; | ||
| } | ||
| svg += `<path d="M47,62 L53,62 L50,65 Z" fill="#ff9ff3" stroke="${stroke}" stroke-width="1" stroke-linejoin="round"/>`; | ||
| if (expression === "smile" || expression === "kawaii" || expression === "winking") { | ||
| svg += `<path d="M42,67 Q46,72 50,67 M50,67 Q54,72 58,67" fill="none" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`; | ||
| } else if (expression === "open") { | ||
| svg += `<path d="M46,67 Q50,75 54,67 Z" fill="#ff7675" stroke="${stroke}" stroke-width="1.5" stroke-linejoin="round"/>`; | ||
| } else if (expression === "flat") { | ||
| svg += `<path d="M47,68 L53,68" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`; | ||
| } else if (expression === "sad") { | ||
| svg += `<path d="M43,70 Q50,64 57,70" fill="none" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`; | ||
| } else if (expression === "surprised") { | ||
| svg += `<circle cx="50" cy="70" r="3" fill="#1a1a1c"/>`; | ||
| } else if (expression === "smirk") { | ||
| svg += `<path d="M46,67 Q52,69 56,64" fill="none" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`; | ||
| } | ||
| svg += `<path d="M28,62 L15,60 M28,65 L14,66" stroke="${stroke}" stroke-width="1.5" stroke-linecap="round" opacity="0.6"/>`; | ||
| svg += `<path d="M72,62 L85,60 M72,65 L86,66" stroke="${stroke}" stroke-width="1.5" stroke-linecap="round" opacity="0.6"/>`; | ||
| if (decoration === "headband") { | ||
| svg += `<path d="M16,35 Q50,20 84,35" fill="none" stroke="#e17055" stroke-width="6" stroke-linecap="round"/>`; | ||
| svg += `<path d="M50,15 L60,25 L50,28 L40,25 Z" fill="#fab1a0" stroke="#e17055" stroke-width="2"/>`; | ||
| } else if (decoration === "flower") { | ||
| svg += `<path d="M75,30 Q80,20 85,30 Q95,25 85,35 Q90,45 80,40 Q70,45 75,35 Q65,25 75,30 Z" fill="#ffeaa7" stroke="#fdcb6e" stroke-width="1.5"/>`; | ||
| svg += `<circle cx="80" cy="33" r="3" fill="#d63031"/>`; | ||
| } else if (decoration === "fish") { | ||
| svg += `<path d="M40,82 Q50,75 60,82 L65,78 L65,86 L60,82 Q50,89 40,82 Z" fill="#81ecec" stroke="${stroke}" stroke-width="1.5"/>`; | ||
| svg += `<circle cx="45" cy="81" r="1" fill="${stroke}"/>`; | ||
| } | ||
| svg += `</svg>`; | ||
| return `data:image/svg+xml,${encodeURIComponent(svg.replace(/\n\s*/g, ""))}`; | ||
| } | ||
| // src/utils/message-commands.ts | ||
| var COMMAND_TOKEN_RE = /(^|[\s([{"'`])\\?\/([A-Za-z][A-Za-z0-9_-]{0,31})(?:\s+([A-Za-z][A-Za-z0-9_-]{0,31}))?/gu; | ||
| var COMMAND_CUE_RE = /\b(reply|respond|send|type|enter|choose|click|press|run|execute|open)\b|回复|回覆|輸入|输入|发送|傳送|执行|執行|送信|응답|입력|보내|실행/iu; | ||
| var ARG_STOP_WORDS = /* @__PURE__ */ new Set([ | ||
| "a", | ||
| "an", | ||
| "and", | ||
| "at", | ||
| "by", | ||
| "cancel", | ||
| "execute", | ||
| "for", | ||
| "from", | ||
| "in", | ||
| "on", | ||
| "or", | ||
| "that", | ||
| "the", | ||
| "this", | ||
| "to", | ||
| "when", | ||
| "with" | ||
| ]); | ||
| var PATH_ROOTS = /* @__PURE__ */ new Set([ | ||
| "applications", | ||
| "bin", | ||
| "etc", | ||
| "home", | ||
| "library", | ||
| "opt", | ||
| "tmp", | ||
| "usr", | ||
| "var" | ||
| ]); | ||
| function removeFencedCode(content) { | ||
| return content.replace(/```[\s\S]*?```/gu, " "); | ||
| } | ||
| function normalizeArgument(argument) { | ||
| if (!argument) return void 0; | ||
| const value = argument.trim(); | ||
| if (!value) return void 0; | ||
| if (ARG_STOP_WORDS.has(value.toLocaleLowerCase())) return void 0; | ||
| return value; | ||
| } | ||
| function extractSlashCommandActions(content, options = {}) { | ||
| const normalized = removeFencedCode(content); | ||
| const matches = Array.from(normalized.matchAll(COMMAND_TOKEN_RE)); | ||
| if (matches.length === 0) return []; | ||
| if (matches.length < 2 && !COMMAND_CUE_RE.test(normalized)) return []; | ||
| const limit = Math.max(1, options.limit ?? 6); | ||
| const seen = /* @__PURE__ */ new Set(); | ||
| const actions = []; | ||
| for (const match of matches) { | ||
| const name = match[2]; | ||
| if (!name) continue; | ||
| const lowerName = name.toLocaleLowerCase(); | ||
| if (PATH_ROOTS.has(lowerName)) continue; | ||
| const argument = normalizeArgument(match[3]); | ||
| const command = `/${name}${argument ? ` ${argument}` : ""}`; | ||
| const key = command.toLocaleLowerCase(); | ||
| if (seen.has(key)) continue; | ||
| seen.add(key); | ||
| actions.push({ | ||
| id: key, | ||
| command, | ||
| name, | ||
| ...argument ? { argument } : {} | ||
| }); | ||
| if (actions.length >= limit) break; | ||
| } | ||
| return actions; | ||
| } | ||
| // src/utils/message-mentions.ts | ||
| function uniqueValues(values) { | ||
| return Array.from(new Set(values.filter((value) => !!value))); | ||
| } | ||
| function canonicalMentionToken(mention) { | ||
| if (mention.kind === "channel") return `<#${mention.channelId ?? mention.targetId}>`; | ||
| if (mention.kind === "server") return `<@server:${mention.serverId ?? mention.targetId}>`; | ||
| if (mention.kind === "app") return `<@app:${mention.appId ?? mention.targetId}>`; | ||
| if (mention.kind === "here" || mention.kind === "everyone") { | ||
| const scope = mention.serverId ?? mention.targetId; | ||
| return scope ? `<!${mention.kind}:${scope}>` : `<!${mention.kind}>`; | ||
| } | ||
| return `<@${mention.userId ?? mention.targetId}>`; | ||
| } | ||
| function parseCanonicalMentionToken(token) { | ||
| const app = token.match(/^<@app:([^>]+)>$/u); | ||
| if (app?.[1]) return { kind: "app", targetId: app[1] }; | ||
| const user = token.match(/^<@([^>:]+)>$/u); | ||
| if (user?.[1]) return { kind: "user", targetId: user[1] }; | ||
| const server = token.match(/^<@server:([^>]+)>$/u); | ||
| if (server?.[1]) return { kind: "server", targetId: server[1] }; | ||
| const channel = token.match(/^<#([^>]+)>$/u); | ||
| if (channel?.[1]) return { kind: "channel", targetId: channel[1] }; | ||
| const broadcast = token.match(/^<!(here|everyone)(?::([^>]+))?>$/u); | ||
| if (broadcast?.[1] === "here" || broadcast?.[1] === "everyone") { | ||
| return { | ||
| kind: broadcast[1], | ||
| ...broadcast[2] ? { targetId: broadcast[2] } : {} | ||
| }; | ||
| } | ||
| return null; | ||
| } | ||
| function isCanonicalMentionToken(token) { | ||
| return parseCanonicalMentionToken(token) !== null; | ||
| } | ||
| function matchTextsForMention(mention) { | ||
| return uniqueValues([mention.token, mention.sourceToken, canonicalMentionToken(mention)]); | ||
| } | ||
| function isValidRange(content, mention, range) { | ||
| if (!range) return false; | ||
| if (!Number.isInteger(range.start) || !Number.isInteger(range.end)) return false; | ||
| if (range.start < 0 || range.end <= range.start || range.end > content.length) return false; | ||
| const sourceText = content.slice(range.start, range.end); | ||
| return matchTextsForMention(mention).includes(sourceText); | ||
| } | ||
| function overlaps(a, b) { | ||
| return a.start < b.end && b.start < a.end; | ||
| } | ||
| function canUseRange(range, used) { | ||
| return !used.some((candidate) => overlaps(candidate, range)); | ||
| } | ||
| function findOccurrences(content, token, used) { | ||
| const occurrences = []; | ||
| let index = content.indexOf(token); | ||
| while (index >= 0) { | ||
| const range = { start: index, end: index + token.length }; | ||
| if (canUseRange(range, used)) occurrences.push(range); | ||
| index = content.indexOf(token, index + token.length); | ||
| } | ||
| return occurrences; | ||
| } | ||
| function addCandidate(candidates, used, mention, range, order, sourceText) { | ||
| if (!canUseRange(range, used)) return; | ||
| const matchedText = sourceText ?? mention.sourceToken ?? mention.token; | ||
| used.push(range); | ||
| candidates.push({ | ||
| start: range.start, | ||
| end: range.end, | ||
| order, | ||
| sourceText: matchedText, | ||
| mention: { ...mention, range } | ||
| }); | ||
| } | ||
| function segmentTextByMentions(content, mentions) { | ||
| if (!content) return []; | ||
| const usableMentions = (mentions ?? []).filter((mention) => mention.token); | ||
| if (usableMentions.length === 0) return [{ type: "text", text: content }]; | ||
| const candidates = []; | ||
| const usedRanges = []; | ||
| const pendingByText = /* @__PURE__ */ new Map(); | ||
| usableMentions.forEach((mention, order) => { | ||
| if (isValidRange(content, mention, mention.range)) { | ||
| addCandidate( | ||
| candidates, | ||
| usedRanges, | ||
| mention, | ||
| mention.range, | ||
| order, | ||
| content.slice(mention.range.start, mention.range.end) | ||
| ); | ||
| return; | ||
| } | ||
| for (const text of matchTextsForMention(mention)) { | ||
| const pending = pendingByText.get(text) ?? []; | ||
| pending.push({ mention, order }); | ||
| pendingByText.set(text, pending); | ||
| } | ||
| }); | ||
| const pendingGroups = Array.from(pendingByText.entries()).sort((a, b) => { | ||
| const lengthDelta = b[0].length - a[0].length; | ||
| if (lengthDelta !== 0) return lengthDelta; | ||
| return a[1][0].order - b[1][0].order; | ||
| }); | ||
| for (const [token, pending] of pendingGroups) { | ||
| const occurrences = findOccurrences(content, token, usedRanges); | ||
| if (occurrences.length === 0) continue; | ||
| if (pending.length === 1) { | ||
| const { mention, order } = pending[0]; | ||
| for (const range of occurrences) { | ||
| addCandidate(candidates, usedRanges, mention, range, order, token); | ||
| } | ||
| continue; | ||
| } | ||
| pending.forEach(({ mention, order }, index) => { | ||
| const range = occurrences[index]; | ||
| if (range) addCandidate(candidates, usedRanges, mention, range, order, token); | ||
| }); | ||
| } | ||
| candidates.sort((a, b) => a.start - b.start || b.end - a.end || a.order - b.order); | ||
| const segments = []; | ||
| let cursor = 0; | ||
| for (const candidate of candidates) { | ||
| if (candidate.start < cursor) continue; | ||
| if (candidate.start > cursor) { | ||
| segments.push({ type: "text", text: content.slice(cursor, candidate.start) }); | ||
| } | ||
| const text = content.slice(candidate.start, candidate.end); | ||
| segments.push({ | ||
| type: "mention", | ||
| text, | ||
| range: { start: candidate.start, end: candidate.end }, | ||
| mention: { ...candidate.mention, sourceToken: candidate.sourceText } | ||
| }); | ||
| cursor = candidate.end; | ||
| } | ||
| if (cursor < content.length) { | ||
| segments.push({ type: "text", text: content.slice(cursor) }); | ||
| } | ||
| return segments.length > 0 ? segments : [{ type: "text", text: content }]; | ||
| } | ||
| function assignMentionRanges(content, mentions) { | ||
| return segmentTextByMentions(content, mentions).filter((segment) => { | ||
| return segment.type === "mention"; | ||
| }).map((segment) => ({ | ||
| ...segment.mention, | ||
| token: segment.mention.token || segment.text, | ||
| range: segment.range | ||
| })); | ||
| } | ||
| function canonicalizeMentionContent(content, mentions) { | ||
| const canonicalMentions = []; | ||
| let nextContent = ""; | ||
| for (const segment of segmentTextByMentions(content, mentions)) { | ||
| if (segment.type === "text") { | ||
| nextContent += segment.text; | ||
| continue; | ||
| } | ||
| const token = canonicalMentionToken(segment.mention); | ||
| const start = nextContent.length; | ||
| nextContent += token; | ||
| canonicalMentions.push({ | ||
| ...segment.mention, | ||
| token, | ||
| sourceToken: segment.text === token ? segment.mention.sourceToken : segment.text, | ||
| range: { start, end: start + token.length } | ||
| }); | ||
| } | ||
| return { content: nextContent, mentions: canonicalMentions }; | ||
| } | ||
| function mentionDisplayText(mention) { | ||
| return mention.label || mention.token; | ||
| } | ||
| function escapeMarkdownLinkLabel(label) { | ||
| return label.replace(/\\/g, "\\\\").replace(/\[/g, "\\[").replace(/\]/g, "\\]"); | ||
| } | ||
| function buildMentionMarkdownLinks(content, mentions, hrefForMention) { | ||
| const linkedMentions = []; | ||
| const markdown = segmentTextByMentions(content, mentions).map((segment) => { | ||
| if (segment.type === "text") return segment.text; | ||
| const href = hrefForMention(segment.mention, linkedMentions.length); | ||
| if (!href) return segment.text; | ||
| linkedMentions.push(segment.mention); | ||
| return `[${escapeMarkdownLinkLabel(mentionDisplayText(segment.mention))}](${href})`; | ||
| }).join(""); | ||
| return { markdown, mentions: linkedMentions }; | ||
| } | ||
| // src/utils/pixel-cats.ts | ||
| var variants = [ | ||
| // 0: Shadow — Black cat (logo style) | ||
| { | ||
| body: "#2d2d30", | ||
| stroke: "#1a1a1c", | ||
| earInner: "#3d3d40", | ||
| eyeL: "#f8e71c", | ||
| eyeR: "#00f3ff", | ||
| nose: "#3a2a26" | ||
| }, | ||
| // 1: Mikan — Orange tabby | ||
| { | ||
| body: "#e8842c", | ||
| stroke: "#1a1a1c", | ||
| earInner: "#f5a623", | ||
| eyeL: "#4ade80", | ||
| eyeR: "#4ade80", | ||
| nose: "#d46b1a" | ||
| }, | ||
| // 2: Yuki — White cat | ||
| { | ||
| body: "#e8e8e8", | ||
| stroke: "#a0a0a0", | ||
| earInner: "#ffc0cb", | ||
| eyeL: "#60a5fa", | ||
| eyeR: "#60a5fa", | ||
| nose: "#f5a0b0" | ||
| }, | ||
| // 3: Haiiro — Gray cat | ||
| { | ||
| body: "#7a7a80", | ||
| stroke: "#4a4a50", | ||
| earInner: "#9a9aa0", | ||
| eyeL: "#fbbf24", | ||
| eyeR: "#fbbf24", | ||
| nose: "#5a4a46" | ||
| }, | ||
| // 4: Tuxedo — Black & white accents | ||
| { | ||
| body: "#2d2d30", | ||
| stroke: "#1a1a1c", | ||
| earInner: "#e0e0e0", | ||
| eyeL: "#22c55e", | ||
| eyeR: "#22c55e", | ||
| nose: "#3a2a26" | ||
| }, | ||
| // 5: Mocha — Cream/beige | ||
| { | ||
| body: "#d4a574", | ||
| stroke: "#8b6914", | ||
| earInner: "#e8c9a0", | ||
| eyeL: "#d97706", | ||
| eyeR: "#d97706", | ||
| nose: "#a0705a" | ||
| }, | ||
| // 6: Blue — Russian blue | ||
| { | ||
| body: "#6b8094", | ||
| stroke: "#3d5060", | ||
| earInner: "#8ba0b4", | ||
| eyeL: "#22c55e", | ||
| eyeR: "#22c55e", | ||
| nose: "#5a6a76" | ||
| }, | ||
| // 7: Sakura — Fantasy pink | ||
| { | ||
| body: "#f472b6", | ||
| stroke: "#be185d", | ||
| earInner: "#f9a8d4", | ||
| eyeL: "#a855f7", | ||
| eyeR: "#c084fc", | ||
| nose: "#d44a8c" | ||
| } | ||
| ]; | ||
| function makeCatSvg(c) { | ||
| return [ | ||
| '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">', | ||
| `<path d="M22,45 Q15,22 28,22 Q34,22 40,38" fill="${c.body}" stroke="${c.stroke}" stroke-width="2.5" stroke-linecap="round"/>`, | ||
| `<path d="M78,45 Q85,22 72,22 Q66,22 60,38" fill="${c.body}" stroke="${c.stroke}" stroke-width="2.5" stroke-linecap="round"/>`, | ||
| `<path d="M26,38 Q22,26 29,26 Q33,26 36,34" fill="${c.earInner}" opacity="0.5"/>`, | ||
| `<path d="M74,38 Q78,26 71,26 Q67,26 64,34" fill="${c.earInner}" opacity="0.5"/>`, | ||
| `<ellipse cx="50" cy="58" rx="36" ry="28" fill="${c.body}" stroke="${c.stroke}" stroke-width="2.5"/>`, | ||
| `<circle cx="35" cy="52" r="7" fill="${c.eyeL}" stroke="${c.stroke}" stroke-width="1.5"/>`, | ||
| `<circle cx="33" cy="49" r="2.5" fill="white"/>`, | ||
| `<circle cx="65" cy="52" r="7" fill="${c.eyeR}" stroke="${c.stroke}" stroke-width="1.5"/>`, | ||
| `<circle cx="63" cy="49" r="2.5" fill="white"/>`, | ||
| `<ellipse cx="50" cy="62" rx="3.5" ry="2.2" fill="${c.nose}"/>`, | ||
| `<path d="M42,67 Q46,72 50,67" fill="none" stroke="${c.stroke}" stroke-width="2" stroke-linecap="round"/>`, | ||
| `<path d="M50,67 Q54,72 58,67" fill="none" stroke="${c.stroke}" stroke-width="2" stroke-linecap="round"/>`, | ||
| "</svg>" | ||
| ].join(""); | ||
| } | ||
| var catDataUris = variants.map((v) => { | ||
| const svg = makeCatSvg(v); | ||
| return `data:image/svg+xml,${encodeURIComponent(svg)}`; | ||
| }); | ||
| function getCatAvatar(index) { | ||
| return catDataUris[index % catDataUris.length]; | ||
| } | ||
| function getCatAvatarByUserId(userId) { | ||
| let hash = 0; | ||
| for (let i = 0; i < userId.length; i++) { | ||
| hash = (hash << 5) - hash + userId.charCodeAt(i) | 0; | ||
| } | ||
| return getCatAvatar(Math.abs(hash) % catDataUris.length); | ||
| } | ||
| function getAllCatAvatars() { | ||
| const names = ["\u5F71\u5B50", "\u871C\u67D1", "\u5C0F\u96EA", "\u7070\u7070", "\u71D5\u5C3E\u670D", "\u6469\u5361", "\u84DD\u84DD", "\u5C0F\u6A31"]; | ||
| return catDataUris.map((uri, i) => ({ index: i, name: names[i], dataUri: uri })); | ||
| } | ||
| function getCatSvgString(index) { | ||
| return makeCatSvg(variants[index % variants.length]); | ||
| } | ||
| var CAT_AVATAR_COUNT = variants.length; | ||
| // src/utils/server-app-routes.ts | ||
| var SERVER_APP_ROUTE_PATH_MAX = 1024; | ||
| function cleanBasePath(basePath) { | ||
| const trimmed = basePath.trim(); | ||
| if (!trimmed || trimmed === "/") return ""; | ||
| return trimmed.startsWith("/") ? trimmed.replace(/\/+$/u, "") : `/${trimmed.replace(/\/+$/u, "")}`; | ||
| } | ||
| function normalizeServerAppRoutePath(value, fallback = null) { | ||
| if (typeof value !== "string") return fallback; | ||
| const trimmed = value.trim(); | ||
| if (!trimmed || !trimmed.startsWith("/") || trimmed.startsWith("//") || /[\r\n\\]/u.test(trimmed)) { | ||
| return fallback; | ||
| } | ||
| return trimmed.slice(0, SERVER_APP_ROUTE_PATH_MAX); | ||
| } | ||
| function withServerAppRoutePathSearch(search, appPath) { | ||
| const next = { ...search ?? {} }; | ||
| const normalized = normalizeServerAppRoutePath(appPath); | ||
| if (normalized && normalized !== "/") { | ||
| next.appPath = normalized; | ||
| } else { | ||
| delete next.appPath; | ||
| } | ||
| return next; | ||
| } | ||
| function serverAppPathFromSearch(search) { | ||
| return normalizeServerAppRoutePath(search?.appPath); | ||
| } | ||
| function buildServerAppCommunityPath(target, options = {}) { | ||
| const basePath = cleanBasePath(options.basePath ?? "/app"); | ||
| const path = `${basePath}/servers/${encodeURIComponent(target.serverSlug)}/apps/${encodeURIComponent( | ||
| target.appKey | ||
| )}`; | ||
| const params = new URLSearchParams(); | ||
| const appPath = normalizeServerAppRoutePath(target.appPath); | ||
| if (appPath && appPath !== "/") params.set("appPath", appPath); | ||
| const query = params.toString(); | ||
| return query ? `${path}?${query}` : path; | ||
| } | ||
| function buildServerAppSharePath(target, options = {}) { | ||
| const basePath = cleanBasePath(options.basePath ?? "/app"); | ||
| const path = `${basePath}/share/server-app/${encodeURIComponent( | ||
| target.serverSlug | ||
| )}/${encodeURIComponent(target.appKey)}`; | ||
| const params = new URLSearchParams(); | ||
| const appPath = normalizeServerAppRoutePath(target.appPath); | ||
| if (appPath && appPath !== "/") params.set("appPath", appPath); | ||
| const query = params.toString(); | ||
| return query ? `${path}?${query}` : path; | ||
| } | ||
| function buildServerAppShareUrl(target, options = {}) { | ||
| return new URL(buildServerAppSharePath(target, options), target.origin).toString(); | ||
| } | ||
| // src/utils/index.ts | ||
| var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | ||
| var generateInviteCode = customAlphabet(alphabet, 8); | ||
| function formatDate(date) { | ||
| const d = typeof date === "string" ? new Date(date) : date; | ||
| return d.toISOString(); | ||
| } | ||
| function isValidEmail(email) { | ||
| return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); | ||
| } | ||
| function slugify(text) { | ||
| return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, ""); | ||
| } | ||
| export { | ||
| generateRandomCatConfig, | ||
| renderCatSvg, | ||
| extractSlashCommandActions, | ||
| canonicalMentionToken, | ||
| parseCanonicalMentionToken, | ||
| isCanonicalMentionToken, | ||
| segmentTextByMentions, | ||
| assignMentionRanges, | ||
| canonicalizeMentionContent, | ||
| mentionDisplayText, | ||
| escapeMarkdownLinkLabel, | ||
| buildMentionMarkdownLinks, | ||
| getCatAvatar, | ||
| getCatAvatarByUserId, | ||
| getAllCatAvatars, | ||
| getCatSvgString, | ||
| CAT_AVATAR_COUNT, | ||
| normalizeServerAppRoutePath, | ||
| withServerAppRoutePathSearch, | ||
| serverAppPathFromSearch, | ||
| buildServerAppCommunityPath, | ||
| buildServerAppSharePath, | ||
| buildServerAppShareUrl, | ||
| generateInviteCode, | ||
| formatDate, | ||
| isValidEmail, | ||
| slugify | ||
| }; |
| interface Message { | ||
| id: string; | ||
| content: string; | ||
| channelId: string; | ||
| authorId: string; | ||
| threadId: string | null; | ||
| replyToId: string | null; | ||
| isEdited: boolean; | ||
| isPinned: boolean; | ||
| createdAt: string; | ||
| updatedAt: string; | ||
| author?: { | ||
| id: string; | ||
| username: string; | ||
| displayName: string; | ||
| avatarUrl: string | null; | ||
| isBot: boolean; | ||
| }; | ||
| attachments?: Attachment[]; | ||
| reactions?: ReactionGroup[]; | ||
| metadata?: MessageMetadata | null; | ||
| } | ||
| type MessageMentionKind = 'user' | 'buddy' | 'app' | 'channel' | 'server' | 'here' | 'everyone'; | ||
| interface MessageMentionRange { | ||
| start: number; | ||
| end: number; | ||
| } | ||
| interface MessageMention { | ||
| kind: MessageMentionKind; | ||
| /** Canonical target id. For users this is userId, for channels channelId, for servers serverId. */ | ||
| targetId: string; | ||
| /** Canonical text persisted in message content, e.g. <@userId>, <#channelId>. */ | ||
| token: string; | ||
| /** Optional display text selected or typed by the sender before canonicalization. */ | ||
| sourceToken?: string; | ||
| /** Human-readable label used by renderers. */ | ||
| label: string; | ||
| /** Optional source range in content. Clients may omit it; servers may recompute later. */ | ||
| range?: MessageMentionRange; | ||
| serverId?: string; | ||
| serverSlug?: string | null; | ||
| serverName?: string | null; | ||
| channelId?: string; | ||
| channelName?: string | null; | ||
| appId?: string; | ||
| appKey?: string; | ||
| appName?: string | null; | ||
| iconUrl?: string | null; | ||
| userId?: string; | ||
| username?: string | null; | ||
| displayName?: string | null; | ||
| avatarUrl?: string | null; | ||
| isBot?: boolean; | ||
| isPrivate?: boolean; | ||
| } | ||
| declare const MESSAGE_COPILOT_CONTEXT_METADATA_KEY: "copilotContext"; | ||
| declare const MESSAGE_AGENT_CHAIN_METADATA_KEY: "agentChain"; | ||
| interface MessageCopilotContext { | ||
| kind: 'server_app_copilot'; | ||
| /** Server app install id when the current surface is an installed server app. */ | ||
| serverAppId?: string | null; | ||
| /** Catalog app id when available. */ | ||
| appId?: string | null; | ||
| /** Stable app key from the app route, e.g. kanban. */ | ||
| appKey: string; | ||
| appName?: string | null; | ||
| serverId?: string | null; | ||
| serverSlug?: string | null; | ||
| /** Channel or Inbox currently opened in the Copilot panel. */ | ||
| channelId?: string | null; | ||
| channelKind?: string | null; | ||
| } | ||
| declare function isMessageCopilotContext(value: unknown): value is MessageCopilotContext; | ||
| declare function buildMessageCopilotContextMetadata(context: MessageCopilotContext | null | undefined): { | ||
| copilotContext: MessageCopilotContext; | ||
| } | undefined; | ||
| interface MessageAgentChainMetadata { | ||
| /** Logical runtime agent id that produced the current message. */ | ||
| agentId: string; | ||
| /** Number of runtime hops from the original trigger to this message. */ | ||
| depth: number; | ||
| /** Bot/user ids that have participated in the chain so far. */ | ||
| participants: string[]; | ||
| /** Runtime start timestamp, usually Date.now(), or an ISO timestamp. */ | ||
| startedAt?: number | string; | ||
| /** Message id that started the chain. */ | ||
| rootMessageId?: string; | ||
| } | ||
| declare function isMessageAgentChainMetadata(value: unknown): value is MessageAgentChainMetadata; | ||
| declare function buildMessageAgentChainMetadata(agentChain: MessageAgentChainMetadata | null | undefined): { | ||
| agentChain: MessageAgentChainMetadata; | ||
| } | undefined; | ||
| interface MessageMetadata { | ||
| /** Runtime trace metadata for agent-to-agent or task-triggered messages. */ | ||
| agentChain?: MessageAgentChainMetadata; | ||
| mentions?: MessageMention[]; | ||
| copilotContext?: MessageCopilotContext; | ||
| interactive?: Record<string, unknown>; | ||
| interactiveResponse?: Record<string, unknown>; | ||
| interactiveState?: Record<string, unknown>; | ||
| ccConnectDelivery?: Record<string, unknown>; | ||
| shadowDelivery?: Record<string, unknown>; | ||
| custom?: { | ||
| buddyInboxTaskResult?: BuddyInboxTaskResultMetadata; | ||
| [key: string]: unknown; | ||
| }; | ||
| /** Unified card protocol. New card-like message surfaces must use this field. */ | ||
| cards?: MessageCard[]; | ||
| [key: string]: unknown; | ||
| } | ||
| type MessageCardStatus = 'queued' | 'claimed' | 'running' | 'completed' | 'failed' | 'canceled' | 'transferred'; | ||
| interface BuddyInboxTaskRefMetadata { | ||
| messageId: string; | ||
| cardId: string; | ||
| channelId: string; | ||
| threadId: string | null; | ||
| title?: string; | ||
| assignee?: unknown; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskResultMessageCard { | ||
| id: string; | ||
| kind: 'task_result'; | ||
| version: number; | ||
| title: string; | ||
| body?: string; | ||
| idempotencyKey?: string; | ||
| taskMessageId: string; | ||
| taskCardId: string; | ||
| status: MessageCardStatus; | ||
| delivery?: string; | ||
| createdAt?: string; | ||
| updatedAt?: string; | ||
| sourceTask?: BuddyInboxTaskRefMetadata; | ||
| parentTask?: BuddyInboxTaskRefMetadata; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| } | ||
| /** @deprecated Use TaskResultMessageCard. Kept for legacy task-result renderers. */ | ||
| type BuddyInboxTaskResultMetadata = TaskResultMessageCard; | ||
| declare function parseBuddyInboxTaskResultMetadata(metadata: unknown): BuddyInboxTaskResultMetadata | null; | ||
| interface MessageCardSource { | ||
| kind: 'user' | 'pat' | 'oauth' | 'agent' | 'system' | 'server_app' | 'buddy'; | ||
| id?: string; | ||
| label?: string; | ||
| userId?: string; | ||
| agentId?: string; | ||
| appId?: string; | ||
| appKey?: string; | ||
| appName?: string | null; | ||
| iconUrl?: string | null; | ||
| serverId?: string; | ||
| channelId?: string; | ||
| command?: string; | ||
| resource?: { | ||
| kind: string; | ||
| id: string; | ||
| label?: string; | ||
| url?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| [key: string]: unknown; | ||
| } | ||
| type TaskMessageCardTag = string | { | ||
| id?: string; | ||
| label: string; | ||
| color?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| interface MessageCardApp { | ||
| id?: string; | ||
| appId?: string; | ||
| appKey?: string; | ||
| name?: string | null; | ||
| label?: string | null; | ||
| iconUrl?: string | null; | ||
| logoUrl?: string | null; | ||
| avatarUrl?: string | null; | ||
| imageUrl?: string | null; | ||
| url?: string | null; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageCardReply { | ||
| id?: string; | ||
| messageId?: string; | ||
| cardId?: string; | ||
| authorId?: string; | ||
| authorLabel?: string; | ||
| authorAvatarUrl?: string | null; | ||
| content: string; | ||
| createdAt: string; | ||
| source?: MessageCardSource; | ||
| [key: string]: unknown; | ||
| } | ||
| interface MessageCardClaim { | ||
| id: string; | ||
| actor: MessageCardSource; | ||
| claimedAt: string; | ||
| expiresAt: string; | ||
| } | ||
| interface MessageCardCapability { | ||
| kind: 'task'; | ||
| scope: string[]; | ||
| issuedAt: string; | ||
| expiresAt: string; | ||
| claimId?: string; | ||
| binding?: { | ||
| messageId?: string; | ||
| cardId: string; | ||
| workspaceId?: string; | ||
| }; | ||
| } | ||
| interface TaskMessageRequirementSkill { | ||
| kind: 'runtime-skill'; | ||
| package: string; | ||
| version?: string; | ||
| required?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageRequirementTool { | ||
| kind: string; | ||
| name: string; | ||
| required?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageRequirements { | ||
| capabilities?: string[]; | ||
| skills?: TaskMessageRequirementSkill[]; | ||
| tools?: TaskMessageRequirementTool[]; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageExpectedArtifact { | ||
| kind: string; | ||
| mimeTypes?: string[]; | ||
| maxBytes?: number; | ||
| required?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageSubmitCommand { | ||
| appKey: string; | ||
| command: string; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageOutputContract { | ||
| expectedArtifacts?: TaskMessageExpectedArtifact[]; | ||
| submitCommand?: TaskMessageSubmitCommand; | ||
| [key: string]: unknown; | ||
| } | ||
| type TaskMessagePrivacyDataClass = 'public' | 'server-private' | 'channel-private' | 'financial' | 'secret' | 'cloud-secret'; | ||
| interface TaskMessagePrivacy { | ||
| dataClass: TaskMessagePrivacyDataClass; | ||
| redactionRequired?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskContextPack { | ||
| snapshotAtMessageId: string | null; | ||
| sourceSurface: 'channel' | 'thread' | 'task-thread' | 'app'; | ||
| policy: 'auto_recent' | 'explicit_refs' | 'thread_context' | 'manual'; | ||
| summary: string | null; | ||
| items: Array<{ | ||
| kind: 'message'; | ||
| messageId: string; | ||
| threadId?: string | null; | ||
| authorId: string; | ||
| createdAt: string; | ||
| text: string; | ||
| } | { | ||
| kind: 'resource'; | ||
| resourceType: string; | ||
| resourceId: string; | ||
| title?: string; | ||
| summary?: string; | ||
| } | { | ||
| kind: 'task_result'; | ||
| messageId: string; | ||
| cardId: string; | ||
| title: string; | ||
| summary: string; | ||
| }>; | ||
| omitted: Array<{ | ||
| messageCount: number; | ||
| reason: 'token_budget' | 'permission' | 'privacy' | 'not_relevant'; | ||
| }>; | ||
| tokenEstimate: number; | ||
| } | ||
| interface TaskMessageCard { | ||
| id: string; | ||
| kind: 'task'; | ||
| version: number; | ||
| title: string; | ||
| body?: string; | ||
| status: MessageCardStatus; | ||
| priority?: 'low' | 'normal' | 'medium' | 'high'; | ||
| tags?: TaskMessageCardTag[]; | ||
| app?: MessageCardApp; | ||
| assignee?: { | ||
| agentId?: string; | ||
| userId?: string; | ||
| label?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| source?: MessageCardSource; | ||
| requirements?: TaskMessageRequirements; | ||
| outputContract?: TaskMessageOutputContract; | ||
| privacy?: TaskMessagePrivacy; | ||
| claim?: MessageCardClaim; | ||
| capability?: MessageCardCapability; | ||
| progress?: Array<{ | ||
| at: string; | ||
| status: MessageCardStatus; | ||
| note?: string; | ||
| actor?: MessageCardSource; | ||
| [key: string]: unknown; | ||
| }>; | ||
| replies?: TaskMessageCardReply[]; | ||
| createdAt: string; | ||
| updatedAt?: string; | ||
| data?: Record<string, unknown> & { | ||
| task?: { | ||
| workspaceId?: string; | ||
| threadId?: string; | ||
| parentTask?: { | ||
| messageId: string; | ||
| cardId: string; | ||
| channelId: string; | ||
| threadId: string; | ||
| title?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| revision?: number; | ||
| contextPack?: TaskContextPack; | ||
| [key: string]: unknown; | ||
| }; | ||
| }; | ||
| [key: string]: unknown; | ||
| } | ||
| type GenericMessageCard = { | ||
| id?: string; | ||
| kind: string; | ||
| version?: number; | ||
| title?: string; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| }; | ||
| interface ServerAppMessageCard { | ||
| id?: string; | ||
| kind: 'server_app'; | ||
| version?: number; | ||
| appKey: string; | ||
| title: string; | ||
| description?: string; | ||
| label?: string; | ||
| action?: { | ||
| mode: 'open_app'; | ||
| path?: string; | ||
| }; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| } | ||
| interface MessageReferenceCard { | ||
| id?: string; | ||
| kind: 'message_reference'; | ||
| version?: number; | ||
| title: string; | ||
| description?: string; | ||
| label?: string; | ||
| target: { | ||
| serverId?: string | null; | ||
| serverSlug?: string | null; | ||
| channelId: string; | ||
| messageId: string; | ||
| taskCardId?: string | null; | ||
| inboxAgentId?: string | null; | ||
| kind?: 'channel_message' | 'inbox_message'; | ||
| }; | ||
| source?: MessageCardSource; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| } | ||
| type MessageCard = TaskMessageCard | TaskResultMessageCard | ServerAppMessageCard | MessageReferenceCard | CommerceProductCard | PaidFileCard | OAuthLinkCard | GenericMessageCard; | ||
| interface CommerceOfferCardInput { | ||
| id?: string; | ||
| kind: 'offer'; | ||
| offerId: string; | ||
| } | ||
| type CommerceMessageCard = CommerceProductCard | CommerceOfferCardInput; | ||
| interface CommerceProductCard { | ||
| id: string; | ||
| kind: 'offer' | 'product'; | ||
| offerId?: string; | ||
| shopId: string; | ||
| shopScope: { | ||
| kind: 'server' | 'user'; | ||
| id: string; | ||
| }; | ||
| productId: string; | ||
| skuId?: string; | ||
| snapshot: { | ||
| name: string; | ||
| summary?: string | null; | ||
| imageUrl?: string | null; | ||
| shopName?: string | null; | ||
| deliveryPromise?: string | null; | ||
| price: number; | ||
| currency: string; | ||
| productType: 'physical' | 'entitlement'; | ||
| billingMode?: 'one_time' | 'fixed_duration' | 'subscription'; | ||
| durationSeconds?: number | null; | ||
| resourceType?: string; | ||
| resourceId?: string; | ||
| capability?: string; | ||
| }; | ||
| purchase: { | ||
| mode: 'direct' | 'select_sku' | 'open_detail'; | ||
| }; | ||
| } | ||
| interface PaidFileCard { | ||
| id: string; | ||
| kind: 'paid_file'; | ||
| fileId: string; | ||
| entitlementId?: string | null; | ||
| deliverableId?: string; | ||
| snapshot: { | ||
| name: string; | ||
| summary?: string | null; | ||
| mime?: string | null; | ||
| sizeBytes?: number | null; | ||
| previewUrl?: string | null; | ||
| }; | ||
| action: { | ||
| mode: 'open_paid_file'; | ||
| }; | ||
| } | ||
| interface OAuthLinkCard { | ||
| id: string; | ||
| kind: 'oauth_link'; | ||
| appId: string; | ||
| clientId?: string | null; | ||
| title: string; | ||
| description?: string | null; | ||
| iconUrl?: string | null; | ||
| meta?: { | ||
| appName?: string | null; | ||
| avatarUrl?: string | null; | ||
| iconUrl?: string | null; | ||
| coverUrl?: string | null; | ||
| homepageUrl?: string | null; | ||
| origin?: string | null; | ||
| }; | ||
| url: string; | ||
| embedUrl?: string | null; | ||
| fallbackUrl?: string | null; | ||
| scopes?: string[]; | ||
| action: { | ||
| mode: 'open_iframe' | 'open_external'; | ||
| }; | ||
| } | ||
| declare function isCommerceMessageCard(card: unknown): card is CommerceProductCard; | ||
| declare function isPaidFileMessageCard(card: unknown): card is PaidFileCard; | ||
| declare function isOAuthLinkMessageCard(card: unknown): card is OAuthLinkCard; | ||
| declare function getCommerceMessageCards(metadata: Pick<MessageMetadata, 'cards'> | null | undefined): CommerceProductCard[]; | ||
| declare function getPaidFileMessageCards(metadata: Pick<MessageMetadata, 'cards'> | null | undefined): PaidFileCard[]; | ||
| declare function getOAuthLinkMessageCards(metadata: Pick<MessageMetadata, 'cards'> | null | undefined): OAuthLinkCard[]; | ||
| type MentionSuggestionTrigger = '@' | '#'; | ||
| interface MentionSuggestion { | ||
| id: string; | ||
| kind: MessageMentionKind; | ||
| targetId: string; | ||
| token: string; | ||
| label: string; | ||
| description?: string | null; | ||
| serverId?: string; | ||
| serverSlug?: string | null; | ||
| serverName?: string | null; | ||
| channelId?: string; | ||
| channelName?: string | null; | ||
| appId?: string; | ||
| appKey?: string; | ||
| appName?: string | null; | ||
| iconUrl?: string | null; | ||
| userId?: string; | ||
| username?: string | null; | ||
| displayName?: string | null; | ||
| avatarUrl?: string | null; | ||
| isBot?: boolean; | ||
| isPrivate?: boolean; | ||
| } | ||
| interface Attachment { | ||
| id: string; | ||
| messageId: string; | ||
| filename: string; | ||
| url: string; | ||
| contentType: string; | ||
| size: number; | ||
| width: number | null; | ||
| height: number | null; | ||
| workspaceNodeId?: string | null; | ||
| kind?: 'file' | 'image' | 'voice'; | ||
| durationMs?: number | null; | ||
| audioCodec?: string | null; | ||
| audioContainer?: string | null; | ||
| waveformPeaks?: number[] | null; | ||
| waveformVersion?: number | null; | ||
| transcript?: { | ||
| id: string; | ||
| status: 'pending' | 'processing' | 'ready' | 'failed'; | ||
| text: string | null; | ||
| language: string | null; | ||
| source: 'client' | 'server' | 'runtime'; | ||
| provider?: string | null; | ||
| confidence?: number | null; | ||
| errorCode?: string | null; | ||
| updatedAt?: string; | ||
| } | null; | ||
| playback?: { | ||
| played: boolean; | ||
| completed: boolean; | ||
| lastPositionMs: number; | ||
| playedCount?: number; | ||
| } | null; | ||
| createdAt: string; | ||
| } | ||
| interface ReactionGroup { | ||
| emoji: string; | ||
| count: number; | ||
| userIds: string[]; | ||
| } | ||
| interface Thread { | ||
| id: string; | ||
| name: string; | ||
| channelId: string; | ||
| parentMessageId: string; | ||
| creatorId: string; | ||
| isArchived: boolean; | ||
| createdAt: string; | ||
| updatedAt: string; | ||
| } | ||
| interface SendMessageRequest { | ||
| content: string; | ||
| threadId?: string; | ||
| replyToId?: string; | ||
| mentions?: MessageMention[]; | ||
| metadata?: MessageMetadata; | ||
| } | ||
| interface UpdateMessageRequest { | ||
| content: string; | ||
| } | ||
| type NotificationType = 'mention' | 'reply' | 'dm' | 'system'; | ||
| interface Notification { | ||
| id: string; | ||
| userId: string; | ||
| type: NotificationType; | ||
| title: string; | ||
| body: string | null; | ||
| referenceId: string | null; | ||
| referenceType: string | null; | ||
| isRead: boolean; | ||
| createdAt: string; | ||
| } | ||
| export { isMessageAgentChainMetadata as $, type Attachment as A, type BuddyInboxTaskRefMetadata as B, type CommerceMessageCard as C, type TaskMessageOutputContract as D, type TaskMessagePrivacy as E, type TaskMessagePrivacyDataClass as F, type GenericMessageCard as G, type TaskMessageRequirementSkill as H, type TaskMessageRequirementTool as I, type TaskMessageRequirements as J, type TaskMessageSubmitCommand as K, type TaskResultMessageCard as L, MESSAGE_AGENT_CHAIN_METADATA_KEY as M, type Notification as N, type OAuthLinkCard as O, type PaidFileCard as P, type Thread as Q, type ReactionGroup as R, type SendMessageRequest as S, type TaskContextPack as T, type UpdateMessageRequest as U, buildMessageAgentChainMetadata as V, buildMessageCopilotContextMetadata as W, getCommerceMessageCards as X, getOAuthLinkMessageCards as Y, getPaidFileMessageCards as Z, isCommerceMessageCard as _, type BuddyInboxTaskResultMetadata as a, isMessageCopilotContext as a0, isOAuthLinkMessageCard as a1, isPaidFileMessageCard as a2, parseBuddyInboxTaskResultMetadata as a3, type CommerceOfferCardInput as b, type CommerceProductCard as c, MESSAGE_COPILOT_CONTEXT_METADATA_KEY as d, type MentionSuggestion as e, type MentionSuggestionTrigger as f, type Message as g, type MessageAgentChainMetadata as h, type MessageCard as i, type MessageCardApp as j, type MessageCardCapability as k, type MessageCardClaim as l, type MessageCardSource as m, type MessageCardStatus as n, type MessageCopilotContext as o, type MessageMention as p, type MessageMentionKind as q, type MessageMentionRange as r, type MessageMetadata as s, type MessageReferenceCard as t, type NotificationType as u, type ServerAppMessageCard as v, type TaskMessageCard as w, type TaskMessageCardReply as x, type TaskMessageCardTag as y, type TaskMessageExpectedArtifact as z }; |
| interface Message { | ||
| id: string; | ||
| content: string; | ||
| channelId: string; | ||
| authorId: string; | ||
| threadId: string | null; | ||
| replyToId: string | null; | ||
| isEdited: boolean; | ||
| isPinned: boolean; | ||
| createdAt: string; | ||
| updatedAt: string; | ||
| author?: { | ||
| id: string; | ||
| username: string; | ||
| displayName: string; | ||
| avatarUrl: string | null; | ||
| isBot: boolean; | ||
| }; | ||
| attachments?: Attachment[]; | ||
| reactions?: ReactionGroup[]; | ||
| metadata?: MessageMetadata | null; | ||
| } | ||
| type MessageMentionKind = 'user' | 'buddy' | 'app' | 'channel' | 'server' | 'here' | 'everyone'; | ||
| interface MessageMentionRange { | ||
| start: number; | ||
| end: number; | ||
| } | ||
| interface MessageMention { | ||
| kind: MessageMentionKind; | ||
| /** Canonical target id. For users this is userId, for channels channelId, for servers serverId. */ | ||
| targetId: string; | ||
| /** Canonical text persisted in message content, e.g. <@userId>, <#channelId>. */ | ||
| token: string; | ||
| /** Optional display text selected or typed by the sender before canonicalization. */ | ||
| sourceToken?: string; | ||
| /** Human-readable label used by renderers. */ | ||
| label: string; | ||
| /** Optional source range in content. Clients may omit it; servers may recompute later. */ | ||
| range?: MessageMentionRange; | ||
| serverId?: string; | ||
| serverSlug?: string | null; | ||
| serverName?: string | null; | ||
| channelId?: string; | ||
| channelName?: string | null; | ||
| appId?: string; | ||
| appKey?: string; | ||
| appName?: string | null; | ||
| iconUrl?: string | null; | ||
| userId?: string; | ||
| username?: string | null; | ||
| displayName?: string | null; | ||
| avatarUrl?: string | null; | ||
| isBot?: boolean; | ||
| isPrivate?: boolean; | ||
| } | ||
| declare const MESSAGE_COPILOT_CONTEXT_METADATA_KEY: "copilotContext"; | ||
| declare const MESSAGE_AGENT_CHAIN_METADATA_KEY: "agentChain"; | ||
| interface MessageCopilotContext { | ||
| kind: 'server_app_copilot'; | ||
| /** Server app install id when the current surface is an installed server app. */ | ||
| serverAppId?: string | null; | ||
| /** Catalog app id when available. */ | ||
| appId?: string | null; | ||
| /** Stable app key from the app route, e.g. kanban. */ | ||
| appKey: string; | ||
| appName?: string | null; | ||
| serverId?: string | null; | ||
| serverSlug?: string | null; | ||
| /** Channel or Inbox currently opened in the Copilot panel. */ | ||
| channelId?: string | null; | ||
| channelKind?: string | null; | ||
| } | ||
| declare function isMessageCopilotContext(value: unknown): value is MessageCopilotContext; | ||
| declare function buildMessageCopilotContextMetadata(context: MessageCopilotContext | null | undefined): { | ||
| copilotContext: MessageCopilotContext; | ||
| } | undefined; | ||
| interface MessageAgentChainMetadata { | ||
| /** Logical runtime agent id that produced the current message. */ | ||
| agentId: string; | ||
| /** Number of runtime hops from the original trigger to this message. */ | ||
| depth: number; | ||
| /** Bot/user ids that have participated in the chain so far. */ | ||
| participants: string[]; | ||
| /** Runtime start timestamp, usually Date.now(), or an ISO timestamp. */ | ||
| startedAt?: number | string; | ||
| /** Message id that started the chain. */ | ||
| rootMessageId?: string; | ||
| } | ||
| declare function isMessageAgentChainMetadata(value: unknown): value is MessageAgentChainMetadata; | ||
| declare function buildMessageAgentChainMetadata(agentChain: MessageAgentChainMetadata | null | undefined): { | ||
| agentChain: MessageAgentChainMetadata; | ||
| } | undefined; | ||
| interface MessageMetadata { | ||
| /** Runtime trace metadata for agent-to-agent or task-triggered messages. */ | ||
| agentChain?: MessageAgentChainMetadata; | ||
| mentions?: MessageMention[]; | ||
| copilotContext?: MessageCopilotContext; | ||
| interactive?: Record<string, unknown>; | ||
| interactiveResponse?: Record<string, unknown>; | ||
| interactiveState?: Record<string, unknown>; | ||
| ccConnectDelivery?: Record<string, unknown>; | ||
| shadowDelivery?: Record<string, unknown>; | ||
| custom?: { | ||
| buddyInboxTaskResult?: BuddyInboxTaskResultMetadata; | ||
| [key: string]: unknown; | ||
| }; | ||
| /** Unified card protocol. New card-like message surfaces must use this field. */ | ||
| cards?: MessageCard[]; | ||
| [key: string]: unknown; | ||
| } | ||
| type MessageCardStatus = 'queued' | 'claimed' | 'running' | 'completed' | 'failed' | 'canceled' | 'transferred'; | ||
| interface BuddyInboxTaskRefMetadata { | ||
| messageId: string; | ||
| cardId: string; | ||
| channelId: string; | ||
| threadId: string | null; | ||
| title?: string; | ||
| assignee?: unknown; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskResultMessageCard { | ||
| id: string; | ||
| kind: 'task_result'; | ||
| version: number; | ||
| title: string; | ||
| body?: string; | ||
| idempotencyKey?: string; | ||
| taskMessageId: string; | ||
| taskCardId: string; | ||
| status: MessageCardStatus; | ||
| delivery?: string; | ||
| createdAt?: string; | ||
| updatedAt?: string; | ||
| sourceTask?: BuddyInboxTaskRefMetadata; | ||
| parentTask?: BuddyInboxTaskRefMetadata; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| } | ||
| /** @deprecated Use TaskResultMessageCard. Kept for legacy task-result renderers. */ | ||
| type BuddyInboxTaskResultMetadata = TaskResultMessageCard; | ||
| declare function parseBuddyInboxTaskResultMetadata(metadata: unknown): BuddyInboxTaskResultMetadata | null; | ||
| interface MessageCardSource { | ||
| kind: 'user' | 'pat' | 'oauth' | 'agent' | 'system' | 'server_app' | 'buddy'; | ||
| id?: string; | ||
| label?: string; | ||
| userId?: string; | ||
| agentId?: string; | ||
| appId?: string; | ||
| appKey?: string; | ||
| appName?: string | null; | ||
| iconUrl?: string | null; | ||
| serverId?: string; | ||
| channelId?: string; | ||
| command?: string; | ||
| resource?: { | ||
| kind: string; | ||
| id: string; | ||
| label?: string; | ||
| url?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| [key: string]: unknown; | ||
| } | ||
| type TaskMessageCardTag = string | { | ||
| id?: string; | ||
| label: string; | ||
| color?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| interface MessageCardApp { | ||
| id?: string; | ||
| appId?: string; | ||
| appKey?: string; | ||
| name?: string | null; | ||
| label?: string | null; | ||
| iconUrl?: string | null; | ||
| logoUrl?: string | null; | ||
| avatarUrl?: string | null; | ||
| imageUrl?: string | null; | ||
| url?: string | null; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageCardReply { | ||
| id?: string; | ||
| messageId?: string; | ||
| cardId?: string; | ||
| authorId?: string; | ||
| authorLabel?: string; | ||
| authorAvatarUrl?: string | null; | ||
| content: string; | ||
| createdAt: string; | ||
| source?: MessageCardSource; | ||
| [key: string]: unknown; | ||
| } | ||
| interface MessageCardClaim { | ||
| id: string; | ||
| actor: MessageCardSource; | ||
| claimedAt: string; | ||
| expiresAt: string; | ||
| } | ||
| interface MessageCardCapability { | ||
| kind: 'task'; | ||
| scope: string[]; | ||
| issuedAt: string; | ||
| expiresAt: string; | ||
| claimId?: string; | ||
| binding?: { | ||
| messageId?: string; | ||
| cardId: string; | ||
| workspaceId?: string; | ||
| }; | ||
| } | ||
| interface TaskMessageRequirementSkill { | ||
| kind: 'runtime-skill'; | ||
| package: string; | ||
| version?: string; | ||
| required?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageRequirementTool { | ||
| kind: string; | ||
| name: string; | ||
| required?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageRequirements { | ||
| capabilities?: string[]; | ||
| skills?: TaskMessageRequirementSkill[]; | ||
| tools?: TaskMessageRequirementTool[]; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageExpectedArtifact { | ||
| kind: string; | ||
| mimeTypes?: string[]; | ||
| maxBytes?: number; | ||
| required?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageSubmitCommand { | ||
| appKey: string; | ||
| command: string; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageOutputContract { | ||
| expectedArtifacts?: TaskMessageExpectedArtifact[]; | ||
| submitCommand?: TaskMessageSubmitCommand; | ||
| [key: string]: unknown; | ||
| } | ||
| type TaskMessagePrivacyDataClass = 'public' | 'server-private' | 'channel-private' | 'financial' | 'secret' | 'cloud-secret'; | ||
| interface TaskMessagePrivacy { | ||
| dataClass: TaskMessagePrivacyDataClass; | ||
| redactionRequired?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskContextPack { | ||
| snapshotAtMessageId: string | null; | ||
| sourceSurface: 'channel' | 'thread' | 'task-thread' | 'app'; | ||
| policy: 'auto_recent' | 'explicit_refs' | 'thread_context' | 'manual'; | ||
| summary: string | null; | ||
| items: Array<{ | ||
| kind: 'message'; | ||
| messageId: string; | ||
| threadId?: string | null; | ||
| authorId: string; | ||
| createdAt: string; | ||
| text: string; | ||
| } | { | ||
| kind: 'resource'; | ||
| resourceType: string; | ||
| resourceId: string; | ||
| title?: string; | ||
| summary?: string; | ||
| } | { | ||
| kind: 'task_result'; | ||
| messageId: string; | ||
| cardId: string; | ||
| title: string; | ||
| summary: string; | ||
| }>; | ||
| omitted: Array<{ | ||
| messageCount: number; | ||
| reason: 'token_budget' | 'permission' | 'privacy' | 'not_relevant'; | ||
| }>; | ||
| tokenEstimate: number; | ||
| } | ||
| interface TaskMessageCard { | ||
| id: string; | ||
| kind: 'task'; | ||
| version: number; | ||
| title: string; | ||
| body?: string; | ||
| status: MessageCardStatus; | ||
| priority?: 'low' | 'normal' | 'medium' | 'high'; | ||
| tags?: TaskMessageCardTag[]; | ||
| app?: MessageCardApp; | ||
| assignee?: { | ||
| agentId?: string; | ||
| userId?: string; | ||
| label?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| source?: MessageCardSource; | ||
| requirements?: TaskMessageRequirements; | ||
| outputContract?: TaskMessageOutputContract; | ||
| privacy?: TaskMessagePrivacy; | ||
| claim?: MessageCardClaim; | ||
| capability?: MessageCardCapability; | ||
| progress?: Array<{ | ||
| at: string; | ||
| status: MessageCardStatus; | ||
| note?: string; | ||
| actor?: MessageCardSource; | ||
| [key: string]: unknown; | ||
| }>; | ||
| replies?: TaskMessageCardReply[]; | ||
| createdAt: string; | ||
| updatedAt?: string; | ||
| data?: Record<string, unknown> & { | ||
| task?: { | ||
| workspaceId?: string; | ||
| threadId?: string; | ||
| parentTask?: { | ||
| messageId: string; | ||
| cardId: string; | ||
| channelId: string; | ||
| threadId: string; | ||
| title?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| revision?: number; | ||
| contextPack?: TaskContextPack; | ||
| [key: string]: unknown; | ||
| }; | ||
| }; | ||
| [key: string]: unknown; | ||
| } | ||
| type GenericMessageCard = { | ||
| id?: string; | ||
| kind: string; | ||
| version?: number; | ||
| title?: string; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| }; | ||
| interface ServerAppMessageCard { | ||
| id?: string; | ||
| kind: 'server_app'; | ||
| version?: number; | ||
| appKey: string; | ||
| title: string; | ||
| description?: string; | ||
| label?: string; | ||
| action?: { | ||
| mode: 'open_app'; | ||
| path?: string; | ||
| }; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| } | ||
| interface MessageReferenceCard { | ||
| id?: string; | ||
| kind: 'message_reference'; | ||
| version?: number; | ||
| title: string; | ||
| description?: string; | ||
| label?: string; | ||
| target: { | ||
| serverId?: string | null; | ||
| serverSlug?: string | null; | ||
| channelId: string; | ||
| messageId: string; | ||
| taskCardId?: string | null; | ||
| inboxAgentId?: string | null; | ||
| kind?: 'channel_message' | 'inbox_message'; | ||
| }; | ||
| source?: MessageCardSource; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| } | ||
| type MessageCard = TaskMessageCard | TaskResultMessageCard | ServerAppMessageCard | MessageReferenceCard | CommerceProductCard | PaidFileCard | OAuthLinkCard | GenericMessageCard; | ||
| interface CommerceOfferCardInput { | ||
| id?: string; | ||
| kind: 'offer'; | ||
| offerId: string; | ||
| } | ||
| type CommerceMessageCard = CommerceProductCard | CommerceOfferCardInput; | ||
| interface CommerceProductCard { | ||
| id: string; | ||
| kind: 'offer' | 'product'; | ||
| offerId?: string; | ||
| shopId: string; | ||
| shopScope: { | ||
| kind: 'server' | 'user'; | ||
| id: string; | ||
| }; | ||
| productId: string; | ||
| skuId?: string; | ||
| snapshot: { | ||
| name: string; | ||
| summary?: string | null; | ||
| imageUrl?: string | null; | ||
| shopName?: string | null; | ||
| deliveryPromise?: string | null; | ||
| price: number; | ||
| currency: string; | ||
| productType: 'physical' | 'entitlement'; | ||
| billingMode?: 'one_time' | 'fixed_duration' | 'subscription'; | ||
| durationSeconds?: number | null; | ||
| resourceType?: string; | ||
| resourceId?: string; | ||
| capability?: string; | ||
| }; | ||
| purchase: { | ||
| mode: 'direct' | 'select_sku' | 'open_detail'; | ||
| }; | ||
| } | ||
| interface PaidFileCard { | ||
| id: string; | ||
| kind: 'paid_file'; | ||
| fileId: string; | ||
| entitlementId?: string | null; | ||
| deliverableId?: string; | ||
| snapshot: { | ||
| name: string; | ||
| summary?: string | null; | ||
| mime?: string | null; | ||
| sizeBytes?: number | null; | ||
| previewUrl?: string | null; | ||
| }; | ||
| action: { | ||
| mode: 'open_paid_file'; | ||
| }; | ||
| } | ||
| interface OAuthLinkCard { | ||
| id: string; | ||
| kind: 'oauth_link'; | ||
| appId: string; | ||
| clientId?: string | null; | ||
| title: string; | ||
| description?: string | null; | ||
| iconUrl?: string | null; | ||
| meta?: { | ||
| appName?: string | null; | ||
| avatarUrl?: string | null; | ||
| iconUrl?: string | null; | ||
| coverUrl?: string | null; | ||
| homepageUrl?: string | null; | ||
| origin?: string | null; | ||
| }; | ||
| url: string; | ||
| embedUrl?: string | null; | ||
| fallbackUrl?: string | null; | ||
| scopes?: string[]; | ||
| action: { | ||
| mode: 'open_iframe' | 'open_external'; | ||
| }; | ||
| } | ||
| declare function isCommerceMessageCard(card: unknown): card is CommerceProductCard; | ||
| declare function isPaidFileMessageCard(card: unknown): card is PaidFileCard; | ||
| declare function isOAuthLinkMessageCard(card: unknown): card is OAuthLinkCard; | ||
| declare function getCommerceMessageCards(metadata: Pick<MessageMetadata, 'cards'> | null | undefined): CommerceProductCard[]; | ||
| declare function getPaidFileMessageCards(metadata: Pick<MessageMetadata, 'cards'> | null | undefined): PaidFileCard[]; | ||
| declare function getOAuthLinkMessageCards(metadata: Pick<MessageMetadata, 'cards'> | null | undefined): OAuthLinkCard[]; | ||
| type MentionSuggestionTrigger = '@' | '#'; | ||
| interface MentionSuggestion { | ||
| id: string; | ||
| kind: MessageMentionKind; | ||
| targetId: string; | ||
| token: string; | ||
| label: string; | ||
| description?: string | null; | ||
| serverId?: string; | ||
| serverSlug?: string | null; | ||
| serverName?: string | null; | ||
| channelId?: string; | ||
| channelName?: string | null; | ||
| appId?: string; | ||
| appKey?: string; | ||
| appName?: string | null; | ||
| iconUrl?: string | null; | ||
| userId?: string; | ||
| username?: string | null; | ||
| displayName?: string | null; | ||
| avatarUrl?: string | null; | ||
| isBot?: boolean; | ||
| isPrivate?: boolean; | ||
| } | ||
| interface Attachment { | ||
| id: string; | ||
| messageId: string; | ||
| filename: string; | ||
| url: string; | ||
| contentType: string; | ||
| size: number; | ||
| width: number | null; | ||
| height: number | null; | ||
| workspaceNodeId?: string | null; | ||
| kind?: 'file' | 'image' | 'voice'; | ||
| durationMs?: number | null; | ||
| audioCodec?: string | null; | ||
| audioContainer?: string | null; | ||
| waveformPeaks?: number[] | null; | ||
| waveformVersion?: number | null; | ||
| transcript?: { | ||
| id: string; | ||
| status: 'pending' | 'processing' | 'ready' | 'failed'; | ||
| text: string | null; | ||
| language: string | null; | ||
| source: 'client' | 'server' | 'runtime'; | ||
| provider?: string | null; | ||
| confidence?: number | null; | ||
| errorCode?: string | null; | ||
| updatedAt?: string; | ||
| } | null; | ||
| playback?: { | ||
| played: boolean; | ||
| completed: boolean; | ||
| lastPositionMs: number; | ||
| playedCount?: number; | ||
| } | null; | ||
| createdAt: string; | ||
| } | ||
| interface ReactionGroup { | ||
| emoji: string; | ||
| count: number; | ||
| userIds: string[]; | ||
| } | ||
| interface Thread { | ||
| id: string; | ||
| name: string; | ||
| channelId: string; | ||
| parentMessageId: string; | ||
| creatorId: string; | ||
| isArchived: boolean; | ||
| createdAt: string; | ||
| updatedAt: string; | ||
| } | ||
| interface SendMessageRequest { | ||
| content: string; | ||
| threadId?: string; | ||
| replyToId?: string; | ||
| mentions?: MessageMention[]; | ||
| metadata?: MessageMetadata; | ||
| } | ||
| interface UpdateMessageRequest { | ||
| content: string; | ||
| } | ||
| type NotificationType = 'mention' | 'reply' | 'dm' | 'system'; | ||
| interface Notification { | ||
| id: string; | ||
| userId: string; | ||
| type: NotificationType; | ||
| title: string; | ||
| body: string | null; | ||
| referenceId: string | null; | ||
| referenceType: string | null; | ||
| isRead: boolean; | ||
| createdAt: string; | ||
| } | ||
| export { isMessageAgentChainMetadata as $, type Attachment as A, type BuddyInboxTaskRefMetadata as B, type CommerceMessageCard as C, type TaskMessageOutputContract as D, type TaskMessagePrivacy as E, type TaskMessagePrivacyDataClass as F, type GenericMessageCard as G, type TaskMessageRequirementSkill as H, type TaskMessageRequirementTool as I, type TaskMessageRequirements as J, type TaskMessageSubmitCommand as K, type TaskResultMessageCard as L, MESSAGE_AGENT_CHAIN_METADATA_KEY as M, type Notification as N, type OAuthLinkCard as O, type PaidFileCard as P, type Thread as Q, type ReactionGroup as R, type SendMessageRequest as S, type TaskContextPack as T, type UpdateMessageRequest as U, buildMessageAgentChainMetadata as V, buildMessageCopilotContextMetadata as W, getCommerceMessageCards as X, getOAuthLinkMessageCards as Y, getPaidFileMessageCards as Z, isCommerceMessageCard as _, type BuddyInboxTaskResultMetadata as a, isMessageCopilotContext as a0, isOAuthLinkMessageCard as a1, isPaidFileMessageCard as a2, parseBuddyInboxTaskResultMetadata as a3, type CommerceOfferCardInput as b, type CommerceProductCard as c, MESSAGE_COPILOT_CONTEXT_METADATA_KEY as d, type MentionSuggestion as e, type MentionSuggestionTrigger as f, type Message as g, type MessageAgentChainMetadata as h, type MessageCard as i, type MessageCardApp as j, type MessageCardCapability as k, type MessageCardClaim as l, type MessageCardSource as m, type MessageCardStatus as n, type MessageCopilotContext as o, type MessageMention as p, type MessageMentionKind as q, type MessageMentionRange as r, type MessageMetadata as s, type MessageReferenceCard as t, type NotificationType as u, type ServerAppMessageCard as v, type TaskMessageCard as w, type TaskMessageCardReply as x, type TaskMessageCardTag as y, type TaskMessageExpectedArtifact as z }; |
@@ -53,2 +53,3 @@ "use strict"; | ||
| NOTIFICATION_NEW: "notification:new", | ||
| SERVER_APP_LIST_CHANGED: "server-app:list-changed", | ||
| VOICE_STATE: "voice:state", | ||
@@ -55,0 +56,0 @@ VOICE_PARTICIPANT_JOINED: "voice:participant-joined", |
@@ -24,2 +24,3 @@ declare const CLIENT_EVENTS: { | ||
| readonly NOTIFICATION_NEW: "notification:new"; | ||
| readonly SERVER_APP_LIST_CHANGED: "server-app:list-changed"; | ||
| readonly VOICE_STATE: "voice:state"; | ||
@@ -26,0 +27,0 @@ readonly VOICE_PARTICIPANT_JOINED: "voice:participant-joined"; |
@@ -24,2 +24,3 @@ declare const CLIENT_EVENTS: { | ||
| readonly NOTIFICATION_NEW: "notification:new"; | ||
| readonly SERVER_APP_LIST_CHANGED: "server-app:list-changed"; | ||
| readonly VOICE_STATE: "voice:state"; | ||
@@ -26,0 +27,0 @@ readonly VOICE_PARTICIPANT_JOINED: "voice:participant-joined"; |
@@ -5,3 +5,3 @@ import { | ||
| SERVER_EVENTS | ||
| } from "../chunk-J34E7LGB.js"; | ||
| } from "../chunk-2CRSZWS7.js"; | ||
| export { | ||
@@ -8,0 +8,0 @@ CLIENT_EVENTS, |
+2
-2
@@ -5,4 +5,4 @@ export { CLIENT_EVENTS, ClientEvent, LIMITS, SERVER_EVENTS, ServerEvent } from './constants/index.cjs'; | ||
| export { Agent, AgentCapability, AgentInfo, AgentKernelType, AgentStatus, AuthResponse, BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, BUDDY_INBOX_DELIVERY_PERMISSION, BUDDY_INBOX_PLATFORM_PERMISSIONS, BUDDY_INBOX_TOPIC_PREFIX, BUDDY_PRESENCE_STATUSES, BuddyInboxAdmissionMode, BuddyInboxAdmissionPendingDelivery, BuddyInboxAdmissionPendingTask, BuddyInboxAdmissionPolicy, BuddyInboxAdmissionRule, BuddyInboxAdmissionSubjectKind, BuddyInboxPlatformPermission, BuddyInboxViewMessage, BuddyInboxViewMode, BuddyPresenceStatus, Channel, ChannelSortBy, ChannelSortDirection, ChannelSortOptions, ChannelType, CreateAgentRequest, CreateChannelRequest, CreateServerRequest, DEFAULT_BUDDY_INBOX_ADMISSION_POLICY, FriendEntry, FriendSource, Friendship, FriendshipStatus, LoginRequest, Member, MemberRole, PresenceChangePayload, PresenceSnapshotPayload, PresenceStatus, RUNTIME_SESSION_PET_REACTION_BY_STATE, RegisterRequest, RuntimeSessionAnimationSignal, RuntimeSessionPetActivity, RuntimeSessionPetActivityKind, RuntimeSessionPetReaction, RuntimeSessionState, Server, TASK_MESSAGE_CARD_STATUSES, TASK_MESSAGE_CARD_STATUS_TRANSITIONS, TERMINAL_TASK_MESSAGE_CARD_STATUSES, USER_STATUSES, UpdateChannelRequest, UpdateServerRequest, User, UserMembership, UserMembershipTier, UserProfile, UserStatus, VoiceChannelCredentials, VoiceChannelJoinResult, VoiceChannelLeaveResult, VoiceChannelPolicy, VoiceChannelState, VoiceParticipant, applyPresenceChangeToRuntime, buddyInboxAdmissionRuleKey, buddyInboxTopic, buildBuddyInboxViewMessages, canTransitionTaskMessageCardStatus, getBuddyInboxTaskCards, getBuddyInboxTaskStatuses, getBuddyPresenceExpiresAt, hasBuddyInboxTaskCard, isBuddyHeartbeatActive, isBuddyInboxPlatformPermission, isBuddyInboxTopic, isMessageReferenceCard, isTaskMessageCardStatus, isTerminalTaskMessageCardStatus, normalizeBuddyInboxAdmissionPendingDeliveries, normalizeBuddyInboxAdmissionPolicy, normalizeBuddyPresenceStatus, normalizeBuddyRuntimePresenceStatus, normalizePresenceStatus, normalizeUserStatus, parseBuddyInboxAgentId, resolvePresenceStatus, runtimeSessionPetReactionForState, runtimeSessionSignalToPetReaction, runtimeSessionStateLooksActive } from './types/index.cjs'; | ||
| export { A as Attachment, C as CommerceMessageCard, a as CommerceOfferCardInput, b as CommerceProductCard, G as GenericMessageCard, M as MESSAGE_AGENT_CHAIN_METADATA_KEY, c as MESSAGE_COPILOT_CONTEXT_METADATA_KEY, d as MentionSuggestion, e as MentionSuggestionTrigger, f as Message, g as MessageAgentChainMetadata, h as MessageCard, i as MessageCardApp, j as MessageCardCapability, k as MessageCardClaim, l as MessageCardSource, m as MessageCardStatus, n as MessageCopilotContext, o as MessageMention, p as MessageMentionKind, q as MessageMentionRange, r as MessageMetadata, s as MessageReferenceCard, N as Notification, t as NotificationType, O as OAuthLinkCard, P as PaidFileCard, R as ReactionGroup, S as SendMessageRequest, u as ServerAppMessageCard, T as TaskContextPack, v as TaskMessageCard, w as TaskMessageCardReply, x as TaskMessageCardTag, y as TaskMessageExpectedArtifact, z as TaskMessageOutputContract, B as TaskMessagePrivacy, D as TaskMessagePrivacyDataClass, E as TaskMessageRequirementSkill, F as TaskMessageRequirementTool, H as TaskMessageRequirements, I as TaskMessageSubmitCommand, J as Thread, U as UpdateMessageRequest, K as buildMessageAgentChainMetadata, L as buildMessageCopilotContextMetadata, Q as isMessageAgentChainMetadata, V as isMessageCopilotContext } from './message.types-KkQdHFE5.cjs'; | ||
| export { BgPattern, CAT_AVATAR_COUNT, CatConfig, CatDecoration, CatExpression, CatPattern, MessageMentionTextSegment, SlashCommandAction, assignMentionRanges, buildMentionMarkdownLinks, canonicalMentionToken, canonicalizeMentionContent, escapeMarkdownLinkLabel, extractSlashCommandActions, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isValidEmail, mentionDisplayText, parseCanonicalMentionToken, renderCatSvg, segmentTextByMentions, slugify } from './utils/index.cjs'; | ||
| export { A as Attachment, B as BuddyInboxTaskRefMetadata, a as BuddyInboxTaskResultMetadata, C as CommerceMessageCard, b as CommerceOfferCardInput, c as CommerceProductCard, G as GenericMessageCard, M as MESSAGE_AGENT_CHAIN_METADATA_KEY, d as MESSAGE_COPILOT_CONTEXT_METADATA_KEY, e as MentionSuggestion, f as MentionSuggestionTrigger, g as Message, h as MessageAgentChainMetadata, i as MessageCard, j as MessageCardApp, k as MessageCardCapability, l as MessageCardClaim, m as MessageCardSource, n as MessageCardStatus, o as MessageCopilotContext, p as MessageMention, q as MessageMentionKind, r as MessageMentionRange, s as MessageMetadata, t as MessageReferenceCard, N as Notification, u as NotificationType, O as OAuthLinkCard, P as PaidFileCard, R as ReactionGroup, S as SendMessageRequest, v as ServerAppMessageCard, T as TaskContextPack, w as TaskMessageCard, x as TaskMessageCardReply, y as TaskMessageCardTag, z as TaskMessageExpectedArtifact, D as TaskMessageOutputContract, E as TaskMessagePrivacy, F as TaskMessagePrivacyDataClass, H as TaskMessageRequirementSkill, I as TaskMessageRequirementTool, J as TaskMessageRequirements, K as TaskMessageSubmitCommand, L as TaskResultMessageCard, Q as Thread, U as UpdateMessageRequest, V as buildMessageAgentChainMetadata, W as buildMessageCopilotContextMetadata, X as getCommerceMessageCards, Y as getOAuthLinkMessageCards, Z as getPaidFileMessageCards, _ as isCommerceMessageCard, $ as isMessageAgentChainMetadata, a0 as isMessageCopilotContext, a1 as isOAuthLinkMessageCard, a2 as isPaidFileMessageCard, a3 as parseBuddyInboxTaskResultMetadata } from './message.types-Cznw92Uq.cjs'; | ||
| export { BgPattern, CAT_AVATAR_COUNT, CatConfig, CatDecoration, CatExpression, CatPattern, MessageMentionTextSegment, ServerAppPathOptions, ServerAppRouteTarget, SlashCommandAction, assignMentionRanges, buildMentionMarkdownLinks, buildServerAppCommunityPath, buildServerAppSharePath, buildServerAppShareUrl, canonicalMentionToken, canonicalizeMentionContent, escapeMarkdownLinkLabel, extractSlashCommandActions, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isValidEmail, mentionDisplayText, normalizeServerAppRoutePath, parseCanonicalMentionToken, renderCatSvg, segmentTextByMentions, serverAppPathFromSearch, slugify, withServerAppRoutePathSearch } from './utils/index.cjs'; | ||
| import 'zod'; |
+2
-2
@@ -5,4 +5,4 @@ export { CLIENT_EVENTS, ClientEvent, LIMITS, SERVER_EVENTS, ServerEvent } from './constants/index.js'; | ||
| export { Agent, AgentCapability, AgentInfo, AgentKernelType, AgentStatus, AuthResponse, BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, BUDDY_INBOX_DELIVERY_PERMISSION, BUDDY_INBOX_PLATFORM_PERMISSIONS, BUDDY_INBOX_TOPIC_PREFIX, BUDDY_PRESENCE_STATUSES, BuddyInboxAdmissionMode, BuddyInboxAdmissionPendingDelivery, BuddyInboxAdmissionPendingTask, BuddyInboxAdmissionPolicy, BuddyInboxAdmissionRule, BuddyInboxAdmissionSubjectKind, BuddyInboxPlatformPermission, BuddyInboxViewMessage, BuddyInboxViewMode, BuddyPresenceStatus, Channel, ChannelSortBy, ChannelSortDirection, ChannelSortOptions, ChannelType, CreateAgentRequest, CreateChannelRequest, CreateServerRequest, DEFAULT_BUDDY_INBOX_ADMISSION_POLICY, FriendEntry, FriendSource, Friendship, FriendshipStatus, LoginRequest, Member, MemberRole, PresenceChangePayload, PresenceSnapshotPayload, PresenceStatus, RUNTIME_SESSION_PET_REACTION_BY_STATE, RegisterRequest, RuntimeSessionAnimationSignal, RuntimeSessionPetActivity, RuntimeSessionPetActivityKind, RuntimeSessionPetReaction, RuntimeSessionState, Server, TASK_MESSAGE_CARD_STATUSES, TASK_MESSAGE_CARD_STATUS_TRANSITIONS, TERMINAL_TASK_MESSAGE_CARD_STATUSES, USER_STATUSES, UpdateChannelRequest, UpdateServerRequest, User, UserMembership, UserMembershipTier, UserProfile, UserStatus, VoiceChannelCredentials, VoiceChannelJoinResult, VoiceChannelLeaveResult, VoiceChannelPolicy, VoiceChannelState, VoiceParticipant, applyPresenceChangeToRuntime, buddyInboxAdmissionRuleKey, buddyInboxTopic, buildBuddyInboxViewMessages, canTransitionTaskMessageCardStatus, getBuddyInboxTaskCards, getBuddyInboxTaskStatuses, getBuddyPresenceExpiresAt, hasBuddyInboxTaskCard, isBuddyHeartbeatActive, isBuddyInboxPlatformPermission, isBuddyInboxTopic, isMessageReferenceCard, isTaskMessageCardStatus, isTerminalTaskMessageCardStatus, normalizeBuddyInboxAdmissionPendingDeliveries, normalizeBuddyInboxAdmissionPolicy, normalizeBuddyPresenceStatus, normalizeBuddyRuntimePresenceStatus, normalizePresenceStatus, normalizeUserStatus, parseBuddyInboxAgentId, resolvePresenceStatus, runtimeSessionPetReactionForState, runtimeSessionSignalToPetReaction, runtimeSessionStateLooksActive } from './types/index.js'; | ||
| export { A as Attachment, C as CommerceMessageCard, a as CommerceOfferCardInput, b as CommerceProductCard, G as GenericMessageCard, M as MESSAGE_AGENT_CHAIN_METADATA_KEY, c as MESSAGE_COPILOT_CONTEXT_METADATA_KEY, d as MentionSuggestion, e as MentionSuggestionTrigger, f as Message, g as MessageAgentChainMetadata, h as MessageCard, i as MessageCardApp, j as MessageCardCapability, k as MessageCardClaim, l as MessageCardSource, m as MessageCardStatus, n as MessageCopilotContext, o as MessageMention, p as MessageMentionKind, q as MessageMentionRange, r as MessageMetadata, s as MessageReferenceCard, N as Notification, t as NotificationType, O as OAuthLinkCard, P as PaidFileCard, R as ReactionGroup, S as SendMessageRequest, u as ServerAppMessageCard, T as TaskContextPack, v as TaskMessageCard, w as TaskMessageCardReply, x as TaskMessageCardTag, y as TaskMessageExpectedArtifact, z as TaskMessageOutputContract, B as TaskMessagePrivacy, D as TaskMessagePrivacyDataClass, E as TaskMessageRequirementSkill, F as TaskMessageRequirementTool, H as TaskMessageRequirements, I as TaskMessageSubmitCommand, J as Thread, U as UpdateMessageRequest, K as buildMessageAgentChainMetadata, L as buildMessageCopilotContextMetadata, Q as isMessageAgentChainMetadata, V as isMessageCopilotContext } from './message.types-KkQdHFE5.js'; | ||
| export { BgPattern, CAT_AVATAR_COUNT, CatConfig, CatDecoration, CatExpression, CatPattern, MessageMentionTextSegment, SlashCommandAction, assignMentionRanges, buildMentionMarkdownLinks, canonicalMentionToken, canonicalizeMentionContent, escapeMarkdownLinkLabel, extractSlashCommandActions, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isValidEmail, mentionDisplayText, parseCanonicalMentionToken, renderCatSvg, segmentTextByMentions, slugify } from './utils/index.js'; | ||
| export { A as Attachment, B as BuddyInboxTaskRefMetadata, a as BuddyInboxTaskResultMetadata, C as CommerceMessageCard, b as CommerceOfferCardInput, c as CommerceProductCard, G as GenericMessageCard, M as MESSAGE_AGENT_CHAIN_METADATA_KEY, d as MESSAGE_COPILOT_CONTEXT_METADATA_KEY, e as MentionSuggestion, f as MentionSuggestionTrigger, g as Message, h as MessageAgentChainMetadata, i as MessageCard, j as MessageCardApp, k as MessageCardCapability, l as MessageCardClaim, m as MessageCardSource, n as MessageCardStatus, o as MessageCopilotContext, p as MessageMention, q as MessageMentionKind, r as MessageMentionRange, s as MessageMetadata, t as MessageReferenceCard, N as Notification, u as NotificationType, O as OAuthLinkCard, P as PaidFileCard, R as ReactionGroup, S as SendMessageRequest, v as ServerAppMessageCard, T as TaskContextPack, w as TaskMessageCard, x as TaskMessageCardReply, y as TaskMessageCardTag, z as TaskMessageExpectedArtifact, D as TaskMessageOutputContract, E as TaskMessagePrivacy, F as TaskMessagePrivacyDataClass, H as TaskMessageRequirementSkill, I as TaskMessageRequirementTool, J as TaskMessageRequirements, K as TaskMessageSubmitCommand, L as TaskResultMessageCard, Q as Thread, U as UpdateMessageRequest, V as buildMessageAgentChainMetadata, W as buildMessageCopilotContextMetadata, X as getCommerceMessageCards, Y as getOAuthLinkMessageCards, Z as getPaidFileMessageCards, _ as isCommerceMessageCard, $ as isMessageAgentChainMetadata, a0 as isMessageCopilotContext, a1 as isOAuthLinkMessageCard, a2 as isPaidFileMessageCard, a3 as parseBuddyInboxTaskResultMetadata } from './message.types-Cznw92Uq.js'; | ||
| export { BgPattern, CAT_AVATAR_COUNT, CatConfig, CatDecoration, CatExpression, CatPattern, MessageMentionTextSegment, ServerAppPathOptions, ServerAppRouteTarget, SlashCommandAction, assignMentionRanges, buildMentionMarkdownLinks, buildServerAppCommunityPath, buildServerAppSharePath, buildServerAppShareUrl, canonicalMentionToken, canonicalizeMentionContent, escapeMarkdownLinkLabel, extractSlashCommandActions, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isValidEmail, mentionDisplayText, normalizeServerAppRoutePath, parseCanonicalMentionToken, renderCatSvg, segmentTextByMentions, serverAppPathFromSearch, slugify, withServerAppRoutePathSearch } from './utils/index.js'; | ||
| import 'zod'; |
+31
-5
@@ -5,3 +5,3 @@ import { | ||
| SERVER_EVENTS | ||
| } from "./chunk-J34E7LGB.js"; | ||
| } from "./chunk-2CRSZWS7.js"; | ||
| import { | ||
@@ -83,2 +83,5 @@ agentProcessIdSchema, | ||
| getBuddyPresenceExpiresAt, | ||
| getCommerceMessageCards, | ||
| getOAuthLinkMessageCards, | ||
| getPaidFileMessageCards, | ||
| hasBuddyInboxTaskCard, | ||
@@ -88,5 +91,8 @@ isBuddyHeartbeatActive, | ||
| isBuddyInboxTopic, | ||
| isCommerceMessageCard, | ||
| isMessageAgentChainMetadata, | ||
| isMessageCopilotContext, | ||
| isMessageReferenceCard, | ||
| isOAuthLinkMessageCard, | ||
| isPaidFileMessageCard, | ||
| isTaskMessageCardStatus, | ||
@@ -101,2 +107,3 @@ isTerminalTaskMessageCardStatus, | ||
| parseBuddyInboxAgentId, | ||
| parseBuddyInboxTaskResultMetadata, | ||
| resolvePresenceStatus, | ||
@@ -106,3 +113,3 @@ runtimeSessionPetReactionForState, | ||
| runtimeSessionStateLooksActive | ||
| } from "./chunk-ATHTS7JM.js"; | ||
| } from "./chunk-7YMBXKQG.js"; | ||
| import { | ||
@@ -118,2 +125,5 @@ DEFAULT_HOMEPLAY_CATALOG, | ||
| buildMentionMarkdownLinks, | ||
| buildServerAppCommunityPath, | ||
| buildServerAppSharePath, | ||
| buildServerAppShareUrl, | ||
| canonicalMentionToken, | ||
@@ -133,7 +143,10 @@ canonicalizeMentionContent, | ||
| mentionDisplayText, | ||
| normalizeServerAppRoutePath, | ||
| parseCanonicalMentionToken, | ||
| renderCatSvg, | ||
| segmentTextByMentions, | ||
| slugify | ||
| } from "./chunk-NPKLJYHP.js"; | ||
| serverAppPathFromSearch, | ||
| slugify, | ||
| withServerAppRoutePathSearch | ||
| } from "./chunk-NWPWICSP.js"; | ||
| export { | ||
@@ -169,2 +182,5 @@ BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, | ||
| buildMessageCopilotContextMetadata, | ||
| buildServerAppCommunityPath, | ||
| buildServerAppSharePath, | ||
| buildServerAppShareUrl, | ||
| canTransitionTaskMessageCardStatus, | ||
@@ -202,3 +218,6 @@ canonicalMentionToken, | ||
| getCatSvgString, | ||
| getCommerceMessageCards, | ||
| getDefaultHomePlay, | ||
| getOAuthLinkMessageCards, | ||
| getPaidFileMessageCards, | ||
| getPlayBuddyEmail, | ||
@@ -215,5 +234,8 @@ getPlayBuddyUsername, | ||
| isCanonicalMentionToken, | ||
| isCommerceMessageCard, | ||
| isMessageAgentChainMetadata, | ||
| isMessageCopilotContext, | ||
| isMessageReferenceCard, | ||
| isOAuthLinkMessageCard, | ||
| isPaidFileMessageCard, | ||
| isTaskMessageCardStatus, | ||
@@ -229,2 +251,3 @@ isTerminalTaskMessageCardStatus, | ||
| normalizePresenceStatus, | ||
| normalizeServerAppRoutePath, | ||
| normalizeUserStatus, | ||
@@ -237,2 +260,3 @@ notificationModeSchema, | ||
| parseBuddyInboxAgentId, | ||
| parseBuddyInboxTaskResultMetadata, | ||
| parseCanonicalMentionToken, | ||
@@ -259,2 +283,3 @@ parseIPCProcedureInput, | ||
| selectDirectorySchema, | ||
| serverAppPathFromSearch, | ||
| showCommunityInputSchema, | ||
@@ -266,3 +291,4 @@ showSettingsInputSchema, | ||
| updateSettingsSchema, | ||
| voiceModelInstallSchema | ||
| voiceModelInstallSchema, | ||
| withServerAppRoutePathSearch | ||
| }; |
+133
-0
@@ -46,2 +46,5 @@ "use strict"; | ||
| getBuddyPresenceExpiresAt: () => getBuddyPresenceExpiresAt, | ||
| getCommerceMessageCards: () => getCommerceMessageCards, | ||
| getOAuthLinkMessageCards: () => getOAuthLinkMessageCards, | ||
| getPaidFileMessageCards: () => getPaidFileMessageCards, | ||
| hasBuddyInboxTaskCard: () => hasBuddyInboxTaskCard, | ||
@@ -51,5 +54,8 @@ isBuddyHeartbeatActive: () => isBuddyHeartbeatActive, | ||
| isBuddyInboxTopic: () => isBuddyInboxTopic, | ||
| isCommerceMessageCard: () => isCommerceMessageCard, | ||
| isMessageAgentChainMetadata: () => isMessageAgentChainMetadata, | ||
| isMessageCopilotContext: () => isMessageCopilotContext, | ||
| isMessageReferenceCard: () => isMessageReferenceCard, | ||
| isOAuthLinkMessageCard: () => isOAuthLinkMessageCard, | ||
| isPaidFileMessageCard: () => isPaidFileMessageCard, | ||
| isTaskMessageCardStatus: () => isTaskMessageCardStatus, | ||
@@ -64,2 +70,3 @@ isTerminalTaskMessageCardStatus: () => isTerminalTaskMessageCardStatus, | ||
| parseBuddyInboxAgentId: () => parseBuddyInboxAgentId, | ||
| parseBuddyInboxTaskResultMetadata: () => parseBuddyInboxTaskResultMetadata, | ||
| resolvePresenceStatus: () => resolvePresenceStatus, | ||
@@ -291,2 +298,121 @@ runtimeSessionPetReactionForState: () => runtimeSessionPetReactionForState, | ||
| } | ||
| function metadataRecord(value) { | ||
| return value && typeof value === "object" && !Array.isArray(value) ? value : null; | ||
| } | ||
| function metadataString(value) { | ||
| return typeof value === "string" && value.trim() ? value.trim() : null; | ||
| } | ||
| function isMessageCardStatus(value) { | ||
| return value === "queued" || value === "claimed" || value === "running" || value === "completed" || value === "failed" || value === "canceled" || value === "transferred"; | ||
| } | ||
| function parseBuddyInboxTaskRef(value) { | ||
| const record = metadataRecord(value); | ||
| if (!record) return void 0; | ||
| const messageId = metadataString(record.messageId); | ||
| const cardId = metadataString(record.cardId); | ||
| const channelId = metadataString(record.channelId); | ||
| const threadId = metadataString(record.threadId); | ||
| const title = metadataString(record.title); | ||
| if (!messageId || !cardId || !channelId) return void 0; | ||
| const extra = { ...record }; | ||
| delete extra.messageId; | ||
| delete extra.cardId; | ||
| delete extra.channelId; | ||
| delete extra.threadId; | ||
| delete extra.title; | ||
| return { | ||
| ...extra, | ||
| messageId, | ||
| cardId, | ||
| channelId, | ||
| threadId, | ||
| ...title ? { title } : {} | ||
| }; | ||
| } | ||
| function parseBuddyInboxTaskResultCard(value) { | ||
| const result = metadataRecord(value); | ||
| if (!result || result.kind !== "task_result") return null; | ||
| const taskMessageId = metadataString(result.taskMessageId); | ||
| const taskCardId = metadataString(result.taskCardId); | ||
| const status = result.status; | ||
| if (!taskMessageId || !taskCardId || !isMessageCardStatus(status)) return null; | ||
| const id = metadataString(result.id) ?? `task-result:${taskMessageId}:${taskCardId}:${status}`; | ||
| const version = typeof result.version === "number" && Number.isFinite(result.version) ? Math.max(1, Math.trunc(result.version)) : 1; | ||
| const title = metadataString(result.title) ?? metadataString(metadataRecord(result.sourceTask)?.title) ?? metadataString(metadataRecord(result.parentTask)?.title) ?? "Task result"; | ||
| const body = metadataString(result.body); | ||
| const idempotencyKey = metadataString(result.idempotencyKey); | ||
| const delivery = metadataString(result.delivery); | ||
| const createdAt = metadataString(result.createdAt); | ||
| const updatedAt = metadataString(result.updatedAt); | ||
| const sourceTask = parseBuddyInboxTaskRef(result.sourceTask); | ||
| const parentTask = parseBuddyInboxTaskRef(result.parentTask); | ||
| const data = metadataRecord(result.data); | ||
| const extra = { ...result }; | ||
| delete extra.id; | ||
| delete extra.kind; | ||
| delete extra.version; | ||
| delete extra.title; | ||
| delete extra.body; | ||
| delete extra.idempotencyKey; | ||
| delete extra.taskMessageId; | ||
| delete extra.taskCardId; | ||
| delete extra.status; | ||
| delete extra.delivery; | ||
| delete extra.createdAt; | ||
| delete extra.updatedAt; | ||
| delete extra.sourceTask; | ||
| delete extra.parentTask; | ||
| delete extra.data; | ||
| return { | ||
| ...extra, | ||
| id, | ||
| kind: "task_result", | ||
| version, | ||
| title, | ||
| taskMessageId, | ||
| taskCardId, | ||
| status, | ||
| ...body ? { body } : {}, | ||
| ...idempotencyKey ? { idempotencyKey } : {}, | ||
| ...delivery ? { delivery } : {}, | ||
| ...createdAt ? { createdAt } : {}, | ||
| ...updatedAt ? { updatedAt } : {}, | ||
| ...sourceTask ? { sourceTask } : {}, | ||
| ...parentTask ? { parentTask } : {}, | ||
| ...data ? { data } : {} | ||
| }; | ||
| } | ||
| function parseBuddyInboxTaskResultMetadata(metadata) { | ||
| const record = metadataRecord(metadata); | ||
| const cards = Array.isArray(record?.cards) ? record.cards : []; | ||
| for (const card of cards) { | ||
| const result = parseBuddyInboxTaskResultCard(card); | ||
| if (result) return result; | ||
| } | ||
| const custom = metadataRecord(record?.custom); | ||
| return parseBuddyInboxTaskResultCard(custom?.buddyInboxTaskResult); | ||
| } | ||
| function isMetadataRecord(value) { | ||
| return Boolean(value) && typeof value === "object" && !Array.isArray(value); | ||
| } | ||
| function isCommerceMessageCard(card) { | ||
| if (!isMetadataRecord(card)) return false; | ||
| const kind = card.kind; | ||
| return (kind === "offer" || kind === "product") && typeof card.id === "string" && typeof card.productId === "string" && typeof card.shopId === "string" && isMetadataRecord(card.snapshot) && isMetadataRecord(card.purchase); | ||
| } | ||
| function isPaidFileMessageCard(card) { | ||
| return isMetadataRecord(card) && card.kind === "paid_file" && typeof card.id === "string" && typeof card.fileId === "string" && isMetadataRecord(card.snapshot); | ||
| } | ||
| function isOAuthLinkMessageCard(card) { | ||
| return isMetadataRecord(card) && card.kind === "oauth_link" && typeof card.id === "string" && typeof card.appId === "string" && typeof card.title === "string" && typeof card.url === "string" && isMetadataRecord(card.action); | ||
| } | ||
| function getCommerceMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isCommerceMessageCard) : []; | ||
| } | ||
| function getPaidFileMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isPaidFileMessageCard) : []; | ||
| } | ||
| function getOAuthLinkMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isOAuthLinkMessageCard) : []; | ||
| } | ||
@@ -448,2 +574,5 @@ // src/types/runtime-session.types.ts | ||
| getBuddyPresenceExpiresAt, | ||
| getCommerceMessageCards, | ||
| getOAuthLinkMessageCards, | ||
| getPaidFileMessageCards, | ||
| hasBuddyInboxTaskCard, | ||
@@ -453,5 +582,8 @@ isBuddyHeartbeatActive, | ||
| isBuddyInboxTopic, | ||
| isCommerceMessageCard, | ||
| isMessageAgentChainMetadata, | ||
| isMessageCopilotContext, | ||
| isMessageReferenceCard, | ||
| isOAuthLinkMessageCard, | ||
| isPaidFileMessageCard, | ||
| isTaskMessageCardStatus, | ||
@@ -466,2 +598,3 @@ isTerminalTaskMessageCardStatus, | ||
| parseBuddyInboxAgentId, | ||
| parseBuddyInboxTaskResultMetadata, | ||
| resolvePresenceStatus, | ||
@@ -468,0 +601,0 @@ runtimeSessionPetReactionForState, |
@@ -1,3 +0,3 @@ | ||
| import { l as MessageCardSource, H as TaskMessageRequirements, z as TaskMessageOutputContract, B as TaskMessagePrivacy, r as MessageMetadata, m as MessageCardStatus, v as TaskMessageCard, h as MessageCard, s as MessageReferenceCard } from '../message.types-KkQdHFE5.cjs'; | ||
| export { A as Attachment, C as CommerceMessageCard, a as CommerceOfferCardInput, b as CommerceProductCard, G as GenericMessageCard, M as MESSAGE_AGENT_CHAIN_METADATA_KEY, c as MESSAGE_COPILOT_CONTEXT_METADATA_KEY, d as MentionSuggestion, e as MentionSuggestionTrigger, f as Message, g as MessageAgentChainMetadata, i as MessageCardApp, j as MessageCardCapability, k as MessageCardClaim, n as MessageCopilotContext, o as MessageMention, p as MessageMentionKind, q as MessageMentionRange, N as Notification, t as NotificationType, O as OAuthLinkCard, P as PaidFileCard, R as ReactionGroup, S as SendMessageRequest, u as ServerAppMessageCard, T as TaskContextPack, w as TaskMessageCardReply, x as TaskMessageCardTag, y as TaskMessageExpectedArtifact, D as TaskMessagePrivacyDataClass, E as TaskMessageRequirementSkill, F as TaskMessageRequirementTool, I as TaskMessageSubmitCommand, J as Thread, U as UpdateMessageRequest, K as buildMessageAgentChainMetadata, L as buildMessageCopilotContextMetadata, Q as isMessageAgentChainMetadata, V as isMessageCopilotContext } from '../message.types-KkQdHFE5.cjs'; | ||
| import { m as MessageCardSource, J as TaskMessageRequirements, D as TaskMessageOutputContract, E as TaskMessagePrivacy, s as MessageMetadata, n as MessageCardStatus, w as TaskMessageCard, i as MessageCard, t as MessageReferenceCard } from '../message.types-Cznw92Uq.cjs'; | ||
| export { A as Attachment, B as BuddyInboxTaskRefMetadata, a as BuddyInboxTaskResultMetadata, C as CommerceMessageCard, b as CommerceOfferCardInput, c as CommerceProductCard, G as GenericMessageCard, M as MESSAGE_AGENT_CHAIN_METADATA_KEY, d as MESSAGE_COPILOT_CONTEXT_METADATA_KEY, e as MentionSuggestion, f as MentionSuggestionTrigger, g as Message, h as MessageAgentChainMetadata, j as MessageCardApp, k as MessageCardCapability, l as MessageCardClaim, o as MessageCopilotContext, p as MessageMention, q as MessageMentionKind, r as MessageMentionRange, N as Notification, u as NotificationType, O as OAuthLinkCard, P as PaidFileCard, R as ReactionGroup, S as SendMessageRequest, v as ServerAppMessageCard, T as TaskContextPack, x as TaskMessageCardReply, y as TaskMessageCardTag, z as TaskMessageExpectedArtifact, F as TaskMessagePrivacyDataClass, H as TaskMessageRequirementSkill, I as TaskMessageRequirementTool, K as TaskMessageSubmitCommand, L as TaskResultMessageCard, Q as Thread, U as UpdateMessageRequest, V as buildMessageAgentChainMetadata, W as buildMessageCopilotContextMetadata, X as getCommerceMessageCards, Y as getOAuthLinkMessageCards, Z as getPaidFileMessageCards, _ as isCommerceMessageCard, $ as isMessageAgentChainMetadata, a0 as isMessageCopilotContext, a1 as isOAuthLinkMessageCard, a2 as isPaidFileMessageCard, a3 as parseBuddyInboxTaskResultMetadata } from '../message.types-Cznw92Uq.cjs'; | ||
@@ -4,0 +4,0 @@ type AgentStatus = 'running' | 'stopped' | 'error'; |
@@ -1,3 +0,3 @@ | ||
| import { l as MessageCardSource, H as TaskMessageRequirements, z as TaskMessageOutputContract, B as TaskMessagePrivacy, r as MessageMetadata, m as MessageCardStatus, v as TaskMessageCard, h as MessageCard, s as MessageReferenceCard } from '../message.types-KkQdHFE5.js'; | ||
| export { A as Attachment, C as CommerceMessageCard, a as CommerceOfferCardInput, b as CommerceProductCard, G as GenericMessageCard, M as MESSAGE_AGENT_CHAIN_METADATA_KEY, c as MESSAGE_COPILOT_CONTEXT_METADATA_KEY, d as MentionSuggestion, e as MentionSuggestionTrigger, f as Message, g as MessageAgentChainMetadata, i as MessageCardApp, j as MessageCardCapability, k as MessageCardClaim, n as MessageCopilotContext, o as MessageMention, p as MessageMentionKind, q as MessageMentionRange, N as Notification, t as NotificationType, O as OAuthLinkCard, P as PaidFileCard, R as ReactionGroup, S as SendMessageRequest, u as ServerAppMessageCard, T as TaskContextPack, w as TaskMessageCardReply, x as TaskMessageCardTag, y as TaskMessageExpectedArtifact, D as TaskMessagePrivacyDataClass, E as TaskMessageRequirementSkill, F as TaskMessageRequirementTool, I as TaskMessageSubmitCommand, J as Thread, U as UpdateMessageRequest, K as buildMessageAgentChainMetadata, L as buildMessageCopilotContextMetadata, Q as isMessageAgentChainMetadata, V as isMessageCopilotContext } from '../message.types-KkQdHFE5.js'; | ||
| import { m as MessageCardSource, J as TaskMessageRequirements, D as TaskMessageOutputContract, E as TaskMessagePrivacy, s as MessageMetadata, n as MessageCardStatus, w as TaskMessageCard, i as MessageCard, t as MessageReferenceCard } from '../message.types-Cznw92Uq.js'; | ||
| export { A as Attachment, B as BuddyInboxTaskRefMetadata, a as BuddyInboxTaskResultMetadata, C as CommerceMessageCard, b as CommerceOfferCardInput, c as CommerceProductCard, G as GenericMessageCard, M as MESSAGE_AGENT_CHAIN_METADATA_KEY, d as MESSAGE_COPILOT_CONTEXT_METADATA_KEY, e as MentionSuggestion, f as MentionSuggestionTrigger, g as Message, h as MessageAgentChainMetadata, j as MessageCardApp, k as MessageCardCapability, l as MessageCardClaim, o as MessageCopilotContext, p as MessageMention, q as MessageMentionKind, r as MessageMentionRange, N as Notification, u as NotificationType, O as OAuthLinkCard, P as PaidFileCard, R as ReactionGroup, S as SendMessageRequest, v as ServerAppMessageCard, T as TaskContextPack, x as TaskMessageCardReply, y as TaskMessageCardTag, z as TaskMessageExpectedArtifact, F as TaskMessagePrivacyDataClass, H as TaskMessageRequirementSkill, I as TaskMessageRequirementTool, K as TaskMessageSubmitCommand, L as TaskResultMessageCard, Q as Thread, U as UpdateMessageRequest, V as buildMessageAgentChainMetadata, W as buildMessageCopilotContextMetadata, X as getCommerceMessageCards, Y as getOAuthLinkMessageCards, Z as getPaidFileMessageCards, _ as isCommerceMessageCard, $ as isMessageAgentChainMetadata, a0 as isMessageCopilotContext, a1 as isOAuthLinkMessageCard, a2 as isPaidFileMessageCard, a3 as parseBuddyInboxTaskResultMetadata } from '../message.types-Cznw92Uq.js'; | ||
@@ -4,0 +4,0 @@ type AgentStatus = 'running' | 'stopped' | 'error'; |
+15
-1
@@ -25,2 +25,5 @@ import { | ||
| getBuddyPresenceExpiresAt, | ||
| getCommerceMessageCards, | ||
| getOAuthLinkMessageCards, | ||
| getPaidFileMessageCards, | ||
| hasBuddyInboxTaskCard, | ||
@@ -30,5 +33,8 @@ isBuddyHeartbeatActive, | ||
| isBuddyInboxTopic, | ||
| isCommerceMessageCard, | ||
| isMessageAgentChainMetadata, | ||
| isMessageCopilotContext, | ||
| isMessageReferenceCard, | ||
| isOAuthLinkMessageCard, | ||
| isPaidFileMessageCard, | ||
| isTaskMessageCardStatus, | ||
@@ -43,2 +49,3 @@ isTerminalTaskMessageCardStatus, | ||
| parseBuddyInboxAgentId, | ||
| parseBuddyInboxTaskResultMetadata, | ||
| resolvePresenceStatus, | ||
@@ -48,3 +55,3 @@ runtimeSessionPetReactionForState, | ||
| runtimeSessionStateLooksActive | ||
| } from "../chunk-ATHTS7JM.js"; | ||
| } from "../chunk-7YMBXKQG.js"; | ||
| export { | ||
@@ -74,2 +81,5 @@ BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, | ||
| getBuddyPresenceExpiresAt, | ||
| getCommerceMessageCards, | ||
| getOAuthLinkMessageCards, | ||
| getPaidFileMessageCards, | ||
| hasBuddyInboxTaskCard, | ||
@@ -79,5 +89,8 @@ isBuddyHeartbeatActive, | ||
| isBuddyInboxTopic, | ||
| isCommerceMessageCard, | ||
| isMessageAgentChainMetadata, | ||
| isMessageCopilotContext, | ||
| isMessageReferenceCard, | ||
| isOAuthLinkMessageCard, | ||
| isPaidFileMessageCard, | ||
| isTaskMessageCardStatus, | ||
@@ -92,2 +105,3 @@ isTerminalTaskMessageCardStatus, | ||
| parseBuddyInboxAgentId, | ||
| parseBuddyInboxTaskResultMetadata, | ||
| resolvePresenceStatus, | ||
@@ -94,0 +108,0 @@ runtimeSessionPetReactionForState, |
+68
-2
@@ -26,2 +26,5 @@ "use strict"; | ||
| buildMentionMarkdownLinks: () => buildMentionMarkdownLinks, | ||
| buildServerAppCommunityPath: () => buildServerAppCommunityPath, | ||
| buildServerAppSharePath: () => buildServerAppSharePath, | ||
| buildServerAppShareUrl: () => buildServerAppShareUrl, | ||
| canonicalMentionToken: () => canonicalMentionToken, | ||
@@ -41,6 +44,9 @@ canonicalizeMentionContent: () => canonicalizeMentionContent, | ||
| mentionDisplayText: () => mentionDisplayText, | ||
| normalizeServerAppRoutePath: () => normalizeServerAppRoutePath, | ||
| parseCanonicalMentionToken: () => parseCanonicalMentionToken, | ||
| renderCatSvg: () => renderCatSvg, | ||
| segmentTextByMentions: () => segmentTextByMentions, | ||
| slugify: () => slugify | ||
| serverAppPathFromSearch: () => serverAppPathFromSearch, | ||
| slugify: () => slugify, | ||
| withServerAppRoutePathSearch: () => withServerAppRoutePathSearch | ||
| }); | ||
@@ -608,2 +614,56 @@ module.exports = __toCommonJS(utils_exports); | ||
| // src/utils/server-app-routes.ts | ||
| var SERVER_APP_ROUTE_PATH_MAX = 1024; | ||
| function cleanBasePath(basePath) { | ||
| const trimmed = basePath.trim(); | ||
| if (!trimmed || trimmed === "/") return ""; | ||
| return trimmed.startsWith("/") ? trimmed.replace(/\/+$/u, "") : `/${trimmed.replace(/\/+$/u, "")}`; | ||
| } | ||
| function normalizeServerAppRoutePath(value, fallback = null) { | ||
| if (typeof value !== "string") return fallback; | ||
| const trimmed = value.trim(); | ||
| if (!trimmed || !trimmed.startsWith("/") || trimmed.startsWith("//") || /[\r\n\\]/u.test(trimmed)) { | ||
| return fallback; | ||
| } | ||
| return trimmed.slice(0, SERVER_APP_ROUTE_PATH_MAX); | ||
| } | ||
| function withServerAppRoutePathSearch(search, appPath) { | ||
| const next = { ...search ?? {} }; | ||
| const normalized = normalizeServerAppRoutePath(appPath); | ||
| if (normalized && normalized !== "/") { | ||
| next.appPath = normalized; | ||
| } else { | ||
| delete next.appPath; | ||
| } | ||
| return next; | ||
| } | ||
| function serverAppPathFromSearch(search) { | ||
| return normalizeServerAppRoutePath(search?.appPath); | ||
| } | ||
| function buildServerAppCommunityPath(target, options = {}) { | ||
| const basePath = cleanBasePath(options.basePath ?? "/app"); | ||
| const path = `${basePath}/servers/${encodeURIComponent(target.serverSlug)}/apps/${encodeURIComponent( | ||
| target.appKey | ||
| )}`; | ||
| const params = new URLSearchParams(); | ||
| const appPath = normalizeServerAppRoutePath(target.appPath); | ||
| if (appPath && appPath !== "/") params.set("appPath", appPath); | ||
| const query = params.toString(); | ||
| return query ? `${path}?${query}` : path; | ||
| } | ||
| function buildServerAppSharePath(target, options = {}) { | ||
| const basePath = cleanBasePath(options.basePath ?? "/app"); | ||
| const path = `${basePath}/share/server-app/${encodeURIComponent( | ||
| target.serverSlug | ||
| )}/${encodeURIComponent(target.appKey)}`; | ||
| const params = new URLSearchParams(); | ||
| const appPath = normalizeServerAppRoutePath(target.appPath); | ||
| if (appPath && appPath !== "/") params.set("appPath", appPath); | ||
| const query = params.toString(); | ||
| return query ? `${path}?${query}` : path; | ||
| } | ||
| function buildServerAppShareUrl(target, options = {}) { | ||
| return new URL(buildServerAppSharePath(target, options), target.origin).toString(); | ||
| } | ||
| // src/utils/index.ts | ||
@@ -627,2 +687,5 @@ var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | ||
| buildMentionMarkdownLinks, | ||
| buildServerAppCommunityPath, | ||
| buildServerAppSharePath, | ||
| buildServerAppShareUrl, | ||
| canonicalMentionToken, | ||
@@ -642,6 +705,9 @@ canonicalizeMentionContent, | ||
| mentionDisplayText, | ||
| normalizeServerAppRoutePath, | ||
| parseCanonicalMentionToken, | ||
| renderCatSvg, | ||
| segmentTextByMentions, | ||
| slugify | ||
| serverAppPathFromSearch, | ||
| slugify, | ||
| withServerAppRoutePathSearch | ||
| }); |
@@ -1,2 +0,2 @@ | ||
| import { q as MessageMentionRange, o as MessageMention } from '../message.types-KkQdHFE5.cjs'; | ||
| import { r as MessageMentionRange, p as MessageMention } from '../message.types-Cznw92Uq.cjs'; | ||
@@ -88,2 +88,21 @@ type CatPattern = 'none' | 'tabby' | 'tuxedo' | 'siamese' | 'calico' | 'bicolor'; | ||
| interface ServerAppRouteTarget { | ||
| serverSlug: string; | ||
| appKey: string; | ||
| appPath?: string | null; | ||
| } | ||
| interface ServerAppPathOptions { | ||
| basePath?: string; | ||
| } | ||
| declare function normalizeServerAppRoutePath(value: unknown, fallback?: string | null): string | null; | ||
| declare function withServerAppRoutePathSearch(search: Record<string, unknown> | null | undefined, appPath: unknown): { | ||
| [x: string]: unknown; | ||
| }; | ||
| declare function serverAppPathFromSearch(search: Record<string, unknown> | null | undefined): string | null; | ||
| declare function buildServerAppCommunityPath(target: ServerAppRouteTarget, options?: ServerAppPathOptions): string; | ||
| declare function buildServerAppSharePath(target: ServerAppRouteTarget, options?: ServerAppPathOptions): string; | ||
| declare function buildServerAppShareUrl(target: ServerAppRouteTarget & { | ||
| origin: string; | ||
| }, options?: ServerAppPathOptions): string; | ||
| declare const generateInviteCode: (size?: number) => string; | ||
@@ -94,2 +113,2 @@ declare function formatDate(date: string | Date): string; | ||
| export { type BgPattern, CAT_AVATAR_COUNT, type CatConfig, type CatDecoration, type CatExpression, type CatPattern, type MessageMentionTextSegment, type SlashCommandAction, assignMentionRanges, buildMentionMarkdownLinks, canonicalMentionToken, canonicalizeMentionContent, escapeMarkdownLinkLabel, extractSlashCommandActions, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isValidEmail, mentionDisplayText, parseCanonicalMentionToken, renderCatSvg, segmentTextByMentions, slugify }; | ||
| export { type BgPattern, CAT_AVATAR_COUNT, type CatConfig, type CatDecoration, type CatExpression, type CatPattern, type MessageMentionTextSegment, type ServerAppPathOptions, type ServerAppRouteTarget, type SlashCommandAction, assignMentionRanges, buildMentionMarkdownLinks, buildServerAppCommunityPath, buildServerAppSharePath, buildServerAppShareUrl, canonicalMentionToken, canonicalizeMentionContent, escapeMarkdownLinkLabel, extractSlashCommandActions, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isValidEmail, mentionDisplayText, normalizeServerAppRoutePath, parseCanonicalMentionToken, renderCatSvg, segmentTextByMentions, serverAppPathFromSearch, slugify, withServerAppRoutePathSearch }; |
@@ -1,2 +0,2 @@ | ||
| import { q as MessageMentionRange, o as MessageMention } from '../message.types-KkQdHFE5.js'; | ||
| import { r as MessageMentionRange, p as MessageMention } from '../message.types-Cznw92Uq.js'; | ||
@@ -88,2 +88,21 @@ type CatPattern = 'none' | 'tabby' | 'tuxedo' | 'siamese' | 'calico' | 'bicolor'; | ||
| interface ServerAppRouteTarget { | ||
| serverSlug: string; | ||
| appKey: string; | ||
| appPath?: string | null; | ||
| } | ||
| interface ServerAppPathOptions { | ||
| basePath?: string; | ||
| } | ||
| declare function normalizeServerAppRoutePath(value: unknown, fallback?: string | null): string | null; | ||
| declare function withServerAppRoutePathSearch(search: Record<string, unknown> | null | undefined, appPath: unknown): { | ||
| [x: string]: unknown; | ||
| }; | ||
| declare function serverAppPathFromSearch(search: Record<string, unknown> | null | undefined): string | null; | ||
| declare function buildServerAppCommunityPath(target: ServerAppRouteTarget, options?: ServerAppPathOptions): string; | ||
| declare function buildServerAppSharePath(target: ServerAppRouteTarget, options?: ServerAppPathOptions): string; | ||
| declare function buildServerAppShareUrl(target: ServerAppRouteTarget & { | ||
| origin: string; | ||
| }, options?: ServerAppPathOptions): string; | ||
| declare const generateInviteCode: (size?: number) => string; | ||
@@ -94,2 +113,2 @@ declare function formatDate(date: string | Date): string; | ||
| export { type BgPattern, CAT_AVATAR_COUNT, type CatConfig, type CatDecoration, type CatExpression, type CatPattern, type MessageMentionTextSegment, type SlashCommandAction, assignMentionRanges, buildMentionMarkdownLinks, canonicalMentionToken, canonicalizeMentionContent, escapeMarkdownLinkLabel, extractSlashCommandActions, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isValidEmail, mentionDisplayText, parseCanonicalMentionToken, renderCatSvg, segmentTextByMentions, slugify }; | ||
| export { type BgPattern, CAT_AVATAR_COUNT, type CatConfig, type CatDecoration, type CatExpression, type CatPattern, type MessageMentionTextSegment, type ServerAppPathOptions, type ServerAppRouteTarget, type SlashCommandAction, assignMentionRanges, buildMentionMarkdownLinks, buildServerAppCommunityPath, buildServerAppSharePath, buildServerAppShareUrl, canonicalMentionToken, canonicalizeMentionContent, escapeMarkdownLinkLabel, extractSlashCommandActions, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isValidEmail, mentionDisplayText, normalizeServerAppRoutePath, parseCanonicalMentionToken, renderCatSvg, segmentTextByMentions, serverAppPathFromSearch, slugify, withServerAppRoutePathSearch }; |
+15
-3
@@ -5,2 +5,5 @@ import { | ||
| buildMentionMarkdownLinks, | ||
| buildServerAppCommunityPath, | ||
| buildServerAppSharePath, | ||
| buildServerAppShareUrl, | ||
| canonicalMentionToken, | ||
@@ -20,7 +23,10 @@ canonicalizeMentionContent, | ||
| mentionDisplayText, | ||
| normalizeServerAppRoutePath, | ||
| parseCanonicalMentionToken, | ||
| renderCatSvg, | ||
| segmentTextByMentions, | ||
| slugify | ||
| } from "../chunk-NPKLJYHP.js"; | ||
| serverAppPathFromSearch, | ||
| slugify, | ||
| withServerAppRoutePathSearch | ||
| } from "../chunk-NWPWICSP.js"; | ||
| export { | ||
@@ -30,2 +36,5 @@ CAT_AVATAR_COUNT, | ||
| buildMentionMarkdownLinks, | ||
| buildServerAppCommunityPath, | ||
| buildServerAppSharePath, | ||
| buildServerAppShareUrl, | ||
| canonicalMentionToken, | ||
@@ -45,6 +54,9 @@ canonicalizeMentionContent, | ||
| mentionDisplayText, | ||
| normalizeServerAppRoutePath, | ||
| parseCanonicalMentionToken, | ||
| renderCatSvg, | ||
| segmentTextByMentions, | ||
| slugify | ||
| serverAppPathFromSearch, | ||
| slugify, | ||
| withServerAppRoutePathSearch | ||
| }; |
+1
-1
| { | ||
| "name": "@shadowob/shared", | ||
| "version": "1.1.57", | ||
| "version": "1.1.58", | ||
| "type": "module", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.js", |
| // src/types/inbox.types.ts | ||
| var BUDDY_INBOX_TOPIC_PREFIX = "shadow:buddy-inbox:"; | ||
| var BUDDY_INBOX_DELIVERY_PERMISSION = "buddy_inbox:deliver"; | ||
| var BUDDY_INBOX_PLATFORM_PERMISSIONS = [BUDDY_INBOX_DELIVERY_PERMISSION]; | ||
| function isBuddyInboxPlatformPermission(value) { | ||
| return typeof value === "string" && BUDDY_INBOX_PLATFORM_PERMISSIONS.includes(value); | ||
| } | ||
| function buddyInboxTopic(agentId) { | ||
| return `${BUDDY_INBOX_TOPIC_PREFIX}${agentId}`; | ||
| } | ||
| function parseBuddyInboxAgentId(topic) { | ||
| if (!topic?.startsWith(BUDDY_INBOX_TOPIC_PREFIX)) return null; | ||
| const agentId = topic.slice(BUDDY_INBOX_TOPIC_PREFIX.length).trim(); | ||
| return agentId || null; | ||
| } | ||
| function isBuddyInboxTopic(topic) { | ||
| return parseBuddyInboxAgentId(topic) !== null; | ||
| } | ||
| var TASK_MESSAGE_CARD_STATUSES = [ | ||
| "queued", | ||
| "claimed", | ||
| "running", | ||
| "completed", | ||
| "failed", | ||
| "canceled", | ||
| "transferred" | ||
| ]; | ||
| var TERMINAL_TASK_MESSAGE_CARD_STATUSES = [ | ||
| "completed", | ||
| "failed", | ||
| "canceled", | ||
| "transferred" | ||
| ]; | ||
| var TASK_MESSAGE_CARD_STATUS_TRANSITIONS = { | ||
| queued: ["queued", "claimed", "running", "completed", "failed", "canceled"], | ||
| claimed: ["claimed", "running", "completed", "failed", "canceled"], | ||
| running: ["running", "completed", "failed", "canceled"], | ||
| completed: ["completed"], | ||
| failed: ["failed", "transferred"], | ||
| canceled: ["canceled"], | ||
| transferred: ["transferred"] | ||
| }; | ||
| function isTerminalTaskMessageCardStatus(status) { | ||
| return TERMINAL_TASK_MESSAGE_CARD_STATUSES.includes( | ||
| status | ||
| ); | ||
| } | ||
| function isTaskMessageCardStatus(value) { | ||
| return typeof value === "string" && TASK_MESSAGE_CARD_STATUSES.includes(value); | ||
| } | ||
| function canTransitionTaskMessageCardStatus(from, to) { | ||
| const allowed = TASK_MESSAGE_CARD_STATUS_TRANSITIONS[from]; | ||
| return allowed.includes(to); | ||
| } | ||
| function isRecord(value) { | ||
| return !!value && typeof value === "object" && !Array.isArray(value); | ||
| } | ||
| function isMessageReferenceCard(card) { | ||
| return card?.kind === "message_reference" && typeof card.title === "string" && isRecord(card.target) && typeof card.target.channelId === "string" && typeof card.target.messageId === "string"; | ||
| } | ||
| function getBuddyInboxTaskCards(message) { | ||
| const cards = message.metadata?.cards; | ||
| if (!Array.isArray(cards)) return []; | ||
| return cards.filter( | ||
| (card) => card?.kind === "task" && typeof card.id === "string" && isTaskMessageCardStatus(card.status) | ||
| ); | ||
| } | ||
| function hasBuddyInboxTaskCard(message) { | ||
| return getBuddyInboxTaskCards(message).length > 0; | ||
| } | ||
| function getBuddyInboxTaskStatuses(message) { | ||
| return getBuddyInboxTaskCards(message).map((card) => card.status); | ||
| } | ||
| function buildBuddyInboxViewMessages(messages, options) { | ||
| void options; | ||
| return [...messages]; | ||
| } | ||
| var DEFAULT_BUDDY_INBOX_ADMISSION_POLICY = { | ||
| defaultMode: "allow", | ||
| rules: [] | ||
| }; | ||
| function parseAdmissionMode(value, fallback) { | ||
| if (value === "allow" || value === "deny" || value === "first_time" || value === "every_time") { | ||
| return value; | ||
| } | ||
| if (value === void 0 || value === null) return fallback; | ||
| throw new Error("Invalid Buddy Inbox admission mode"); | ||
| } | ||
| function parseSubjectKind(value) { | ||
| if (value === "user" || value === "agent" || value === "server_app" || value === "system") { | ||
| return value; | ||
| } | ||
| throw new Error("Invalid Buddy Inbox admission subject kind"); | ||
| } | ||
| function parseOptionalString(value, field, maxLength) { | ||
| if (value === void 0 || value === null || value === "") return void 0; | ||
| if (typeof value !== "string" || value.length > maxLength) { | ||
| throw new Error(`Invalid Buddy Inbox admission ${field}`); | ||
| } | ||
| return value; | ||
| } | ||
| function normalizeBuddyInboxAdmissionPolicy(value) { | ||
| if (value === void 0 || value === null) return { ...DEFAULT_BUDDY_INBOX_ADMISSION_POLICY }; | ||
| if (!isRecord(value)) throw new Error("Invalid Buddy Inbox admission policy"); | ||
| const defaultMode = parseAdmissionMode(value.defaultMode, "allow"); | ||
| const rawRules = value.rules; | ||
| if (rawRules !== void 0 && !Array.isArray(rawRules)) { | ||
| throw new Error("Invalid Buddy Inbox admission rules"); | ||
| } | ||
| const rules = (rawRules ?? []).slice(0, 100).map((entry) => { | ||
| if (!isRecord(entry)) throw new Error("Invalid Buddy Inbox admission rule"); | ||
| return { | ||
| subjectKind: parseSubjectKind(entry.subjectKind), | ||
| subjectId: parseOptionalString(entry.subjectId, "subjectId", 160), | ||
| appKey: parseOptionalString(entry.appKey, "appKey", 120), | ||
| mode: parseAdmissionMode(entry.mode, defaultMode), | ||
| ...entry.approved === true ? { approved: true } : {}, | ||
| note: parseOptionalString(entry.note, "note", 500), | ||
| createdAt: parseOptionalString(entry.createdAt, "createdAt", 64), | ||
| updatedAt: parseOptionalString(entry.updatedAt, "updatedAt", 64) | ||
| }; | ||
| }); | ||
| return { defaultMode, rules }; | ||
| } | ||
| function buddyInboxAdmissionRuleKey(rule) { | ||
| return [rule.subjectKind, rule.subjectId ?? "", rule.appKey ?? ""].join(":"); | ||
| } | ||
| function parsePendingTask(value) { | ||
| if (!isRecord(value)) throw new Error("Invalid Buddy Inbox pending task"); | ||
| const title = parseOptionalString(value.title, "task.title", 180); | ||
| if (!title) throw new Error("Invalid Buddy Inbox pending task title"); | ||
| const body = parseOptionalString(value.body, "task.body", 8e3); | ||
| const priority = value.priority; | ||
| if (priority !== void 0 && priority !== "low" && priority !== "normal" && priority !== "medium" && priority !== "high") { | ||
| throw new Error("Invalid Buddy Inbox pending task priority"); | ||
| } | ||
| const idempotencyKey = parseOptionalString(value.idempotencyKey, "task.idempotencyKey", 240); | ||
| const source = isRecord(value.source) ? value.source : void 0; | ||
| const requirements = isRecord(value.requirements) ? value.requirements : void 0; | ||
| const outputContract = isRecord(value.outputContract) ? value.outputContract : void 0; | ||
| const privacy = isRecord(value.privacy) ? value.privacy : void 0; | ||
| const data = isRecord(value.data) ? value.data : void 0; | ||
| return { | ||
| title, | ||
| ...body ? { body } : {}, | ||
| ...priority ? { priority } : {}, | ||
| ...idempotencyKey ? { idempotencyKey } : {}, | ||
| ...source ? { source } : {}, | ||
| ...requirements ? { requirements } : {}, | ||
| ...outputContract ? { outputContract } : {}, | ||
| ...privacy ? { privacy } : {}, | ||
| ...data ? { data } : {} | ||
| }; | ||
| } | ||
| function normalizeBuddyInboxAdmissionPendingDeliveries(value) { | ||
| if (value === void 0 || value === null) return []; | ||
| if (!Array.isArray(value)) throw new Error("Invalid Buddy Inbox pending deliveries"); | ||
| return value.slice(0, 100).map((entry) => { | ||
| if (!isRecord(entry)) throw new Error("Invalid Buddy Inbox pending delivery"); | ||
| const id = parseOptionalString(entry.id, "pending.id", 80); | ||
| const serverId = parseOptionalString(entry.serverId, "pending.serverId", 160); | ||
| const channelId = parseOptionalString(entry.channelId, "pending.channelId", 160); | ||
| const agentId = parseOptionalString(entry.agentId, "pending.agentId", 160); | ||
| const mode = parseAdmissionMode(entry.mode, "first_time"); | ||
| if (mode !== "first_time" && mode !== "every_time") { | ||
| throw new Error("Invalid Buddy Inbox pending mode"); | ||
| } | ||
| if (!isRecord(entry.subject)) throw new Error("Invalid Buddy Inbox pending subject"); | ||
| if (!isRecord(entry.requestedBy)) throw new Error("Invalid Buddy Inbox pending requester"); | ||
| if (!id || !serverId || !channelId || !agentId) { | ||
| throw new Error("Invalid Buddy Inbox pending delivery identifiers"); | ||
| } | ||
| const requestedAt = parseOptionalString(entry.requestedAt, "pending.requestedAt", 64); | ||
| if (!requestedAt) throw new Error("Invalid Buddy Inbox pending requestedAt"); | ||
| return { | ||
| id, | ||
| serverId, | ||
| channelId, | ||
| agentId, | ||
| mode, | ||
| subject: { | ||
| kind: parseSubjectKind(entry.subject.kind), | ||
| id: parseOptionalString(entry.subject.id, "subject.id", 160), | ||
| appKey: parseOptionalString(entry.subject.appKey, "subject.appKey", 120), | ||
| label: parseOptionalString(entry.subject.label, "subject.label", 160) | ||
| }, | ||
| task: parsePendingTask(entry.task), | ||
| requestedBy: entry.requestedBy, | ||
| requestedAt, | ||
| updatedAt: parseOptionalString(entry.updatedAt, "pending.updatedAt", 64) | ||
| }; | ||
| }); | ||
| } | ||
| // src/types/message.types.ts | ||
| var MESSAGE_COPILOT_CONTEXT_METADATA_KEY = "copilotContext"; | ||
| var MESSAGE_AGENT_CHAIN_METADATA_KEY = "agentChain"; | ||
| function isBoundedMetadataString(value, maxLength, required = false) { | ||
| if (typeof value !== "string") return !required && value == null; | ||
| const trimmed = value.trim(); | ||
| return trimmed.length > 0 && trimmed.length <= maxLength; | ||
| } | ||
| function isMessageCopilotContext(value) { | ||
| if (!value || typeof value !== "object") return false; | ||
| const record = value; | ||
| return record.kind === "server_app_copilot" && isBoundedMetadataString(record.appKey, 120, true) && isBoundedMetadataString(record.serverAppId, 160) && isBoundedMetadataString(record.appId, 160) && isBoundedMetadataString(record.appName, 160) && isBoundedMetadataString(record.serverId, 160) && isBoundedMetadataString(record.serverSlug, 160) && isBoundedMetadataString(record.channelId, 160) && isBoundedMetadataString(record.channelKind, 40); | ||
| } | ||
| function buildMessageCopilotContextMetadata(context) { | ||
| return context && isMessageCopilotContext(context) ? { copilotContext: context } : void 0; | ||
| } | ||
| function isMessageAgentChainMetadata(value) { | ||
| if (!value || typeof value !== "object") return false; | ||
| const record = value; | ||
| const startedAt = record.startedAt; | ||
| return isBoundedMetadataString(record.agentId, 160, true) && typeof record.depth === "number" && Number.isInteger(record.depth) && record.depth >= 0 && record.depth <= 100 && Array.isArray(record.participants) && record.participants.length <= 100 && record.participants.every((participant) => isBoundedMetadataString(participant, 160, true)) && (startedAt == null || typeof startedAt === "number" && Number.isInteger(startedAt) && startedAt >= 0 || isBoundedMetadataString(startedAt, 64, true)) && isBoundedMetadataString(record.rootMessageId, 160); | ||
| } | ||
| function buildMessageAgentChainMetadata(agentChain) { | ||
| return agentChain && isMessageAgentChainMetadata(agentChain) ? { agentChain } : void 0; | ||
| } | ||
| // src/types/runtime-session.types.ts | ||
| var RUNTIME_SESSION_PET_REACTION_BY_STATE = { | ||
| idle: "idle", | ||
| running: "working", | ||
| streaming: "thinking", | ||
| tool_call: "working", | ||
| waiting_for_approval: "waiting", | ||
| blocked: "waiting", | ||
| completed: "success", | ||
| failed: "error", | ||
| stopped: "idle", | ||
| unknown: "idle" | ||
| }; | ||
| function runtimeSessionPetReactionForState(state) { | ||
| return RUNTIME_SESSION_PET_REACTION_BY_STATE[state] ?? "idle"; | ||
| } | ||
| function runtimeSessionSignalToPetReaction(signal) { | ||
| switch (signal) { | ||
| case "running": | ||
| return "working"; | ||
| case "streaming": | ||
| return "thinking"; | ||
| case "tool_call": | ||
| return "working"; | ||
| case "waiting_for_approval": | ||
| case "blocked": | ||
| return "waiting"; | ||
| case "completed": | ||
| return "success"; | ||
| case "failed": | ||
| return "error"; | ||
| case "stopped": | ||
| case "unknown": | ||
| return "idle"; | ||
| default: | ||
| return signal; | ||
| } | ||
| } | ||
| function runtimeSessionStateLooksActive(state) { | ||
| return state === "running" || state === "streaming" || state === "tool_call" || state === "waiting_for_approval" || state === "blocked"; | ||
| } | ||
| // src/types/user.types.ts | ||
| var USER_STATUSES = ["online", "idle", "dnd", "offline"]; | ||
| var BUDDY_PRESENCE_STATUSES = ["online", "busy", "idle", "dnd", "offline"]; | ||
| var BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS = 9e4; | ||
| function normalizeUserStatus(status) { | ||
| if (status === "online" || status === "idle" || status === "dnd" || status === "offline") { | ||
| return status; | ||
| } | ||
| return "offline"; | ||
| } | ||
| function normalizeBuddyPresenceStatus(status, options) { | ||
| if (options?.busy) { | ||
| return "busy"; | ||
| } | ||
| if (status === "busy") { | ||
| return "busy"; | ||
| } | ||
| return normalizeUserStatus(status); | ||
| } | ||
| function normalizePresenceStatus(status, options) { | ||
| return normalizeBuddyPresenceStatus(status, options); | ||
| } | ||
| function isBuddyHeartbeatActive(lastHeartbeat, options) { | ||
| if (!lastHeartbeat) return false; | ||
| const heartbeatMs = lastHeartbeat instanceof Date ? lastHeartbeat.getTime() : new Date(lastHeartbeat).getTime(); | ||
| if (!Number.isFinite(heartbeatMs)) return false; | ||
| const nowMs = options?.nowMs ?? Date.now(); | ||
| const thresholdMs = options?.thresholdMs ?? BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS; | ||
| return nowMs - heartbeatMs <= thresholdMs; | ||
| } | ||
| function normalizeBuddyRuntimePresenceStatus({ | ||
| userStatus, | ||
| agentStatus, | ||
| lastHeartbeat, | ||
| busy = false, | ||
| nowMs | ||
| }) { | ||
| if (busy || agentStatus === "busy") return "busy"; | ||
| if (agentStatus === "running") { | ||
| return isBuddyHeartbeatActive(lastHeartbeat, { nowMs }) ? "online" : "offline"; | ||
| } | ||
| const normalizedAgentStatus = normalizeBuddyPresenceStatus(agentStatus); | ||
| if (normalizedAgentStatus !== "offline") return normalizedAgentStatus; | ||
| return normalizeUserStatus(userStatus); | ||
| } | ||
| function resolvePresenceStatus({ | ||
| userStatus, | ||
| isBot, | ||
| agentStatus, | ||
| lastHeartbeat, | ||
| busy = false, | ||
| nowMs | ||
| }) { | ||
| if (busy) return "busy"; | ||
| if (isBot || agentStatus != null || lastHeartbeat != null) { | ||
| return normalizeBuddyRuntimePresenceStatus({ | ||
| userStatus, | ||
| agentStatus, | ||
| lastHeartbeat, | ||
| nowMs | ||
| }); | ||
| } | ||
| return normalizePresenceStatus(userStatus); | ||
| } | ||
| function getBuddyPresenceExpiresAt(lastHeartbeat, options) { | ||
| if (!lastHeartbeat) return null; | ||
| const heartbeatMs = lastHeartbeat instanceof Date ? lastHeartbeat.getTime() : new Date(lastHeartbeat).getTime(); | ||
| if (!Number.isFinite(heartbeatMs)) return null; | ||
| return new Date( | ||
| heartbeatMs + (options?.thresholdMs ?? BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS) | ||
| ).toISOString(); | ||
| } | ||
| function applyPresenceChangeToRuntime(current, update, options) { | ||
| const observedAt = update.observedAt ?? options?.observedAt ?? (/* @__PURE__ */ new Date()).toISOString(); | ||
| const userStatus = normalizeUserStatus(update.status); | ||
| const hasAgentPresence = current.isBot === true || current.agentStatus != null || current.lastHeartbeat != null || update.agentId != null || update.agentStatus !== void 0 || update.lastHeartbeat !== void 0; | ||
| if (!hasAgentPresence) return { userStatus }; | ||
| const agentStatus = update.agentStatus !== void 0 ? update.agentStatus : current.agentStatus ?? (userStatus === "online" ? "running" : null); | ||
| let lastHeartbeat = current.lastHeartbeat ?? null; | ||
| if (update.lastHeartbeat !== void 0) { | ||
| lastHeartbeat = update.lastHeartbeat; | ||
| } else if (userStatus === "online") { | ||
| lastHeartbeat = observedAt; | ||
| } else if (userStatus === "offline") { | ||
| lastHeartbeat = null; | ||
| } | ||
| return { userStatus, agentStatus, lastHeartbeat }; | ||
| } | ||
| export { | ||
| BUDDY_INBOX_TOPIC_PREFIX, | ||
| BUDDY_INBOX_DELIVERY_PERMISSION, | ||
| BUDDY_INBOX_PLATFORM_PERMISSIONS, | ||
| isBuddyInboxPlatformPermission, | ||
| buddyInboxTopic, | ||
| parseBuddyInboxAgentId, | ||
| isBuddyInboxTopic, | ||
| TASK_MESSAGE_CARD_STATUSES, | ||
| TERMINAL_TASK_MESSAGE_CARD_STATUSES, | ||
| TASK_MESSAGE_CARD_STATUS_TRANSITIONS, | ||
| isTerminalTaskMessageCardStatus, | ||
| isTaskMessageCardStatus, | ||
| canTransitionTaskMessageCardStatus, | ||
| isMessageReferenceCard, | ||
| getBuddyInboxTaskCards, | ||
| hasBuddyInboxTaskCard, | ||
| getBuddyInboxTaskStatuses, | ||
| buildBuddyInboxViewMessages, | ||
| DEFAULT_BUDDY_INBOX_ADMISSION_POLICY, | ||
| normalizeBuddyInboxAdmissionPolicy, | ||
| buddyInboxAdmissionRuleKey, | ||
| normalizeBuddyInboxAdmissionPendingDeliveries, | ||
| MESSAGE_COPILOT_CONTEXT_METADATA_KEY, | ||
| MESSAGE_AGENT_CHAIN_METADATA_KEY, | ||
| isMessageCopilotContext, | ||
| buildMessageCopilotContextMetadata, | ||
| isMessageAgentChainMetadata, | ||
| buildMessageAgentChainMetadata, | ||
| RUNTIME_SESSION_PET_REACTION_BY_STATE, | ||
| runtimeSessionPetReactionForState, | ||
| runtimeSessionSignalToPetReaction, | ||
| runtimeSessionStateLooksActive, | ||
| USER_STATUSES, | ||
| BUDDY_PRESENCE_STATUSES, | ||
| BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, | ||
| normalizeUserStatus, | ||
| normalizeBuddyPresenceStatus, | ||
| normalizePresenceStatus, | ||
| isBuddyHeartbeatActive, | ||
| normalizeBuddyRuntimePresenceStatus, | ||
| resolvePresenceStatus, | ||
| getBuddyPresenceExpiresAt, | ||
| applyPresenceChangeToRuntime | ||
| }; |
| // src/constants/events.ts | ||
| var CLIENT_EVENTS = { | ||
| CHANNEL_JOIN: "channel:join", | ||
| CHANNEL_LEAVE: "channel:leave", | ||
| MESSAGE_SEND: "message:send", | ||
| MESSAGE_TYPING: "message:typing", | ||
| PRESENCE_UPDATE: "presence:update", | ||
| VOICE_JOIN: "voice:join", | ||
| VOICE_LEAVE: "voice:leave", | ||
| VOICE_STATE_UPDATE: "voice:state:update", | ||
| VOICE_TOKEN_RENEW: "voice:token:renew", | ||
| VOICE_HEARTBEAT: "voice:heartbeat" | ||
| }; | ||
| var SERVER_EVENTS = { | ||
| MESSAGE_NEW: "message:new", | ||
| MESSAGE_UPDATE: "message:update", | ||
| MESSAGE_DELETE: "message:delete", | ||
| MEMBER_TYPING: "member:typing", | ||
| MEMBER_JOIN: "member:join", | ||
| MEMBER_LEAVE: "member:leave", | ||
| PRESENCE_CHANGE: "presence:change", | ||
| REACTION_ADD: "reaction:add", | ||
| REACTION_REMOVE: "reaction:remove", | ||
| NOTIFICATION_NEW: "notification:new", | ||
| VOICE_STATE: "voice:state", | ||
| VOICE_PARTICIPANT_JOINED: "voice:participant-joined", | ||
| VOICE_PARTICIPANT_LEFT: "voice:participant-left", | ||
| VOICE_PARTICIPANT_UPDATED: "voice:participant-updated", | ||
| VOICE_POLICY_UPDATED: "voice:policy-updated" | ||
| }; | ||
| // src/constants/limits.ts | ||
| var LIMITS = { | ||
| /** Max message content length (16KB — enough for detailed agent responses) */ | ||
| MESSAGE_CONTENT_MAX: 16e3, | ||
| /** Max username length */ | ||
| USERNAME_MAX: 32, | ||
| /** Min username length */ | ||
| USERNAME_MIN: 3, | ||
| /** Max display name length */ | ||
| DISPLAY_NAME_MAX: 64, | ||
| /** Max server name length */ | ||
| SERVER_NAME_MAX: 100, | ||
| /** Max channel name length */ | ||
| CHANNEL_NAME_MAX: 100, | ||
| /** Max thread name length */ | ||
| THREAD_NAME_MAX: 100, | ||
| /** Max file upload size (10MB) */ | ||
| FILE_UPLOAD_MAX_SIZE: 10 * 1024 * 1024, | ||
| /** Messages per page (cursor pagination) */ | ||
| MESSAGES_PER_PAGE: 50, | ||
| /** Max servers per user */ | ||
| SERVERS_PER_USER_MAX: 100, | ||
| /** Max channels per server */ | ||
| CHANNELS_PER_SERVER_MAX: 200, | ||
| /** Invite code length */ | ||
| INVITE_CODE_LENGTH: 8, | ||
| /** Password min length */ | ||
| PASSWORD_MIN: 8, | ||
| /** Max reactions per message per user */ | ||
| REACTIONS_PER_MESSAGE_MAX: 20 | ||
| }; | ||
| export { | ||
| CLIENT_EVENTS, | ||
| SERVER_EVENTS, | ||
| LIMITS | ||
| }; |
| // src/utils/index.ts | ||
| import { customAlphabet } from "nanoid"; | ||
| // src/utils/avatar-generator.ts | ||
| var COLORS = { | ||
| bg: [ | ||
| "transparent", | ||
| "#1e1f22", | ||
| "#313338", | ||
| "#5865F2", | ||
| "#23a559", | ||
| "#da373c", | ||
| "#f472b6", | ||
| "#3b82f6", | ||
| "#fbbf24", | ||
| "#a855f7", | ||
| "#1abc9c", | ||
| "#f39c12", | ||
| "#e74c3c" | ||
| ], | ||
| body: [ | ||
| "#2d2d30", | ||
| "#e8842c", | ||
| "#e8e8e8", | ||
| "#7a7a80", | ||
| "#d4a574", | ||
| "#6b8094", | ||
| "#f472b6", | ||
| "#c8d6e5", | ||
| "#3e2723", | ||
| "#bdc3c7", | ||
| "#ffb8b8" | ||
| ], | ||
| eyes: [ | ||
| "#f8e71c", | ||
| "#00f3ff", | ||
| "#4ade80", | ||
| "#60a5fa", | ||
| "#a855f7", | ||
| "#fbbf24", | ||
| "#f87171", | ||
| "#ffc0cb", | ||
| "#1dd1a1", | ||
| "#e056fd" | ||
| ], | ||
| pattern: ["#1a1a1c", "#ffffff", "#5a4a46", "#3d3d40", "#9a9aa0", "#d1ccc0", "#2d3436"] | ||
| }; | ||
| function getRandomElement(arr) { | ||
| return arr[Math.floor(Math.random() * arr.length)]; | ||
| } | ||
| function generateRandomCatConfig() { | ||
| return { | ||
| bg: getRandomElement(COLORS.bg), | ||
| bgPattern: getRandomElement(["none", "dots", "stripes", "grid", "stars"]), | ||
| body: getRandomElement(COLORS.body), | ||
| pattern: getRandomElement([ | ||
| "none", | ||
| "tabby", | ||
| "tuxedo", | ||
| "siamese", | ||
| "calico", | ||
| "bicolor" | ||
| ]), | ||
| patternColor: getRandomElement(COLORS.pattern), | ||
| eyeColor: getRandomElement(COLORS.eyes), | ||
| expression: getRandomElement([ | ||
| "smile", | ||
| "open", | ||
| "flat", | ||
| "sad", | ||
| "surprised", | ||
| "kawaii", | ||
| "winking", | ||
| "smirk" | ||
| ]), | ||
| decoration: getRandomElement([ | ||
| "none", | ||
| "glasses", | ||
| "blush", | ||
| "scar", | ||
| "flower", | ||
| "fish", | ||
| "headband" | ||
| ]) | ||
| }; | ||
| } | ||
| function renderCatSvg(config) { | ||
| const { bg, bgPattern, body, pattern, patternColor, eyeColor, expression, decoration } = config; | ||
| const stroke = "#1a1a1c"; | ||
| let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">`; | ||
| if (bg && bg !== "transparent") { | ||
| svg += `<rect width="100" height="100" fill="${bg}" rx="20" />`; | ||
| const pColor = `rgba(255,255,255,0.15)`; | ||
| const cleanBg = bg.replace("#", ""); | ||
| if (bgPattern === "dots") { | ||
| svg += `<pattern id="p-${cleanBg}-dots" x="0" y="0" width="10" height="10" patternUnits="userSpaceOnUse"><circle cx="2" cy="2" r="2" fill="${pColor}"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-dots)" rx="20" />`; | ||
| } else if (bgPattern === "stripes") { | ||
| svg += `<pattern id="p-${cleanBg}-str" x="0" y="0" width="12" height="12" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="12" stroke="${pColor}" stroke-width="4"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-str)" rx="20" />`; | ||
| } else if (bgPattern === "grid") { | ||
| svg += `<pattern id="p-${cleanBg}-grid" width="16" height="16" patternUnits="userSpaceOnUse"><path d="M 16 0 L 0 0 0 16" fill="none" stroke="${pColor}" stroke-width="1"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-grid)" rx="20" />`; | ||
| } else if (bgPattern === "stars") { | ||
| svg += `<pattern id="p-${cleanBg}-star" width="20" height="20" patternUnits="userSpaceOnUse"><path d="M10,2 L12,8 L18,8 L13,12 L15,18 L10,14 L5,18 L7,12 L2,8 L8,8 Z" fill="${pColor}" transform="scale(0.5) translate(5,5)"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-star)" rx="20" />`; | ||
| } | ||
| } | ||
| svg += `<ellipse cx="50" cy="85" rx="30" ry="6" fill="rgba(0,0,0,0.2)"/>`; | ||
| svg += `<path d="M22,45 C15,22 28,18 34,22 C38,25 40,38 40,38" fill="${body}" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>`; | ||
| svg += `<path d="M78,45 C85,22 72,18 66,22 C62,25 60,38 60,38" fill="${body}" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>`; | ||
| svg += `<path d="M26,38 C22,26 29,24 33,26 C35,28 36,34 36,34" fill="#ffb8b8" opacity="0.8"/>`; | ||
| svg += `<path d="M74,38 C78,26 71,24 67,26 C65,28 64,34 64,34" fill="#ffb8b8" opacity="0.8"/>`; | ||
| svg += `<ellipse cx="50" cy="58" rx="38" ry="30" fill="${body}" stroke="${stroke}" stroke-width="2.5"/>`; | ||
| if (pattern === "tabby") { | ||
| svg += `<path d="M50,30 L50,40 M42,32 L46,39 M58,32 L54,39" stroke="${patternColor}" stroke-width="3" stroke-linecap="round" opacity="0.7"/>`; | ||
| svg += `<path d="M18,55 L26,57 M20,62 L27,62" stroke="${patternColor}" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/>`; | ||
| svg += `<path d="M82,55 L74,57 M80,62 L73,62" stroke="${patternColor}" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/>`; | ||
| } else if (pattern === "tuxedo") { | ||
| svg += `<path d="M50,56 C30,68 28,88 50,88 C72,88 70,68 50,56" fill="${patternColor}" opacity="0.95"/>`; | ||
| svg += `<ellipse cx="50" cy="65" rx="16" ry="12" fill="${patternColor}" opacity="0.95"/>`; | ||
| } else if (pattern === "siamese") { | ||
| svg += `<ellipse cx="50" cy="62" rx="20" ry="16" fill="${patternColor}" opacity="0.6"/>`; | ||
| } else if (pattern === "calico") { | ||
| svg += `<path d="M25,40 Q35,30 45,45 Q35,55 25,40" fill="${patternColor}" opacity="0.8"/>`; | ||
| svg += `<path d="M75,45 Q65,60 55,50 Q65,35 75,45" fill="#e8842c" opacity="0.8"/>`; | ||
| } else if (pattern === "bicolor") { | ||
| svg += `<path d="M12,58 Q30,30 50,40 Q60,70 50,88 Q12,88 12,58 Z" fill="${patternColor}" opacity="0.8"/>`; | ||
| } | ||
| if (decoration === "blush") { | ||
| svg += `<ellipse cx="28" cy="62" rx="5" ry="3" fill="#ff7675" opacity="0.7"/>`; | ||
| svg += `<ellipse cx="72" cy="62" rx="5" ry="3" fill="#ff7675" opacity="0.7"/>`; | ||
| } | ||
| if (decoration === "scar") { | ||
| svg += `<path d="M28,42 L40,52 M30,48 L35,43 M34,51 L39,46 M32,53 L37,48" stroke="#d63031" stroke-width="1.5" stroke-linecap="round"/>`; | ||
| } | ||
| const drawEye = (cx, cy, lookDir = 0) => { | ||
| if (expression === "kawaii") { | ||
| return `<path d="M${cx - 8},${cy} Q${cx},${cy - 8} ${cx + 8},${cy} Q${cx},${cy - 3} ${cx - 8},${cy}" fill="${eyeColor}" stroke="${stroke}" stroke-width="1.5"/><circle cx="${cx + lookDir}" cy="${cy - 2}" r="3" fill="white"/><circle cx="${cx - 3 + lookDir}" cy="${cy}" r="1" fill="white"/>`; | ||
| } else if (expression === "winking" && cx > 50) { | ||
| return `<path d="M${cx - 7},${cy + 2} Q${cx},${cy - 4} ${cx + 7},${cy + 2}" fill="none" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round"/>`; | ||
| } else if (expression === "surprised") { | ||
| return `<circle cx="${cx}" cy="${cy}" r="8" fill="white" stroke="${stroke}" stroke-width="1.5"/><circle cx="${cx}" cy="${cy}" r="3" fill="${eyeColor}"/>`; | ||
| } else { | ||
| return `<circle cx="${cx}" cy="${cy}" r="7.5" fill="${eyeColor}" stroke="${stroke}" stroke-width="1.5"/><circle cx="${cx - 2 + lookDir}" cy="${cy - 2}" r="2.5" fill="white"/><circle cx="${cx + 2 + lookDir}" cy="${cy + 1}" r="1" fill="white"/>`; | ||
| } | ||
| }; | ||
| if (expression === "smirk") { | ||
| svg += `<path d="M26,50 L42,50" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round"/>`; | ||
| svg += drawEye(66, 52, 2); | ||
| } else { | ||
| svg += drawEye(34, 52, 0); | ||
| svg += drawEye(66, 52, 0); | ||
| } | ||
| if (decoration === "glasses") { | ||
| svg += `<circle cx="34" cy="52" r="11" fill="rgba(255,255,255,0.2)" stroke="#2d3436" stroke-width="2.5"/>`; | ||
| svg += `<circle cx="66" cy="52" r="11" fill="rgba(255,255,255,0.2)" stroke="#2d3436" stroke-width="2.5"/>`; | ||
| svg += `<path d="M45,50 Q50,48 55,50" fill="none" stroke="#2d3436" stroke-width="2.5" stroke-linecap="round"/>`; | ||
| } | ||
| svg += `<path d="M47,62 L53,62 L50,65 Z" fill="#ff9ff3" stroke="${stroke}" stroke-width="1" stroke-linejoin="round"/>`; | ||
| if (expression === "smile" || expression === "kawaii" || expression === "winking") { | ||
| svg += `<path d="M42,67 Q46,72 50,67 M50,67 Q54,72 58,67" fill="none" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`; | ||
| } else if (expression === "open") { | ||
| svg += `<path d="M46,67 Q50,75 54,67 Z" fill="#ff7675" stroke="${stroke}" stroke-width="1.5" stroke-linejoin="round"/>`; | ||
| } else if (expression === "flat") { | ||
| svg += `<path d="M47,68 L53,68" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`; | ||
| } else if (expression === "sad") { | ||
| svg += `<path d="M43,70 Q50,64 57,70" fill="none" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`; | ||
| } else if (expression === "surprised") { | ||
| svg += `<circle cx="50" cy="70" r="3" fill="#1a1a1c"/>`; | ||
| } else if (expression === "smirk") { | ||
| svg += `<path d="M46,67 Q52,69 56,64" fill="none" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`; | ||
| } | ||
| svg += `<path d="M28,62 L15,60 M28,65 L14,66" stroke="${stroke}" stroke-width="1.5" stroke-linecap="round" opacity="0.6"/>`; | ||
| svg += `<path d="M72,62 L85,60 M72,65 L86,66" stroke="${stroke}" stroke-width="1.5" stroke-linecap="round" opacity="0.6"/>`; | ||
| if (decoration === "headband") { | ||
| svg += `<path d="M16,35 Q50,20 84,35" fill="none" stroke="#e17055" stroke-width="6" stroke-linecap="round"/>`; | ||
| svg += `<path d="M50,15 L60,25 L50,28 L40,25 Z" fill="#fab1a0" stroke="#e17055" stroke-width="2"/>`; | ||
| } else if (decoration === "flower") { | ||
| svg += `<path d="M75,30 Q80,20 85,30 Q95,25 85,35 Q90,45 80,40 Q70,45 75,35 Q65,25 75,30 Z" fill="#ffeaa7" stroke="#fdcb6e" stroke-width="1.5"/>`; | ||
| svg += `<circle cx="80" cy="33" r="3" fill="#d63031"/>`; | ||
| } else if (decoration === "fish") { | ||
| svg += `<path d="M40,82 Q50,75 60,82 L65,78 L65,86 L60,82 Q50,89 40,82 Z" fill="#81ecec" stroke="${stroke}" stroke-width="1.5"/>`; | ||
| svg += `<circle cx="45" cy="81" r="1" fill="${stroke}"/>`; | ||
| } | ||
| svg += `</svg>`; | ||
| return `data:image/svg+xml,${encodeURIComponent(svg.replace(/\n\s*/g, ""))}`; | ||
| } | ||
| // src/utils/message-commands.ts | ||
| var COMMAND_TOKEN_RE = /(^|[\s([{"'`])\\?\/([A-Za-z][A-Za-z0-9_-]{0,31})(?:\s+([A-Za-z][A-Za-z0-9_-]{0,31}))?/gu; | ||
| var COMMAND_CUE_RE = /\b(reply|respond|send|type|enter|choose|click|press|run|execute|open)\b|回复|回覆|輸入|输入|发送|傳送|执行|執行|送信|응답|입력|보내|실행/iu; | ||
| var ARG_STOP_WORDS = /* @__PURE__ */ new Set([ | ||
| "a", | ||
| "an", | ||
| "and", | ||
| "at", | ||
| "by", | ||
| "cancel", | ||
| "execute", | ||
| "for", | ||
| "from", | ||
| "in", | ||
| "on", | ||
| "or", | ||
| "that", | ||
| "the", | ||
| "this", | ||
| "to", | ||
| "when", | ||
| "with" | ||
| ]); | ||
| var PATH_ROOTS = /* @__PURE__ */ new Set([ | ||
| "applications", | ||
| "bin", | ||
| "etc", | ||
| "home", | ||
| "library", | ||
| "opt", | ||
| "tmp", | ||
| "usr", | ||
| "var" | ||
| ]); | ||
| function removeFencedCode(content) { | ||
| return content.replace(/```[\s\S]*?```/gu, " "); | ||
| } | ||
| function normalizeArgument(argument) { | ||
| if (!argument) return void 0; | ||
| const value = argument.trim(); | ||
| if (!value) return void 0; | ||
| if (ARG_STOP_WORDS.has(value.toLocaleLowerCase())) return void 0; | ||
| return value; | ||
| } | ||
| function extractSlashCommandActions(content, options = {}) { | ||
| const normalized = removeFencedCode(content); | ||
| const matches = Array.from(normalized.matchAll(COMMAND_TOKEN_RE)); | ||
| if (matches.length === 0) return []; | ||
| if (matches.length < 2 && !COMMAND_CUE_RE.test(normalized)) return []; | ||
| const limit = Math.max(1, options.limit ?? 6); | ||
| const seen = /* @__PURE__ */ new Set(); | ||
| const actions = []; | ||
| for (const match of matches) { | ||
| const name = match[2]; | ||
| if (!name) continue; | ||
| const lowerName = name.toLocaleLowerCase(); | ||
| if (PATH_ROOTS.has(lowerName)) continue; | ||
| const argument = normalizeArgument(match[3]); | ||
| const command = `/${name}${argument ? ` ${argument}` : ""}`; | ||
| const key = command.toLocaleLowerCase(); | ||
| if (seen.has(key)) continue; | ||
| seen.add(key); | ||
| actions.push({ | ||
| id: key, | ||
| command, | ||
| name, | ||
| ...argument ? { argument } : {} | ||
| }); | ||
| if (actions.length >= limit) break; | ||
| } | ||
| return actions; | ||
| } | ||
| // src/utils/message-mentions.ts | ||
| function uniqueValues(values) { | ||
| return Array.from(new Set(values.filter((value) => !!value))); | ||
| } | ||
| function canonicalMentionToken(mention) { | ||
| if (mention.kind === "channel") return `<#${mention.channelId ?? mention.targetId}>`; | ||
| if (mention.kind === "server") return `<@server:${mention.serverId ?? mention.targetId}>`; | ||
| if (mention.kind === "app") return `<@app:${mention.appId ?? mention.targetId}>`; | ||
| if (mention.kind === "here" || mention.kind === "everyone") { | ||
| const scope = mention.serverId ?? mention.targetId; | ||
| return scope ? `<!${mention.kind}:${scope}>` : `<!${mention.kind}>`; | ||
| } | ||
| return `<@${mention.userId ?? mention.targetId}>`; | ||
| } | ||
| function parseCanonicalMentionToken(token) { | ||
| const app = token.match(/^<@app:([^>]+)>$/u); | ||
| if (app?.[1]) return { kind: "app", targetId: app[1] }; | ||
| const user = token.match(/^<@([^>:]+)>$/u); | ||
| if (user?.[1]) return { kind: "user", targetId: user[1] }; | ||
| const server = token.match(/^<@server:([^>]+)>$/u); | ||
| if (server?.[1]) return { kind: "server", targetId: server[1] }; | ||
| const channel = token.match(/^<#([^>]+)>$/u); | ||
| if (channel?.[1]) return { kind: "channel", targetId: channel[1] }; | ||
| const broadcast = token.match(/^<!(here|everyone)(?::([^>]+))?>$/u); | ||
| if (broadcast?.[1] === "here" || broadcast?.[1] === "everyone") { | ||
| return { | ||
| kind: broadcast[1], | ||
| ...broadcast[2] ? { targetId: broadcast[2] } : {} | ||
| }; | ||
| } | ||
| return null; | ||
| } | ||
| function isCanonicalMentionToken(token) { | ||
| return parseCanonicalMentionToken(token) !== null; | ||
| } | ||
| function matchTextsForMention(mention) { | ||
| return uniqueValues([mention.token, mention.sourceToken, canonicalMentionToken(mention)]); | ||
| } | ||
| function isValidRange(content, mention, range) { | ||
| if (!range) return false; | ||
| if (!Number.isInteger(range.start) || !Number.isInteger(range.end)) return false; | ||
| if (range.start < 0 || range.end <= range.start || range.end > content.length) return false; | ||
| const sourceText = content.slice(range.start, range.end); | ||
| return matchTextsForMention(mention).includes(sourceText); | ||
| } | ||
| function overlaps(a, b) { | ||
| return a.start < b.end && b.start < a.end; | ||
| } | ||
| function canUseRange(range, used) { | ||
| return !used.some((candidate) => overlaps(candidate, range)); | ||
| } | ||
| function findOccurrences(content, token, used) { | ||
| const occurrences = []; | ||
| let index = content.indexOf(token); | ||
| while (index >= 0) { | ||
| const range = { start: index, end: index + token.length }; | ||
| if (canUseRange(range, used)) occurrences.push(range); | ||
| index = content.indexOf(token, index + token.length); | ||
| } | ||
| return occurrences; | ||
| } | ||
| function addCandidate(candidates, used, mention, range, order, sourceText) { | ||
| if (!canUseRange(range, used)) return; | ||
| const matchedText = sourceText ?? mention.sourceToken ?? mention.token; | ||
| used.push(range); | ||
| candidates.push({ | ||
| start: range.start, | ||
| end: range.end, | ||
| order, | ||
| sourceText: matchedText, | ||
| mention: { ...mention, range } | ||
| }); | ||
| } | ||
| function segmentTextByMentions(content, mentions) { | ||
| if (!content) return []; | ||
| const usableMentions = (mentions ?? []).filter((mention) => mention.token); | ||
| if (usableMentions.length === 0) return [{ type: "text", text: content }]; | ||
| const candidates = []; | ||
| const usedRanges = []; | ||
| const pendingByText = /* @__PURE__ */ new Map(); | ||
| usableMentions.forEach((mention, order) => { | ||
| if (isValidRange(content, mention, mention.range)) { | ||
| addCandidate( | ||
| candidates, | ||
| usedRanges, | ||
| mention, | ||
| mention.range, | ||
| order, | ||
| content.slice(mention.range.start, mention.range.end) | ||
| ); | ||
| return; | ||
| } | ||
| for (const text of matchTextsForMention(mention)) { | ||
| const pending = pendingByText.get(text) ?? []; | ||
| pending.push({ mention, order }); | ||
| pendingByText.set(text, pending); | ||
| } | ||
| }); | ||
| const pendingGroups = Array.from(pendingByText.entries()).sort((a, b) => { | ||
| const lengthDelta = b[0].length - a[0].length; | ||
| if (lengthDelta !== 0) return lengthDelta; | ||
| return a[1][0].order - b[1][0].order; | ||
| }); | ||
| for (const [token, pending] of pendingGroups) { | ||
| const occurrences = findOccurrences(content, token, usedRanges); | ||
| if (occurrences.length === 0) continue; | ||
| if (pending.length === 1) { | ||
| const { mention, order } = pending[0]; | ||
| for (const range of occurrences) { | ||
| addCandidate(candidates, usedRanges, mention, range, order, token); | ||
| } | ||
| continue; | ||
| } | ||
| pending.forEach(({ mention, order }, index) => { | ||
| const range = occurrences[index]; | ||
| if (range) addCandidate(candidates, usedRanges, mention, range, order, token); | ||
| }); | ||
| } | ||
| candidates.sort((a, b) => a.start - b.start || b.end - a.end || a.order - b.order); | ||
| const segments = []; | ||
| let cursor = 0; | ||
| for (const candidate of candidates) { | ||
| if (candidate.start < cursor) continue; | ||
| if (candidate.start > cursor) { | ||
| segments.push({ type: "text", text: content.slice(cursor, candidate.start) }); | ||
| } | ||
| const text = content.slice(candidate.start, candidate.end); | ||
| segments.push({ | ||
| type: "mention", | ||
| text, | ||
| range: { start: candidate.start, end: candidate.end }, | ||
| mention: { ...candidate.mention, sourceToken: candidate.sourceText } | ||
| }); | ||
| cursor = candidate.end; | ||
| } | ||
| if (cursor < content.length) { | ||
| segments.push({ type: "text", text: content.slice(cursor) }); | ||
| } | ||
| return segments.length > 0 ? segments : [{ type: "text", text: content }]; | ||
| } | ||
| function assignMentionRanges(content, mentions) { | ||
| return segmentTextByMentions(content, mentions).filter((segment) => { | ||
| return segment.type === "mention"; | ||
| }).map((segment) => ({ | ||
| ...segment.mention, | ||
| token: segment.mention.token || segment.text, | ||
| range: segment.range | ||
| })); | ||
| } | ||
| function canonicalizeMentionContent(content, mentions) { | ||
| const canonicalMentions = []; | ||
| let nextContent = ""; | ||
| for (const segment of segmentTextByMentions(content, mentions)) { | ||
| if (segment.type === "text") { | ||
| nextContent += segment.text; | ||
| continue; | ||
| } | ||
| const token = canonicalMentionToken(segment.mention); | ||
| const start = nextContent.length; | ||
| nextContent += token; | ||
| canonicalMentions.push({ | ||
| ...segment.mention, | ||
| token, | ||
| sourceToken: segment.text === token ? segment.mention.sourceToken : segment.text, | ||
| range: { start, end: start + token.length } | ||
| }); | ||
| } | ||
| return { content: nextContent, mentions: canonicalMentions }; | ||
| } | ||
| function mentionDisplayText(mention) { | ||
| return mention.label || mention.token; | ||
| } | ||
| function escapeMarkdownLinkLabel(label) { | ||
| return label.replace(/\\/g, "\\\\").replace(/\[/g, "\\[").replace(/\]/g, "\\]"); | ||
| } | ||
| function buildMentionMarkdownLinks(content, mentions, hrefForMention) { | ||
| const linkedMentions = []; | ||
| const markdown = segmentTextByMentions(content, mentions).map((segment) => { | ||
| if (segment.type === "text") return segment.text; | ||
| const href = hrefForMention(segment.mention, linkedMentions.length); | ||
| if (!href) return segment.text; | ||
| linkedMentions.push(segment.mention); | ||
| return `[${escapeMarkdownLinkLabel(mentionDisplayText(segment.mention))}](${href})`; | ||
| }).join(""); | ||
| return { markdown, mentions: linkedMentions }; | ||
| } | ||
| // src/utils/pixel-cats.ts | ||
| var variants = [ | ||
| // 0: Shadow — Black cat (logo style) | ||
| { | ||
| body: "#2d2d30", | ||
| stroke: "#1a1a1c", | ||
| earInner: "#3d3d40", | ||
| eyeL: "#f8e71c", | ||
| eyeR: "#00f3ff", | ||
| nose: "#3a2a26" | ||
| }, | ||
| // 1: Mikan — Orange tabby | ||
| { | ||
| body: "#e8842c", | ||
| stroke: "#1a1a1c", | ||
| earInner: "#f5a623", | ||
| eyeL: "#4ade80", | ||
| eyeR: "#4ade80", | ||
| nose: "#d46b1a" | ||
| }, | ||
| // 2: Yuki — White cat | ||
| { | ||
| body: "#e8e8e8", | ||
| stroke: "#a0a0a0", | ||
| earInner: "#ffc0cb", | ||
| eyeL: "#60a5fa", | ||
| eyeR: "#60a5fa", | ||
| nose: "#f5a0b0" | ||
| }, | ||
| // 3: Haiiro — Gray cat | ||
| { | ||
| body: "#7a7a80", | ||
| stroke: "#4a4a50", | ||
| earInner: "#9a9aa0", | ||
| eyeL: "#fbbf24", | ||
| eyeR: "#fbbf24", | ||
| nose: "#5a4a46" | ||
| }, | ||
| // 4: Tuxedo — Black & white accents | ||
| { | ||
| body: "#2d2d30", | ||
| stroke: "#1a1a1c", | ||
| earInner: "#e0e0e0", | ||
| eyeL: "#22c55e", | ||
| eyeR: "#22c55e", | ||
| nose: "#3a2a26" | ||
| }, | ||
| // 5: Mocha — Cream/beige | ||
| { | ||
| body: "#d4a574", | ||
| stroke: "#8b6914", | ||
| earInner: "#e8c9a0", | ||
| eyeL: "#d97706", | ||
| eyeR: "#d97706", | ||
| nose: "#a0705a" | ||
| }, | ||
| // 6: Blue — Russian blue | ||
| { | ||
| body: "#6b8094", | ||
| stroke: "#3d5060", | ||
| earInner: "#8ba0b4", | ||
| eyeL: "#22c55e", | ||
| eyeR: "#22c55e", | ||
| nose: "#5a6a76" | ||
| }, | ||
| // 7: Sakura — Fantasy pink | ||
| { | ||
| body: "#f472b6", | ||
| stroke: "#be185d", | ||
| earInner: "#f9a8d4", | ||
| eyeL: "#a855f7", | ||
| eyeR: "#c084fc", | ||
| nose: "#d44a8c" | ||
| } | ||
| ]; | ||
| function makeCatSvg(c) { | ||
| return [ | ||
| '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">', | ||
| `<path d="M22,45 Q15,22 28,22 Q34,22 40,38" fill="${c.body}" stroke="${c.stroke}" stroke-width="2.5" stroke-linecap="round"/>`, | ||
| `<path d="M78,45 Q85,22 72,22 Q66,22 60,38" fill="${c.body}" stroke="${c.stroke}" stroke-width="2.5" stroke-linecap="round"/>`, | ||
| `<path d="M26,38 Q22,26 29,26 Q33,26 36,34" fill="${c.earInner}" opacity="0.5"/>`, | ||
| `<path d="M74,38 Q78,26 71,26 Q67,26 64,34" fill="${c.earInner}" opacity="0.5"/>`, | ||
| `<ellipse cx="50" cy="58" rx="36" ry="28" fill="${c.body}" stroke="${c.stroke}" stroke-width="2.5"/>`, | ||
| `<circle cx="35" cy="52" r="7" fill="${c.eyeL}" stroke="${c.stroke}" stroke-width="1.5"/>`, | ||
| `<circle cx="33" cy="49" r="2.5" fill="white"/>`, | ||
| `<circle cx="65" cy="52" r="7" fill="${c.eyeR}" stroke="${c.stroke}" stroke-width="1.5"/>`, | ||
| `<circle cx="63" cy="49" r="2.5" fill="white"/>`, | ||
| `<ellipse cx="50" cy="62" rx="3.5" ry="2.2" fill="${c.nose}"/>`, | ||
| `<path d="M42,67 Q46,72 50,67" fill="none" stroke="${c.stroke}" stroke-width="2" stroke-linecap="round"/>`, | ||
| `<path d="M50,67 Q54,72 58,67" fill="none" stroke="${c.stroke}" stroke-width="2" stroke-linecap="round"/>`, | ||
| "</svg>" | ||
| ].join(""); | ||
| } | ||
| var catDataUris = variants.map((v) => { | ||
| const svg = makeCatSvg(v); | ||
| return `data:image/svg+xml,${encodeURIComponent(svg)}`; | ||
| }); | ||
| function getCatAvatar(index) { | ||
| return catDataUris[index % catDataUris.length]; | ||
| } | ||
| function getCatAvatarByUserId(userId) { | ||
| let hash = 0; | ||
| for (let i = 0; i < userId.length; i++) { | ||
| hash = (hash << 5) - hash + userId.charCodeAt(i) | 0; | ||
| } | ||
| return getCatAvatar(Math.abs(hash) % catDataUris.length); | ||
| } | ||
| function getAllCatAvatars() { | ||
| const names = ["\u5F71\u5B50", "\u871C\u67D1", "\u5C0F\u96EA", "\u7070\u7070", "\u71D5\u5C3E\u670D", "\u6469\u5361", "\u84DD\u84DD", "\u5C0F\u6A31"]; | ||
| return catDataUris.map((uri, i) => ({ index: i, name: names[i], dataUri: uri })); | ||
| } | ||
| function getCatSvgString(index) { | ||
| return makeCatSvg(variants[index % variants.length]); | ||
| } | ||
| var CAT_AVATAR_COUNT = variants.length; | ||
| // src/utils/index.ts | ||
| var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | ||
| var generateInviteCode = customAlphabet(alphabet, 8); | ||
| function formatDate(date) { | ||
| const d = typeof date === "string" ? new Date(date) : date; | ||
| return d.toISOString(); | ||
| } | ||
| function isValidEmail(email) { | ||
| return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); | ||
| } | ||
| function slugify(text) { | ||
| return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, ""); | ||
| } | ||
| export { | ||
| generateRandomCatConfig, | ||
| renderCatSvg, | ||
| extractSlashCommandActions, | ||
| canonicalMentionToken, | ||
| parseCanonicalMentionToken, | ||
| isCanonicalMentionToken, | ||
| segmentTextByMentions, | ||
| assignMentionRanges, | ||
| canonicalizeMentionContent, | ||
| mentionDisplayText, | ||
| escapeMarkdownLinkLabel, | ||
| buildMentionMarkdownLinks, | ||
| getCatAvatar, | ||
| getCatAvatarByUserId, | ||
| getAllCatAvatars, | ||
| getCatSvgString, | ||
| CAT_AVATAR_COUNT, | ||
| generateInviteCode, | ||
| formatDate, | ||
| isValidEmail, | ||
| slugify | ||
| }; |
| interface Message { | ||
| id: string; | ||
| content: string; | ||
| channelId: string; | ||
| authorId: string; | ||
| threadId: string | null; | ||
| replyToId: string | null; | ||
| isEdited: boolean; | ||
| isPinned: boolean; | ||
| createdAt: string; | ||
| updatedAt: string; | ||
| author?: { | ||
| id: string; | ||
| username: string; | ||
| displayName: string; | ||
| avatarUrl: string | null; | ||
| isBot: boolean; | ||
| }; | ||
| attachments?: Attachment[]; | ||
| reactions?: ReactionGroup[]; | ||
| metadata?: MessageMetadata | null; | ||
| } | ||
| type MessageMentionKind = 'user' | 'buddy' | 'app' | 'channel' | 'server' | 'here' | 'everyone'; | ||
| interface MessageMentionRange { | ||
| start: number; | ||
| end: number; | ||
| } | ||
| interface MessageMention { | ||
| kind: MessageMentionKind; | ||
| /** Canonical target id. For users this is userId, for channels channelId, for servers serverId. */ | ||
| targetId: string; | ||
| /** Canonical text persisted in message content, e.g. <@userId>, <#channelId>. */ | ||
| token: string; | ||
| /** Optional display text selected or typed by the sender before canonicalization. */ | ||
| sourceToken?: string; | ||
| /** Human-readable label used by renderers. */ | ||
| label: string; | ||
| /** Optional source range in content. Clients may omit it; servers may recompute later. */ | ||
| range?: MessageMentionRange; | ||
| serverId?: string; | ||
| serverSlug?: string | null; | ||
| serverName?: string | null; | ||
| channelId?: string; | ||
| channelName?: string | null; | ||
| appId?: string; | ||
| appKey?: string; | ||
| appName?: string | null; | ||
| iconUrl?: string | null; | ||
| userId?: string; | ||
| username?: string | null; | ||
| displayName?: string | null; | ||
| avatarUrl?: string | null; | ||
| isBot?: boolean; | ||
| isPrivate?: boolean; | ||
| } | ||
| declare const MESSAGE_COPILOT_CONTEXT_METADATA_KEY: "copilotContext"; | ||
| declare const MESSAGE_AGENT_CHAIN_METADATA_KEY: "agentChain"; | ||
| interface MessageCopilotContext { | ||
| kind: 'server_app_copilot'; | ||
| /** Server app install id when the current surface is an installed server app. */ | ||
| serverAppId?: string | null; | ||
| /** Catalog app id when available. */ | ||
| appId?: string | null; | ||
| /** Stable app key from the app route, e.g. kanban. */ | ||
| appKey: string; | ||
| appName?: string | null; | ||
| serverId?: string | null; | ||
| serverSlug?: string | null; | ||
| /** Channel or Inbox currently opened in the Copilot panel. */ | ||
| channelId?: string | null; | ||
| channelKind?: string | null; | ||
| } | ||
| declare function isMessageCopilotContext(value: unknown): value is MessageCopilotContext; | ||
| declare function buildMessageCopilotContextMetadata(context: MessageCopilotContext | null | undefined): { | ||
| copilotContext: MessageCopilotContext; | ||
| } | undefined; | ||
| interface MessageAgentChainMetadata { | ||
| /** Logical runtime agent id that produced the current message. */ | ||
| agentId: string; | ||
| /** Number of runtime hops from the original trigger to this message. */ | ||
| depth: number; | ||
| /** Bot/user ids that have participated in the chain so far. */ | ||
| participants: string[]; | ||
| /** Runtime start timestamp, usually Date.now(), or an ISO timestamp. */ | ||
| startedAt?: number | string; | ||
| /** Message id that started the chain. */ | ||
| rootMessageId?: string; | ||
| } | ||
| declare function isMessageAgentChainMetadata(value: unknown): value is MessageAgentChainMetadata; | ||
| declare function buildMessageAgentChainMetadata(agentChain: MessageAgentChainMetadata | null | undefined): { | ||
| agentChain: MessageAgentChainMetadata; | ||
| } | undefined; | ||
| interface MessageMetadata { | ||
| /** Runtime trace metadata for agent-to-agent or task-triggered messages. */ | ||
| agentChain?: MessageAgentChainMetadata; | ||
| mentions?: MessageMention[]; | ||
| copilotContext?: MessageCopilotContext; | ||
| collaboration?: { | ||
| id: string; | ||
| rootMessageId: string; | ||
| buddyId: string; | ||
| turn: number; | ||
| target?: 'main' | 'thread'; | ||
| threadId?: string; | ||
| suggestedTextLimit?: number; | ||
| replyDensity?: 'reaction' | 'short' | 'normal' | 'long'; | ||
| }; | ||
| interactive?: Record<string, unknown>; | ||
| interactiveResponse?: Record<string, unknown>; | ||
| interactiveState?: Record<string, unknown>; | ||
| ccConnectDelivery?: Record<string, unknown>; | ||
| shadowDelivery?: Record<string, unknown>; | ||
| /** Unified card protocol. New card-like message surfaces must use this field. */ | ||
| cards?: MessageCard[]; | ||
| /** | ||
| * @deprecated Compatibility-only commerce card array. | ||
| * New card-like protocols must use `cards`; do not use this field for new product decisions. | ||
| */ | ||
| commerceCards?: CommerceMessageCard[]; | ||
| /** | ||
| * @deprecated Compatibility-only paid-file delivery card array. | ||
| * New card-like protocols must use `cards`; do not use this field for new product decisions. | ||
| */ | ||
| paidFileCards?: PaidFileCard[]; | ||
| /** | ||
| * @deprecated Compatibility-only OAuth link card array. | ||
| * New card-like protocols must use `cards`; do not use this field for new product decisions. | ||
| */ | ||
| oauthLinkCards?: OAuthLinkCard[]; | ||
| [key: string]: unknown; | ||
| } | ||
| type MessageCardStatus = 'queued' | 'claimed' | 'running' | 'completed' | 'failed' | 'canceled' | 'transferred'; | ||
| interface MessageCardSource { | ||
| kind: 'user' | 'pat' | 'oauth' | 'agent' | 'system' | 'server_app' | 'buddy'; | ||
| id?: string; | ||
| label?: string; | ||
| userId?: string; | ||
| agentId?: string; | ||
| appId?: string; | ||
| appKey?: string; | ||
| appName?: string | null; | ||
| iconUrl?: string | null; | ||
| serverId?: string; | ||
| channelId?: string; | ||
| command?: string; | ||
| resource?: { | ||
| kind: string; | ||
| id: string; | ||
| label?: string; | ||
| url?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| [key: string]: unknown; | ||
| } | ||
| type TaskMessageCardTag = string | { | ||
| id?: string; | ||
| label: string; | ||
| color?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| interface MessageCardApp { | ||
| id?: string; | ||
| appId?: string; | ||
| appKey?: string; | ||
| name?: string | null; | ||
| label?: string | null; | ||
| iconUrl?: string | null; | ||
| logoUrl?: string | null; | ||
| avatarUrl?: string | null; | ||
| imageUrl?: string | null; | ||
| url?: string | null; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageCardReply { | ||
| id?: string; | ||
| messageId?: string; | ||
| cardId?: string; | ||
| authorId?: string; | ||
| authorLabel?: string; | ||
| authorAvatarUrl?: string | null; | ||
| content: string; | ||
| createdAt: string; | ||
| source?: MessageCardSource; | ||
| [key: string]: unknown; | ||
| } | ||
| interface MessageCardClaim { | ||
| id: string; | ||
| actor: MessageCardSource; | ||
| claimedAt: string; | ||
| expiresAt: string; | ||
| } | ||
| interface MessageCardCapability { | ||
| kind: 'task'; | ||
| scope: string[]; | ||
| issuedAt: string; | ||
| expiresAt: string; | ||
| claimId?: string; | ||
| binding?: { | ||
| messageId?: string; | ||
| cardId: string; | ||
| workspaceId?: string; | ||
| }; | ||
| } | ||
| interface TaskMessageRequirementSkill { | ||
| kind: 'runtime-skill'; | ||
| package: string; | ||
| version?: string; | ||
| required?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageRequirementTool { | ||
| kind: string; | ||
| name: string; | ||
| required?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageRequirements { | ||
| capabilities?: string[]; | ||
| skills?: TaskMessageRequirementSkill[]; | ||
| tools?: TaskMessageRequirementTool[]; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageExpectedArtifact { | ||
| kind: string; | ||
| mimeTypes?: string[]; | ||
| maxBytes?: number; | ||
| required?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageSubmitCommand { | ||
| appKey: string; | ||
| command: string; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageOutputContract { | ||
| expectedArtifacts?: TaskMessageExpectedArtifact[]; | ||
| submitCommand?: TaskMessageSubmitCommand; | ||
| [key: string]: unknown; | ||
| } | ||
| type TaskMessagePrivacyDataClass = 'public' | 'server-private' | 'channel-private' | 'financial' | 'secret' | 'cloud-secret'; | ||
| interface TaskMessagePrivacy { | ||
| dataClass: TaskMessagePrivacyDataClass; | ||
| redactionRequired?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskContextPack { | ||
| snapshotAtMessageId: string | null; | ||
| sourceSurface: 'channel' | 'thread' | 'task-thread' | 'app'; | ||
| policy: 'auto_recent' | 'explicit_refs' | 'thread_context' | 'manual'; | ||
| summary: string | null; | ||
| items: Array<{ | ||
| kind: 'message'; | ||
| messageId: string; | ||
| threadId?: string | null; | ||
| authorId: string; | ||
| createdAt: string; | ||
| text: string; | ||
| } | { | ||
| kind: 'resource'; | ||
| resourceType: string; | ||
| resourceId: string; | ||
| title?: string; | ||
| summary?: string; | ||
| } | { | ||
| kind: 'task_result'; | ||
| messageId: string; | ||
| cardId: string; | ||
| title: string; | ||
| summary: string; | ||
| }>; | ||
| omitted: Array<{ | ||
| messageCount: number; | ||
| reason: 'token_budget' | 'permission' | 'privacy' | 'not_relevant'; | ||
| }>; | ||
| tokenEstimate: number; | ||
| } | ||
| interface TaskMessageCard { | ||
| id: string; | ||
| kind: 'task'; | ||
| version: number; | ||
| title: string; | ||
| body?: string; | ||
| status: MessageCardStatus; | ||
| priority?: 'low' | 'normal' | 'medium' | 'high'; | ||
| tags?: TaskMessageCardTag[]; | ||
| app?: MessageCardApp; | ||
| assignee?: { | ||
| agentId?: string; | ||
| userId?: string; | ||
| label?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| source?: MessageCardSource; | ||
| requirements?: TaskMessageRequirements; | ||
| outputContract?: TaskMessageOutputContract; | ||
| privacy?: TaskMessagePrivacy; | ||
| claim?: MessageCardClaim; | ||
| capability?: MessageCardCapability; | ||
| progress?: Array<{ | ||
| at: string; | ||
| status: MessageCardStatus; | ||
| note?: string; | ||
| actor?: MessageCardSource; | ||
| [key: string]: unknown; | ||
| }>; | ||
| replies?: TaskMessageCardReply[]; | ||
| createdAt: string; | ||
| updatedAt?: string; | ||
| data?: Record<string, unknown> & { | ||
| task?: { | ||
| workspaceId?: string; | ||
| threadId?: string; | ||
| revision?: number; | ||
| contextPack?: TaskContextPack; | ||
| [key: string]: unknown; | ||
| }; | ||
| }; | ||
| [key: string]: unknown; | ||
| } | ||
| type GenericMessageCard = { | ||
| id?: string; | ||
| kind: string; | ||
| version?: number; | ||
| title?: string; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| }; | ||
| interface ServerAppMessageCard { | ||
| id?: string; | ||
| kind: 'server_app'; | ||
| version?: number; | ||
| appKey: string; | ||
| title: string; | ||
| description?: string; | ||
| label?: string; | ||
| action?: { | ||
| mode: 'open_app'; | ||
| path?: string; | ||
| }; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| } | ||
| interface MessageReferenceCard { | ||
| id?: string; | ||
| kind: 'message_reference'; | ||
| version?: number; | ||
| title: string; | ||
| description?: string; | ||
| label?: string; | ||
| target: { | ||
| serverId?: string | null; | ||
| serverSlug?: string | null; | ||
| channelId: string; | ||
| messageId: string; | ||
| taskCardId?: string | null; | ||
| inboxAgentId?: string | null; | ||
| kind?: 'channel_message' | 'inbox_message'; | ||
| }; | ||
| source?: MessageCardSource; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| } | ||
| type MessageCard = TaskMessageCard | ServerAppMessageCard | MessageReferenceCard | GenericMessageCard; | ||
| interface CommerceOfferCardInput { | ||
| id?: string; | ||
| kind: 'offer'; | ||
| offerId: string; | ||
| } | ||
| type CommerceMessageCard = CommerceProductCard | CommerceOfferCardInput; | ||
| interface CommerceProductCard { | ||
| id: string; | ||
| kind: 'offer' | 'product'; | ||
| offerId?: string; | ||
| shopId: string; | ||
| shopScope: { | ||
| kind: 'server' | 'user'; | ||
| id: string; | ||
| }; | ||
| productId: string; | ||
| skuId?: string; | ||
| snapshot: { | ||
| name: string; | ||
| summary?: string | null; | ||
| imageUrl?: string | null; | ||
| shopName?: string | null; | ||
| deliveryPromise?: string | null; | ||
| price: number; | ||
| currency: string; | ||
| productType: 'physical' | 'entitlement'; | ||
| billingMode?: 'one_time' | 'fixed_duration' | 'subscription'; | ||
| durationSeconds?: number | null; | ||
| resourceType?: string; | ||
| resourceId?: string; | ||
| capability?: string; | ||
| }; | ||
| purchase: { | ||
| mode: 'direct' | 'select_sku' | 'open_detail'; | ||
| }; | ||
| } | ||
| interface PaidFileCard { | ||
| id: string; | ||
| kind: 'paid_file'; | ||
| fileId: string; | ||
| entitlementId?: string | null; | ||
| deliverableId?: string; | ||
| snapshot: { | ||
| name: string; | ||
| summary?: string | null; | ||
| mime?: string | null; | ||
| sizeBytes?: number | null; | ||
| previewUrl?: string | null; | ||
| }; | ||
| action: { | ||
| mode: 'open_paid_file'; | ||
| }; | ||
| } | ||
| interface OAuthLinkCard { | ||
| id: string; | ||
| kind: 'oauth_link'; | ||
| appId: string; | ||
| clientId?: string | null; | ||
| title: string; | ||
| description?: string | null; | ||
| iconUrl?: string | null; | ||
| meta?: { | ||
| appName?: string | null; | ||
| avatarUrl?: string | null; | ||
| iconUrl?: string | null; | ||
| coverUrl?: string | null; | ||
| homepageUrl?: string | null; | ||
| origin?: string | null; | ||
| }; | ||
| url: string; | ||
| embedUrl?: string | null; | ||
| fallbackUrl?: string | null; | ||
| scopes?: string[]; | ||
| action: { | ||
| mode: 'open_iframe' | 'open_external'; | ||
| }; | ||
| } | ||
| type MentionSuggestionTrigger = '@' | '#'; | ||
| interface MentionSuggestion { | ||
| id: string; | ||
| kind: MessageMentionKind; | ||
| targetId: string; | ||
| token: string; | ||
| label: string; | ||
| description?: string | null; | ||
| serverId?: string; | ||
| serverSlug?: string | null; | ||
| serverName?: string | null; | ||
| channelId?: string; | ||
| channelName?: string | null; | ||
| appId?: string; | ||
| appKey?: string; | ||
| appName?: string | null; | ||
| iconUrl?: string | null; | ||
| userId?: string; | ||
| username?: string | null; | ||
| displayName?: string | null; | ||
| avatarUrl?: string | null; | ||
| isBot?: boolean; | ||
| isPrivate?: boolean; | ||
| } | ||
| interface Attachment { | ||
| id: string; | ||
| messageId: string; | ||
| filename: string; | ||
| url: string; | ||
| contentType: string; | ||
| size: number; | ||
| width: number | null; | ||
| height: number | null; | ||
| workspaceNodeId?: string | null; | ||
| kind?: 'file' | 'image' | 'voice'; | ||
| durationMs?: number | null; | ||
| audioCodec?: string | null; | ||
| audioContainer?: string | null; | ||
| waveformPeaks?: number[] | null; | ||
| waveformVersion?: number | null; | ||
| transcript?: { | ||
| id: string; | ||
| status: 'pending' | 'processing' | 'ready' | 'failed'; | ||
| text: string | null; | ||
| language: string | null; | ||
| source: 'client' | 'server' | 'runtime'; | ||
| provider?: string | null; | ||
| confidence?: number | null; | ||
| errorCode?: string | null; | ||
| updatedAt?: string; | ||
| } | null; | ||
| playback?: { | ||
| played: boolean; | ||
| completed: boolean; | ||
| lastPositionMs: number; | ||
| playedCount?: number; | ||
| } | null; | ||
| createdAt: string; | ||
| } | ||
| interface ReactionGroup { | ||
| emoji: string; | ||
| count: number; | ||
| userIds: string[]; | ||
| } | ||
| interface Thread { | ||
| id: string; | ||
| name: string; | ||
| channelId: string; | ||
| parentMessageId: string; | ||
| creatorId: string; | ||
| isArchived: boolean; | ||
| createdAt: string; | ||
| updatedAt: string; | ||
| } | ||
| interface SendMessageRequest { | ||
| content: string; | ||
| threadId?: string; | ||
| replyToId?: string; | ||
| mentions?: MessageMention[]; | ||
| metadata?: MessageMetadata; | ||
| } | ||
| interface UpdateMessageRequest { | ||
| content: string; | ||
| } | ||
| type NotificationType = 'mention' | 'reply' | 'dm' | 'system'; | ||
| interface Notification { | ||
| id: string; | ||
| userId: string; | ||
| type: NotificationType; | ||
| title: string; | ||
| body: string | null; | ||
| referenceId: string | null; | ||
| referenceType: string | null; | ||
| isRead: boolean; | ||
| createdAt: string; | ||
| } | ||
| export { type Attachment as A, type TaskMessagePrivacy as B, type CommerceMessageCard as C, type TaskMessagePrivacyDataClass as D, type TaskMessageRequirementSkill as E, type TaskMessageRequirementTool as F, type GenericMessageCard as G, type TaskMessageRequirements as H, type TaskMessageSubmitCommand as I, type Thread as J, buildMessageAgentChainMetadata as K, buildMessageCopilotContextMetadata as L, MESSAGE_AGENT_CHAIN_METADATA_KEY as M, type Notification as N, type OAuthLinkCard as O, type PaidFileCard as P, isMessageAgentChainMetadata as Q, type ReactionGroup as R, type SendMessageRequest as S, type TaskContextPack as T, type UpdateMessageRequest as U, isMessageCopilotContext as V, type CommerceOfferCardInput as a, type CommerceProductCard as b, MESSAGE_COPILOT_CONTEXT_METADATA_KEY as c, type MentionSuggestion as d, type MentionSuggestionTrigger as e, type Message as f, type MessageAgentChainMetadata as g, type MessageCard as h, type MessageCardApp as i, type MessageCardCapability as j, type MessageCardClaim as k, type MessageCardSource as l, type MessageCardStatus as m, type MessageCopilotContext as n, type MessageMention as o, type MessageMentionKind as p, type MessageMentionRange as q, type MessageMetadata as r, type MessageReferenceCard as s, type NotificationType as t, type ServerAppMessageCard as u, type TaskMessageCard as v, type TaskMessageCardReply as w, type TaskMessageCardTag as x, type TaskMessageExpectedArtifact as y, type TaskMessageOutputContract as z }; |
| interface Message { | ||
| id: string; | ||
| content: string; | ||
| channelId: string; | ||
| authorId: string; | ||
| threadId: string | null; | ||
| replyToId: string | null; | ||
| isEdited: boolean; | ||
| isPinned: boolean; | ||
| createdAt: string; | ||
| updatedAt: string; | ||
| author?: { | ||
| id: string; | ||
| username: string; | ||
| displayName: string; | ||
| avatarUrl: string | null; | ||
| isBot: boolean; | ||
| }; | ||
| attachments?: Attachment[]; | ||
| reactions?: ReactionGroup[]; | ||
| metadata?: MessageMetadata | null; | ||
| } | ||
| type MessageMentionKind = 'user' | 'buddy' | 'app' | 'channel' | 'server' | 'here' | 'everyone'; | ||
| interface MessageMentionRange { | ||
| start: number; | ||
| end: number; | ||
| } | ||
| interface MessageMention { | ||
| kind: MessageMentionKind; | ||
| /** Canonical target id. For users this is userId, for channels channelId, for servers serverId. */ | ||
| targetId: string; | ||
| /** Canonical text persisted in message content, e.g. <@userId>, <#channelId>. */ | ||
| token: string; | ||
| /** Optional display text selected or typed by the sender before canonicalization. */ | ||
| sourceToken?: string; | ||
| /** Human-readable label used by renderers. */ | ||
| label: string; | ||
| /** Optional source range in content. Clients may omit it; servers may recompute later. */ | ||
| range?: MessageMentionRange; | ||
| serverId?: string; | ||
| serverSlug?: string | null; | ||
| serverName?: string | null; | ||
| channelId?: string; | ||
| channelName?: string | null; | ||
| appId?: string; | ||
| appKey?: string; | ||
| appName?: string | null; | ||
| iconUrl?: string | null; | ||
| userId?: string; | ||
| username?: string | null; | ||
| displayName?: string | null; | ||
| avatarUrl?: string | null; | ||
| isBot?: boolean; | ||
| isPrivate?: boolean; | ||
| } | ||
| declare const MESSAGE_COPILOT_CONTEXT_METADATA_KEY: "copilotContext"; | ||
| declare const MESSAGE_AGENT_CHAIN_METADATA_KEY: "agentChain"; | ||
| interface MessageCopilotContext { | ||
| kind: 'server_app_copilot'; | ||
| /** Server app install id when the current surface is an installed server app. */ | ||
| serverAppId?: string | null; | ||
| /** Catalog app id when available. */ | ||
| appId?: string | null; | ||
| /** Stable app key from the app route, e.g. kanban. */ | ||
| appKey: string; | ||
| appName?: string | null; | ||
| serverId?: string | null; | ||
| serverSlug?: string | null; | ||
| /** Channel or Inbox currently opened in the Copilot panel. */ | ||
| channelId?: string | null; | ||
| channelKind?: string | null; | ||
| } | ||
| declare function isMessageCopilotContext(value: unknown): value is MessageCopilotContext; | ||
| declare function buildMessageCopilotContextMetadata(context: MessageCopilotContext | null | undefined): { | ||
| copilotContext: MessageCopilotContext; | ||
| } | undefined; | ||
| interface MessageAgentChainMetadata { | ||
| /** Logical runtime agent id that produced the current message. */ | ||
| agentId: string; | ||
| /** Number of runtime hops from the original trigger to this message. */ | ||
| depth: number; | ||
| /** Bot/user ids that have participated in the chain so far. */ | ||
| participants: string[]; | ||
| /** Runtime start timestamp, usually Date.now(), or an ISO timestamp. */ | ||
| startedAt?: number | string; | ||
| /** Message id that started the chain. */ | ||
| rootMessageId?: string; | ||
| } | ||
| declare function isMessageAgentChainMetadata(value: unknown): value is MessageAgentChainMetadata; | ||
| declare function buildMessageAgentChainMetadata(agentChain: MessageAgentChainMetadata | null | undefined): { | ||
| agentChain: MessageAgentChainMetadata; | ||
| } | undefined; | ||
| interface MessageMetadata { | ||
| /** Runtime trace metadata for agent-to-agent or task-triggered messages. */ | ||
| agentChain?: MessageAgentChainMetadata; | ||
| mentions?: MessageMention[]; | ||
| copilotContext?: MessageCopilotContext; | ||
| collaboration?: { | ||
| id: string; | ||
| rootMessageId: string; | ||
| buddyId: string; | ||
| turn: number; | ||
| target?: 'main' | 'thread'; | ||
| threadId?: string; | ||
| suggestedTextLimit?: number; | ||
| replyDensity?: 'reaction' | 'short' | 'normal' | 'long'; | ||
| }; | ||
| interactive?: Record<string, unknown>; | ||
| interactiveResponse?: Record<string, unknown>; | ||
| interactiveState?: Record<string, unknown>; | ||
| ccConnectDelivery?: Record<string, unknown>; | ||
| shadowDelivery?: Record<string, unknown>; | ||
| /** Unified card protocol. New card-like message surfaces must use this field. */ | ||
| cards?: MessageCard[]; | ||
| /** | ||
| * @deprecated Compatibility-only commerce card array. | ||
| * New card-like protocols must use `cards`; do not use this field for new product decisions. | ||
| */ | ||
| commerceCards?: CommerceMessageCard[]; | ||
| /** | ||
| * @deprecated Compatibility-only paid-file delivery card array. | ||
| * New card-like protocols must use `cards`; do not use this field for new product decisions. | ||
| */ | ||
| paidFileCards?: PaidFileCard[]; | ||
| /** | ||
| * @deprecated Compatibility-only OAuth link card array. | ||
| * New card-like protocols must use `cards`; do not use this field for new product decisions. | ||
| */ | ||
| oauthLinkCards?: OAuthLinkCard[]; | ||
| [key: string]: unknown; | ||
| } | ||
| type MessageCardStatus = 'queued' | 'claimed' | 'running' | 'completed' | 'failed' | 'canceled' | 'transferred'; | ||
| interface MessageCardSource { | ||
| kind: 'user' | 'pat' | 'oauth' | 'agent' | 'system' | 'server_app' | 'buddy'; | ||
| id?: string; | ||
| label?: string; | ||
| userId?: string; | ||
| agentId?: string; | ||
| appId?: string; | ||
| appKey?: string; | ||
| appName?: string | null; | ||
| iconUrl?: string | null; | ||
| serverId?: string; | ||
| channelId?: string; | ||
| command?: string; | ||
| resource?: { | ||
| kind: string; | ||
| id: string; | ||
| label?: string; | ||
| url?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| [key: string]: unknown; | ||
| } | ||
| type TaskMessageCardTag = string | { | ||
| id?: string; | ||
| label: string; | ||
| color?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| interface MessageCardApp { | ||
| id?: string; | ||
| appId?: string; | ||
| appKey?: string; | ||
| name?: string | null; | ||
| label?: string | null; | ||
| iconUrl?: string | null; | ||
| logoUrl?: string | null; | ||
| avatarUrl?: string | null; | ||
| imageUrl?: string | null; | ||
| url?: string | null; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageCardReply { | ||
| id?: string; | ||
| messageId?: string; | ||
| cardId?: string; | ||
| authorId?: string; | ||
| authorLabel?: string; | ||
| authorAvatarUrl?: string | null; | ||
| content: string; | ||
| createdAt: string; | ||
| source?: MessageCardSource; | ||
| [key: string]: unknown; | ||
| } | ||
| interface MessageCardClaim { | ||
| id: string; | ||
| actor: MessageCardSource; | ||
| claimedAt: string; | ||
| expiresAt: string; | ||
| } | ||
| interface MessageCardCapability { | ||
| kind: 'task'; | ||
| scope: string[]; | ||
| issuedAt: string; | ||
| expiresAt: string; | ||
| claimId?: string; | ||
| binding?: { | ||
| messageId?: string; | ||
| cardId: string; | ||
| workspaceId?: string; | ||
| }; | ||
| } | ||
| interface TaskMessageRequirementSkill { | ||
| kind: 'runtime-skill'; | ||
| package: string; | ||
| version?: string; | ||
| required?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageRequirementTool { | ||
| kind: string; | ||
| name: string; | ||
| required?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageRequirements { | ||
| capabilities?: string[]; | ||
| skills?: TaskMessageRequirementSkill[]; | ||
| tools?: TaskMessageRequirementTool[]; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageExpectedArtifact { | ||
| kind: string; | ||
| mimeTypes?: string[]; | ||
| maxBytes?: number; | ||
| required?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageSubmitCommand { | ||
| appKey: string; | ||
| command: string; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskMessageOutputContract { | ||
| expectedArtifacts?: TaskMessageExpectedArtifact[]; | ||
| submitCommand?: TaskMessageSubmitCommand; | ||
| [key: string]: unknown; | ||
| } | ||
| type TaskMessagePrivacyDataClass = 'public' | 'server-private' | 'channel-private' | 'financial' | 'secret' | 'cloud-secret'; | ||
| interface TaskMessagePrivacy { | ||
| dataClass: TaskMessagePrivacyDataClass; | ||
| redactionRequired?: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| interface TaskContextPack { | ||
| snapshotAtMessageId: string | null; | ||
| sourceSurface: 'channel' | 'thread' | 'task-thread' | 'app'; | ||
| policy: 'auto_recent' | 'explicit_refs' | 'thread_context' | 'manual'; | ||
| summary: string | null; | ||
| items: Array<{ | ||
| kind: 'message'; | ||
| messageId: string; | ||
| threadId?: string | null; | ||
| authorId: string; | ||
| createdAt: string; | ||
| text: string; | ||
| } | { | ||
| kind: 'resource'; | ||
| resourceType: string; | ||
| resourceId: string; | ||
| title?: string; | ||
| summary?: string; | ||
| } | { | ||
| kind: 'task_result'; | ||
| messageId: string; | ||
| cardId: string; | ||
| title: string; | ||
| summary: string; | ||
| }>; | ||
| omitted: Array<{ | ||
| messageCount: number; | ||
| reason: 'token_budget' | 'permission' | 'privacy' | 'not_relevant'; | ||
| }>; | ||
| tokenEstimate: number; | ||
| } | ||
| interface TaskMessageCard { | ||
| id: string; | ||
| kind: 'task'; | ||
| version: number; | ||
| title: string; | ||
| body?: string; | ||
| status: MessageCardStatus; | ||
| priority?: 'low' | 'normal' | 'medium' | 'high'; | ||
| tags?: TaskMessageCardTag[]; | ||
| app?: MessageCardApp; | ||
| assignee?: { | ||
| agentId?: string; | ||
| userId?: string; | ||
| label?: string; | ||
| [key: string]: unknown; | ||
| }; | ||
| source?: MessageCardSource; | ||
| requirements?: TaskMessageRequirements; | ||
| outputContract?: TaskMessageOutputContract; | ||
| privacy?: TaskMessagePrivacy; | ||
| claim?: MessageCardClaim; | ||
| capability?: MessageCardCapability; | ||
| progress?: Array<{ | ||
| at: string; | ||
| status: MessageCardStatus; | ||
| note?: string; | ||
| actor?: MessageCardSource; | ||
| [key: string]: unknown; | ||
| }>; | ||
| replies?: TaskMessageCardReply[]; | ||
| createdAt: string; | ||
| updatedAt?: string; | ||
| data?: Record<string, unknown> & { | ||
| task?: { | ||
| workspaceId?: string; | ||
| threadId?: string; | ||
| revision?: number; | ||
| contextPack?: TaskContextPack; | ||
| [key: string]: unknown; | ||
| }; | ||
| }; | ||
| [key: string]: unknown; | ||
| } | ||
| type GenericMessageCard = { | ||
| id?: string; | ||
| kind: string; | ||
| version?: number; | ||
| title?: string; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| }; | ||
| interface ServerAppMessageCard { | ||
| id?: string; | ||
| kind: 'server_app'; | ||
| version?: number; | ||
| appKey: string; | ||
| title: string; | ||
| description?: string; | ||
| label?: string; | ||
| action?: { | ||
| mode: 'open_app'; | ||
| path?: string; | ||
| }; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| } | ||
| interface MessageReferenceCard { | ||
| id?: string; | ||
| kind: 'message_reference'; | ||
| version?: number; | ||
| title: string; | ||
| description?: string; | ||
| label?: string; | ||
| target: { | ||
| serverId?: string | null; | ||
| serverSlug?: string | null; | ||
| channelId: string; | ||
| messageId: string; | ||
| taskCardId?: string | null; | ||
| inboxAgentId?: string | null; | ||
| kind?: 'channel_message' | 'inbox_message'; | ||
| }; | ||
| source?: MessageCardSource; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| } | ||
| type MessageCard = TaskMessageCard | ServerAppMessageCard | MessageReferenceCard | GenericMessageCard; | ||
| interface CommerceOfferCardInput { | ||
| id?: string; | ||
| kind: 'offer'; | ||
| offerId: string; | ||
| } | ||
| type CommerceMessageCard = CommerceProductCard | CommerceOfferCardInput; | ||
| interface CommerceProductCard { | ||
| id: string; | ||
| kind: 'offer' | 'product'; | ||
| offerId?: string; | ||
| shopId: string; | ||
| shopScope: { | ||
| kind: 'server' | 'user'; | ||
| id: string; | ||
| }; | ||
| productId: string; | ||
| skuId?: string; | ||
| snapshot: { | ||
| name: string; | ||
| summary?: string | null; | ||
| imageUrl?: string | null; | ||
| shopName?: string | null; | ||
| deliveryPromise?: string | null; | ||
| price: number; | ||
| currency: string; | ||
| productType: 'physical' | 'entitlement'; | ||
| billingMode?: 'one_time' | 'fixed_duration' | 'subscription'; | ||
| durationSeconds?: number | null; | ||
| resourceType?: string; | ||
| resourceId?: string; | ||
| capability?: string; | ||
| }; | ||
| purchase: { | ||
| mode: 'direct' | 'select_sku' | 'open_detail'; | ||
| }; | ||
| } | ||
| interface PaidFileCard { | ||
| id: string; | ||
| kind: 'paid_file'; | ||
| fileId: string; | ||
| entitlementId?: string | null; | ||
| deliverableId?: string; | ||
| snapshot: { | ||
| name: string; | ||
| summary?: string | null; | ||
| mime?: string | null; | ||
| sizeBytes?: number | null; | ||
| previewUrl?: string | null; | ||
| }; | ||
| action: { | ||
| mode: 'open_paid_file'; | ||
| }; | ||
| } | ||
| interface OAuthLinkCard { | ||
| id: string; | ||
| kind: 'oauth_link'; | ||
| appId: string; | ||
| clientId?: string | null; | ||
| title: string; | ||
| description?: string | null; | ||
| iconUrl?: string | null; | ||
| meta?: { | ||
| appName?: string | null; | ||
| avatarUrl?: string | null; | ||
| iconUrl?: string | null; | ||
| coverUrl?: string | null; | ||
| homepageUrl?: string | null; | ||
| origin?: string | null; | ||
| }; | ||
| url: string; | ||
| embedUrl?: string | null; | ||
| fallbackUrl?: string | null; | ||
| scopes?: string[]; | ||
| action: { | ||
| mode: 'open_iframe' | 'open_external'; | ||
| }; | ||
| } | ||
| type MentionSuggestionTrigger = '@' | '#'; | ||
| interface MentionSuggestion { | ||
| id: string; | ||
| kind: MessageMentionKind; | ||
| targetId: string; | ||
| token: string; | ||
| label: string; | ||
| description?: string | null; | ||
| serverId?: string; | ||
| serverSlug?: string | null; | ||
| serverName?: string | null; | ||
| channelId?: string; | ||
| channelName?: string | null; | ||
| appId?: string; | ||
| appKey?: string; | ||
| appName?: string | null; | ||
| iconUrl?: string | null; | ||
| userId?: string; | ||
| username?: string | null; | ||
| displayName?: string | null; | ||
| avatarUrl?: string | null; | ||
| isBot?: boolean; | ||
| isPrivate?: boolean; | ||
| } | ||
| interface Attachment { | ||
| id: string; | ||
| messageId: string; | ||
| filename: string; | ||
| url: string; | ||
| contentType: string; | ||
| size: number; | ||
| width: number | null; | ||
| height: number | null; | ||
| workspaceNodeId?: string | null; | ||
| kind?: 'file' | 'image' | 'voice'; | ||
| durationMs?: number | null; | ||
| audioCodec?: string | null; | ||
| audioContainer?: string | null; | ||
| waveformPeaks?: number[] | null; | ||
| waveformVersion?: number | null; | ||
| transcript?: { | ||
| id: string; | ||
| status: 'pending' | 'processing' | 'ready' | 'failed'; | ||
| text: string | null; | ||
| language: string | null; | ||
| source: 'client' | 'server' | 'runtime'; | ||
| provider?: string | null; | ||
| confidence?: number | null; | ||
| errorCode?: string | null; | ||
| updatedAt?: string; | ||
| } | null; | ||
| playback?: { | ||
| played: boolean; | ||
| completed: boolean; | ||
| lastPositionMs: number; | ||
| playedCount?: number; | ||
| } | null; | ||
| createdAt: string; | ||
| } | ||
| interface ReactionGroup { | ||
| emoji: string; | ||
| count: number; | ||
| userIds: string[]; | ||
| } | ||
| interface Thread { | ||
| id: string; | ||
| name: string; | ||
| channelId: string; | ||
| parentMessageId: string; | ||
| creatorId: string; | ||
| isArchived: boolean; | ||
| createdAt: string; | ||
| updatedAt: string; | ||
| } | ||
| interface SendMessageRequest { | ||
| content: string; | ||
| threadId?: string; | ||
| replyToId?: string; | ||
| mentions?: MessageMention[]; | ||
| metadata?: MessageMetadata; | ||
| } | ||
| interface UpdateMessageRequest { | ||
| content: string; | ||
| } | ||
| type NotificationType = 'mention' | 'reply' | 'dm' | 'system'; | ||
| interface Notification { | ||
| id: string; | ||
| userId: string; | ||
| type: NotificationType; | ||
| title: string; | ||
| body: string | null; | ||
| referenceId: string | null; | ||
| referenceType: string | null; | ||
| isRead: boolean; | ||
| createdAt: string; | ||
| } | ||
| export { type Attachment as A, type TaskMessagePrivacy as B, type CommerceMessageCard as C, type TaskMessagePrivacyDataClass as D, type TaskMessageRequirementSkill as E, type TaskMessageRequirementTool as F, type GenericMessageCard as G, type TaskMessageRequirements as H, type TaskMessageSubmitCommand as I, type Thread as J, buildMessageAgentChainMetadata as K, buildMessageCopilotContextMetadata as L, MESSAGE_AGENT_CHAIN_METADATA_KEY as M, type Notification as N, type OAuthLinkCard as O, type PaidFileCard as P, isMessageAgentChainMetadata as Q, type ReactionGroup as R, type SendMessageRequest as S, type TaskContextPack as T, type UpdateMessageRequest as U, isMessageCopilotContext as V, type CommerceOfferCardInput as a, type CommerceProductCard as b, MESSAGE_COPILOT_CONTEXT_METADATA_KEY as c, type MentionSuggestion as d, type MentionSuggestionTrigger as e, type Message as f, type MessageAgentChainMetadata as g, type MessageCard as h, type MessageCardApp as i, type MessageCardCapability as j, type MessageCardClaim as k, type MessageCardSource as l, type MessageCardStatus as m, type MessageCopilotContext as n, type MessageMention as o, type MessageMentionKind as p, type MessageMentionRange as q, type MessageMetadata as r, type MessageReferenceCard as s, type NotificationType as t, type ServerAppMessageCard as u, type TaskMessageCard as v, type TaskMessageCardReply as w, type TaskMessageCardTag as x, type TaskMessageExpectedArtifact as y, type TaskMessageOutputContract as z }; |
Sorry, the diff of this file is too big to display
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
728141
4.66%12618
5.7%