(sessionId: string, annotation: any)
| 312 | } |
| 313 | |
| 314 | async function queueAnnotationPrompt(sessionId: string, annotation: any): Promise<void> { |
| 315 | if (!pluginClient) { |
| 316 | setLastAnnotationStatus({ ok: false, sessionId, error: "No OpenCode client is available" }); |
| 317 | throw new Error("No OpenCode client is available"); |
| 318 | } |
| 319 | |
| 320 | setLastAnnotationStatus({ |
| 321 | ok: null, |
| 322 | sessionId, |
| 323 | phase: "received", |
| 324 | commentLength: typeof annotation?.comment === "string" ? annotation.comment.length : 0, |
| 325 | }); |
| 326 | |
| 327 | let promptText = buildAnnotationPrompt(annotation); |
| 328 | const screenshot = annotation?.screenshot; |
| 329 | if (screenshot?.dataUrl) { |
| 330 | mkdirSync(ANNOTATION_DIR, { recursive: true }); |
| 331 | const { mime, bytes } = decodeDataUrl(screenshot.dataUrl); |
| 332 | const ext = mime === "image/jpeg" ? "jpg" : mime === "image/webp" ? "webp" : "png"; |
| 333 | const stem = sanitizeFileStem(annotation?.page?.title || annotation?.element?.tag || "annotation"); |
| 334 | const filePath = join(ANNOTATION_DIR, `${Date.now()}-${stem}.${ext}`); |
| 335 | writeFileSync(filePath, bytes); |
| 336 | promptText += `\n\nScreenshot: ${filePath}`; |
| 337 | } |
| 338 | |
| 339 | const promptBody = { parts: [{ type: "text", text: promptText }] }; |
| 340 | |
| 341 | if (typeof pluginClient?.session?.promptAsync === "function") { |
| 342 | const response = await pluginClient.session.promptAsync({ |
| 343 | path: { id: sessionId }, |
| 344 | query: { directory: pluginDirectory }, |
| 345 | body: promptBody, |
| 346 | }); |
| 347 | const data = unwrapClientResult(response, "session prompt"); |
| 348 | if (isExplicitFalse(data)) throw new Error("OpenCode rejected session prompt submission"); |
| 349 | setLastAnnotationStatus({ ok: true, sessionId, transport: "session.promptAsync", response: data ?? null }); |
| 350 | return; |
| 351 | } |
| 352 | |
| 353 | if (typeof pluginClient?.session?.prompt === "function") { |
| 354 | const response = await pluginClient.session.prompt({ |
| 355 | path: { id: sessionId }, |
| 356 | query: { directory: pluginDirectory }, |
| 357 | body: promptBody, |
| 358 | }); |
| 359 | const data = unwrapClientResult(response, "session prompt"); |
| 360 | if (isExplicitFalse(data)) throw new Error("OpenCode rejected session prompt submission"); |
| 361 | setLastAnnotationStatus({ ok: true, sessionId, transport: "session.prompt", response: data ?? null }); |
| 362 | return; |
| 363 | } |
| 364 | |
| 365 | const text = promptText; |
| 366 | |
| 367 | const appended = await pluginClient.tui.appendPrompt({ |
| 368 | query: { directory: pluginDirectory }, |
| 369 | body: { text }, |
| 370 | }); |
| 371 | const appendedData = unwrapClientResult(appended, "tui append prompt"); |
no test coverage detected