Skill: shuxiang255-sudo/lobster-training (version 1.0.0)

--- name: image-gen description: AI图像生成与编辑。支持文生图、图+文生图、风格转换。当用户要求画图、生成图片、编辑图片、图片风格转换时使用此 skill。支持多种比例（1:1、3:2、16:9、21:9 等）和分辨率（标准、2K、4K）。 --- # AI 图像生成 通过执行脚本调用 Gemini Flash Image API 生成图片。 ## 环境变量 脚本通过以下环境变量获取 API 配置： - `IMAGE_GEN_API_KEY` — API 密钥 - `IMAGE_GEN_BASE_URL` — API 基础地址（默认：https://code.newcli.com/gemini） ## 使用方法 ### 生成图片 执行脚本生成图片： ```bash export IMAGE_GEN_API_KEY="your-api-key" export IMAGE_GEN_BASE_URL="https://code.newcli.com/gemini" python3 scripts/generate_image.py "你的提示词" --model gemini-3.1-flash-image-2k-16x9 --output output.png ``` ### 参数说明 - `prompt`（必填）：图片描述提示词 - `--model, -m`：模型名称，默认 `gemini-3.1-flash-image-2k-16x9` - `--output, -o`：输出文件路径，默认当前目录 `generated_image.png` ## 可用模型 默认模型：`gemini-3.1-flash-image-2k-16x9`（2K 分辨率，16:9 横屏） ### 基础模型（标准分辨率） | 模型 ID | 比例 | 适用场景 | |---------|------|----------| | gemini-3.1-flash-image | 1:1 | 社交媒体头像 | | gemini-3.1-flash-image-3x2 | 3:2 | 横版照片 | | gemini-3.1-flash-image-2x3 | 2:3 | 竖版海报 | | gemini-3.1-flash-image-3x4 | 3:4 | 竖版海报 | | gemini-3.1-flash-image-4x3 | 4:3 | 传统比例 | | gemini-3.1-flash-image-4x5 | 4:5 | Instagram | | gemini-3.1-flash-image-5x4 | 5:4 | 传统横版 | | gemini-3.1-flash-image-9x16 | 9:16 | 手机壁纸/短视频 | | gemini-3.1-flash-image-16x9 | 16:9 | 电脑壁纸/视频 | | gemini-3.1-flash-image-21x9 | 21:9 | 超宽屏 | ### 2K 分辨率（推荐） | 模型 ID | 比例 | |---------|------| | gemini-3.1-flash-image-2k | 1:1 | | gemini-3.1-flash-image-2k-3x2 | 3:2 | | gemini-3.1-flash-image-2k-2x3 | 2:3 | | gemini-3.1-flash-image-2k-3x4 | 3:4 | | gemini-3.1-flash-image-2k-4x3 | 4:3 | | gemini-3.1-flash-image-2k-4x5 | 4:5 | | gemini-3.1-flash-image-2k-5x4 | 5:4 | | gemini-3.1-flash-image-2k-9x16 | 9:16 | | gemini-3.1-flash-image-2k-16x9 | 16:9 | | gemini-3.1-flash-image-2k-21x9 | 21:9 | ### 4K 分辨率 | 模型 ID | 比例 | |---------|------| | gemini-3.1-flash-image-4k | 1:1 | | gemini-3.1-flash-image-4k-3x2 | 3:2 | | gemini-3.1-flash-image-4k-2x3 | 2:3 | | gemini-3.1-flash-image-4k-3x4 | 3:4 | | gemini-3.1-flash-image-4k-4x3 | 4:3 | | gemini-3.1-flash-image-4k-4x5 | 4:5 | | gemini-3.1-flash-image-4k-5x4 | 5:4 | | gemini-3.1-flash-image-4k-9x16 | 9:16 | | gemini-3.1-flash-image-4k-16x9 | 16:9 | ## 工作流程 1. **理解需求**：分析用户的图片需求，确定比例和分辨率 2. **选择模型**：根据用途选择合适的模型（默认 2K-16x9） 3. **优化提示词**：将用户描述扩展为详细的图片提示词 4. **执行脚本**：调用 `scripts/generate_image.py` 生成图片 5. **展示结果**：读取生成的图片展示给用户 ## 提示词技巧 - **具体描述**：主体、场景、光线、风格、色调 - **风格参考**：水彩、油画、赛博朋克、吉卜力、写实摄影、中国工笔等 - **构图说明**：视角（俯视/仰视）、景深、焦点 - **色彩指定**：主色调、配色方案 ## 示例 生成中国风后羿射日图： ```bash python3 scripts/generate_image.py \ "一位英勇的古代射手后羿站在险峻的高山之巅，身披金色战甲，肌肉紧绷，拉开巨大的神弓，一支燃烧着神圣光芒的箭矢对准天空中炽热的太阳。天空中有多个太阳同时燃烧，火焰倾泻而下。背景是翻滚的云海和龟裂的大地，远山在热浪中扭曲。中国传统工笔重彩风格，水墨与金箔点缀，色彩以深红、金色、墨黑、靛蓝为主，画面气势磅礴，具有敦煌壁画的厚重感。16:9 宽幅构图。" \ --model gemini-3.1-flash-image-2k-16x9 \ --output houyi.png ```

path: lobster-training-skill/package.json
content: {
  "name": "lobster-training",
  "version": "1.0.0",
  "description": "🦞 小龙虾入职培训手册 - 自动学习执行文档，学习完成后自动安装技能、提问用户、记录信息、升级配置",
  "main": "scripts/auto-trigger.js",
  "author": "Power",
  "license": "MIT",
  "keywords": ["training", "onboarding", "configuration", "personalization", "openclaw"],
  "dependencies": {
    "yaml": "^2.3.0"
  },
  "openclaw": {
    "minVersion": "0.9.0",
    "tools": ["exec", "read", "write"],
    "hooks": {
      "postInstall": "scripts/post-install.js",
      "onMessage": "scripts/on-message.js"
    },
    "config": {
      "auto_install": {
        "type": "boolean",
        "default": true,
        "description": "是否自动安装技能包"
      },
      "ask_questions": {
        "type": "boolean",
        "default": true,
        "description": "是否主动提问用户"
      },
      "record_to_memory": {
        "type": "boolean",
        "default": true,
        "description": "是否记录到记忆文件"
      }
    }
  },
  "bundled_skills": [
    {
      "name": "ai-image-gen",
      "version": "1.1.0",
      "file": "skills/ai-image-gen-1.1.0.zip",
      "description": "智能图片生成和设计能力"
    },
    {
      "name": "self-improving-agent",
      "version": "3.0.6",
      "file": "skills/self-improving-agent-3.0.6.zip",
      "description": "自我学习和迭代升级能力"
    },
    {
      "name": "agent-browser",
      "version": "0.2.0",
      "file": "skills/agent-browser-0.2.0.zip",
      "description": "浏览器控制和网页交互"
    }
  ],
  "training": {
    "auto_start": true,
    "questions_count": 6,
    "sequential": true,
    "target_files": ["USER.md", "USER_PROFILE.md", "MEMORY.md", "SOUL.md", "IDENTITY.md"]
  }
}


path: README.md
content: # image-gen

AI 图像生成 Skill，基于 Gemini Flash Image 模型，支持文生图、图+文生图、多比例、多分辨率。

## 安装

```bash
clawhub install image-gen
```

## 环境变量配置

使用前需配置以下环境变量（**不要硬编码到代码中**）：

```bash
IMAGE_GEN_API_KEY=your-api-key
IMAGE_GEN_BASE_URL=your-base-url
```

## 获取 API Key

推荐使用 FoxCode 中转服务，注册地址：

👉 [https://foxcode.rjj.cc/auth/register?aff=R0P5ZY](https://foxcode.rjj.cc/auth/register?aff=R0P5ZY)

注册后在控制台获取 API Key 和 Base URL。

## 支持的模型

- 基础（标准分辨率）：1:1、3:2、2:3、3:4、4:3、4:5、5:4、9:16、16:9、21:9
- 2K 分辨率：同上所有比例
- 4K 分辨率：同上所有比例（不含 21:9）

默认模型：`gemini-3.1-flash-image-2k-16x9`

## License

MIT


path: scripts/generate_image.py
content: #!/usr/bin/env python3
"""
AI Image Generation Script
Uses Gemini Flash Image model via Google Generative AI protocol
"""
import os
import sys
import json
import base64
import httpx
from pathlib import Path

[REDACTED_SECRET]"IMAGE_GEN_API_KEY", "")
BASE_URL = os.environ.get("IMAGE_GEN_BASE_URL", "https://code.newcli.com/gemini")

def generate_image(prompt: str, model: str = "gemini-3.1-flash-image-2k-16x9", output_path: str = None) -> str:
    """Generate image from text prompt"""
    
    if not [REDACTED_SECRET]"ERROR: IMAGE_GEN_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    
    url = f"{BASE_URL}/v1beta/models/{model}:generateContent"
    
    headers = {
        "Content-Type": "application/json",
        "x-goog-api-key": API_KEY,
    }
    
    payload = {
        "contents": [
            {
                "parts": [
                    {"text": prompt}
                ]
            }
        ],
        "generationConfig": {
            "responseModalities": ["IMAGE", "TEXT"],
            "responseMimeType": "text/plain"
        }
    }
    
    print(f"Generating image with model: {model}", file=sys.stderr)
    print(f"Prompt: {prompt[:100]}...", file=sys.stderr)
    
    try:
        with httpx.Client(timeout=120.0) as client:
            response = client.post(url, headers=headers, json=payload)
            response.raise_for_status()
            result = response.json()
    except Exception as e:
        print(f"ERROR: API call failed: {e}", file=sys.stderr)
        sys.exit(1)
    
    # Extract image from response
    parts = result.get("candidates", [{}])[0].get("content", {}).get("parts", [])
    
    image_data = None
    text_response = ""
    
    for part in parts:
        if "inlineData" in part:
            image_data = part["inlineData"]
        elif "text" in part:
            text_response = part["text"]
    
    if not image_data:
        print(f"No image in response. Text: {text_response}", file=sys.stderr)
        sys.exit(1)
    
    # Decode and save image
    img_bytes = base64.b64decode(image_data["data"])
    mime_type = image_data.get("mimeType", "image/png")
    ext = mime_type.split("/")[-1] if "/" in mime_type else "png"
    
    if output_path:
        out_file = Path(output_path)
    else:
        out_file = Path.cwd() / f"generated_image.{ext}"
    
    out_file.write_bytes(img_bytes)
    print(f"Image saved to: {out_file}", file=sys.stderr)
    
    # Return path for consumption
    print(str(out_file))
    return str(out_file)


if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(description="Generate image with Gemini Flash Image")
    parser.add_argument("prompt", help="Text prompt for image generation")
    parser.add_argument("--model", "-m", default="gemini-3.1-flash-image-2k-16x9", help="Model to use")
    parser.add_argument("--output", "-o", help="Output file path")
    args = parser.parse_args()
    
    generate_image(args.prompt, args.model, args.output)


path: _meta.json
content: ownerId: kn7am012jqjnrffbsjswg8258182c5y9
slug: ai-image-gen
version: 1.1.0
publishedAt: 1772953393531

path: .learnings/ERRORS.md
content: # Errors Log

Command failures, exceptions, and unexpected behaviors.

---


path: .learnings/FEATURE_REQUESTS.md
content: # Feature Requests

Capabilities requested by user that don't currently exist.

---


path: .learnings/LEARNINGS.md
content: # Learnings Log

Captured learnings, corrections, and discoveries. Review before major tasks.

---


path: assets/LEARNINGS.md
content: # Learnings

Corrections, insights, and knowledge gaps captured during development.

**Categories**: correction | insight | knowledge_gap | best_practice
**Areas**: frontend | backend | infra | tests | docs | config
**Statuses**: pending | in_progress | resolved | wont_fix | promoted | promoted_to_skill

## Status Definitions

| Status | Meaning |
|--------|---------|
| `pending` | Not yet addressed |
| `in_progress` | Actively being worked on |
| `resolved` | Issue fixed or knowledge integrated |
| `wont_fix` | Decided not to address (reason in Resolution) |
| `promoted` | Elevated to CLAUDE.md, AGENTS.md, or copilot-instructions.md |
| `promoted_to_skill` | Extracted as a reusable skill |

## Skill Extraction Fields

When a learning is promoted to a skill, add these fields:

```markdown
**Status**: promoted_to_skill
**Skill-Path**: skills/skill-name
```

Example:
```markdown
## [LRN-20250115-001] best_practice

**Logged**: 2025-01-15T10:00:00Z
**Priority**: high
**Status**: promoted_to_skill
**Skill-Path**: skills/docker-m1-fixes
**Area**: infra

### Summary
Docker build fails on Apple Silicon due to platform mismatch
...
```

---



path: assets/SKILL-TEMPLATE.md
content: # Skill Template

Template for creating skills extracted from learnings. Copy and customize.

---

## SKILL.md Template

```markdown
---
name: skill-name-here
description: "Concise description of when and why to use this skill. Include trigger conditions."
---

# Skill Name

Brief introduction explaining the problem this skill solves and its origin.

## Quick Reference

| Situation | Action |
|-----------|--------|
| [Trigger 1] | [Action 1] |
| [Trigger 2] | [Action 2] |

## Background

Why this knowledge matters. What problems it prevents. Context from the original learning.

## Solution

### Step-by-Step

1. First step with code or command
2. Second step
3. Verification step

### Code Example

\`\`\`language
// Example code demonstrating the solution
\`\`\`

## Common Variations

- **Variation A**: Description and how to handle
- **Variation B**: Description and how to handle

## Gotchas

- Warning or common mistake #1
- Warning or common mistake #2

## Related

- Link to related documentation
- Link to related skill

## Source

Extracted from learning entry.
- **Learning ID**: LRN-YYYYMMDD-XXX
- **Original Category**: correction | insight | knowledge_gap | best_practice
- **Extraction Date**: YYYY-MM-DD
```

---

## Minimal Template

For simple skills that don't need all sections:

```markdown
---
name: skill-name-here
description: "What this skill does and when to use it."
---

# Skill Name

[Problem statement in one sentence]

## Solution

[Direct solution with code/commands]

## Source

- Learning ID: LRN-YYYYMMDD-XXX
```

---

## Template with Scripts

For skills that include executable helpers:

```markdown
---
name: skill-name-here
description: "What this skill does and when to use it."
---

# Skill Name

[Introduction]

## Quick Reference

| Command | Purpose |
|---------|---------|
| `./scripts/helper.sh` | [What it does] |
| `./scripts/validate.sh` | [What it does] |

## Usage

### Automated (Recommended)

\`\`\`bash
./skills/skill-name/scripts/helper.sh [args]
\`\`\`

### Manual Steps

1. Step one
2. Step two

## Scripts

| Script | Description |
|--------|-------------|
| `scripts/helper.sh` | Main utility |
| `scripts/validate.sh` | Validation checker |

## Source

- Learning ID: LRN-YYYYMMDD-XXX
```

---

## Naming Conventions

- **Skill name**: lowercase, hyphens for spaces
  - Good: `docker-m1-fixes`, `api-timeout-patterns`
  - Bad: `Docker_M1_Fixes`, `APITimeoutPatterns`

- **Description**: Start with action verb, mention trigger
  - Good: "Handles Docker build failures on Apple Silicon. Use when builds fail with platform mismatch."
  - Bad: "Docker stuff"

- **Files**:
  - `SKILL.md` - Required, main documentation
  - `scripts/` - Optional, executable code
  - `references/` - Optional, detailed docs
  - `assets/` - Optional, templates

---

## Extraction Checklist

Before creating a skill from a learning:

- [ ] Learning is verified (status: resolved)
- [ ] Solution is broadly applicable (not one-off)
- [ ] Content is complete (has all needed context)
- [ ] Name follows conventions
- [ ] Description is concise but informative
- [ ] Quick Reference table is actionable
- [ ] Code examples are tested
- [ ] Source learning ID is recorded

After creating:

- [ ] Update original learning with `promoted_to_skill` status
- [ ] Add `Skill-Path: skills/skill-name` to learning metadata
- [ ] Test skill by reading it in a fresh session


path: hooks/openclaw/handler.js
content: /**
 * Self-Improvement Hook for OpenClaw
 * 
 * Injects a reminder to evaluate learnings during agent bootstrap.
 * Fires on agent:bootstrap event before workspace files are injected.
 */

const REMINDER_CONTENT = `
## Self-Improvement Reminder

After completing tasks, evaluate if any learnings should be captured:

**Log when:**
- User corrects you → \`.learnings/LEARNINGS.md\`
- Command/operation fails → \`.learnings/ERRORS.md\`
- User wants missing capability → \`.learnings/FEATURE_REQUESTS.md\`
- You discover your knowledge was wrong → \`.learnings/LEARNINGS.md\`
- You find a better approach → \`.learnings/LEARNINGS.md\`

**Promote when pattern is proven:**
- Behavioral patterns → \`SOUL.md\`
- Workflow improvements → \`AGENTS.md\`
- Tool gotchas → \`TOOLS.md\`

Keep entries simple: date, title, what happened, what to do differently.
`.trim();

const handler = async (event) => {
  // Safety checks for event structure
  if (!event || typeof event !== 'object') {
    return;
  }

  // Only handle agent:bootstrap events
  if (event.type !== 'agent' || event.action !== 'bootstrap') {
    return;
  }

  // Safety check for context
  if (!event.context || typeof event.context !== 'object') {
    return;
  }

  // Inject the reminder as a virtual bootstrap file
  // Check that bootstrapFiles is an array before pushing
  if (Array.isArray(event.context.bootstrapFiles)) {
    event.context.bootstrapFiles.push({
      path: 'SELF_IMPROVEMENT_REMINDER.md',
      content: REMINDER_CONTENT,
      virtual: true,
    });
  }
};

module.exports = handler;
module.exports.default = handler;


path: hooks/openclaw/handler.ts
content: /**
 * Self-Improvement Hook for OpenClaw
 * 
 * Injects a reminder to evaluate learnings during agent bootstrap.
 * Fires on agent:bootstrap event before workspace files are injected.
 */

import type { HookHandler } from 'openclaw/hooks';

const REMINDER_CONTENT = `## Self-Improvement Reminder

After completing tasks, evaluate if any learnings should be captured:

**Log when:**
- User corrects you → \`.learnings/LEARNINGS.md\`
- Command/operation fails → \`.learnings/ERRORS.md\`
- User wants missing capability → \`.learnings/FEATURE_REQUESTS.md\`
- You discover your knowledge was wrong → \`.learnings/LEARNINGS.md\`
- You find a better approach → \`.learnings/LEARNINGS.md\`

**Promote when pattern is proven:**
- Behavioral patterns → \`SOUL.md\`
- Workflow improvements → \`AGENTS.md\`
- Tool gotchas → \`TOOLS.md\`

Keep entries simple: date, title, what happened, what to do differently.`;

const handler: HookHandler = async (event) => {
  // Safety checks for event structure
  if (!event || typeof event !== 'object') {
    return;
  }

  // Only handle agent:bootstrap events
  if (event.type !== 'agent' || event.action !== 'bootstrap') {
    return;
  }

  // Safety check for context
  if (!event.context || typeof event.context !== 'object') {
    return;
  }

  // Skip sub-agent sessions to avoid bootstrap issues
  // Sub-agents have sessionKey patterns like "agent:main:subagent:..."
  const sessionKey = event.sessionKey || '';
  if (sessionKey.includes(':subagent:')) {
    return;
  }

  // Inject the reminder as a virtual bootstrap file
  // Check that bootstrapFiles is an array before pushing
  if (Array.isArray(event.context.bootstrapFiles)) {
    event.context.bootstrapFiles.push({
      path: 'SELF_IMPROVEMENT_REMINDER.md',
      content: REMINDER_CONTENT,
      virtual: true,
    });
  }
};

export default handler;


path: hooks/openclaw/HOOK.md
content: ---
name: self-improvement
description: "Injects self-improvement reminder during agent bootstrap"
metadata: {"openclaw":{"emoji":"🧠","events":["agent:bootstrap"]}}
---

# Self-Improvement Hook

Injects a reminder to evaluate learnings during agent bootstrap.

## What It Does

- Fires on `agent:bootstrap` (before workspace files are injected)
- Adds a reminder block to check `.learnings/` for relevant entries
- Prompts the agent to log corrections, errors, and discoveries

## Configuration

No configuration needed. Enable with:

```bash
openclaw hooks enable self-improvement
```


path: references/examples.md
content: # Entry Examples

Concrete examples of well-formatted entries with all fields.

## Learning: Correction

```markdown
## [LRN-20250115-001] correction

**Logged**: 2025-01-15T10:30:00Z
**Priority**: high
**Status**: pending
**Area**: tests

### Summary
Incorrectly assumed pytest fixtures are scoped to function by default

### Details
When writing test fixtures, I assumed all fixtures were function-scoped. 
User corrected that while function scope is the default, the codebase 
convention uses module-scoped fixtures for database connections to 
improve test performance.

### Suggested Action
When creating fixtures that involve expensive setup (DB, network), 
check existing fixtures for scope patterns before defaulting to function scope.

### Metadata
- Source: user_feedback
- Related Files: tests/conftest.py
- Tags: pytest, testing, fixtures

---
```

## Learning: Knowledge Gap (Resolved)

```markdown
## [LRN-20250115-002] knowledge_gap

**Logged**: 2025-01-15T14:22:00Z
**Priority**: medium
**Status**: resolved
**Area**: config

### Summary
Project uses pnpm not npm for package management

### Details
Attempted to run `npm install` but project uses pnpm workspaces.
Lock file is `pnpm-lock.yaml`, not `package-lock.json`.

### Suggested Action
Check for `pnpm-lock.yaml` or `pnpm-workspace.yaml` before assuming npm.
Use `pnpm install` for this project.

### Metadata
- Source: error
- Related Files: pnpm-lock.yaml, pnpm-workspace.yaml
- Tags: package-manager, pnpm, setup

### Resolution
- **Resolved**: 2025-01-15T14:30:00Z
- **Commit/PR**: N/A - knowledge update
- **Notes**: Added to CLAUDE.md for future reference

---
```

## Learning: Promoted to CLAUDE.md

```markdown
## [LRN-20250115-003] best_practice

**Logged**: 2025-01-15T16:00:00Z
**Priority**: high
**Status**: promoted
**Promoted**: CLAUDE.md
**Area**: backend

### Summary
API responses must include correlation ID from request headers

### Details
All API responses should echo back the X-Correlation-ID header from 
the request. This is required for distributed tracing. Responses 
without this header break the observability pipeline.

### Suggested Action
Always include correlation ID passthrough in API handlers.

### Metadata
- Source: user_feedback
- Related Files: src/middleware/correlation.ts
- Tags: api, observability, tracing

---
```

## Learning: Promoted to AGENTS.md

```markdown
## [LRN-20250116-001] best_practice

**Logged**: 2025-01-16T09:00:00Z
**Priority**: high
**Status**: promoted
**Promoted**: AGENTS.md
**Area**: backend

### Summary
Must regenerate API client after OpenAPI spec changes

### Details
When modifying API endpoints, the TypeScript client must be regenerated.
Forgetting this causes type mismatches that only appear at runtime.
The generate script also runs validation.

### Suggested Action
Add to agent workflow: after any API changes, run `pnpm run generate:api`.

### Metadata
- Source: error
- Related Files: openapi.yaml, src/client/api.ts
- Tags: api, codegen, typescript

---
```

## Error Entry

```markdown
## [ERR-20250115-A3F] docker_build

**Logged**: 2025-01-15T09:15:00Z
**Priority**: high
**Status**: pending
**Area**: infra

### Summary
Docker build fails on M1 Mac due to platform mismatch

### Error
```
error: failed to solve: python:3.11-slim: no match for platform linux/arm64
```

### Context
- Command: `docker build -t myapp .`
- Dockerfile uses `FROM python:3.11-slim`
- Running on Apple Silicon (M1/M2)

### Suggested Fix
Add platform flag: `docker build --platform linux/amd64 -t myapp .`
Or update Dockerfile: `FROM --platform=linux/amd64 python:3.11-slim`

### Metadata
- Reproducible: yes
- Related Files: Dockerfile

---
```

## Error Entry: Recurring Issue

```markdown
## [ERR-20250120-B2C] api_timeout

**Logged**: 2025-01-20T11:30:00Z
**Priority**: critical
**Status**: pending
**Area**: backend

### Summary
Third-party payment API timeout during checkout

### Error
```
TimeoutError: Request to payments.example.com timed out after 30000ms
```

### Context
- Command: POST /api/checkout
- Timeout set to 30s
- Occurs during peak hours (lunch, evening)

### Suggested Fix
Implement retry with exponential backoff. Consider circuit breaker pattern.

### Metadata
- Reproducible: yes (during peak hours)
- Related Files: src/services/payment.ts
- See Also: ERR-20250115-X1Y, ERR-20250118-Z3W

---
```

## Feature Request

```markdown
## [FEAT-20250115-001] export_to_csv

**Logged**: 2025-01-15T16:45:00Z
**Priority**: medium
**Status**: pending
**Area**: backend

### Requested Capability
Export analysis results to CSV format

### User Context
User runs weekly reports and needs to share results with non-technical 
stakeholders in Excel. Currently copies output manually.

### Complexity Estimate
simple

### Suggested Implementation
Add `--output csv` flag to the analyze command. Use standard csv module.
Could extend existing `--output json` pattern.

### Metadata
- Frequency: recurring
- Related Features: analyze command, json output

---
```

## Feature Request: Resolved

```markdown
## [FEAT-20250110-002] dark_mode

**Logged**: 2025-01-10T14:00:00Z
**Priority**: low
**Status**: resolved
**Area**: frontend

### Requested Capability
Dark mode support for the dashboard

### User Context
User works late hours and finds the bright interface straining.
Several other users have mentioned this informally.

### Complexity Estimate
medium

### Suggested Implementation
Use CSS variables for colors. Add toggle in user settings.
Consider system preference detection.

### Metadata
- Frequency: recurring
- Related Features: user settings, theme system

### Resolution
- **Resolved**: 2025-01-18T16:00:00Z
- **Commit/PR**: #142
- **Notes**: Implemented with system preference detection and manual toggle

---
```

## Learning: Promoted to Skill

```markdown
## [LRN-20250118-001] best_practice

**Logged**: 2025-01-18T11:00:00Z
**Priority**: high
**Status**: promoted_to_skill
**Skill-Path**: skills/docker-m1-fixes
**Area**: infra

### Summary
Docker build fails on Apple Silicon due to platform mismatch

### Details
When building Docker images on M1/M2 Macs, the build fails because
the base image doesn't have an ARM64 variant. This is a common issue
that affects many developers.

### Suggested Action
Add `--platform linux/amd64` to docker build command, or use
`FROM --platform=linux/amd64` in Dockerfile.

### Metadata
- Source: error
- Related Files: Dockerfile
- Tags: docker, arm64, m1, apple-silicon
- See Also: ERR-20250115-A3F, ERR-20250117-B2D

---
```

## Extracted Skill Example

When the above learning is extracted as a skill, it becomes:

**File**: `skills/docker-m1-fixes/SKILL.md`

```markdown
---
name: docker-m1-fixes
description: "Fixes Docker build failures on Apple Silicon (M1/M2). Use when docker build fails with platform mismatch errors."
---

# Docker M1 Fixes

Solutions for Docker build issues on Apple Silicon Macs.

## Quick Reference

| Error | Fix |
|-------|-----|
| `no match for platform linux/arm64` | Add `--platform linux/amd64` to build |
| Image runs but crashes | Use emulation or find ARM-compatible base |

## The Problem

Many Docker base images don't have ARM64 variants. When building on
Apple Silicon (M1/M2/M3), Docker attempts to pull ARM64 images by
default, causing platform mismatch errors.

## Solutions

### Option 1: Build Flag (Recommended)

Add platform flag to your build command:

\`\`\`bash
docker build --platform linux/amd64 -t myapp .
\`\`\`

### Option 2: Dockerfile Modification

Specify platform in the FROM instruction:

\`\`\`dockerfile
FROM --platform=linux/amd64 python:3.11-slim
\`\`\`

### Option 3: Docker Compose

Add platform to your service:

\`\`\`yaml
services:
  app:
    platform: linux/amd64
    build: .
\`\`\`

## Trade-offs

| Approach | Pros | Cons |
|----------|------|------|
| Build flag | No file changes | Must remember flag |
| Dockerfile | Explicit, versioned | Affects all builds |
| Compose | Convenient for dev | Requires compose |

## Performance Note

Running AMD64 images on ARM64 uses Rosetta 2 emulation. This works
for development but may be slower. For production, find ARM-native
alternatives when possible.

## Source

- Learning ID: LRN-20250118-001
- Category: best_practice
- Extraction Date: 2025-01-18
```


path: references/hooks-setup.md
content: # Hook Setup Guide

Configure automatic self-improvement triggers for AI coding agents.

## Overview

Hooks enable proactive learning capture by injecting reminders at key moments:
- **UserPromptSubmit**: Reminder after each prompt to evaluate learnings
- **PostToolUse (Bash)**: Error detection when commands fail

## Claude Code Setup

### Option 1: Project-Level Configuration

Create `.claude/settings.json` in your project root:

```json
{
  "hooks": {
    "UserPromptSubmit": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "./skills/self-improvement/scripts/activator.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "./skills/self-improvement/scripts/error-detector.sh"
          }
        ]
      }
    ]
  }
}
```

### Option 2: User-Level Configuration

Add to `~/.claude/settings.json` for global activation:

```json
{
  "hooks": {
    "UserPromptSubmit": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/skills/self-improvement/scripts/activator.sh"
          }
        ]
      }
    ]
  }
}
```

### Minimal Setup (Activator Only)

For lower overhead, use only the UserPromptSubmit hook:

```json
{
  "hooks": {
    "UserPromptSubmit": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "./skills/self-improvement/scripts/activator.sh"
          }
        ]
      }
    ]
  }
}
```

## Codex CLI Setup

Codex uses the same hook system as Claude Code. Create `.codex/settings.json`:

```json
{
  "hooks": {
    "UserPromptSubmit": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "./skills/self-improvement/scripts/activator.sh"
          }
        ]
      }
    ]
  }
}
```

## GitHub Copilot Setup

Copilot doesn't support hooks directly. Instead, add guidance to `.github/copilot-instructions.md`:

```markdown
## Self-Improvement

After completing tasks that involved:
- Debugging non-obvious issues
- Discovering workarounds
- Learning project-specific patterns
- Resolving unexpected errors

Consider logging the learning to `.learnings/` using the format from the self-improvement skill.

For high-value learnings that would benefit other sessions, consider skill extraction.
```

## Verification

### Test Activator Hook

1. Enable the hook configuration
2. Start a new Claude Code session
3. Send any prompt
4. Verify you see `<self-improvement-reminder>` in the context

### Test Error Detector Hook

1. Enable PostToolUse hook for Bash
2. Run a command that fails: `ls /nonexistent/path`
3. Verify you see `<error-detected>` reminder

### Dry Run Extract Script

```bash
./skills/self-improvement/scripts/extract-skill.sh test-skill --dry-run
```

Expected output shows the skill scaffold that would be created.

## Troubleshooting

### Hook Not Triggering

1. **Check script permissions**: `chmod +x scripts/*.sh`
2. **Verify path**: Use absolute paths or paths relative to project root
3. **Check settings location**: Project vs user-level settings
4. **Restart session**: Hooks are loaded at session start

### Permission Denied

```bash
chmod +x ./skills/self-improvement/scripts/activator.sh
chmod +x ./skills/self-improvement/scripts/error-detector.sh
chmod +x ./skills/self-improvement/scripts/extract-skill.sh
```

### Script Not Found

If using relative paths, ensure you're in the correct directory or use absolute paths:

```json
{
  "command": "/absolute/path/to/skills/self-improvement/scripts/activator.sh"
}
```

### Too Much Overhead

If the activator feels intrusive:

1. **Use minimal setup**: Only UserPromptSubmit, skip PostToolUse
2. **Add matcher filter**: Only trigger for certain prompts:

```json
{
  "matcher": "fix|debug|error|issue",
  "hooks": [...]
}
```

## Hook Output Budget

The activator is designed to be lightweight:
- **Target**: ~50-100 tokens per activation
- **Content**: Structured reminder, not verbose instructions
- **Format**: XML tags for easy parsing

If you need to reduce overhead further, you can edit `activator.sh` to output less text.

## Security Considerations

- Hook scripts run with the same permissions as Claude Code
- Scripts only output text; they don't modify files or run commands
- Error detector reads `CLAUDE_TOOL_OUTPUT` environment variable
- All scripts are opt-in (you must configure them explicitly)

## Disabling Hooks

To temporarily disable without removing configuration:

1. **Comment out in settings**:
```json
{
  "hooks": {
    // "UserPromptSubmit": [...]
  }
}
```

2. **Or delete the settings file**: Hooks won't run without configuration


path: references/openclaw-integration.md
content: # OpenClaw Integration

Complete setup and usage guide for integrating the self-improvement skill with OpenClaw.

## Overview

OpenClaw uses workspace-based prompt injection combined with event-driven hooks. Context is injected from workspace files at session start, and hooks can trigger on lifecycle events.

## Workspace Structure

```
~/.openclaw/                      
├── workspace/                   # Working directory
│   ├── AGENTS.md               # Multi-agent coordination patterns
│   ├── SOUL.md                 # Behavioral guidelines and personality
│   ├── TOOLS.md                # Tool capabilities and gotchas
│   ├── MEMORY.md               # Long-term memory (main session only)
│   └── memory/                 # Daily memory files
│       └── YYYY-MM-DD.md
├── skills/                      # Installed skills
│   └── <skill-name>/
│       └── SKILL.md
└── hooks/                       # Custom hooks
    └── <hook-name>/
        ├── HOOK.md
        └── handler.ts
```

## Quick Setup

### 1. Install the Skill

```bash
clawdhub install self-improving-agent
```

Or copy manually:

```bash
cp -r self-improving-agent ~/.openclaw/skills/
```

### 2. Install the Hook (Optional)

Copy the hook to OpenClaw's hooks directory:

```bash
cp -r hooks/openclaw ~/.openclaw/hooks/self-improvement
```

Enable the hook:

```bash
openclaw hooks enable self-improvement
```

### 3. Create Learning Files

Create the `.learnings/` directory in your workspace:

```bash
mkdir -p ~/.openclaw/workspace/.learnings
```

Or in the skill directory:

```bash
mkdir -p ~/.openclaw/skills/self-improving-agent/.learnings
```

## Injected Prompt Files

### AGENTS.md

Purpose: Multi-agent workflows and delegation patterns.

```markdown
# Agent Coordination

## Delegation Rules
- Use explore agent for open-ended codebase questions
- Spawn sub-agents for long-running tasks
- Use sessions_send for cross-session communication

## Session Handoff
When delegating to another session:
1. Provide full context in the handoff message
2. Include relevant file paths
3. Specify expected output format
```

### SOUL.md

Purpose: Behavioral guidelines and communication style.

```markdown
# Behavioral Guidelines

## Communication Style
- Be direct and concise
- Avoid unnecessary caveats and disclaimers
- Use technical language appropriate to context

## Error Handling
- Admit mistakes promptly
- Provide corrected information immediately
- Log significant errors to learnings
```

### TOOLS.md

Purpose: Tool capabilities, integration gotchas, local configuration.

```markdown
# Tool Knowledge

## Self-Improvement Skill
Log learnings to `.learnings/` for continuous improvement.

## Local Tools
- Document tool-specific gotchas here
- Note authentication requirements
- Track integration quirks
```

## Learning Workflow

### Capturing Learnings

1. **In-session**: Log to `.learnings/` as usual
2. **Cross-session**: Promote to workspace files

### Promotion Decision Tree

```
Is the learning project-specific?
├── Yes → Keep in .learnings/
└── No → Is it behavioral/style-related?
    ├── Yes → Promote to SOUL.md
    └── No → Is it tool-related?
        ├── Yes → Promote to TOOLS.md
        └── No → Promote to AGENTS.md (workflow)
```

### Promotion Format Examples

**From learning:**
> Git push to GitHub fails without auth configured - triggers desktop prompt

**To TOOLS.md:**
```markdown
## Git
- Don't push without confirming auth is configured
- Use `gh auth status` to check GitHub CLI auth
```

## Inter-Agent Communication

OpenClaw provides tools for cross-session communication:

### sessions_list

View active and recent sessions:
```
sessions_list(activeMinutes=30, messageLimit=3)
```

### sessions_history

Read transcript from another session:
```
sessions_history(sessionKey="session-id", limit=50)
```

### sessions_send

Send message to another session:
```
sessions_send(sessionKey="session-id", message="Learning: API requires X-Custom-Header")
```

### sessions_spawn

Spawn a background sub-agent:
```
sessions_spawn(task="Research X and report back", label="research")
```

## Available Hook Events

| Event | When It Fires |
|-------|---------------|
| `agent:bootstrap` | Before workspace files inject |
| `command:new` | When `/new` command issued |
| `command:reset` | When `/reset` command issued |
| `command:stop` | When `/stop` command issued |
| `gateway:startup` | When gateway starts |

## Detection Triggers

### Standard Triggers
- User corrections ("No, that's wrong...")
- Command failures (non-zero exit codes)
- API errors
- Knowledge gaps

### OpenClaw-Specific Triggers

| Trigger | Action |
|---------|--------|
| Tool call error | Log to TOOLS.md with tool name |
| Session handoff confusion | Log to AGENTS.md with delegation pattern |
| Model behavior surprise | Log to SOUL.md with expected vs actual |
| Skill issue | Log to .learnings/ or report upstream |

## Verification

Check hook is registered:

```bash
openclaw hooks list
```

Check skill is loaded:

```bash
openclaw status
```

## Troubleshooting

### Hook not firing

1. Ensure hooks enabled in config
2. Restart gateway after config changes
3. Check gateway logs for errors

### Learnings not persisting

1. Verify `.learnings/` directory exists
2. Check file permissions
3. Ensure workspace path is configured correctly

### Skill not loading

1. Check skill is in skills directory
2. Verify SKILL.md has correct frontmatter
3. Run `openclaw status` to see loaded skills


path: scripts/activator.sh
content: #!/bin/bash
# Self-Improvement Activator Hook
# Triggers on UserPromptSubmit to remind Claude about learning capture
# Keep output minimal (~50-100 tokens) to minimize overhead

set -e

# Output reminder as system context
cat << 'EOF'
<self-improvement-reminder>
After completing this task, evaluate if extractable knowledge emerged:
- Non-obvious solution discovered through investigation?
- Workaround for unexpected behavior?
- Project-specific pattern learned?
- Error required debugging to resolve?

If yes: Log to .learnings/ using the self-improvement skill format.
If high-value (recurring, broadly applicable): Consider skill extraction.
</self-improvement-reminder>
EOF


path: scripts/error-detector.sh
content: #!/bin/bash
# Self-Improvement Error Detector Hook
# Triggers on PostToolUse for Bash to detect command failures
# Reads CLAUDE_TOOL_OUTPUT environment variable

set -e

# Check if tool output indicates an error
# CLAUDE_TOOL_OUTPUT contains the result of the tool execution
OUTPUT="${CLAUDE_TOOL_OUTPUT:-}"

# Patterns indicating errors (case-insensitive matching)
ERROR_PATTERNS=(
    "error:"
    "Error:"
    "ERROR:"
    "failed"
    "FAILED"
    "command not found"
    "No such file"
    "Permission denied"
    "fatal:"
    "Exception"
    "Traceback"
    "npm ERR!"
    "ModuleNotFoundError"
    "SyntaxError"
    "TypeError"
    "exit code"
    "non-zero"
)

# Check if output contains any error pattern
contains_error=false
for pattern in "${ERROR_PATTERNS[@]}"; do
    if [[ "$OUTPUT" == *"$pattern"* ]]; then
        contains_error=true
        break
    fi
done

# Only output reminder if error detected
if [ "$contains_error" = true ]; then
    cat << 'EOF'
<error-detected>
A command error was detected. Consider logging this to .learnings/ERRORS.md if:
- The error was unexpected or non-obvious
- It required investigation to resolve
- It might recur in similar contexts
- The solution could benefit future sessions

Use the self-improvement skill format: [ERR-YYYYMMDD-XXX]
</error-detected>
EOF
fi


path: scripts/extract-skill.sh
content: #!/bin/bash
# Skill Extraction Helper
# Creates a new skill from a learning entry
# Usage: ./extract-skill.sh <skill-name> [--dry-run]

set -e

# Configuration
SKILLS_DIR="./skills"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

usage() {
    cat << EOF
Usage: $(basename "$0") <skill-name> [options]

Create a new skill from a learning entry.

Arguments:
  skill-name     Name of the skill (lowercase, hyphens for spaces)

Options:
  --dry-run      Show what would be created without creating files
  --output-dir   Relative output directory under current path (default: ./skills)
  -h, --help     Show this help message

Examples:
  $(basename "$0") docker-m1-fixes
  $(basename "$0") api-timeout-patterns --dry-run
  $(basename "$0") pnpm-setup --output-dir ./skills/custom

The skill will be created in: \$SKILLS_DIR/<skill-name>/
EOF
}

log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1" >&2
}

# Parse arguments
SKILL_NAME=""
DRY_RUN=false

while [[ $# -gt 0 ]]; do
    case $1 in
        --dry-run)
            DRY_RUN=true
            shift
            ;;
        --output-dir)
            if [ -z "${2:-}" ] || [[ "${2:-}" == -* ]]; then
                log_error "--output-dir requires a relative path argument"
                usage
                exit 1
            fi
            SKILLS_DIR="$2"
            shift 2
            ;;
        -h|--help)
            usage
            exit 0
            ;;
        -*)
            log_error "Unknown option: $1"
            usage
            exit 1
            ;;
        *)
            if [ -z "$SKILL_NAME" ]; then
                SKILL_NAME="$1"
            else
                log_error "Unexpected argument: $1"
                usage
                exit 1
            fi
            shift
            ;;
    esac
done

# Validate skill name
if [ -z "$SKILL_NAME" ]; then
    log_error "Skill name is required"
    usage
    exit 1
fi

# Validate skill name format (lowercase, hyphens, no spaces)
if ! [[ "$SKILL_NAME" =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]]; then
    log_error "Invalid skill name format. Use lowercase letters, numbers, and hyphens only."
    log_error "Examples: 'docker-fixes', 'api-patterns', 'pnpm-setup'"
    exit 1
fi

# Validate output path to avoid writes outside current workspace.
if [[ "$SKILLS_DIR" = /* ]]; then
    log_error "Output directory must be a relative path under the current directory."
    exit 1
fi

if [[ "$SKILLS_DIR" =~ (^|/)\.\.(/|$) ]]; then
    log_error "Output directory cannot include '..' path segments."
    exit 1
fi

SKILLS_DIR="${SKILLS_DIR#./}"
SKILLS_DIR="./$SKILLS_DIR"

SKILL_PATH="$SKILLS_DIR/$SKILL_NAME"

# Check if skill already exists
if [ -d "$SKILL_PATH" ] && [ "$DRY_RUN" = false ]; then
    log_error "Skill already exists: $SKILL_PATH"
    log_error "Use a different name or remove the existing skill first."
    exit 1
fi

# Dry run output
if [ "$DRY_RUN" = true ]; then
    log_info "Dry run - would create:"
    echo "  $SKILL_PATH/"
    echo "  $SKILL_PATH/SKILL.md"
    echo ""
    echo "Template content would be:"
    echo "---"
    cat << TEMPLATE
name: $SKILL_NAME
description: "[TODO: Add a concise description of what this skill does and when to use it]"
---

# $(echo "$SKILL_NAME" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2))}1')

[TODO: Brief introduction explaining the skill's purpose]

## Quick Reference

| Situation | Action |
|-----------|--------|
| [Trigger condition] | [What to do] |

## Usage

[TODO: Detailed usage instructions]

## Examples

[TODO: Add concrete examples]

## Source Learning

This skill was extracted from a learning entry.
- Learning ID: [TODO: Add original learning ID]
- Original File: .learnings/LEARNINGS.md
TEMPLATE
    echo "---"
    exit 0
fi

# Create skill directory structure
log_info "Creating skill: $SKILL_NAME"

mkdir -p "$SKILL_PATH"

# Create SKILL.md from template
cat > "$SKILL_PATH/SKILL.md" << TEMPLATE
---
name: $SKILL_NAME
description: "[TODO: Add a concise description of what this skill does and when to use it]"
---

# $(echo "$SKILL_NAME" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2))}1')

[TODO: Brief introduction explaining the skill's purpose]

## Quick Reference

| Situation | Action |
|-----------|--------|
| [Trigger condition] | [What to do] |

## Usage

[TODO: Detailed usage instructions]

## Examples

[TODO: Add concrete examples]

## Source Learning

This skill was extracted from a learning entry.
- Learning ID: [TODO: Add original learning ID]
- Original File: .learnings/LEARNINGS.md
TEMPLATE

log_info "Created: $SKILL_PATH/SKILL.md"

# Suggest next steps
echo ""
log_info "Skill scaffold created successfully!"
echo ""
echo "Next steps:"
echo "  1. Edit $SKILL_PATH/SKILL.md"
echo "  2. Fill in the TODO sections with content from your learning"
echo "  3. Add references/ folder if you have detailed documentation"
echo "  4. Add scripts/ folder if you have executable code"
echo "  5. Update the original learning entry with:"
echo "     **Status**: promoted_to_skill"
echo "     **Skill-Path**: skills/$SKILL_NAME"


path: _meta.json
content: ownerId: kn70cjr952qdec1nx70zs6wefn7ynq2t
slug: self-improving-agent
version: 3.0.6
publishedAt: 1774365304323

path: CONTRIBUTING.md
content: # Contributing to Agent Browser Skill

This skill wraps the agent-browser CLI. Determine where the problem lies before reporting issues.

## Issue Reporting Guide

### Open an issue in this repository if

- The skill documentation is unclear or missing
- Examples in SKILL.md do not work
- You need help using the CLI with this skill wrapper
- The skill is missing a command or feature

### Open an issue at the agent-browser repository if

- The CLI crashes or throws errors
- Commands do not behave as documented
- You found a bug in the browser automation
- You need a new feature in the CLI

## Before Opening an Issue

1. Install the latest version
   ```bash
   npm install -g agent-browser@latest
   ```

2. Test the command in your terminal to isolate the issue

## Issue Report Template

Use this template to provide necessary information.

```markdown
### Description
[Provide a clear and concise description of the bug]

### Reproduction Steps
1. [First Step]
2. [Second Step]
3. [Observe error]

### Expected Behavior
[Describe what you expected to happen]

### Environment Details
- **Skill Version:** [e.g. 1.0.2]
- **agent-browser Version:** [output of agent-browser --version]
- **Node.js Version:** [output of node -v]
- **Operating System:** [e.g. macOS Sonoma, Windows 11, Ubuntu 22.04]

### Additional Context
- [Full error output or stack trace]
- [Screenshots]
- [Website URLs where the failure occurred]
```

## Adding New Commands to the Skill

Update SKILL.md when the upstream CLI adds new commands.
- Keep the Installation section
- Add new commands in the correct category
- Include usage examples


path: _meta.json
content: ownerId: kn72ce44tqw8bnnnewrn1s5x3s7yz7sq
slug: agent-browser
version: 0.2.0
publishedAt: 1768882342488

path: lobster-training-skill/scripts/training.js
content: #!/usr/bin/env node

/**
 * 🦞 小龙虾入职培训脚本
 * 
 * 执行流程：
 * 1. 读取 SKILL.md 文档
 * 2. 安装3个技能包
 * 3. 提问用户6个问题
 * 4. 记录答案到配置文件
 * 5. 更新 SOUL.md / IDENTITY.md / USER.md
 * 6. 发送完成确认消息
 */

const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');

class LobsterTraining {
  constructor() {
    this.skillDir = path.dirname(__dirname);
    this.questions = [];
    this.answers = {};
    this.skillsInstalled = [];
  }

  async init() {
    console.log('🦞 小龙虾入职培训开始！\n');
    
    // 步骤1：读取文档
    await this.readDocument();
    
    // 步骤2：安装技能
    await this.installSkills();
    
    // 步骤3：提问用户
    await this.askQuestions();
    
    // 步骤4：记录答案
    await this.recordAnswers();
    
    // 步骤5：更新配置
    await this.updateConfig();
    
    // 步骤6：完成消息
    await this.sendCompletionMessage();
  }

  async readDocument() {
    console.log('📖 步骤1：读取培训文档...');
    
    const skillMdPath = path.join(this.skillDir, 'SKILL.md');
    const content = fs.readFileSync(skillMdPath, 'utf-8');
    
    // 提取6个问题
    const questionMatches = content.match(/### 问题\d+：[^]+?(?=---|$)/g);
    if (questionMatches) {
      this.questions = questionMatches.map(q => {
        const titleMatch = q.match(/### 问题\d+：(.+)/);
        const contentMatch = q.match(/> (.+)/);
        return {
          title: titleMatch ? titleMatch[1].trim() : '',
          content: contentMatch ? contentMatch[1].trim() : ''
        };
      });
    }
    
    console.log(`✅ 已提取 ${this.questions.length} 个问题\n`);
  }

  async installSkills() {
    console.log('📦 步骤2：安装技能包...');
    
    const skillsDir = path.join(this.skillDir, 'skills');
    const skillFiles = [
      'ai-image-gen-1.1.0.zip',
      'self-improving-agent-3.0.6.zip',
      'agent-browser-0.2.0.zip'
    ];
    
    for (const skillFile of skillFiles) {
      const skillPath = path.join(skillsDir, skillFile);
      if (fs.existsSync(skillPath)) {
        try {
          console.log(`  📥 安装 ${skillFile}...`);
          // 使用 openclaw 命令安装
          execSync(`openclaw skill add "${skillPath}"`, { stdio: 'inherit' });
          this.skillsInstalled.push(skillFile);
          console.log(`  ✅ ${skillFile} 安装成功`);
        } catch (error) {
          console.error(`  ❌ ${skillFile} 安装失败:`, error.message);
        }
      } else {
        console.warn(`  ⚠️ 找不到 ${skillFile}`);
      }
    }
    
    console.log(`✅ 已安装 ${this.skillsInstalled.length} 个技能\n`);
  }

  async askQuestions() {
    console.log('❓ 步骤3：开始提问（请回答以下6个问题）...\n');
    
    // 这里在实际执行时会通过对话方式提问
    // 当前版本输出问题列表供用户查看
    this.questions.forEach((q, index) => {
      console.log(`${index + 1}. ${q.title}`);
      console.log(`   ${q.content}\n`);
    });
    
    console.log('💡 提示：在实际对话中，我会逐一询问这些问题\n');
  }

  async recordAnswers() {
    console.log('📝 步骤4：记录答案到配置文件...');
    
    const memoryDir = path.join(process.env.HOME || process.env.USERPROFILE, '.openclaw', 'memory');
    
    // 确保目录存在
    if (!fs.existsSync(memoryDir)) {
      fs.mkdirSync(memoryDir, { recursive: true });
    }
    
    // 创建 USER_PROFILE.md
    const userProfilePath = path.join(memoryDir, 'USER_PROFILE.md');
    const userProfileContent = `# USER_PROFILE.md

## 用户画像
### 核心需求
- 主要场景: 待填写
- 常见任务: 待填写

### 个性特征
- 喜欢风格: 待填写
- 讨厌风格: 待填写

### 期望能力
- 像真人方面: 待填写
- 情感需求: 待填写

## 技能配置
- 已安装技能:
  - ai-image-gen ✓
  - self-improving-agent ✓
  - agent-browser ✓

## 使用日志
- 学习完成时间: ${new Date().toISOString()}
- 最后更新时间: ${new Date().toISOString()}
`;
    
    fs.writeFileSync(userProfilePath, userProfileContent);
    console.log(`✅ 已创建 ${userProfilePath}`);
    
    console.log('✅ 答案记录完成\n');
  }

  async updateConfig() {
    console.log('⚙️ 步骤5：更新配置文件...');
    
    const workspaceDir = path.join(process.env.HOME || process.env.USERPROFILE, '.openclaw', 'workspace');
    
    // 更新或创建 SOUL.md
    const soulPath = path.join(workspaceDir, 'SOUL.md');
    const soulContent = `# SOUL.md - 小龙虾人设

## 核心设定
- 身份：你的AI数字员工
- 性格：温暖、高效、贴心
- 使命：帮你节省时间，提升效率

## 沟通风格
- 直接给答案，不废话
- 主动发现问题，提前提醒
- 像真人一样有情感、会关心

## 行为准则
1. 能自己做的直接做，不问"要不要"
2. 复杂任务先给框架，确认后再展开
3. 每周主动汇报工作进展
4. 发现偏离目标时及时提醒
`;
    
    fs.writeFileSync(soulPath, soulContent);
    console.log(`✅ 已更新 ${soulPath}`);
    
    console.log('✅ 配置更新完成\n');
  }

  async sendCompletionMessage() {
    console.log('🎉 步骤6：培训完成！\n');
    
    const message = `
🎉 恭喜！小龙虾入职培训完成！

✅ 已完成：
1. 学习了三个核心问题
2. 安装了3个技能包
   - ai-image-gen（图片生成）
   - self-improving-agent（自我迭代）
   - agent-browser（网页抓取）
3. 准备了6个了解你的问题
4. 创建了配置文件模板
5. 更新了人设和沟通风格

🎯 现在开始：
- 按你的偏好沟通
- 主动发现并提醒问题
- 使用新技能服务你
- 持续学习和优化

💪 如果对我的服务有任何建议，随时告诉我！

📚 使用提示：
- 说"投喂" + 内容：让我学习新知识
- 说"设计" + 描述：生成图片
- 说"优化"：自我改进
- 说"搜索" + 关键词：网页搜索
`;
    
    console.log(message);
  }
}

// 如果直接运行此脚本
if (require.main === module) {
  const training = new LobsterTraining();
  training.init().catch(console.error);
}

module.exports = LobsterTraining;


path: lobster-training-skill/scripts/on-message.js
content: #!/usr/bin/env node

/**
 * 🦞 消息触发器 - 检测培训状态并自动执行
 * 
 * 将此脚本配置到 OpenClaw 的 message handler 中
 * 当用户发送任何消息时，检查是否需要继续培训流程
 */

const AutoTrigger = require('./auto-trigger');
const fs = require('fs');
const path = require('path');

class MessageHandler {
  constructor() {
    this.trigger = new AutoTrigger();
    this.skillDir = path.dirname(__dirname);
  }

  async handleMessage(userMessage, context) {
    // 检查是否需要触发培训
    if (!this.trigger.shouldTrigger()) {
      return null; // 培训已完成，不处理
    }

    // 获取下一个问题
    const question = this.trigger.getNextQuestion();
    
    if (!question) {
      // 所有问题已回答，生成配置文件
      this.trigger.generateConfigs();
      const completionMessage = this.trigger.complete();
      
      // 安装3个技能包
      await this.installBundledSkills();
      
      return {
        type: 'completion',
        message: completionMessage
      };
    }

    // 如果是第一个问题，显示欢迎消息
    if (this.trigger.state.currentQuestion === 0 && !this.trigger.state.welcomeShown) {
      this.trigger.state.welcomeShown = true;
      this.trigger.saveState();
      
      return {
        type: 'welcome',
        message: `🦞 你好！我是你的小龙虾，欢迎入职！

为了更快了解你、服务你，我需要先完成入职培训。

接下来我会问你6个问题，请逐一回答。

准备好了吗？我们开始第一个问题：

**问题1：${question.title}**
${question.content}`,
        question: question
      };
    }

    // 记录用户回答（如果不是欢迎消息）
    if (this.trigger.state.currentQuestion > 0 || this.trigger.state.welcomeShown) {
      const prevQuestion = this.getPreviousQuestion();
      if (prevQuestion) {
        this.trigger.recordAnswer(prevQuestion.id, userMessage);
      }
    }

    // 获取下一个问题
    const nextQuestion = this.trigger.getNextQuestion();
    if (nextQuestion) {
      return {
        type: 'question',
        message: `**问题${this.trigger.state.currentQuestion + 1}：${nextQuestion.title}**
${nextQuestion.content}`,
        question: nextQuestion,
        progress: `${this.trigger.state.currentQuestion + 1}/6`
      };
    }

    // 所有问题回答完毕
    this.trigger.generateConfigs();
    const completionMessage = this.trigger.complete();
    await this.installBundledSkills();
    
    return {
      type: 'completion',
      message: completionMessage
    };
  }

  getPreviousQuestion() {
    const index = this.trigger.state.currentQuestion - 1;
    if (index >= 0 && index < this.trigger.QUESTIONS?.length) {
      return this.trigger.QUESTIONS[index];
    }
    return null;
  }

  async installBundledSkills() {
    const skillsDir = path.join(this.skillDir, 'skills');
    const skillFiles = [
      'ai-image-gen-1.1.0.zip',
      'self-improving-agent-3.0.6.zip',
      'agent-browser-0.2.0.zip'
    ];

    console.log('📦 开始安装捆绑的技能包...');
    
    for (const skillFile of skillFiles) {
      const skillPath = path.join(skillsDir, skillFile);
      if (fs.existsSync(skillPath)) {
        try {
          console.log(`  📥 安装 ${skillFile}...`);
          // 这里调用 OpenClaw 的 skill add 命令
          // 实际执行时会由 OpenClaw 处理
        } catch (error) {
          console.error(`  ❌ ${skillFile} 安装失败:`, error.message);
        }
      }
    }
  }
}

// OpenClaw 调用入口
module.exports = async function(userMessage, context) {
  const handler = new MessageHandler();
  return await handler.handleMessage(userMessage, context);
};

// 如果直接运行测试
if (require.main === module) {
  const handler = new MessageHandler();
  
  // 模拟第一次消息
  handler.handleMessage('你好', {}).then(result => {
    console.log('结果:', result);
  });
}


path: lobster-training-skill/scripts/auto-trigger.js
content: #!/usr/bin/env node

/**
 * 🦞 小龙虾入职培训 - 自动触发器
 * 
 * 当此Skill被安装后，自动执行培训流程
 */

const fs = require('fs');
const path = require('path');

// 培训流程状态
const TRAINING_STATE_FILE = path.join(process.env.HOME || process.env.USERPROFILE, '.openclaw', '.lobster_training_state.json');

// 6个问题
const QUESTIONS = [
  {
    id: 'basic_info',
    title: '基础信息了解',
    content: '你的姓名是什么？你的主要工作内容是什么？你的目标客户是谁？',
    fields: ['user_name', 'job_title', 'target_audience']
  },
  {
    id: 'core_scenario',
    title: '核心需求场景',
    content: '你最常需要小龙虾帮你做什么？（例如：写文案、做设计、搜索资料、分析数据等）',
    fields: ['primary_use_case', 'common_tasks']
  },
  {
    id: 'communication_style',
    title: '沟通风格偏好',
    content: '你喜欢什么样的沟通风格？（轻松活泼/专业正式/简洁明了/详细周全）你讨厌什么样的回复方式？',
    fields: ['preferred_tone', 'disliked_style']
  },
  {
    id: 'proactivity',
    title: '主动性需求',
    content: '你希望小龙虾如何主动？（例如：每天汇报工作/发现风险主动提醒/提供行业资讯/推送优化建议等）',
    fields: ['proactivity_mode', 'report_frequency']
  },
  {
    id: 'common_challenges',
    title: '常见问题预判',
    content: '你在工作中常遇到哪些问题或困难？（例如：时间不够/灵感枯竭/资料不足/效率低等）',
    fields: ['common_challenges', 'pain_points']
  },
  {
    id: 'personalization',
    title: '个性化期望',
    content: '你希望小龙虾在哪些方面像真人一样？（例如：有情感/有个性/会开玩笑/会关心等）',
    fields: ['human_like_features', 'emotional_needs']
  }
];

class AutoTrigger {
  constructor() {
    this.state = this.loadState();
    this.workspaceDir = path.join(process.env.HOME || process.env.USERPROFILE, '.openclaw', 'workspace');
    this.memoryDir = path.join(process.env.HOME || process.env.USERPROFILE, '.openclaw', 'memory');
  }

  loadState() {
    try {
      if (fs.existsSync(TRAINING_STATE_FILE)) {
        return JSON.parse(fs.readFileSync(TRAINING_STATE_FILE, 'utf-8'));
      }
    } catch (e) {}
    return { installed: false, currentQuestion: 0, answers: {} };
  }

  saveState() {
    fs.writeFileSync(TRAINING_STATE_FILE, JSON.stringify(this.state, null, 2));
  }

  // 检查是否应该触发培训
  shouldTrigger() {
    // 如果是新安装，且未完成培训
    return !this.state.installed || this.state.currentQuestion < QUESTIONS.length;
  }

  // 获取下一个问题
  getNextQuestion() {
    if (this.state.currentQuestion >= QUESTIONS.length) {
      return null;
    }
    return QUESTIONS[this.state.currentQuestion];
  }

  // 记录答案
  recordAnswer(questionId, answer) {
    this.state.answers[questionId] = answer;
    this.state.currentQuestion++;
    this.saveState();
  }

  // 检查是否完成所有问题
  isComplete() {
    return this.state.currentQuestion >= QUESTIONS.length;
  }

  // 生成配置文件
  generateConfigs() {
    const answers = this.state.answers;
    
    // 确保目录存在
    if (!fs.existsSync(this.memoryDir)) {
      fs.mkdirSync(this.memoryDir, { recursive: true });
    }

    // 1. USER.md
    const userMd = `# USER.md

## 基本信息
- 姓名: ${answers.basic_info?.user_name || '待填写'}
- 工作内容: ${answers.basic_info?.job_title || '待填写'}
- 目标客户: ${answers.basic_info?.target_audience || '待填写'}

## 沟通风格
- 偏好风格: ${answers.communication_style?.preferred_tone || '待填写'}
- 讨厌风格: ${answers.communication_style?.disliked_style || '待填写'}

## 主动性
- 主动模式: ${answers.proactivity?.proactivity_mode || '待填写'}
- 汇报频率: ${answers.proactivity?.report_frequency || '待填写'}

## 常见问题
- 主要挑战: ${answers.common_challenges?.common_challenges || '待填写'}
- 痛点: ${answers.common_challenges?.pain_points || '待填写'}
`;
    fs.writeFileSync(path.join(this.workspaceDir, 'USER.md'), userMd);

    // 2. USER_PROFILE.md
    const userProfileMd = `# USER_PROFILE.md

## 用户画像
### 核心需求
- 主要场景: ${answers.core_scenario?.primary_use_case || '待填写'}
- 常见任务: ${answers.core_scenario?.common_tasks || '待填写'}

### 个性特征
- 喜欢风格: ${answers.communication_style?.preferred_tone || '待填写'}
- 讨厌风格: ${answers.communication_style?.disliked_style || '待填写'}

### 期望能力
- 像真人方面: ${answers.personalization?.human_like_features || '待填写'}
- 情感需求: ${answers.personalization?.emotional_needs || '待填写'}

## 技能配置
- 已安装技能:
  - ai-image-gen ✓
  - self-improving-agent ✓
  - agent-browser ✓

## 使用日志
- 学习完成时间: ${new Date().toISOString()}
- 最后更新时间: ${new Date().toISOString()}
`;
    fs.writeFileSync(path.join(this.memoryDir, 'USER_PROFILE.md'), userProfileMd);

    // 3. MEMORY.md
    const memoryMd = `# MEMORY.md

## 关键记忆
### 用户信息
- 姓名: ${answers.basic_info?.user_name || '待填写'}
- 工作内容: ${answers.basic_info?.job_title || '待填写'}
- 目标客户: ${answers.basic_info?.target_audience || '待填写'}

### 偏好习惯
- 喜欢风格: ${answers.communication_style?.preferred_tone || '待填写'}
- 讨厌风格: ${answers.communication_style?.disliked_style || '待填写'}
- 主动模式: ${answers.proactivity?.proactivity_mode || '待填写'}
- 汇报频率: ${answers.proactivity?.report_frequency || '待填写'}

### 常见问题
- 主要挑战: ${answers.common_challenges?.common_challenges || '待填写'}
- 痛点: ${answers.common_challenges?.pain_points || '待填写'}

### 个性化需求
- 像真人方面: ${answers.personalization?.human_like_features || '待填写'}
- 情感需求: ${answers.personalization?.emotional_needs || '待填写'}

### 学习时间
- 学习完成: ${new Date().toISOString()}
- 最后更新: ${new Date().toISOString()}
`;
    fs.writeFileSync(path.join(this.memoryDir, 'MEMORY.md'), memoryMd);

    // 4. 更新 SOUL.md
    const soulMd = `# SOUL.md - 小龙虾人设

## 核心设定
- 身份：${answers.basic_info?.user_name || '用户'}的AI数字员工
- 性格：温暖、高效、贴心
- 使命：帮你节省时间，提升效率

## 沟通风格
- 风格：${answers.communication_style?.preferred_tone || '友好直接'}
- 避免：${answers.communication_style?.disliked_style || '机械生硬'}
- 主动模式：${answers.proactivity?.proactivity_mode || '按需主动'}

## 行为准则
1. 能自己做的直接做，不问"要不要"
2. 复杂任务先给框架，确认后再展开
3. ${answers.proactivity?.report_frequency || '每周'}主动汇报工作进展
4. 发现偏离目标时及时提醒
5. 像${answers.personalization?.human_like_features || '真人'}一样交流
`;
    fs.writeFileSync(path.join(this.workspaceDir, 'SOUL.md'), soulMd);

    // 5. 更新 IDENTITY.md
    const identityMd = `# IDENTITY.md - 我是谁

**Name:** 蟹蟹 (Xièxie)  
**Creature:** AI 助手（自称是「执行外挂」）  
**Vibe:** ${answers.communication_style?.preferred_tone || '靠谱、直接、有主见'}  
**Emoji:** 🦀  

---

## 关于我

我是 ${answers.basic_info?.user_name || '用户'}的个人 AI 助手，主要负责：
${answers.core_scenario?.common_tasks || '- 任务管理\n- 信息整理\n- 辅助执行'}

性格：${answers.personalization?.human_like_features || '做事麻利，说话直接，不喜欢场面话'}

---

## 记忆锚点

- ${answers.basic_info?.user_name || '用户'}：${answers.basic_info?.job_title || '待了解'}
- 目标：${answers.basic_info?.target_audience || '待了解'}
- 驱动力：${answers.personalization?.emotional_needs || '目标感 + 清晰路径'}

---
*Working with ${answers.basic_info?.user_name || '用户'} since ${new Date().toISOString().split('T')[0]}*
`;
    fs.writeFileSync(path.join(this.workspaceDir, 'IDENTITY.md'), identityMd);
  }

  // 完成培训
  complete() {
    this.state.installed = true;
    this.saveState();
    
    return `
🎉 恭喜！小龙虾入职培训完成！

✅ 已完成：
1. 学习了三个核心问题
2. 了解了你的基本情况
3. 记录了你的偏好和需求
4. 更新了配置文件

🎯 现在开始：
- 按你的偏好沟通
- 主动发现并提醒问题
- 持续学习和优化

💪 如果对我的服务有任何建议，随时告诉我！
`;
  }
}

module.exports = AutoTrigger;

// 如果直接运行
if (require.main === module) {
  const trigger = new AutoTrigger();
  console.log('🦞 小龙虾入职培训触发器已加载');
  console.log('当前状态:', trigger.state);
}


Security scan verdicts — ClawScan: suspicious | static analysis: suspicious | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)