AI prompts are starting to look a lot like software.
Not just the quick one-off prompts we type into a chat box, but the reusable stuff.
The slash commands.
The agent definitions.
The rule files.
The system prompts.
The project-specific workflows.
The “please do this exact thing every time, in this exact order, with these exact constraints” files.
At some point, those stop feeling like notes.
They start feeling like source code.
So I built Stim.
Stim is a small DSL for writing AI prompts, commands, agents, and orchestration workflows as actual source files.
You write one .stim file, then compile it to the AI tool you want to use.
Claude Code today.
ChatGPT.
Cursor.
And hopefully more tools over time.
Repo:
https://github.com/wess/stim
The problem
Most AI workflow files are just Markdown.
And Markdown is great.
Until it isn’t.
A simple prompt is fine in Markdown:
You are a senior engineer.
Review this code for bugs.
Explain the most important issues first.
No problem there.
But then real workflows start creeping in.
You want the prompt to ask questions.
You want it to branch based on the answer.
You want reusable agents.
You want different output formats for different tools.
You want one version of the workflow that works in Claude Code, Cursor, or ChatGPT.
You want a review agent, a planning command, a security workflow, a writing assistant, and maybe a little team of agents that can work together.
Eventually the Markdown starts doing that thing where it is technically still Markdown, but spiritually it is a programming language wearing a fake mustache.
That is where Stim comes in.
What Stim is
Stim is a DSL for writing AI workflows.
It lets you define things like:
- commands
- agents
- reusable orchestration harnesses
- variables
- imports
- loops
- conditionals
- parallel tasks
- fan-out and gather flows
- package-based prompt libraries
Then Stim compiles those files into whatever your target tool expects.
For example:
stim install reviewer.stim
Can install a Claude Code agent.
stim install reviewer.stim --target cursor
Can compile the same source into a Cursor rule.
stim compile reviewer.stim --target chatgpt
Can create Markdown you can paste into ChatGPT or a Custom GPT.
That is the main idea:
Write the workflow once. Target the tool later.
A simple command
Here is a tiny Stim command:
command greet {
ask("What's your name?")
wait_for_response()
ask("Nice to meet you! How can I help today?")
}
That can compile into a Claude Code slash command.
Nothing too wild.
But once commands become more involved, the structure starts to matter.
Here is a more useful example:
command brainstorm {
ask("What problem are you trying to solve?")
wait_for_response()
done = false
while (!done) {
ask("What's the next important question we should answer?")
wait_for_response()
if (confirm("Does this feel complete enough to turn into a spec?")) {
done = true
}
}
create_file("SPEC.md", "Create a clear project spec from the conversation.")
}
That is the kind of thing I kept wanting.
Not just a prompt.
A workflow.
Something that can guide an AI tool through a repeatable process.
Agents are first-class too
Stim is not only for commands.
You can define agents:
agent security_reviewer {
description "Reviews code for security vulnerabilities"
tools [Read, Grep, Bash]
model "sonnet"
"You are a security engineer specializing in web application security."
"Look for SQL injection, XSS, auth bypasses, exposed secrets, and unsafe deserialization."
"Cite file paths and line numbers for every finding."
"Prioritize findings by severity."
}
That can become a Claude Code agent.
Or it can compile to another target where some fields are handled differently.
For example, if a target does not support a field like tools or model, Stim can warn and drop that field instead of making you maintain a totally separate version.
That matters because every AI tool has its own format.
Claude Code wants one thing.
Cursor wants another thing.
ChatGPT wants something else.
Stim gives you a source format above those tools.
Commands, agents, and harnesses
Stim has three big building blocks.
Commands are interactive workflows:
command plan_feature {
ask("What feature are we planning?")
wait_for_response()
}
Agents are reusable personas with metadata:
agent doc_writer {
description "Writes clear technical documentation"
"You write documentation for engineers."
"Use concrete examples from the actual code."
}
Harnesses are reusable orchestration templates:
harness find_verify {
param finders
param votes 3
fanout over finders {
task explore "investigate" {
ask("Investigate this lead")
}
}
gather "merge findings and remove duplicates"
}
That third one is important.
Stim is not just trying to make prettier prompt files.
It is trying to describe agentic workflows in a way that can be reused, shared, and compiled.
Multi-agent workflows
One of the things I’m most excited about is orchestration.
For example, you can describe a deeper review workflow like this:
command deep_review {
ask("What code should I review?")
wait_for_response()
parallel {
task explore "security scan" {
ask("Check for SQL injection, XSS, auth flaws, and exposed secrets")
}
task explore "performance audit" {
ask("Find N+1 queries, unnecessary allocations, and blocking I/O")
}
task explore "architecture review" {
ask("Evaluate separation of concerns and dependency management")
}
}
ask("Compile all findings into a single report")
create_file("REVIEW.md", "review_report")
}
This is where Stim starts to feel different from just writing a prompt.
The file is describing a workflow shape.
Ask this.
Then run these tasks in parallel.
Then gather the result.
Then write the final output.
The AI tool still executes the workflow, but Stim gives you a cleaner way to define it.
Why this matters
I think prompt files are going to become more like code.
Maybe not all prompts.
A quick “explain this error” does not need a DSL.
But the prompts we reuse?
The prompts we commit to a repo?
The prompts that define how our agents behave?
The prompts that control team workflows?
Those deserve better tooling.
They should be parseable.
They should be validated.
They should be compiled.
They should be shared.
They should be versioned.
They should have packages.
They should have editor support.
They should eventually have tests.
That is the direction Stim is exploring.
Target different AI tools
Right now Stim supports multiple targets.
The idea is that a .stim file should be the source of truth, and each target adapter decides how to emit the final output.
For example:
stim install security_reviewer.stim
Installs for Claude by default.
stim install security_reviewer.stim --target cursor
Installs as a Cursor rule.
stim compile security_reviewer.stim --target chatgpt
Compiles to Markdown for ChatGPT.
This is one of the big reasons I wanted Stim to exist.
I do not want to rewrite the same agent or workflow three different ways just because every AI tool has a slightly different file format.
That gets old fast.
Package management
Stim also has a decentralized package idea.
Any GitHub repo with a stim.yaml manifest can become a package.
So you can install shared commands, agents, and workflows like this:
stim add github/wess/stim/packages/reviews
stim add github/wess/stim/packages/gitflow
stim add github/wess/stim/packages/planning
stim add github/wess/stim/packages/writing
That opens the door for reusable AI workflow libraries.
A team could have its own internal Stim package.
An open source project could publish review agents.
Someone could publish a whole set of planning, refactoring, testing, and documentation workflows.
That feels useful to me.
Not because every workflow should be installed from a package.
But because the good ones should be shareable.
Editor support
Stim also has an LSP.
That means editor integrations can share the same language server.
The repo includes plugin work for:
- VS Code
- Neovim
- Zed
The goal is to make writing AI workflows feel more like writing code.
Syntax highlighting.
Diagnostics.
Snippets.
Compile commands.
Eventually, I want the experience to feel natural enough that editing a prompt workflow does not feel like editing a giant magic text blob.
Built with TypeScript and Bun
Stim is written in TypeScript and built with Bun.
To try it:
git clone https://github.com/wess/stim.git
cd stim
bun install
bun run build
Then:
./dist/stim version
You can compile a file:
stim compile examples/brainstorm.stim
Or install one:
stim install examples/reviewer.stim
There is also a token command:
stim tokens examples/deepreview.stim
That estimates the compiled token count, which is useful when workflows start getting bigger.
What I want Stim to become
The bigger idea is this:
AI workflows should not be locked inside one tool’s format.
I want to write the workflow once and take it with me.
I want to define a reviewer agent once.
I want to define a planning command once.
I want to define a multi-agent review process once.
Then I want to point it at Claude Code, ChatGPT, Cursor, or whatever tool comes next.
Tools will keep changing.
Prompt formats will keep changing.
Agent systems will keep changing.
But the workflow itself should be portable.
That is what Stim is aiming for.
A few things I’m excited to explore next
There is still a lot I want to improve.
Some ideas:
- more target adapters
- better package discovery
- richer validation
- stronger editor integrations
- more first-party workflow packages
- better examples
- workflow testing
- cleaner docs around advanced orchestration
I especially want to see what kinds of workflows other people would build with it.
Because everyone uses AI tools a little differently.
Some people want code review agents.
Some want planning systems.
Some want writing helpers.
Some want project-specific rule files.
Some want a small team of agents that can coordinate on a task.
Stim is meant to give those ideas a source format.
Try it out
Stim is early, but it is already useful enough that I wanted to share it.
You can check it out here:
https://github.com/wess/stim
If you are already building custom AI commands, agents, rules, or prompts, I would love for you to try it.
And if you have ideas, issues, or weird workflows you want to support, open an issue or send a PR.
I think we are still early in figuring out how developers should organize AI workflows.
Stim is my attempt at one answer:
Treat prompts like source code.
Then compile them wherever they need to go.
Top comments (0)