@codemation/agent-skills 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/dist/metadata.json +147 -0
- package/package.json +4 -1
- package/skills/codemation-ai-agent-node/SKILL.md +34 -96
- package/skills/codemation-ai-agent-node/references/anti-patterns.md +11 -0
- package/skills/codemation-cli/SKILL.md +30 -24
- package/skills/codemation-credential-development/SKILL.md +27 -12
- package/skills/codemation-custom-node-development/SKILL.md +8 -0
- package/skills/codemation-document-scanner/SKILL.md +136 -0
- package/skills/codemation-framework-concepts/SKILL.md +21 -34
- package/skills/codemation-mcp-capabilities/SKILL.md +33 -65
- package/skills/codemation-plugin-development/SKILL.md +11 -75
- package/skills/codemation-plugin-development/references/plugin-anatomy.md +115 -0
- package/skills/codemation-workflow-dsl/SKILL.md +43 -243
- package/skills/codemation-workspace-files/SKILL.md +142 -0
|
@@ -2,10 +2,16 @@
|
|
|
2
2
|
name: codemation-custom-node-development
|
|
3
3
|
description: Guides Codemation custom node development with `defineNode(...)` (`execute` per item), `defineBatchNode(...)` (batch `run`), reusable node modules, credential-aware nodes, and the class-based node fallback for advanced cases. Use when creating or updating custom nodes for apps or plugin packages.
|
|
4
4
|
compatibility: Designed for Codemation apps and plugin packages that define reusable nodes.
|
|
5
|
+
tags: node, custom, plugin
|
|
6
|
+
uses: "@codemation/core"
|
|
5
7
|
---
|
|
6
8
|
|
|
7
9
|
# Codemation Custom Node Development
|
|
8
10
|
|
|
11
|
+
## Mental model
|
|
12
|
+
|
|
13
|
+
Custom nodes are the extension point for reusable business logic that doesn't belong inline in a workflow callback. `defineNode(...)` wraps a per-item `execute` function with a typed contract (input schema, credential slots, output shape); the engine calls it once per item. `defineBatchNode(...)` is the batch variant for logic that must see all items at once. Nodes compose into workflows via config class instances — the node definition is separate from the config class used to wire it into a workflow.
|
|
14
|
+
|
|
9
15
|
## Use this skill when
|
|
10
16
|
|
|
11
17
|
Use this skill for reusable custom node work, whether the node lives inside an app or a published plugin package.
|
|
@@ -45,6 +51,8 @@ export const uppercaseNode = defineNode({
|
|
|
45
51
|
});
|
|
46
52
|
```
|
|
47
53
|
|
|
54
|
+
For full patterns — credential-slotted nodes, batch nodes, fan-out, binary payloads, and test kit usage — use your harness's example-discovery tool: `find_examples({ query: "defineNode" })` or `find_examples({ query: "defineBatchNode" })`.
|
|
55
|
+
|
|
48
56
|
## Read next
|
|
49
57
|
|
|
50
58
|
- `references/define-node-per-item.md` — full `defineNode(...)` contract, `inputSchema`, `itemExpr`, fan-out, assertion nodes, and `WorkflowTestKit` usage. Load this when writing or debugging a per-item node.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codemation-document-scanner
|
|
3
|
+
description: CodemationDocumentScanner node — managed document/invoice/image extraction via the Codemation doc-scanner service. No Azure credentials required. Read before writing any workflow that scans documents, invoices, or images.
|
|
4
|
+
compatibility: Codemation core-nodes. Requires @codemation/core-nodes import.
|
|
5
|
+
tags: ocr, document, invoice, image, scan, extract, managed, confidence
|
|
6
|
+
uses: "@codemation/core-nodes"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Codemation Document Scanner Node
|
|
10
|
+
|
|
11
|
+
> **Start here: call `find_examples` before reading further.**
|
|
12
|
+
>
|
|
13
|
+
> - `find_examples({ query: "CodemationDocumentScanner" })` — node-level usage and all analyzerType variants
|
|
14
|
+
> - `find_examples({ query: "invoice scan post accounting" })` — end-to-end invoice extraction scenario
|
|
15
|
+
> - `find_examples({ query: "document scanner confidence fields" })` — how to enable per-field confidence scores
|
|
16
|
+
|
|
17
|
+
## Use this skill when
|
|
18
|
+
|
|
19
|
+
Writing a workflow that extracts text and/or structured fields from documents, invoices, or images
|
|
20
|
+
using the Codemation managed scanning service. No Azure credentials are required — the service is
|
|
21
|
+
pre-wired to the platform.
|
|
22
|
+
|
|
23
|
+
Use `codemation-workflow-dsl` for surrounding workflow structure.
|
|
24
|
+
Use `codemation-ai-agent-node` if you need to pass the extracted markdown to an LLM for further processing.
|
|
25
|
+
|
|
26
|
+
## When to use CodemationDocumentScanner vs the standalone OCR nodes
|
|
27
|
+
|
|
28
|
+
| Situation | Use |
|
|
29
|
+
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------- |
|
|
30
|
+
| Managed platform deployment, no Azure credential | `codemationDocumentScannerNode` (this skill) |
|
|
31
|
+
| Self-hosted / BYOK Azure Content Understanding | `analyzeDocumentNode` / `analyzeInvoiceNode` / `analyzeImageNode` from `@codemation/core-nodes-ocr` |
|
|
32
|
+
|
|
33
|
+
`codemationDocumentScannerNode` calls the internal `doc-scanner` service via HMAC — the workspace holds
|
|
34
|
+
no Azure key. The standalone OCR nodes call Azure directly using a per-workspace credential.
|
|
35
|
+
|
|
36
|
+
## Choosing `analyzerType`
|
|
37
|
+
|
|
38
|
+
| `analyzerType` | When to use | Azure analyzer | Field extraction | Confidence opt-in supported |
|
|
39
|
+
| -------------- | ----------------------------------------------- | ----------------------------------------------------------------------- | ---------------------- | --------------------------------------- |
|
|
40
|
+
| `"document"` | General PDFs, Word docs, HTML, text-heavy files | `prebuilt-document` | Yes | Yes |
|
|
41
|
+
| `"invoice"` | Invoices, receipts — always prebuilt-invoice | `prebuilt-invoice` | Yes | Yes |
|
|
42
|
+
| `"image"` | Photos, screenshots, diagrams | `prebuilt-imageAnalyzer` | No (markdown only) | No — image carries no extraction charge |
|
|
43
|
+
| `"auto"` | Unknown mime type at author time | Routes on `Content-Type`: `image/*` → image, everything else → document | Depends on routed type | Depends on routed type |
|
|
44
|
+
|
|
45
|
+
**Default is `"auto"`.** Set an explicit type whenever you know the content class — it avoids
|
|
46
|
+
unnecessary re-routing and makes the workflow self-documenting.
|
|
47
|
+
|
|
48
|
+
## Output shape
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
{
|
|
52
|
+
markdown: string; // full text content
|
|
53
|
+
fields: Record<
|
|
54
|
+
string,
|
|
55
|
+
{
|
|
56
|
+
value: unknown; // extracted scalar, date ISO string, nested object, or array
|
|
57
|
+
confidence: number | null; // 0–1 when includeConfidence:true; null otherwise
|
|
58
|
+
}
|
|
59
|
+
>;
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`item.json.markdown` is the Markdown rendering of the document.
|
|
64
|
+
`item.json.fields` is a flat-or-nested map of structured fields found by the analyzer.
|
|
65
|
+
For `analyzerType: "image"`, `fields` is always `{}`.
|
|
66
|
+
Fields may be sparse or absent for generic documents — extraction is best-effort.
|
|
67
|
+
|
|
68
|
+
## WARNING: How to enable per-field confidence scores (LD6)
|
|
69
|
+
|
|
70
|
+
**By default, `confidence` is `null` on every field.** This keeps token cost low for the majority
|
|
71
|
+
of workflows that only need `value`.
|
|
72
|
+
|
|
73
|
+
To get a populated `confidence` (0–1 float) on each field, set `includeConfidence: true`:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
codemationDocumentScannerNode.create(
|
|
77
|
+
{
|
|
78
|
+
binaryField: "data",
|
|
79
|
+
analyzerType: "invoice",
|
|
80
|
+
includeConfidence: true, // ← opt-in: fields carry confidence 0–1
|
|
81
|
+
},
|
|
82
|
+
"Scan invoice",
|
|
83
|
+
"scan-invoice",
|
|
84
|
+
);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Cost implication:** enabling confidence routes the request to a confidence-enabled analyzer variant,
|
|
88
|
+
which roughly doubles the contextualization token count for document/invoice analyzers.
|
|
89
|
+
Only enable it when your downstream logic actually reads `field.confidence`.
|
|
90
|
+
|
|
91
|
+
Images (`analyzerType: "image"`) and auto-routed-to-image requests carry no field-extraction charge
|
|
92
|
+
regardless of this flag — they silently ignore `includeConfidence` (confidence stays `null`, never a 400).
|
|
93
|
+
|
|
94
|
+
## API usage
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { codemationDocumentScannerNode } from "@codemation/core-nodes";
|
|
98
|
+
|
|
99
|
+
codemationDocumentScannerNode.create(
|
|
100
|
+
{
|
|
101
|
+
binaryField?: string; // key on item.binary — default "data"
|
|
102
|
+
analyzerType?: "document" | "invoice" | "image" | "auto"; // default "auto"
|
|
103
|
+
contentType?: string; // MIME type override — falls back to attachment.mimeType
|
|
104
|
+
includeConfidence?: boolean; // default false — see cost note above
|
|
105
|
+
maxBytes?: number; // size cap before reading; default 50 MiB (LD10)
|
|
106
|
+
},
|
|
107
|
+
label?: string, // node label on the canvas
|
|
108
|
+
nodeId?: string, // explicit stable id — set when output is used downstream
|
|
109
|
+
)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Set an explicit `nodeId` whenever downstream nodes reference this node's output by id, or when
|
|
113
|
+
the node may be renamed later (avoids credential-binding orphaning).
|
|
114
|
+
|
|
115
|
+
## Consuming fields downstream
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import type { DocScannerOutput, DocScannerField } from "@codemation/core-nodes";
|
|
119
|
+
|
|
120
|
+
// item.json after codemationDocumentScannerNode:
|
|
121
|
+
// DocScannerOutput = { markdown: string; fields: Record<string, DocScannerField> }
|
|
122
|
+
// DocScannerField = { value: unknown; confidence: number | null }
|
|
123
|
+
|
|
124
|
+
new Callback<DocScannerOutput>("Use fields", (items, _ctx) =>
|
|
125
|
+
items.map((item) => {
|
|
126
|
+
const vendorName = item.json.fields["VendorName"]?.value as string | undefined;
|
|
127
|
+
const vendorConf = item.json.fields["VendorName"]?.confidence; // null unless includeConfidence:true
|
|
128
|
+
return { ...item, json: { ...item.json, vendorName, vendorConf } };
|
|
129
|
+
}),
|
|
130
|
+
);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Read next when needed
|
|
134
|
+
|
|
135
|
+
- `codemation-workflow-dsl` — workflow builder, trigger types, fluent vs low-level API.
|
|
136
|
+
- `codemation-ai-agent-node` — pass `item.json.markdown` to an LLM for summarisation or extraction.
|
|
@@ -2,53 +2,40 @@
|
|
|
2
2
|
name: codemation-framework-concepts
|
|
3
3
|
description: Explains Codemation package boundaries, runtime concepts, observability shape, and the normal consumer mental model. Use when the user asks where code belongs across `@codemation/core`, `@codemation/host`, `@codemation/next-host`, `@codemation/cli`, workflows, plugins, credentials, activation, telemetry, or runtime modes. Read this first when starting any Codemation task — it points at the right skill for the work.
|
|
4
4
|
compatibility: Designed for Codemation apps, plugins, and framework contributors.
|
|
5
|
+
tags: concepts, architecture
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# Codemation Framework Concepts
|
|
8
9
|
|
|
9
|
-
##
|
|
10
|
+
## Mental model
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Codemation is a workflow engine with a layered package structure. `@codemation/core` owns the engine and runtime contracts (must stay pure — no HTTP, UI, or vendor SDKs). `@codemation/host` adds persistence, credentials, APIs, and scheduler wiring. `@codemation/next-host` is the framework UI shell. `@codemation/cli` runs local development, build, and serve. Consumer apps define behavior in `codemation.config.ts` and `src/workflows/` — they never touch core internals.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
## When to use / when NOT
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
Use this skill to orient on package ownership, runtime shape, observability boundaries, and the consumer/framework divide.
|
|
17
|
+
Do not use as a substitute for detailed CLI, workflow DSL, or plugin implementation guidance when you already know which skill you need.
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
2. `@codemation/host` adds config loading, persistence, credentials, APIs, and scheduler wiring.
|
|
19
|
-
3. `@codemation/next-host` owns the framework UI.
|
|
20
|
-
4. `@codemation/cli` runs local development, build, serve, and user commands.
|
|
21
|
-
5. Consumer apps define `codemation.config.ts` and workflow files.
|
|
19
|
+
## Core concepts
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
- nodes
|
|
28
|
-
-
|
|
29
|
-
- credentials provide typed runtime resources
|
|
30
|
-
- activation is framework-managed and happens in the UI
|
|
31
|
-
- telemetry is observability-first: traces, spans, artifacts, and metric points are framework-owned runtime data
|
|
32
|
-
- run retention and telemetry retention can differ, so trend data can outlive raw run state
|
|
33
|
-
- **workflow testing** is a first-class primitive: a `TestTrigger` node yields one item per test case, the orchestrator dispatches a workflow run per case with `executionOptions.testContext` set, and `Assertion` nodes (`emitsAssertions: true`) record per-run results into `TestAssertion` rows; the canvas exposes a Tests tab parallel to Live and Executions
|
|
34
|
-
|
|
35
|
-
## Runtime rule of thumb
|
|
36
|
-
|
|
37
|
-
1. Start with the minimum setup.
|
|
38
|
-
2. Move to shared PostgreSQL and Redis when execution needs separate worker infrastructure.
|
|
39
|
-
3. Keep workflow code stable while the runtime shape grows around it.
|
|
40
|
-
4. Treat telemetry as part of the runtime contract, not as ad-hoc node-local logging.
|
|
21
|
+
- **workflows** define behavior; **triggers** start runs; **nodes** process items; **items** carry `item.json` data.
|
|
22
|
+
- **credentials** provide typed runtime resources (bound per operator instance, not per workflow code).
|
|
23
|
+
- **activation** is framework-managed and happens in the UI — consumer code does not call it directly.
|
|
24
|
+
- **telemetry** is observability-first: traces, spans, artifacts, and metric points are framework-owned runtime data.
|
|
25
|
+
- **workflow testing** is a first-class primitive: `TestTrigger` yields one item per test case; `Assertion` nodes record per-run results into `TestAssertion` rows; the canvas exposes a Tests tab.
|
|
26
|
+
- **run retention** and **telemetry retention** can differ — trend data can outlive raw run state.
|
|
41
27
|
|
|
42
28
|
## Where to go next
|
|
43
29
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
30
|
+
| Task | Skill |
|
|
31
|
+
| ------------------------------------- | ------------------------------------ |
|
|
32
|
+
| Authoring workflows | `codemation-workflow-dsl` |
|
|
33
|
+
| Building a reusable node | `codemation-custom-node-development` |
|
|
34
|
+
| Building a credential type | `codemation-credential-development` |
|
|
35
|
+
| Packaging as a plugin | `codemation-plugin-development` |
|
|
36
|
+
| Calling an MCP server from a workflow | `codemation-mcp-capabilities` |
|
|
37
|
+
| CLI commands / dev loop | `codemation-cli` |
|
|
50
38
|
|
|
51
39
|
## Read next when needed
|
|
52
40
|
|
|
53
41
|
- Read `references/architecture-map.md` for package ownership and runtime-mode guidance.
|
|
54
|
-
- Use the `codemation-workflow-dsl` skill (and its `references/workflow-testing.md`) for hands-on test authoring with TestTrigger / IsTestRun / Assertion.
|
|
@@ -2,84 +2,52 @@
|
|
|
2
2
|
name: codemation-mcp-capabilities
|
|
3
3
|
description: Discover MCP servers registered on the Codemation control plane. Use before authoring agent workflows that reference mcpServers to find available server ids and their credential requirements.
|
|
4
4
|
compatibility: Requires an installation paired with a connected control plane (Sprint 2+).
|
|
5
|
+
tags: mcp, agent, tool
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# Codemation MCP Capabilities
|
|
8
9
|
|
|
9
|
-
##
|
|
10
|
+
## Mental model
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
available and what credential types they require. Without it, you'd have to guess server ids or
|
|
13
|
-
ask the user.
|
|
12
|
+
MCP servers extend `AIAgent` with tool access to external services (Gmail, Sheets, etc.). Server ids and credential requirements come from the control-plane registry — they are not hard-coded in framework code. The agent's `mcpServers` array contains stable server id slugs; each declared server surfaces a credential slot the operator must bind in the canvas before activation.
|
|
14
13
|
|
|
15
|
-
##
|
|
14
|
+
## When to use / when NOT
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
Use this skill before writing `agent({ mcpServers: ["..."] })` to discover available server ids and their credential types.
|
|
17
|
+
Do not use for general AIAgent authoring — read `codemation-ai-agent-node` for that.
|
|
18
|
+
|
|
19
|
+
## Managed mode: CP-loaded MCP servers (default path)
|
|
20
|
+
|
|
21
|
+
In **managed mode**, MCP servers are loaded from the **control plane (CP)** — not declared in plugin code. Discover available servers by querying the CP registry:
|
|
20
22
|
|
|
21
23
|
```
|
|
22
24
|
GET /api/registry/capabilities?query=gmail
|
|
23
25
|
```
|
|
24
26
|
|
|
25
|
-
Response
|
|
26
|
-
|
|
27
|
-
```json
|
|
28
|
-
[
|
|
29
|
-
{
|
|
30
|
-
"kind": "mcp-server",
|
|
31
|
-
"id": "gmail",
|
|
32
|
-
"displayName": "Gmail",
|
|
33
|
-
"description": "Read, send, and manage Gmail messages and labels.",
|
|
34
|
-
"acceptedCredentialTypes": ["oauth.google.gmail"]
|
|
35
|
-
}
|
|
36
|
-
]
|
|
37
|
-
```
|
|
27
|
+
Response contains objects with `{ kind, id, displayName, description, acceptedCredentialTypes }`. Use `id` in the workflow's `mcpServers` array. An empty `query` string returns all registered servers.
|
|
38
28
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
##
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
credential dialog before the workflow runs. The same credential instance can be shared between
|
|
55
|
-
a `GmailTrigger` node and the Gmail MCP server.
|
|
56
|
-
- **`"bearer_token"`** etc. — user configures a static credential via the credential dialog.
|
|
57
|
-
- **empty array** — no credential required. The server is usable immediately.
|
|
58
|
-
|
|
59
|
-
## Using results in workflow config
|
|
60
|
-
|
|
61
|
-
The `id` field from the response is added to the agent's `mcpServers` array. Each entry
|
|
62
|
-
surfaces a credential slot on the materialized MCP connection node (same shape as
|
|
63
|
-
ChatModel and Tool connection nodes); the user picks a specific credential instance via
|
|
64
|
-
the canvas credential dropdown — same flow as a trigger credential. A user may have
|
|
65
|
-
multiple instances of the same type (personal vs work Gmail); the dropdown surfaces all
|
|
66
|
-
matching instances.
|
|
67
|
-
|
|
68
|
-
```ts
|
|
69
|
-
new AIAgent({
|
|
70
|
-
name: "Gmail reader",
|
|
71
|
-
mcpServers: ["gmail"],
|
|
72
|
-
// ...
|
|
73
|
-
});
|
|
74
|
-
```
|
|
29
|
+
For a full wired example — cron workflow + AIAgent + mcpServers — use your harness's example-discovery tool: `find_examples({ query: "AIAgent gmail mcpServers" })` or `find_examples({ query: "mcp server" })`.
|
|
30
|
+
|
|
31
|
+
## Non-managed: plugin-declared MCP servers
|
|
32
|
+
|
|
33
|
+
In self-hosted / non-managed deployments, MCP servers can also be declared via `mcpServers: [...]` in a `definePlugin(...)` call. This is a framework-author pattern — do not use it in managed-mode workflows. See `references/plugin-anatomy.md` in the `codemation-plugin-development` skill for the plugin declaration syntax.
|
|
34
|
+
|
|
35
|
+
## Decision branches & gotchas
|
|
36
|
+
|
|
37
|
+
**Credential types:** `"oauth.google.gmail"` requires the user to connect a Google account via the credential dialog before the workflow runs. The same instance can be shared between a `GmailTrigger` and the Gmail MCP server. An empty `acceptedCredentialTypes` array means no credential is needed.
|
|
38
|
+
|
|
39
|
+
**Multiple instances:** a user may have multiple instances of the same credential type (personal vs work Gmail). The canvas credential dropdown surfaces all matching instances — the operator picks the one to bind.
|
|
40
|
+
|
|
41
|
+
**Bind via UI only:** there is no inline credential field on the workflow definition. The operator binds the credential instance via the canvas credential dropdown before activation.
|
|
42
|
+
|
|
43
|
+
**Typical flow (managed):**
|
|
75
44
|
|
|
76
|
-
|
|
77
|
-
|
|
45
|
+
1. `GET /api/registry/capabilities?query=<term>` → find `id` and `acceptedCredentialTypes`.
|
|
46
|
+
2. Add `id` to `mcpServers` in the `AIAgent` config.
|
|
47
|
+
3. Report: "The user will need to bind a `<type>` credential instance via the canvas before activating."
|
|
78
48
|
|
|
79
|
-
##
|
|
49
|
+
## Anti-patterns
|
|
80
50
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
4. In the workflow, use `mcpServers: ["gmail"]`.
|
|
85
|
-
5. The user binds their credential instance via the canvas credential dropdown before activating.
|
|
51
|
+
- Do not guess server ids — always query the registry first.
|
|
52
|
+
- Do not add `acceptedCredentialTypes` to the workflow definition — credential binding is UI-driven, not code-driven.
|
|
53
|
+
- Do not declare MCP servers inside plugin code for managed-mode workflows — use the CP registry instead.
|
|
@@ -2,92 +2,28 @@
|
|
|
2
2
|
name: codemation-plugin-development
|
|
3
3
|
description: Guides Codemation plugin package development, including `definePlugin(...)`, plugin sandboxes, custom nodes, custom credentials, and publishable plugin package structure. Use when building or updating a Codemation plugin package or the plugin starter template.
|
|
4
4
|
compatibility: Designed for Codemation plugin packages and the Codemation plugin starter template.
|
|
5
|
+
tags: plugin, node, package
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# Codemation Plugin Development
|
|
8
9
|
|
|
9
|
-
##
|
|
10
|
+
## Mental model
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
A Codemation plugin is an npm package with a `codemation.plugin.ts` composition root that calls `definePlugin(...)`. It registers custom nodes and credential types, optionally declares MCP servers, and ships a sandbox app so the plugin is immediately testable. Consumers load the built JavaScript entry (`package.json#codemation.plugin`) — not TypeScript source. Plugin code follows the same `defineNode` / `defineCredential` patterns as app-level code; the plugin boundary is purely about packaging and distribution.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
## When to use / when NOT
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
**Plugin authoring is a framework-author / non-managed task.** Managed-mode agents work with credential slots and workflow DSL — they do not author or modify plugin packages.
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
2. Register custom credentials and custom nodes from explicit modules.
|
|
19
|
-
3. Keep the sandbox app small and useful so plugin behavior is testable immediately.
|
|
20
|
-
4. Prefer helper-based node and credential definitions first, then drop to class-based APIs only when needed.
|
|
18
|
+
Use this skill for published plugin packages, plugin starter work, and sandbox-driven plugin development. Do not use for ordinary consumer workflow-only changes.
|
|
21
19
|
|
|
22
|
-
##
|
|
20
|
+
## Decision branches & gotchas
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
2. Keep plugin registration separate from node and credential implementation modules.
|
|
26
|
-
3. Use the sandbox app to exercise the plugin right away.
|
|
27
|
-
4. Keep the package publishable like a normal npm package.
|
|
28
|
-
5. Treat `codemation.plugin.ts` as the plugin repo's source composition root; consumer projects should load the built JavaScript entry declared in `package.json#codemation.plugin`.
|
|
22
|
+
**MCP servers in plugins:** Plugin-declared `mcpServers` is a non-managed pattern for self-hosted / framework-author scenarios. In managed mode, MCP servers are loaded from the control plane — see `codemation-mcp-capabilities` for the managed path.
|
|
29
23
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- `codemation.plugin.ts`: plugin registration and sandbox app source, compiled to the published plugin entry in `dist/`
|
|
33
|
-
- `src/nodes/*`: custom node definitions (`defineNode` → **`execute`**; `defineBatchNode` → batch **`run`**)
|
|
34
|
-
- `src/credentialTypes/*`: custom credential definitions
|
|
35
|
-
- `src/index.ts`: package exports
|
|
36
|
-
- `test/*.test.ts` (optional): Vitest + `WorkflowTestKit` from `@codemation/core/testing` for engine-backed unit tests without starting the full host (`pnpm test`)
|
|
37
|
-
|
|
38
|
-
## Packaging guardrail
|
|
39
|
-
|
|
40
|
-
- `package.json#codemation.plugin` should point at runnable JavaScript such as `./dist/codemation.plugin.js`.
|
|
41
|
-
- Do not rely on consumers TypeScript-loading plugin files from `node_modules`.
|
|
42
|
-
- Prefer publishing `dist/**` plus package metadata/docs rather than shipping source-only plugin entry files as runtime dependencies.
|
|
43
|
-
|
|
44
|
-
## Unit tests (`WorkflowTestKit`)
|
|
45
|
-
|
|
46
|
-
Import **`WorkflowTestKit`** from **`@codemation/core/testing`**. Use **`registerDefinedNodes([...])`** for `defineNode` packages, then **`runNode({ node: yourNode.create(...), items })`** or **`run({ workflow, items })`** for fuller graphs. Prefer this for fast node tests; use **`codemation dev:plugin`** when you need the UI and persistence.
|
|
47
|
-
|
|
48
|
-
## Declaring MCP servers from a plugin (`mcpServers?`)
|
|
49
|
-
|
|
50
|
-
A plugin can declare MCP servers that the framework merges into its in-memory catalog at startup. Use this for providers that need non-standard auth, custom adapter logic, or are shipping alongside custom nodes. For standard SaaS providers (OAuth via broker, plain bearer/API key), prefer the control-plane registry instead — no plugin code required.
|
|
51
|
-
|
|
52
|
-
### When to use plugin-declared MCP servers
|
|
53
|
-
|
|
54
|
-
- The provider's MCP server has non-standard auth the generic credential types cannot express.
|
|
55
|
-
- The plugin already ships custom nodes for the same provider and wants to co-locate the MCP declaration.
|
|
56
|
-
- Self-hosted deployments where no control-plane registry is available.
|
|
57
|
-
|
|
58
|
-
### Required fields
|
|
59
|
-
|
|
60
|
-
```ts
|
|
61
|
-
import { definePlugin } from "@codemation/host/authoring";
|
|
62
|
-
import type { McpServerDeclaration } from "@codemation/core";
|
|
63
|
-
|
|
64
|
-
const myServer: McpServerDeclaration = {
|
|
65
|
-
id: "my-service", // globally unique slug: /^[a-z0-9-]+$/
|
|
66
|
-
displayName: "My Service",
|
|
67
|
-
description: "Provides MCP tools for My Service.",
|
|
68
|
-
transport: "http",
|
|
69
|
-
url: "https://mcp.my-service.com",
|
|
70
|
-
// Credential types this server accepts. Users bind a credential instance
|
|
71
|
-
// per slot via the UI. Omit (or set to []) for servers requiring no auth.
|
|
72
|
-
acceptedCredentialTypes: ["my-service.bearer-token"],
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
export default definePlugin({
|
|
76
|
-
mcpServers: [myServer],
|
|
77
|
-
// credentials, nodes, register, etc.
|
|
78
|
-
});
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Merge precedence
|
|
82
|
-
|
|
83
|
-
The framework merges from three sources in this order (last-write-wins on `id` collisions):
|
|
84
|
-
|
|
85
|
-
1. **Plugin** (lowest) — code in `codemation.plugin.ts`
|
|
86
|
-
2. **`codemation.config.ts`** — dev/self-host declarations
|
|
87
|
-
3. **Control-plane registry** (highest) — managed-mode fast lane; shadows plugin declarations to fix descriptions without a plugin release
|
|
88
|
-
|
|
89
|
-
A warning is logged when a higher-priority source shadows a plugin declaration. This is intentional.
|
|
24
|
+
**Publishing guardrail:** `package.json#codemation.plugin` must point at runnable JavaScript (`./dist/codemation.plugin.js`). Do not rely on consumers TypeScript-loading plugin files from `node_modules`.
|
|
90
25
|
|
|
91
26
|
## Read next when needed
|
|
92
27
|
|
|
93
|
-
- Read `references/plugin-
|
|
28
|
+
- Read `references/plugin-anatomy.md` for the full `definePlugin(...)` code, package layout, sandbox setup, MCP server declaration, binary payload rules, and publishing guidance.
|
|
29
|
+
- Read `references/plugin-structure.md` for a concise package layout reference.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Plugin Anatomy
|
|
2
|
+
|
|
3
|
+
Plugin authoring is a **framework-author / non-managed task**. Managed-mode agents almost never need to create or modify plugin packages — they work with credential slots and workflow DSL. This reference is for developers building and publishing reusable Codemation plugin packages.
|
|
4
|
+
|
|
5
|
+
## Quickstart
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { definePlugin } from "@codemation/host/authoring";
|
|
9
|
+
|
|
10
|
+
export default definePlugin({
|
|
11
|
+
nodes: [myNode],
|
|
12
|
+
credentials: [myCredentialType],
|
|
13
|
+
// mcpServers: [...], // optional — see MCP section below
|
|
14
|
+
});
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Plugin package layout
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
codemation.plugin.ts ← composition root; calls definePlugin(...)
|
|
21
|
+
src/
|
|
22
|
+
nodes/ ← defineNode / defineBatchNode / defineRestNode files
|
|
23
|
+
credentialTypes/ ← defineCredential files
|
|
24
|
+
index.ts ← public package exports (types, session shapes)
|
|
25
|
+
test/
|
|
26
|
+
*.test.ts ← Vitest + WorkflowTestKit tests
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Composition root (`codemation.plugin.ts`)
|
|
30
|
+
|
|
31
|
+
The single file that:
|
|
32
|
+
|
|
33
|
+
- calls `definePlugin(...)` and registers nodes + credentials
|
|
34
|
+
- optionally defines a sandbox app via `defineCodemationApp(...)`
|
|
35
|
+
|
|
36
|
+
Consumers discover the plugin through `package.json#codemation.plugin`, which must point at built JavaScript in `dist/` — NOT TypeScript source.
|
|
37
|
+
|
|
38
|
+
## Node guidance
|
|
39
|
+
|
|
40
|
+
- Start with `defineNode(...)` and `execute(...)` for per-item nodes (most common).
|
|
41
|
+
- Use `defineBatchNode(...)` only when the node must process the whole activation batch in one `run(items, ...)`.
|
|
42
|
+
- Keep runtime logic close to the node definition; use class-based APIs only when you need constructor-injected collaborators.
|
|
43
|
+
|
|
44
|
+
## Credential guidance
|
|
45
|
+
|
|
46
|
+
- Start with `defineCredential(...)`.
|
|
47
|
+
- Build typed sessions in `createSession(...)`.
|
|
48
|
+
- Implement `test(...)` so operators can validate configuration before activation.
|
|
49
|
+
- For OAuth2 redirect flows, use the URL-template variant (`auth: { kind: "oauth2", authorizeUrl, tokenUrl, scopes }`).
|
|
50
|
+
- See the `codemation-credential-development` skill for detailed credential patterns.
|
|
51
|
+
|
|
52
|
+
## Declaring MCP servers in a plugin
|
|
53
|
+
|
|
54
|
+
> **Non-managed pattern.** In managed mode, MCP servers are loaded from the control plane — see `codemation-mcp-capabilities`. Plugin-declared MCP servers are for self-hosted / framework-author scenarios.
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { definePlugin } from "@codemation/host/authoring";
|
|
58
|
+
import type { McpServerDeclaration } from "@codemation/host/authoring";
|
|
59
|
+
|
|
60
|
+
const myMcpServer: McpServerDeclaration = {
|
|
61
|
+
id: "my-provider-mcp", // globally unique slug /^[a-z0-9-]+$/
|
|
62
|
+
displayName: "My Provider",
|
|
63
|
+
description: "Exposes My Provider tools to AIAgent.",
|
|
64
|
+
transport: "streamable-http",
|
|
65
|
+
url: "https://my-provider.example.com/mcp",
|
|
66
|
+
acceptedCredentialTypes: ["my-provider.api-key"],
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default definePlugin({
|
|
70
|
+
nodes: [myNode],
|
|
71
|
+
credentials: [myCredentialType],
|
|
72
|
+
mcpServers: [myMcpServer],
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Merge precedence:** plugin declarations < `codemation.config.ts` < control-plane registry. A warning is logged when a higher-priority source shadows a plugin declaration.
|
|
77
|
+
|
|
78
|
+
Use plugin-declared MCP servers only when the provider has non-standard auth or when co-locating with custom nodes for the same provider. For standard OAuth/API-key providers, prefer the control-plane registry.
|
|
79
|
+
|
|
80
|
+
## WorkflowTestKit
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { WorkflowTestKit } from "@codemation/core/testing";
|
|
84
|
+
// For defineNode packages:
|
|
85
|
+
import { registerDefinedNodes } from "@codemation/core/testing";
|
|
86
|
+
registerDefinedNodes([myNode]);
|
|
87
|
+
// Then use runNode(...) or run(...) for fuller graph tests.
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Binary payloads — never put bytes on item.json
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
// Inside execute(items, ctx) when a node fetches binary content:
|
|
94
|
+
const stored = await ctx.binary.attach({
|
|
95
|
+
name: "report.pdf",
|
|
96
|
+
body: Buffer.from(bytes),
|
|
97
|
+
mimeType: "application/pdf",
|
|
98
|
+
filename: "report.pdf",
|
|
99
|
+
});
|
|
100
|
+
const enriched = ctx.binary.withAttachment(item, "report.pdf", stored);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Only the `BinaryAttachment` reference (id, storageKey, mimeType, size) belongs on the item — not the bytes.
|
|
104
|
+
|
|
105
|
+
## Publishing
|
|
106
|
+
|
|
107
|
+
- `package.json#codemation.plugin` must point at `./dist/codemation.plugin.js`.
|
|
108
|
+
- Do not rely on consumers TypeScript-loading plugin files from `node_modules`.
|
|
109
|
+
- Treat the plugin as a normal npm package: install it in a Codemation app for auto-discovery.
|
|
110
|
+
|
|
111
|
+
## Anti-patterns
|
|
112
|
+
|
|
113
|
+
- Do not put plugin registration logic inside workflow files — use `codemation.plugin.ts`.
|
|
114
|
+
- Do not ship source-only plugin entries as runtime dependencies — publish `dist/**`.
|
|
115
|
+
- Do not declare an MCP server in a plugin for standard OAuth/API-key providers already in the control-plane registry.
|