Writing your own style
A style is a folder holding a style.yml and a prompts/ directory.
There is no code to write and nothing to register — drop the folder in
and it appears in the + New Spec menu beside the built-ins.
- Where a style can live
- Changing one prompt without forking a style
style.yml, key by key- The four rules that decide everything
- A prompt’s job
- Trying it
Where a style can live
Three places, and the folder name is the style’s id:
| Scope | Location |
|---|---|
| workspace | <repo>/.local-workflows/styles/<id>/ |
| profile | ~/.local-workflows/styles/<id>/ |
| builtin | ships with the extension |
Workspace wins over profile, which wins over builtin. Put a style in your profile to use it in every repository you open; put it in the workspace to commit it with the project, so the whole team runs the same process.
With a
.code-workspaceopen, “workspace” means the workspace, not a repository. Styles are read from the workspace root’s.local-workflows/styles/, and a style committed inside one of the open repositories is not loaded. That is the same rule as spec placement: with several repositories open, the process is the workspace’s decision rather than each repository’s. See Workspaces.
Every style — built-in included — is parsed by the same code. That is what makes a shipped style and a hand-written one behave identically by construction, and what makes “eject a built-in and modify it” a file copy rather than a code generator.
Changing one prompt without forking a style
You usually do not need a whole style. The definition and the prompts
resolve separately: the highest scope holding a style.yml supplies
the definition, but every scope holding that id contributes prompts.
So to change how Kiro writes design documents, and nothing else:
.local-workflows/styles/kiro/prompts/design.md
No style.yml. Kiro’s own definition still drives the pipeline; your
file replaces that one prompt. You inherit every later fix to the rest of
the style instead of freezing a copy of it.
style.yml, key by key
schema: 1
# Names the process this implements. The folder name is the identity;
# this field asserts it.
id: my-process
name: My Process
desc: One line, shown in the style picker.
# NOT a stage. The first document is drafted in a native chat, because a
# conversation gets more out of a person than a form does. Declared here
# so the engine knows which stage a spec lands on when the file appears.
intake:
prompt: prompts/intake.md
produces: requirements.md
# What + New Spec offers. A single entry means nobody is asked.
specTypes:
- id: feature
label: Feature
stages: [requirements, design, tasks, implement]
- id: bug
label: Bug fix
stages: [requirements, tasks, implement]
# Read first by every phase: what this process is and that the document,
# not the reply, is the deliverable.
intro: prompts/intro.md
format:
# Parser-critical rules. Given to every phase.
grammar: prompts/grammar.md
# House style, given only to the stage writing that document.
house:
requirements: prompts/format-requirements.md
design: prompts/format-design.md
tasks: prompts/format-tasks.md
stages:
- id: requirements
kind: ai
produces: [requirements.md]
gate: manual
prompt: prompts/requirements.md
- id: design
kind: ai
produces: [design.md]
gate: manual
prompt: prompts/design.md
- id: tasks
kind: ai
produces: [tasks.md]
mayProduce: [notes.md] # written only when the work calls for it
gate: manual
prompt: prompts/tasks.md
# The engine starts the session and does not wait. No artifacts, so
# this stage is never satisfied - which makes it terminal.
- id: implement
kind: implement
prompt: prompts/implement.md
For editor completion and hover docs on every key:
# yaml-language-server: $schema=https://local-workflows/schemas/sdd-style.schema.json
The four rules that decide everything
Get these and the format stops needing memorisation.
1. A stage is satisfied when its artifacts exist
This one rule does the most work in the whole design. It is why a spec
folder someone else wrote resumes at the right phase, why intake can
write requirements.md before the pipeline starts, and why re-running a
finished phase does nothing.
Its consequence: every stage must leave an artifact. A stage that writes nothing can never be satisfied, so the walk would park on it forever — which is why “review the documents and report” is not a phase.
2. kind: is either ai or implement
ai runs the prompt and waits for the artifacts it declared. An ai
stage with no produces is refused at load — it could never complete.
implement starts the session and does not wait. Declare no produces
and it can never be satisfied, which makes it terminal — how you say
the work for this phase happens somewhere the engine cannot reach.
That is what both shipped styles do. Give an implement stage a
produces and it becomes satisfiable, and no longer terminal.
A terminal stage must be the last one a spec type visits. Anything listed after it is unreachable, because the walk stops at the first unsatisfied stage — so that is refused at load too, rather than shipping a phase nobody can reach.
3. There is no requires: key
What a stage needs is whatever the prior stages of that spec type produced. Declaring it per stage would state the pipeline twice, and the two copies would eventually disagree.
This is also why a stage can appear in several spec types with different
args and no conditionals: in a Bug fix that skips design, the tasks
stage simply sees one document instead of two.
4. gate: manual parks the walk for a human
Put the gate on the phase that depends on a document, not on the one that wrote it. What a person approves is “this is good enough to build on” — a judgement made when you are about to rely on it.
A prompt’s job
Prompts are Markdown, and they are handed a specific, bounded context — never the whole folder, never a conversation.
Write a phase prompt about doing its job well. The pipeline, the
deliverable-is-the-document rule, and the parser-critical grammar are
already supplied by intro: and format.grammar:, to every phase. A
prompt that re-explains them is duplicated text that will drift.
Keep an ## Open Questions section in your document format. It is the
one hard block in the process: while it holds questions, the next phase
will not start.
Trying it
- Run Local Workflows: Eject Style and pick a built-in. It copies
the style’s files, byte for byte, into the scope you choose — your
user profile (
~/.local-workflows/styles/, the default, applies everywhere you work) or the workspace (committed with the repo). Existing files are listed and confirmed before anything is overwritten. - To make it a new style rather than a replacement of the built-in,
rename the folder and change
id:andname:to match. - Edit a prompt, or add a stage.
- Set
style: my-processin.local-workflows/config.yml. - + New Spec — your style is in the menu.
Starting from a copy rather than a blank file is the fastest path, because the shipped styles are heavily commented with the reasoning behind each key.
An ejected copy stops receiving improvements to the built-in. Kept under its original id it shadows the built-in outright. Reverting is deleting files — each file you remove falls back to the built-in.