feat: compound start, viewport screenshot, openclaw skill (0.2.8)#41
Merged
Conversation
Spec for v0.2.8 covering three test-found issues: - per-target OpenClaw SKILL.md note (screenshots to /tmp/openclaw) - shell wrapping of compound Sandbox daemon already running on port 15801 Creating sandbox: mode=cli, command=zsh Sandbox created: id=9e684f01, pty_pid=Some(1004), window_id=Some(170387) Daemon port: 15801 Waiting for renderer done Waiting for terminal Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... Waiting for terminal. Waiting for terminal.. Waiting for terminal... commands (zsh -lc) - fix screenshot viewport (baseY), scroll-over-buffer, full-session text Co-Authored-By: Claude <noreply@anthropic.com>
…ot, openclaw skill Co-Authored-By: Claude <noreply@anthropic.com>
…enclaw Co-Authored-By: Claude <noreply@anthropic.com>
…commands Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
…l offset Co-Authored-By: Claude <noreply@anthropic.com>
…set 0 Co-Authored-By: Claude <noreply@anthropic.com>
- Extend ScreenshotQuery with optional scroll (u32) and top (bool);
top maps to u32::MAX so renderer clamps to scrollback top.
- Add scroll field to capture_request WS message and pass through to
request_renderer_screenshot.
- Add new /box/{id}/scrollback route backed by request_renderer_scrollback
(ScrollbackQuery: raw/from_line/to_line). Response is text/plain.
- Add pending_scrollback HashMap to DaemonState; resolve scrollback_response
and scrollback_error WS arms from it.
- IT: screenshot_query_parses_scroll_and_top and scrollback_route_exists.
Co-Authored-By: Claude <noreply@anthropic.com>
…shot WS Co-Authored-By: Claude <noreply@anthropic.com>
Extend daemon_screenshot with scroll/top query params and add daemon_scrollback client helper. Wire them into the CLI surface: - screenshot --up N / --top thread into the daemon URL - new \`scrollback\` subcommand dumps the clean ANSI-free session text to stdout or -o <file>, with optional --raw / --from-line / --to-line - MCP tool list: extend screenshot_sandbox schema with up/top and add scrollback_sandbox tool Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
🔒 门禁检查结果
Rust 测试覆盖率
前端测试覆盖率
✅ 所有检查通过,可以合入
|
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Previously cli-box-daemon ignored all args and always started serving, so 'cli-box-daemon --version' would silently launch a daemon. Handle the introspection flags before initializing the runtime. Co-Authored-By: Claude <noreply@anthropic.com>
xterm renders CJK/emoji as double-width: the char sits in a width-2 cell
followed by a width-0 continuation cell with no glyph. The buffer readers
treated that empty continuation cell as a space, padding CJK text
('执 行 pwd 命 令'). Skip cells where getWidth()===0 in both readScrollback
and renderBufferToPng so CJK is contiguous.
Co-Authored-By: Claude <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.
Problem
Three issues found during v0.2.7 release testing:
cli-boxSKILL.md is identical for every harness, so OpenClaw-driven agents savecli-box screenshotoutput to the CWD. OpenClaw is sandboxed to/tmp/openclaw/and cannot read/send those images.startfails.cli-box start "cd /x && claude -r"errors out — the daemon's PTY spawn treats the whole string as the executable name (CommandBuilder::new(command)), so&&,;,|, andcdare never interpreted.cli-box screenshoton a longclaudetask returns the oldest lines, not the visible viewport. The renderer's buffer-fallback loop readsbuffer.getLine(0..rows)(scrollback top) instead of the viewport (baseY..baseY+rows). There is also no way to scroll the capture window, and no way to dump the whole session.Solution
1. OpenClaw screenshot path (
329d992)packages/cli-box-skill/installer/shared.mjs: newtargetSpecificNote(id);installSkillToTargetscomposesreadBundledSkill() + targetSpecificNote(id)per target. Only the OpenClaw copy gains a note instructing agents to save screenshots under/tmp/openclaw/. Claude/OpenCode bodies are byte-identical to before.2. Compound
startvia shell (e669c5a,e216755)crates/cli-box-core/src/process/mod.rs: pureneeds_shell+wrap_shell_command+prepare_spawnhelpers. When the command contains a space or shell metacharacters, it is re-spawned aszsh -lc "<full line>"; plain commands pass through unchanged. Wired at the top of the macOSspawn_cli_with_size, so CLI/MCP/Electron-new-dialog all benefit..apppaths are unaffected (mode split happens upstream); the displayed command inlist/inspectstill shows the original (stored separately inInstanceKind).3. Viewport screenshot + scroll + full-session text
buffer.baseYwith a clamped scroll offset (a8cfe45,dca44ce).captureToPng(offset)uses the live xterm canvas only at offset 0, else renders the buffer window.screenshot?scroll=N|top=trueand a new/box/{id}/scrollbackroute (5bc769c).capture_request.scrolland newscrollback_request/responseover the screenshot socket; purereadScrollbacktext extractor (dc8e1b6).screenshot --up N/--top, newscrollback --idsubcommand, plus MCP tools (77eb8ca).tests/e2e-compound-start-screenshot.sh(b9fb981). Polish: dead-code removal + negative-offset guard test (dd80f59). Version 0.2.8 / skill 0.2.2 (5cd9b24).Spec:
docs/superpowers/specs/2026-06-17-start-shell-screenshot-openclaw-design.mdPlan:
docs/superpowers/plans/2026-06-17-start-shell-screenshot-openclaw.mdTest Plan
needs_shell/wrap_shell_command/prepare_spawntruth table (8 tests)/tmp/openclaw/; Claude/OpenCode do not (skill suite 18/18)renderBufferToPngviewport(baseY)+offset+clamp+negative (4 tests);readScrollbacktrim/range/clamp (4 tests);captureToPngbackground/dimensions migrated to the extracted module/box/{id}/screenshot?scroll=/?top=parse;/box/{id}/scrollbackroute exists (daemon_integration)cargo test/cargo clippy -D warnings/cargo fmt --check/pnpm typecheck/pnpm vitest run— all greencli-box screenshot --helpshows--up/--top;cli-box scrollback --helpshows its optionssh release.sh+ daemon restart): the compound-start E2E needs the rebuilt 0.2.8 daemon on PATH. A stale 0.2.4 release daemon is currently running in this environment, so the live E2E exercised the old spawn path (the 8 unit tests + 2 ITs verify the new logic). After a release rebuild + daemon restart the E2E passes.scrollbackreturns claude's full conversation (vs. current screen only) and whether--upreveals older content — to determine if claude uses the alternate-screen buffer (which would limit terminal-scrollback history).🤖 Generated with Claude Code