diff --git a/diagnostic/index.html b/diagnostic/index.html index 428aaec..4e71bda 100644 --- a/diagnostic/index.html +++ b/diagnostic/index.html @@ -602,6 +602,24 @@ selbst (Skills + skill_create Meta-Tool). Es gibt keine granulare Permission-Maske, Brain weiss zur Laufzeit welche Tools es hat. --> + +
+~/.claude/settings.json —
- greift bei jeder neuen Anfrage, kein Neustart nötig.
+ Anfrage Daten verschickt.
+ ~/.claude/settings.json, und die Claude-CLI liest
+ die Datei bei jedem Aufruf neu. Speichern genügt — die nächste Anfrage
+ nutzt die neue Einstellung. Nur ein gerade laufender Turn arbeitet noch
+ mit der alten, weil sein Prozess schon gestartet ist.
' + escapeHtml(s.file) + ' — geändert '
+ + fmt(s.srcAt) + ', eingespielt ' + fmt(s.activeAt)).join('--build reicht nicht:';
+ }
+ }
+ return;
+ }
if (msg.type === 'privacy_flags') { renderPrivacyFlags(msg); return; }
if (msg.type === 'privacy_flags_saved') {
const st = document.getElementById('privacy-flags-status');
@@ -4754,6 +4797,7 @@
refreshVoiceIdStatus();
send({ action: 'get_attachment_limit' });
send({ action: 'get_privacy_flags' });
+ send({ action: 'check_proxy_patches' });
} else if (tab === 'brain') {
loadBrainStatus();
loadBrainMemoryList();
diff --git a/diagnostic/server.js b/diagnostic/server.js
index 221d900..1dc00fc 100644
--- a/diagnostic/server.js
+++ b/diagnostic/server.js
@@ -3217,6 +3217,8 @@ wss.on("connection", (ws) => {
handleSetModel(ws, msg.model);
} else if (msg.action === "test_model") {
handleTestModel(ws, msg.model);
+ } else if (msg.action === "check_proxy_patches") {
+ handleCheckProxyPatches(ws);
} else if (msg.action === "get_privacy_flags") {
handleGetPrivacyFlags(ws);
} else if (msg.action === "set_privacy_flags") {
@@ -3647,6 +3649,50 @@ function handleSetModel(clientWs, model) {
return;
}
+// ── Laufen im Proxy die aktuellen Patches? ──────────────────────────
+//
+// Der Proxy kopiert proxy-patches/*.js beim START ueber den npm-Code (siehe
+// docker-compose.yml, command:). Wer nach einem git pull nur `restart` macht —
+// oder neu startet, BEVOR der Pull durch ist — laeuft still mit der alten
+// Fassung weiter. Das faellt sonst nirgends auf: der Container ist "Up", die
+// Oberflaeche sieht normal aus, nur wirkt die Aenderung nicht.
+//
+// Darum: Zeitstempel der Quelldateien gegen die eingespielten vergleichen.
+const PROXY_PATCH_MAP = [
+ ["routes.js", "server/routes.js"],
+ ["manager.js", "subprocess/manager.js"],
+ ["openai-to-cli.js", "adapter/openai-to-cli.js"],
+ ["cli-to-openai.js", "adapter/cli-to-openai.js"],
+];
+
+async function handleCheckProxyPatches(clientWs) {
+ try {
+ const dist = "/usr/local/lib/node_modules/claude-max-api-proxy/dist";
+ const pairs = PROXY_PATCH_MAP
+ .map(([src, dst]) => `/proxy-patches/${src} ${dist}/${dst}`).join(" ");
+ // %Y = mtime als Unix-Zeit, %n = Dateiname
+ const out = await dockerExec("aria-proxy", `stat -c '%Y %n' ${pairs} 2>/dev/null || true`);
+ const mtime = {};
+ for (const line of String(out || "").split("\n")) {
+ const m = line.trim().match(/^(\d+)\s+(.+)$/);
+ if (m) mtime[m[2]] = parseInt(m[1], 10);
+ }
+ const stale = [];
+ for (const [src, dst] of PROXY_PATCH_MAP) {
+ const a = mtime[`/proxy-patches/${src}`];
+ const b = mtime[`${dist}/${dst}`];
+ if (a == null || b == null) continue;
+ // Toleranz 5s: Quelle und Kopie entstehen beim Start kurz nacheinander.
+ if (a > b + 5) stale.push({ file: src, srcAt: a * 1000, activeAt: b * 1000 });
+ }
+ clientWs.send(JSON.stringify({ type: "proxy_patch_state", stale }));
+ } catch (err) {
+ // Kein Alarm bei einem Pruef-Fehler — sonst steht da eine Warnung, die
+ // gar nichts ueber die Patches aussagt.
+ clientWs.send(JSON.stringify({ type: "proxy_patch_state", stale: [], error: String((err && err.message) || err) }));
+ }
+}
+
// ── Einstellungen: Datenschutz-Schalter von Claude Code ─────────────
//
// Drei Kanaele, ueber die Claude Code von sich aus Daten an Anthropic bzw. an