From fcee6fa0474c1b79216141837076f83cf66615d3 Mon Sep 17 00:00:00 2001 From: Harold Hunt Date: Sat, 28 Mar 2026 20:22:03 -0400 Subject: [PATCH] Docs: add boundary AGENTS guides (#56647) --- AGENTS.md | 42 +++++++++++++++++++++++++++++ extensions/AGENTS.md | 47 +++++++++++++++++++++++++++++++++ extensions/CLAUDE.md | 1 + src/channels/AGENTS.md | 27 +++++++++++++++++++ src/channels/CLAUDE.md | 1 + src/gateway/protocol/AGENTS.md | 25 ++++++++++++++++++ src/gateway/protocol/CLAUDE.md | 1 + src/plugin-sdk/AGENTS.md | 48 ++++++++++++++++++++++++++++++++++ src/plugin-sdk/CLAUDE.md | 1 + src/plugins/AGENTS.md | 36 +++++++++++++++++++++++++ src/plugins/CLAUDE.md | 1 + 11 files changed, 230 insertions(+) create mode 100644 extensions/AGENTS.md create mode 120000 extensions/CLAUDE.md create mode 100644 src/channels/AGENTS.md create mode 120000 src/channels/CLAUDE.md create mode 100644 src/gateway/protocol/AGENTS.md create mode 120000 src/gateway/protocol/CLAUDE.md create mode 100644 src/plugin-sdk/AGENTS.md create mode 120000 src/plugin-sdk/CLAUDE.md create mode 100644 src/plugins/AGENTS.md create mode 120000 src/plugins/CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md index 986b395616e..d29cb96da52 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,6 +21,48 @@ - Extensions (channel plugins): `extensions/*` (e.g. `extensions/msteams`, `extensions/matrix`, `extensions/zalo`, `extensions/zalouser`, `extensions/voice-call`) - When adding channels/extensions/apps/docs, update `.github/labeler.yml` and create matching GitHub labels (use existing channel/extension label colors). +## Architecture Boundaries + +- Start here for the repo map: + - `extensions/*` = bundled plugins and the closest example surface for third-party plugins + - `src/plugin-sdk/*` = the public plugin contract that extensions are allowed to import + - `src/channels/*` = core channel implementation details behind the plugin/channel boundary + - `src/plugins/*` = plugin discovery, manifest validation, loader, registry, and contract enforcement + - `src/gateway/protocol/*` = typed Gateway control-plane and node wire protocol +- Progressive disclosure lives in local boundary guides: + - `extensions/AGENTS.md` + - `src/plugin-sdk/AGENTS.md` + - `src/channels/AGENTS.md` + - `src/plugins/AGENTS.md` + - `src/gateway/protocol/AGENTS.md` +- Plugin and extension boundary: + - Public docs: `docs/plugins/building-plugins.md`, `docs/plugins/architecture.md`, `docs/plugins/sdk-overview.md`, `docs/plugins/sdk-entrypoints.md`, `docs/plugins/sdk-runtime.md`, `docs/plugins/manifest.md`, `docs/plugins/sdk-channel-plugins.md`, `docs/plugins/sdk-provider-plugins.md` + - Definition files: `src/plugin-sdk/plugin-entry.ts`, `src/plugin-sdk/core.ts`, `src/plugin-sdk/provider-entry.ts`, `src/plugin-sdk/channel-contract.ts`, `scripts/lib/plugin-sdk-entrypoints.json`, `package.json` + - Rule: extensions must cross into core only through `openclaw/plugin-sdk/*`, manifest metadata, and documented runtime helpers. Do not import `src/**` from extension production code. + - Rule: core code and tests must not deep-import bundled plugin internals such as `extensions//src/**` or `extensions//onboard.js`. If core needs a bundled plugin helper, expose it through `extensions//api.ts` and, when it is a real cross-package contract, through `src/plugin-sdk/.ts`. + - Compatibility: new plugin seams are allowed, but they must be added as documented, backwards-compatible, versioned contracts. We have third-party plugins in the wild and do not break them casually. +- Channel boundary: + - Public docs: `docs/plugins/sdk-channel-plugins.md`, `docs/plugins/architecture.md` + - Definition files: `src/channels/plugins/types.plugin.ts`, `src/channels/plugins/types.core.ts`, `src/channels/plugins/types.adapters.ts`, `src/plugin-sdk/core.ts`, `src/plugin-sdk/channel-contract.ts` + - Rule: `src/channels/**` is core implementation. If plugin authors need a new seam, add it to the Plugin SDK instead of telling them to import channel internals. +- Provider/model boundary: + - Public docs: `docs/plugins/sdk-provider-plugins.md`, `docs/concepts/model-providers.md`, `docs/plugins/architecture.md` + - Definition files: `src/plugins/types.ts`, `src/plugin-sdk/provider-entry.ts`, `src/plugin-sdk/provider-auth.ts`, `src/plugin-sdk/provider-catalog-shared.ts`, `src/plugin-sdk/provider-model-shared.ts` + - Rule: core owns the generic inference loop; provider plugins own provider-specific behavior through registration and typed hooks. Do not solve provider needs by reaching into unrelated core internals. + - Rule: avoid ad hoc reads of `plugins.entries..config` from unrelated core code. If core needs plugin-owned auth/config behavior, add or use a generic seam (`resolveSyntheticAuth`, public SDK/helper facades, manifest metadata, plugin auto-enable hooks) and honor plugin disablement plus SecretRef semantics. + - Rule: vendor-owned tools and settings belong in the owning plugin. Do not add provider-specific tool config, secret collection, or runtime enablement to core `tools.*` surfaces unless the tool is intentionally core-owned. +- Gateway protocol boundary: + - Public docs: `docs/gateway/protocol.md`, `docs/gateway/bridge-protocol.md`, `docs/concepts/architecture.md` + - Definition files: `src/gateway/protocol/schema.ts`, `src/gateway/protocol/schema/*.ts`, `src/gateway/protocol/index.ts` + - Rule: protocol changes are contract changes. Prefer additive evolution; incompatible changes require explicit versioning, docs, and client/codegen follow-through. +- Bundled plugin contract boundary: + - Public docs: `docs/plugins/architecture.md`, `docs/plugins/manifest.md`, `docs/plugins/sdk-overview.md` + - Definition files: `src/plugins/contracts/registry.ts`, `src/plugins/types.ts`, `src/extensions/public-artifacts.ts` + - Rule: keep manifest metadata, runtime registration, public SDK exports, and contract tests aligned. Do not create a hidden path around the declared plugin interfaces. +- Extension test boundary: + - Keep extension-owned onboarding/config/provider coverage under `extensions//**` when feasible. + - If core tests need bundled plugin behavior, consume it through public `src/plugin-sdk/.ts` facades or `extensions//api.ts`, not private extension modules. + ## Docs Linking (Mintlify) - Docs are hosted on Mintlify (docs.openclaw.ai). diff --git a/extensions/AGENTS.md b/extensions/AGENTS.md new file mode 100644 index 00000000000..2ee72ff767a --- /dev/null +++ b/extensions/AGENTS.md @@ -0,0 +1,47 @@ +# Extensions Boundary + +This directory contains bundled plugins. Treat it as the same boundary that +third-party plugins see. + +## Public Contracts + +- Docs: + - `docs/plugins/building-plugins.md` + - `docs/plugins/architecture.md` + - `docs/plugins/sdk-overview.md` + - `docs/plugins/sdk-entrypoints.md` + - `docs/plugins/sdk-runtime.md` + - `docs/plugins/sdk-channel-plugins.md` + - `docs/plugins/sdk-provider-plugins.md` + - `docs/plugins/manifest.md` +- Definition files: + - `src/plugin-sdk/plugin-entry.ts` + - `src/plugin-sdk/core.ts` + - `src/plugin-sdk/provider-entry.ts` + - `src/plugin-sdk/channel-contract.ts` + - `scripts/lib/plugin-sdk-entrypoints.json` + - `package.json` + +## Boundary Rules + +- Extension production code should import from `openclaw/plugin-sdk/*` and its + own local barrels such as `./api.ts` and `./runtime-api.ts`. +- Do not import core internals from `src/**`, `src/channels/**`, + `src/plugin-sdk-internal/**`, or another extension's `src/**`. +- Do not use relative imports that escape the current extension package root. +- Keep plugin metadata accurate in `openclaw.plugin.json` and the package + `openclaw` block so discovery and setup work without executing plugin code. +- Treat files like `src/**`, `onboard.ts`, and other local helpers as private + unless you intentionally promote them through `api.ts` and, if needed, a + matching `src/plugin-sdk/.ts` facade. +- If core or core tests need a bundled plugin helper, export it from `api.ts` + first instead of letting them deep-import extension internals. + +## Expanding The Boundary + +- If an extension needs a new seam, add a typed Plugin SDK subpath or additive + export instead of reaching into core. +- Keep new plugin-facing seams backwards-compatible and versioned. Third-party + plugins consume this surface. +- When intentionally expanding the contract, update the docs, exported subpath + list, package exports, and API/contract checks in the same change. diff --git a/extensions/CLAUDE.md b/extensions/CLAUDE.md new file mode 120000 index 00000000000..47dc3e3d863 --- /dev/null +++ b/extensions/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/src/channels/AGENTS.md b/src/channels/AGENTS.md new file mode 100644 index 00000000000..7aee546fa1b --- /dev/null +++ b/src/channels/AGENTS.md @@ -0,0 +1,27 @@ +# Channels Boundary + +`src/channels/**` is core channel implementation. Plugin authors should not +import from this tree directly. + +## Public Contracts + +- Docs: + - `docs/plugins/sdk-channel-plugins.md` + - `docs/plugins/architecture.md` + - `docs/plugins/sdk-overview.md` +- Definition files: + - `src/channels/plugins/types.plugin.ts` + - `src/channels/plugins/types.core.ts` + - `src/channels/plugins/types.adapters.ts` + - `src/plugin-sdk/core.ts` + - `src/plugin-sdk/channel-contract.ts` + +## Boundary Rules + +- Keep extension-facing channel surfaces flowing through `openclaw/plugin-sdk/*` + instead of direct imports from `src/channels/**`. +- When a bundled or third-party channel needs a new seam, add a typed SDK + contract or facade first. +- Remember that shared channel changes affect both built-in and extension + channels. Check routing, pairing, allowlists, command gating, onboarding, and + reply behavior across the full set. diff --git a/src/channels/CLAUDE.md b/src/channels/CLAUDE.md new file mode 120000 index 00000000000..47dc3e3d863 --- /dev/null +++ b/src/channels/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/src/gateway/protocol/AGENTS.md b/src/gateway/protocol/AGENTS.md new file mode 100644 index 00000000000..2293c7ab94f --- /dev/null +++ b/src/gateway/protocol/AGENTS.md @@ -0,0 +1,25 @@ +# Gateway Protocol Boundary + +This directory defines the Gateway wire contract for operator clients and +nodes. + +## Public Contracts + +- Docs: + - `docs/gateway/protocol.md` + - `docs/gateway/bridge-protocol.md` + - `docs/concepts/architecture.md` +- Definition files: + - `src/gateway/protocol/schema.ts` + - `src/gateway/protocol/schema/*.ts` + - `src/gateway/protocol/index.ts` + +## Boundary Rules + +- Treat schema changes as protocol changes, not local refactors. +- Prefer additive evolution. If a change is incompatible, handle versioning + explicitly and update all affected clients. +- Keep schema, runtime validators, docs, tests, and generated client artifacts + in sync. +- New Gateway methods, events, or payload fields should land through the typed + protocol definitions here rather than ad hoc JSON shapes elsewhere. diff --git a/src/gateway/protocol/CLAUDE.md b/src/gateway/protocol/CLAUDE.md new file mode 120000 index 00000000000..47dc3e3d863 --- /dev/null +++ b/src/gateway/protocol/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/src/plugin-sdk/AGENTS.md b/src/plugin-sdk/AGENTS.md new file mode 100644 index 00000000000..cd10f32a304 --- /dev/null +++ b/src/plugin-sdk/AGENTS.md @@ -0,0 +1,48 @@ +# Plugin SDK Boundary + +This directory is the public contract between plugins and core. Changes here +can affect bundled plugins and third-party plugins. + +## Source Of Truth + +- Docs: + - `docs/plugins/sdk-overview.md` + - `docs/plugins/sdk-entrypoints.md` + - `docs/plugins/sdk-runtime.md` + - `docs/plugins/sdk-migration.md` + - `docs/plugins/architecture.md` +- Definition files: + - `package.json` + - `scripts/lib/plugin-sdk-entrypoints.json` + - `src/plugin-sdk/entrypoints.ts` + - `src/plugin-sdk/api-baseline.ts` + - `src/plugin-sdk/plugin-entry.ts` + - `src/plugin-sdk/core.ts` + - `src/plugin-sdk/provider-entry.ts` + +## Boundary Rules + +- Prefer narrow, purpose-built subpaths over broad convenience re-exports. +- Do not expose implementation convenience from `src/channels/**`, + `src/agents/**`, `src/plugins/**`, or other internals unless you are + intentionally promoting a supported public contract. +- Prefer `api.runtime` or a focused SDK facade over telling extensions to reach + into host internals directly. +- When core or tests need bundled plugin helpers, expose them through + `extensions//api.ts` and a matching `src/plugin-sdk/.ts` facade + instead of importing `extensions//src/**` or `extensions//onboard.js` + directly. + +## Expanding The Boundary + +- Additive, backwards-compatible changes are the default. +- When adding or changing a public subpath, keep these aligned: + - docs in `docs/plugins/*` + - `scripts/lib/plugin-sdk-entrypoints.json` + - `src/plugin-sdk/entrypoints.ts` + - `package.json` exports + - API baseline and export checks +- If the seam is for bundled-provider onboarding/config helpers, update the + generated plugin facades instead of teaching core tests or commands to reach + into private extension files. +- Breaking removals or renames are major-version work, not drive-by cleanup. diff --git a/src/plugin-sdk/CLAUDE.md b/src/plugin-sdk/CLAUDE.md new file mode 120000 index 00000000000..47dc3e3d863 --- /dev/null +++ b/src/plugin-sdk/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/src/plugins/AGENTS.md b/src/plugins/AGENTS.md new file mode 100644 index 00000000000..04373075ee4 --- /dev/null +++ b/src/plugins/AGENTS.md @@ -0,0 +1,36 @@ +# Plugins Boundary + +This directory owns plugin discovery, manifest validation, loading, registry +assembly, and contract enforcement. + +## Public Contracts + +- Docs: + - `docs/plugins/architecture.md` + - `docs/plugins/manifest.md` + - `docs/plugins/sdk-overview.md` + - `docs/plugins/sdk-entrypoints.md` +- Definition files: + - `src/plugins/types.ts` + - `src/plugins/runtime/types.ts` + - `src/plugins/contracts/registry.ts` + - `src/extensions/public-artifacts.ts` + +## Boundary Rules + +- Preserve manifest-first behavior: discovery, config validation, and setup + should work from metadata before plugin runtime executes. +- Keep loader behavior aligned with the documented Plugin SDK and manifest + contracts. Do not create private backdoors that bundled plugins can use but + external plugins cannot. +- If a loader or registry change affects plugin authors, update the public SDK, + docs, and contract tests instead of relying on incidental internals. +- Do not normalize "plugin-owned" into "core-owned" by scattering direct reads + of `plugins.entries..config` through unrelated core paths. Prefer generic + helpers, plugin runtime hooks, manifest metadata, and explicit auto-enable + wiring. +- When plugin-owned tools or provider fallbacks need core participation, keep + the contract generic and honor plugin disablement plus SecretRef semantics. +- Keep contract loading and contract tests on the dedicated bundled registry + path. Do not make contract validation depend on activating providers through + unrelated production resolution flows. diff --git a/src/plugins/CLAUDE.md b/src/plugins/CLAUDE.md new file mode 120000 index 00000000000..47dc3e3d863 --- /dev/null +++ b/src/plugins/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file