Commit Graph

281 Commits

Author SHA1 Message Date
Priyanshu Choudhary 5da9bedf5c fix(web): prevent nft EPERM on Windows home directory junction points
Next.js nft (Node File Tracer) scans homedir() at build time and hits
EPERM on Windows junction points (e.g. Application Data). Adds homedir()/**
to TraceEntryPointsPlugin.traceIgnores on Windows server builds.
2026-04-10 01:09:32 +05:30
Priyanshu Choudhary 117b10aae9 fix(windows): QA fixes — dashboard spawn, shellEscape, tmux hint, PID fallback
T04: resolveNextBin() skips POSIX .bin/next shim on Windows; invokes
next/dist/bin/next via process.execPath instead (ENOENT fix).

T18: shellEscape() branches on isWindows() — PowerShell uses '' doubling,
Unix uses POSIX '\'' escaping. All 4 agent plugins benefit automatically.

T06 secondary: tmux attach hint in `ao spawn` output gated behind
runtimeName === "tmux" (process runtime has no tmux session).

T06/T11: runtime-process destroy() and isAlive() fall back to
handle.data.pid when the in-memory processes Map is empty — fixes
cross-process CLI calls (ao session ls / ao session kill).
2026-04-10 01:09:30 +05:30
Priyanshu Choudhary 34b4d29db5 fix: project builds on Windows
Replace Unix cp -r with Node.js fs.cpSync in CLI build script.
Add webpack snapshot config to prevent Next.js scanning Windows junction points.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 01:03:49 +05:30
Dhruv Sharma c00618048f
Merge pull request #887 from fastestdevalive/feat/single-socket 2026-04-09 18:30:51 +05:30
Ashish Huddar 0b49ff352f fix(web): display PR details card above terminal in session detail page
Closes #1024

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 02:08:05 +05:30
suraj_markup ed21aae631
Merge pull request #886 from fireddd/fix/web-tracker-linear-bundling
fix: add @composio/core to serverExternalPackages to fix dashboard 500
2026-04-07 23:47:01 +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
Ashish Huddar 7fff3b940e
fix(web): remove CLI instructions from empty state, clean up misleading UI text (#957)
* 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>
2026-04-07 14:44:07 +05:30
Gaurav Bhola 5cb17c081a test(web): add mux refresh test for useSessionEvents 2026-04-06 23:02:30 -07:00
Gaurav Bhola 1fa88cdf9d fix(web): mux additions trigger refresh; cli: read version from package.json
- 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.
2026-04-06 22:53:21 -07:00
Gaurav Bhola a95f0ca881 test(web): add Providers component test for diff coverage
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>
2026-04-06 22:52:53 -07:00
Gaurav Bhola a25db10523 test(web): add SessionBroadcaster tests and improve diff coverage
- 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>
2026-04-06 22:52:53 -07:00
Gaurav Bhola 11103f0e9e fix(ci): remove mux test file that causes OOM in coverage runs
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>
2026-04-06 22:52:51 -07:00
Gaurav Bhola 047880435c fix(ci): prevent OOM in web coverage by splitting tests and raising heap limit
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>
2026-04-06 22:52:51 -07:00
Gaurav Bhola 6f3aec703e fix(web): wrap session broadcast subscriber callbacks in try-catch
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>
2026-04-06 22:52:47 -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 00045973fb style: align done bar typography with board section head
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>
2026-04-06 22:49:51 -07:00
Ashish Huddar c1f6d00c59 fix: remove done from kanban/mobile arrays to prevent double rendering
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>
2026-04-06 22:49:51 -07:00
Ashish Huddar cc07cb028d test: add done bar coverage for diff-coverage CI gate
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>
2026-04-06 22:49:51 -07:00
Ashish Huddar 5a5624f154 fix: restore done/terminated sessions column on kanban board
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>
2026-04-06 22:49:51 -07:00
Ashish Huddar 19deb059ab fix(web): guard polling 404 with hasLoadedSessionRef and add missing link mock
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>
2026-04-06 22:49:51 -07:00
Ashish Huddar c1feb90fe2 fix(web): preserve session view on polling errors and add missing link mock
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>
2026-04-06 22:49:51 -07:00
Ashish Huddar eeda416055 feat(web): add dashboard error boundaries 2026-04-06 22:49:51 -07:00
Ashish Huddar ab8250fe7d fix(cli,web): stabilize isolated workspace checks 2026-04-06 22:49:51 -07:00
Ashish Huddar d956c52eef feat(web): add session-specific not-found.tsx for 404 handling
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:49:51 -07:00
Ashish Huddar 694332d789 feat(web): add global not-found.tsx for 404 handling
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:49:51 -07:00
Ashish Huddar fa73a9fb7f feat(web): add session loading.tsx with spinner for route transitions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:49:51 -07:00
Ashish Huddar 6bfc239af0 feat(web): add global loading.tsx with spinner for route transitions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:49:51 -07:00
Ashish Huddar c473088373 fix: prevent retry storms and stale refresh on project switch
- 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>
2026-04-06 22:49:51 -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 1116363a9b fix: clean up OrchestratorSelector tests and add spawn resilience
- Remove phantom `projects` prop from test setup (was dead code)
- Deduplicate test coverage: consolidate component tests into
  OrchestratorSelector.test.tsx, keep only page route tests in
  orchestrators.test.tsx
- Fix useRouter mock to capture and assert router.push calls
- Add finally block to handleSpawnNew for resilience (ensures
  isSpawning is reset even if router.push fails)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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
harshitsinghbhandari 63a796274a refactor: deduplicate Orchestrator interface
Export Orchestrator interface from OrchestratorSelector component
and import it in page.tsx to avoid silent divergence risk.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 22:48:01 -07:00
harshitsinghbhandari 6778c280e1 test: add edge case tests for formatRelativeTime
Add tests to verify proper handling of:
- Invalid date strings (returns "Unknown")
- Future timestamps (returns "Just now")
- Null dates (returns "Unknown")

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 22:48:01 -07:00
harshitsinghbhandari 672f2ad6f0 fix: remove unused projects prop from OrchestratorSelector
The projects prop was declared and passed but never used, causing
unnecessary data fetching and serialization. Removed the prop from
the component interface, page, and tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 22:48:01 -07:00
harshitsinghbhandari 81258468ce fix: handle invalid and future dates in formatRelativeTime
Guard against NaN timestamps from invalid ISO date strings and handle
future timestamps gracefully by returning "Just now" instead of
negative values.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 22:48:01 -07:00
harshitsinghbhandari 10163f0ec2 fix tests 2026-04-06 22:48:01 -07:00
harshitsinghbhandari 9d4d3412fa fix: prevent ao start from spawning duplicate orchestrators
When ao start is run and existing orchestrator sessions exist for the
project, the CLI now skips spawning a new one. Instead:

- Detects existing orchestrator sessions before spawning
- Opens the dashboard to a new /orchestrators page for session selection
- Users can resume an existing orchestrator or start a new one

Changes:
- packages/cli/src/commands/start.ts: Check for existing orchestrators,
  redirect to selection page if found
- packages/web/src/app/api/orchestrators/route.ts: Add GET endpoint to
  list orchestrators for a project
- packages/web/src/app/orchestrators/page.tsx: New page for orchestrator
  selection
- packages/web/src/components/OrchestratorSelector.tsx: UI component for
  selecting or spawning orchestrators
- packages/web/src/components/__tests__/OrchestratorSelector.test.tsx:
  Tests for the selector component

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