---
name: qqbrowser-playbook
description: Playbook management skill for generating, listing, and running parameterized browser automation replay scripts. Use after completing a browser automation task with qqbrowser-skill to convert the recorded steps into a reusable, parameterized playbook.
source: local
homepage: https://browser.qq.com/
permissions:
  - filesystem: Required for reading/writing playbook files in the playbooks directory
  - network: Required for executing replay via qqbrowser-skill
---

# qqbrowser-playbook

A skill for managing browser automation playbooks. It works alongside `qqbrowser-skill` to convert raw task recordings into reusable, parameterized replay scripts.

## Overview

After you complete a browser automation task using `qqbrowser-skill` (wrapped in `task_begin`/`task_end`), use this skill to:

1. **Retrieve** the latest task recording
2. **Analyze** the steps and identify values that should be parameterized
3. **Generate** a playbook file (parameterized replay script)
4. **List** all available playbooks
5. **Run** a playbook with specified parameters

**CRITICAL RULES:**
- A playbook MUST be generated from an actual task recording (`task_latest`). You MUST NOT invent or fabricate steps.
- You MUST only use actions that appear in the `task_latest` output. These are the only valid actions for the playbook.
- The generated playbook steps must be a direct transformation of the recorded steps — only replacing literal user data with `{{param_name}}` placeholders.
- Element identification MUST use the `index` field from the recording (e.g., `"index": "154_17q6_1w8c"`). Do NOT substitute indices with arbitrary values.
- If no recording exists (`task_latest` returns empty), you MUST first complete the task using `qqbrowser-skill` with `task_begin`/`task_end`, then generate the playbook from the recording.
- **FILE PATH**: Playbook files MUST be saved to `~/.qqbrowser-skill/playbooks/<name>.json` on macOS/Linux. Do NOT save to any other directory such as `~/.qbotclaw/`, project directories, or temp directories.
- **FILE FORMAT**: The JSON file MUST follow the exact nested structure defined below (with `version`, `metadata`, `params`, `settings`, `steps` as top-level keys). Do NOT use a flat/simplified format. Do NOT use `parameters` instead of `params`. Do NOT omit `metadata` or `settings`.
- **USE write_to_file**: When saving the playbook JSON, use the `write_to_file` tool with the full absolute path (e.g., `/Users/<username>/.qqbrowser-skill/playbooks/xiaohongshu-publish-note.json`). Ensure the directory exists first (create with `mkdir -p`).

## Playbook Storage

Playbooks are stored in the `playbooks` subdirectory under the qqbrowser-skill data directory (`DEFAULT_DATA_DIR/playbooks/`). The data directory follows the same convention as `qqbrowser-skill`:

| Platform | Playbooks Directory |
|----------|-------------------|
| Linux / macOS | `~/.qqbrowser-skill/playbooks/` |
| Windows | `%LOCALAPPDATA%/qqbrowser-skill/playbooks/` |

**To determine the playbooks directory at runtime:**

```bash
# Linux / macOS
PLAYBOOKS_DIR="$HOME/.qqbrowser-skill/playbooks"

# Windows (PowerShell)
$PLAYBOOKS_DIR = "$env:LOCALAPPDATA/qqbrowser-skill/playbooks"
```

File naming convention: `<name>.json` (name derived from metadata, kebab-case, e.g. `xiaohongshu-publish-note.json`)

## Workflow

### Step 1: Get the Latest Task Recording

```bash
qqbrowser-skill task_latest
```

This returns a JSON object with the raw recorded steps. Example output:

```json
{
  "task_id": "task_20260521_165900",
  "description": "自动打开小红书并发布一篇笔记",
  "commands": [
    {"skill_name": "browser_go_to_url", "params": {"url": "https://www.xiaohongshu.com/explore"}},
    {"skill_name": "browser_click_element", "params": {"index": "154_17q6_1w8c"}},
    {"skill_name": "browser_click_element", "params": {"index": "7_ek3h_2b3r"}},
    {"skill_name": "browser_click_element", "params": {"index": "10_4bq5_u01g"}},
    {"skill_name": "browser_input_text", "params": {"index": "6_2vl4_txwg", "text": "我的笔记标题"}},
    {"skill_name": "browser_input_text", "params": {"index": "4_ku44_rrpt", "text": "这是笔记的正文内容..."}},
    {"skill_name": "browser_click_element", "params": {"index": "19_oxgq_ttmr"}}
  ],
  "started_at": "2026-05-21T16:59:00Z",
  "ended_at": "2026-05-21T17:01:30Z"
}
```

### Step 2: AI Analyzes and Generates the Playbook

Based on the task recording, you (the AI) must:

1. **Keep all actions and indices exactly as recorded** — do NOT change `action` names or `index` values
2. **Identify parameterizable values** — values that a user would likely want to change on each run:
   - Text inputs (`browser_input_text` → the `text` field)
   - URLs (`browser_go_to_url` → the `url` field, only if the URL varies per use)
   - File paths in upload actions
   - Any user-specific data (names, emails, content, etc.)
3. **Define parameters** with descriptive names, descriptions, and whether they are required
4. **Replace ONLY literal values** with `{{param_name}}` placeholders in the steps (only the `text`, `url`, or file path fields — NEVER replace `action` or `index`)
5. **Add meaningful descriptions** to each step
6. **Set appropriate metadata** (name, description, url)

**IMPORTANT**: The transformation from recording to playbook is purely:
- Recording `"text": "我的搜索词"` → Playbook `"text": "{{search_keyword}}"`
- Everything else (action names, index values, key names) stays **exactly** the same.

### Step 3: Write the Playbook File

Generate a JSON file conforming to this exact format and save it to the playbooks directory:

```json
{
  "version": "1.0",
  "metadata": {
    "name": "小红书发布长文笔记",
    "description": "自动打开小红书，发布一篇长文笔记并暂存离开",
    "created_at": "2026-05-21T16:59:00Z",
    "url": "https://www.xiaohongshu.com/explore"
  },
  "params": {
    "notes_title": {
      "description": "笔记标题",
      "required": true
    },
    "notes_content": {
      "description": "笔记正文内容",
      "required": true
    }
  },
  "settings": {
    "default_delay_ms": 1000,
    "default_retry_count": 1,
    "step_timeout_ms": 30000
  },
  "steps": [
    {
      "action": "browser_go_to_url",
      "params": { "url": "https://www.xiaohongshu.com/explore" },
      "description": "打开小红书探索页"
    },
    {
      "action": "browser_click_element",
      "params": { "index": "154_17q6_1w8c" },
      "description": "点击发布按钮"
    },
    {
      "action": "browser_click_element",
      "params": { "index": "7_ek3h_2b3r" },
      "description": "选择写长文"
    },
    {
      "action": "browser_click_element",
      "params": { "index": "10_4bq5_u01g" },
      "description": "点击新的创作"
    },
    {
      "action": "browser_input_text",
      "params": { "index": "6_2vl4_txwg", "text": "{{notes_title}}" },
      "description": "输入笔记标题"
    },
    {
      "action": "browser_input_text",
      "params": { "index": "4_ku44_rrpt", "text": "{{notes_content}}" },
      "description": "输入笔记正文"
    },
    {
      "action": "browser_click_element",
      "params": { "index": "19_oxgq_ttmr" },
      "description": "点击暂存离开"
    }
  ]
}
```

## Playbook File Format Specification

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `version` | string | Yes | Always `"1.0"` |
| `metadata.name` | string | Yes | Human-readable name of the playbook |
| `metadata.description` | string | Yes | What this playbook does |
| `metadata.created_at` | string | Yes | ISO 8601 timestamp of creation |
| `metadata.url` | string | No | The starting URL of the automation |
| `params` | object | No | Parameter definitions (omit if no parameters needed) |
| `params.<key>.description` | string | Yes | What this parameter is for |
| `params.<key>.required` | boolean | Yes | Whether the parameter must be provided |
| `params.<key>.default` | string | No | Default value if not provided |
| `settings.default_delay_ms` | number | Yes | Delay between steps in milliseconds |
| `settings.default_retry_count` | number | Yes | Number of retries on step failure |
| `settings.step_timeout_ms` | number | Yes | Timeout for each step |
| `steps[].action` | string | Yes | The browser action (must have `browser_` prefix) |
| `steps[].params` | object | Yes | Parameters for the action |
| `steps[].description` | string | Yes | Human-readable step description |

### Parameter Placeholder Syntax

Use `{{param_name}}` in step params to reference a defined parameter. The param_name must match a key in the top-level `params` object.

## Commands

### Generate a Playbook

After retrieving task_latest output, write the generated playbook JSON to the playbooks directory:

```bash
# 1. Get the latest recording
qqbrowser-skill task_latest

# 2. AI analyzes the output and generates the playbook content (this is done by you, the AI)

# 3. Ensure the playbooks directory exists and write the file
# Linux / macOS:
mkdir -p "$HOME/.qqbrowser-skill/playbooks"
# Windows (PowerShell):
New-Item -ItemType Directory -Force -Path "$env:LOCALAPPDATA/qqbrowser-skill/playbooks"

# 4. Save the JSON file as <kebab-case-name>.json in the playbooks directory
```

### List Available Playbooks

```bash
# Linux / macOS
ls ~/.qqbrowser-skill/playbooks/

# Windows (PowerShell)
Get-ChildItem "$env:LOCALAPPDATA/qqbrowser-skill/playbooks"
```

To show details of a specific playbook:

```bash
cat "<playbooks_dir>/<name>.json"
```

### Run a Playbook

Use `qqbrowser-skill browser_replay` to execute a playbook:

```bash
# Run without parameters (all params must have defaults or be optional)
qqbrowser-skill browser_replay --script "<playbooks_dir>/<name>.json"

# Run with parameters
qqbrowser-skill browser_replay --script "<playbooks_dir>/<name>.json" --variables '{"notes_title": "今日分享", "notes_content": "这是内容..."}'
```

## Parameter Extraction Guidelines

When analyzing task recordings to identify parameters, follow these rules:

### SHOULD be parameterized:
- **User-generated text content**: titles, messages, descriptions, comments, posts
- **User-specific data**: usernames, email addresses, phone numbers, passwords
- **Search queries**: any text entered into search boxes
- **File paths**: paths to files being uploaded
- **Variable URLs**: URLs that contain user-specific identifiers or change per use

### Should NOT be parameterized:
- **Fixed navigation URLs**: the starting URL of the workflow (e.g., `https://www.xiaohongshu.com/explore`)
- **Element indices**: the `index` field in click/input actions (these are structural, not data)
- **UI interaction steps**: clicks on fixed buttons like "Submit", "Next", "Save"
- **Fixed option selections**: dropdown choices that are always the same for this workflow

### Naming Conventions for Parameters:
- Use `snake_case` for parameter names
- Be descriptive: `notes_title` not `title`, `search_query` not `q`
- Group related params with common prefix: `login_username`, `login_password`

## Example: Full Workflow

```
User: "帮我生成一个回放脚本"

AI steps:
1. Run: qqbrowser-skill task_latest
2. Analyze the returned commands
3. Identify that browser_input_text steps contain user data that should be parameterized
4. Generate the playbook JSON with params and {{placeholders}}
5. Determine the correct playbooks directory for the current platform
6. Ensure the playbooks directory exists (mkdir -p)
7. Write the JSON file to <playbooks_dir>/<name>.json
8. Report to the user: playbook name, parameters defined, file path, and how to run it
```

## Notes

- This skill does NOT require any additional installation — it uses `qqbrowser-skill` commands and file system operations
- The AI is responsible for the analysis and generation logic — no separate binary or service is needed
- Playbook files are plain JSON and can be manually edited if needed
- Always ensure the playbooks directory exists before writing
- The playbooks directory follows the same platform convention as `qqbrowser-skill` data directory (`~/.qqbrowser-skill/` on Linux/macOS, `%LOCALAPPDATA%/qqbrowser-skill/` on Windows)

## Common Mistakes to Avoid

| Mistake | Why it's wrong | Correct approach |
|---------|---------------|-----------------|
| Generating steps without running `task_latest` first | Playbooks must be based on actual recordings | Always run `task_latest` first, then transform |
| Using actions not in `task_latest` output | Only actions from the recording are valid | Copy actions exactly from `task_latest` output |
| Changing the `action` field from what was recorded | Actions must match the recording exactly | Copy action names verbatim |
| Replacing `index` values with something else | Index is a structural reference, not user data | Never parameterize index values |
| Using `{{param}}` in fields other than user data | Only user-provided content should be parameterized | Only replace `text`, `url`, or file path values |
| Saving to wrong directory (e.g. `~/.qbotclaw/workspace/`) | Playbooks have a designated storage path | Always save to `~/.qqbrowser-skill/playbooks/` |
| Using flat JSON format (top-level `name`, `parameters`, `steps`) | The schema requires nested structure | Must use `metadata.name`, `params`, `settings`, `steps` structure |
| Using `parameters` key instead of `params` | The schema key is `params` | Use `params` with `description` and `required` fields |
| Using `write content=` shell command to save | May corrupt JSON formatting | Use `write_to_file` tool with proper path |
