- name
- skill-learn
- description
- Scan codebase for FIX:/NOTE:/TODO:/QUESTION: tags and create structured tasks with interactive selection. Invoke for /learn command.
# 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:
```bash
# 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:
```bash
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)**:
```bash
grep -rn --include="*.lua" "-- FIX:" $paths 2>/dev/null || true
```
**LaTeX files**:
```bash
grep -rn --include="*.tex" "% FIX:" $paths 2>/dev/null || true
```
**Markdown files**:
```bash
grep -rn --include="*.md" "<!-- FIX:" $paths 2>/dev/null || true
```
**Python/Shell/YAML files**:
```bash
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)**:
```bash
grep -rn --include="*.lua" "-- QUESTION:" $paths 2>/dev/null || true
```
**LaTeX files**:
```bash
grep -rn --include="*.tex" "% QUESTION:" $paths 2>/dev/null || true
```
**Markdown files**:
```bash
grep -rn --include="*.md" "<!-- QUESTION:" $paths 2>/dev/null || true
```
**Python/Shell/YAML files**:
```bash
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: tags
- `note_tags[]` - All NOTE: tags
- `todo_tags[]` - All TODO: tags
- `question_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:
```json
{
"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)
```json
{
"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:
```json
{
"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**:
1. Start with first TODO as initial group
2. 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
3. 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:
```json
{
"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)
```json
{
"question": "Select QUESTION items to create as research tasks:",
"header": "QUESTION Selection",
GitHubで見る