# Plugin SDK

CodeAgent plugins are bounded declarative manifests. They cannot load JavaScript,
native modules, HTML, or arbitrary components into the CodeAgent process. External
programs are supported only as permission-gated stdio MCP servers.

## Import and Discover

The **Skills** settings page includes fourteen first-party workflows ready for automatic task matching. They ship with the client, use the separate `builtin:` namespace, and require no import or activation. Examples append to the composer without sending a task. See [built-in Skills](builtin-skills.md) for supported workflows and context limits. Imported extensions use the separate review and activation flow below.

In the desktop **Skills** or **Plugins** panel, use **Import file** for a standalone `SKILL.md` / CodeAgent `plugin.json`, or **Import folder** to include scripts and references. The file mode imports only the selected manifest. The folder root must contain the manifest; unwrap downloaded ZIPs first. Review the original manifest/instructions, file count and declared permissions, then confirm. Imported extensions start disabled; activation uses the existing approval and publisher-trust flow. No installation scripts execute during import.

**Discover** has two sources. **Bundled** contains offline first-party recipes: evidence-based code review and interface-review Skills, the delivery-helper command plugin, and three productivity plugin packs listed below. **GitHub sources** searches public repositories, or scans a repository root URL / `owner/repo` with an optional branch, tag or commit. Select a discovered `SKILL.md` or CodeAgent `plugin.json` to check compatibility, download its directory and review the manifest before importing. Repository search results and scanned manifest paths are not compatibility approvals; the check runs when you select a manifest. GitHub access is anonymous, so rate limits may require retrying later or importing a local folder. ZIP extraction, ratings, publishing and automatic updates are not implemented.

### Productivity packs

| Pack | Purpose | Copy-ready folder |
| --- | --- | --- |
| 开发协作工具箱 | Review changes, design regression tests, check API contracts, and explain a project | [development-productivity](../examples/plugins/development-productivity/) |
| 办公文档工具箱 | Organize meeting minutes, work reports, and documents from supplied material | [office-productivity](../examples/plugins/office-productivity/) |
| 数据对账工具箱 | Reconcile spreadsheets and report duplicates, missing records, and value differences | [data-reconciliation](../examples/plugins/data-reconciliation/) |

Open a project, then use **Settings → Plugins → Discover → Bundled** to review and import a pack. Imports start disabled; use the existing **Enable** action to activate the reviewed manifest. Its commands insert task drafts for review, its static view provides shortcuts, and its Agent profiles use a bounded set of existing tools. These packs require no connector credentials or external installation. They do not add new remote services or extend execution permissions. Standalone `SKILL.md` copies of the six new built-in workflows are also available under [examples/skills](../examples/skills/).

GitHub imports resolve the selected revision to a commit and verify each downloaded blob against the repository tree before preview. The import records the repository, commit and path in `.codeagent-source.json`. A remote plugin must use the CodeAgent declarative manifest format; third-party application formats are not converted. Imported content remains disabled until the separate activation review. The importer does not run Git hooks, install scripts or downloaded executables.

Imports stay in the current project's `.codeagent/skills` or `.codeagent/plugins`. Existing names are never overwritten. Files are snapshotted before review; changing the selected project invalidates approval. Preview tokens are single-use and expire after five minutes. Import limits: 64 KiB manifest, 128 regular files, 8 MiB total and eight subdirectory levels; local folder traversal is capped at 256 entries. Symbolic links/reparse points are rejected; `.git` and `node_modules` are omitted. Same-name import failures leave existing activation state intact. Re-importing an extension that was manually removed clears stale activation approval before publishing it.

Skills accept plain Markdown or the bounded flat frontmatter fields `name`, `description`, `tools`, `permissions`, `license`, `compatibility`, `allowed-tools`, and optional `manifestVersion: 1`. The compatibility metadata fields do not grant permissions; `allowed-tools` is not converted into a CodeAgent execution allowlist. Common name/description-only frontmatter is supported. Unsupported YAML fields/syntax and incompatible plugin formats are rejected explicitly; plugins for other Agent applications are not silently converted. Folder resources are preserved, and the Skill's path is exposed through the existing context loader. Scripts still require the normal shell permission when invoked.

## Start from the reference plugin

Copy [the reference plugin](../examples/plugins/release-review/) into a workspace:

```text
<workspace>/.codeagent/plugins/release-review/
```

Its `plugin.json` demonstrates root instructions, a built-in Tool alias, an
embedded Skill, a reviewable Command draft, a restricted Agent profile, a static
View, and an external MCP server with a declared credential field.

Validate a plugin before opening CodeAgent:

```powershell
pnpm plugin:validate -- .\examples\plugins\release-review
```

The command uses the same `validatePluginManifest` parser as production plugin
discovery. Successful output contains metadata, contribution names, signature
status, and the canonical manifest digest, but never instruction bodies or
credential values.

For editor completion and structural diagnostics, associate
`packages/plugins/plugin-manifest.schema.json` with `plugin.json`. The JSON
Schema covers field grammar and bounds. The runtime validator remains authoritative
for cross-field permission sets, contribution matching, same-plugin View
references, directory identity, canonical digest, and Ed25519 verification.

## Directory and identity

Each plugin occupies one direct child directory:

```text
.codeagent/plugins/<plugin-id>/plugin.json
```

The manifest `id` must exactly equal `<plugin-id>`. IDs contain at most 64
letters, digits, or hyphens and start with a letter or digit. Manifests must be
regular, non-symlink files no larger than 64 KiB. CodeAgent scans at most 64
plugins per workspace.

## Contributions

- `instructions`: private text appended inside an untrusted Plugin boundary.
- `tools`: aliases for existing built-in Agent tools. A plugin cannot supply an
  implementation or schema.
- `skills`: private instructions plus declared tool and permission metadata.
- `commands`: prompt drafts inserted into the Composer for user review.
- `agents`: private profiles restricted to an exact built-in tool allowlist.
- `ui`: static text, key/value, badge, Command, and Agent elements.
- `mcp`: external direct-command stdio servers; no shell command layer.

When `contributions` is present it must exactly match the corresponding fields.
If omitted, CodeAgent derives it from the populated supported fields.

## Permissions

Permissions are declarations, not grants. Every operation still goes through the
normal Permission Engine and native approval boundaries.

Tool aliases must declare the exact permission set required by their target:

- inspection targets: `workspace.read`
- mutation targets: `workspace.write` and `artifact.write`
- shell targets: `shell.execute`

Agent profiles declare the exact union required by their tools. Every child
permission must also appear in the root `permissions` array. MCP entries require
exactly `mcp.start` at both levels.

## Credentials and MCP

An MCP declaration may describe credential fields with `name`, `label`,
`description`, `required`, and `secret`. It must never contain a value.
Users configure values in Plugin Manager; Electron main encrypts them with
operating-system secure storage and injects them only into the selected child
process.

The MCP `command` is launched directly with its `args`; shell interpolation is
not supported. Startup and every tool call remain approval-gated, bounded, and
secret-redacted.

## Static View grammar

Views can use only:

- `text`
- `key_value`
- `badge` with `neutral`, `success`, or `warning`
- `command` referencing a Command in the same manifest
- `agent` referencing an Agent in the same manifest

HTML, scripts, URLs, styles, handlers, remote resources, and cross-plugin actions
are rejected.

## Integrity and trust

Unsigned local plugins require native approval bound to their canonical SHA-256
manifest digest. Any manifest change disables the plugin until reapproval.

Signed plugins use an Ed25519 `signature` over
`pluginSignaturePayload(manifest)`, which canonicalizes the manifest after
removing the signature field. A signed plugin must declare a publisher. Signature
validity proves integrity, not authority; the publisher key fingerprint still
requires explicit workspace-scoped trust.

The TypeScript SDK entry points are:

```ts
import {
  pluginSignaturePayload,
  validatePluginManifest,
  type PluginManifest,
} from "./packages/plugins/src/plugin-service";
```

Never place a private signing key, access token, password, or environment value in
the plugin directory.
