mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-01 19:25:10 +02:00
7665adf4fe
* feat: CDP connect — control real Chrome/Comet via Playwright Add `connectCDP()` to BrowserManager: connects to a running browser via Chrome DevTools Protocol. All existing browse commands work unchanged through Playwright's abstraction layer. - chrome-launcher.ts: browser discovery, CDP probe, auto-relaunch with rollback - browser-manager.ts: connectCDP(), mode guards (close/closeTab/recreateContext/handoff), auto-reconnect on browser restart, getRefMap() for extension API - server.ts: CDP branch in start(), /health gains mode field, /refs endpoint, idle timer only resets on /command (not passive endpoints) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: browse connect/disconnect/focus CLI commands - connect: pre-server command that discovers browser, starts server in CDP mode - disconnect: drops CDP connection, restarts in headless mode - focus: brings browser window to foreground via osascript (macOS) - status: now shows Mode: cdp | launched | headed - startServer() accepts extra env vars for CDP URL/port passthrough Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: CDP-aware skill templates — skip cookie import in real browser mode Skills now check `$B status` for CDP mode and skip: - /qa: cookie import prompt, user-agent override, headless workarounds - /design-review: cookie import for authenticated pages - /setup-browser-cookies: returns "not needed" in CDP mode Regenerated SKILL.md files from updated templates. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: activity streaming — SSE endpoint for Chrome extension Side Panel Real-time browse command feed via Server-Sent Events: - activity.ts: ActivityEntry type, CircularBuffer (capacity 1000), privacy filtering (redacts passwords, auth tokens, sensitive URL params), cursor-based gap detection, async subscriber notification - server.ts: /activity/stream SSE, /activity/history REST, handleCommand instrumented with command_start/command_end events - 18 unit tests for filterArgs privacy, emitActivity, subscribe lifecycle Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: Chrome extension Side Panel + Conductor API proposal Chrome extension (Manifest V3, sideload): - Side Panel with live activity feed, @ref overlays, dark terminal aesthetic - Background worker: health polling, SSE relay, ref fetching - Popup: port config, connection status, side panel launcher - Content script: floating ref panel with @ref badges Conductor API proposal (docs/designs/CONDUCTOR_SESSION_API.md): - SSE endpoint for full Claude Code session mirroring in Side Panel - Discovery via HTTP endpoint (not filesystem — extensions can't read files) TODOS.md: add $B watch, multi-agent tabs, cross-platform CDP, Web Store publishing. Mark CDP mode as shipped. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: detect Conductor runtime, skip osascript quit for sandboxed apps macOS App Management blocks Electron apps (Conductor) from quitting other apps via osascript. Now detects the runtime environment: - terminal/claude-code/codex: can manage apps freely - conductor: prints manual restart instructions + polls for 60s detectRuntime() checks env vars and parent process. When Chrome needs restart but we can't quit it, prints step-by-step instructions and waits for the user to restart Chrome with --remote-debugging-port. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: detect Conductor via actual env vars (CONDUCTOR_WORKSPACE_NAME) Previous detection checked CONDUCTOR_WORKSPACE_ID which doesn't exist. Conductor sets CONDUCTOR_WORKSPACE_NAME, CONDUCTOR_BIN_DIR, CONDUCTOR_PORT, and __CFBundleIdentifier=com.conductor.app. Check these FIRST because Conductor sessions also have ANTHROPIC_API_KEY (which was matching claude-code). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: connection status pill — floating indicator when gstack controls Chrome Small pill in bottom-right corner of every page: "● gstack · 3 refs" Shows when connected via CDP, fades to 30% opacity after 3s, full on hover. Disappears entirely when disconnected. Background worker now notifies content scripts on connect/disconnect state changes so the pill appears/disappears without polling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: Chrome requires --user-data-dir for remote debugging Chrome refuses --remote-debugging-port without an explicit --user-data-dir. Add userDataDir to BrowserBinary registry (macOS Application Support paths) and pass it in both auto-launch and manual restart instructions. Fix double-quoting in CLI manual restart instructions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: Chrome must be fully quit before launching with --remote-debugging-port Chrome refuses to enable CDP on its default profile when another instance is running (even with explicit --user-data-dir). The only reliable path: fully quit Chrome first, then relaunch with the flag. Updated instructions to emphasize this clearly with verification step. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: bin/chrome-cdp — quit Chrome and relaunch with CDP in one command Quits Chrome gracefully, waits for full exit, relaunches with --remote-debugging-port, polls until CDP is ready. Usage: chrome-cdp [port] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use Playwright channel:chrome instead of broken connectOverCDP Playwright's connectOverCDP hangs with Chrome 146 due to CDP protocol version mismatch. Switch to channel:'chrome' which uses Playwright's native pipe protocol to launch the system Chrome binary directly. This is simpler and more reliable: - No CDP port discovery needed - No --remote-debugging-port or --user-data-dir hassles - $B connect just works — launches real Chrome headed window - All Playwright APIs (snapshot, click, fill) work unchanged bin/chrome-cdp updated with symlinked profile approach (kept for manual CDP use cases, but $B connect no longer needs it). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: green border + gstack label on controlled Chrome window Injects a 2px green border and small "gstack" label on every page loaded in the controlled Chrome window via context.addInitScript(). Users can instantly tell which Chrome window Claude controls. Also fixes close() for channel:chrome mode (uses browser.close() not browser.disconnect() which doesn't exist). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: cleanup chrome-launcher runtime detection, remove puppeteer-core dep Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style(design): redesign controlled Chrome indicator Replace crude green border + label with polished indicator: - 2px shimmer gradient at top edge (green→cyan→green, 3s loop) - Floating pill bottom-right with frosted glass bg, fades to 25% opacity after 4s so it doesn't compete with page content - prefers-reduced-motion disables shimmer animation - Much more subtle — looks like a developer tool, not broken CSS Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: document real browser mode + Chrome extension in BROWSER.md and README.md BROWSER.md: new sections for connect/disconnect/focus commands, Chrome extension Side Panel install, CDP-aware skills, activity streaming. Updated command reference table, key components, env vars, source map. README.md: updated /browse description, added "Real browser mode" to What's New section. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: step-by-step Chrome extension install guide in BROWSER.md Replace terse bullet points with numbered walkthrough covering: developer mode toggle, load unpacked, macOS file picker tip (Cmd+Shift+G), pin extension, configure port, open side panel. Added troubleshooting section. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add Cmd+Shift+. tip for hidden folders in macOS file picker macOS hides folders starting with . by default. Added both shortcuts: Cmd+Shift+G (paste path directly) and Cmd+Shift+. (show hidden files). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: integrate hidden folder tips into the install flow naturally Move Cmd+Shift+G and Cmd+Shift+. tips inline with the file picker step instead of as a separate tip block after it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: auto-load Chrome extension when $B connect launches Chrome Extension auto-loads via --load-extension flag — no manual chrome://extensions install needed. findExtensionPath() checks repo root, global install, and dev paths. Also adds bin/gstack-extension helper for manual install in regular Chrome, and rewrites BROWSER.md install docs with auto-load as primary path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: /connect-chrome skill — one command to launch Chrome with Side Panel New skill that runs $B connect, verifies the connection, guides the user to open the Side Panel, and demos the live activity feed. Extension auto-loads via --load-extension so no manual chrome://extensions install needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use launchPersistentContext for Chrome extension loading Playwright's chromium.launch() silently ignores --load-extension. Switch to launchPersistentContext with ignoreDefaultArgs to remove --disable-extensions flag. Use bundled Chromium (real Chrome blocks unpacked extensions). Fixed port 34567 for CDP mode so the extension auto-connects. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: sync extension to DESIGN.md — amber accent, zinc neutrals, grain texture Import design system from gstack-website. Update all extension colors: green (#4ade80) → amber (#F59E0B/#FBBF24), zinc gray neutrals, grain texture overlay. Regenerate icons as amber "G" monogram on dark background. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: sidebar chat with Claude Code — icon opens side panel directly Replace popup flyout with direct side panel open on icon click. Primary UI is now a chat interface that sends messages to Claude Code via file queue. Activity/Refs tabs moved behind a debug toggle in the footer. Command bar with history, auto-poll for responses, amber design system. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: sidebar agent — Claude-powered chat backend via file queue Add /sidebar-command, /sidebar-response, and /sidebar-chat endpoints to the browse server. sidebar-agent.ts watches the command queue file, spawns claude -p with browse context for each message, and streams responses back to the sidebar chat. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove duplicate gstack pill overlay, hide crash restore bubble The addInitScript indicator and the extension's content script were both injecting bottom-right pills, causing duplicates. Remove the pill from addInitScript (extension handles it). Replace --restore-last-session with --hide-crash-restore-bubble to suppress the "Chromium didn't shut down correctly" dialog. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: state file authority — CDP server cannot be silently replaced Hardens the connect/disconnect lifecycle: - ensureServer() refuses to auto-start headless when CDP server is alive - $B connect does full cleanup: SIGTERM → 2s → SIGKILL, profile locks, state - shutdown() cleans Chromium SingletonLock/Socket/Cookie files - uncaughtException/unhandledRejection handlers do emergency cleanup This prevents the bug where a headless server overwrites the CDP server's state file, causing $B commands to hit the wrong browser. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: sidebar agent streaming events + session state management Enhance sidebar-agent.ts with: - Live streaming of claude -p events (tool_use, text, result) to sidebar - Session state file for BROWSE_STATE_FILE propagation to claude subprocess - Improved logging (stderr, exit codes, event types) - stdin.end() to prevent claude waiting for input - summarizeToolInput() with path shortening for compact sidebar display Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: sidebar chat UI — streaming events, agent status, reconnect retry Sidebar panel improvements: - Chat tab renders streaming agent events (tool_use, text, result) - Thinking dots animation while agent processes - Agent error display with styled error blocks - tryConnect() with 2s retry loop for initial connection - Debug tabs (Activity/Refs) hidden behind gear toggle - Clear chat button - Compact tool call display with path shortening Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: server-integrated sidebar agent with sessions and message queue Move the sidebar agent from a separate bun process into server.ts: - Agent spawns claude -p directly when messages arrive via /sidebar-command - In-memory chat buffer backed by per-session chat.jsonl on disk - Session manager: create, load, persist, list sessions - Message queue (cap 5) with agent status tracking (idle/processing/hung) - Stop/kill endpoints with queue dismiss support - /health now returns agent status + session info - All sidebar endpoints require Bearer auth - Agent killed on server shutdown - 120s timeout detects hung claude processes Eliminates: file-queue polling, separate sidebar-agent.ts process, stale auth tokens, state file conflicts between processes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: extension auth + token flow for server-integrated agent Update Chrome extension to use Bearer auth on all sidebar endpoints: - background.js captures auth token from /health, exposes via getToken msg - background.js sets openPanelOnActionClick for direct side panel access - sidepanel.js gets token from background, sends in all fetch headers - Health broadcasts include token so sidebar auto-authenticates - Removes popup from manifest — icon click opens side panel directly Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: self-healing sidebar — reconnect banner, state machine, copy button Sidebar UI now handles disconnection gracefully: - Connection state machine: connected → reconnecting → dead - Amber pulsing banner during reconnect (2s retry, 30 attempts) - Red "Server offline" banner with Reconnect + Copy /connect-chrome buttons - Green "Reconnected" toast that fades after 3s on successful reconnect - Copy button lets user paste /connect-chrome into any Claude Code session Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: crash handling — save session, kill agent, distinct exit codes Hardened shutdown/crash behavior: - Browser disconnect exits with code 2 (distinct from crash code 1) - emergencyCleanup kills agent subprocess and saves session state - Clean shutdown saves session before exit (chat history persists) - Clear user message on browser disconnect: "Run $B connect to reconnect" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: worktree-per-session isolation for sidebar agent Each sidebar session gets an isolated git worktree so the agent's file operations don't conflict with the user's working directory: - createWorktree() creates detached HEAD worktree in ~/.gstack/worktrees/ - Falls back to main cwd for non-git repos or on creation failure - Handles collision cleanup from prior crashes - removeWorktree() cleans up on session switch and shutdown - worktreePath persisted in session.json Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(qa): ISSUE-001 — disconnect blocked by CDP guard in ensureServer $B disconnect was routed through ensureServer() which refused to start a headless server when a CDP state file existed. Disconnect is now handled before ensureServer() (like connect), with force-kill + cleanup fallback when the CDP server is unresponsive. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve claude binary path for daemon-spawned agent The browse server runs as a daemon and may not inherit the user's shell PATH. Add findClaudeBin() that checks ~/.local/bin/claude (standard install location), which claude, and common system paths. Shows a clear error in the sidebar chat if claude CLI is not found. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve claude symlinks + check Conductor bundled binary posix_spawn fails on symlinks in compiled bun binaries. Now: - Checks Conductor app's bundled binary first (not a symlink) - Scans ~/.local/share/claude/versions/ for direct versioned binaries - Uses fs.realpathSync() to resolve symlinks before spawning Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: compiled bun binary cannot posix_spawn — use external agent process Compiled bun binaries fail posix_spawn on ALL executables (even /bin/bash). The server now writes to an agent queue file, and a separate non-compiled bun process (sidebar-agent.ts) reads the queue, spawns claude, and POSTs events back via /sidebar-agent/event. Changes: - server.ts: spawnClaude writes to queue file instead of spawning directly - server.ts: new /sidebar-agent/event endpoint for agent → server relay - server.ts: fix result event field name (event.text vs event.result) - sidebar-agent.ts: rewritten to poll queue file, relay events via HTTP - cli.ts: $B connect auto-starts sidebar-agent as non-compiled bun process Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: loading spinner on sidebar open while connecting to server Shows an amber spinner with "Connecting..." when the sidebar first opens, replacing the empty state. After the first successful /sidebar-chat poll: - If chat history exists: renders it immediately - If no history: shows the welcome message Prevents the jarring empty-then-populated flash on sidebar open. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: zero-friction side panel — auto-open on install, pill is clickable Three changes to eliminate manual side panel setup: - Auto-open side panel on extension install/update (onInstalled listener) - gstack pill (bottom-right) is now clickable — opens the side panel - Pill has pointer-events: auto so clicks always register (was: none) User no longer needs to find the puzzle piece icon, pin the extension, or know the side panel exists. It opens automatically on first launch and can be re-opened by clicking the floating gstack pill. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: kill CDP naming, delete chrome-launcher.ts dead code The connectCDP() method and connectionMode: 'cdp' naming was a legacy artifact — real Chrome was tried but failed (silently blocks --load-extension), so the implementation already used Playwright's bundled Chromium via launchPersistentContext(). The naming was misleading. Changes: - Delete chrome-launcher.ts (361 LOC) — only import was in unreachable attemptReconnect() method - Delete dead attemptReconnect() and reconnecting field - Delete preExistingTabIds (was for protecting real Chrome tabs we never connect to) - Rename connectCDP() → launchHeaded() - Rename connectionMode: 'cdp' → 'headed' across all files - Replace BROWSE_CDP_URL/BROWSE_CDP_PORT env vars with BROWSE_HEADED=1 - Regenerate SKILL.md files for updated command descriptions - Move BrowserManager unit tests to browser-manager-unit.test.ts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: converge handoff into connect — extension loads on handoff Handoff now uses launchPersistentContext() with extension auto-loading, same as the connect/launchHeaded() path. This means when the agent gets stuck (2FA, CAPTCHA) and hands off to the user, the Chrome extension + side panel are available automatically. Before: handoff used chromium.launch() + newContext() — no extension After: handoff uses chromium.launchPersistentContext() — extension loads Also sets connectionMode to 'headed' and disables dialog auto-accept on handoff, matching connect behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: gate sidebar chat behind --chat flag $B connect (default): headed Chromium + extension with Activity + Refs tabs only. No separate agent spawned. Clean, no confusion. $B connect --chat: same + Chat tab with standalone claude -p agent. Shows experimental banner: "Standalone mode — this is a separate agent from your workspace." Implementation: - cli.ts: parse --chat, set BROWSE_SIDEBAR_CHAT env, conditionally spawn sidebar-agent - server.ts: gate /sidebar-* routes behind chatEnabled, return 403 when disabled, include chatEnabled in /health response - sidepanel.js: applyChatEnabled() hides/shows Chat tab + banner - background.js: forward chatEnabled from health response - sidepanel.html/css: experimental banner with amber styling Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: file drop relay + $B inbox command Sidebar agent now writes structured messages to .context/sidebar-inbox/ when processing user input. The workspace agent can read these via $B inbox to see what the user reported from the browser. File drop format: .context/sidebar-inbox/{timestamp}-observation.json { type, timestamp, page: {url}, userMessage, sidebarSessionId } Atomic writes (tmp + rename) prevent partial reads. $B inbox --clear removes messages after display. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: $B watch — passive observation mode Claude enters read-only mode and captures periodic snapshots (every 5s) while the user browses. Mutation commands (click, fill, etc.) are blocked during watch. $B watch stop exits and returns a summary with the last snapshot. Requires headed mode ($B connect). This is the inverse of the scout pattern — the workspace agent watches through the browser instead of the sidebar relaying to it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: add coverage for sidebar-agent, file-drop, and watch mode 33 new tests covering: - Sidebar agent queue parsing (valid/malformed/empty JSONL) - writeToInbox file drop (directory creation, atomic writes, JSON format) - Inbox command (display, sorting, --clear, malformed file handling) - Watch mode state machine (start/stop cycles, snapshots, duration) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: TODOS cleanup + Chrome vs Chromium exploration doc - Update TODOS.md: mark CDP mode, $B watch, sidebar scout as SHIPPED - Delete dead "cross-platform CDP browser discovery" TODO - Rename dependencies from "CDP connect" to "headed mode" - Add docs/designs/CHROME_VS_CHROMIUM_EXPLORATION.md memorializing the architecture exploration and decision to use Playwright Chromium Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add Conductor Chrome sidebar integration design doc Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: sidebar-agent validates cwd before spawning claude The queue entry may reference a worktree that was cleaned up between sessions. Now falls back to process.cwd() if the path doesn't exist, preventing silent spawn failures. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: gen-skill-docs resolver merge + preamble tier gate + plan file discovery The local RESOLVERS record in gen-skill-docs.ts was shadowing the imported canonical resolvers, causing stale test coverage and preamble generators to be used instead of the authoritative versions in resolvers/. Changes: - Merge imported RESOLVERS with local overrides (spread + override pattern) - Fix preamble tier gate: tier 1 skills no longer get AskUserQuestion format - Make plan file discovery host-agnostic (search multiple plan dirs) - Add missing E2E tier entries for ship/review plan completion tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: ungate sidebar agent + raise timeout to 5 minutes (v0.12.0) Sidebar chat is now always available in headed mode — no --chat flag needed. Agent tasks get 5 minutes instead of 2, enabling multi-page workflows like navigating directories and filling forms across pages. Changes: - cli.ts: remove --chat flag, always set BROWSE_SIDEBAR_CHAT=1, always spawn agent - server.ts: remove chatEnabled gate (403 response), raise AGENT_TIMEOUT_MS to 300s - sidebar-agent.ts: raise child process timeout from 120s to 300s Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: headed mode + sidebar agent documentation (v0.12.0) - README: sidebar agent section, personal automation example (school parent portal), two auth paths (manual login + cookie import), DevTools MCP mention - BROWSER.md: sidebar agent section with usage, timeout, session isolation, authentication, and random delay documentation - connect-chrome template: add sidebar chat onboarding step - CHANGELOG: v0.12.0 entry covering headed mode, sidebar agent, extension - VERSION: bump to 0.12.0.0 - TODOS: Chrome DevTools MCP integration as P0 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: regenerate SKILL.md files Generated from updated templates + resolver merge. Key changes: - Tier 1 skills no longer include AskUserQuestion format section - Ship/review skills now include coverage gate with thresholds - Connect-chrome skill includes sidebar chat onboarding step - Plan file discovery uses host-agnostic paths Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: regenerate Codex connect-chrome skill Updated preamble with proactive prompt and sidebar chat onboarding step. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: network idle, state persistence, iframe support, chain pipe format (v0.12.1.0) (#516) * feat: network idle detection + chain pipe format - Upgrade click/fill/select from domcontentloaded to networkidle wait (2s timeout, best-effort). Catches XHR/fetch triggered by interactions. - Add pipe-delimited format to chain as JSON fallback: $B chain 'goto url | click @e5 | snapshot -ic' - Add post-loop networkidle wait in chain when last command was a write. - Frame-aware: commands use target (getActiveFrameOrPage) for locator ops, page-only ops (goto/back/forward/reload) guard against frame context. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: $B state save/load + $B frame — new browse commands - state save/load: persist cookies + URLs to .gstack/browse-states/{name}.json File perms 0o600, name sanitized to [a-zA-Z0-9_-]. V1 skips localStorage (breaks on load-before-navigate). Load replaces session via closeAllPages(). - frame: switch command context to iframe via CSS selector, @ref, --name, or --url. 'frame main' returns to main frame. Execution target abstraction (getActiveFrameOrPage) across read-commands, snapshot, and write-commands. - Frame context cleared on tab switch, navigation, resume, and handoff. - Snapshot shows [Context: iframe src="..."] header when in frame. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: add tests for network idle, chain pipe format, state, and frame - Network idle: click on fetch button waits for XHR, static click is fast - Chain pipe: pipe-delimited commands, quoted args, JSON still works - State: save/load round-trip, name sanitization, missing state error - Frame: switch to iframe + back, snapshot context header, fill in frame, goto-in-frame guard, usage error New fixtures: network-idle.html (fetch + static buttons), iframe.html (srcdoc) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: review fixes — iframe ref scoping, detached frame recovery, state validation - snapshot.ts: ref locators, cursor-interactive scan, and cursor locator now use target (frame-aware) instead of page — fixes @ref clicking in iframes - browser-manager.ts: getActiveFrameOrPage auto-recovers from detached frames via isDetached() check - meta-commands.ts: state load resets activeFrame, elementHandle disposed after contentFrame(), state file schema validation (cookies + pages arrays), filter empty pipe segments in chain tokenizer - write-commands.ts: upload command uses target.locator() for frame support Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: regenerate SKILL.md files + rebuild binary Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: bump version and changelog (v0.12.1.0) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
668 lines
29 KiB
Markdown
668 lines
29 KiB
Markdown
# TODOS
|
|
|
|
## Builder Ethos
|
|
|
|
### First-time Search Before Building intro
|
|
|
|
**What:** Add a `generateSearchIntro()` function (like `generateLakeIntro()`) that introduces the Search Before Building principle on first use, with a link to the blog essay.
|
|
|
|
**Why:** Boil the Lake has an intro flow that links to the essay and marks `.completeness-intro-seen`. Search Before Building should have the same pattern for discoverability.
|
|
|
|
**Context:** Blocked on a blog post to link to. When the essay exists, add the intro flow with a `.search-intro-seen` marker file. Pattern: `generateLakeIntro()` at gen-skill-docs.ts:176.
|
|
|
|
**Effort:** S
|
|
**Priority:** P2
|
|
**Depends on:** Blog post about Search Before Building
|
|
|
|
## Chrome DevTools MCP Integration
|
|
|
|
### Real Chrome session access
|
|
|
|
**What:** Integrate Chrome DevTools MCP to connect to the user's real Chrome session with real cookies, real state, no Playwright middleman.
|
|
|
|
**Why:** Right now, headed mode launches a fresh Chromium profile. Users must log in manually or import cookies. Chrome DevTools MCP connects to the user's actual Chrome ... instant access to every authenticated site. This is the future of browser automation for AI agents.
|
|
|
|
**Context:** Google shipped Chrome DevTools MCP in Chrome 146+ (June 2025). It provides screenshots, console messages, performance traces, Lighthouse audits, and full page interaction through the user's real browser. gstack should use it for real-session access while keeping Playwright for headless CI/testing workflows.
|
|
|
|
Potential new skills:
|
|
- `/debug-browser`: JS error tracing with source-mapped stack traces
|
|
- `/perf-debug`: performance traces, Core Web Vitals, network waterfall
|
|
|
|
May replace `/setup-browser-cookies` for most use cases since the user's real cookies are already there.
|
|
|
|
**Effort:** L (human: ~2 weeks / CC: ~2 hours)
|
|
**Priority:** P0
|
|
**Depends on:** Chrome 146+, DevTools MCP server installed
|
|
|
|
## Browse
|
|
|
|
### Bundle server.ts into compiled binary
|
|
|
|
**What:** Eliminate `resolveServerScript()` fallback chain entirely — bundle server.ts into the compiled browse binary.
|
|
|
|
**Why:** The current fallback chain (check adjacent to cli.ts, check global install) is fragile and caused bugs in v0.3.2. A single compiled binary is simpler and more reliable.
|
|
|
|
**Context:** Bun's `--compile` flag can bundle multiple entry points. The server is currently resolved at runtime via file path lookup. Bundling it removes the resolution step entirely.
|
|
|
|
**Effort:** M
|
|
**Priority:** P2
|
|
**Depends on:** None
|
|
|
|
### Sessions (isolated browser instances)
|
|
|
|
**What:** Isolated browser instances with separate cookies/storage/history, addressable by name.
|
|
|
|
**Why:** Enables parallel testing of different user roles, A/B test verification, and clean auth state management.
|
|
|
|
**Context:** Requires Playwright browser context isolation. Each session gets its own context with independent cookies/localStorage. Prerequisite for video recording (clean context lifecycle) and auth vault.
|
|
|
|
**Effort:** L
|
|
**Priority:** P3
|
|
|
|
### Video recording
|
|
|
|
**What:** Record browser interactions as video (start/stop controls).
|
|
|
|
**Why:** Video evidence in QA reports and PR bodies. Currently deferred because `recreateContext()` destroys page state.
|
|
|
|
**Context:** Needs sessions for clean context lifecycle. Playwright supports video recording per context. Also needs WebM → GIF conversion for PR embedding.
|
|
|
|
**Effort:** M
|
|
**Priority:** P3
|
|
**Depends on:** Sessions
|
|
|
|
### v20 encryption format support
|
|
|
|
**What:** AES-256-GCM support for future Chromium cookie DB versions (currently v10).
|
|
|
|
**Why:** Future Chromium versions may change encryption format. Proactive support prevents breakage.
|
|
|
|
**Effort:** S
|
|
**Priority:** P3
|
|
|
|
### State persistence — SHIPPED
|
|
|
|
~~**What:** Save/load cookies + localStorage to JSON files for reproducible test sessions.~~
|
|
|
|
`$B state save/load` ships in v0.12.1.0. V1 saves cookies + URLs only (not localStorage, which breaks on load-before-navigate). Files at `.gstack/browse-states/{name}.json` with 0o600 permissions. Load replaces session (closes all pages first). Name sanitized to `[a-zA-Z0-9_-]`.
|
|
|
|
**Remaining:** V2 localStorage support (needs pre-navigation injection strategy).
|
|
**Completed:** v0.12.1.0 (2026-03-26)
|
|
|
|
### Auth vault
|
|
|
|
**What:** Encrypted credential storage, referenced by name. LLM never sees passwords.
|
|
|
|
**Why:** Security — currently auth credentials flow through the LLM context. Vault keeps secrets out of the AI's view.
|
|
|
|
**Effort:** L
|
|
**Priority:** P3
|
|
**Depends on:** Sessions, state persistence
|
|
|
|
### Iframe support — SHIPPED
|
|
|
|
~~**What:** `frame <sel>` and `frame main` commands for cross-frame interaction.~~
|
|
|
|
`$B frame` ships in v0.12.1.0. Supports CSS selector, @ref, `--name`, and `--url` pattern matching. Execution target abstraction (`getActiveFrameOrPage()`) across all read/write/snapshot commands. Frame context cleared on navigation, tab switch, resume. Detached frame auto-recovery. Page-only operations (goto, screenshot, viewport) throw clear error when in frame context.
|
|
|
|
**Completed:** v0.12.1.0 (2026-03-26)
|
|
|
|
### Semantic locators
|
|
|
|
**What:** `find role/label/text/placeholder/testid` with attached actions.
|
|
|
|
**Why:** More resilient element selection than CSS selectors or ref numbers.
|
|
|
|
**Effort:** M
|
|
**Priority:** P4
|
|
|
|
### Device emulation presets
|
|
|
|
**What:** `set device "iPhone 16 Pro"` for mobile/tablet testing.
|
|
|
|
**Why:** Responsive layout testing without manual viewport resizing.
|
|
|
|
**Effort:** S
|
|
**Priority:** P4
|
|
|
|
### Network mocking/routing
|
|
|
|
**What:** Intercept, block, and mock network requests.
|
|
|
|
**Why:** Test error states, loading states, and offline behavior.
|
|
|
|
**Effort:** M
|
|
**Priority:** P4
|
|
|
|
### Download handling
|
|
|
|
**What:** Click-to-download with path control.
|
|
|
|
**Why:** Test file download flows end-to-end.
|
|
|
|
**Effort:** S
|
|
**Priority:** P4
|
|
|
|
### Content safety
|
|
|
|
**What:** `--max-output` truncation, `--allowed-domains` filtering.
|
|
|
|
**Why:** Prevent context window overflow and restrict navigation to safe domains.
|
|
|
|
**Effort:** S
|
|
**Priority:** P4
|
|
|
|
### Streaming (WebSocket live preview)
|
|
|
|
**What:** WebSocket-based live preview for pair browsing sessions.
|
|
|
|
**Why:** Enables real-time collaboration — human watches AI browse.
|
|
|
|
**Effort:** L
|
|
**Priority:** P4
|
|
|
|
### Headed mode with Chrome extension — SHIPPED
|
|
|
|
`$B connect` launches Playwright's bundled Chromium in headed mode with the gstack Chrome extension auto-loaded. `$B handoff` now produces the same result (extension + side panel). Sidebar chat gated behind `--chat` flag.
|
|
|
|
### `$B watch` — SHIPPED
|
|
|
|
Claude observes user browsing in passive read-only mode with periodic snapshots. `$B watch stop` exits with summary. Mutation commands blocked during watch.
|
|
|
|
### Sidebar scout / file drop relay — SHIPPED
|
|
|
|
Sidebar agent writes structured messages to `.context/sidebar-inbox/`. Workspace agent reads via `$B inbox`. Message format: `{type, timestamp, page, userMessage, sidebarSessionId}`.
|
|
|
|
### Multi-agent tab isolation
|
|
|
|
**What:** Two Claude sessions connect to the same browser, each operating on different tabs. No cross-contamination.
|
|
|
|
**Why:** Enables parallel /qa + /design-review on different tabs in the same browser.
|
|
|
|
**Context:** Requires tab ownership model for concurrent headed connections. Playwright may not cleanly support two persistent contexts. Needs investigation.
|
|
|
|
**Effort:** L (human: ~2 weeks / CC: ~2 hours)
|
|
**Priority:** P3
|
|
**Depends on:** Headed mode (shipped)
|
|
|
|
### Chrome Web Store publishing
|
|
|
|
**What:** Publish the gstack browse Chrome extension to Chrome Web Store for easier install.
|
|
|
|
**Why:** Currently sideloaded via chrome://extensions. Web Store makes install one-click.
|
|
|
|
**Effort:** S
|
|
**Priority:** P4
|
|
**Depends on:** Chrome extension proving value via sideloading
|
|
|
|
### Linux cookie decryption — PARTIALLY SHIPPED
|
|
|
|
~~**What:** GNOME Keyring / kwallet / DPAPI support for non-macOS cookie import.~~
|
|
|
|
Linux cookie import shipped in v0.11.11.0 (Wave 3). Supports Chrome, Chromium, Brave, Edge on Linux with GNOME Keyring (libsecret) and "peanuts" fallback. Windows DPAPI support remains deferred.
|
|
|
|
**Remaining:** Windows cookie decryption (DPAPI). Needs complete rewrite — PR #64 was 1346 lines and stale.
|
|
|
|
**Effort:** L (Windows only)
|
|
**Priority:** P4
|
|
**Completed (Linux):** v0.11.11.0 (2026-03-23)
|
|
|
|
## Ship
|
|
|
|
### GitLab support for /land-and-deploy
|
|
|
|
**What:** Add GitLab MR merge + CI polling support to `/land-and-deploy` skill. Currently uses `gh pr view`, `gh pr checks`, `gh pr merge`, and `gh run list/view` in 15+ places — each needs a GitLab conditional path using `glab ci status`, `glab mr merge`, etc.
|
|
|
|
**Why:** Without this, GitLab users can `/ship` (create MR) but can't `/land-and-deploy` (merge + verify). Completes the GitLab story end-to-end.
|
|
|
|
**Context:** `/retro`, `/ship`, and `/document-release` now support GitLab via the multi-platform `BASE_BRANCH_DETECT` resolver. `/land-and-deploy` has deeper GitHub-specific semantics (merge queues, required checks via `gh pr checks`, deploy workflow polling) that have different shapes on GitLab. The `glab` CLI (v1.90.0) supports `glab mr merge`, `glab ci status`, `glab ci view` but with different output formats and no merge queue concept.
|
|
|
|
**Effort:** L
|
|
**Priority:** P2
|
|
**Depends on:** None (BASE_BRANCH_DETECT multi-platform resolver is already done)
|
|
|
|
### Ship log — persistent record of /ship runs
|
|
|
|
**What:** Append structured JSON entry to `.gstack/ship-log.json` at end of every /ship run (version, date, branch, PR URL, review findings, Greptile stats, todos completed, test results).
|
|
|
|
**Why:** /retro has no structured data about shipping velocity. Ship log enables: PRs-per-week trending, review finding rates, Greptile signal over time, test suite growth.
|
|
|
|
**Context:** /retro already reads greptile-history.md — same pattern. Eval persistence (eval-store.ts) shows the JSON append pattern exists in the codebase. ~15 lines in ship template.
|
|
|
|
**Effort:** S
|
|
**Priority:** P2
|
|
**Depends on:** None
|
|
|
|
|
|
### Visual verification with screenshots in PR body
|
|
|
|
**What:** /ship Step 7.5: screenshot key pages after push, embed in PR body.
|
|
|
|
**Why:** Visual evidence in PRs. Reviewers see what changed without deploying locally.
|
|
|
|
**Context:** Part of Phase 3.6. Needs S3 upload for image hosting.
|
|
|
|
**Effort:** M
|
|
**Priority:** P2
|
|
**Depends on:** /setup-gstack-upload
|
|
|
|
## Review
|
|
|
|
### Inline PR annotations
|
|
|
|
**What:** /ship and /review post inline review comments at specific file:line locations using `gh api` to create pull request review comments.
|
|
|
|
**Why:** Line-level annotations are more actionable than top-level comments. The PR thread becomes a line-by-line conversation between Greptile, Claude, and human reviewers.
|
|
|
|
**Context:** GitHub supports inline review comments via `gh api repos/$REPO/pulls/$PR/reviews`. Pairs naturally with Phase 3.6 visual annotations.
|
|
|
|
**Effort:** S
|
|
**Priority:** P2
|
|
**Depends on:** None
|
|
|
|
### Greptile training feedback export
|
|
|
|
**What:** Aggregate greptile-history.md into machine-readable JSON summary of false positive patterns, exportable to the Greptile team for model improvement.
|
|
|
|
**Why:** Closes the feedback loop — Greptile can use FP data to stop making the same mistakes on your codebase.
|
|
|
|
**Context:** Was a P3 Future Idea. Upgraded to P2 now that greptile-history.md data infrastructure exists. The signal data is already being collected; this just makes it exportable. ~40 lines.
|
|
|
|
**Effort:** S
|
|
**Priority:** P2
|
|
**Depends on:** Enough FP data accumulated (10+ entries)
|
|
|
|
### Visual review with annotated screenshots
|
|
|
|
**What:** /review Step 4.5: browse PR's preview deploy, annotated screenshots of changed pages, compare against production, check responsive layouts, verify accessibility tree.
|
|
|
|
**Why:** Visual diff catches layout regressions that code review misses.
|
|
|
|
**Context:** Part of Phase 3.6. Needs S3 upload for image hosting.
|
|
|
|
**Effort:** M
|
|
**Priority:** P2
|
|
**Depends on:** /setup-gstack-upload
|
|
|
|
## QA
|
|
|
|
### QA trend tracking
|
|
|
|
**What:** Compare baseline.json over time, detect regressions across QA runs.
|
|
|
|
**Why:** Spot quality trends — is the app getting better or worse?
|
|
|
|
**Context:** QA already writes structured reports. This adds cross-run comparison.
|
|
|
|
**Effort:** S
|
|
**Priority:** P2
|
|
|
|
### CI/CD QA integration
|
|
|
|
**What:** `/qa` as GitHub Action step, fail PR if health score drops.
|
|
|
|
**Why:** Automated quality gate in CI. Catch regressions before merge.
|
|
|
|
**Effort:** M
|
|
**Priority:** P2
|
|
|
|
### Smart default QA tier
|
|
|
|
**What:** After a few runs, check index.md for user's usual tier pick, skip the AskUserQuestion.
|
|
|
|
**Why:** Reduces friction for repeat users.
|
|
|
|
**Effort:** S
|
|
**Priority:** P2
|
|
|
|
### Accessibility audit mode
|
|
|
|
**What:** `--a11y` flag for focused accessibility testing.
|
|
|
|
**Why:** Dedicated accessibility testing beyond the general QA checklist.
|
|
|
|
**Effort:** S
|
|
**Priority:** P3
|
|
|
|
### CI/CD generation for non-GitHub providers
|
|
|
|
**What:** Extend CI/CD bootstrap to generate GitLab CI (`.gitlab-ci.yml`), CircleCI (`.circleci/config.yml`), and Bitrise pipelines.
|
|
|
|
**Why:** Not all projects use GitHub Actions. Universal CI/CD bootstrap would make test bootstrap work for everyone.
|
|
|
|
**Context:** v1 ships with GitHub Actions only. Detection logic already checks for `.gitlab-ci.yml`, `.circleci/`, `bitrise.yml` and skips with an informational note. Each provider needs ~20 lines of template text in `generateTestBootstrap()`.
|
|
|
|
**Effort:** M
|
|
**Priority:** P3
|
|
**Depends on:** Test bootstrap (shipped)
|
|
|
|
### Auto-upgrade weak tests (★) to strong tests (★★★)
|
|
|
|
**What:** When Step 3.4 coverage audit identifies existing ★-rated tests (smoke/trivial assertions), generate improved versions testing edge cases and error paths.
|
|
|
|
**Why:** Many codebases have tests that technically exist but don't catch real bugs — `expect(component).toBeDefined()` isn't testing behavior. Upgrading these closes the gap between "has tests" and "has good tests."
|
|
|
|
**Context:** Requires the quality scoring rubric from the test coverage audit. Modifying existing test files is riskier than creating new ones — needs careful diffing to ensure the upgraded test still passes. Consider creating a companion test file rather than modifying the original.
|
|
|
|
**Effort:** M
|
|
**Priority:** P3
|
|
**Depends on:** Test quality scoring (shipped)
|
|
|
|
## Retro
|
|
|
|
### Deployment health tracking (retro + browse)
|
|
|
|
**What:** Screenshot production state, check perf metrics (page load times), count console errors across key pages, track trends over retro window.
|
|
|
|
**Why:** Retro should include production health alongside code metrics.
|
|
|
|
**Context:** Requires browse integration. Screenshots + metrics fed into retro output.
|
|
|
|
**Effort:** L
|
|
**Priority:** P3
|
|
**Depends on:** Browse sessions
|
|
|
|
## Infrastructure
|
|
|
|
### /setup-gstack-upload skill (S3 bucket)
|
|
|
|
**What:** Configure S3 bucket for image hosting. One-time setup for visual PR annotations.
|
|
|
|
**Why:** Prerequisite for visual PR annotations in /ship and /review.
|
|
|
|
**Effort:** M
|
|
**Priority:** P2
|
|
|
|
### gstack-upload helper
|
|
|
|
**What:** `browse/bin/gstack-upload` — upload file to S3, return public URL.
|
|
|
|
**Why:** Shared utility for all skills that need to embed images in PRs.
|
|
|
|
**Effort:** S
|
|
**Priority:** P2
|
|
**Depends on:** /setup-gstack-upload
|
|
|
|
### WebM to GIF conversion
|
|
|
|
**What:** ffmpeg-based WebM → GIF conversion for video evidence in PRs.
|
|
|
|
**Why:** GitHub PR bodies render GIFs but not WebM. Needed for video recording evidence.
|
|
|
|
**Effort:** S
|
|
**Priority:** P3
|
|
**Depends on:** Video recording
|
|
|
|
|
|
|
|
### Extend worktree isolation to Claude E2E tests
|
|
|
|
**What:** Add `useWorktree?: boolean` option to `runSkillTest()` so any Claude E2E test can opt into worktree mode for full repo context instead of tmpdir fixtures.
|
|
|
|
**Why:** Some Claude E2E tests (CSO audit, review-sql-injection) create minimal fake repos but would produce more realistic results with full repo context. The infrastructure exists (`describeWithWorktree()` in e2e-helpers.ts) — this extends it to the session-runner level.
|
|
|
|
**Context:** WorktreeManager shipped in v0.11.12.0. Currently only Gemini/Codex tests use worktrees. Claude tests use planted-bug fixture repos which are correct for their purpose, but new tests that want real repo context can use `describeWithWorktree()` today. This TODO is about making it even easier via a flag on `runSkillTest()`.
|
|
|
|
**Effort:** M (human: ~2 days / CC: ~20 min)
|
|
**Priority:** P3
|
|
**Depends on:** Worktree isolation (shipped v0.11.12.0)
|
|
|
|
### E2E model pinning — SHIPPED
|
|
|
|
~~**What:** Pin E2E tests to claude-sonnet-4-6 for cost efficiency, add retry:2 for flaky LLM responses.~~
|
|
|
|
Shipped: Default model changed to Sonnet for structure tests (~30), Opus retained for quality tests (~10). `--retry 2` added. `EVALS_MODEL` env var for override. `test:e2e:fast` tier added. Rate-limit telemetry (first_response_ms, max_inter_turn_ms) and wall_clock_ms tracking added to eval-store.
|
|
|
|
### Eval web dashboard
|
|
|
|
**What:** `bun run eval:dashboard` serves local HTML with charts: cost trending, detection rate, pass/fail history.
|
|
|
|
**Why:** Visual charts better for spotting trends than CLI tools.
|
|
|
|
**Context:** Reads `~/.gstack-dev/evals/*.json`. ~200 lines HTML + chart.js via Bun HTTP server.
|
|
|
|
**Effort:** M
|
|
**Priority:** P3
|
|
**Depends on:** Eval persistence (shipped in v0.3.6)
|
|
|
|
### CI/CD QA quality gate
|
|
|
|
**What:** Run `/qa` as a GitHub Action step, fail PR if health score drops below threshold.
|
|
|
|
**Why:** Automated quality gate catches regressions before merge. Currently QA is manual — CI integration makes it part of the standard workflow.
|
|
|
|
**Context:** Requires headless browse binary available in CI. The `/qa` skill already produces `baseline.json` with health scores — CI step would compare against the main branch baseline and fail if score drops. Would need `ANTHROPIC_API_KEY` in CI secrets since `/qa` uses Claude.
|
|
|
|
**Effort:** M
|
|
**Priority:** P2
|
|
**Depends on:** None
|
|
|
|
### Cross-platform URL open helper
|
|
|
|
**What:** `gstack-open-url` helper script — detect platform, use `open` (macOS) or `xdg-open` (Linux).
|
|
|
|
**Why:** The first-time Completeness Principle intro uses macOS `open` to launch the essay. If gstack ever supports Linux, this silently fails.
|
|
|
|
**Effort:** S (human: ~30 min / CC: ~2 min)
|
|
**Priority:** P4
|
|
**Depends on:** Nothing
|
|
|
|
### CDP-based DOM mutation detection for ref staleness
|
|
|
|
**What:** Use Chrome DevTools Protocol `DOM.documentUpdated` / MutationObserver events to proactively invalidate stale refs when the DOM changes, without requiring an explicit `snapshot` call.
|
|
|
|
**Why:** Current ref staleness detection (async count() check) only catches stale refs at action time. CDP mutation detection would proactively warn when refs become stale, preventing the 5-second timeout entirely for SPA re-renders.
|
|
|
|
**Context:** Parts 1+2 of ref staleness fix (RefEntry metadata + eager validation via count()) are shipped. This is Part 3 — the most ambitious piece. Requires CDP session alongside Playwright, MutationObserver bridge, and careful performance tuning to avoid overhead on every DOM change.
|
|
|
|
**Effort:** L
|
|
**Priority:** P3
|
|
**Depends on:** Ref staleness Parts 1+2 (shipped)
|
|
|
|
## Office Hours / Design
|
|
|
|
### Design docs → Supabase team store sync
|
|
|
|
**What:** Add design docs (`*-design-*.md`) to the Supabase sync pipeline alongside test plans, retro snapshots, and QA reports.
|
|
|
|
**Why:** Cross-team design discovery at scale. Local `~/.gstack/projects/$SLUG/` keyword-grep discovery works for same-machine users now, but Supabase sync makes it work across the whole team. Duplicate ideas surface, everyone sees what's been explored.
|
|
|
|
**Context:** /office-hours writes design docs to `~/.gstack/projects/$SLUG/`. The team store already syncs test plans, retro snapshots, QA reports. Design docs follow the same pattern — just add a sync adapter.
|
|
|
|
**Effort:** S
|
|
**Priority:** P2
|
|
**Depends on:** `garrytan/team-supabase-store` branch landing on main
|
|
|
|
### /yc-prep skill
|
|
|
|
**What:** Skill that helps founders prepare their YC application after /office-hours identifies strong signal. Pulls from the design doc, structures answers to YC app questions, runs a mock interview.
|
|
|
|
**Why:** Closes the loop. /office-hours identifies the founder, /yc-prep helps them apply well. The design doc already contains most of the raw material for a YC application.
|
|
|
|
**Effort:** M (human: ~2 weeks / CC: ~2 hours)
|
|
**Priority:** P2
|
|
**Depends on:** office-hours founder discovery engine shipping first
|
|
|
|
## Design Review
|
|
|
|
### /plan-design-review + /qa-design-review + /design-consultation — SHIPPED
|
|
|
|
Shipped as v0.5.0 on main. Includes `/plan-design-review` (report-only design audit), `/qa-design-review` (audit + fix loop), and `/design-consultation` (interactive DESIGN.md creation). `{{DESIGN_METHODOLOGY}}` resolver provides shared 80-item design audit checklist.
|
|
|
|
### Design outside voices in /plan-eng-review
|
|
|
|
**What:** Extend the parallel dual-voice pattern (Codex + Claude subagent) to /plan-eng-review's architecture review section.
|
|
|
|
**Why:** The design beachhead (v0.11.3.0) proves cross-model consensus works for subjective reviews. Architecture reviews have similar subjectivity in tradeoff decisions.
|
|
|
|
**Context:** Depends on learnings from the design beachhead. If the litmus scorecard format proves useful, adapt it for architecture dimensions (coupling, scaling, reversibility).
|
|
|
|
**Effort:** S
|
|
**Priority:** P3
|
|
**Depends on:** Design outside voices shipped (v0.11.3.0)
|
|
|
|
### Outside voices in /qa visual regression detection
|
|
|
|
**What:** Add Codex design voice to /qa for detecting visual regressions during bug-fix verification.
|
|
|
|
**Why:** When fixing bugs, the fix can introduce visual regressions that code-level checks miss. Codex could flag "the fix broke the responsive layout" during re-test.
|
|
|
|
**Context:** Depends on /qa having design awareness. Currently /qa focuses on functional testing.
|
|
|
|
**Effort:** M
|
|
**Priority:** P3
|
|
**Depends on:** Design outside voices shipped (v0.11.3.0)
|
|
|
|
## Document-Release
|
|
|
|
### Auto-invoke /document-release from /ship — SHIPPED
|
|
|
|
Shipped in v0.8.3. Step 8.5 added to `/ship` — after creating the PR, `/ship` automatically reads `document-release/SKILL.md` and executes the doc update workflow. Zero-friction doc updates.
|
|
|
|
### `{{DOC_VOICE}}` shared resolver
|
|
|
|
**What:** Create a placeholder resolver in gen-skill-docs.ts encoding the gstack voice guide (friendly, user-forward, lead with benefits). Inject into /ship Step 5, /document-release Step 5, and reference from CLAUDE.md.
|
|
|
|
**Why:** DRY — voice rules currently live inline in 3 places (CLAUDE.md CHANGELOG style section, /ship Step 5, /document-release Step 5). When the voice evolves, all three drift.
|
|
|
|
**Context:** Same pattern as `{{QA_METHODOLOGY}}` — shared block injected into multiple templates to prevent drift. ~20 lines in gen-skill-docs.ts.
|
|
|
|
**Effort:** S
|
|
**Priority:** P2
|
|
**Depends on:** None
|
|
|
|
## Ship Confidence Dashboard
|
|
|
|
### Smart review relevance detection — PARTIALLY SHIPPED
|
|
|
|
~~**What:** Auto-detect which of the 4 reviews are relevant based on branch changes (skip Design Review if no CSS/view changes, skip Code Review if plan-only).~~
|
|
|
|
`bin/gstack-diff-scope` shipped — categorizes diff into SCOPE_FRONTEND, SCOPE_BACKEND, SCOPE_PROMPTS, SCOPE_TESTS, SCOPE_DOCS, SCOPE_CONFIG. Used by design-review-lite to skip when no frontend files changed. Dashboard integration for conditional row display is a follow-up.
|
|
|
|
**Remaining:** Dashboard conditional row display (hide "Design Review: NOT YET RUN" when SCOPE_FRONTEND=false). Extend to Eng Review (skip for docs-only) and CEO Review (skip for config-only).
|
|
|
|
**Effort:** S
|
|
**Priority:** P3
|
|
**Depends on:** gstack-diff-scope (shipped)
|
|
|
|
|
|
## Codex
|
|
|
|
### Codex→Claude reverse buddy check skill
|
|
|
|
**What:** A Codex-native skill (`.agents/skills/gstack-claude/SKILL.md`) that runs `claude -p` to get an independent second opinion from Claude — the reverse of what `/codex` does today from Claude Code.
|
|
|
|
**Why:** Codex users deserve the same cross-model challenge that Claude users get via `/codex`. Currently the flow is one-way (Claude→Codex). Codex users have no way to get a Claude second opinion.
|
|
|
|
**Context:** The `/codex` skill template (`codex/SKILL.md.tmpl`) shows the pattern — it wraps `codex exec` with JSONL parsing, timeout handling, and structured output. The reverse skill would wrap `claude -p` with similar infrastructure. Would be generated into `.agents/skills/gstack-claude/` by `gen-skill-docs --host codex`.
|
|
|
|
**Effort:** M (human: ~2 weeks / CC: ~30 min)
|
|
**Priority:** P1
|
|
**Depends on:** None
|
|
|
|
## Completeness
|
|
|
|
### Completeness metrics dashboard
|
|
|
|
**What:** Track how often Claude chooses the complete option vs shortcut across gstack sessions. Aggregate into a dashboard showing completeness trend over time.
|
|
|
|
**Why:** Without measurement, we can't know if the Completeness Principle is working. Could surface patterns (e.g., certain skills still bias toward shortcuts).
|
|
|
|
**Context:** Would require logging choices (e.g., append to a JSONL file when AskUserQuestion resolves), parsing them, and displaying trends. Similar pattern to eval persistence.
|
|
|
|
**Effort:** M (human) / S (CC)
|
|
**Priority:** P3
|
|
**Depends on:** Boil the Lake shipped (v0.6.1)
|
|
|
|
## Safety & Observability
|
|
|
|
### On-demand hook skills (/careful, /freeze, /guard) — SHIPPED
|
|
|
|
~~**What:** Three new skills that use Claude Code's session-scoped PreToolUse hooks to add safety guardrails on demand.~~
|
|
|
|
Shipped as `/careful`, `/freeze`, `/guard`, and `/unfreeze` in v0.6.5. Includes hook fire-rate telemetry (pattern name only, no command content) and inline skill activation telemetry.
|
|
|
|
### Skill usage telemetry — SHIPPED
|
|
|
|
~~**What:** Track which skills get invoked, how often, from which repo.~~
|
|
|
|
Shipped in v0.6.5. TemplateContext in gen-skill-docs.ts bakes skill name into preamble telemetry line. Analytics CLI (`bun run analytics`) for querying. /retro integration shows skills-used-this-week.
|
|
|
|
### /investigate scoped debugging enhancements (gated on telemetry)
|
|
|
|
**What:** Six enhancements to /investigate auto-freeze, contingent on telemetry showing the freeze hook actually fires in real debugging sessions.
|
|
|
|
**Why:** /investigate v0.7.1 auto-freezes edits to the module being debugged. If telemetry shows the hook fires often, these enhancements make the experience smarter. If it never fires, the problem wasn't real and these aren't worth building.
|
|
|
|
**Context:** All items are prose additions to `investigate/SKILL.md.tmpl`. No new scripts.
|
|
|
|
**Items:**
|
|
1. Stack trace auto-detection for freeze directory (parse deepest app frame)
|
|
2. Freeze boundary widening (ask to widen instead of hard-block when hitting boundary)
|
|
3. Post-fix auto-unfreeze + full test suite run
|
|
4. Debug instrumentation cleanup (tag with DEBUG-TEMP, remove before commit)
|
|
5. Debug session persistence (~/.gstack/investigate-sessions/ — save investigation for reuse)
|
|
6. Investigation timeline in debug report (hypothesis log with timing)
|
|
|
|
**Effort:** M (all 6 combined)
|
|
**Priority:** P3
|
|
**Depends on:** Telemetry data showing freeze hook fires in real /investigate sessions
|
|
|
|
## Completed
|
|
|
|
### CI eval pipeline (v0.9.9.0)
|
|
- GitHub Actions eval upload on Ubicloud runners ($0.006/run)
|
|
- Within-file test concurrency (test() → testConcurrentIfSelected())
|
|
- Eval artifact upload + PR comment with pass/fail + cost
|
|
- Baseline comparison via artifact download from main
|
|
- EVALS_CONCURRENCY=40 for ~6min wall clock (was ~18min)
|
|
**Completed:** v0.9.9.0
|
|
|
|
### Deploy pipeline (v0.9.8.0)
|
|
- /land-and-deploy — merge PR, wait for CI/deploy, canary verification
|
|
- /canary — post-deploy monitoring loop with anomaly detection
|
|
- /benchmark — performance regression detection with Core Web Vitals
|
|
- /setup-deploy — one-time deploy platform configuration
|
|
- /review Performance & Bundle Impact pass
|
|
- E2E model pinning (Sonnet default, Opus for quality tests)
|
|
- E2E timing telemetry (first_response_ms, max_inter_turn_ms, wall_clock_ms)
|
|
- test:e2e:fast tier, --retry 2 on all E2E scripts
|
|
**Completed:** v0.9.8.0
|
|
|
|
### Phase 1: Foundations (v0.2.0)
|
|
- Rename to gstack
|
|
- Restructure to monorepo layout
|
|
- Setup script for skill symlinks
|
|
- Snapshot command with ref-based element selection
|
|
- Snapshot tests
|
|
**Completed:** v0.2.0
|
|
|
|
### Phase 2: Enhanced Browser (v0.2.0)
|
|
- Annotated screenshots, snapshot diffing, dialog handling, file upload
|
|
- Cursor-interactive elements, element state checks
|
|
- CircularBuffer, async buffer flush, health check
|
|
- Playwright error wrapping, useragent fix
|
|
- 148 integration tests
|
|
**Completed:** v0.2.0
|
|
|
|
### Phase 3: QA Testing Agent (v0.3.0)
|
|
- /qa SKILL.md with 6-phase workflow, 3 modes (full/quick/regression)
|
|
- Issue taxonomy, severity classification, exploration checklist
|
|
- Report template, health score rubric, framework detection
|
|
- wait/console/cookie-import commands, find-browse binary
|
|
**Completed:** v0.3.0
|
|
|
|
### Phase 3.5: Browser Cookie Import (v0.3.x)
|
|
- cookie-import-browser command (Chromium cookie DB decryption)
|
|
- Cookie picker web UI, /setup-browser-cookies skill
|
|
- 18 unit tests, browser registry (Comet, Chrome, Arc, Brave, Edge)
|
|
**Completed:** v0.3.1
|
|
|
|
### E2E test cost tracking
|
|
- Track cumulative API spend, warn if over threshold
|
|
**Completed:** v0.3.6
|
|
|
|
### Auto-upgrade mode + smart update check
|
|
- Config CLI (`bin/gstack-config`), auto-upgrade via `~/.gstack/config.yaml`, 12h cache TTL, exponential snooze backoff (24h→48h→1wk), "never ask again" option, vendored copy sync on upgrade
|
|
**Completed:** v0.3.8
|