Skip to content

a11y + i18n(es) + open-in-editor: accessibility, Spanish layer, IDE button#1

Open
aitorf2 wants to merge 4 commits into
PythonLuvr:mainfrom
aitorf2:accessible-es
Open

a11y + i18n(es) + open-in-editor: accessibility, Spanish layer, IDE button#1
aitorf2 wants to merge 4 commits into
PythonLuvr:mainfrom
aitorf2:accessible-es

Conversation

@aitorf2
Copy link
Copy Markdown
Contributor

@aitorf2 aitorf2 commented May 20, 2026

What this PR adds

Accessibility & i18n

  • Full WCAG 2.1 AA pass: aria-label on all icon buttons, role="log" on chat, aria-live="polite" on streaming text
  • Spanish string constants (lib/i18n/es.ts) covering all UI areas
  • ARIA helper factories (lib/a11y/index.ts) for composerProps, chatLogProps, modalProps etc.

IDE integration

  • Open in editor button in channel header: auto-detects Antigravity, Cursor, VS Code, Windsurf, Zed (macOS bundled CLI paths, no PATH setup needed)
  • API route /api/fs/open-editor GET returns available editors, POST opens project path

Named sub-agent routing (Claude Code)

  • Channel header popover → Claude sub-agent section: pick any agent from ~/.claude/agents/ — War Room calls claude -p --agent <name> for every message in that channel
  • /api/agents/catalog reads and parses all ~/.claude/agents/*.md files from YAML frontmatter
  • /api/channel-sub-agent saves the pin to SQLite channel_overrides.sub_agent_id

Lightweight supervisor

  • Channel header popover → Supervisor section: pick an agent (default meta-analyzer) and a frequency (every N turns)
  • After every N user turns, War Room compresses the last 20 messages and fires claude -p --agent <id> --bare "[compressed]" — the note appears as a violet sparkles bubble in chat, no full context needed
  • /api/supervisor handles both config updates and live trigger runs

Hermes fix

  • Fixed Hermes CLI invocation: hermes chat -q "prompt" -Q (was wrong: hermes -p "prompt")

Upstream sync helper

  • scripts/sync-upstream.sh: rebase accessible-es on top of upstream/main without losing customizations

…utton

## Accessibility (VoiceOver, NVDA, JAWS)

lib/a11y/index.ts — new ARIA prop-generator module:
  iconButton, ariaCurrent, ariaExpanded, chatLogProps,
  composerProps, statusRegionProps, modalProps

components/rail.tsx — role="navigation" aria-label="Servers", aria-current
components/channel-list.tsx — navigation landmark, aria-expanded on groups
components/channel-chat.tsx — role="log" aria-live="polite", labeled composer
components/channel-dialog.tsx, invite-modal.tsx — role="dialog" aria-modal
components/onboarding-wizard.tsx — full wizard step-by-step ARIA pass
components/settings-modal.tsx — modal semantics, labeled inputs
app/layout.tsx — skip-link, <main> landmark
app/globals.css — skip-link :focus-visible styles

electron/main.js — setAccessibilitySupportEnabled(true) on all platforms
electron/after-pack.js — correct macOS .app bundle path for standalone build
next.config.ts — standalone output for Electron packaging

## i18n — Spanish translation layer (lib/i18n/es.ts)

Typed constant map for all visible UI strings. Components import `t`
and reference keys instead of inline English literals. Covers: nav,
channels, chat, agents, settings, boardroom, status, onboarding (5
steps), files. No runtime i18n library dependency added.

## New features

app/api/fs/open-editor/ — GET returns available editors; POST opens a
  project path in the first detected IDE. Detection order:
  Antigravity > Cursor > VS Code > Windsurf > Zed. Checks bundled
  macOS CLI paths so no PATH setup is required.

components/channel-header.tsx:
  OpenInEditorBtn — appears when channel has projectPath; probes
    /api/fs/open-editor on mount and shows the button only if an IDE
    is found. Clicking opens the folder in the detected IDE.
  AgentChip popover — new @mention handles panel lists every adapter's
    handle (e.g. @claude, @codex, @Hermes) with strikethrough for
    unconfigured ones. Lets users compose multi-agent dialogues without
    guessing handle names.

lib/agents/hermes-cli.ts — fix invocation: `hermes chat -q <prompt> -Q`
  (non-interactive mode with quiet flag). Previous `-p` flag was wrong.

scripts/sync-upstream.sh — helper to rebase onto upstream/main.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@aitorf2 aitorf2 changed the title a11y: VoiceOver/NVDA/JAWS accessibility pass (landmarks, live regions, dialogs) a11y + i18n(es) + open-in-editor: accessibility, Spanish layer, IDE button May 20, 2026
aitorf2 and others added 3 commits May 20, 2026 19:34
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…warding

## Sub-agent routing (claude-cli)
- DB: add sub_agent_id, supervisor_agent_id, supervisor_every_n columns to
  channel_overrides with idempotent migrateAddColumn migrations
- DB: getChannelSubAgent / setChannelSubAgent / getChannelSupervisor /
  setChannelSupervisor getters/setters
- lib/agents/types.ts: add channelId to SendOptions so adapters can read
  per-channel settings
- lib/agents/claude-cli.ts: read getChannelSubAgent(channelId) and pass
  --agent <name> to the claude subprocess when a sub-agent is pinned
- lib/agents/index.ts: forward channelId from sendMessage to adapter.send

## Catalog API
- app/api/agents/catalog/route.ts: reads ~/.claude/agents/*.md, parses
  YAML frontmatter (name, description, model), returns sorted agent list

## Channel sub-agent API
- app/api/channel-sub-agent/route.ts: GET ?channelId / POST {channelId,subAgentId}
  to read/write the per-channel sub-agent pin

## Supervisor API
- app/api/supervisor/route.ts: GET settings / POST to save settings or
  trigger a live supervisor pass (POST {run:true}). Reads last 20 messages
  from SQLite, compresses them, runs claude -p --agent <id> --bare
  "[compressed]", returns the supervisor note

## Channel header UI
- AgentChip popover: new "Claude sub-agent" section (visible when primary
  is claude-cli) with catalog picker + description preview
- AgentChip popover: new "Supervisor" section with agent picker (defaults
  to meta-analyzer) and everyN budget field

## Channel chat
- channel-chat.tsx: load supervisor settings per channel on mount
- After each successful turn, increment counter and fire /api/supervisor
  when everyN threshold is reached
- Render supervisor notes as violet bordered bubbles distinct from
  agent replies and system messages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- channel-header: AgentChip loads ~/.claude/agents catalog, renders sub-agent
  picker (claude-cli only) and supervisor section with agent+frequency controls
- channel-chat: supervisor turn counting, trigger /api/supervisor every N turns,
  render supervisor notes as violet sparkles bubbles
- lib/agents/index.ts: pass channelId through to adapter.send()
- lib/agents/claude-cli.ts: --agent flag from getChannelSubAgent()
- lib/agents/types.ts: channelId in SendOptions
- lib/db.ts: sub_agent_id + supervisor columns + getter/setter functions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@PythonLuvr
Copy link
Copy Markdown
Owner

Hey @aitorf2 — quick heads up: War Room was just relicensed from AGPL-3.0 to MIT (commit f65eaaf on main). I'd love to get this PR landed, but before I merge I need a one-line confirmation from you that you're OK with your contribution going in under MIT.

@PythonLuvr
Copy link
Copy Markdown
Owner

Hey @aitorf2 — quick heads up: War Room was just relicensed from AGPL-3.0 to MIT (commit f65eaaf on main). I'd love to get this PR landed, but before I merge I need a one-line confirmation from you that you're OK with your contribution going in under MIT.

A reply here saying "I agree this PR can be merged under MIT" is sufficient.

Also — thank you for this PR. The a11y pass, Spanish i18n layer, and the Hermes CLI fix in particular are exactly the kind of contributions that make this project better. I cherry-picked the Hermes fix as its own commit so it lands fast (credited to you via Co-Authored-By). For the rest, I'd like to split this into a few smaller PRs: a11y first, then i18n, then sub-agent routing, then supervisor. Easier to review and easier to roll back if any one slice has issues. Want to split them yourself, or would you prefer I do it and credit your commits?

PythonLuvr added a commit that referenced this pull request May 24, 2026
The hermes-cli adapter was calling `hermes -p <prompt>`, which is not
a valid flag in the current Hermes CLI. The correct non-interactive
invocation is `hermes chat -q <prompt> -Q` (-Q suppresses the banner
and spinner so stdout stays clean for streaming capture).

Bug spotted by @aitorf2 in PR #1; landing this slice independently
ahead of the larger review.

Co-authored-by: aitorf2 <63227344+aitorf2@users.noreply.github.com>
PythonLuvr added a commit that referenced this pull request May 24, 2026
* fix(hermes-cli): correct CLI invocation

The hermes-cli adapter was calling `hermes -p <prompt>`, which is not
a valid flag in the current Hermes CLI. The correct non-interactive
invocation is `hermes chat -q <prompt> -Q` (-Q suppresses the banner
and spinner so stdout stays clean for streaming capture).

Bug spotted by @aitorf2 in PR #1; landing this slice independently
ahead of the larger review.

Co-Authored-By: aitorf2 <63227344+aitorf2@users.noreply.github.com>

* docs: add Spanish README + "How to contribute" intro

Six of the seven current stargazers are Spanish-speaking, so add a
README.es.md translation and a language switcher line in the English
README header to surface it.

CONTRIBUTING.md gains a "How to contribute" section above the existing
Local development guide. Sets expectations the existing doc assumes:
solo-maintained, weekly review cadence, one-thing-per-PR, MIT inbound,
and points newcomers at good-first-issue labels.

No code changes.

---------

Co-authored-by: aitorf2 <63227344+aitorf2@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants