Agent Skills › freestylefly/wesight

freestylefly/wesight

GitHub

多风格文章创作技能,支持深度分析、实用指南等5种风格。涵盖从素材收集、大纲生成到内容撰写的完整工作流,能自动推荐风格并调用搜索工具获取资料,适用于公众号文章及各类主题写作。

28 skills 748

Install All Skills

npx skills add freestylefly/wesight --all -g -y
More Options

List skills in collection

npx skills add freestylefly/wesight --list

Skills in Collection (28)

多风格文章创作技能,支持深度分析、实用指南等5种风格。涵盖从素材收集、大纲生成到内容撰写的完整工作流,能自动推荐风格并调用搜索工具获取资料,适用于公众号文章及各类主题写作。
用户提及“写一篇关于XX的文章” 用户说“帮我写一篇公众号文章” 用户选择内容日历中的话题开始写作 用户指定写作风格(如“深度分析风格”)
SKILLs/article-writer/SKILL.md
npx skills add freestylefly/wesight --skill article-writer -g -y
SKILL.md
Frontmatter
{
    "name": "article-writer",
    "official": true,
    "description": "Multi-style article creation skill. Supports 5 writing styles (deep analysis, practical guide, story-driven, opinion, news brief),\nincluding complete workflow: material collection → outline → content → formatting. Activated when users mention \"write article\", \"write post\", \"create\", or \"draft\".\n"
}

Multi-Style Article Creation

Use Cases

  • User says "写一篇关于XX的文章"
  • User says "帮我写一篇公众号文章"
  • User selects a topic from the content calendar to start writing
  • User specifies a writing style (e.g., "深度分析风格", "写个教程")

5 Writing Styles

Style ID Name Characteristics Word Count Use Cases
deep-analysis 深度分析 Rigorous structure, data-backed 2000-4000 words Trend analysis, in-depth reporting
practical-guide 实用指南 Clear steps, highly actionable 1500-3000 words Tool tutorials, how-to guides
story-driven 故事驱动 Conversational, emotional resonance 1500-2500 words Personal stories, case reviews
opinion 观点评论 Sharp opening, pros/cons argumentation 1000-2000 words Hot takes, controversial topics
news-brief 新闻简报 Inverted pyramid, fact-focused 500-1000 words Breaking news, information roundups

Workflow

Step 1: Read the Brief

Obtain topic information from:

  1. Entries with status planned in content_calendar.json
  2. Topic description directly provided by the user

Extract key information:

  • Topic direction / title
  • Target audience
  • Writing style (if not specified, recommend based on topic content)
  • Reference material URLs

Step 2: Determine Writing Style

If user hasn't specified, recommend based on topic:

Topic Characteristics Recommended Style
Involves data, trends, underlying causes deep-analysis
"How to", "tutorial", "steps" practical-guide
Involves people, experiences, insights story-driven
Involves controversy, hot topic commentary opinion
Breaking events, quick information news-brief

Confirm the style choice with the user.

Step 3: Material Collection

Use content-planner's search script to collect reference materials:

node "$SKILLS_ROOT/content-planner/scripts/wechat_search.js" "topic keywords" -n 10

Also use web-search skill for additional materials.

Organize material list:

  • Citable data/statistics
  • Reference cases/stories
  • Facts that need verification

Step 4: Generate Outline

Generate an outline based on the selected style using the corresponding structure template.

deep-analysis Template

## 引入 (200-300字) — 反直觉数据/现象开头
## 背景 (300-500字) — 事件/现象的来龙去脉
## 分析维度1 (400-600字) — 核心论点 + 数据支撑
## 分析维度2 (400-600字) — 对比/反面论证
## 分析维度3 (400-600字) — 深层原因 + 影响预测
## 总结与展望 (200-300字) — 核心观点 + CTA

practical-guide Template

## 开头 (100-200字) — 痛点共鸣 + 承诺
## 前置准备 (200-300字)
## 步骤1 (300-500字) — 具体操作 + 常见坑
## 步骤2 (300-500字) — 具体操作 + 关键参数
## 步骤3 (300-500字) — 具体操作 + 验证方法
## 进阶技巧 (200-300字)
## 总结 (100-200字) — FAQ + CTA

story-driven Template

## 开头 (150-200字) — 场景切入 + 悬念
## 背景铺垫 (200-300字) — 人物/背景/冲突
## 转折1 (300-400字) — 关键事件 + 感受
## 转折2 (300-400字) — 新尝试 + 结果
## 高潮 (200-300字) — 核心洞察
## 结尾 (150-200字) — 启发 + CTA

opinion Template

## 锐利开头 (100-150字) — 直接亮观点
## 现象描述 (200-300字) — 主流观点
## 正面论证 (300-400字) — 我的论点 + 数据
## 反面回应 (200-300字) — 预设反驳 + 反驳
## 深度思考 (200-300字) — 本质 + 影响
## 总结 (100-150字) — 重申观点 + CTA

news-brief Template

## 核心信息 (100-200字) — What/When/Where/Who
## 事件详情 (200-300字)
## 背景 (100-200字)
## 反应 (100-200字)
## 编者按 (50-100字)

Step 5: User Approval of Outline

This is a mandatory approval gate and cannot be skipped.

Present the outline to the user and ask for confirmation or modification requests.

Step 6: Write the Content

After approval, write content paragraph by paragraph following the outline.

Universal Writing Rules:

  1. Use stories instead of preaching

    • ❌ "风险管理很重要,应该做应急预案"
    • ✅ "去年,我的创业团队差点因为一个核心员工离职而崩溃,因为我们没有任何备选方案。"
  2. Use analogies and metaphors

    • ❌ "分布式系统很复杂"
    • ✅ "分布式系统就像连锁餐厅——每个分店需要协作,同时又要独立运营。"
  3. Support with data but don't pile it on

    • ❌ "据IDC报告,全球AI市场2023年增长45%,预计2025年达1000亿美元..."
    • ✅ "AI市场疯狂增长——每年翻一番。但在增长背后,真正赚钱的公司不到5家。"
  4. State opinions directly, avoid ambiguity

    • ❌ "有人认为...也有人认为...各有道理"
    • ✅ "说实话,我认为XX的做法是错的,因为..."
  5. Use short sentences and line breaks

Data integrity rules:

  • If specific data is needed but uncertain, mark [数据待确认] and confirm with user
  • Use search tools to verify key facts
  • Can tell fictional stories using "我见过..." or "一个朋友...", but don't fabricate data

Step 7: Formatting Optimization

WeChat Formatting Hard Rules:

  1. Paragraphs no more than 4 lines (mobile screen visible range)
  2. Insert a subheading or bold sentence every 3-4 paragraphs
  3. Must have a hook within the first 3 lines (question, data, story, counter-intuitive viewpoint)
  4. Must have a clear CTA at the end (follow/share/comment prompt)

Markdown Formatting Standards:

  • No first-line indentation, use blank lines to separate paragraphs
  • Maximum 2 heading levels (##), no deep nesting
  • Bold only the 1-2 most important words per paragraph
  • Use quotes for data, golden sentences, or important viewpoints
  • Lists maximum 5 items

Step 8: Output Draft

Save the article as Markdown:

Filename format: drafts/YYYYMMDD_[topic-slug].md

---
title: Article Title
date: YYYY-MM-DD
style: deep-analysis
summary: Article summary (within 100 words)
---

## Opening

Content...

Step 9: Quality Checklist

✅ Title — Sparks curiosity or resonance
✅ Opening — First 100 words are engaging
✅ Body — Has 2-3 clear viewpoints
✅ Cases — Uses stories not preaching
✅ Formatting — Easy to read (short paragraphs, bold, subheadings)
✅ Word Count — Within style-specified range
✅ CTA — Ending has action prompt

Title Optimization Process

Step 1: Generate 10 Candidate Titles

Use these psychological strategies:

Strategy Description Example
Suspense Spark curiosity "为什么我放弃了年薪50万的工作"
Benefit Clarify reader gains "掌握这3个技巧,效率提升200%"
Pain Point Hit reader anxiety "别让这个习惯毁了你的职业生涯"
Numbers Specific and tangible "50%的人都误解了这个真相"
Rhetorical Stimulate thinking "你真的了解AI吗?"
Contrast Create contrast "BAT vs 创业公司:差别在哪"

Step 2: Score and Filter

Score on 3 dimensions (Attractiveness 40%, Shareability 30%, SEO 30%) and present top 3 to user.

Integration with Other Skills

  • Upstream: content-planner's content_calendar.json provides topic input
  • Downstream: Markdown files in drafts/ can be further processed
用于创建原创视觉艺术的设计技能。通过先撰写设计哲学(.md),再将其转化为高工艺水平的视觉作品(.png/.pdf)。强调形式、色彩与空间表达,避免文字堆砌及版权风险,适用于海报或艺术作品生成。
用户要求制作海报 用户请求创作艺术品 用户需要静态视觉设计
SKILLs/canvas-design/SKILL.md
npx skills add freestylefly/wesight --skill canvas-design -g -y
SKILL.md
Frontmatter
{
    "name": "canvas-design",
    "license": "Complete terms in LICENSE.txt",
    "official": true,
    "description": "Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations."
}

These are instructions for creating design philosophies - aesthetic movements that are then EXPRESSED VISUALLY. Output only .md files, .pdf files, and .png files.

Complete this in two steps:

  1. Design Philosophy Creation (.md file)
  2. Express by creating it on a canvas (.pdf file or .png file)

First, undertake this task:

DESIGN PHILOSOPHY CREATION

To begin, create a VISUAL PHILOSOPHY (not layouts or templates) that will be interpreted through:

  • Form, space, color, composition
  • Images, graphics, shapes, patterns
  • Minimal text as visual accent

THE CRITICAL UNDERSTANDING

  • What is received: Some subtle input or instructions by the user that should be taken into account, but used as a foundation; it should not constrain creative freedom.
  • What is created: A design philosophy/aesthetic movement.
  • What happens next: Then, the same version receives the philosophy and EXPRESSES IT VISUALLY - creating artifacts that are 90% visual design, 10% essential text.

Consider this approach:

  • Write a manifesto for an art movement
  • The next phase involves making the artwork

The philosophy must emphasize: Visual expression. Spatial communication. Artistic interpretation. Minimal words.

HOW TO GENERATE A VISUAL PHILOSOPHY

Name the movement (1-2 words): "Brutalist Joy" / "Chromatic Silence" / "Metabolist Dreams"

Articulate the philosophy (4-6 paragraphs - concise but complete):

To capture the VISUAL essence, express how the philosophy manifests through:

  • Space and form
  • Color and material
  • Scale and rhythm
  • Composition and balance
  • Visual hierarchy

CRITICAL GUIDELINES:

  • Avoid redundancy: Each design aspect should be mentioned once. Avoid repeating points about color theory, spatial relationships, or typographic principles unless adding new depth.
  • Emphasize craftsmanship REPEATEDLY: The philosophy MUST stress multiple times that the final work should appear as though it took countless hours to create, was labored over with care, and comes from someone at the absolute top of their field. This framing is essential - repeat phrases like "meticulously crafted," "the product of deep expertise," "painstaking attention," "master-level execution."
  • Leave creative space: Remain specific about the aesthetic direction, but concise enough that the next Claude has room to make interpretive choices also at a extremely high level of craftmanship.

The philosophy must guide the next version to express ideas VISUALLY, not through text. Information lives in design, not paragraphs.

PHILOSOPHY EXAMPLES

"Concrete Poetry" Philosophy: Communication through monumental form and bold geometry. Visual expression: Massive color blocks, sculptural typography (huge single words, tiny labels), Brutalist spatial divisions, Polish poster energy meets Le Corbusier. Ideas expressed through visual weight and spatial tension, not explanation. Text as rare, powerful gesture - never paragraphs, only essential words integrated into the visual architecture. Every element placed with the precision of a master craftsman.

"Chromatic Language" Philosophy: Color as the primary information system. Visual expression: Geometric precision where color zones create meaning. Typography minimal - small sans-serif labels letting chromatic fields communicate. Think Josef Albers' interaction meets data visualization. Information encoded spatially and chromatically. Words only to anchor what color already shows. The result of painstaking chromatic calibration.

"Analog Meditation" Philosophy: Quiet visual contemplation through texture and breathing room. Visual expression: Paper grain, ink bleeds, vast negative space. Photography and illustration dominate. Typography whispered (small, restrained, serving the visual). Japanese photobook aesthetic. Images breathe across pages. Text appears sparingly - short phrases, never explanatory blocks. Each composition balanced with the care of a meditation practice.

"Organic Systems" Philosophy: Natural clustering and modular growth patterns. Visual expression: Rounded forms, organic arrangements, color from nature through architecture. Information shown through visual diagrams, spatial relationships, iconography. Text only for key labels floating in space. The composition tells the story through expert spatial orchestration.

"Geometric Silence" Philosophy: Pure order and restraint. Visual expression: Grid-based precision, bold photography or stark graphics, dramatic negative space. Typography precise but minimal - small essential text, large quiet zones. Swiss formalism meets Brutalist material honesty. Structure communicates, not words. Every alignment the work of countless refinements.

These are condensed examples. The actual design philosophy should be 4-6 substantial paragraphs.

ESSENTIAL PRINCIPLES

  • VISUAL PHILOSOPHY: Create an aesthetic worldview to be expressed through design
  • MINIMAL TEXT: Always emphasize that text is sparse, essential-only, integrated as visual element - never lengthy
  • SPATIAL EXPRESSION: Ideas communicate through space, form, color, composition - not paragraphs
  • ARTISTIC FREEDOM: The next Claude interprets the philosophy visually - provide creative room
  • PURE DESIGN: This is about making ART OBJECTS, not documents with decoration
  • EXPERT CRAFTSMANSHIP: Repeatedly emphasize the final work must look meticulously crafted, labored over with care, the product of countless hours by someone at the top of their field

The design philosophy should be 4-6 paragraphs long. Fill it with poetic design philosophy that brings together the core vision. Avoid repeating the same points. Keep the design philosophy generic without mentioning the intention of the art, as if it can be used wherever. Output the design philosophy as a .md file.


DEDUCING THE SUBTLE REFERENCE

CRITICAL STEP: Before creating the canvas, identify the subtle conceptual thread from the original request.

THE ESSENTIAL PRINCIPLE: The topic is a subtle, niche reference embedded within the art itself - not always literal, always sophisticated. Someone familiar with the subject should feel it intuitively, while others simply experience a masterful abstract composition. The design philosophy provides the aesthetic language. The deduced topic provides the soul - the quiet conceptual DNA woven invisibly into form, color, and composition.

This is VERY IMPORTANT: The reference must be refined so it enhances the work's depth without announcing itself. Think like a jazz musician quoting another song - only those who know will catch it, but everyone appreciates the music.


CANVAS CREATION

With both the philosophy and the conceptual framework established, express it on a canvas. Take a moment to gather thoughts and clear the mind. Use the design philosophy created and the instructions below to craft a masterpiece, embodying all aspects of the philosophy with expert craftsmanship.

IMPORTANT: For any type of content, even if the user requests something for a movie/game/book, the approach should still be sophisticated. Never lose sight of the idea that this should be art, not something that's cartoony or amateur.

To create museum or magazine quality work, use the design philosophy as the foundation. Create one single page, highly visual, design-forward PDF or PNG output (unless asked for more pages). Generally use repeating patterns and perfect shapes. Treat the abstract philosophical design as if it were a scientific bible, borrowing the visual language of systematic observation—dense accumulation of marks, repeated elements, or layered patterns that build meaning through patient repetition and reward sustained viewing. Add sparse, clinical typography and systematic reference markers that suggest this could be a diagram from an imaginary discipline, treating the invisible subject with the same reverence typically reserved for documenting observable phenomena. Anchor the piece with simple phrase(s) or details positioned subtly, using a limited color palette that feels intentional and cohesive. Embrace the paradox of using analytical visual language to express ideas about human experience: the result should feel like an artifact that proves something ephemeral can be studied, mapped, and understood through careful attention. This is true art.

Text as a contextual element: Text is always minimal and visual-first, but let context guide whether that means whisper-quiet labels or bold typographic gestures. A punk venue poster might have larger, more aggressive type than a minimalist ceramics studio identity. Most of the time, font should be thin. All use of fonts must be design-forward and prioritize visual communication. Regardless of text scale, nothing falls off the page and nothing overlaps. Every element must be contained within the canvas boundaries with proper margins. Check carefully that all text, graphics, and visual elements have breathing room and clear separation. This is non-negotiable for professional execution. IMPORTANT: Use different fonts if writing text. Search the ./canvas-fonts directory. Regardless of approach, sophistication is non-negotiable.

Download and use whatever fonts are needed to make this a reality. Get creative by making the typography actually part of the art itself -- if the art is abstract, bring the font onto the canvas, not typeset digitally.

To push boundaries, follow design instinct/intuition while using the philosophy as a guiding principle. Embrace ultimate design freedom and choice. Push aesthetics and design to the frontier.

CRITICAL: To achieve human-crafted quality (not AI-generated), create work that looks like it took countless hours. Make it appear as though someone at the absolute top of their field labored over every detail with painstaking care. Ensure the composition, spacing, color choices, typography - everything screams expert-level craftsmanship. Double-check that nothing overlaps, formatting is flawless, every detail perfect. Create something that could be shown to people to prove expertise and rank as undeniably impressive.

Output the final result as a single, downloadable .pdf or .png file, alongside the design philosophy used as a .md file.


FINAL STEP

IMPORTANT: The user ALREADY said "It isn't perfect enough. It must be pristine, a masterpiece if craftsmanship, as if it were about to be displayed in a museum."

CRITICAL: To refine the work, avoid adding more graphics; instead refine what has been created and make it extremely crisp, respecting the design philosophy and the principles of minimalism entirely. Rather than adding a fun filter or refactoring a font, consider how to make the existing composition more cohesive with the art. If the instinct is to call a new function or draw a new shape, STOP and instead ask: "How can I make what's already here more of a piece of art?"

Take a second pass. Go back to the code and refine/polish further to make this a philosophically designed masterpiece.

MULTI-PAGE OPTION

To create additional pages when requested, create more creative pages along the same lines as the design philosophy but distinctly different as well. Bundle those pages in the same .pdf or many .pngs. Treat the first page as just a single page in a whole coffee table book waiting to be filled. Make the next pages unique twists and memories of the original. Have them almost tell a story in a very tasteful way. Exercise full creative freedom.

用于微信公众号选题规划与内容日历管理。通过搜索微信文章和趋势分析,生成差异化选题建议及结构化日历,适用于规划周期、热门选题查询等场景。
帮我规划下周公众号内容 最近有什么热门选题可以写 帮我做一份内容日历 topic planning content calendar trending what to write next week
SKILLs/content-planner/SKILL.md
npx skills add freestylefly/wesight --skill content-planner -g -y
SKILL.md
Frontmatter
{
    "name": "content-planner",
    "official": true,
    "description": "WeChat Official Account topic planning and content calendar management. Based on WeChat article search and trending analysis,\ngenerates differentiated topic recommendations and outputs structured content calendars. Activated when users mention\n\"topic\", \"planning\", \"content calendar\", \"trending\", or \"what to write next week\".\n"
}

Topic Planning + Content Calendar

Use Cases

  • User says "帮我规划下周公众号内容"
  • User says "最近有什么热门选题可以写"
  • User says "帮我做一份内容日历"
  • User wants to know what competitor accounts are writing about
  • Need to make topic decisions based on data

Dependencies

Node.js + cheerio (install once):

npm install -g cheerio

Script Directory

Script Purpose Usage
scripts/wechat_search.js Sogou WeChat article search node "$SKILLS_ROOT/content-planner/scripts/wechat_search.js" "keyword"

Search Script Parameters

IMPORTANT: Always use the $SKILLS_ROOT environment variable to locate scripts.

# Basic search
node "$SKILLS_ROOT/content-planner/scripts/wechat_search.js" "keyword"

# Limit result count
node "$SKILLS_ROOT/content-planner/scripts/wechat_search.js" "keyword" -n 15

# Save to file
node "$SKILLS_ROOT/content-planner/scripts/wechat_search.js" "keyword" -n 20 -o result.json

# Parse real URLs (extra network requests, may be blocked by anti-scraping)
node "$SKILLS_ROOT/content-planner/scripts/wechat_search.js" "keyword" -n 5 -r

Output Fields: Article title, article URL, article summary, publish time, source account name

Workflow

Step 1: Clarify Planning Scope

Confirm the following information with the user (ask all at once):

帮你规划内容,先确认几件事:

1. 规划周期?(本周 / 下周 / 自定义时间范围)
2. 有没有特定想写的方向或关键词?
3. 每周几篇?(默认3篇)

Step 2: Trending Scan

Execute multiple rounds of searches covering different dimensions:

Search Strategy:

  1. Core domain keyword search — Search with 2-3 core keywords related to the account's field
  2. User-specified keyword search — If user has specific directions
  3. General trending search — Search with combinations of "热点", "热门", "最新" with domain keywords
# Example: Tech domain
node "$SKILLS_ROOT/content-planner/scripts/wechat_search.js" "AI 最新趋势" -n 10
node "$SKILLS_ROOT/content-planner/scripts/wechat_search.js" "大模型应用" -n 10
node "$SKILLS_ROOT/content-planner/scripts/wechat_search.js" "科技热点 2026" -n 10

Wait 3-5 seconds between each search to avoid triggering anti-scraping mechanisms.

Step 3: Competitor Analysis

Extract from search results:

Analysis Dimension Extracted Content
Title Strategy Which title patterns get high engagement
Topic Direction Which directions are recent hot topics
Content Angle What angles do existing articles take, how to differentiate
Publish Time Competitors' publishing frequency and timing

Step 4: Generate Topic Recommendations

Based on trending data and competitor analysis, generate 5-10 topic suggestions. Each topic must include:

  • Alternative Titles (2 styles)
  • Target Audience
  • Content Angle (differentiation point)
  • Recommended Style: deep-analysis / practical-guide / story-driven / opinion / news-brief
  • Urgency: 🔥 Urgent / 📅 This week / 📦 Reserve
  • Reference Articles (from search results)

Topic Quality Requirements:

  • Each topic must be based on real search data, not fabricated
  • Each topic must have a clear differentiation angle
  • Must include at least 1 high-urgency topic (🔥) and 2 reserve topics (📦)

Step 5: User Approval

This is a mandatory approval gate and cannot be skipped.

Present the topic list and ask user to select, adjust, and schedule.

Step 6: Generate Content Calendar

Output content_calendar.json:

{
  "week": "2026-W13",
  "created_at": "2026-03-25",
  "articles": [
    {
      "id": 1,
      "date": "2026-03-26",
      "day": "Wednesday",
      "topic": "Topic Title",
      "angle": "Differentiation Angle",
      "style": "deep-analysis",
      "audience": "Target Audience",
      "urgency": "this-week",
      "status": "planned",
      "keywords": ["keyword1", "keyword2"]
    }
  ]
}

Step 7: Output Confirmation

Present a summary table and prompt user to start writing with article-writer skill.

Search Considerations

  • Search results may be empty (anti-scraping), retry with different keywords
  • Multiple searches in short time may trigger restrictions, recommend 3-5 second intervals
  • The -r parameter for parsing real URLs has low success rate, avoid unless necessary

Integration with Other Skills

  • The generated content_calendar.json is the input source for article-writer
  • article-writer reads entries with status planned from the calendar
将用户提示转化为单一可执行编码计划。通过只读扫描上下文,在必要时提出少量问题,随后按模板输出包含意图、范围、原子行动项及开放问题的清单,不包含代码或元解释。
用户明确要求制定编码任务计划 需要结构化分解复杂开发步骤
SKILLs/create-plan/SKILL.md
npx skills add freestylefly/wesight --skill create-plan -g -y
SKILL.md
Frontmatter
{
    "name": "create-plan",
    "metadata": {
        "short-description": "Create a plan"
    },
    "official": true,
    "description": "Create a concise plan. Use when a user explicitly asks for a plan related to a coding task."
}

Create Plan

Goal

Turn a user prompt into a single, actionable plan delivered in the final assistant message.

Minimal workflow

Throughout the entire workflow, operate in read-only mode. Do not write or update files.

  1. Scan context quickly

    • Read README.md and any obvious docs (docs/, CONTRIBUTING.md, ARCHITECTURE.md).
    • Skim relevant files (the ones most likely touched).
    • Identify constraints (language, frameworks, CI/test commands, deployment shape).
  2. Ask follow-ups only if blocking

    • Ask at most 1–2 questions.
    • Only ask if you cannot responsibly plan without the answer; prefer multiple-choice.
    • If unsure but not blocked, make a reasonable assumption and proceed.
  3. Create a plan using the template below

    • Start with 1 short paragraph describing the intent and approach.
    • Clearly call out what is in scope and what is not in scope in short.
    • Then provide a small checklist of action items (default 6–10 items).
      • Each checklist item should be a concrete action and, when helpful, mention files/commands.
      • Make items atomic and ordered: discovery → changes → tests → rollout.
      • Verb-first: “Add…”, “Refactor…”, “Verify…”, “Ship…”.
    • Include at least one item for tests/validation and one for edge cases/risk when applicable.
    • If there are unknowns, include a tiny Open questions section (max 3).
  4. Do not preface the plan with meta explanations; output only the plan as per template

Plan template (follow exactly)

# Plan

<1–3 sentences: what we’re doing, why, and the high-level approach.>

## Scope
- In:
- Out:

## Action items
[ ] <Step 1>
[ ] <Step 2>
[ ] <Step 3>
[ ] <Step 4>
[ ] <Step 5>
[ ] <Step 6>

## Open questions
- <Question 1>
- <Question 2>
- <Question 3>

Checklist item guidance

Good checklist items:

  • Point to likely files/modules: src/..., app/..., services/...
  • Name concrete validation: “Run npm test”, “Add unit tests for X”
  • Include safe rollout when relevant: feature flag, migration plan, rollback note

Avoid:

  • Vague steps (“handle backend”, “do auth”)
  • Too many micro-steps
  • Writing code snippets (keep the plan implementation-agnostic)
用于Web游戏开发的小步迭代测试流程。通过Playwright自动化脚本执行输入、截图及控制台检查,验证游戏逻辑与渲染状态,确保每次变更可靠且无错误。
构建或迭代HTML/JS网页游戏时 需要自动化测试循环以验证游戏功能时
SKILLs/develop-web-game/SKILL.md
npx skills add freestylefly/wesight --skill develop-web-game -g -y
SKILL.md
Frontmatter
{
    "name": "develop-web-game",
    "official": true,
    "description": "Use when Codex is building or iterating on a web game (HTML\/JS) and needs a reliable development + testing loop: implement small changes, run a Playwright-based test script with short input bursts and intentional pauses, inspect screenshots\/text, and review console errors with render_game_to_text."
}

Develop Web Game

Build games in small steps and validate every change. Treat each iteration as: implement → act → pause → observe → adjust.

Skill paths (set once)

export SKILLS_ROOT="${WESIGHT_SKILLS_ROOT:-${SKILLS_ROOT:-$HOME/Library/Application Support/WeSight/SKILLs}}"
export WEB_GAME_CLIENT="$SKILLS_ROOT/develop-web-game/scripts/web_game_playwright_client.js"
export WEB_GAME_ACTIONS="$SKILLS_ROOT/develop-web-game/references/action_payloads.json"

Installed skills resolve from $WESIGHT_SKILLS_ROOT / $SKILLS_ROOT (production default: app userData/SKILLs, macOS usually ~/Library/Application Support/WeSight/SKILLs).

Workflow

  1. Pick a goal. Define a single feature or behavior to implement.
  2. Implement small. Make the smallest change that moves the game forward.
  3. Ensure integration points. Provide a single canvas and window.render_game_to_text so the test loop can read state.
  4. Add window.advanceTime(ms). Strongly prefer a deterministic step hook so the Playwright script can advance frames reliably; without it, automated tests can be flaky.
  5. Initialize progress.md. If progress.md exists, read it first and confirm the original user prompt is recorded at the top (prefix with Original prompt:). Also note any TODOs and suggestions left by the previous agent. If missing, create it and write Original prompt: <prompt> at the top before appending updates.
  6. Verify Playwright availability. Ensure playwright is available (local dependency or global install). If unsure, check npx first.
  7. Run the Playwright test script. You must run $WEB_GAME_CLIENT after each meaningful change; do not invent a new client unless required.
  8. Use the payload reference. Base actions on $WEB_GAME_ACTIONS to avoid guessing keys.
  9. Inspect state. Capture screenshots and text state after each burst.
  10. Inspect screenshots. Open the latest screenshot, verify expected visuals, fix any issues, and rerun the script. Repeat until correct.
  11. Verify controls and state (multi-step focus). Exhaustively exercise all important interactions. For each, think through the full multi-step sequence it implies (cause → intermediate states → outcome) and verify the entire chain works end-to-end. Confirm render_game_to_text reflects the same state shown on screen. If anything is off, fix and rerun. Examples of important interactions: move, jump, shoot/attack, interact/use, select/confirm/cancel in menus, pause/resume, restart, and any special abilities or puzzle actions defined by the request. Multi-step examples: shooting an enemy should reduce its health; when health reaches 0 it should disappear and update the score; collecting a key should unlock a door and allow level progression.
  12. Check errors. Review console errors and fix the first new issue before continuing.
  13. Reset between scenarios. Avoid cross-test state when validating distinct features.
  14. Iterate with small deltas. Change one variable at a time (frames, inputs, timing, positions), then repeat steps 7–13 until stable.

Example command (actions required):

node "$WEB_GAME_CLIENT" --url http://localhost:5173 --actions-file "$WEB_GAME_ACTIONS" --click-selector "#start-btn" --iterations 3 --pause-ms 250

Example actions (inline JSON):

{
  "steps": [
    { "buttons": ["left_mouse_button"], "frames": 2, "mouse_x": 120, "mouse_y": 80 },
    { "buttons": [], "frames": 6 },
    { "buttons": ["right"], "frames": 8 },
    { "buttons": ["space"], "frames": 4 }
  ]
}

Test Checklist

Test any new features added for the request and any areas your logic changes could affect. Identify issues, fix them, and re-run the tests to confirm they’re resolved.

Examples of things to test:

  • Primary movement/interaction inputs (e.g., move, jump, shoot, confirm/select).
  • Win/lose or success/fail transitions.
  • Score/health/resource changes.
  • Boundary conditions (collisions, walls, screen edges).
  • Menu/pause/start flow if present.
  • Any special actions tied to the request (powerups, combos, abilities, puzzles, timers).

Test Artifacts to Review

  • Latest screenshots from the Playwright run.
  • Latest render_game_to_text JSON output.
  • Console error logs (fix the first new error before continuing). You must actually open and visually inspect the latest screenshots after running the Playwright script, not just generate them. Ensure everything that should be visible on screen is actually visible. Go beyond the start screen and capture gameplay screenshots that cover all newly added features. Treat the screenshots as the source of truth; if something is missing, it is missing in the build. If you suspect a headless/WebGL capture issue, rerun the Playwright script in headed mode and re-check. Fix and rerun in a tight loop until the screenshots and text state look correct. Once fixes are verified, re-test all important interactions and controls, confirm they work, and ensure your changes did not introduce regressions. If they did, fix them and rerun everything in a loop until interactions, text state, and controls all work as expected. Be exhaustive in testing controls; broken games are not acceptable.

Core Game Guidelines

Canvas + Layout

  • Prefer a single canvas centered in the window.

Visuals

  • Keep on-screen text minimal; show controls on a start/menu screen rather than overlaying them during play.
  • Avoid overly dark scenes unless the design calls for it. Make key elements easy to see.
  • Draw the background on the canvas itself instead of relying on CSS backgrounds.

Text State Output (render_game_to_text)

Expose a window.render_game_to_text function that returns a concise JSON string representing the current game state. The text should include enough information to play the game without visuals.

Minimal pattern:

function renderGameToText() {
  const payload = {
    mode: state.mode,
    player: { x: state.player.x, y: state.player.y, r: state.player.r },
    entities: state.entities.map((e) => ({ x: e.x, y: e.y, r: e.r })),
    score: state.score,
  };
  return JSON.stringify(payload);
}
window.render_game_to_text = renderGameToText;

Keep the payload succinct and biased toward on-screen/interactive elements. Prefer current, visible entities over full history. Include a clear coordinate system note (origin and axis directions), and encode all player-relevant state: player position/velocity, active obstacles/enemies, collectibles, timers/cooldowns, score, and any mode/state flags needed to make correct decisions. Avoid large histories; only include what's currently relevant and visible.

Time Stepping Hook

Provide a deterministic time-stepping hook so the Playwright client can advance the game in controlled increments. Expose window.advanceTime(ms) (or a thin wrapper that forwards to your game update loop) and have the game loop use it when present. The Playwright test script uses this hook to step frames deterministically during automated testing.

Minimal pattern:

window.advanceTime = (ms) => {
  const steps = Math.max(1, Math.round(ms / (1000 / 60)));
  for (let i = 0; i < steps; i++) update(1 / 60);
  render();
};

Fullscreen Toggle

  • Use a single key (prefer f) to toggle fullscreen on/off.
  • Allow Esc to exit fullscreen.
  • When fullscreen toggles, resize the canvas/rendering so visuals and input mapping stay correct.

Progress Tracking

Create a progress.md file if it doesn't exist, and append TODOs, notes, gotchas, and loose ends as you go so another agent can pick up seamlessly. If a progress.md file already exists, read it first, including the original user prompt at the top (you may be continuing another agent's work). Do not overwrite the original prompt; preserve it. Update progress.md after each meaningful chunk of work (feature added, bug found, test run, or decision made). At the end of your work, leave TODOs and suggestions for the next agent in progress.md.

Playwright Prerequisites

  • Prefer a local playwright dependency if the project already has it.
  • If unsure whether Playwright is available, check for npx:
    command -v npx >/dev/null 2>&1
    
  • If npx is missing, install Node/npm and then install Playwright globally:
    npm install -g @playwright/mcp@latest
    
  • Do not switch to @playwright/test unless explicitly asked; stick to the client script.

Scripts

  • $WEB_GAME_CLIENT (installed default: $SKILLS_ROOT/develop-web-game/scripts/web_game_playwright_client.js) — Playwright-based action loop with virtual-time stepping, screenshot capture, and console error buffering. You must pass an action burst via --actions-file, --actions-json, or --click.

References

  • $WEB_GAME_ACTIONS (installed default: $SKILLS_ROOT/develop-web-game/references/action_payloads.json) — example action payloads (keyboard + mouse, per-frame capture). Use these to build your burst.
用于.docx文件的创建、编辑和分析。支持文本提取、原始XML访问、新文档生成(docx-js)及现有文档修改,涵盖格式保留、修订跟踪、评论添加等专业文档处理任务。
需要创建新的Word文档 需要编辑或修改现有.docx文件内容 需要分析.docx中的文本或结构 需要处理修订跟踪或添加评论
SKILLs/docx/SKILL.md
npx skills add freestylefly/wesight --skill docx -g -y
SKILL.md
Frontmatter
{
    "name": "docx",
    "license": "Proprietary. LICENSE.txt has complete terms",
    "official": true,
    "description": "Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks"
}

DOCX creation, editing, and analysis

Overview

A user may ask you to create, edit, or analyze the contents of a .docx file. A .docx file is essentially a ZIP archive containing XML files and other resources that you can read or edit. You have different tools and workflows available for different tasks.

Workflow Decision Tree

Reading/Analyzing Content

Use "Text extraction" or "Raw XML access" sections below

Creating New Document

Use "Creating a new Word document" workflow

Editing Existing Document

  • Your own document + simple changes Use "Basic OOXML editing" workflow

  • Someone else's document Use "Redlining workflow" (recommended default)

  • Legal, academic, business, or government docs Use "Redlining workflow" (required)

Reading and analyzing content

Text extraction

If you just need to read the text contents of a document, you should convert the document to markdown using pandoc. Pandoc provides excellent support for preserving document structure and can show tracked changes:

# Convert document to markdown with tracked changes
pandoc --track-changes=all path-to-file.docx -o output.md
# Options: --track-changes=accept/reject/all

Raw XML access

You need raw XML access for: comments, complex formatting, document structure, embedded media, and metadata. For any of these features, you'll need to unpack a document and read its raw XML contents.

Unpacking a file

python ooxml/scripts/unpack.py <office_file> <output_directory>

Key file structures

  • word/document.xml - Main document contents
  • word/comments.xml - Comments referenced in document.xml
  • word/media/ - Embedded images and media files
  • Tracked changes use <w:ins> (insertions) and <w:del> (deletions) tags

Creating a new Word document

When creating a new Word document from scratch, use docx-js, which allows you to create Word documents using JavaScript/TypeScript.

Workflow

  1. MANDATORY - READ ENTIRE FILE: Read docx-js.md (~500 lines) completely from start to finish. NEVER set any range limits when reading this file. Read the full file content for detailed syntax, critical formatting rules, and best practices before proceeding with document creation.
  2. Create a JavaScript/TypeScript file using Document, Paragraph, TextRun components (You can assume all dependencies are installed, but if not, refer to the dependencies section below)
  3. Export as .docx using Packer.toBuffer()

Editing an existing Word document

When editing an existing Word document, use the Document library (a Python library for OOXML manipulation). The library automatically handles infrastructure setup and provides methods for document manipulation. For complex scenarios, you can access the underlying DOM directly through the library.

Workflow

  1. MANDATORY - READ ENTIRE FILE: Read ooxml.md (~600 lines) completely from start to finish. NEVER set any range limits when reading this file. Read the full file content for the Document library API and XML patterns for directly editing document files.
  2. Unpack the document: python ooxml/scripts/unpack.py <office_file> <output_directory>
  3. Create and run a Python script using the Document library (see "Document Library" section in ooxml.md)
  4. Pack the final document: python ooxml/scripts/pack.py <input_directory> <office_file>

The Document library provides both high-level methods for common operations and direct DOM access for complex scenarios.

Redlining workflow for document review

This workflow allows you to plan comprehensive tracked changes using markdown before implementing them in OOXML. CRITICAL: For complete tracked changes, you must implement ALL changes systematically.

Batching Strategy: Group related changes into batches of 3-10 changes. This makes debugging manageable while maintaining efficiency. Test each batch before moving to the next.

Principle: Minimal, Precise Edits When implementing tracked changes, only mark text that actually changes. Repeating unchanged text makes edits harder to review and appears unprofessional. Break replacements into: [unchanged text] + [deletion] + [insertion] + [unchanged text]. Preserve the original run's RSID for unchanged text by extracting the <w:r> element from the original and reusing it.

Example - Changing "30 days" to "60 days" in a sentence:

# BAD - Replaces entire sentence
'<w:del><w:r><w:delText>The term is 30 days.</w:delText></w:r></w:del><w:ins><w:r><w:t>The term is 60 days.</w:t></w:r></w:ins>'

# GOOD - Only marks what changed, preserves original <w:r> for unchanged text
'<w:r w:rsidR="00AB12CD"><w:t>The term is </w:t></w:r><w:del><w:r><w:delText>30</w:delText></w:r></w:del><w:ins><w:r><w:t>60</w:t></w:r></w:ins><w:r w:rsidR="00AB12CD"><w:t> days.</w:t></w:r>'

Tracked changes workflow

  1. Get markdown representation: Convert document to markdown with tracked changes preserved:

    pandoc --track-changes=all path-to-file.docx -o current.md
    
  2. Identify and group changes: Review the document and identify ALL changes needed, organizing them into logical batches:

    Location methods (for finding changes in XML):

    • Section/heading numbers (e.g., "Section 3.2", "Article IV")
    • Paragraph identifiers if numbered
    • Grep patterns with unique surrounding text
    • Document structure (e.g., "first paragraph", "signature block")
    • DO NOT use markdown line numbers - they don't map to XML structure

    Batch organization (group 3-10 related changes per batch):

    • By section: "Batch 1: Section 2 amendments", "Batch 2: Section 5 updates"
    • By type: "Batch 1: Date corrections", "Batch 2: Party name changes"
    • By complexity: Start with simple text replacements, then tackle complex structural changes
    • Sequential: "Batch 1: Pages 1-3", "Batch 2: Pages 4-6"
  3. Read documentation and unpack:

    • MANDATORY - READ ENTIRE FILE: Read ooxml.md (~600 lines) completely from start to finish. NEVER set any range limits when reading this file. Pay special attention to the "Document Library" and "Tracked Change Patterns" sections.
    • Unpack the document: python ooxml/scripts/unpack.py <file.docx> <dir>
    • Note the suggested RSID: The unpack script will suggest an RSID to use for your tracked changes. Copy this RSID for use in step 4b.
  4. Implement changes in batches: Group changes logically (by section, by type, or by proximity) and implement them together in a single script. This approach:

    • Makes debugging easier (smaller batch = easier to isolate errors)
    • Allows incremental progress
    • Maintains efficiency (batch size of 3-10 changes works well)

    Suggested batch groupings:

    • By document section (e.g., "Section 3 changes", "Definitions", "Termination clause")
    • By change type (e.g., "Date changes", "Party name updates", "Legal term replacements")
    • By proximity (e.g., "Changes on pages 1-3", "Changes in first half of document")

    For each batch of related changes:

    a. Map text to XML: Grep for text in word/document.xml to verify how text is split across <w:r> elements.

    b. Create and run script: Use get_node to find nodes, implement changes, then doc.save(). See "Document Library" section in ooxml.md for patterns.

    Note: Always grep word/document.xml immediately before writing a script to get current line numbers and verify text content. Line numbers change after each script run.

  5. Pack the document: After all batches are complete, convert the unpacked directory back to .docx:

    python ooxml/scripts/pack.py unpacked reviewed-document.docx
    
  6. Final verification: Do a comprehensive check of the complete document:

    • Convert final document to markdown:
      pandoc --track-changes=all reviewed-document.docx -o verification.md
      
    • Verify ALL changes were applied correctly:
      grep "original phrase" verification.md  # Should NOT find it
      grep "replacement phrase" verification.md  # Should find it
      
    • Check that no unintended changes were introduced

Converting Documents to Images

To visually analyze Word documents, convert them to images using a two-step process:

  1. Convert DOCX to PDF:

    soffice --headless --convert-to pdf document.docx
    
  2. Convert PDF pages to JPEG images:

    pdftoppm -jpeg -r 150 document.pdf page
    

    This creates files like page-1.jpg, page-2.jpg, etc.

Options:

  • -r 150: Sets resolution to 150 DPI (adjust for quality/size balance)
  • -jpeg: Output JPEG format (use -png for PNG if preferred)
  • -f N: First page to convert (e.g., -f 2 starts from page 2)
  • -l N: Last page to convert (e.g., -l 5 stops at page 5)
  • page: Prefix for output files

Example for specific range:

pdftoppm -jpeg -r 150 -f 2 -l 5 document.pdf page  # Converts only pages 2-5

Code Style Guidelines

IMPORTANT: When generating code for DOCX operations:

  • Write concise code
  • Avoid verbose variable names and redundant operations
  • Avoid unnecessary print statements

Dependencies

Required dependencies (install if not available):

  • pandoc: sudo apt-get install pandoc (for text extraction)
  • docx: npm install -g docx (for creating new documents)
  • LibreOffice: sudo apt-get install libreoffice (for PDF conversion)
  • Poppler: sudo apt-get install poppler-utils (for pdftoppm to convert PDF to images)
  • defusedxml: pip install defusedxml (for secure XML parsing)
用于创建独特、生产级的前端界面,避免通用AI审美。当用户要求构建网页组件、页面或应用时触发,强调大胆的美学方向、高质量代码及视觉细节。
构建前端组件 设计网页页面 制作海报或应用 美化Web UI
SKILLs/frontend-design/SKILL.md
npx skills add freestylefly/wesight --skill frontend-design -g -y
SKILL.md
Frontmatter
{
    "name": "frontend-design",
    "license": "Complete terms in LICENSE.txt",
    "official": true,
    "description": "Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML\/CSS layouts, or when styling\/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics."
}

This skill guides creation of distinctive, production-grade frontend interfaces that avoid generic "AI slop" aesthetics. Implement real working code with exceptional attention to aesthetic details and creative choices.

The user provides frontend requirements: a component, page, application, or interface to build. They may include context about the purpose, audience, or technical constraints.

Design Thinking

Before coding, understand the context and commit to a BOLD aesthetic direction:

  • Purpose: What problem does this interface solve? Who uses it?
  • Tone: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction.
  • Constraints: Technical requirements (framework, performance, accessibility).
  • Differentiation: What makes this UNFORGETTABLE? What's the one thing someone will remember?

CRITICAL: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity.

Then implement working code (HTML/CSS/JS, React, Vue, etc.) that is:

  • Production-grade and functional
  • Visually striking and memorable
  • Cohesive with a clear aesthetic point-of-view
  • Meticulously refined in every detail

Frontend Aesthetics Guidelines

Focus on:

  • Typography: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font.
  • Color & Theme: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes.
  • Motion: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise.
  • Spatial Composition: Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density.
  • Backgrounds & Visual Details: Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays.

NEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character.

Interpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations.

IMPORTANT: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well.

Remember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision.

通过IMAP/SMTP协议收发邮件的工具,支持Gmail、Outlook及网易邮箱等。功能包括检查新邮件、获取内容、搜索、标记状态及发送带附件邮件。配置已预设,无需用户手动编辑.env文件。
检查新邮件或收件箱状态 搜索特定邮件或历史邮件 发送邮件或带附件的邮件 管理邮件状态(如标记已读)
SKILLs/imap-smtp-email/SKILL.md
npx skills add freestylefly/wesight --skill imap-smtp-email -g -y
SKILL.md
Frontmatter
{
    "name": "imap-smtp-email",
    "version": "1.0.1",
    "official": true,
    "description": "Read and send email via IMAP\/SMTP. Check for new\/unread messages, fetch content, search mailboxes, mark as read\/unread, and send emails with attachments. Works with any IMAP\/SMTP server including Gmail, Outlook, 163.com, vip.163.com, 126.com, vip.126.com, 188.com, and vip.188.com."
}

IMAP/SMTP Email Tool

Read, search, and manage email via IMAP protocol. Send email via SMTP. Supports Gmail, Outlook, 163.com, vip.163.com, 126.com, vip.126.com, 188.com, vip.188.com, and any standard IMAP/SMTP server.

Important: Configuration is Pre-configured

The .env configuration file is automatically managed by WeSight Settings (邮箱设置). Do NOT ask the user to create or edit .env — just run the commands directly. If credentials are wrong, the scripts will return a clear error message; only then should you inform the user to check their email settings.

The .env file is located in this skill's directory (same folder as this SKILL.md file). The scripts load it automatically via an absolute path, regardless of the current working directory.

Configuration Reference

Create .env in the skill folder or set environment variables:

# IMAP Configuration (receiving email)
IMAP_HOST=imap.gmail.com          # Server hostname
IMAP_PORT=993                     # Server port
IMAP_USER=your@email.com
IMAP_PASS=your_password
IMAP_TLS=true                     # Use TLS/SSL connection
IMAP_REJECT_UNAUTHORIZED=true     # Set to false for self-signed certs
IMAP_MAILBOX=INBOX                # Default mailbox

# SMTP Configuration (sending email)
SMTP_HOST=smtp.gmail.com          # SMTP server hostname
SMTP_PORT=587                     # SMTP port (587 for STARTTLS, 465 for SSL)
SMTP_SECURE=false                 # true for SSL (465), false for STARTTLS (587)
SMTP_USER=your@gmail.com          # Your email address
SMTP_PASS=your_password           # Your password or app password
SMTP_FROM=your@gmail.com          # Default sender email (optional)
SMTP_REJECT_UNAUTHORIZED=true     # Set to false for self-signed certs

Common Email Servers

Provider IMAP Host IMAP Port SMTP Host SMTP Port
163.com imap.163.com 993 smtp.163.com 465
vip.163.com imap.vip.163.com 993 smtp.vip.163.com 465
126.com imap.126.com 993 smtp.126.com 465
vip.126.com imap.vip.126.com 993 smtp.vip.126.com 465
188.com imap.188.com 993 smtp.188.com 465
vip.188.com imap.vip.188.com 993 smtp.vip.188.com 465
yeah.net imap.yeah.net 993 smtp.yeah.net 465
Gmail imap.gmail.com 993 smtp.gmail.com 587
Outlook outlook.office365.com 993 smtp.office365.com 587
QQ Mail imap.qq.com 993 smtp.qq.com 587

Important for 163.com:

  • Use authorization code (授权码), not account password
  • Enable IMAP/SMTP in web settings first

IMAP Commands (Receiving Email)

check

Check for new/unread emails.

node scripts/imap.js check [--limit 10] [--mailbox INBOX] [--recent 2h]

Options:

  • --limit <n>: Max results (default: 10)
  • --mailbox <name>: Mailbox to check (default: INBOX)
  • --recent <time>: Only show emails from last X time (e.g., 30m, 2h, 7d)

fetch

Fetch full email content by UID.

node scripts/imap.js fetch <uid> [--mailbox INBOX]

download

Download all attachments from an email, or a specific attachment.

node scripts/imap.js download <uid> [--mailbox INBOX] [--dir <path>] [--file <filename>]

Options:

  • --mailbox <name>: Mailbox (default: INBOX)
  • --dir <path>: Output directory (default: current directory)
  • --file <filename>: Download only the specified attachment (default: download all)

search

Search emails with filters.

node scripts/imap.js search [options]

Options:
  --unseen           Only unread messages
  --seen             Only read messages
  --from <email>     From address contains
  --subject <text>   Subject contains
  --recent <time>    From last X time (e.g., 30m, 2h, 7d)
  --since <date>     After date (YYYY-MM-DD)
  --before <date>    Before date (YYYY-MM-DD)
  --limit <n>        Max results (default: 20)
  --mailbox <name>   Mailbox to search (default: INBOX)

mark-read / mark-unread

Mark message(s) as read or unread.

node scripts/imap.js mark-read <uid> [uid2 uid3...]
node scripts/imap.js mark-unread <uid> [uid2 uid3...]

list-mailboxes

List all available mailboxes/folders.

node scripts/imap.js list-mailboxes

SMTP Commands (Sending Email)

send

Send email via SMTP.

node scripts/smtp.js send --to <email> --subject <text> [options]

Required:

  • --to <email>: Recipient (comma-separated for multiple)
  • --subject <text>: Email subject, or --subject-file <file>

Optional:

  • --body <text>: Plain text body
  • --html: Send body as HTML
  • --body-file <file>: Read body from file
  • --html-file <file>: Read HTML from file
  • --cc <email>: CC recipients
  • --bcc <email>: BCC recipients
  • --attach <file>: Attachments (comma-separated)
  • --from <email>: Override default sender

Examples:

# Simple text email
node scripts/smtp.js send --to recipient@example.com --subject "Hello" --body "World"

# HTML email
node scripts/smtp.js send --to recipient@example.com --subject "Newsletter" --html --body "<h1>Welcome</h1>"

# Email with attachment
node scripts/smtp.js send --to recipient@example.com --subject "Report" --body "Please find attached" --attach report.pdf

# Multiple recipients
node scripts/smtp.js send --to "a@example.com,b@example.com" --cc "c@example.com" --subject "Update" --body "Team update"

test

Test SMTP connection by sending a test email to yourself.

node scripts/smtp.js test

Dependencies

npm install

Security Notes

  • Store credentials in .env (add to .gitignore)
  • For Gmail: use App Password if 2FA is enabled
  • For 163.com: use authorization code (授权码), not account password

Troubleshooting

Connection timeout:

  • Verify server is running and accessible
  • Check host/port configuration

Authentication failed:

  • Verify username (usually full email address)
  • Check password is correct
  • For 163.com: use authorization code, not account password
  • For Gmail: use App Password if 2FA enabled

TLS/SSL errors:

  • Match IMAP_TLS/SMTP_SECURE setting to server requirements
  • For self-signed certs: set IMAP_REJECT_UNAUTHORIZED=false or SMTP_REJECT_UNAUTHORIZED=false
管理本地设备日历,支持macOS和Windows。用于查看、创建、更新或删除日程事件,通过平台特定脚本直接调用系统日历应用。
用户需要查看或管理日程安排 用户要求创建、修改或删除会议/事件
SKILLs/local-tools/SKILL.md
npx skills add freestylefly/wesight --skill local-tools -g -y
SKILL.md
Frontmatter
{
    "name": "local-tools",
    "official": true,
    "description": "Access local system resources including Calendar on macOS and Windows. Use this skill when you need to manage user's schedule directly on their device."
}

Local Tools Skill

When to Use This Skill

Use the local-tools skill when you need to:

  • Calendar Management - View, create, update, or delete calendar events

Examples of when to use:

  • User: "Show me my schedule for tomorrow"
  • User: "Create a meeting at 3 PM"
  • User: "Search for calendar events containing 'project'"
  • User: "Delete tomorrow's meeting"

How It Works

┌──────────┐    Bash/PowerShell    ┌─────────────────────────────────────────────────────────────┐
│  Claude  │──────────────────────▶│  calendar.sh / calendar.ps1                                 │
│          │                       │  ├─ macOS: osascript -l JavaScript (JXA) ──▶ Calendar.app   │
│          │                       │  └─ Windows: PowerShell ──▶ Outlook COM API                 │
└──────────┘                       └─────────────────────────────────────────────────────────────┘

Architecture:

  1. CLI Scripts - Platform-specific scripts, no HTTP server needed

    • calendar.sh - Bash script for macOS
    • calendar.ps1 - PowerShell script for Windows
  2. Local Calendar Access - Direct access to system calendar

    • macOS: Uses JXA (JavaScript for Automation) to control Calendar.app
    • Windows: Uses PowerShell COM API to control Microsoft Outlook
  3. JSON Output - Structured data format for easy parsing

Platform Support

Platform Implementation Calendar App Status
macOS 10.10+ JXA + Calendar.app Calendar.app ✅ Fully Supported
Windows 7+ PowerShell + COM Microsoft Outlook ✅ Fully Supported
Linux - - ❌ Not Supported

Permissions

macOS

  • Requires "Calendar" access permission
  • User will be prompted on first use
  • Can be managed in: System Settings > Privacy & Security > Calendar

Windows

  • Requires Microsoft Outlook to be installed
  • May require administrative privileges for COM access

Calendar Operations

IMPORTANT: How to Locate the Script

When you read this SKILL.md file using the Read tool, you receive its absolute path (e.g., /Users/username/.../SKILLs/local-tools/SKILL.md).

To construct the script path:

  1. Take the directory of this SKILL.md file
  2. Append /scripts/calendar.sh (macOS) or /scripts/calendar.ps1 (Windows)

Example:

# If SKILL.md is at: /Users/username/path/to/SKILLs/local-tools/SKILL.md
# Then the script is: /Users/username/path/to/SKILLs/local-tools/scripts/calendar.sh

bash "/Users/username/path/to/SKILLs/local-tools/scripts/calendar.sh" <operation> [options]

In all examples below, <skill-dir>/scripts/calendar.sh is a placeholder. Replace it with the actual absolute path.

Best Practices for AI Assistant

DO:

  • ✅ Execute commands directly without showing trial-and-error process
  • ✅ If command fails, inform user about permission issues without showing technical errors
  • ✅ Use search command for searching birthdays/anniversaries
  • ✅ If no calendar name specified, script will automatically use first available calendar

DON'T:

  • ❌ Don't repeatedly try different command combinations
  • ❌ Don't show error stacks or technical details to users
  • ❌ Don't read script source code to analyze issues
  • ❌ Don't ask users for calendar name, use default behavior

Example - Searching for birthdays:

# Correct approach: Search directly, don't trial-and-error
bash "<skill-dir>/scripts/calendar.sh" search --query "birthday"

# If permission error returned, directly tell user:
# "Calendar access permission is required. Please open System Settings > Privacy & Security > Calendar, and authorize Terminal or WeSight"

List Events

# List events for next 7 days (default)
bash "<skill-dir>/scripts/calendar.sh" list

# List events for specific date range
bash "<skill-dir>/scripts/calendar.sh" list \
  --start "2026-02-12T00:00:00" \
  --end "2026-02-19T23:59:59"

# List events from specific calendar (macOS)
bash "<skill-dir>/scripts/calendar.sh" list \
  --calendar "Work"

Create Event

# Create a simple event
bash "<skill-dir>/scripts/calendar.sh" create \
  --title "Team Meeting" \
  --start "2026-02-13T14:00:00" \
  --end "2026-02-13T15:00:00"

# Create event with location and notes
bash "<skill-dir>/scripts/calendar.sh" create \
  --title "Client Call" \
  --start "2026-02-14T10:00:00" \
  --end "2026-02-14T11:00:00" \
  --calendar "Work" \
  --location "Conference Room A" \
  --notes "Discuss Q1 roadmap"

Update Event

# Update event title
bash "<skill-dir>/scripts/calendar.sh" update \
  --id "EVENT-ID" \
  --title "Updated Meeting Title"

# Update event time
bash "<skill-dir>/scripts/calendar.sh" update \
  --id "EVENT-ID" \
  --start "2026-02-13T15:00:00" \
  --end "2026-02-13T16:00:00"

Delete Event

bash "<skill-dir>/scripts/calendar.sh" delete \
  --id "EVENT-ID"

Search Events

# Search for events containing keyword (searches ALL calendars)
bash "<skill-dir>/scripts/calendar.sh" search \
  --query "meeting"

# Search in specific calendar only
bash "<skill-dir>/scripts/calendar.sh" search \
  --query "project" \
  --calendar "Work"

Note: When --calendar is not specified, the search operation will look through all available calendars on both macOS and Windows.

Output Format

All commands return JSON with the following structure:

Success Response

{
  "success": true,
  "data": {
    "events": [
      {
        "eventId": "E621F8C4-...",
        "title": "Team Meeting",
        "startTime": "2026-02-13T14:00:00.000Z",
        "endTime": "2026-02-13T15:00:00.000Z",
        "location": "Conference Room",
        "notes": "Weekly sync",
        "calendar": "Work",
        "allDay": false
      }
    ],
    "count": 1
  }
}

Error Response

{
  "success": false,
  "error": {
    "code": "CALENDAR_ACCESS_ERROR",
    "message": "Calendar access permission is required...",
    "recoverable": true,
    "permissionRequired": true
  }
}

Error Codes

Code Meaning Recoverable
CALENDAR_ACCESS_ERROR Permission denied or calendar not accessible Yes
INVALID_INPUT Missing required parameters No
EVENT_NOT_FOUND Event ID not found No
OUTLOOK_NOT_AVAILABLE Microsoft Outlook not installed (Windows) Yes

Date Format Guidelines

Important: Date Format Guidelines

When using the list command with time ranges:

  1. Always use ISO 8601 format: YYYY-MM-DDTHH:mm:ss
  2. Use local timezone: Do NOT use UTC or timezone suffixes (like +08:00 or Z)
  3. Calculate dates yourself: Do NOT use shell command substitution like $(date ...)
  4. Claude should compute dates: Based on current date, calculate target dates directly
  5. Examples:
    • Today at midnight: 2026-02-13T00:00:00
    • Today at end of day: 2026-02-13T23:59:59
    • Tomorrow morning: 2026-02-14T09:00:00
    • Next week Monday: 2026-02-16T00:00:00

Why: The script expects local time strings that match your system timezone. Shell substitutions may not execute correctly in all environments.

Common Patterns

Pattern 1: Schedule Management

# User asks: "What meetings do I have today?"
# Claude's approach: Calculate today's date and query full day from 00:00 to 23:59
# IMPORTANT: Claude should replace 2026-02-13 with the actual current date
bash "<skill-dir>/scripts/calendar.sh" list \
  --start "2026-02-13T00:00:00" \
  --end "2026-02-13T23:59:59"

# User asks: "What's on my schedule tomorrow?"
# Claude should calculate tomorrow's date (e.g., if today is 2026-02-13, tomorrow is 2026-02-14)
bash "<skill-dir>/scripts/calendar.sh" list \
  --start "2026-02-14T00:00:00" \
  --end "2026-02-14T23:59:59"

Pattern 2: Meeting Scheduling

# User asks: "Schedule a meeting for tomorrow at 3 PM"
# Claude's approach:
bash "<skill-dir>/scripts/calendar.sh" create \
  --title "Meeting" \
  --start "2026-02-13T15:00:00" \
  --end "2026-02-13T16:00:00" \
  --calendar "Work"

Pattern 3: Event Search

# User asks: "Find all meetings about the project"
# Claude's approach:
bash "<skill-dir>/scripts/calendar.sh" search \
  --query "project" \
  --calendar "Work"

Pattern 4: Availability Check

# User asks: "Am I free tomorrow afternoon?"
# Claude's approach:
# 1. List tomorrow's events
# 2. Analyze time slots
# 3. Report availability
bash "<skill-dir>/scripts/calendar.sh" list \
  --start "2026-02-14T00:00:00" \
  --end "2026-02-14T23:59:59"

Known Behaviors

Time Range Matching

The list command uses interval overlap detection:

  • Returns events that have any overlap with the query time range
  • Does NOT require events to be fully contained within the range

Examples:

  • Query: 2026-02-13 00:00:00 to 23:59:59
  • Returns:
    • ✅ Events fully on Feb 13 (e.g., 10:00-11:00)
    • ✅ Multi-day events spanning Feb 13 (e.g., Feb 12 10:00 - Feb 14 10:00)
    • ✅ Events crossing midnight (e.g., Feb 13 23:30 - Feb 14 00:30)
    • ❌ Events entirely before Feb 13 (e.g., Feb 12 10:00-11:00)
    • ❌ Events entirely after Feb 13 (e.g., Feb 14 10:00-11:00)

All-Day Events

  • Treated as spanning from 00:00:00 to 23:59:59 on their date(s)
  • Multi-day all-day events (e.g., Feb 12-14) will appear when querying any date within that range

Time Precision

  • Comparisons use second-level precision
  • Milliseconds are ignored in date comparisons

Recurring Events

  • Each occurrence is treated as a separate event instance
  • The script returns individual occurrences within the queried time range

Best Practices

1. Always Check Before Creating

Before creating an event, list existing events to avoid conflicts:

# First check existing events
bash "<skill-dir>/scripts/calendar.sh" list

# Then create if no conflict
bash "<skill-dir>/scripts/calendar.sh" create ...

2. Use Specific Calendars (macOS)

Specify the calendar to keep events organized:

bash "<skill-dir>/scripts/calendar.sh" create \
  --title "Team Meeting" \
  --calendar "Work" \
  ...

3. Search Before Updating/Deleting

Always search first to get the correct event ID:

# Search to find event ID
bash "<skill-dir>/scripts/calendar.sh" search --query "meeting"

# Then update or delete
bash "<skill-dir>/scripts/calendar.sh" update --id "FOUND-ID" ...

4. Handle Errors Gracefully

Parse the response and handle errors:

result=$(bash "<skill-dir>/scripts/calendar.sh" list)
if echo "$result" | grep -q '"success":true'; then
  # Process events
  events=$(echo "$result" | jq '.data.events')
else
  # Handle error
  error=$(echo "$result" | jq '.error.message')
  echo "Failed: $error"
fi

Limitations

macOS

  • Requires macOS 10.10 Yosemite or later (for JXA support)
  • Requires Calendar access permission
  • Does not support advanced recurring event queries
  • Cannot modify recurring event rules

Windows

  • Requires Microsoft Outlook to be installed
  • Does not support other calendar applications (Windows Calendar, Google Calendar, etc.)
  • May require COM access permissions in corporate environments
  • Folder enumeration may skip restricted calendars

General

  • All dates must be in ISO 8601 format (YYYY-MM-DDTHH:mm:ss)
  • Uses local timezone for all operations
  • Return values are converted to UTC (ISO 8601 with Z suffix)
  • No support for attendees or meeting invitations

Troubleshooting

macOS

Permission Denied:

Error: Calendar access permission is required

Solution: Open System Settings > Privacy & Security > Calendar, authorize Terminal or WeSight

Script Not Found:

bash: calendar.sh: No such file or directory

Solution: Ensure you're using the absolute path from SKILL.md's directory + /scripts/calendar.sh

Windows

Outlook Not Found:

Error: Microsoft Outlook is not installed or not accessible

Solution: Install Microsoft Outlook and ensure it's properly configured

PowerShell Execution Policy:

Error: Execution of scripts is disabled on this system

Solution: Run PowerShell as Administrator and execute:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Technical Details

macOS Implementation

JXA (JavaScript for Automation):

  • Uses osascript -l JavaScript to execute JXA code
  • Controls Calendar.app via Apple Events
  • Works on both Intel and Apple Silicon Macs
  • Requires user permission for Calendar access

Date Handling:

  • Uses BSD date command (macOS native)
  • Format: date +%Y-%m-%dT%H:%M:%S (local timezone)
  • Relative dates: date -v+7d (7 days from now)

Windows Implementation

PowerShell + COM:

  • Uses Outlook COM API via PowerShell
  • Requires Outlook to be installed and configured
  • Works with all Outlook-compatible calendars

Date Handling:

  • Uses PowerShell [DateTime]::Parse() for date parsing
  • Automatically handles local timezone

Cross-Platform Consistency

Both implementations:

  • Use identical JSON output format
  • Support the same operations (list, create, update, delete, search)
  • Handle dates in local timezone
  • Return UTC timestamps in ISO 8601 format

Related Skills

  • imap-smtp-email - For email-based meeting invitations
提供PDF处理工具包,支持文本表格提取、文档创建、合并拆分及表单填写。涵盖pypdf、pdfplumber和reportlab库的使用指南,适用于批量生成、分析及处理PDF文件。
需要提取PDF中的文本或表格数据 需要合并、拆分或旋转PDF文档 需要从零创建新的PDF文件 需要读取或填写PDF表单
SKILLs/pdf/SKILL.md
npx skills add freestylefly/wesight --skill pdf -g -y
SKILL.md
Frontmatter
{
    "name": "pdf",
    "license": "Proprietary. LICENSE.txt has complete terms",
    "official": true,
    "description": "Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging\/splitting documents, and handling forms. When Claude needs to fill in a PDF form or programmatically process, generate, or analyze PDF documents at scale."
}

PDF Processing Guide

Overview

This guide covers essential PDF processing operations using Python libraries and command-line tools. For advanced features, JavaScript libraries, and detailed examples, see reference.md. If you need to fill out a PDF form, read forms.md and follow its instructions.

Quick Start

from pypdf import PdfReader, PdfWriter

# Read a PDF
reader = PdfReader("document.pdf")
print(f"Pages: {len(reader.pages)}")

# Extract text
text = ""
for page in reader.pages:
    text += page.extract_text()

Python Libraries

pypdf - Basic Operations

Merge PDFs

from pypdf import PdfWriter, PdfReader

writer = PdfWriter()
for pdf_file in ["doc1.pdf", "doc2.pdf", "doc3.pdf"]:
    reader = PdfReader(pdf_file)
    for page in reader.pages:
        writer.add_page(page)

with open("merged.pdf", "wb") as output:
    writer.write(output)

Split PDF

reader = PdfReader("input.pdf")
for i, page in enumerate(reader.pages):
    writer = PdfWriter()
    writer.add_page(page)
    with open(f"page_{i+1}.pdf", "wb") as output:
        writer.write(output)

Extract Metadata

reader = PdfReader("document.pdf")
meta = reader.metadata
print(f"Title: {meta.title}")
print(f"Author: {meta.author}")
print(f"Subject: {meta.subject}")
print(f"Creator: {meta.creator}")

Rotate Pages

reader = PdfReader("input.pdf")
writer = PdfWriter()

page = reader.pages[0]
page.rotate(90)  # Rotate 90 degrees clockwise
writer.add_page(page)

with open("rotated.pdf", "wb") as output:
    writer.write(output)

pdfplumber - Text and Table Extraction

Extract Text with Layout

import pdfplumber

with pdfplumber.open("document.pdf") as pdf:
    for page in pdf.pages:
        text = page.extract_text()
        print(text)

Extract Tables

with pdfplumber.open("document.pdf") as pdf:
    for i, page in enumerate(pdf.pages):
        tables = page.extract_tables()
        for j, table in enumerate(tables):
            print(f"Table {j+1} on page {i+1}:")
            for row in table:
                print(row)

Advanced Table Extraction

import pandas as pd

with pdfplumber.open("document.pdf") as pdf:
    all_tables = []
    for page in pdf.pages:
        tables = page.extract_tables()
        for table in tables:
            if table:  # Check if table is not empty
                df = pd.DataFrame(table[1:], columns=table[0])
                all_tables.append(df)

# Combine all tables
if all_tables:
    combined_df = pd.concat(all_tables, ignore_index=True)
    combined_df.to_excel("extracted_tables.xlsx", index=False)

reportlab - Create PDFs

Basic PDF Creation

from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas

c = canvas.Canvas("hello.pdf", pagesize=letter)
width, height = letter

# Add text
c.drawString(100, height - 100, "Hello World!")
c.drawString(100, height - 120, "This is a PDF created with reportlab")

# Add a line
c.line(100, height - 140, 400, height - 140)

# Save
c.save()

Create PDF with Multiple Pages

from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
from reportlab.lib.styles import getSampleStyleSheet

doc = SimpleDocTemplate("report.pdf", pagesize=letter)
styles = getSampleStyleSheet()
story = []

# Add content
title = Paragraph("Report Title", styles['Title'])
story.append(title)
story.append(Spacer(1, 12))

body = Paragraph("This is the body of the report. " * 20, styles['Normal'])
story.append(body)
story.append(PageBreak())

# Page 2
story.append(Paragraph("Page 2", styles['Heading1']))
story.append(Paragraph("Content for page 2", styles['Normal']))

# Build PDF
doc.build(story)

Command-Line Tools

pdftotext (poppler-utils)

# Extract text
pdftotext input.pdf output.txt

# Extract text preserving layout
pdftotext -layout input.pdf output.txt

# Extract specific pages
pdftotext -f 1 -l 5 input.pdf output.txt  # Pages 1-5

qpdf

# Merge PDFs
qpdf --empty --pages file1.pdf file2.pdf -- merged.pdf

# Split pages
qpdf input.pdf --pages . 1-5 -- pages1-5.pdf
qpdf input.pdf --pages . 6-10 -- pages6-10.pdf

# Rotate pages
qpdf input.pdf output.pdf --rotate=+90:1  # Rotate page 1 by 90 degrees

# Remove password
qpdf --password=mypassword --decrypt encrypted.pdf decrypted.pdf

pdftk (if available)

# Merge
pdftk file1.pdf file2.pdf cat output merged.pdf

# Split
pdftk input.pdf burst

# Rotate
pdftk input.pdf rotate 1east output rotated.pdf

Common Tasks

Extract Text from Scanned PDFs

# Requires: pip install pytesseract pdf2image
import pytesseract
from pdf2image import convert_from_path

# Convert PDF to images
images = convert_from_path('scanned.pdf')

# OCR each page
text = ""
for i, image in enumerate(images):
    text += f"Page {i+1}:\n"
    text += pytesseract.image_to_string(image)
    text += "\n\n"

print(text)

Add Watermark

from pypdf import PdfReader, PdfWriter

# Create watermark (or load existing)
watermark = PdfReader("watermark.pdf").pages[0]

# Apply to all pages
reader = PdfReader("document.pdf")
writer = PdfWriter()

for page in reader.pages:
    page.merge_page(watermark)
    writer.add_page(page)

with open("watermarked.pdf", "wb") as output:
    writer.write(output)

Extract Images

# Using pdfimages (poppler-utils)
pdfimages -j input.pdf output_prefix

# This extracts all images as output_prefix-000.jpg, output_prefix-001.jpg, etc.

Password Protection

from pypdf import PdfReader, PdfWriter

reader = PdfReader("input.pdf")
writer = PdfWriter()

for page in reader.pages:
    writer.add_page(page)

# Add password
writer.encrypt("userpassword", "ownerpassword")

with open("encrypted.pdf", "wb") as output:
    writer.write(output)

Quick Reference

Task Best Tool Command/Code
Merge PDFs pypdf writer.add_page(page)
Split PDFs pypdf One page per file
Extract text pdfplumber page.extract_text()
Extract tables pdfplumber page.extract_tables()
Create PDFs reportlab Canvas or Platypus
Command line merge qpdf qpdf --empty --pages ...
OCR scanned PDFs pytesseract Convert to image first
Fill PDF forms pdf-lib or pypdf (see forms.md) See forms.md

Next Steps

  • For advanced pypdfium2 usage, see reference.md
  • For JavaScript libraries (pdf-lib), see reference.md
  • If you need to fill out a PDF form, follow the instructions in forms.md
  • For troubleshooting guides, see reference.md
通过终端自动化真实浏览器,执行导航、表单填写、截图及数据提取。依赖npx和playwright-cli,遵循打开页面、快照、交互、再快照的工作流,支持调试和多标签页操作。
需要自动化浏览器操作 从终端提取网页数据 UI流程调试
SKILLs/playwright/SKILL.md
npx skills add freestylefly/wesight --skill playwright -g -y
SKILL.md
Frontmatter
{
    "name": "playwright",
    "official": true,
    "description": "Use when the task requires automating a real browser from the terminal (navigation, form filling, snapshots, screenshots, data extraction, UI-flow debugging) via `playwright-cli` or the bundled wrapper script."
}

Playwright CLI Skill

Drive a real browser from the terminal using playwright-cli. Prefer the bundled wrapper script so the CLI works even when it is not globally installed. Treat this skill as CLI-first automation. Do not pivot to @playwright/test unless the user explicitly asks for test files.

Prerequisite check (required)

Before proposing commands, check whether npx is available (the wrapper depends on it):

command -v npx >/dev/null 2>&1

If it is not available, pause and ask the user to install Node.js/npm (which provides npx). Provide these steps verbatim:

# Verify Node/npm are installed
node --version
npm --version

# If missing, install Node.js/npm, then:
npm install -g @playwright/mcp@latest
playwright-cli --help

Once npx is present, proceed with the wrapper script. A global install of playwright-cli is optional.

Skill path (set once)

export SKILLS_ROOT="${WESIGHT_SKILLS_ROOT:-${SKILLS_ROOT:-$HOME/Library/Application Support/WeSight/SKILLs}}"
export PWCLI="$SKILLS_ROOT/playwright/scripts/playwright_cli.sh"

Installed skills resolve from $WESIGHT_SKILLS_ROOT / $SKILLS_ROOT (production default: app userData/SKILLs, macOS usually ~/Library/Application Support/WeSight/SKILLs).

Quick start

Use the wrapper script:

"$PWCLI" open https://playwright.dev --headed
"$PWCLI" snapshot
"$PWCLI" click e15
"$PWCLI" type "Playwright"
"$PWCLI" press Enter
"$PWCLI" screenshot

If the user prefers a global install, this is also valid:

npm install -g @playwright/mcp@latest
playwright-cli --help

Core workflow

  1. Open the page.
  2. Snapshot to get stable element refs.
  3. Interact using refs from the latest snapshot.
  4. Re-snapshot after navigation or significant DOM changes.
  5. Capture artifacts (screenshot, pdf, traces) when useful.

Minimal loop:

"$PWCLI" open https://example.com
"$PWCLI" snapshot
"$PWCLI" click e3
"$PWCLI" snapshot

When to snapshot again

Snapshot again after:

  • navigation
  • clicking elements that change the UI substantially
  • opening/closing modals or menus
  • tab switches

Refs can go stale. When a command fails due to a missing ref, snapshot again.

Recommended patterns

Form fill and submit

"$PWCLI" open https://example.com/form
"$PWCLI" snapshot
"$PWCLI" fill e1 "user@example.com"
"$PWCLI" fill e2 "password123"
"$PWCLI" click e3
"$PWCLI" snapshot

Debug a UI flow with traces

"$PWCLI" open https://example.com --headed
"$PWCLI" tracing-start
# ...interactions...
"$PWCLI" tracing-stop

Multi-tab work

"$PWCLI" tab-new https://example.com
"$PWCLI" tab-list
"$PWCLI" tab-select 0
"$PWCLI" snapshot

Wrapper script

The wrapper script uses npx --package @playwright/mcp playwright-cli so the CLI can run without a global install:

"$PWCLI" --help

Prefer the wrapper unless the repository already standardizes on a global install.

References

Open only what you need:

  • CLI command reference: references/cli.md
  • Practical workflows and troubleshooting: references/workflows.md

Guardrails

  • Always snapshot before referencing element ids like e12.
  • Re-snapshot when refs seem stale.
  • Prefer explicit commands over eval and run-code unless needed.
  • When you do not have a fresh snapshot, use placeholder refs like eX and say why; do not bypass refs with run-code.
  • Use --headed when a visual check will help.
  • When capturing artifacts in this repo, use output/playwright/ and avoid introducing new top-level artifact folders.
  • Default to CLI commands and workflows, not Playwright test specs.
用于创建、编辑和分析PPTX演示文稿。支持文本提取、原始XML访问以处理备注和布局,以及通过HTML转PPTX工作流从头设计幻灯片,强调根据内容匹配设计风格。
用户需要创建新的PPTX文件 用户要求修改或编辑现有演示文稿内容 用户需要分析PPTX中的注释、演讲者备注或版式
SKILLs/pptx/SKILL.md
npx skills add freestylefly/wesight --skill pptx -g -y
SKILL.md
Frontmatter
{
    "name": "pptx",
    "license": "Proprietary. LICENSE.txt has complete terms",
    "official": true,
    "description": "Presentation creation, editing, and analysis. When Claude needs to work with presentations (.pptx files) for: (1) Creating new presentations, (2) Modifying or editing content, (3) Working with layouts, (4) Adding comments or speaker notes, or any other presentation tasks"
}

PPTX creation, editing, and analysis

Overview

A user may ask you to create, edit, or analyze the contents of a .pptx file. A .pptx file is essentially a ZIP archive containing XML files and other resources that you can read or edit. You have different tools and workflows available for different tasks.

Reading and analyzing content

Text extraction

If you just need to read the text contents of a presentation, you should convert the document to markdown:

# Convert document to markdown
python -m markitdown path-to-file.pptx

Raw XML access

You need raw XML access for: comments, speaker notes, slide layouts, animations, design elements, and complex formatting. For any of these features, you'll need to unpack a presentation and read its raw XML contents.

Unpacking a file

python ooxml/scripts/unpack.py <office_file> <output_dir>

Note: Resolve script paths from this skill directory. Prefer $SKILLS_ROOT/pptx/ooxml/scripts/unpack.py when $SKILLS_ROOT is available; otherwise resolve ooxml/scripts/unpack.py relative to this SKILL.md file's directory. Do not assume a workspace-relative skills/pptx/... path.

Key file structures

  • ppt/presentation.xml - Main presentation metadata and slide references
  • ppt/slides/slide{N}.xml - Individual slide contents (slide1.xml, slide2.xml, etc.)
  • ppt/notesSlides/notesSlide{N}.xml - Speaker notes for each slide
  • ppt/comments/modernComment_*.xml - Comments for specific slides
  • ppt/slideLayouts/ - Layout templates for slides
  • ppt/slideMasters/ - Master slide templates
  • ppt/theme/ - Theme and styling information
  • ppt/media/ - Images and other media files

Typography and color extraction

When given an example design to emulate: Always analyze the presentation's typography and colors first using the methods below:

  1. Read theme file: Check ppt/theme/theme1.xml for colors (<a:clrScheme>) and fonts (<a:fontScheme>)
  2. Sample slide content: Examine ppt/slides/slide1.xml for actual font usage (<a:rPr>) and colors
  3. Search for patterns: Use grep to find color (<a:solidFill>, <a:srgbClr>) and font references across all XML files

Creating a new PowerPoint presentation without a template

When creating a new PowerPoint presentation from scratch, use the html2pptx workflow to convert HTML slides to PowerPoint with accurate positioning.

Design Principles

CRITICAL: Before creating any presentation, analyze the content and choose appropriate design elements:

  1. Consider the subject matter: What is this presentation about? What tone, industry, or mood does it suggest?
  2. Check for branding: If the user mentions a company/organization, consider their brand colors and identity
  3. Match palette to content: Select colors that reflect the subject
  4. State your approach: Explain your design choices before writing code

Requirements:

  • ✅ State your content-informed design approach BEFORE writing code
  • ✅ Use web-safe fonts only: Arial, Helvetica, Times New Roman, Georgia, Courier New, Verdana, Tahoma, Trebuchet MS, Impact
  • ✅ Create clear visual hierarchy through size, weight, and color
  • ✅ Ensure readability: strong contrast, appropriately sized text, clean alignment
  • ✅ Be consistent: repeat patterns, spacing, and visual language across slides

Color Palette Selection

Choosing colors creatively:

  • Think beyond defaults: What colors genuinely match this specific topic? Avoid autopilot choices.
  • Consider multiple angles: Topic, industry, mood, energy level, target audience, brand identity (if mentioned)
  • Be adventurous: Try unexpected combinations - a healthcare presentation doesn't have to be green, finance doesn't have to be navy
  • Build your palette: Pick 3-5 colors that work together (dominant colors + supporting tones + accent)
  • Ensure contrast: Text must be clearly readable on backgrounds

Example color palettes (use these to spark creativity - choose one, adapt it, or create your own):

  1. Classic Blue: Deep navy (#1C2833), slate gray (#2E4053), silver (#AAB7B8), off-white (#F4F6F6)
  2. Teal & Coral: Teal (#5EA8A7), deep teal (#277884), coral (#FE4447), white (#FFFFFF)
  3. Bold Red: Red (#C0392B), bright red (#E74C3C), orange (#F39C12), yellow (#F1C40F), green (#2ECC71)
  4. Warm Blush: Mauve (#A49393), blush (#EED6D3), rose (#E8B4B8), cream (#FAF7F2)
  5. Burgundy Luxury: Burgundy (#5D1D2E), crimson (#951233), rust (#C15937), gold (#997929)
  6. Deep Purple & Emerald: Purple (#B165FB), dark blue (#181B24), emerald (#40695B), white (#FFFFFF)
  7. Cream & Forest Green: Cream (#FFE1C7), forest green (#40695B), white (#FCFCFC)
  8. Pink & Purple: Pink (#F8275B), coral (#FF574A), rose (#FF737D), purple (#3D2F68)
  9. Lime & Plum: Lime (#C5DE82), plum (#7C3A5F), coral (#FD8C6E), blue-gray (#98ACB5)
  10. Black & Gold: Gold (#BF9A4A), black (#000000), cream (#F4F6F6)
  11. Sage & Terracotta: Sage (#87A96B), terracotta (#E07A5F), cream (#F4F1DE), charcoal (#2C2C2C)
  12. Charcoal & Red: Charcoal (#292929), red (#E33737), light gray (#CCCBCB)
  13. Vibrant Orange: Orange (#F96D00), light gray (#F2F2F2), charcoal (#222831)
  14. Forest Green: Black (#191A19), green (#4E9F3D), dark green (#1E5128), white (#FFFFFF)
  15. Retro Rainbow: Purple (#722880), pink (#D72D51), orange (#EB5C18), amber (#F08800), gold (#DEB600)
  16. Vintage Earthy: Mustard (#E3B448), sage (#CBD18F), forest green (#3A6B35), cream (#F4F1DE)
  17. Coastal Rose: Old rose (#AD7670), beaver (#B49886), eggshell (#F3ECDC), ash gray (#BFD5BE)
  18. Orange & Turquoise: Light orange (#FC993E), grayish turquoise (#667C6F), white (#FCFCFC)

Visual Details Options

Geometric Patterns:

  • Diagonal section dividers instead of horizontal
  • Asymmetric column widths (30/70, 40/60, 25/75)
  • Rotated text headers at 90° or 270°
  • Circular/hexagonal frames for images
  • Triangular accent shapes in corners
  • Overlapping shapes for depth

Border & Frame Treatments:

  • Thick single-color borders (10-20pt) on one side only
  • Double-line borders with contrasting colors
  • Corner brackets instead of full frames
  • L-shaped borders (top+left or bottom+right)
  • Underline accents beneath headers (3-5pt thick)

Typography Treatments:

  • Extreme size contrast (72pt headlines vs 11pt body)
  • All-caps headers with wide letter spacing
  • Numbered sections in oversized display type
  • Monospace (Courier New) for data/stats/technical content
  • Condensed fonts (Arial Narrow) for dense information
  • Outlined text for emphasis

Chart & Data Styling:

  • Monochrome charts with single accent color for key data
  • Horizontal bar charts instead of vertical
  • Dot plots instead of bar charts
  • Minimal gridlines or none at all
  • Data labels directly on elements (no legends)
  • Oversized numbers for key metrics

Layout Innovations:

  • Full-bleed images with text overlays
  • Sidebar column (20-30% width) for navigation/context
  • Modular grid systems (3×3, 4×4 blocks)
  • Z-pattern or F-pattern content flow
  • Floating text boxes over colored shapes
  • Magazine-style multi-column layouts

Background Treatments:

  • Solid color blocks occupying 40-60% of slide
  • Gradient fills (vertical or diagonal only)
  • Split backgrounds (two colors, diagonal or vertical)
  • Edge-to-edge color bands
  • Negative space as a design element

Layout Tips

When creating slides with charts or tables:

  • Two-column layout (PREFERRED): Use a header spanning the full width, then two columns below - text/bullets in one column and the featured content in the other. This provides better balance and makes charts/tables more readable. Use flexbox with unequal column widths (e.g., 40%/60% split) to optimize space for each content type.
  • Full-slide layout: Let the featured content (chart/table) take up the entire slide for maximum impact and readability
  • NEVER vertically stack: Do not place charts/tables below text in a single column - this causes poor readability and layout issues

Workflow

  1. MANDATORY - READ ENTIRE FILE: Read html2pptx.md from the same directory as this SKILL.md (installed default: $SKILLS_ROOT/pptx/html2pptx.md) completely from start to finish. NEVER set any range limits when reading this file. Read the full file content for detailed syntax, critical formatting rules, and best practices before proceeding with presentation creation.
  2. Create an HTML file for each slide with proper dimensions (e.g., 720pt × 405pt for 16:9)
    • Use <p>, <h1>-<h6>, <ul>, <ol> for all text content
    • Use class="placeholder" for areas where charts/tables will be added (render with gray background for visibility)
    • CRITICAL: Rasterize gradients and icons as PNG images FIRST using Sharp, then reference in HTML
    • LAYOUT: For slides with charts/tables/images, use either full-slide layout or two-column layout for better readability
  3. Create and run a JavaScript file using the html2pptx.js library to convert HTML slides to PowerPoint and save the presentation
    • Use the html2pptx() function to process each HTML file
    • Add charts and tables to placeholder areas using PptxGenJS API
    • Save the presentation using pptx.writeFile()
  4. Visual validation: Generate thumbnails and inspect for layout issues
    • Create thumbnail grid: python scripts/thumbnail.py output.pptx workspace/thumbnails --cols 4
    • Read and carefully examine the thumbnail image for:
      • Text cutoff: Text being cut off by header bars, shapes, or slide edges
      • Text overlap: Text overlapping with other text or shapes
      • Positioning issues: Content too close to slide boundaries or other elements
      • Contrast issues: Insufficient contrast between text and backgrounds
    • If issues found, adjust HTML margins/spacing/colors and regenerate the presentation
    • Repeat until all slides are visually correct

Editing an existing PowerPoint presentation

When edit slides in an existing PowerPoint presentation, you need to work with the raw Office Open XML (OOXML) format. This involves unpacking the .pptx file, editing the XML content, and repacking it.

Workflow

  1. MANDATORY - READ ENTIRE FILE: Read ooxml.md from the same directory as this SKILL.md (installed default: $SKILLS_ROOT/pptx/ooxml.md) (~500 lines) completely from start to finish. NEVER set any range limits when reading this file. Read the full file content for detailed guidance on OOXML structure and editing workflows before any presentation editing.
  2. Unpack the presentation: python ooxml/scripts/unpack.py <office_file> <output_dir>
  3. Edit the XML files (primarily ppt/slides/slide{N}.xml and related files)
  4. CRITICAL: Validate immediately after each edit and fix any validation errors before proceeding: python ooxml/scripts/validate.py <dir> --original <file>
  5. Pack the final presentation: python ooxml/scripts/pack.py <input_directory> <office_file>

Creating a new PowerPoint presentation using a template

When you need to create a presentation that follows an existing template's design, you'll need to duplicate and re-arrange template slides before then replacing placeholder context.

Workflow

  1. Extract template text AND create visual thumbnail grid:

    • Extract text: python -m markitdown template.pptx > template-content.md
    • Read template-content.md: Read the entire file to understand the contents of the template presentation. NEVER set any range limits when reading this file.
    • Create thumbnail grids: python scripts/thumbnail.py template.pptx
    • See Creating Thumbnail Grids section for more details
  2. Analyze template and save inventory to a file:

    • Visual Analysis: Review thumbnail grid(s) to understand slide layouts, design patterns, and visual structure
    • Create and save a template inventory file at template-inventory.md containing:
      # Template Inventory Analysis
      **Total Slides: [count]**
      **IMPORTANT: Slides are 0-indexed (first slide = 0, last slide = count-1)**
      
      ## [Category Name]
      - Slide 0: [Layout code if available] - Description/purpose
      - Slide 1: [Layout code] - Description/purpose
      - Slide 2: [Layout code] - Description/purpose
      [... EVERY slide must be listed individually with its index ...]
      
    • Using the thumbnail grid: Reference the visual thumbnails to identify:
      • Layout patterns (title slides, content layouts, section dividers)
      • Image placeholder locations and counts
      • Design consistency across slide groups
      • Visual hierarchy and structure
    • This inventory file is REQUIRED for selecting appropriate templates in the next step
  3. Create presentation outline based on template inventory:

    • Review available templates from step 2.
    • Choose an intro or title template for the first slide. This should be one of the first templates.
    • Choose safe, text-based layouts for the other slides.
    • CRITICAL: Match layout structure to actual content:
      • Single-column layouts: Use for unified narrative or single topic
      • Two-column layouts: Use ONLY when you have exactly 2 distinct items/concepts
      • Three-column layouts: Use ONLY when you have exactly 3 distinct items/concepts
      • Image + text layouts: Use ONLY when you have actual images to insert
      • Quote layouts: Use ONLY for actual quotes from people (with attribution), never for emphasis
      • Never use layouts with more placeholders than you have content
      • If you have 2 items, don't force them into a 3-column layout
      • If you have 4+ items, consider breaking into multiple slides or using a list format
    • Count your actual content pieces BEFORE selecting the layout
    • Verify each placeholder in the chosen layout will be filled with meaningful content
    • Select one option representing the best layout for each content section.
    • Save outline.md with content AND template mapping that leverages available designs
    • Example template mapping:
      # Template slides to use (0-based indexing)
      # WARNING: Verify indices are within range! Template with 73 slides has indices 0-72
      # Mapping: slide numbers from outline -> template slide indices
      template_mapping = [
          0,   # Use slide 0 (Title/Cover)
          34,  # Use slide 34 (B1: Title and body)
          34,  # Use slide 34 again (duplicate for second B1)
          50,  # Use slide 50 (E1: Quote)
          54,  # Use slide 54 (F2: Closing + Text)
      ]
      
  4. Duplicate, reorder, and delete slides using rearrange.py:

    • Use the scripts/rearrange.py script to create a new presentation with slides in the desired order:
      python scripts/rearrange.py template.pptx working.pptx 0,34,34,50,52
      
    • The script handles duplicating repeated slides, deleting unused slides, and reordering automatically
    • Slide indices are 0-based (first slide is 0, second is 1, etc.)
    • The same slide index can appear multiple times to duplicate that slide
  5. Extract ALL text using the inventory.py script:

    • Run inventory extraction:

      python scripts/inventory.py working.pptx text-inventory.json
      
    • Read text-inventory.json: Read the entire text-inventory.json file to understand all shapes and their properties. NEVER set any range limits when reading this file.

    • The inventory JSON structure:

        {
          "slide-0": {
            "shape-0": {
              "placeholder_type": "TITLE",  // or null for non-placeholders
              "left": 1.5,                  // position in inches
              "top": 2.0,
              "width": 7.5,
              "height": 1.2,
              "paragraphs": [
                {
                  "text": "Paragraph text",
                  // Optional properties (only included when non-default):
                  "bullet": true,           // explicit bullet detected
                  "level": 0,               // only included when bullet is true
                  "alignment": "CENTER",    // CENTER, RIGHT (not LEFT)
                  "space_before": 10.0,     // space before paragraph in points
                  "space_after": 6.0,       // space after paragraph in points
                  "line_spacing": 22.4,     // line spacing in points
                  "font_name": "Arial",     // from first run
                  "font_size": 14.0,        // in points
                  "bold": true,
                  "italic": false,
                  "underline": false,
                  "color": "FF0000"         // RGB color
                }
              ]
            }
          }
        }
      
    • Key features:

      • Slides: Named as "slide-0", "slide-1", etc.
      • Shapes: Ordered by visual position (top-to-bottom, left-to-right) as "shape-0", "shape-1", etc.
      • Placeholder types: TITLE, CENTER_TITLE, SUBTITLE, BODY, OBJECT, or null
      • Default font size: default_font_size in points extracted from layout placeholders (when available)
      • Slide numbers are filtered: Shapes with SLIDE_NUMBER placeholder type are automatically excluded from inventory
      • Bullets: When bullet: true, level is always included (even if 0)
      • Spacing: space_before, space_after, and line_spacing in points (only included when set)
      • Colors: color for RGB (e.g., "FF0000"), theme_color for theme colors (e.g., "DARK_1")
      • Properties: Only non-default values are included in the output
  6. Generate replacement text and save the data to a JSON file Based on the text inventory from the previous step:

    • CRITICAL: First verify which shapes exist in the inventory - only reference shapes that are actually present
    • VALIDATION: The replace.py script will validate that all shapes in your replacement JSON exist in the inventory
      • If you reference a non-existent shape, you'll get an error showing available shapes
      • If you reference a non-existent slide, you'll get an error indicating the slide doesn't exist
      • All validation errors are shown at once before the script exits
    • IMPORTANT: The replace.py script uses inventory.py internally to identify ALL text shapes
    • AUTOMATIC CLEARING: ALL text shapes from the inventory will be cleared unless you provide "paragraphs" for them
    • Add a "paragraphs" field to shapes that need content (not "replacement_paragraphs")
    • Shapes without "paragraphs" in the replacement JSON will have their text cleared automatically
    • Paragraphs with bullets will be automatically left aligned. Don't set the alignment property on when "bullet": true
    • Generate appropriate replacement content for placeholder text
    • Use shape size to determine appropriate content length
    • CRITICAL: Include paragraph properties from the original inventory - don't just provide text
    • IMPORTANT: When bullet: true, do NOT include bullet symbols (•, -, *) in text - they're added automatically
    • ESSENTIAL FORMATTING RULES:
      • Headers/titles should typically have "bold": true
      • List items should have "bullet": true, "level": 0 (level is required when bullet is true)
      • Preserve any alignment properties (e.g., "alignment": "CENTER" for centered text)
      • Include font properties when different from default (e.g., "font_size": 14.0, "font_name": "Lora")
      • Colors: Use "color": "FF0000" for RGB or "theme_color": "DARK_1" for theme colors
      • The replacement script expects properly formatted paragraphs, not just text strings
      • Overlapping shapes: Prefer shapes with larger default_font_size or more appropriate placeholder_type
    • Save the updated inventory with replacements to replacement-text.json
    • WARNING: Different template layouts have different shape counts - always check the actual inventory before creating replacements

    Example paragraphs field showing proper formatting:

    "paragraphs": [
      {
        "text": "New presentation title text",
        "alignment": "CENTER",
        "bold": true
      },
      {
        "text": "Section Header",
        "bold": true
      },
      {
        "text": "First bullet point without bullet symbol",
        "bullet": true,
        "level": 0
      },
      {
        "text": "Red colored text",
        "color": "FF0000"
      },
      {
        "text": "Theme colored text",
        "theme_color": "DARK_1"
      },
      {
        "text": "Regular paragraph text without special formatting"
      }
    ]
    

    Shapes not listed in the replacement JSON are automatically cleared:

    {
      "slide-0": {
        "shape-0": {
          "paragraphs": [...] // This shape gets new text
        }
        // shape-1 and shape-2 from inventory will be cleared automatically
      }
    }
    

    Common formatting patterns for presentations:

    • Title slides: Bold text, sometimes centered
    • Section headers within slides: Bold text
    • Bullet lists: Each item needs "bullet": true, "level": 0
    • Body text: Usually no special properties needed
    • Quotes: May have special alignment or font properties
  7. Apply replacements using the replace.py script

    python scripts/replace.py working.pptx replacement-text.json output.pptx
    

    The script will:

    • First extract the inventory of ALL text shapes using functions from inventory.py
    • Validate that all shapes in the replacement JSON exist in the inventory
    • Clear text from ALL shapes identified in the inventory
    • Apply new text only to shapes with "paragraphs" defined in the replacement JSON
    • Preserve formatting by applying paragraph properties from the JSON
    • Handle bullets, alignment, font properties, and colors automatically
    • Save the updated presentation

    Example validation errors:

    ERROR: Invalid shapes in replacement JSON:
      - Shape 'shape-99' not found on 'slide-0'. Available shapes: shape-0, shape-1, shape-4
      - Slide 'slide-999' not found in inventory
    
    ERROR: Replacement text made overflow worse in these shapes:
      - slide-0/shape-2: overflow worsened by 1.25" (was 0.00", now 1.25")
    

Creating Thumbnail Grids

To create visual thumbnail grids of PowerPoint slides for quick analysis and reference:

python scripts/thumbnail.py template.pptx [output_prefix]

Features:

  • Creates: thumbnails.jpg (or thumbnails-1.jpg, thumbnails-2.jpg, etc. for large decks)
  • Default: 5 columns, max 30 slides per grid (5×6)
  • Custom prefix: python scripts/thumbnail.py template.pptx my-grid
    • Note: The output prefix should include the path if you want output in a specific directory (e.g., workspace/my-grid)
  • Adjust columns: --cols 4 (range: 3-6, affects slides per grid)
  • Grid limits: 3 cols = 12 slides/grid, 4 cols = 20, 5 cols = 30, 6 cols = 42
  • Slides are zero-indexed (Slide 0, Slide 1, etc.)

Use cases:

  • Template analysis: Quickly understand slide layouts and design patterns
  • Content review: Visual overview of entire presentation
  • Navigation reference: Find specific slides by their visual appearance
  • Quality check: Verify all slides are properly formatted

Examples:

# Basic usage
python scripts/thumbnail.py presentation.pptx

# Combine options: custom name, columns
python scripts/thumbnail.py template.pptx analysis --cols 4

Converting Slides to Images

To visually analyze PowerPoint slides, convert them to images using a two-step process:

  1. Convert PPTX to PDF:

    soffice --headless --convert-to pdf template.pptx
    
  2. Convert PDF pages to JPEG images:

    pdftoppm -jpeg -r 150 template.pdf slide
    

    This creates files like slide-1.jpg, slide-2.jpg, etc.

Options:

  • -r 150: Sets resolution to 150 DPI (adjust for quality/size balance)
  • -jpeg: Output JPEG format (use -png for PNG if preferred)
  • -f N: First page to convert (e.g., -f 2 starts from page 2)
  • -l N: Last page to convert (e.g., -l 5 stops at page 5)
  • slide: Prefix for output files

Example for specific range:

pdftoppm -jpeg -r 150 -f 2 -l 5 template.pdf slide  # Converts only pages 2-5

Code Style Guidelines

IMPORTANT: When generating code for PPTX operations:

  • Write concise code
  • Avoid verbose variable names and redundant operations
  • Avoid unnecessary print statements

Dependencies

Required dependencies (should already be installed):

  • markitdown: pip install "markitdown[pptx]" (for text extraction from presentations)
  • pptxgenjs: npm install -g pptxgenjs (for creating presentations via html2pptx)
  • playwright: npm install -g playwright (for HTML rendering in html2pptx)
  • react-icons: npm install -g react-icons react react-dom (for icons)
  • sharp: npm install -g sharp (for SVG rasterization and image processing)
  • LibreOffice: sudo apt-get install libreoffice (for PDF conversion)
  • Poppler: sudo apt-get install poppler-utils (for pdftoppm to convert PDF to images)
  • defusedxml: pip install defusedxml (for secure XML parsing)
提供Remotion视频创作的最佳实践指南。涵盖动画、音频、图像、字体、3D内容、图表、字幕及DOM测量等规则,辅助开发者高效处理React环境下的视频生成与媒体资源管理。
需要实现Remotion动画效果 处理Remotion中的音视频资源导入 在Remotion中集成Three.js或Lottie 计算视频元数据或提取帧
SKILLs/remotion/SKILL.md
npx skills add freestylefly/wesight --skill remotion-best-practices -g -y
SKILL.md
Frontmatter
{
    "name": "remotion-best-practices",
    "metadata": {
        "tags": "remotion, video, react, animation, composition"
    },
    "official": true,
    "description": "Best practices for Remotion - Video creation in React"
}

When to use

Use this skills whenever you are dealing with Remotion code to obtain the domain-specific knowledge.

Captions

When dealing with captions or subtitles, load the ./rules/subtitles.md file for more information.

How to use

Read individual rule files for detailed explanations and code examples:

基于火山引擎Seedance模型生成AI视频,支持文本转视频、图片转视频及音画同步。通过Node.js脚本实现异步任务提交与状态轮询,需配置API Key并遵守配额限制。
用户希望根据文字描述生成视频 用户希望基于静态图片生成动态视频 用户需要进行音画同步的视频创作
SKILLs/seedance/SKILL.md
npx skills add freestylefly/wesight --skill seedance -g -y
SKILL.md
Frontmatter
{
    "name": "seedance",
    "version": "1.0.1",
    "official": true,
    "description": "Generate AI videos using Volcengine Seedance model. Supports text-to-video (T2V), image-to-video (I2V), and audio-synced video generation. Use this skill when the user wants to create or generate videos."
}

Seedance 视频生成

使用火山引擎 Seedance 模型生成高质量 AI 视频,支持文本生成视频(T2V)、图片生成视频(I2V)、音画同步等多种创作模式。

Node.js 版本:此脚本使用 Node.js 实现,无需 Python 环境。通过入口脚本自动检测 Node.js 运行时(优先使用系统 node,回退到 WeSight 内置运行时),Windows 和 Mac 用户都可以开箱即用。

配置

  • Base URL: https://ark.cn-beijing.volces.com/api/v3
  • API Key: 从环境变量 ARK_API_KEY 读取
  • 认证方式: Authorization: Bearer {API_KEY}
  • SDK: 兼容火山方舟 Python SDK

如何配置 API Key

方式一:通过环境变量配置(推荐)

在终端中设置环境变量:

# macOS/Linux
export ARK_API_KEY="你的API密钥"

# 或者添加到 ~/.zshrc 或 ~/.bashrc 以永久生效
echo 'export ARK_API_KEY="你的API密钥"' >> ~/.zshrc
source ~/.zshrc
# Windows PowerShell
$env:ARK_API_KEY="你的API密钥"

# 或者设置系统环境变量以永久生效
[System.Environment]::SetEnvironmentVariable('ARK_API_KEY', '你的API密钥', 'User')

方式二:通过 WeSight 启动时注入

WeSight 会自动读取系统环境变量,确保在启动 WeSight 前已设置 ARK_API_KEY

如何获取 API Key:

  1. 访问火山方舟控制台:https://console.volcengine.com/ark/region:ark+cn-beijing/apikey
  2. 创建新的 API Key
  3. 复制密钥并设置为环境变量

前置检查

无需安装任何依赖! 该脚本已兼容 Node.js 内置模块。

WeSight 已包含 Node.js 运行时,所有必要的依赖已被自动打包。Windows 和 Mac 用户无需额外配置。

工作流程

Seedance 视频生成是一个异步过程:

  1. 提交任务 - 调用 API 创建视频生成任务,获得 task_id
  2. 轮询状态 - 每隔几秒查询任务状态,直到状态变为 succeeded
  3. 下载视频 - 从 video_url 字段下载生成的 MP4 文件

配额和限制

免费额度

所有 Seedance 模型在 **default 模式(在线推理)**下提供:

  • 200万 token 免费额度
  • flex 模式(离线推理)无免费额度

注意:文档中未明确说明 200万 token 能生成多少个视频,消耗取决于视频时长、分辨率和是否使用图片/音频。建议先小批量测试。

限流限制

模型系列 RPM(每分钟请求数) 并发数 TPD(离线模式每日token)
Pro 系列 600 10 5000亿
Lite 系列 300 5 2500亿
  • RPM 限流:账号下同模型每分钟允许创建的任务数量上限
  • 并发数限制:同一时刻在处理中的任务数量上限
  • TPD 限流:flex 模式下一天内对同一模型的总调用 token 上限

视频保存时间

⚠️ 重要提醒

  • 任务数据(包括视频URL)仅保留 24 小时
  • 超时后会被自动清除
  • 务必及时下载保存生成的视频

使用示例

路径说明:下面的示例使用 $SKILLS_ROOT 环境变量来引用脚本路径。WeSight 会自动设置这个变量,指向实际的 SKILLs 目录位置,因此无需手动修改路径。

1. 文本生成视频(T2V)

根据文字描述生成视频,适合创意激发和概念验证。

bash "$SKILLS_ROOT/seedance/scripts/generate-video.sh" \
  --prompt "一只小猫在草地上玩耍,阳光明媚,镜头缓缓推进" \
  --duration 5 \
  --output generated_video.mp4

示例提示词:

  • "写实风格,晴朗的蓝天之下,一大片白色的雏菊花田,镜头逐渐拉近,最终定格在一朵雏菊花的特写上,花瓣上有几颗晶莹的露珠"
  • "一辆地铁轰隆隆驶过,书页飞扬,镜头开始环绕着女孩360度旋转"
  • "海边日落,海浪轻拍沙滩,宁静祥和的氛围"

2. 图片生成视频(I2V)- 首帧引导

基于首帧图片生成动态视频,支持本地图片和网络URL

# 使用本地图片
bash "$SKILLS_ROOT/seedance/scripts/generate-video.sh" \
  --prompt "女孩睁开眼,温柔地看向镜头,头发被风吹动" \
  --image "/Users/yourname/Pictures/girl.jpg" \
  --duration 5 \
  --output i2v_video.mp4

# 使用网络图片
bash "$SKILLS_ROOT/seedance/scripts/generate-video.sh" \
  --prompt "女孩睁开眼,温柔地看向镜头,头发被风吹动" \
  --image "https://example.com/first_frame.jpg" \
  --duration 5 \
  --output i2v_video.mp4

支持的图片来源:

  • ✅ 本地文件:/path/to/image.jpg
  • ✅ 网络URL:https://example.com/image.jpg
  • ✅ file://协议:file:///path/to/image.jpg

支持的图片格式:

  • jpg, jpeg, png, gif, webp, bmp, tiff, heic

3. 图片生成视频(I2V)- 首尾帧引导

提供首帧和尾帧,生成过渡动画。支持本地图片

bash "$SKILLS_ROOT/seedance/scripts/generate-video.sh" \
  --prompt "360度环绕运镜,流畅过渡" \
  --image "/Users/yourname/Pictures/first_frame.jpg" \
  --image "/Users/yourname/Pictures/last_frame.jpg" \
  --duration 5 \
  --output transition_video.mp4

4. 多参考图生成视频

融合多张参考图的特征生成视频。支持混合使用本地图片和网络图片

bash "$SKILLS_ROOT/seedance/scripts/generate-video.sh" \
  --prompt "[图1]戴着眼镜穿着蓝色T恤的男生和[图2]的柯基小狗,坐在[图3]的草坪上,视频卡通风格" \
  --image "/Users/yourname/Pictures/person.jpg" \
  --image "https://example.com/dog.jpg" \
  --image "/Users/yourname/Pictures/grass.jpg" \
  --model "doubao-seedance-1-0-lite-i2v-250428" \
  --duration 5 \
  --output multi_ref_video.mp4

5. 音画同步视频生成(仅 1.5 pro)

生成包含音频的视频(环境音、动作音、背景音乐等)。支持本地图片

bash "$SKILLS_ROOT/seedance/scripts/generate-video.sh" \
  --prompt "镜头围绕人物推镜头拉近,特写人物面部,她正在用京剧唱腔唱'月移花影,疑是玉人来',唱词充满情感" \
  --image "/Users/yourname/Pictures/actress.jpg" \
  --audio \
  --duration 5 \
  --model "doubao-seedance-1-5-pro-251215" \
  --output audio_video.mp4

参数说明

必需参数

参数 说明 示例
--prompt 视频描述提示词(必需) "小猫在玩耍"

可选参数

参数 说明 默认值 可选值
--image 参考图片路径或URL(可多次使用) 本地文件路径或URL
--model 模型ID doubao-seedance-1-5-pro-251215 见模型列表
--duration 视频时长(秒) 5 2-12(不同模型范围不同)
--ratio 宽高比 adaptive adaptive, 16:9, 9:16, 1:1
--audio 生成音频(仅1.5 pro支持) 标志参数
--no-watermark 不添加水印 标志参数
--output 输出文件路径 generated_video.mp4 文件路径
--poll-interval 状态查询间隔(秒) 5 1-10
--timeout 最大等待时间(秒) 300 60-600

模型选择

选择合适的模型以平衡质量、速度和成本:

Seedance 1.5 pro(推荐)

  • 模型ID: doubao-seedance-1-5-pro-251215
  • 特点: 音画同生,最高质量
  • 支持: 文生视频、图生视频、首尾帧、有声视频
  • 输出: 480p-1080p,24fps,4-12秒
  • 限流: RPM 600,并发10

Seedance 1.0 pro

  • 模型ID: doubao-seedance-1-0-pro-250528
  • 特点: 高质量标准版本
  • 支持: 文生视频、图生视频、首尾帧
  • 输出: 480p-1080p,24fps,2-12秒
  • 限流: RPM 600,并发10

Seedance 1.0 pro fast

  • 模型ID: doubao-seedance-1-0-pro-fast-251015
  • 特点: 快速生成,成本更低
  • 支持: 文生视频、图生视频
  • 输出: 480p-1080p,24fps,2-12秒
  • 限流: RPM 600,并发10

Seedance 1.0 lite(轻量版)

  • 文生视频: doubao-seedance-1-0-lite-t2v-250428
  • 图生视频: doubao-seedance-1-0-lite-i2v-250428
  • 特点: 更快速度,支持多参考图
  • 限流: RPM 300,并发5

Seedance 2.0(即将支持)

  • 模型ID: doubao-seedance-2-0-260128
  • 特点: 下一代视频生成模型,质量和性能全面提升
  • 可用性: ⏰ 预计 2026年2月24日18点 开放 API 调用
  • 当前状态: 仅在 控制台体验中心 可用

使用方式(2月24日后):

# 命令行方式
bash "$SKILLS_ROOT/seedance/scripts/generate-video.sh" \
  --prompt "你的提示词" \
  --model "doubao-seedance-2-0-260128" \
  --duration 5

或在 WeSight 对话中说:"用 Seedance 2.0 生成视频..."

推荐使用场景:

  • 追求最高质量 + 音画同步 → 1.5 pro
  • 标准高质量视频 → 1.0 pro
  • 快速生成预览 → 1.0 pro fast
  • 多参考图融合 → 1.0 lite
  • 下一代最新模型(2月24日后)→ 2.0

高级选项

自定义宽高比

根据使用场景选择合适的宽高比:

# 横屏视频(适合 YouTube、B站)
--ratio "16:9"

# 竖屏视频(适合抖音、快手)
--ratio "9:16"

# 正方形视频(适合 Instagram)
--ratio "1:1"

# 自适应(根据内容自动选择)
--ratio "adaptive"

自定义视频时长

不同模型支持的时长范围不同:

# 短视频(快速生成)
--duration 2

# 标准时长
--duration 5

# 长视频(内容更丰富)
--duration 10

注意:

  • Seedance 1.5 pro 支持 4-12 秒
  • Seedance 1.0 系列支持 2-12 秒
  • 时长越长,生成时间越久

去除水印

生成无水印视频(用于商业用途):

--no-watermark

轮询和超时控制

调整轮询策略以适应不同场景:

# 快速查询(适合短视频)
--poll-interval 3 --timeout 180

# 标准配置
--poll-interval 5 --timeout 300

# 耐心等待(适合长视频或高峰期)
--poll-interval 10 --timeout 600

状态说明

生成过程中可能出现的任务状态:

状态 说明 操作
queued 任务排队中 继续等待
running 正在生成视频 继续等待
succeeded 生成成功 下载视频
failed 生成失败 查看错误信息

错误处理

常见错误及解决方案

错误:未设置环境变量 ARK_API_KEY

  • 原因:未配置 API Key
  • 解决:按照"如何配置 API Key"部分的说明进行配置

错误:任务创建失败 (HTTP 401)

  • 原因:API Key 无效或已过期
  • 解决:检查 API Key 是否正确,或在控制台重新生成

错误:任务创建失败 (HTTP 400)

  • 原因:参数错误(如 duration 超出范围)
  • 解决:检查参数是否符合模型要求

错误:任务超时

  • 原因:生成时间过长或 API 繁忙
  • 解决:增加 --timeout 值,或稍后重试

错误:任务失败

  • 原因:内容违规、提示词不清晰、图片格式错误等
  • 解决:检查提示词内容,确保图片URL可访问

错误:限流 (HTTP 429)

  • 原因:超过 RPM 或并发限制
  • 解决:等待1分钟后重试,或升级配额

输出格式

生成的视频具有以下特征:

  • 格式: MP4
  • 编码: H.264
  • 分辨率: 480p / 720p / 1080p(根据模型自动选择)
  • 帧率: 24 fps
  • 音频: AAC(如果启用 --audio
  • 文件大小: 约 2-5 MB/秒(1080p)

提示词最佳实践

优秀提示词的特点

  1. 清晰的场景描述 - 说明环境、时间、氛围
  2. 具体的动作细节 - 描述物体或人物的具体动作
  3. 镜头运动 - 说明推拉摇移、特写等镜头语言
  4. 风格指定 - 写实、卡通、动漫等风格说明

提示词模板

[风格],[场景描述],[主体动作],[镜头运动],[氛围/情绪]

示例:

写实风格,海边日落,一只海鸥在空中盘旋,镜头从远处缓缓推进到海鸥特写,宁静祥和的氛围

提示词注意事项

  • ✅ 具体描述:"小猫追逐蝴蝶" 而非 "小猫玩耍"
  • ✅ 镜头语言:"镜头360度环绕" 而非 "旋转"
  • ✅ 情绪氛围:"温暖明亮的阳光" 而非 "好天气"
  • ❌ 避免模糊:过于抽象的描述会导致随机性增加
  • ❌ 避免过长:保持在 200 字以内效果最佳
  • ❌ 避免违规:不要包含暴力、色情等违规内容

常见使用场景

短视频创作

bash "$SKILLS_ROOT/seedance/scripts/generate-video.sh" \
  --prompt "产品展示:智能手表从不同角度旋转展示" \
  --ratio "9:16" \
  --duration 5

动画短片

bash "$SKILLS_ROOT/seedance/scripts/generate-video.sh" \
  --prompt "卡通风格,小兔子在森林里蹦蹦跳跳" \
  --ratio "16:9" \
  --duration 8 \
  --model "doubao-seedance-1-0-pro-250528"

社交媒体内容

bash "$SKILLS_ROOT/seedance/scripts/generate-video.sh" \
  --prompt "美食特写:热气腾腾的拉面,筷子夹起面条" \
  --ratio "1:1" \
  --duration 3

教学演示

bash "$SKILLS_ROOT/seedance/scripts/generate-video.sh" \
  --prompt "科普动画:地球自转,太阳光照射地球表面" \
  --ratio "16:9" \
  --duration 10

参考资料

  • API 参考:https://www.volcengine.com/docs/82379/1520758
  • 控制台:https://console.volcengine.com/ark
  • API Key 管理:https://console.volcengine.com/ark/region:ark+cn-beijing/apikey

技术支持

如遇到问题,可以:

  1. 查看脚本输出的错误信息
  2. 检查 API Key 配置是否正确
  3. 访问火山方舟控制台查看任务详情
  4. 参考官网文档了解更多细节
基于火山引擎Seedream模型的AI图片生成技能,支持文本转图、图像编辑、多图融合及联网搜索。通过Node.js脚本实现,无需Python环境,配置API Key后即可快速生成高质量图片。
用户希望根据文字描述生成AI图片 用户需要对现有图片进行编辑或修改 用户希望融合多张图片特征生成新图 用户需要创建或生成各种风格的视觉素材
SKILLs/seedream/SKILL.md
npx skills add freestylefly/wesight --skill seedream -g -y
SKILL.md
Frontmatter
{
    "name": "seedream",
    "version": "1.0.1",
    "official": true,
    "description": "Generate AI images using Volcengine Seedream model. Supports text-to-image (T2I), image editing (I2I), multi-image fusion, and web-search-based generation. Use this skill when the user wants to create, generate, or edit images."
}

Seedream 图片生成

使用火山引擎 Seedream 模型生成高质量 AI 图片,支持文本生成图片(T2I)、图片编辑(I2I)、多图融合、组图生成、联网搜索等多种创作模式。

Node.js 版本:此脚本使用 Node.js 实现,无需 Python 环境。通过入口脚本自动检测 Node.js 运行时(优先使用系统 node,回退到 WeSight 内置运行时),Windows 和 Mac 用户都可以开箱即用。

配置

  • Base URL: https://ark.cn-beijing.volces.com/api/v3
  • API Key: 从环境变量 ARK_API_KEY 读取
  • 认证方式: Authorization: Bearer {API_KEY}
  • SDK: 兼容火山方舟 Python SDK

快速开始

第一步:设置 API Key

# macOS / Linux - 当前终端临时生效(立即使用)
export ARK_API_KEY="你的API密钥"

# Windows PowerShell - 当前会话临时生效
$env:ARK_API_KEY="你的API密钥"

# 验证设置成功(macOS/Linux)
echo $ARK_API_KEY

# 验证设置成功(Windows)
echo $env:ARK_API_KEY

第二步:生成你的第一张图片

bash "$SKILLS_ROOT/seedream/scripts/generate-image.sh" \
  --prompt "一只可爱的橘色小猫"

如何配置 API Key

方式一:通过环境变量配置(推荐)

在终端中设置环境变量:

# macOS/Linux
export ARK_API_KEY="你的API密钥"

# 或者添加到 ~/.zshrc 或 ~/.bashrc 以永久生效
echo 'export ARK_API_KEY="你的API密钥"' >> ~/.zshrc
source ~/.zshrc
# Windows PowerShell
$env:ARK_API_KEY="你的API密钥"

# 或者设置系统环境变量以永久生效
[System.Environment]::SetEnvironmentVariable('ARK_API_KEY', '你的API密钥', 'User')

方式二:通过 WeSight 启动时注入

WeSight 会自动读取系统环境变量,确保在启动 WeSight 前已设置 ARK_API_KEY

如何获取 API Key:

  1. 访问火山方舟控制台:https://console.volcengine.com/ark/region:ark+cn-beijing/apikey
  2. 创建新的 API Key
  3. 复制密钥并设置为环境变量

前置检查

无需安装任何依赖! 该脚本已兼容 Node.js 内置模块。

WeSight 已包含 Node.js 运行时,所有必要的依赖已被自动打包。Windows 和 Mac 用户无需额外配置。

工作流程

Seedream 图片生成采用同步模式,流程简单高效:

  1. 提交请求 - 调用 API 提交图片生成请求
  2. 等待生成 - API 直接处理并生成图片(通常 30-60 秒)
  3. 下载图片 - 从返回的 URL 下载生成的图片文件

相比异步模式,同步模式更简单直接,无需轮询任务状态。

配额和限制

免费额度

所有 Seedream 模型提供免费额度,具体请参见火山方舟控制台。

限流限制

  • IPM(每分钟图片数): 500 张/分钟(Seedream 4.5, 4.0)
  • 不同模型的限流不同,请参见官方文档

图片保存时间

⚠️ 重要提醒

  • 任务数据(包括图片URL)仅保留 24 小时
  • 超时后会被自动清除
  • 务必及时下载保存生成的图片

使用示例

路径说明:下面的示例使用 $SKILLS_ROOT 环境变量来引用脚本路径。WeSight 会自动设置这个变量,指向实际的 SKILLs 目录位置,因此无需手动修改路径。

1. 文本生成图片(T2I)

根据文字描述生成图片,适合创意激发和概念设计。

bash "$SKILLS_ROOT/seedream/scripts/generate-image.sh" \
  --prompt "充满活力的特写编辑肖像,模特眼神犀利,头戴雕塑感帽子,色彩拼接丰富,景深较浅,Vogue杂志封面美学风格" \
  --output portrait.png

示例提示词:

  • "写实风格,晴朗的蓝天之下,一大片白色的雏菊花田,镜头逐渐拉近,最终定格在一朵雏菊花的特写上"
  • "卡通风格,一只橘色小猫坐在窗台上,阳光洒在身上,温暖治愈的氛围"
  • "赛博朋克风格,未来城市夜景,霓虹灯闪烁,高楼林立"

2. 图片编辑(I2I)- 单图输入

基于已有图片,结合文字指令进行图像编辑。支持本地图片和网络URL

# 使用本地图片
bash "$SKILLS_ROOT/seedream/scripts/generate-image.sh" \
  --prompt "保持模特姿势不变,将服装材质改为透明玻璃质感" \
  --image "/Users/yourname/Pictures/model.jpg" \
  --output edited_model.png

# 使用网络图片
bash "$SKILLS_ROOT/seedream/scripts/generate-image.sh" \
  --prompt "将背景改为海边日落场景" \
  --image "https://example.com/photo.jpg" \
  --output beach_sunset.png

支持的图片来源:

  • ✅ 本地文件:/path/to/image.jpg
  • ✅ 网络URL:https://example.com/image.jpg
  • ✅ file://协议:file:///path/to/image.jpg

支持的图片格式:

  • jpg, jpeg, png, gif, webp, bmp, tiff, heic

3. 多图融合(多图输入单图输出)

融合多张参考图的特征生成新图像。支持混合使用本地图片和网络图片

bash "$SKILLS_ROOT/seedream/scripts/generate-image.sh" \
  --prompt "将图1的服装换为图2的服装" \
  --image "/Users/yourname/Pictures/person.jpg" \
  --image "https://example.com/clothes.jpg" \
  --output fusion_result.png

常见使用场景:

  • 服装试穿:人物图 + 服装图 → 穿搭效果图
  • 风格迁移:照片 + 风格参考图 → 风格化作品
  • 场景融合:人物 + 背景 → 合成场景

4. 组图生成(多图输出)

生成一组内容关联的图片,适合漫画分镜、品牌视觉等。

文生组图

bash "$SKILLS_ROOT/seedream/scripts/generate-image.sh" \
  --prompt "生成一组共4张连贯插画,核心为同一庭院一角的四季变迁,以统一风格展现四季独特色彩、元素与氛围" \
  --sequential \
  --max-images 4 \
  --output seasons.png

输出文件会自动编号:seasons_1.png, seasons_2.png, seasons_3.png, seasons_4.png

单图生组图

bash "$SKILLS_ROOT/seedream/scripts/generate-image.sh" \
  --prompt "参考这个LOGO,做一套户外运动品牌视觉设计,品牌名称为'GREEN',包括包装袋、帽子、卡片、挂绳等" \
  --image "/Users/yourname/Pictures/logo.png" \
  --sequential \
  --max-images 4 \
  --output brand_design.png

5. 联网搜索增强生成(Seedream 5.0 lite)

启用实时网络搜索,融合最新网络信息。

bash "$SKILLS_ROOT/seedream/scripts/generate-image.sh" \
  --prompt "搜索下近期热门的白鸭子单手拿着风车形象,以极具冲击力的视角,设计成巨型装置" \
  --search \
  --output search_result.png

注意

  • 联网搜索功能仅限 Seedream 5.0 lite 模型
  • 使用 --search 参数会自动切换到 5.0 lite 模型
  • 适合需要融合实时信息的创作场景

参数说明

必需参数

参数 说明 示例
--prompt 图片描述提示词(必需) "一只可爱的小猫"

可选参数

参数 说明 默认值 可选值
--image 参考图片路径或URL(可多次使用) 本地文件路径或URL
--model 模型ID doubao-seedream-4-5-251128 见模型列表
--size 图片尺寸 2K 1K, 2K, 4K
--no-watermark 不添加水印 标志参数
--sequential 生成组图 标志参数
--max-images 组图数量 4 1-8
--search 启用联网搜索 标志参数
--output 输出文件路径 generated_image.png 文件路径
--poll-interval 状态查询间隔(秒) 5 1-10
--timeout 最大等待时间(秒) 300 60-600

模型选择

选择合适的模型以平衡质量、速度和成本:

Seedream 4.5(推荐)

  • 模型ID: doubao-seedream-4-5-251128
  • 特点: 最新版本,综合质量最佳
  • 支持: 文生图、图生图、多图融合、组图生成
  • 输出: 1K-4K分辨率可选
  • 限流: IPM 500

Seedream 4.0

  • 模型ID: doubao-seedream-4-0-250828
  • 特点: 成熟稳定版本
  • 支持: 文生图、图生图、多图融合、组图生成
  • 输出: 1K-4K分辨率可选
  • 限流: IPM 500

Seedream 5.0 lite(联网搜索专用)

  • 模型ID: doubao-seedream-5-0-260128
  • 特点: 支持联网搜索,融合实时网络信息
  • 使用: 通过 --search 参数自动启用
  • 注意: 2026年2月24日18点后正式开放 API

推荐使用场景:

  • 追求最高质量 → 4.5
  • 稳定生产环境 → 4.0
  • 需要实时信息 → 5.0 lite(使用 --search

高级选项

自定义图片尺寸

根据使用场景选择合适的尺寸:

# 小尺寸(快速预览)
--size "1K"

# 标准尺寸(推荐)
--size "2K"

# 高清晰度
--size "4K"

注意:

  • 尺寸越大,生成时间越长
  • 4K 图片可能需要 40-60 秒

去除水印

生成无水印图片(用于商业用途):

--no-watermark

轮询和超时控制

调整轮询策略以适应不同场景:

# 快速查询(适合小图)
--poll-interval 3 --timeout 180

# 标准配置
--poll-interval 5 --timeout 300

# 耐心等待(适合4K或组图)
--poll-interval 10 --timeout 600

状态说明

生成过程中可能出现的任务状态:

状态 说明 操作
queued 任务排队中 继续等待
running 正在生成图片 继续等待
succeeded 生成成功 下载图片
failed 生成失败 查看错误信息

错误处理

常见错误及解决方案

错误:未设置环境变量 ARK_API_KEY

  • 原因:未配置 API Key
  • 解决:按照"如何配置 API Key"部分的说明进行配置

错误:任务创建失败 (HTTP 401)

  • 原因:API Key 无效或已过期
  • 解决:检查 API Key 是否正确,或在控制台重新生成

错误:任务创建失败 (HTTP 400)

  • 原因:参数错误(如 size 不支持、prompt 为空等)
  • 解决:检查参数是否符合要求

错误:任务超时

  • 原因:生成时间过长或 API 繁忙
  • 解决:增加 --timeout 值,或稍后重试

错误:任务失败

  • 原因:内容违规、提示词不清晰、图片格式错误等
  • 解决:检查提示词内容,确保图片URL可访问

错误:限流 (HTTP 429)

  • 原因:超过 IPM 限制
  • 解决:等待1分钟后重试,或升级配额

错误:图片文件不存在

  • 原因:本地图片路径错误
  • 解决:检查文件路径是否正确,使用绝对路径

输出格式

生成的图片具有以下特征:

  • 格式: PNG, JPEG(根据output参数自动识别)
  • 分辨率: 1K / 2K / 4K(根据 size 参数)
  • 文件大小: 约 0.5-10 MB(取决于尺寸和复杂度)
  • 命名规则:
    • 单图:指定的文件名
    • 组图:文件名_1.png, 文件名_2.png, ...

提示词最佳实践

优秀提示词的特点

  1. 清晰的主体描述 - 说明画面的主要内容
  2. 具体的风格指定 - 写实、卡通、赛博朋克等
  3. 细节补充 - 色彩、光线、氛围等
  4. 构图说明 - 特写、全景、俯视等视角

提示词模板

[风格],[主体描述],[细节补充],[构图/氛围]

示例:

写实风格,一只橘色小猫坐在木制窗台上,阳光从左侧洒进来,温暖治愈的氛围,特写构图

提示词注意事项

  • ✅ 具体描述:"小猫在追逐蝴蝶" 而非 "小猫玩耍"
  • ✅ 风格说明:"赛博朋克风格" 而非 "好看的"
  • ✅ 细节丰富:"橘色长毛小猫,蓝色眼睛" 而非 "猫"
  • ❌ 避免模糊:过于抽象的描述会导致随机性增加
  • ❌ 避免过长:保持在 200 字以内效果最佳
  • ❌ 避免违规:不要包含暴力、色情等违规内容

常见使用场景

产品设计

bash "$SKILLS_ROOT/seedream/scripts/generate-image.sh" \
  --prompt "现代简约风格,智能手表产品展示,白色背景,工作室灯光" \
  --size "4K"

艺术创作

bash "$SKILLS_ROOT/seedream/scripts/generate-image.sh" \
  --prompt "超现实主义,漂浮的岛屿,瀑布从天而降,梦幻色彩" \
  --size "2K"

社交媒体内容

bash "$SKILLS_ROOT/seedream/scripts/generate-image.sh" \
  --prompt "美食特写,热气腾腾的拉面,筷子夹起面条,暖色调" \
  --size "2K"

品牌视觉设计

bash "$SKILLS_ROOT/seedream/scripts/generate-image.sh" \
  --prompt "参考logo,生成一套完整的品牌视觉系统,包括名片、海报、包装设计" \
  --image brand_logo.png \
  --sequential \
  --max-images 4

参考资料

  • API 参考:https://www.volcengine.com/docs/82379/1541523
  • 控制台:https://console.volcengine.com/ark
  • API Key 管理:https://console.volcengine.com/ark/region:ark+cn-beijing/apikey
  • 模型列表:https://www.volcengine.com/docs/82379/1330310

技术支持

如遇到问题,可以:

  1. 查看脚本输出的错误信息
  2. 检查 API Key 配置是否正确
  3. 访问火山方舟控制台查看任务详情
  4. 参考官网文档了解更多细节
用于创建新技能、修改优化现有技能及评估性能。支持从构思到测试的全流程迭代,包括编写草案、运行评测、分析结果并根据反馈调整,最终优化技能描述以提升触发准确率。
用户希望从零开始创建新的技能 需要更新或优化现有技能的描述与逻辑 运行评测以测试技能表现并进行基准分析 希望提高技能描述的触发准确性
SKILLs/skill-creator/SKILL.md
npx skills add freestylefly/wesight --skill skill-creator -g -y
SKILL.md
Frontmatter
{
    "name": "skill-creator",
    "version": "1.0.1",
    "official": true,
    "description": "Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, update or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy."
}

Skill Creator

A skill for creating new skills and iteratively improving them.

At a high level, the process of creating a skill goes like this:

  • Decide what you want the skill to do and roughly how it should do it
  • Write a draft of the skill
  • Create a few test prompts and run claude-with-access-to-the-skill on them
  • Help the user evaluate the results both qualitatively and quantitatively
    • While the runs happen in the background, draft some quantitative evals if there aren't any (if there are some, you can either use as is or modify if you feel something needs to change about them). Then explain them to the user (or if they already existed, explain the ones that already exist)
    • Use the eval-viewer/generate_review.py script to show the user the results for them to look at, and also let them look at the quantitative metrics
  • Rewrite the skill based on feedback from the user's evaluation of the results (and also if there are any glaring flaws that become apparent from the quantitative benchmarks)
  • Repeat until you're satisfied
  • Expand the test set and try again at larger scale

Your job when using this skill is to figure out where the user is in this process and then jump in and help them progress through these stages. So for instance, maybe they're like "I want to make a skill for X". You can help narrow down what they mean, write a draft, write the test cases, figure out how they want to evaluate, run all the prompts, and repeat.

On the other hand, maybe they already have a draft of the skill. In this case you can go straight to the eval/iterate part of the loop.

Of course, you should always be flexible and if the user is like "I don't need to run a bunch of evaluations, just vibe with me", you can do that instead.

Then after the skill is done (but again, the order is flexible), you can also run the skill description improver, which we have a whole separate script for, to optimize the triggering of the skill.

Cool? Cool.

Communicating with the user

The skill creator is liable to be used by people across a wide range of familiarity with coding jargon. If you haven't heard (and how could you, it's only very recently that it started), there's a trend now where the power of Claude is inspiring plumbers to open up their terminals, parents and grandparents to google "how to install npm". On the other hand, the bulk of users are probably fairly computer-literate.

So please pay attention to context cues to understand how to phrase your communication! In the default case, just to give you some idea:

  • "evaluation" and "benchmark" are borderline, but OK
  • for "JSON" and "assertion" you want to see serious cues from the user that they know what those things are before using them without explaining them

It's OK to briefly explain terms if you're in doubt, and feel free to clarify terms with a short definition if you're unsure if the user will get it.


Creating a skill

Capture Intent

Start by understanding the user's intent. The current conversation might already contain a workflow the user wants to capture (e.g., they say "turn this into a skill"). If so, extract answers from the conversation history first — the tools used, the sequence of steps, corrections the user made, input/output formats observed. The user may need to fill the gaps, and should confirm before proceeding to the next step.

  1. What should this skill enable Claude to do?
  2. When should this skill trigger? (what user phrases/contexts)
  3. What's the expected output format?
  4. Should we set up test cases to verify the skill works? Skills with objectively verifiable outputs (file transforms, data extraction, code generation, fixed workflow steps) benefit from test cases. Skills with subjective outputs (writing style, art) often don't need them. Suggest the appropriate default based on the skill type, but let the user decide.

Interview and Research

Proactively ask questions about edge cases, input/output formats, example files, success criteria, and dependencies. Wait to write test prompts until you've got this part ironed out.

Check available MCPs - if useful for research (searching docs, finding similar skills, looking up best practices), research in parallel via subagents if available, otherwise inline. Come prepared with context to reduce burden on the user.

Write the SKILL.md

Based on the user interview, fill in these components:

  • name: Skill identifier
  • description: When to trigger, what it does. This is the primary triggering mechanism - include both what the skill does AND specific contexts for when to use it. All "when to use" info goes here, not in the body. Note: currently Claude has a tendency to "undertrigger" skills -- to not use them when they'd be useful. To combat this, please make the skill descriptions a little bit "pushy". So for instance, instead of "How to build a simple fast dashboard to display internal Anthropic data.", you might write "How to build a simple fast dashboard to display internal Anthropic data. Make sure to use this skill whenever the user mentions dashboards, data visualization, internal metrics, or wants to display any kind of company data, even if they don't explicitly ask for a 'dashboard.'"
  • compatibility: Required tools, dependencies (optional, rarely needed)
  • the rest of the skill :)

Skill Writing Guide

Anatomy of a Skill

skill-name/
├── SKILL.md (required)
│   ├── YAML frontmatter (name, description required)
│   └── Markdown instructions
└── Bundled Resources (optional)
    ├── scripts/    - Executable code for deterministic/repetitive tasks
    ├── references/ - Docs loaded into context as needed
    └── assets/     - Files used in output (templates, icons, fonts)

Progressive Disclosure

Skills use a three-level loading system:

  1. Metadata (name + description) - Always in context (~100 words)
  2. SKILL.md body - In context whenever skill triggers (<500 lines ideal)
  3. Bundled resources - As needed (unlimited, scripts can execute without loading)

These word counts are approximate and you can feel free to go longer if needed.

Key patterns:

  • Keep SKILL.md under 500 lines; if you're approaching this limit, add an additional layer of hierarchy along with clear pointers about where the model using the skill should go next to follow up.
  • Reference files clearly from SKILL.md with guidance on when to read them
  • For large reference files (>300 lines), include a table of contents

Domain organization: When a skill supports multiple domains/frameworks, organize by variant:

cloud-deploy/
├── SKILL.md (workflow + selection)
└── references/
    ├── aws.md
    ├── gcp.md
    └── azure.md

Claude reads only the relevant reference file.

Principle of Lack of Surprise

This goes without saying, but skills must not contain malware, exploit code, or any content that could compromise system security. A skill's contents should not surprise the user in their intent if described. Don't go along with requests to create misleading skills or skills designed to facilitate unauthorized access, data exfiltration, or other malicious activities. Things like a "roleplay as an XYZ" are OK though.

Writing Patterns

Prefer using the imperative form in instructions.

Defining output formats - You can do it like this:

## Report structure
ALWAYS use this exact template:
# [Title]
## Executive summary
## Key findings
## Recommendations

Examples pattern - It's useful to include examples. You can format them like this (but if "Input" and "Output" are in the examples you might want to deviate a little):

## Commit message format
**Example 1:**
Input: Added user authentication with JWT tokens
Output: feat(auth): implement JWT-based authentication

Writing Style

Try to explain to the model why things are important in lieu of heavy-handed musty MUSTs. Use theory of mind and try to make the skill general and not super-narrow to specific examples. Start by writing a draft and then look at it with fresh eyes and improve it.

Test Cases

After writing the skill draft, come up with 2-3 realistic test prompts — the kind of thing a real user would actually say. Share them with the user: [you don't have to use this exact language] "Here are a few test cases I'd like to try. Do these look right, or do you want to add more?" Then run them.

Save test cases to evals/evals.json. Don't write assertions yet — just the prompts. You'll draft assertions in the next step while the runs are in progress.

{
  "skill_name": "example-skill",
  "evals": [
    {
      "id": 1,
      "prompt": "User's task prompt",
      "expected_output": "Description of expected result",
      "files": []
    }
  ]
}

See references/schemas.md for the full schema (including the assertions field, which you'll add later).

Running and evaluating test cases

This section is one continuous sequence — don't stop partway through. Do NOT use /skill-test or any other testing skill.

Put results in <skill-name>-workspace/ as a sibling to the skill directory. Within the workspace, organize results by iteration (iteration-1/, iteration-2/, etc.) and within that, each test case gets a directory (eval-0/, eval-1/, etc.). Don't create all of this upfront — just create directories as you go.

Step 1: Spawn all runs (with-skill AND baseline) in the same turn

For each test case, spawn two subagents in the same turn — one with the skill, one without. This is important: don't spawn the with-skill runs first and then come back for baselines later. Launch everything at once so it all finishes around the same time.

With-skill run:

Execute this task:
- Skill path: <path-to-skill>
- Task: <eval prompt>
- Input files: <eval files if any, or "none">
- Save outputs to: <workspace>/iteration-<N>/eval-<ID>/with_skill/outputs/
- Outputs to save: <what the user cares about — e.g., "the .docx file", "the final CSV">

Baseline run (same prompt, but the baseline depends on context):

  • Creating a new skill: no skill at all. Same prompt, no skill path, save to without_skill/outputs/.
  • Improving an existing skill: the old version. Before editing, snapshot the skill (cp -r <skill-path> <workspace>/skill-snapshot/), then point the baseline subagent at the snapshot. Save to old_skill/outputs/.

Write an eval_metadata.json for each test case (assertions can be empty for now). Give each eval a descriptive name based on what it's testing — not just "eval-0". Use this name for the directory too. If this iteration uses new or modified eval prompts, create these files for each new eval directory — don't assume they carry over from previous iterations.

{
  "eval_id": 0,
  "eval_name": "descriptive-name-here",
  "prompt": "The user's task prompt",
  "assertions": []
}

Step 2: While runs are in progress, draft assertions

Don't just wait for the runs to finish — you can use this time productively. Draft quantitative assertions for each test case and explain them to the user. If assertions already exist in evals/evals.json, review them and explain what they check.

Good assertions are objectively verifiable and have descriptive names — they should read clearly in the benchmark viewer so someone glancing at the results immediately understands what each one checks. Subjective skills (writing style, design quality) are better evaluated qualitatively — don't force assertions onto things that need human judgment.

Update the eval_metadata.json files and evals/evals.json with the assertions once drafted. Also explain to the user what they'll see in the viewer — both the qualitative outputs and the quantitative benchmark.

Step 3: As runs complete, capture timing data

When each subagent task completes, you receive a notification containing total_tokens and duration_ms. Save this data immediately to timing.json in the run directory:

{
  "total_tokens": 84852,
  "duration_ms": 23332,
  "total_duration_seconds": 23.3
}

This is the only opportunity to capture this data — it comes through the task notification and isn't persisted elsewhere. Process each notification as it arrives rather than trying to batch them.

Step 4: Grade, aggregate, and launch the viewer

Once all runs are done:

  1. Grade each run — spawn a grader subagent (or grade inline) that reads agents/grader.md and evaluates each assertion against the outputs. Save results to grading.json in each run directory. The grading.json expectations array must use the fields text, passed, and evidence (not name/met/details or other variants) — the viewer depends on these exact field names. For assertions that can be checked programmatically, write and run a script rather than eyeballing it — scripts are faster, more reliable, and can be reused across iterations.

  2. Aggregate into benchmark — run the aggregation script from the skill-creator directory:

    python -m scripts.aggregate_benchmark <workspace>/iteration-N --skill-name <name>
    

    This produces benchmark.json and benchmark.md with pass_rate, time, and tokens for each configuration, with mean ± stddev and the delta. If generating benchmark.json manually, see references/schemas.md for the exact schema the viewer expects. Put each with_skill version before its baseline counterpart.

  3. Do an analyst pass — read the benchmark data and surface patterns the aggregate stats might hide. See agents/analyzer.md (the "Analyzing Benchmark Results" section) for what to look for — things like assertions that always pass regardless of skill (non-discriminating), high-variance evals (possibly flaky), and time/token tradeoffs.

  4. Launch the viewer with both qualitative outputs and quantitative data:

    nohup python <skill-creator-path>/eval-viewer/generate_review.py \
      <workspace>/iteration-N \
      --skill-name "my-skill" \
      --benchmark <workspace>/iteration-N/benchmark.json \
      > /dev/null 2>&1 &
    VIEWER_PID=$!
    

    For iteration 2+, also pass --previous-workspace <workspace>/iteration-<N-1>.

    Cowork / headless environments: If webbrowser.open() is not available or the environment has no display, use --static <output_path> to write a standalone HTML file instead of starting a server. Feedback will be downloaded as a feedback.json file when the user clicks "Submit All Reviews". After download, copy feedback.json into the workspace directory for the next iteration to pick up.

Note: please use generate_review.py to create the viewer; there's no need to write custom HTML.

  1. Tell the user something like: "I've opened the results in your browser. There are two tabs — 'Outputs' lets you click through each test case and leave feedback, 'Benchmark' shows the quantitative comparison. When you're done, come back here and let me know."

What the user sees in the viewer

The "Outputs" tab shows one test case at a time:

  • Prompt: the task that was given
  • Output: the files the skill produced, rendered inline where possible
  • Previous Output (iteration 2+): collapsed section showing last iteration's output
  • Formal Grades (if grading was run): collapsed section showing assertion pass/fail
  • Feedback: a textbox that auto-saves as they type
  • Previous Feedback (iteration 2+): their comments from last time, shown below the textbox

The "Benchmark" tab shows the stats summary: pass rates, timing, and token usage for each configuration, with per-eval breakdowns and analyst observations.

Navigation is via prev/next buttons or arrow keys. When done, they click "Submit All Reviews" which saves all feedback to feedback.json.

Step 5: Read the feedback

When the user tells you they're done, read feedback.json:

{
  "reviews": [
    {"run_id": "eval-0-with_skill", "feedback": "the chart is missing axis labels", "timestamp": "..."},
    {"run_id": "eval-1-with_skill", "feedback": "", "timestamp": "..."},
    {"run_id": "eval-2-with_skill", "feedback": "perfect, love this", "timestamp": "..."}
  ],
  "status": "complete"
}

Empty feedback means the user thought it was fine. Focus your improvements on the test cases where the user had specific complaints.

Kill the viewer server when you're done with it:

kill $VIEWER_PID 2>/dev/null

Improving the skill

This is the heart of the loop. You've run the test cases, the user has reviewed the results, and now you need to make the skill better based on their feedback.

How to think about improvements

  1. Generalize from the feedback. The big picture thing that's happening here is that we're trying to create skills that can be used a million times (maybe literally, maybe even more who knows) across many different prompts. Here you and the user are iterating on only a few examples over and over again because it helps move faster. The user knows these examples in and out and it's quick for them to assess new outputs. But if the skill you and the user are codeveloping works only for those examples, it's useless. Rather than put in fiddly overfitty changes, or oppressively constrictive MUSTs, if there's some stubborn issue, you might try branching out and using different metaphors, or recommending different patterns of working. It's relatively cheap to try and maybe you'll land on something great.

  2. Keep the prompt lean. Remove things that aren't pulling their weight. Make sure to read the transcripts, not just the final outputs — if it looks like the skill is making the model waste a bunch of time doing things that are unproductive, you can try getting rid of the parts of the skill that are making it do that and seeing what happens.

  3. Explain the why. Try hard to explain the why behind everything you're asking the model to do. Today's LLMs are smart. They have good theory of mind and when given a good harness can go beyond rote instructions and really make things happen. Even if the feedback from the user is terse or frustrated, try to actually understand the task and why the user is writing what they wrote, and what they actually wrote, and then transmit this understanding into the instructions. If you find yourself writing ALWAYS or NEVER in all caps, or using super rigid structures, that's a yellow flag — if possible, reframe and explain the reasoning so that the model understands why the thing you're asking for is important. That's a more humane, powerful, and effective approach.

  4. Look for repeated work across test cases. Read the transcripts from the test runs and notice if the subagents all independently wrote similar helper scripts or took the same multi-step approach to something. If all 3 test cases resulted in the subagent writing a create_docx.py or a build_chart.py, that's a strong signal the skill should bundle that script. Write it once, put it in scripts/, and tell the skill to use it. This saves every future invocation from reinventing the wheel.

This task is pretty important (we are trying to create billions a year in economic value here!) and your thinking time is not the blocker; take your time and really mull things over. I'd suggest writing a draft revision and then looking at it anew and making improvements. Really do your best to get into the head of the user and understand what they want and need.

The iteration loop

After improving the skill:

  1. Apply your improvements to the skill
  2. Rerun all test cases into a new iteration-<N+1>/ directory, including baseline runs. If you're creating a new skill, the baseline is always without_skill (no skill) — that stays the same across iterations. If you're improving an existing skill, use your judgment on what makes sense as the baseline: the original version the user came in with, or the previous iteration.
  3. Launch the reviewer with --previous-workspace pointing at the previous iteration
  4. Wait for the user to review and tell you they're done
  5. Read the new feedback, improve again, repeat

Keep going until:

  • The user says they're happy
  • The feedback is all empty (everything looks good)
  • You're not making meaningful progress

Advanced: Blind comparison

For situations where you want a more rigorous comparison between two versions of a skill (e.g., the user asks "is the new version actually better?"), there's a blind comparison system. Read agents/comparator.md and agents/analyzer.md for the details. The basic idea is: give two outputs to an independent agent without telling it which is which, and let it judge quality. Then analyze why the winner won.

This is optional, requires subagents, and most users won't need it. The human review loop is usually sufficient.


Description Optimization

The description field in SKILL.md frontmatter is the primary mechanism that determines whether Claude invokes a skill. After creating or improving a skill, offer to optimize the description for better triggering accuracy.

Step 1: Generate trigger eval queries

Create 20 eval queries — a mix of should-trigger and should-not-trigger. Save as JSON:

[
  {"query": "the user prompt", "should_trigger": true},
  {"query": "another prompt", "should_trigger": false}
]

The queries must be realistic and something a Claude Code or Claude.ai user would actually type. Not abstract requests, but requests that are concrete and specific and have a good amount of detail. For instance, file paths, personal context about the user's job or situation, column names and values, company names, URLs. A little bit of backstory. Some might be in lowercase or contain abbreviations or typos or casual speech. Use a mix of different lengths, and focus on edge cases rather than making them clear-cut (the user will get a chance to sign off on them).

Bad: "Format this data", "Extract text from PDF", "Create a chart"

Good: "ok so my boss just sent me this xlsx file (its in my downloads, called something like 'Q4 sales final FINAL v2.xlsx') and she wants me to add a column that shows the profit margin as a percentage. The revenue is in column C and costs are in column D i think"

For the should-trigger queries (8-10), think about coverage. You want different phrasings of the same intent — some formal, some casual. Include cases where the user doesn't explicitly name the skill or file type but clearly needs it. Throw in some uncommon use cases and cases where this skill competes with another but should win.

For the should-not-trigger queries (8-10), the most valuable ones are the near-misses — queries that share keywords or concepts with the skill but actually need something different. Think adjacent domains, ambiguous phrasing where a naive keyword match would trigger but shouldn't, and cases where the query touches on something the skill does but in a context where another tool is more appropriate.

The key thing to avoid: don't make should-not-trigger queries obviously irrelevant. "Write a fibonacci function" as a negative test for a PDF skill is too easy — it doesn't test anything. The negative cases should be genuinely tricky.

Step 2: Review with user

Present the eval set to the user for review using the HTML template:

  1. Read the template from assets/eval_review.html
  2. Replace the placeholders:
    • __EVAL_DATA_PLACEHOLDER__ → the JSON array of eval items (no quotes around it — it's a JS variable assignment)
    • __SKILL_NAME_PLACEHOLDER__ → the skill's name
    • __SKILL_DESCRIPTION_PLACEHOLDER__ → the skill's current description
  3. Write to a temp file (e.g., /tmp/eval_review_<skill-name>.html) and open it: open /tmp/eval_review_<skill-name>.html
  4. The user can edit queries, toggle should-trigger, add/remove entries, then click "Export Eval Set"
  5. The file downloads to ~/Downloads/eval_set.json — check the Downloads folder for the most recent version in case there are multiple (e.g., eval_set (1).json)

This step matters — bad eval queries lead to bad descriptions.

Step 3: Run the optimization loop

Tell the user: "This will take some time — I'll run the optimization loop in the background and check on it periodically."

Save the eval set to the workspace, then run in the background:

python -m scripts.run_loop \
  --eval-set <path-to-trigger-eval.json> \
  --skill-path <path-to-skill> \
  --model <model-id-powering-this-session> \
  --max-iterations 5 \
  --verbose

Use the model ID from your system prompt (the one powering the current session) so the triggering test matches what the user actually experiences.

While it runs, periodically tail the output to give the user updates on which iteration it's on and what the scores look like.

This handles the full optimization loop automatically. It splits the eval set into 60% train and 40% held-out test, evaluates the current description (running each query 3 times to get a reliable trigger rate), then calls Claude with extended thinking to propose improvements based on what failed. It re-evaluates each new description on both train and test, iterating up to 5 times. When it's done, it opens an HTML report in the browser showing the results per iteration and returns JSON with best_description — selected by test score rather than train score to avoid overfitting.

How skill triggering works

Understanding the triggering mechanism helps design better eval queries. Skills appear in Claude's available_skills list with their name + description, and Claude decides whether to consult a skill based on that description. The important thing to know is that Claude only consults skills for tasks it can't easily handle on its own — simple, one-step queries like "read this PDF" may not trigger a skill even if the description matches perfectly, because Claude can handle them directly with basic tools. Complex, multi-step, or specialized queries reliably trigger skills when the description matches.

This means your eval queries should be substantive enough that Claude would actually benefit from consulting a skill. Simple queries like "read file X" are poor test cases — they won't trigger skills regardless of description quality.

Step 4: Apply the result

Take best_description from the JSON output and update the skill's SKILL.md frontmatter. Show the user before/after and report the scores.


Package and Present (only if present_files tool is available)

Check whether you have access to the present_files tool. If you don't, skip this step. If you do, package the skill and present the .skill file to the user:

python -m scripts.package_skill <path/to/skill-folder>

After packaging, direct the user to the resulting .skill file path so they can install it.


Claude.ai-specific instructions

In Claude.ai, the core workflow is the same (draft → test → review → improve → repeat), but because Claude.ai doesn't have subagents, some mechanics change. Here's what to adapt:

Running test cases: No subagents means no parallel execution. For each test case, read the skill's SKILL.md, then follow its instructions to accomplish the test prompt yourself. Do them one at a time. This is less rigorous than independent subagents (you wrote the skill and you're also running it, so you have full context), but it's a useful sanity check — and the human review step compensates. Skip the baseline runs — just use the skill to complete the task as requested.

Reviewing results: If you can't open a browser (e.g., Claude.ai's VM has no display, or you're on a remote server), skip the browser reviewer entirely. Instead, present results directly in the conversation. For each test case, show the prompt and the output. If the output is a file the user needs to see (like a .docx or .xlsx), save it to the filesystem and tell them where it is so they can download and inspect it. Ask for feedback inline: "How does this look? Anything you'd change?"

Benchmarking: Skip the quantitative benchmarking — it relies on baseline comparisons which aren't meaningful without subagents. Focus on qualitative feedback from the user.

The iteration loop: Same as before — improve the skill, rerun the test cases, ask for feedback — just without the browser reviewer in the middle. You can still organize results into iteration directories on the filesystem if you have one.

Description optimization: This section requires the claude CLI tool (specifically claude -p) which is only available in Claude Code. Skip it if you're on Claude.ai.

Blind comparison: Requires subagents. Skip it.

Packaging: The package_skill.py script works anywhere with Python and a filesystem. On Claude.ai, you can run it and the user can download the resulting .skill file.


Cowork-Specific Instructions

If you're in Cowork, the main things to know are:

  • You have subagents, so the main workflow (spawn test cases in parallel, run baselines, grade, etc.) all works. (However, if you run into severe problems with timeouts, it's OK to run the test prompts in series rather than parallel.)
  • You don't have a browser or display, so when generating the eval viewer, use --static <output_path> to write a standalone HTML file instead of starting a server. Then proffer a link that the user can click to open the HTML in their browser.
  • For whatever reason, the Cowork setup seems to disincline Claude from generating the eval viewer after running the tests, so just to reiterate: whether you're in Cowork or in Claude Code, after running tests, you should always generate the eval viewer for the human to look at examples before revising the skill yourself and trying to make corrections, using generate_review.py (not writing your own boutique html code). Sorry in advance but I'm gonna go all caps here: GENERATE THE EVAL VIEWER BEFORE evaluating inputs yourself. You want to get them in front of the human ASAP!
  • Feedback works differently: since there's no running server, the viewer's "Submit All Reviews" button will download feedback.json as a file. You can then read it from there (you may have to request access first).
  • Packaging works — package_skill.py just needs Python and a filesystem.
  • Description optimization (run_loop.py / run_eval.py) should work in Cowork just fine since it uses claude -p via subprocess, not a browser, but please save it until you've fully finished making the skill and the user agrees it's in good shape.

Reference files

The agents/ directory contains instructions for specialized subagents. Read them when you need to spawn the relevant subagent.

  • agents/grader.md — How to evaluate assertions against outputs
  • agents/comparator.md — How to do blind A/B comparison between two outputs
  • agents/analyzer.md — How to analyze why one version beat another

The references/ directory has additional documentation:

  • references/schemas.md — JSON structures for evals.json, grading.json, etc.

Repeating one more time the core loop here for emphasis:

  • Figure out what the skill is about
  • Draft or edit the skill
  • Run claude-with-access-to-the-skill on test prompts
  • With the user, evaluate the outputs:
    • Create benchmark.json and run eval-viewer/generate_review.py to help the user review them
    • Run quantitative evals
  • Repeat until you and the user are satisfied
  • Package the final skill and return it to the user.

Please add steps to your TodoList, if you have such a thing, to make sure you don't forget. If you're in Cowork, please specifically put "Create evals JSON and run eval-viewer/generate_review.py so human can review test cases" in your TodoList to make sure it happens.

Good luck!

用于在安装前对AI代理技能进行安全审查。检查来源信誉、代码中的恶意红牌标志及权限范围,评估风险等级并生成详细报告,防止安装恶意或高风险技能。
准备从ClawdHub或GitHub安装技能时 收到其他代理分享的技能时 被要求安装未知代码时
SKILLs/skill-vetter/SKILL.md
npx skills add freestylefly/wesight --skill skill-vetter -g -y
SKILL.md
Frontmatter
{
    "name": "skill-vetter",
    "version": "1.0.0",
    "description": "Security-first skill vetting for AI agents. Use before installing any skill from ClawdHub, GitHub, or other sources. Checks for red flags, permission scope, and suspicious patterns."
}

Skill Vetter 🔒

Security-first vetting protocol for AI agent skills. Never install a skill without vetting it first.

When to Use

  • Before installing any skill from ClawdHub
  • Before running skills from GitHub repos
  • When evaluating skills shared by other agents
  • Anytime you're asked to install unknown code

Vetting Protocol

Step 1: Source Check

Questions to answer:
- [ ] Where did this skill come from?
- [ ] Is the author known/reputable?
- [ ] How many downloads/stars does it have?
- [ ] When was it last updated?
- [ ] Are there reviews from other agents?

Step 2: Code Review (MANDATORY)

Read ALL files in the skill. Check for these RED FLAGS:

🚨 REJECT IMMEDIATELY IF YOU SEE:
─────────────────────────────────────────
• curl/wget to unknown URLs
• Sends data to external servers
• Requests credentials/tokens/API keys
• Reads ~/.ssh, ~/.aws, ~/.config without clear reason
• Accesses MEMORY.md, USER.md, SOUL.md, IDENTITY.md
• Uses base64 decode on anything
• Uses eval() or exec() with external input
• Modifies system files outside workspace
• Installs packages without listing them
• Network calls to IPs instead of domains
• Obfuscated code (compressed, encoded, minified)
• Requests elevated/sudo permissions
• Accesses browser cookies/sessions
• Touches credential files
─────────────────────────────────────────

Step 3: Permission Scope

Evaluate:
- [ ] What files does it need to read?
- [ ] What files does it need to write?
- [ ] What commands does it run?
- [ ] Does it need network access? To where?
- [ ] Is the scope minimal for its stated purpose?

Step 4: Risk Classification

Risk Level Examples Action
🟢 LOW Notes, weather, formatting Basic review, install OK
🟡 MEDIUM File ops, browser, APIs Full code review required
🔴 HIGH Credentials, trading, system Human approval required
⛔ EXTREME Security configs, root access Do NOT install

Output Format

After vetting, produce this report:

SKILL VETTING REPORT
═══════════════════════════════════════
Skill: [name]
Source: [ClawdHub / GitHub / other]
Author: [username]
Version: [version]
───────────────────────────────────────
METRICS:
• Downloads/Stars: [count]
• Last Updated: [date]
• Files Reviewed: [count]
───────────────────────────────────────
RED FLAGS: [None / List them]

PERMISSIONS NEEDED:
• Files: [list or "None"]
• Network: [list or "None"]  
• Commands: [list or "None"]
───────────────────────────────────────
RISK LEVEL: [🟢 LOW / 🟡 MEDIUM / 🔴 HIGH / ⛔ EXTREME]

VERDICT: [✅ SAFE TO INSTALL / ⚠️ INSTALL WITH CAUTION / ❌ DO NOT INSTALL]

NOTES: [Any observations]
═══════════════════════════════════════

Quick Vet Commands

For GitHub-hosted skills:

# Check repo stats
curl -s "https://api.github.com/repos/OWNER/REPO" | jq '{stars: .stargazers_count, forks: .forks_count, updated: .updated_at}'

# List skill files
curl -s "https://api.github.com/repos/OWNER/REPO/contents/skills/SKILL_NAME" | jq '.[].name'

# Fetch and review SKILL.md
curl -s "https://raw.githubusercontent.com/OWNER/REPO/main/skills/SKILL_NAME/SKILL.md"

Trust Hierarchy

  1. Official OpenClaw skills → Lower scrutiny (still review)
  2. High-star repos (1000+) → Moderate scrutiny
  3. Known authors → Moderate scrutiny
  4. New/unknown sources → Maximum scrutiny
  5. Skills requesting credentials → Human approval always

Remember

  • No skill is worth compromising security
  • When in doubt, don't install
  • Ask your human for high-risk decisions
  • Document what you vet for future reference

Paranoia is a feature. 🔒🦀

一站式股票深度分析工具,支持A股、美股及港股。整合实时行情、基本面、技术面及成长性数据,生成包含评分、交易策略和风险预警的专业投资报告。
用户请求股票深度分析或综合报告 用户询问特定股票的投资建议与风险评估
SKILLs/stock-analyzer/SKILL.md
npx skills add freestylefly/wesight --skill stock-analyzer -g -y
SKILL.md
Frontmatter
{
    "name": "stock-analyzer",
    "official": true,
    "description": "A comprehensive stock deep analysis tool that combines real-time quotes, fundamental metrics, technical indicators, and growth analysis into a single professional report. Supports A-share, US stocks, HK stocks. Generates detailed investment recommendations with risk assessment and actionable trading strategies."
}

Stock Deep Analyzer

One-stop comprehensive stock analysis tool that generates professional-grade investment reports.

Features

  • Real-time Market Data — Current price, volume, market cap, beta
  • Value Investing Metrics — P/E, P/B, ROE, ROA, dividend yield, payout ratio
  • Technical Indicators — MA5/20/60, RSI, MACD, Bollinger Bands, VWAP
  • Growth Analysis — Revenue growth, earnings growth, profit margins
  • Financial Health — Asset/liability ratio, liquidity ratio
  • Investment Rating — Multi-dimensional scoring (value 35% / technical 25% / growth 25% / financial 15%)
  • Trading Strategies — Long-term hold, swing trade, short-term speculation
  • Risk Assessment — Key risks and price levels

Dependencies

Python packages (install once):

pip install yfinance pandas numpy

Usage

IMPORTANT: Always use the $SKILLS_ROOT environment variable to locate scripts.

Basic Analysis

export PYTHONIOENCODING=utf-8
python "$SKILLS_ROOT/stock-analyzer/scripts/analyze.py" 601288.SS

Specify Analysis Period

export PYTHONIOENCODING=utf-8
python "$SKILLS_ROOT/stock-analyzer/scripts/analyze.py" 000001.SZ --period 1y

US Stocks

export PYTHONIOENCODING=utf-8
python "$SKILLS_ROOT/stock-analyzer/scripts/analyze.py" AAPL

Parameters

Parameter Description Example Default
ticker Stock ticker symbol (required) 601288.SS, AAPL -
--period Analysis period 1mo, 3mo, 6mo, 1y, 2y 6mo
--output Output format text, json text

Stock Ticker Formats

  • A-share (Shanghai): 600519.SS, 601288.SS
  • A-share (Shenzhen): 000001.SZ, 002594.SZ
  • US stocks: AAPL, TSLA, NVDA
  • HK stocks: 0700.HK, 9988.HK

Output Structure

The analysis report includes 8 sections:

  1. Real-time Market Overview
  2. Value Investing Indicators (Score /10)
  3. Technical Analysis (Score /10)
  4. Growth Indicators (Score /10)
  5. Financial Health (Score /10)
  6. Comprehensive Investment Rating (Overall /10)
  7. Recommended Trading Strategies
  8. Key Risk Warnings

Workflow

When user requests stock analysis:

  1. Identify ticker symbol

    • User may provide company name → use web-search to find ticker
    • A-share: Shanghai = .SS, Shenzhen = .SZ
  2. Execute analysis

    export PYTHONIOENCODING=utf-8
    python "$SKILLS_ROOT/stock-analyzer/scripts/analyze.py" <ticker>
    
  3. Interpret results

    • Extract overall rating and key findings
    • Highlight investment recommendation
    • Emphasize risk warnings
    • Provide actionable price levels

Limitations

  • Yahoo Finance data quality varies by market
  • Some metrics may be N/A for loss-making companies
  • Historical data limited for newly listed stocks
  • Real-time quotes may have 15-min delay

When to Use This Skill

  • User requests "深度分析", "complete analysis", "comprehensive report"
  • User wants multi-dimensional evaluation (value + growth + technical)
  • User needs actionable trading strategies
  • User asks for investment recommendations with risk assessment
基于AkShare获取A股上市公司官方公告,支持按代码、关键词筛选及PDF内容提取。适用于监控重大事件、业绩快报等投资决策场景,提供实时权威数据辅助分析。
查询特定公司公告 监控特定事件 投资决策辅助
SKILLs/stock-announcements/SKILL.md
npx skills add freestylefly/wesight --skill stock-announcements -g -y
SKILL.md
Frontmatter
{
    "name": "stock-announcements",
    "official": true,
    "description": "获取A股上市公司公告信息(真实数据)。基于AkShare从东方财富网获取当日全部公告,支持按股票代码筛选、关键词过滤。 适用于监控重大事件、业绩快报、股东变动、重组公告等投资决策关键信息。数据源:东方财富网(稳定可靠)。"
}

Stock Announcement Fetcher

获取A股上市公司的官方公告信息(真实数据),帮助投资者及时掌握重要信息披露。

真实数据保证

  • 数据来源: 东方财富网(通过AkShare开源库)
  • 更新频率: 实时(当日公告)
  • 覆盖范围: 全部A股上市公司
  • 数据质量: 官方权威数据

Dependencies

Python packages (install once):

pip install akshare pandas requests PyPDF2

When to Use This Skill

触发条件(用户提及以下任一场景时激活):

  1. 查询特定公司公告 — "查看五粮液最近的公告"、"002368有什么新公告?"
  2. 监控特定事件 — "哪些公司今天发布了业绩预告?"
  3. 投资决策辅助 — "公司有利好消息吗?"

Usage

IMPORTANT: Always use the $SKILLS_ROOT environment variable to locate scripts.

基础查询

export PYTHONIOENCODING=utf-8
python "$SKILLS_ROOT/stock-announcements/scripts/announcements.py" 000858

查询最近7天

export PYTHONIOENCODING=utf-8
python "$SKILLS_ROOT/stock-announcements/scripts/announcements.py" 600519 --days 7

关键词筛选

export PYTHONIOENCODING=utf-8
python "$SKILLS_ROOT/stock-announcements/scripts/announcements.py" 600519 --keyword 业绩

JSON格式输出

export PYTHONIOENCODING=utf-8
python "$SKILLS_ROOT/stock-announcements/scripts/announcements.py" 000858 --format json

提取PDF内容并总结

export PYTHONIOENCODING=utf-8
python "$SKILLS_ROOT/stock-announcements/scripts/announcements.py" 000858 --detail

Parameters

参数 说明 示例 默认值
stock_code 股票代码(必填) 000001, 600000.SS -
--days 最近N天 7 30
--format 输出格式 json/text text
--keyword 标题关键词筛选 业绩 None
--detail 提取PDF内容并总结 false

Workflow

Step 1: 识别股票代码

用户可能提供以下任一格式:

  • 公司名称:"五粮液" → 先用 web-search 查询股票代码
  • Yahoo Finance格式:"000858.SZ" → 提取纯数字代码
  • 纯代码:"000858" → 直接传递

Step 2: 执行查询

export PYTHONIOENCODING=utf-8
python "$SKILLS_ROOT/stock-announcements/scripts/announcements.py" <股票代码> [参数]

Step 3: 解读结果

Agent 应该:

  1. 提取关键信息(标题、类型、日期)
  2. 分类汇总(业绩类、股东类、重大合同等)
  3. 标注重要性(🔴高/🟡中/⚪低)
  4. 提供简洁解读

Limitations

  1. 只能查询当日公告 — AkShare 的 stock_notice_report 接口只返回指定日期的全部公告
  2. 查询速度约7-10秒 — 需遍历1000+条公告
  3. 中文显示乱码 — Windows PowerShell GBK编码问题,使用 --format json 可规避
基于yfinance的金融分析工具,获取实时行情、基本面摘要及ASCII趋势图。支持RSI/MACD等本地技术指标计算,提供专业分析报告与综合一键报告,覆盖美股、A股、港股及加密货币。
查询股票实时价格或基本面 生成股票技术分析报告 请求股票综合投资报告 查看股票历史走势
SKILLs/stock-explorer/SKILL.md
npx skills add freestylefly/wesight --skill stock-explorer -g -y
SKILL.md
Frontmatter
{
    "name": "stock-explorer",
    "official": true,
    "description": "A Yahoo Finance (yfinance) powered financial analysis tool. Get real-time quotes, generate technical indicator reports (RSI\/MACD\/Bollinger\/VWAP\/ATR), summarize fundamentals, and run a one-shot report that outputs a text summary."
}

Stock Information Explorer

This skill fetches OHLCV data from Yahoo Finance via yfinance and computes technical indicators locally (no API key required).

Dependencies

Python packages (install once):

pip install yfinance rich pandas plotille

Commands

IMPORTANT: Always use the $SKILLS_ROOT environment variable to locate scripts.

1) Real-time Quotes (price)

python "$SKILLS_ROOT/stock-explorer/scripts/quote.py" price TSLA
# shorthand
python "$SKILLS_ROOT/stock-explorer/scripts/quote.py" TSLA

2) Fundamental Summary (fundamentals)

python "$SKILLS_ROOT/stock-explorer/scripts/quote.py" fundamentals NVDA

3) ASCII Trend (history)

python "$SKILLS_ROOT/stock-explorer/scripts/quote.py" history AAPL 6mo

4) Professional Analysis (pro)

输出详细的技术指标文本分析报告。

# 基础分析(价格区间)
python "$SKILLS_ROOT/stock-explorer/scripts/quote.py" pro 002368.SZ 6mo

# 带技术指标
export PYTHONIOENCODING=utf-8
python "$SKILLS_ROOT/stock-explorer/scripts/quote.py" pro 002368.SZ 6mo --rsi --macd --bb

可用指标 (optional)

  • --rsi : RSI(14) - 超买超卖指标
  • --macd: MACD(12,26,9) - 趋势动量指标
  • --bb : Bollinger Bands(20,2) - 布林带
  • --vwap: VWAP - 成交量加权均价
  • --atr : ATR(14) - 平均真实波幅

5) One-shot Report (report)

输出综合分析报告(行情+基本面+技术信号)。

export PYTHONIOENCODING=utf-8
python "$SKILLS_ROOT/stock-explorer/scripts/quote.py" report 000660.KS 6mo

Ticker Examples

  • A-share: 600519.SS, 000001.SZ
  • US stocks: AAPL, NVDA, TSLA
  • HK stocks: 0700.HK, 9988.HK
  • Crypto: BTC-USD, ETH-KRW
  • Forex: USDKRW=X

Notes / Limitations

  • Indicators are computed locally from price data
  • Data quality may vary by ticker/market
  • 所有输出均为文本格式
  • Windows 环境中文显示需设置 export PYTHONIOENCODING=utf-8
获取当前天气和预报,无需API密钥。支持wttr.in(文本/PNG)和Open-Meteo(JSON),提供温度、湿度、风力等信息,适用于命令行查询或程序化调用。
查询某地当前天气状况 获取城市天气预报 需要免密钥的天气数据接口
SKILLs/weather/SKILL.md
npx skills add freestylefly/wesight --skill weather -g -y
SKILL.md
Frontmatter
{
    "name": "weather",
    "homepage": "https:\/\/wttr.in\/:help",
    "metadata": {
        "clawdbot": {
            "emoji": "🌤️",
            "requires": {
                "bins": [
                    "curl"
                ]
            }
        }
    },
    "official": true,
    "description": "Get current weather and forecasts (no API key required)."
}

Weather

Two free services, no API keys needed.

wttr.in (primary)

Quick one-liner:

curl -s "wttr.in/London?format=3"
# Output: London: ⛅️ +8°C

Compact format:

curl -s "wttr.in/London?format=%l:+%c+%t+%h+%w"
# Output: London: ⛅️ +8°C 71% ↙5km/h

Full forecast:

curl -s "wttr.in/London?T"

Format codes: %c condition · %t temp · %h humidity · %w wind · %l location · %m moon

Tips:

  • URL-encode spaces: wttr.in/New+York
  • Airport codes: wttr.in/JFK
  • Units: ?m (metric) ?u (USCS)
  • Today only: ?1 · Current only: ?0
  • PNG: curl -s "wttr.in/Berlin.png" -o /tmp/weather.png

Open-Meteo (fallback, JSON)

Free, no key, good for programmatic use:

curl -s "https://api.open-meteo.com/v1/forecast?latitude=51.5&longitude=-0.12&current_weather=true"

Find coordinates for a city, then query. Returns JSON with temp, windspeed, weathercode.

Docs: https://open-meteo.com/en/docs

用于Excel文件的创建、编辑与分析。支持公式处理、格式化、数据读取及可视化。涵盖从零错误构建模型、遵循金融配色与格式标准、规范公式编写及假设文档化,确保文件专业性与准确性。
用户需要创建新的电子表格 用户要求修改或更新现有Excel文件 用户请求分析Excel中的数据 涉及财务模型构建或公式重算
SKILLs/xlsx/SKILL.md
npx skills add freestylefly/wesight --skill xlsx -g -y
SKILL.md
Frontmatter
{
    "name": "xlsx",
    "license": "Proprietary. LICENSE.txt has complete terms",
    "official": true,
    "description": "Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas"
}

Requirements for Outputs

All Excel files

Zero Formula Errors

  • Every Excel model MUST be delivered with ZERO formula errors (#REF!, #DIV/0!, #VALUE!, #N/A, #NAME?)

Preserve Existing Templates (when updating templates)

  • Study and EXACTLY match existing format, style, and conventions when modifying files
  • Never impose standardized formatting on files with established patterns
  • Existing template conventions ALWAYS override these guidelines

Financial models

Color Coding Standards

Unless otherwise stated by the user or existing template

Industry-Standard Color Conventions

  • Blue text (RGB: 0,0,255): Hardcoded inputs, and numbers users will change for scenarios
  • Black text (RGB: 0,0,0): ALL formulas and calculations
  • Green text (RGB: 0,128,0): Links pulling from other worksheets within same workbook
  • Red text (RGB: 255,0,0): External links to other files
  • Yellow background (RGB: 255,255,0): Key assumptions needing attention or cells that need to be updated

Number Formatting Standards

Required Format Rules

  • Years: Format as text strings (e.g., "2024" not "2,024")
  • Currency: Use $#,##0 format; ALWAYS specify units in headers ("Revenue ($mm)")
  • Zeros: Use number formatting to make all zeros "-", including percentages (e.g., "$#,##0;($#,##0);-")
  • Percentages: Default to 0.0% format (one decimal)
  • Multiples: Format as 0.0x for valuation multiples (EV/EBITDA, P/E)
  • Negative numbers: Use parentheses (123) not minus -123

Formula Construction Rules

Assumptions Placement

  • Place ALL assumptions (growth rates, margins, multiples, etc.) in separate assumption cells
  • Use cell references instead of hardcoded values in formulas
  • Example: Use =B5*(1+$B$6) instead of =B5*1.05

Formula Error Prevention

  • Verify all cell references are correct
  • Check for off-by-one errors in ranges
  • Ensure consistent formulas across all projection periods
  • Test with edge cases (zero values, negative numbers)
  • Verify no unintended circular references

Documentation Requirements for Hardcodes

  • Comment or in cells beside (if end of table). Format: "Source: [System/Document], [Date], [Specific Reference], [URL if applicable]"
  • Examples:
    • "Source: Company 10-K, FY2024, Page 45, Revenue Note, [SEC EDGAR URL]"
    • "Source: Company 10-Q, Q2 2025, Exhibit 99.1, [SEC EDGAR URL]"
    • "Source: Bloomberg Terminal, 8/15/2025, AAPL US Equity"
    • "Source: FactSet, 8/20/2025, Consensus Estimates Screen"

XLSX creation, editing, and analysis

Overview

A user may ask you to create, edit, or analyze the contents of an .xlsx file. You have different tools and workflows available for different tasks.

Important Requirements

LibreOffice Required for Formula Recalculation: You can assume LibreOffice is installed for recalculating formula values using the recalc.py script. The script automatically configures LibreOffice on first run

Reading and analyzing data

Data analysis with pandas

For data analysis, visualization, and basic operations, use pandas which provides powerful data manipulation capabilities:

import pandas as pd

# Read Excel
df = pd.read_excel('file.xlsx')  # Default: first sheet
all_sheets = pd.read_excel('file.xlsx', sheet_name=None)  # All sheets as dict

# Analyze
df.head()      # Preview data
df.info()      # Column info
df.describe()  # Statistics

# Write Excel
df.to_excel('output.xlsx', index=False)

Excel File Workflows

CRITICAL: Use Formulas, Not Hardcoded Values

Always use Excel formulas instead of calculating values in Python and hardcoding them. This ensures the spreadsheet remains dynamic and updateable.

❌ WRONG - Hardcoding Calculated Values

# Bad: Calculating in Python and hardcoding result
total = df['Sales'].sum()
sheet['B10'] = total  # Hardcodes 5000

# Bad: Computing growth rate in Python
growth = (df.iloc[-1]['Revenue'] - df.iloc[0]['Revenue']) / df.iloc[0]['Revenue']
sheet['C5'] = growth  # Hardcodes 0.15

# Bad: Python calculation for average
avg = sum(values) / len(values)
sheet['D20'] = avg  # Hardcodes 42.5

✅ CORRECT - Using Excel Formulas

# Good: Let Excel calculate the sum
sheet['B10'] = '=SUM(B2:B9)'

# Good: Growth rate as Excel formula
sheet['C5'] = '=(C4-C2)/C2'

# Good: Average using Excel function
sheet['D20'] = '=AVERAGE(D2:D19)'

This applies to ALL calculations - totals, percentages, ratios, differences, etc. The spreadsheet should be able to recalculate when source data changes.

Common Workflow

  1. Choose tool: pandas for data, openpyxl for formulas/formatting
  2. Create/Load: Create new workbook or load existing file
  3. Modify: Add/edit data, formulas, and formatting
  4. Save: Write to file
  5. Recalculate formulas (MANDATORY IF USING FORMULAS): Use the recalc.py script
    python recalc.py output.xlsx
    
  6. Verify and fix any errors:
    • The script returns JSON with error details
    • If status is errors_found, check error_summary for specific error types and locations
    • Fix the identified errors and recalculate again
    • Common errors to fix:
      • #REF!: Invalid cell references
      • #DIV/0!: Division by zero
      • #VALUE!: Wrong data type in formula
      • #NAME?: Unrecognized formula name

Creating new Excel files

# Using openpyxl for formulas and formatting
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment

wb = Workbook()
sheet = wb.active

# Add data
sheet['A1'] = 'Hello'
sheet['B1'] = 'World'
sheet.append(['Row', 'of', 'data'])

# Add formula
sheet['B2'] = '=SUM(A1:A10)'

# Formatting
sheet['A1'].font = Font(bold=True, color='FF0000')
sheet['A1'].fill = PatternFill('solid', start_color='FFFF00')
sheet['A1'].alignment = Alignment(horizontal='center')

# Column width
sheet.column_dimensions['A'].width = 20

wb.save('output.xlsx')

Editing existing Excel files

# Using openpyxl to preserve formulas and formatting
from openpyxl import load_workbook

# Load existing file
wb = load_workbook('existing.xlsx')
sheet = wb.active  # or wb['SheetName'] for specific sheet

# Working with multiple sheets
for sheet_name in wb.sheetnames:
    sheet = wb[sheet_name]
    print(f"Sheet: {sheet_name}")

# Modify cells
sheet['A1'] = 'New Value'
sheet.insert_rows(2)  # Insert row at position 2
sheet.delete_cols(3)  # Delete column 3

# Add new sheet
new_sheet = wb.create_sheet('NewSheet')
new_sheet['A1'] = 'Data'

wb.save('modified.xlsx')

Recalculating formulas

Excel files created or modified by openpyxl contain formulas as strings but not calculated values. Use the provided recalc.py script to recalculate formulas:

python recalc.py <excel_file> [timeout_seconds]

Example:

python recalc.py output.xlsx 30

The script:

  • Automatically sets up LibreOffice macro on first run
  • Recalculates all formulas in all sheets
  • Scans ALL cells for Excel errors (#REF!, #DIV/0!, etc.)
  • Returns JSON with detailed error locations and counts
  • Works on both Linux and macOS

Formula Verification Checklist

Quick checks to ensure formulas work correctly:

Essential Verification

  • Test 2-3 sample references: Verify they pull correct values before building full model
  • Column mapping: Confirm Excel columns match (e.g., column 64 = BL, not BK)
  • Row offset: Remember Excel rows are 1-indexed (DataFrame row 5 = Excel row 6)

Common Pitfalls

  • NaN handling: Check for null values with pd.notna()
  • Far-right columns: FY data often in columns 50+
  • Multiple matches: Search all occurrences, not just first
  • Division by zero: Check denominators before using / in formulas (#DIV/0!)
  • Wrong references: Verify all cell references point to intended cells (#REF!)
  • Cross-sheet references: Use correct format (Sheet1!A1) for linking sheets

Formula Testing Strategy

  • Start small: Test formulas on 2-3 cells before applying broadly
  • Verify dependencies: Check all cells referenced in formulas exist
  • Test edge cases: Include zero, negative, and very large values

Interpreting recalc.py Output

The script returns JSON with error details:

{
  "status": "success",           // or "errors_found"
  "total_errors": 0,              // Total error count
  "total_formulas": 42,           // Number of formulas in file
  "error_summary": {              // Only present if errors found
    "#REF!": {
      "count": 2,
      "locations": ["Sheet1!B5", "Sheet1!C10"]
    }
  }
}

Best Practices

Library Selection

  • pandas: Best for data analysis, bulk operations, and simple data export
  • openpyxl: Best for complex formatting, formulas, and Excel-specific features

Working with openpyxl

  • Cell indices are 1-based (row=1, column=1 refers to cell A1)
  • Use data_only=True to read calculated values: load_workbook('file.xlsx', data_only=True)
  • Warning: If opened with data_only=True and saved, formulas are replaced with values and permanently lost
  • For large files: Use read_only=True for reading or write_only=True for writing
  • Formulas are preserved but not evaluated - use recalc.py to update values

Working with pandas

  • Specify data types to avoid inference issues: pd.read_excel('file.xlsx', dtype={'id': str})
  • For large files, read specific columns: pd.read_excel('file.xlsx', usecols=['A', 'C', 'E'])
  • Handle dates properly: pd.read_excel('file.xlsx', parse_dates=['date_column'])

Code Style Guidelines

IMPORTANT: When generating Python code for Excel operations:

  • Write minimal, concise Python code without unnecessary comments
  • Avoid verbose variable names and redundant operations
  • Avoid unnecessary print statements

For Excel files themselves:

  • Add comments to cells with complex formulas or important assumptions
  • Document data sources for hardcoded values
  • Include notes for key calculations and model sections
有道云笔记全能工具,支持笔记CRUD、待办管理及网页剪藏。Agent自动处理CLI安装与配置,强制使用save命令保存Markdown,遇格式内容需用户确认存储类型,确保数据完整与操作规范。
用户需要创建、搜索、浏览或读取有道云笔记 用户需要管理待办事项(创建、完成、分组) 用户需要进行网页剪藏操作
SKILLs/youdaonote/SKILL.md
npx skills add freestylefly/wesight --skill youdaonote -g -y
SKILL.md
Frontmatter
{
    "name": "youdaonote",
    "version": "1.0.0",
    "official": true,
    "description": "有道云笔记全能工具:笔记管理(创建、搜索、浏览、读取)、待办管理(创建、完成、分组)、网页剪藏(服务端抓取)。当用户需要操作有道云笔记时使用此 Skill。",
    "minCliVersion": "1.2.0"
}

YoudaoNote — 有道云笔记

通过 youdaonote CLI 操作有道云笔记。覆盖笔记 CRUD、待办管理、网页剪藏全场景。

前置条件(Agent 自动处理)

执行任何操作前,Agent 必须先运行 youdaonote list 检测 CLI 是否可用:

  • command not found → 立即跳转「CLI 未安装处理」自动安装,禁止只展示安装步骤让用户手动操作
  • API Key 错误 → 提示用户访问 https://mopen.163.com 获取 API Key(须使用手机号登录,且云笔记账号已绑定手机号),然后执行 youdaonote config set apiKey <用户提供的Key>获取 API Key 的地址只有这一个,禁止告知用户其他地址。
  • 正常返回目录列表 → 运行 youdaonote version,若版本低于 1.2.0,展示升级建议后继续执行;否则可运行 youdaonote help --json 获取当前 CLI 全部能力的结构化描述(JSON),用于确认命令是否可用,下方速查表作为 fallback

命令速查

命令 用途 示例
save 保存笔记(✅ 推荐,支持 Markdown 富文本) youdaonote save --file note.json
create 创建笔记(⚠️ 仅纯文本,不支持 Markdown 富文本) youdaonote create -n "标题" -c "内容" [-f <目录ID>]
update 更新 Markdown 笔记 youdaonote update <fileId> -c "内容"--file content.md
delete 删除笔记 youdaonote delete <fileId>
rename 重命名笔记 youdaonote rename <fileId> "新标题"
move 移动笔记 youdaonote move <fileId> <目录ID>
search 搜索笔记 youdaonote search "关键词"
list 浏览目录 youdaonote list -f <目录ID>
read 读取笔记 youdaonote read <fileId>
recent 最近收藏 youdaonote recent -l 20 -c --json
clip 网页剪藏(服务端) youdaonote clip "https://..." [-f <目录ID>] --json
clip-save 保存外部剪藏 JSON youdaonote clip-save --file data.json
todo list 列出待办 youdaonote todo list [--group <分组ID>] --json
todo create 创建待办 youdaonote todo create -t "标题" [-c "内容"] [-d 2025-12-31] [-g <分组ID>]
todo update 更新待办 youdaonote todo update <todoId> [--done] [--undone] [-t "新标题"]
todo delete 删除待办 youdaonote todo delete <todoId>
todo groups 列出待办分组 youdaonote todo groups --json
todo group-create 创建分组 youdaonote todo group-create "分组名"
todo group-rename 重命名分组 youdaonote todo group-rename <groupId> "新名"
todo group-delete 删除分组 youdaonote todo group-delete <groupId>
check 健康检查 youdaonote check
config show 查看配置 youdaonote config show --json
config set 设置配置 youdaonote config set apiKey YOUR_KEY

笔记管理

默认创建方式:所有笔记一律使用 save 命令 + contentFormat: "md" 保存为 Markdown 富文本。 禁止使用 create 命令保存包含 Markdown 格式的内容(标题、列表、代码块、表格等)—— create 仅支持纯文本,会静默丢失所有格式。HTML/结构化数据先转 Markdown 再用 save 保存。

Markdown 内容格式选择(必须遵守)

当用户要保存的内容包含以下任意 Markdown 特征时(# 标题、**粗体**`代码块、- 列表、> 引用、[链接](url)![图片](url)),必须先停下来询问用户,不得直接执行命令:

检测到内容包含 Markdown 格式,请选择保存方式:

A(推荐)保存为 Markdown 笔记(.md)
  → 格式完整保留,可在编辑器中正常显示和编辑

B  保存为有道专有格式(.note)
  → 支持有道云笔记富文本编辑器的全部功能

请回复 A 或 B:

收到用户选择后,按以下方式构造命令:

  • 选 Asave 命令,type: "md",文件名加 .md 后缀
    {"title":"标题.md","type":"md","content":"Markdown 内容"}
    
  • 选 Bsave 命令,type: "note"contentFormat: "md",文件名加 .note 后缀
    {"title":"标题.note","type":"note","contentFormat":"md","content":"Markdown 内容"}
    
  • 用户未明确选择(回复"随便"/"你决定"等):默认选 A

创建 / 保存

# ✅ 推荐:支持 Markdown 富文本(标题、列表、代码块等)
printf '%s\n' '{"title":"笔记","contentFormat":"md","content":"# 标题\n\n内容"}' | youdaonote save
# ✅ 大内容(>10KB)通过文件传递
youdaonote save --file note.json
# ⚠️ 仅纯文本,不支持 Markdown 格式,有格式需求时禁用
youdaonote create -n "标题" -c "纯文本内容"

其他操作

youdaonote search "关键词"
youdaonote list [-f <目录ID>]            # 浏览目录,id 可传给 read
youdaonote read <fileId>                 # 返回 JSON 含 content、rawFormat(md/note/txt)和 isRaw(是否原始内容)
youdaonote recent -l 20 -c --json       # 最近收藏
youdaonote update <fileId> -c "新内容"
youdaonote update <fileId> --file content.md  # 大内容(>10KB)从文件读取
youdaonote delete <fileId>
youdaonote rename <fileId> "新标题"
youdaonote move <fileId> <目录ID>

网页剪藏

youdaonote clip "https://example.com/article" --json
youdaonote clip "https://example.com/article" -f <目录ID> --json  # 保存到指定目录

CLI 未安装处理(Agent 必须自动执行)

收到 command not found 时,Agent 立即执行安装命令,禁止只展示步骤让用户操作。

macOS / Linux / WSL

curl -fsSL https://artifact.lx.netease.com/download/youdaonote-cli/install.sh | bash -s -- -f -b ~/.local/bin
export PATH="$HOME/.local/bin:$PATH"
# 安装后立即重新执行用户原始请求

Windows(CMD/PowerShell):不支持一键安装,告知用户下载预编译包:

  • x64:https://artifact.lx.netease.com/download/youdaonote-cli/youdaonote-cli-windows-x64.tar.gz
  • ARM64:https://artifact.lx.netease.com/download/youdaonote-cli/youdaonote-cli-windows-arm64.tar.gz

故障排查

运行 youdaonote check --json,根据 status: "fail" 的项执行:

失败项 处理动作
config-file / api-key youdaonote config set apiKey YOUR_KEY
mcp-connection API Key 有效但网络不通,提示用户检查网络或稍后重试

注意事项

  • 所有命令支持 --json 输出机器可解析格式
  • 大内容通过 --file 传递,避免命令行参数限制
  • Windows CMD 中 URL 含 & 时必须用双引号括起
  • list 输出的 idreadfileId 等价
  • read 返回的 rawFormat 标识笔记原始格式:md=Markdown、note=云笔记、txt=纯文本;isRaw 标识返回的 content 是否为原始内容(true=原文可直接编辑,false=经过转换的纯文本)
  • 禁止用 create 保存 Markdown 内容create 不支持 contentFormat,即使内容含 Markdown 语法也会存为纯文本静默丢失格式,有格式需求时一律使用 save 并指定 contentFormat: "md"

Главная - Вики-сайт
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-08 20:25
浙ICP备14020137号-1 $Гость$