8aa758ae64
- Andockbares Panel im Terminal-Fenster: Markdown-Rendering, Copy-Button, normale Selektion; in eigenes Fenster ablösbar und wieder andockbar (Splitter, panel-detached/panel-attached). - MCP-stdio-Server (app --mcp-panel) mit Tool write_panel; schreibt in die Datei aus AI_CONTROL_PANEL, Watcher zieht sie ins Panel. - Provisionierung je Pool: Server-Registrierung in .claude.json (alwaysLoad), Freigabe mcp__text-panel__write_panel in settings.json, Panel-Skill; bei App-Start (alle Pools) und Pool-Anlage. Alte tee-Freigaben werden entfernt. - Capability deckt panel-*-Fenster ab.
54 lines
1.3 KiB
TypeScript
54 lines
1.3 KiB
TypeScript
import { marked } from "marked";
|
|
|
|
export interface PanelView {
|
|
set(text: string): void;
|
|
raw(): string;
|
|
}
|
|
|
|
/// Verkabelt einen Panel-Inhaltsbereich: MD/Roh-Umschalter und Copy-Button.
|
|
/// Der Rohtext bleibt die Quelle für „Kopieren"; die Ansicht rendert Markdown.
|
|
export function initPanelView(opts: {
|
|
content: HTMLElement;
|
|
copyBtn: HTMLElement;
|
|
modeBtn: HTMLElement;
|
|
}): PanelView {
|
|
let rawText = "";
|
|
let rendered = true;
|
|
|
|
function draw() {
|
|
if (rendered) {
|
|
opts.content.className = "md";
|
|
opts.content.innerHTML = marked.parse(rawText, { async: false });
|
|
} else {
|
|
opts.content.className = "raw";
|
|
opts.content.textContent = rawText;
|
|
}
|
|
opts.modeBtn.textContent = rendered ? "MD" : "Roh";
|
|
}
|
|
|
|
opts.modeBtn.addEventListener("click", () => {
|
|
rendered = !rendered;
|
|
draw();
|
|
});
|
|
|
|
opts.copyBtn.addEventListener("click", async () => {
|
|
await navigator.clipboard.writeText(rawText);
|
|
opts.copyBtn.classList.add("copied");
|
|
const label = opts.copyBtn.textContent;
|
|
opts.copyBtn.textContent = "Kopiert";
|
|
setTimeout(() => {
|
|
opts.copyBtn.classList.remove("copied");
|
|
opts.copyBtn.textContent = label;
|
|
}, 1200);
|
|
});
|
|
|
|
draw();
|
|
return {
|
|
set(text: string) {
|
|
rawText = text;
|
|
draw();
|
|
},
|
|
raw: () => rawText,
|
|
};
|
|
}
|