Agent审计
- 作者仓库星标 435
- 作者更新于 实时读取
- 作者仓库 nvim
- 领域
- 效率工具
- 兼容 Agent
-
- Claude Code
- Cursor
- Cline
- Codex
- Windsurf
- Gemini CLI
- +20
- 信任分
- 88 / 100 · 社区维护
- 作者 / 版本 / 许可
- @benbrastmckie · 未声明 license
- Token 消耗评级
- 中等消耗
- 接入复杂程度
- 需简单配置
- 是否需要外部 API Key
- 不需要
- 兼容的系统
- Windows
- 底层运行要求
- Python
- 文件与系统权限
-
- 只读
- 允许写入 / 修改
- Shell 执行
- 网络行为
- 仅限本地
- 安装命令数
- 26 条
档案由构建时根据 SKILL.md 与安装命令自动衍生,可能与作者实际意图存在差异。
需要注意: 未限定 allowed-tools,默认拥有全部工具权限。
---
name: skill-learn
description: Scan codebase for FIX:/NOTE:/TODO:/QUESTION: tags and create structured tasks with interactive s…
category: 效率工具
runtime: Python
---
# skill-learn 输出预览
## PART A: 任务判断
- 适用问题:日常重复事务、资料整理、邮件或工作流提效。
- 输入要求:目标材料、限制条件、期望输出和验收方式。
- 证据边界:围绕“Context References / Execution / Step 1: Parse Arguments”读取原文规则,不把推断写成作者承诺。
## PART B: 执行结果
- **01** 任务判断:确认你的需求是否属于日常重复事务、资料整理、邮件或工作流提效,并标出输入、限制和预期结果。
- **02** 执行计划:优先按“Context References / Execution / Step 1: Parse Arguments”拆成步骤,说明每一步会读取什么、修改什么、产出什么。
- **03** 交付结果:给出可复制的命令、文件改动、检查清单或内容草稿,并说明如何继续迭代。
- **04** 风险边界:结合 读取文件、写入/修改文件、执行终端命令、主要在本地完成、通常不需要额外 API Key 给出执行前确认项。
## Running Rules
- 读取文件、写入/修改文件、执行终端命令;主要在本地完成;通常不需要额外 API Key。
- 先小样例验证,再放大到真实任务。
- 交付时同时给结果、检查口径和下一步迭代建议。 原文出现了 `/dev`、`/research`、`/plan`、`/implement` 这类斜杠命令;如果你的 Agent 支持命令触发,优先用命令开场,再补充目标和边界。
告诉 Agent 目标文件或材料、期望结果、不可改范围、是否允许联网或执行命令。本 Skill 的权限画像是:读取文件、写入/修改文件、执行终端命令。
先用一个小任务确认它会围绕“Context References / Execution / Step 1: Parse Arguments”工作;涉及文件或命令时,先看 diff、日志、预览或测试结果。
检查最终产物是否包含明确结果、必要证据和下一步动作;如果输出泛泛而谈,就补充输入、边界和验收标准后重跑。
---
name: skill-learn
description: Scan codebase for FIX:/NOTE:/TODO:/QUESTION: tags and create structured tasks with interactive s…
category: 效率工具
source: benbrastmckie/nvim
---
# skill-learn
## 什么时候使用
- 把日常协作方向的常用动作沉淀成 Agent 可调用的技能 适合处理重复事务、信息整理、邮件和日常工作流提效,核心价值是把输入、判断、执行、验证和交付边界固定下来,避免 Agent 泛泛回答。 把任务拆成可执行、可检查、可继续迭代的步骤…
- 面向日常重复事务、资料整理、邮件或工作流提效,优先处理能明确输入、步骤和验收标准的工作。
## 需要提供什么
- 目标材料、目录范围、期望结果和不可改动内容。
- 是否允许联网、执行命令、读写文件或调用外部服务。
## 执行规则
- 围绕「Context References / Execution / Step 1: Parse Arguments」组织步骤,不把推断写成作者事实。
- 读取文件、写入/修改文件、执行终端命令;主要在本地完成;通常不需要额外 API Key。
- 先跑小样例,确认结果可检查后再扩大任务范围。
## 输出要求
- 给出最终产物、关键证据、验证方式和下一步动作。
- 信息不足时标记 unknown,不编造命令、平台或依赖。 作者原文负责流程事实;仓库文件负责来源和命令;流狐只补充适用场景、限制和质量判断。
skill "skill-learn" {
输入层 -> 用户目标 + 目标文件 + 禁止范围 + 验收标准
上下文层 -> Context References / Execution / Step 1: Parse Arguments
规则层 -> SKILL.md 触发条件 / 执行顺序 / 输出格式
运行层 -> Python | 读取文件、写入/修改文件、执行终端命令 | 主要在本地完成
安全层 -> 通常不需要额外 API Key + 小任务验证 + diff / 日志复核
输出层 -> 可复制结果 + 检查清单 + 下一步迭代
} Learn Skill (Direct Execution)
Direct execution skill for scanning files, presenting findings interactively, and creating user-selected tasks. Replaces the previous delegation-based approach with synchronous execution and AskUserQuestion prompts.
Key behavior: Users always see tag scan results BEFORE any tasks are created. Users select which task types to create via interactive prompts.
Context References
Reference (do not load eagerly):
- Path:
@specs/TODO.md- Current task list - Path:
@specs/state.json- Machine state
Execution
Step 1: Parse Arguments
Extract paths from command input:
# Parse from command input
paths="$ARGUMENTS"
# Default to project root if no paths specified
if [ -z "$paths" ]; then
paths="."
fi
Note: The --dry-run flag is no longer supported. The interactive flow is inherently "preview first" - users always see findings before any tasks are created.
Step 2: Generate Session ID
Generate session ID for tracking:
session_id="sess_$(date +%s)_$(od -An -N3 -tx1 /dev/urandom | tr -d ' ')"
Step 3: Execute Tag Extraction
Scan for tags using file-type-specific patterns. Use Bash with grep for consistent output parsing.
3.1: Extract FIX: Tags
Lua files (Neovim config):
grep -rn --include="*.lua" "-- FIX:" $paths 2>/dev/null || true
LaTeX files:
grep -rn --include="*.tex" "% FIX:" $paths 2>/dev/null || true
Markdown files:
grep -rn --include="*.md" "<!-- FIX:" $paths 2>/dev/null || true
Python/Shell/YAML files:
grep -rn --include="*.py" --include="*.sh" --include="*.yaml" --include="*.yml" "# FIX:" $paths 2>/dev/null || true
3.2: Extract NOTE: Tags
Same patterns as above, replacing FIX: with NOTE:.
3.3: Extract TODO: Tags
Same patterns as above, replacing FIX: with TODO:.
3.4: Extract QUESTION: Tags
Lua files (Neovim config):
grep -rn --include="*.lua" "-- QUESTION:" $paths 2>/dev/null || true
LaTeX files:
grep -rn --include="*.tex" "% QUESTION:" $paths 2>/dev/null || true
Markdown files:
grep -rn --include="*.md" "<!-- QUESTION:" $paths 2>/dev/null || true
Python/Shell/YAML files:
grep -rn --include="*.py" --include="*.sh" --include="*.yaml" --include="*.yml" "# QUESTION:" $paths 2>/dev/null || true
3.5: Parse Results
For each grep match, extract:
- File path
- Line number
- Tag type (FIX, NOTE, TODO, QUESTION)
- Tag content (text after the tag)
Example raw output:
nvim/lua/plugins/telescope.lua:67:-- TODO: Add custom picker for git worktrees
docs/KEYMAPS.md:89:<!-- FIX: Update keymap table with new bindings -->
nvim/lua/config/lsp.lua:45:-- QUESTION: What is the best way to configure LSP hover windows?
Categorize into four arrays:
fix_tags[]- All FIX: tagsnote_tags[]- All NOTE: tagstodo_tags[]- All TODO: tagsquestion_tags[]- All QUESTION: tags
Step 4: Display Tag Summary
Present findings to user BEFORE any selection:
## Tag Scan Results
**Files Scanned**: {paths}
**Tags Found**: {total_count}
### FIX: Tags ({count})
- `{file}:{line}` - {content}
- ...
### NOTE: Tags ({count})
- `{file}:{line}` - {content}
- ...
### TODO: Tags ({count})
- `{file}:{line}` - {content}
- ...
### QUESTION: Tags ({count})
- `{file}:{line}` - {content}
- ...
Step 5: Handle Edge Cases
No Tags Found
If no tags found:
## No Tags Found
Scanned files in: {paths}
No FIX:, NOTE:, TODO:, or QUESTION: tags detected.
Nothing to create.
Exit gracefully without prompts.
Only Certain Tag Types
Only show task type options for tag types that exist:
- FIX: tags exist -> offer "fix-it task"
- NOTE: tags exist -> offer "fix-it task" AND "learn-it task"
- TODO: tags exist -> offer "TODO tasks"
- QUESTION: tags exist -> offer "Research tasks"
Step 6: Task Type Selection
If tags were found, prompt user to select task types:
{
"question": "Which task types should be created?",
"header": "Task Types",
"multiSelect": true,
"options": [
{
"label": "fix-it task",
"description": "Combine {N} FIX:/NOTE: tags into single task"
},
{
"label": "learn-it task",
"description": "Update context from {N} NOTE: tags"
},
{
"label": "TODO tasks",
"description": "Create tasks for {N} TODO: items"
},
{
"label": "Research tasks",
"description": "Create research tasks for {N} QUESTION: items"
}
]
}
Important: Only include options where the tag type exists:
- Include "fix-it task" only if FIX: or NOTE: tags exist
- Include "learn-it task" only if NOTE: tags exist
- Include "TODO tasks" only if TODO: tags exist
- Include "Research tasks" only if QUESTION: tags exist
If user selects nothing, exit gracefully:
No task types selected. No tasks created.
Step 7: Individual TODO Selection
If "TODO tasks" was selected AND there are TODO: tags:
Standard Case (<=20 TODOs)
{
"question": "Select TODO items to create as tasks:",
"header": "TODO Selection",
"multiSelect": true,
"options": [
{
"label": "{content truncated to 50 chars}",
"description": "{file}:{line}"
},
...
]
}
Large Number of TODOs (>20)
Add a "Select all" option at the top:
{
"question": "Select TODO items to create as tasks:",
"header": "TODO Selection (many items)",
"multiSelect": true,
"options": [
{
"label": "Select all ({N} items)",
"description": "Create a task for every TODO tag"
},
{
"label": "{content truncated to 50 chars}",
"description": "{file}:{line}"
},
...
]
}
If "Select all" is chosen, include all TODOs. Otherwise, only selected items.
Step 7.5: Topic Grouping for TODO Items
Condition: User selected "TODO tasks" AND selected more than 1 TODO item
If only 1 TODO item was selected, skip to Step 8 (no grouping benefit).
7.5.1: Extract Topic Indicators
For each selected TODO item, extract topic indicators:
Key Terms: Extract significant words from the TODO content (nouns, verbs). Ignore stop words (the, a, is, to, for, etc.).
File Section: Group by file path prefix (e.g., Logos/Layer1/ vs Logos/Shared/).
Action Type: Identify common action patterns:
- "Add/Implement/Create" → implementation tasks
- "Fix/Handle/Correct" → fix tasks
- "Document/Update docs" → documentation tasks
- "Test/Verify" → testing tasks
- "Refactor/Optimize" → improvement tasks
Example extraction:
TODO: "Add custom picker for worktrees" at nvim/lua/plugins/telescope.lua:67
→ key_terms: ["picker", "worktrees", "telescope"]
→ file_section: "nvim/lua/plugins/"
→ action_type: "implementation"
TODO: "Add preview window for worktrees" at nvim/lua/plugins/telescope.lua:89
→ key_terms: ["preview", "worktrees", "telescope"]
→ file_section: "nvim/lua/plugins/"
→ action_type: "implementation"
TODO: "Optimize lazy loading" at nvim/lua/config/lazy.lua:23
→ key_terms: ["optimize", "lazy", "loading"]
→ file_section: "nvim/lua/config/"
→ action_type: "improvement"
7.5.2: Cluster TODOs by Shared Terms
Group TODOs that share 2 or more significant terms or share file section + action type.
Clustering algorithm:
- Start with first TODO as initial group
- For each remaining TODO:
- If shares 2+ key terms with existing group → add to group
- If shares file_section AND action_type with existing group → add to group
- Otherwise → start new group
- Generate topic label from most common shared terms in group
Example clustering:
Group 1: "Telescope Worktrees" (shared: worktrees, telescope, nvim/lua/plugins/, implementation)
- Add custom picker for worktrees
- Add preview window for worktrees
Group 2: "Config Optimization" (shared: nvim/lua/config/, improvement)
- Optimize lazy loading
Single-item groups: If a TODO doesn't cluster with others, it becomes its own single-item group.
7.5.3: Store Grouped Topics
Store the topic groups for use in Step 7.5.4:
topic_groups = [
{
label: "Telescope Worktrees",
items: [
{file: "nvim/lua/plugins/telescope.lua", line: 67, content: "Add custom picker for worktrees"},
{file: "nvim/lua/plugins/telescope.lua", line: 89, content: "Add preview window for worktrees"}
],
shared_terms: ["worktrees", "telescope"],
action_type: "implementation"
},
{
label: "Config Optimization",
items: [
{file: "nvim/lua/config/lazy.lua", line: 23, content: "Optimize lazy loading"}
],
shared_terms: [],
action_type: "improvement"
}
]
Step 7.5.4: Topic Group Confirmation
Condition: topic_groups contains at least one group with 2+ items
If all groups have only 1 item, skip to Step 8 (no grouping benefit).
Present topic groups via AskUserQuestion:
{
"question": "How should TODO items be grouped into tasks?",
"header": "TODO Topic Grouping",
"multiSelect": false,
"options": [
{
"label": "Accept suggested topic groups",
"description": "Creates {N} grouped tasks: {group_summaries}"
},
{
"label": "Keep as separate tasks",
"description": "Creates {M} individual tasks (one per TODO item)"
},
{
"label": "Create single combined task",
"description": "Creates 1 task containing all {M} TODO items"
}
]
}
Where:
{N}= number of topic groups{M}= total number of selected TODO items{group_summaries}= comma-separated list like "S5 Theorems (2 items), Utility Optimization (1 item)"
Store user choice: grouping_mode = "grouped" | "separate" | "combined"
Step 7.6: Individual QUESTION Selection
Condition: User selected "Research tasks" in Step 6 AND QUESTION: tags exist
If "Research tasks" was selected AND there are QUESTION: tags:
Standard Case (<=20 QUESTIONs)
{
"question": "Select QUESTION items to create as research tasks:",
"header": "QUESTION Selection",
"multiSelect": true,
"options": [
{
"label": "{content truncated to 50 chars}",
"description": "{file}:{line}"
},
...
]
}
Large Number of QUESTIONs (>20)
Add a "Select all" option at the top:
{
"question": "Select QUESTION items to create as research tasks:",
"header": "QUESTION Selection (many items)",
"multiSelect": true,
"options": [
{
"label": "Select all ({N} items)",
"description": "Create a research task for every QUESTION tag"
},
{
"label": "{content truncated to 50 chars}",
"description": "{file}:{line}"
},
...
]
}
If "Select all" is chosen, include all QUESTIONs. Otherwise, only selected items.
Step 7.7: Topic Grouping for QUESTION Items
Condition: User selected "Research tasks" AND selected more than 1 QUESTION item
If only 1 QUESTION item was selected, skip to Step 8 (no grouping benefit).
7.7.1: Extract Topic Indicators
For each selected QUESTION item, extract topic indicators. Use the same algorithm as Step 7.5.1 (TODO topic extraction):
Key Terms: Extract significant words from the QUESTION content (nouns, verbs). Ignore stop words (the, a, is, to, for, etc.).
File Section: Group by file path prefix (e.g., nvim/lua/plugins/ vs nvim/lua/config/).
Action Type: For QUESTION tags, action_type defaults to "research" for all items (since all are questions to be researched).
Example extraction:
QUESTION: "What is the best way to configure LSP hover windows?" at nvim/lua/config/lsp.lua:45
→ key_terms: ["configure", "LSP", "hover", "windows"]
→ file_section: "nvim/lua/config/"
→ action_type: "research"
QUESTION: "How do I add custom LSP handlers?" at nvim/lua/config/lsp.lua:89
→ key_terms: ["custom", "LSP", "handlers"]
→ file_section: "nvim/lua/config/"
→ action_type: "research"
QUESTION: "What telescope extensions are available for git worktrees?" at nvim/lua/plugins/telescope.lua:23
→ key_terms: ["telescope", "extensions", "git", "worktrees"]
→ file_section: "nvim/lua/plugins/"
→ action_type: "research"
7.7.2: Cluster QUESTIONs by Shared Terms
Use the same clustering algorithm as Step 7.5.2 (TODO clustering).
Group QUESTIONs that share 2 or more significant terms or share file section (action_type is always "research" for questions, so only file_section matters for secondary matching).
Example clustering:
Group 1: "LSP Configuration" (shared: LSP, nvim/lua/config/)
- What is the best way to configure LSP hover windows?
- How do I add custom LSP handlers?
Group 2: "Telescope Extensions" (shared: nvim/lua/plugins/)
- What telescope extensions are available for git worktrees?
Single-item groups: If a QUESTION doesn't cluster with others, it becomes its own single-item group.
7.7.3: Store Grouped Topics
Store the topic groups for use in Step 7.7.4:
question_topic_groups = [
{
label: "LSP Configuration",
items: [
{file: "nvim/lua/config/lsp.lua", line: 45, content: "What is the best way to configure LSP hover windows?"},
{file: "nvim/lua/config/lsp.lua", line: 89, content: "How do I add custom LSP handlers?"}
],
shared_terms: ["LSP"],
action_type: "research"
},
{
label: "Telescope Extensions",
items: [
{file: "nvim/lua/plugins/telescope.lua", line: 23, content: "What telescope extensions are available for git worktrees?"}
],
shared_terms: [],
action_type: "research"
}
]
Step 7.7.4: QUESTION Topic Group Confirmation
Condition: question_topic_groups contains at least one group with 2+ items
If all groups have only 1 item, skip to Step 8 (no grouping benefit).
Present topic groups via AskUserQuestion:
{
"question": "How should QUESTION items be grouped into research tasks?",
"header": "QUESTION Topic Grouping",
"multiSelect": false,
"options": [
{
"label": "Accept suggested topic groups",
"description": "Creates {N} grouped research tasks: {group_summaries}"
},
{
"label": "Keep as separate tasks",
"description": "Creates {M} individual research tasks (one per QUESTION item)"
},
{
"label": "Create single combined task",
"description": "Creates 1 research task containing all {M} QUESTION items"
}
]
}
Where:
{N}= number of topic groups{M}= total number of selected QUESTION items{group_summaries}= comma-separated list like "LSP Configuration (2 items), Telescope Extensions (1 item)"
Store user choice: question_grouping_mode = "grouped" | "separate" | "combined"
Step 8: Create Selected Tasks
For each selected task type, create the task. Important: When NOTE: tags exist and both fix-it and learn-it tasks are selected, create learn-it FIRST so fix-it can depend on it.
8.1: Get Next Task Number
next_num=$(jq -r '.next_project_number' specs/state.json)
8.2: Dependency-Aware Task Creation Order
Check for NOTE: dependency condition:
has_note_dependency = (NOTE: tags exist) AND (user selected both "fix-it task" AND "learn-it task")
If has_note_dependency is TRUE:
- Create learn-it task FIRST (Step 8.2a)
- Store learn-it task number as
learn_it_task_num - Create fix-it task SECOND with dependency (Step 8.2b)
If has_note_dependency is FALSE:
- Create fix-it task first (if selected)
- Create learn-it task second (if selected)
- No dependency relationship
8.2a: Learn-It Task (when created first for dependency)
Condition: has_note_dependency is TRUE
{
"title": "Update context files from NOTE: tags",
"description": "Update {N} context files based on learnings:\n\n{grouped by target context}",
"language": "meta",
"effort": "1-2 hours"
}
Store the task number: learn_it_task_num = next_num
Increment: next_num = next_num + 1
8.2b: Fix-It Task (with dependency when has_note_dependency)
Condition: User selected "fix-it task" AND (FIX: or NOTE: tags exist)
When has_note_dependency is TRUE:
{
"title": "Fix issues from FIX:/NOTE: tags",
"description": "Address {N} items from embedded tags:\n\n{list of items with file:line references}\n\n**Important**: When making changes, remove the FIX: and NOTE: tags from the source files. Leave TODO: tags untouched (they create separate tasks).",
"language": "{predominant language from source files}",
"effort": "2-4 hours",
"dependencies": [learn_it_task_num]
}
When has_note_dependency is FALSE:
{
"title": "Fix issues from FIX:/NOTE: tags",
"description": "Address {N} items from embedded tags:\n\n{list of items with file:line references}\n\n**Important**: When making changes, remove the FIX: and NOTE: tags from the source files. Leave TODO: tags untouched (they create separate tasks).",
"language": "{predominant language from source files}",
"effort": "2-4 hours"
}
Language Detection:
if majority of tags from .lean files -> "lean"
elif majority from .tex files -> "latex"
elif majority from .opencode/ files -> "meta"
else -> "general"
8.3: Learn-It Task (when created without dependency)
Condition: User selected "learn-it task" AND NOTE: tags exist AND has_note_dependency is FALSE
{
"title": "Update context files from NOTE: tags",
"description": "Update {N} context files based on learnings:\n\n{grouped by target context}",
"language": "meta",
"effort": "1-2 hours"
}
8.4: Todo-Tasks (if selected)
Condition: User selected "TODO tasks" AND user selected specific TODO items
Check grouping_mode (from Step 7.5.4, defaults to "separate" if Step 7.5.4 was skipped):
8.4.1: Grouped Mode (grouping_mode == "grouped")
For each topic group in topic_groups:
{
"title": "{topic_label}: {item_count} TODO items",
"description": "Address TODO items related to {topic_label}:\n\n{item_list}\n\n---\n\nShared context: {shared_terms_description}",
"language": "{detected from majority file type in group}",
"effort": "{scaled_effort}"
}
Where:
{topic_label}= generated label (e.g., "Telescope Worktrees"){item_count}= number of items in group{item_list}= formatted list of items:- [ ] {content} (`{file}:{line}`) - [ ] {content} (`{file}:{line}`){shared_terms_description}= brief description of why items are grouped (e.g., "Related to telescope worktree functionality")
Effort Scaling Formula:
base_effort = 1 hour
scaled_effort = base_effort + (30 min * (item_count - 1))
Examples:
1 item → 1 hour
2 items → 1.5 hours (1h + 30min)
3 items → 2 hours (1h + 60min)
4 items → 2.5 hours (1h + 90min)
8.4.2: Combined Mode (grouping_mode == "combined")
Create single task containing all selected TODO items:
{
"title": "Address {item_count} TODO items",
"description": "Combined TODO items from scan:\n\n{all_items_list}\n\n---\n\nFiles: {unique_files_list}",
"language": "{detected from majority file type}",
"effort": "{scaled_effort}"
}
Where:
{item_count}= total number of selected TODO items{all_items_list}= formatted list of all items with checkboxes{unique_files_list}= comma-separated list of unique files involved
Effort Scaling: Same formula as grouped mode.
8.4.3: Separate Mode (grouping_mode == "separate" or default)
For each selected TODO item individually:
{
"title": "{tag content, truncated to 60 chars}",
"description": "{full tag content}\n\nSource: {file}:{line}",
"language": "{detected from file type}",
"effort": "1 hour"
}
Language Detection for Todo-Task (all modes):
.lua (nvim/) -> "neovim"
.tex -> "latex"
.md -> "markdown"
.py/.sh -> "general"
.opencode/* -> "meta"
8.5: Research-Tasks (if selected)
Condition: User selected "Research tasks" AND user selected specific QUESTION items
Check question_grouping_mode (from Step 7.7.4, defaults to "separate" if Step 7.7.4 was skipped):
8.5.1: Content-Based Language Detection for Research Tasks
IMPORTANT: Research task language is detected from the content of the question, NOT the source file type. This ensures questions are routed to the appropriate research agent based on what is being asked.
Keyword-to-Language Mapping:
neovim_keywords = ["nvim", "neovim", "plugin", "lazy", "telescope", "treesitter", "lsp", "buffer", "window", "keymap", "autocmd", "filetype", "lua"]
latex_keywords = ["theorem", "proof", "lemma", "axiom", "logic", "formula", "derivation", "proposition", "corollary", "latex", "tex"]
meta_keywords = [".claude", "command", "agent", "skill", "workflow", "state.json", "TODO.md", "specs/"]
function detect_research_language(question_content):
content_lower = question_content.lower()
# Check for neovim keywords
for keyword in neovim_keywords:
if keyword in content_lower:
return "neovim"
# Check for latex keywords
for keyword in latex_keywords:
if keyword in content_lower:
return "latex"
# Check for meta keywords
for keyword in meta_keywords:
if keyword in content_lower:
return "meta"
# Default to general for all other cases
return "general"
Examples:
- "What is the best way to configure LSP hover windows?" → neovim (contains "LSP")
- "How do I prove this theorem about completeness?" → latex (contains "theorem")
- "What is the difference between a skill and an agent?" → meta (contains "skill", "agent")
- "What are the best practices for API design?" → general (no matching keywords)
8.5.2: Grouped Mode (question_grouping_mode == "grouped")
For each topic group in question_topic_groups:
{
"title": "{topic_label}: {item_count} research questions",
"description": "Research questions related to {topic_label}:\n\n{question_list}\n\n---\n\nShared context: {shared_terms_description}",
"language": "{detected from majority question content in group}",
"effort": "{scaled_effort}"
}
Where:
{topic_label}= generated label (e.g., "LSP Configuration"){item_count}= number of items in group{question_list}= formatted list of questions using blockquote syntax:> {question text} > Source: `{file}:{line}` > {question text} > Source: `{file}:{line}`{shared_terms_description}= brief description of why questions are grouped
Effort Scaling Formula (research tasks use slightly higher base):
base_effort = 1.5 hours (research requires more exploration)
scaled_effort = base_effort + (30 min * (item_count - 1))
Examples:
1 item → 1-2 hours
2 items → 2 hours (1.5h + 30min)
3 items → 2.5 hours (1.5h + 60min)
4 items → 3 hours (1.5h + 90min)
Language Detection for Grouped Mode: Analyze all question content in the group, use the most frequently detected language. If tie, default to "general".
8.5.3: Combined Mode (question_grouping_mode == "combined")
Create single task containing all selected QUESTION items:
{
"title": "Research: {item_count} questions",
"description": "Research questions from scan:\n\n{all_questions_list}\n\n---\n\nFiles: {unique_files_list}",
"language": "{detected from majority question content}",
"effort": "{scaled_effort}"
}
Where:
{item_count}= total number of selected QUESTION items{all_questions_list}= formatted list of all questions with blockquotes{unique_files_list}= comma-separated list of unique source files
Effort Scaling: Same formula as grouped mode.
8.5.4: Separate Mode (question_grouping_mode == "separate" or default)
For each selected QUESTION item individually:
{
"title": "Research: {question content, truncated to 60 chars}",
"description": "> {full question text}\n\nSource: `{file}:{line}`",
"language": "{detected from question content}",
"effort": "1-2 hours"
}
Language Detection: Apply content-based detection (Step 8.5.1) to the individual question.
Step 9: Update State Files
For each task created:
9.1: Update state.json
Read current state, add new task entry, increment next_project_number:
# Create slug from title
slug=$(echo "$title" | tr '[:upper:]' '[:lower:]' | tr ' ' '_' | tr -cd 'a-z0-9_' | cut -c1-50)
# Read current state
current=$(cat specs/state.json)
# Add task using jq (use two-step pattern to avoid escaping issues)
# Step 1: Write task data to temp file
# Step 2: Use jq with slurpfile
For fix-it task when has_note_dependency is TRUE, include dependencies array:
{
"project_number": {N},
"project_name": "{slug}",
"status": "not_started",
"language": "{language}",
"dependencies": [learn_it_task_num]
}
For all other tasks, no dependencies field needed.
9.2: Update TODO.md
CRITICAL — Batch Insertion: Learn may create multiple tasks (learn-it, fix-it, TODO, research). Build a single batch_markdown string by joining all task entries with \n\n, then use ONE Edit tool call:
oldString: "## Tasks\n"
newString: "## Tasks\n\n{batch_markdown}\n"
WARNING: DO NOT search for the last --- separator and append text after it.
DO NOT insert at the bottom of the file.
DO NOT prepend each task individually — individual prepending reverses task order (last task becomes first).
ALWAYS use the heading-anchored Edit tool pattern with oldString: "## Tasks\n".
The heading ## Tasks is unique in TODO.md and is the only reliable insertion anchor.
After inserting, re-read the first few lines after ## Tasks:
- Confirm the first task after ## Tasks has the expected task number
- If it doesn't match, the insertion went wrong — fix and re-verify
Task entry format (no dependency):
### {N}. {Title}
- **Effort**: {estimate}
- **Status**: [NOT STARTED]
- **Language**: {language}
- **Started**: {timestamp}
**Description**: {description}
---
Task entry format when has_note_dependency is TRUE:
### {N}. {Title}
- **Effort**: {estimate}
- **Status**: [NOT STARTED]
- **Language**: {language}
- **Dependencies**: {learn_it_task_num}
- **Started**: {timestamp}
**Description**: {description}
---
Step 10: Display Results
Show summary of created tasks:
## Tasks Created from Tags
**Tags Processed**: {N} across scanned files
### Created Tasks
| # | Type | Title | Language |
|---|------|-------|----------|
| {N} | fix-it | Fix issues from FIX:/NOTE: tags | {lang} |
| {N+1} | learn-it | Update context files from NOTE: tags | meta |
| {N+2} | todo | {title} | {lang} |
| {N+3} | research | Research: {question title} | {lang} |
---
**Next Steps**:
1. Review tasks in TODO.md
2. Run `/research {first_task}` to begin
3. Progress through /research -> /plan -> /implement cycle
Step 11: Git Commit (Postflight)
If tasks were created, commit changes:
task_count={number of tasks created}
git add specs/TODO.md specs/state.json
git commit -m "learn: create $task_count tasks from tags
Session: $session_id
Error Handling
Path Access Errors
When paths don't exist or can't be accessed:
- Log warning for each invalid path
- Continue with valid paths
- If no valid paths remain, report and exit
No Tags Found
This is NOT an error condition:
- Report informatively
- Exit without prompts
state.json Update Failure
If jq fails:
- Log error with command and output
- Try two-step jq pattern
- If still failing, report partial success (tags found but tasks not created)
TODO.md Parse Error
If TODO.md format is corrupted:
- Log error
- Skip TODO.md update
- State.json update may still succeed
- Report partial success
Git Commit Failure
Non-blocking:
- Log the failure
- Tasks are still created successfully
- Report that commit failed but tasks exist
Standards Reference
This skill implements the multi-task creation pattern. See .opencode/docs/reference/standards/multi-task-creation-standard.md for the complete standard.
Compliance Level: Full (all required components)
| Component | Status | Notes |
|---|---|---|
| Discovery | Yes | Tag scanning (FIX:, NOTE:, TODO:, QUESTION:) |
| Selection | Yes | AskUserQuestion with multiSelect |
| Grouping | Yes | Topic clustering (Step 7.5 for TODO, Step 7.7 for QUESTION) |
| Dependencies | Partial | Internal only (learn-it -> fix-it in Step 8.2) |
| Ordering | No | Sequential creation |
| Visualization | No | Not implemented |
| Confirmation | Yes | Implicit via selection |
| State Updates | Yes | Atomic updates (Step 9) |
Limitation: External dependencies (TODO tasks depending on existing tasks) not implemented. Consider as future enhancement.
先判断是否适合
作者设计意图
作者的方法与取舍
边界和复核