Sakura — Project Overview
Deterministic AI CLI with plan/apply safety gates and AWS passthrough.
Sources: README.md · CLAUDE.md · package.json
What Is Sakura?
Sakura is a terminal-first AI assistant that routes your natural-language requests through a deterministic plan → confirm → execute pipeline. Unlike raw LLM chat, every mutating action (AWS command, code patch, shell operation) is classified by risk, serialized as a plan, and requires explicit user confirmation before execution.
For complex multi-step tasks, Sakura hands off to a full LLM tool loop — giving the model access to file I/O, shell, AWS CLI, web fetch, and MCP-connected external servers — while keeping the human in the loop for anything destructive.
Sources: src/sakura.ts · src/cli.ts · src/types.ts
The Problem It Solves
| Pain Point | Sakura's Answer |
|---|---|
| LLMs run AWS commands without asking | Risk classification gate — readonly runs immediately, mutating requires confirmation |
| AI edits files without showing diffs | Code plans serialize a unified diff before applying |
| No audit trail for AI actions | Every plan is written to .sakura/plans/ as JSON with provenance |
| Context window bloat in long sessions | Auto-compact summarizes history; state anchors prevent drift |
| Vendor lock-in to one LLM | Provider abstraction supports OpenAI, Anthropic, and a managed API proxy |
Tech Stack
CLI (/)
| Layer | Technology |
|---|---|
| Runtime | Node.js ≥ 20, TypeScript 5.8, ESM |
| CLI framework | Commander.js |
| LLM SDKs | @anthropic-ai/sdk, openai |
| MCP | @modelcontextprotocol/sdk |
| Process execution | execa |
| Config | TOML + Zod validation |
| Tests | Vitest |
Sources: package.json · tsconfig.json
API (/api)
| Layer | Technology |
|---|---|
| Framework | Express 4 + serverless-http |
| Deployment | AWS Lambda (Node 20) via AWS SAM |
| Database | DynamoDB (PAY_PER_REQUEST) |
| Auth | JWT + bcrypt |
| Billing | Stripe |
| Secrets | AWS SSM Parameter Store |
Sources: api/package.json · api/template.yaml
Web (/web)
| Layer | Technology |
|---|---|
| Framework | Next.js (static export) |
| Styling | Tailwind CSS |
| Deployment | S3 + CloudFront |
Sources: web/next.config.mjs
High-Level Architecture
Sources: src/routing.ts · src/repl/tool-loop.ts · src/mcp/lifecycle.ts · api/template.yaml
Request Flow (Detailed)
Sources: src/cli.ts · src/repl/aws-handler.ts · src/repl/tool-loop.ts
Quick Start
Install
# One-liner (macOS/Linux)
curl -fsSL https://cli.sakura-ai.dev/install.sh | bash
# From source
git clone <repo-url> && cd sakura
npm install && npm run build && npm link
Authenticate
# Via Sakura account (managed API — no local keys needed)
sakura login --github
# or
sakura login --email you@example.com --password yourpassword
# Or set local API keys directly
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...
Initialize a project
cd your-project
sakura init
# Creates .sakura/config.toml
Configure (.sakura/config.toml)
version = 1
defaultProfile = "default"
[profiles.default]
provider = "openai"
model = "gpt-5.2"
temperature = 0.2
[profiles.coding-claude]
provider = "anthropic"
model = "claude-sonnet-4-20250514"
temperature = 0.2
Sources: src/config.ts
Use it
# Interactive REPL (default)
sakura
# One-shot commands
sakura ask "list all S3 buckets in us-east-1"
sakura ask "refactor src/auth.ts to use a class"
sakura ask "what does src/routing.ts do"
# AWS passthrough with safety gate
sakura aws "s3 ls" # readonly — runs immediately
sakura aws "s3 rm s3://my-bucket/file.txt" # mutating — shows plan + confirms
# Apply a saved plan
sakura apply .sakura/plans/latest.json
REPL slash commands
/init Scan project and generate .sakura/project.md context
/plan <task> Generate and execute a multi-step plan
/scaffold Scaffold a project from a template
/build Guided project builder (discovery → scaffold → implement)
/phase [n] Execute a build phase from BUILD_ORDER.md
/parallel Split a task and run subtasks in parallel
/planner Toggle read-only task breakdown mode
/trust Trust all commands for this session
/mcp Show loaded MCP knowledge pack info
/context Show context window usage
/help Full command list
Sources: src/repl/slash-commands.ts
Monorepo Structure
sakura/
├── src/ # CLI source
│ ├── sakura.ts # Entry point
│ ├── cli.ts # Commander subcommands
│ ├── config.ts # TOML config + Zod schemas
│ ├── routing.ts # Intent classification
│ ├── types.ts # Shared types (Intent, Plan, etc.)
│ ├── providers/ # LLM provider adapters
│ │ ├── provider.ts # LlmProvider interface
│ │ ├── openai.ts
│ │ ├── anthropic.ts
│ │ └── api.ts # Managed API proxy
│ ├── repl/ # Interactive REPL
│ │ ├── index.ts # REPL startup + main loop
│ │ ├── tool-loop.ts # LLM tool-call loop
│ │ ├── aws-handler.ts # AWS intent handler
│ │ └── slash-commands.ts
│ ├── planning/ # Plan generation + storage
│ ├── tools/ # Tool registry + implementations
│ ├── mcp/ # MCP client + bridge
│ ├── aws/ # AWS guard + runner
│ ├── auth/ # Key resolution + session
│ ├── sessions/ # Conversation persistence
│ ├── scaffold/ # Project scaffolding
│ └── plugins/ # @tag plugin system
├── api/ # Express API → AWS Lambda
│ ├── src/
│ │ ├── routes/ # auth, llm, billing, account, admin
│ │ ├── services/ # db, secrets, model-router, prompts
│ │ └── middleware/ # auth, rate-limit
│ └── template.yaml # SAM / CloudFormation
├── web/ # Next.js marketing + docs site
│ ├── app/ # App Router pages
│ └── components/ # UI components
└── test/ # Vitest test suite
Sources: src/ · api/src/ · web/app/
Table of Contents
| Document | Description |
|---|---|
| Overview | ← You are here |
| Architecture | Deep-dive: routing, tool loop, MCP, planning |
| Configuration | config.toml, profiles, MCP config, settings |
| Data Models | Plan, Session, User, DynamoDB tables |
| Development | Build, test, deploy, contributing |
Key Design Principles
-
Plan before mutate — every destructive action is serialized as a JSON plan with risk classification before execution. Sources: src/planning/store.ts · src/aws/guard.ts
-
Provider agnostic — the
LlmProviderinterface abstracts OpenAI, Anthropic, and the managed API proxy behind a singlecomplete()/stream()contract. Sources: src/providers/provider.ts -
Trust levels — every tool declares
trusted | trust_read_only | trust_working_dir | not_trusted; the executor enforces these before callingexecute(). Sources: src/tools/registry.ts · src/tools/executor.ts -
Context hygiene — the tool loop auto-compacts history at 32 000 chars and injects state anchors every 5 iterations to prevent model drift. Sources: src/repl/tool-loop.ts
-
MCP as first-class — external MCP servers (stdio, SSE, HTTP) are loaded at startup and their tools/resources are registered into the same tool registry as built-ins. Sources: src/mcp/bridge.ts · src/mcp/lifecycle.ts