@shadowob/shared
Advanced tools
| // src/types/computer.types.ts | ||
| function shadowComputerId(kind, sourceId) { | ||
| return `${kind}:${sourceId}`; | ||
| } | ||
| function parseShadowComputerId(id) { | ||
| const separator = id.indexOf(":"); | ||
| if (separator <= 0) return null; | ||
| const kind = id.slice(0, separator); | ||
| const sourceId = id.slice(separator + 1); | ||
| if (kind !== "local" && kind !== "cloud" || !sourceId) return null; | ||
| return { kind, sourceId }; | ||
| } | ||
| // 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 === "space_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 === "space_app_copilot" && isBoundedMetadataString(record.appKey, 120, true) && isBoundedMetadataString(record.spaceAppId, 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 isPollMessageCard(card) { | ||
| return isMetadataRecord(card) && card.kind === "poll" && typeof card.id === "string" && typeof card.pollId === "string" && typeof card.title === "string"; | ||
| } | ||
| function getPollMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isPollMessageCard) : []; | ||
| } | ||
| 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 "offline"; | ||
| } | ||
| 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 ?? null; | ||
| let lastHeartbeat = current.lastHeartbeat ?? null; | ||
| if (update.lastHeartbeat !== void 0) { | ||
| lastHeartbeat = update.lastHeartbeat; | ||
| } else if (userStatus === "online" && (update.agentStatus === "running" || current.agentStatus === "running")) { | ||
| lastHeartbeat = observedAt; | ||
| } else if (userStatus === "offline") { | ||
| lastHeartbeat = null; | ||
| } | ||
| return { userStatus, agentStatus, lastHeartbeat }; | ||
| } | ||
| export { | ||
| shadowComputerId, | ||
| parseShadowComputerId, | ||
| 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, | ||
| isPollMessageCard, | ||
| getPollMessageCards, | ||
| 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/cloud-computer-appearance.ts | ||
| var CLOUD_COMPUTER_SHELL_COLORS = [ | ||
| "aqua", | ||
| "grape", | ||
| "tangerine", | ||
| "lime", | ||
| "strawberry", | ||
| "blueberry", | ||
| "graphite" | ||
| ]; | ||
| var CLOUD_COMPUTER_SHELL_PALETTE = { | ||
| aqua: { shell: "#43D7D1", deep: "#087B83", glow: "#BFFFF7", highlight: "#E9FFFC" }, | ||
| grape: { shell: "#A978E8", deep: "#59349A", glow: "#E7D4FF", highlight: "#F8F1FF" }, | ||
| tangerine: { shell: "#FF9A3D", deep: "#B94F12", glow: "#FFD7A8", highlight: "#FFF3E4" }, | ||
| lime: { shell: "#A7D83E", deep: "#527B13", glow: "#E4F6A8", highlight: "#F8FFE5" }, | ||
| strawberry: { shell: "#F76F96", deep: "#A92C58", glow: "#FFD0DF", highlight: "#FFF0F5" }, | ||
| blueberry: { shell: "#5B8FF4", deep: "#2853A6", glow: "#C9DBFF", highlight: "#EFF5FF" }, | ||
| graphite: { shell: "#7D8999", deep: "#343C48", glow: "#D6DEE8", highlight: "#F1F4F8" } | ||
| }; | ||
| function isCloudComputerShellColor(value) { | ||
| return typeof value === "string" && CLOUD_COMPUTER_SHELL_COLORS.includes(value); | ||
| } | ||
| function defaultCloudComputerShellColor(seed) { | ||
| let hash = 0; | ||
| for (const character of seed) hash = hash * 31 + character.charCodeAt(0) >>> 0; | ||
| return CLOUD_COMPUTER_SHELL_COLORS[hash % CLOUD_COMPUTER_SHELL_COLORS.length] ?? "aqua"; | ||
| } | ||
| function resolveCloudComputerShellColor(value, seed) { | ||
| return isCloudComputerShellColor(value) ? value : defaultCloudComputerShellColor(seed); | ||
| } | ||
| // src/utils/cloud-computer-buddy.ts | ||
| function findReadyCloudComputerBuddy(buddies, expectedId) { | ||
| const buddy = buddies.find((candidate) => candidate.id === expectedId); | ||
| return buddy?.status === "running" && typeof buddy.botUser?.id === "string" && buddy.botUser.id.trim().length > 0 ? buddy : null; | ||
| } | ||
| async function waitForCloudComputerBuddy(input) { | ||
| const timeoutMs = input.timeoutMs ?? 12e4; | ||
| const pollIntervalMs = input.pollIntervalMs ?? 1500; | ||
| const deadline = Date.now() + timeoutMs; | ||
| while (!input.signal?.aborted && Date.now() < deadline) { | ||
| try { | ||
| const buddy = findReadyCloudComputerBuddy(await input.load(), input.expectedId); | ||
| if (buddy) return buddy; | ||
| } catch { | ||
| } | ||
| await new Promise((resolve) => { | ||
| let settled = false; | ||
| const finish = () => { | ||
| if (settled) return; | ||
| settled = true; | ||
| clearTimeout(timer); | ||
| input.signal?.removeEventListener("abort", finish); | ||
| resolve(); | ||
| }; | ||
| const timer = setTimeout(finish, pollIntervalMs); | ||
| input.signal?.addEventListener("abort", finish, { once: true }); | ||
| }); | ||
| } | ||
| return null; | ||
| } | ||
| // src/utils/cloud-connector-access.ts | ||
| function cloudConnectorAccessKind(connector) { | ||
| if (connector.oauth?.available && connector.oauth.configured !== false) return "oauth"; | ||
| if (connector.oauth?.available && connector.oauth.configured === false && connector.authFields.length === 0) { | ||
| return "unavailable"; | ||
| } | ||
| if (connector.authType === "none") return "direct"; | ||
| if (connector.authFields.length === 0 || connector.authFields.every( | ||
| (field) => !field || typeof field !== "object" || Array.isArray(field) || field.required !== true | ||
| )) { | ||
| return "direct"; | ||
| } | ||
| return "manual"; | ||
| } | ||
| // 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 === "space_app") return `<@space-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(/^<@space-app:([^>]+)>$/u); | ||
| if (app?.[1]) return { kind: "space_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/space-app-routes.ts | ||
| var SPACE_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 normalizeSpaceAppRoutePath(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, SPACE_APP_ROUTE_PATH_MAX); | ||
| } | ||
| function withSpaceAppRoutePathSearch(search, appPath) { | ||
| const next = { ...search ?? {} }; | ||
| const normalized = normalizeSpaceAppRoutePath(appPath); | ||
| if (normalized && normalized !== "/") { | ||
| next.appPath = normalized; | ||
| } else { | ||
| delete next.appPath; | ||
| } | ||
| return next; | ||
| } | ||
| function spaceAppPathFromSearch(search) { | ||
| return normalizeSpaceAppRoutePath(search?.appPath); | ||
| } | ||
| function buildSpaceAppCommunityPath(target, options = {}) { | ||
| const basePath = cleanBasePath(options.basePath ?? "/app"); | ||
| const path = `${basePath}/servers/${encodeURIComponent(target.serverSlug)}/space-apps/${encodeURIComponent( | ||
| target.appKey | ||
| )}`; | ||
| const params = new URLSearchParams(); | ||
| const appPath = normalizeSpaceAppRoutePath(target.appPath); | ||
| if (appPath && appPath !== "/") params.set("appPath", appPath); | ||
| const query = params.toString(); | ||
| return query ? `${path}?${query}` : path; | ||
| } | ||
| function buildSpaceAppSharePath(target, options = {}) { | ||
| const basePath = cleanBasePath(options.basePath ?? "/app"); | ||
| const path = `${basePath}/share/space-app/${encodeURIComponent( | ||
| target.serverSlug | ||
| )}/${encodeURIComponent(target.appKey)}`; | ||
| const params = new URLSearchParams(); | ||
| const appPath = normalizeSpaceAppRoutePath(target.appPath); | ||
| if (appPath && appPath !== "/") params.set("appPath", appPath); | ||
| const query = params.toString(); | ||
| return query ? `${path}?${query}` : path; | ||
| } | ||
| function buildSpaceAppShareUrl(target, options = {}) { | ||
| return new URL(buildSpaceAppSharePath(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, | ||
| CLOUD_COMPUTER_SHELL_COLORS, | ||
| CLOUD_COMPUTER_SHELL_PALETTE, | ||
| isCloudComputerShellColor, | ||
| defaultCloudComputerShellColor, | ||
| resolveCloudComputerShellColor, | ||
| findReadyCloudComputerBuddy, | ||
| waitForCloudComputerBuddy, | ||
| cloudConnectorAccessKind, | ||
| extractSlashCommandActions, | ||
| canonicalMentionToken, | ||
| parseCanonicalMentionToken, | ||
| isCanonicalMentionToken, | ||
| segmentTextByMentions, | ||
| assignMentionRanges, | ||
| canonicalizeMentionContent, | ||
| mentionDisplayText, | ||
| escapeMarkdownLinkLabel, | ||
| buildMentionMarkdownLinks, | ||
| getCatAvatar, | ||
| getCatAvatarByUserId, | ||
| getAllCatAvatars, | ||
| getCatSvgString, | ||
| CAT_AVATAR_COUNT, | ||
| normalizeSpaceAppRoutePath, | ||
| withSpaceAppRoutePathSearch, | ||
| spaceAppPathFromSearch, | ||
| buildSpaceAppCommunityPath, | ||
| buildSpaceAppSharePath, | ||
| buildSpaceAppShareUrl, | ||
| generateInviteCode, | ||
| formatDate, | ||
| isValidEmail, | ||
| slugify | ||
| }; |
| // src/desktop-ipc/protocol.ts | ||
| import { z as z3 } from "zod"; | ||
| // src/desktop-ipc/rpc.ts | ||
| import { z } from "zod"; | ||
| function ipcProcedure(definition = { | ||
| input: ipcVoidInputSchema, | ||
| output: ipcVoidOutputSchema | ||
| }) { | ||
| return definition; | ||
| } | ||
| function defineIPCService(service) { | ||
| return service; | ||
| } | ||
| function defineIPCProtocol(protocol) { | ||
| return protocol; | ||
| } | ||
| function ipcProcedureChannel(serviceName, methodName, procedure) { | ||
| return procedure?.channel ?? `desktop-rpc:${serviceName}.${methodName}`; | ||
| } | ||
| function parseIPCProcedureInput(procedure, input) { | ||
| return procedure.input.parse(input); | ||
| } | ||
| function parseIPCProcedureOutput(procedure, output) { | ||
| return procedure.output.parse(output); | ||
| } | ||
| var ipcVoidInputSchema = z.void(); | ||
| var ipcVoidOutputSchema = z.void(); | ||
| // src/desktop-ipc/schema.ts | ||
| import { z as z2 } from "zod"; | ||
| var ipcObjectSchema = z2.preprocess( | ||
| (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {}, | ||
| z2.object({}).passthrough() | ||
| ); | ||
| var optionalStringSchema = z2.string().optional(); | ||
| var optionalBooleanSchema = z2.boolean().optional(); | ||
| var optionalTrimmedStringSchema = z2.string().trim().transform((value) => value || void 0).optional(); | ||
| function requiredTrimmedStringSchema(field) { | ||
| return z2.string({ required_error: `Missing ${field}`, invalid_type_error: `Missing ${field}` }).trim().min(1, `Missing ${field}`); | ||
| } | ||
| var connectorStartSettingsSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| connectorApiKey: optionalStringSchema, | ||
| connectorComputerId: optionalStringSchema, | ||
| connectorAutoStart: optionalBooleanSchema, | ||
| connectorWorkDir: optionalStringSchema, | ||
| httpProxy: optionalStringSchema, | ||
| httpsProxy: optionalStringSchema, | ||
| serverBaseUrl: optionalStringSchema | ||
| }) | ||
| ); | ||
| var forceOptionsSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| force: optionalBooleanSchema | ||
| }) | ||
| ); | ||
| var desktopWindowFullscreenInputSchema = z2.boolean(); | ||
| var desktopWindowChromeStateSchema = z2.object({ | ||
| fullscreen: z2.boolean(), | ||
| maximized: z2.boolean() | ||
| }); | ||
| var runtimeIdInputSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| runtimeId: requiredTrimmedStringSchema("runtime id") | ||
| }) | ||
| ); | ||
| var createConnectorBuddySchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| runtimeId: requiredTrimmedStringSchema("runtime id"), | ||
| name: requiredTrimmedStringSchema("Buddy name"), | ||
| username: requiredTrimmedStringSchema("Buddy username"), | ||
| description: optionalTrimmedStringSchema, | ||
| avatarUrl: optionalTrimmedStringSchema.nullable().optional().transform((value) => value ?? null) | ||
| }) | ||
| ); | ||
| var connectorConnectionEnabledSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| agentId: requiredTrimmedStringSchema("Buddy id"), | ||
| enabled: z2.boolean().catch(false) | ||
| }) | ||
| ); | ||
| var connectorDeleteSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| agentId: requiredTrimmedStringSchema("Buddy id"), | ||
| deleteCloudBuddy: optionalBooleanSchema | ||
| }) | ||
| ); | ||
| var connectorWorkDirSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| agentId: requiredTrimmedStringSchema("Buddy id"), | ||
| workDir: optionalStringSchema | ||
| }) | ||
| ); | ||
| var desktopPetAssetSpriteSchema = z2.object({ | ||
| src: z2.string(), | ||
| frame: z2.object({ | ||
| width: z2.number(), | ||
| height: z2.number(), | ||
| count: z2.number(), | ||
| fps: z2.number() | ||
| }).optional(), | ||
| atlas: z2.object({ | ||
| columns: z2.number(), | ||
| rows: z2.number(), | ||
| row: z2.number() | ||
| }).optional(), | ||
| loop: z2.boolean().optional() | ||
| }).passthrough(); | ||
| var desktopPetAssetPackSchema = z2.object({ | ||
| id: z2.string(), | ||
| version: z2.string().optional(), | ||
| spriteVersionNumber: z2.union([z2.literal(1), z2.literal(2)]).default(1), | ||
| displayName: z2.record(z2.string()), | ||
| description: z2.union([z2.record(z2.string()), z2.string()]).optional(), | ||
| spritesheetPath: z2.string(), | ||
| sprites: z2.record(desktopPetAssetSpriteSchema), | ||
| importedAt: z2.string(), | ||
| source: z2.enum(["local", "marketplace"]), | ||
| sourcePath: z2.string(), | ||
| marketplaceProductId: z2.string().optional(), | ||
| marketplaceEntitlementId: z2.string().optional(), | ||
| marketplacePaidFileId: z2.string().optional() | ||
| }).passthrough(); | ||
| var desktopShortcutSettingsSchema = z2.object({ | ||
| openCommunity: z2.string(), | ||
| togglePet: z2.string(), | ||
| petVoice: z2.string(), | ||
| petChat: z2.string(), | ||
| showNotifications: z2.string() | ||
| }); | ||
| var desktopSettingsPatchSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| serverBaseUrl: z2.string().optional(), | ||
| httpProxy: z2.string().optional(), | ||
| httpsProxy: z2.string().optional(), | ||
| connectorApiKey: z2.string().optional(), | ||
| connectorComputerId: z2.string().optional(), | ||
| connectorAutoStart: z2.boolean().optional(), | ||
| connectorWorkDir: z2.string().optional(), | ||
| connectorBuddyWorkDirs: z2.record(z2.string()).optional(), | ||
| connectorDeletedConnectionIds: z2.array(z2.string()).optional(), | ||
| connectorRuntimeNotifications: z2.record(z2.boolean()).optional(), | ||
| ttsProvider: z2.enum(["system", "moss-tts-nano", "sherpa-local", "voxcpm2"]).optional(), | ||
| asrProvider: z2.enum(["sherpa-local", "web-speech"]).optional(), | ||
| desktopPetVisible: z2.boolean().optional(), | ||
| desktopPetPacks: z2.array(z2.record(z2.unknown())).optional(), | ||
| desktopPetActivePackId: z2.string().optional(), | ||
| shortcuts: desktopShortcutSettingsSchema.partial().optional() | ||
| }) | ||
| ); | ||
| var optionalPathInputSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| path: optionalStringSchema | ||
| }) | ||
| ); | ||
| var petMarketplaceImportSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| entitlementId: optionalStringSchema, | ||
| fileId: requiredTrimmedStringSchema("paid file id"), | ||
| productId: optionalStringSchema | ||
| }) | ||
| ); | ||
| var petArchiveImportSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| name: z2.unknown().optional(), | ||
| data: z2.unknown().optional() | ||
| }) | ||
| ); | ||
| var packIdInputSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| packId: z2.string().optional().default("") | ||
| }) | ||
| ); | ||
| var startAgentSchema = z2.object({ | ||
| name: z2.string().min(1).max(120), | ||
| scriptPath: z2.string().min(1), | ||
| args: z2.array(z2.string()).optional() | ||
| }); | ||
| var agentProcessIdSchema = z2.string().min(1); | ||
| var desktopNotificationSchema = z2.object({ | ||
| title: z2.string().min(1).max(200), | ||
| body: z2.string().max(2e3), | ||
| channelId: z2.string().optional(), | ||
| messageId: z2.string().optional(), | ||
| routePath: z2.string().optional(), | ||
| target: z2.enum(["community", "pet"]).optional() | ||
| }); | ||
| var badgeCountSchema = z2.number().int().min(0).max(9999).catch(0); | ||
| var notificationModeSchema = z2.string().max(80); | ||
| var updateSettingsSchema = z2.object({ | ||
| autoCheckOnLaunch: z2.boolean().optional(), | ||
| channel: z2.enum(["production", "beta"]).optional() | ||
| }); | ||
| var downloadUpdateUrlSchema = z2.string().url(); | ||
| var openAtLoginSchema = z2.boolean(); | ||
| var voiceModelInstallSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| provider: z2.enum(["system", "moss-tts-nano", "sherpa-local", "voxcpm2"]).optional() | ||
| }) | ||
| ); | ||
| var asrAcceptSchema = z2.object({ | ||
| samples: z2.instanceof(ArrayBuffer), | ||
| sampleRate: z2.number().positive() | ||
| }); | ||
| var speechTextSchema = z2.string().max(8e3); | ||
| var rendererLogSchema = z2.object({ | ||
| scope: z2.string(), | ||
| payload: z2.unknown().optional() | ||
| }).passthrough(); | ||
| var externalUrlSchema = z2.string(); | ||
| var clipboardTextSchema = z2.string(); | ||
| var readerOpenSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| url: z2.string().optional(), | ||
| title: z2.string().optional(), | ||
| useDefaultApp: z2.boolean().optional(), | ||
| attachmentId: z2.string().optional() | ||
| }) | ||
| ); | ||
| var readerIdInputSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| id: z2.string().optional().default("") | ||
| }) | ||
| ); | ||
| var selectDirectorySchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| defaultPath: z2.string().optional() | ||
| }) | ||
| ); | ||
| var communityAuthSnapshotReasonSchema = z2.enum([ | ||
| "startup", | ||
| "storage", | ||
| "sync", | ||
| "login", | ||
| "refresh", | ||
| "logout", | ||
| "settings", | ||
| "revoked" | ||
| ]); | ||
| var communityAuthSnapshotSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| accessToken: z2.string().optional(), | ||
| refreshToken: z2.string().optional(), | ||
| reason: communityAuthSnapshotReasonSchema.optional().default("sync"), | ||
| sourceUrl: z2.string().optional() | ||
| }) | ||
| ); | ||
| var communityFetchJsonSchema = z2.object({ | ||
| path: z2.string().min(1), | ||
| method: z2.string().optional(), | ||
| body: z2.unknown().optional(), | ||
| headers: z2.record(z2.string()).optional(), | ||
| optional: z2.boolean().optional() | ||
| }); | ||
| var modelProxyStreamSchema = z2.object({ | ||
| requestId: z2.string().min(1), | ||
| body: z2.record(z2.unknown()) | ||
| }); | ||
| function optionalStringValueFromPathInput(value, key) { | ||
| if (typeof value === "string") return value; | ||
| const parsed = ipcObjectSchema.pipe(z2.object({ [key]: z2.string().optional() })).parse(value); | ||
| return parsed[key]; | ||
| } | ||
| var showCommunityInputSchema = z2.unknown().transform((value) => optionalStringValueFromPathInput(value, "path")); | ||
| var openCommunityLoginInputSchema = z2.unknown().transform( | ||
| (value) => optionalStringValueFromPathInput(value, "redirect") ?? "/discover" | ||
| ); | ||
| var showSettingsInputSchema = z2.unknown().transform((value) => optionalStringValueFromPathInput(value, "tab")); | ||
| var petPanelModeSchema = z2.enum(["compact", "expanded"]); | ||
| var petWindowDragStartSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| pointerId: z2.number().optional(), | ||
| screenX: z2.number().optional(), | ||
| screenY: z2.number().optional() | ||
| }) | ||
| ); | ||
| var petWindowDragMoveSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| x: z2.number().optional(), | ||
| y: z2.number().optional(), | ||
| pointerId: z2.number().optional(), | ||
| screenX: z2.number().optional(), | ||
| screenY: z2.number().optional() | ||
| }) | ||
| ); | ||
| var petWindowPointerIdSchema = z2.number().optional(); | ||
| var petWindowMouseInteractiveSchema = z2.boolean(); | ||
| var petCursorPositionSchema = z2.object({ | ||
| x: z2.number(), | ||
| y: z2.number() | ||
| }); | ||
| var desktopIpcInvokeSchemas = { | ||
| "desktop:getSettings": void 0, | ||
| "desktop:setSettings": desktopSettingsPatchSchema, | ||
| "desktop:showNotification": desktopNotificationSchema, | ||
| "desktop:setBadgeCount": badgeCountSchema, | ||
| "desktop:setNotificationMode": notificationModeSchema, | ||
| "desktop:minimizeToTray": void 0, | ||
| "desktop:window:chrome-state": void 0, | ||
| "desktop:window:set-full-screen": desktopWindowFullscreenInputSchema, | ||
| "desktop:openExternal": externalUrlSchema, | ||
| "desktop:clipboard:writeText": clipboardTextSchema, | ||
| "desktop:openReader": readerOpenSchema, | ||
| "desktop:reader:getState": void 0, | ||
| "desktop:reader:activate": readerIdInputSchema, | ||
| "desktop:reader:close": readerIdInputSchema, | ||
| "desktop:reader:openDefault": readerIdInputSchema, | ||
| "desktop:selectDirectory": selectDirectorySchema, | ||
| "desktop:quit": void 0, | ||
| "desktop:getCommunityAuthToken": void 0, | ||
| "desktop:getCommunityAuthTokens": void 0, | ||
| "desktop:community:fetchJson": communityFetchJsonSchema, | ||
| "desktop:diagnostics:getSnapshot": void 0, | ||
| "desktop:diagnostics:exportLogs": void 0, | ||
| "desktop:showMainWindow": void 0, | ||
| "desktop:showCommunity": showCommunityInputSchema, | ||
| "desktop:openCommunityLogin": openCommunityLoginInputSchema, | ||
| "desktop:showCreateBuddy": void 0, | ||
| "desktop:showContextMenu": void 0, | ||
| "desktop:showSettings": showSettingsInputSchema, | ||
| "desktop:pet:show": void 0, | ||
| "desktop:pet:hide": void 0, | ||
| "desktop:pet:cursor-position": void 0, | ||
| "desktop:pet:panel-mode": petPanelModeSchema, | ||
| "desktop:pet:begin-window-drag": petWindowDragStartSchema, | ||
| "desktop:pet:move-window": petWindowDragMoveSchema, | ||
| "desktop:pet:end-window-drag": petWindowPointerIdSchema, | ||
| "desktop:pet:mouse-interactive": petWindowMouseInteractiveSchema, | ||
| "desktop:pet:modelProxyStream": modelProxyStreamSchema, | ||
| "desktop:pet:speak": speechTextSchema, | ||
| "desktop:pet:cancelSpeech": void 0, | ||
| "desktop:pet:voiceEngineStatus": void 0, | ||
| "desktop:pet:prewarmVoice": void 0, | ||
| "desktop:pet:installVoiceModel": voiceModelInstallSchema, | ||
| "desktop:pet:asrStart": void 0, | ||
| "desktop:pet:asrAccept": asrAcceptSchema, | ||
| "desktop:pet:asrStop": void 0, | ||
| "desktop:startAgent": startAgentSchema, | ||
| "desktop:stopAgent": agentProcessIdSchema, | ||
| "desktop:getAgentStatus": agentProcessIdSchema, | ||
| "desktop:listAgents": void 0, | ||
| "desktop:getVersion": void 0, | ||
| "desktop:checkForUpdate": void 0, | ||
| "desktop:getUpdateState": void 0, | ||
| "desktop:getUpdateSettings": void 0, | ||
| "desktop:setUpdateSettings": updateSettingsSchema, | ||
| "desktop:downloadUpdate": downloadUpdateUrlSchema, | ||
| "desktop:setOpenAtLogin": openAtLoginSchema, | ||
| "desktop:getOpenAtLogin": void 0, | ||
| "desktop:quitAndRestart": void 0, | ||
| "desktop:petAssets:importDirectory": optionalPathInputSchema, | ||
| "desktop:petAssets:importMarketplace": petMarketplaceImportSchema, | ||
| "desktop:petAssets:importArchiveBuffer": petArchiveImportSchema, | ||
| "desktop:petAssets:setActive": packIdInputSchema, | ||
| "desktop:petAssets:remove": packIdInputSchema, | ||
| "desktop:connector:getStatus": void 0, | ||
| "desktop:connector:start": connectorStartSettingsSchema, | ||
| "desktop:connector:stop": void 0, | ||
| "desktop:connector:scan": void 0, | ||
| "desktop:connector:scanRuntimes": forceOptionsSchema, | ||
| "desktop:connector:scanRuntimeSessions": forceOptionsSchema, | ||
| "desktop:connector:installRuntime": runtimeIdInputSchema, | ||
| "desktop:connector:createBuddy": createConnectorBuddySchema, | ||
| "desktop:connector:getConnections": void 0, | ||
| "desktop:connector:setConnectionEnabled": connectorConnectionEnabledSchema, | ||
| "desktop:connector:deleteConnection": connectorDeleteSchema, | ||
| "desktop:connector:setConnectionWorkDir": connectorWorkDirSchema, | ||
| "desktop:shortcuts:reload": void 0, | ||
| "desktop:shortcuts:suspend": void 0, | ||
| "desktop:shortcuts:resume": void 0 | ||
| }; | ||
| // src/desktop-ipc/protocol.ts | ||
| var desktopPlatformSchema = z3.enum([ | ||
| "aix", | ||
| "android", | ||
| "darwin", | ||
| "freebsd", | ||
| "haiku", | ||
| "linux", | ||
| "openbsd", | ||
| "sunos", | ||
| "win32", | ||
| "cygwin", | ||
| "netbsd" | ||
| ]); | ||
| var desktopRuntimeSettingsSnapshotSchema = z3.object({ | ||
| serverBaseUrl: z3.string(), | ||
| httpProxy: z3.string(), | ||
| httpsProxy: z3.string(), | ||
| connectorApiKey: z3.string(), | ||
| connectorComputerId: z3.string(), | ||
| connectorAutoStart: z3.boolean(), | ||
| connectorWorkDir: z3.string(), | ||
| connectorBuddyWorkDirs: z3.record(z3.string()), | ||
| connectorRuntimeNotifications: z3.record(z3.boolean()), | ||
| ttsProvider: z3.enum(["system", "moss-tts-nano", "sherpa-local", "voxcpm2"]), | ||
| asrProvider: z3.enum(["sherpa-local", "web-speech"]), | ||
| shortcuts: z3.object({ | ||
| openCommunity: z3.string(), | ||
| togglePet: z3.string(), | ||
| petVoice: z3.string(), | ||
| petChat: z3.string(), | ||
| showNotifications: z3.string() | ||
| }), | ||
| desktopPetVisible: z3.boolean(), | ||
| desktopPetActivePackId: z3.string(), | ||
| desktopPetPacks: z3.array(z3.unknown()) | ||
| }); | ||
| var readerResourceSnapshotSchema = z3.object({ | ||
| id: z3.string(), | ||
| title: z3.string(), | ||
| sourceUrl: z3.string(), | ||
| displayAddress: z3.string(), | ||
| contentType: z3.string(), | ||
| fileName: z3.string(), | ||
| assetUrl: z3.string(), | ||
| createdAt: z3.number() | ||
| }); | ||
| var readerStateSnapshotSchema = z3.object({ | ||
| activeId: z3.string().nullable(), | ||
| tabs: z3.array(readerResourceSnapshotSchema) | ||
| }); | ||
| var desktopUpdateChannelSchema = z3.enum(["production", "beta"]); | ||
| var desktopUpdateInfoSchema = z3.object({ | ||
| hasUpdate: z3.boolean(), | ||
| version: z3.string(), | ||
| downloadUrl: z3.string(), | ||
| releaseNotes: z3.string(), | ||
| channel: desktopUpdateChannelSchema | ||
| }); | ||
| var desktopUpdateStateSchema = z3.object({ | ||
| status: z3.enum(["idle", "checking", "update-available", "up-to-date", "error"]), | ||
| checkedAt: z3.number().nullable(), | ||
| info: desktopUpdateInfoSchema.nullable(), | ||
| error: z3.string().nullable(), | ||
| channel: desktopUpdateChannelSchema | ||
| }); | ||
| var desktopUpdateSettingsSchema = z3.object({ | ||
| autoCheckOnLaunch: z3.boolean(), | ||
| channel: desktopUpdateChannelSchema | ||
| }); | ||
| var desktopDiagnosticsSnapshotSchema = z3.object({ | ||
| appName: z3.string(), | ||
| version: z3.string(), | ||
| platform: desktopPlatformSchema, | ||
| arch: z3.string(), | ||
| pid: z3.number(), | ||
| electron: z3.string(), | ||
| node: z3.string(), | ||
| buildId: z3.string(), | ||
| logFilePath: z3.string(), | ||
| logFileExists: z3.boolean(), | ||
| connector: z3.object({ | ||
| serverBaseUrl: z3.string(), | ||
| cliPath: z3.string().nullable(), | ||
| cliBundled: z3.boolean(), | ||
| nodeBinary: z3.string(), | ||
| state: z3.unknown() | ||
| }) | ||
| }); | ||
| var desktopLogExportResultSchema = z3.object({ | ||
| filePath: z3.string().nullable() | ||
| }); | ||
| var voiceProviderStatusSchema = z3.object({ | ||
| installed: z3.boolean(), | ||
| runtimeInstalled: z3.boolean().optional(), | ||
| modelInstalled: z3.boolean().optional(), | ||
| name: z3.string(), | ||
| sourceUrl: z3.string() | ||
| }); | ||
| var voiceEngineStatusSchema = z3.object({ | ||
| engine: z3.string(), | ||
| asrProvider: z3.enum(["sherpa-local", "web-speech"]), | ||
| ttsProvider: z3.enum(["system", "moss-tts-nano", "sherpa-local", "voxcpm2"]), | ||
| nativeAddonAvailable: z3.boolean(), | ||
| modelRoot: z3.string(), | ||
| asr: voiceProviderStatusSchema, | ||
| tts: voiceProviderStatusSchema, | ||
| ttsProviders: z3.object({ | ||
| system: voiceProviderStatusSchema, | ||
| "moss-tts-nano": voiceProviderStatusSchema, | ||
| "sherpa-local": voiceProviderStatusSchema, | ||
| voxcpm2: voiceProviderStatusSchema | ||
| }) | ||
| }); | ||
| var authTokensSchema = z3.object({ | ||
| accessToken: z3.string(), | ||
| refreshToken: z3.string() | ||
| }); | ||
| var agentStartResultSchema = z3.object({ | ||
| id: z3.string(), | ||
| pid: z3.number().optional() | ||
| }); | ||
| var agentStatusSchema = z3.object({ | ||
| running: z3.boolean(), | ||
| name: z3.string().optional(), | ||
| pid: z3.number().optional(), | ||
| uptime: z3.number().optional() | ||
| }); | ||
| var agentListSchema = z3.array( | ||
| z3.object({ | ||
| id: z3.string(), | ||
| name: z3.string(), | ||
| pid: z3.number().optional(), | ||
| running: z3.boolean(), | ||
| uptime: z3.number() | ||
| }) | ||
| ); | ||
| var connectorScanOutputSchema = z3.object({ | ||
| output: z3.string() | ||
| }); | ||
| var petPanelModeResultSchema = z3.object({ | ||
| stageOffsetY: z3.number() | ||
| }); | ||
| var modelProxyStreamResultSchema = z3.object({ | ||
| text: z3.string() | ||
| }); | ||
| var okResultSchema = z3.object({ | ||
| ok: z3.boolean() | ||
| }); | ||
| var textResultSchema = z3.object({ | ||
| text: z3.string() | ||
| }); | ||
| var unknownResultSchema = z3.unknown(); | ||
| var booleanResultSchema = z3.boolean(); | ||
| var stringResultSchema = z3.string(); | ||
| var nullableStringResultSchema = z3.string().nullable(); | ||
| var legacyProcedure = (channel, input, output) => ipcProcedure({ | ||
| channel, | ||
| input, | ||
| output | ||
| }); | ||
| var legacyVoidProcedure = (channel) => legacyProcedure(channel, ipcVoidInputSchema, ipcVoidOutputSchema); | ||
| var desktopIpcProtocol = defineIPCProtocol({ | ||
| app: defineIPCService({ | ||
| getVersion: legacyProcedure("desktop:getVersion", ipcVoidInputSchema, stringResultSchema), | ||
| setOpenAtLogin: legacyProcedure( | ||
| "desktop:setOpenAtLogin", | ||
| openAtLoginSchema, | ||
| ipcVoidOutputSchema | ||
| ), | ||
| getOpenAtLogin: legacyProcedure( | ||
| "desktop:getOpenAtLogin", | ||
| ipcVoidInputSchema, | ||
| booleanResultSchema | ||
| ), | ||
| quitAndRestart: legacyProcedure( | ||
| "desktop:quitAndRestart", | ||
| ipcVoidInputSchema, | ||
| booleanResultSchema | ||
| ) | ||
| }), | ||
| window: defineIPCService({ | ||
| minimizeToTray: legacyVoidProcedure("desktop:minimizeToTray"), | ||
| getChromeState: legacyProcedure( | ||
| "desktop:window:chrome-state", | ||
| ipcVoidInputSchema, | ||
| desktopWindowChromeStateSchema | ||
| ), | ||
| setFullScreen: legacyProcedure( | ||
| "desktop:window:set-full-screen", | ||
| desktopWindowFullscreenInputSchema, | ||
| desktopWindowChromeStateSchema | ||
| ), | ||
| openExternal: legacyProcedure("desktop:openExternal", externalUrlSchema, booleanResultSchema), | ||
| writeClipboardText: legacyProcedure( | ||
| "desktop:clipboard:writeText", | ||
| clipboardTextSchema, | ||
| booleanResultSchema | ||
| ), | ||
| selectDirectory: legacyProcedure( | ||
| "desktop:selectDirectory", | ||
| selectDirectorySchema, | ||
| nullableStringResultSchema | ||
| ), | ||
| quit: legacyVoidProcedure("desktop:quit"), | ||
| showMainWindow: legacyVoidProcedure("desktop:showMainWindow"), | ||
| showCommunity: legacyProcedure( | ||
| "desktop:showCommunity", | ||
| showCommunityInputSchema, | ||
| ipcVoidOutputSchema | ||
| ), | ||
| openCommunityLogin: legacyProcedure( | ||
| "desktop:openCommunityLogin", | ||
| openCommunityLoginInputSchema, | ||
| booleanResultSchema | ||
| ), | ||
| showCreateBuddy: legacyVoidProcedure("desktop:showCreateBuddy"), | ||
| showContextMenu: legacyVoidProcedure("desktop:showContextMenu"), | ||
| showSettings: legacyProcedure( | ||
| "desktop:showSettings", | ||
| showSettingsInputSchema, | ||
| ipcVoidOutputSchema | ||
| ) | ||
| }), | ||
| settings: defineIPCService({ | ||
| get: legacyProcedure( | ||
| "desktop:getSettings", | ||
| ipcVoidInputSchema, | ||
| desktopRuntimeSettingsSnapshotSchema | ||
| ), | ||
| set: legacyProcedure( | ||
| "desktop:setSettings", | ||
| desktopSettingsPatchSchema, | ||
| desktopRuntimeSettingsSnapshotSchema | ||
| ) | ||
| }), | ||
| notifications: defineIPCService({ | ||
| show: legacyProcedure( | ||
| "desktop:showNotification", | ||
| desktopNotificationSchema, | ||
| ipcVoidOutputSchema | ||
| ), | ||
| setBadgeCount: legacyProcedure("desktop:setBadgeCount", badgeCountSchema, ipcVoidOutputSchema), | ||
| setMode: legacyProcedure( | ||
| "desktop:setNotificationMode", | ||
| notificationModeSchema, | ||
| ipcVoidOutputSchema | ||
| ) | ||
| }), | ||
| reader: defineIPCService({ | ||
| open: legacyProcedure("desktop:openReader", readerOpenSchema, booleanResultSchema), | ||
| getState: legacyProcedure( | ||
| "desktop:reader:getState", | ||
| ipcVoidInputSchema, | ||
| readerStateSnapshotSchema | ||
| ), | ||
| activate: legacyProcedure( | ||
| "desktop:reader:activate", | ||
| readerIdInputSchema, | ||
| readerStateSnapshotSchema | ||
| ), | ||
| close: legacyProcedure("desktop:reader:close", readerIdInputSchema, readerStateSnapshotSchema), | ||
| openDefault: legacyProcedure( | ||
| "desktop:reader:openDefault", | ||
| readerIdInputSchema, | ||
| booleanResultSchema | ||
| ) | ||
| }), | ||
| community: defineIPCService({ | ||
| getAuthToken: legacyProcedure( | ||
| "desktop:getCommunityAuthToken", | ||
| ipcVoidInputSchema, | ||
| stringResultSchema | ||
| ), | ||
| getAuthTokens: legacyProcedure( | ||
| "desktop:getCommunityAuthTokens", | ||
| ipcVoidInputSchema, | ||
| authTokensSchema | ||
| ), | ||
| fetchJson: legacyProcedure( | ||
| "desktop:community:fetchJson", | ||
| communityFetchJsonSchema, | ||
| unknownResultSchema | ||
| ) | ||
| }), | ||
| diagnostics: defineIPCService({ | ||
| getSnapshot: ipcProcedure({ | ||
| input: ipcVoidInputSchema, | ||
| output: desktopDiagnosticsSnapshotSchema | ||
| }), | ||
| exportLogs: ipcProcedure({ | ||
| input: ipcVoidInputSchema, | ||
| output: desktopLogExportResultSchema | ||
| }) | ||
| }), | ||
| petWindow: defineIPCService({ | ||
| show: legacyVoidProcedure("desktop:pet:show"), | ||
| hide: legacyVoidProcedure("desktop:pet:hide"), | ||
| getCursorPosition: legacyProcedure( | ||
| "desktop:pet:cursor-position", | ||
| ipcVoidInputSchema, | ||
| petCursorPositionSchema | ||
| ), | ||
| setPanelMode: legacyProcedure( | ||
| "desktop:pet:panel-mode", | ||
| petPanelModeSchema, | ||
| petPanelModeResultSchema | ||
| ), | ||
| beginWindowDrag: legacyProcedure( | ||
| "desktop:pet:begin-window-drag", | ||
| petWindowDragStartSchema, | ||
| ipcVoidOutputSchema | ||
| ), | ||
| moveWindow: legacyProcedure( | ||
| "desktop:pet:move-window", | ||
| petWindowDragMoveSchema, | ||
| ipcVoidOutputSchema | ||
| ), | ||
| endWindowDrag: legacyProcedure( | ||
| "desktop:pet:end-window-drag", | ||
| petWindowPointerIdSchema, | ||
| ipcVoidOutputSchema | ||
| ), | ||
| setMouseInteractive: legacyProcedure( | ||
| "desktop:pet:mouse-interactive", | ||
| petWindowMouseInteractiveSchema, | ||
| ipcVoidOutputSchema | ||
| ) | ||
| }), | ||
| petModel: defineIPCService({ | ||
| modelProxyStream: legacyProcedure( | ||
| "desktop:pet:modelProxyStream", | ||
| modelProxyStreamSchema, | ||
| modelProxyStreamResultSchema | ||
| ) | ||
| }), | ||
| petVoice: defineIPCService({ | ||
| speak: legacyProcedure("desktop:pet:speak", speechTextSchema, booleanResultSchema), | ||
| cancelSpeech: legacyVoidProcedure("desktop:pet:cancelSpeech"), | ||
| voiceEngineStatus: legacyProcedure( | ||
| "desktop:pet:voiceEngineStatus", | ||
| ipcVoidInputSchema, | ||
| voiceEngineStatusSchema | ||
| ), | ||
| prewarmVoice: legacyProcedure( | ||
| "desktop:pet:prewarmVoice", | ||
| ipcVoidInputSchema, | ||
| booleanResultSchema | ||
| ), | ||
| installVoiceModel: legacyProcedure( | ||
| "desktop:pet:installVoiceModel", | ||
| voiceModelInstallSchema, | ||
| voiceEngineStatusSchema | ||
| ), | ||
| asrStart: legacyProcedure("desktop:pet:asrStart", ipcVoidInputSchema, okResultSchema), | ||
| asrAccept: legacyProcedure("desktop:pet:asrAccept", asrAcceptSchema, okResultSchema), | ||
| asrStop: legacyProcedure("desktop:pet:asrStop", ipcVoidInputSchema, textResultSchema) | ||
| }), | ||
| agents: defineIPCService({ | ||
| start: legacyProcedure("desktop:startAgent", startAgentSchema, agentStartResultSchema), | ||
| stop: legacyProcedure("desktop:stopAgent", agentProcessIdSchema, ipcVoidOutputSchema), | ||
| getStatus: legacyProcedure("desktop:getAgentStatus", agentProcessIdSchema, agentStatusSchema), | ||
| list: legacyProcedure("desktop:listAgents", ipcVoidInputSchema, agentListSchema) | ||
| }), | ||
| updates: defineIPCService({ | ||
| check: legacyProcedure("desktop:checkForUpdate", ipcVoidInputSchema, desktopUpdateInfoSchema), | ||
| getState: legacyProcedure( | ||
| "desktop:getUpdateState", | ||
| ipcVoidInputSchema, | ||
| desktopUpdateStateSchema | ||
| ), | ||
| getSettings: legacyProcedure( | ||
| "desktop:getUpdateSettings", | ||
| ipcVoidInputSchema, | ||
| desktopUpdateSettingsSchema | ||
| ), | ||
| setSettings: legacyProcedure( | ||
| "desktop:setUpdateSettings", | ||
| updateSettingsSchema, | ||
| desktopUpdateSettingsSchema | ||
| ), | ||
| download: legacyProcedure( | ||
| "desktop:downloadUpdate", | ||
| downloadUpdateUrlSchema, | ||
| booleanResultSchema | ||
| ) | ||
| }), | ||
| petAssets: defineIPCService({ | ||
| importDirectory: legacyProcedure( | ||
| "desktop:petAssets:importDirectory", | ||
| optionalPathInputSchema, | ||
| unknownResultSchema | ||
| ), | ||
| importMarketplace: legacyProcedure( | ||
| "desktop:petAssets:importMarketplace", | ||
| petMarketplaceImportSchema, | ||
| unknownResultSchema | ||
| ), | ||
| importArchiveBuffer: legacyProcedure( | ||
| "desktop:petAssets:importArchiveBuffer", | ||
| petArchiveImportSchema, | ||
| unknownResultSchema | ||
| ), | ||
| setActive: legacyProcedure( | ||
| "desktop:petAssets:setActive", | ||
| packIdInputSchema, | ||
| unknownResultSchema | ||
| ), | ||
| remove: legacyProcedure("desktop:petAssets:remove", packIdInputSchema, unknownResultSchema) | ||
| }), | ||
| connector: defineIPCService({ | ||
| getStatus: legacyProcedure( | ||
| "desktop:connector:getStatus", | ||
| ipcVoidInputSchema, | ||
| unknownResultSchema | ||
| ), | ||
| start: legacyProcedure( | ||
| "desktop:connector:start", | ||
| connectorStartSettingsSchema, | ||
| unknownResultSchema | ||
| ), | ||
| stop: legacyProcedure("desktop:connector:stop", ipcVoidInputSchema, unknownResultSchema), | ||
| scan: legacyProcedure("desktop:connector:scan", ipcVoidInputSchema, connectorScanOutputSchema), | ||
| scanRuntimes: legacyProcedure( | ||
| "desktop:connector:scanRuntimes", | ||
| forceOptionsSchema, | ||
| unknownResultSchema | ||
| ), | ||
| scanRuntimeSessions: legacyProcedure( | ||
| "desktop:connector:scanRuntimeSessions", | ||
| forceOptionsSchema, | ||
| unknownResultSchema | ||
| ), | ||
| installRuntime: legacyProcedure( | ||
| "desktop:connector:installRuntime", | ||
| runtimeIdInputSchema, | ||
| unknownResultSchema | ||
| ), | ||
| createBuddy: legacyProcedure( | ||
| "desktop:connector:createBuddy", | ||
| createConnectorBuddySchema, | ||
| unknownResultSchema | ||
| ), | ||
| getConnections: legacyProcedure( | ||
| "desktop:connector:getConnections", | ||
| ipcVoidInputSchema, | ||
| unknownResultSchema | ||
| ), | ||
| setConnectionEnabled: legacyProcedure( | ||
| "desktop:connector:setConnectionEnabled", | ||
| connectorConnectionEnabledSchema, | ||
| unknownResultSchema | ||
| ), | ||
| deleteConnection: legacyProcedure( | ||
| "desktop:connector:deleteConnection", | ||
| connectorDeleteSchema, | ||
| unknownResultSchema | ||
| ), | ||
| setConnectionWorkDir: legacyProcedure( | ||
| "desktop:connector:setConnectionWorkDir", | ||
| connectorWorkDirSchema, | ||
| unknownResultSchema | ||
| ) | ||
| }), | ||
| shortcuts: defineIPCService({ | ||
| reload: legacyProcedure("desktop:shortcuts:reload", ipcVoidInputSchema, unknownResultSchema), | ||
| suspend: legacyProcedure("desktop:shortcuts:suspend", ipcVoidInputSchema, unknownResultSchema), | ||
| resume: legacyProcedure("desktop:shortcuts:resume", ipcVoidInputSchema, unknownResultSchema) | ||
| }) | ||
| }); | ||
| export { | ||
| ipcProcedure, | ||
| defineIPCService, | ||
| defineIPCProtocol, | ||
| ipcProcedureChannel, | ||
| parseIPCProcedureInput, | ||
| parseIPCProcedureOutput, | ||
| ipcVoidInputSchema, | ||
| ipcVoidOutputSchema, | ||
| connectorStartSettingsSchema, | ||
| forceOptionsSchema, | ||
| desktopWindowFullscreenInputSchema, | ||
| desktopWindowChromeStateSchema, | ||
| runtimeIdInputSchema, | ||
| createConnectorBuddySchema, | ||
| connectorConnectionEnabledSchema, | ||
| connectorDeleteSchema, | ||
| connectorWorkDirSchema, | ||
| desktopSettingsPatchSchema, | ||
| optionalPathInputSchema, | ||
| petMarketplaceImportSchema, | ||
| petArchiveImportSchema, | ||
| packIdInputSchema, | ||
| startAgentSchema, | ||
| agentProcessIdSchema, | ||
| desktopNotificationSchema, | ||
| badgeCountSchema, | ||
| notificationModeSchema, | ||
| updateSettingsSchema, | ||
| downloadUpdateUrlSchema, | ||
| openAtLoginSchema, | ||
| voiceModelInstallSchema, | ||
| asrAcceptSchema, | ||
| speechTextSchema, | ||
| rendererLogSchema, | ||
| externalUrlSchema, | ||
| clipboardTextSchema, | ||
| readerOpenSchema, | ||
| readerIdInputSchema, | ||
| selectDirectorySchema, | ||
| communityAuthSnapshotSchema, | ||
| communityFetchJsonSchema, | ||
| modelProxyStreamSchema, | ||
| showCommunityInputSchema, | ||
| openCommunityLoginInputSchema, | ||
| showSettingsInputSchema, | ||
| petPanelModeSchema, | ||
| petWindowDragStartSchema, | ||
| petWindowDragMoveSchema, | ||
| petWindowPointerIdSchema, | ||
| petWindowMouseInteractiveSchema, | ||
| petCursorPositionSchema, | ||
| desktopIpcInvokeSchemas, | ||
| desktopIpcProtocol | ||
| }; |
| // 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", | ||
| POLL_UPDATED: "poll:updated", | ||
| NOTIFICATION_NEW: "notification:new", | ||
| SPACE_APP_LIST_CHANGED: "space-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/play-catalog/index.ts | ||
| var playCover = (id) => `/home-assets/plays/${id}.jpg`; | ||
| var playTemplate = (id) => ({ | ||
| template: { | ||
| kind: "cloud", | ||
| slug: id, | ||
| path: `apps/cloud/templates/${id}.template.json` | ||
| }, | ||
| materials: { cover: playCover(id) } | ||
| }); | ||
| var communityAction = (channelName) => ({ | ||
| kind: "public_channel", | ||
| channelName, | ||
| buddyTemplateSlug: channelName | ||
| }); | ||
| var roomAction = (namePrefix) => ({ | ||
| kind: "private_room", | ||
| namePrefix, | ||
| buddyTemplateSlug: namePrefix | ||
| }); | ||
| var cloudAction = (templateSlug, resourceTier = "lightweight") => ({ | ||
| kind: "cloud_deploy", | ||
| templateSlug, | ||
| buddyTemplateSlug: templateSlug, | ||
| resourceTier | ||
| }); | ||
| function getPlayBuddyUsername(templateSlug) { | ||
| const normalized = templateSlug.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 27) || "play"; | ||
| return `play_${normalized}`.slice(0, 32); | ||
| } | ||
| function getPlayBuddyEmail(templateSlug) { | ||
| return `${getPlayBuddyUsername(templateSlug)}@shadowob.bot`; | ||
| } | ||
| function cloudPlay(id, input) { | ||
| return { | ||
| id, | ||
| image: playCover(id), | ||
| status: "gated", | ||
| action: cloudAction(id, "lightweight"), | ||
| gates: { auth: "required", membership: "required", profile: "optional" }, | ||
| ...playTemplate(id), | ||
| ...input | ||
| }; | ||
| } | ||
| var DEFAULT_HOMEPLAY_CATALOG = [ | ||
| { | ||
| id: "retire-buddy", | ||
| image: playCover("retire-buddy"), | ||
| title: "\u9000\u4F11\u52A9\u624B", | ||
| titleEn: "RetireBuddy", | ||
| desc: "\u5E2E\u4F60\u89C4\u5212\u9000\u4F11\u751F\u6D3B\u3001\u8D22\u52A1\u81EA\u7531\u8DEF\u5F84\uFF0C24\u5C0F\u65F6\u6E29\u6696\u966A\u4F34\uFF0C\u8BA9\u544A\u522B\u804C\u573A\u53D8\u6210\u4EBA\u751F\u65B0\u7AE0\u8282\u3002", | ||
| descEn: "Plan your retirement and path to financial freedom with a warm 24/7 companion.", | ||
| category: "\u5FC3\u7406\u7597\u6108", | ||
| categoryEn: "Healing", | ||
| starts: "24.5k", | ||
| accentColor: "var(--shadow-accent)", | ||
| hot: true, | ||
| status: "available", | ||
| action: roomAction("retire-buddy"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("retire-buddy") | ||
| }, | ||
| { | ||
| id: "financial-freedom", | ||
| image: playCover("financial-freedom"), | ||
| title: "\u6211\u8D22\u5BCC\u81EA\u7531\u4E86\u5417\uFF1F", | ||
| titleEn: "Am I Free?", | ||
| desc: "\u8F93\u5165\u4F60\u7684\u8D44\u4EA7\u4E0E\u652F\u51FA\uFF0CAI \u4E3A\u4F60\u8BA1\u7B97\u8D22\u52A1\u81EA\u7531\u8DDD\u79BB\uFF0C\u7ED9\u51FA\u6E05\u6670\u7684\u8FBE\u6210\u8DEF\u7EBF\u56FE\u3002", | ||
| descEn: "Input your assets and expenses \u2014 get your financial freedom score and roadmap.", | ||
| category: "\u5FC3\u7406\u7597\u6108", | ||
| categoryEn: "Healing", | ||
| starts: "18.2k", | ||
| accentColor: "#f8e71c", | ||
| status: "available", | ||
| action: communityAction("financial-freedom"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("financial-freedom") | ||
| }, | ||
| { | ||
| id: "brain-fix", | ||
| image: playCover("brain-fix"), | ||
| title: "\u4E00\u5206\u949F\u4FEE\u590D\u4F60\u7684\u5927\u8111\uFF01", | ||
| titleEn: "1-Min Brain Fix", | ||
| desc: "\u79D1\u5B66\u51A5\u60F3 + \u5FAE\u547C\u5438\u7EC3\u4E60\uFF0C60\u79D2\u5185\u4ECE\u7126\u8651\u6A21\u5F0F\u5207\u6362\u5230\u4E13\u6CE8\u72B6\u6001\uFF0C\u5C61\u8BD5\u4E0D\u723D\u3002", | ||
| descEn: "Science-backed micro-meditation. Switch from anxious to focused in 60 seconds.", | ||
| category: "\u5FC3\u7406\u7597\u6108", | ||
| categoryEn: "Healing", | ||
| starts: "15.9k", | ||
| accentColor: "#a78bfa", | ||
| status: "available", | ||
| action: communityAction("brain-fix"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("brain-fix") | ||
| }, | ||
| { | ||
| id: "world-pulse", | ||
| image: playCover("world-pulse"), | ||
| title: "\u5730\u7403\u8109\u640F", | ||
| titleEn: "World Pulse", | ||
| desc: "\u5B9E\u65F6\u6293\u53D6\u5168\u7403\u91CD\u5927\u4E8B\u4EF6\uFF0C\u7528\u4E09\u53E5\u8BDD\u544A\u8BC9\u4F60\u4ECA\u5929\u771F\u6B63\u53D1\u751F\u4E86\u4EC0\u4E48\uFF0C\u65E0\u5E9F\u8BDD\u3002", | ||
| descEn: "Real-time global events in 3 sentences. No filler, just signal.", | ||
| category: "\u4E16\u754C\u8D44\u8BAF", | ||
| categoryEn: "World News", | ||
| starts: "14.1k", | ||
| accentColor: "#38bdf8", | ||
| status: "available", | ||
| action: communityAction("world-pulse"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("world-pulse") | ||
| }, | ||
| { | ||
| id: "daily-brief", | ||
| image: playCover("daily-brief"), | ||
| title: "\u6668\u95F4\u7B80\u62A5", | ||
| titleEn: "Morning Brief", | ||
| desc: "\u6BCF\u5929 7:00 \u63A8\u9001\u4E00\u4EFD\u5B9A\u5236\u65E9\u62A5\uFF1A\u56FD\u9645\u3001\u79D1\u6280\u3001\u5E02\u573A\u4E09\u5927\u677F\u5757\uFF0C\u8BFB\u5B8C\u53EA\u9700 3 \u5206\u949F\u3002", | ||
| descEn: "Custom morning digest at 7am \u2014 global news, tech, markets. 3-minute read.", | ||
| category: "\u4E16\u754C\u8D44\u8BAF", | ||
| categoryEn: "World News", | ||
| starts: "11.3k", | ||
| accentColor: "#fb923c", | ||
| status: "available", | ||
| action: roomAction("daily-brief"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("daily-brief") | ||
| }, | ||
| { | ||
| id: "ai-werewolf", | ||
| image: playCover("ai-werewolf"), | ||
| title: "AI \u72FC\u4EBA\u6740", | ||
| titleEn: "AI Werewolf", | ||
| desc: "AI \u62C5\u4EFB\u4E3B\u6301\uFF0C\u968F\u673A\u5206\u914D\u8EAB\u4EFD\uFF0C\u5728\u804A\u5929\u4E2D\u5C55\u5F00\u63A8\u7406\u4E0E\u535A\u5F08\uFF0C3 \u4EBA\u5373\u53EF\u5F00\u5C40\u3002", | ||
| descEn: "AI-hosted werewolf \u2014 roles assigned randomly, deduce, bluff, and vote. 3+ players.", | ||
| category: "\u4E92\u52A8\u6E38\u620F", | ||
| categoryEn: "Games", | ||
| starts: "20.8k", | ||
| accentColor: "#f87171", | ||
| hot: true, | ||
| status: "available", | ||
| action: communityAction("ai-werewolf"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("ai-werewolf") | ||
| }, | ||
| { | ||
| id: "code-arena", | ||
| image: playCover("code-arena"), | ||
| title: "\u4EE3\u7801\u64C2\u53F0", | ||
| titleEn: "Code Arena", | ||
| desc: "\u5B9E\u65F6\u7F16\u7A0B\u5BF9\u6218\uFF0CAI \u51FA\u9898\u3001\u8BA1\u65F6\u3001\u81EA\u52A8\u8BC4\u6D4B\uFF0C\u6311\u6218\u597D\u53CB\u6216\u5339\u914D\u964C\u751F\u5BF9\u624B\u3002", | ||
| descEn: "Real-time coding battles \u2014 AI generates problems, auto-judges, ranks you live.", | ||
| category: "\u4E92\u52A8\u6E38\u620F", | ||
| categoryEn: "Games", | ||
| starts: "8.6k", | ||
| accentColor: "#fbbf24", | ||
| status: "available", | ||
| action: communityAction("code-arena"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("code-arena") | ||
| }, | ||
| { | ||
| id: "gitstory", | ||
| image: playCover("gitstory"), | ||
| title: "GitStory", | ||
| titleEn: "GitStory", | ||
| desc: "\u628A\u4F60\u7684 GitHub \u63D0\u4EA4\u5386\u53F2\u53D8\u6210\u4E00\u672C\u81EA\u4F20\u5C0F\u8BF4\u2014\u2014AI \u5E2E\u4F60\u56DE\u987E\u6BCF\u4E00\u6BB5\u4EE3\u7801\u80CC\u540E\u7684\u6545\u4E8B\u3002", | ||
| descEn: "Turn your GitHub commits into an autobiography. Every line of code has a story.", | ||
| category: "\u9ED1\u5BA2\u4E0E\u753B\u5BB6", | ||
| categoryEn: "Hacker & Painter", | ||
| starts: "12.1k", | ||
| accentColor: "#34d399", | ||
| hot: true, | ||
| status: "available", | ||
| action: communityAction("gitstory"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("gitstory") | ||
| }, | ||
| { | ||
| id: "gstack", | ||
| image: playCover("gstack"), | ||
| title: "gstack", | ||
| titleEn: "gstack", | ||
| desc: "\u521B\u4E1A\u8005\u7684 AI \u53C2\u8C0B\uFF0C\u5E2E\u4F60\u5FEB\u901F\u9A8C\u8BC1\u5546\u4E1A\u60F3\u6CD5\u3001\u5206\u6790\u7ADE\u4E89\u683C\u5C40\u3001\u751F\u6210\u878D\u8D44\u6587\u4EF6\u3002", | ||
| descEn: "AI co-founder for founders. Validate ideas, map competitors, generate pitch decks.", | ||
| category: "\u9ED1\u5BA2\u4E0E\u753B\u5BB6", | ||
| categoryEn: "Hacker & Painter", | ||
| starts: "9.3k", | ||
| accentColor: "#f97316", | ||
| status: "available", | ||
| action: communityAction("gstack"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("gstack") | ||
| }, | ||
| { | ||
| id: "little-match-girl", | ||
| image: "/home-assets/topics/night-radio.jpg", | ||
| title: "\u5356\u706B\u67F4\u7684\u5C0F\u5973\u5B69", | ||
| titleEn: "Little Match Girl", | ||
| desc: "\u90E8\u7F72\u4E00\u4E2A\u4F1A\u63A8\u9500\u706B\u67F4\u7684\u7AE5\u8BDD Buddy\uFF0C\u8D2D\u4E70\u540E\u5728\u804A\u5929\u53F3\u4FA7\u6253\u5F00\u706B\u67F4\u52A8\u753B\u4ED8\u8D39\u6587\u4EF6\u3002", | ||
| descEn: "Deploy a fairy-tale Buddy who sells glowing matches and unlocks a paid HTML flame animation.", | ||
| category: "MVP \u5B9E\u9A8C", | ||
| categoryEn: "MVP Labs", | ||
| starts: "1.2k", | ||
| accentColor: "#f59e0b", | ||
| hot: true, | ||
| status: "gated", | ||
| action: cloudAction("little-match-girl", "lightweight"), | ||
| gates: { auth: "required", membership: "required", profile: "optional" }, | ||
| ...playTemplate("little-match-girl"), | ||
| materials: { cover: "/home-assets/topics/night-radio.jpg" } | ||
| }, | ||
| cloudPlay("agent-marketplace-buddy", { | ||
| title: "Agent Marketplace Buddy", | ||
| titleEn: "Agent Marketplace Buddy", | ||
| desc: "\u53EF\u7EC4\u5408\u4E13\u5BB6 agent \u5E02\u573A\uFF0C\u8986\u76D6\u5F00\u53D1\u3001\u5B89\u5168\u3001\u57FA\u7840\u8BBE\u65BD\u3001\u6570\u636E\u3001\u6587\u6863\u3001SEO \u548C workflow \u7F16\u6392\u3002", | ||
| descEn: "A composable specialist-agent marketplace for development, security, infra, data, docs, SEO, and workflow orchestration.", | ||
| category: "Buddy \u56E2\u961F", | ||
| categoryEn: "Buddy Teams", | ||
| starts: "16.4k", | ||
| accentColor: "#22d3ee", | ||
| hot: true | ||
| }), | ||
| cloudPlay("bmad-method-buddy", { | ||
| title: "BMAD \u65B9\u6CD5 Buddy", | ||
| titleEn: "BMAD Method Buddy", | ||
| desc: "\u5B8C\u6574 BMAD \u65B9\u6CD5\u8BBA\u56E2\u961F\uFF1A\u5206\u6790\u5E08\u3001PM\u3001\u67B6\u6784\u5E08\u3001Scrum Master\u3001\u5F00\u53D1\u3001QA\uFF0C\u8D2F\u7A7F\u89C4\u5212\u5230\u4EA4\u4ED8\u3002", | ||
| descEn: "A full BMAD method team: analyst, PM, architect, scrum master, dev, and QA from planning to delivery.", | ||
| category: "Buddy \u56E2\u961F", | ||
| categoryEn: "Buddy Teams", | ||
| starts: "13.7k", | ||
| accentColor: "#60a5fa" | ||
| }), | ||
| cloudPlay("claude-ads-buddy", { | ||
| title: "Claude Ads Buddy", | ||
| titleEn: "Claude Ads Buddy", | ||
| desc: "\u4ED8\u8D39\u6295\u653E\u8BCA\u65AD\u3001\u9884\u7B97\u5EFA\u6A21\u3001\u521B\u610F\u5BA1\u67E5\u3001\u8FFD\u8E2A\u95EE\u9898\u548C\u843D\u5730\u9875\u74F6\u9888\u5206\u6790\u3002", | ||
| descEn: "Paid ads audits, budget models, creative review, tracking issues, and landing-page bottlenecks.", | ||
| category: "\u8425\u9500\u6280\u80FD", | ||
| categoryEn: "Marketing Skills", | ||
| starts: "10.8k", | ||
| accentColor: "#fb7185" | ||
| }), | ||
| cloudPlay("claude-seo-buddy", { | ||
| title: "Claude SEO Buddy", | ||
| titleEn: "Claude SEO Buddy", | ||
| desc: "SEO \u5185\u5BB9\u548C\u6280\u672F\u5BA1\u67E5\u56E2\u961F\uFF0C\u8986\u76D6\u5173\u952E\u8BCD\u3001\u5185\u94FE\u3001\u7ED3\u6784\u5316\u6570\u636E\u3001\u9875\u9762\u8D28\u91CF\u548C\u589E\u957F\u8BA1\u5212\u3002", | ||
| descEn: "SEO content and technical review for keywords, links, schema, quality, and growth plans.", | ||
| category: "\u8425\u9500\u6280\u80FD", | ||
| categoryEn: "Marketing Skills", | ||
| starts: "12.6k", | ||
| accentColor: "#84cc16" | ||
| }), | ||
| cloudPlay("everything-claude-code-buddy", { | ||
| title: "Everything Claude Code Buddy", | ||
| titleEn: "Everything Claude Code Buddy", | ||
| desc: "Claude Code \u5DE5\u4F5C\u6D41\u3001\u547D\u4EE4\u548C\u5DE5\u7A0B\u5B9E\u8DF5\u5408\u96C6\uFF0C\u9002\u5408\u7814\u53D1\u56E2\u961F\u6C89\u6DC0\u81EA\u52A8\u5316\u80FD\u529B\u3002", | ||
| descEn: "Claude Code workflows, commands, and engineering practices for automation-heavy teams.", | ||
| category: "\u5F00\u53D1\u6280\u80FD", | ||
| categoryEn: "Developer Skills", | ||
| starts: "19.2k", | ||
| accentColor: "#c084fc", | ||
| hot: true | ||
| }), | ||
| cloudPlay("google-workspace-buddy", { | ||
| title: "Google Workspace Buddy", | ||
| titleEn: "Google Workspace Buddy", | ||
| desc: "\u628A Docs\u3001Sheets\u3001Drive\u3001\u65E5\u5386\u548C\u90AE\u4EF6\u534F\u4F5C\u7F16\u6392\u5230 Buddy \u5DE5\u4F5C\u6D41\u91CC\u3002", | ||
| descEn: "Coordinate Docs, Sheets, Drive, Calendar, and email collaboration through Buddy workflows.", | ||
| category: "\u6548\u7387\u5DE5\u5177", | ||
| categoryEn: "Productivity", | ||
| starts: "9.9k", | ||
| accentColor: "#34d399" | ||
| }), | ||
| cloudPlay("gsd-buddy", { | ||
| title: "GSD Buddy", | ||
| titleEn: "GSD Buddy", | ||
| desc: "\u6267\u884C\u529B\u56E2\u961F\uFF1A\u62C6\u89E3\u4EFB\u52A1\u3001\u6392\u4F18\u5148\u7EA7\u3001\u63A8\u52A8\u51B3\u7B56\u3001\u8FFD\u8E2A\u963B\u585E\uFF0C\u5E2E\u56E2\u961F\u6301\u7EED get stuff done\u3002", | ||
| descEn: "Execution team for task breakdown, priority, decisions, blockers, and getting stuff done.", | ||
| category: "\u6548\u7387\u5DE5\u5177", | ||
| categoryEn: "Productivity", | ||
| starts: "17.5k", | ||
| accentColor: "#facc15", | ||
| hot: true | ||
| }), | ||
| cloudPlay("gstack-buddy", { | ||
| title: "gstack \u6218\u7565 Buddy", | ||
| titleEn: "gstack Strategy Buddy", | ||
| desc: "YC \u98CE\u683C\u4EA7\u54C1\u538B\u529B\u6D4B\u8BD5\u3001CEO \u89C6\u89D2\u8303\u56F4\u8BC4\u5BA1\u3001\u8C03\u67E5\u7EAA\u5F8B\u3001\u5468\u590D\u76D8\u548C gstack \u811A\u672C\u5DE5\u5177\u3002", | ||
| descEn: "YC-style product pressure testing, CEO scope review, investigation discipline, retros, and gstack scripts.", | ||
| category: "\u9ED1\u5BA2\u4E0E\u753B\u5BB6", | ||
| categoryEn: "Hacker & Painter", | ||
| starts: "15.1k", | ||
| accentColor: "#fb923c", | ||
| hot: true | ||
| }), | ||
| cloudPlay("marketingskills-buddy", { | ||
| title: "\u8425\u9500\u6280\u80FD Buddy", | ||
| titleEn: "MarketingSkills Buddy", | ||
| desc: "\u589E\u957F\u56E2\u961F\u7684\u8425\u9500\u534F\u4F5C Agent\uFF0C\u8986\u76D6 CRO\u3001\u6587\u6848\u3001SEO\u3001\u4ED8\u8D39\u3001\u90AE\u4EF6\u548C\u589E\u957F\u51B3\u7B56\u3002", | ||
| descEn: "Marketing collaboration agents for CRO, copy, SEO, paid, email, and growth decisions.", | ||
| category: "\u8425\u9500\u6280\u80FD", | ||
| categoryEn: "Marketing Skills", | ||
| starts: "11.7k", | ||
| accentColor: "#f472b6" | ||
| }), | ||
| cloudPlay("scientific-skills-buddy", { | ||
| title: "\u79D1\u7814\u6280\u80FD Buddy", | ||
| titleEn: "Scientific Skills Buddy", | ||
| desc: "\u7814\u7A76\u9605\u8BFB\u3001\u5B9E\u9A8C\u8BBE\u8BA1\u3001\u8BBA\u6587\u7ED3\u6784\u3001\u6570\u636E\u5206\u6790\u548C\u5B66\u672F\u5199\u4F5C\u534F\u4F5C\u56E2\u961F\u3002", | ||
| descEn: "Research reading, experiment design, paper structure, data analysis, and academic writing workflows.", | ||
| category: "\u79D1\u7814\u6280\u80FD", | ||
| categoryEn: "Research Skills", | ||
| starts: "7.8k", | ||
| accentColor: "#38bdf8" | ||
| }), | ||
| cloudPlay("seomachine-buddy", { | ||
| title: "SEO Machine Buddy", | ||
| titleEn: "SEO Machine Buddy", | ||
| desc: "\u6301\u7EED\u8FD0\u884C\u7684 SEO \u673A\u5668\uFF1A\u9009\u9898\u3001brief\u3001\u5185\u5BB9\u5BA1\u67E5\u3001\u6280\u672F\u68C0\u67E5\u548C\u6392\u540D\u590D\u76D8\u3002", | ||
| descEn: "An always-on SEO machine for topics, briefs, review, technical checks, and ranking retros.", | ||
| category: "\u8425\u9500\u6280\u80FD", | ||
| categoryEn: "Marketing Skills", | ||
| starts: "10.2k", | ||
| accentColor: "#a3e635" | ||
| }), | ||
| cloudPlay("slavingia-skills-buddy", { | ||
| title: "Slavingia Skills Buddy", | ||
| titleEn: "Slavingia Skills Buddy", | ||
| desc: "\u521B\u4F5C\u8005\u548C\u72EC\u7ACB\u5F00\u53D1\u8005\u7684\u6280\u80FD\u5E93\uFF0C\u8986\u76D6\u5199\u4F5C\u3001\u4EA7\u54C1\u3001\u589E\u957F\u3001\u793E\u533A\u548C\u53D1\u5E03\u8282\u594F\u3002", | ||
| descEn: "A creator and indie-builder skill stack for writing, product, growth, community, and shipping rhythm.", | ||
| category: "\u521B\u4F5C\u8005\u6280\u80FD", | ||
| categoryEn: "Creator Skills", | ||
| starts: "8.4k", | ||
| accentColor: "#f97316" | ||
| }), | ||
| cloudPlay("superclaude-buddy", { | ||
| title: "SuperClaude Buddy", | ||
| titleEn: "SuperClaude Buddy", | ||
| desc: "SuperClaude \u6307\u4EE4\u3001\u89D2\u8272\u548C\u5DE5\u4F5C\u6D41\u80FD\u529B\uFF0C\u5E2E\u52A9\u56E2\u961F\u628A Claude \u7528\u6210\u7ED3\u6784\u5316\u5DE5\u7A0B\u4F19\u4F34\u3002", | ||
| descEn: "SuperClaude commands, personas, and workflows for structured engineering collaboration.", | ||
| category: "\u5F00\u53D1\u6280\u80FD", | ||
| categoryEn: "Developer Skills", | ||
| starts: "18.9k", | ||
| accentColor: "#818cf8", | ||
| hot: true | ||
| }), | ||
| cloudPlay("superpowers-buddy", { | ||
| title: "Superpowers Buddy", | ||
| titleEn: "Superpowers Buddy", | ||
| desc: "\u4E2A\u4EBA\u751F\u4EA7\u529B\u8D85\u80FD\u529B\u7EC4\u5408\uFF1A\u9605\u8BFB\u3001\u5199\u4F5C\u3001\u4EFB\u52A1\u3001\u7814\u7A76\u3001\u81EA\u52A8\u5316\u548C\u590D\u76D8\u3002", | ||
| descEn: "Personal productivity superpowers for reading, writing, tasks, research, automation, and retros.", | ||
| category: "\u6548\u7387\u5DE5\u5177", | ||
| categoryEn: "Productivity", | ||
| starts: "12.4k", | ||
| accentColor: "#2dd4bf" | ||
| }), | ||
| { | ||
| id: "e-wife", | ||
| image: playCover("e-wife"), | ||
| title: "\u7535\u5B50\u8001\u5A46", | ||
| titleEn: "E-Wife", | ||
| desc: "\u4E00\u4E2A\u5E26\u6709\u966A\u4F34\u611F\u7684\u865A\u62DF\u751F\u6D3B\u4F19\u4F34\u73A9\u6CD5\uFF0C\u540E\u7EED\u4F1A\u63A5\u5165\u4E2A\u6027\u5316\u8BB0\u5FC6\u548C\u79C1\u6709\u623F\u95F4\u3002", | ||
| descEn: "A companion-style virtual life partner play, later connected to memory and private rooms.", | ||
| category: "\u5FC3\u7406\u7597\u6108", | ||
| categoryEn: "Healing", | ||
| starts: "22.0k", | ||
| accentColor: "#f0abfc", | ||
| status: "available", | ||
| action: roomAction("e-wife"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("e-wife") | ||
| } | ||
| ]; | ||
| function getDefaultHomePlay(playId) { | ||
| return DEFAULT_HOMEPLAY_CATALOG.find((play) => play.id === playId) ?? null; | ||
| } | ||
| export { | ||
| getPlayBuddyUsername, | ||
| getPlayBuddyEmail, | ||
| DEFAULT_HOMEPLAY_CATALOG, | ||
| getDefaultHomePlay | ||
| }; |
| 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' | 'space_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: 'space_app_copilot'; | ||
| /** Space App installation id when the current surface is an installed Space App. */ | ||
| spaceAppId?: 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' | 'space_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' | 'space_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 SpaceAppMessageCard { | ||
| id?: string; | ||
| kind: 'space_app'; | ||
| version?: number; | ||
| appKey: string; | ||
| title: string; | ||
| description?: string; | ||
| label?: string; | ||
| action?: { | ||
| mode: 'open_space_app'; | ||
| path?: string; | ||
| }; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| } | ||
| interface PollMessageCard { | ||
| id: string; | ||
| kind: 'poll'; | ||
| version: number; | ||
| pollId: string; | ||
| title: string; | ||
| allowMultiselect?: boolean; | ||
| expiresAt?: string; | ||
| status?: 'active' | 'ended'; | ||
| 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 | SpaceAppMessageCard | PollMessageCard | 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 isPollMessageCard(card: unknown): card is PollMessageCard; | ||
| declare function getPollMessageCards(metadata: Pick<MessageMetadata, 'cards'> | null | undefined): PollMessageCard[]; | ||
| interface PollOptionSummary { | ||
| id: string; | ||
| answerId: number; | ||
| text: string; | ||
| emoji?: string | null; | ||
| voteCount: number; | ||
| votedByViewer: boolean; | ||
| } | ||
| interface MessagePollSummary { | ||
| id: string; | ||
| messageId: string; | ||
| channelId: string; | ||
| serverId?: string | null; | ||
| creatorId: string; | ||
| question: string; | ||
| allowMultiselect: boolean; | ||
| status: 'active' | 'ended'; | ||
| layoutType: number; | ||
| expiresAt: string; | ||
| finalizedAt?: string | null; | ||
| isExpired: boolean; | ||
| isFinalized: boolean; | ||
| totalVotes: number; | ||
| viewerOptionIds: string[]; | ||
| viewerAnswerIds: number[]; | ||
| viewerCanEnd?: boolean; | ||
| options: PollOptionSummary[]; | ||
| createdAt: string; | ||
| updatedAt: string; | ||
| } | ||
| interface PollVoterSummary { | ||
| id: string; | ||
| username: string; | ||
| displayName: string | null; | ||
| avatarUrl: string | null; | ||
| votedAt: string; | ||
| } | ||
| interface PollVotersPage { | ||
| voters: PollVoterSummary[]; | ||
| hasMore: boolean; | ||
| nextCursor?: string | null; | ||
| } | ||
| 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 { buildMessageCopilotContextMetadata as $, type Attachment as A, type BuddyInboxTaskRefMetadata as B, type CommerceMessageCard as C, type SpaceAppMessageCard as D, type TaskMessageCard as E, type TaskMessageCardReply as F, type GenericMessageCard as G, type TaskMessageCardTag as H, type TaskMessageExpectedArtifact as I, type TaskMessageOutputContract as J, type TaskMessagePrivacy as K, type TaskMessagePrivacyDataClass as L, MESSAGE_AGENT_CHAIN_METADATA_KEY as M, type Notification as N, type OAuthLinkCard as O, type PaidFileCard as P, type TaskMessageRequirementSkill as Q, type ReactionGroup as R, type SendMessageRequest as S, type TaskContextPack as T, type TaskMessageRequirementTool as U, type TaskMessageRequirements as V, type TaskMessageSubmitCommand as W, type TaskResultMessageCard as X, type Thread as Y, type UpdateMessageRequest as Z, buildMessageAgentChainMetadata as _, type BuddyInboxTaskResultMetadata as a, getCommerceMessageCards as a0, getOAuthLinkMessageCards as a1, getPaidFileMessageCards as a2, getPollMessageCards as a3, isCommerceMessageCard as a4, isMessageAgentChainMetadata as a5, isMessageCopilotContext as a6, isOAuthLinkMessageCard as a7, isPaidFileMessageCard as a8, isPollMessageCard as a9, parseBuddyInboxTaskResultMetadata as aa, 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 MessagePollSummary as t, type MessageReferenceCard as u, type NotificationType as v, type PollMessageCard as w, type PollOptionSummary as x, type PollVoterSummary as y, type PollVotersPage 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' | 'space_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: 'space_app_copilot'; | ||
| /** Space App installation id when the current surface is an installed Space App. */ | ||
| spaceAppId?: 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' | 'space_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' | 'space_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 SpaceAppMessageCard { | ||
| id?: string; | ||
| kind: 'space_app'; | ||
| version?: number; | ||
| appKey: string; | ||
| title: string; | ||
| description?: string; | ||
| label?: string; | ||
| action?: { | ||
| mode: 'open_space_app'; | ||
| path?: string; | ||
| }; | ||
| data?: Record<string, unknown>; | ||
| [key: string]: unknown; | ||
| } | ||
| interface PollMessageCard { | ||
| id: string; | ||
| kind: 'poll'; | ||
| version: number; | ||
| pollId: string; | ||
| title: string; | ||
| allowMultiselect?: boolean; | ||
| expiresAt?: string; | ||
| status?: 'active' | 'ended'; | ||
| 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 | SpaceAppMessageCard | PollMessageCard | 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 isPollMessageCard(card: unknown): card is PollMessageCard; | ||
| declare function getPollMessageCards(metadata: Pick<MessageMetadata, 'cards'> | null | undefined): PollMessageCard[]; | ||
| interface PollOptionSummary { | ||
| id: string; | ||
| answerId: number; | ||
| text: string; | ||
| emoji?: string | null; | ||
| voteCount: number; | ||
| votedByViewer: boolean; | ||
| } | ||
| interface MessagePollSummary { | ||
| id: string; | ||
| messageId: string; | ||
| channelId: string; | ||
| serverId?: string | null; | ||
| creatorId: string; | ||
| question: string; | ||
| allowMultiselect: boolean; | ||
| status: 'active' | 'ended'; | ||
| layoutType: number; | ||
| expiresAt: string; | ||
| finalizedAt?: string | null; | ||
| isExpired: boolean; | ||
| isFinalized: boolean; | ||
| totalVotes: number; | ||
| viewerOptionIds: string[]; | ||
| viewerAnswerIds: number[]; | ||
| viewerCanEnd?: boolean; | ||
| options: PollOptionSummary[]; | ||
| createdAt: string; | ||
| updatedAt: string; | ||
| } | ||
| interface PollVoterSummary { | ||
| id: string; | ||
| username: string; | ||
| displayName: string | null; | ||
| avatarUrl: string | null; | ||
| votedAt: string; | ||
| } | ||
| interface PollVotersPage { | ||
| voters: PollVoterSummary[]; | ||
| hasMore: boolean; | ||
| nextCursor?: string | null; | ||
| } | ||
| 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 { buildMessageCopilotContextMetadata as $, type Attachment as A, type BuddyInboxTaskRefMetadata as B, type CommerceMessageCard as C, type SpaceAppMessageCard as D, type TaskMessageCard as E, type TaskMessageCardReply as F, type GenericMessageCard as G, type TaskMessageCardTag as H, type TaskMessageExpectedArtifact as I, type TaskMessageOutputContract as J, type TaskMessagePrivacy as K, type TaskMessagePrivacyDataClass as L, MESSAGE_AGENT_CHAIN_METADATA_KEY as M, type Notification as N, type OAuthLinkCard as O, type PaidFileCard as P, type TaskMessageRequirementSkill as Q, type ReactionGroup as R, type SendMessageRequest as S, type TaskContextPack as T, type TaskMessageRequirementTool as U, type TaskMessageRequirements as V, type TaskMessageSubmitCommand as W, type TaskResultMessageCard as X, type Thread as Y, type UpdateMessageRequest as Z, buildMessageAgentChainMetadata as _, type BuddyInboxTaskResultMetadata as a, getCommerceMessageCards as a0, getOAuthLinkMessageCards as a1, getPaidFileMessageCards as a2, getPollMessageCards as a3, isCommerceMessageCard as a4, isMessageAgentChainMetadata as a5, isMessageCopilotContext as a6, isOAuthLinkMessageCard as a7, isPaidFileMessageCard as a8, isPollMessageCard as a9, parseBuddyInboxTaskResultMetadata as aa, 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 MessagePollSummary as t, type MessageReferenceCard as u, type NotificationType as v, type PollMessageCard as w, type PollOptionSummary as x, type PollVoterSummary as y, type PollVotersPage as z }; |
| "use strict"; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
| // src/node/device-identity.ts | ||
| var device_identity_exports = {}; | ||
| __export(device_identity_exports, { | ||
| SHADOW_DEVICE_IDENTITY_FILENAME: () => SHADOW_DEVICE_IDENTITY_FILENAME, | ||
| SHADOW_DEVICE_IDENTITY_VERSION: () => SHADOW_DEVICE_IDENTITY_VERSION, | ||
| normalizeShadowDeviceFingerprint: () => normalizeShadowDeviceFingerprint, | ||
| resolveShadowDeviceIdentitySync: () => resolveShadowDeviceIdentitySync, | ||
| shadowDeviceIdentityPath: () => shadowDeviceIdentityPath, | ||
| shadowStateRoot: () => shadowStateRoot | ||
| }); | ||
| module.exports = __toCommonJS(device_identity_exports); | ||
| var import_node_crypto = require("crypto"); | ||
| var import_node_fs = require("fs"); | ||
| var import_node_os = require("os"); | ||
| var import_node_path = require("path"); | ||
| var SHADOW_DEVICE_IDENTITY_VERSION = 1; | ||
| var SHADOW_DEVICE_IDENTITY_FILENAME = "device-identity.json"; | ||
| var LOCK_RETRY_COUNT = 100; | ||
| var LOCK_RETRY_MS = 20; | ||
| var STALE_LOCK_MS = 1e4; | ||
| var waitBuffer = new Int32Array(new SharedArrayBuffer(4)); | ||
| function wait(ms) { | ||
| Atomics.wait(waitBuffer, 0, 0, ms); | ||
| } | ||
| function normalizeShadowDeviceFingerprint(value) { | ||
| if (typeof value !== "string") return null; | ||
| const fingerprint = value.trim(); | ||
| if (fingerprint.length < 8 || fingerprint.length > 128 || /\s/.test(fingerprint)) return null; | ||
| return fingerprint; | ||
| } | ||
| function shadowStateRoot(rootDir) { | ||
| const configured = rootDir ?? process.env.SHADOWOB_HOME?.trim(); | ||
| return configured ? (0, import_node_path.resolve)(configured) : (0, import_node_path.join)((0, import_node_os.homedir)(), ".shadowob"); | ||
| } | ||
| function shadowDeviceIdentityPath(rootDir) { | ||
| return (0, import_node_path.join)(shadowStateRoot(rootDir), SHADOW_DEVICE_IDENTITY_FILENAME); | ||
| } | ||
| function parseIdentity(path) { | ||
| let value; | ||
| try { | ||
| value = JSON.parse((0, import_node_fs.readFileSync)(path, "utf8")); | ||
| } catch (error) { | ||
| if (error.code === "ENOENT") throw error; | ||
| throw new Error( | ||
| `Shadow device identity is unreadable at ${path}. Repair or remove it before reconnecting.`, | ||
| { cause: error } | ||
| ); | ||
| } | ||
| const record = value && typeof value === "object" ? value : null; | ||
| const fingerprint = normalizeShadowDeviceFingerprint(record?.fingerprint); | ||
| const createdAt = typeof record?.createdAt === "string" ? record.createdAt : ""; | ||
| const createdBy = record?.createdBy; | ||
| if (record?.version !== SHADOW_DEVICE_IDENTITY_VERSION || !fingerprint || !createdAt || createdBy !== "cli" && createdBy !== "desktop" && createdBy !== "unknown") { | ||
| throw new Error( | ||
| `Shadow device identity is invalid at ${path}. Repair or remove it before reconnecting.` | ||
| ); | ||
| } | ||
| return { | ||
| version: SHADOW_DEVICE_IDENTITY_VERSION, | ||
| fingerprint, | ||
| createdAt, | ||
| createdBy | ||
| }; | ||
| } | ||
| function acquireIdentityLock(lockPath) { | ||
| for (let attempt = 0; attempt < LOCK_RETRY_COUNT; attempt += 1) { | ||
| try { | ||
| (0, import_node_fs.mkdirSync)(lockPath, { mode: 448 }); | ||
| return; | ||
| } catch (error) { | ||
| if (error.code !== "EEXIST") throw error; | ||
| try { | ||
| if (Date.now() - (0, import_node_fs.statSync)(lockPath).mtimeMs > STALE_LOCK_MS) { | ||
| (0, import_node_fs.rmSync)(lockPath, { recursive: true, force: true }); | ||
| continue; | ||
| } | ||
| } catch { | ||
| continue; | ||
| } | ||
| wait(LOCK_RETRY_MS); | ||
| } | ||
| } | ||
| throw new Error(`Timed out waiting for the Shadow device identity lock at ${lockPath}`); | ||
| } | ||
| function resolveShadowDeviceIdentitySync(options = {}) { | ||
| const root = shadowStateRoot(options.rootDir); | ||
| const path = shadowDeviceIdentityPath(root); | ||
| const lockPath = (0, import_node_path.join)(root, ".device-identity.lock"); | ||
| (0, import_node_fs.mkdirSync)(root, { recursive: true, mode: 448 }); | ||
| (0, import_node_fs.chmodSync)(root, 448); | ||
| acquireIdentityLock(lockPath); | ||
| try { | ||
| try { | ||
| const identity2 = parseIdentity(path); | ||
| (0, import_node_fs.chmodSync)(path, 384); | ||
| return identity2; | ||
| } catch (error) { | ||
| if (error.code !== "ENOENT") throw error; | ||
| } | ||
| const legacy = normalizeShadowDeviceFingerprint(options.legacyFingerprint); | ||
| const fingerprint = legacy ?? `device_${(options.randomId ?? import_node_crypto.randomUUID)()}`; | ||
| const identity = { | ||
| version: SHADOW_DEVICE_IDENTITY_VERSION, | ||
| fingerprint, | ||
| createdAt: (options.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(), | ||
| createdBy: options.createdBy ?? "unknown" | ||
| }; | ||
| const temporaryPath = `${path}.${process.pid}.${(0, import_node_crypto.randomUUID)()}.tmp`; | ||
| (0, import_node_fs.writeFileSync)(temporaryPath, `${JSON.stringify(identity, null, 2)} | ||
| `, { | ||
| encoding: "utf8", | ||
| mode: 384, | ||
| flag: "wx" | ||
| }); | ||
| (0, import_node_fs.renameSync)(temporaryPath, path); | ||
| (0, import_node_fs.chmodSync)(path, 384); | ||
| return identity; | ||
| } finally { | ||
| (0, import_node_fs.rmSync)(lockPath, { recursive: true, force: true }); | ||
| } | ||
| } | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| SHADOW_DEVICE_IDENTITY_FILENAME, | ||
| SHADOW_DEVICE_IDENTITY_VERSION, | ||
| normalizeShadowDeviceFingerprint, | ||
| resolveShadowDeviceIdentitySync, | ||
| shadowDeviceIdentityPath, | ||
| shadowStateRoot | ||
| }); |
| declare const SHADOW_DEVICE_IDENTITY_VERSION: 1; | ||
| declare const SHADOW_DEVICE_IDENTITY_FILENAME = "device-identity.json"; | ||
| interface ShadowDeviceIdentity { | ||
| version: typeof SHADOW_DEVICE_IDENTITY_VERSION; | ||
| fingerprint: string; | ||
| createdAt: string; | ||
| createdBy: 'cli' | 'desktop' | 'unknown'; | ||
| } | ||
| interface ResolveShadowDeviceIdentityOptions { | ||
| rootDir?: string; | ||
| legacyFingerprint?: string | null; | ||
| createdBy?: ShadowDeviceIdentity['createdBy']; | ||
| now?: () => Date; | ||
| randomId?: () => string; | ||
| } | ||
| declare function normalizeShadowDeviceFingerprint(value: unknown): string | null; | ||
| declare function shadowStateRoot(rootDir?: string): string; | ||
| declare function shadowDeviceIdentityPath(rootDir?: string): string; | ||
| /** | ||
| * Resolve the random, machine-local Shadow identity shared by Desktop and CLI. | ||
| * | ||
| * The identity intentionally does not derive from a serial number, MAC address, or platform UUID. | ||
| * The lock plus atomic rename guarantees that concurrent first launches converge on one value. | ||
| */ | ||
| declare function resolveShadowDeviceIdentitySync(options?: ResolveShadowDeviceIdentityOptions): ShadowDeviceIdentity; | ||
| export { type ResolveShadowDeviceIdentityOptions, SHADOW_DEVICE_IDENTITY_FILENAME, SHADOW_DEVICE_IDENTITY_VERSION, type ShadowDeviceIdentity, normalizeShadowDeviceFingerprint, resolveShadowDeviceIdentitySync, shadowDeviceIdentityPath, shadowStateRoot }; |
| declare const SHADOW_DEVICE_IDENTITY_VERSION: 1; | ||
| declare const SHADOW_DEVICE_IDENTITY_FILENAME = "device-identity.json"; | ||
| interface ShadowDeviceIdentity { | ||
| version: typeof SHADOW_DEVICE_IDENTITY_VERSION; | ||
| fingerprint: string; | ||
| createdAt: string; | ||
| createdBy: 'cli' | 'desktop' | 'unknown'; | ||
| } | ||
| interface ResolveShadowDeviceIdentityOptions { | ||
| rootDir?: string; | ||
| legacyFingerprint?: string | null; | ||
| createdBy?: ShadowDeviceIdentity['createdBy']; | ||
| now?: () => Date; | ||
| randomId?: () => string; | ||
| } | ||
| declare function normalizeShadowDeviceFingerprint(value: unknown): string | null; | ||
| declare function shadowStateRoot(rootDir?: string): string; | ||
| declare function shadowDeviceIdentityPath(rootDir?: string): string; | ||
| /** | ||
| * Resolve the random, machine-local Shadow identity shared by Desktop and CLI. | ||
| * | ||
| * The identity intentionally does not derive from a serial number, MAC address, or platform UUID. | ||
| * The lock plus atomic rename guarantees that concurrent first launches converge on one value. | ||
| */ | ||
| declare function resolveShadowDeviceIdentitySync(options?: ResolveShadowDeviceIdentityOptions): ShadowDeviceIdentity; | ||
| export { type ResolveShadowDeviceIdentityOptions, SHADOW_DEVICE_IDENTITY_FILENAME, SHADOW_DEVICE_IDENTITY_VERSION, type ShadowDeviceIdentity, normalizeShadowDeviceFingerprint, resolveShadowDeviceIdentitySync, shadowDeviceIdentityPath, shadowStateRoot }; |
| // src/node/device-identity.ts | ||
| import { randomUUID } from "crypto"; | ||
| import { | ||
| chmodSync, | ||
| mkdirSync, | ||
| readFileSync, | ||
| renameSync, | ||
| rmSync, | ||
| statSync, | ||
| writeFileSync | ||
| } from "fs"; | ||
| import { homedir } from "os"; | ||
| import { join, resolve } from "path"; | ||
| var SHADOW_DEVICE_IDENTITY_VERSION = 1; | ||
| var SHADOW_DEVICE_IDENTITY_FILENAME = "device-identity.json"; | ||
| var LOCK_RETRY_COUNT = 100; | ||
| var LOCK_RETRY_MS = 20; | ||
| var STALE_LOCK_MS = 1e4; | ||
| var waitBuffer = new Int32Array(new SharedArrayBuffer(4)); | ||
| function wait(ms) { | ||
| Atomics.wait(waitBuffer, 0, 0, ms); | ||
| } | ||
| function normalizeShadowDeviceFingerprint(value) { | ||
| if (typeof value !== "string") return null; | ||
| const fingerprint = value.trim(); | ||
| if (fingerprint.length < 8 || fingerprint.length > 128 || /\s/.test(fingerprint)) return null; | ||
| return fingerprint; | ||
| } | ||
| function shadowStateRoot(rootDir) { | ||
| const configured = rootDir ?? process.env.SHADOWOB_HOME?.trim(); | ||
| return configured ? resolve(configured) : join(homedir(), ".shadowob"); | ||
| } | ||
| function shadowDeviceIdentityPath(rootDir) { | ||
| return join(shadowStateRoot(rootDir), SHADOW_DEVICE_IDENTITY_FILENAME); | ||
| } | ||
| function parseIdentity(path) { | ||
| let value; | ||
| try { | ||
| value = JSON.parse(readFileSync(path, "utf8")); | ||
| } catch (error) { | ||
| if (error.code === "ENOENT") throw error; | ||
| throw new Error( | ||
| `Shadow device identity is unreadable at ${path}. Repair or remove it before reconnecting.`, | ||
| { cause: error } | ||
| ); | ||
| } | ||
| const record = value && typeof value === "object" ? value : null; | ||
| const fingerprint = normalizeShadowDeviceFingerprint(record?.fingerprint); | ||
| const createdAt = typeof record?.createdAt === "string" ? record.createdAt : ""; | ||
| const createdBy = record?.createdBy; | ||
| if (record?.version !== SHADOW_DEVICE_IDENTITY_VERSION || !fingerprint || !createdAt || createdBy !== "cli" && createdBy !== "desktop" && createdBy !== "unknown") { | ||
| throw new Error( | ||
| `Shadow device identity is invalid at ${path}. Repair or remove it before reconnecting.` | ||
| ); | ||
| } | ||
| return { | ||
| version: SHADOW_DEVICE_IDENTITY_VERSION, | ||
| fingerprint, | ||
| createdAt, | ||
| createdBy | ||
| }; | ||
| } | ||
| function acquireIdentityLock(lockPath) { | ||
| for (let attempt = 0; attempt < LOCK_RETRY_COUNT; attempt += 1) { | ||
| try { | ||
| mkdirSync(lockPath, { mode: 448 }); | ||
| return; | ||
| } catch (error) { | ||
| if (error.code !== "EEXIST") throw error; | ||
| try { | ||
| if (Date.now() - statSync(lockPath).mtimeMs > STALE_LOCK_MS) { | ||
| rmSync(lockPath, { recursive: true, force: true }); | ||
| continue; | ||
| } | ||
| } catch { | ||
| continue; | ||
| } | ||
| wait(LOCK_RETRY_MS); | ||
| } | ||
| } | ||
| throw new Error(`Timed out waiting for the Shadow device identity lock at ${lockPath}`); | ||
| } | ||
| function resolveShadowDeviceIdentitySync(options = {}) { | ||
| const root = shadowStateRoot(options.rootDir); | ||
| const path = shadowDeviceIdentityPath(root); | ||
| const lockPath = join(root, ".device-identity.lock"); | ||
| mkdirSync(root, { recursive: true, mode: 448 }); | ||
| chmodSync(root, 448); | ||
| acquireIdentityLock(lockPath); | ||
| try { | ||
| try { | ||
| const identity2 = parseIdentity(path); | ||
| chmodSync(path, 384); | ||
| return identity2; | ||
| } catch (error) { | ||
| if (error.code !== "ENOENT") throw error; | ||
| } | ||
| const legacy = normalizeShadowDeviceFingerprint(options.legacyFingerprint); | ||
| const fingerprint = legacy ?? `device_${(options.randomId ?? randomUUID)()}`; | ||
| const identity = { | ||
| version: SHADOW_DEVICE_IDENTITY_VERSION, | ||
| fingerprint, | ||
| createdAt: (options.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(), | ||
| createdBy: options.createdBy ?? "unknown" | ||
| }; | ||
| const temporaryPath = `${path}.${process.pid}.${randomUUID()}.tmp`; | ||
| writeFileSync(temporaryPath, `${JSON.stringify(identity, null, 2)} | ||
| `, { | ||
| encoding: "utf8", | ||
| mode: 384, | ||
| flag: "wx" | ||
| }); | ||
| renameSync(temporaryPath, path); | ||
| chmodSync(path, 384); | ||
| return identity; | ||
| } finally { | ||
| rmSync(lockPath, { recursive: true, force: true }); | ||
| } | ||
| } | ||
| export { | ||
| SHADOW_DEVICE_IDENTITY_FILENAME, | ||
| SHADOW_DEVICE_IDENTITY_VERSION, | ||
| normalizeShadowDeviceFingerprint, | ||
| resolveShadowDeviceIdentitySync, | ||
| shadowDeviceIdentityPath, | ||
| shadowStateRoot | ||
| }; |
@@ -52,4 +52,5 @@ "use strict"; | ||
| REACTION_REMOVE: "reaction:remove", | ||
| POLL_UPDATED: "poll:updated", | ||
| NOTIFICATION_NEW: "notification:new", | ||
| SERVER_APP_LIST_CHANGED: "server-app:list-changed", | ||
| SPACE_APP_LIST_CHANGED: "space-app:list-changed", | ||
| VOICE_STATE: "voice:state", | ||
@@ -56,0 +57,0 @@ VOICE_PARTICIPANT_JOINED: "voice:participant-joined", |
@@ -23,4 +23,5 @@ declare const CLIENT_EVENTS: { | ||
| readonly REACTION_REMOVE: "reaction:remove"; | ||
| readonly POLL_UPDATED: "poll:updated"; | ||
| readonly NOTIFICATION_NEW: "notification:new"; | ||
| readonly SERVER_APP_LIST_CHANGED: "server-app:list-changed"; | ||
| readonly SPACE_APP_LIST_CHANGED: "space-app:list-changed"; | ||
| readonly VOICE_STATE: "voice:state"; | ||
@@ -27,0 +28,0 @@ readonly VOICE_PARTICIPANT_JOINED: "voice:participant-joined"; |
@@ -23,4 +23,5 @@ declare const CLIENT_EVENTS: { | ||
| readonly REACTION_REMOVE: "reaction:remove"; | ||
| readonly POLL_UPDATED: "poll:updated"; | ||
| readonly NOTIFICATION_NEW: "notification:new"; | ||
| readonly SERVER_APP_LIST_CHANGED: "server-app:list-changed"; | ||
| readonly SPACE_APP_LIST_CHANGED: "space-app:list-changed"; | ||
| readonly VOICE_STATE: "voice:state"; | ||
@@ -27,0 +28,0 @@ readonly VOICE_PARTICIPANT_JOINED: "voice:participant-joined"; |
@@ -5,3 +5,3 @@ import { | ||
| SERVER_EVENTS | ||
| } from "../chunk-2CRSZWS7.js"; | ||
| } from "../chunk-VHR3M5IB.js"; | ||
| export { | ||
@@ -8,0 +8,0 @@ CLIENT_EVENTS, |
@@ -40,2 +40,4 @@ "use strict"; | ||
| desktopSettingsPatchSchema: () => desktopSettingsPatchSchema, | ||
| desktopWindowChromeStateSchema: () => desktopWindowChromeStateSchema, | ||
| desktopWindowFullscreenInputSchema: () => desktopWindowFullscreenInputSchema, | ||
| downloadUpdateUrlSchema: () => downloadUpdateUrlSchema, | ||
@@ -57,2 +59,3 @@ externalUrlSchema: () => externalUrlSchema, | ||
| petArchiveImportSchema: () => petArchiveImportSchema, | ||
| petCursorPositionSchema: () => petCursorPositionSchema, | ||
| petMarketplaceImportSchema: () => petMarketplaceImportSchema, | ||
@@ -135,2 +138,7 @@ petPanelModeSchema: () => petPanelModeSchema, | ||
| ); | ||
| var desktopWindowFullscreenInputSchema = import_zod2.z.boolean(); | ||
| var desktopWindowChromeStateSchema = import_zod2.z.object({ | ||
| fullscreen: import_zod2.z.boolean(), | ||
| maximized: import_zod2.z.boolean() | ||
| }); | ||
| var runtimeIdInputSchema = ipcObjectSchema.pipe( | ||
@@ -186,2 +194,3 @@ import_zod2.z.object({ | ||
| version: import_zod2.z.string().optional(), | ||
| spriteVersionNumber: import_zod2.z.union([import_zod2.z.literal(1), import_zod2.z.literal(2)]).default(1), | ||
| displayName: import_zod2.z.record(import_zod2.z.string()), | ||
@@ -362,2 +371,6 @@ description: import_zod2.z.union([import_zod2.z.record(import_zod2.z.string()), import_zod2.z.string()]).optional(), | ||
| var petWindowMouseInteractiveSchema = import_zod2.z.boolean(); | ||
| var petCursorPositionSchema = import_zod2.z.object({ | ||
| x: import_zod2.z.number(), | ||
| y: import_zod2.z.number() | ||
| }); | ||
| var desktopIpcInvokeSchemas = { | ||
@@ -370,2 +383,4 @@ "desktop:getSettings": void 0, | ||
| "desktop:minimizeToTray": void 0, | ||
| "desktop:window:chrome-state": void 0, | ||
| "desktop:window:set-full-screen": desktopWindowFullscreenInputSchema, | ||
| "desktop:openExternal": externalUrlSchema, | ||
@@ -393,2 +408,3 @@ "desktop:clipboard:writeText": clipboardTextSchema, | ||
| "desktop:pet:hide": void 0, | ||
| "desktop:pet:cursor-position": void 0, | ||
| "desktop:pet:panel-mode": petPanelModeSchema, | ||
@@ -626,2 +642,12 @@ "desktop:pet:begin-window-drag": petWindowDragStartSchema, | ||
| minimizeToTray: legacyVoidProcedure("desktop:minimizeToTray"), | ||
| getChromeState: legacyProcedure( | ||
| "desktop:window:chrome-state", | ||
| ipcVoidInputSchema, | ||
| desktopWindowChromeStateSchema | ||
| ), | ||
| setFullScreen: legacyProcedure( | ||
| "desktop:window:set-full-screen", | ||
| desktopWindowFullscreenInputSchema, | ||
| desktopWindowChromeStateSchema | ||
| ), | ||
| openExternal: legacyProcedure("desktop:openExternal", externalUrlSchema, booleanResultSchema), | ||
@@ -732,2 +758,7 @@ writeClipboardText: legacyProcedure( | ||
| hide: legacyVoidProcedure("desktop:pet:hide"), | ||
| getCursorPosition: legacyProcedure( | ||
| "desktop:pet:cursor-position", | ||
| ipcVoidInputSchema, | ||
| petCursorPositionSchema | ||
| ), | ||
| setPanelMode: legacyProcedure( | ||
@@ -919,2 +950,4 @@ "desktop:pet:panel-mode", | ||
| desktopSettingsPatchSchema, | ||
| desktopWindowChromeStateSchema, | ||
| desktopWindowFullscreenInputSchema, | ||
| downloadUpdateUrlSchema, | ||
@@ -936,2 +969,3 @@ externalUrlSchema, | ||
| petArchiveImportSchema, | ||
| petCursorPositionSchema, | ||
| petMarketplaceImportSchema, | ||
@@ -938,0 +972,0 @@ petPanelModeSchema, |
@@ -19,2 +19,4 @@ import { | ||
| desktopSettingsPatchSchema, | ||
| desktopWindowChromeStateSchema, | ||
| desktopWindowFullscreenInputSchema, | ||
| downloadUpdateUrlSchema, | ||
@@ -36,2 +38,3 @@ externalUrlSchema, | ||
| petArchiveImportSchema, | ||
| petCursorPositionSchema, | ||
| petMarketplaceImportSchema, | ||
@@ -54,3 +57,3 @@ petPanelModeSchema, | ||
| voiceModelInstallSchema | ||
| } from "../chunk-FZVO64KZ.js"; | ||
| } from "../chunk-NWO4VES5.js"; | ||
| export { | ||
@@ -74,2 +77,4 @@ agentProcessIdSchema, | ||
| desktopSettingsPatchSchema, | ||
| desktopWindowChromeStateSchema, | ||
| desktopWindowFullscreenInputSchema, | ||
| downloadUpdateUrlSchema, | ||
@@ -91,2 +96,3 @@ externalUrlSchema, | ||
| petArchiveImportSchema, | ||
| petCursorPositionSchema, | ||
| petMarketplaceImportSchema, | ||
@@ -93,0 +99,0 @@ petPanelModeSchema, |
+106
-4
| export { CLIENT_EVENTS, ClientEvent, LIMITS, SERVER_EVENTS, ServerEvent } from './constants/index.cjs'; | ||
| export { AgentProcessIdInput, AsrAcceptInput, BadgeCountInput, ClipboardTextInput, CommunityAuthSnapshotInput, CommunityFetchJsonInput, ConnectorConnectionEnabledInput, ConnectorDeleteInput, ConnectorStartSettingsInput, ConnectorWorkDirInput, CreateConnectorBuddyInput, DesktopDiagnosticsSnapshot, DesktopIPCApi, DesktopIpcClient, DesktopIpcInvokeArgs, DesktopIpcInvokeChannel, DesktopIpcInvokeFn, DesktopIpcInvokeInput, DesktopIpcInvokeMap, DesktopIpcInvokeParsedInput, DesktopIpcInvokeResult, DesktopIpcInvokeSchemaMap, DesktopIpcProtocol, DesktopLogExportResult, DesktopNotificationInput, DesktopPlatform, DesktopRuntimeSettingsSnapshot, DesktopSettingsPatchInput, DesktopTtsProvider, DesktopUpdateChannel, DesktopUpdateInfo, DesktopUpdateSettings, DesktopUpdateState, DownloadUpdateUrlInput, ExternalUrlInput, ForceOptionsInput, IPCClient, IPCProcedureArgs, IPCProcedureArgument, IPCProcedureDefinition, IPCProcedureInput, IPCProcedureOutput, IPCProtocolDefinition, IPCProtocolImplementation, IPCServiceClient, IPCServiceDefinition, IPCServiceImplementation, ModelProxyStreamInput, NotificationModeInput, OpenAtLoginInput, OpenCommunityLoginInput, OpenCommunityLoginIpcInput, OptionalPathInput, PackIdInput, PetArchiveImportInput, PetMarketplaceImportInput, PetPanelModeInput, PetWindowDragMoveInput, PetWindowDragStartInput, PetWindowMouseInteractiveInput, PetWindowPointerIdInput, ReaderIdInput, ReaderOpenInput, ReaderResourceSnapshot, ReaderStateSnapshot, RendererLogInput, RuntimeIdInput, SelectDirectoryInput, ShowCommunityInput, ShowCommunityIpcInput, ShowSettingsInput, ShowSettingsIpcInput, SpeechTextInput, StartAgentInput, UpdateSettingsInput, VoiceEngineStatus, VoiceModelInstallInput, agentProcessIdSchema, asrAcceptSchema, badgeCountSchema, clipboardTextSchema, communityAuthSnapshotSchema, communityFetchJsonSchema, connectorConnectionEnabledSchema, connectorDeleteSchema, connectorStartSettingsSchema, connectorWorkDirSchema, createConnectorBuddySchema, defineIPCProtocol, defineIPCService, desktopIpcInvokeSchemas, desktopIpcProtocol, desktopNotificationSchema, desktopSettingsPatchSchema, downloadUpdateUrlSchema, externalUrlSchema, forceOptionsSchema, ipcProcedure, ipcProcedureChannel, ipcVoidInputSchema, ipcVoidOutputSchema, modelProxyStreamSchema, notificationModeSchema, openAtLoginSchema, openCommunityLoginInputSchema, optionalPathInputSchema, packIdInputSchema, parseIPCProcedureInput, parseIPCProcedureOutput, petArchiveImportSchema, petMarketplaceImportSchema, petPanelModeSchema, petWindowDragMoveSchema, petWindowDragStartSchema, petWindowMouseInteractiveSchema, petWindowPointerIdSchema, readerIdInputSchema, readerOpenSchema, rendererLogSchema, runtimeIdInputSchema, selectDirectorySchema, showCommunityInputSchema, showSettingsInputSchema, speechTextSchema, startAgentSchema, updateSettingsSchema, voiceModelInstallSchema } from './desktop-ipc/index.cjs'; | ||
| export { AgentProcessIdInput, AsrAcceptInput, BadgeCountInput, ClipboardTextInput, CommunityAuthSnapshotInput, CommunityFetchJsonInput, ConnectorConnectionEnabledInput, ConnectorDeleteInput, ConnectorStartSettingsInput, ConnectorWorkDirInput, CreateConnectorBuddyInput, DesktopDiagnosticsSnapshot, DesktopIPCApi, DesktopIpcClient, DesktopIpcInvokeArgs, DesktopIpcInvokeChannel, DesktopIpcInvokeFn, DesktopIpcInvokeInput, DesktopIpcInvokeMap, DesktopIpcInvokeParsedInput, DesktopIpcInvokeResult, DesktopIpcInvokeSchemaMap, DesktopIpcProtocol, DesktopLogExportResult, DesktopNotificationInput, DesktopPlatform, DesktopRuntimeSettingsSnapshot, DesktopSettingsPatchInput, DesktopTtsProvider, DesktopUpdateChannel, DesktopUpdateInfo, DesktopUpdateSettings, DesktopUpdateState, DesktopWindowChromeState, DesktopWindowFullscreenInput, DownloadUpdateUrlInput, ExternalUrlInput, ForceOptionsInput, IPCClient, IPCProcedureArgs, IPCProcedureArgument, IPCProcedureDefinition, IPCProcedureInput, IPCProcedureOutput, IPCProtocolDefinition, IPCProtocolImplementation, IPCServiceClient, IPCServiceDefinition, IPCServiceImplementation, ModelProxyStreamInput, NotificationModeInput, OpenAtLoginInput, OpenCommunityLoginInput, OpenCommunityLoginIpcInput, OptionalPathInput, PackIdInput, PetArchiveImportInput, PetCursorPosition, PetMarketplaceImportInput, PetPanelModeInput, PetWindowDragMoveInput, PetWindowDragStartInput, PetWindowMouseInteractiveInput, PetWindowPointerIdInput, ReaderIdInput, ReaderOpenInput, ReaderResourceSnapshot, ReaderStateSnapshot, RendererLogInput, RuntimeIdInput, SelectDirectoryInput, ShowCommunityInput, ShowCommunityIpcInput, ShowSettingsInput, ShowSettingsIpcInput, SpeechTextInput, StartAgentInput, UpdateSettingsInput, VoiceEngineStatus, VoiceModelInstallInput, agentProcessIdSchema, asrAcceptSchema, badgeCountSchema, clipboardTextSchema, communityAuthSnapshotSchema, communityFetchJsonSchema, connectorConnectionEnabledSchema, connectorDeleteSchema, connectorStartSettingsSchema, connectorWorkDirSchema, createConnectorBuddySchema, defineIPCProtocol, defineIPCService, desktopIpcInvokeSchemas, desktopIpcProtocol, desktopNotificationSchema, desktopSettingsPatchSchema, desktopWindowChromeStateSchema, desktopWindowFullscreenInputSchema, downloadUpdateUrlSchema, externalUrlSchema, forceOptionsSchema, ipcProcedure, ipcProcedureChannel, ipcVoidInputSchema, ipcVoidOutputSchema, modelProxyStreamSchema, notificationModeSchema, openAtLoginSchema, openCommunityLoginInputSchema, optionalPathInputSchema, packIdInputSchema, parseIPCProcedureInput, parseIPCProcedureOutput, petArchiveImportSchema, petCursorPositionSchema, petMarketplaceImportSchema, petPanelModeSchema, petWindowDragMoveSchema, petWindowDragStartSchema, petWindowMouseInteractiveSchema, petWindowPointerIdSchema, readerIdInputSchema, readerOpenSchema, rendererLogSchema, runtimeIdInputSchema, selectDirectorySchema, showCommunityInputSchema, showSettingsInputSchema, speechTextSchema, startAgentSchema, updateSettingsSchema, voiceModelInstallSchema } from './desktop-ipc/index.cjs'; | ||
| export { DEFAULT_HOMEPLAY_CATALOG, ShadowHomePlayCatalogItem, ShadowPlayAction, ShadowPlayAvailability, getDefaultHomePlay, getPlayBuddyEmail, getPlayBuddyUsername } from './play-catalog/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, ServerDesktopChatInputWidget, ServerDesktopChatInputWidgetMode, ServerDesktopLayout, ServerDesktopLayoutBuiltinAppItem, ServerDesktopLayoutItem, ServerDesktopLayoutServerAppItem, ServerDesktopLayoutWorkspaceItem, ServerDesktopPhotoWidget, ServerDesktopPhotoWidgetSourceType, ServerDesktopStickyNoteWidget, ServerDesktopTypewriterWidget, ServerDesktopTypewriterWidgetFontFamily, ServerDesktopTypewriterWidgetTextShadow, ServerDesktopVideoWidget, ServerDesktopVideoWidgetProvider, ServerDesktopWebEmbedWidget, ServerDesktopWebEmbedWidgetSourceType, ServerDesktopWidget, ServerWallpaperType, 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, 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'; | ||
| 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, ServerDesktopChatInputWidget, ServerDesktopChatInputWidgetMode, ServerDesktopLayout, ServerDesktopLayoutBuddyInboxItem, ServerDesktopLayoutBuiltinAppItem, ServerDesktopLayoutItem, ServerDesktopLayoutSpaceAppItem, ServerDesktopLayoutWorkspaceItem, ServerDesktopPhotoWidget, ServerDesktopPhotoWidgetSourceType, ServerDesktopRemoteWidget, ServerDesktopStickyNoteWidget, ServerDesktopTypewriterWidget, ServerDesktopTypewriterWidgetFontFamily, ServerDesktopTypewriterWidgetTextShadow, ServerDesktopVideoWidget, ServerDesktopVideoWidgetProvider, ServerDesktopWebEmbedWidget, ServerDesktopWebEmbedWidgetSourceType, ServerDesktopWidget, ServerWallpaperType, ShadowAgentComputerPlacement, ShadowComputer, ShadowComputerBuddy, ShadowComputerCapabilities, ShadowComputerDevice, ShadowComputerDeviceClass, ShadowComputerKind, ShadowComputerRuntime, ShadowComputerStatus, 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, parseShadowComputerId, resolvePresenceStatus, runtimeSessionPetReactionForState, runtimeSessionSignalToPetReaction, runtimeSessionStateLooksActive, shadowComputerId } from './types/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 MessagePollSummary, u as MessageReferenceCard, N as Notification, v as NotificationType, O as OAuthLinkCard, P as PaidFileCard, w as PollMessageCard, x as PollOptionSummary, y as PollVoterSummary, z as PollVotersPage, R as ReactionGroup, S as SendMessageRequest, D as SpaceAppMessageCard, T as TaskContextPack, E as TaskMessageCard, F as TaskMessageCardReply, H as TaskMessageCardTag, I as TaskMessageExpectedArtifact, J as TaskMessageOutputContract, K as TaskMessagePrivacy, L as TaskMessagePrivacyDataClass, Q as TaskMessageRequirementSkill, U as TaskMessageRequirementTool, V as TaskMessageRequirements, W as TaskMessageSubmitCommand, X as TaskResultMessageCard, Y as Thread, Z as UpdateMessageRequest, _ as buildMessageAgentChainMetadata, $ as buildMessageCopilotContextMetadata, a0 as getCommerceMessageCards, a1 as getOAuthLinkMessageCards, a2 as getPaidFileMessageCards, a3 as getPollMessageCards, a4 as isCommerceMessageCard, a5 as isMessageAgentChainMetadata, a6 as isMessageCopilotContext, a7 as isOAuthLinkMessageCard, a8 as isPaidFileMessageCard, a9 as isPollMessageCard, aa as parseBuddyInboxTaskResultMetadata } from './message.types-4XQpzQsK.cjs'; | ||
| export { BgPattern, CAT_AVATAR_COUNT, CLOUD_COMPUTER_SHELL_COLORS, CLOUD_COMPUTER_SHELL_PALETTE, CatConfig, CatDecoration, CatExpression, CatPattern, CloudComputerBuddyHandshakeCandidate, CloudComputerShellColor, CloudConnectorAccessKind, MessageMentionTextSegment, SlashCommandAction, SpaceAppPathOptions, SpaceAppRouteTarget, assignMentionRanges, buildMentionMarkdownLinks, buildSpaceAppCommunityPath, buildSpaceAppSharePath, buildSpaceAppShareUrl, canonicalMentionToken, canonicalizeMentionContent, cloudConnectorAccessKind, defaultCloudComputerShellColor, escapeMarkdownLinkLabel, extractSlashCommandActions, findReadyCloudComputerBuddy, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isCloudComputerShellColor, isValidEmail, mentionDisplayText, normalizeSpaceAppRoutePath, parseCanonicalMentionToken, renderCatSvg, resolveCloudComputerShellColor, segmentTextByMentions, slugify, spaceAppPathFromSearch, waitForCloudComputerBuddy, withSpaceAppRoutePathSearch } from './utils/index.cjs'; | ||
| import 'zod'; | ||
| type ShadowWidgetSurface = 'desktop' | 'mobile'; | ||
| type ShadowWidgetCategory = 'productivity' | 'communication' | 'media' | 'finance' | 'information' | 'lifestyle' | 'developer' | 'web' | 'other'; | ||
| interface ShadowWidgetSize { | ||
| widthCells: number; | ||
| heightCells: number; | ||
| } | ||
| type ShadowWidgetValue = { | ||
| literal: string; | ||
| } | { | ||
| path: string; | ||
| } | { | ||
| stringKey: string; | ||
| }; | ||
| type ShadowWidgetTextVariant = 'title' | 'body' | 'label' | 'caption' | 'value'; | ||
| type ShadowWidgetTone = 'default' | 'muted' | 'accent' | 'positive' | 'warning' | 'danger'; | ||
| type ShadowWidgetViewNode = { | ||
| type: 'stack' | 'row'; | ||
| gap?: 'none' | 'sm' | 'md' | 'lg'; | ||
| align?: 'start' | 'center' | 'end' | 'stretch'; | ||
| children: ShadowWidgetViewNode[]; | ||
| } | { | ||
| type: 'grid'; | ||
| minColumnWidth?: number; | ||
| gap?: 'none' | 'sm' | 'md' | 'lg'; | ||
| children: ShadowWidgetViewNode[]; | ||
| } | { | ||
| type: 'text'; | ||
| value: ShadowWidgetValue; | ||
| variant?: ShadowWidgetTextVariant; | ||
| tone?: ShadowWidgetTone; | ||
| } | { | ||
| type: 'metric'; | ||
| label: ShadowWidgetValue; | ||
| value: ShadowWidgetValue; | ||
| detail?: ShadowWidgetValue; | ||
| tone?: ShadowWidgetTone; | ||
| } | { | ||
| type: 'badge'; | ||
| value: ShadowWidgetValue; | ||
| tone?: ShadowWidgetTone; | ||
| } | { | ||
| type: 'divider'; | ||
| } | { | ||
| type: 'spacer'; | ||
| }; | ||
| interface ShadowWidgetSelectOptionChoice { | ||
| value: string; | ||
| label: string; | ||
| } | ||
| interface ShadowWidgetSelectOption { | ||
| key: string; | ||
| type: 'select'; | ||
| label: string; | ||
| defaultValue: string; | ||
| choices: ShadowWidgetSelectOptionChoice[]; | ||
| } | ||
| type ShadowWidgetOption = ShadowWidgetSelectOption; | ||
| interface ShadowWidgetDefinition { | ||
| key: string; | ||
| title: string; | ||
| description?: string; | ||
| category?: ShadowWidgetCategory; | ||
| surfaces?: ShadowWidgetSurface[]; | ||
| strings?: Record<string, string>; | ||
| i18n?: Record<string, Record<string, string>>; | ||
| size: { | ||
| default: ShadowWidgetSize; | ||
| min?: ShadowWidgetSize; | ||
| max?: ShadowWidgetSize; | ||
| }; | ||
| options?: ShadowWidgetOption[]; | ||
| data: { | ||
| command: string; | ||
| refreshIntervalSeconds?: number; | ||
| }; | ||
| view: ShadowWidgetViewNode; | ||
| } | ||
| interface ShadowWidgetCatalogEntry { | ||
| sourceId: string; | ||
| provider: { | ||
| id: string; | ||
| name: string; | ||
| iconUrl?: string | null; | ||
| }; | ||
| definition: ShadowWidgetDefinition; | ||
| } | ||
| interface ShadowWidgetDataRequest { | ||
| options?: Record<string, string>; | ||
| } | ||
| interface ShadowWidgetDataResponse { | ||
| sourceId: string; | ||
| data: Record<string, unknown>; | ||
| updatedAt: string; | ||
| } | ||
| declare function defaultShadowWidgetOptions(definition: ShadowWidgetDefinition): { | ||
| [k: string]: string; | ||
| }; | ||
| declare function localizeShadowWidgetDefinition(definition: ShadowWidgetDefinition, locale?: string | null): ShadowWidgetDefinition; | ||
| declare function resolveShadowWidgetValue(value: ShadowWidgetValue, data: Record<string, unknown>, strings?: Record<string, string>): string; | ||
| export { type ShadowWidgetCatalogEntry, type ShadowWidgetCategory, type ShadowWidgetDataRequest, type ShadowWidgetDataResponse, type ShadowWidgetDefinition, type ShadowWidgetOption, type ShadowWidgetSelectOption, type ShadowWidgetSelectOptionChoice, type ShadowWidgetSize, type ShadowWidgetSurface, type ShadowWidgetTextVariant, type ShadowWidgetTone, type ShadowWidgetValue, type ShadowWidgetViewNode, defaultShadowWidgetOptions, localizeShadowWidgetDefinition, resolveShadowWidgetValue }; |
+106
-4
| export { CLIENT_EVENTS, ClientEvent, LIMITS, SERVER_EVENTS, ServerEvent } from './constants/index.js'; | ||
| export { AgentProcessIdInput, AsrAcceptInput, BadgeCountInput, ClipboardTextInput, CommunityAuthSnapshotInput, CommunityFetchJsonInput, ConnectorConnectionEnabledInput, ConnectorDeleteInput, ConnectorStartSettingsInput, ConnectorWorkDirInput, CreateConnectorBuddyInput, DesktopDiagnosticsSnapshot, DesktopIPCApi, DesktopIpcClient, DesktopIpcInvokeArgs, DesktopIpcInvokeChannel, DesktopIpcInvokeFn, DesktopIpcInvokeInput, DesktopIpcInvokeMap, DesktopIpcInvokeParsedInput, DesktopIpcInvokeResult, DesktopIpcInvokeSchemaMap, DesktopIpcProtocol, DesktopLogExportResult, DesktopNotificationInput, DesktopPlatform, DesktopRuntimeSettingsSnapshot, DesktopSettingsPatchInput, DesktopTtsProvider, DesktopUpdateChannel, DesktopUpdateInfo, DesktopUpdateSettings, DesktopUpdateState, DownloadUpdateUrlInput, ExternalUrlInput, ForceOptionsInput, IPCClient, IPCProcedureArgs, IPCProcedureArgument, IPCProcedureDefinition, IPCProcedureInput, IPCProcedureOutput, IPCProtocolDefinition, IPCProtocolImplementation, IPCServiceClient, IPCServiceDefinition, IPCServiceImplementation, ModelProxyStreamInput, NotificationModeInput, OpenAtLoginInput, OpenCommunityLoginInput, OpenCommunityLoginIpcInput, OptionalPathInput, PackIdInput, PetArchiveImportInput, PetMarketplaceImportInput, PetPanelModeInput, PetWindowDragMoveInput, PetWindowDragStartInput, PetWindowMouseInteractiveInput, PetWindowPointerIdInput, ReaderIdInput, ReaderOpenInput, ReaderResourceSnapshot, ReaderStateSnapshot, RendererLogInput, RuntimeIdInput, SelectDirectoryInput, ShowCommunityInput, ShowCommunityIpcInput, ShowSettingsInput, ShowSettingsIpcInput, SpeechTextInput, StartAgentInput, UpdateSettingsInput, VoiceEngineStatus, VoiceModelInstallInput, agentProcessIdSchema, asrAcceptSchema, badgeCountSchema, clipboardTextSchema, communityAuthSnapshotSchema, communityFetchJsonSchema, connectorConnectionEnabledSchema, connectorDeleteSchema, connectorStartSettingsSchema, connectorWorkDirSchema, createConnectorBuddySchema, defineIPCProtocol, defineIPCService, desktopIpcInvokeSchemas, desktopIpcProtocol, desktopNotificationSchema, desktopSettingsPatchSchema, downloadUpdateUrlSchema, externalUrlSchema, forceOptionsSchema, ipcProcedure, ipcProcedureChannel, ipcVoidInputSchema, ipcVoidOutputSchema, modelProxyStreamSchema, notificationModeSchema, openAtLoginSchema, openCommunityLoginInputSchema, optionalPathInputSchema, packIdInputSchema, parseIPCProcedureInput, parseIPCProcedureOutput, petArchiveImportSchema, petMarketplaceImportSchema, petPanelModeSchema, petWindowDragMoveSchema, petWindowDragStartSchema, petWindowMouseInteractiveSchema, petWindowPointerIdSchema, readerIdInputSchema, readerOpenSchema, rendererLogSchema, runtimeIdInputSchema, selectDirectorySchema, showCommunityInputSchema, showSettingsInputSchema, speechTextSchema, startAgentSchema, updateSettingsSchema, voiceModelInstallSchema } from './desktop-ipc/index.js'; | ||
| export { AgentProcessIdInput, AsrAcceptInput, BadgeCountInput, ClipboardTextInput, CommunityAuthSnapshotInput, CommunityFetchJsonInput, ConnectorConnectionEnabledInput, ConnectorDeleteInput, ConnectorStartSettingsInput, ConnectorWorkDirInput, CreateConnectorBuddyInput, DesktopDiagnosticsSnapshot, DesktopIPCApi, DesktopIpcClient, DesktopIpcInvokeArgs, DesktopIpcInvokeChannel, DesktopIpcInvokeFn, DesktopIpcInvokeInput, DesktopIpcInvokeMap, DesktopIpcInvokeParsedInput, DesktopIpcInvokeResult, DesktopIpcInvokeSchemaMap, DesktopIpcProtocol, DesktopLogExportResult, DesktopNotificationInput, DesktopPlatform, DesktopRuntimeSettingsSnapshot, DesktopSettingsPatchInput, DesktopTtsProvider, DesktopUpdateChannel, DesktopUpdateInfo, DesktopUpdateSettings, DesktopUpdateState, DesktopWindowChromeState, DesktopWindowFullscreenInput, DownloadUpdateUrlInput, ExternalUrlInput, ForceOptionsInput, IPCClient, IPCProcedureArgs, IPCProcedureArgument, IPCProcedureDefinition, IPCProcedureInput, IPCProcedureOutput, IPCProtocolDefinition, IPCProtocolImplementation, IPCServiceClient, IPCServiceDefinition, IPCServiceImplementation, ModelProxyStreamInput, NotificationModeInput, OpenAtLoginInput, OpenCommunityLoginInput, OpenCommunityLoginIpcInput, OptionalPathInput, PackIdInput, PetArchiveImportInput, PetCursorPosition, PetMarketplaceImportInput, PetPanelModeInput, PetWindowDragMoveInput, PetWindowDragStartInput, PetWindowMouseInteractiveInput, PetWindowPointerIdInput, ReaderIdInput, ReaderOpenInput, ReaderResourceSnapshot, ReaderStateSnapshot, RendererLogInput, RuntimeIdInput, SelectDirectoryInput, ShowCommunityInput, ShowCommunityIpcInput, ShowSettingsInput, ShowSettingsIpcInput, SpeechTextInput, StartAgentInput, UpdateSettingsInput, VoiceEngineStatus, VoiceModelInstallInput, agentProcessIdSchema, asrAcceptSchema, badgeCountSchema, clipboardTextSchema, communityAuthSnapshotSchema, communityFetchJsonSchema, connectorConnectionEnabledSchema, connectorDeleteSchema, connectorStartSettingsSchema, connectorWorkDirSchema, createConnectorBuddySchema, defineIPCProtocol, defineIPCService, desktopIpcInvokeSchemas, desktopIpcProtocol, desktopNotificationSchema, desktopSettingsPatchSchema, desktopWindowChromeStateSchema, desktopWindowFullscreenInputSchema, downloadUpdateUrlSchema, externalUrlSchema, forceOptionsSchema, ipcProcedure, ipcProcedureChannel, ipcVoidInputSchema, ipcVoidOutputSchema, modelProxyStreamSchema, notificationModeSchema, openAtLoginSchema, openCommunityLoginInputSchema, optionalPathInputSchema, packIdInputSchema, parseIPCProcedureInput, parseIPCProcedureOutput, petArchiveImportSchema, petCursorPositionSchema, petMarketplaceImportSchema, petPanelModeSchema, petWindowDragMoveSchema, petWindowDragStartSchema, petWindowMouseInteractiveSchema, petWindowPointerIdSchema, readerIdInputSchema, readerOpenSchema, rendererLogSchema, runtimeIdInputSchema, selectDirectorySchema, showCommunityInputSchema, showSettingsInputSchema, speechTextSchema, startAgentSchema, updateSettingsSchema, voiceModelInstallSchema } from './desktop-ipc/index.js'; | ||
| export { DEFAULT_HOMEPLAY_CATALOG, ShadowHomePlayCatalogItem, ShadowPlayAction, ShadowPlayAvailability, getDefaultHomePlay, getPlayBuddyEmail, getPlayBuddyUsername } from './play-catalog/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, ServerDesktopChatInputWidget, ServerDesktopChatInputWidgetMode, ServerDesktopLayout, ServerDesktopLayoutBuiltinAppItem, ServerDesktopLayoutItem, ServerDesktopLayoutServerAppItem, ServerDesktopLayoutWorkspaceItem, ServerDesktopPhotoWidget, ServerDesktopPhotoWidgetSourceType, ServerDesktopStickyNoteWidget, ServerDesktopTypewriterWidget, ServerDesktopTypewriterWidgetFontFamily, ServerDesktopTypewriterWidgetTextShadow, ServerDesktopVideoWidget, ServerDesktopVideoWidgetProvider, ServerDesktopWebEmbedWidget, ServerDesktopWebEmbedWidgetSourceType, ServerDesktopWidget, ServerWallpaperType, 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, 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'; | ||
| 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, ServerDesktopChatInputWidget, ServerDesktopChatInputWidgetMode, ServerDesktopLayout, ServerDesktopLayoutBuddyInboxItem, ServerDesktopLayoutBuiltinAppItem, ServerDesktopLayoutItem, ServerDesktopLayoutSpaceAppItem, ServerDesktopLayoutWorkspaceItem, ServerDesktopPhotoWidget, ServerDesktopPhotoWidgetSourceType, ServerDesktopRemoteWidget, ServerDesktopStickyNoteWidget, ServerDesktopTypewriterWidget, ServerDesktopTypewriterWidgetFontFamily, ServerDesktopTypewriterWidgetTextShadow, ServerDesktopVideoWidget, ServerDesktopVideoWidgetProvider, ServerDesktopWebEmbedWidget, ServerDesktopWebEmbedWidgetSourceType, ServerDesktopWidget, ServerWallpaperType, ShadowAgentComputerPlacement, ShadowComputer, ShadowComputerBuddy, ShadowComputerCapabilities, ShadowComputerDevice, ShadowComputerDeviceClass, ShadowComputerKind, ShadowComputerRuntime, ShadowComputerStatus, 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, parseShadowComputerId, resolvePresenceStatus, runtimeSessionPetReactionForState, runtimeSessionSignalToPetReaction, runtimeSessionStateLooksActive, shadowComputerId } from './types/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 MessagePollSummary, u as MessageReferenceCard, N as Notification, v as NotificationType, O as OAuthLinkCard, P as PaidFileCard, w as PollMessageCard, x as PollOptionSummary, y as PollVoterSummary, z as PollVotersPage, R as ReactionGroup, S as SendMessageRequest, D as SpaceAppMessageCard, T as TaskContextPack, E as TaskMessageCard, F as TaskMessageCardReply, H as TaskMessageCardTag, I as TaskMessageExpectedArtifact, J as TaskMessageOutputContract, K as TaskMessagePrivacy, L as TaskMessagePrivacyDataClass, Q as TaskMessageRequirementSkill, U as TaskMessageRequirementTool, V as TaskMessageRequirements, W as TaskMessageSubmitCommand, X as TaskResultMessageCard, Y as Thread, Z as UpdateMessageRequest, _ as buildMessageAgentChainMetadata, $ as buildMessageCopilotContextMetadata, a0 as getCommerceMessageCards, a1 as getOAuthLinkMessageCards, a2 as getPaidFileMessageCards, a3 as getPollMessageCards, a4 as isCommerceMessageCard, a5 as isMessageAgentChainMetadata, a6 as isMessageCopilotContext, a7 as isOAuthLinkMessageCard, a8 as isPaidFileMessageCard, a9 as isPollMessageCard, aa as parseBuddyInboxTaskResultMetadata } from './message.types-4XQpzQsK.js'; | ||
| export { BgPattern, CAT_AVATAR_COUNT, CLOUD_COMPUTER_SHELL_COLORS, CLOUD_COMPUTER_SHELL_PALETTE, CatConfig, CatDecoration, CatExpression, CatPattern, CloudComputerBuddyHandshakeCandidate, CloudComputerShellColor, CloudConnectorAccessKind, MessageMentionTextSegment, SlashCommandAction, SpaceAppPathOptions, SpaceAppRouteTarget, assignMentionRanges, buildMentionMarkdownLinks, buildSpaceAppCommunityPath, buildSpaceAppSharePath, buildSpaceAppShareUrl, canonicalMentionToken, canonicalizeMentionContent, cloudConnectorAccessKind, defaultCloudComputerShellColor, escapeMarkdownLinkLabel, extractSlashCommandActions, findReadyCloudComputerBuddy, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isCloudComputerShellColor, isValidEmail, mentionDisplayText, normalizeSpaceAppRoutePath, parseCanonicalMentionToken, renderCatSvg, resolveCloudComputerShellColor, segmentTextByMentions, slugify, spaceAppPathFromSearch, waitForCloudComputerBuddy, withSpaceAppRoutePathSearch } from './utils/index.js'; | ||
| import 'zod'; | ||
| type ShadowWidgetSurface = 'desktop' | 'mobile'; | ||
| type ShadowWidgetCategory = 'productivity' | 'communication' | 'media' | 'finance' | 'information' | 'lifestyle' | 'developer' | 'web' | 'other'; | ||
| interface ShadowWidgetSize { | ||
| widthCells: number; | ||
| heightCells: number; | ||
| } | ||
| type ShadowWidgetValue = { | ||
| literal: string; | ||
| } | { | ||
| path: string; | ||
| } | { | ||
| stringKey: string; | ||
| }; | ||
| type ShadowWidgetTextVariant = 'title' | 'body' | 'label' | 'caption' | 'value'; | ||
| type ShadowWidgetTone = 'default' | 'muted' | 'accent' | 'positive' | 'warning' | 'danger'; | ||
| type ShadowWidgetViewNode = { | ||
| type: 'stack' | 'row'; | ||
| gap?: 'none' | 'sm' | 'md' | 'lg'; | ||
| align?: 'start' | 'center' | 'end' | 'stretch'; | ||
| children: ShadowWidgetViewNode[]; | ||
| } | { | ||
| type: 'grid'; | ||
| minColumnWidth?: number; | ||
| gap?: 'none' | 'sm' | 'md' | 'lg'; | ||
| children: ShadowWidgetViewNode[]; | ||
| } | { | ||
| type: 'text'; | ||
| value: ShadowWidgetValue; | ||
| variant?: ShadowWidgetTextVariant; | ||
| tone?: ShadowWidgetTone; | ||
| } | { | ||
| type: 'metric'; | ||
| label: ShadowWidgetValue; | ||
| value: ShadowWidgetValue; | ||
| detail?: ShadowWidgetValue; | ||
| tone?: ShadowWidgetTone; | ||
| } | { | ||
| type: 'badge'; | ||
| value: ShadowWidgetValue; | ||
| tone?: ShadowWidgetTone; | ||
| } | { | ||
| type: 'divider'; | ||
| } | { | ||
| type: 'spacer'; | ||
| }; | ||
| interface ShadowWidgetSelectOptionChoice { | ||
| value: string; | ||
| label: string; | ||
| } | ||
| interface ShadowWidgetSelectOption { | ||
| key: string; | ||
| type: 'select'; | ||
| label: string; | ||
| defaultValue: string; | ||
| choices: ShadowWidgetSelectOptionChoice[]; | ||
| } | ||
| type ShadowWidgetOption = ShadowWidgetSelectOption; | ||
| interface ShadowWidgetDefinition { | ||
| key: string; | ||
| title: string; | ||
| description?: string; | ||
| category?: ShadowWidgetCategory; | ||
| surfaces?: ShadowWidgetSurface[]; | ||
| strings?: Record<string, string>; | ||
| i18n?: Record<string, Record<string, string>>; | ||
| size: { | ||
| default: ShadowWidgetSize; | ||
| min?: ShadowWidgetSize; | ||
| max?: ShadowWidgetSize; | ||
| }; | ||
| options?: ShadowWidgetOption[]; | ||
| data: { | ||
| command: string; | ||
| refreshIntervalSeconds?: number; | ||
| }; | ||
| view: ShadowWidgetViewNode; | ||
| } | ||
| interface ShadowWidgetCatalogEntry { | ||
| sourceId: string; | ||
| provider: { | ||
| id: string; | ||
| name: string; | ||
| iconUrl?: string | null; | ||
| }; | ||
| definition: ShadowWidgetDefinition; | ||
| } | ||
| interface ShadowWidgetDataRequest { | ||
| options?: Record<string, string>; | ||
| } | ||
| interface ShadowWidgetDataResponse { | ||
| sourceId: string; | ||
| data: Record<string, unknown>; | ||
| updatedAt: string; | ||
| } | ||
| declare function defaultShadowWidgetOptions(definition: ShadowWidgetDefinition): { | ||
| [k: string]: string; | ||
| }; | ||
| declare function localizeShadowWidgetDefinition(definition: ShadowWidgetDefinition, locale?: string | null): ShadowWidgetDefinition; | ||
| declare function resolveShadowWidgetValue(value: ShadowWidgetValue, data: Record<string, unknown>, strings?: Record<string, string>): string; | ||
| export { type ShadowWidgetCatalogEntry, type ShadowWidgetCategory, type ShadowWidgetDataRequest, type ShadowWidgetDataResponse, type ShadowWidgetDefinition, type ShadowWidgetOption, type ShadowWidgetSelectOption, type ShadowWidgetSelectOptionChoice, type ShadowWidgetSize, type ShadowWidgetSurface, type ShadowWidgetTextVariant, type ShadowWidgetTone, type ShadowWidgetValue, type ShadowWidgetViewNode, defaultShadowWidgetOptions, localizeShadowWidgetDefinition, resolveShadowWidgetValue }; |
+98
-18
@@ -5,3 +5,3 @@ import { | ||
| SERVER_EVENTS | ||
| } from "./chunk-2CRSZWS7.js"; | ||
| } from "./chunk-VHR3M5IB.js"; | ||
| import { | ||
@@ -25,2 +25,4 @@ agentProcessIdSchema, | ||
| desktopSettingsPatchSchema, | ||
| desktopWindowChromeStateSchema, | ||
| desktopWindowFullscreenInputSchema, | ||
| downloadUpdateUrlSchema, | ||
@@ -42,2 +44,3 @@ externalUrlSchema, | ||
| petArchiveImportSchema, | ||
| petCursorPositionSchema, | ||
| petMarketplaceImportSchema, | ||
@@ -60,3 +63,3 @@ petPanelModeSchema, | ||
| voiceModelInstallSchema | ||
| } from "./chunk-FZVO64KZ.js"; | ||
| } from "./chunk-NWO4VES5.js"; | ||
| import { | ||
@@ -67,3 +70,3 @@ DEFAULT_HOMEPLAY_CATALOG, | ||
| getPlayBuddyUsername | ||
| } from "./chunk-KKRZTKE6.js"; | ||
| } from "./chunk-ZMZKOC2K.js"; | ||
| import { | ||
@@ -96,2 +99,3 @@ BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, | ||
| getPaidFileMessageCards, | ||
| getPollMessageCards, | ||
| hasBuddyInboxTaskCard, | ||
@@ -107,2 +111,3 @@ isBuddyHeartbeatActive, | ||
| isPaidFileMessageCard, | ||
| isPollMessageCard, | ||
| isTaskMessageCardStatus, | ||
@@ -118,18 +123,25 @@ isTerminalTaskMessageCardStatus, | ||
| parseBuddyInboxTaskResultMetadata, | ||
| parseShadowComputerId, | ||
| resolvePresenceStatus, | ||
| runtimeSessionPetReactionForState, | ||
| runtimeSessionSignalToPetReaction, | ||
| runtimeSessionStateLooksActive | ||
| } from "./chunk-G7TRWZCK.js"; | ||
| runtimeSessionStateLooksActive, | ||
| shadowComputerId | ||
| } from "./chunk-DR5LLHH3.js"; | ||
| import { | ||
| CAT_AVATAR_COUNT, | ||
| CLOUD_COMPUTER_SHELL_COLORS, | ||
| CLOUD_COMPUTER_SHELL_PALETTE, | ||
| assignMentionRanges, | ||
| buildMentionMarkdownLinks, | ||
| buildServerAppCommunityPath, | ||
| buildServerAppSharePath, | ||
| buildServerAppShareUrl, | ||
| buildSpaceAppCommunityPath, | ||
| buildSpaceAppSharePath, | ||
| buildSpaceAppShareUrl, | ||
| canonicalMentionToken, | ||
| canonicalizeMentionContent, | ||
| cloudConnectorAccessKind, | ||
| defaultCloudComputerShellColor, | ||
| escapeMarkdownLinkLabel, | ||
| extractSlashCommandActions, | ||
| findReadyCloudComputerBuddy, | ||
| formatDate, | ||
@@ -143,12 +155,62 @@ generateInviteCode, | ||
| isCanonicalMentionToken, | ||
| isCloudComputerShellColor, | ||
| isValidEmail, | ||
| mentionDisplayText, | ||
| normalizeServerAppRoutePath, | ||
| normalizeSpaceAppRoutePath, | ||
| parseCanonicalMentionToken, | ||
| renderCatSvg, | ||
| resolveCloudComputerShellColor, | ||
| segmentTextByMentions, | ||
| serverAppPathFromSearch, | ||
| slugify, | ||
| withServerAppRoutePathSearch | ||
| } from "./chunk-NWPWICSP.js"; | ||
| spaceAppPathFromSearch, | ||
| waitForCloudComputerBuddy, | ||
| withSpaceAppRoutePathSearch | ||
| } from "./chunk-K4GUGXY5.js"; | ||
| // src/widget.ts | ||
| function defaultShadowWidgetOptions(definition) { | ||
| return Object.fromEntries( | ||
| (definition.options ?? []).map((option) => [option.key, option.defaultValue]) | ||
| ); | ||
| } | ||
| function widgetLocaleCandidates(locale) { | ||
| const normalized = locale?.trim().replace("_", "-"); | ||
| const language = normalized?.split("-")[0]; | ||
| return [normalized, normalized?.toLowerCase(), language, language?.toLowerCase(), "en"].filter( | ||
| (value, index, values) => Boolean(value) && values.indexOf(value) === index | ||
| ); | ||
| } | ||
| function localizeShadowWidgetDefinition(definition, locale) { | ||
| const localized = widgetLocaleCandidates(locale).map((candidate) => definition.i18n?.[candidate]).find(Boolean); | ||
| if (!localized) return definition; | ||
| const strings = Object.fromEntries( | ||
| Object.entries(localized).filter(([key]) => !key.startsWith("$")) | ||
| ); | ||
| return { | ||
| ...definition, | ||
| title: localized.$title ?? definition.title, | ||
| description: localized.$description ?? definition.description, | ||
| strings: { ...definition.strings ?? {}, ...strings }, | ||
| options: definition.options?.map((option) => ({ | ||
| ...option, | ||
| label: localized[`$option.${option.key}`] ?? option.label, | ||
| choices: option.choices.map((choice) => ({ | ||
| ...choice, | ||
| label: localized[`$choice.${option.key}.${choice.value}`] ?? choice.label | ||
| })) | ||
| })) | ||
| }; | ||
| } | ||
| function resolveShadowWidgetValue(value, data, strings = {}) { | ||
| if ("literal" in value) return value.literal; | ||
| if ("stringKey" in value) return strings[value.stringKey] ?? value.stringKey; | ||
| const segments = value.path.replace(/^\$\.?/, "").split(".").map((segment) => segment.trim()).filter(Boolean); | ||
| let current = data; | ||
| for (const segment of segments) { | ||
| if (!current || typeof current !== "object" || Array.isArray(current)) return ""; | ||
| current = current[segment]; | ||
| } | ||
| if (current === null || current === void 0) return ""; | ||
| return typeof current === "string" ? current : String(current); | ||
| } | ||
| export { | ||
@@ -162,2 +224,4 @@ BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, | ||
| CLIENT_EVENTS, | ||
| CLOUD_COMPUTER_SHELL_COLORS, | ||
| CLOUD_COMPUTER_SHELL_PALETTE, | ||
| DEFAULT_BUDDY_INBOX_ADMISSION_POLICY, | ||
@@ -185,5 +249,5 @@ DEFAULT_HOMEPLAY_CATALOG, | ||
| buildMessageCopilotContextMetadata, | ||
| buildServerAppCommunityPath, | ||
| buildServerAppSharePath, | ||
| buildServerAppShareUrl, | ||
| buildSpaceAppCommunityPath, | ||
| buildSpaceAppSharePath, | ||
| buildSpaceAppShareUrl, | ||
| canTransitionTaskMessageCardStatus, | ||
@@ -193,2 +257,3 @@ canonicalMentionToken, | ||
| clipboardTextSchema, | ||
| cloudConnectorAccessKind, | ||
| communityAuthSnapshotSchema, | ||
@@ -201,2 +266,4 @@ communityFetchJsonSchema, | ||
| createConnectorBuddySchema, | ||
| defaultCloudComputerShellColor, | ||
| defaultShadowWidgetOptions, | ||
| defineIPCProtocol, | ||
@@ -208,2 +275,4 @@ defineIPCService, | ||
| desktopSettingsPatchSchema, | ||
| desktopWindowChromeStateSchema, | ||
| desktopWindowFullscreenInputSchema, | ||
| downloadUpdateUrlSchema, | ||
@@ -213,2 +282,3 @@ escapeMarkdownLinkLabel, | ||
| extractSlashCommandActions, | ||
| findReadyCloudComputerBuddy, | ||
| forceOptionsSchema, | ||
@@ -231,2 +301,3 @@ formatDate, | ||
| getPlayBuddyUsername, | ||
| getPollMessageCards, | ||
| hasBuddyInboxTaskCard, | ||
@@ -241,2 +312,3 @@ ipcProcedure, | ||
| isCanonicalMentionToken, | ||
| isCloudComputerShellColor, | ||
| isCommerceMessageCard, | ||
@@ -248,5 +320,7 @@ isMessageAgentChainMetadata, | ||
| isPaidFileMessageCard, | ||
| isPollMessageCard, | ||
| isTaskMessageCardStatus, | ||
| isTerminalTaskMessageCardStatus, | ||
| isValidEmail, | ||
| localizeShadowWidgetDefinition, | ||
| mentionDisplayText, | ||
@@ -259,3 +333,3 @@ modelProxyStreamSchema, | ||
| normalizePresenceStatus, | ||
| normalizeServerAppRoutePath, | ||
| normalizeSpaceAppRoutePath, | ||
| normalizeUserStatus, | ||
@@ -272,3 +346,5 @@ notificationModeSchema, | ||
| parseIPCProcedureOutput, | ||
| parseShadowComputerId, | ||
| petArchiveImportSchema, | ||
| petCursorPositionSchema, | ||
| petMarketplaceImportSchema, | ||
@@ -284,3 +360,5 @@ petPanelModeSchema, | ||
| rendererLogSchema, | ||
| resolveCloudComputerShellColor, | ||
| resolvePresenceStatus, | ||
| resolveShadowWidgetValue, | ||
| runtimeIdInputSchema, | ||
@@ -292,6 +370,7 @@ runtimeSessionPetReactionForState, | ||
| selectDirectorySchema, | ||
| serverAppPathFromSearch, | ||
| shadowComputerId, | ||
| showCommunityInputSchema, | ||
| showSettingsInputSchema, | ||
| slugify, | ||
| spaceAppPathFromSearch, | ||
| speechTextSchema, | ||
@@ -301,3 +380,4 @@ startAgentSchema, | ||
| voiceModelInstallSchema, | ||
| withServerAppRoutePathSearch | ||
| waitForCloudComputerBuddy, | ||
| withSpaceAppRoutePathSearch | ||
| }; |
@@ -325,3 +325,3 @@ "use strict"; | ||
| titleEn: "MarketingSkills Buddy", | ||
| desc: "\u589E\u957F\u56E2\u961F\u7684\u8425\u9500\u534F\u4F5C\u667A\u80FD\u4F53\uFF0C\u8986\u76D6 CRO\u3001\u6587\u6848\u3001SEO\u3001\u4ED8\u8D39\u3001\u90AE\u4EF6\u548C\u589E\u957F\u51B3\u7B56\u3002", | ||
| desc: "\u589E\u957F\u56E2\u961F\u7684\u8425\u9500\u534F\u4F5C Agent\uFF0C\u8986\u76D6 CRO\u3001\u6587\u6848\u3001SEO\u3001\u4ED8\u8D39\u3001\u90AE\u4EF6\u548C\u589E\u957F\u51B3\u7B56\u3002", | ||
| descEn: "Marketing collaboration agents for CRO, copy, SEO, paid, email, and growth decisions.", | ||
@@ -328,0 +328,0 @@ category: "\u8425\u9500\u6280\u80FD", |
@@ -6,3 +6,3 @@ import { | ||
| getPlayBuddyUsername | ||
| } from "../chunk-KKRZTKE6.js"; | ||
| } from "../chunk-ZMZKOC2K.js"; | ||
| export { | ||
@@ -9,0 +9,0 @@ DEFAULT_HOMEPLAY_CATALOG, |
+31
-4
@@ -49,2 +49,3 @@ "use strict"; | ||
| getPaidFileMessageCards: () => getPaidFileMessageCards, | ||
| getPollMessageCards: () => getPollMessageCards, | ||
| hasBuddyInboxTaskCard: () => hasBuddyInboxTaskCard, | ||
@@ -60,2 +61,3 @@ isBuddyHeartbeatActive: () => isBuddyHeartbeatActive, | ||
| isPaidFileMessageCard: () => isPaidFileMessageCard, | ||
| isPollMessageCard: () => isPollMessageCard, | ||
| isTaskMessageCardStatus: () => isTaskMessageCardStatus, | ||
@@ -71,9 +73,24 @@ isTerminalTaskMessageCardStatus: () => isTerminalTaskMessageCardStatus, | ||
| parseBuddyInboxTaskResultMetadata: () => parseBuddyInboxTaskResultMetadata, | ||
| parseShadowComputerId: () => parseShadowComputerId, | ||
| resolvePresenceStatus: () => resolvePresenceStatus, | ||
| runtimeSessionPetReactionForState: () => runtimeSessionPetReactionForState, | ||
| runtimeSessionSignalToPetReaction: () => runtimeSessionSignalToPetReaction, | ||
| runtimeSessionStateLooksActive: () => runtimeSessionStateLooksActive | ||
| runtimeSessionStateLooksActive: () => runtimeSessionStateLooksActive, | ||
| shadowComputerId: () => shadowComputerId | ||
| }); | ||
| module.exports = __toCommonJS(types_exports); | ||
| // src/types/computer.types.ts | ||
| function shadowComputerId(kind, sourceId) { | ||
| return `${kind}:${sourceId}`; | ||
| } | ||
| function parseShadowComputerId(id) { | ||
| const separator = id.indexOf(":"); | ||
| if (separator <= 0) return null; | ||
| const kind = id.slice(0, separator); | ||
| const sourceId = id.slice(separator + 1); | ||
| if (kind !== "local" && kind !== "cloud" || !sourceId) return null; | ||
| return { kind, sourceId }; | ||
| } | ||
| // src/types/inbox.types.ts | ||
@@ -168,3 +185,3 @@ var BUDDY_INBOX_TOPIC_PREFIX = "shadow:buddy-inbox:"; | ||
| function parseSubjectKind(value) { | ||
| if (value === "user" || value === "agent" || value === "server_app" || value === "system") { | ||
| if (value === "user" || value === "agent" || value === "space_app" || value === "system") { | ||
| return value; | ||
@@ -285,3 +302,3 @@ } | ||
| 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); | ||
| return record.kind === "space_app_copilot" && isBoundedMetadataString(record.appKey, 120, true) && isBoundedMetadataString(record.spaceAppId, 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); | ||
| } | ||
@@ -410,2 +427,8 @@ function buildMessageCopilotContextMetadata(context) { | ||
| } | ||
| function isPollMessageCard(card) { | ||
| return isMetadataRecord(card) && card.kind === "poll" && typeof card.id === "string" && typeof card.pollId === "string" && typeof card.title === "string"; | ||
| } | ||
| function getPollMessageCards(metadata) { | ||
| return Array.isArray(metadata?.cards) ? metadata.cards.filter(isPollMessageCard) : []; | ||
| } | ||
| function getCommerceMessageCards(metadata) { | ||
@@ -579,2 +602,3 @@ return Array.isArray(metadata?.cards) ? metadata.cards.filter(isCommerceMessageCard) : []; | ||
| getPaidFileMessageCards, | ||
| getPollMessageCards, | ||
| hasBuddyInboxTaskCard, | ||
@@ -590,2 +614,3 @@ isBuddyHeartbeatActive, | ||
| isPaidFileMessageCard, | ||
| isPollMessageCard, | ||
| isTaskMessageCardStatus, | ||
@@ -601,6 +626,8 @@ isTerminalTaskMessageCardStatus, | ||
| parseBuddyInboxTaskResultMetadata, | ||
| parseShadowComputerId, | ||
| resolvePresenceStatus, | ||
| runtimeSessionPetReactionForState, | ||
| runtimeSessionSignalToPetReaction, | ||
| runtimeSessionStateLooksActive | ||
| runtimeSessionStateLooksActive, | ||
| shadowComputerId | ||
| }); |
+125
-8
@@ -1,3 +0,3 @@ | ||
| 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'; | ||
| import { m as MessageCardSource, V as TaskMessageRequirements, J as TaskMessageOutputContract, K as TaskMessagePrivacy, s as MessageMetadata, n as MessageCardStatus, E as TaskMessageCard, i as MessageCard, u as MessageReferenceCard } from '../message.types-4XQpzQsK.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, t as MessagePollSummary, N as Notification, v as NotificationType, O as OAuthLinkCard, P as PaidFileCard, w as PollMessageCard, x as PollOptionSummary, y as PollVoterSummary, z as PollVotersPage, R as ReactionGroup, S as SendMessageRequest, D as SpaceAppMessageCard, T as TaskContextPack, F as TaskMessageCardReply, H as TaskMessageCardTag, I as TaskMessageExpectedArtifact, L as TaskMessagePrivacyDataClass, Q as TaskMessageRequirementSkill, U as TaskMessageRequirementTool, W as TaskMessageSubmitCommand, X as TaskResultMessageCard, Y as Thread, Z as UpdateMessageRequest, _ as buildMessageAgentChainMetadata, $ as buildMessageCopilotContextMetadata, a0 as getCommerceMessageCards, a1 as getOAuthLinkMessageCards, a2 as getPaidFileMessageCards, a3 as getPollMessageCards, a4 as isCommerceMessageCard, a5 as isMessageAgentChainMetadata, a6 as isMessageCopilotContext, a7 as isOAuthLinkMessageCard, a8 as isPaidFileMessageCard, a9 as isPollMessageCard, aa as parseBuddyInboxTaskResultMetadata } from '../message.types-4XQpzQsK.cjs'; | ||
@@ -123,2 +123,90 @@ type AgentStatus = 'running' | 'stopped' | 'error'; | ||
| type ShadowComputerKind = 'local' | 'cloud'; | ||
| type ShadowComputerDeviceClass = 'cloud' | 'macbook' | 'imac' | 'mac-mini' | 'mac-studio' | 'laptop' | 'desktop' | 'workstation' | 'server' | 'unknown'; | ||
| type ShadowComputerStatus = 'pending' | 'online' | 'offline' | 'deploying' | 'deployed' | 'paused' | 'resuming' | 'destroying' | 'cancelling' | 'failed' | 'unknown'; | ||
| interface ShadowComputerDevice { | ||
| class: ShadowComputerDeviceClass; | ||
| vendor?: string | null; | ||
| model?: string | null; | ||
| hostname?: string | null; | ||
| os: string | null; | ||
| osVersion?: string | null; | ||
| arch: string | null; | ||
| } | ||
| interface ShadowComputerCapabilities { | ||
| buddies: boolean; | ||
| runtimes: boolean; | ||
| tasks: boolean; | ||
| diagnostics: boolean; | ||
| files: boolean; | ||
| terminal: boolean; | ||
| browser: boolean; | ||
| desktop: boolean; | ||
| backups: boolean; | ||
| connectors: boolean; | ||
| power: boolean; | ||
| } | ||
| interface ShadowComputerRuntime { | ||
| id: string; | ||
| label: string; | ||
| kind?: 'openclaw' | 'cli' | string; | ||
| status: string; | ||
| version?: string | null; | ||
| command?: string | null; | ||
| iconId?: string | null; | ||
| } | ||
| interface ShadowComputerBuddy { | ||
| agentId: string | null; | ||
| buddyId: string; | ||
| name: string; | ||
| username?: string | null; | ||
| avatarUrl?: string | null; | ||
| status: string; | ||
| runtimeId?: string | null; | ||
| runtimeLabel?: string | null; | ||
| workDir?: string | null; | ||
| } | ||
| interface ShadowComputer { | ||
| /** Stable product-layer identifier. Source ids remain available for legacy APIs. */ | ||
| id: string; | ||
| sourceId: string; | ||
| kind: ShadowComputerKind; | ||
| name: string; | ||
| status: ShadowComputerStatus | string; | ||
| device: ShadowComputerDevice; | ||
| capabilities: ShadowComputerCapabilities; | ||
| runtimes: ShadowComputerRuntime[]; | ||
| buddies: ShadowComputerBuddy[]; | ||
| buddyCount: number; | ||
| lastSeenAt?: string | null; | ||
| lastActiveAt?: string | null; | ||
| createdAt?: string | null; | ||
| updatedAt?: string | null; | ||
| local?: { | ||
| installationId?: string | null; | ||
| deviceFingerprint?: string | null; | ||
| daemonVersion?: string | null; | ||
| }; | ||
| cloud?: { | ||
| shellColor?: string | null; | ||
| hourlyCredits?: number | null; | ||
| monthlyCredits?: number | null; | ||
| }; | ||
| } | ||
| interface ShadowAgentComputerPlacement { | ||
| computerId: string; | ||
| computerKind: ShadowComputerKind; | ||
| computerName: string; | ||
| computerStatus: ShadowComputerStatus | string; | ||
| deviceClass: ShadowComputerDeviceClass; | ||
| deviceModel?: string | null; | ||
| runtimeId?: string | null; | ||
| runtimeLabel?: string | null; | ||
| } | ||
| declare function shadowComputerId(kind: ShadowComputerKind, sourceId: string): string; | ||
| declare function parseShadowComputerId(id: string): { | ||
| kind: ShadowComputerKind; | ||
| sourceId: string; | ||
| } | null; | ||
| type FriendshipStatus = 'pending' | 'accepted' | 'blocked'; | ||
@@ -186,3 +274,3 @@ interface Friendship { | ||
| type BuddyInboxAdmissionMode = 'allow' | 'deny' | 'first_time' | 'every_time'; | ||
| type BuddyInboxAdmissionSubjectKind = 'user' | 'agent' | 'server_app' | 'system'; | ||
| type BuddyInboxAdmissionSubjectKind = 'user' | 'agent' | 'space_app' | 'system'; | ||
| interface BuddyInboxAdmissionRule { | ||
@@ -267,5 +355,5 @@ subjectKind: BuddyInboxAdmissionSubjectKind; | ||
| } | ||
| interface ServerDesktopLayoutServerAppItem { | ||
| interface ServerDesktopLayoutSpaceAppItem { | ||
| id: string; | ||
| kind: 'server-app'; | ||
| kind: 'space-app'; | ||
| appKey: string; | ||
@@ -279,3 +367,13 @@ appId?: string; | ||
| } | ||
| type ServerDesktopLayoutItem = ServerDesktopLayoutWorkspaceItem | ServerDesktopLayoutBuiltinAppItem | ServerDesktopLayoutServerAppItem; | ||
| interface ServerDesktopLayoutBuddyInboxItem { | ||
| id: string; | ||
| kind: 'buddy-inbox'; | ||
| agentId: string; | ||
| channelId?: string | null; | ||
| title?: string; | ||
| x: number; | ||
| y: number; | ||
| hidden?: boolean; | ||
| } | ||
| type ServerDesktopLayoutItem = ServerDesktopLayoutWorkspaceItem | ServerDesktopLayoutBuiltinAppItem | ServerDesktopLayoutSpaceAppItem | ServerDesktopLayoutBuddyInboxItem; | ||
| interface ServerDesktopStickyNoteWidget { | ||
@@ -286,2 +384,3 @@ id: string; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
@@ -299,2 +398,3 @@ heightCells: number; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
@@ -316,2 +416,3 @@ heightCells: number; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
@@ -341,2 +442,3 @@ heightCells: number; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
@@ -356,2 +458,3 @@ aspectRatio: number; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
@@ -377,2 +480,3 @@ heightCells: number; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
@@ -385,3 +489,16 @@ heightCells: number; | ||
| } | ||
| type ServerDesktopWidget = ServerDesktopStickyNoteWidget | ServerDesktopChatInputWidget | ServerDesktopTypewriterWidget | ServerDesktopPhotoWidget | ServerDesktopVideoWidget | ServerDesktopWebEmbedWidget; | ||
| interface ServerDesktopRemoteWidget { | ||
| id: string; | ||
| kind: 'remote-widget'; | ||
| sourceId: string; | ||
| options?: Record<string, string>; | ||
| x: number; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
| heightCells: number; | ||
| rotation?: number; | ||
| updatedAt?: string; | ||
| } | ||
| type ServerDesktopWidget = ServerDesktopStickyNoteWidget | ServerDesktopChatInputWidget | ServerDesktopTypewriterWidget | ServerDesktopPhotoWidget | ServerDesktopVideoWidget | ServerDesktopWebEmbedWidget | ServerDesktopRemoteWidget; | ||
| interface ServerDesktopLayout { | ||
@@ -557,2 +674,2 @@ version: 1 | 2; | ||
| export { type Agent, type AgentCapability, type AgentInfo, type AgentKernelType, type AgentStatus, type AuthResponse, BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, BUDDY_INBOX_DELIVERY_PERMISSION, BUDDY_INBOX_PLATFORM_PERMISSIONS, BUDDY_INBOX_TOPIC_PREFIX, BUDDY_PRESENCE_STATUSES, type BuddyInboxAdmissionMode, type BuddyInboxAdmissionPendingDelivery, type BuddyInboxAdmissionPendingTask, type BuddyInboxAdmissionPolicy, type BuddyInboxAdmissionRule, type BuddyInboxAdmissionSubjectKind, type BuddyInboxPlatformPermission, type BuddyInboxViewMessage, type BuddyInboxViewMode, type BuddyPresenceStatus, type Channel, type ChannelSortBy, type ChannelSortDirection, type ChannelSortOptions, type ChannelType, type CreateAgentRequest, type CreateChannelRequest, type CreateServerRequest, DEFAULT_BUDDY_INBOX_ADMISSION_POLICY, type FriendEntry, type FriendSource, type Friendship, type FriendshipStatus, type LoginRequest, type Member, type MemberRole, MessageCard, MessageCardSource, MessageCardStatus, MessageMetadata, MessageReferenceCard, type PresenceChangePayload, type PresenceSnapshotPayload, type PresenceStatus, RUNTIME_SESSION_PET_REACTION_BY_STATE, type RegisterRequest, type RuntimeSessionAnimationSignal, type RuntimeSessionPetActivity, type RuntimeSessionPetActivityKind, type RuntimeSessionPetReaction, type RuntimeSessionState, type Server, type ServerDesktopChatInputWidget, type ServerDesktopChatInputWidgetMode, type ServerDesktopLayout, type ServerDesktopLayoutBuiltinAppItem, type ServerDesktopLayoutItem, type ServerDesktopLayoutServerAppItem, type ServerDesktopLayoutWorkspaceItem, type ServerDesktopPhotoWidget, type ServerDesktopPhotoWidgetSourceType, type ServerDesktopStickyNoteWidget, type ServerDesktopTypewriterWidget, type ServerDesktopTypewriterWidgetFontFamily, type ServerDesktopTypewriterWidgetTextShadow, type ServerDesktopVideoWidget, type ServerDesktopVideoWidgetProvider, type ServerDesktopWebEmbedWidget, type ServerDesktopWebEmbedWidgetSourceType, type ServerDesktopWidget, type ServerWallpaperType, TASK_MESSAGE_CARD_STATUSES, TASK_MESSAGE_CARD_STATUS_TRANSITIONS, TERMINAL_TASK_MESSAGE_CARD_STATUSES, TaskMessageCard, TaskMessageOutputContract, TaskMessagePrivacy, TaskMessageRequirements, USER_STATUSES, type UpdateChannelRequest, type UpdateServerRequest, type User, type UserMembership, type UserMembershipTier, type UserProfile, type UserStatus, type VoiceChannelCredentials, type VoiceChannelJoinResult, type VoiceChannelLeaveResult, type VoiceChannelPolicy, type VoiceChannelState, type 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 }; | ||
| export { type Agent, type AgentCapability, type AgentInfo, type AgentKernelType, type AgentStatus, type AuthResponse, BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, BUDDY_INBOX_DELIVERY_PERMISSION, BUDDY_INBOX_PLATFORM_PERMISSIONS, BUDDY_INBOX_TOPIC_PREFIX, BUDDY_PRESENCE_STATUSES, type BuddyInboxAdmissionMode, type BuddyInboxAdmissionPendingDelivery, type BuddyInboxAdmissionPendingTask, type BuddyInboxAdmissionPolicy, type BuddyInboxAdmissionRule, type BuddyInboxAdmissionSubjectKind, type BuddyInboxPlatformPermission, type BuddyInboxViewMessage, type BuddyInboxViewMode, type BuddyPresenceStatus, type Channel, type ChannelSortBy, type ChannelSortDirection, type ChannelSortOptions, type ChannelType, type CreateAgentRequest, type CreateChannelRequest, type CreateServerRequest, DEFAULT_BUDDY_INBOX_ADMISSION_POLICY, type FriendEntry, type FriendSource, type Friendship, type FriendshipStatus, type LoginRequest, type Member, type MemberRole, MessageCard, MessageCardSource, MessageCardStatus, MessageMetadata, MessageReferenceCard, type PresenceChangePayload, type PresenceSnapshotPayload, type PresenceStatus, RUNTIME_SESSION_PET_REACTION_BY_STATE, type RegisterRequest, type RuntimeSessionAnimationSignal, type RuntimeSessionPetActivity, type RuntimeSessionPetActivityKind, type RuntimeSessionPetReaction, type RuntimeSessionState, type Server, type ServerDesktopChatInputWidget, type ServerDesktopChatInputWidgetMode, type ServerDesktopLayout, type ServerDesktopLayoutBuddyInboxItem, type ServerDesktopLayoutBuiltinAppItem, type ServerDesktopLayoutItem, type ServerDesktopLayoutSpaceAppItem, type ServerDesktopLayoutWorkspaceItem, type ServerDesktopPhotoWidget, type ServerDesktopPhotoWidgetSourceType, type ServerDesktopRemoteWidget, type ServerDesktopStickyNoteWidget, type ServerDesktopTypewriterWidget, type ServerDesktopTypewriterWidgetFontFamily, type ServerDesktopTypewriterWidgetTextShadow, type ServerDesktopVideoWidget, type ServerDesktopVideoWidgetProvider, type ServerDesktopWebEmbedWidget, type ServerDesktopWebEmbedWidgetSourceType, type ServerDesktopWidget, type ServerWallpaperType, type ShadowAgentComputerPlacement, type ShadowComputer, type ShadowComputerBuddy, type ShadowComputerCapabilities, type ShadowComputerDevice, type ShadowComputerDeviceClass, type ShadowComputerKind, type ShadowComputerRuntime, type ShadowComputerStatus, TASK_MESSAGE_CARD_STATUSES, TASK_MESSAGE_CARD_STATUS_TRANSITIONS, TERMINAL_TASK_MESSAGE_CARD_STATUSES, TaskMessageCard, TaskMessageOutputContract, TaskMessagePrivacy, TaskMessageRequirements, USER_STATUSES, type UpdateChannelRequest, type UpdateServerRequest, type User, type UserMembership, type UserMembershipTier, type UserProfile, type UserStatus, type VoiceChannelCredentials, type VoiceChannelJoinResult, type VoiceChannelLeaveResult, type VoiceChannelPolicy, type VoiceChannelState, type VoiceParticipant, applyPresenceChangeToRuntime, buddyInboxAdmissionRuleKey, buddyInboxTopic, buildBuddyInboxViewMessages, canTransitionTaskMessageCardStatus, getBuddyInboxTaskCards, getBuddyInboxTaskStatuses, getBuddyPresenceExpiresAt, hasBuddyInboxTaskCard, isBuddyHeartbeatActive, isBuddyInboxPlatformPermission, isBuddyInboxTopic, isMessageReferenceCard, isTaskMessageCardStatus, isTerminalTaskMessageCardStatus, normalizeBuddyInboxAdmissionPendingDeliveries, normalizeBuddyInboxAdmissionPolicy, normalizeBuddyPresenceStatus, normalizeBuddyRuntimePresenceStatus, normalizePresenceStatus, normalizeUserStatus, parseBuddyInboxAgentId, parseShadowComputerId, resolvePresenceStatus, runtimeSessionPetReactionForState, runtimeSessionSignalToPetReaction, runtimeSessionStateLooksActive, shadowComputerId }; |
+125
-8
@@ -1,3 +0,3 @@ | ||
| 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'; | ||
| import { m as MessageCardSource, V as TaskMessageRequirements, J as TaskMessageOutputContract, K as TaskMessagePrivacy, s as MessageMetadata, n as MessageCardStatus, E as TaskMessageCard, i as MessageCard, u as MessageReferenceCard } from '../message.types-4XQpzQsK.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, t as MessagePollSummary, N as Notification, v as NotificationType, O as OAuthLinkCard, P as PaidFileCard, w as PollMessageCard, x as PollOptionSummary, y as PollVoterSummary, z as PollVotersPage, R as ReactionGroup, S as SendMessageRequest, D as SpaceAppMessageCard, T as TaskContextPack, F as TaskMessageCardReply, H as TaskMessageCardTag, I as TaskMessageExpectedArtifact, L as TaskMessagePrivacyDataClass, Q as TaskMessageRequirementSkill, U as TaskMessageRequirementTool, W as TaskMessageSubmitCommand, X as TaskResultMessageCard, Y as Thread, Z as UpdateMessageRequest, _ as buildMessageAgentChainMetadata, $ as buildMessageCopilotContextMetadata, a0 as getCommerceMessageCards, a1 as getOAuthLinkMessageCards, a2 as getPaidFileMessageCards, a3 as getPollMessageCards, a4 as isCommerceMessageCard, a5 as isMessageAgentChainMetadata, a6 as isMessageCopilotContext, a7 as isOAuthLinkMessageCard, a8 as isPaidFileMessageCard, a9 as isPollMessageCard, aa as parseBuddyInboxTaskResultMetadata } from '../message.types-4XQpzQsK.js'; | ||
@@ -123,2 +123,90 @@ type AgentStatus = 'running' | 'stopped' | 'error'; | ||
| type ShadowComputerKind = 'local' | 'cloud'; | ||
| type ShadowComputerDeviceClass = 'cloud' | 'macbook' | 'imac' | 'mac-mini' | 'mac-studio' | 'laptop' | 'desktop' | 'workstation' | 'server' | 'unknown'; | ||
| type ShadowComputerStatus = 'pending' | 'online' | 'offline' | 'deploying' | 'deployed' | 'paused' | 'resuming' | 'destroying' | 'cancelling' | 'failed' | 'unknown'; | ||
| interface ShadowComputerDevice { | ||
| class: ShadowComputerDeviceClass; | ||
| vendor?: string | null; | ||
| model?: string | null; | ||
| hostname?: string | null; | ||
| os: string | null; | ||
| osVersion?: string | null; | ||
| arch: string | null; | ||
| } | ||
| interface ShadowComputerCapabilities { | ||
| buddies: boolean; | ||
| runtimes: boolean; | ||
| tasks: boolean; | ||
| diagnostics: boolean; | ||
| files: boolean; | ||
| terminal: boolean; | ||
| browser: boolean; | ||
| desktop: boolean; | ||
| backups: boolean; | ||
| connectors: boolean; | ||
| power: boolean; | ||
| } | ||
| interface ShadowComputerRuntime { | ||
| id: string; | ||
| label: string; | ||
| kind?: 'openclaw' | 'cli' | string; | ||
| status: string; | ||
| version?: string | null; | ||
| command?: string | null; | ||
| iconId?: string | null; | ||
| } | ||
| interface ShadowComputerBuddy { | ||
| agentId: string | null; | ||
| buddyId: string; | ||
| name: string; | ||
| username?: string | null; | ||
| avatarUrl?: string | null; | ||
| status: string; | ||
| runtimeId?: string | null; | ||
| runtimeLabel?: string | null; | ||
| workDir?: string | null; | ||
| } | ||
| interface ShadowComputer { | ||
| /** Stable product-layer identifier. Source ids remain available for legacy APIs. */ | ||
| id: string; | ||
| sourceId: string; | ||
| kind: ShadowComputerKind; | ||
| name: string; | ||
| status: ShadowComputerStatus | string; | ||
| device: ShadowComputerDevice; | ||
| capabilities: ShadowComputerCapabilities; | ||
| runtimes: ShadowComputerRuntime[]; | ||
| buddies: ShadowComputerBuddy[]; | ||
| buddyCount: number; | ||
| lastSeenAt?: string | null; | ||
| lastActiveAt?: string | null; | ||
| createdAt?: string | null; | ||
| updatedAt?: string | null; | ||
| local?: { | ||
| installationId?: string | null; | ||
| deviceFingerprint?: string | null; | ||
| daemonVersion?: string | null; | ||
| }; | ||
| cloud?: { | ||
| shellColor?: string | null; | ||
| hourlyCredits?: number | null; | ||
| monthlyCredits?: number | null; | ||
| }; | ||
| } | ||
| interface ShadowAgentComputerPlacement { | ||
| computerId: string; | ||
| computerKind: ShadowComputerKind; | ||
| computerName: string; | ||
| computerStatus: ShadowComputerStatus | string; | ||
| deviceClass: ShadowComputerDeviceClass; | ||
| deviceModel?: string | null; | ||
| runtimeId?: string | null; | ||
| runtimeLabel?: string | null; | ||
| } | ||
| declare function shadowComputerId(kind: ShadowComputerKind, sourceId: string): string; | ||
| declare function parseShadowComputerId(id: string): { | ||
| kind: ShadowComputerKind; | ||
| sourceId: string; | ||
| } | null; | ||
| type FriendshipStatus = 'pending' | 'accepted' | 'blocked'; | ||
@@ -186,3 +274,3 @@ interface Friendship { | ||
| type BuddyInboxAdmissionMode = 'allow' | 'deny' | 'first_time' | 'every_time'; | ||
| type BuddyInboxAdmissionSubjectKind = 'user' | 'agent' | 'server_app' | 'system'; | ||
| type BuddyInboxAdmissionSubjectKind = 'user' | 'agent' | 'space_app' | 'system'; | ||
| interface BuddyInboxAdmissionRule { | ||
@@ -267,5 +355,5 @@ subjectKind: BuddyInboxAdmissionSubjectKind; | ||
| } | ||
| interface ServerDesktopLayoutServerAppItem { | ||
| interface ServerDesktopLayoutSpaceAppItem { | ||
| id: string; | ||
| kind: 'server-app'; | ||
| kind: 'space-app'; | ||
| appKey: string; | ||
@@ -279,3 +367,13 @@ appId?: string; | ||
| } | ||
| type ServerDesktopLayoutItem = ServerDesktopLayoutWorkspaceItem | ServerDesktopLayoutBuiltinAppItem | ServerDesktopLayoutServerAppItem; | ||
| interface ServerDesktopLayoutBuddyInboxItem { | ||
| id: string; | ||
| kind: 'buddy-inbox'; | ||
| agentId: string; | ||
| channelId?: string | null; | ||
| title?: string; | ||
| x: number; | ||
| y: number; | ||
| hidden?: boolean; | ||
| } | ||
| type ServerDesktopLayoutItem = ServerDesktopLayoutWorkspaceItem | ServerDesktopLayoutBuiltinAppItem | ServerDesktopLayoutSpaceAppItem | ServerDesktopLayoutBuddyInboxItem; | ||
| interface ServerDesktopStickyNoteWidget { | ||
@@ -286,2 +384,3 @@ id: string; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
@@ -299,2 +398,3 @@ heightCells: number; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
@@ -316,2 +416,3 @@ heightCells: number; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
@@ -341,2 +442,3 @@ heightCells: number; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
@@ -356,2 +458,3 @@ aspectRatio: number; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
@@ -377,2 +480,3 @@ heightCells: number; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
@@ -385,3 +489,16 @@ heightCells: number; | ||
| } | ||
| type ServerDesktopWidget = ServerDesktopStickyNoteWidget | ServerDesktopChatInputWidget | ServerDesktopTypewriterWidget | ServerDesktopPhotoWidget | ServerDesktopVideoWidget | ServerDesktopWebEmbedWidget; | ||
| interface ServerDesktopRemoteWidget { | ||
| id: string; | ||
| kind: 'remote-widget'; | ||
| sourceId: string; | ||
| options?: Record<string, string>; | ||
| x: number; | ||
| y: number; | ||
| zIndex?: number; | ||
| widthCells: number; | ||
| heightCells: number; | ||
| rotation?: number; | ||
| updatedAt?: string; | ||
| } | ||
| type ServerDesktopWidget = ServerDesktopStickyNoteWidget | ServerDesktopChatInputWidget | ServerDesktopTypewriterWidget | ServerDesktopPhotoWidget | ServerDesktopVideoWidget | ServerDesktopWebEmbedWidget | ServerDesktopRemoteWidget; | ||
| interface ServerDesktopLayout { | ||
@@ -557,2 +674,2 @@ version: 1 | 2; | ||
| export { type Agent, type AgentCapability, type AgentInfo, type AgentKernelType, type AgentStatus, type AuthResponse, BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, BUDDY_INBOX_DELIVERY_PERMISSION, BUDDY_INBOX_PLATFORM_PERMISSIONS, BUDDY_INBOX_TOPIC_PREFIX, BUDDY_PRESENCE_STATUSES, type BuddyInboxAdmissionMode, type BuddyInboxAdmissionPendingDelivery, type BuddyInboxAdmissionPendingTask, type BuddyInboxAdmissionPolicy, type BuddyInboxAdmissionRule, type BuddyInboxAdmissionSubjectKind, type BuddyInboxPlatformPermission, type BuddyInboxViewMessage, type BuddyInboxViewMode, type BuddyPresenceStatus, type Channel, type ChannelSortBy, type ChannelSortDirection, type ChannelSortOptions, type ChannelType, type CreateAgentRequest, type CreateChannelRequest, type CreateServerRequest, DEFAULT_BUDDY_INBOX_ADMISSION_POLICY, type FriendEntry, type FriendSource, type Friendship, type FriendshipStatus, type LoginRequest, type Member, type MemberRole, MessageCard, MessageCardSource, MessageCardStatus, MessageMetadata, MessageReferenceCard, type PresenceChangePayload, type PresenceSnapshotPayload, type PresenceStatus, RUNTIME_SESSION_PET_REACTION_BY_STATE, type RegisterRequest, type RuntimeSessionAnimationSignal, type RuntimeSessionPetActivity, type RuntimeSessionPetActivityKind, type RuntimeSessionPetReaction, type RuntimeSessionState, type Server, type ServerDesktopChatInputWidget, type ServerDesktopChatInputWidgetMode, type ServerDesktopLayout, type ServerDesktopLayoutBuiltinAppItem, type ServerDesktopLayoutItem, type ServerDesktopLayoutServerAppItem, type ServerDesktopLayoutWorkspaceItem, type ServerDesktopPhotoWidget, type ServerDesktopPhotoWidgetSourceType, type ServerDesktopStickyNoteWidget, type ServerDesktopTypewriterWidget, type ServerDesktopTypewriterWidgetFontFamily, type ServerDesktopTypewriterWidgetTextShadow, type ServerDesktopVideoWidget, type ServerDesktopVideoWidgetProvider, type ServerDesktopWebEmbedWidget, type ServerDesktopWebEmbedWidgetSourceType, type ServerDesktopWidget, type ServerWallpaperType, TASK_MESSAGE_CARD_STATUSES, TASK_MESSAGE_CARD_STATUS_TRANSITIONS, TERMINAL_TASK_MESSAGE_CARD_STATUSES, TaskMessageCard, TaskMessageOutputContract, TaskMessagePrivacy, TaskMessageRequirements, USER_STATUSES, type UpdateChannelRequest, type UpdateServerRequest, type User, type UserMembership, type UserMembershipTier, type UserProfile, type UserStatus, type VoiceChannelCredentials, type VoiceChannelJoinResult, type VoiceChannelLeaveResult, type VoiceChannelPolicy, type VoiceChannelState, type 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 }; | ||
| export { type Agent, type AgentCapability, type AgentInfo, type AgentKernelType, type AgentStatus, type AuthResponse, BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, BUDDY_INBOX_DELIVERY_PERMISSION, BUDDY_INBOX_PLATFORM_PERMISSIONS, BUDDY_INBOX_TOPIC_PREFIX, BUDDY_PRESENCE_STATUSES, type BuddyInboxAdmissionMode, type BuddyInboxAdmissionPendingDelivery, type BuddyInboxAdmissionPendingTask, type BuddyInboxAdmissionPolicy, type BuddyInboxAdmissionRule, type BuddyInboxAdmissionSubjectKind, type BuddyInboxPlatformPermission, type BuddyInboxViewMessage, type BuddyInboxViewMode, type BuddyPresenceStatus, type Channel, type ChannelSortBy, type ChannelSortDirection, type ChannelSortOptions, type ChannelType, type CreateAgentRequest, type CreateChannelRequest, type CreateServerRequest, DEFAULT_BUDDY_INBOX_ADMISSION_POLICY, type FriendEntry, type FriendSource, type Friendship, type FriendshipStatus, type LoginRequest, type Member, type MemberRole, MessageCard, MessageCardSource, MessageCardStatus, MessageMetadata, MessageReferenceCard, type PresenceChangePayload, type PresenceSnapshotPayload, type PresenceStatus, RUNTIME_SESSION_PET_REACTION_BY_STATE, type RegisterRequest, type RuntimeSessionAnimationSignal, type RuntimeSessionPetActivity, type RuntimeSessionPetActivityKind, type RuntimeSessionPetReaction, type RuntimeSessionState, type Server, type ServerDesktopChatInputWidget, type ServerDesktopChatInputWidgetMode, type ServerDesktopLayout, type ServerDesktopLayoutBuddyInboxItem, type ServerDesktopLayoutBuiltinAppItem, type ServerDesktopLayoutItem, type ServerDesktopLayoutSpaceAppItem, type ServerDesktopLayoutWorkspaceItem, type ServerDesktopPhotoWidget, type ServerDesktopPhotoWidgetSourceType, type ServerDesktopRemoteWidget, type ServerDesktopStickyNoteWidget, type ServerDesktopTypewriterWidget, type ServerDesktopTypewriterWidgetFontFamily, type ServerDesktopTypewriterWidgetTextShadow, type ServerDesktopVideoWidget, type ServerDesktopVideoWidgetProvider, type ServerDesktopWebEmbedWidget, type ServerDesktopWebEmbedWidgetSourceType, type ServerDesktopWidget, type ServerWallpaperType, type ShadowAgentComputerPlacement, type ShadowComputer, type ShadowComputerBuddy, type ShadowComputerCapabilities, type ShadowComputerDevice, type ShadowComputerDeviceClass, type ShadowComputerKind, type ShadowComputerRuntime, type ShadowComputerStatus, TASK_MESSAGE_CARD_STATUSES, TASK_MESSAGE_CARD_STATUS_TRANSITIONS, TERMINAL_TASK_MESSAGE_CARD_STATUSES, TaskMessageCard, TaskMessageOutputContract, TaskMessagePrivacy, TaskMessageRequirements, USER_STATUSES, type UpdateChannelRequest, type UpdateServerRequest, type User, type UserMembership, type UserMembershipTier, type UserProfile, type UserStatus, type VoiceChannelCredentials, type VoiceChannelJoinResult, type VoiceChannelLeaveResult, type VoiceChannelPolicy, type VoiceChannelState, type VoiceParticipant, applyPresenceChangeToRuntime, buddyInboxAdmissionRuleKey, buddyInboxTopic, buildBuddyInboxViewMessages, canTransitionTaskMessageCardStatus, getBuddyInboxTaskCards, getBuddyInboxTaskStatuses, getBuddyPresenceExpiresAt, hasBuddyInboxTaskCard, isBuddyHeartbeatActive, isBuddyInboxPlatformPermission, isBuddyInboxTopic, isMessageReferenceCard, isTaskMessageCardStatus, isTerminalTaskMessageCardStatus, normalizeBuddyInboxAdmissionPendingDeliveries, normalizeBuddyInboxAdmissionPolicy, normalizeBuddyPresenceStatus, normalizeBuddyRuntimePresenceStatus, normalizePresenceStatus, normalizeUserStatus, parseBuddyInboxAgentId, parseShadowComputerId, resolvePresenceStatus, runtimeSessionPetReactionForState, runtimeSessionSignalToPetReaction, runtimeSessionStateLooksActive, shadowComputerId }; |
+11
-3
@@ -28,2 +28,3 @@ import { | ||
| getPaidFileMessageCards, | ||
| getPollMessageCards, | ||
| hasBuddyInboxTaskCard, | ||
@@ -39,2 +40,3 @@ isBuddyHeartbeatActive, | ||
| isPaidFileMessageCard, | ||
| isPollMessageCard, | ||
| isTaskMessageCardStatus, | ||
@@ -50,7 +52,9 @@ isTerminalTaskMessageCardStatus, | ||
| parseBuddyInboxTaskResultMetadata, | ||
| parseShadowComputerId, | ||
| resolvePresenceStatus, | ||
| runtimeSessionPetReactionForState, | ||
| runtimeSessionSignalToPetReaction, | ||
| runtimeSessionStateLooksActive | ||
| } from "../chunk-G7TRWZCK.js"; | ||
| runtimeSessionStateLooksActive, | ||
| shadowComputerId | ||
| } from "../chunk-DR5LLHH3.js"; | ||
| export { | ||
@@ -83,2 +87,3 @@ BUDDY_HEARTBEAT_ONLINE_THRESHOLD_MS, | ||
| getPaidFileMessageCards, | ||
| getPollMessageCards, | ||
| hasBuddyInboxTaskCard, | ||
@@ -94,2 +99,3 @@ isBuddyHeartbeatActive, | ||
| isPaidFileMessageCard, | ||
| isPollMessageCard, | ||
| isTaskMessageCardStatus, | ||
@@ -105,6 +111,8 @@ isTerminalTaskMessageCardStatus, | ||
| parseBuddyInboxTaskResultMetadata, | ||
| parseShadowComputerId, | ||
| resolvePresenceStatus, | ||
| runtimeSessionPetReactionForState, | ||
| runtimeSessionSignalToPetReaction, | ||
| runtimeSessionStateLooksActive | ||
| runtimeSessionStateLooksActive, | ||
| shadowComputerId | ||
| }; |
+124
-31
@@ -24,11 +24,16 @@ "use strict"; | ||
| CAT_AVATAR_COUNT: () => CAT_AVATAR_COUNT, | ||
| CLOUD_COMPUTER_SHELL_COLORS: () => CLOUD_COMPUTER_SHELL_COLORS, | ||
| CLOUD_COMPUTER_SHELL_PALETTE: () => CLOUD_COMPUTER_SHELL_PALETTE, | ||
| assignMentionRanges: () => assignMentionRanges, | ||
| buildMentionMarkdownLinks: () => buildMentionMarkdownLinks, | ||
| buildServerAppCommunityPath: () => buildServerAppCommunityPath, | ||
| buildServerAppSharePath: () => buildServerAppSharePath, | ||
| buildServerAppShareUrl: () => buildServerAppShareUrl, | ||
| buildSpaceAppCommunityPath: () => buildSpaceAppCommunityPath, | ||
| buildSpaceAppSharePath: () => buildSpaceAppSharePath, | ||
| buildSpaceAppShareUrl: () => buildSpaceAppShareUrl, | ||
| canonicalMentionToken: () => canonicalMentionToken, | ||
| canonicalizeMentionContent: () => canonicalizeMentionContent, | ||
| cloudConnectorAccessKind: () => cloudConnectorAccessKind, | ||
| defaultCloudComputerShellColor: () => defaultCloudComputerShellColor, | ||
| escapeMarkdownLinkLabel: () => escapeMarkdownLinkLabel, | ||
| extractSlashCommandActions: () => extractSlashCommandActions, | ||
| findReadyCloudComputerBuddy: () => findReadyCloudComputerBuddy, | ||
| formatDate: () => formatDate, | ||
@@ -42,11 +47,14 @@ generateInviteCode: () => generateInviteCode, | ||
| isCanonicalMentionToken: () => isCanonicalMentionToken, | ||
| isCloudComputerShellColor: () => isCloudComputerShellColor, | ||
| isValidEmail: () => isValidEmail, | ||
| mentionDisplayText: () => mentionDisplayText, | ||
| normalizeServerAppRoutePath: () => normalizeServerAppRoutePath, | ||
| normalizeSpaceAppRoutePath: () => normalizeSpaceAppRoutePath, | ||
| parseCanonicalMentionToken: () => parseCanonicalMentionToken, | ||
| renderCatSvg: () => renderCatSvg, | ||
| resolveCloudComputerShellColor: () => resolveCloudComputerShellColor, | ||
| segmentTextByMentions: () => segmentTextByMentions, | ||
| serverAppPathFromSearch: () => serverAppPathFromSearch, | ||
| slugify: () => slugify, | ||
| withServerAppRoutePathSearch: () => withServerAppRoutePathSearch | ||
| spaceAppPathFromSearch: () => spaceAppPathFromSearch, | ||
| waitForCloudComputerBuddy: () => waitForCloudComputerBuddy, | ||
| withSpaceAppRoutePathSearch: () => withSpaceAppRoutePathSearch | ||
| }); | ||
@@ -238,2 +246,79 @@ module.exports = __toCommonJS(utils_exports); | ||
| // src/utils/cloud-computer-appearance.ts | ||
| var CLOUD_COMPUTER_SHELL_COLORS = [ | ||
| "aqua", | ||
| "grape", | ||
| "tangerine", | ||
| "lime", | ||
| "strawberry", | ||
| "blueberry", | ||
| "graphite" | ||
| ]; | ||
| var CLOUD_COMPUTER_SHELL_PALETTE = { | ||
| aqua: { shell: "#43D7D1", deep: "#087B83", glow: "#BFFFF7", highlight: "#E9FFFC" }, | ||
| grape: { shell: "#A978E8", deep: "#59349A", glow: "#E7D4FF", highlight: "#F8F1FF" }, | ||
| tangerine: { shell: "#FF9A3D", deep: "#B94F12", glow: "#FFD7A8", highlight: "#FFF3E4" }, | ||
| lime: { shell: "#A7D83E", deep: "#527B13", glow: "#E4F6A8", highlight: "#F8FFE5" }, | ||
| strawberry: { shell: "#F76F96", deep: "#A92C58", glow: "#FFD0DF", highlight: "#FFF0F5" }, | ||
| blueberry: { shell: "#5B8FF4", deep: "#2853A6", glow: "#C9DBFF", highlight: "#EFF5FF" }, | ||
| graphite: { shell: "#7D8999", deep: "#343C48", glow: "#D6DEE8", highlight: "#F1F4F8" } | ||
| }; | ||
| function isCloudComputerShellColor(value) { | ||
| return typeof value === "string" && CLOUD_COMPUTER_SHELL_COLORS.includes(value); | ||
| } | ||
| function defaultCloudComputerShellColor(seed) { | ||
| let hash = 0; | ||
| for (const character of seed) hash = hash * 31 + character.charCodeAt(0) >>> 0; | ||
| return CLOUD_COMPUTER_SHELL_COLORS[hash % CLOUD_COMPUTER_SHELL_COLORS.length] ?? "aqua"; | ||
| } | ||
| function resolveCloudComputerShellColor(value, seed) { | ||
| return isCloudComputerShellColor(value) ? value : defaultCloudComputerShellColor(seed); | ||
| } | ||
| // src/utils/cloud-computer-buddy.ts | ||
| function findReadyCloudComputerBuddy(buddies, expectedId) { | ||
| const buddy = buddies.find((candidate) => candidate.id === expectedId); | ||
| return buddy?.status === "running" && typeof buddy.botUser?.id === "string" && buddy.botUser.id.trim().length > 0 ? buddy : null; | ||
| } | ||
| async function waitForCloudComputerBuddy(input) { | ||
| const timeoutMs = input.timeoutMs ?? 12e4; | ||
| const pollIntervalMs = input.pollIntervalMs ?? 1500; | ||
| const deadline = Date.now() + timeoutMs; | ||
| while (!input.signal?.aborted && Date.now() < deadline) { | ||
| try { | ||
| const buddy = findReadyCloudComputerBuddy(await input.load(), input.expectedId); | ||
| if (buddy) return buddy; | ||
| } catch { | ||
| } | ||
| await new Promise((resolve) => { | ||
| let settled = false; | ||
| const finish = () => { | ||
| if (settled) return; | ||
| settled = true; | ||
| clearTimeout(timer); | ||
| input.signal?.removeEventListener("abort", finish); | ||
| resolve(); | ||
| }; | ||
| const timer = setTimeout(finish, pollIntervalMs); | ||
| input.signal?.addEventListener("abort", finish, { once: true }); | ||
| }); | ||
| } | ||
| return null; | ||
| } | ||
| // src/utils/cloud-connector-access.ts | ||
| function cloudConnectorAccessKind(connector) { | ||
| if (connector.oauth?.available && connector.oauth.configured !== false) return "oauth"; | ||
| if (connector.oauth?.available && connector.oauth.configured === false && connector.authFields.length === 0) { | ||
| return "unavailable"; | ||
| } | ||
| if (connector.authType === "none") return "direct"; | ||
| if (connector.authFields.length === 0 || connector.authFields.every( | ||
| (field) => !field || typeof field !== "object" || Array.isArray(field) || field.required !== true | ||
| )) { | ||
| return "direct"; | ||
| } | ||
| return "manual"; | ||
| } | ||
| // src/utils/message-commands.ts | ||
@@ -319,3 +404,3 @@ 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; | ||
| if (mention.kind === "server") return `<@server:${mention.serverId ?? mention.targetId}>`; | ||
| if (mention.kind === "app") return `<@app:${mention.appId ?? mention.targetId}>`; | ||
| if (mention.kind === "space_app") return `<@space-app:${mention.appId ?? mention.targetId}>`; | ||
| if (mention.kind === "here" || mention.kind === "everyone") { | ||
@@ -328,4 +413,4 @@ const scope = mention.serverId ?? mention.targetId; | ||
| function parseCanonicalMentionToken(token) { | ||
| const app = token.match(/^<@app:([^>]+)>$/u); | ||
| if (app?.[1]) return { kind: "app", targetId: app[1] }; | ||
| const app = token.match(/^<@space-app:([^>]+)>$/u); | ||
| if (app?.[1]) return { kind: "space_app", targetId: app[1] }; | ||
| const user = token.match(/^<@([^>:]+)>$/u); | ||
@@ -617,4 +702,4 @@ if (user?.[1]) return { kind: "user", targetId: user[1] }; | ||
| // src/utils/server-app-routes.ts | ||
| var SERVER_APP_ROUTE_PATH_MAX = 1024; | ||
| // src/utils/space-app-routes.ts | ||
| var SPACE_APP_ROUTE_PATH_MAX = 1024; | ||
| function cleanBasePath(basePath) { | ||
@@ -625,3 +710,3 @@ const trimmed = basePath.trim(); | ||
| } | ||
| function normalizeServerAppRoutePath(value, fallback = null) { | ||
| function normalizeSpaceAppRoutePath(value, fallback = null) { | ||
| if (typeof value !== "string") return fallback; | ||
@@ -632,7 +717,7 @@ const trimmed = value.trim(); | ||
| } | ||
| return trimmed.slice(0, SERVER_APP_ROUTE_PATH_MAX); | ||
| return trimmed.slice(0, SPACE_APP_ROUTE_PATH_MAX); | ||
| } | ||
| function withServerAppRoutePathSearch(search, appPath) { | ||
| function withSpaceAppRoutePathSearch(search, appPath) { | ||
| const next = { ...search ?? {} }; | ||
| const normalized = normalizeServerAppRoutePath(appPath); | ||
| const normalized = normalizeSpaceAppRoutePath(appPath); | ||
| if (normalized && normalized !== "/") { | ||
@@ -645,12 +730,12 @@ next.appPath = normalized; | ||
| } | ||
| function serverAppPathFromSearch(search) { | ||
| return normalizeServerAppRoutePath(search?.appPath); | ||
| function spaceAppPathFromSearch(search) { | ||
| return normalizeSpaceAppRoutePath(search?.appPath); | ||
| } | ||
| function buildServerAppCommunityPath(target, options = {}) { | ||
| function buildSpaceAppCommunityPath(target, options = {}) { | ||
| const basePath = cleanBasePath(options.basePath ?? "/app"); | ||
| const path = `${basePath}/servers/${encodeURIComponent(target.serverSlug)}/apps/${encodeURIComponent( | ||
| const path = `${basePath}/servers/${encodeURIComponent(target.serverSlug)}/space-apps/${encodeURIComponent( | ||
| target.appKey | ||
| )}`; | ||
| const params = new URLSearchParams(); | ||
| const appPath = normalizeServerAppRoutePath(target.appPath); | ||
| const appPath = normalizeSpaceAppRoutePath(target.appPath); | ||
| if (appPath && appPath !== "/") params.set("appPath", appPath); | ||
@@ -660,9 +745,9 @@ const query = params.toString(); | ||
| } | ||
| function buildServerAppSharePath(target, options = {}) { | ||
| function buildSpaceAppSharePath(target, options = {}) { | ||
| const basePath = cleanBasePath(options.basePath ?? "/app"); | ||
| const path = `${basePath}/share/server-app/${encodeURIComponent( | ||
| const path = `${basePath}/share/space-app/${encodeURIComponent( | ||
| target.serverSlug | ||
| )}/${encodeURIComponent(target.appKey)}`; | ||
| const params = new URLSearchParams(); | ||
| const appPath = normalizeServerAppRoutePath(target.appPath); | ||
| const appPath = normalizeSpaceAppRoutePath(target.appPath); | ||
| if (appPath && appPath !== "/") params.set("appPath", appPath); | ||
@@ -672,4 +757,4 @@ const query = params.toString(); | ||
| } | ||
| function buildServerAppShareUrl(target, options = {}) { | ||
| return new URL(buildServerAppSharePath(target, options), target.origin).toString(); | ||
| function buildSpaceAppShareUrl(target, options = {}) { | ||
| return new URL(buildSpaceAppSharePath(target, options), target.origin).toString(); | ||
| } | ||
@@ -693,11 +778,16 @@ | ||
| CAT_AVATAR_COUNT, | ||
| CLOUD_COMPUTER_SHELL_COLORS, | ||
| CLOUD_COMPUTER_SHELL_PALETTE, | ||
| assignMentionRanges, | ||
| buildMentionMarkdownLinks, | ||
| buildServerAppCommunityPath, | ||
| buildServerAppSharePath, | ||
| buildServerAppShareUrl, | ||
| buildSpaceAppCommunityPath, | ||
| buildSpaceAppSharePath, | ||
| buildSpaceAppShareUrl, | ||
| canonicalMentionToken, | ||
| canonicalizeMentionContent, | ||
| cloudConnectorAccessKind, | ||
| defaultCloudComputerShellColor, | ||
| escapeMarkdownLinkLabel, | ||
| extractSlashCommandActions, | ||
| findReadyCloudComputerBuddy, | ||
| formatDate, | ||
@@ -711,11 +801,14 @@ generateInviteCode, | ||
| isCanonicalMentionToken, | ||
| isCloudComputerShellColor, | ||
| isValidEmail, | ||
| mentionDisplayText, | ||
| normalizeServerAppRoutePath, | ||
| normalizeSpaceAppRoutePath, | ||
| parseCanonicalMentionToken, | ||
| renderCatSvg, | ||
| resolveCloudComputerShellColor, | ||
| segmentTextByMentions, | ||
| serverAppPathFromSearch, | ||
| slugify, | ||
| withServerAppRoutePathSearch | ||
| spaceAppPathFromSearch, | ||
| waitForCloudComputerBuddy, | ||
| withSpaceAppRoutePathSearch | ||
| }); |
+56
-12
@@ -1,2 +0,2 @@ | ||
| import { r as MessageMentionRange, p as MessageMention } from '../message.types-Cznw92Uq.cjs'; | ||
| import { r as MessageMentionRange, p as MessageMention } from '../message.types-4XQpzQsK.cjs'; | ||
@@ -20,2 +20,46 @@ type CatPattern = 'none' | 'tabby' | 'tuxedo' | 'siamese' | 'calico' | 'bicolor'; | ||
| declare const CLOUD_COMPUTER_SHELL_COLORS: readonly ["aqua", "grape", "tangerine", "lime", "strawberry", "blueberry", "graphite"]; | ||
| type CloudComputerShellColor = (typeof CLOUD_COMPUTER_SHELL_COLORS)[number]; | ||
| declare const CLOUD_COMPUTER_SHELL_PALETTE: Record<CloudComputerShellColor, { | ||
| shell: string; | ||
| deep: string; | ||
| glow: string; | ||
| highlight: string; | ||
| }>; | ||
| declare function isCloudComputerShellColor(value: unknown): value is CloudComputerShellColor; | ||
| declare function defaultCloudComputerShellColor(seed: string): CloudComputerShellColor; | ||
| declare function resolveCloudComputerShellColor(value: unknown, seed: string): CloudComputerShellColor; | ||
| type CloudComputerBuddyHandshakeCandidate = { | ||
| id: string; | ||
| name: string; | ||
| status: string; | ||
| botUser?: { | ||
| id?: string | null; | ||
| displayName?: string | null; | ||
| username?: string | null; | ||
| avatarUrl?: string | null; | ||
| } | null; | ||
| }; | ||
| declare function findReadyCloudComputerBuddy<T extends CloudComputerBuddyHandshakeCandidate>(buddies: T[], expectedId: string): T | null; | ||
| declare function waitForCloudComputerBuddy<T extends CloudComputerBuddyHandshakeCandidate>(input: { | ||
| load: () => Promise<T[]>; | ||
| expectedId: string; | ||
| timeoutMs?: number; | ||
| pollIntervalMs?: number; | ||
| signal?: AbortSignal; | ||
| }): Promise<T | null>; | ||
| type CloudConnectorAccessKind = 'oauth' | 'manual' | 'direct' | 'unavailable'; | ||
| declare function cloudConnectorAccessKind(connector: { | ||
| oauth?: { | ||
| available?: boolean; | ||
| configured?: boolean; | ||
| } | null; | ||
| authType?: string | null; | ||
| authFields: ReadonlyArray<{ | ||
| required?: boolean; | ||
| } | unknown>; | ||
| }): CloudConnectorAccessKind; | ||
| interface SlashCommandAction { | ||
@@ -45,3 +89,3 @@ id: string; | ||
| } | { | ||
| kind: 'app'; | ||
| kind: 'space_app'; | ||
| targetId: string; | ||
@@ -90,3 +134,3 @@ } | { | ||
| interface ServerAppRouteTarget { | ||
| interface SpaceAppRouteTarget { | ||
| serverSlug: string; | ||
@@ -96,15 +140,15 @@ appKey: string; | ||
| } | ||
| interface ServerAppPathOptions { | ||
| interface SpaceAppPathOptions { | ||
| basePath?: string; | ||
| } | ||
| declare function normalizeServerAppRoutePath(value: unknown, fallback?: string | null): string | null; | ||
| declare function withServerAppRoutePathSearch(search: Record<string, unknown> | null | undefined, appPath: unknown): { | ||
| declare function normalizeSpaceAppRoutePath(value: unknown, fallback?: string | null): string | null; | ||
| declare function withSpaceAppRoutePathSearch(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 & { | ||
| declare function spaceAppPathFromSearch(search: Record<string, unknown> | null | undefined): string | null; | ||
| declare function buildSpaceAppCommunityPath(target: SpaceAppRouteTarget, options?: SpaceAppPathOptions): string; | ||
| declare function buildSpaceAppSharePath(target: SpaceAppRouteTarget, options?: SpaceAppPathOptions): string; | ||
| declare function buildSpaceAppShareUrl(target: SpaceAppRouteTarget & { | ||
| origin: string; | ||
| }, options?: ServerAppPathOptions): string; | ||
| }, options?: SpaceAppPathOptions): string; | ||
@@ -116,2 +160,2 @@ declare const generateInviteCode: (size?: number) => string; | ||
| 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 }; | ||
| export { type BgPattern, CAT_AVATAR_COUNT, CLOUD_COMPUTER_SHELL_COLORS, CLOUD_COMPUTER_SHELL_PALETTE, type CatConfig, type CatDecoration, type CatExpression, type CatPattern, type CloudComputerBuddyHandshakeCandidate, type CloudComputerShellColor, type CloudConnectorAccessKind, type MessageMentionTextSegment, type SlashCommandAction, type SpaceAppPathOptions, type SpaceAppRouteTarget, assignMentionRanges, buildMentionMarkdownLinks, buildSpaceAppCommunityPath, buildSpaceAppSharePath, buildSpaceAppShareUrl, canonicalMentionToken, canonicalizeMentionContent, cloudConnectorAccessKind, defaultCloudComputerShellColor, escapeMarkdownLinkLabel, extractSlashCommandActions, findReadyCloudComputerBuddy, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isCloudComputerShellColor, isValidEmail, mentionDisplayText, normalizeSpaceAppRoutePath, parseCanonicalMentionToken, renderCatSvg, resolveCloudComputerShellColor, segmentTextByMentions, slugify, spaceAppPathFromSearch, waitForCloudComputerBuddy, withSpaceAppRoutePathSearch }; |
+56
-12
@@ -1,2 +0,2 @@ | ||
| import { r as MessageMentionRange, p as MessageMention } from '../message.types-Cznw92Uq.js'; | ||
| import { r as MessageMentionRange, p as MessageMention } from '../message.types-4XQpzQsK.js'; | ||
@@ -20,2 +20,46 @@ type CatPattern = 'none' | 'tabby' | 'tuxedo' | 'siamese' | 'calico' | 'bicolor'; | ||
| declare const CLOUD_COMPUTER_SHELL_COLORS: readonly ["aqua", "grape", "tangerine", "lime", "strawberry", "blueberry", "graphite"]; | ||
| type CloudComputerShellColor = (typeof CLOUD_COMPUTER_SHELL_COLORS)[number]; | ||
| declare const CLOUD_COMPUTER_SHELL_PALETTE: Record<CloudComputerShellColor, { | ||
| shell: string; | ||
| deep: string; | ||
| glow: string; | ||
| highlight: string; | ||
| }>; | ||
| declare function isCloudComputerShellColor(value: unknown): value is CloudComputerShellColor; | ||
| declare function defaultCloudComputerShellColor(seed: string): CloudComputerShellColor; | ||
| declare function resolveCloudComputerShellColor(value: unknown, seed: string): CloudComputerShellColor; | ||
| type CloudComputerBuddyHandshakeCandidate = { | ||
| id: string; | ||
| name: string; | ||
| status: string; | ||
| botUser?: { | ||
| id?: string | null; | ||
| displayName?: string | null; | ||
| username?: string | null; | ||
| avatarUrl?: string | null; | ||
| } | null; | ||
| }; | ||
| declare function findReadyCloudComputerBuddy<T extends CloudComputerBuddyHandshakeCandidate>(buddies: T[], expectedId: string): T | null; | ||
| declare function waitForCloudComputerBuddy<T extends CloudComputerBuddyHandshakeCandidate>(input: { | ||
| load: () => Promise<T[]>; | ||
| expectedId: string; | ||
| timeoutMs?: number; | ||
| pollIntervalMs?: number; | ||
| signal?: AbortSignal; | ||
| }): Promise<T | null>; | ||
| type CloudConnectorAccessKind = 'oauth' | 'manual' | 'direct' | 'unavailable'; | ||
| declare function cloudConnectorAccessKind(connector: { | ||
| oauth?: { | ||
| available?: boolean; | ||
| configured?: boolean; | ||
| } | null; | ||
| authType?: string | null; | ||
| authFields: ReadonlyArray<{ | ||
| required?: boolean; | ||
| } | unknown>; | ||
| }): CloudConnectorAccessKind; | ||
| interface SlashCommandAction { | ||
@@ -45,3 +89,3 @@ id: string; | ||
| } | { | ||
| kind: 'app'; | ||
| kind: 'space_app'; | ||
| targetId: string; | ||
@@ -90,3 +134,3 @@ } | { | ||
| interface ServerAppRouteTarget { | ||
| interface SpaceAppRouteTarget { | ||
| serverSlug: string; | ||
@@ -96,15 +140,15 @@ appKey: string; | ||
| } | ||
| interface ServerAppPathOptions { | ||
| interface SpaceAppPathOptions { | ||
| basePath?: string; | ||
| } | ||
| declare function normalizeServerAppRoutePath(value: unknown, fallback?: string | null): string | null; | ||
| declare function withServerAppRoutePathSearch(search: Record<string, unknown> | null | undefined, appPath: unknown): { | ||
| declare function normalizeSpaceAppRoutePath(value: unknown, fallback?: string | null): string | null; | ||
| declare function withSpaceAppRoutePathSearch(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 & { | ||
| declare function spaceAppPathFromSearch(search: Record<string, unknown> | null | undefined): string | null; | ||
| declare function buildSpaceAppCommunityPath(target: SpaceAppRouteTarget, options?: SpaceAppPathOptions): string; | ||
| declare function buildSpaceAppSharePath(target: SpaceAppRouteTarget, options?: SpaceAppPathOptions): string; | ||
| declare function buildSpaceAppShareUrl(target: SpaceAppRouteTarget & { | ||
| origin: string; | ||
| }, options?: ServerAppPathOptions): string; | ||
| }, options?: SpaceAppPathOptions): string; | ||
@@ -116,2 +160,2 @@ declare const generateInviteCode: (size?: number) => string; | ||
| 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 }; | ||
| export { type BgPattern, CAT_AVATAR_COUNT, CLOUD_COMPUTER_SHELL_COLORS, CLOUD_COMPUTER_SHELL_PALETTE, type CatConfig, type CatDecoration, type CatExpression, type CatPattern, type CloudComputerBuddyHandshakeCandidate, type CloudComputerShellColor, type CloudConnectorAccessKind, type MessageMentionTextSegment, type SlashCommandAction, type SpaceAppPathOptions, type SpaceAppRouteTarget, assignMentionRanges, buildMentionMarkdownLinks, buildSpaceAppCommunityPath, buildSpaceAppSharePath, buildSpaceAppShareUrl, canonicalMentionToken, canonicalizeMentionContent, cloudConnectorAccessKind, defaultCloudComputerShellColor, escapeMarkdownLinkLabel, extractSlashCommandActions, findReadyCloudComputerBuddy, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isCloudComputerShellColor, isValidEmail, mentionDisplayText, normalizeSpaceAppRoutePath, parseCanonicalMentionToken, renderCatSvg, resolveCloudComputerShellColor, segmentTextByMentions, slugify, spaceAppPathFromSearch, waitForCloudComputerBuddy, withSpaceAppRoutePathSearch }; |
+29
-13
| import { | ||
| CAT_AVATAR_COUNT, | ||
| CLOUD_COMPUTER_SHELL_COLORS, | ||
| CLOUD_COMPUTER_SHELL_PALETTE, | ||
| assignMentionRanges, | ||
| buildMentionMarkdownLinks, | ||
| buildServerAppCommunityPath, | ||
| buildServerAppSharePath, | ||
| buildServerAppShareUrl, | ||
| buildSpaceAppCommunityPath, | ||
| buildSpaceAppSharePath, | ||
| buildSpaceAppShareUrl, | ||
| canonicalMentionToken, | ||
| canonicalizeMentionContent, | ||
| cloudConnectorAccessKind, | ||
| defaultCloudComputerShellColor, | ||
| escapeMarkdownLinkLabel, | ||
| extractSlashCommandActions, | ||
| findReadyCloudComputerBuddy, | ||
| formatDate, | ||
@@ -20,23 +25,31 @@ generateInviteCode, | ||
| isCanonicalMentionToken, | ||
| isCloudComputerShellColor, | ||
| isValidEmail, | ||
| mentionDisplayText, | ||
| normalizeServerAppRoutePath, | ||
| normalizeSpaceAppRoutePath, | ||
| parseCanonicalMentionToken, | ||
| renderCatSvg, | ||
| resolveCloudComputerShellColor, | ||
| segmentTextByMentions, | ||
| serverAppPathFromSearch, | ||
| slugify, | ||
| withServerAppRoutePathSearch | ||
| } from "../chunk-NWPWICSP.js"; | ||
| spaceAppPathFromSearch, | ||
| waitForCloudComputerBuddy, | ||
| withSpaceAppRoutePathSearch | ||
| } from "../chunk-K4GUGXY5.js"; | ||
| export { | ||
| CAT_AVATAR_COUNT, | ||
| CLOUD_COMPUTER_SHELL_COLORS, | ||
| CLOUD_COMPUTER_SHELL_PALETTE, | ||
| assignMentionRanges, | ||
| buildMentionMarkdownLinks, | ||
| buildServerAppCommunityPath, | ||
| buildServerAppSharePath, | ||
| buildServerAppShareUrl, | ||
| buildSpaceAppCommunityPath, | ||
| buildSpaceAppSharePath, | ||
| buildSpaceAppShareUrl, | ||
| canonicalMentionToken, | ||
| canonicalizeMentionContent, | ||
| cloudConnectorAccessKind, | ||
| defaultCloudComputerShellColor, | ||
| escapeMarkdownLinkLabel, | ||
| extractSlashCommandActions, | ||
| findReadyCloudComputerBuddy, | ||
| formatDate, | ||
@@ -50,11 +63,14 @@ generateInviteCode, | ||
| isCanonicalMentionToken, | ||
| isCloudComputerShellColor, | ||
| isValidEmail, | ||
| mentionDisplayText, | ||
| normalizeServerAppRoutePath, | ||
| normalizeSpaceAppRoutePath, | ||
| parseCanonicalMentionToken, | ||
| renderCatSvg, | ||
| resolveCloudComputerShellColor, | ||
| segmentTextByMentions, | ||
| serverAppPathFromSearch, | ||
| slugify, | ||
| withServerAppRoutePathSearch | ||
| spaceAppPathFromSearch, | ||
| waitForCloudComputerBuddy, | ||
| withSpaceAppRoutePathSearch | ||
| }; |
+9
-1
| { | ||
| "name": "@shadowob/shared", | ||
| "version": "1.1.65", | ||
| "version": "1.1.66", | ||
| "type": "module", | ||
@@ -57,2 +57,9 @@ "main": "./dist/index.js", | ||
| "default": "./dist/utils/index.js" | ||
| }, | ||
| "./node/device-identity": { | ||
| "types": "./dist/node/device-identity.d.ts", | ||
| "development": "./src/node/device-identity.ts", | ||
| "import": "./dist/node/device-identity.js", | ||
| "require": "./dist/node/device-identity.cjs", | ||
| "default": "./dist/node/device-identity.js" | ||
| } | ||
@@ -68,2 +75,3 @@ }, | ||
| "devDependencies": { | ||
| "@types/node": "^22.19.19", | ||
| "tsup": "^8.5.0", | ||
@@ -70,0 +78,0 @@ "typescript": "^5.9.3" |
| // 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/desktop-ipc/protocol.ts | ||
| import { z as z3 } from "zod"; | ||
| // src/desktop-ipc/rpc.ts | ||
| import { z } from "zod"; | ||
| function ipcProcedure(definition = { | ||
| input: ipcVoidInputSchema, | ||
| output: ipcVoidOutputSchema | ||
| }) { | ||
| return definition; | ||
| } | ||
| function defineIPCService(service) { | ||
| return service; | ||
| } | ||
| function defineIPCProtocol(protocol) { | ||
| return protocol; | ||
| } | ||
| function ipcProcedureChannel(serviceName, methodName, procedure) { | ||
| return procedure?.channel ?? `desktop-rpc:${serviceName}.${methodName}`; | ||
| } | ||
| function parseIPCProcedureInput(procedure, input) { | ||
| return procedure.input.parse(input); | ||
| } | ||
| function parseIPCProcedureOutput(procedure, output) { | ||
| return procedure.output.parse(output); | ||
| } | ||
| var ipcVoidInputSchema = z.void(); | ||
| var ipcVoidOutputSchema = z.void(); | ||
| // src/desktop-ipc/schema.ts | ||
| import { z as z2 } from "zod"; | ||
| var ipcObjectSchema = z2.preprocess( | ||
| (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {}, | ||
| z2.object({}).passthrough() | ||
| ); | ||
| var optionalStringSchema = z2.string().optional(); | ||
| var optionalBooleanSchema = z2.boolean().optional(); | ||
| var optionalTrimmedStringSchema = z2.string().trim().transform((value) => value || void 0).optional(); | ||
| function requiredTrimmedStringSchema(field) { | ||
| return z2.string({ required_error: `Missing ${field}`, invalid_type_error: `Missing ${field}` }).trim().min(1, `Missing ${field}`); | ||
| } | ||
| var connectorStartSettingsSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| connectorApiKey: optionalStringSchema, | ||
| connectorComputerId: optionalStringSchema, | ||
| connectorAutoStart: optionalBooleanSchema, | ||
| connectorWorkDir: optionalStringSchema, | ||
| httpProxy: optionalStringSchema, | ||
| httpsProxy: optionalStringSchema, | ||
| serverBaseUrl: optionalStringSchema | ||
| }) | ||
| ); | ||
| var forceOptionsSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| force: optionalBooleanSchema | ||
| }) | ||
| ); | ||
| var runtimeIdInputSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| runtimeId: requiredTrimmedStringSchema("runtime id") | ||
| }) | ||
| ); | ||
| var createConnectorBuddySchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| runtimeId: requiredTrimmedStringSchema("runtime id"), | ||
| name: requiredTrimmedStringSchema("Buddy name"), | ||
| username: requiredTrimmedStringSchema("Buddy username"), | ||
| description: optionalTrimmedStringSchema, | ||
| avatarUrl: optionalTrimmedStringSchema.nullable().optional().transform((value) => value ?? null) | ||
| }) | ||
| ); | ||
| var connectorConnectionEnabledSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| agentId: requiredTrimmedStringSchema("Buddy id"), | ||
| enabled: z2.boolean().catch(false) | ||
| }) | ||
| ); | ||
| var connectorDeleteSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| agentId: requiredTrimmedStringSchema("Buddy id"), | ||
| deleteCloudBuddy: optionalBooleanSchema | ||
| }) | ||
| ); | ||
| var connectorWorkDirSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| agentId: requiredTrimmedStringSchema("Buddy id"), | ||
| workDir: optionalStringSchema | ||
| }) | ||
| ); | ||
| var desktopPetAssetSpriteSchema = z2.object({ | ||
| src: z2.string(), | ||
| frame: z2.object({ | ||
| width: z2.number(), | ||
| height: z2.number(), | ||
| count: z2.number(), | ||
| fps: z2.number() | ||
| }).optional(), | ||
| atlas: z2.object({ | ||
| columns: z2.number(), | ||
| rows: z2.number(), | ||
| row: z2.number() | ||
| }).optional(), | ||
| loop: z2.boolean().optional() | ||
| }).passthrough(); | ||
| var desktopPetAssetPackSchema = z2.object({ | ||
| id: z2.string(), | ||
| version: z2.string().optional(), | ||
| displayName: z2.record(z2.string()), | ||
| description: z2.union([z2.record(z2.string()), z2.string()]).optional(), | ||
| spritesheetPath: z2.string(), | ||
| sprites: z2.record(desktopPetAssetSpriteSchema), | ||
| importedAt: z2.string(), | ||
| source: z2.enum(["local", "marketplace"]), | ||
| sourcePath: z2.string(), | ||
| marketplaceProductId: z2.string().optional(), | ||
| marketplaceEntitlementId: z2.string().optional(), | ||
| marketplacePaidFileId: z2.string().optional() | ||
| }).passthrough(); | ||
| var desktopShortcutSettingsSchema = z2.object({ | ||
| openCommunity: z2.string(), | ||
| togglePet: z2.string(), | ||
| petVoice: z2.string(), | ||
| petChat: z2.string(), | ||
| showNotifications: z2.string() | ||
| }); | ||
| var desktopSettingsPatchSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| serverBaseUrl: z2.string().optional(), | ||
| httpProxy: z2.string().optional(), | ||
| httpsProxy: z2.string().optional(), | ||
| connectorApiKey: z2.string().optional(), | ||
| connectorComputerId: z2.string().optional(), | ||
| connectorAutoStart: z2.boolean().optional(), | ||
| connectorWorkDir: z2.string().optional(), | ||
| connectorBuddyWorkDirs: z2.record(z2.string()).optional(), | ||
| connectorDeletedConnectionIds: z2.array(z2.string()).optional(), | ||
| connectorRuntimeNotifications: z2.record(z2.boolean()).optional(), | ||
| ttsProvider: z2.enum(["system", "moss-tts-nano", "sherpa-local", "voxcpm2"]).optional(), | ||
| asrProvider: z2.enum(["sherpa-local", "web-speech"]).optional(), | ||
| desktopPetVisible: z2.boolean().optional(), | ||
| desktopPetPacks: z2.array(z2.record(z2.unknown())).optional(), | ||
| desktopPetActivePackId: z2.string().optional(), | ||
| shortcuts: desktopShortcutSettingsSchema.partial().optional() | ||
| }) | ||
| ); | ||
| var optionalPathInputSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| path: optionalStringSchema | ||
| }) | ||
| ); | ||
| var petMarketplaceImportSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| entitlementId: optionalStringSchema, | ||
| fileId: requiredTrimmedStringSchema("paid file id"), | ||
| productId: optionalStringSchema | ||
| }) | ||
| ); | ||
| var petArchiveImportSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| name: z2.unknown().optional(), | ||
| data: z2.unknown().optional() | ||
| }) | ||
| ); | ||
| var packIdInputSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| packId: z2.string().optional().default("") | ||
| }) | ||
| ); | ||
| var startAgentSchema = z2.object({ | ||
| name: z2.string().min(1).max(120), | ||
| scriptPath: z2.string().min(1), | ||
| args: z2.array(z2.string()).optional() | ||
| }); | ||
| var agentProcessIdSchema = z2.string().min(1); | ||
| var desktopNotificationSchema = z2.object({ | ||
| title: z2.string().min(1).max(200), | ||
| body: z2.string().max(2e3), | ||
| channelId: z2.string().optional(), | ||
| messageId: z2.string().optional(), | ||
| routePath: z2.string().optional(), | ||
| target: z2.enum(["community", "pet"]).optional() | ||
| }); | ||
| var badgeCountSchema = z2.number().int().min(0).max(9999).catch(0); | ||
| var notificationModeSchema = z2.string().max(80); | ||
| var updateSettingsSchema = z2.object({ | ||
| autoCheckOnLaunch: z2.boolean().optional(), | ||
| channel: z2.enum(["production", "beta"]).optional() | ||
| }); | ||
| var downloadUpdateUrlSchema = z2.string().url(); | ||
| var openAtLoginSchema = z2.boolean(); | ||
| var voiceModelInstallSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| provider: z2.enum(["system", "moss-tts-nano", "sherpa-local", "voxcpm2"]).optional() | ||
| }) | ||
| ); | ||
| var asrAcceptSchema = z2.object({ | ||
| samples: z2.instanceof(ArrayBuffer), | ||
| sampleRate: z2.number().positive() | ||
| }); | ||
| var speechTextSchema = z2.string().max(8e3); | ||
| var rendererLogSchema = z2.object({ | ||
| scope: z2.string(), | ||
| payload: z2.unknown().optional() | ||
| }).passthrough(); | ||
| var externalUrlSchema = z2.string(); | ||
| var clipboardTextSchema = z2.string(); | ||
| var readerOpenSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| url: z2.string().optional(), | ||
| title: z2.string().optional(), | ||
| useDefaultApp: z2.boolean().optional(), | ||
| attachmentId: z2.string().optional() | ||
| }) | ||
| ); | ||
| var readerIdInputSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| id: z2.string().optional().default("") | ||
| }) | ||
| ); | ||
| var selectDirectorySchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| defaultPath: z2.string().optional() | ||
| }) | ||
| ); | ||
| var communityAuthSnapshotReasonSchema = z2.enum([ | ||
| "startup", | ||
| "storage", | ||
| "sync", | ||
| "login", | ||
| "refresh", | ||
| "logout", | ||
| "settings", | ||
| "revoked" | ||
| ]); | ||
| var communityAuthSnapshotSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| accessToken: z2.string().optional(), | ||
| refreshToken: z2.string().optional(), | ||
| reason: communityAuthSnapshotReasonSchema.optional().default("sync"), | ||
| sourceUrl: z2.string().optional() | ||
| }) | ||
| ); | ||
| var communityFetchJsonSchema = z2.object({ | ||
| path: z2.string().min(1), | ||
| method: z2.string().optional(), | ||
| body: z2.unknown().optional(), | ||
| headers: z2.record(z2.string()).optional(), | ||
| optional: z2.boolean().optional() | ||
| }); | ||
| var modelProxyStreamSchema = z2.object({ | ||
| requestId: z2.string().min(1), | ||
| body: z2.record(z2.unknown()) | ||
| }); | ||
| function optionalStringValueFromPathInput(value, key) { | ||
| if (typeof value === "string") return value; | ||
| const parsed = ipcObjectSchema.pipe(z2.object({ [key]: z2.string().optional() })).parse(value); | ||
| return parsed[key]; | ||
| } | ||
| var showCommunityInputSchema = z2.unknown().transform((value) => optionalStringValueFromPathInput(value, "path")); | ||
| var openCommunityLoginInputSchema = z2.unknown().transform( | ||
| (value) => optionalStringValueFromPathInput(value, "redirect") ?? "/discover" | ||
| ); | ||
| var showSettingsInputSchema = z2.unknown().transform((value) => optionalStringValueFromPathInput(value, "tab")); | ||
| var petPanelModeSchema = z2.enum(["compact", "expanded"]); | ||
| var petWindowDragStartSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| pointerId: z2.number().optional(), | ||
| screenX: z2.number().optional(), | ||
| screenY: z2.number().optional() | ||
| }) | ||
| ); | ||
| var petWindowDragMoveSchema = ipcObjectSchema.pipe( | ||
| z2.object({ | ||
| x: z2.number().optional(), | ||
| y: z2.number().optional(), | ||
| pointerId: z2.number().optional(), | ||
| screenX: z2.number().optional(), | ||
| screenY: z2.number().optional() | ||
| }) | ||
| ); | ||
| var petWindowPointerIdSchema = z2.number().optional(); | ||
| var petWindowMouseInteractiveSchema = z2.boolean(); | ||
| var desktopIpcInvokeSchemas = { | ||
| "desktop:getSettings": void 0, | ||
| "desktop:setSettings": desktopSettingsPatchSchema, | ||
| "desktop:showNotification": desktopNotificationSchema, | ||
| "desktop:setBadgeCount": badgeCountSchema, | ||
| "desktop:setNotificationMode": notificationModeSchema, | ||
| "desktop:minimizeToTray": void 0, | ||
| "desktop:openExternal": externalUrlSchema, | ||
| "desktop:clipboard:writeText": clipboardTextSchema, | ||
| "desktop:openReader": readerOpenSchema, | ||
| "desktop:reader:getState": void 0, | ||
| "desktop:reader:activate": readerIdInputSchema, | ||
| "desktop:reader:close": readerIdInputSchema, | ||
| "desktop:reader:openDefault": readerIdInputSchema, | ||
| "desktop:selectDirectory": selectDirectorySchema, | ||
| "desktop:quit": void 0, | ||
| "desktop:getCommunityAuthToken": void 0, | ||
| "desktop:getCommunityAuthTokens": void 0, | ||
| "desktop:community:fetchJson": communityFetchJsonSchema, | ||
| "desktop:diagnostics:getSnapshot": void 0, | ||
| "desktop:diagnostics:exportLogs": void 0, | ||
| "desktop:showMainWindow": void 0, | ||
| "desktop:showCommunity": showCommunityInputSchema, | ||
| "desktop:openCommunityLogin": openCommunityLoginInputSchema, | ||
| "desktop:showCreateBuddy": void 0, | ||
| "desktop:showContextMenu": void 0, | ||
| "desktop:showSettings": showSettingsInputSchema, | ||
| "desktop:pet:show": void 0, | ||
| "desktop:pet:hide": void 0, | ||
| "desktop:pet:panel-mode": petPanelModeSchema, | ||
| "desktop:pet:begin-window-drag": petWindowDragStartSchema, | ||
| "desktop:pet:move-window": petWindowDragMoveSchema, | ||
| "desktop:pet:end-window-drag": petWindowPointerIdSchema, | ||
| "desktop:pet:mouse-interactive": petWindowMouseInteractiveSchema, | ||
| "desktop:pet:modelProxyStream": modelProxyStreamSchema, | ||
| "desktop:pet:speak": speechTextSchema, | ||
| "desktop:pet:cancelSpeech": void 0, | ||
| "desktop:pet:voiceEngineStatus": void 0, | ||
| "desktop:pet:prewarmVoice": void 0, | ||
| "desktop:pet:installVoiceModel": voiceModelInstallSchema, | ||
| "desktop:pet:asrStart": void 0, | ||
| "desktop:pet:asrAccept": asrAcceptSchema, | ||
| "desktop:pet:asrStop": void 0, | ||
| "desktop:startAgent": startAgentSchema, | ||
| "desktop:stopAgent": agentProcessIdSchema, | ||
| "desktop:getAgentStatus": agentProcessIdSchema, | ||
| "desktop:listAgents": void 0, | ||
| "desktop:getVersion": void 0, | ||
| "desktop:checkForUpdate": void 0, | ||
| "desktop:getUpdateState": void 0, | ||
| "desktop:getUpdateSettings": void 0, | ||
| "desktop:setUpdateSettings": updateSettingsSchema, | ||
| "desktop:downloadUpdate": downloadUpdateUrlSchema, | ||
| "desktop:setOpenAtLogin": openAtLoginSchema, | ||
| "desktop:getOpenAtLogin": void 0, | ||
| "desktop:quitAndRestart": void 0, | ||
| "desktop:petAssets:importDirectory": optionalPathInputSchema, | ||
| "desktop:petAssets:importMarketplace": petMarketplaceImportSchema, | ||
| "desktop:petAssets:importArchiveBuffer": petArchiveImportSchema, | ||
| "desktop:petAssets:setActive": packIdInputSchema, | ||
| "desktop:petAssets:remove": packIdInputSchema, | ||
| "desktop:connector:getStatus": void 0, | ||
| "desktop:connector:start": connectorStartSettingsSchema, | ||
| "desktop:connector:stop": void 0, | ||
| "desktop:connector:scan": void 0, | ||
| "desktop:connector:scanRuntimes": forceOptionsSchema, | ||
| "desktop:connector:scanRuntimeSessions": forceOptionsSchema, | ||
| "desktop:connector:installRuntime": runtimeIdInputSchema, | ||
| "desktop:connector:createBuddy": createConnectorBuddySchema, | ||
| "desktop:connector:getConnections": void 0, | ||
| "desktop:connector:setConnectionEnabled": connectorConnectionEnabledSchema, | ||
| "desktop:connector:deleteConnection": connectorDeleteSchema, | ||
| "desktop:connector:setConnectionWorkDir": connectorWorkDirSchema, | ||
| "desktop:shortcuts:reload": void 0, | ||
| "desktop:shortcuts:suspend": void 0, | ||
| "desktop:shortcuts:resume": void 0 | ||
| }; | ||
| // src/desktop-ipc/protocol.ts | ||
| var desktopPlatformSchema = z3.enum([ | ||
| "aix", | ||
| "android", | ||
| "darwin", | ||
| "freebsd", | ||
| "haiku", | ||
| "linux", | ||
| "openbsd", | ||
| "sunos", | ||
| "win32", | ||
| "cygwin", | ||
| "netbsd" | ||
| ]); | ||
| var desktopRuntimeSettingsSnapshotSchema = z3.object({ | ||
| serverBaseUrl: z3.string(), | ||
| httpProxy: z3.string(), | ||
| httpsProxy: z3.string(), | ||
| connectorApiKey: z3.string(), | ||
| connectorComputerId: z3.string(), | ||
| connectorAutoStart: z3.boolean(), | ||
| connectorWorkDir: z3.string(), | ||
| connectorBuddyWorkDirs: z3.record(z3.string()), | ||
| connectorRuntimeNotifications: z3.record(z3.boolean()), | ||
| ttsProvider: z3.enum(["system", "moss-tts-nano", "sherpa-local", "voxcpm2"]), | ||
| asrProvider: z3.enum(["sherpa-local", "web-speech"]), | ||
| shortcuts: z3.object({ | ||
| openCommunity: z3.string(), | ||
| togglePet: z3.string(), | ||
| petVoice: z3.string(), | ||
| petChat: z3.string(), | ||
| showNotifications: z3.string() | ||
| }), | ||
| desktopPetVisible: z3.boolean(), | ||
| desktopPetActivePackId: z3.string(), | ||
| desktopPetPacks: z3.array(z3.unknown()) | ||
| }); | ||
| var readerResourceSnapshotSchema = z3.object({ | ||
| id: z3.string(), | ||
| title: z3.string(), | ||
| sourceUrl: z3.string(), | ||
| displayAddress: z3.string(), | ||
| contentType: z3.string(), | ||
| fileName: z3.string(), | ||
| assetUrl: z3.string(), | ||
| createdAt: z3.number() | ||
| }); | ||
| var readerStateSnapshotSchema = z3.object({ | ||
| activeId: z3.string().nullable(), | ||
| tabs: z3.array(readerResourceSnapshotSchema) | ||
| }); | ||
| var desktopUpdateChannelSchema = z3.enum(["production", "beta"]); | ||
| var desktopUpdateInfoSchema = z3.object({ | ||
| hasUpdate: z3.boolean(), | ||
| version: z3.string(), | ||
| downloadUrl: z3.string(), | ||
| releaseNotes: z3.string(), | ||
| channel: desktopUpdateChannelSchema | ||
| }); | ||
| var desktopUpdateStateSchema = z3.object({ | ||
| status: z3.enum(["idle", "checking", "update-available", "up-to-date", "error"]), | ||
| checkedAt: z3.number().nullable(), | ||
| info: desktopUpdateInfoSchema.nullable(), | ||
| error: z3.string().nullable(), | ||
| channel: desktopUpdateChannelSchema | ||
| }); | ||
| var desktopUpdateSettingsSchema = z3.object({ | ||
| autoCheckOnLaunch: z3.boolean(), | ||
| channel: desktopUpdateChannelSchema | ||
| }); | ||
| var desktopDiagnosticsSnapshotSchema = z3.object({ | ||
| appName: z3.string(), | ||
| version: z3.string(), | ||
| platform: desktopPlatformSchema, | ||
| arch: z3.string(), | ||
| pid: z3.number(), | ||
| electron: z3.string(), | ||
| node: z3.string(), | ||
| buildId: z3.string(), | ||
| logFilePath: z3.string(), | ||
| logFileExists: z3.boolean(), | ||
| connector: z3.object({ | ||
| serverBaseUrl: z3.string(), | ||
| cliPath: z3.string().nullable(), | ||
| cliBundled: z3.boolean(), | ||
| nodeBinary: z3.string(), | ||
| state: z3.unknown() | ||
| }) | ||
| }); | ||
| var desktopLogExportResultSchema = z3.object({ | ||
| filePath: z3.string().nullable() | ||
| }); | ||
| var voiceProviderStatusSchema = z3.object({ | ||
| installed: z3.boolean(), | ||
| runtimeInstalled: z3.boolean().optional(), | ||
| modelInstalled: z3.boolean().optional(), | ||
| name: z3.string(), | ||
| sourceUrl: z3.string() | ||
| }); | ||
| var voiceEngineStatusSchema = z3.object({ | ||
| engine: z3.string(), | ||
| asrProvider: z3.enum(["sherpa-local", "web-speech"]), | ||
| ttsProvider: z3.enum(["system", "moss-tts-nano", "sherpa-local", "voxcpm2"]), | ||
| nativeAddonAvailable: z3.boolean(), | ||
| modelRoot: z3.string(), | ||
| asr: voiceProviderStatusSchema, | ||
| tts: voiceProviderStatusSchema, | ||
| ttsProviders: z3.object({ | ||
| system: voiceProviderStatusSchema, | ||
| "moss-tts-nano": voiceProviderStatusSchema, | ||
| "sherpa-local": voiceProviderStatusSchema, | ||
| voxcpm2: voiceProviderStatusSchema | ||
| }) | ||
| }); | ||
| var authTokensSchema = z3.object({ | ||
| accessToken: z3.string(), | ||
| refreshToken: z3.string() | ||
| }); | ||
| var agentStartResultSchema = z3.object({ | ||
| id: z3.string(), | ||
| pid: z3.number().optional() | ||
| }); | ||
| var agentStatusSchema = z3.object({ | ||
| running: z3.boolean(), | ||
| name: z3.string().optional(), | ||
| pid: z3.number().optional(), | ||
| uptime: z3.number().optional() | ||
| }); | ||
| var agentListSchema = z3.array( | ||
| z3.object({ | ||
| id: z3.string(), | ||
| name: z3.string(), | ||
| pid: z3.number().optional(), | ||
| running: z3.boolean(), | ||
| uptime: z3.number() | ||
| }) | ||
| ); | ||
| var connectorScanOutputSchema = z3.object({ | ||
| output: z3.string() | ||
| }); | ||
| var petPanelModeResultSchema = z3.object({ | ||
| stageOffsetY: z3.number() | ||
| }); | ||
| var modelProxyStreamResultSchema = z3.object({ | ||
| text: z3.string() | ||
| }); | ||
| var okResultSchema = z3.object({ | ||
| ok: z3.boolean() | ||
| }); | ||
| var textResultSchema = z3.object({ | ||
| text: z3.string() | ||
| }); | ||
| var unknownResultSchema = z3.unknown(); | ||
| var booleanResultSchema = z3.boolean(); | ||
| var stringResultSchema = z3.string(); | ||
| var nullableStringResultSchema = z3.string().nullable(); | ||
| var legacyProcedure = (channel, input, output) => ipcProcedure({ | ||
| channel, | ||
| input, | ||
| output | ||
| }); | ||
| var legacyVoidProcedure = (channel) => legacyProcedure(channel, ipcVoidInputSchema, ipcVoidOutputSchema); | ||
| var desktopIpcProtocol = defineIPCProtocol({ | ||
| app: defineIPCService({ | ||
| getVersion: legacyProcedure("desktop:getVersion", ipcVoidInputSchema, stringResultSchema), | ||
| setOpenAtLogin: legacyProcedure( | ||
| "desktop:setOpenAtLogin", | ||
| openAtLoginSchema, | ||
| ipcVoidOutputSchema | ||
| ), | ||
| getOpenAtLogin: legacyProcedure( | ||
| "desktop:getOpenAtLogin", | ||
| ipcVoidInputSchema, | ||
| booleanResultSchema | ||
| ), | ||
| quitAndRestart: legacyProcedure( | ||
| "desktop:quitAndRestart", | ||
| ipcVoidInputSchema, | ||
| booleanResultSchema | ||
| ) | ||
| }), | ||
| window: defineIPCService({ | ||
| minimizeToTray: legacyVoidProcedure("desktop:minimizeToTray"), | ||
| openExternal: legacyProcedure("desktop:openExternal", externalUrlSchema, booleanResultSchema), | ||
| writeClipboardText: legacyProcedure( | ||
| "desktop:clipboard:writeText", | ||
| clipboardTextSchema, | ||
| booleanResultSchema | ||
| ), | ||
| selectDirectory: legacyProcedure( | ||
| "desktop:selectDirectory", | ||
| selectDirectorySchema, | ||
| nullableStringResultSchema | ||
| ), | ||
| quit: legacyVoidProcedure("desktop:quit"), | ||
| showMainWindow: legacyVoidProcedure("desktop:showMainWindow"), | ||
| showCommunity: legacyProcedure( | ||
| "desktop:showCommunity", | ||
| showCommunityInputSchema, | ||
| ipcVoidOutputSchema | ||
| ), | ||
| openCommunityLogin: legacyProcedure( | ||
| "desktop:openCommunityLogin", | ||
| openCommunityLoginInputSchema, | ||
| booleanResultSchema | ||
| ), | ||
| showCreateBuddy: legacyVoidProcedure("desktop:showCreateBuddy"), | ||
| showContextMenu: legacyVoidProcedure("desktop:showContextMenu"), | ||
| showSettings: legacyProcedure( | ||
| "desktop:showSettings", | ||
| showSettingsInputSchema, | ||
| ipcVoidOutputSchema | ||
| ) | ||
| }), | ||
| settings: defineIPCService({ | ||
| get: legacyProcedure( | ||
| "desktop:getSettings", | ||
| ipcVoidInputSchema, | ||
| desktopRuntimeSettingsSnapshotSchema | ||
| ), | ||
| set: legacyProcedure( | ||
| "desktop:setSettings", | ||
| desktopSettingsPatchSchema, | ||
| desktopRuntimeSettingsSnapshotSchema | ||
| ) | ||
| }), | ||
| notifications: defineIPCService({ | ||
| show: legacyProcedure( | ||
| "desktop:showNotification", | ||
| desktopNotificationSchema, | ||
| ipcVoidOutputSchema | ||
| ), | ||
| setBadgeCount: legacyProcedure("desktop:setBadgeCount", badgeCountSchema, ipcVoidOutputSchema), | ||
| setMode: legacyProcedure( | ||
| "desktop:setNotificationMode", | ||
| notificationModeSchema, | ||
| ipcVoidOutputSchema | ||
| ) | ||
| }), | ||
| reader: defineIPCService({ | ||
| open: legacyProcedure("desktop:openReader", readerOpenSchema, booleanResultSchema), | ||
| getState: legacyProcedure( | ||
| "desktop:reader:getState", | ||
| ipcVoidInputSchema, | ||
| readerStateSnapshotSchema | ||
| ), | ||
| activate: legacyProcedure( | ||
| "desktop:reader:activate", | ||
| readerIdInputSchema, | ||
| readerStateSnapshotSchema | ||
| ), | ||
| close: legacyProcedure("desktop:reader:close", readerIdInputSchema, readerStateSnapshotSchema), | ||
| openDefault: legacyProcedure( | ||
| "desktop:reader:openDefault", | ||
| readerIdInputSchema, | ||
| booleanResultSchema | ||
| ) | ||
| }), | ||
| community: defineIPCService({ | ||
| getAuthToken: legacyProcedure( | ||
| "desktop:getCommunityAuthToken", | ||
| ipcVoidInputSchema, | ||
| stringResultSchema | ||
| ), | ||
| getAuthTokens: legacyProcedure( | ||
| "desktop:getCommunityAuthTokens", | ||
| ipcVoidInputSchema, | ||
| authTokensSchema | ||
| ), | ||
| fetchJson: legacyProcedure( | ||
| "desktop:community:fetchJson", | ||
| communityFetchJsonSchema, | ||
| unknownResultSchema | ||
| ) | ||
| }), | ||
| diagnostics: defineIPCService({ | ||
| getSnapshot: ipcProcedure({ | ||
| input: ipcVoidInputSchema, | ||
| output: desktopDiagnosticsSnapshotSchema | ||
| }), | ||
| exportLogs: ipcProcedure({ | ||
| input: ipcVoidInputSchema, | ||
| output: desktopLogExportResultSchema | ||
| }) | ||
| }), | ||
| petWindow: defineIPCService({ | ||
| show: legacyVoidProcedure("desktop:pet:show"), | ||
| hide: legacyVoidProcedure("desktop:pet:hide"), | ||
| setPanelMode: legacyProcedure( | ||
| "desktop:pet:panel-mode", | ||
| petPanelModeSchema, | ||
| petPanelModeResultSchema | ||
| ), | ||
| beginWindowDrag: legacyProcedure( | ||
| "desktop:pet:begin-window-drag", | ||
| petWindowDragStartSchema, | ||
| ipcVoidOutputSchema | ||
| ), | ||
| moveWindow: legacyProcedure( | ||
| "desktop:pet:move-window", | ||
| petWindowDragMoveSchema, | ||
| ipcVoidOutputSchema | ||
| ), | ||
| endWindowDrag: legacyProcedure( | ||
| "desktop:pet:end-window-drag", | ||
| petWindowPointerIdSchema, | ||
| ipcVoidOutputSchema | ||
| ), | ||
| setMouseInteractive: legacyProcedure( | ||
| "desktop:pet:mouse-interactive", | ||
| petWindowMouseInteractiveSchema, | ||
| ipcVoidOutputSchema | ||
| ) | ||
| }), | ||
| petModel: defineIPCService({ | ||
| modelProxyStream: legacyProcedure( | ||
| "desktop:pet:modelProxyStream", | ||
| modelProxyStreamSchema, | ||
| modelProxyStreamResultSchema | ||
| ) | ||
| }), | ||
| petVoice: defineIPCService({ | ||
| speak: legacyProcedure("desktop:pet:speak", speechTextSchema, booleanResultSchema), | ||
| cancelSpeech: legacyVoidProcedure("desktop:pet:cancelSpeech"), | ||
| voiceEngineStatus: legacyProcedure( | ||
| "desktop:pet:voiceEngineStatus", | ||
| ipcVoidInputSchema, | ||
| voiceEngineStatusSchema | ||
| ), | ||
| prewarmVoice: legacyProcedure( | ||
| "desktop:pet:prewarmVoice", | ||
| ipcVoidInputSchema, | ||
| booleanResultSchema | ||
| ), | ||
| installVoiceModel: legacyProcedure( | ||
| "desktop:pet:installVoiceModel", | ||
| voiceModelInstallSchema, | ||
| voiceEngineStatusSchema | ||
| ), | ||
| asrStart: legacyProcedure("desktop:pet:asrStart", ipcVoidInputSchema, okResultSchema), | ||
| asrAccept: legacyProcedure("desktop:pet:asrAccept", asrAcceptSchema, okResultSchema), | ||
| asrStop: legacyProcedure("desktop:pet:asrStop", ipcVoidInputSchema, textResultSchema) | ||
| }), | ||
| agents: defineIPCService({ | ||
| start: legacyProcedure("desktop:startAgent", startAgentSchema, agentStartResultSchema), | ||
| stop: legacyProcedure("desktop:stopAgent", agentProcessIdSchema, ipcVoidOutputSchema), | ||
| getStatus: legacyProcedure("desktop:getAgentStatus", agentProcessIdSchema, agentStatusSchema), | ||
| list: legacyProcedure("desktop:listAgents", ipcVoidInputSchema, agentListSchema) | ||
| }), | ||
| updates: defineIPCService({ | ||
| check: legacyProcedure("desktop:checkForUpdate", ipcVoidInputSchema, desktopUpdateInfoSchema), | ||
| getState: legacyProcedure( | ||
| "desktop:getUpdateState", | ||
| ipcVoidInputSchema, | ||
| desktopUpdateStateSchema | ||
| ), | ||
| getSettings: legacyProcedure( | ||
| "desktop:getUpdateSettings", | ||
| ipcVoidInputSchema, | ||
| desktopUpdateSettingsSchema | ||
| ), | ||
| setSettings: legacyProcedure( | ||
| "desktop:setUpdateSettings", | ||
| updateSettingsSchema, | ||
| desktopUpdateSettingsSchema | ||
| ), | ||
| download: legacyProcedure( | ||
| "desktop:downloadUpdate", | ||
| downloadUpdateUrlSchema, | ||
| booleanResultSchema | ||
| ) | ||
| }), | ||
| petAssets: defineIPCService({ | ||
| importDirectory: legacyProcedure( | ||
| "desktop:petAssets:importDirectory", | ||
| optionalPathInputSchema, | ||
| unknownResultSchema | ||
| ), | ||
| importMarketplace: legacyProcedure( | ||
| "desktop:petAssets:importMarketplace", | ||
| petMarketplaceImportSchema, | ||
| unknownResultSchema | ||
| ), | ||
| importArchiveBuffer: legacyProcedure( | ||
| "desktop:petAssets:importArchiveBuffer", | ||
| petArchiveImportSchema, | ||
| unknownResultSchema | ||
| ), | ||
| setActive: legacyProcedure( | ||
| "desktop:petAssets:setActive", | ||
| packIdInputSchema, | ||
| unknownResultSchema | ||
| ), | ||
| remove: legacyProcedure("desktop:petAssets:remove", packIdInputSchema, unknownResultSchema) | ||
| }), | ||
| connector: defineIPCService({ | ||
| getStatus: legacyProcedure( | ||
| "desktop:connector:getStatus", | ||
| ipcVoidInputSchema, | ||
| unknownResultSchema | ||
| ), | ||
| start: legacyProcedure( | ||
| "desktop:connector:start", | ||
| connectorStartSettingsSchema, | ||
| unknownResultSchema | ||
| ), | ||
| stop: legacyProcedure("desktop:connector:stop", ipcVoidInputSchema, unknownResultSchema), | ||
| scan: legacyProcedure("desktop:connector:scan", ipcVoidInputSchema, connectorScanOutputSchema), | ||
| scanRuntimes: legacyProcedure( | ||
| "desktop:connector:scanRuntimes", | ||
| forceOptionsSchema, | ||
| unknownResultSchema | ||
| ), | ||
| scanRuntimeSessions: legacyProcedure( | ||
| "desktop:connector:scanRuntimeSessions", | ||
| forceOptionsSchema, | ||
| unknownResultSchema | ||
| ), | ||
| installRuntime: legacyProcedure( | ||
| "desktop:connector:installRuntime", | ||
| runtimeIdInputSchema, | ||
| unknownResultSchema | ||
| ), | ||
| createBuddy: legacyProcedure( | ||
| "desktop:connector:createBuddy", | ||
| createConnectorBuddySchema, | ||
| unknownResultSchema | ||
| ), | ||
| getConnections: legacyProcedure( | ||
| "desktop:connector:getConnections", | ||
| ipcVoidInputSchema, | ||
| unknownResultSchema | ||
| ), | ||
| setConnectionEnabled: legacyProcedure( | ||
| "desktop:connector:setConnectionEnabled", | ||
| connectorConnectionEnabledSchema, | ||
| unknownResultSchema | ||
| ), | ||
| deleteConnection: legacyProcedure( | ||
| "desktop:connector:deleteConnection", | ||
| connectorDeleteSchema, | ||
| unknownResultSchema | ||
| ), | ||
| setConnectionWorkDir: legacyProcedure( | ||
| "desktop:connector:setConnectionWorkDir", | ||
| connectorWorkDirSchema, | ||
| unknownResultSchema | ||
| ) | ||
| }), | ||
| shortcuts: defineIPCService({ | ||
| reload: legacyProcedure("desktop:shortcuts:reload", ipcVoidInputSchema, unknownResultSchema), | ||
| suspend: legacyProcedure("desktop:shortcuts:suspend", ipcVoidInputSchema, unknownResultSchema), | ||
| resume: legacyProcedure("desktop:shortcuts:resume", ipcVoidInputSchema, unknownResultSchema) | ||
| }) | ||
| }); | ||
| export { | ||
| ipcProcedure, | ||
| defineIPCService, | ||
| defineIPCProtocol, | ||
| ipcProcedureChannel, | ||
| parseIPCProcedureInput, | ||
| parseIPCProcedureOutput, | ||
| ipcVoidInputSchema, | ||
| ipcVoidOutputSchema, | ||
| connectorStartSettingsSchema, | ||
| forceOptionsSchema, | ||
| runtimeIdInputSchema, | ||
| createConnectorBuddySchema, | ||
| connectorConnectionEnabledSchema, | ||
| connectorDeleteSchema, | ||
| connectorWorkDirSchema, | ||
| desktopSettingsPatchSchema, | ||
| optionalPathInputSchema, | ||
| petMarketplaceImportSchema, | ||
| petArchiveImportSchema, | ||
| packIdInputSchema, | ||
| startAgentSchema, | ||
| agentProcessIdSchema, | ||
| desktopNotificationSchema, | ||
| badgeCountSchema, | ||
| notificationModeSchema, | ||
| updateSettingsSchema, | ||
| downloadUpdateUrlSchema, | ||
| openAtLoginSchema, | ||
| voiceModelInstallSchema, | ||
| asrAcceptSchema, | ||
| speechTextSchema, | ||
| rendererLogSchema, | ||
| externalUrlSchema, | ||
| clipboardTextSchema, | ||
| readerOpenSchema, | ||
| readerIdInputSchema, | ||
| selectDirectorySchema, | ||
| communityAuthSnapshotSchema, | ||
| communityFetchJsonSchema, | ||
| modelProxyStreamSchema, | ||
| showCommunityInputSchema, | ||
| openCommunityLoginInputSchema, | ||
| showSettingsInputSchema, | ||
| petPanelModeSchema, | ||
| petWindowDragStartSchema, | ||
| petWindowDragMoveSchema, | ||
| petWindowPointerIdSchema, | ||
| petWindowMouseInteractiveSchema, | ||
| desktopIpcInvokeSchemas, | ||
| desktopIpcProtocol | ||
| }; |
| // 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 "offline"; | ||
| } | ||
| 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 ?? null; | ||
| let lastHeartbeat = current.lastHeartbeat ?? null; | ||
| if (update.lastHeartbeat !== void 0) { | ||
| lastHeartbeat = update.lastHeartbeat; | ||
| } else if (userStatus === "online" && (update.agentStatus === "running" || current.agentStatus === "running")) { | ||
| 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/play-catalog/index.ts | ||
| var playCover = (id) => `/home-assets/plays/${id}.jpg`; | ||
| var playTemplate = (id) => ({ | ||
| template: { | ||
| kind: "cloud", | ||
| slug: id, | ||
| path: `apps/cloud/templates/${id}.template.json` | ||
| }, | ||
| materials: { cover: playCover(id) } | ||
| }); | ||
| var communityAction = (channelName) => ({ | ||
| kind: "public_channel", | ||
| channelName, | ||
| buddyTemplateSlug: channelName | ||
| }); | ||
| var roomAction = (namePrefix) => ({ | ||
| kind: "private_room", | ||
| namePrefix, | ||
| buddyTemplateSlug: namePrefix | ||
| }); | ||
| var cloudAction = (templateSlug, resourceTier = "lightweight") => ({ | ||
| kind: "cloud_deploy", | ||
| templateSlug, | ||
| buddyTemplateSlug: templateSlug, | ||
| resourceTier | ||
| }); | ||
| function getPlayBuddyUsername(templateSlug) { | ||
| const normalized = templateSlug.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 27) || "play"; | ||
| return `play_${normalized}`.slice(0, 32); | ||
| } | ||
| function getPlayBuddyEmail(templateSlug) { | ||
| return `${getPlayBuddyUsername(templateSlug)}@shadowob.bot`; | ||
| } | ||
| function cloudPlay(id, input) { | ||
| return { | ||
| id, | ||
| image: playCover(id), | ||
| status: "gated", | ||
| action: cloudAction(id, "lightweight"), | ||
| gates: { auth: "required", membership: "required", profile: "optional" }, | ||
| ...playTemplate(id), | ||
| ...input | ||
| }; | ||
| } | ||
| var DEFAULT_HOMEPLAY_CATALOG = [ | ||
| { | ||
| id: "retire-buddy", | ||
| image: playCover("retire-buddy"), | ||
| title: "\u9000\u4F11\u52A9\u624B", | ||
| titleEn: "RetireBuddy", | ||
| desc: "\u5E2E\u4F60\u89C4\u5212\u9000\u4F11\u751F\u6D3B\u3001\u8D22\u52A1\u81EA\u7531\u8DEF\u5F84\uFF0C24\u5C0F\u65F6\u6E29\u6696\u966A\u4F34\uFF0C\u8BA9\u544A\u522B\u804C\u573A\u53D8\u6210\u4EBA\u751F\u65B0\u7AE0\u8282\u3002", | ||
| descEn: "Plan your retirement and path to financial freedom with a warm 24/7 companion.", | ||
| category: "\u5FC3\u7406\u7597\u6108", | ||
| categoryEn: "Healing", | ||
| starts: "24.5k", | ||
| accentColor: "var(--shadow-accent)", | ||
| hot: true, | ||
| status: "available", | ||
| action: roomAction("retire-buddy"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("retire-buddy") | ||
| }, | ||
| { | ||
| id: "financial-freedom", | ||
| image: playCover("financial-freedom"), | ||
| title: "\u6211\u8D22\u5BCC\u81EA\u7531\u4E86\u5417\uFF1F", | ||
| titleEn: "Am I Free?", | ||
| desc: "\u8F93\u5165\u4F60\u7684\u8D44\u4EA7\u4E0E\u652F\u51FA\uFF0CAI \u4E3A\u4F60\u8BA1\u7B97\u8D22\u52A1\u81EA\u7531\u8DDD\u79BB\uFF0C\u7ED9\u51FA\u6E05\u6670\u7684\u8FBE\u6210\u8DEF\u7EBF\u56FE\u3002", | ||
| descEn: "Input your assets and expenses \u2014 get your financial freedom score and roadmap.", | ||
| category: "\u5FC3\u7406\u7597\u6108", | ||
| categoryEn: "Healing", | ||
| starts: "18.2k", | ||
| accentColor: "#f8e71c", | ||
| status: "available", | ||
| action: communityAction("financial-freedom"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("financial-freedom") | ||
| }, | ||
| { | ||
| id: "brain-fix", | ||
| image: playCover("brain-fix"), | ||
| title: "\u4E00\u5206\u949F\u4FEE\u590D\u4F60\u7684\u5927\u8111\uFF01", | ||
| titleEn: "1-Min Brain Fix", | ||
| desc: "\u79D1\u5B66\u51A5\u60F3 + \u5FAE\u547C\u5438\u7EC3\u4E60\uFF0C60\u79D2\u5185\u4ECE\u7126\u8651\u6A21\u5F0F\u5207\u6362\u5230\u4E13\u6CE8\u72B6\u6001\uFF0C\u5C61\u8BD5\u4E0D\u723D\u3002", | ||
| descEn: "Science-backed micro-meditation. Switch from anxious to focused in 60 seconds.", | ||
| category: "\u5FC3\u7406\u7597\u6108", | ||
| categoryEn: "Healing", | ||
| starts: "15.9k", | ||
| accentColor: "#a78bfa", | ||
| status: "available", | ||
| action: communityAction("brain-fix"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("brain-fix") | ||
| }, | ||
| { | ||
| id: "world-pulse", | ||
| image: playCover("world-pulse"), | ||
| title: "\u5730\u7403\u8109\u640F", | ||
| titleEn: "World Pulse", | ||
| desc: "\u5B9E\u65F6\u6293\u53D6\u5168\u7403\u91CD\u5927\u4E8B\u4EF6\uFF0C\u7528\u4E09\u53E5\u8BDD\u544A\u8BC9\u4F60\u4ECA\u5929\u771F\u6B63\u53D1\u751F\u4E86\u4EC0\u4E48\uFF0C\u65E0\u5E9F\u8BDD\u3002", | ||
| descEn: "Real-time global events in 3 sentences. No filler, just signal.", | ||
| category: "\u4E16\u754C\u8D44\u8BAF", | ||
| categoryEn: "World News", | ||
| starts: "14.1k", | ||
| accentColor: "#38bdf8", | ||
| status: "available", | ||
| action: communityAction("world-pulse"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("world-pulse") | ||
| }, | ||
| { | ||
| id: "daily-brief", | ||
| image: playCover("daily-brief"), | ||
| title: "\u6668\u95F4\u7B80\u62A5", | ||
| titleEn: "Morning Brief", | ||
| desc: "\u6BCF\u5929 7:00 \u63A8\u9001\u4E00\u4EFD\u5B9A\u5236\u65E9\u62A5\uFF1A\u56FD\u9645\u3001\u79D1\u6280\u3001\u5E02\u573A\u4E09\u5927\u677F\u5757\uFF0C\u8BFB\u5B8C\u53EA\u9700 3 \u5206\u949F\u3002", | ||
| descEn: "Custom morning digest at 7am \u2014 global news, tech, markets. 3-minute read.", | ||
| category: "\u4E16\u754C\u8D44\u8BAF", | ||
| categoryEn: "World News", | ||
| starts: "11.3k", | ||
| accentColor: "#fb923c", | ||
| status: "available", | ||
| action: roomAction("daily-brief"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("daily-brief") | ||
| }, | ||
| { | ||
| id: "ai-werewolf", | ||
| image: playCover("ai-werewolf"), | ||
| title: "AI \u72FC\u4EBA\u6740", | ||
| titleEn: "AI Werewolf", | ||
| desc: "AI \u62C5\u4EFB\u4E3B\u6301\uFF0C\u968F\u673A\u5206\u914D\u8EAB\u4EFD\uFF0C\u5728\u804A\u5929\u4E2D\u5C55\u5F00\u63A8\u7406\u4E0E\u535A\u5F08\uFF0C3 \u4EBA\u5373\u53EF\u5F00\u5C40\u3002", | ||
| descEn: "AI-hosted werewolf \u2014 roles assigned randomly, deduce, bluff, and vote. 3+ players.", | ||
| category: "\u4E92\u52A8\u6E38\u620F", | ||
| categoryEn: "Games", | ||
| starts: "20.8k", | ||
| accentColor: "#f87171", | ||
| hot: true, | ||
| status: "available", | ||
| action: communityAction("ai-werewolf"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("ai-werewolf") | ||
| }, | ||
| { | ||
| id: "code-arena", | ||
| image: playCover("code-arena"), | ||
| title: "\u4EE3\u7801\u64C2\u53F0", | ||
| titleEn: "Code Arena", | ||
| desc: "\u5B9E\u65F6\u7F16\u7A0B\u5BF9\u6218\uFF0CAI \u51FA\u9898\u3001\u8BA1\u65F6\u3001\u81EA\u52A8\u8BC4\u6D4B\uFF0C\u6311\u6218\u597D\u53CB\u6216\u5339\u914D\u964C\u751F\u5BF9\u624B\u3002", | ||
| descEn: "Real-time coding battles \u2014 AI generates problems, auto-judges, ranks you live.", | ||
| category: "\u4E92\u52A8\u6E38\u620F", | ||
| categoryEn: "Games", | ||
| starts: "8.6k", | ||
| accentColor: "#fbbf24", | ||
| status: "available", | ||
| action: communityAction("code-arena"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("code-arena") | ||
| }, | ||
| { | ||
| id: "gitstory", | ||
| image: playCover("gitstory"), | ||
| title: "GitStory", | ||
| titleEn: "GitStory", | ||
| desc: "\u628A\u4F60\u7684 GitHub \u63D0\u4EA4\u5386\u53F2\u53D8\u6210\u4E00\u672C\u81EA\u4F20\u5C0F\u8BF4\u2014\u2014AI \u5E2E\u4F60\u56DE\u987E\u6BCF\u4E00\u6BB5\u4EE3\u7801\u80CC\u540E\u7684\u6545\u4E8B\u3002", | ||
| descEn: "Turn your GitHub commits into an autobiography. Every line of code has a story.", | ||
| category: "\u9ED1\u5BA2\u4E0E\u753B\u5BB6", | ||
| categoryEn: "Hacker & Painter", | ||
| starts: "12.1k", | ||
| accentColor: "#34d399", | ||
| hot: true, | ||
| status: "available", | ||
| action: communityAction("gitstory"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("gitstory") | ||
| }, | ||
| { | ||
| id: "gstack", | ||
| image: playCover("gstack"), | ||
| title: "gstack", | ||
| titleEn: "gstack", | ||
| desc: "\u521B\u4E1A\u8005\u7684 AI \u53C2\u8C0B\uFF0C\u5E2E\u4F60\u5FEB\u901F\u9A8C\u8BC1\u5546\u4E1A\u60F3\u6CD5\u3001\u5206\u6790\u7ADE\u4E89\u683C\u5C40\u3001\u751F\u6210\u878D\u8D44\u6587\u4EF6\u3002", | ||
| descEn: "AI co-founder for founders. Validate ideas, map competitors, generate pitch decks.", | ||
| category: "\u9ED1\u5BA2\u4E0E\u753B\u5BB6", | ||
| categoryEn: "Hacker & Painter", | ||
| starts: "9.3k", | ||
| accentColor: "#f97316", | ||
| status: "available", | ||
| action: communityAction("gstack"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("gstack") | ||
| }, | ||
| { | ||
| id: "little-match-girl", | ||
| image: "/home-assets/topics/night-radio.jpg", | ||
| title: "\u5356\u706B\u67F4\u7684\u5C0F\u5973\u5B69", | ||
| titleEn: "Little Match Girl", | ||
| desc: "\u90E8\u7F72\u4E00\u4E2A\u4F1A\u63A8\u9500\u706B\u67F4\u7684\u7AE5\u8BDD Buddy\uFF0C\u8D2D\u4E70\u540E\u5728\u804A\u5929\u53F3\u4FA7\u6253\u5F00\u706B\u67F4\u52A8\u753B\u4ED8\u8D39\u6587\u4EF6\u3002", | ||
| descEn: "Deploy a fairy-tale Buddy who sells glowing matches and unlocks a paid HTML flame animation.", | ||
| category: "MVP \u5B9E\u9A8C", | ||
| categoryEn: "MVP Labs", | ||
| starts: "1.2k", | ||
| accentColor: "#f59e0b", | ||
| hot: true, | ||
| status: "gated", | ||
| action: cloudAction("little-match-girl", "lightweight"), | ||
| gates: { auth: "required", membership: "required", profile: "optional" }, | ||
| ...playTemplate("little-match-girl"), | ||
| materials: { cover: "/home-assets/topics/night-radio.jpg" } | ||
| }, | ||
| cloudPlay("agent-marketplace-buddy", { | ||
| title: "Agent Marketplace Buddy", | ||
| titleEn: "Agent Marketplace Buddy", | ||
| desc: "\u53EF\u7EC4\u5408\u4E13\u5BB6 agent \u5E02\u573A\uFF0C\u8986\u76D6\u5F00\u53D1\u3001\u5B89\u5168\u3001\u57FA\u7840\u8BBE\u65BD\u3001\u6570\u636E\u3001\u6587\u6863\u3001SEO \u548C workflow \u7F16\u6392\u3002", | ||
| descEn: "A composable specialist-agent marketplace for development, security, infra, data, docs, SEO, and workflow orchestration.", | ||
| category: "Buddy \u56E2\u961F", | ||
| categoryEn: "Buddy Teams", | ||
| starts: "16.4k", | ||
| accentColor: "#22d3ee", | ||
| hot: true | ||
| }), | ||
| cloudPlay("bmad-method-buddy", { | ||
| title: "BMAD \u65B9\u6CD5 Buddy", | ||
| titleEn: "BMAD Method Buddy", | ||
| desc: "\u5B8C\u6574 BMAD \u65B9\u6CD5\u8BBA\u56E2\u961F\uFF1A\u5206\u6790\u5E08\u3001PM\u3001\u67B6\u6784\u5E08\u3001Scrum Master\u3001\u5F00\u53D1\u3001QA\uFF0C\u8D2F\u7A7F\u89C4\u5212\u5230\u4EA4\u4ED8\u3002", | ||
| descEn: "A full BMAD method team: analyst, PM, architect, scrum master, dev, and QA from planning to delivery.", | ||
| category: "Buddy \u56E2\u961F", | ||
| categoryEn: "Buddy Teams", | ||
| starts: "13.7k", | ||
| accentColor: "#60a5fa" | ||
| }), | ||
| cloudPlay("claude-ads-buddy", { | ||
| title: "Claude Ads Buddy", | ||
| titleEn: "Claude Ads Buddy", | ||
| desc: "\u4ED8\u8D39\u6295\u653E\u8BCA\u65AD\u3001\u9884\u7B97\u5EFA\u6A21\u3001\u521B\u610F\u5BA1\u67E5\u3001\u8FFD\u8E2A\u95EE\u9898\u548C\u843D\u5730\u9875\u74F6\u9888\u5206\u6790\u3002", | ||
| descEn: "Paid ads audits, budget models, creative review, tracking issues, and landing-page bottlenecks.", | ||
| category: "\u8425\u9500\u6280\u80FD", | ||
| categoryEn: "Marketing Skills", | ||
| starts: "10.8k", | ||
| accentColor: "#fb7185" | ||
| }), | ||
| cloudPlay("claude-seo-buddy", { | ||
| title: "Claude SEO Buddy", | ||
| titleEn: "Claude SEO Buddy", | ||
| desc: "SEO \u5185\u5BB9\u548C\u6280\u672F\u5BA1\u67E5\u56E2\u961F\uFF0C\u8986\u76D6\u5173\u952E\u8BCD\u3001\u5185\u94FE\u3001\u7ED3\u6784\u5316\u6570\u636E\u3001\u9875\u9762\u8D28\u91CF\u548C\u589E\u957F\u8BA1\u5212\u3002", | ||
| descEn: "SEO content and technical review for keywords, links, schema, quality, and growth plans.", | ||
| category: "\u8425\u9500\u6280\u80FD", | ||
| categoryEn: "Marketing Skills", | ||
| starts: "12.6k", | ||
| accentColor: "#84cc16" | ||
| }), | ||
| cloudPlay("everything-claude-code-buddy", { | ||
| title: "Everything Claude Code Buddy", | ||
| titleEn: "Everything Claude Code Buddy", | ||
| desc: "Claude Code \u5DE5\u4F5C\u6D41\u3001\u547D\u4EE4\u548C\u5DE5\u7A0B\u5B9E\u8DF5\u5408\u96C6\uFF0C\u9002\u5408\u7814\u53D1\u56E2\u961F\u6C89\u6DC0\u81EA\u52A8\u5316\u80FD\u529B\u3002", | ||
| descEn: "Claude Code workflows, commands, and engineering practices for automation-heavy teams.", | ||
| category: "\u5F00\u53D1\u6280\u80FD", | ||
| categoryEn: "Developer Skills", | ||
| starts: "19.2k", | ||
| accentColor: "#c084fc", | ||
| hot: true | ||
| }), | ||
| cloudPlay("google-workspace-buddy", { | ||
| title: "Google Workspace Buddy", | ||
| titleEn: "Google Workspace Buddy", | ||
| desc: "\u628A Docs\u3001Sheets\u3001Drive\u3001\u65E5\u5386\u548C\u90AE\u4EF6\u534F\u4F5C\u7F16\u6392\u5230 Buddy \u5DE5\u4F5C\u6D41\u91CC\u3002", | ||
| descEn: "Coordinate Docs, Sheets, Drive, Calendar, and email collaboration through Buddy workflows.", | ||
| category: "\u6548\u7387\u5DE5\u5177", | ||
| categoryEn: "Productivity", | ||
| starts: "9.9k", | ||
| accentColor: "#34d399" | ||
| }), | ||
| cloudPlay("gsd-buddy", { | ||
| title: "GSD Buddy", | ||
| titleEn: "GSD Buddy", | ||
| desc: "\u6267\u884C\u529B\u56E2\u961F\uFF1A\u62C6\u89E3\u4EFB\u52A1\u3001\u6392\u4F18\u5148\u7EA7\u3001\u63A8\u52A8\u51B3\u7B56\u3001\u8FFD\u8E2A\u963B\u585E\uFF0C\u5E2E\u56E2\u961F\u6301\u7EED get stuff done\u3002", | ||
| descEn: "Execution team for task breakdown, priority, decisions, blockers, and getting stuff done.", | ||
| category: "\u6548\u7387\u5DE5\u5177", | ||
| categoryEn: "Productivity", | ||
| starts: "17.5k", | ||
| accentColor: "#facc15", | ||
| hot: true | ||
| }), | ||
| cloudPlay("gstack-buddy", { | ||
| title: "gstack \u6218\u7565 Buddy", | ||
| titleEn: "gstack Strategy Buddy", | ||
| desc: "YC \u98CE\u683C\u4EA7\u54C1\u538B\u529B\u6D4B\u8BD5\u3001CEO \u89C6\u89D2\u8303\u56F4\u8BC4\u5BA1\u3001\u8C03\u67E5\u7EAA\u5F8B\u3001\u5468\u590D\u76D8\u548C gstack \u811A\u672C\u5DE5\u5177\u3002", | ||
| descEn: "YC-style product pressure testing, CEO scope review, investigation discipline, retros, and gstack scripts.", | ||
| category: "\u9ED1\u5BA2\u4E0E\u753B\u5BB6", | ||
| categoryEn: "Hacker & Painter", | ||
| starts: "15.1k", | ||
| accentColor: "#fb923c", | ||
| hot: true | ||
| }), | ||
| cloudPlay("marketingskills-buddy", { | ||
| title: "\u8425\u9500\u6280\u80FD Buddy", | ||
| titleEn: "MarketingSkills Buddy", | ||
| desc: "\u589E\u957F\u56E2\u961F\u7684\u8425\u9500\u534F\u4F5C\u667A\u80FD\u4F53\uFF0C\u8986\u76D6 CRO\u3001\u6587\u6848\u3001SEO\u3001\u4ED8\u8D39\u3001\u90AE\u4EF6\u548C\u589E\u957F\u51B3\u7B56\u3002", | ||
| descEn: "Marketing collaboration agents for CRO, copy, SEO, paid, email, and growth decisions.", | ||
| category: "\u8425\u9500\u6280\u80FD", | ||
| categoryEn: "Marketing Skills", | ||
| starts: "11.7k", | ||
| accentColor: "#f472b6" | ||
| }), | ||
| cloudPlay("scientific-skills-buddy", { | ||
| title: "\u79D1\u7814\u6280\u80FD Buddy", | ||
| titleEn: "Scientific Skills Buddy", | ||
| desc: "\u7814\u7A76\u9605\u8BFB\u3001\u5B9E\u9A8C\u8BBE\u8BA1\u3001\u8BBA\u6587\u7ED3\u6784\u3001\u6570\u636E\u5206\u6790\u548C\u5B66\u672F\u5199\u4F5C\u534F\u4F5C\u56E2\u961F\u3002", | ||
| descEn: "Research reading, experiment design, paper structure, data analysis, and academic writing workflows.", | ||
| category: "\u79D1\u7814\u6280\u80FD", | ||
| categoryEn: "Research Skills", | ||
| starts: "7.8k", | ||
| accentColor: "#38bdf8" | ||
| }), | ||
| cloudPlay("seomachine-buddy", { | ||
| title: "SEO Machine Buddy", | ||
| titleEn: "SEO Machine Buddy", | ||
| desc: "\u6301\u7EED\u8FD0\u884C\u7684 SEO \u673A\u5668\uFF1A\u9009\u9898\u3001brief\u3001\u5185\u5BB9\u5BA1\u67E5\u3001\u6280\u672F\u68C0\u67E5\u548C\u6392\u540D\u590D\u76D8\u3002", | ||
| descEn: "An always-on SEO machine for topics, briefs, review, technical checks, and ranking retros.", | ||
| category: "\u8425\u9500\u6280\u80FD", | ||
| categoryEn: "Marketing Skills", | ||
| starts: "10.2k", | ||
| accentColor: "#a3e635" | ||
| }), | ||
| cloudPlay("slavingia-skills-buddy", { | ||
| title: "Slavingia Skills Buddy", | ||
| titleEn: "Slavingia Skills Buddy", | ||
| desc: "\u521B\u4F5C\u8005\u548C\u72EC\u7ACB\u5F00\u53D1\u8005\u7684\u6280\u80FD\u5E93\uFF0C\u8986\u76D6\u5199\u4F5C\u3001\u4EA7\u54C1\u3001\u589E\u957F\u3001\u793E\u533A\u548C\u53D1\u5E03\u8282\u594F\u3002", | ||
| descEn: "A creator and indie-builder skill stack for writing, product, growth, community, and shipping rhythm.", | ||
| category: "\u521B\u4F5C\u8005\u6280\u80FD", | ||
| categoryEn: "Creator Skills", | ||
| starts: "8.4k", | ||
| accentColor: "#f97316" | ||
| }), | ||
| cloudPlay("superclaude-buddy", { | ||
| title: "SuperClaude Buddy", | ||
| titleEn: "SuperClaude Buddy", | ||
| desc: "SuperClaude \u6307\u4EE4\u3001\u89D2\u8272\u548C\u5DE5\u4F5C\u6D41\u80FD\u529B\uFF0C\u5E2E\u52A9\u56E2\u961F\u628A Claude \u7528\u6210\u7ED3\u6784\u5316\u5DE5\u7A0B\u4F19\u4F34\u3002", | ||
| descEn: "SuperClaude commands, personas, and workflows for structured engineering collaboration.", | ||
| category: "\u5F00\u53D1\u6280\u80FD", | ||
| categoryEn: "Developer Skills", | ||
| starts: "18.9k", | ||
| accentColor: "#818cf8", | ||
| hot: true | ||
| }), | ||
| cloudPlay("superpowers-buddy", { | ||
| title: "Superpowers Buddy", | ||
| titleEn: "Superpowers Buddy", | ||
| desc: "\u4E2A\u4EBA\u751F\u4EA7\u529B\u8D85\u80FD\u529B\u7EC4\u5408\uFF1A\u9605\u8BFB\u3001\u5199\u4F5C\u3001\u4EFB\u52A1\u3001\u7814\u7A76\u3001\u81EA\u52A8\u5316\u548C\u590D\u76D8\u3002", | ||
| descEn: "Personal productivity superpowers for reading, writing, tasks, research, automation, and retros.", | ||
| category: "\u6548\u7387\u5DE5\u5177", | ||
| categoryEn: "Productivity", | ||
| starts: "12.4k", | ||
| accentColor: "#2dd4bf" | ||
| }), | ||
| { | ||
| id: "e-wife", | ||
| image: playCover("e-wife"), | ||
| title: "\u7535\u5B50\u8001\u5A46", | ||
| titleEn: "E-Wife", | ||
| desc: "\u4E00\u4E2A\u5E26\u6709\u966A\u4F34\u611F\u7684\u865A\u62DF\u751F\u6D3B\u4F19\u4F34\u73A9\u6CD5\uFF0C\u540E\u7EED\u4F1A\u63A5\u5165\u4E2A\u6027\u5316\u8BB0\u5FC6\u548C\u79C1\u6709\u623F\u95F4\u3002", | ||
| descEn: "A companion-style virtual life partner play, later connected to memory and private rooms.", | ||
| category: "\u5FC3\u7406\u7597\u6108", | ||
| categoryEn: "Healing", | ||
| starts: "22.0k", | ||
| accentColor: "#f0abfc", | ||
| status: "available", | ||
| action: roomAction("e-wife"), | ||
| gates: { auth: "required", membership: "none", profile: "optional" }, | ||
| ...playTemplate("e-wife") | ||
| } | ||
| ]; | ||
| function getDefaultHomePlay(playId) { | ||
| return DEFAULT_HOMEPLAY_CATALOG.find((play) => play.id === playId) ?? null; | ||
| } | ||
| export { | ||
| getPlayBuddyUsername, | ||
| getPlayBuddyEmail, | ||
| DEFAULT_HOMEPLAY_CATALOG, | ||
| getDefaultHomePlay | ||
| }; |
| // 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 }; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
805229
8.88%37
12.12%14070
10.13%3
50%6
200%