Package format
Reference for .soduwork-plugin packages, schemaVersion: 1.
The package
A .soduwork-plugin file is a zip archive.
my-team-flow.soduwork-plugin
├─ plugin.json required
├─ workflow.json optional; or put "workflow" inside plugin.json
├─ skills/ optional
└─ README.md optional
| Limit | Value |
|---|---|
| Package size | 10 MB |
| Files in the package | 300 |
| Manifest | plugin.json at the root |
The package identity is a SHA-256 over file names and contents. Compression time, order and algorithm don't change it. Importing a package never runs scripts or opens network connections.
plugin.json fields
| Field | Type | Required | Notes |
|---|---|---|---|
schemaVersion | number | yes | 1 |
key | string | yes | Lowercase letters, digits and hyphens. The stable identity; it never changes |
version | string | yes | SemVer. A version with different content is rejected, never overwritten |
name | string | yes | Display name |
description | string | yes | What the plugin is for |
instructions | string | see note | The method. A plugin without a workflow needs instructions, a Skill or an MCP connection |
author | string | no | |
template | string | no | method, connector, workflow or app. Inferred when missing: a workflow means workflow; MCP or platforms mean connector; otherwise method |
locales | object | no | Translations of name, description and input labels, keyed by zh-CN, en-US and so on |
entrypoints | object | no | conversation, task, automation, each true or false |
inputs | array | no | Inputs |
setup | object | no | Setup preferences |
capabilities | object | no | Capabilities |
workflow | object | no | { "nodes": [...] }. See Workflow nodes |
resources | array | no | Bundled files |
evaluations | array | no | Up to 20 release tests. See Publish |
ui | object | apps | Window and navigation entries. See Apps |
appWindow | object | no | Default window size for apps |
process | object | no | Process label for organization workflows |
icon | string | no | PNG, 256 px and 96 KB at most |
Identity
| Where the plugin lives | Shown as |
|---|---|
| Built in | soduwork/<key> |
| Organization | org:<org-id>/<key> |
| Personal, on one computer | local:<uuid> |
A key must be unique within the platform or within one organization. Different organizations can use the same key.
Inputs
Inputs are public parameters filled in when the plugin starts from a task or an automation.
{
"key": "run_mode",
"type": "select",
"label": "Run mode",
"options": [
{ "value": "confirm", "label": "Confirm each step (default)" },
{ "value": "auto", "label": "Run automatically" }
],
"default": "confirm",
"required": true
}
| Field | Notes |
|---|---|
key | Stable name |
type | text, textarea, boolean, number or select |
label, description, placeholder | Shown to the user |
required | true or false |
options | For select: strings, or { "value", "label" } objects |
default | For select, exactly one option's value |
Inputs must never collect accounts, passwords, tokens or keys.
Setup preferences
Non-sensitive preferences each user fills in once after installing.
"setup": {
"title": "Preferences",
"description": "Set once after installing",
"preferences": [
{ "key": "language", "label": "Language", "type": "select", "options": ["Chinese", "English"], "default": "English" }
]
}
Types: text, textarea, boolean, number, select, multiselect, url. With no preferences, use { "preferences": [] }. Accounts, passwords, tokens and OAuth go through organization connections, never setup.
Bundled files
Templates, examples, scripts and assets that ship with the plugin.
"resources": [
{ "path": "templates/report.md", "kind": "template" },
{ "path": "examples/input.json", "kind": "example" },
{ "path": "scripts/render.py", "kind": "script" }
]
| Rule | Value |
|---|---|
kind | template, example, asset, script, reference, ui |
| Folders | templates/, examples/, assets/, scripts/, references/, ui/ |
| Files | 64 at most, 8 MB in total |
| Import file (draft JSON, ZIP or package) | 24 MB at most |
Paths that leave the folder, symbolic links, key files and obvious credentials are rejected. Installing stores files with their SHA-256; it never runs scripts. A local chat that uses the plugin gets the files under .soduwork/plugins/<key>/<digest>/ in its working folder. Copy a template before editing it.
Default window size
Apps open at a default size, centered on the main window's screen and scaled down on smaller screens. Set appWindow only if your app needs a specific default size.
"appWindow": {
"width": 1280, "height": 800,
"minWidth": 480, "minHeight": 360,
"rules": [ { "maxScreenWidth": 1366, "width": "100vw", "height": "100vh" } ]
}
Values are numbers (px) or strings in px, vw or vh. rules (up to 12) are checked from top to bottom against the screen's available width, and the first match wins. maxWidth and maxHeight limit only the default size; users can still maximize. A changed size applies the next time the app opens.
Process label
Organization workflows can show what they do and where they deliver, wherever a user picks a workflow.
"process": {
"enterprise": true,
"label": "Engineering process",
"route": "AI change → code review → merge → release",
"environments": [ { "label": "QA environment", "scope": "company" } ]
}
| Field | Notes |
|---|---|
enterprise | Shows a badge in the client and admin console |
label | Defaults to "Enterprise process" |
route | One sentence, 200 characters at most |
environments | Up to 8; scope is company, department or project |
Without process, a workflow with merge, deploy or deploy_chain nodes is treated as an enterprise process.
Generated report
From each version, SoduWork generates a report for reviewers. You don't maintain it yourself.
- Components: instructions, Skills, MCP connections, workflow, and any unsupported third-party parts.
- Dependencies: external Skills, MCP, secret names and environments. Names only, never values.
- Permissions: network, scripts, secrets and compatibility blocks, with a low, medium or high risk note.
- Entry points: chat, task, automation. Removing one is a breaking change; adding one needs a new review.
The binding can't grant more than the version declares.