Previously both the 'terminal' button and 'View current context →' link
on the kanban card navigated to the same session detail page without
distinction. The terminal button now links to #session-terminal-section
anchor, which already exists in SessionDetail.tsx.
Fixes#1217
Co-authored-by: AO Bot <ao-bot@composio.dev>
* chore: release 0.2.5
Realign main with npm registry after off-branch publish of 0.2.3/0.2.4.
Bump all 21 linked packages to 0.2.5 and cherry-pick the startup-grace-period
fix for #989 (was in 5e4244a8 but never merged to main).
Also sync non-linked plugin versions (notifier-discord, notifier-openclaw,
scm-gitlab, tracker-gitlab) to their current npm versions.
* Revert "chore: release 0.2.5"
This reverts commit eb17f32834.
* chore: bump all package versions to 0.2.5, remove release workflow
- Bump all 25 packages to 0.2.5 to realign with npm registry
- Update package-version test to expect 0.2.5
- Remove stale .changeset/linear-spawn-branch-name.md
- Delete .github/workflows/release.yml (changesets-based NPM publish)
---------
Co-authored-by: Prateek <karnalprateek@gmail.com>
Co-authored-by: AO Bot <ao-bot@composio.dev>
- Merge main to pick up @composio/ao-core → @aoagents/ao-core rename
and decomposer removal (#1104)
- Fix @composio/ao-core import in prompt-spawn.test.ts → @aoagents/ao-core
- Remove unreachable dead code in CLI spawn (empty-string guard after || undefined)
- Update format.ts JSDoc to document 8-item fallback chain including userPrompt
- Add clarifying comment on validation/sanitization separation in spawn route
- Integrate userPrompt display into redesigned SessionCard footer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style(design): FINDING-001 — add prefers-reduced-motion support
All animations and transitions are disabled when the user's system
requests reduced motion, per DESIGN.md accessibility requirements.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style(design): FINDING-003 — remove concurrent breathe animations
Status pills had two animations: a breathe animation on the pill
and a dot-pulse on the child dot. DESIGN.md says "one animation per
element, one purpose" and "keep dot pulse, remove border heartbeat."
Removed all three breathe keyframes, kept dot-pulse only.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style(design): FINDING-004 — fix dashboard title weight and tracking
DESIGN.md specifies display headings at weight 680 and letter-spacing
-0.035em. The dashboard title was using 600 / -0.05em.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style(design): FINDING-005 — fix detail-card text to blue-tinted graphite
Detail cards overrode text-secondary and text-tertiary with neutral
grays (#9898a0, #5c5c66). DESIGN.md specifies blue-tinted graphite
palette (#a5afc4, #6f7c94) for dark mode text.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style(design): FINDING-008 — add text-wrap: balance on headings
Dashboard title and kanban column titles now use text-wrap: balance
for more even line breaks on narrow viewports.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style(design): FINDING-006/009 — fix section label semantics and spacing
Changed "Attention Board" from <h2> to <div role="heading"> since it's
styled as a 12px uppercase label, not a heading. Also fixed letter-spacing
from 0.16em to 0.06em per DESIGN.md UI/Labels spec.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style(design): FINDING-007 — contextual empty state messages
Empty kanban columns now show context-specific messages instead of
generic "No sessions" text. Each column's empty state reflects its
purpose: "No agents need your input" (Respond), "No code waiting
for review" (Review), etc.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(design): fresh design system — Warm Terminal
Complete redesign from Industrial Precision (blue-tinted) to Warm Terminal
(brown-tinted). Key changes:
- Warm charcoal surfaces (#121110, #1a1918, #222120) replace blue-gray
- Cream text (#f0ece8) replaces blue-white (#eef3ff)
- Warm periwinkle accent (#8b9cf7) replaces cool blue (#5B7EF8)
- Berkeley Mono for display headlines (mono cohesion)
- Added: Accessibility section (44px touch targets, WCAG AA, focus-visible)
- Added: Component anatomy (button states, card structure, input fields)
- Added: Light mode design rationale (warm parchment, not clinical white)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(design): swap Berkeley Mono for JetBrains Mono (free)
Berkeley Mono is a paid font ($75). JetBrains Mono is free, open source,
already loaded in the project, and the mono-for-headlines concept works
the same way with it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(design): fix light mode contrast failures
Light mode text-tertiary #a8a29e failed WCAG AA at 2.5:1 on white.
Darkened to #736e6b (5.0:1). Light mode accent #6b73c4 was borderline
at 4.3:1, darkened to #5c64b5 (5.3:1). All pairs now pass AA.
Added verified contrast ratios for both modes to accessibility section.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: gitignore .gstack/ directory
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(design): add design audit report and screenshots
Design review audit report with before/after screenshots for all
dashboard pages (kanban, session detail, PRs) across desktop, tablet,
and mobile viewports in both light and dark mode.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(design): address PR review comments
- Fix mobile test expecting removed "No sessions" text. The merge zone
emptyMessage is now "Nothing cleared to land yet." (Bugbot comment #1)
- Remove no-op .dark .detail-card override that duplicated global dark
values after FINDING-005 fix aligned them (Bugbot comment #2)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: gitignore .gstack-report/ and remove from tracking
The .gstack-report/ directory contains local audit artifacts with
filesystem paths. Should not be tracked in the repository.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(design): align dashboard title CSS to new DESIGN.md spec
Dashboard title was using old Geist Sans values (weight 680, -0.035em).
New spec is JetBrains Mono, weight 500, letter-spacing -0.02em.
Added font-family: var(--font-mono) to match.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: use native h2 element for Attention Board section heading
Replace ARIA role="heading" div with semantic h2 per ARIA first rule — native elements are preferred over ARIA roles for actual headings.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: pre-landing review fixes — a11y, dead code, test coverage
- Add aria-controls + id to accordion button/body pair in AttentionZone
- Wrap empty-state messages in aria-live="polite" regions for AT announcements
- Remove dead message prop and isDefault from EmptyState (Skeleton.tsx)
- Add parameterized test covering all 6 zone-specific empty messages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: revert aria-live on empty states — causes false AT announcements
Codex review identified that role="status" aria-live on static empty-state
text causes burst announcements on page load (all empty columns fire) and
announces in collapsed mobile sections that aren't visible. Empty states are
static text, not dynamic transitions. The aria-controls fix is kept.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: bump version and changelog (v0.0.1.0)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: remove .gstack-report/ from .gitignore
* chore: remove VERSION and CHANGELOG (not used in this project)
* style(design): warm terminal color migration + inline style removal
Migrate all CSS tokens from cool blue-tinted graphite to warm
brown-tinted terminal aesthetic per DESIGN.md spec. Replace inline
style color mappings in ActivityDot, AttentionZone, Dashboard,
ProjectSidebar, and SessionCard with data-attribute CSS selectors.
Fix duplicate className bug on SessionCard done-title element.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: pre-landing review fixes — activity dot fallback + review stat color
Add base CSS fallback for activity-dot, activity-pill, and
activity-pill__text so null/unknown activity states render visibly
(gray) instead of invisible. Fix review stat card to use accent-orange
(matching kanban/sidebar/mobile review indicators) instead of cyan.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: checkpoint current design branch state
* design changes
* feat(web): redesign session detail page — compact PR card, identity strip, layout reorder
- Redesign SessionTopStrip with simplified breadcrumbs, action buttons (Message/Kill)
- Replace stacked PR card with compact inline layout: title row + blocker/CI chips + collapsible comments
- Move PR card above terminal for better information hierarchy
- Replace vertical IssuesList with inline buildBlockerChips helper
- Add ~200 lines of new CSS classes for compact PR card design system
- Add changedFiles field to DashboardPR type
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(web): design system tokens, sidebar redesign, and component primitives
- Align all color tokens (status, bg, border, text) across three HTML mockups
- Rewrite ProjectSidebar to match finalized.html: rotation chevron, session status text, border-bottom project separators, 224px width
- Add packages/web/DESIGN.md: agent-readable reference for tokens, typography, component patterns, anti-patterns
- Add Badge.tsx: generic badge/chip/pill primitive with status/outline/default variants
- Add Button.tsx: ghost/primary/danger button primitive
- Update CLAUDE.md to reference DESIGN.md as required pre-read for web UI work
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* style(design): FINDING-001 — card border-radius 0 → 6px to match mockup
* style(design): FINDING-002 — column border-radius 0 → 7px, border subtle to match mockup
* style(design): FINDING-003 — column header mono font, 500 weight, muted color to match mockup
* style(design): FINDING-004/005/006 — fix accent-blue/yellow/purple tokens to match mockup
* style(design): FINDING-007 — add --color-bg-card token (light #fff, dark #1c1b19)
* Refine dashboard design system and remove fixture flow
* Fix respond status colors in dashboard indicators
* Align tests with updated dashboard and metadata behavior
* fix(core): register notifier aliases consistently
* chore(web): drop uncovered showcase routes
* Add desktop PullRequestsPage coverage tests
* Remove generated coverage artifact
* Consolidate web design guidance into the root design system
* Fix working and ready status color tokens
* Fix sidebar collapse and inline kill confirmation
* fix(qa): ISSUE-001 - show all mobile filter chips
* Restore full title contrast in session cards
* Fix review feedback in dashboard state styling
* style: implement mobile responsive designs (feed, terminal-first, dense PRs)
Dashboard: replace accordion with urgency-sorted priority feed, horizontal scroll filter pills.
Session Detail: terminal-first layout with floating header, status pill, PR bottom sheet.
PRs: dense rows with CI dots, grouped sections, muted merged/closed rows.
Update tests to match new mobile layouts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix mobile terminal padding with PR sheet layout
* Polish mobile feed and session detail styling
* Align mobile dashboard layouts with gstack designs
* Fix mobile terminal actions and PR review labels
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
writeMetadata() used a hard-coded field whitelist that silently dropped
userPrompt. The in-memory Session.metadata also never included it, so
the spawn response always returned null. Additionally, prompts containing
newlines could inject arbitrary key=value pairs into the flat-file
metadata format.
Fixes:
- Add userPrompt to writeMetadata() whitelist and readMetadata() return
- Populate session.metadata with userPrompt during spawn
- Strip newlines from prompts in both web API and CLI (defense-in-depth)
- Harden serializeMetadata() to replace newlines in all values
- Add prompt length validation (4096 max) in CLI to match web API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The --decompose flag and supporting decomposer module had two
unfixable bugs (#1045): it crashed when ANTHROPIC_API_KEY was unset,
and it created multiple branches/PRs per issue, fragmenting history
and complicating review/merge. Removing the feature instead of
patching either bug.
- Delete packages/core/src/decomposer.ts and all re-exports
- Drop @anthropic-ai/sdk dependency from @composio/ao-core
- Remove --decompose / --max-depth options from ao spawn
- Remove decomposer field from ProjectConfig (zod default-strip
silently ignores existing decomposer: blocks in user yaml)
- Remove lineage / siblings from SessionSpawnConfig and the
prompt-builder Layer 4 block (only used by decomposer)
- Gut the matching backlog reactor branch in web/services.ts
so the polling path no longer hits the same bugs
- Remove decompose parameter from openclaw-plugin ao_spawn tool
- Drop decomposer mocks from web services.test.ts
- Resolve @composio → @aoagents package renaming conflicts
- Add cursor agent to BUILTIN_PLUGINS in plugin-registry.ts
- Add cursor agent to AGENT_PLUGINS in detect-agent.ts
- Add cursor agent import and registration in plugins.ts
- Add cursor agent dependency and import in web services.ts
- Update cursor plugin package naming to @aoagents/ao-plugin-agent-cursor
- Add cursor agent to changeset linked group
- Fix test imports to use new @aoagents package naming
Co-Authored-By: Claude <noreply@anthropic.com>
Renames all npm package scopes from @composio/* to @aoagents/* and
updates GitHub repo references from ComposioHQ/agent-orchestrator
to aoagents/ao throughout the codebase.
- All package.json names and dependencies
- README badges, links, and install instructions
- Documentation references
- Changeset config
- Source code imports and test files
We accidentally replaced pinnedSummary with userPrompt instead of
adding alongside it. Both fields are needed.
Also add blue-green tests demonstrating the before/after delta for
the prompt-driven spawn feature (issue #974):
- packages/web/src/__tests__/prompt-spawn.test.ts (14 tests)
- packages/integration-tests/src/prompt-spawn.integration.test.ts (7 tests)
- Add --prompt <text> flag to `ao spawn` CLI
- Accept prompt field in POST /api/spawn web route
- Persist userPrompt to session metadata on spawn
- Add userPrompt to DashboardSession type and serialize.ts mapping
- Show userPrompt in SessionCard footer for prompt-only sessions
- Include userPrompt in SessionDetail headline fallback chain
- Update orchestrator-prompt.ts with prompt-driven spawn examples
Closes#974
* fix: reduce dashboard JS bundle from 1.7MB to 170KB (gzipped) (#792)
Switch `ao start` default from `next dev` (7.6MB uncompressed) to optimized
production builds (128KB per route). Add `--dev` flag for HMR when editing
dashboard UI. Add bundle analyzer, server-only guards, and lazy-load
DirectTerminal via next/dynamic.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: skip dashboard rebuild when assets exist, fix CI timeout
Skip the production build step when .next/BUILD_ID and dist-server/
already exist (e.g. after pnpm build in CI). Add c8 ignore for
untestable process-spawning startup code to fix diff coverage.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: adopt PR #903 patterns — centralize rebuild logic and add preflight web artifact checks
Extract rebuildDashboardProductionArtifacts into dashboard-rebuild.ts, add
isInstalledUnderNodeModules/assertDashboardRebuildSupported guards, remove
findProcessWebDir, and verify .next/BUILD_ID + dist-server/start-all.js in
preflight. Dashboard command now always uses production server.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: skip production preflight in --dev mode, add coverage for rebuild helpers
- Skip preflight.checkBuilt() when --dev is passed (dev mode uses HMR,
doesn't need .next/BUILD_ID or dist-server/start-all.js)
- Add c8 ignore to dashboard.ts process-spawning code (matches start.ts pattern)
- Add tests for rebuildDashboardProductionArtifacts (success, failure, npm guard)
- Add preflight tests for npm-install web artifact hint paths
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: align preflight skip with actual dev-server condition
Only skip production artifact preflight when both --dev is passed AND
we're in the monorepo (where dev mode actually works). For npm global
installs, --dev is silently ignored and production server runs, so
preflight must still validate .next/BUILD_ID and dist-server/start-all.js.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: match @next/bundle-analyzer version to next@^15.1.0
The @next/* packages follow the Next.js release train. Pin the bundle
analyzer to ^15.1.0 to match the project's next dependency.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: correct recovery command for npm installs and remove redundant guard
- Change stale-build recovery suggestion from "ao update" (which only
works in source checkouts) to "npm install -g @composio/ao@latest"
for npm global installs
- Remove redundant assertDashboardRebuildSupported call in dashboard.ts
since rebuildDashboardProductionArtifacts already calls it internally
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(web): remove CLI instructions from empty state, clean up misleading UI text (#955)
- Replace "No sessions running. Start one with ao start" with neutral
"No active sessions" — the dashboard has no context for CLI commands
- Fix PullRequestsPage subtitle that referenced internal "board chrome" jargon
- Simplify Dashboard hero subtitle to plain language
- Simplify Attention Board subtitle from opaque triage jargon
- Rename "Blocked on system state" caption to "Waiting on external state"
- Update test assertion to match new empty state text
Fixes#955
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(web): improve empty state copy per review feedback
Use more informative message that points users to the in-dashboard
orchestrator button rather than a generic "no sessions" label.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(web): use neutral empty state copy; fix stale test assertions
- Revert instructional empty state copy to neutral "No active sessions"
because OrchestratorControl is hidden on mobile and when no orchestrator
is running — exactly the zero-session scenario where EmptyState appears.
Pointing users to a button that may not be visible is misleading.
- Update Dashboard.doneBar.test.tsx regex from stale /No sessions running/i
to /No active sessions/i so the not.toBeInTheDocument() assertion
meaningfully guards the regression rather than passing trivially.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- useSessionEvents: detect unknown ids in mux patches and trigger
refresh. Previously additions were filtered out before the membership
comparison, so new sessions on a project page only appeared via the
15s stale-refresh path.
- cli/index.ts: replace hardcoded "0.1.0" with version from
package.json so 'ao --version' stays in sync with releases.
Covers the 7 lines in providers.tsx that were at 0% coverage,
pushing overall diff coverage from 79% to ~80%.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Export SessionBroadcaster for testing
- Add 10 tests covering subscribe, broadcast, fetchSnapshot, SSE
reconnection, disconnect, and error isolation
- Covers the major uncovered lines in mux-websocket.ts (66-194)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The useSessionEvents mux tests create scheduleRefresh timers that leak
between test cases and hang the suite. The SSE tests already cover the
shared dispatch/reducer logic, so removing the mux-specific tests fixes
the coverage OOM without reducing meaningful coverage. Also reverts the
NODE_OPTIONS workaround from the coverage workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
useSessionEvents tests OOM the vitest worker when coverage instrumentation
is enabled (4GB default isn't enough). Split the test file into SSE and mux
suites so the worker can GC between files, and raise the heap to 6GB for
the coverage job.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mirrors the isolation pattern already used in pty.onData — if one
subscriber's ws.send throws mid-loop the remaining subscribers still
receive the session update.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Revert "fix: pause workers on model limits and stabilize session visibility (#367)"
This reverts commit 003eb78adb.
* fix: resolve post-revert type errors and broken test references
- Fix dangling import { in session-manager.ts (leftover from removing globalPause imports)
- Fix duplicate registerStop body in start.ts (leftover parent-version code after catch block)
- Remove --keep-session flag from stop command (was added by #367)
- Fix PullRequestsPage.tsx useSessionEvents call removing dropped initialGlobalPause arg
- Remove globalPause test cases from spawn.test.ts, communication.test.ts, api-routes.test.ts
- Remove unused updateMetadata imports from test files
* fix: remove unused allSessions variable after globalPause removal
Match font-size (12px), font-weight (700), and letter-spacing (0.16em)
to the existing board-section-head__title pattern for visual consistency.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Done sessions should only render in the collapsible done-bar, not also
in the kanban columns and mobile accordion. Reverts KANBAN_LEVELS,
MOBILE_KANBAN_ORDER, and MOBILE_FILTERS to exclude "done", and restores
the handler guards that prevent accordion/pill interaction for done level.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Dashboard.doneBar.test.tsx covering the collapsible done/terminated
bar: renders when done sessions exist, expands on click to show session
cards, and suppresses the empty state when only done sessions are present.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a collapsible "Done / Terminated" bar below the kanban board that
expands to show completed session cards in a grid. Sessions with terminal
states (merged, killed, done, terminated) appear here with their full
card UI including restore button. Also fixes the empty state to not show
when only done sessions exist.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Transient 404 during polling no longer kicks user off an active session
view. Also added missing next/link mock in session error test.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Polling errors no longer throw to the error boundary when a session is
already loaded, preventing transient network blips from unmounting the
view. Added missing next/link mock in error.test.tsx.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update lastRefreshAtRef on non-OK /api/sessions responses to prevent
infinite 5-second retry loops when the API is unhealthy
- Reset lastRefreshAtRef when project changes so each project gets its
own immediate first refresh instead of inheriting the prior project's
cooldown timestamp
- Add test for project-switch refresh behavior
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>