Skip to content

Guides

Task-shaped walkthroughs: writing a skill, building a plugin, publishing it.

5 min readUpdated 13 Sept 2026Reviewed 12 Sept 2026Published 12 Sept 2026/docs/guides

These are the things you will actually want to do once the office is running. Each guide ends with what to check if it did not work, and each one is written against the real implementation rather than the intent behind it.

What the three guides get you

GuideYou end up withYou need to know first
Writing a skill A markdown file in skills/ that the engine loads at boot and selects into a turn when the task looks like it needs it. Which stage kinds your colleagues work in, because skill selection runs off the stage's task class.
Building a plugin A directory with a plugin.json — and, if it registers a tool or watches events, an entry module beside it. The manifest reference, or at least the fields table on it.
Publishing to the marketplace A .tar.gz, a sha256, and a catalog entry that another installation can install from with one command. The plugin guide, because a bundle is only ever a packaged plugin.

Read them in that order if you are new to the system: skills are the smallest useful unit of change, a plugin is a container for skills plus everything else, and publishing is what you do when the plugin is worth somebody else's time. If you only want to route a task class at a cheaper model, skip to Building a plugin — that is eight lines of JSON and no code.

The one decision that matters: declarative or code

The single choice that shapes everything else is whether your plugin ships an entry module. That field is the whole distinction. A manifest with no entry is declarative: data the host reads, validates and renders. A manifest that names one is a code plugin: the host imports that module at boot and calls activate(api) inside the orchestrator's own process.

DeclarativeCode
Shipsplugin.json onlyplugin.json plus an entry module
Can contributeproviders, models, skills, roleTemplates, pipelines, routingRules, uiPanels, toolNamesThe same, plus tools it actually registers at runtime and subscriptions to the event stream
Can do at runtimeNothing. Every string is length-capped and every list is row-capped by the validator; the console renders it from the manifest.Anything the orchestrator can do. It reads and writes files as the server user, and it is not confined to a workspace.
What it costs youNothing to trust. A hostile declarative plugin can waste console space and nothing else.Code review, or you are trusting the author with your checkout and your provider keys.
The honest exampledev3d.cost-guard: two routing rules, one model, one skill, one role template, one pipeline, three settings.dev3d.office-echo: one tool called echo and a log line per run.

A declarative plugin can add a model but cannot make the office use it. Routing is decided per turn by the router, which weighs tier affinity, capability and cost against the role's policy. A plugin can bias that walk with a routingRules entry — and a rule that names a tier really does move it — but it cannot force a model on a role that is not allowed to run there. If you want a specific model always, that is a role policy or a pin, and neither is a plugin permission.

Who each guide is for

  • Writing a skill is for anyone who wants the same colleague to behave differently on a class of task: a checklist that gets applied to every review, a house style for reports, a rule about when to stop debugging and escalate. It needs no JavaScript and touches nothing the host enforces.
  • Building a plugin is for someone adding a capability to the installation rather than to one employee: a local model server, a provider with a gateway in front of it, a routing posture for a task class, a console panel that shows what a plugin is spending.
  • Publishing to the marketplace is for the person who has a working plugin and wants other installations to be able to install it by URL, with a checksum the host verifies before it unpacks anything.

What you need before you start

  1. A running office. Quick start gets you there in a few minutes; Installation is the longer version with the .env decisions in it. Nothing in these guides makes sense while looking at a socket error.
  2. The ability to restart it. Skills are loaded from disk at boot, before the server listens. Nothing reloads the catalogue underneath a running process — the Skills API lists what was loaded, so a file added afterwards does not appear.
  3. Write access to the right directory. Skills live in whatever DEV3D_SKILLS_DIR points at, ./skills by default. Bundled plugins live in DEV3D_PLUGINS_DIR (./plugins); marketplace installs land in DEV3D_PLUGIN_INSTALL_DIR (./data/plugins). See Environment.
  4. A text editor and no build step. There is no bundler, no transpiler and no dependency install in either of the first two guides. A skill is a text file; a declarative plugin is JSON; a code plugin is a module Node imports directly.
  5. For publishing only: permission to write plugin listings in the console, and a .tar.gz of your plugin directory. The site computes the checksum, so you do not need to.

The guides assume the shipped defaults. Where a limit is quoted — a 32 MB bundle, a 2048-entry cap, a 500-character panel string — that is the host's real cap at PLUGIN_API_VERSION 1. If you have changed environment variables, the caps that come from the environment may differ; the ones baked into the validator do not.

How to use these pages

Every guide is written to be followed top to bottom with the source open in another window, and every code block is a complete artefact rather than a fragment: a whole skill file, a whole manifest, a whole module. If you are the kind of reader who wants the field tables instead, the plugin manifest reference and the environment reference are the lookup versions of the same material.

If something in a guide does not reproduce, the troubleshooting table at the end of that page is ordered roughly by how often each cause is the answer. That ordering is not a guess: it reflects which failures the host reports loudly and which ones it can only report as a warning beside a plugin that otherwise looks fine.

Linked from

Did this page answer your question?