From 78db4454b06b31f4a458b4164ae99570c2827c54 Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Sun, 21 Jun 2026 10:04:10 +0000 Subject: [PATCH] feat(skills): add research skill for web-sourced reference file generation Standalone /research skill that scans the codebase, discovers canonical sources via websearch, reads and deepens in parallel via subagents, and writes structured topic files + sources.md to an explicit output path. Co-Authored-By: Claude Sonnet 4.6 --- .agents/evals/research/research/eval.yaml | 95 +++++++++++++++++++ .agents/skills/research/META.md | 11 +++ .agents/skills/research/SKILL.md | 89 +++++++++++++++++ .../skills/research/references/file-format.md | 39 ++++++++ .agents/skills/research/references/topics.md | 17 ++++ 5 files changed, 251 insertions(+) create mode 100644 .agents/evals/research/research/eval.yaml create mode 100644 .agents/skills/research/META.md create mode 100644 .agents/skills/research/SKILL.md create mode 100644 .agents/skills/research/references/file-format.md create mode 100644 .agents/skills/research/references/topics.md diff --git a/.agents/evals/research/research/eval.yaml b/.agents/evals/research/research/eval.yaml new file mode 100644 index 0000000..58d6ebe --- /dev/null +++ b/.agents/evals/research/research/eval.yaml @@ -0,0 +1,95 @@ +skill_name: research + +trigger_tests: + - id: explicit-basic + name: "Explicit trigger — basic invocation with topic and path" + query: "/research stripe .agents/skills/stripe/references/" + should_trigger: true + + - id: explicit-with-urls + name: "Explicit trigger — topic, path, and starting URLs provided" + query: "Research the FastMCP library and put refs in .agents/skills/mcp/references/ — start here: https://fastmcp.dev/llms.txt" + should_trigger: true + + - id: implicit-pre-skill + name: "Implicit trigger — looking up docs before writing a skill" + query: "Before we write the GitHub Actions skill, can you look up the API and put the docs somewhere useful?" + should_trigger: true + + - id: negative-write-docs + name: "Negative — documenting existing code goes to write-docs" + query: "Document the auth module for me" + should_trigger: false + + - id: negative-diagnose + name: "Negative — debugging investigation goes to diagnose" + query: "Research why these integration tests are failing" + should_trigger: false + + - id: negative-neuledge + name: "Negative — MCP server setup goes to neuledge-context" + query: "Install the neuledge context server and set it up" + should_trigger: false + +output_tests: + - id: sources-always-written + name: "sources.md is always produced at the output path" + type: deterministic + prompt: "/research redis .agents/skills/redis/references/" + expected_output: >- + A sources.md file written to .agents/skills/redis/references/sources.md + containing at least one source section with a URL and status field. + assertions: + - "Output path .agents/skills/redis/references/sources.md is created" + - "sources.md contains at least one ## section" + - "Each section in sources.md includes a URL: line and a Status: line" + + - id: topic-frontmatter + name: "Every topic file has required frontmatter fields" + type: deterministic + prompt: "/research stripe .agents/skills/stripe/references/" + expected_output: >- + One or more topic .md files written to .agents/skills/stripe/references/, + each with YAML frontmatter containing topic: and source_keys: fields. + assertions: + - "Every .md file except sources.md contains a YAML frontmatter block delimited by ---" + - "Every topic file frontmatter contains a topic: field" + - "Every topic file frontmatter contains a source_keys: field with at least one entry" + + - id: no-empty-files + name: "No topic files written when no content is found" + type: deterministic + prompt: "/research xyzzy-nonexistent-tool-404 /tmp/refs-test/" + expected_output: >- + No topic .md files written. Skill reports what was searched and asks user + to provide starting URLs. sources.md may still be written if sources were attempted. + assertions: + - "Skill does not write any topic .md files to the output path" + - "Skill reports the search terms or URLs it tried" + - "Skill asks the user to provide starting URLs or confirm the topic name" + + - id: output-path-respected + name: "All files written inside the provided output path only" + type: deterministic + prompt: "/research openai .agents/skills/openai/references/" + expected_output: >- + All written files are under .agents/skills/openai/references/. No files + created outside that directory. + assertions: + - "Every file path in the write operations starts with .agents/skills/openai/references/" + - "No files are written to the current working directory root or any other path" + + - id: content-quality + name: "Extracted content is relevant, concise, and well-organised" + type: llm-rubric + prompt: "/research fastapi .agents/skills/fastapi/references/" + expected_output: >- + A set of topic files covering FastAPI concepts relevant to skill authoring: + installation, API reference, configuration, and examples at minimum. Content + is concise summaries, not verbatim page dumps. sources.md accurately maps + each source to the files it contributed to. + assertions: + - "Topic files cover concepts relevant to FastAPI (routing, request handling, dependency injection, or similar) — not generic web framework content" + - "Body prose in each topic file is a synthesis or extraction, not a verbatim copy of the source page" + - "source_keys in each topic file match slugs present in sources.md" + - "sources.md contributing files list accurately reflects which topic files each source contributed to" diff --git a/.agents/skills/research/META.md b/.agents/skills/research/META.md new file mode 100644 index 0000000..cb35c08 --- /dev/null +++ b/.agents/skills/research/META.md @@ -0,0 +1,11 @@ +```yaml +version: "1.0" +updated: 2026-06-21 + +when: >- + Invoked when the user wants to gather structured reference documentation for a + tool, library, or API from web sources. Typically run before writing a new skill + that wraps an external tool, or any time reference files are needed for a topic. + Triggered explicitly ("/research ") or implicitly when the user + asks to look up, gather, or pull docs for a topic before implementing something. +``` diff --git a/.agents/skills/research/SKILL.md b/.agents/skills/research/SKILL.md new file mode 100644 index 0000000..0ff8ff7 --- /dev/null +++ b/.agents/skills/research/SKILL.md @@ -0,0 +1,89 @@ +--- +name: research +description: >- + Use when the user wants to research a topic and generate structured reference + markdown files from web sources. Handles: finding canonical docs for a + tool/library/API, reading and deepening into linked pages, organizing extracted + content into topic files (overview, installation, configuration, cli-reference, + api-reference, examples, troubleshooting). Do NOT use when the user wants to + write documentation from existing code or specs (use write-docs), install or + query a specific documentation MCP server (use neuledge-context), or research + a bug/incident (use diagnose). +metadata: + category: research +allowed-tools: + - WebSearch + - WebFetch + - Read + - Write +model: sonnet +--- + + + +## Required inputs + +- **Topic** — the subject to research (tool, library, API, concept); inferred from user description if clear, ask if ambiguous +- **Output path** — directory where reference files will be written; must be provided explicitly — do not infer or default +- **Starting URLs** — optional; if provided, skip discovery websearch and read these first + +## Constraints + +- Never write files outside the explicitly provided output path +- Skip any default topic file if no relevant content is found for it — do not create empty files +- Create additional topic files beyond the default list when content warrants it (e.g. `webhooks.md`, `rate-limits.md`) +- Subagents handle parallel source reading and link deepening — the orchestrator writes all files; subagents return summaries only, never write directly +- `sources.md` is always written, even if only one source was read +- Each topic file must have frontmatter with `topic` and `source_keys`; body is prose only — no inline URLs +- Source keys in `sources.md` must be kebab-case slugs derived from the source domain or page title +- Default topic list and file format spec live in `references/` sub-files — read them at step 1 + + + + + +## Process + +1. **Scan codebase.** Search the working directory for existing usage of the topic — imports, config files, version pins, existing reference files. Use findings to narrow research scope (e.g. target the version already in use, skip topics already documented). Read `references/topics.md` for the default topic list and `references/file-format.md` for the output file format spec. + +2. **Discover sources.** If no starting URLs were provided, websearch for canonical documentation (prefer `llms.txt`, developer docs, official API references over tutorials or blog posts). Collect 3–5 candidate URLs before reading any. + +3. **Read sources in parallel.** Spawn one subagent per source URL. Each subagent fetches the page, extracts relevant content, identifies links worth deepening, and returns a structured summary (content by topic area + links to follow). Subagents do not write files. + +4. **Deepen.** For each subagent that returned links worth following, spawn child subagents per branch. Continue until content becomes repetitive or out of scope. Cap at ~10 additional pages total across all branches. + +5. **Consolidate.** Merge all subagent summaries by topic area. Identify which default topics have sufficient content and which custom topics emerged. + +6. **Write topic files.** For each topic with content, write `/.md` using the format in `references/file-format.md`. Orchestrator writes all files — never delegate file writing to a subagent. + +7. **Write `sources.md`.** Write `/sources.md` mapping each source slug to its URL, description, and list of topic files it contributed to. Include sources that yielded no content, marked `no content extracted`. + +## Output format + +- `/.md` per topic with content — formatted per `references/file-format.md` +- `/sources.md` — always produced; maps slug → URL, description, contributing files + + + + + +## Failure handling + +- Output path not provided — stop and ask; do not infer or default +- No sources found after websearch — report what was searched, ask user to provide starting URLs +- Subagent returns no usable content — skip that source, log in `sources.md` as `no content extracted` +- All topic files would be empty — stop, report what was searched, do not write any files + +## Self-check + +- [ ] Codebase scanned before any websearch was performed +- [ ] Output path was explicitly provided — not inferred +- [ ] `references/topics.md` and `references/file-format.md` read at step 1 +- [ ] No topic file written without content +- [ ] `sources.md` written with all sources read (including those with no content extracted) +- [ ] All file writes performed by the orchestrator, not subagents +- [ ] Each topic file has `topic` and `source_keys` frontmatter fields +- [ ] All source keys in topic files have a matching entry in `sources.md` +- [ ] No files written outside the provided output path + + diff --git a/.agents/skills/research/references/file-format.md b/.agents/skills/research/references/file-format.md new file mode 100644 index 0000000..ad3b18b --- /dev/null +++ b/.agents/skills/research/references/file-format.md @@ -0,0 +1,39 @@ +# Reference file format + +Every topic file follows this structure. + +## Frontmatter + +```yaml +--- +topic: # matches the filename without .md (e.g. "api-reference") +source_keys: # kebab-case slugs of sources that contributed; must match sources.md entries + - + - +--- +``` + +## Body + +Plain prose organized into markdown sections (`##`, `###`). Extract the content most relevant to skill authoring or implementation — not a verbatim copy of the source. Focus on: +- Decisions that affect how to call the API or tool +- Options, flags, or parameters with non-obvious behavior +- Constraints, rate limits, or gotchas +- Canonical patterns the skill should follow + +No inline URLs in the body — all source traceability lives in `sources.md` via `source_keys`. + +## sources.md format + +```markdown +# Sources + +## + +- **URL:** +- **Description:** +- **Contributing files:** +- **Status:** `extracted` | `no content extracted` +``` + +Use one `##` section per source. Slugs are kebab-case derived from the domain or page title (e.g. `stripe-api-docs`, `openai-python-sdk-readme`). diff --git a/.agents/skills/research/references/topics.md b/.agents/skills/research/references/topics.md new file mode 100644 index 0000000..da0c6dd --- /dev/null +++ b/.agents/skills/research/references/topics.md @@ -0,0 +1,17 @@ +# Default topic list + +Create one file per topic when relevant content is found. Skip topics with no content. Add custom topics when content warrants it. + +| File | Covers | +|---|---| +| `overview.md` | What it is, key concepts, mental model, architecture summary | +| `installation.md` | Setup, dependencies, prerequisites, version requirements | +| `configuration.md` | Config files, options, environment variables, defaults | +| `cli-reference.md` | Commands, subcommands, flags, exit codes | +| `api-reference.md` | Endpoints, SDK methods, types, request/response shapes | +| `examples.md` | Common usage patterns, recipes, quickstart walkthroughs | +| `troubleshooting.md` | Known issues, error codes, gotchas, workarounds | + +## Custom topics + +Create additional topic files when content doesn't fit the defaults. Examples: `webhooks.md`, `rate-limits.md`, `authentication.md`, `migrations.md`, `security.md`. Use kebab-case filenames.