@clawhub-bird-frank-859173f322
Expert guidance for querying, writing, and managing emails using the `himalaya` CLI. Use this skill whenever the user wants to list emails, search envelopes,...
--- name: himalaya description: | Expert guidance for querying, writing, and managing emails using the `himalaya` CLI. Use this skill whenever the user wants to list emails, search envelopes, compose messages, manage flags/folders, or execute any himalaya command. Also trigger when the user mentions "email CLI", "terminal email", "manage emails from command line", or references the Himalaya mail client. This skill provides the full query DSL specification, command patterns, and best practices for the himalaya email CLI. --- # Himalaya CLI Expert This skill makes you an instant expert on the [Himalaya](https://github.com/pimalaya/himalaya) command-line email client. Himalaya is a stateless CLI (not a TUI) that lets users manage emails via shell commands. ## When this skill applies Use this skill for ANY task involving: - Listing, searching, or sorting emails (`himalaya envelope list|thread`) - Reading, writing, replying to, or forwarding messages (`himalaya message ...`) - Managing flags (`himalaya flag ...`) - Managing folders/mailboxes (`himalaya folder ...`) - Message templates and attachments (`himalaya template ...`, `himalaya attachment ...`) - Interpreting or constructing Himalaya query DSL strings ## Architecture overview Himalaya CLI is organized around nouns: ``` himalaya <noun> <verb> [args...] ``` Key nouns: - `envelope` (aliases: `envelopes`) — email envelopes (metadata, no body) - `message` (aliases: `msg`, `msgs`, `messages`) — full email messages - `flag` (aliases: `flags`) — message flags (seen, answered, flagged, deleted…) - `folder` (aliases: `folders`, `mailbox`, `mailboxes`, `mbox`, `mboxes`) — mailboxes - `template` (aliases: `tpl`, `tpls`, `templates`) — message templates - `attachment` (aliases: `attachments`) — message attachments - `account` (aliases: `accounts`) — account configuration Global flags (available on all commands): - `--config <PATH>` — override config file path - `--output json` / `--output plain` — choose output format - `--quiet`, `--debug`, `--trace` — logging levels Common per-command flags: - `-a <NAME>` / `--account <NAME>` — target a specific configured account - `-f <NAME>` / `--folder <NAME>` — target a specific folder ## Querying emails: envelope commands The most common operation is listing envelopes. Read the full Query DSL reference (`references/query_dsl.md`) **whenever the user asks anything about search, filter, sort, or list queries**. ### Essential commands ```bash # List all envelopes in the default folder himalaya envelope list # List envelopes in a specific folder, page 2, 20 per page himalaya envelope list -f Archives.FOSS --page 2 --page-size 20 # Thread view for envelopes matching a query himalaya envelope thread subject "product requirement" ``` ### Query DSL quick reference A query string has the form: ``` [filter-query] [order by sort-query] ``` **Filter conditions:** - `date <yyyy-mm-dd>` — exact date match - `before <yyyy-mm-dd>` — strictly before date - `after <yyyy-mm-dd>` — strictly after date - `from <pattern>` — sender pattern match - `to <pattern>` — recipient pattern match - `subject <pattern>` — subject pattern match - `body <pattern>` — body text match (slower) - `flag <flag>` — flag match (e.g., `seen`, `deleted`) **Operators (precedence: `not` > `and` > `or`):** - `not <condition>` - `<condition> and <condition>` - `<condition> or <condition>` **Sort query:** - `order by date [asc|desc]` - `order by from [asc|desc]` - `order by to [asc|desc]` - `order by subject [asc|desc]` - Multiple fields are allowed: `order by from asc date desc` **Quoting and escaping:** - Use double quotes for values containing spaces: `subject "meeting notes"` - Or escape with backslash: `subject meeting\ notes` - In shell, the entire query may need to be passed as a single string or joined args. ### Query examples (detailed) ```bash # Unread emails, newest first himalaya envelope list "not flag seen order by date desc" # From boss or CEO, sorted by date desc himalaya envelope list "from [email protected] or from [email protected] order by date desc" # Subject contains "周报" AND body contains "进度" himalaya envelope list "subject 周报 and body 进度" # Date range: after March 31 and before April 11, 2025 himalaya envelope list "after 2025-03-31 and before 2025-04-11" # Complex grouped condition: (subject urgent OR body error) AND from ops himalaya envelope list '(subject 紧急 or body 报错) and from [email protected]' # Specific folder + pagination + query himalaya envelope list -f INBOX --page 2 --page-size 20 'subject "release plan" order by date desc' ``` > **Performance tip**: Prefer `from`, `to`, `subject` over `body` because `body` triggers a > server-side full-text scan. > **Reference**: For the complete Query DSL specification, IMAP mapping, and compatibility > notes, read `references/query_dsl.md`. ## Writing and sending emails: message commands ### Composing a new message Himalaya uses your `$EDITOR` to compose messages from a template. ```bash # Compose a new message interactively himalaya message write # Pre-fill headers via CLI arguments himalaya message write --to "[email protected]" --subject "Sprint review" # Compose using a saved template himalaya message write --template /path/to/template.eml ``` ### Reply and forward ```bash # Reply to message ID 42 himalaya message reply 42 # Reply-all himalaya message reply 42 --all # Forward message ID 42 himalaya message forward 42 --to "[email protected]" ``` ### Reading, saving, and exporting ```bash # Read raw message content himalaya message read 42 # Save message to local .eml file himalaya message save 42 --path ./message42.eml # Export message(s) himalaya message export 42 --path ./exports/ ``` ### Message template format A template is a set of headers followed by a blank line and then the body: ```eml From: [email protected] To: Bob <[email protected]> Subject: Hello from Himalaya Hello, world! ``` Valid headers include: `From`, `To`, `Cc`, `Bcc`, `Reply-To`, `Subject`, `Date`, `Message-ID`, `In-Reply-To`. Addresses can be: - Plain: `user@domain` - Named: `Name <user@domain>` - Quoted named: `"Name" <user@domain>` - Multiple addresses separated by commas. ### Attachments Attachments are handled via the `attachment` noun or MML syntax in templates. ```bash # Download attachments from message 42 himalaya attachment download 42 --path ./downloads/ ``` MML attachment example inside a template body: ```eml From: [email protected] To: [email protected] Subject: Attaching a doc <#part filename=/path/to/file.pdf><#/part> ``` ## Managing emails: flags and folders ### Flags ```bash # Add flag(s) to envelope(s) himalaya flag add 42,43 flagged answered # Remove flag(s) himalaya flag remove 42 flagged # Set exact flags (replaces existing) himalaya flag set 42 seen ``` Common flags: `seen`, `answered`, `flagged`, `deleted`, `draft`. ### Folders ```bash # List folders himalaya folder list # Add a folder himalaya folder add MyFolder # Delete a folder himalaya folder delete MyFolder # Purge deleted messages from a folder himalaya folder purge MyFolder # Expunge a folder himalaya folder expunge MyFolder ``` ## Multi-account workflows Himalaya supports multiple accounts via TOML config. Target a non-default account with `-a`: ```bash himalaya envelope list -a work -f INBOX himalaya message write -a personal --to "[email protected]" ``` ## Output format tips - Use `--output json` when you need structured data for piping into `jq` or scripts. - Use `--output plain` (default) for human-readable tables and text. ## Common gotchas 1. **Trailing query args**: `himalaya envelope list` accepts the query as trailing arguments. Shell escaping matters. If the query has spaces, quote the entire query string. 2. **Page numbering**: `--page` starts at 1 (not 0). 3. **Date boundaries**: `before 2025-04-01` excludes April 1; `after 2025-04-01` also excludes April 1 (Himalaya adjusts internally by adding a day to use `SENTSINCE`). 4. **Config location**: Default is `~/.config/himalaya/config.toml`. Run `himalaya account configure <name>` for the wizard. ## External resources - Repository: https://github.com/pimalaya/himalaya - Query DSL reference (bundled): `references/query_dsl.md` FILE:references/query_dsl.md # Himalaya 邮件查询使用指南 ## 概述 Himalaya 的 `envelope list` 和 `envelope thread` 命令支持一套专门设计的查询 DSL(领域特定语言),用于**筛选**和**排序**邮件。你的查询字符串会被 Himalaya 解析成 AST,最终转换为 IMAP `SEARCH` / `SORT` 命令发送给邮件服务器。 > **注意**:Himalaya 的查询语法是高层封装,并非直接使用 IMAP 原始关键字,但底层会映射为 IMAP 搜索条件。 --- ## 查询语法结构 一条完整查询由 **过滤条件** 和 **排序条件** 组成,两者可选: ``` [filter-query] [order by sort-query] ``` - `filter-query`:指定筛选条件(可选) - `sort-query`:指定排序规则(可选) - 若两者同时存在,**过滤条件必须写在 `order by` 前面** --- ## 过滤条件语法 ### 基本形式 过滤条件由**条件**和**运算符**组合而成,支持使用括号 `()` 改变优先级。 ### 可用的条件 | Himalaya 语法 | 含义 | 对应 IMAP 搜索键 | 示例 | |--------------|------|-----------------|------| | `date <yyyy-mm-dd>` | 日期精确匹配 | `SENTON` | `date 2025-04-12` | | `before <yyyy-mm-dd>` | 日期严格小于 | `SENTBEFORE` | `before 2025-04-01` | | `after <yyyy-mm-dd>` | 日期严格大于 | `SENTSINCE` (+1天) | `after 2025-04-01` | | `from <pattern>` | 发件人匹配 | `FROM` | `from [email protected]` | | `to <pattern>` | 收件人匹配 | `TO` | `to [email protected]` | | `subject <pattern>` | 主题匹配 | `SUBJECT` | `subject "会议通知"` | | `body <pattern>` | 正文内容匹配 | `BODY` | `body 项目进度` | | `flag <flag>` | 邮件标志匹配 | 对应状态标志 | `flag seen` | ### 可用的运算符 | 运算符 | 优先级 | 含义 | 示例 | |--------|--------|------|------| | `not` | 最高 | 取反 | `not from [email protected]` | | `and` | 中 | 两者都必须满足 | `from boss and subject 周报` | | `or` | 最低 | 满足其一即可 | `from alice or from bob` | **优先级规则**:`not` > `and` > `or`,复杂查询建议用括号明确优先级。 ### 模式匹配中的空格与引号 - **引号**:用双引号包裹含空格的字符串,如 `subject "foo bar"` - **转义**:无引号模式下可用反斜杠转义空格和括号,如 `subject foo\ bar` - 引号内可转义 `\"` 和 `\\` --- ## 排序条件语法 使用关键字 `order by` 开头,后跟一个或多个排序字段,每个字段可指定 `asc` 或 `desc`。 ### 可用的排序字段 | 字段 | 排序依据 | |------|---------| | `date` | 邮件日期 | | `from` | 发件人 | | `to` | 收件人 | | `subject` | 主题 | ### 默认顺序 - 不指定时默认为 **升序** (`asc`) - 多字段排序时按声明顺序依次应用 --- ## 组合查询示例 ### 纯过滤 ```bash # 主题包含"周报"且正文包含"进度" himalaya envelope list subject 周报 and body 进度 # 来自老板或 CEO 的邮件 himalaya envelope list from [email protected] or from [email protected] # 不是已删除的邮件(假设服务器支持相关标志) himalaya envelope list not flag deleted ``` ### 纯排序 ```bash # 按日期降序排列(最新的在前) himalaya envelope list order by date desc # 先按发件人升序,再按主题降序 himalaya envelope list order by from asc subject desc ``` ### 过滤 + 排序 ```bash # 查找未读邮件,按日期降序排列 himalaya envelope list not flag seen order by date desc # 查找4月以来的重要邮件,先按发件人排序再按日期排序 himalaya envelope list after 2025-04-01 and subject 重要 order by from date desc ``` --- ## 常见场景命令示例 ### 1. 查看未读邮件 ```bash himalaya envelope list not flag seen himalaya envelope list not flag seen order by date desc ``` ### 2. 查看来自特定发件人的邮件 ```bash himaya envelope list from [email protected] himalaya envelope list from [email protected] order by date desc ``` ### 3. 按日期范围查找 ```bash # 2025年4月1日至4月10日(before 不包含边界) himalaya envelope list after 2025-03-31 and before 2025-04-11 # 2025年4月12日当天的邮件 himalaya envelope list date 2025-04-12 ``` ### 4. 主题搜索 ```bash # 简单关键词 himalaya envelope list subject 项目 # 带空格的短语 himalaya envelope list subject "会议通知" # 转义空格(等效写法) himalaya envelope list subject 会议\ 通知 ``` ### 5. 复杂组合查询 ```bash # (主题含"紧急"或正文含"报错")且来自运维组 himalaya envelope list "(subject 紧急 or body 报错) and from [email protected]" # 来自老板且不是已读的 himalaya envelope list from [email protected] and not flag seen ``` ### 6. 分页浏览 ```bash # 每页 20 封,浏览第 2 页 himalaya envelope list --page 2 --page-size 20 subject 周报 order by date desc ``` ### 7. 指定文件夹查询 ```bash # 在 Archives.FOSS 文件夹中查找 himalaya envelope list --folder Archives.FOSS from kernel.org ``` ### 8. 线程视图 ```bash # 以线程形式查看包含某查询的邮件 himalaya envelope thread subject "产品需求" ``` --- ## Himalaya DSL 到 IMAP 的映射速查 了解映射关系有助于理解服务器侧实际执行的搜索行为: | Himalaya DSL | IMAP SEARCH 键 | 备注 | |-------------|----------------|------| | `date D` | `SENTON D` | 精确匹配发送日期 | | `before D` | `SENTBEFORE D` | 不包含边界日 | | `after D` | `SENTSINCE (D+1)` | 为排除边界,Himalaya 会替你加一天 | | `from P` | `FROM P` | 模糊匹配发件人 | | `to P` | `TO P` | 模糊匹配收件人 | | `subject P` | `SUBJECT P` | 模糊匹配主题 | | `body P` | `BODY P` | 搜索正文,性能较低 | | `flag F` | 对应状态键 | 如 `flag seen` → `SEEN` | | `and` | 隐式 `AND`(多个 `SearchKey::And`) | 两者都必须满足 | | `or` | `OR` | 满足其一 | | `not` | `NOT` | 取反 | | `order by date desc` | `SortCriterion { reverse: true, key: Date }` | 需要服务器支持 `SORT` 扩展 | --- ## 性能与兼容性提示 1. **优先使用头部字段搜索**:`from`、`to`、`subject` 比 `body` 搜索速度快得多 2. **避免频繁全文搜索**:`body` 会触发服务器全文扫描,大量邮件时较慢 3. **排序依赖服务器能力**: - 若服务器支持 `SORT` 扩展,Himalaya 使用 `UID SORT` 在服务器端排序并分页 - 若不支持,Himalaya 先 `SEARCH` 获取 UID,然后在客户端内存中排序和分页 4. **日期格式**:Himalaya 支持 `yyyy-mm-dd`、`yyyy/mm/dd`、`dd-mm-yyyy`、`dd/mm/yyyy` 四种日期格式 5. **引号与特殊字符**:查询中包含空格或括号时,请使用双引号包裹或反斜杠转义 --- ## 参考文件 - Himalaya CLI 查询解析入口:`src/email/envelope/command/list.rs` - 底层查询 AST 与 IMAP 映射:`email-lib` 中的 `src/email/envelope/list/imap.rs` - 查询语法解析器:`email-lib` 中的 `src/email/search_query/parser.rs` FILE:evals/evals.json { "skill_name": "himalaya", "evals": [ { "id": 1, "prompt": "I need to find all unread emails from my boss ([email protected]) in Himalaya, sorted with the newest first. Give me the exact command to run.", "expected_output": "The assistant returns the correct himalaya CLI command using 'not flag seen', 'from [email protected]', and 'order by date desc'.", "files": [], "expectations": [ "The output contains the command 'himalaya envelope list'", "The output includes 'not flag seen' or equivalent unread filter", "The output includes 'from [email protected]'", "The output includes 'order by date desc'", "The command is syntactically valid for the Himalaya query DSL" ] }, { "id": 2, "prompt": "Show me how to compose and send an email to the [email protected] with the subject 'Weekly Sync' using himalaya. Include any relevant flags or options I should know about.", "expected_output": "The assistant explains how to use 'himalaya message write' with --to and --subject flags, and describes the $EDITOR workflow.", "files": [], "expectations": [ "The output mentions 'himalaya message write'", "The output includes '--to [email protected]' or equivalent", "The output includes '--subject \"Weekly Sync\"' or equivalent", "The output mentions $EDITOR or interactive composition", "The output describes the template header format (From, To, Subject, blank line, body)" ] }, { "id": 3, "prompt": "Using himalaya, how do I search for emails with the subject ' invoices ' (with a space) sent after 2025-03-01, and also show them in the Archive folder instead of INBOX? I want 15 per page and page 2.", "expected_output": "The assistant constructs a single himalaya envelope list command with proper quoting for the spaced subject, the after date filter, folder flag, pagination flags, and page size.", "files": [], "expectations": [ "The output contains 'himalaya envelope list'", "The output includes a folder flag like '-f Archive' or '--folder Archive'", "The output includes '--page 2'", "The output includes '--page-size 15' or '-s 15'", "The output includes 'after 2025-03-01'", "The subject query correctly quotes or escapes the space in 'invoices'" ] } ] }
Execute deep research by performing comprehensive web searches and synthesizing findings into detailed reports. This skill enforces strict search protocols t...
---
name: deep-research-executor
description: Execute deep research by performing comprehensive web searches and synthesizing findings into detailed reports. This skill enforces strict search protocols to ensure thorough research coverage.
---
# Deep Research Executor
Execute comprehensive research tasks following strict protocols.
## Your Role
You are a research execution specialist. Your job is to:
1. Read the research plan
2. Execute thorough web searches (both Chinese and English)
3. Analyze sources and synthesize findings
4. Generate a comprehensive report in English
## MANDATORY RULES - YOU MUST FOLLOW THESE
### Rule 1: ALWAYS Search First
- **YOU MUST** use search tools BEFORE fetching known URLs
- **NEVER** jump directly to known URLs without searching first
- Search results will give you URLs to analyze
- Exclude duplicate URLs from search results and avoid duplicate fetching.
### Rule 2: Bilingual Search Required
**If the user's input question or research plan is NOT in English:**
For EACH research question, you MUST search in BOTH languages:
**Step 1 - Search in the original language of the question:**
- Use the original language keywords to search
- Example (Chinese): "GTD 方法 详细步骤"
**Step 2 - Search in English:**
- Translate and search in English
- Example: "Getting Things Done methodology steps"
**If the user's input question or research plan IS already in English:**
- You may search only in English
- However, consider also searching in Chinese if the topic has significant Chinese sources (e.g., China-specific topics)
### Rule 3: Dynamic Search
- After initial searches, add more targeted searches based on findings
- If you find a gap in information, search to fill it
- Aim for at least 12 diverse sources
## Execution Workflow
### Step 1: Read Research Plan
Read the JSON research plan file provided in the task to understand:
- Research questions to investigate
- Scope (include/exclude)
- Report requirements (sections, depth, min_sources)
### Step 2: Execute Bilingual Searches
For each research question:
1. Formulate Chinese search queries
2. Formulate English search queries
3. Execute searches using available search tools
4. Collect promising URLs from results
### Step 3: Analyze Sources
For each valuable URL found:
1. Fetch content using appropriate tools and extract relevant information **ALWAYS** with subagent.
2. Track citations with [^1], [^2] format
### Step 4: Synthesize & Report
Progressively complete the report writing during the search and information gathering process, rather than generating it all at once at the end.
1. First, generate a report file with an initial outline based on the requirements.
2. Gradually fill in the report content in the file according to the outline and the information found.
3. Modify and optimize the report chapter structure based on search results, and add chapters as needed.
Report Requirements:
1. Address each research question from the plan
2. Structure report according to report_requirements.sections
3. Write in English
4. Include proper citations
5. Save to the specified report path
### Step 5: Append Research Report Record
After the research is completed and the report is generated, add an entry to the `index.md` file in the following format:
```markdown
- [<report title>](<report path>)
```
## Report File
Steps to generate the report file name:
1. Generate a report title according to the topic.
2. Convert the title to snake_case, e.g., `what_is_gtd`.
3. Generate the file name in the format `ds_{title_in_snake_case}_{timestamp}.md`
The report file is always saved to the `report/` directory.
## Report Structure
Follow the sections specified in the research plan.
## Quality Checklist
Before finishing, verify:
- [ ] Used search tools for ALL research questions
- [ ] Searched in BOTH Chinese and English
- [ ] Minimum 12 sources analyzed
- [ ] All research questions addressed
- [ ] Proper citations included [^1], [^2]
- [ ] Report saved to correct path
- [ ] Report entry appended to `index.md`
## Key Principle
Remember: **Search FIRST, Fetch SECOND**. Always. **Research, record, and write the report simultaneously**.
Automated deep research that performs comprehensive multi-source investigation and produces detailed reports with citations. Use when user requests research,...
---
name: deep-research
description: "Automated deep research that performs comprehensive multi-source investigation and produces detailed reports with citations. Use when user requests research, investigation, or in-depth analysis of any topic. Capabilities: generate structured research plans, and start sub agent to execute the plan. "
---
# Deep Research
Two-phase research workflow: planning then execution.
## Overview
This skill provides a structured approach to deep research:
**Phase 1: Planning** (High Freedom)
- Discuss with user to clarify and refine research questions.
- Define what to investigate and what the report should cover.
- Set expectations for research depth and output.
- Create research plan document.
**Phase 2: Execution** (Low Freedom)
- Sub-agent reads the research plan
- Independently decides how to search for each sub-question
- Can dynamically add searches based on findings
- Analyzes content and generates report with citations
## Phase 1: Generate Research Plan
The coordinator (main session) performs:
1. **Understand the research topic** — Listen to user's request and understand what they want to investigate
2. **Collaborate with user** — Discuss and clarify research questions together. Present 3-5 potential sub-questions or research angles for user to review
3. **Define scope together** — Discuss what to include/exclude, confirm boundaries of the research
4. **Confirm report expectations** — Ask user what sections they want, what depth, any specific focus areas
5. **Get user confirmation** — Present the draft plan to user and wait for approval before proceeding
6. **Output: Research plan document** — Only after user confirms, save to `plans/research-plan-{timestamp}.json`
**Key principle:** The plan is a collaboration between coordinator and user. Never proceed to Phase 2 without explicit user confirmation of the research plan.
## Research plan format (JSON):
```json
{
"topic": "Original research topic",
"research_questions": [
"What are the latest breakthroughs in this field?",
"Who are the leading organizations or researchers?",
"What are the current limitations or challenges?",
"What are the practical applications?"
],
"scope": {
"include": ["recent developments", "key players", "technical details"],
"exclude": ["historical background before 2020", "unrelated applications"]
},
"report_requirements": {
"sections": ["executive_summary", "findings", "conclusion", "references"],
"depth": "comprehensive",
"min_sources": 8,
"focus_areas": ["technical analysis", "market landscape"]
}
}
```
## Research Plan Schema
Required fields:
- topic: Original research topic
- research_questions: Array of questions to investigate
- report_requirements: Object specifying output expectations
Optional fields:
- scope: Define boundaries of research (include/exclude)
- min_sources: Minimum sources to analyze (default: 8)
- max_sources: Maximum sources to analyze (default: 20)
- notes: Additional context or special instructions
Save plan to: `plans/research-plan-{timestamp}.json`
**⚠️ WAIT FOR USER CONFIRMATION — Do not proceed to Phase 2 until user explicitly approves the research plan.**
Key principle: The plan defines WHAT to research and WHAT the output should contain. It does NOT specify HOW to search (keywords, sources, rounds) - that is up to the research agent to determine dynamically.
## Phase 2: Execute Research Plan
Launch sub agent with the research plan. Launch sub agent with `session_spawn` tool. Instruct subagent to use `deep-research-executor` to execute the plan EXPLICITLY.
FILE:references/plan-examples.md
# Research Plan Examples
These examples demonstrate the research plan format that defines WHAT to research without specifying HOW to search.
## Example 1: Technology Research
```json
{
"topic": "AI agents in software development",
"research_questions": [
"What AI agent frameworks and tools are currently available?",
"How are companies and developers using AI agents for coding?",
"What are the main limitations and challenges of AI coding agents?",
"What is the future outlook and roadmap for AI coding agents?"
],
"scope": {
"include": ["development tools", "productivity studies", "enterprise adoption"],
"exclude": ["AI agents for non-coding tasks", "general AI research"]
},
"report_requirements": {
"sections": ["executive_summary", "findings", "conclusion", "references"],
"depth": "comprehensive",
"min_sources": 10,
"focus_areas": ["practical applications", "technical capabilities"]
}
}
```
## Example 2: Market Research
```json
{
"topic": "Electric vehicle market in China",
"research_questions": [
"What is the current market size and growth trajectory?",
"Who are the major players and what are their market positions?",
"What government policies and incentives affect the market?",
"What are consumer adoption trends and preferences?"
],
"scope": {
"include": ["passenger EVs", "charging infrastructure", "policy analysis"],
"exclude": ["commercial vehicles", "hybrid vehicles"]
},
"report_requirements": {
"sections": ["executive_summary", "market_overview", "competitive_landscape", "policy_analysis", "conclusion", "references"],
"depth": "detailed",
"min_sources": 12,
"focus_areas": ["market data", "policy impact"]
}
}
```
## Example 3: Academic/Technical Research
```json
{
"topic": "Large language model safety and alignment",
"research_questions": [
"What are the primary safety concerns with current LLMs?",
"What alignment techniques are being researched and deployed?",
"What evaluation methods and benchmarks exist for safety?",
"What are the major open problems and research directions?"
],
"scope": {
"include": ["safety techniques", "evaluation frameworks", "recent research"],
"exclude": ["general AI ethics", "non-LLM AI safety"]
},
"report_requirements": {
"sections": ["executive_summary", "findings", "conclusion", "references"],
"depth": "technical",
"min_sources": 15,
"focus_areas": ["technical approaches", "evaluation methods"]
},
"notes": "Focus on papers from 2023-2025 and major research labs"
}
```
## Example 4: Competitive Analysis
```json
{
"topic": "Cloud storage services comparison",
"research_questions": [
"What are the major cloud storage providers and their offerings?",
"How do pricing models compare across providers?",
"What are the key differentiating features?",
"What are user reviews and satisfaction ratings?"
],
"scope": {
"include": ["AWS S3", "Google Cloud Storage", "Azure Blob", "pricing analysis"],
"exclude": ["consumer file sharing", "personal backup solutions"]
},
"report_requirements": {
"sections": ["executive_summary", "provider_comparison", "pricing_analysis", "feature_matrix", "conclusion", "references"],
"depth": "detailed",
"min_sources": 8,
"focus_areas": ["enterprise features", "cost comparison"]
}
}
```
## Key Principles
**Research Questions**: Define what to investigate. Should be specific enough to guide research but open enough to allow discovery.
**Scope**: Boundaries of research. Include defines what must be covered. Exclude prevents drift into tangential topics.
**Report Requirements**: Expectations for output. Sections define structure. Depth guides analysis level. Focus areas indicate priorities.
**No Search Specification**: The plan does NOT include keywords, queries, sources, or number of searches. The Sub Agent determines search strategy based on research questions.
Use when needing to search the web in AI coding tools or OpenClaw. Uses DuckDuckGo API without API key.
--- name: ddgs-web-search description: Use when needing to search the web in AI coding tools or OpenClaw. Uses DuckDuckGo API without API key. --- # DuckDuckGo Web Search Skill An Agent Skill for searching web content via DuckDuckGo. ## Overview This Skill provides a command-line tool for web search using the `ddgs` Python package. Suitable for: - Real-time web information needs in AI coding tools - Fetching search results in OpenClaw workflows ## Core Features - **Web Search**: General web search - **News Search**: Dedicated news content search - **Multiple Output Formats**: Text or JSON format - **Flexible Configuration**: Region, time limits, and safe search level - **Proxy Support**: HTTP/HTTPS/SOCKS5 proxy via CLI args or environment variables ## Installation This project uses `uv` as the Python package manager. ### Option 1: Run with uv (Recommended) ```bash # Run the script directly (uv will auto-install dependencies) uv run scripts/ddgs_search.py "Python programming" # Or navigate to the directory first cd skills/ddgs-search uv run scripts/ddgs_search.py "machine learning" ``` ### Option 2: Manual Dependency Installation ```bash # Install dependencies using uv uv pip install ddgs # Or use pip pip install ddgs ``` ## Quick Start ### Basic Usage ```bash # Run with uv (recommended) uv run scripts/ddgs_search.py "Python programming" # Limit the number of results uv run scripts/ddgs_search.py "machine learning" --max-results 5 # Search news uv run scripts/ddgs_search.py "tech news" --news # JSON output (for programmatic parsing) uv run scripts/ddgs_search.py "API documentation" --json # Time limit (today) uv run scripts/ddgs_search.py "breaking news" --timelimit d ``` ## Complete Parameter Reference | Parameter | Short | Description | Default | | --------- | ----- | ----------- | ------- | | `query` | - | Search keywords | Required | | `--max-results` | `-n` | Maximum number of results | 10 | | `--region` | `-r` | Region code | `wt-wt` | | `--safesearch` | `-s` | Safe search (on/moderate/off) | `moderate` | | `--timelimit` | `-t` | Time limit (d/w/m/y) | - | | `--backend` | `-b` | Search backend (auto/html/lite) | `auto` | | `--proxy` | `-p` | Proxy server (http/https/socks5) | - | | `--news` | - | Search news | - | | `--json` | `-j` | JSON format output | - | | `--verbose` | `-v` | Show detailed information | - | ### Proxy Configuration Proxy settings are resolved in the following priority order: 1. **Command line**: `--proxy` / `-p` 2. **Environment variable**: `HTTP_PROXY` or `http_proxy` 3. **Environment variable**: `DDGS_PROXY` **Proxy format examples:** - `http://proxy.example.com:8080` - `http://user:[email protected]:8080` - `socks5://127.0.0.1:9150` (Tor Browser) - `socks5h://user:[email protected]:32325` ### Region Code Examples - `wt-wt` - Worldwide (default) - `us-en` - United States English - `cn-zh` - China Chinese - `jp-jp` - Japan - `uk-en` - United Kingdom ### Time Limits - `d` - Past day - `w` - Past week - `m` - Past month - `y` - Past year ## Usage in OpenClaw In OpenClaw workflows, you can invoke it via the `bash` tool: ```yaml # Example workflow step - name: search_web tool: bash command: cd skills/ddgs-search && uv run scripts/ddgs_search.py "{{ query }}" --json ``` Or using the Python tool: ```python # Assuming the current directory is the project root import subprocess import json result = subprocess.run( ["uv", "run", "skills/ddgs-search/scripts/ddgs_search.py", "Python tips", "--json"], capture_output=True, text=True ) data = json.loads(result.stdout) ``` ## Return Result Format ### Web Search Results ```json [ { "title": "Result Title", "href": "https://example.com/page", "body": "Page snippet/description..." } ] ``` ### News Search Results ```json [ { "title": "News Headline", "href": "https://news.example.com/article", "body": "Article summary...", "date": "2024-01-15", "source": "News Source Name" } ] ``` ## Usage Examples ### Example 1: Search Technical Documentation ```bash uv run scripts/ddgs_search.py "FastAPI documentation" -n 5 ``` ### Example 2: Get Latest News ```bash uv run scripts/ddgs_search.py "artificial intelligence" --news -t d -n 3 ``` ### Example 3: Chinese Search ```bash uv run scripts/ddgs_search.py "机器学习教程" -r cn-zh -n 8 ``` ### Example 4: JSON Output Processing ```bash uv run scripts/ddgs_search.py "python tips" --json | jq '.[0].href' ``` ### Example 5: Using Proxy ```bash # Via command line argument uv run scripts/ddgs_search.py "query" --proxy http://1.2.3.4:8080 # Via HTTP_PROXY environment variable export HTTP_PROXY="http://proxy.example.com:8080" uv run scripts/ddgs_search.py "query" # Via DDGS_PROXY environment variable export DDGS_PROXY="socks5://127.0.0.1:9150" uv run scripts/ddgs_search.py "query" ``` ## FAQ ### uv Not Installed ```bash # macOS/Linux curl -LsSf https://astral.sh/uv/install.sh | sh # Windows powershell -c "irm https://astral.sh/uv/install.ps1 | iex" ``` ### ImportError: No module named 'ddgs' ```bash # Install using uv uv pip install ddgs # Or run in the script directory (uv will auto-handle) cd skills/ddgs-search uv run scripts/ddgs_search.py "query" ``` ### Empty Search Results - Check network connection - Try changing the `--backend` parameter (auto/html/lite) - Some regions may require a proxy (see [Proxy Configuration](#proxy-configuration)) ### Proxy Not Working - Verify proxy format: `http://host:port` or `socks5://host:port` - Check if authentication is required: `http://user:pass@host:port` - Ensure the proxy server is accessible from your network - Try using `HTTP_PROXY` environment variable instead of command line argument ### Rate Limiting DuckDuckGo has implicit rate limiting. If frequent requests fail: - Reduce request frequency - Add delays between requests - Use a different backend ## Dependencies - Python 3.9+ - `uv` (package manager) - `ddgs` >= 8.0.0 FILE:scripts/ddgs_search.py #!/usr/bin/env python3 """ DuckDuckGo Search CLI Tool 使用 ddgs 包执行网络搜索 依赖安装: uv pip install ddgs 或直接运行: uv run ddgs_search.py "query" """ import argparse import json import os import sys from typing import Optional try: from ddgs import DDGS except ImportError: print("Error: ddgs package not found.", file=sys.stderr) print("Install it with: uv pip install ddgs", file=sys.stderr) print("Or run directly: uv run ddgs_search.py 'query'", file=sys.stderr) sys.exit(1) def get_proxy(cli_proxy: Optional[str] = None) -> Optional[str]: """ 按优先级获取代理设置: 1. 命令行参数 2. 环境变量 HTTP_PROXY 3. 环境变量 DDGS_PROXY Args: cli_proxy: 命令行传入的代理地址 Returns: 代理地址字符串或 None """ if cli_proxy: return cli_proxy # 检查 HTTP_PROXY (requests 库标准环境变量) http_proxy = os.environ.get("HTTP_PROXY") or os.environ.get("http_proxy") if http_proxy: return http_proxy # 检查 DDGS_PROXY (ddgs 库专用环境变量) ddgs_proxy = os.environ.get("DDGS_PROXY") if ddgs_proxy: return ddgs_proxy return None def search_web( query: str, max_results: int = 10, region: str = "wt-wt", safesearch: str = "moderate", timelimit: Optional[str] = None, backend: str = "auto", proxy: Optional[str] = None, ) -> list: """ 执行DuckDuckGo网络搜索 Args: query: 搜索关键词 max_results: 最大返回结果数 (默认10) region: 地区代码 (默认 wt-wt 全球) safesearch: 安全搜索级别 (on/moderate/off) timelimit: 时间限制 (d/w/m/y 或 None) backend: 搜索后端 (auto/html/lite) proxy: 代理服务器地址 Returns: 搜索结果列表 """ ddgs = DDGS(proxy=proxy) results = ddgs.text( query, region=region, safesearch=safesearch, timelimit=timelimit, max_results=max_results, backend=backend, ) return list(results) def search_news( query: str, max_results: int = 10, region: str = "wt-wt", safesearch: str = "moderate", timelimit: Optional[str] = None, proxy: Optional[str] = None, ) -> list: """ 执行DuckDuckGo新闻搜索 Args: query: 搜索关键词 max_results: 最大返回结果数 (默认10) region: 地区代码 safesearch: 安全搜索级别 timelimit: 时间限制 proxy: 代理服务器地址 Returns: 新闻结果列表 """ ddgs = DDGS(proxy=proxy) results = ddgs.news( query, region=region, safesearch=safesearch, timelimit=timelimit, max_results=max_results, ) return list(results) def format_result(result: dict, index: int = 0) -> str: output = [] if index > 0: output.append(f"\n{'=' * 60}") title = result.get("title", "N/A") href = result.get("href", "N/A") body = result.get("body", "N/A") output.append(f"[{index}] {title}") output.append(f"URL: {href}") output.append(f"摘要: {body}") # 新闻特有字段 if "date" in result: output.append(f"日期: {result['date']}") if "source" in result: output.append(f"来源: {result['source']}") return "\n".join(output) def main(): parser = argparse.ArgumentParser( description="DuckDuckGo Search CLI - 网络搜索工具\n\n使用 uv 运行: uv run ddgs_search.py 'query'", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" 示例: uv run ddgs_search.py "Python tutorial" # 基本搜索 uv run ddgs_search.py "AI news" --max-results 5 # 限制结果数量 uv run ddgs_search.py "tech" --region us-en # 指定地区 uv run ddgs_search.py "sports" --timelimit d # 今日结果 uv run ddgs_search.py "politics" --news # 搜索新闻 uv run ddgs_search.py "query" --json # JSON格式输出 uv run ddgs_search.py "query" --proxy http://1.2.3.4:8080 # 使用代理 """, ) parser.add_argument("query", help="搜索关键词") parser.add_argument( "-n", "--max-results", type=int, default=10, help="最大返回结果数 (默认: 10)" ) parser.add_argument( "-r", "--region", default="wt-wt", help="地区代码 (默认: wt-wt, 如: us-en, cn-zh)", ) parser.add_argument( "-s", "--safesearch", default="moderate", choices=["on", "moderate", "off"], help="安全搜索级别 (默认: moderate)", ) parser.add_argument( "-t", "--timelimit", choices=["d", "w", "m", "y"], help="时间限制 (d=天, w=周, m=月, y=年)", ) parser.add_argument( "-b", "--backend", default="auto", choices=["auto", "html", "lite"], help="搜索后端 (默认: auto)", ) parser.add_argument("--news", action="store_true", help="搜索新闻 (默认搜索网页)") parser.add_argument("-j", "--json", action="store_true", help="JSON格式输出") parser.add_argument("-v", "--verbose", action="store_true", help="显示详细信息") parser.add_argument( "-p", "--proxy", help="代理服务器地址 (默认优先级: 命令行参数 > HTTP_PROXY环境变量 > DDGS_PROXY环境变量)", ) args = parser.parse_args() proxy = get_proxy(args.proxy) try: if args.news: results = search_news( query=args.query, max_results=args.max_results, region=args.region, safesearch=args.safesearch, timelimit=args.timelimit, proxy=proxy, ) search_type = "新闻" else: results = search_web( query=args.query, max_results=args.max_results, region=args.region, safesearch=args.safesearch, timelimit=args.timelimit, backend=args.backend, proxy=proxy, ) search_type = "网页" if args.json: print(json.dumps(results, ensure_ascii=False, indent=2)) else: print(f'\n🔍 DuckDuckGo {search_type}搜索: "{args.query}"') print(f"找到 {len(results)} 条结果\n") for i, result in enumerate(results, 1): print(format_result(result, i)) if args.verbose: print(f"\n{'=' * 60}") print(f"搜索参数: region={args.region}, safesearch={args.safesearch}") if args.timelimit: print(f"时间限制: {args.timelimit}") except KeyboardInterrupt: print("\n\n搜索已取消", file=sys.stderr) sys.exit(130) except Exception as e: print(f"\n错误: {e}", file=sys.stderr) sys.exit(1) if __name__ == "__main__": main()