| 95 | } |
| 96 | |
| 97 | function parseMessages(flags: GlobalFlags): ParsedMessages { |
| 98 | const messages: ChatMessage[] = []; |
| 99 | let system: string | undefined; |
| 100 | |
| 101 | if (flags.system) { |
| 102 | system = flags.system as string; |
| 103 | } |
| 104 | |
| 105 | if (flags.messagesFile) { |
| 106 | const filePath = flags.messagesFile as string; |
| 107 | const raw = filePath === '-' |
| 108 | ? readFileSync('/dev/stdin', 'utf-8') |
| 109 | : readFileSync(filePath, 'utf-8'); |
| 110 | const parsed = JSON.parse(raw) as Array<{ role: string; content: string | ContentBlock[] }>; |
| 111 | for (const m of parsed) { |
| 112 | if (m.role === 'system') { |
| 113 | system = typeof m.content === 'string' ? m.content : ''; |
| 114 | } else { |
| 115 | messages.push(m as ChatMessage); |
| 116 | } |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | // --prompt is an alias for --message |
| 121 | if (!flags.message && flags.prompt) { |
| 122 | flags.message = Array.isArray(flags.prompt) ? flags.prompt : [flags.prompt as string]; |
| 123 | } |
| 124 | |
| 125 | if (flags.message) { |
| 126 | const validRoles = new Set(['system', 'user', 'assistant']); |
| 127 | const msgs = flags.message as string[]; |
| 128 | for (const m of msgs) { |
| 129 | const colonIdx = m.indexOf(':'); |
| 130 | const maybeRole = colonIdx !== -1 ? m.slice(0, colonIdx) : ''; |
| 131 | |
| 132 | if (validRoles.has(maybeRole)) { |
| 133 | const content = m.slice(colonIdx + 1); |
| 134 | if (maybeRole === 'system') { |
| 135 | system = content; |
| 136 | } else { |
| 137 | messages.push({ role: maybeRole as 'user' | 'assistant', content }); |
| 138 | } |
| 139 | } else { |
| 140 | // Bare string → user message |
| 141 | messages.push({ role: 'user', content: m }); |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | return { system, messages }; |
| 147 | } |
| 148 | |
| 149 | function extractText(content: ContentBlock[]): string { |
| 150 | return content |