Commit Graph

107 Commits

Author SHA1 Message Date
harshitsinghbhandari bcdda4b9ba fix: address PR #1300 requested changes 2026-04-18 11:13:53 +05:30
harshitsinghbhandari 5f3cdf4e5e fix: remove unused TERMINAL_STATUSES import
Fixes CI lint error in dashboard-page-data.ts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-18 00:58:27 +05:30
harshitsinghbhandari 0d03c46ca5 Merge upstream/main into session/aa-22-lifecycle-fixes
Resolved conflicts in:
- packages/web/src/lib/types.ts (merged canonical type imports with DashboardAttentionZoneMode)
- packages/web/src/lib/dashboard-page-data.ts (kept upstream imports)
- packages/web/src/components/Dashboard.tsx (kept upstream mobileKanbanOrder)

Updated getAttentionLevel to support mode parameter from upstream
while preserving lifecycle-aware helper functions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-18 00:53:06 +05:30
Ashish Huddar 237c99f76e
feat(web): collapse attention zones to 4 with 5-zone feature flag (#1202)
* feat(web): collapse attention zones to 4 with feature flag for 5 (#1201)

Simplify the dashboard to a 4-zone kanban by default (WORKING,
PENDING, ACTION, READY), merging the former REVIEW + RESPOND
columns into a single ACTION zone that just asks "does the human
need to do something?". The card-level badges still surface the
underlying granular state (ci_failed, needs_input, changes_requested),
so nothing is lost — it just moves off the column header.

Add a `dashboard.attentionZones` config (defaults to "simple") that
opts back into the original 5-zone layout for power users. The
function-level `getAttentionLevel(session, mode)` still defaults to
"detailed" so card-level call sites (SessionCard, BottomSheet,
ProjectSidebar, etc.) keep their granular behavior untouched. Only
the Dashboard kanban and SSE server routes read the config and pass
the mode.

Closes #1201

* fix(web): address PR review feedback on attention zones (#1201)

- Drop .strict() from DashboardConfigSchema (Cursor Bugbot):
  matches other schemas in config.ts so typos in the dashboard
  block gracefully default instead of crashing the whole loader.

- DynamicFavicon: keep `action` at yellow, not red (Codex P2).
  In simple mode, `action` collapses respond + review, which
  means it necessarily catches routine review work (ci_failed,
  changes_requested) that was previously yellow. Escalating to
  red would make every typical PR scream critical. Only the
  detailed-mode `respond` bucket still triggers red.

- useSessionEvents default → "detailed" (Codex P3). The hook
  default now matches getAttentionLevel's default so callers
  that seed with `getAttentionLevel(s)` (no mode) — notably
  PullRequestsPage — stay consistent with their seed after
  the first live SSE/refresh snapshot. Dashboard explicitly
  passes the config's attentionZones to opt into simple mode.

- Expand mobile action chip (Codex P3). When a session
  collapses to `action`, derive the most specific underlying
  cause (needs input, stuck, errored, ci failed, changes,
  waiting, conflicts) instead of falling through to the
  generic "action" label, so mobile users keep the reason to
  intervene.

- DynamicFavicon tests: add cases for `action` staying yellow
  and `respond` still escalating when both are present.

* fix(web): thread attentionZones config through PullRequestsPage (#1201)

Cursor Bugbot caught a deeper version of the same inconsistency
my previous fix didn't fully resolve: the server SSE route uses
`config.dashboard?.attentionZones ?? "simple"`, but PullRequestsPage
was seeding `initialAttentionLevels` and calling useSessionEvents
without passing any mode (falling back to the hook's "detailed"
default). Result: snapshots from the server arrived as "action"/
"merge", then scheduleRefresh recomputed them client-side as
"respond"/"review", and the favicon oscillated between yellow
and red on every refresh cycle.

Fix: plumb pageData.attentionZones through prs/page.tsx into
PullRequestsPage, use it in both the seed and useSessionEvents.
Now the seed, the server SSE, and the client refresh all use the
same mode — stable, no flicker.

* fix(web): accurate action labels for crashed agents + yellow tone (#1201)

Two Cursor Bugbot findings on the action-zone collapse work:

1. [Medium] Mobile chip mislabeled crashed agents as "needs input".
   When an agent's activity is `exited` and the session is in the
   action bucket, the agent has crashed — sending it a message
   won't help, the user needs to restart. Split the label: exited
   → "crashed", blocked → "blocked".

2. [Low] ProjectMetric for Action used tone="error" (red), which
   contradicts the favicon fix's rationale. The action bucket
   catches routine review work (ci_failed, changes_requested)
   that was previously orange/yellow severity; screaming red in
   the project overview grid would have the same cry-wolf problem
   as the favicon did. Use tone="orange" (the less severe of the
   two merged buckets) to match.

* refactor(web): make attentionZones required in useSessionEvents (#1201)

Cursor Bugbot caught that the hook default of "detailed" mismatches
the server SSE route default of "simple" — a latent footgun for any
future caller that forgets to pass the mode explicitly. The exact
oscillation bug I already fixed once for PullRequestsPage would
silently come back on the next page that uses this hook.

Real fix: refactor the hook to take an options object and make
`attentionZones` required with no default. TypeScript now enforces
that every caller explicitly passes the mode the server is using.
You literally cannot call useSessionEvents without supplying it.

Also cleaner: the hook had 6 positional parameters, which is past
the point where an options object helps readability. Dashboard and
PullRequestsPage call sites now read as self-documenting.

* fix(web): address human code review on attention zones (#1201)

Review from i-trytoohard on commit 8d27db79:

1. [Medium] `ZoneCounts` in sessions/[id]/page.tsx had an `action`
   field that was always 0 — the page always computes in detailed
   mode (getAttentionLevel with no mode = detailed), and the
   consumer (`OrchestratorZones` in SessionDetail) never reads
   an `action` field either. Removed the dead field, added a
   `continue` guard for the never-reached "action" case so
   TypeScript narrows the index correctly, and documented the
   intent in a header comment.

2. [Medium] The simple-mode action chip had 10+ sub-conditions
   with no tests. Extracted the label logic into a pure
   `getActionChipLabel(session)` helper and added 16 unit tests
   covering every branch: status-based signals (needs_input,
   stuck, errored, ci_failed, changes_requested), activity-based
   (waiting_input, exited→crashed, blocked), PR-based (failing
   CI, changes_requested, conflicts), precedence between signal
   classes, and the generic fallback.

3. [Low] `LEVEL_LABELS.action` in ProjectSidebar is dead code
   today (sidebar uses detailed mode). Added a comment explaining
   why the entry still exists (TypeScript exhaustiveness on
   `Record<AttentionLevel, string>` + forward-compat).

* fix(web): address inline review on attention zones (#1201)

- Reorder getActionChipLabel to mirror getDetailedAttentionLevel: respond-class
  activity (waiting_input/exited/blocked) now outranks review-class status
  (ci_failed/changes_requested). A crashed agent with changes_requested no
  longer reads as "changes" and hides the crash.
- Paint data-level="action" dot with --color-accent-orange to match the
  favicon's yellow-severity treatment of the collapsed bucket.
- Tighten attentionLevel on the mux boundary (mux-protocol, mux-websocket,
  useSessionEvents) from string to AttentionLevel so invalid values like "none"
  no longer launder through into DynamicFavicon's count.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 22:24:25 +05:30
harshitsinghbhandari 1cbf6579c2 fix: address PR review feedback for session audit trail 2026-04-17 21:06:08 +05:30
harshitsinghbhandari 28ce462ef0 feat: unify session detail auditability and lifecycle stability (#123 #124 #126) 2026-04-17 20:48:02 +05:30
harshitsinghbhandari f1769ec910 fix: address final lifecycle review findings (#122) 2026-04-17 19:52:15 +05:30
harshitsinghbhandari ca8c4cc7ab fix: address lifecycle review feedback (#122)
Keep reconstructed activity and activitySignal coherent, preserve stronger lifecycle states when repeated polls only surface weak evidence, and switch release notes from manual changelog edits to a Changesets entry. This also stabilizes the respond/working path investigated in issue #126.
2026-04-17 19:38:32 +05:30
harshitsinghbhandari dd83a11503 fix: model missing activity evidence explicitly (#122)
Represent missing activity probes as first-class signal states so lifecycle inference only treats valid idle evidence as proof. This prevents false stuck transitions, keeps API/UI lifecycle truth aligned, and makes root monorepo verification deterministic by serializing recursive build and typecheck.
2026-04-17 19:28:56 +05:30
harshitsinghbhandari 08667c8cb5 fix(web): keep closed-unmerged sessions actionable 2026-04-17 14:42:25 +05:30
harshitsinghbhandari da1e2ceae2 fix: restore Next-resolvable serialize types import (#119) 2026-04-17 13:43:26 +05:30
harshitsinghbhandari d3cf4ae3de fix: address PR review comments on stage 5 rollout (#119) 2026-04-17 13:36:09 +05:30
harshitsinghbhandari 690242e379 fix: keep active PR sessions in working lane
Prevent open PR sessions with only  PR truth from being misclassified as pending during the Stage 5 rollout, and add coverage for the regression.
2026-04-17 13:15:11 +05:30
harshitsinghbhandari 88cd9e7ed1 merge: resolve sessions-redone conflicts for stage5
Preserve the split lifecycle observability and UI truth model while retaining the latest sessions-redone PR transition handling and dependency updates.
2026-04-17 13:09:13 +05:30
harshitsinghbhandari 7072143138 feat: expose split lifecycle truth in dashboard
Implement the Stage 5 rollout so API and UI consumers stop depending on one overloaded status and operators can see structured transition evidence without breaking older session metadata.
2026-04-17 13:00:26 +05:30
harshitsinghbhandari b5c969c6b4 fix: address PR review policy regressions (#118) 2026-04-17 11:39:13 +05:30
harshitsinghbhandari a45eb322bb fix: decouple PR truth from worker session policy 2026-04-17 10:44:35 +05:30
Harshit Singh Bhandari 42e9be13a5
Merge pull request #114 from harshitsinghbhandari/plan/stage1-lifecycle-foundation
Plan/stage1 lifecycle foundation
2026-04-16 22:09:41 +05:30
harshitsinghbhandari d466118450 feat(core): add canonical lifecycle persistence foundation 2026-04-15 12:41:06 +05:30
adil 72e3620b8d test: add tests for optional repo across all changed modules
- detect-env: test GitHub/GitLab HTTPS/SSH remote extraction, unknown
  hosts returning null, missing remote, and non-git directories
- repo-validation: test the anchored regex accepts owner/repo, rejects
  empty, lone slash, missing segments, whitespace, and nested paths
- config-validation: test SCM/tracker inference skipped when repo is
  missing or has no slash, and inferred correctly with owner/repo
- scm-webhooks: test eventMatchesProject returns false when project
  has no repo configured
- orchestrator-prompt: existing test covers repo:undefined → "not configured"
- prompt-builder: existing test covers BASE_AGENT_PROMPT_NO_REPO selection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 12:06:09 +05:30
adil c8af50fac2 fix: address all 9 review comments from @illegalcall
1. prompt-builder: gate PR/CI instructions on project.repo — use
   trimmed BASE_AGENT_PROMPT_NO_REPO when no remote configured
2. orchestrator-prompt: gate Quick Start and Available Commands
   sections on project.repo — omit issue/PR commands when absent
3. types.ts: add changeset (minor for ao-core) with migration note
4. config.ts: consistent includes("/") guard for tracker inference
5. start.ts: fail fast with clear error when run in non-git directory
6. start.ts: stricter repo validation regex (requires non-empty
   segments on both sides of slash)
7. start.ts: addProjectToConfig now prompts for repo like
   autoCreateConfig does, with matching warning message
8. scm-webhooks.ts: pre-filter projects without repo in
   findWebhookProjects to skip unnecessary SCM plugin lookups
9. lifecycle-manager.ts: fix GitLab subgroup split — use lastIndexOf
   to correctly handle group/subgroup/repo paths

Closes #1154

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 03:04:12 +05:30
adil 17ea240f68 fix(cli): stop writing broken yaml when `ao start` runs in a new folder
- Make `repo` field optional in ProjectConfig and Zod schema so projects
  without a detected GitHub remote can still load and run
- Remove placeholder `repo: "owner/repo"` from autoCreateConfig() and
  addProjectToConfig() — omit the field entirely when no remote is found
- Always use actual workingDir for `path` instead of unreliable `~/<projectId>`
  fallback for non-git directories
- Add null guards for `project.repo` across SCM plugins, tracker plugins,
  lifecycle manager, webhooks, and prompt builders to prevent crashes when
  repo is not configured

Closes #1154

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 22:13:01 +05:30
Dhruv Sharma 663c61e16d fix: merge main and address review findings for prompt-driven spawn
- 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>
2026-04-11 21:44:57 +05:30
Ashish Huddar af2af115bd
style(design): design review fixes + fresh Warm Terminal design system (#927)
* 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>
2026-04-11 16:30:03 +05:30
Dhruv Sharma ba899f9c30
Merge pull request #1104 from ComposioHQ/feat/issue-1045
refactor: remove ao spawn --decompose feature
2026-04-11 10:22:22 +05:30
Harsh Batheja 3fb2ddf06d refactor: remove --decompose feature entirely
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
2026-04-10 13:02:52 +05:30
harshitsinghbhandari f154f87add fix: merge upstream main and resolve conflicts for cursor agent
- 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>
2026-04-10 11:48:27 +05:30
Prateek 967e864f5a chore: rename @composio scope to @aoagents across all packages
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
2026-04-09 15:59:33 +00:00
harshitsinghbhandari 04f3a7c27f fix(cursor): register plugin in all discovery/resolution layers
Address PR review feedback from #1076 to make Cursor agent fully functional.

## Changes

### Plugin Registration (High Severity Fixes)
- **core/plugin-registry.ts**: Add cursor to BUILTIN_PLUGINS array for config-based resolution
- **cli/plugins.ts**: Import and register cursor in agentPlugins map for getAgent/getAgentByName
- **cli/detect-agent.ts**: Add cursor to AGENT_PLUGINS array for detectAvailableAgents()
- **web/services.ts**: Import and register cursor plugin for dashboard SessionManager/LifecycleManager
- **web/package.json**: Add @composio/ao-plugin-agent-cursor dependency

### Activity Detection Fix (Medium Severity)
- **cursor/index.ts**: Remove overly broad blocked detection patterns (error:/failed:)
  - Compiler errors, test failures, and linter output are normal tool output
  - Terminal-based detection can't distinguish between actionable agent errors and normal output
  - Follow Aider/OpenCode pattern: only Claude Code detects blocked (has native JSONL)
  - Added comment explaining why blocked detection is removed
- **cursor/index.test.ts**: Remove blocked detection test cases

## Why These Changes Are Needed

Before these fixes:
- `defaults.agent: cursor` in config would throw "Unknown agent plugin: cursor"
- `ao spawn --agent cursor` would fail
- Dashboard couldn't resolve cursor agent (SessionManager/LifecycleManager failures)
- `detectAvailableAgents()` never discovered Cursor
- False "blocked" states when agent encountered normal compiler errors

After these fixes:
- Cursor agent fully discoverable and usable via config and CLI
- Dashboard can spawn and manage Cursor sessions
- Activity detection matches other terminal-based agents (Aider, OpenCode)
- No false positives from normal tool output

## Testing
-  cursor plugin tests: 51/51 passing (reduced from 52 due to removed blocked tests)
-  core typecheck: clean
-  web typecheck: clean
-  CLI can import cursor plugin without errors

Addresses: ComposioHQ/agent-orchestrator#1076

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-09 19:17:41 +05:30
Dhruv Sharma aa2177698a feat(spawn): support prompt-driven sessions without a tracker issue (#974)
- 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
2026-04-09 18:43:55 +05:30
Dhruv Sharma c00618048f
Merge pull request #887 from fastestdevalive/feat/single-socket 2026-04-09 18:30:51 +05:30
Ashish Huddar 48d655d932
fix: reduce dashboard JS bundle from 1.7MB to 170KB (#792) (#928)
* 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>
2026-04-07 16:12:51 +05:30
Gaurav Bhola 0613ac2970 Merge remote-tracking branch 'upstream/main' into feat/single-socket
# Conflicts:
#	packages/cli/__tests__/commands/start.test.ts
#	packages/cli/src/commands/start.ts
#	packages/core/src/__tests__/lifecycle-manager.test.ts
#	packages/core/src/agent-selection.ts
#	packages/core/src/lifecycle-manager.ts
#	packages/core/src/plugin-registry.ts
#	packages/core/src/recovery/validator.ts
#	packages/core/src/session-manager.ts
#	packages/web/src/__tests__/api-routes.test.ts
#	packages/web/src/app/sessions/[id]/page.tsx
#	packages/web/src/components/Dashboard.tsx
#	packages/web/src/components/PullRequestsPage.tsx
#	packages/web/src/components/__tests__/Dashboard.doneBar.test.tsx
#	packages/web/src/hooks/useSessionEvents.ts
2026-04-07 03:37:36 -07:00
Harsh Batheja 649fc67f6a revert: remove model rate-limit pause functionality (PR #367) (#908)
* 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
2026-04-06 22:52:47 -07:00
Ashish Huddar a63aaf0652 test: improve diff coverage for TTFB fast-path changes
Cover enriched done-card PR detail panel (SessionCard lines 361-377),
non-OK response timestamp update (useSessionEvents lines 180-181),
and enrichSessionsMetadataFast function (serialize lines 369-383).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:49:09 -07:00
Ashish Huddar 67371d2c6f fix: polish shimmer states, terminal PR inference, and gitignore .gstack
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:49:09 -07:00
Ashish Huddar a815fd1196 refactor: extract settlesWithin to shared async-utils module
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:48:50 -07:00
Ashish Huddar e38c7e947f Restore SSR metadata timeout 2026-04-06 22:48:50 -07:00
Ashish Huddar 5cb66a9b40 Infer terminal PR state without SCM 2026-04-06 22:48:50 -07:00
Ashish Huddar 27ce7d56db Restore parallel session metadata enrichment 2026-04-06 22:48:50 -07:00
Ashish Huddar e0b216c369 Add diff coverage for dashboard fast path 2026-04-06 22:48:50 -07:00
Ashish Huddar 1825e6a880 Improve dashboard fast-path session hydration
Treat unenriched PRs as a first-class state in the dashboard so SSR can
return fast-path session data without showing misleading PR status, size,
or alert states. Add shimmer placeholders for partial PR data, avoid
classifying unenriched PRs as merge/review/pending work, and ensure the
first SSE snapshot triggers an immediate refresh without failure loops.
2026-04-06 22:48:50 -07:00
harshitsinghbhandari 074b7f2ef0 fix: replicate terminal session filtering 2026-04-06 22:48:01 -07:00
harshitsinghbhandari 49426ccddb fix comments 2026-04-06 22:48:01 -07:00
harshitsinghbhandari 9c0245a33a fix: correct tmux target fallback and deduplicate orchestrator listing
- Fix tmux target to use session ID when runtimeHandle is missing,
  preventing references to non-existent sessions
- Extract mapSessionsToOrchestrators helper to eliminate duplicate
  orchestrator listing logic between page.tsx and API route

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 22:48:01 -07:00
Harsh Batheja 7e53542f9d feat: support multiple concurrent orchestrators with isolated worktrees (#870)
* feat: support multiple concurrent orchestrators with isolated worktrees

- Each orchestrator session gets a numbered ID ({prefix}-orchestrator-N)
  and an isolated git worktree, replacing the single shared orchestrator
- reserveNextOrchestratorIdentity atomically reserves the next available
  number and detects conflicting project prefix configurations early
- isOrchestratorSession / isOrchestratorSessionName accept optional
  allSessionPrefixes for cross-project false-positive prevention
- getProjectPause and resolveGlobalPause track the longest active pause
  across all concurrent orchestrators instead of returning the first found
- cleanupWorktreeAndMetadata helper used consistently on all failure paths
  including post-launch; system prompt file included in cleanup
- pollBacklog, status.ts, ProjectSidebar, sessions page, global-pause,
  project-utils, serialize, and sessions API route all pass
  allSessionPrefixes to isOrchestratorSession
- Web sessions/[id]/page.tsx fetches project prefix map and passes it
  through prefixByProjectRef to avoid stale closure in fetchProjectSessions

* fix: seed sseAttentionLevels from fresh sessions on full refresh

When scheduleRefresh dispatches a reset action, derive sseAttentionLevels
from the freshly fetched sessions using getAttentionLevel. This clears
phantom entries for removed sessions and seeds correct levels for new
sessions, preventing stale favicon color and attention counts until the
next SSE snapshot.

* fix: merge duplicate @/lib/types imports into single import statement

Combining the separate import type and value import from @/lib/types
into one import to satisfy the no-duplicate-imports lint rule.
2026-04-06 22:48:01 -07:00
harshitsinghbhandari f9d991d4fd fix: handle optional plugin field in CLI and web packages
Update all usages of project.tracker.plugin and project.scm.plugin
to use optional chaining since the plugin field is now optional
when package or path fields are specified.

Files updated:
- CLI: doctor.ts, status.ts, verify.ts
- Web: issues/route.ts, verify/route.ts, scm-webhooks.ts,
       serialize.ts, services.ts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 22:46:29 -07:00
Gaurav Bhola 2e5ee30fcf feat(web): add multiplexed WebSocket protocol and mux server
Implements backend multiplexed WebSocket server on /mux endpoint:
- Add mux-protocol.ts with ClientMessage and ServerMessage types
- Create TerminalManager class for managing PTY processes independently
- Implement mux-websocket.ts with attachMuxWebSocket() function
- Wire mux server into existing direct-terminal-ws server
- Support multiple terminals over single persistent WebSocket connection
- Implement 50KB ring buffer for background terminal output
- Add heartbeat and reconnection logic

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 22:46:29 -07:00
Ashish Huddar 1bb80ef67c
feat: stable session titles via pinnedSummary metadata (#946)
* feat(core): pin first quality summary for stable session titles

When a session's first non-fallback summary is obtained, persist it to
metadata as pinnedSummary. This prevents the dashboard title from drifting
as the agent generates new summaries each turn.

Changes:
- Add pinnedSummary to SessionMetadata type
- Serialize/deserialize in writeMetadata/readMetadata
- Pin in lifecycle manager's checkSession (correct write path)
- Propagate through restore path

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(web): stable session titles via unified getSessionTitle

Reorder title fallback: PR > issue > branch > summary (was: summary > issue > branch).
Replace inline getSessionHeadline with shared getSessionTitle in both
SessionDetail and page.tsx for consistent behavior across all components.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: coverage for pinnedSummary and title fallback chain

9 new tests:
- 3 serialize tests: pinnedSummary priority over agent/metadata summary
- 5 lifecycle-manager tests: pinning logic guards and error handling
- 1 metadata test: pinnedSummary serialization in writeMetadata

Updated existing tests to match new title fallback order.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: fix mobile title expectations

* fix(web): use pinnedSummary only for title selection, not dashboard.summary

Previously, pinnedSummary was assigned to dashboard.summary in
sessionToDashboard(), causing two problems:
1. enrichSessionAgentSummary() never fetched newer summaries because
   dashboard.summary was already set
2. Every UI surface rendering session.summary showed the stale pinned
   value instead of live agent output

Fix: pinnedSummary is now read only by getSessionTitle() via
session.metadata["pinnedSummary"], keeping title stable without
freezing the live summary field. dashboard.summary always reflects the
current agentInfo or metadata summary.

Addresses review comment on PR #946.

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 09:52:48 +05:30
Harsh Batheja 9ac659066a
revert: remove model rate-limit pause functionality (PR #367) (#908)
* 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
2026-04-06 14:58:41 +05:30