Skip to content

Feat/horizon UI phase1 cleanup#198

Merged
dgarson merged 364 commits intomainfrom
feat/horizon-ui-phase1-cleanup
Mar 3, 2026
Merged

Feat/horizon UI phase1 cleanup#198
dgarson merged 364 commits intomainfrom
feat/horizon-ui-phase1-cleanup

Conversation

@dgarson
Copy link
Owner

@dgarson dgarson commented Mar 3, 2026

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem:
  • Why it matters:
  • What changed:
  • What did NOT change (scope boundary):

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #

User-visible / Behavior Changes

List user-visible changes (including defaults/config).
If none, write None.

Security Impact (required)

  • New permissions/capabilities? (Yes/No)
  • Secrets/tokens handling changed? (Yes/No)
  • New/changed network calls? (Yes/No)
  • Command/tool execution surface changed? (Yes/No)
  • Data access scope changed? (Yes/No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS:
  • Runtime/container:
  • Model/provider:
  • Integration/channel (if any):
  • Relevant config (redacted):

Steps

Expected

Actual

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
  • Edge cases checked:
  • What you did not verify:

Compatibility / Migration

  • Backward compatible? (Yes/No)
  • Config/env changes? (Yes/No)
  • Migration needed? (Yes/No)
  • If yes, exact upgrade steps:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly:
  • Files/config to restore:
  • Known bad symptoms reviewers should watch for:

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk:
    • Mitigation:

dgarson and others added 30 commits February 22, 2026 12:05
* feat: register workq gateway rpc handlers

* feat(workq): integrate extension scaffolding and gateway bindings

* docs(workq): expand Pi/ARM runtime portability guidance in README

- Replace minimal Pi note with comprehensive portability table (node:sqlite,
  Node version, architecture, WAL/filesystem considerations)
- Add recommended database path section for Pi (/data/openclaw/workq/workq.db)
  with config example and directory setup commands
- Add 5-step probe/verification command sequence for new host deployments
- Fix hardcoded local path in Installation section to use relative repo path

* fix(workq): remove rootDir from tsconfig to allow plugin-sdk imports

* style(workq): fix formatting issues in extension files

* docs(workq): expand CLAUDE.md with comprehensive tool guidance

Enhances workq extension documentation for Claude Code agents with:

- Detailed breakdown of all 8 queue tools with parameters and examples
- Expected call order workflow (claim -> status/files -> in-review -> done)
- Status state machine diagram and valid transitions
- Practical examples covering happy path, conflicts, blocked tasks, queries
- Common pitfalls and integration notes for platform squad agents
- File conflict detection guidance

Provides agents with actionable reference for coordinating work across
the multi-agent fleet.

* fix(workq): correct test mock for WorkqDatabase class constructor

The previous test used vi.fn() to mock the WorkqDatabase class, but this
doesn't work properly when the actual code uses 'new WorkqDatabase()'.

Changed to use a proper class mock with vi.hoisted() to ensure the mock
functions are available when the vi.mock() factory runs.

All 41 tests now pass.
…oter parsing (#71)

* feat: register workq gateway rpc handlers

* feat(workq): integrate extension scaffolding and gateway bindings

* docs(workq): expand Pi/ARM runtime portability guidance in README

- Replace minimal Pi note with comprehensive portability table (node:sqlite,
  Node version, architecture, WAL/filesystem considerations)
- Add recommended database path section for Pi (/data/openclaw/workq/workq.db)
  with config example and directory setup commands
- Add 5-step probe/verification command sequence for new host deployments
- Fix hardcoded local path in Installation section to use relative repo path

* fix(workq): remove rootDir from tsconfig to allow plugin-sdk imports

* style(workq): fix formatting issues in extension files

* docs(workq): expand CLAUDE.md with comprehensive tool guidance

Enhances workq extension documentation for Claude Code agents with:

- Detailed breakdown of all 8 queue tools with parameters and examples
- Expected call order workflow (claim -> status/files -> in-review -> done)
- Status state machine diagram and valid transitions
- Practical examples covering happy path, conflicts, blocked tasks, queries
- Common pitfalls and integration notes for platform squad agents
- File conflict detection guidance

Provides agents with actionable reference for coordinating work across
the multi-agent fleet.

* fix(workq): correct test mock for WorkqDatabase class constructor

The previous test used vi.fn() to mock the WorkqDatabase class, but this
doesn't work properly when the actual code uses 'new WorkqDatabase()'.

Changed to use a proper class mock with vi.hoisted() to ensure the mock
functions are available when the vi.mock() factory runs.

All 41 tests now pass.

* workq: enforce session-end auto-release and stale sweep
* feat(ui): Agent configuration experience — gateway hooks, file editors, LLM assist, auto-review

Major additions to the OpenClaw web UI:

Gateway Integration Layer:
- gateway-hooks.ts: React Query integration for all gateway RPC methods
- Typed query/mutation hooks for agents, config, models, sessions, skills, etc.
- Gateway event subscription hook for real-time updates

Agent Configuration Experience:
- AgentConfigPage: Tabbed config with progressive disclosure
- SoulEditor: SOUL.md editor with split view and markdown preview
- AgentFileEditor: Generic file editor for workspace files
- AgentOverviewConfig: Identity card, file health, suggestions
- Route: /agents/:agentId/configure

LLM Assist Panel:
- Conversational AI sidebar for configuration help
- Context-aware suggestions per config section
- Apply changes directly from suggestions

Auto-Review Panel:
- One-click config analysis with score/grade
- Actionable fix suggestions

Updated hooks and navigation to connect config flow.

* fix(ui): lint cleanup — remove unused imports, prefix unused params

- AutoReviewPanel: remove unused AnimatePresence, CardDescription; prefix unused params
- SkillConfigurator: remove unused AnimatePresence, Button; prefix agentId
- AgentConfigPage: remove unused AlertTriangle, RefreshCw, AGENT_FILES; wire SkillConfigurator into skills tab
- LLMAssistPanel: remove unused RefreshCw, ScrollArea, Separator; prefix agentId
- ModelBehaviorConfig: prefix unused isLoading param
- ModelSelector: remove unused Badge; prefix placeholder param
- useAgents: prefix unused isDefault param, fetchAgentsFromConfig fn

* perf(ui): split @xyflow into separate vendor chunk

@xyflow (React Flow for DAG visualization) was bundled into the vendor-react
chunk despite only being used on workstream/workflow pages. Moving it to
vendor-xyflow isolates 122 kB that's only loaded when needed.

Before: vendor-react 557 kB (everything)
After:  vendor-react 433 kB + vendor-xyflow 122 kB (lazy)

* feat(ui): content-shaped page skeletons for improved perceived performance

Add page-specific skeleton loading states that match actual content layout:
- HomeSkeleton: greeting, quick chat, agent grid, panel layout
- AgentListSkeleton: header + search + 3x3 card grid
- AgentDetailSkeleton: back nav, agent header, tabs, stats, content area
- ConversationListSkeleton: sidebar + empty state
- ChatThreadSkeleton: header, message bubbles pattern, input bar
- SettingsSkeleton: sidebar nav + settings content
- WorkstreamsSkeleton: header, filter tabs, workstream cards

Wire AgentDetailSkeleton into /agents/[agentId] route.

* fix(ui): UX polish — branding, cleanup, Skills route, container consistency

- Fix sidebar branding: 'Second Brain' → 'OpenClaw', logo initial 'S' → 'O'
- Remove 211 'use client' directives (Next.js artifact, meaningless in Vite)
- Fix homepage greeting: remove hardcoded 'User!' placeholder
- Normalize container patterns in Nodes and Jobs pages (remove redundant
  min-h-screen/max-w-7xl wrappers — AppShell already provides these)
- Add new /skills route with full CRUD: list, search, filter, enable/disable,
  install from URL/ClawhHub, uninstall, detail panel with config view
- Add Skills nav item to sidebar under Team section
- All changes use existing gateway hooks and API layer (no new APIs needed)
- Build passes cleanly (6.71s)

* feat(ui): mobile bottom navigation for responsive layout

- Add MobileBottomNav component with Home, Chat, Agents, Settings tabs
- 'More' tab opens full sidebar as a slide-out sheet
- Visible only on screens < md (768px), hidden on tablet/desktop
- Auto-hides on fullscreen pages (onboarding, unlock)
- Add bottom padding to content area on mobile to prevent nav overlap
- Respects safe-area-inset for notched devices
- Export from layout index

* feat(ui): add Logs route and mobile navigation improvements

- Add /logs route with log stream viewer (Power User mode)
  - Level filtering (trace/debug/info/warn/error/fatal) with counts
  - Search/filter by message or subsystem
  - Auto-scroll toggle, pause/resume stream
  - Export filtered logs as text file
  - Color-coded log levels with appropriate icons
  - Monospace font, compact density for log readability
- Add Logs nav item to sidebar Power User section
- Uses sample data for UI development; ready for gateway integration

* fix(ui): rebrand Second Brain → OpenClaw, use profile name on home page

- Sidebar: Updated logo text from 'Second Brain' to 'OpenClaw'
- Home page: Reads user display name from profile settings instead of hardcoded 'User!'
- Filesystem: Updated API endpoint and config references to openclaw.ai
- App.tsx: Updated sandbox page branding

Files changed:
- /Users/openclaw/openclaw-ui-redesign/apps/web/src/components/layout/Sidebar.tsx
- /Users/openclaw/openclaw-ui-redesign/apps/web/src/routes/index.tsx
- /Users/openclaw/openclaw-ui-redesign/apps/web/src/routes/filesystem/index.tsx
- /Users/openclaw/openclaw-ui-redesign/apps/web/src/App.tsx

* feat(ui): add /logs route — real-time gateway log streaming

- New route: /logs with polling-based log tail via gateway 'logs.tail' RPC
- Features: level filtering (trace/debug/info/warn/error/fatal), text search,
  auto-follow, pause/resume, export to JSONL, entry counts per level
- Dark terminal-style UI with color-coded log levels
- Added to sidebar Power User section with ScrollText icon
- Handles disconnected state gracefully

Files changed:
- /Users/openclaw/openclaw-ui-redesign/apps/web/src/routes/logs/index.tsx (new)
- /Users/openclaw/openclaw-ui-redesign/apps/web/src/components/layout/Sidebar.tsx
- /Users/openclaw/openclaw-ui-redesign/apps/web/src/routeTree.gen.ts (auto-generated)

* feat(ui): add /analytics route — usage dashboard with token/cost/model/agent breakdowns

- New route: /analytics with gateway 'sessions.usage' + 'usage.cost' RPC
- Features: date range picker, stat cards (tokens/cost/messages/tools),
  daily bar charts (tokens + cost), model/agent/tool breakdowns with progress bars,
  full session table with sort-by-cost, expand/collapse
- Token and cost breakdown cards showing input/output/cache splits
- Responsive grid layout, loading skeletons, disconnected state
- Added to sidebar Power User section with BarChart3 icon

Files changed:
- /Users/openclaw/openclaw-ui-redesign/apps/web/src/routes/analytics/index.tsx (new)
- /Users/openclaw/openclaw-ui-redesign/apps/web/src/components/layout/Sidebar.tsx
- /Users/openclaw/openclaw-ui-redesign/apps/web/src/routeTree.gen.ts (auto-generated)

* fix(ui): add TanStack Router errorComponent on root route

- RouteErrorComponent wraps ErrorFallback with router-aware recovery
- 'Try Again' invalidates the current route (re-fetches data)
- 'Go Home' navigates to / via router (no full page reload)
- Complements existing React ErrorBoundary for render-crash recovery

File changed:
- /Users/openclaw/openclaw-ui-redesign/apps/web/src/routes/__root.tsx

* a11y: skip nav, reduced motion, keyboard support, ARIA landmarks, live region announcer

- Add SkipNavLink + SkipNavContent for keyboard users to bypass sidebar (WCAG 2.4.1)
- Add ReducedMotionProvider wrapping app root — respects prefers-reduced-motion (WCAG 2.3.3)
- Add role/tabIndex/onKeyDown to 6 interactive non-button elements:
  ToolCategorySection, ConversationItem, MemoryCard (2 variants),
  agent-plan task toggle, GatewaySetupStep radio cards
- Add focus-visible ring styles to all fixed elements
- Add aria-label/role='navigation' to Sidebar landmark
- Add aria-expanded/aria-controls to expandable sections
- Add useAnnounce hook + useRouteAnnouncer for screen reader live regions
- Build verified: 7.03s, no errors

* a11y: route change announcer + dynamic document.title

- Announce navigation to screen readers via useAnnounce live region
- Update document.title on route changes (e.g. 'Settings — OpenClaw')
- Derives human-readable page name from URL path segment
- WCAG 4.1.3: Status Messages compliance

* feat(ui): agent activity feed widget on home dashboard

- New AgentActivityFeed component with real-time agent activity stream
- Shows agent avatar, activity type (7 types), description, relative timestamp
- Color-coded activity icons: session started, message sent, tool called,
  task completed, task failed, agent spawned, file edited
- Auto-refresh every 30s with live indicator pulse
- Proper empty state with guidance text
- ARIA: role=feed, role=article, aria-labels, semantic time elements
- Mock data hook (useAgentActivity) ready for real API swap
- Replaces placeholder widget on home page grid
- Build: 6.96s, no errors

* feat(ux): agent status indicators on avatars (#19)

Add reusable AgentStatusDot component with Framer Motion pulse
animations and useAgentStatus hook for deriving display status from
agent store data.

Status types:
- Online (green, slow pulse): active within last 5 minutes
- Busy (amber, fast pulse): currently processing or awaiting approval
- Offline (gray, static): inactive
- Error (red, static): error state

Integrated into:
- AgentAvatar (composed) — shared avatar used across the app
- AgentCard (compact + expanded variants) — home grid and agent list
- AgentSessionsIndicator — sidebar waiting-agents popover

Includes auto-expiry timer in useAgentStatus that transitions
online → offline when lastActive exceeds the 5-minute threshold.

* feat(ux): keyboard shortcuts discoverability badge (#18)

Changes landed in c6a1309 (co-committed with #19).

Summary of changes:
- apps/web/src/hooks/useShortcutsSeen.ts (new)
  localStorage-gated hook (key: oc_shortcuts_seen) tracking first-visit state

- apps/web/src/hooks/index.ts
  Export useShortcutsSeen from hooks barrel

- apps/web/src/providers/ShortcutsProvider.tsx
  Add ShortcutsContext exposing openShortcutsModal / shortcutsSeen / markShortcutsSeen;
  mark as seen whenever modal opens via keyboard, button, or command palette

- apps/web/src/providers/index.ts
  Export ShortcutsContext and useShortcutsContext

- apps/web/src/components/layout/Sidebar.tsx
  Add KeyboardShortcutsButton with Framer Motion pulsing dot + 'NEW' badge;
  button calls openShortcutsModal from context; dot/badge auto-dismiss on first open

- apps/web/src/components/composed/CommandPalette.tsx
  Add footer hint: 'Press ? to see all keyboard shortcuts'

* fix(a11y): dark mode color contrast improvements (#20)

- Remove all text-muted-foreground opacity modifiers (/40, /50, /60, /70, /80)
  that caused WCAG AA failures in dark mode. Replaced with full-opacity
  text-muted-foreground which passes at 6.16:1 on background and 5.81:1 on card.

- Add dark: overrides for hardcoded Tailwind gray/slate text colors:
  - text-gray-500 → dark:text-gray-400 (4.13:1→7.86:1)
  - text-gray-600 → dark:text-gray-400 (2.64:1→7.86:1)
  - text-slate-500 → dark:text-slate-400 (4.19:1→7.78:1)

Affected components: 25 files across composed, domain, and route layers.

Key contrast ratios (before → after on --background):
  muted-foreground/40:  1.88:1 → 6.16:1
  muted-foreground/50:  2.32:1 → 6.16:1
  muted-foreground/60:  2.85:1 → 6.16:1
  muted-foreground/70:  3.52:1 → 6.16:1
  muted-foreground/80:  4.27:1 → 6.16:1
  gray-500:             4.13:1 → 7.86:1 (via gray-400)
  gray-600:             2.64:1 → 7.86:1 (via gray-400)
  slate-500:            4.19:1 → 7.78:1 (via slate-400)

* feat(i18n): internationalization infrastructure with en/pt-BR/zh-CN/zh-TW (#11)

- Add react-i18next, i18next, i18next-browser-languagedetector dependencies
- Create i18n setup with language detection, localStorage persistence, en fallback
- Add 4 locale files (en, pt-BR, zh-CN, zh-TW) with ~75 key strings each:
  - common actions (Save, Cancel, Delete, Create, etc.)
  - navigation labels (Home, Conversations, Goals, Memories, etc.)
  - home dashboard greetings and section titles
  - settings section headings and appearance labels
  - error messages
  - agent status labels
- Import i18n initialization in main.tsx (before component tree)
- Integrate useTranslation in 5 key components:
  - Sidebar: all nav labels and section titles
  - AppearanceSection: all labels + language selector with 4 language options
  - HomePage: time-of-day greeting
  - SettingsPage: page title and subtitle
  - YouPage: page title and subtitle
- Language selector in You > Appearance with live switching

* feat(ui): Monaco editor component with lazy loading, fallback textarea, Cmd+S save binding

* fix(build): clear postcss.config.mjs — Tailwind v4 handled by @tailwindcss/vite plugin, not PostCSS

* chore: update pnpm-lock.yaml for @monaco-editor/react dependency

* feat(ui): activity heat map on agent-status route (#14)

* feat(ui): agent relationship graph visualization (#13)

- New route /agents/graph with live agent data from gateway
- Parses session key patterns to infer spawn/delegation edges
- ReagraphView integration with custom health-based node coloring
- CSS fallback tree view when reagraph unavailable
- Slide-in detail panel on node click: task, model, tokens, cost, links
- Stats bar: total agents, active count, tokens, cost
- Legend: health colors + spawn edge indicator
- Back link to /agents, 15s auto-refresh
- Added Network icon + Agent Graph link to sidebar Team section
- Removed duplicate Logs entry from Power User section

* feat(ui): chat-driven agent builder at /agents/new (#15)

- New /agents/new route: conversational interface for agent creation
- Split-panel: chat on left, live config preview on right
- NLP parser: extracts name, role, tags, model, personality from freetext
  - Keyword inference for 8 roles (Monitor, Researcher, Developer, etc.)
  - Domain tag extraction for 15 platforms (github, slack, discord, email, etc.)
  - Model preference detection (opus, haiku, gpt-4, gemini, grok)
  - Personality trait extraction (concise, thorough, friendly, etc.)
- Config preview: flash-highlights fields as they update (framer-motion)
- Tags: editable inline with + input and × remove button
- All fields manually editable in preview panel
- Readiness checklist: name + description = ready to create
- 5 suggested starter prompts (GitHub monitor, research, code review, etc.)
- Animated typing indicator while processing
- useCreateAgent() integration → navigates to agent config after creation
- 'Chat Builder' secondary button added to agents list page header
- Simple markdown renderer for **bold** and `code` in assistant messages

* fix(ui): correct createAgent status field + add Graph View link to agent-status header

- Chat builder: pass required status: 'offline' to createAgent.mutateAsync
  (Agent interface requires status, new agents start offline)
- Agent Status dashboard: add 'Graph View' ghost button linking to /agents/graph
  (natural navigation path from status dashboard → relationship graph)

* chore(ui): remove Next.js 'use client' directives from Vite project

8 files had 'use client' at the top — a Next.js App Router directive that is
meaningless in Vite/React. Strips as dead noise. No behavior change.

* docs: add approvals + milestone feed design doc

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add approvals + milestone feed implementation plan

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update plan with tsc-per-task, tests-only-at-end strategy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(approvals): add ApprovalItem component

* feat(approvals): add ApprovalsQueue with compact/full modes and agent grouping

* feat(approvals): add MilestoneItem and MilestoneDetailPanel

* feat(ui): redesign layout, session view, and nav components

Redesigns the app shell, sidebar, nav items, session workspace, and agent
status pages with updated visual styling. Adds TerminalOverlay component
and updates NewSessionDialog, SessionHeader, and related routes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(approvals): add MilestoneFeed with date grouping

* feat(approvals): add InboxPanel slide-out with compact approvals + milestones

* feat(approvals): add inbox icon + badge to sidebar

* feat(approvals): add /approvals page with full queue and milestone feed

* docs: add Configure tab redesign design doc

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ui): fix calendar icon color, reassign button, pill heights, and arrow styling

- Fix black native calendar picker icon on dark theme with CSS invert filter
- Add prominent Reassign button with UserCog icon to agent assignment card in RitualDetailPanel
- Align date/time content text with label text in schedule info cards (pl-6 indent)
- Normalize execution pill font size to text-xs so Status, Tool Calls, and Token/Cost share the same height
- Reduce TokenCostIndicator padding by 50% (px-3 py-1 → px-1.5 py-0.5)
- Improve arrow button visibility in Recent Executions with muted-foreground color

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add Configure tab redesign implementation plan

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(approvals): reuse GoalDetailPanel in MilestoneFeed with highlightMilestoneId prop

* fix(inbox): widen panel to 520px and add Open Inbox link in header

* feat(agents): add embedded prop to AgentConfigPage

* feat(agents): add AgentConfigureTab with nested builder/rituals/tools sub-tabs

* chore(agents): export AgentConfigureTab from barrel

* feat(agents): replace Rituals/Tools/Soul tabs with Configure nested tab panel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(goals): add Edit button to Goal Details panel with working edit modal

- Add headerActions slot to DetailPanel so callsites can inject title-bar buttons
- Add Edit icon button in GoalDetailPanel title bar (visible without scrolling)
- Remove goal.status !== 'completed' guard so any goal can be edited
- Extend CreateGoalModal with edit mode: initialGoal prop pre-populates all fields,
  milestones preserve original IDs and completion state, title/CTA reflect edit context
- Wire GoalsPage: handleEdit opens the shared modal in edit mode via useUpdateGoal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(ids): consolidate all UUID generation to uuidv7

Replace crypto.randomUUID() in new.lazy.tsx and the custom generateUUID()
utility in gateway-client.ts with the project-standard uuidv7() from @/lib/ids.
Also convert WebSocket on* property handlers to addEventListener calls and
remove unused Card/CardContent imports surfaced during linting.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(assist): add rituals section prompts to LLMAssistPanel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(sidebar): increase collapsed icon hit area and nav item spacing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(agents): lift assist/review state and fix embedded padding in AgentConfigPage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(agents): lift AI Assist and Auto Review to AgentConfigureTab level

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(agents): edit button navigates to configure tab, persist configureTab in URL

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(agents): remove AgentSoulTab, consolidated into SoulEditor guided mode

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ui): follow-ups + ph1 tab config

Follow-ups:
- GoalDetailPanel: add pl-6 indent to Due Date + Created content text
- RitualScheduler: fix dark time input picker icon with CSS invert filter
- RitualDetailPanel: add Trigger quick-action to DetailPanel headerActions slot
- RitualsPage: wire onReassign → RitualAssignDialog (full agent reassignment flow)
- Export RitualAssignDialog + RitualAssignPayload from rituals barrel

Phase 1:
- Add src/config/agent-tabs.ts with AGENT_TABS config, isValidTab(), resolveTab(),
  and TAB_REDIRECTS backwards-compat map for old tab URL params

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ui): ph5 inheritance system - useInheritanceStore, InheritanceBadge, InheritableField

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ui): ph2 new tab components - AgentWorkTab, AgentChatTab, WorkSubNav

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ui): ph4 persona tier system - FeatureGate, usePersonaStore, PersonaTierSection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ui): ph3 - wire 5-tab structure into $agentId route

Replaces local AgentDetailTab type with imported type + resolveTab() from
config/agent-tabs.ts. Swaps workstreams tab for work (AgentWorkTab with
WorkSubNav) and adds chat tab (AgentChatTab). Old URL params like
?tab=workstreams and ?tab=rituals are resolved to 'work' via TAB_REDIRECTS.
Section param threaded through for WorkSubNav sub-navigation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ui): ph6 - responsive tab triggers and MobileTabNav

Tab triggers now show icon+label stacked on mobile (grid-cols-5) and
side-by-side on sm+. MobileTabNav provides a fixed bottom nav bar on
mobile (hidden sm+) with the same 5-tab structure from AGENT_TABS.
Bottom padding added to page content to prevent overlap with the bar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(agents): update AgentConfigureTab tests for rewritten component

* chore(agents): remove unused filesLoading destructure in AgentConfigureTab

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(agents): sync AgentConfigureTab sub-tab with URL on back/forward navigation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(routes): remove orphaned /agents/$agentId/configure full-page route

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ui): expand command palette - full action vocab + NL intent (task 2)

* feat(ui): live RPC-connected onboarding wizard (task 1)

* test(ui): ph8 unit tests for tab config, stores, and feature gate components

Add vitest setup fixes (in-memory localStorage mock + jsdom URL) to make
zustand persist middleware work in tests, and update usePersonaStore tests
to avoid replace=true state reset that strips action functions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ui): visual agent config editor - identity/model/memory/thinking (task 3)

* Add isSlackId function to validate Slack IDs

* Refactor Slack ID validation to use normalizeSlackId

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…very run (#72)

* feat(horizon-ui): add DiscoveryRunMonitor view — pre-flight checklist, wave countdowns, 15 agents, Brave key alert

* feat(horizon): add 4 discovery-run views (BraveAPIKeySetupWizard, DiscoveryWaveResults, DiscoveryAgentCostTracker, ToolReliabilityDashboard)

* UX: add 4 discovery-run views (preflight, wave scheduler, model comparison, findings search)
…tructure

Agent: luis
Original branch: feat/horizon-post-merge
Working on: horizon-ux-views
Reason: restructuring workspace so git repos live at git/{reponame}/
All untracked config + code changes captured here.
- Add maxApprovalChainDepth for approval-boundary enforcement
- Add no-self-approval enforcement via requireDifferentActor
- Add escalation config (onDeny, onTimeout, maxEscalations)
- Add shouldEscalate() to policy engine for deny/timeout scenarios
- Add comprehensive integration tests for approve/deny/timeout/escalation paths

This extends the Phase 1 HITL infrastructure with strict policy enforcement
and escalation behavior for denied or timed-out approvals.
…indingTrendChart, AgentSkillHeatmap) — batch 6PM
- Updated quiz questions to be friendlier and more conversational
- Enhanced level descriptions with more engaging copy
- Improved template descriptions with clearer value propositions
- Refreshed empty state messages for better user guidance
- Updated setup step descriptions for clarity

Part of bs-ux-1-copy
* feat: scaffold deterministic replay framework

* feat(replay): add manifest schema validation helpers

* feat(sessions): add replay session manifest types and serialization helpers

Add session-level replay manifest types distinct from the replay bundle
format in src/replay/types.ts (Nate's work in PR #92).

- ReplaySessionManifest: session metadata for replay-capable sessions
- ReplaySessionEvent: session-level events in the replay lifecycle
- ReplaySessionEventLog: collection of session events
- Serialization helpers: parse/serialize functions
- Factory functions: createReplaySessionId, createReplaySessionManifest, createReplaySessionEvent
- exportSessionManifest stub: placeholder for future storage integration

Add 43 focused tests covering:
- Schema validation for all types
- Serialization round-trips
- Factory function behavior
- Edge cases and error handling

* feat(replay): parse replay events and normalize recording categories

* feat(sessions): add replay session manifest types and serialization helpers (#98)

Add session-level replay manifest types distinct from the replay bundle
format in src/replay/types.ts (Nate's work in PR #92).

- ReplaySessionManifest: session metadata for replay-capable sessions
- ReplaySessionEvent: session-level events in the replay lifecycle
- ReplaySessionEventLog: collection of session events
- Serialization helpers: parse/serialize functions
- Factory functions: createReplaySessionId, createReplaySessionManifest, createReplaySessionEvent
- exportSessionManifest stub: placeholder for future storage integration

Add 43 focused tests covering:
- Schema validation for all types
- Serialization round-trips
- Factory function behavior
- Edge cases and error handling

* docs: add deterministic replay architecture and TDD plan (#108)

* feat: scaffold deterministic replay framework

* feat(replay): add manifest schema validation helpers

* feat(sessions): add replay session manifest types and serialization helpers

Add session-level replay manifest types distinct from the replay bundle
format in src/replay/types.ts (Nate's work in PR #92).

- ReplaySessionManifest: session metadata for replay-capable sessions
- ReplaySessionEvent: session-level events in the replay lifecycle
- ReplaySessionEventLog: collection of session events
- Serialization helpers: parse/serialize functions
- Factory functions: createReplaySessionId, createReplaySessionManifest, createReplaySessionEvent
- exportSessionManifest stub: placeholder for future storage integration

Add 43 focused tests covering:
- Schema validation for all types
- Serialization round-trips
- Factory function behavior
- Edge cases and error handling

* feat(replay): parse replay events and normalize recording categories

* feat(sessions): add replay session manifest types and serialization helpers (#98)

Add session-level replay manifest types distinct from the replay bundle
format in src/replay/types.ts (Nate's work in PR #92).

- ReplaySessionManifest: session metadata for replay-capable sessions
- ReplaySessionEvent: session-level events in the replay lifecycle
- ReplaySessionEventLog: collection of session events
- Serialization helpers: parse/serialize functions
- Factory functions: createReplaySessionId, createReplaySessionManifest, createReplaySessionEvent
- exportSessionManifest stub: placeholder for future storage integration

Add 43 focused tests covering:
- Schema validation for all types
- Serialization round-trips
- Factory function behavior
- Edge cases and error handling

* docs: add deterministic replay architecture and TDD plan (#108)

* Replay: harden recorder and deterministic clock edge cases (#182)
- Convert hardcoded zinc-* classes to named token utilities
- AgentTracer.tsx: 51 zinc refs → 0 (full conversion)
- Batch 1 views: 14 files converted

Token mappings applied:
- bg-zinc-950 → bg-surface-0
- bg-zinc-900 → bg-surface-1
- bg-zinc-800 → bg-surface-2
- bg-zinc-700 → bg-surface-3
- text-white/text-zinc-100/200/300 → text-fg-primary
- text-zinc-400 → text-fg-secondary
- text-zinc-500/600/700 → text-fg-muted
- border-zinc-800/700 → border-tok-border
- divide-zinc-800 → divide-tok-border
- ring-zinc-500/700/800 → ring-tok-border
- placeholder-zinc-500 → placeholder:text-fg-muted
- ring-offset-zinc-900 → ring-offset-surface-1
- fill-zinc-500 → fill-fg-muted

Note: Opacity variants (e.g., bg-zinc-400/10) retained pending
token system extension for opacity utilities.
## Summary
- Added skip links to all 10 modified views for keyboard navigation
- Added main landmarks with role='main' for screen reader navigation
- Fixed animate-pulse to use motion-safe: prefix for reduced motion
- Added aria-hidden to decorative status indicator dots
- Added aria-labels to filter selects without visible labels
- Added scope='col' to table headers in SupportTicketDashboard
- Added screen reader text to color-only status indicators

## Files Modified
1. SupportTicketDashboard.tsx
2. CloudCostOptimizer.tsx
3. EnvironmentDriftDetector.tsx
4. APIRateLimitManager.tsx
5. DataCatalog.tsx
6. DatabaseSchemaViewer.tsx
7. QueueInspector.tsx
8. TokenUsageOptimizer.tsx
9. SecurityAuditTrail.tsx
10. DecisionProvenance.tsx

## Audit Document
- WCAG_AUDIT_PHASE2.md contains full audit findings

WCAG Criteria Addressed:
- 2.4.1 Bypass Blocks (Level A) - Skip links
- 1.3.1 Info and Relationships (Level A) - Main landmarks, table scope
- 1.4.1 Use of Color (Level A) - Status indicator text alternatives
- 2.3.3 Animation from Interactions (Level AAA) - motion-safe prefix
Merge Wes's token unification (conflicts resolved)
Merge Reed's WCAG fixes onto Wes's token base
Resolve merge conflicts to bring PR up to date with main branch.

Conflict resolution strategy:
- CI workflow files: Kept from main (working CI workflows)
- .gitignore: Merged both sides' additions
- CHANGELOG.md: Merged both sides' changelog entries
- package.json: Merged both sides' script and dependency additions
- Test files: Took from main (updated tests)
- Source files: Took from main (stable main branch code)

This preserves the main branch's stable codebase while incorporating
cleanup work from the feature branch.
@dgarson dgarson marked this pull request as ready for review March 3, 2026 01:55
@dgarson dgarson merged commit 672cfd9 into main Mar 3, 2026
2 of 7 checks passed
@dgarson dgarson deleted the feat/horizon-ui-phase1-cleanup branch March 3, 2026 01:55
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 059c3a37f2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

const archiveAtMs =
spawnMode === "session" ? undefined : archiveAfterMs ? now + archiveAfterMs : undefined;
const runTimeoutSeconds = params.runTimeoutSeconds ?? 0;
const archiveAtMs = archiveAfterMs ? now + archiveAfterMs : undefined;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve session-mode runs from archival expiration

registerSubagentRun now assigns archiveAtMs unconditionally, so spawnMode: "session" runs will be swept and deleted after archiveAfterMinutes (default 60m) instead of remaining persistent. That changes session-mode semantics from long-lived to expiring, and can silently drop active subagent context/transcripts in ongoing workflows; the same regression also appears in the steer-restart path. This conflicts with the existing expected behavior in src/agents/subagent-registry.archive.e2e.test.ts where session-mode runs must keep archiveAtMs unset.

Useful? React with 👍 / 👎.

Comment on lines +61 to +65
const base0 = basenameLower(token0);

// POSIX-style shells: sh -lc "<cmd>"
if (
base0 === "sh" ||

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore wrapper-aware shell command extraction

extractShellCommandFromArgv now parses only the first argv token directly, which drops support for wrapper forms previously handled via extractShellWrapperCommand (for example /usr/bin/env ..., busybox/toybox shell wrappers, and pwsh -Command ...). As a result, valid wrapped shell commands now resolve to null, regressing command extraction behavior that other tooling/tests expect in src/infra/system-run-command.test.ts.

Useful? React with 👍 / 👎.

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