| 203 | } |
| 204 | |
| 205 | function createCliStderrForwarder(client: OpenCodeClient) { |
| 206 | let pending = ""; |
| 207 | const forwarded = new Set<string>(); |
| 208 | |
| 209 | const forwardLine = (line: string) => { |
| 210 | const message = formatUserFacingCliStderrLine(line); |
| 211 | if (!message || forwarded.has(message)) return; |
| 212 | forwarded.add(message); |
| 213 | log(client, "info", `[Plannotator] ${message}`); |
| 214 | }; |
| 215 | |
| 216 | return { |
| 217 | push(chunk: string) { |
| 218 | pending += chunk; |
| 219 | const lines = pending.split(/\r?\n/); |
| 220 | pending = lines.pop() ?? ""; |
| 221 | for (const line of lines) forwardLine(line); |
| 222 | }, |
| 223 | flush() { |
| 224 | if (!pending) return; |
| 225 | forwardLine(pending); |
| 226 | pending = ""; |
| 227 | }, |
| 228 | }; |
| 229 | } |
| 230 | |
| 231 | function logReadyFile(client: OpenCodeClient, readyFile: string, readyLabel: string, loggedUrls: Set<string>): void { |
| 232 | if (!existsSync(readyFile)) return; |