Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ packages/core/src/generated/
packages/vscode-ide-companion/*.vsix

# Qwen Code Configs

.qwen/
!.qwen/commands/
!.qwen/skills/
Expand All @@ -72,6 +73,8 @@ __pycache__/
integration-tests/concurrent-runner/output/
integration-tests/concurrent-runner/task-*

integration-tests/terminal-capture/scenarios/screenshots/

# storybook
*storybook.log
storybook-static
104 changes: 104 additions & 0 deletions .qwen/skills/pr-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
name: pr-review
description: Reviews pull requests with code analysis and terminal smoke testing. Applies when examining code changes, running CLI tests, or when 'PR review', 'code review', 'terminal screenshot', 'visual test' is mentioned.
---

# PR Review β€” Code Review + Terminal Smoke Testing

## Workflow

### 1. Fetch PR Information

```bash
# List open PRs
gh pr list

# View PR details
gh pr view <number>

# Get diff
gh pr diff <number>
```

### 2. Code Review

Analyze changes across the following dimensions:

- **Correctness** β€” Is the logic correct? Are edge cases handled?
- **Code Style** β€” Does it follow existing code style and conventions?
- **Performance** β€” Are there any performance concerns?
- **Test Coverage** β€” Are there corresponding tests for the changes?
- **Security** β€” Does it introduce any security risks?

Output format:

- πŸ”΄ **Critical** β€” Must fix
- 🟑 **Suggestion** β€” Suggested improvement
- 🟒 **Nice to have** β€” Optional optimization

### 3. Terminal Smoke Testing (Run for Every PR)

**Run terminal-capture for every PR review**, not just UI changes. Reasons:

- **Smoke Test** β€” Verify the CLI starts correctly and responds to user input, ensuring the PR didn't break anything
- **Visual Verification** β€” If there are UI changes, screenshots provide the most intuitive review evidence
- **Documentation** β€” Attach screenshots to the PR comments so reviewers can see the results without building locally

```bash
# Checkout branch & build
gh pr checkout <number>
npm run build
```

#### Scenario Selection Strategy

Choose appropriate scenarios based on the PR's scope of changes:

| PR Type | Recommended Scenarios | Description |
| ------------------------------------- | ------------------------------------------------------------ | --------------------------------- |
| **Any PR** (default) | smoke test: send `hi`, verify startup & response | Minimal-cost smoke validation |
| Slash command changes | Corresponding command scenarios (`/about`, `/context`, etc.) | Verify command output correctness |
| Ink component / layout changes | Multiple scenarios + full-flow long screenshot | Verify visual effects |
| Large refactors / dependency upgrades | Run `scenarios/all.ts` fully | Full regression |

#### Running Screenshots

```bash
# Write scenario config to integration-tests/terminal-capture/scenarios/
# See terminal-capture skill for FlowStep API reference

# Single scenario
npx tsx integration-tests/terminal-capture/run.ts integration-tests/terminal-capture/scenarios/<scenario>.ts


# Check output in screenshots/ directory
```

#### Minimal Smoke Test Example

No need to write a new scenario file β€” just use the existing `about.ts`. It sends "hi" then runs `/about`, covering startup + input + command response:

```bash
npx tsx integration-tests/terminal-capture/run.ts integration-tests/terminal-capture/scenarios/about.ts
```

### 4. Upload Screenshots to PR

Use Playwright MCP browser to upload screenshots to the PR comments (images hosted at `github.com/user-attachments/assets/`, zero side effects):

1. Open the PR page with Playwright: `https://github.com/<repo>/pull/<number>`
2. Click the comment text box and enter a comment title (e.g., `## πŸ“· Terminal Smoke Test Screenshots`)
3. Click the "Paste, drop, or click to add files" button to trigger the file picker
4. Upload screenshot PNG files via `browser_file_upload` (can upload multiple one by one)
5. Wait for GitHub to process (about 2-3 seconds) β€” image links auto-insert into the comment box
6. Click the "Comment" button to submit

> **Prerequisite**: Playwright MCP needs `--user-data-dir` configured to persist GitHub login session. First time use requires manually logging into GitHub in the Playwright browser.

### 5. Submit Review

Submit code review comments via `gh pr review`:

```bash
gh pr review <number> --comment --body "review content"
```
197 changes: 197 additions & 0 deletions .qwen/skills/terminal-capture/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
---
name: terminal-capture
description: Automates terminal UI screenshot testing for CLI commands. Applies when reviewing PRs that affect CLI output, testing slash commands (/about, /context, /auth, /export), generating visual documentation, or when 'terminal screenshot', 'CLI test', 'visual test', or 'terminal-capture' is mentioned.
---

# Terminal Capture β€” CLI Terminal Screenshot Automation

Drive terminal interactions and screenshots via TypeScript configuration, used for visual verification during PR reviews.

## Prerequisites

Ensure the following dependencies are installed before running:

```bash
npm install # Install project dependencies (including node-pty, xterm, playwright, etc.)
npx playwright install chromium # Install Playwright browser
```

## Architecture

```
node-pty (pseudo-terminal) β†’ ANSI byte stream β†’ xterm.js (Playwright headless) β†’ Screenshot
```

Core files:

| File | Purpose |
| -------------------------------------------------------- | ------------------------------------------------------------------------ |
| `integration-tests/terminal-capture/terminal-capture.ts` | Low-level engine (PTY + xterm.js + Playwright) |
| `integration-tests/terminal-capture/scenario-runner.ts` | Scenario executor (parses config, drives interactions, auto-screenshots) |
| `integration-tests/terminal-capture/run.ts` | CLI entry point (batch run scenarios) |
| `integration-tests/terminal-capture/scenarios/*.ts` | Scenario configuration files |

## Quick Start

### 1. Write Scenario Configuration

Create a `.ts` file under `integration-tests/terminal-capture/scenarios/`:

```typescript
import type { ScenarioConfig } from '../scenario-runner.js';

export default {
name: '/about',
spawn: ['node', 'dist/cli.js', '--yolo'],
terminal: { title: 'qwen-code', cwd: '../../..' }, // Relative to this config file's location
flow: [
{ type: 'Hi, can you help me understand this codebase?' },
{ type: '/about' },
],
} satisfies ScenarioConfig;
```

### 2. Run

```bash
# Single scenario
npx tsx integration-tests/terminal-capture/run.ts integration-tests/terminal-capture/scenarios/about.ts

# Batch (entire directory)
npx tsx integration-tests/terminal-capture/run.ts integration-tests/terminal-capture/scenarios/
```

### 3. Output

Screenshots are saved to `integration-tests/terminal-capture/scenarios/screenshots/{name}/`:

| File | Description |
| --------------- | ---------------------------------- |
| `01-01.png` | Step 1 input state |
| `01-02.png` | Step 1 execution result |
| `02-01.png` | Step 2 input state |
| `02-02.png` | Step 2 execution result |
| `full-flow.png` | Final state full-length screenshot |

## FlowStep API

Each flow step can contain the following fields:

### `type: string` β€” Input Text

Automatic behavior: Input text β†’ Screenshot (01) β†’ Press Enter β†’ Wait for output to stabilize β†’ Screenshot (02).

```typescript
{
type: 'Hello';
} // Plain text
{
type: '/about';
} // Slash command (auto-completion handled automatically)
```

**Special rule**: If the next step is `key`, do not auto-press Enter (hand over control to the key sequence).

### `key: string | string[]` β€” Send Key Press

Used for menu selection, Tab completion, and other interactions. Does not auto-press Enter or auto-screenshot.

Supported key names: `ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight`, `Enter`, `Tab`, `Escape`, `Backspace`, `Space`, `Home`, `End`, `PageUp`, `PageDown`, `Delete`

```typescript
{
key: 'ArrowDown';
} // Single key
{
key: ['ArrowDown', 'ArrowDown', 'Enter'];
} // Multiple keys
```

Auto-screenshot is triggered after the key sequence ends (when the next step is not a `key`).

### `capture` / `captureFull` β€” Explicit Screenshot

Use as a standalone step, or override automatic naming:

```typescript
{
capture: 'initial.png';
} // Screenshot current viewport only
{
captureFull: 'all-output.png';
} // Screenshot full scrollback buffer
```

## Scenario Examples

### Basic: Input + Command

```typescript
flow: [{ type: 'explain this project' }, { type: '/about' }];
```

### Secondary Menu Selection (/auth)

```typescript
flow: [
{ type: '/auth' },
{ key: 'ArrowDown' }, // Select API Key option
{ key: 'Enter' }, // Confirm
{ type: 'sk-xxx' }, // Input API key
];
```

### Tab Completion Selection (/export)

```typescript
flow: [
{ type: 'Tell me about yourself' },
{ type: '/export' }, // No auto-Enter (next step is key)
{ key: 'Tab' }, // Pop format selection
{ key: 'ArrowDown' }, // Select format
{ key: 'Enter' }, // Confirm β†’ auto-screenshot
];
```

### Array Batch (Multiple Scenarios in One File)

```typescript
export default [
{ name: '/about', spawn: [...], flow: [...] },
{ name: '/context', spawn: [...], flow: [...] },
] satisfies ScenarioConfig[];
```

## Integration with PR Review

This tool is commonly used for visual verification during PR reviews. For the complete code review + screenshot workflow, see the [pr-review](../pr-review/SKILL.md) skill.

## Troubleshooting

| Issue | Cause | Solution |
| ------------------------------------ | ------------------------------------- | ---------------------------------------------------- |
| Playwright error `browser not found` | Browser not installed | `npx playwright install chromium` |
| Blank screenshot | Process starts slowly or build failed | Ensure `npm run build` succeeds, check spawn command |
| PTY-related errors | node-pty native module not compiled | `npm rebuild node-pty` |
| Unstable screenshot output | Terminal output not fully rendered | Check if the scenario needs additional wait time |

## Full ScenarioConfig Type

```typescript
interface ScenarioConfig {
name: string; // Scenario name (also used as screenshot subdirectory name)
spawn: string[]; // Launch command ["node", "dist/cli.js", "--yolo"]
flow: FlowStep[]; // Interaction steps
terminal?: {
// Terminal configuration (all optional)
cols?: number; // Number of columns, default 100
rows?: number; // Number of rows, default 28
theme?: string; // Theme: dracula|one-dark|github-dark|monokai|night-owl
chrome?: boolean; // macOS window decorations, default true
title?: string; // Window title, default "Terminal"
fontSize?: number; // Font size
cwd?: string; // Working directory (relative to config file)
};
outputDir?: string; // Screenshot output directory (relative to config file)
}
```
Loading