Open-source tools to assist with spec-driven software development.
A simple spec format called feature.yaml, that keeps your requirements organized and traceable.
A CLI for you or your LLM to push and pull specs, requirements, coverage, status and comments.
A server and dashboard to facilitate QA, code review, and collaboration.
A process and convention for identifying spec requirements from within your code comments and tests, to create a searchable, greppable connection between the two.
Acai can be incrementally adopted into any existing project.
npx @acai.sh/cli --help
1
Specify
Write requirements and acceptance criteria in feature.yaml spec files.
2
Push
Run acai push to extract the specs and push them to an Acai Server.
3
Ship
Give your agents access to the cli so they can implement, review, self-assign and share status updates.
This unlocks a spec-oriented workflow that can replace GitHub and Linear tickets. You, your agent swarm, and your product manager can stay in-sync while rapidly iterating on specs and their implementations.
Invite your team to a shared Acai dashboard, or create access tokens for AI agents and CLI access to the server.
Track progress from spec, to implementation, to agent review, to human acceptance:No status -> Assigned -> Completed -> Accepted
Agent Code Reviewer
I've reviewed profile.MENU.2 and profile.AUTH.1I see no issues. Unit tests are satisfactory.I am marking the requirement as `COMPLETED`...I am merging the changes to the feature branch...
Acai introduces the ACID system for referencing your spec from anywhere in your repo. This makes it easy to see exactly where a requirement has been implemented or tested, so you (or your agent) can improve test coverage, QA, and react to ever-changing requirements.
Stop trying to read huge diffs from top to bottom. Instead, use the acai dashboard and jump straight to the functions, tests or comments that reference each requirement in your spec. Start by reviewing the requirements that matter most; auth, security, performance, and user happiness.
At the top of the page you can see a fun terminal animation we created as a demo of Acai in action. Below you can see the spec, code, and tests for that animation.
feature: name: animated-terminal product: docs description: | A mock terminal animation for our docs site. It demonstrates how an AI agent uses the acai toolkit to work on a software project. π₯ In the example, it is self-referentially building itself, from this very same spec.components: FRAME: name: Terminal frame and container description: UI container that looks like a terminal window on a Mac with a TUI instance running inside it requirements: 1: Renders scrollable mock chat history 1-1: Does not auto-scroll unless user is already at the bottom of scroll container 2: Renders mock text input 2-1: Does not accept actual user inputs (no typing, no buttons) STORY: name: Rough storyboard for the animation requirements: 1: Animation starts with user typing "I've made some changes to the spec @animated-terminal.feature.yaml - please run `acai skill` to learn spec-driven development." 2: Shows the agent run `acai skill`. Agent says "Got it. I will look to see what changed, then re-align the code to spec." 3: Concludes with user typing "Nice job. I'm looking at it right now. It's flawless. Go ahead and mark all requirements as accepted." 3-1: Agent runs `acai set-status` and marks all requirements as accepted. 4: The animation stops after the final step and does not loop.constraints: DEV: requirements: 1: Must be a single, self-contained standalone react component (a single export, with no imports)
// animated-terminal.DEV.1 - No importsexport const AnimatedTerminal = () => { const chatRef = useRef(null); useEffect(() => { // animated-terminal.FRAME.1-1 - autoscroll const el = chatRef.current; if (el) { // Use a threshold to detect if the user is "near" the bottom const isNearBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 100; if (isNearBottom) el.scrollTop = el.scrollHeight; } }, [messages]); return ( {/* animated-terminal.FRAME.1 */} <div ref={chatRef} className="chat-history flex-grow overflow-y-auto p-4 scroll-smooth"> {messages.map((msg, i) => renderMessage(msg, i))} </div> );};
// When we tag tests with requirement IDs, the acai.sh dashboard automatically tracks coverage!describe("Constraints", () => { // animated-terminal.DEV.1 - Dev constraint it("self-contained standalone component (no imports)", () => {});});describe("UI rendering", () => { // animated-terminal.FRAME.1 it("renders scrollable mock chat history", () => {}); // animated-terminal.FRAME.1-1 it("auto-scrolls ONLY if user is at bottom threshold", () => {}); // animated-terminal.FRAME.2 it("renders mock text input", () => {}); // animated-terminal.FRAME.2-1 it("ignores user typing and button interactions", () => {});});
As shown above, acai gives each requirement an ID that is unique, stable, and readable. These IDs should be referenced liberally (in tests, comments, and other specs), and are extracted from code with a single command.The idea is when your spec changes, your code must change too.
LLM agents love Acai IDs. They make it easy to pull in context, find references, and trace the intent of an implementation or test.
Stable, durable
Stop losing progress when agents go off the rails. Your spec is the source
of truth, even as complexity grows and requirements evolve.
Rapidly iterate
Quickly prototype, try throwaway implementations, and solidify the spec
before touching production code. The result is less time prompting, and a
better end result.
No tedium
In the past, this level of specification rigour was painful for human teams. Today, for an LLM with access to Acai, itβs painless.