fix(#1661): show default-perms agents with effective values in perms tab

This commit is contained in:
damocles 2026-06-14 20:46:18 +02:00 committed by mara
commit 789ecd86f6
6 changed files with 193 additions and 24 deletions

View file

@ -50,17 +50,21 @@ export async function fetchAndRenderCapabilities() {
function renderCapabilities(root, data) {
root.replaceChildren();
const { caps, descriptions = {}, assignments } = data;
const { caps, descriptions = {}, assignments, effective = {} } = data;
if (!caps || !caps.length) {
root.append(el('p', { class: 'meta' }, '(no capabilities defined)'));
return;
}
// Agent names: union of live containers + keys already in assignments.
const agentNames = [...new Set([
...Array.from(containersState.keys()),
...Object.keys(assignments),
])].sort();
// Agent rows: prefer the backend roster (every manageable agent,
// default-perms included). Fall back to the live-container explicit
// union for older payloads that don't carry `agents`.
const agentNames = (data.agents && data.agents.length)
? [...data.agents]
: [...new Set([
...Array.from(containersState.keys()),
...Object.keys(assignments),
])].sort();
if (!agentNames.length) {
root.append(el('p', { class: 'meta' }, '(no agents)'));
@ -83,7 +87,9 @@ function renderCapabilities(root, data) {
const tbody = el('tbody');
for (const name of agentNames) {
const assigned = assignments[name] || [];
// Effective caps (explicit-or-default) drive the checkboxes so
// default-perms agents show their real grants, not blank.
const assigned = effective[name] || assignments[name] || [];
const tr = el('tr', { class: 'cap-row' });
// Agent name cell.
@ -165,18 +171,20 @@ export async function fetchAndRenderToolGroups() {
function renderToolGroups(root, data) {
root.replaceChildren();
const { groups, descriptions = {}, assignments } = data;
const { groups, descriptions = {}, assignments, effective = {} } = data;
if (!groups || !groups.length) {
root.append(el('p', { class: 'meta' }, '(no tool groups defined)'));
return;
}
// Agent names: union of live containers + keys already in assignments,
// sorted alphabetically.
const agentNames = [...new Set([
...Array.from(containersState.keys()),
...Object.keys(assignments),
])].sort();
// Agent rows: prefer the backend roster (default-perms agents included);
// fall back to the live-container explicit union for older payloads.
const agentNames = (data.agents && data.agents.length)
? [...data.agents]
: [...new Set([
...Array.from(containersState.keys()),
...Object.keys(assignments),
])].sort();
if (!agentNames.length) {
root.append(el('p', { class: 'meta' }, '(no agents)'));
@ -199,8 +207,11 @@ function renderToolGroups(root, data) {
const tbody = el('tbody');
for (const name of agentNames) {
// Explicit assignment or empty = using role default.
const assigned = assignments[name] || [];
// Effective groups (explicit-or-role-default) drive the checkboxes so
// a default agent shows its real groups, not blank — and saving keeps
// them instead of silently stripping the defaults. The "(default)"
// badge still keys off explicit-assignment presence.
const assigned = effective[name] || assignments[name] || [];
const hasExplicit = Object.prototype.hasOwnProperty.call(assignments, name);
const tr = el('tr', { class: 'tg-row' });