/** * Inbox "noise" messages are structured JSON objects that represent internal coordination * signals (idle/shutdown/etc.). They should not trigger user-facing notifications or * automatic lead relays. */ export const INBOX_NOISE_TYPES = [ 'idle_notification', 'shutdown_approved', 'teammate_terminated', 'shutdown_request', ] as const; const INBOX_NOISE_SET = new Set(INBOX_NOISE_TYPES); export function parseInboxJson(text: string): Record | null { const trimmed = text.trim(); if (!trimmed.startsWith('{')) return null; try { const parsed = JSON.parse(trimmed) as unknown; if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) { return parsed as Record; } } catch { // not JSON } return null; } export function getInboxJsonType(text: string): string | null { const parsed = parseInboxJson(text); if (!parsed) return null; return typeof parsed.type === 'string' ? parsed.type : null; } export function isInboxNoiseMessage(text: string): boolean { const type = getInboxJsonType(text); return !!type && INBOX_NOISE_SET.has(type); } /** * Returns true when a teammate message is substantive enough to count as a real * bootstrap/check-in signal. Internal coordination noise like idle/shutdown * JSON should keep the runtime marked alive, but must not be treated as a * teammate "checked in" signal in launch UX. */ export function isMeaningfulBootstrapCheckInMessage(text: string): boolean { return text.trim().length > 0 && !isInboxNoiseMessage(text); } // --------------------------------------------------------------------------- // Teammate permission request parsing // --------------------------------------------------------------------------- /** A single permission suggestion from the teammate runtime. */ export interface PermissionSuggestion { type: string; rules?: { toolName: string }[]; behavior?: string; destination?: string; /** Permission mode name (for type: "setMode"). FACT: observed values: "acceptEdits", "bypassPermissions" */ mode?: string; } /** Parsed teammate permission request from inbox message. */ export interface ParsedPermissionRequest { requestId: string; agentId: string; toolName: string; toolUseId: string; description: string; input: Record; /** Suggestions from teammate runtime on how to resolve the permission. * FACT: This field is populated by Claude Code runtime, not by the AI agent. * FACT: Observed format: { type: "addRules", rules: [{toolName}], behavior: "allow", destination: "localSettings" } */ permissionSuggestions: PermissionSuggestion[]; } /** * Parses a `permission_request` JSON message from a teammate's inbox entry. * Returns null if the text is not a valid permission_request. */ export function parsePermissionRequest(text: string): ParsedPermissionRequest | null { const parsed = parseInboxJson(text); if (parsed?.type !== 'permission_request') return null; const requestId = typeof parsed.request_id === 'string' ? parsed.request_id : null; const agentId = typeof parsed.agent_id === 'string' ? parsed.agent_id : null; const toolName = typeof parsed.tool_name === 'string' ? parsed.tool_name : null; if (!requestId || !agentId || !toolName) return null; return { requestId, agentId, toolName, toolUseId: typeof parsed.tool_use_id === 'string' ? parsed.tool_use_id : '', description: typeof parsed.description === 'string' ? parsed.description : '', input: parsed.input && typeof parsed.input === 'object' && !Array.isArray(parsed.input) ? (parsed.input as Record) : {}, permissionSuggestions: Array.isArray(parsed.permission_suggestions) ? (parsed.permission_suggestions as PermissionSuggestion[]) : [], }; } // --------------------------------------------------------------------------- // Teammate-message XML block detection & stripping // --------------------------------------------------------------------------- const TEAMMATE_MESSAGE_BLOCK_RE = /]*>[\s\S]*?<\/teammate-message>/g; /** * Removes `` XML blocks from text. * Used to clean protocol artifacts that leak into lead thoughts. */ export function stripTeammateMessageBlocks(text: string): string { return text .replace(TEAMMATE_MESSAGE_BLOCK_RE, '\n') .replace(/\n{3,}/g, '\n\n') .trim(); } /** * Returns true if the entire text consists only of `` blocks * (possibly with whitespace between them) and no meaningful user-visible content. */ export function isOnlyTeammateMessageBlocks(text: string): boolean { const stripped = stripTeammateMessageBlocks(text); return stripped.length === 0; } // --------------------------------------------------------------------------- // Combined protocol noise check for lead thoughts // --------------------------------------------------------------------------- /** * Detects `` opening tags (even without closing tag). * Claude's lead model sometimes echoes raw teammate message XML in assistant * text output — these are always protocol artifacts, never real user content. */ const TEAMMATE_MESSAGE_OPEN_RE = /^\s*