export type InputMessage = InitInputMessage | MessageInputMessage | AbortInputMessage | AnswerQuestionInputMessage | ResetConversationInputMessage | DeleteConversationInputMessage | RestoreConversationsInputMessage | PingInputMessage | UpdateClaudeTokenInputMessage | SyncSkillsInputMessage; export interface InitInputMessage { type: "init"; sessionId: string; model?: string; } export interface MessageInputMessage { type: "message"; sessionId: string; content: string; conversation_id: string; streamFormat?: "delta" | "content"; } export interface AbortInputMessage { type: "abort"; sessionId: string; conversation_id: string; } export interface AnswerQuestionInputMessage { type: "answer_question"; request_id: string; answers: Record; } export interface ResetConversationInputMessage { type: "reset_conversation"; conversation_id: string; } export interface DeleteConversationInputMessage { type: "delete_conversation"; conversation_id: string; } export interface RestoreConversationsInputMessage { type: "restore_conversations"; conversations: Array<{ conversation_id: string; claude_sdk_session_id: string; created_at: string; last_message_at: string; }>; } export interface PingInputMessage { type: "ping"; } export interface UpdateClaudeTokenInputMessage { type: "update_claude_token"; token: string; } /** * Sent by session-gateway (via ws-bridge.js default-forward) to trigger * marketplace plugin sync. Spec: docs/superpowers/specs/2026-05-23-ai-shell-marketplace-integration-design.md */ export interface SyncSkillsInputMessage { type: "sync_skills"; userId: string; /** * Plugin desired list — shape matches gateway-protocol's `SkillSyncDesired`. * Kept structurally typed (not nominal import) to avoid pulling in gateway-protocol * package; session-gateway uses the canonical type at the send side. */ desired: Array<{ pluginSlug: string; pluginVersion: string; s3TarUrl: string; distMode: 'thin' | 'fat' | 'both'; skills: Array<{ slug: string; name: string; description: string; configSchema: unknown; }>; }>; } export type OutputEvent = InitEvent | ThinkingEvent | ContentEvent | TextDeltaEvent | ToolCallEvent | ToolResultEvent | AskQuestionEvent | ProgressEvent | FinishEvent | ErrorEvent | InfoEvent | ConversationUpdateEvent | PongEvent; export interface InitEvent { type: "init"; conversation_id?: string; init: { model: string; maxContextTokens: number; workspaceDir: string; }; } export interface ThinkingEvent { type: "thinking"; conversation_id?: string; } export interface ContentEvent { type: "content"; conversation_id?: string; content: { text: string; }; } export interface TextDeltaEvent { type: "text_delta"; conversation_id?: string; delta: { text: string; }; } export interface ToolCallEvent { type: "tool_call"; conversation_id?: string; tool_call: { id: string; name: string; arguments: string; }; } export interface ToolResultEvent { type: "tool_result"; conversation_id?: string; tool_result: { tool_call_id: string; tool_name: string; output: string; error?: string; }; } export interface AskQuestionEvent { type: "ask_question"; conversation_id?: string; request_id: string; questions: Array<{ question: string; header: string; options: Array<{ label: string; description: string; }>; multiSelect: boolean; }>; } /** * Token 使用统计事件 * * 注意:这个事件在每次 API 调用完成(收到 assistant 消息)时发送, * 不是实时增量更新。根据 Claude API 限制,message_delta 事件只在 * 消息结束时发送一次,工具参数生成期间(可能持续数分钟)不会有 * token 更新。这是 API 的预期行为,不是 bug。 */ export interface ProgressEvent { type: "progress"; conversation_id?: string; progress: { total_input_tokens: number; total_output_tokens: number; current_input_tokens?: number; current_output_tokens?: number; by_model?: Record; timestamp?: number; }; } export interface FinishEvent { type: "finish"; conversation_id?: string; finish: { reason: string; iterations: number; usage?: { input_tokens: number; output_tokens: number; by_model: Record; }; }; } export interface ErrorEvent { type: "error"; conversation_id?: string; error: { message: string; code: string; }; } export interface InfoEvent { type: "info"; conversation_id?: string; info: { message: string; code?: string; }; } export interface ConversationUpdateEvent { type: "conversation_update"; update: { conversation_id: string; claude_sdk_session_id: string; last_message_at: string; }; } export interface PongEvent { type: "pong"; timestamp: number; } export interface ConversationState { conversation_id: string; claude_sdk_session_id?: string; created_at: Date; last_message_at: Date; message_count: number; } /** * Headless 模式参数化配置 * * 支持 Docker 和 Lambda 两种模式: * - Docker: stdin/stdout 通信,永久运行 * - Lambda: Response Stream 输出,SQS 等待回答,处理完退出 */ export interface HeadlessOptions { cwd?: string; model?: string; /** * 流式输出格式 * - content: 每个 text block 作为完整 content 事件发送 * - delta: 使用 text_delta 事件逐字符流式输出 * @default 'content' */ streamFormat?: "delta" | "content"; /** * 输出事件的方式 * - Docker: console.log(JSON.stringify(event)) * - Lambda: responseStream.write(JSON.stringify(event) + '\n') */ sendOutput: (event: OutputEvent) => void; /** * 等待用户回答 AskUserQuestion 的方式 * - Docker: Promise + stdin 监听 * - Lambda: SQS 轮询 * * @param requestId - 问题的唯一 ID * @param conversationId - 对话 ID * @returns 用户的回答 */ waitForAnswer: (requestId: string, conversationId: string) => Promise>; /** * 是否永久运行 * - Docker: true - 永不退出,持续监听 stdin * - Lambda: false - 处理完消息后退出 * @default true */ runForever?: boolean; /** * 获取下一条消息的方式 * - Docker: 从 readline 读取 * - Lambda: 返回单条消息后返回 null * * 返回 null 表示没有更多消息 */ getNextMessage?: () => Promise; /** * 恢复对话列表(可选) * 启动时恢复之前的对话状态 */ restoreConversations?: Array<{ conversation_id: string; claude_sdk_session_id: string; created_at: string; last_message_at: string; }>; } //# sourceMappingURL=headless-types.d.ts.map