@guildai/cli 0.12.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/{auth-CRMO5O3N.js → auth-67G3BIAW.js} +2 -2
  2. package/dist/{chat-5VX2WJH2.js → chat-ALOJ22JR.js} +7 -7
  3. package/dist/{chat-SIKDYZQK.js → chat-SG2I727J.js} +8 -6
  4. package/dist/{chunk-IBRKVGMZ.js → chunk-7JJT3RNI.js} +607 -376
  5. package/dist/{chunk-IBRKVGMZ.js.map → chunk-7JJT3RNI.js.map} +4 -4
  6. package/dist/{chunk-B7VAF5UG.js → chunk-EQUW4M5A.js} +3 -3
  7. package/dist/{chunk-SPZPZXUN.js → chunk-F3F5CUO3.js} +18 -3
  8. package/dist/chunk-F3F5CUO3.js.map +7 -0
  9. package/dist/{chunk-LFMQJOKC.js → chunk-JQRJ4A4S.js} +2 -2
  10. package/dist/{chunk-RIG2HZWM.js → chunk-RJHD6XTV.js} +2 -2
  11. package/dist/{chunk-DOIYVBNY.js → chunk-YQWI6SUV.js} +2 -2
  12. package/dist/commands/chat.d.ts +21 -0
  13. package/dist/index.js +8 -8
  14. package/dist/lib/display-message.d.ts +11 -0
  15. package/dist/lib/markdown.d.ts +2 -9
  16. package/dist/lib/response-stream-display-state.d.ts +51 -0
  17. package/dist/lib/session-events.d.ts +4 -0
  18. package/dist/lib/session-resume.d.ts +2 -6
  19. package/dist/{server-JYVH64FD.js → server-CKXFV2JC.js} +4 -4
  20. package/dist/{test-SNIYRJ32.js → test-VEA4ENOR.js} +7 -7
  21. package/package.json +1 -1
  22. package/dist/chunk-SPZPZXUN.js.map +0 -7
  23. /package/dist/{auth-CRMO5O3N.js.map → auth-67G3BIAW.js.map} +0 -0
  24. /package/dist/{chat-5VX2WJH2.js.map → chat-ALOJ22JR.js.map} +0 -0
  25. /package/dist/{chat-SIKDYZQK.js.map → chat-SG2I727J.js.map} +0 -0
  26. /package/dist/{chunk-B7VAF5UG.js.map → chunk-EQUW4M5A.js.map} +0 -0
  27. /package/dist/{chunk-LFMQJOKC.js.map → chunk-JQRJ4A4S.js.map} +0 -0
  28. /package/dist/{chunk-RIG2HZWM.js.map → chunk-RJHD6XTV.js.map} +0 -0
  29. /package/dist/{chunk-DOIYVBNY.js.map → chunk-YQWI6SUV.js.map} +0 -0
  30. /package/dist/{server-JYVH64FD.js.map → server-CKXFV2JC.js.map} +0 -0
  31. /package/dist/{test-SNIYRJ32.js.map → test-VEA4ENOR.js.map} +0 -0
@@ -6,11 +6,11 @@ import {
6
6
  GuildAPIClient,
7
7
  loadGlobalConfig,
8
8
  loadLocalConfig
9
- } from "./chunk-RIG2HZWM.js";
9
+ } from "./chunk-RJHD6XTV.js";
10
10
  import {
11
11
  createSpinner,
12
12
  debug
13
- } from "./chunk-LFMQJOKC.js";
13
+ } from "./chunk-JQRJ4A4S.js";
14
14
  import {
15
15
  esm_default
16
16
  } from "./chunk-M347HP6M.js";
@@ -529,4 +529,4 @@ export {
529
529
  BundleNotFoundError,
530
530
  buildBundledVersion
531
531
  };
532
- //# sourceMappingURL=chunk-B7VAF5UG.js.map
532
+ //# sourceMappingURL=chunk-EQUW4M5A.js.map
@@ -1,7 +1,7 @@
1
1
  import { createRequire as _cjsReq } from 'module'; if(typeof require === 'undefined') var require = _cjsReq(import.meta.url);
2
2
  import {
3
3
  shouldShowEvent
4
- } from "./chunk-RIG2HZWM.js";
4
+ } from "./chunk-RJHD6XTV.js";
5
5
  import {
6
6
  ErrorCodes,
7
7
  GuildCLIError,
@@ -10,7 +10,7 @@ import {
10
10
  getGuildcoreWsUrl,
11
11
  getIapHeaders,
12
12
  isDebugMode
13
- } from "./chunk-LFMQJOKC.js";
13
+ } from "./chunk-JQRJ4A4S.js";
14
14
  import {
15
15
  wrapper_default
16
16
  } from "./chunk-X3ADGWOF.js";
@@ -60,6 +60,20 @@ function getTaskDisplayName(task) {
60
60
  }
61
61
  return "Unknown";
62
62
  }
63
+ function getEventAgentName(event, fallbackName = "assistant") {
64
+ const task = event.task;
65
+ if (!task) return fallbackName;
66
+ if ("agent" in task && task.agent) {
67
+ return getAgentName(task.agent);
68
+ }
69
+ if ("parent_task" in task && task.parent_task) {
70
+ const parent = task.parent_task;
71
+ if ("agent" in parent && parent.agent) {
72
+ return getAgentName(parent.agent);
73
+ }
74
+ }
75
+ return fallbackName;
76
+ }
63
77
  function isUnfulfilledAgentInstallRequest(event) {
64
78
  return event.type === "agent_install_request" && !event.is_fulfilled;
65
79
  }
@@ -813,6 +827,7 @@ export {
813
827
  isFilteredTaskName,
814
828
  getAgentName,
815
829
  getTaskDisplayName,
830
+ getEventAgentName,
816
831
  isUnfulfilledAgentInstallRequest,
817
832
  isResponseStreamEvent,
818
833
  isDoneResponseStreamEvent,
@@ -823,4 +838,4 @@ export {
823
838
  pollForResponseWithEvents,
824
839
  pollForOnce
825
840
  };
826
- //# sourceMappingURL=chunk-SPZPZXUN.js.map
841
+ //# sourceMappingURL=chunk-F3F5CUO3.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/lib/session-events-fetch.ts", "../src/lib/session-events.ts", "../src/lib/websocket-client.ts", "../src/lib/session-polling.ts"],
4
+ "sourcesContent": ["// Copyright 2026 Guild.ai\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Shared event/task fetching for session polling.\n *\n * Consolidates the duplicate response parsing that was scattered across\n * chat.tsx, session-polling.ts, and session-resume.ts.\n */\n\nimport { GuildAPIClient } from './api-client.js';\nimport { SessionEvent, SessionTask } from './session-events.js';\n\ninterface FetchOptions {\n /** Only return events after this event ID (server-side cursor). */\n fromId?: string;\n /** Maximum number of events to return. Default 1000. */\n limit?: number;\n}\n\n/**\n * Fetch session events from the API.\n *\n * Uses from_id cursor so callers only fetch new events\n * instead of re-fetching everything on every poll cycle.\n */\nexport async function fetchEvents(\n client: GuildAPIClient,\n sessionId: string,\n options: FetchOptions = {}\n): Promise<SessionEvent[]> {\n const { fromId, limit = 1000 } = options;\n let url = `/sessions/${sessionId}/events?limit=${limit}`;\n if (fromId) {\n url += `&from_id=${fromId}`;\n }\n const response = await client.get<{ items: SessionEvent[] }>(url);\n return response?.items || [];\n}\n\n/**\n * Fetch session tasks from the API.\n */\nexport async function fetchTasks(\n client: GuildAPIClient,\n sessionId: string\n): Promise<SessionTask[]> {\n const response = await client.get<{ items: SessionTask[] }>(\n `/sessions/${sessionId}/tasks?limit=1000`\n );\n return response?.items || [];\n}\n", "// Copyright 2026 Guild.ai\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Shared session event type definitions for Guild CLI\n *\n * These types match the backend event system from the messaging refactor (PR #819).\n * All CLI commands should import these types instead of defining their own.\n */\n\n// =============================================================================\n// Task Types\n// =============================================================================\n\nexport type TaskStatus =\n | 'CREATED'\n | 'DISPATCHED'\n | 'STARTED'\n | 'RUNNING'\n | 'WAITING'\n | 'DONE'\n | 'ERROR'\n | 'INTERRUPTED';\n\nexport interface BaseTaskFields {\n id: string;\n status: TaskStatus;\n created_at: string;\n updated_at: string;\n}\n\n/** Serialized agent reference returned by the backend */\nexport interface AgentRef {\n id: string;\n name: string;\n full_name: string;\n}\n\nexport interface SessionTaskAgentItem extends BaseTaskFields {\n agent: AgentRef;\n parent_task_id: string | null;\n}\n\nexport interface SessionTaskToolItem extends BaseTaskFields {\n tool_name: string;\n tool_call_id: string;\n parent_task: SessionTaskItem | null;\n}\n\nexport type SessionTaskItem = SessionTaskAgentItem | SessionTaskToolItem;\n\nexport interface SessionTaskAgent extends SessionTaskAgentItem {\n parent_task: SessionTaskItem | null;\n}\n\nexport interface SessionTaskTool extends SessionTaskToolItem {\n parent_task: SessionTaskItem | null;\n}\n\nexport type SessionTask = SessionTaskAgent | SessionTaskTool;\n\n// =============================================================================\n// Task Filtering\n// =============================================================================\n\n/**\n * Internal task names that should be hidden from user-facing displays.\n * These are coordination/UI mechanisms, not meaningful tasks to show.\n *\n * - ui_notify: Internal notification dispatch\n * - ui_prompt: User input prompts (shown via dedicated UI, not task panel)\n * - __submit__: Internal message submission\n * - guild_credentials_request: Credential configuration prompts (shown via dedicated UI)\n */\nexport const FILTERED_TASK_NAMES = new Set([\n 'ui_notify',\n 'ui_prompt',\n '__submit__',\n 'guild_credentials_request',\n]);\n\n/** Check if a task/tool name should be filtered from display */\nexport function isFilteredTaskName(name: string): boolean {\n return FILTERED_TASK_NAMES.has(name);\n}\n\n// =============================================================================\n// Task Utility Functions\n// =============================================================================\n\n/** Check if task is an agent task (has agent property) */\nexport function isAgentTask(task: SessionTask): task is SessionTaskAgent {\n return 'agent' in task;\n}\n\n/** Check if task is a tool task (has tool_name property) */\nexport function isToolTask(task: SessionTask): task is SessionTaskTool {\n return 'tool_name' in task;\n}\n\n/** Extract display name from an agent reference */\nexport function getAgentName(agent: AgentRef | null | undefined): string {\n return agent?.full_name || 'assistant';\n}\n\n/**\n * Check if a task's agent matches a target agent identifier.\n *\n * Target format: \"@scope/owner~name\" (e.g. \"@guildai/guildai~agent-builder\") or simple name (\"assistant\")\n * AgentRef format: { name: \"agent-builder\", full_name: \"guildai~agent-builder\", ... }\n */\nexport function matchesAgent(\n taskAgent: AgentRef | null | undefined,\n targetAgent: string\n): boolean {\n if (!taskAgent) return false;\n // Direct name match for simple identifiers like \"assistant\"\n if (taskAgent.name === targetAgent) return true;\n // Normalize target to match full_name format:\n // 1. Strip npm scope prefix: \"@scope/owner~name\" -> \"owner~name\"\n // 2. Convert slash separator to tilde: \"owner/name\" -> \"owner~name\"\n if (taskAgent.full_name) {\n const normalized = targetAgent.replace(/^@[^/]+\\//, '').replace('/', '~');\n if (taskAgent.full_name === normalized) return true;\n }\n return false;\n}\n\n/** Get display name for a task - agent name or tool name */\nexport function getTaskDisplayName(task: SessionTask): string {\n if (isAgentTask(task)) {\n return getAgentName(task.agent);\n }\n if (isToolTask(task)) {\n return task.tool_name;\n }\n return 'Unknown';\n}\n\n/** Resolve the display name for an event's originating agent. */\nexport function getEventAgentName(\n event: { task?: SessionTaskItem | SessionTask },\n fallbackName = 'assistant'\n): string {\n const task = event.task;\n if (!task) return fallbackName;\n if ('agent' in task && task.agent) {\n return getAgentName(task.agent);\n }\n if ('parent_task' in task && task.parent_task) {\n const parent = task.parent_task;\n if ('agent' in parent && parent.agent) {\n return getAgentName(parent.agent);\n }\n }\n return fallbackName;\n}\n\n/** Get task type label */\nexport function getTaskTypeLabel(task: SessionTask): string {\n if (isAgentTask(task)) {\n return 'Agent';\n }\n if (isToolTask(task)) {\n return 'Tool';\n }\n return 'Task';\n}\n\n// =============================================================================\n// Event Types\n// =============================================================================\n\nexport interface BaseEvent {\n id: string;\n created_at: string;\n updated_at: string;\n task?: SessionTaskItem; // Task context for this event\n}\n\nexport interface UserMessageEvent extends BaseEvent {\n type: 'user_message';\n author_id: string;\n content: string;\n}\n\n// Runtime system events (from new messaging system)\nexport interface RuntimeStartEvent extends BaseEvent {\n type: 'runtime_start';\n content: Record<string, unknown>;\n}\n\nexport interface RuntimeRunningEvent extends BaseEvent {\n type: 'runtime_running';\n}\n\nexport interface RuntimeWaitingEvent extends BaseEvent {\n type: 'runtime_waiting';\n}\n\nexport interface RuntimeErrorEvent extends BaseEvent {\n type: 'runtime_error';\n content: string;\n stack: string | null;\n}\n\nexport interface RuntimeDoneEvent extends BaseEvent {\n type: 'runtime_done';\n content: Record<string, unknown>;\n}\n\n// Agent notification events (from new messaging system)\nexport interface TextContent {\n type: 'text';\n data: string;\n}\n\nexport interface UnknownContent {\n type: string;\n data?: unknown;\n}\n\nexport interface MultipartContent {\n type: 'multipart/mixed';\n parts: UnknownContent[];\n}\n\nexport interface ResponseStreamContent {\n type: 'application/guild-response-stream';\n stream_id: string;\n sequence: number;\n status: 'streaming' | 'done' | 'continued' | 'aborted';\n text: string;\n is_delta?: boolean;\n}\n\nexport type AgentNotificationMessageContent =\n | TextContent\n | MultipartContent\n | ResponseStreamContent;\n\nexport interface AgentNotificationMessageEvent extends BaseEvent {\n type: 'agent_notification_message';\n content: AgentNotificationMessageContent;\n}\n\nexport interface AgentNotificationProgressEvent extends BaseEvent {\n type: 'agent_notification_progress';\n content: TextContent;\n}\n\nexport interface AgentNotificationErrorEvent extends BaseEvent {\n type: 'agent_notification_error';\n content: TextContent;\n}\n\n// Agent console events (debug/logging)\nexport interface AgentConsoleEvent extends BaseEvent {\n type: 'agent_console';\n level: 'debug' | 'info' | 'warn' | 'error';\n content: string;\n}\n\n// Trigger message events (from system triggers like webhooks)\nexport interface TriggerMessageEvent extends BaseEvent {\n type: 'trigger_message';\n content: { type: 'text'; data: string };\n}\n\n// System error events (infrastructure/runtime system errors)\nexport interface SystemErrorEvent extends BaseEvent {\n type: 'system_error';\n content: TextContent;\n details?: Record<string, unknown>;\n}\n\n// LLM start event (LLM API request initiated)\nexport interface LlmStartEvent extends BaseEvent {\n type: 'llm_start';\n provider: string;\n payload: Record<string, unknown>;\n}\n\n// LLM done event (LLM API response received)\nexport interface LlmDoneEvent extends BaseEvent {\n type: 'llm_done';\n status_code: number;\n body: string;\n}\n\n// =============================================================================\n// Interactive Request Events\n// =============================================================================\n\n/** Agent info as returned in install request */\nexport interface RequestedAgent {\n id: string;\n name: string;\n description: string;\n}\n\n/** Agent install request - when an agent wants to install another agent */\nexport interface AgentInstallRequestEvent extends BaseEvent {\n type: 'agent_install_request';\n requested_agent: RequestedAgent;\n agent: AgentRef | null; // The agent that made the request\n is_fulfilled: boolean;\n installed_agent: { id: string } | null;\n}\n\n/** Credentials request - when an agent needs third-party service access */\nexport interface CredentialsRequestEvent extends BaseEvent {\n type: 'credentials_request';\n service: 'GITHUB' | 'SLACK' | 'LINEAR';\n agent: AgentRef | null; // The agent that made the request\n is_fulfilled: boolean;\n}\n\n/** Check if event is an unfulfilled agent install request */\nexport function isUnfulfilledAgentInstallRequest(\n event: SessionEvent\n): event is AgentInstallRequestEvent {\n return event.type === 'agent_install_request' && !event.is_fulfilled;\n}\n\n/** Check if event is an unfulfilled credentials request */\nexport function isUnfulfilledCredentialsRequest(\n event: SessionEvent\n): event is CredentialsRequestEvent {\n return event.type === 'credentials_request' && !event.is_fulfilled;\n}\n\n/** Check if an agent notification message is a transient response stream draft. */\nexport function isResponseStreamEvent(\n event: SessionEvent\n): event is AgentNotificationMessageEvent & {\n content: ResponseStreamContent;\n} {\n return (\n event.type === 'agent_notification_message' &&\n event.content.type === 'application/guild-response-stream'\n );\n}\n\n/** Check if a response stream event carries the final generated text. */\nexport function isDoneResponseStreamEvent(\n event: SessionEvent\n): event is AgentNotificationMessageEvent & {\n content: ResponseStreamContent & { status: 'done' };\n} {\n return isResponseStreamEvent(event) && event.content.status === 'done';\n}\n\n/** Apply a response-stream payload to the accumulated display text. */\nexport function applyResponseStreamText(\n currentText: string,\n content: ResponseStreamContent\n): string {\n return content.is_delta ? currentText + content.text : content.text;\n}\n\n/** Extract display text from notification content. */\nexport function getAgentNotificationText(event: AgentNotificationMessageEvent): string {\n if (event.content.type === 'text') {\n return event.content.data;\n }\n if (event.content.type === 'application/guild-response-stream') {\n return event.content.text;\n }\n if (event.content.type === 'multipart/mixed' && event.content.parts.length === 1) {\n const part = event.content.parts[0];\n return part.type === 'text' && typeof part.data === 'string' ? part.data : '';\n }\n return '';\n}\n\n/** Check if an event belongs to the root task or has no task context. */\nexport function isRootTaskEvent(event: SessionEvent): boolean {\n const task = event.task;\n if (!task) return true;\n if ('parent_task_id' in task) return task.parent_task_id === null;\n return task.parent_task === null;\n}\n\nexport interface InterruptedEvent extends BaseEvent {\n type: 'interrupted';\n interrupted_at: string;\n interrupted_by_id: string;\n}\n\n// Union type for all session events\nexport type SessionEvent =\n | UserMessageEvent\n | RuntimeStartEvent\n | RuntimeRunningEvent\n | RuntimeWaitingEvent\n | RuntimeErrorEvent\n | RuntimeDoneEvent\n | AgentNotificationMessageEvent\n | AgentNotificationProgressEvent\n | AgentNotificationErrorEvent\n | AgentConsoleEvent\n | TriggerMessageEvent\n | SystemErrorEvent\n | LlmStartEvent\n | LlmDoneEvent\n | AgentInstallRequestEvent\n | CredentialsRequestEvent\n | InterruptedEvent;\n\n// Session interface\nexport interface Session {\n id: string;\n workspace_id?: string;\n created_at?: string;\n session_url?: string;\n}\n", "// Copyright 2026 Guild.ai\n// SPDX-License-Identifier: Apache-2.0\n\nimport WebSocket from 'ws';\nimport { getAuthToken } from './auth.js';\nimport { getIapHeaders } from './iap.js';\nimport { getGuildcoreWsUrl } from './config.js';\nimport { debug, GuildCLIError, ErrorCodes } from './errors.js';\n\nconst BASE_RECONNECT_DELAY = 3000;\nconst MAX_RECONNECT_DELAY = 30000;\nconst CONNECT_TIMEOUT = 15000;\nconst MAX_RECONNECT_ATTEMPTS = 10;\n\n// Server close codes that indicate auth failure \u2014 don't auto-reconnect.\nconst AUTH_CLOSE_CODES = new Set([4001, 4003, 4004]);\n\ntype WsState = 'connecting' | 'connected' | 'disconnected' | 'reconnecting';\n\nexport interface WebSocketClientOptions<R> {\n /** WebSocket endpoint path (e.g., \"/sessions/{id}/events/ws\") */\n path: string;\n /** Query parameters to append to the URL */\n queryParams?: Record<string, string>;\n /** Called for each received JSON message */\n onMessage: (message: R) => void;\n /** Called when the connection fails permanently (auth error, max retries) */\n onError?: (error: Error) => void;\n /** Returns the last seen ID for reconnection resume via from_id */\n getFromId?: () => string | undefined;\n /** Debug label for logging */\n label: string;\n}\n\n/**\n * Node.js WebSocket client for Guild backend endpoints.\n *\n * Handles auth headers (Bearer + IAP), auto-reconnect with exponential\n * backoff + jitter, connection timeout, and from_id resume on reconnect.\n */\nexport class GuildWebSocketClient<R> {\n private ws: WebSocket | null = null;\n private state: WsState = 'disconnected';\n private readonly options: WebSocketClientOptions<R>;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private connectTimeout: ReturnType<typeof setTimeout> | null = null;\n private reconnectAttempts = 0;\n\n private constructor(options: WebSocketClientOptions<R>) {\n this.options = options;\n }\n\n /**\n * Create and connect a WebSocket client.\n * Rejects if initial connection or auth fails.\n */\n static async create<R>(\n options: WebSocketClientOptions<R>\n ): Promise<GuildWebSocketClient<R>> {\n const client = new GuildWebSocketClient<R>(options);\n await client.connect();\n return client;\n }\n\n private buildUrl(): string {\n const baseUrl = getGuildcoreWsUrl();\n const params = new URLSearchParams();\n\n if (this.options.queryParams) {\n for (const [key, value] of Object.entries(this.options.queryParams)) {\n params.set(key, value);\n }\n }\n\n const resumeId = this.options.getFromId?.();\n if (resumeId) {\n params.set('from_id', resumeId);\n }\n\n const queryString = params.toString();\n const separator = queryString ? '?' : '';\n return `${baseUrl}${this.options.path}${separator}${queryString}`;\n }\n\n private async getHeaders(): Promise<Record<string, string>> {\n const headers: Record<string, string> = {};\n\n const token = await getAuthToken();\n if (!token) {\n throw new GuildCLIError(\n ErrorCodes.AUTH_REQUIRED,\n 'Authentication required. Please run: guild auth login'\n );\n }\n headers['Authorization'] = `Bearer ${token}`;\n\n const baseUrl = getGuildcoreWsUrl();\n const httpUrl = baseUrl.replace(/^ws/, 'http');\n const iapHeaders = await getIapHeaders(httpUrl);\n Object.assign(headers, iapHeaders);\n\n return headers;\n }\n\n private cleanupSocket(): void {\n if (this.ws) {\n this.ws.removeAllListeners();\n try {\n this.ws.close();\n } catch {\n // Already closed\n }\n this.ws = null;\n }\n if (this.connectTimeout) {\n clearTimeout(this.connectTimeout);\n this.connectTimeout = null;\n }\n }\n\n private async connect(): Promise<void> {\n this.cleanupSocket();\n this.state = 'connecting';\n\n let headers: Record<string, string>;\n try {\n headers = await this.getHeaders();\n } catch (err) {\n this.state = 'disconnected';\n throw err;\n }\n\n const url = this.buildUrl();\n debug(`[WS ${this.options.label}] Connecting to ${url}`);\n\n return new Promise<void>((resolve, reject) => {\n const ws = new WebSocket(url, { headers });\n\n // Connection timeout\n this.connectTimeout = setTimeout(() => {\n this.connectTimeout = null;\n if (this.state === 'connecting') {\n debug(\n `[WS ${this.options.label}] Connection timeout after ${CONNECT_TIMEOUT}ms`\n );\n ws.removeAllListeners();\n ws.close();\n const err = new Error('WebSocket connection timeout');\n if (this.reconnectAttempts === 0) {\n this.state = 'disconnected';\n reject(err);\n } else {\n this.scheduleReconnect();\n }\n }\n }, CONNECT_TIMEOUT);\n\n ws.on('open', () => {\n if (this.connectTimeout) {\n clearTimeout(this.connectTimeout);\n this.connectTimeout = null;\n }\n debug(`[WS ${this.options.label}] Connected`);\n this.state = 'connected';\n this.reconnectAttempts = 0;\n resolve();\n });\n\n ws.on('message', (data: WebSocket.Data) => {\n try {\n const message = JSON.parse(data.toString()) as R;\n this.options.onMessage(message);\n } catch (err) {\n debug(`[WS ${this.options.label}] Failed to parse message: ${err}`);\n }\n });\n\n ws.on('error', (err: Error) => {\n debug(`[WS ${this.options.label}] Error: ${err.message}`);\n // 'close' event will follow, handle reconnect there\n });\n\n ws.on('close', (code: number) => {\n debug(`[WS ${this.options.label}] Closed with code ${code}`);\n\n if (this.state === 'disconnected') return;\n\n if (code === 1000) {\n // Normal closure, don't reconnect\n this.state = 'disconnected';\n return;\n }\n\n if (AUTH_CLOSE_CODES.has(code)) {\n // Auth failure \u2014 don't reconnect, surface error\n this.state = 'disconnected';\n const authErr = new Error(`WebSocket auth failure (close code ${code})`);\n this.options.onError?.(authErr);\n return;\n }\n\n this.scheduleReconnect();\n });\n\n this.ws = ws;\n });\n }\n\n private scheduleReconnect(): void {\n if (this.state === 'disconnected') return;\n\n this.reconnectAttempts++;\n if (this.reconnectAttempts > MAX_RECONNECT_ATTEMPTS) {\n debug(\n `[WS ${this.options.label}] Max reconnect attempts (${MAX_RECONNECT_ATTEMPTS}) reached`\n );\n this.state = 'disconnected';\n this.options.onError?.(\n new Error(`WebSocket failed after ${MAX_RECONNECT_ATTEMPTS} reconnect attempts`)\n );\n return;\n }\n\n this.state = 'reconnecting';\n\n // Exponential backoff with jitter\n const backoff = Math.min(\n BASE_RECONNECT_DELAY * Math.pow(2, this.reconnectAttempts - 1),\n MAX_RECONNECT_DELAY\n );\n const jitter = Math.random() * 2000;\n const delay = backoff + jitter;\n\n debug(\n `[WS ${this.options.label}] Reconnecting in ${Math.round(delay)}ms (attempt ${this.reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})`\n );\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n if (this.state === 'disconnected') return;\n\n this.connect().catch((err) => {\n debug(`[WS ${this.options.label}] Reconnect failed: ${err}`);\n if (err instanceof GuildCLIError && err.code === ErrorCodes.AUTH_REQUIRED) {\n // Auth failure is fatal \u2014 don't retry\n this.state = 'disconnected';\n this.options.onError?.(err);\n } else {\n this.scheduleReconnect();\n }\n });\n }, delay);\n }\n\n /** Close the connection cleanly. No reconnection will be attempted. */\n close(): void {\n this.state = 'disconnected';\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.cleanupSocket();\n debug(`[WS ${this.options.label}] Closed by client`);\n }\n\n /** Current connection state */\n getState(): WsState {\n return this.state;\n }\n}\n", "// Copyright 2026 Guild.ai\n// SPDX-License-Identifier: Apache-2.0\n\nimport { GuildAPIClient } from './api-client.js';\nimport { SessionEvent } from './session-events.js';\nimport { debug, isDebugMode } from './errors.js';\nimport { shouldShowEvent } from './event-filter.js';\nimport { fetchEvents } from './session-events-fetch.js';\nimport {\n applyResponseStreamText,\n getAgentNotificationText,\n isDoneResponseStreamEvent,\n isResponseStreamEvent,\n isRootTaskEvent,\n} from './session-events.js';\nimport { GuildWebSocketClient } from './websocket-client.js';\n\nexport interface PollResult {\n response: string | null;\n /** Last event ID seen \u2014 pass as `afterEventId` on next call. */\n lastEventId: string | undefined;\n}\n\nexport interface PollOnceResult {\n events: SessionEvent[];\n lastEventId: string | undefined;\n reason: 'completion' | 'error' | 'ui_prompt' | 'inactivity_timeout';\n}\n\n/**\n * Poll for agent response using WebSocket streaming with HTTP fallback.\n *\n * Does one initial HTTP GET (using from_id cursor) to check if the response\n * is already available, then opens a WebSocket for real-time events.\n * Falls back to HTTP polling if the WebSocket connection fails.\n *\n * Handles both multi-turn agents (which emit agent_notification_message)\n * and one-shot agents (which may only emit runtime_done with output content).\n *\n * Priority:\n * 1. root agent_notification_message \u2014 preferred, immediate return\n * 2. root runtime_error \u2014 fail fast\n * 3. root runtime_done content \u2014 fallback for one-shot agents\n * 4. root done response-stream after root runtime_done \u2014 streaming fallback\n */\nexport async function pollForResponse(\n client: GuildAPIClient,\n sessionId: string,\n afterEventId: string | undefined,\n maxWaitTime = 60000\n): Promise<PollResult> {\n // Initial HTTP GET to check for already-available response\n const existingEvents = await fetchEvents(client, sessionId, {\n fromId: afterEventId,\n });\n\n // Check existing events for completion (may already be done)\n let lastAgentRuntimeDone: string | null = null;\n let latestEventId = afterEventId;\n let rootRuntimeDone = false;\n let responseStreamDone: PollResult | null = null;\n const responseStreamTexts = new Map<string, string>();\n\n for (const event of existingEvents) {\n latestEventId = event.id;\n\n if (event.type === 'agent_notification_message') {\n if (isResponseStreamEvent(event)) {\n const streamText = applyResponseStreamText(\n responseStreamTexts.get(event.content.stream_id) ?? '',\n event.content\n );\n responseStreamTexts.set(event.content.stream_id, streamText);\n if (isRootTaskEvent(event) && isDoneResponseStreamEvent(event)) {\n responseStreamDone = {\n response: streamText,\n lastEventId: event.id,\n };\n }\n continue;\n }\n if (!isRootTaskEvent(event)) continue;\n return {\n response: getAgentNotificationText(event),\n lastEventId: event.id,\n };\n }\n\n if (\n event.type === 'runtime_done' &&\n event.task &&\n 'agent' in event.task &&\n isRootTaskEvent(event)\n ) {\n rootRuntimeDone = true;\n if (event.content !== undefined) {\n lastAgentRuntimeDone = JSON.stringify(event.content);\n }\n }\n\n if (\n event.type === 'runtime_error' &&\n event.task &&\n 'agent' in event.task &&\n isRootTaskEvent(event)\n ) {\n return {\n response: JSON.stringify({ error: event.content }),\n lastEventId: event.id,\n };\n }\n\n if (event.type === 'agent_console' && isDebugMode()) {\n process.stderr.write(`[console.${event.level}] ${event.content}\\n`);\n }\n }\n\n if (lastAgentRuntimeDone !== null) {\n return { response: lastAgentRuntimeDone, lastEventId: latestEventId };\n }\n\n if (rootRuntimeDone && responseStreamDone !== null) {\n return { response: responseStreamDone.response, lastEventId: latestEventId };\n }\n\n // Not done yet \u2014 try WebSocket streaming, fall back to HTTP polling\n try {\n return await pollViaWebSocket(\n sessionId,\n latestEventId,\n maxWaitTime,\n responseStreamTexts\n );\n } catch (err) {\n debug(`pollForResponse: WebSocket failed (${err}), falling back to HTTP polling`);\n return await pollViaHttp(\n client,\n sessionId,\n latestEventId,\n maxWaitTime,\n responseStreamTexts\n );\n }\n}\n\n/**\n * Stream events via WebSocket until a completion event arrives.\n */\nfunction pollViaWebSocket(\n sessionId: string,\n fromId: string | undefined,\n maxWaitTime: number,\n inheritedStreamTexts?: Map<string, string>\n): Promise<PollResult> {\n return new Promise<PollResult>((resolve, reject) => {\n let settled = false;\n let pendingRuntimeDone: string | null = null;\n let latestEventId = fromId;\n let runtimeDoneTimer: ReturnType<typeof setTimeout> | null = null;\n let wsClient: GuildWebSocketClient<SessionEvent> | null = null;\n const seenIds = new Set<string>();\n let responseStreamDone: PollResult | null = null;\n const responseStreamTexts = new Map<string, string>(inheritedStreamTexts);\n\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n debug('pollViaWebSocket: timeout reached');\n if (runtimeDoneTimer) clearTimeout(runtimeDoneTimer);\n wsClient?.close();\n const fallback = responseStreamDone\n ? { response: responseStreamDone.response, lastEventId: latestEventId }\n : { response: pendingRuntimeDone, lastEventId: latestEventId };\n resolve(fallback);\n }\n }, maxWaitTime);\n\n const cleanup = (result: PollResult): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n if (runtimeDoneTimer) clearTimeout(runtimeDoneTimer);\n wsClient?.close();\n resolve(result);\n };\n\n GuildWebSocketClient.create<SessionEvent>({\n path: `/sessions/${sessionId}/events/ws`,\n label: `poll-${sessionId.substring(0, 8)}`,\n getFromId: () => latestEventId,\n onMessage: (event) => {\n // Deduplicate events (safety net for reconnection overlap)\n if (seenIds.has(event.id)) {\n debug(`pollViaWebSocket: skipping duplicate event ${event.id}`);\n return;\n }\n seenIds.add(event.id);\n latestEventId = event.id;\n\n if (event.type === 'agent_notification_message') {\n if (isResponseStreamEvent(event)) {\n const streamText = applyResponseStreamText(\n responseStreamTexts.get(event.content.stream_id) ?? '',\n event.content\n );\n responseStreamTexts.set(event.content.stream_id, streamText);\n if (isRootTaskEvent(event) && isDoneResponseStreamEvent(event)) {\n responseStreamDone = {\n response: streamText,\n lastEventId: event.id,\n };\n // If we already saw runtime_done, resolve with the stream text\n if (pendingRuntimeDone !== null) {\n cleanup({\n response: streamText,\n lastEventId: event.id,\n });\n }\n }\n return;\n }\n if (!isRootTaskEvent(event)) return;\n cleanup({\n response: getAgentNotificationText(event),\n lastEventId: event.id,\n });\n return;\n }\n\n if (\n event.type === 'runtime_done' &&\n event.task &&\n 'agent' in event.task &&\n isRootTaskEvent(event)\n ) {\n if (event.content !== undefined) {\n pendingRuntimeDone = JSON.stringify(event.content);\n }\n // If we already have a completed response stream, use that\n if (responseStreamDone !== null) {\n cleanup({\n response: responseStreamDone.response,\n lastEventId: latestEventId,\n });\n return;\n }\n // Wait briefly for a possible agent_notification_message to follow.\n if (runtimeDoneTimer) clearTimeout(runtimeDoneTimer);\n runtimeDoneTimer = setTimeout(() => {\n runtimeDoneTimer = null;\n if (!settled && pendingRuntimeDone !== null) {\n cleanup({\n response: pendingRuntimeDone,\n lastEventId: latestEventId,\n });\n }\n }, 500);\n }\n\n if (\n event.type === 'runtime_error' &&\n event.task &&\n 'agent' in event.task &&\n isRootTaskEvent(event)\n ) {\n cleanup({\n response: JSON.stringify({ error: event.content }),\n lastEventId: event.id,\n });\n return;\n }\n\n if (event.type === 'agent_console' && isDebugMode()) {\n process.stderr.write(`[console.${event.level}] ${event.content}\\n`);\n }\n },\n onError: (err) => {\n debug(`pollViaWebSocket: fatal error: ${err.message}`);\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n if (runtimeDoneTimer) clearTimeout(runtimeDoneTimer);\n reject(err);\n }\n },\n })\n .then((ws) => {\n wsClient = ws;\n if (settled) {\n ws.close();\n }\n })\n .catch((err) => {\n debug(`pollViaWebSocket: connection failed: ${err}`);\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n if (runtimeDoneTimer) clearTimeout(runtimeDoneTimer);\n reject(err);\n }\n });\n });\n}\n\n/**\n * HTTP polling fallback \u2014 same logic as the main branch pollForResponse.\n */\nasync function pollViaHttp(\n client: GuildAPIClient,\n sessionId: string,\n fromId: string | undefined,\n maxWaitTime: number,\n inheritedStreamTexts?: Map<string, string>\n): Promise<PollResult> {\n const startTime = Date.now();\n let currentFromId = fromId;\n let responseStreamDone: PollResult | null = null;\n const responseStreamTexts = new Map<string, string>(inheritedStreamTexts);\n\n while (Date.now() - startTime < maxWaitTime) {\n const events = await fetchEvents(client, sessionId, {\n fromId: currentFromId,\n });\n\n let lastAgentRuntimeDone: string | null = null;\n let rootRuntimeDone = false;\n\n for (const event of events) {\n debug(`pollViaHttp event: ${event.type}`);\n\n if (event.type === 'agent_notification_message') {\n if (isResponseStreamEvent(event)) {\n const streamText = applyResponseStreamText(\n responseStreamTexts.get(event.content.stream_id) ?? '',\n event.content\n );\n responseStreamTexts.set(event.content.stream_id, streamText);\n if (isRootTaskEvent(event) && isDoneResponseStreamEvent(event)) {\n responseStreamDone = {\n response: streamText,\n lastEventId: event.id,\n };\n }\n continue;\n }\n if (!isRootTaskEvent(event)) continue;\n return {\n response: getAgentNotificationText(event),\n lastEventId: event.id,\n };\n }\n\n if (\n event.type === 'runtime_done' &&\n event.task &&\n 'agent' in event.task &&\n isRootTaskEvent(event)\n ) {\n rootRuntimeDone = true;\n if (event.content !== undefined) {\n lastAgentRuntimeDone = JSON.stringify(event.content);\n }\n }\n\n if (\n event.type === 'runtime_error' &&\n event.task &&\n 'agent' in event.task &&\n isRootTaskEvent(event)\n ) {\n return {\n response: JSON.stringify({ error: event.content }),\n lastEventId: event.id,\n };\n }\n\n if (event.type === 'agent_console' && isDebugMode()) {\n process.stderr.write(`[console.${event.level}] ${event.content}\\n`);\n }\n }\n\n if (events.length > 0) {\n currentFromId = events[events.length - 1].id;\n }\n\n if (lastAgentRuntimeDone !== null) {\n return { response: lastAgentRuntimeDone, lastEventId: currentFromId };\n }\n\n if (rootRuntimeDone && responseStreamDone !== null) {\n return { response: responseStreamDone.response, lastEventId: currentFromId };\n }\n\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n\n return responseStreamDone\n ? { response: responseStreamDone.response, lastEventId: currentFromId }\n : { response: null, lastEventId: currentFromId };\n}\n\n/**\n * Poll for agent response while streaming matching events to stdout as JSONL.\n *\n * Same completion logic as pollForResponse(), but writes each event that\n * passes the filter to stdout so callers get intermediate output (console.log,\n * progress, etc.) in JSON/JSONL automation modes.\n *\n * Uses HTTP polling (not WebSocket) since it needs to emit each event\n * individually to stdout as JSONL.\n */\nexport async function pollForResponseWithEvents(\n client: GuildAPIClient,\n sessionId: string,\n eventFilter: Set<string>,\n afterEventId: string | undefined,\n maxWaitTime = 60000\n): Promise<PollResult> {\n const startTime = Date.now();\n let fromId = afterEventId;\n let responseStreamDone: PollResult | null = null;\n const responseStreamTexts = new Map<string, string>();\n\n while (Date.now() - startTime < maxWaitTime) {\n const events = await fetchEvents(client, sessionId, { fromId });\n\n let lastAgentRuntimeDone: string | null = null;\n let rootRuntimeDone = false;\n\n for (const event of events) {\n debug(`pollForResponseWithEvents event: ${event.type}`);\n\n // Stream matching events to stdout as JSONL. Response-stream events are\n // transient drafts, so keep automation output stable and wait for the\n // final agent message or terminal fallback.\n if (shouldShowEvent(event.type, eventFilter) && !isResponseStreamEvent(event)) {\n process.stdout.write(JSON.stringify(event) + '\\n');\n }\n\n if (event.type === 'agent_notification_message') {\n if (isResponseStreamEvent(event)) {\n const streamText = applyResponseStreamText(\n responseStreamTexts.get(event.content.stream_id) ?? '',\n event.content\n );\n responseStreamTexts.set(event.content.stream_id, streamText);\n if (isRootTaskEvent(event) && isDoneResponseStreamEvent(event)) {\n responseStreamDone = {\n response: streamText,\n lastEventId: event.id,\n };\n }\n continue;\n }\n if (!isRootTaskEvent(event)) continue;\n return {\n response: getAgentNotificationText(event),\n lastEventId: event.id,\n };\n }\n\n if (\n event.type === 'runtime_done' &&\n event.task &&\n 'agent' in event.task &&\n isRootTaskEvent(event)\n ) {\n rootRuntimeDone = true;\n if (event.content !== undefined) {\n lastAgentRuntimeDone = JSON.stringify(event.content);\n }\n }\n\n if (\n event.type === 'runtime_error' &&\n event.task &&\n 'agent' in event.task &&\n isRootTaskEvent(event)\n ) {\n return {\n response: JSON.stringify({ error: event.content }),\n lastEventId: event.id,\n };\n }\n\n if (event.type === 'agent_console' && isDebugMode()) {\n process.stderr.write(`[console.${event.level}] ${event.content}\\n`);\n }\n }\n\n if (events.length > 0) {\n fromId = events[events.length - 1].id;\n }\n\n if (lastAgentRuntimeDone !== null) {\n return { response: lastAgentRuntimeDone, lastEventId: fromId };\n }\n\n if (rootRuntimeDone && responseStreamDone !== null) {\n return { response: responseStreamDone.response, lastEventId: fromId };\n }\n\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n\n return responseStreamDone\n ? { response: responseStreamDone.response, lastEventId: fromId }\n : { response: null, lastEventId: fromId };\n}\n\n// ---------------------------------------------------------------------------\n// pollForOnce \u2014 dedicated polling for --once mode\n// ---------------------------------------------------------------------------\n\n/**\n * Check accumulated events for a completion condition.\n *\n * Priority (matches existing --once behavior):\n * 1. runtime_error on root task \u2192 'error'\n * 2. agent_notification_message (root, non-stream, tool_name === 'ui_prompt') \u2192 'ui_prompt'\n * 3. runtime_done on root task OR agent_notification_message (root, non-stream) \u2192 'completion'\n */\nfunction checkOnceCompletion(events: SessionEvent[]): PollOnceResult['reason'] | null {\n const hasRootError = events.some(\n (e) => e.type === 'runtime_error' && isRootTaskEvent(e)\n );\n if (hasRootError) return 'error';\n\n const hasUIPrompt = events.some(\n (e: SessionEvent & { task?: { tool_name?: string } }) =>\n e.type === 'agent_notification_message' &&\n !isResponseStreamEvent(e) &&\n e.task?.tool_name === 'ui_prompt'\n );\n if (hasUIPrompt) return 'ui_prompt';\n\n const hasRootDone = events.some(\n (e) => e.type === 'runtime_done' && isRootTaskEvent(e)\n );\n const hasAgentMessage = events.some(\n (e) =>\n e.type === 'agent_notification_message' &&\n isRootTaskEvent(e) &&\n !isResponseStreamEvent(e)\n );\n if (hasRootDone || hasAgentMessage) return 'completion';\n\n return null;\n}\n\n/**\n * Poll for --once mode using WebSocket streaming with HTTP fallback.\n *\n * Accumulates all events (unlike pollForResponse which returns a single response)\n * and checks for completion conditions after each batch.\n */\nexport async function pollForOnce(\n client: GuildAPIClient,\n sessionId: string,\n options?: {\n inactivityTimeoutMs?: number;\n pollIntervalMs?: number;\n }\n): Promise<PollOnceResult> {\n const inactivityTimeoutMs = options?.inactivityTimeoutMs ?? 300000;\n const pollIntervalMs = options?.pollIntervalMs ?? 2000;\n\n // Initial HTTP fetch to get already-available events\n const initialEvents = await fetchEvents(client, sessionId, {});\n const allEvents: SessionEvent[] = [...initialEvents];\n let latestEventId =\n initialEvents.length > 0 ? initialEvents[initialEvents.length - 1].id : undefined;\n\n for (const evt of initialEvents) {\n logOnceEvent(evt);\n }\n\n // Check for immediate completion\n const immediateReason = checkOnceCompletion(allEvents);\n if (immediateReason) {\n debug('pollForOnce: immediate completion via initial fetch');\n return { events: allEvents, lastEventId: latestEventId, reason: immediateReason };\n }\n\n // Try WebSocket, fall back to HTTP\n try {\n return await pollOnceViaWebSocket(\n sessionId,\n allEvents,\n latestEventId,\n inactivityTimeoutMs\n );\n } catch (err) {\n debug(`pollForOnce: WebSocket failed (${err}), falling back to HTTP`);\n return await pollOnceViaHttp(\n client,\n sessionId,\n allEvents,\n latestEventId,\n inactivityTimeoutMs,\n pollIntervalMs\n );\n }\n}\n\n/** Log an event in --once debug format. */\nfunction logOnceEvent(evt: SessionEvent): void {\n const taskInfo = evt.task as\n | { id?: string; agent?: string; status?: string; tool_name?: string }\n | undefined;\n if (taskInfo) {\n debug(\n `Event: ${evt.type}, task=${taskInfo.agent || taskInfo.tool_name || 'unknown'}:${(taskInfo.id || '').substring(0, 8)}, status=${taskInfo.status}`\n );\n } else {\n debug(`Event: ${evt.type} (no task info)`);\n }\n}\n\n/**\n * WebSocket path for --once polling.\n */\nfunction pollOnceViaWebSocket(\n sessionId: string,\n initialEvents: SessionEvent[],\n fromId: string | undefined,\n inactivityTimeoutMs: number\n): Promise<PollOnceResult> {\n return new Promise<PollOnceResult>((resolve, reject) => {\n let settled = false;\n let latestEventId = fromId;\n let wsClient: GuildWebSocketClient<SessionEvent> | null = null;\n const allEvents = [...initialEvents];\n const seenIds = new Set<string>(initialEvents.map((e) => e.id));\n let runtimeDoneTimer: ReturnType<typeof setTimeout> | null = null;\n let inactivityTimer: ReturnType<typeof setTimeout> | null = null;\n\n const resetInactivityTimer = (): void => {\n if (inactivityTimer) clearTimeout(inactivityTimer);\n inactivityTimer = setTimeout(() => {\n if (!settled) {\n debug('pollOnceViaWebSocket: inactivity timeout');\n cleanup({\n events: allEvents,\n lastEventId: latestEventId,\n reason: 'inactivity_timeout',\n });\n }\n }, inactivityTimeoutMs);\n };\n\n const cleanup = (result: PollOnceResult): void => {\n if (settled) return;\n settled = true;\n if (runtimeDoneTimer) clearTimeout(runtimeDoneTimer);\n if (inactivityTimer) clearTimeout(inactivityTimer);\n wsClient?.close();\n resolve(result);\n };\n\n // Start inactivity timer\n resetInactivityTimer();\n\n GuildWebSocketClient.create<SessionEvent>({\n path: `/sessions/${sessionId}/events/ws`,\n label: `poll-${sessionId.substring(0, 8)}`,\n getFromId: () => latestEventId,\n onMessage: (event) => {\n if (seenIds.has(event.id)) return;\n seenIds.add(event.id);\n latestEventId = event.id;\n allEvents.push(event);\n logOnceEvent(event);\n\n // Reset inactivity timer on every new event\n resetInactivityTimer();\n\n const reason = checkOnceCompletion(allEvents);\n if (reason) {\n // Grace period after runtime_done: wait for trailing agent_notification_message\n if (reason === 'completion' && !runtimeDoneTimer) {\n runtimeDoneTimer = setTimeout(() => {\n runtimeDoneTimer = null;\n const finalReason = checkOnceCompletion(allEvents) ?? 'completion';\n cleanup({\n events: allEvents,\n lastEventId: latestEventId,\n reason: finalReason,\n });\n }, 500);\n return;\n }\n if (reason !== 'completion') {\n cleanup({ events: allEvents, lastEventId: latestEventId, reason });\n }\n }\n },\n onError: (err) => {\n debug(`pollOnceViaWebSocket: fatal error: ${err.message}`);\n if (!settled) {\n settled = true;\n if (runtimeDoneTimer) clearTimeout(runtimeDoneTimer);\n if (inactivityTimer) clearTimeout(inactivityTimer);\n reject(err);\n }\n },\n })\n .then((ws) => {\n wsClient = ws;\n if (settled) ws.close();\n })\n .catch((err) => {\n debug(`pollOnceViaWebSocket: connection failed: ${err}`);\n if (!settled) {\n settled = true;\n if (runtimeDoneTimer) clearTimeout(runtimeDoneTimer);\n if (inactivityTimer) clearTimeout(inactivityTimer);\n reject(err);\n }\n });\n });\n}\n\n/**\n * HTTP fallback for --once polling.\n */\nasync function pollOnceViaHttp(\n client: GuildAPIClient,\n sessionId: string,\n initialEvents: SessionEvent[],\n fromId: string | undefined,\n inactivityTimeoutMs: number,\n pollIntervalMs: number\n): Promise<PollOnceResult> {\n const allEvents = [...initialEvents];\n let currentFromId = fromId;\n const maxInactivityAttempts = inactivityTimeoutMs / pollIntervalMs;\n let inactivityCounter = 0;\n\n while (true) {\n await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n\n const newEvents = await fetchEvents(client, sessionId, {\n fromId: currentFromId,\n });\n\n if (newEvents.length > 0) {\n for (const evt of newEvents) {\n logOnceEvent(evt);\n }\n allEvents.push(...newEvents);\n currentFromId = newEvents[newEvents.length - 1].id;\n inactivityCounter = 0;\n } else {\n inactivityCounter++;\n }\n\n const reason = checkOnceCompletion(allEvents);\n if (reason) {\n // Grace period: one more poll to catch trailing events\n await new Promise((resolve) => setTimeout(resolve, 500));\n const trailingEvents = await fetchEvents(client, sessionId, {\n fromId: currentFromId,\n });\n if (trailingEvents.length > 0) {\n for (const evt of trailingEvents) {\n logOnceEvent(evt);\n }\n allEvents.push(...trailingEvents);\n currentFromId = trailingEvents[trailingEvents.length - 1].id;\n }\n const finalReason = checkOnceCompletion(allEvents) ?? reason;\n return { events: allEvents, lastEventId: currentFromId, reason: finalReason };\n }\n\n if (inactivityCounter >= maxInactivityAttempts) {\n debug(`pollOnceViaHttp: inactivity timeout (${inactivityCounter} empty polls)`);\n return {\n events: allEvents,\n lastEventId: currentFromId,\n reason: 'inactivity_timeout',\n };\n }\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AA0BA,eAAsB,YACpB,QACA,WACA,UAAwB,CAAC,GACA;AACzB,QAAM,EAAE,QAAQ,QAAQ,IAAK,IAAI;AACjC,MAAI,MAAM,aAAa,SAAS,iBAAiB,KAAK;AACtD,MAAI,QAAQ;AACV,WAAO,YAAY,MAAM;AAAA,EAC3B;AACA,QAAM,WAAW,MAAM,OAAO,IAA+B,GAAG;AAChE,SAAO,UAAU,SAAS,CAAC;AAC7B;AAKA,eAAsB,WACpB,QACA,WACwB;AACxB,QAAM,WAAW,MAAM,OAAO;AAAA,IAC5B,aAAa,SAAS;AAAA,EACxB;AACA,SAAO,UAAU,SAAS,CAAC;AAC7B;;;ACuBO,IAAM,sBAAsB,oBAAI,IAAI;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,SAAS,mBAAmB,MAAuB;AACxD,SAAO,oBAAoB,IAAI,IAAI;AACrC;AAOO,SAAS,YAAY,MAA6C;AACvE,SAAO,WAAW;AACpB;AAGO,SAAS,WAAW,MAA4C;AACrE,SAAO,eAAe;AACxB;AAGO,SAAS,aAAa,OAA4C;AACvE,SAAO,OAAO,aAAa;AAC7B;AA0BO,SAAS,mBAAmB,MAA2B;AAC5D,MAAI,YAAY,IAAI,GAAG;AACrB,WAAO,aAAa,KAAK,KAAK;AAAA,EAChC;AACA,MAAI,WAAW,IAAI,GAAG;AACpB,WAAO,KAAK;AAAA,EACd;AACA,SAAO;AACT;AAGO,SAAS,kBACd,OACA,eAAe,aACP;AACR,QAAM,OAAO,MAAM;AACnB,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,WAAW,QAAQ,KAAK,OAAO;AACjC,WAAO,aAAa,KAAK,KAAK;AAAA,EAChC;AACA,MAAI,iBAAiB,QAAQ,KAAK,aAAa;AAC7C,UAAM,SAAS,KAAK;AACpB,QAAI,WAAW,UAAU,OAAO,OAAO;AACrC,aAAO,aAAa,OAAO,KAAK;AAAA,IAClC;AAAA,EACF;AACA,SAAO;AACT;AAmKO,SAAS,iCACd,OACmC;AACnC,SAAO,MAAM,SAAS,2BAA2B,CAAC,MAAM;AAC1D;AAUO,SAAS,sBACd,OAGA;AACA,SACE,MAAM,SAAS,gCACf,MAAM,QAAQ,SAAS;AAE3B;AAGO,SAAS,0BACd,OAGA;AACA,SAAO,sBAAsB,KAAK,KAAK,MAAM,QAAQ,WAAW;AAClE;AAGO,SAAS,wBACd,aACA,SACQ;AACR,SAAO,QAAQ,WAAW,cAAc,QAAQ,OAAO,QAAQ;AACjE;AAGO,SAAS,yBAAyB,OAA8C;AACrF,MAAI,MAAM,QAAQ,SAAS,QAAQ;AACjC,WAAO,MAAM,QAAQ;AAAA,EACvB;AACA,MAAI,MAAM,QAAQ,SAAS,qCAAqC;AAC9D,WAAO,MAAM,QAAQ;AAAA,EACvB;AACA,MAAI,MAAM,QAAQ,SAAS,qBAAqB,MAAM,QAAQ,MAAM,WAAW,GAAG;AAChF,UAAM,OAAO,MAAM,QAAQ,MAAM,CAAC;AAClC,WAAO,KAAK,SAAS,UAAU,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AAAA,EAC7E;AACA,SAAO;AACT;AAGO,SAAS,gBAAgB,OAA8B;AAC5D,QAAM,OAAO,MAAM;AACnB,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,oBAAoB,KAAM,QAAO,KAAK,mBAAmB;AAC7D,SAAO,KAAK,gBAAgB;AAC9B;;;ACrXA,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAC5B,IAAM,kBAAkB;AACxB,IAAM,yBAAyB;AAG/B,IAAM,mBAAmB,oBAAI,IAAI,CAAC,MAAM,MAAM,IAAI,CAAC;AAyB5C,IAAM,uBAAN,MAAM,sBAAwB;AAAA,EAC3B,KAAuB;AAAA,EACvB,QAAiB;AAAA,EACR;AAAA,EACT,iBAAuD;AAAA,EACvD,iBAAuD;AAAA,EACvD,oBAAoB;AAAA,EAEpB,YAAY,SAAoC;AACtD,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,OACX,SACkC;AAClC,UAAM,SAAS,IAAI,sBAAwB,OAAO;AAClD,UAAM,OAAO,QAAQ;AACrB,WAAO;AAAA,EACT;AAAA,EAEQ,WAAmB;AACzB,UAAM,UAAU,kBAAkB;AAClC,UAAM,SAAS,IAAI,gBAAgB;AAEnC,QAAI,KAAK,QAAQ,aAAa;AAC5B,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,QAAQ,WAAW,GAAG;AACnE,eAAO,IAAI,KAAK,KAAK;AAAA,MACvB;AAAA,IACF;AAEA,UAAM,WAAW,KAAK,QAAQ,YAAY;AAC1C,QAAI,UAAU;AACZ,aAAO,IAAI,WAAW,QAAQ;AAAA,IAChC;AAEA,UAAM,cAAc,OAAO,SAAS;AACpC,UAAM,YAAY,cAAc,MAAM;AACtC,WAAO,GAAG,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,SAAS,GAAG,WAAW;AAAA,EACjE;AAAA,EAEA,MAAc,aAA8C;AAC1D,UAAM,UAAkC,CAAC;AAEzC,UAAM,QAAQ,MAAM,aAAa;AACjC,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR,WAAW;AAAA,QACX;AAAA,MACF;AAAA,IACF;AACA,YAAQ,eAAe,IAAI,UAAU,KAAK;AAE1C,UAAM,UAAU,kBAAkB;AAClC,UAAM,UAAU,QAAQ,QAAQ,OAAO,MAAM;AAC7C,UAAM,aAAa,MAAM,cAAc,OAAO;AAC9C,WAAO,OAAO,SAAS,UAAU;AAEjC,WAAO;AAAA,EACT;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,KAAK,IAAI;AACX,WAAK,GAAG,mBAAmB;AAC3B,UAAI;AACF,aAAK,GAAG,MAAM;AAAA,MAChB,QAAQ;AAAA,MAER;AACA,WAAK,KAAK;AAAA,IACZ;AACA,QAAI,KAAK,gBAAgB;AACvB,mBAAa,KAAK,cAAc;AAChC,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,UAAyB;AACrC,SAAK,cAAc;AACnB,SAAK,QAAQ;AAEb,QAAI;AACJ,QAAI;AACF,gBAAU,MAAM,KAAK,WAAW;AAAA,IAClC,SAAS,KAAK;AACZ,WAAK,QAAQ;AACb,YAAM;AAAA,IACR;AAEA,UAAM,MAAM,KAAK,SAAS;AAC1B,UAAM,OAAO,KAAK,QAAQ,KAAK,mBAAmB,GAAG,EAAE;AAEvD,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,YAAM,KAAK,IAAI,gBAAU,KAAK,EAAE,QAAQ,CAAC;AAGzC,WAAK,iBAAiB,WAAW,MAAM;AACrC,aAAK,iBAAiB;AACtB,YAAI,KAAK,UAAU,cAAc;AAC/B;AAAA,YACE,OAAO,KAAK,QAAQ,KAAK,8BAA8B,eAAe;AAAA,UACxE;AACA,aAAG,mBAAmB;AACtB,aAAG,MAAM;AACT,gBAAM,MAAM,IAAI,MAAM,8BAA8B;AACpD,cAAI,KAAK,sBAAsB,GAAG;AAChC,iBAAK,QAAQ;AACb,mBAAO,GAAG;AAAA,UACZ,OAAO;AACL,iBAAK,kBAAkB;AAAA,UACzB;AAAA,QACF;AAAA,MACF,GAAG,eAAe;AAElB,SAAG,GAAG,QAAQ,MAAM;AAClB,YAAI,KAAK,gBAAgB;AACvB,uBAAa,KAAK,cAAc;AAChC,eAAK,iBAAiB;AAAA,QACxB;AACA,cAAM,OAAO,KAAK,QAAQ,KAAK,aAAa;AAC5C,aAAK,QAAQ;AACb,aAAK,oBAAoB;AACzB,gBAAQ;AAAA,MACV,CAAC;AAED,SAAG,GAAG,WAAW,CAAC,SAAyB;AACzC,YAAI;AACF,gBAAM,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC;AAC1C,eAAK,QAAQ,UAAU,OAAO;AAAA,QAChC,SAAS,KAAK;AACZ,gBAAM,OAAO,KAAK,QAAQ,KAAK,8BAA8B,GAAG,EAAE;AAAA,QACpE;AAAA,MACF,CAAC;AAED,SAAG,GAAG,SAAS,CAAC,QAAe;AAC7B,cAAM,OAAO,KAAK,QAAQ,KAAK,YAAY,IAAI,OAAO,EAAE;AAAA,MAE1D,CAAC;AAED,SAAG,GAAG,SAAS,CAAC,SAAiB;AAC/B,cAAM,OAAO,KAAK,QAAQ,KAAK,sBAAsB,IAAI,EAAE;AAE3D,YAAI,KAAK,UAAU,eAAgB;AAEnC,YAAI,SAAS,KAAM;AAEjB,eAAK,QAAQ;AACb;AAAA,QACF;AAEA,YAAI,iBAAiB,IAAI,IAAI,GAAG;AAE9B,eAAK,QAAQ;AACb,gBAAM,UAAU,IAAI,MAAM,sCAAsC,IAAI,GAAG;AACvE,eAAK,QAAQ,UAAU,OAAO;AAC9B;AAAA,QACF;AAEA,aAAK,kBAAkB;AAAA,MACzB,CAAC;AAED,WAAK,KAAK;AAAA,IACZ,CAAC;AAAA,EACH;AAAA,EAEQ,oBAA0B;AAChC,QAAI,KAAK,UAAU,eAAgB;AAEnC,SAAK;AACL,QAAI,KAAK,oBAAoB,wBAAwB;AACnD;AAAA,QACE,OAAO,KAAK,QAAQ,KAAK,6BAA6B,sBAAsB;AAAA,MAC9E;AACA,WAAK,QAAQ;AACb,WAAK,QAAQ;AAAA,QACX,IAAI,MAAM,0BAA0B,sBAAsB,qBAAqB;AAAA,MACjF;AACA;AAAA,IACF;AAEA,SAAK,QAAQ;AAGb,UAAM,UAAU,KAAK;AAAA,MACnB,uBAAuB,KAAK,IAAI,GAAG,KAAK,oBAAoB,CAAC;AAAA,MAC7D;AAAA,IACF;AACA,UAAM,SAAS,KAAK,OAAO,IAAI;AAC/B,UAAM,QAAQ,UAAU;AAExB;AAAA,MACE,OAAO,KAAK,QAAQ,KAAK,qBAAqB,KAAK,MAAM,KAAK,CAAC,eAAe,KAAK,iBAAiB,IAAI,sBAAsB;AAAA,IAChI;AAEA,SAAK,iBAAiB,WAAW,MAAM;AACrC,WAAK,iBAAiB;AACtB,UAAI,KAAK,UAAU,eAAgB;AAEnC,WAAK,QAAQ,EAAE,MAAM,CAAC,QAAQ;AAC5B,cAAM,OAAO,KAAK,QAAQ,KAAK,uBAAuB,GAAG,EAAE;AAC3D,YAAI,eAAe,iBAAiB,IAAI,SAAS,WAAW,eAAe;AAEzE,eAAK,QAAQ;AACb,eAAK,QAAQ,UAAU,GAAG;AAAA,QAC5B,OAAO;AACL,eAAK,kBAAkB;AAAA,QACzB;AAAA,MACF,CAAC;AAAA,IACH,GAAG,KAAK;AAAA,EACV;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,QAAQ;AACb,QAAI,KAAK,gBAAgB;AACvB,mBAAa,KAAK,cAAc;AAChC,WAAK,iBAAiB;AAAA,IACxB;AACA,SAAK,cAAc;AACnB,UAAM,OAAO,KAAK,QAAQ,KAAK,oBAAoB;AAAA,EACrD;AAAA;AAAA,EAGA,WAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AACF;;;AChOA,eAAsB,gBACpB,QACA,WACA,cACA,cAAc,KACO;AAErB,QAAM,iBAAiB,MAAM,YAAY,QAAQ,WAAW;AAAA,IAC1D,QAAQ;AAAA,EACV,CAAC;AAGD,MAAI,uBAAsC;AAC1C,MAAI,gBAAgB;AACpB,MAAI,kBAAkB;AACtB,MAAI,qBAAwC;AAC5C,QAAM,sBAAsB,oBAAI,IAAoB;AAEpD,aAAW,SAAS,gBAAgB;AAClC,oBAAgB,MAAM;AAEtB,QAAI,MAAM,SAAS,8BAA8B;AAC/C,UAAI,sBAAsB,KAAK,GAAG;AAChC,cAAM,aAAa;AAAA,UACjB,oBAAoB,IAAI,MAAM,QAAQ,SAAS,KAAK;AAAA,UACpD,MAAM;AAAA,QACR;AACA,4BAAoB,IAAI,MAAM,QAAQ,WAAW,UAAU;AAC3D,YAAI,gBAAgB,KAAK,KAAK,0BAA0B,KAAK,GAAG;AAC9D,+BAAqB;AAAA,YACnB,UAAU;AAAA,YACV,aAAa,MAAM;AAAA,UACrB;AAAA,QACF;AACA;AAAA,MACF;AACA,UAAI,CAAC,gBAAgB,KAAK,EAAG;AAC7B,aAAO;AAAA,QACL,UAAU,yBAAyB,KAAK;AAAA,QACxC,aAAa,MAAM;AAAA,MACrB;AAAA,IACF;AAEA,QACE,MAAM,SAAS,kBACf,MAAM,QACN,WAAW,MAAM,QACjB,gBAAgB,KAAK,GACrB;AACA,wBAAkB;AAClB,UAAI,MAAM,YAAY,QAAW;AAC/B,+BAAuB,KAAK,UAAU,MAAM,OAAO;AAAA,MACrD;AAAA,IACF;AAEA,QACE,MAAM,SAAS,mBACf,MAAM,QACN,WAAW,MAAM,QACjB,gBAAgB,KAAK,GACrB;AACA,aAAO;AAAA,QACL,UAAU,KAAK,UAAU,EAAE,OAAO,MAAM,QAAQ,CAAC;AAAA,QACjD,aAAa,MAAM;AAAA,MACrB;AAAA,IACF;AAEA,QAAI,MAAM,SAAS,mBAAmB,YAAY,GAAG;AACnD,cAAQ,OAAO,MAAM,YAAY,MAAM,KAAK,KAAK,MAAM,OAAO;AAAA,CAAI;AAAA,IACpE;AAAA,EACF;AAEA,MAAI,yBAAyB,MAAM;AACjC,WAAO,EAAE,UAAU,sBAAsB,aAAa,cAAc;AAAA,EACtE;AAEA,MAAI,mBAAmB,uBAAuB,MAAM;AAClD,WAAO,EAAE,UAAU,mBAAmB,UAAU,aAAa,cAAc;AAAA,EAC7E;AAGA,MAAI;AACF,WAAO,MAAM;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,sCAAsC,GAAG,iCAAiC;AAChF,WAAO,MAAM;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,iBACP,WACA,QACA,aACA,sBACqB;AACrB,SAAO,IAAI,QAAoB,CAAC,SAAS,WAAW;AAClD,QAAI,UAAU;AACd,QAAI,qBAAoC;AACxC,QAAI,gBAAgB;AACpB,QAAI,mBAAyD;AAC7D,QAAI,WAAsD;AAC1D,UAAM,UAAU,oBAAI,IAAY;AAChC,QAAI,qBAAwC;AAC5C,UAAM,sBAAsB,IAAI,IAAoB,oBAAoB;AAExE,UAAM,QAAQ,WAAW,MAAM;AAC7B,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV,cAAM,mCAAmC;AACzC,YAAI,iBAAkB,cAAa,gBAAgB;AACnD,kBAAU,MAAM;AAChB,cAAM,WAAW,qBACb,EAAE,UAAU,mBAAmB,UAAU,aAAa,cAAc,IACpE,EAAE,UAAU,oBAAoB,aAAa,cAAc;AAC/D,gBAAQ,QAAQ;AAAA,MAClB;AAAA,IACF,GAAG,WAAW;AAEd,UAAM,UAAU,CAAC,WAA6B;AAC5C,UAAI,QAAS;AACb,gBAAU;AACV,mBAAa,KAAK;AAClB,UAAI,iBAAkB,cAAa,gBAAgB;AACnD,gBAAU,MAAM;AAChB,cAAQ,MAAM;AAAA,IAChB;AAEA,yBAAqB,OAAqB;AAAA,MACxC,MAAM,aAAa,SAAS;AAAA,MAC5B,OAAO,QAAQ,UAAU,UAAU,GAAG,CAAC,CAAC;AAAA,MACxC,WAAW,MAAM;AAAA,MACjB,WAAW,CAAC,UAAU;AAEpB,YAAI,QAAQ,IAAI,MAAM,EAAE,GAAG;AACzB,gBAAM,8CAA8C,MAAM,EAAE,EAAE;AAC9D;AAAA,QACF;AACA,gBAAQ,IAAI,MAAM,EAAE;AACpB,wBAAgB,MAAM;AAEtB,YAAI,MAAM,SAAS,8BAA8B;AAC/C,cAAI,sBAAsB,KAAK,GAAG;AAChC,kBAAM,aAAa;AAAA,cACjB,oBAAoB,IAAI,MAAM,QAAQ,SAAS,KAAK;AAAA,cACpD,MAAM;AAAA,YACR;AACA,gCAAoB,IAAI,MAAM,QAAQ,WAAW,UAAU;AAC3D,gBAAI,gBAAgB,KAAK,KAAK,0BAA0B,KAAK,GAAG;AAC9D,mCAAqB;AAAA,gBACnB,UAAU;AAAA,gBACV,aAAa,MAAM;AAAA,cACrB;AAEA,kBAAI,uBAAuB,MAAM;AAC/B,wBAAQ;AAAA,kBACN,UAAU;AAAA,kBACV,aAAa,MAAM;AAAA,gBACrB,CAAC;AAAA,cACH;AAAA,YACF;AACA;AAAA,UACF;AACA,cAAI,CAAC,gBAAgB,KAAK,EAAG;AAC7B,kBAAQ;AAAA,YACN,UAAU,yBAAyB,KAAK;AAAA,YACxC,aAAa,MAAM;AAAA,UACrB,CAAC;AACD;AAAA,QACF;AAEA,YACE,MAAM,SAAS,kBACf,MAAM,QACN,WAAW,MAAM,QACjB,gBAAgB,KAAK,GACrB;AACA,cAAI,MAAM,YAAY,QAAW;AAC/B,iCAAqB,KAAK,UAAU,MAAM,OAAO;AAAA,UACnD;AAEA,cAAI,uBAAuB,MAAM;AAC/B,oBAAQ;AAAA,cACN,UAAU,mBAAmB;AAAA,cAC7B,aAAa;AAAA,YACf,CAAC;AACD;AAAA,UACF;AAEA,cAAI,iBAAkB,cAAa,gBAAgB;AACnD,6BAAmB,WAAW,MAAM;AAClC,+BAAmB;AACnB,gBAAI,CAAC,WAAW,uBAAuB,MAAM;AAC3C,sBAAQ;AAAA,gBACN,UAAU;AAAA,gBACV,aAAa;AAAA,cACf,CAAC;AAAA,YACH;AAAA,UACF,GAAG,GAAG;AAAA,QACR;AAEA,YACE,MAAM,SAAS,mBACf,MAAM,QACN,WAAW,MAAM,QACjB,gBAAgB,KAAK,GACrB;AACA,kBAAQ;AAAA,YACN,UAAU,KAAK,UAAU,EAAE,OAAO,MAAM,QAAQ,CAAC;AAAA,YACjD,aAAa,MAAM;AAAA,UACrB,CAAC;AACD;AAAA,QACF;AAEA,YAAI,MAAM,SAAS,mBAAmB,YAAY,GAAG;AACnD,kBAAQ,OAAO,MAAM,YAAY,MAAM,KAAK,KAAK,MAAM,OAAO;AAAA,CAAI;AAAA,QACpE;AAAA,MACF;AAAA,MACA,SAAS,CAAC,QAAQ;AAChB,cAAM,kCAAkC,IAAI,OAAO,EAAE;AACrD,YAAI,CAAC,SAAS;AACZ,oBAAU;AACV,uBAAa,KAAK;AAClB,cAAI,iBAAkB,cAAa,gBAAgB;AACnD,iBAAO,GAAG;AAAA,QACZ;AAAA,MACF;AAAA,IACF,CAAC,EACE,KAAK,CAAC,OAAO;AACZ,iBAAW;AACX,UAAI,SAAS;AACX,WAAG,MAAM;AAAA,MACX;AAAA,IACF,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,YAAM,wCAAwC,GAAG,EAAE;AACnD,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV,qBAAa,KAAK;AAClB,YAAI,iBAAkB,cAAa,gBAAgB;AACnD,eAAO,GAAG;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACL,CAAC;AACH;AAKA,eAAe,YACb,QACA,WACA,QACA,aACA,sBACqB;AACrB,QAAM,YAAY,KAAK,IAAI;AAC3B,MAAI,gBAAgB;AACpB,MAAI,qBAAwC;AAC5C,QAAM,sBAAsB,IAAI,IAAoB,oBAAoB;AAExE,SAAO,KAAK,IAAI,IAAI,YAAY,aAAa;AAC3C,UAAM,SAAS,MAAM,YAAY,QAAQ,WAAW;AAAA,MAClD,QAAQ;AAAA,IACV,CAAC;AAED,QAAI,uBAAsC;AAC1C,QAAI,kBAAkB;AAEtB,eAAW,SAAS,QAAQ;AAC1B,YAAM,sBAAsB,MAAM,IAAI,EAAE;AAExC,UAAI,MAAM,SAAS,8BAA8B;AAC/C,YAAI,sBAAsB,KAAK,GAAG;AAChC,gBAAM,aAAa;AAAA,YACjB,oBAAoB,IAAI,MAAM,QAAQ,SAAS,KAAK;AAAA,YACpD,MAAM;AAAA,UACR;AACA,8BAAoB,IAAI,MAAM,QAAQ,WAAW,UAAU;AAC3D,cAAI,gBAAgB,KAAK,KAAK,0BAA0B,KAAK,GAAG;AAC9D,iCAAqB;AAAA,cACnB,UAAU;AAAA,cACV,aAAa,MAAM;AAAA,YACrB;AAAA,UACF;AACA;AAAA,QACF;AACA,YAAI,CAAC,gBAAgB,KAAK,EAAG;AAC7B,eAAO;AAAA,UACL,UAAU,yBAAyB,KAAK;AAAA,UACxC,aAAa,MAAM;AAAA,QACrB;AAAA,MACF;AAEA,UACE,MAAM,SAAS,kBACf,MAAM,QACN,WAAW,MAAM,QACjB,gBAAgB,KAAK,GACrB;AACA,0BAAkB;AAClB,YAAI,MAAM,YAAY,QAAW;AAC/B,iCAAuB,KAAK,UAAU,MAAM,OAAO;AAAA,QACrD;AAAA,MACF;AAEA,UACE,MAAM,SAAS,mBACf,MAAM,QACN,WAAW,MAAM,QACjB,gBAAgB,KAAK,GACrB;AACA,eAAO;AAAA,UACL,UAAU,KAAK,UAAU,EAAE,OAAO,MAAM,QAAQ,CAAC;AAAA,UACjD,aAAa,MAAM;AAAA,QACrB;AAAA,MACF;AAEA,UAAI,MAAM,SAAS,mBAAmB,YAAY,GAAG;AACnD,gBAAQ,OAAO,MAAM,YAAY,MAAM,KAAK,KAAK,MAAM,OAAO;AAAA,CAAI;AAAA,MACpE;AAAA,IACF;AAEA,QAAI,OAAO,SAAS,GAAG;AACrB,sBAAgB,OAAO,OAAO,SAAS,CAAC,EAAE;AAAA,IAC5C;AAEA,QAAI,yBAAyB,MAAM;AACjC,aAAO,EAAE,UAAU,sBAAsB,aAAa,cAAc;AAAA,IACtE;AAEA,QAAI,mBAAmB,uBAAuB,MAAM;AAClD,aAAO,EAAE,UAAU,mBAAmB,UAAU,aAAa,cAAc;AAAA,IAC7E;AAEA,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAI,CAAC;AAAA,EAC1D;AAEA,SAAO,qBACH,EAAE,UAAU,mBAAmB,UAAU,aAAa,cAAc,IACpE,EAAE,UAAU,MAAM,aAAa,cAAc;AACnD;AAYA,eAAsB,0BACpB,QACA,WACA,aACA,cACA,cAAc,KACO;AACrB,QAAM,YAAY,KAAK,IAAI;AAC3B,MAAI,SAAS;AACb,MAAI,qBAAwC;AAC5C,QAAM,sBAAsB,oBAAI,IAAoB;AAEpD,SAAO,KAAK,IAAI,IAAI,YAAY,aAAa;AAC3C,UAAM,SAAS,MAAM,YAAY,QAAQ,WAAW,EAAE,OAAO,CAAC;AAE9D,QAAI,uBAAsC;AAC1C,QAAI,kBAAkB;AAEtB,eAAW,SAAS,QAAQ;AAC1B,YAAM,oCAAoC,MAAM,IAAI,EAAE;AAKtD,UAAI,gBAAgB,MAAM,MAAM,WAAW,KAAK,CAAC,sBAAsB,KAAK,GAAG;AAC7E,gBAAQ,OAAO,MAAM,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,MACnD;AAEA,UAAI,MAAM,SAAS,8BAA8B;AAC/C,YAAI,sBAAsB,KAAK,GAAG;AAChC,gBAAM,aAAa;AAAA,YACjB,oBAAoB,IAAI,MAAM,QAAQ,SAAS,KAAK;AAAA,YACpD,MAAM;AAAA,UACR;AACA,8BAAoB,IAAI,MAAM,QAAQ,WAAW,UAAU;AAC3D,cAAI,gBAAgB,KAAK,KAAK,0BAA0B,KAAK,GAAG;AAC9D,iCAAqB;AAAA,cACnB,UAAU;AAAA,cACV,aAAa,MAAM;AAAA,YACrB;AAAA,UACF;AACA;AAAA,QACF;AACA,YAAI,CAAC,gBAAgB,KAAK,EAAG;AAC7B,eAAO;AAAA,UACL,UAAU,yBAAyB,KAAK;AAAA,UACxC,aAAa,MAAM;AAAA,QACrB;AAAA,MACF;AAEA,UACE,MAAM,SAAS,kBACf,MAAM,QACN,WAAW,MAAM,QACjB,gBAAgB,KAAK,GACrB;AACA,0BAAkB;AAClB,YAAI,MAAM,YAAY,QAAW;AAC/B,iCAAuB,KAAK,UAAU,MAAM,OAAO;AAAA,QACrD;AAAA,MACF;AAEA,UACE,MAAM,SAAS,mBACf,MAAM,QACN,WAAW,MAAM,QACjB,gBAAgB,KAAK,GACrB;AACA,eAAO;AAAA,UACL,UAAU,KAAK,UAAU,EAAE,OAAO,MAAM,QAAQ,CAAC;AAAA,UACjD,aAAa,MAAM;AAAA,QACrB;AAAA,MACF;AAEA,UAAI,MAAM,SAAS,mBAAmB,YAAY,GAAG;AACnD,gBAAQ,OAAO,MAAM,YAAY,MAAM,KAAK,KAAK,MAAM,OAAO;AAAA,CAAI;AAAA,MACpE;AAAA,IACF;AAEA,QAAI,OAAO,SAAS,GAAG;AACrB,eAAS,OAAO,OAAO,SAAS,CAAC,EAAE;AAAA,IACrC;AAEA,QAAI,yBAAyB,MAAM;AACjC,aAAO,EAAE,UAAU,sBAAsB,aAAa,OAAO;AAAA,IAC/D;AAEA,QAAI,mBAAmB,uBAAuB,MAAM;AAClD,aAAO,EAAE,UAAU,mBAAmB,UAAU,aAAa,OAAO;AAAA,IACtE;AAEA,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAI,CAAC;AAAA,EAC1D;AAEA,SAAO,qBACH,EAAE,UAAU,mBAAmB,UAAU,aAAa,OAAO,IAC7D,EAAE,UAAU,MAAM,aAAa,OAAO;AAC5C;AAcA,SAAS,oBAAoB,QAAyD;AACpF,QAAM,eAAe,OAAO;AAAA,IAC1B,CAAC,MAAM,EAAE,SAAS,mBAAmB,gBAAgB,CAAC;AAAA,EACxD;AACA,MAAI,aAAc,QAAO;AAEzB,QAAM,cAAc,OAAO;AAAA,IACzB,CAAC,MACC,EAAE,SAAS,gCACX,CAAC,sBAAsB,CAAC,KACxB,EAAE,MAAM,cAAc;AAAA,EAC1B;AACA,MAAI,YAAa,QAAO;AAExB,QAAM,cAAc,OAAO;AAAA,IACzB,CAAC,MAAM,EAAE,SAAS,kBAAkB,gBAAgB,CAAC;AAAA,EACvD;AACA,QAAM,kBAAkB,OAAO;AAAA,IAC7B,CAAC,MACC,EAAE,SAAS,gCACX,gBAAgB,CAAC,KACjB,CAAC,sBAAsB,CAAC;AAAA,EAC5B;AACA,MAAI,eAAe,gBAAiB,QAAO;AAE3C,SAAO;AACT;AAQA,eAAsB,YACpB,QACA,WACA,SAIyB;AACzB,QAAM,sBAAsB,SAAS,uBAAuB;AAC5D,QAAM,iBAAiB,SAAS,kBAAkB;AAGlD,QAAM,gBAAgB,MAAM,YAAY,QAAQ,WAAW,CAAC,CAAC;AAC7D,QAAM,YAA4B,CAAC,GAAG,aAAa;AACnD,MAAI,gBACF,cAAc,SAAS,IAAI,cAAc,cAAc,SAAS,CAAC,EAAE,KAAK;AAE1E,aAAW,OAAO,eAAe;AAC/B,iBAAa,GAAG;AAAA,EAClB;AAGA,QAAM,kBAAkB,oBAAoB,SAAS;AACrD,MAAI,iBAAiB;AACnB,UAAM,qDAAqD;AAC3D,WAAO,EAAE,QAAQ,WAAW,aAAa,eAAe,QAAQ,gBAAgB;AAAA,EAClF;AAGA,MAAI;AACF,WAAO,MAAM;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,kCAAkC,GAAG,yBAAyB;AACpE,WAAO,MAAM;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAGA,SAAS,aAAa,KAAyB;AAC7C,QAAM,WAAW,IAAI;AAGrB,MAAI,UAAU;AACZ;AAAA,MACE,UAAU,IAAI,IAAI,UAAU,SAAS,SAAS,SAAS,aAAa,SAAS,KAAK,SAAS,MAAM,IAAI,UAAU,GAAG,CAAC,CAAC,YAAY,SAAS,MAAM;AAAA,IACjJ;AAAA,EACF,OAAO;AACL,UAAM,UAAU,IAAI,IAAI,iBAAiB;AAAA,EAC3C;AACF;AAKA,SAAS,qBACP,WACA,eACA,QACA,qBACyB;AACzB,SAAO,IAAI,QAAwB,CAAC,SAAS,WAAW;AACtD,QAAI,UAAU;AACd,QAAI,gBAAgB;AACpB,QAAI,WAAsD;AAC1D,UAAM,YAAY,CAAC,GAAG,aAAa;AACnC,UAAM,UAAU,IAAI,IAAY,cAAc,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC9D,QAAI,mBAAyD;AAC7D,QAAI,kBAAwD;AAE5D,UAAM,uBAAuB,MAAY;AACvC,UAAI,gBAAiB,cAAa,eAAe;AACjD,wBAAkB,WAAW,MAAM;AACjC,YAAI,CAAC,SAAS;AACZ,gBAAM,0CAA0C;AAChD,kBAAQ;AAAA,YACN,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AAAA,MACF,GAAG,mBAAmB;AAAA,IACxB;AAEA,UAAM,UAAU,CAAC,WAAiC;AAChD,UAAI,QAAS;AACb,gBAAU;AACV,UAAI,iBAAkB,cAAa,gBAAgB;AACnD,UAAI,gBAAiB,cAAa,eAAe;AACjD,gBAAU,MAAM;AAChB,cAAQ,MAAM;AAAA,IAChB;AAGA,yBAAqB;AAErB,yBAAqB,OAAqB;AAAA,MACxC,MAAM,aAAa,SAAS;AAAA,MAC5B,OAAO,QAAQ,UAAU,UAAU,GAAG,CAAC,CAAC;AAAA,MACxC,WAAW,MAAM;AAAA,MACjB,WAAW,CAAC,UAAU;AACpB,YAAI,QAAQ,IAAI,MAAM,EAAE,EAAG;AAC3B,gBAAQ,IAAI,MAAM,EAAE;AACpB,wBAAgB,MAAM;AACtB,kBAAU,KAAK,KAAK;AACpB,qBAAa,KAAK;AAGlB,6BAAqB;AAErB,cAAM,SAAS,oBAAoB,SAAS;AAC5C,YAAI,QAAQ;AAEV,cAAI,WAAW,gBAAgB,CAAC,kBAAkB;AAChD,+BAAmB,WAAW,MAAM;AAClC,iCAAmB;AACnB,oBAAM,cAAc,oBAAoB,SAAS,KAAK;AACtD,sBAAQ;AAAA,gBACN,QAAQ;AAAA,gBACR,aAAa;AAAA,gBACb,QAAQ;AAAA,cACV,CAAC;AAAA,YACH,GAAG,GAAG;AACN;AAAA,UACF;AACA,cAAI,WAAW,cAAc;AAC3B,oBAAQ,EAAE,QAAQ,WAAW,aAAa,eAAe,OAAO,CAAC;AAAA,UACnE;AAAA,QACF;AAAA,MACF;AAAA,MACA,SAAS,CAAC,QAAQ;AAChB,cAAM,sCAAsC,IAAI,OAAO,EAAE;AACzD,YAAI,CAAC,SAAS;AACZ,oBAAU;AACV,cAAI,iBAAkB,cAAa,gBAAgB;AACnD,cAAI,gBAAiB,cAAa,eAAe;AACjD,iBAAO,GAAG;AAAA,QACZ;AAAA,MACF;AAAA,IACF,CAAC,EACE,KAAK,CAAC,OAAO;AACZ,iBAAW;AACX,UAAI,QAAS,IAAG,MAAM;AAAA,IACxB,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,YAAM,4CAA4C,GAAG,EAAE;AACvD,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV,YAAI,iBAAkB,cAAa,gBAAgB;AACnD,YAAI,gBAAiB,cAAa,eAAe;AACjD,eAAO,GAAG;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACL,CAAC;AACH;AAKA,eAAe,gBACb,QACA,WACA,eACA,QACA,qBACA,gBACyB;AACzB,QAAM,YAAY,CAAC,GAAG,aAAa;AACnC,MAAI,gBAAgB;AACpB,QAAM,wBAAwB,sBAAsB;AACpD,MAAI,oBAAoB;AAExB,SAAO,MAAM;AACX,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,cAAc,CAAC;AAElE,UAAM,YAAY,MAAM,YAAY,QAAQ,WAAW;AAAA,MACrD,QAAQ;AAAA,IACV,CAAC;AAED,QAAI,UAAU,SAAS,GAAG;AACxB,iBAAW,OAAO,WAAW;AAC3B,qBAAa,GAAG;AAAA,MAClB;AACA,gBAAU,KAAK,GAAG,SAAS;AAC3B,sBAAgB,UAAU,UAAU,SAAS,CAAC,EAAE;AAChD,0BAAoB;AAAA,IACtB,OAAO;AACL;AAAA,IACF;AAEA,UAAM,SAAS,oBAAoB,SAAS;AAC5C,QAAI,QAAQ;AAEV,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AACvD,YAAM,iBAAiB,MAAM,YAAY,QAAQ,WAAW;AAAA,QAC1D,QAAQ;AAAA,MACV,CAAC;AACD,UAAI,eAAe,SAAS,GAAG;AAC7B,mBAAW,OAAO,gBAAgB;AAChC,uBAAa,GAAG;AAAA,QAClB;AACA,kBAAU,KAAK,GAAG,cAAc;AAChC,wBAAgB,eAAe,eAAe,SAAS,CAAC,EAAE;AAAA,MAC5D;AACA,YAAM,cAAc,oBAAoB,SAAS,KAAK;AACtD,aAAO,EAAE,QAAQ,WAAW,aAAa,eAAe,QAAQ,YAAY;AAAA,IAC9E;AAEA,QAAI,qBAAqB,uBAAuB;AAC9C,YAAM,wCAAwC,iBAAiB,eAAe;AAC9E,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -19287,7 +19287,7 @@ ${message}
19287
19287
  import path2 from "path";
19288
19288
  import { fileURLToPath } from "url";
19289
19289
  function getCliVersion() {
19290
- return "0.12.0";
19290
+ return "0.12.1";
19291
19291
  }
19292
19292
  function isDevBuild() {
19293
19293
  const dir = path2.dirname(fileURLToPath(import.meta.url));
@@ -19775,4 +19775,4 @@ mime-types/index.js:
19775
19775
  * MIT Licensed
19776
19776
  *)
19777
19777
  */
19778
- //# sourceMappingURL=chunk-LFMQJOKC.js.map
19778
+ //# sourceMappingURL=chunk-JQRJ4A4S.js.map
@@ -11,7 +11,7 @@ import {
11
11
  getUserAgent,
12
12
  retry,
13
13
  shouldClearAuthToken
14
- } from "./chunk-LFMQJOKC.js";
14
+ } from "./chunk-JQRJ4A4S.js";
15
15
 
16
16
  // src/lib/api-client.ts
17
17
  var GuildAPIClient = class {
@@ -314,4 +314,4 @@ export {
314
314
  parseEventFilter,
315
315
  shouldShowEvent
316
316
  };
317
- //# sourceMappingURL=chunk-RIG2HZWM.js.map
317
+ //# sourceMappingURL=chunk-RJHD6XTV.js.map
@@ -1,7 +1,7 @@
1
1
  import { createRequire as _cjsReq } from 'module'; if(typeof require === 'undefined') var require = _cjsReq(import.meta.url);
2
2
  import {
3
3
  getConfigFlag
4
- } from "./chunk-LFMQJOKC.js";
4
+ } from "./chunk-JQRJ4A4S.js";
5
5
  import {
6
6
  __commonJS,
7
7
  __require,
@@ -3054,4 +3054,4 @@ export {
3054
3054
  isMachineReadable,
3055
3055
  isQuietMode
3056
3056
  };
3057
- //# sourceMappingURL=chunk-DOIYVBNY.js.map
3057
+ //# sourceMappingURL=chunk-YQWI6SUV.js.map
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { Command } from 'commander';
3
3
  import { GuildAPIClient } from '../lib/api-client.js';
4
4
  import { SessionEvent, Session } from '../lib/session-events.js';
5
+ import { fetchEvents, fetchTasks } from '../lib/session-events-fetch.js';
5
6
  /** Thrown when no workspace is configured (no --workspace flag, no config). */
6
7
  export declare class WorkspaceNotConfiguredError extends Error {
7
8
  constructor();
@@ -29,8 +30,28 @@ export interface ChatAppProps {
29
30
  eventFilter?: Set<string>;
30
31
  }
31
32
  export declare function ChatApp({ initialPrompt, version, workspaceId, versionId, agentName, showSplash, resumeSession, resumeEvents, resumeCommand, openDashboard, eventFilter, }: ChatAppProps): React.JSX.Element;
33
+ /**
34
+ * Chat UI that accepts a pre-established connection from ChatApp
35
+ */
36
+ interface ChatUIWithConnectionProps {
37
+ initialPrompt: string;
38
+ version: string;
39
+ versionId?: string;
40
+ agentName?: string;
41
+ client: GuildAPIClient | null;
42
+ session: Session | null;
43
+ onFirstMessage?: () => void;
44
+ isVisible?: boolean;
45
+ resumeEvents?: SessionEvent[];
46
+ resumeCommand?: string;
47
+ eventFilter?: Set<string>;
48
+ fetchEventsFn?: typeof fetchEvents;
49
+ fetchTasksFn?: typeof fetchTasks;
50
+ }
51
+ export declare function ChatUIWithConnection({ initialPrompt, version: _version, versionId: _versionId, agentName, client: preConnectedClient, session: preConnectedSession, onFirstMessage, isVisible, resumeEvents, resumeCommand, eventFilter, fetchEventsFn, fetchTasksFn, }: ChatUIWithConnectionProps): React.JSX.Element | null;
32
52
  export declare function ensureAuthenticated(): Promise<string>;
33
53
  export declare function createSession(client: GuildAPIClient, workspaceId: string | undefined, initialPrompt: string, versionId?: string, onProgress?: (status: string) => void): Promise<Session>;
34
54
  export declare function createChatCommand(): Command;
35
55
  export declare function handleChatAction(_promptArgs: string[], _options: Record<string, unknown>): Promise<void>;
56
+ export {};
36
57
  //# sourceMappingURL=chat.d.ts.map
package/dist/index.js CHANGED
@@ -9,14 +9,14 @@ import {
9
9
  resolveAgentRef,
10
10
  resolveOwnerId,
11
11
  runGit
12
- } from "./chunk-B7VAF5UG.js";
12
+ } from "./chunk-EQUW4M5A.js";
13
13
  import {
14
14
  Command,
15
15
  Option,
16
16
  getOutputMode,
17
17
  isMachineReadable,
18
18
  isQuietMode
19
- } from "./chunk-DOIYVBNY.js";
19
+ } from "./chunk-YQWI6SUV.js";
20
20
  import {
21
21
  execa
22
22
  } from "./chunk-6EX6E7WP.js";
@@ -35,7 +35,7 @@ import {
35
35
  loadLocalConfig,
36
36
  parseEventFilter,
37
37
  saveGlobalConfig
38
- } from "./chunk-RIG2HZWM.js";
38
+ } from "./chunk-RJHD6XTV.js";
39
39
  import {
40
40
  ErrorCodes,
41
41
  GuildCLIError,
@@ -58,7 +58,7 @@ import {
58
58
  logout,
59
59
  source_default,
60
60
  stringWidth
61
- } from "./chunk-LFMQJOKC.js";
61
+ } from "./chunk-JQRJ4A4S.js";
62
62
  import "./chunk-M347HP6M.js";
63
63
  import "./chunk-ENKEEJ45.js";
64
64
  import "./chunk-VVSOU6ON.js";
@@ -6063,7 +6063,7 @@ Configuration:
6063
6063
  Or run: guild setup --mcp
6064
6064
  `
6065
6065
  ).action(async (options) => {
6066
- const { startMcpServer } = await import("./server-JYVH64FD.js");
6066
+ const { startMcpServer } = await import("./server-CKXFV2JC.js");
6067
6067
  await startMcpServer({
6068
6068
  workspace: options.workspace,
6069
6069
  debug: options.debug
@@ -8151,7 +8151,7 @@ program.command("chat").description("Chat with an agent (default: Guild assistan
8151
8151
  "after",
8152
8152
  "\nTo chat with a local agent under development: guild agent chat"
8153
8153
  ).action(async (promptArgs, options) => {
8154
- const { handleChatAction } = await import("./chat-SIKDYZQK.js");
8154
+ const { handleChatAction } = await import("./chat-SG2I727J.js");
8155
8155
  await handleChatAction(
8156
8156
  promptArgs,
8157
8157
  options
@@ -8183,7 +8183,7 @@ agentCmd.command("chat").description("Chat with the agent in current directory")
8183
8183
  "after",
8184
8184
  "\nTo chat with a published agent by name: guild chat --agent owner~agent-name"
8185
8185
  ).action(async (promptArgs, options) => {
8186
- const { handleAgentChatAction } = await import("./chat-5VX2WJH2.js");
8186
+ const { handleAgentChatAction } = await import("./chat-ALOJ22JR.js");
8187
8187
  await handleAgentChatAction(
8188
8188
  promptArgs,
8189
8189
  options
@@ -8200,7 +8200,7 @@ agentCmd.command("test").description("Test agent in interactive REPL session").o
8200
8200
  "--events <types>",
8201
8201
  "Event types to stream (default: all). Shorthands: none, user, system, all, or comma-separated type names"
8202
8202
  ).option("--bundle <file>", "Path to a pre-built gzip+base64 bundle file").option("--no-cache", "Skip ephemeral build cache (force a fresh build)").addOption(new Option("--mode <format>").hideHelp()).action(async (options) => {
8203
- const { handleAgentTestAction } = await import("./test-SNIYRJ32.js");
8203
+ const { handleAgentTestAction } = await import("./test-VEA4ENOR.js");
8204
8204
  await handleAgentTestAction(options);
8205
8205
  });
8206
8206
  agentCmd.addCommand(createAgentPublishCommand());
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Canonical terminal chat row shared by live chat, resume rendering, and
3
+ * markdown helpers.
4
+ */
5
+ export interface DisplayMessage {
6
+ key: string;
7
+ content: string;
8
+ type: 'user' | 'assistant' | 'progress';
9
+ timestamp?: string;
10
+ }
11
+ //# sourceMappingURL=display-message.d.ts.map
@@ -12,13 +12,6 @@ export declare function renderMarkdown(content: string): Promise<string>;
12
12
  * Render markdown synchronously (for use in non-async contexts)
13
13
  */
14
14
  export declare function renderMarkdownSync(content: string): string;
15
- /**
16
- * Message type for display in chat UI
17
- */
18
- export interface DisplayMessage {
19
- key: string;
20
- content: string;
21
- type: 'user' | 'assistant' | 'progress';
22
- timestamp?: string;
23
- }
15
+ export declare function renderAssistantMessageContent(text: string, taskName: string): string;
16
+ export type { DisplayMessage } from './display-message.js';
24
17
  //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Response-stream chat display state.
3
+ *
4
+ * Ink's <Static> component is append-only, so live LLM draft text cannot be
5
+ * rendered there without printing every update as a new transcript row. These
6
+ * helpers keep in-flight response streams in a dynamic active block, then
7
+ * remove or commit them into the append-only transcript once terminal events
8
+ * and final-message dedupe decide their durable fate.
9
+ */
10
+ import type { DisplayMessage } from './display-message.js';
11
+ import type { ResponseStreamResumeState } from './session-resume.js';
12
+ export interface SplitResponseStreamDisplayMessages {
13
+ transcriptMessages: DisplayMessage[];
14
+ dynamicMessages: DisplayMessage[];
15
+ activeMessages: DisplayMessage[];
16
+ }
17
+ export interface ClearResponseStreamResult {
18
+ removedKeys: Set<string>;
19
+ detachedKeys: Set<string>;
20
+ }
21
+ export interface ActiveResponseStreamUpdate {
22
+ dynamicMessages: DisplayMessage[];
23
+ affectedMessages: DisplayMessage[];
24
+ }
25
+ export declare function splitResponseStreamDisplayMessages(displayMessages: DisplayMessage[], responseStreamState: ResponseStreamResumeState | null | undefined): SplitResponseStreamDisplayMessages;
26
+ /** Build the mutable active-draft lookup used by the live chat renderer. */
27
+ export declare function createActiveResponseStreamMessageMap(messages: DisplayMessage[]): Map<string, DisplayMessage>;
28
+ /** Replace or insert a live draft in the repaintable chronological tail. */
29
+ export declare function upsertDynamicResponseStreamMessage(dynamicMessages: DisplayMessage[], activeMessagesByKey: Map<string, DisplayMessage>, message: DisplayMessage): DisplayMessage[];
30
+ /** Remove live drafts without keeping them in the visible chronological tail. */
31
+ export declare function removeDynamicResponseStreamMessages(dynamicMessages: DisplayMessage[], activeMessagesByKey: Map<string, DisplayMessage>, keys: Set<string>): ActiveResponseStreamUpdate;
32
+ /** Stop repainting live drafts while keeping their current row in chronological order. */
33
+ export declare function commitDynamicResponseStreamMessages(dynamicMessages: DisplayMessage[], activeMessagesByKey: Map<string, DisplayMessage>, keys: Set<string>): {
34
+ dynamicMessages: DisplayMessage[];
35
+ committedMessages: DisplayMessage[];
36
+ affectedMessages: DisplayMessage[];
37
+ };
38
+ /** Append the repaintable chronological tail to the append-only transcript. */
39
+ export declare function flushDynamicMessagesIntoTranscript(transcriptMessages: DisplayMessage[], dynamicMessages: DisplayMessage[]): DisplayMessage[];
40
+ /** Drop an aborted stream from all tracking maps and return its display key. */
41
+ export declare function abortTrackedResponseStream(state: ResponseStreamResumeState, streamId: string, taskId: string | undefined): Set<string>;
42
+ /** Clear tracked streams after a durable final message or error arrives. */
43
+ export declare function clearTrackedResponseStreamsForTask(state: ResponseStreamResumeState, taskId: string | undefined, options?: {
44
+ preserveContinued?: boolean;
45
+ finalText?: string;
46
+ }): ClearResponseStreamResult;
47
+ /** Clear tracked terminal streams after root runtime completion. */
48
+ export declare function commitTerminalTrackedResponseStreamsForTask(state: ResponseStreamResumeState, taskId: string | undefined): Set<string>;
49
+ /** Commit terminal tracked streams for every task, leaving active streams live. */
50
+ export declare function commitAllTerminalTrackedResponseStreams(state: ResponseStreamResumeState): Set<string>;
51
+ //# sourceMappingURL=response-stream-display-state.d.ts.map
@@ -61,6 +61,10 @@ export declare function getAgentName(agent: AgentRef | null | undefined): string
61
61
  export declare function matchesAgent(taskAgent: AgentRef | null | undefined, targetAgent: string): boolean;
62
62
  /** Get display name for a task - agent name or tool name */
63
63
  export declare function getTaskDisplayName(task: SessionTask): string;
64
+ /** Resolve the display name for an event's originating agent. */
65
+ export declare function getEventAgentName(event: {
66
+ task?: SessionTaskItem | SessionTask;
67
+ }, fallbackName?: string): string;
64
68
  /** Get task type label */
65
69
  export declare function getTaskTypeLabel(task: SessionTask): string;
66
70
  export interface BaseEvent {
@@ -1,5 +1,7 @@
1
1
  import { GuildAPIClient } from './api-client.js';
2
2
  import { type ResponseStreamContent, SessionEvent, Session } from './session-events.js';
3
+ import type { DisplayMessage } from './display-message.js';
4
+ export type { DisplayMessage } from './display-message.js';
3
5
  /**
4
6
  * Print a dimmed resume hint to stderr on session exit.
5
7
  * Only call when a session ID is available.
@@ -13,12 +15,6 @@ export declare function fetchSessionEvents(client: GuildAPIClient, sessionId: st
13
15
  * Fetch an existing session by ID.
14
16
  */
15
17
  export declare function fetchSession(client: GuildAPIClient, sessionId: string): Promise<Session>;
16
- export interface DisplayMessage {
17
- key: string;
18
- content: string;
19
- type: 'user' | 'assistant' | 'progress';
20
- timestamp?: string;
21
- }
22
18
  export interface ResponseStreamResumeState {
23
19
  keys: Map<string, string>;
24
20
  contents: Map<string, ResponseStreamContent[]>;
@@ -1,15 +1,15 @@
1
1
  import { createRequire as _cjsReq } from 'module'; if(typeof require === 'undefined') var require = _cjsReq(import.meta.url);
2
2
  import {
3
3
  pollForResponse
4
- } from "./chunk-SPZPZXUN.js";
4
+ } from "./chunk-F3F5CUO3.js";
5
5
  import {
6
6
  GuildAPIClient,
7
7
  getWorkspaceId
8
- } from "./chunk-RIG2HZWM.js";
8
+ } from "./chunk-RJHD6XTV.js";
9
9
  import {
10
10
  getAuthToken,
11
11
  getCliVersion
12
- } from "./chunk-LFMQJOKC.js";
12
+ } from "./chunk-JQRJ4A4S.js";
13
13
  import "./chunk-M347HP6M.js";
14
14
  import "./chunk-ENKEEJ45.js";
15
15
  import "./chunk-VVSOU6ON.js";
@@ -27656,4 +27656,4 @@ async function startMcpServer(options) {
27656
27656
  export {
27657
27657
  startMcpServer
27658
27658
  };
27659
- //# sourceMappingURL=server-JYVH64FD.js.map
27659
+ //# sourceMappingURL=server-CKXFV2JC.js.map
@@ -7,7 +7,7 @@ import {
7
7
  render_default,
8
8
  require_react,
9
9
  suppressScrollbackClear
10
- } from "./chunk-IBRKVGMZ.js";
10
+ } from "./chunk-7JJT3RNI.js";
11
11
  import {
12
12
  BuildFailedError,
13
13
  BuildTimeoutError,
@@ -17,13 +17,13 @@ import {
17
17
  buildEphemeralVersion,
18
18
  formatGitError,
19
19
  readAgentFiles
20
- } from "./chunk-B7VAF5UG.js";
20
+ } from "./chunk-EQUW4M5A.js";
21
21
  import {
22
22
  Command,
23
23
  Option,
24
24
  getOutputMode,
25
25
  isQuietMode
26
- } from "./chunk-DOIYVBNY.js";
26
+ } from "./chunk-YQWI6SUV.js";
27
27
  import {
28
28
  open_default
29
29
  } from "./chunk-56YCMGL3.js";
@@ -31,14 +31,14 @@ import "./chunk-6EX6E7WP.js";
31
31
  import {
32
32
  pollForResponse,
33
33
  pollForResponseWithEvents
34
- } from "./chunk-SPZPZXUN.js";
34
+ } from "./chunk-F3F5CUO3.js";
35
35
  import {
36
36
  GuildAPIClient,
37
37
  getWorkspaceId,
38
38
  getWorkspaceSourceLabel,
39
39
  loadLocalConfig,
40
40
  parseEventFilter
41
- } from "./chunk-RIG2HZWM.js";
41
+ } from "./chunk-RJHD6XTV.js";
42
42
  import {
43
43
  ErrorCodes,
44
44
  debug,
@@ -49,7 +49,7 @@ import {
49
49
  hyperlink,
50
50
  readStdinAsJSON,
51
51
  readStdinAsText
52
- } from "./chunk-LFMQJOKC.js";
52
+ } from "./chunk-JQRJ4A4S.js";
53
53
  import "./chunk-M347HP6M.js";
54
54
  import "./chunk-ENKEEJ45.js";
55
55
  import "./chunk-VVSOU6ON.js";
@@ -689,4 +689,4 @@ export {
689
689
  createAgentTestCommand,
690
690
  handleAgentTestAction
691
691
  };
692
- //# sourceMappingURL=test-SNIYRJ32.js.map
692
+ //# sourceMappingURL=test-VEA4ENOR.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guildai/cli",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "Guild.ai CLI - Build, test, and deploy AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",