Skip to content

chore: merge upstream main into gb-personal (April 2026 catchup)#40

Open
fastestdevalive wants to merge 397 commits into
mainfrom
gb-personal
Open

chore: merge upstream main into gb-personal (April 2026 catchup)#40
fastestdevalive wants to merge 397 commits into
mainfrom
gb-personal

Conversation

@fastestdevalive
Copy link
Copy Markdown
Owner

Summary

  • Merges ~137 upstream commits from ComposioHQ/agent-orchestrator main into gb-personal
  • Preserves all gb-personal UI features: DashboardGB, DirectTerminalGB, SessionCardGB, file tree, markdown preview, cursor/amp agents, MuxProvider, mobile touch, xterm v6, sidebar UX
  • All unit tests passing (600+ tests across core, plugins, CLI)
  • Build and typecheck clean

Key upstream changes included

  • PowerConfig / power management support in OrchestratorConfig
  • branchName on Issue, userPrompt on SessionMetadata
  • global-pause feature reverted upstream → self-contained web-local copy created
  • Sub-session methods removed from SessionManager interface
  • Layered prompt builder: Session Lifecycle, Git Workflow, PR Best Practices sections
  • Lifecycle reactions (auto send-to-agent on CI failure)
  • isKilledSession / SessionAttentionLevel / "killed" AttentionLevel
  • Plugin improvements: opencode TTL session cache, aider/codex activity detection
  • scm-gitlab / tracker-gitlab new plugins
  • CI/CD workflow updates, docs cleanup

Conflict resolution policy applied

  • Web UI components → --ours (gb-personal forks preserved)
  • Core / CLI engine → --theirs (upstream improvements taken)
  • Manual merge: types.ts, opencode plugin, format.ts, global-pause

Test plan

  • Spawn a new session and verify it reaches working state
  • Verify terminal output shows correctly in DashboardGB
  • Open session detail — file tree, markdown preview, DirectTerminalGB all render
  • Cursor and Amp agent options appear in new-session form
  • CI failure reaction fires and sends prompt to agent (if configured)
  • Mobile view: sidebar and PR cards render correctly
  • Dark theme preserved throughout

🤖 Generated with Claude Code

gautamtayal1 and others added 30 commits April 2, 2026 08:24
Add tests for runtime.isAlive, workspace.destroy, and runtime.destroy
error handling to ensure cleanup continues despite partial failures.

Fixes test coverage gaps in validator and cleanup actions.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add comprehensive tests for retry logic including retry count,
delays, error propagation, early exit, and not-found handling.

Fixes Issue #5

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add top-level "default" key fallback in CLI's resolvePackageExportsEntry
  to match core's plugin-registry.ts (fixes local plugin resolution for
  packages using exports: { "default": "./dist/index.js" })
- Remove dead exports: MARKETPLACE_PLUGIN_CATALOG, printPluginList,
  getAgentFromRegistry, resolveInstalledPluginSpecifier
- Fix incomplete string escaping in plugin scaffold (backslash/newline)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove unused `resolve` import from node:path
- Add `{ cause: err }` to re-thrown errors (preserve-caught-error rule)
- Fix import() type annotation in plugin test (consistent-type-imports)

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

- Remove unused printPluginList wrapper (all callers use printPluginListFromCatalog directly)
- Remove unused getAgentFromRegistry export (all callers use getAgentByNameFromRegistry)
- Validate SHELL env var starts with / before passing to spawnSync
- Add shape validation for openclaw-health.json parsed content

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fastestdevalive and others added 24 commits April 11, 2026 16:35
…-one

feat(web): flatten workspace theme + markdown code-block affordances
… prose dim

Switch markdown headings to the 100gb-minimalist white→grey brightness
ladder (primary→secondary decay, no hue). Add a .dark-scoped prose dim
that drops body text (p, li, td) to text-secondary so h1, bold and
inline code at text-primary visibly pop above surrounding paragraphs
in dark mode without touching light mode. Keep h5/h6 one step brighter
than the new body baseline so smallest headings stay distinguishable.
Bold gains a subtle highlight-strip background (monochrome) for
in-prose emphasis.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-one

feat(web): refine markdown preview — monochrome heading ladder + dark prose dim
Bug 1 (feature never fires): the stub session renders with metadata:{}
before the real session loads, so lastSessionRef is set to the session id
during the stub render and the guard blocks re-reading when real metadata
arrives. Fix: add fileRestoredRef that tracks whether we've populated
restoredFile for this session. The else-if branch re-checks on subsequent
metadata updates until a file is found.

Bug 2 (user can't collapse preview pane): ensurePreviewVisible is a
useCallback with [collapsed, toggleCollapsed] in its deps, so its identity
changes on every toggle. The [restoredFile, ensurePreviewVisible] effect
therefore re-fires and re-expands the preview every time the user collapses
it. Fix: gate the call with ensuredPreviewForFileRef so ensurePreviewVisible
is called at most once per unique restoredFile value.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…prompt

The TUI's --prompt flag only pre-fills the input box and does not
auto-submit the message to the LLM. Pass the prompt as a positional
message arg to `opencode run` so it is submitted immediately before
the TUI opens for continued interaction.

Without this fix, every new OpenCode session silently dropped the
initial task prompt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
OpenCode's TUI --prompt flag only pre-fills the input box without
auto-submitting. The previous approach of passing the prompt inline
(either via --prompt on TUI or as a positional arg to opencode run)
either silently drops the prompt or blocks the terminal while the LLM
responds before the TUI opens.

The correct fix — matching how Claude Code works — is:
- Set promptDelivery: "post-launch" so session-manager delivers the
  task prompt via runtime.sendMessage() (tmux key injection) after the
  TUI starts
- opencode run --command true creates the session quickly; TUI opens
  immediately so the user sees it right away
- System-level context (orchestrator systemPromptFile/systemPrompt)
  still goes to opencode run as the first message, since the
  post-launch mechanism only handles config.prompt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Post-launch sendMessage fails because the multi-step launch script
(opencode run | node → fallback → exec opencode) takes 5-10s and the
typed prompt text gets consumed by the shell pipeline, not the TUI.

Instead, pass the prompt as a positional arg to `opencode run` so it's
submitted to the LLM during session creation. The capture script now
exits immediately after finding the session_id (SIGPIPE is fine — the
session and prompt are already submitted).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dist-server/ was accidentally committed on this branch. Remove it from
tracking and add it to .gitignore.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Opus review incorrectly identified a stub-session bug that doesn't
exist: the workspace page shows a loading screen until the real session
is fetched, so WorkspaceLayout always renders with full metadata on
first mount. The fileRestoredRef + else-if branch was solving a phantom
problem.

The ensurePreviewVisible effect on restoredFile also caused a regression:
ensurePreviewVisible's identity changes with collapsed state, so the
user could never collapse the preview pane. Removing it entirely — the
preview pane is visible by default, and if the user collapsed it we
should respect that choice.

Net change from baseline: 3 lines added to read metadata hint as
fallback when sessionStorage is empty. No new refs, no new effects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix(agent-opencode): deliver initial prompt via opencode run
fetchOpenCodeSessionList() spawns a new `opencode` process on every
call with no caching. SSE polls list() every 3s, lifecycle every 30s,
plus API routes — each triggering a fresh subprocess whose V8 JIT
creates temp files that never get cleaned up (250GB in 4 hours).

Add a 10s TTL cache so repeated calls reuse results. Delivery
confirmation in send() bypasses the cache since it needs fresh
timestamps to detect changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
feat: auto-open plan in file preview on first session visit
fix(core): cache opencode session list to prevent tmp file spam
…ouple vertical dividers

- Add Aa button in PREVIEW pane header with slider popover (10-18px, persisted per session)
  Applies to code viewer, diff viewer, and markdown preview via --preview-font-size CSS var
- Fix terminal not refreshing after font size change: call terminal.refresh() in fitTerminal()
  so glyphs repaint immediately without needing a manual resize nudge
- Decouple vertical layout dividers: introduce verticalSplit [top%, bottom%] state so the
  row separator (top|terminal) no longer shares sizes[1] with the column separator
  (file tree|preview), eliminating cross-axis interference and the "moves faster than finger" bug

Closes #text-size

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Column separator in vertical layout moved 1.67× faster than the finger because
  buildTemplate normalizes over sizes[0]+sizes[1] (~60) not 100; scale delta by
  normFactor = sizes[0]+sizes[1] so pixel movement matches finger exactly
- Terminal font size change now defers fitTerminal() via requestAnimationFrame so
  the renderer has time to update cell dimensions before cols/rows are recalculated;
  also sends updated size to the mux after the fit

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat(web): preview text size + terminal refresh fix + vertical divider decoupling
Three root causes were stalling the dashboard:

1. execFileSync in API routes blocked the Node.js event loop. Every 3s,
   /api/terminals and /api/events each ran N synchronous tmux has-session
   calls (one per terminal). With 18 sessions this blocked for seconds,
   making all HTTP requests (sidebar, file tree, preview) queue as pending.
   Fix: replace all execFileSync with a single async tmux list-sessions
   call via shared tmux-async.ts helper.

2. The opencode plugin's findOpenCodeSession() spawned a fresh
   `opencode session list` subprocess (30s timeout) on every
   getActivityState/getSessionInfo call with no caching. Once an opencode
   session was viewed, SSE's 3s poll triggered these for every opencode
   session, stacking up slow subprocesses.
   Fix: add 10s TTL cache matching core's pattern.

3. resolveTmuxSession tried has-session exact match first, which always
   fails for hash-prefixed sessions (the common case), printing
   "can't find session" to stderr on every call.
   Fix: try list-sessions first, fall back to has-session with suppressed
   stderr.

Also adds diagnostic logging to mux WebSocket close/error events and
MuxProvider cleanup for future debugging.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merges ~137 upstream commits from ComposioHQ/agent-orchestrator main into
gb-personal, preserving all gb-personal UI features (DashboardGB, DirectTerminalGB,
SessionCardGB, file tree, markdown preview, cursor/amp agents, MuxProvider,
mobile touch, xterm v6, sidebar UX).

Key changes from upstream:
- PowerConfig / power management support in OrchestratorConfig
- branchName on Issue, userPrompt on SessionMetadata
- global-pause feature reverted upstream → self-contained web-local copy
- Sub-session methods removed from SessionManager interface
- prompt-builder layered system (Session Lifecycle, Git Workflow, PR Best Practices)
- Lifecycle reactions (auto send-to-agent on CI failure)
- isKilledSession / SessionAttentionLevel / killed AttentionLevel
- Various plugin improvements (opencode TTL cache, aider/codex activity detection)
- scm-gitlab / tracker-gitlab additions
- CI/CD workflow updates, docs cleanup

Conflict resolution policy:
- Web UI components → ours (gb-personal forks)
- Core/CLI engine → theirs (upstream)
- Manual merge for types.ts and opencode plugin

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

- dependency-review-action requires Dependency Graph enabled on the repo;
  skip on forks with repository condition
- pnpm audit strict step: add continue-on-error since npm retired the old
  audit endpoint (HTTP 410) and pnpm hasn't switched to the bulk advisory API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- agent-aider test: remove duplicate vi.hoisted/vi.mock block (merge artifact)
- opencode: use two-phase launch (--command true + --prompt on resume)
- opencode test: reset session list cache in beforeEach

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- vitest.config.ts: update all package aliases from @composio/ to @aoagents/
- vitest.config.ts: add server-only mock and agent-cursor alias (from upstream)
- DynamicFavicon: support both sseAttentionLevels and sessions props
- DynamicFavicon: export countNeedingAttention for upstream tests
- Remove 2 global-pause api-routes tests (feature removed from core)

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

Theme:
- Replace globals.css with upstream's warm earth-toned palette (Geist Sans
  + JetBrains Mono fonts, cream/stone surfaces, warm periwinkle accent)
- Restore gb-personal xterm touch-scroll rules (touch-action, overscroll-behavior)
- Restore collapsed sidebar CSS (avatar buttons, session abbreviation pills)
- Reset link color inheritance inside sidebar and dashboard to prevent
  global accent blue from leaking into nav items
- Set sidebar width back to 244px (gb-personal default)

Sub-sessions:
- Restore listSubSessionIds in metadata.ts
- Restore createSubSession, listSubSessions, killSubSession,
  restoreTerminalSubSession in session-manager.ts
- Add sub-session methods to SessionManager interface in types.ts
- Restore API routes: GET/POST sub-sessions, DELETE/restore sub-session

Sidebar:
- Merge desktop + mobile sidebar into single wrapper (sidebar-wrapper)
  to eliminate duplicate sidebar instances on mobile
- Mobile sidebar uses CSS off-canvas drawer with backdrop overlay
- Force expanded mode when mobile overlay is open (ignore collapsed state)
- Compact summary section (inline metrics instead of card grid)
- Add separators between projects
- Active items use bold primary text instead of accent blue

Components:
- DirectTerminalGB: session ID uses text-secondary instead of accent
- Skeleton: use var(--color-bg-base) instead of hardcoded #0a0a0f
- Terminal: status dots use CSS variables instead of hardcoded hex

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The modal was rendering inside sidebar-wrapper which has overflow:hidden,
causing it to be clipped to the sidebar area instead of covering the
full screen.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fastestdevalive and others added 5 commits April 15, 2026 21:20
…disk scan

sessionManager.list() does a full disk scan + runtime enrichment for every
session on every call (~7s for 90 sessions). The /sessions/light endpoint
was calling this on every 5s poll, causing the sidebar to perpetually reload.

- Add listCached() to SessionManager interface — returns sessions from an
  in-memory snapshot, falling back to list() on cache miss
- list() populates the cache after each full (unfiltered) scan
- Cache TTL is 35s (exceeds the 30s lifecycle poll interval)
- spawn() and kill() invalidate the cache immediately so mutations are
  visible on the next poll without waiting for TTL expiry
- services.ts fires a background list() at startup to warm the cache
  so the first API request after boot hits memory, not disk
- /sessions/light route uses listCached() instead of list()

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

Layout / sidebar polling:
- Remove duplicate MuxProvider import from layout (already in providers.tsx)
- Replace Promise.allSettled blocking fetch with independent per-fetch chains
  so projects/sessions update as soon as each resolves, not when slowest finishes
- Add inFlight guards to all polling loops (terminals, sidebar data, sessions)
  to prevent request pile-up when previous fetch is still running
- handleSessionCreated replaces spawning-* stubs with real session on spawn

Spawn:
- Forward agent field from request body to sessionManager.spawn()

API route optimisations:
- Cache workspace path (60s TTL) in files/diff routes to skip getServices()
  on repeated requests for the same session
- Deduplicate /sessions/light allSessions call (use filtered coreSessions
  when no project filter is active)

UI fixes:
- ProjectSidebar: fix blue link color leaking from global anchor styles
- SpawnSessionModal: call onSessionCreated with real DashboardSession so the
  optimistic stub is replaced correctly after spawn completes
- SessionTerminalTabs: minor polish
- globals.css: add sidebar-wrapper off-canvas CSS for mobile overlay

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Detailed plan for upstreaming gb-personal features to
ComposioHQ/agent-orchestrator main in 8 sequential PRs:

PR1: Amp agent plugin
PR2: Terminal viewport fill + touch scroll + font size
PR3: Topbar / sidebar / hamburger (upstream chrome, our flavors)
PR4: Configurable agent base prompt with UI panel
PR5: New session UI + spawn backend
PR6: Sub-sessions + backend support
PR7a: File/diff API routes (with path traversal protection)
PR7b: File tree + workspace layout + markdown/mermaid

Each PR has exact file paths, API shapes, commit structure,
and test requirements detailed enough for an AI agent to
implement without reading gb-personal source directly.

Reviewed by Claude Opus 4.6; addressed all feedback:
- Fixed DirectTerminalGB import → DirectTerminal in PR6
- Split original PR6 into PR7a (API) + PR7b (UI)
- Corrected path traversal check (prefix-attack safe)
- Added source-extraction instructions for implementing agents
- Clarified sidebar: prefer upstream chrome, add our flavors

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

docs: upstream-to-main plan — 8 focused PRs
- Reorder PRs: file tree/workspace UI becomes PR6a/6b, sub-sessions PR7, new sidebar lone terminals PR8
- Revise PR6b layout deps based on feat/upstream-pr2-pr3 findings (sidebar+topbar live inside Dashboard/SessionDetail, not layout.tsx)
- Evolve PR7 sub-session spawn flow: SpawnSubSessionModal with locked issue ID, agent selector, optional prompt
- Add PR8: sidebar lone terminals (raw tmux panes, no parent session)
- Add subsession-concept.md: ASCII diagrams for hierarchy, lifecycle, spawn flow, workspace integration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

8 participants