remove granular tool permissions, add architecture docs
Granulare Tool-Permissions in der Diagnostic UI entfernt — sie hatten keinen Effekt weil Claude Code mit --dangerously-skip-permissions läuft (Alles-oder-Nichts). Ersetzt durch statischen Hinweis-Toggle. Neue Doku in aria-data/docs/tool-permissions.md: alle Erkenntnisse zu OpenClaw Tool-Permissions, 17 gescheiterte Versuche, finale Lösung (CLAUDE_CODE_BUBBLEWRAP=1). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+19
-152
@@ -311,20 +311,23 @@
|
||||
|
||||
<!-- Tool-Berechtigungen -->
|
||||
<div class="settings-section">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;">
|
||||
<h2>Tool-Berechtigungen</h2>
|
||||
<div style="display:flex;gap:6px;">
|
||||
<button class="btn secondary" onclick="loadPermissions()" style="padding:4px 12px;font-size:11px;">Laden</button>
|
||||
<button class="btn" onclick="savePermissions()" id="btn-save-perms" style="padding:4px 12px;font-size:11px;" disabled>Speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Tool-Berechtigungen</h2>
|
||||
<div style="font-size:11px;color:#8888AA;margin-bottom:12px;">
|
||||
Hier kannst du festlegen, welche Tools ARIA benutzen darf. Aenderungen werden in der OpenClaw-Konfiguration gespeichert.
|
||||
Claude Code laeuft mit <code>--dangerously-skip-permissions</code> im Proxy — Alles oder Nichts.
|
||||
Granulare Tool-Kontrolle ist in dieser Architektur nicht moeglich.
|
||||
</div>
|
||||
<div id="perms-status" style="font-size:11px;margin-bottom:8px;display:none;"></div>
|
||||
<div id="perms-grid" class="perm-grid">
|
||||
<!-- Wird dynamisch gefuellt -->
|
||||
<div style="color:#555570;padding:12px;">Klicke "Laden" um die aktuellen Berechtigungen abzurufen</div>
|
||||
<div class="card" style="max-width:500px;">
|
||||
<div class="perm-item" style="border:none;padding:0;">
|
||||
<div class="perm-info">
|
||||
<div class="perm-name">Claude darf alle Tools benutzen</div>
|
||||
<div class="perm-desc">WebFetch, Bash, Read/Write/Edit, WebSearch, Agent, etc.</div>
|
||||
</div>
|
||||
<label class="toggle"><input type="checkbox" checked disabled><span class="slider"></span></label>
|
||||
</div>
|
||||
<div style="font-size:10px;color:#555570;margin-top:8px;">
|
||||
Deaktivieren = <code>--dangerously-skip-permissions</code> aus docker-compose.yml entfernen.
|
||||
Dann kann ARIA keine Tools mehr benutzen (auch kein WebFetch fuer Wetter etc.).
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -576,25 +579,7 @@
|
||||
}
|
||||
if (msg.type === 'brain_list') { renderBrainList(msg); return; }
|
||||
if (msg.type === 'brain_content') { renderBrainContent(msg); return; }
|
||||
// Settings
|
||||
if (msg.type === 'permissions_list') { renderPermissions(msg); return; }
|
||||
if (msg.type === 'permissions_saved') {
|
||||
const s = document.getElementById('perms-status');
|
||||
s.style.display = 'block';
|
||||
if (msg.ok) {
|
||||
// Nachricht merken und nach Reload wieder anzeigen
|
||||
permsSavedMsg = (msg.info || 'Berechtigungen gespeichert!')
|
||||
+ '<br><span style="color:#FFD60A;font-size:10px;">Session muss neu gestartet werden damit Aenderungen wirksam werden.</span>'
|
||||
+ ' <button class="btn secondary" onclick="restartAriaSession()" style="padding:2px 8px;font-size:10px;margin-left:4px;">Session neu starten</button>';
|
||||
s.style.color = '#34C759';
|
||||
s.innerHTML = permsSavedMsg;
|
||||
loadPermissions();
|
||||
} else {
|
||||
s.style.color = '#FF6B6B';
|
||||
s.textContent = 'Fehler: ' + (msg.error || '?');
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Settings (permissions_list/permissions_saved entfernt — Alles-oder-Nichts via --dangerously-skip-permissions)
|
||||
if (msg.type === 'session_restarted') {
|
||||
const s = document.getElementById('perms-status');
|
||||
s.style.display = 'block';
|
||||
@@ -1206,127 +1191,9 @@
|
||||
}
|
||||
|
||||
// ── Einstellungen: Tool-Berechtigungen ──────────────────
|
||||
|
||||
const TOOL_DEFS = [
|
||||
{ id: 'Bash', name: 'Bash', desc: 'Shell-Befehle ausfuehren', cat: 'System' },
|
||||
{ id: 'Read', name: 'Read', desc: 'Dateien lesen', cat: 'Dateien' },
|
||||
{ id: 'Write', name: 'Write', desc: 'Dateien schreiben/erstellen', cat: 'Dateien' },
|
||||
{ id: 'Edit', name: 'Edit', desc: 'Dateien bearbeiten (Diff)', cat: 'Dateien' },
|
||||
{ id: 'Grep', name: 'Grep', desc: 'In Dateien suchen', cat: 'Dateien' },
|
||||
{ id: 'Glob', name: 'Glob', desc: 'Dateien nach Muster finden', cat: 'Dateien' },
|
||||
{ id: 'WebFetch', name: 'WebFetch', desc: 'Webseiten abrufen (HTTP)', cat: 'Netzwerk' },
|
||||
{ id: 'WebSearch', name: 'WebSearch', desc: 'Web-Suche durchfuehren', cat: 'Netzwerk' },
|
||||
{ id: 'NotebookEdit', name: 'NotebookEdit', desc: 'Jupyter Notebooks bearbeiten', cat: 'Dateien' },
|
||||
{ id: 'TodoWrite', name: 'TodoWrite', desc: 'Aufgaben/Todos verwalten', cat: 'Organisation' },
|
||||
{ id: 'Agent', name: 'Agent', desc: 'Sub-Agenten starten', cat: 'System' },
|
||||
{ id: 'AskUserQuestion', name: 'AskUserQuestion', desc: 'Rueckfragen stellen', cat: 'Kommunikation' },
|
||||
];
|
||||
|
||||
let permState = {}; // { toolId: true/false }
|
||||
let permsDirty = false;
|
||||
let permsSavedMsg = ''; // Gespeicherte Erfolgsmeldung (ueberlebt renderPermissions)
|
||||
|
||||
function loadPermissions() {
|
||||
const grid = document.getElementById('perms-grid');
|
||||
grid.innerHTML = '<div style="color:#8888AA;padding:12px;">Lade Berechtigungen...</div>';
|
||||
send({ action: 'list_permissions' });
|
||||
}
|
||||
|
||||
function renderPermissions(data) {
|
||||
const grid = document.getElementById('perms-grid');
|
||||
const status = document.getElementById('perms-status');
|
||||
|
||||
if (data.error) {
|
||||
status.style.display = 'block';
|
||||
status.style.color = '#FF6B6B';
|
||||
status.textContent = 'Fehler: ' + data.error;
|
||||
} else if (data.info) {
|
||||
status.style.display = 'block';
|
||||
status.style.color = '#8888AA';
|
||||
status.textContent = data.info;
|
||||
} else {
|
||||
status.style.display = 'none';
|
||||
}
|
||||
|
||||
// Merge: Server-Daten als Basis
|
||||
permState = {};
|
||||
const serverPerms = data.permissions || {};
|
||||
const hasExplicitList = Array.isArray(data.allowedTools) && data.allowedTools.length > 0;
|
||||
for (const tool of TOOL_DEFS) {
|
||||
if (hasExplicitList) {
|
||||
permState[tool.id] = data.allowedTools.includes(tool.id);
|
||||
} else if (serverPerms[tool.id] !== undefined) {
|
||||
permState[tool.id] = !!serverPerms[tool.id];
|
||||
} else {
|
||||
permState[tool.id] = true; // Default: an
|
||||
}
|
||||
}
|
||||
// Hinweis wenn kein expliziter Filter gesetzt ist
|
||||
if (!hasExplicitList && !Object.keys(serverPerms).length) {
|
||||
status.style.display = 'block';
|
||||
status.style.color = '#FFD60A';
|
||||
status.textContent = (data.info || '') + ' — Kein Tool-Filter gesetzt: alle Tools sind erlaubt. Speichern um explizit zu setzen.';
|
||||
}
|
||||
// Debug-Info anzeigen (Settings-Pfade)
|
||||
if (data.debug) {
|
||||
const dbg = document.createElement('div');
|
||||
dbg.style.cssText = 'font-size:9px;color:#555570;margin-top:6px;font-family:monospace;white-space:pre-line;';
|
||||
dbg.textContent = (data.debug.allPaths || '?') + '\nKeys: ' + (data.debug.rawKeys || 'keine');
|
||||
if (hasExplicitList) dbg.textContent += '\nallowedTools: [' + data.allowedTools.join(', ') + ']';
|
||||
status.appendChild(dbg);
|
||||
}
|
||||
|
||||
// Gruppieren nach Kategorie
|
||||
const cats = {};
|
||||
for (const tool of TOOL_DEFS) {
|
||||
if (!cats[tool.cat]) cats[tool.cat] = [];
|
||||
cats[tool.cat].push(tool);
|
||||
}
|
||||
|
||||
let html = '';
|
||||
for (const [cat, tools] of Object.entries(cats)) {
|
||||
html += `<div style="grid-column:1/-1;font-size:11px;color:#0096FF;margin-top:8px;text-transform:uppercase;letter-spacing:1px;">${escapeHtml(cat)}</div>`;
|
||||
for (const tool of tools) {
|
||||
const checked = permState[tool.id] ? 'checked' : '';
|
||||
html += `<div class="perm-item">`
|
||||
+ `<div class="perm-info"><div class="perm-name">${escapeHtml(tool.name)}</div><div class="perm-desc">${escapeHtml(tool.desc)}</div></div>`
|
||||
+ `<label class="toggle"><input type="checkbox" ${checked} onchange="togglePerm('${tool.id}', this.checked)"><span class="slider"></span></label>`
|
||||
+ `</div>`;
|
||||
}
|
||||
}
|
||||
grid.innerHTML = html;
|
||||
permsDirty = false;
|
||||
document.getElementById('btn-save-perms').disabled = true;
|
||||
|
||||
// Gespeicherte Erfolgsmeldung nach Reload wieder anzeigen
|
||||
if (permsSavedMsg) {
|
||||
status.style.display = 'block';
|
||||
status.style.color = '#34C759';
|
||||
status.innerHTML = permsSavedMsg;
|
||||
permsSavedMsg = ''; // Nur einmal anzeigen
|
||||
}
|
||||
}
|
||||
|
||||
function togglePerm(toolId, enabled) {
|
||||
permState[toolId] = enabled;
|
||||
permsDirty = true;
|
||||
document.getElementById('btn-save-perms').disabled = false;
|
||||
}
|
||||
|
||||
function savePermissions() {
|
||||
if (!permsDirty) return;
|
||||
const allowedTools = Object.entries(permState).filter(([_, v]) => v).map(([k]) => k);
|
||||
send({ action: 'save_permissions', allowedTools });
|
||||
document.getElementById('btn-save-perms').disabled = true;
|
||||
}
|
||||
|
||||
function restartAriaSession() {
|
||||
if (!confirm('Aktive Session neu starten? Der Kontext bleibt erhalten, Permissions werden neu geladen.')) return;
|
||||
send({ action: 'restart_session' });
|
||||
const s = document.getElementById('perms-status');
|
||||
s.style.color = '#FFD60A';
|
||||
s.textContent = 'Session wird neu gestartet...';
|
||||
}
|
||||
// Granulare Permissions entfernt — Claude Code laeuft mit
|
||||
// --dangerously-skip-permissions (Alles oder Nichts).
|
||||
// Siehe docker-compose.yml: CLAUDE_CODE_BUBBLEWRAP=1
|
||||
|
||||
// ── Einstellungen: Model ────────────────────────────────
|
||||
|
||||
|
||||
Reference in New Issue
Block a user