--- name: skill-web-research description: Conduct web development research using framework docs and codebase exploration. Invoke for web research tasks. allowed-tools: Task, Bash, Edit, Read, Write, Read(/tmp/*.json), Bash(rm:*) --- # Web Research Skill Thin wrapper that delegates web research to `web-research-agent` subagent. **IMPORTANT**: This skill implements the skill-internal postflight pattern. After the subagent returns, this skill handles all postflight operations (status update, artifact linking, git commit) before returning. ## Context References Reference (do not load eagerly): - Path: `.opencode/context/core/formats/return-metadata-file.md` - Metadata file schema - Path: `.opencode/context/core/patterns/postflight-control.md` - Marker file protocol - Path: `.opencode/context/core/patterns/jq-escaping-workarounds.md` - jq escaping patterns (Issue #1132) ## Trigger Conditions This skill activates when: - Task language is "web" - Research is needed for web development tasks - Astro, Tailwind, Cloudflare, or accessibility documentation needs to be gathered --- ## Execution Flow ### Stage 1: Input Validation Validate required inputs: - `task_number` - Must be provided and exist in state.json - `focus_prompt` - Optional focus for research direction ```bash # Lookup task task_data=$(jq -r --argjson num "$task_number" \ '.active_projects[] | select(.project_number == $num)' \ specs/state.json) # Validate exists if [ -z "$task_data" ]; then return error "Task $task_number not found" fi # Extract fields language=$(echo "$task_data" | jq -r '.language // "web"') status=$(echo "$task_data" | jq -r '.status') project_name=$(echo "$task_data" | jq -r '.project_name') description=$(echo "$task_data" | jq -r '.description // ""') ``` --- ### Stage 2: Preflight Status Update Update task status to "researching" BEFORE invoking subagent. **Update state.json**: ```bash jq --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ --arg status "researching" \ --arg sid "$session_id" \ '(.active_projects[] | select(.project_number == '$task_number')) |= . + { status: $status, last_updated: $ts, session_id: $sid }' specs/state.json > /tmp/state.json && mv /tmp/state.json specs/state.json ``` **Update TODO.md**: Use Edit tool to change status marker to `[RESEARCHING]`. --- ### Stage 3: Create Postflight Marker ```bash padded_num=$(printf "%03d" "$task_number") mkdir -p "specs/${padded_num}_${project_name}" cat > "specs/${padded_num}_${project_name}/.postflight-pending" << EOF { "session_id": "${session_id}", "skill": "skill-web-research", "task_number": ${task_number}, "operation": "research", "reason": "Postflight pending: status update, artifact linking, git commit", "created": "$(date -u +%Y-%m-%dT%H:%M:%SZ)" } EOF ``` --- ### Stage 4: Prepare Delegation Context ```json { "session_id": "sess_{timestamp}_{random}", "delegation_depth": 1, "delegation_path": ["orchestrator", "research", "skill-web-research"], "timeout": 3600, "task_context": { "task_number": N, "task_name": "{project_name}", "description": "{description}", "language": "web" }, "focus_prompt": "{optional focus}", "metadata_file_path": "specs/{NNN}_{SLUG}/.return-meta.json" } ``` --- ### Stage 5: Invoke Subagent **CRITICAL**: You MUST use the **Task** tool to spawn the subagent. ``` Tool: Task (NOT Skill) Parameters: - subagent_type: "web-research-agent" - prompt: [Include task_context, delegation_context, focus_prompt, metadata_file_path] - description: "Execute web research for task {N}" ``` The subagent will: - Search local web project files (src/, public/) - Search web for framework documentation - Analyze findings and synthesize recommendations - Create research report - Write metadata file - Return brief text summary --- ### Stage 6: Parse Subagent Return ```bash metadata_file="specs/${padded_num}_${project_name}/.return-meta.json" if [ -f "$metadata_file" ] && jq empty "$metadata_file" 2>/dev/null; then status=$(jq -r '.status' "$metadata_file") artifact_path=$(jq -r '.artifacts[0].path // ""' "$metadata_file") artifact_type=$(jq -r '.artifacts[0].type // ""' "$metadata_file") artifact_summary=$(jq -r '.artifacts[0].summary // ""' "$metadata_file") else status="failed" fi ``` --- ### Stage 7: Update Task Status (Postflight) If status is "researched", update state.json and TODO.md. --- ### Stage 8: Link Artifacts Add artifact to state.json with summary. **IMPORTANT**: Use two-step jq pattern to avoid Issue #1132 escaping bug. See `jq-escaping-workarounds.md`. ```bash if [ -n "$artifact_path" ]; then # Step 1: Filter out existing research artifacts (use "| not" pattern to avoid != escaping - Issue #1132) jq '(.active_projects[] | select(.project_number == '$task_number')).artifacts = [(.active_projects[] | select(.project_number == '$task_number')).artifacts // [] | .[] | select(.type == "research" | not)]' \ specs/state.json > /tmp/state.json && mv /tmp/state.json specs/state.json # Step 2: Add new research artifact jq --arg path "$artifact_path" \ --arg type "$artifact_type" \ --arg summary "$artifact_summary" \ '(.active_projects[] | select(.project_number == '$task_number')).artifacts += [{"path": $path, "type": $type, "summary": $summary}]' \ specs/state.json > /tmp/state.json && mv /tmp/state.json specs/state.json fi ``` **Update TODO.md**: Add research artifact link. **Strip specs/ prefix for TODO.md** (TODO.md is inside specs/): `todo_link_path="${artifact_path#specs/}"` ```markdown - **Research**: [research-{NNN}.md]({todo_link_path}) ``` --- ### Stage 9: Git Commit ```bash git add -A git commit -m "task ${task_number}: complete research Session: ${session_id} Co-Authored-By: Claude Opus 4.5 " ``` --- ### Stage 10: Cleanup ```bash rm -f "specs/${padded_num}_${project_name}/.postflight-pending" rm -f "specs/${padded_num}_${project_name}/.postflight-loop-guard" rm -f "specs/${padded_num}_${project_name}/.return-meta.json" ``` --- ### Stage 11: Return Brief Summary ``` Research completed for task {N}: - Found framework documentation and project patterns - Identified implementation approach with accessibility considerations - Created report at specs/{NNN}_{SLUG}/reports/research-{NNN}.md - Status updated to [RESEARCHED] - Changes committed ``` --- ## Error Handling ### Input Validation Errors Return immediately if task not found. ### Metadata File Missing Keep status as "researching" for resume. ### Git Commit Failure Non-blocking: Log failure but continue. --- ## Return Format Brief text summary (NOT JSON). Example successful return: ``` Research completed for task 412: - Found Astro component patterns and Tailwind v4 styling approaches - Identified accessibility requirements for interactive elements - Created report at specs/412_add_blog_section/reports/research-001.md - Status updated to [RESEARCHED] - Changes committed with session sess_1736700000_abc123 ``` Example partial return: ``` Research partially completed for task 412: - Found local project patterns - Web search failed due to network error - Partial report created at specs/412_add_blog_section/reports/research-001.md - Status remains [RESEARCHING] - run /research 412 to continue ```