Panel: Entwürfe archivieren, Titel aus Überschrift, Titel-Edit
- Archiv pro Projekt: Panel-Button „Archivieren" und MCP-Tool archive_panel legen den Entwurf als <YYYY-MM-DD_HHMM>-<slug>.md mit Frontmatter im Archiv-Ordner ab. Ordner in ai-control.json (archiveDir) + als additionalDirectories/Edit in .claude/settings.json (scanbar). Kein Ordner: Panel öffnet Ordner-Dialog, Zuruf nutzt Argument dir. - Panel-Titel zeigt die erste Überschrift des Entwurfs (Inline-Markdown gestrippt), Fallback „Entwurf"; Bleistift-Button macht ihn editierbar, schreibt die Überschrift via panel_set zurück. - Panel-Kopf zweizeilig: Titel + Edit oben, Aktionen rechtsbündig darunter. - AI_CONTROL_PROJECT als PTY-Env für den MCP-Server.
This commit is contained in:
+66
-22
@@ -58,25 +58,48 @@ fn handle(method: &str, req: &Value) -> Option<Value> {
|
||||
}))
|
||||
}
|
||||
"tools/list" => Some(json!({
|
||||
"tools": [{
|
||||
"name": "write_panel",
|
||||
"description":
|
||||
"Legt einen längeren Entwurf (ADR, E-Mail, Dokument, Spezifikation, \
|
||||
Commit-Message, Textbaustein) im ai-control-Panel neben dem Terminal \
|
||||
ab, wo er mit der Maus selektierbar und über einen Button kopierbar \
|
||||
ist. Statt den Text zusätzlich als Fließtext auszugeben, dieses Tool \
|
||||
aufrufen und im Chat nur kurz bestätigen.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string",
|
||||
"description": "Vollständiger Entwurf als Markdown-Rohtext.",
|
||||
}
|
||||
"tools": [
|
||||
{
|
||||
"name": "write_panel",
|
||||
"description":
|
||||
"Legt einen längeren Entwurf (ADR, E-Mail, Dokument, Spezifikation, \
|
||||
Commit-Message, Textbaustein) im ai-control-Panel neben dem Terminal \
|
||||
ab, wo er mit der Maus selektierbar und über einen Button kopierbar \
|
||||
ist. Statt den Text zusätzlich als Fließtext auszugeben, dieses Tool \
|
||||
aufrufen und im Chat nur kurz bestätigen.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string",
|
||||
"description": "Vollständiger Entwurf als Markdown-Rohtext.",
|
||||
}
|
||||
},
|
||||
"required": ["text"],
|
||||
},
|
||||
"required": ["text"],
|
||||
},
|
||||
}],
|
||||
{
|
||||
"name": "archive_panel",
|
||||
"description":
|
||||
"Archiviert den aktuell im Panel liegenden Entwurf dauerhaft als \
|
||||
Markdown-Datei im Archiv-Ordner des Projekts. Auf Wunsch nutzen \
|
||||
(Nutzer sagt etwa „archiviere das“). Ist kein Ordner konfiguriert, \
|
||||
den Zielpfad im \
|
||||
Argument `dir` mitgeben (der Nutzer nennt ihn); ohne `dir` und ohne \
|
||||
konfigurierten Ordner meldet das Tool das zurück.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dir": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"Optionaler Archiv-Ordner. Wird gesetzt und für künftige \
|
||||
Archivierungen gemerkt.",
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
})),
|
||||
"tools/call" => Some(call_tool(req)),
|
||||
"ping" => Some(json!({})),
|
||||
@@ -85,13 +108,17 @@ fn handle(method: &str, req: &Value) -> Option<Value> {
|
||||
}
|
||||
|
||||
fn call_tool(req: &Value) -> Value {
|
||||
let name = req["params"]["name"].as_str().unwrap_or("");
|
||||
if name != "write_panel" {
|
||||
return json!({
|
||||
"content": [{ "type": "text", "text": format!("Unbekanntes Tool: {name}") }],
|
||||
match req["params"]["name"].as_str().unwrap_or("") {
|
||||
"write_panel" => call_write(req),
|
||||
"archive_panel" => call_archive(req),
|
||||
other => json!({
|
||||
"content": [{ "type": "text", "text": format!("Unbekanntes Tool: {other}") }],
|
||||
"isError": true,
|
||||
});
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn call_write(req: &Value) -> Value {
|
||||
let text = req["params"]["arguments"]["text"].as_str().unwrap_or("");
|
||||
match std::env::var("AI_CONTROL_PANEL") {
|
||||
Ok(path) => match std::fs::write(&path, text) {
|
||||
@@ -107,3 +134,20 @@ fn call_tool(req: &Value) -> Value {
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn call_archive(req: &Value) -> Value {
|
||||
let project = std::env::var("AI_CONTROL_PROJECT").unwrap_or_default();
|
||||
let dir = req["params"]["arguments"]["dir"].as_str();
|
||||
match crate::archive_panel_content(&project, dir) {
|
||||
Ok(path) => json!({
|
||||
"content": [{ "type": "text", "text": format!("Archiviert: {}", path.display()) }],
|
||||
}),
|
||||
Err(e) => json!({
|
||||
"content": [{
|
||||
"type": "text",
|
||||
"text": format!("Nicht archiviert: {e}. Zielordner im Argument `dir` angeben oder im Panel wählen."),
|
||||
}],
|
||||
"isError": true,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user