Authoring, sharing & importing templates
A template bundles a pipeline configuration — which stages run, agent models and effort, loop limits, governance — behind a single name you pick at launch. This page covers the three things you’ll do with templates beyond the built-ins: author one, share one (export), and import one a teammate made.
The easiest path for all three is the guided skill. CLI commands are documented further down for scripting and CI.
The /worca-template skill (recommended for everything)
Section titled “The /worca-template skill (recommended for everything)”worca ships a guided skill that handles authoring, exporting, and importing in one place. In a Claude Code session in your project, trigger it by command or with a natural phrase. The skill picks which flow to run from what you say.
Triggering it
Section titled “Triggering it”/worca-templateOr a natural phrase — these all land on the same skill, which then decides whether to author, export, or import based on the wording:
| If you say something like… | The skill runs… |
|---|---|
| “create a new pipeline template” / “new template for backend bug fixes” / “customize my pipeline” | Authoring flow |
| ”export my templates” / “share my template” / “bundle templates” | Export flow |
| ”import a template” / “load this bundle” / “install templates from a gist” | Import flow |
You can also pass an explicit hint as an argument — /worca-template export or /worca-template import — if you want to skip the autodetect.
Authoring flow
Section titled “Authoring flow”When you ask for a new template, the skill walks you through six phases:
- Enumerate existing templates. Reads every built-in, project, and user template so it can reason about reuse.
- Intent interview. Asks what kind of work the template is for, how strict the review needs to be, how cheap/fast vs. thorough it should be.
- Reuse-first proposal. If an existing template already fits, it offers to point you there instead of creating a near-duplicate. If a close-but-imperfect match exists, it offers to extend it.
- Scope. Asks whether the new template should be a project template (
.claude/templates/, committable, shared with everyone on the repo) or a user template (~/.worca/templates/, available across every project on your machine). Never silently defaults — you always pick. - Compose a minimal config delta. Writes only the keys that differ from your baseline — not a full settings dump. This keeps the template robust across worca upgrades, because everything you didn’t explicitly set continues to pick up the latest default.
- Validate and write via the CLI. Runs through
worca templates create, which validates the JSON shape, ID format, tag count/format, and rejects built-in ID collisions. Errors are returned per-field with a fix offer.
Then it offers next steps — a dry-run, a real launch, or a pointer to the launcher UI.
Export flow
Section titled “Export flow”When you ask to share or export, the skill walks you through four choices and runs the CLI for you:
- Which templates to include. Lists every project- and user-tier template (built-ins are excluded by default since they ship with worca). You multi-select.
- Models and pricing opt-in. Asks whether to include your
worca.modelsand/orworca.pricingfromsettings.json. Both default to No. When you opt in, the skill explains exactly what’s carried and what’s redacted (see What’s in a bundle below). - Destination. Three choices:
- Local file — write to a path you specify. The format is chosen automatically:
.zipwhen the template has overlay files inagents/,.jsonfor config-only templates. Best for committing to a separate repo or attaching to an issue. - GitHub gist (secret) — unlisted, shareable via URL but not search-indexed. JSON-only: templates with prompt overlays must be downloaded as a
.zipfile and shared via file attachment — gist export is rejected with a clear error. - GitHub gist (public) — search-indexed, visible to everyone. Same JSON-only restriction applies.
- Local file — write to a path you specify. The format is chosen automatically:
- Run the export and report results. Surfaces the
_redactedlist (per-value secret replacements), the_strippedlist (config subtrees removed wholesale), and the output location (including the format chosen for each template). Reminds you to inspect the bundle before sharing publicly.
Import flow (zip bundles supported)
Section titled “Import flow (zip bundles supported)”When you ask to import or load a bundle, the skill walks you through three steps and handles every collision interactively:
-
Source. Three forms:
- Local file — path to a
.jsonor.zipbundle. The format is detected automatically (magic bytes, then file extension). A zip bundle imports the template config and all prompt overlays (agents/*.md) atomically; the summary after import lists every overlay file that landed. - HTTPS URL — 1 MiB cap, redirects blocked, private/loopback/link-local hosts refused. Zip bundles are accepted at URLs (detected by
Content-Type, then magic bytes, then.zipextension). - GitHub gist — gist URL or bare gist ID. Gist sources are JSON-only; zip bundles cannot be fetched from gists.
Before fetching, the skill reminds you that bundles are config-as-data and warns about the trust boundary.
- Local file — path to a
-
Target scope. Either project (writes templates to
.claude/templates/) or user (writes templates to~/.worca/templates/). Model aliases and pricing always land in user-global~/.worca/settings.jsonregardless of the template scope — this keeps the project’s committed settings free of per-developer env scaffolds and secret placeholders. If you share the bundle with a teammate via the repo, each collaborator runs the import on their machine to pick up the alias definitions. -
Run the import, handle collisions, and follow up on placeholders. Imports run in two phases: a passive preview that detects every collision before any write, then a commit that respects the resolutions you picked. The skill prompts:
- For each template id that already exists in the target scope, replace / skip / abort — unrecognized input re-prompts, never silently skips.
- For each model alias whose incoming definition differs from the existing one in user-global, rename / overwrite / skip / abort. The default for rename is a zero-padded
-NNsuffix (e.g.glm-ds→glm-ds-01, probing-01..-99for the first free slot). When you rename, the imported template’sconfig.agents.*.modelreferences are rewritten to point at the new alias name transactionally with the alias write, so the template never lands referencing a missing alias.
After the import:
- If any
<YOUR-SECRET-HERE>placeholder values landed, the skill lists every path needing a real secret and points you at Secrets for where to put them. - If the import landed templates that shadow built-ins, you get an
info:line per shadow so it’s visible, not silent. - On any failure, the rollback restores every replaced template and
settings.jsonfrom the snapshots taken before mutation; nothing partial is ever committed.
Why the skill is the recommended path
Section titled “Why the skill is the recommended path”The minimal-delta authoring keeps your template forward-compatible; the interactive collision UI and placeholder follow-up keep imports safe; the destination/source pickers cover the cases you’d otherwise have to remember CLI flags for. CLI is still there when you need it — for CI, scripts, or one-shot operations — but the skill is the default.
Sharing templates with overlays (zip bundles)
Section titled “Sharing templates with overlays (zip bundles)”Templates can carry prompt overlay files alongside their config — .md files in an agents/ directory that replace or augment the default system prompts for each pipeline stage. When a template has overlays, the bundle format changes from JSON to zip automatically.
Format auto-selection
Section titled “Format auto-selection”The export command picks the format based on what’s in the template:
| Condition | Format | Extension |
|---|---|---|
Template has files under agents/*.md | Zip bundle | .zip |
Config-only (no agents/ dir, or empty) | JSON bundle | .json |
You don’t pick the format — the CLI tells you on stderr which format was chosen for each template. Multi-template export emits one file per template; each is independently .zip or .json.
Zip layout
Section titled “Zip layout”A single-template zip bundle has this structure:
<id>-bundle.zip template.json # required — the template config (same schema as the on-disk file) models.json # optional (v3) — { "models": {...}, "pricing": {...} } agents/ # optional — present only when overlays exist planner.md coordinator.md plan.block.md …any other *.md or *.block.md filesmodels.json carries any worca.models alias definition that the template references, alongside its pricing entry. The importer lifts both back to the manifest top-level models and pricing keys at parse time, so they participate in the same redaction and collision flow as JSON bundles.
When a zip bundle includes models.json the synthesized worca_bundle_version is 3; otherwise it stays at 2. The importer accepts versions 1, 2, and 3.
One template per zip. There is no multi-template zip — if you export multiple templates, only those with overlays become .zip; the rest stay .json.
Gist limitation
Section titled “Gist limitation”Gist export supports JSON bundles only. If you try to export a template with overlays to a gist, the CLI exits with:
gist export only supports JSON bundles; download the .zip and share via fileShare zip bundles as file attachments (issue comments, shared drives, direct messages) or host them at an HTTPS URL.
Viewing overlays in the UI
Section titled “Viewing overlays in the UI”After importing a zip bundle — or after duplicating a built-in that has overlays — the Pipelines editor shows an Overlays tab on that template. The tab is read-only and groups overlays by pipeline stage, with sub-tabs for the agent system prompt and the user-injected block prompt. Overlays acquired via any path (import, duplicate, or filesystem drop) appear there.
Direct CLI
Section titled “Direct CLI”For scripting, CI, and one-shot operations.
Snapshot the current settings into a template
Section titled “Snapshot the current settings into a template”Alternatively, tune a project’s settings until a run behaves the way you want, then snapshot them into a named template:
worca templates save my-workflow --description "Backend service changes with strict review"This captures the project’s current worca configuration as a project template. Add --global to save to your user scope (~/.worca/templates/) so it’s available across every project:
worca templates save my-workflow --global --description "My standard workflow"A snapshot captures everything, so trim it afterwards if you only meant to change a few keys — the skill avoids this by composing the delta directly.
Manage templates
Section titled “Manage templates”worca templates listworca templates show my-workflowworca templates delete my-workflowworca templates create --from-file ./my-template.json # or '-' for stdin
# Rename — atomic: duplicate → pointer rewrite → delete sourceworca templates rename --src-id old-name --src-scope project \ --dst-id new-name --dst-scope projectworca templates list --json emits a machine-readable array (id, name, description, tier, tags, builtin, created_at). Templates resolve in tiers — project > user > built-in — so a project template shadows a user one of the same name.
Rename and the default-template pointer. When you rename a template that is set as the project default (worca.default_template in .claude/settings.json), the pointer is automatically updated to the new {tier, id} — no manual reset needed. The rename is a single CLI call that carries any agents/ overlay files through unchanged. If the duplicate step succeeds but the delete fails, both copies remain and the CLI exits with code: "partial_rename" — the recovery action is to manually delete one side.
Export to a bundle
Section titled “Export to a bundle”# All non-builtin templates, to local files:# (format is auto-selected per template — .zip if overlays, .json otherwise)worca templates export --to ./
# Specific templates, plus model aliases:worca templates export --to ./bundle.json \ --templates my-workflow,backend-bugfix \ --include-models
# Direct to a secret (unlisted) GitHub gist — prints the URL:# Note: gist export is JSON-only. Templates with overlays (agents/*.md) must# be exported to a local file and shared as a file attachment instead.worca templates export --to gist
# Public, search-indexed gist:worca templates export --to gist:publicFlags:
| Flag | Effect |
|---|---|
--to <dest> | Destination: file path, gist, or gist:public. Required. |
--templates <ids> | Comma-separated IDs to include. Default: all project + user templates. |
--include-models | Carry worca.models from settings.json (env keys preserved, secret values redacted). |
--include-pricing | Carry worca.pricing from settings.json. |
Import from a bundle
Section titled “Import from a bundle”# From a local JSON bundle:worca templates import --from ./team-bundle.json
# From a local zip bundle (carries config + overlays + optional models.json):worca templates import --from ./bugfix-bundle.zip
# From an HTTPS URL (JSON or zip — hardened, see Trust boundary below):worca templates import --from https://example.com/bundles/team.json
# From a GitHub gist (URL or bare ID — JSON-only; zip not accepted from gists):worca templates import --from https://gist.github.com/alice/abc123def456...
# Into the user scope instead of project:worca templates import --from ./bundle.json --scope user
# Non-interactive policies for the two collision dimensions:worca templates import --from ./bundle.json --non-interactive \ --on-template-conflict replace \ --on-model-conflict rename
# Preview-only: print collisions JSON and exit without writing anything.worca templates import --from ./bundle.json --preview
# Drive resolutions programmatically (used by the worca-ui import dialog):worca templates import --from ./bundle.json --non-interactive \ --resolutions ./resolutions.jsonFlags:
| Flag | Effect |
|---|---|
--from <src> | Source: file path, HTTPS URL, or gist URL/ID. Required. |
--scope project|user | Where templates land. Default project. Model aliases always land in user-global ~/.worca/settings.json regardless of --scope. |
--non-interactive | Don’t prompt; honor the --on-*-conflict policies and --resolutions instead. |
--on-template-conflict abort|skip|replace | Non-interactive policy when a template id already exists in the target scope. Default abort. |
--on-model-conflict abort|skip|overwrite|rename | Non-interactive policy when a model alias collides with one in user-global settings. Default abort. rename appends a zero-padded -NN suffix and rewrites the template’s config.agents.*.model references. |
--preview | Print a JSON collision report to stdout and exit; no files are written. Used by the worca-ui dialog. |
--resolutions <path> | JSON file mapping each collision to an explicit action. Structured shape: {"models": {"<alias>": {"action": "skip|overwrite|rename", "new_name": "<optional>"}}, "templates": {"<tid>": {"action": "skip|replace"}}}. A flat root-level object is treated as the models block for back-compat. |
In interactive mode, template collisions prompt [r]eplace / [s]kip / [a]bort and model alias collisions prompt [s]kip / [o]verwrite / [r]ename / [a]bort. Unrecognized input re-prompts. Imports are atomic with rollback (see Rollback below).
What’s in a bundle (the safety model)
Section titled “What’s in a bundle (the safety model)”Bundles are designed to be safe to share. Two layers run before anything is written.
Layer 1 — config allowlist on templates[*].config.*. Only known-safe pipeline behavior survives the export: stages, agents, effort, loops, circuit_breaker, milestones, models. Anything else — webhooks, integrations, governance, the graphify and crg knowledge-graph configs — is stripped wholesale and listed in the bundle’s _stripped field for transparency. graphify and crg are stripped because they require external packages installed on the importer’s machine; auto-importing them would silently change behavior once those packages appeared. Note that governance.dispatch is itself a template-owned key, but it’s excluded from the bundle allowlist — built-ins rely on the orchestrator’s _DISPATCH_DEFAULTS, and authored templates that need non-default dispatch must add it after import by editing the saved template directly.
Layer 2 — per-value secret redaction on what’s left. Env-block keys are always preserved (so the importer sees which env vars are expected), but each value is checked against known secret prefixes — Anthropic sk-…, GitHub ghp_… / github_pat_…, Slack xoxb-… / xoxp-…, AWS AKIA…. Matches are replaced with the literal placeholder <YOUR-SECRET-HERE> and the JSON paths are listed in the bundle’s _redacted field.
So a bundle export of a model with a real API key looks like this on the wire:
{ "worca_bundle_version": 1, "exported_at": "2026-05-30T08:00:00Z", "templates": [ /* ... */ ], "models": { "opus": { "id": "claude-opus-4-7", "env": { "ANTHROPIC_BASE_URL": "https://proxy.example.com", // preserved "ANTHROPIC_API_KEY": "<YOUR-SECRET-HERE>" // value redacted, key kept } } }, "_redacted": ["models.opus.env.ANTHROPIC_API_KEY"], "_stripped": ["templates[0].config.webhooks"]}The importer sees the env scaffold and knows which secret to fill in — without ever seeing yours.
The bundle never reads settings.local.json — your real secrets stay in the local file regardless of what you export.
Filling in the placeholders
Section titled “Filling in the placeholders”If the bundle landed any <YOUR-SECRET-HERE> values, the importer ends with a list of exactly which paths need real secrets:
info: 2 secret placeholder(s) landed — replace "<YOUR-SECRET-HERE>" before running the pipeline: - templates.my-workflow.config.agents.planner.env.ANTHROPIC_API_KEY - settings.worca.models.opus.env.FOO_TOKENPut the real values in settings.local.json (via the Secrets panel in Settings, or by hand) — see Secrets — and the placeholders are deep-merged away at runtime. The bundle on disk stays committable.
Trust boundary
Section titled “Trust boundary”Bundles are config as data. On import they get merged into your settings.json and used to drive subsequent pipeline runs — so only import bundles from sources you trust.
worca hardens HTTPS fetches against the obvious slip-ups: redirects are blocked (the URL you typed is the bundle), and DNS resolution rejects private, loopback, link-local, reserved, and multicast addresses (no http://169.254.169.254/, no https://localhost/, no internal CIDRs). The size cap is 1 MiB. None of this defends against a hostile upstream — treat a bundle URL with the same care you’d treat a curl | sh URL.
Zip bundles add a second layer of host-level protection before any file is extracted:
| Rule | Cap |
|---|---|
| Compressed size | ≤ 1 MiB |
| Uncompressed total | ≤ 4 MiB |
| Per-file uncompressed | ≤ 256 KiB |
| Member count | ≤ 64 files |
| Compression ratio per file | ≤ 100× (zip-bomb backstop) |
| Path traversal, symlinks, absolute paths, drive letters | Rejected outright |
All rules are checked against the zip central directory metadata before any extraction begins — no bytes are written to disk until every member passes. Overlay content (the .md files under agents/) goes through the same secret-redaction scan as the JSON config.
The trust boundary is unchanged: overlays are inert markdown files that only activate at pipeline runtime, when a pipeline run loads the template and mounts the overlay into an agent system prompt. Only import zip bundles from sources you trust — a crafted overlay could instruct agents to behave in unintended ways, just as a malicious settings blob could.
Rollback and atomicity
Section titled “Rollback and atomicity”Imports are atomic with full rollback. Before any mutation, every existing template directory and settings.json is snapshotted to a .bak-<rand> sibling. If any step fails (disk full, cross-device os.replace, permission), every change is reverted and the backups restored. On success, the backups are deleted. No partial-write state is ever left behind.
Schema forward compatibility
Section titled “Schema forward compatibility”Bundles carry worca_bundle_version. The importer accepts:
1(or string forms"1","1.0") — original JSON bundle layout.2("2","2.0") — zip bundle withtemplate.jsonandagents/*.mdoverlays.3("3","3.0") — zip bundle that also carries a top-levelmodels.jsonfor alias and pricing definitions.
Forward-compat minor mismatches ("1.1", "2.3", "3.1", …) log a warning but proceed; unknown additive fields are preserved. Major versions outside the supported set are rejected outright with a clear error so an older importer never silently drops content from a newer bundle.
Where templates fit
Section titled “Where templates fit”Once saved, your template appears in the Run Pipeline launcher’s dropdown and works with worca run --template my-workflow. When a template is in play, the template-owned keys in project settings — worca.agents, worca.stages, worca.loops, worca.circuit_breaker, worca.effort, worca.governance.dispatch, and worca.milestones — are stripped from the merge base before the template’s config deep-merges over. Cross-template keys (worca.models, worca.webhooks, worca.pricing, worca.governance.guards, worca.graphify, worca.code_review_graph, and stages.preflight as a carve-out) still fall through from settings as before. A built-in template that doesn’t declare a template-owned block falls to the runtime defaults baked into the orchestrator, not to your Settings values — so the built-ins ship with explicit declarations for every template-owned block. See Configuration precedence for the full strip-and-merge rules.