chore: merge upstream main into gb-personal (April 2026 catchup)#40
Open
fastestdevalive wants to merge 397 commits into
Open
chore: merge upstream main into gb-personal (April 2026 catchup)#40fastestdevalive wants to merge 397 commits into
fastestdevalive wants to merge 397 commits into
Conversation
…y confirmation step
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>
…-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>
4c3919d to
c3b9f1a
Compare
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
mainintogb-personalKey upstream changes included
PowerConfig/ power management support inOrchestratorConfigbranchNameonIssue,userPromptonSessionMetadataglobal-pausefeature reverted upstream → self-contained web-local copy createdSessionManagerinterfaceisKilledSession/SessionAttentionLevel/"killed"AttentionLevelConflict resolution policy applied
--ours(gb-personal forks preserved)--theirs(upstream improvements taken)types.ts,opencodeplugin,format.ts,global-pauseTest plan
workingstate🤖 Generated with Claude Code