diff --git a/frontend/packages/dashboard/src/tabs.js b/frontend/packages/dashboard/src/tabs.js index a1ecf14f..44f2f7d2 100644 --- a/frontend/packages/dashboard/src/tabs.js +++ b/frontend/packages/dashboard/src/tabs.js @@ -1196,7 +1196,7 @@ window.marked = marked; function renderCapabilities(root, data) { root.replaceChildren(); - const { caps, assignments } = data; + const { caps, descriptions = {}, assignments } = data; if (!caps || !caps.length) { root.append(el('p', { class: 'meta' }, '(no capabilities defined)')); return; @@ -1221,7 +1221,7 @@ window.marked = marked; const hrow = el('tr'); hrow.append(el('th', { class: 'cap-agent-col' }, 'agent')); for (const c of caps) { - hrow.append(el('th', { class: 'cap-col', title: c }, c)); + hrow.append(el('th', { class: 'cap-col', title: descriptions[c] || c }, c)); } hrow.append(el('th', { class: 'cap-save-col' }, '')); thead.append(hrow); @@ -1311,7 +1311,7 @@ window.marked = marked; function renderToolGroups(root, data) { root.replaceChildren(); - const { groups, assignments } = data; + const { groups, descriptions = {}, assignments } = data; if (!groups || !groups.length) { root.append(el('p', { class: 'meta' }, '(no tool groups defined)')); return; @@ -1337,7 +1337,7 @@ window.marked = marked; const hrow = el('tr'); hrow.append(el('th', { class: 'tg-agent-col' }, 'agent')); for (const g of groups) { - hrow.append(el('th', { class: 'tg-group-col', title: g }, g)); + hrow.append(el('th', { class: 'tg-group-col', title: descriptions[g] || g }, g)); } hrow.append(el('th', { class: 'tg-save-col' }, '')); thead.append(hrow); diff --git a/hive-c0re/src/dashboard.rs b/hive-c0re/src/dashboard.rs index 87519331..53ff1173 100644 --- a/hive-c0re/src/dashboard.rs +++ b/hive-c0re/src/dashboard.rs @@ -2512,6 +2512,8 @@ struct ToolGroupsSnapshot { /// Ordered list of all known tool-group names. Drives the column /// headers in the capabilities table — the UI does not hard-code them. groups: Vec<&'static str>, + /// Short description for each group name. Keys match `groups` entries. + descriptions: std::collections::BTreeMap<&'static str, &'static str>, /// Per-agent assignment map. Absent agents use the role default /// (agents: messaging+meta+inbox+execution; manager: all groups). assignments: std::collections::BTreeMap>, @@ -2522,9 +2524,14 @@ async fn get_tool_groups(State(_state): State) -> axum::Json, + /// Short description for each capability name. Keys match `caps` entries. + descriptions: std::collections::BTreeMap<&'static str, &'static str>, /// Per-agent capability grant map. Absent agents have no extra caps. assignments: std::collections::BTreeMap>, } async fn get_capabilities(State(_state): State) -> axum::Json { - let caps = hive_sh4re::Capability::ALL.iter().map(|c| c.as_str()).collect(); + use hive_sh4re::Capability; + let caps = Capability::ALL.iter().map(|c| c.as_str()).collect(); + let descriptions = Capability::ALL + .iter() + .map(|c| (c.as_str(), c.description())) + .collect(); let assignments = crate::capabilities::read(); - axum::Json(CapabilitiesSnapshot { caps, assignments }) + axum::Json(CapabilitiesSnapshot { + caps, + descriptions, + assignments, + }) } #[derive(Deserialize)] diff --git a/hive-sh4re/src/lib.rs b/hive-sh4re/src/lib.rs index 87ab7caf..85041045 100644 --- a/hive-sh4re/src/lib.rs +++ b/hive-sh4re/src/lib.rs @@ -876,6 +876,30 @@ impl ToolGroup { Self::WebTools => "web_tools", } } + + /// Short human-readable description suitable for a tooltip or help text. + #[must_use] + pub fn description(self) -> &'static str { + match self { + Self::Messaging => "send, recv, ask, answer — core agent communication", + Self::Meta => "set_status, get_agent_meta — identity and status", + Self::Inbox => { + "get_loose_ends, cancel_loose_end, remind, request_next_turn — self-scheduling" + } + Self::Lifecycle => "kill, start, restart, update — container lifecycle (privileged)", + Self::Approvals => { + "request_init_config, request_apply_commit, request_update_meta_inputs — config change flow (privileged)" + } + Self::Scheduling => { + "request_schedule_prompt and related — operator-visible scheduled prompts (privileged)" + } + Self::Diagnostics => "get_logs — read host journal and build logs (privileged)", + Self::Execution => "bash_run, bash_status — run shell commands in the container", + Self::WebTools => { + "WebFetch, WebSearch — Claude built-in web egress; not MCP tools" + } + } + } } /// Per-agent capability grants. Stored in `meta/capabilities.json` @@ -962,6 +986,20 @@ impl Capability { Self::QueryAgentState => "query_agent_state", } } + + /// Short human-readable description suitable for a tooltip or help text. + #[must_use] + pub fn description(self) -> &'static str { + match self { + Self::ManageRootAgent => { + "lifecycle-manage the root/manager agent on hive crash recovery" + } + Self::ReadHostJournal => "read host journald via get_host_journal MCP tool", + Self::QueryAgentState => { + "query non-child agents' loose ends and reminder state via get_loose_ends" + } + } + } } /// Schedule row shape on the wire — mirror of