// Doua completari pentru OpenCode: // /think -- porneste sau opreste gandirea modelului, fara repornire de server // /copy -- pune ultimul raspuns in clipboard-ul masinii unde ruleaza OpenCode // // Starea gandirii sta intr-un fisier, nu in memorie, ca sa supravietuiasca // repornirii sesiunii si ca sa poata fi citita si din afara. import fs from "fs"; import os from "os"; import path from "path"; const STARE = path.join(os.homedir(), ".config", "opencode", "stare-think.json"); function gandire() { try { return JSON.parse(fs.readFileSync(STARE, "utf8")).thinking === true; } catch { return false; } } function scrieGandire(v) { fs.mkdirSync(path.dirname(STARE), { recursive: true }); fs.writeFileSync(STARE, JSON.stringify({ thinking: v }, null, 2) + "\n"); } // Reatribuirea lui output.parts nu se vede intotdeauna in gazda; modificam vectorul pe loc. function pune(output, text) { if (!Array.isArray(output.parts)) output.parts = []; output.parts.length = 0; output.parts.push({ type: "text", text }); } export const Extras = async ({ client, $ }) => { return { "command.execute.before": async (input, output) => { if (input.command === "think") { const a = String(input.arguments || "").trim().toLowerCase(); const nou = ["on", "pornit", "da", "1", "true"].includes(a) ? true : ["off", "oprit", "nu", "0", "false"].includes(a) ? false : !gandire(); scrieGandire(nou); pune(output, `Raspunde cu exact o linie, fara nimic altceva: Gandirea e acum ${nou ? "PORNITA" : "OPRITA"}.`); return; } if (input.command === "copy") { let text = ""; try { const r = await client.session.messages({ path: { id: input.sessionID } }); const msgs = r.data ?? r ?? []; for (let i = msgs.length - 1; i >= 0; i--) { const m = msgs[i]; const rol = m.info?.role ?? m.role; if (rol !== "assistant") continue; const parti = m.parts ?? []; text = parti.filter((p) => p.type === "text").map((p) => p.text).join("\n").trim(); if (text) break; } } catch (e) { text = ""; } if (!text) { pune(output, "Raspunde cu exact o linie, fara nimic altceva: Nu am gasit niciun raspuns de copiat."); return; } // clipboard-ul difera de la sistem la sistem; incercam pe rand ce exista const candidati = process.platform === "darwin" ? [["pbcopy"]] : process.platform === "win32" // clip.exe e in orice Windows; Set-Clipboard e rezerva daca lipseste. // Nu folosim printf pe Windows: nu exista, nici ca program, nici ca builtin Bun. ? [["clip"], ["powershell", "-NoProfile", "-Command", "$input | Set-Clipboard"]] : [["wl-copy"], ["xclip", "-selection", "clipboard"], ["xsel", "--clipboard", "--input"]]; let copiat = false; for (const cmd of candidati) { // .pipe() nu exista in acest Bun shell; conducta se scrie in sablon const r = process.platform === "win32" // pe Windows dam textul pe stdin dintr-un buffer, fara printf ? await $`${cmd} < ${Buffer.from(text)}`.nothrow() : await $`printf %s ${text} | ${cmd}`.nothrow(); if (r.exitCode === 0) { copiat = true; break; } } if (!copiat) { pune(output, "Raspunde cu exact o linie, fara nimic altceva: Nu am gasit niciun program de clipboard (pbcopy, clip, wl-copy, xclip sau xsel)."); return; } pune(output, `Raspunde cu exact o linie, fara nimic altceva: Am copiat ultimul raspuns in clipboard (${text.length} caractere).`); } }, "chat.params": async (input, output) => { output.options = output.options || {}; output.options.chat_template_kwargs = { enable_thinking: gandire() }; }, }; };