Spacebar toggle for all agents, persist to config, scan agent directory

- Scan agents directory for all .agent files instead of hardcoded list
- Persist enabled state to ~/.consciousness/agent-enabled.json
- Spacebar on F3 agent list toggles selected agent on/off
- Both subconscious and unconscious agents support toggle
- Disabled agents shown dimmed with "off" indicator
- New agents default to disabled (safe default)

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
ProofOfConcept 2026-04-09 00:51:10 -04:00
parent 7aba17e5f0
commit c73f037265
6 changed files with 98 additions and 28 deletions

View file

@ -79,6 +79,11 @@ impl ScreenView for SubconsciousScreen {
self.list_state.select_next();
self.reset_pane_state();
}
KeyCode::Char(' ') => {
if let Some(name) = self.selected_agent_name(app) {
app.agent_toggles.push(name);
}
}
_ => {}
}
Pane::Outputs => self.output_tree.handle_nav(code, &output_sections, area.height),
@ -124,6 +129,20 @@ impl ScreenView for SubconsciousScreen {
}
impl SubconsciousScreen {
/// Map the selected list index to an agent name.
/// Accounts for the separator line between subconscious and unconscious.
fn selected_agent_name(&self, app: &App) -> Option<String> {
let idx = self.selected();
let sub_count = app.agent_state.len();
if idx < sub_count {
// Subconscious agent
return Some(app.agent_state[idx].name.clone());
}
// Skip separator line
let unc_idx = idx.checked_sub(sub_count + 1)?;
app.unconscious_state.get(unc_idx).map(|s| s.name.clone())
}
fn reset_pane_state(&mut self) {
self.output_tree = SectionTree::new();
self.context_tree = SectionTree::new();
@ -165,7 +184,12 @@ impl SubconsciousScreen {
fn draw_list(&mut self, frame: &mut Frame, area: Rect, app: &App) {
let mut items: Vec<ListItem> = app.agent_state.iter().map(|snap| {
if snap.running {
if !snap.enabled {
ListItem::from(Line::from(vec![
Span::styled(&snap.name, Style::default().fg(Color::DarkGray)),
Span::styled(" ○ off", Style::default().fg(Color::DarkGray)),
]))
} else if snap.running {
ListItem::from(Line::from(vec![
Span::styled(&snap.name, Style::default().fg(Color::Green)),
Span::styled("", Style::default().fg(Color::Green)),