#!/bin/sh # SeibertGPT – Einrichtung für OpenWork (macOS). Quelle: https://gpt.seibert.ai/clients # Der Key wird nur lokal abgefragt und landet im Schlüsselbund, nie in einer Datei; gesendet wird er nur an das Gateway. set -eu say() { printf '%s\n' "$*"; } our_config() { cat <<'SGPT_CONFIG_EOF' { "$schema": "https://opencode.ai/config.json", "model": "seibertgpt/deepseek-v41-flash-fast", "small_model": "seibertgpt/deepseek-v41-flash-fast", "provider": { "seibertgpt": { "npm": "@ai-sdk/openai-compatible", "name": "SeibertGPT", "options": { "baseURL": "https://api.gpt.seibert.ai/v1", "apiKey": "{env:SEIBERTGPT_API_KEY}" }, "models": { "deepseek-v41-flash": { "name": "Standard mit Denkmodus", "tool_call": true, "attachment": true, "limit": { "context": 1000000, "output": 32000 } }, "deepseek-v41-flash-fast": { "name": "ohne Denkmodus – schnell", "tool_call": true, "attachment": true, "limit": { "context": 1000000, "output": 32000 } }, "deepseek-v41-flash-low": { "name": "Denkaufwand niedrig", "tool_call": true, "attachment": true, "limit": { "context": 1000000, "output": 32000 } }, "deepseek-v41-flash-high": { "name": "Denkaufwand hoch", "tool_call": true, "attachment": true, "limit": { "context": 1000000, "output": 32000 } }, "deepseek-v41-flash-max": { "name": "Denkaufwand maximal", "tool_call": true, "attachment": true, "limit": { "context": 1000000, "output": 32000 } } } } } } SGPT_CONFIG_EOF } merge_jxa() { cat <<'SGPT_JXA_EOF' ObjC.import("Foundation"); function run(argv) { var target = argv[0], ours = JSON.parse(argv[1]), merge = JSON.parse(argv[2]), absent = JSON.parse(argv[3]); var fm = $.NSFileManager.defaultManager; function write(path, obj) { var ok = $(JSON.stringify(obj, null, 2) + "\n").writeToFileAtomicallyEncodingError(path, true, $.NSUTF8StringEncoding, null); if (!ok) throw new Error("Konnte " + path + " nicht schreiben."); } function get(o, p) { for (var i = 0; i < p.length; i++) { if (o == null || typeof o !== "object") return undefined; o = o[p[i]]; } return o; } function set(o, p, v) { for (var i = 0; i < p.length - 1; i++) { if (typeof o[p[i]] !== "object" || o[p[i]] === null) o[p[i]] = {}; o = o[p[i]]; } o[p[p.length - 1]] = v; } if (!fm.fileExistsAtPath(target)) { write(target, ours); return "created"; } var text = null; try { text = $.NSString.stringWithContentsOfFileEncodingError(target, $.NSUTF8StringEncoding, null).js; } catch (e) { text = null; } if (typeof text === "string" && text.trim() === "") { write(target, ours); return "created"; } var existing; try { existing = JSON.parse(text); } catch (e) { existing = null; } if (existing === null || typeof existing !== "object" || Array.isArray(existing)) { write(target.replace(/\.jsonc?$/, "") + ".seibertgpt.json", ours); return "sidecar"; } var stamp = new Date().toISOString().replace(/[-:]/g, "").replace("T", "-").slice(0, 15); var backup = target + ".bak-" + stamp; if (!fm.copyItemAtPathToPathError(target, backup, null) && !fm.fileExistsAtPath(backup)) { throw new Error("Konnte keine Sicherung von " + target + " anlegen."); } merge.forEach(function (p) { var v = get(ours, p); if (v !== undefined) set(existing, p, v); }); absent.forEach(function (p) { var v = get(ours, p); if (v !== undefined && get(existing, p) === undefined) set(existing, p, v); }); write(target, existing); return "merged"; } SGPT_JXA_EOF } main() { say 'SeibertGPT: Einrichtung für OpenWork' if ! { true; }; then say 'OpenWork scheint nicht installiert zu sein. Download: https://openworklabs.com/download' printf '%s' 'Trotzdem fortfahren? (j/N) '; read -r ans