Files
holocron/plugins/bin/.apm/skills/research/SKILL.md
Defame1297 5e232503c4 feat(kyberforge): execute plugin-to-apm marketplace conversion
Why:
ADR-0015 established that Microsoft APM (apm.yml + .apm/) should replace
this repo's hand-authored plugin.json/marketplace.json model, with those
files becoming compiled output of `apm pack` instead of files edited by
hand via the (now-retired) plugin-author/marketplace-author skills.
Issue #90 was the deferred execution of that decision, gated on #88
(apm tooling) and #89 (apm-native agent-author/skill-author routing).

Implementation notes:
- All six plugins (bin, core, git, gitea, kyberforge, lint) now carry
  apm.yml + .apm/{skills,agents,hooks} as their authoring source. Skills
  moved with a plain git mv (content-identical across targets). Agents
  were re-authored, not moved: per ADR-0016, .apm/agents/*.agent.md
  compiles verbatim to both Claude and Copilot, so plugin-scope agents
  now carry only name/description/model/source_keys -- no tools: field,
  no Claude-only knobs (isolation, maxTurns, effort, memory,
  permissionMode).
- Root apm.yml registers all 7 marketplace packages (6 local plus
  mattpocock-skills as a remote entry) under versioning: per_package,
  matching this repo's existing independent-plugin-versioning practice.
- .claude-plugin/marketplace.json and every plugin's plugin.json are now
  apm-pack-compiled output, verified against the prior hand-maintained
  content: same names/descriptions/versions/licenses/authors, only
  cosmetic serialization differences (JSON key order, owner email vs.
  url, Unicode escaping).
- plugin-author and marketplace-author are retired now that apm-based
  authoring fully replaces their job; kyberforge bumped 1.3.1 -> 1.4.0
  for that removal, and the root marketplace catalog bumped
  0.3.1 -> 0.3.2 to match, per the version-bump convention now
  documented in apm-workflow's reference docs instead of a dedicated
  script (apm has no native version-bump automation).
- Fixed hardcoded pre-.apm/ path assumptions across
  .pre-commit-config.yaml, .pre-commit-hooks.yaml,
  scripts/check-scope-walkup-sync.sh, scripts/sync-vale-styles.sh,
  scripts/check-vale-style-sync.sh, six plugins' root plugin.json
  (stale skills/hooks/agents pointer fields that check-manifests.sh
  validates), and several tests/*.bats and tests/*.sh fixtures --
  including a bats REPO_ROOT relative-path depth bug (10 files, one
  extra .apm/ directory level to walk up) and a vale probe-path
  isolation regression introduced mid-fix.
- Corrected empirically-wrong assumptions surfaced this session in
  apm-workflow/apm-install's own reference docs: `apm marketplace
  package add` does not accept local paths (only owner/repo remote
  shorthand -- local packages are registered by editing apm.yml's
  marketplace.packages[] directly); `apm compile` is a consumer-side
  AGENTS.md/CLAUDE.md generator, not the plugin.json producer, and
  hard-fails on skill/agent-only packages without --clean; `apm plugin
  init <name>` nests a stray subdirectory when run with a positional
  name arg from inside a same-named directory; no native Copilot
  marketplace output profile exists; .mcp.json is merged into the
  compiled plugin.json content-aware and target-scoped, with no
  dependencies.mcp entry needed for simple passthrough; pipx is the
  correct pip fallback on externally-managed Python environments.
- Renamed agent-author's copilot.agent.md template asset to
  copilot.agent.md.template so apm compile's recursive *.agent.md glob
  stops misparsing the placeholder template as a real agent primitive.

Impact:
plugin.json and marketplace.json are compiled artifacts from here on --
editing them by hand is no longer the workflow; edit apm.yml/.apm/ and
run apm pack. CONTEXT.md's Plugin/Plugin marketplace glossary entries
reflect this. ADR-0001 is marked superseded, ADR-0006 moot, and
ADR-0010 updated for the new .apm/agents/ path (project/user scope
unaffected, per ADR-0016). Full local verification: claude plugin
validate --strict on all 6 plugins, apm audit --ci, apm marketplace
check, check-manifests.sh, and the full test suite (165/165 bats,
13/13 shell scripts) all pass clean.

Fixes: #90
Refs: #88, #89
ADR: 0015
ADR: 0016

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub96PyaSRD9BHPktotj1pC
2026-08-12 18:21:24 +00:00

6.3 KiB
Raw Blame History

name, description, metadata, allowed-tools, model
name description metadata allowed-tools model
research Use when the user wants to research a topic and generate structured reference markdown files. Handles: finding canonical docs for a tool/library/API via Context7 MCP or web sources, 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 manage the neuledge-context MCP server (use neuledge-context), or research a bug/incident (use diagnose).
category
research
WebSearch
WebFetch
Read
Write
mcp__context7__resolve-library-id
mcp__context7__query-docs
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
  • Context7 MCP calls (resolve-library-id, query-docs) are made only by the orchestrator at step 2 — subagents must not call them
  • 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 for web sources; for Context7 sources use context7-<library-slug> (e.g. context7-vercel-next-js)
  • 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. Try Context7. If the topic is a library, framework, or API and no starting URLs were provided, call resolve-library-id with the topic name and the user's question. If a match resolves, call query-docs once per default topic area (see references/topics.md). Treat each response as a source summary with slug context7-<library-slug> (e.g. context7-vercel-next-js). A topic area has sufficient content when the Context7 response contains at least one substantive paragraph — not a "no results" message, redirect notice, or header-only boilerplate. Mark covered topic areas — skip their subagent web reads in step 4. If the library does not resolve, or starting URLs were provided (explicit source choice by the user), skip this step entirely.

  3. Discover sources. For topics not covered by Context7 (or when no starting URLs were provided and Context7 did not resolve), 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.

  4. 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.

  5. 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.

  6. Consolidate. Merge all subagent summaries (Context7 and web) by topic area. Identify which default topics have sufficient content and which custom topics emerged.

  7. Write topic files. For each topic with content, write <output-path>/<topic>.md using the format in references/file-format.md. Orchestrator writes all files — never delegate file writing to a subagent.

  8. Write sources.md. Write <output-path>/sources.md mapping each source slug to its URL (use context7:<library-id> as the URL for Context7 sources), description, and list of topic files it contributed to. Include sources that yielded no content, marked no content extracted.

Output format

  • <output-path>/<topic>.md per topic with content — formatted per references/file-format.md
  • <output-path>/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
  • Context7 resolution attempted before websearch when topic is a library/framework/API
  • Context7 calls made only at orchestrator step 2 — no subagent called resolve-library-id or query-docs
  • Context7 sources recorded in sources.md with context7:<library-id> as URL
  • 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