* docs: turn README into an index and move reference detail to docs/guide The README had grown to 393 KB because every change appended its notes there. The text moves verbatim into 18 topic guides under docs/guide/; only headings are re-leveled and relative links re-pointed. The README keeps the introduction, a quick start and a guide index. Contributor test notes move to CONTRIBUTING.md. * docs: send user docs to topic guides and budget the root README The rule 'update README.md for user-facing changes' is what grew the README. Guidance now points to docs/guide/, and check_agent_guidance.py fails when the root README exceeds 16 KiB (AG003). * chore: remove unreferenced screenshots and finished plan notes pr-build/ holds two PR screenshots (3 MB) from #1986. plans/ holds the plan for the merged #4049. docs/SKILL_NAME_CONFLICT_FIX.md is a February change note. Nothing references them. * docs: route always-loaded AGENTS.md files to scoped guides * docs(agents): cut scoped guides to scope, verify, traps, decisions Each AGENTS.md keeps four kinds of content: the scope of the directory, the verification commands, traps a local test run does not show, and decisions the code cannot state. Values, field lists, function inventories, test names, issue numbers and history are deleted, because the code, the tests and git state them. Search and fetch providers share one community guide. Four guides with no remaining content are removed. The size check now allows 6 KiB per file (hard limit 8 KiB) and 24 KiB per chain (hard limit 32 KiB). * style: format frontend guide table and guidance test imports --------- Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Develop an extension from an existing example
Start with the smallest example that covers your extension. Each directory is an
independent Python package using the public deerflow-extension-api contract.
| Start here | What it demonstrates |
|---|---|
| Extension example | Middleware, task lifecycle, model observations, services, and HTTP routes. Start here for backend extensions. |
| Conversation bookmarks | A browser page, conversation action, backend actions, packaged resources, and a model tool. Start here for full-stack plugins. |
| Agent teams | Full Agent orchestration. Use this after the basic contribution and lifecycle patterns are familiar. |
Additional examples cover text-list classification, context pruning, advisory screening of fetched content, and sectioned long-form report writing.
Describe the extension
Package deerflow-extension.json beside the entrypoint's Python module (beside
__init__.py for a package). Capability Center renders this public description
without requiring a browser module. Use the full-stack plugin namespace as id,
or a unique stable ID for a backend-only extension. A v1 document requires an ID,
at least one locale, and a nonempty title, description (purpose) and
usage list in every supplied locale. requirements and docs_url are optional;
omit requirements when none apply. Keep secrets and deployment configuration out
of this file. Names, purposes and instructions are authored by the package;
loaded/enabled state and registered tools come from the host.
{
"schema_version": 1,
"id": "company.helper",
"locales": {
"en-US": {
"title": "Task statistics",
"description": "Collect tool-call statistics during tasks.",
"usage": [
{"title": "Run a task", "description": "Statistics are collected automatically after activation."}
]
}
}
}
The packaging checker validates this file when present and detects omitted wheel resources. Older packages without it remain compatible. Invalid optional copy produces a startup diagnostic while the working extension remains available. Gateway reads copy at startup only, after successful registration. Disabled and failed packages are not imported for documentation; a catalog entry alone does not prove activation. A documented backend extension with actual registrations appears in discovery even if it supplies no full-stack plugin.
For bundled examples, update their package files and run
python scripts/sync_extension_documentation.py from the repository root. The
generated frontend snapshot supplies descriptions before installation; installed
package copy takes precedence. Backend tests check that the snapshot is current.
Edit, test, check, then install
-
Copy the selected example outside the DeerFlow checkout. Rename its Python package, distribution and
deerflow.extensionsentry point. For a full-stack plugin, also choose its own namespace and browser module name. -
Follow the example's README to configure its dependencies and run its tests. Keep package behavior tests alongside the extension. For a bundled example with a
tests/directory, CI installs the package with itsdevextra next to this checkout'sdeerflow-extension-api, then runspytest,ruff checkandruff format --check. -
From the DeerFlow checkout root, prepare the backend environment with
make -C backend install, then check the package:uv run --project backend --no-sync python scripts/check_extension.py /absolute/path/to/your-extensionTo try the checker on an unchanged example:
uv run --project backend --no-sync python scripts/check_extension.py examples/deerflow-extension-bookmarks -
Follow that example's deployment and try-it instructions. Restart Gateway, refresh the browser when applicable, and exercise the installed feature. Use
make extension-upgrade SOURCE=/absolute/path/to/your-extensionto apply later source edits: local installs are snapshots.
What the checker covers
The script builds a wheel in a temporary directory, checks exactly one extension
entry point and its packaged Python module, parses packaged Python syntax, and
checks that the API dependency range accepts this checkout's contract version.
It validates conventional ui_manifest.json resources with the same validator
used by Gateway, including detecting manifests left out of the wheel in flat or
src/ layouts. A custom manifest filename needs an explicit wheel-relative path:
uv run --project backend --no-sync python scripts/check_extension.py /absolute/path/to/your-extension --manifest your_package/resources.json
The build executes the package's build backend, so check trusted sources. The
checker does not import the extension, call install(), install the extension, or
change deployment configuration. Registration/configuration behavior and the
@extension version marker are verified when loading the plugin; continue to run
the package tests and the installed feature after packaging checks pass.