Files
roboco/panel
192524265c [f309463f] Systematic tooltip and aria-label pass across the entire panel (#484)
* [001c9a7a] Author tooltip/aria-label spec for the panel (#469) (#473)

* [001c9a7a] docs(ux_ui): add tooltip/aria-label classification spec for panel controls

* [001c9a7a] docs(ux_ui): commit missing tooltip/aria-label spec content

Prior commit's message claimed to add the spec but only touched
unrelated generated lifecycle prompt files — the actual spec file was
never git-added. This commits the real content.

---------

Co-authored-by: UX/UI Developer 1 <ux-dev-1@roboco.tech>

* [dbe222aa] Implement tooltip and aria-label sweep across all panel surfaces (#478)

* [6f991331] Add aria-label + matching tooltip per tooltip-aria-label-spec.md (#476)

* [6f991331] feat(panel): add aria-label + matching tooltip to 8 icon-only controls per tooltip-aria-label-spec.md §1a/§1b, wrap assignee-avatar initials in a full-name tooltip

* [6f991331] docs(accessibility): add icon-only controls pattern guide for aria-label + matching tooltip

Documented the implemented pattern for accessible icon-only controls across 8 components (bell, back-arrow, menu, toggle, drag-handle, move-forward, settings, review-link) plus the assignee-avatar tooltip. Covers when to apply the pattern, naming conventions, state-dependent labels, testing approach, and rationale for local TooltipProvider scope.

---------

Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech>
Co-authored-by: Frontend Documenter <fe-doc@roboco.tech>

* [e34da833] Fix notification-bell.tsx and assignee-avatar.tsx, re-verify all 9 claimed tooltip/aria-label retrofits (#480)

* [e34da833] test(notifications): add regression coverage confirming the bell button's aria-label/title/Tooltip and re-verify the other 8 tooltip-aria-label-spec controls by direct file read

* [e34da833] docs(ux_ui): update tooltip-aria-label-spec.md status to "implemented" with test coverage summary

---------

Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech>
Co-authored-by: Frontend Documenter <fe-doc@roboco.tech>

* [09414273] fix(header): wrap refresh button in Tooltip; correct spec.md and accessible-icon-buttons.md doc-accuracy issues (#483)

Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech>

---------

Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech>
Co-authored-by: Frontend Documenter <fe-doc@roboco.tech>

* [f309463f] fix: missing tooltip/Link/ArrowLeft imports + dedupe command-center tooltip import, drop redundant native title on refresh button, reflow doc prose

- kanban-card.tsx, header.tsx: import TooltipProvider (used but undefined -> eslint react/jsx-no-undef, blocked Panel lint + QA image panel build)
- task-header.tsx: import Link (next/link) and ArrowLeft (lucide-react) for the back button tooltip
- command-center.tsx: remove the duplicate tooltip primitive import block (kept the one with TooltipProvider; tsc duplicate-identifier)
- header.tsx: drop native title= on the refresh button now that a Radix Tooltip carries the hint (header test expects no native title)
- docs/frontend/components/accessible-icon-buttons.md: reflow hard-wrapped prose (python gate make reflow-docs)

* [f309463f] chore: regenerate lifecycle artifacts + verb tables (reconcile after master merge)

The branch's generated intro prose in agents/prompts/_generated/lifecycle-*.md
and verbs.md had drifted to unwrapped lines (master is wrapped). The foundation-
check gate (make lifecycle + regenerate_verb_tables + git diff --exit-code) caught
the drift. Re-rendered via the canonical generators; no hand-edits.

* [f309463f] Close remaining a11y gaps: aria-labels on task-table row-expand + pagination, titles on work-session truncated task-id/branch, secretary Start loading label

---------

Co-authored-by: UX/UI Developer 1 <ux-dev-1@roboco.tech>
Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech>
Co-authored-by: Frontend Documenter <fe-doc@roboco.tech>
Co-authored-by: Renn F <rennf93@users.noreply.github.com>
2026-07-13 06:38:48 +02:00
..
2026-07-02 15:36:49 +02:00
2026-04-20 15:10:54 +02:00
2026-06-29 05:38:21 +02:00
2026-07-11 09:45:54 +02:00
2026-05-09 03:15:09 +02:00

RoboCo Control Panel

Next.js 16 control panel for the RoboCo AI agent system. Formerly a separate repository (rennf93/roboco-panel), now vendored under panel/ in this monorepo so docker compose up -d brings up the whole stack from one place.

Stack

  • Next.js 16 (App Router, standalone output)
  • TypeScript
  • Tailwind CSS
  • Radix UI primitives
  • dnd-kit for drag/drop (kanban)
  • pnpm for package management

Running in production (the normal path)

Use the root-level Docker Compose:

# from the repo root (one level up from this directory)
docker compose up -d

The panel is built as part of the compose stack via docker/panel.Dockerfile and served internally on port 3000. Nginx (also in the compose stack) is the single externally-exposed service on http://localhost:3000 and routes:

  • /api/* and /ws/* → orchestrator (FastAPI, port 8000)
  • everything else → the Next.js panel

The panel uses relative URLs (/api/v1, /ws) so nothing here needs a backend URL in .env.

Running the panel alone for UI development

cd panel
pnpm install
pnpm dev

That gives you Next dev-server on localhost:3000, but you still need the orchestrator reachable at localhost:8000 (or via nginx) for API calls to work. Easiest: docker compose up -d the backend services, then run pnpm dev against that.

Build scripts

  • pnpm dev — development server with hot reload
  • pnpm build — production build (outputs .next/standalone/)
  • pnpm start — run the standalone build
  • pnpm lint — ESLint

Where things live

  • src/app/ — Next.js App Router pages
  • src/components/ — React components (organized by feature: tasks, agents, channels, …)
  • src/lib/api/ — typed API client (thin wrappers over fetch)
  • src/lib/ — constants, utilities, WebSocket hooks
  • src/types/ — shared TypeScript types mirroring backend schemas (includes NotificationType enum)
  • src/hooks/ — reusable React hooks (see Frontend hooks)
  • src/app/(dashboard)/notifications/ — notifications inbox page and components

Hooks

The panel exposes public hooks under @/hooks. See Frontend hooks for full API reference and examples.

usePageRefresh

Page-scoped refresh coordinator. Pages register data-refetch callbacks; the navbar refresh button in src/components/layout/header.tsx calls refresh() and reflects the combined loading/disabled state. The button is disabled when no callbacks are registered (the registry is empty) and while a refresh is in progress.

import { usePageRefresh } from "@/hooks";

const { register, unregister, refresh, loading, disabled } = usePageRefresh();
  • disabled is true when no callbacks are registered (there is nothing to refresh)
  • disabled becomes false once a callback is registered
  • disabled returns to true when all callbacks are unregistered

Wrap your page or layout in PageRefreshProvider from @/components/providers before consuming the hook. Dashboard pages should register their refetch callbacks and avoid adding inline "Refresh" buttons; see docs/frontend/components/page-refresh-provider.md for the full wiring list and examples.

Notifications

The panel renders five core coordination-event notification types that signal task lifecycle transitions between agents:

Type Icon Color Meaning
TASK_ASSIGNMENT ListTodo green A task has been assigned to you
BLOCKER_ESCALATION AlertTriangle red A developer is blocked and escalated
REVIEW_REQUEST Check purple Your review is needed
DOCUMENTATION_REQUEST Info blue Documentation is needed
APPROVAL ShieldCheck emerald Board-level approval requested

Each notification optionally carries a related_task_id rendered as a deep-link to /tasks/{id}. For full details on types, icons, and adding new types, see docs/frontend/components/notification-types.md.

Dependency Management

Version Alignment

When bumping Next.js, always update eslint-config-next to match the same version. These packages must stay in sync. See UPGRADE.md for detailed procedures and troubleshooting.

Backend schema changes

When the backend changes response shapes, mirror them in src/types/ and the relevant src/lib/api/ module. Keep API paths relative so nginx routing keeps working.