██╗ ██╗███████╗███████╗███████╗██╗██████╗
╚██╗ ██╔╝██╔════╝██╔════╝██╔════╝██║██╔══██╗
╚████╔╝ █████╗ ███████╗███████╗██║██████╔╝
╚██╔╝ ██╔══╝ ╚════██║╚════██║██║██╔══██╗
██║ ███████╗███████║███████║██║██║ ██║
╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝
the safety layer for autonomous coding agents
Let AI coding agents work. Keep the dangerous decisions yours.
Yessir runs next to your terminal agent and answers all the boring “are you sure?” prompts for you — while blocking the ones that could wreck your repo. 🛡️
🧬 Yessir is the OSS spin-off of the safety layer that powers PromptOps — the full AI-agent orchestration platform by ShellOnBack. We pulled the part that every developer needs into its own MIT-licensed CLI. No account, no cloud, no UI.
Quick start · How it works · Policy · Modes · PromptOps · FAQ
Coding agents are fast — until they stop every 30 seconds to ask:
🤖 “Can I run
npm test?” 🤖 “Should I readpackage.json?” 🤖 “Do you want me to commit this?”
You have two bad options today:
- 😴 babysit every prompt and waste your focus, or
- 🙈 turn on dangerously-skip-permissions and pray the model isn't having a bad day.
Yessir is the third way. It reads your project's policy file, approves the boring stuff instantly, blocks the dangerous stuff deterministically, and escalates to you only when a human judgement actually matters. 🎯
npx yessir-cli init --hookThat's it. Now:
- 📝
.yessir/yessir.ymlis a conservative default policy (editable, commit it). - 🪝
.claude/settings.jsonwires aPreToolUsehook into Claude Code. - 🏃 Every active and future Claude Code session in this project follows the policy automatically.
Open Claude Code and watch it stop asking. 🤫
💡 Naming heads-up. The package is
yessir-cli(fornpx/npm install), the binary isyessir(after global install). So usenpx yessir-cli <cmd>without a global install, ornpm install -g yessir-clionce and thenyessir <cmd>everywhere.npx yessir …won't work — that name belongs to an unrelated npm package.
💡 Prefer to wrap the CLI instead of using the hook?
npx yessir-cli claude # wrap Claude Code in a managed PTY
npx yessir-cli codex # same, for OpenAI Codex
npx yessir-cli gemini # same, for Gemini CLI
npx yessir-cli -- aider # generic wrapper for any interactive agentUseful when a provider doesn't support hooks, or when you want the wrapper to also tail the terminal for heuristic detection.
$ yessir claude
🫡 Claude wants to run: npm test
Policy: allow.commands → "npm test"
Decision: ✅ APPROVED (3ms, deterministic)
🫡 Claude wants to edit: src/auth/login.ts
Policy: allow.write → "src/**"
Decision: ✅ APPROVED
🫡 Claude wants to run: git push --force origin main
Policy: deny.commands → "git push --force *"
Decision: ⛔ BLOCKED (conservative by design)
🫡 Claude asks: "Should I also update the snapshot files?"
Context tail: 212 lines
Decision: 🙋 ESCALATED to you (open question, AI reviewer disabled)
flowchart LR
A[Claude Code] -- PreToolUse --> B[yessir hook]
B --> C{Policy engine}
C -->|match deny| D[⛔ block]
C -->|match allow| E[✅ approve]
C -->|match require_manual| F[🙋 ask you]
C -->|destructive heuristic| F
C -->|unknown + AI mode| G[🤖 AI reviewer]
G --> C
D --> A
E --> A
F --> A
Precedence (highest wins):
- 🔴
deny - 🟡
require_manual - 🧨 destructive heuristics —
rm -rf,sudo,curl | bash, shell metacharacters - 🟢
allow - ❓ unknown → AI reviewer in
hybrid/aimode, otherwise escalated to you
🧱 Deny rules always override allow rules. Unknown destructive commands are never silently approved.
Generated by yessir init, lives at .yessir/yessir.yml, commits with your repo.
mode: hybrid
allow:
commands:
- git status
- git diff *
- npm test
- npm run test *
- npm run lint
read:
- "**/*"
write:
- src/**
- tests/**
deny:
commands:
- rm -rf *
- sudo *
- git push --force *
- curl * | bash
- npm publish
require_manual:
commands:
- git push
- git push *
- docker compose up *
- npm install *
ai_reply:
enabled: true
model: auto
max_tail_lines: 300| Where | * means |
Example |
|---|---|---|
commands |
any run of non-shell-metachars | git diff * matches git diff HEAD but NOT git diff && rm -rf |
read/write |
any run of non-slash chars (glob) | src/** matches src/a/b/c.ts |
? |
single non-slash char | file?.txt matches file1.txt |
| shell chars | |, &, ;, <, >, backtick, $ are dangerous — only allowed when a rule matches the exact pipeline |
| Mode | Who decides | Latency | Token cost |
|---|---|---|---|
quick |
policy only | ⚡ ~1ms | 0 |
hybrid ⭐ |
policy for known, AI reviewer for ambiguous (default) | ⚡/🤖 | tiny |
ai |
AI reviewer on every ambiguous decision | 🤖 | per-call |
yessir claude --mode quick # zero AI calls
yessir claude --mode hybrid # default
yessir claude --mode ai # everything through the reviewer
yessir claude --dry-run # see decisions without injecting anythingEvery approval, block, or escalation is written to .yessir/yessir.log as
one structured JSON line. Use the built-in streamer to watch it in real time:
yessir tail # follows the log, emoji + color, Ctrl+C to stop
yessir tail -n 200 # show the last 200 entries first
yessir tail --no-follow # print and exit (good for CI / scripting)
yessir tail --raw # raw JSON lines (no formatting)Example output while Claude Code is working next door:
12:00:00 Bash ✅ APPROVE matched allow rule "npm test"
12:00:02 Bash ⛔ BLOCK matched deny rule "rm -rf *"
12:00:04 Write ✅ APPROVE matched allow.write rule "src/**"
12:00:06 Bash 🙋 ASK unknown command, deferring to AI reviewer
Aliases: yessir watch and yessir logs do the same.
The default reviewer is a NoopReviewer that always escalates (safe default).
Swap in your model of choice:
import { AiReviewer, ReviewerInput, ReviewerOutput } from 'yessir-cli';
export class OpenAiReviewer implements AiReviewer {
readonly name = 'openai';
async review(input: ReviewerInput): Promise<ReviewerOutput> {
// call your model ...
return { decision: 'approve', reason: 'non-destructive read on tests/' };
}
}🔒 Context passed to your reviewer is first run through redactSecrets
(API keys, GitHub tokens, AWS keys, PEM blocks — masked before leaving
the process).
- 🏠 Local-first. Policy stays in your repo. No cloud proxy. No hosted runtime.
- 📦 Zero runtime dependencies. The whole safety layer is auditable in an afternoon.
- 🚫 Deny always wins. If two rules match, the deny one decides.
- 🧨 Destructive-by-heuristic stays manual.
rm -rf,sudo, pipes-to-bash, unknown shell metacharacters — none of those get auto-approved. - 🤖 The AI reviewer never runs commands. It returns a decision; the engine enforces it.
- 🔐 Secrets redacted before any context leaves the process.
- 🗂️ Append-only decision log at
.yessir/yessir.log.
bin/ thin launcher
src/
cli.ts argv → command dispatcher
commands/ init · hook · run · doctor · explain
policy/ yaml parser · loader · matchers · engine
detector/ provider adapters (claude · codex · gemini · generic)
tailer/ rolling buffer + ANSI strip
writer/ PTY write with y-streak + cooldown guardrails
hook/ Claude Code PreToolUse JSON adapter
ai/ reviewer interface · noop · secret redaction
pty/ node-pty wrapper (lazy-loaded, optional dep)
util/ append-only file logger
templates/ default .yessir/yessir.yml
test/ node --test suites (86 tests)
git clone https://github.com/shellonback/yessir-cli.git
cd yessir-cli
npm install
npm test86 tests covering policy matching, engine decisions, YAML parsing, tailer bounds, detector regex, writer concurrency, hook I/O, init idempotence, CLI argv parsing. CI runs on Ubuntu + macOS × Node 18/20/22.
- Claude Code
PreToolUsehook adapter - PTY wrapper for Claude / Codex / Gemini / generic agents
- YAML policy engine with deny-wins precedence
- Pluggable AI reviewer + secret redaction
- 🧷 Native provider for OpenAI + Anthropic reviewers
- 🌍
yessir doctor --fixauto-remediation - 📊 Opt-in local decision dashboard
- 🪟 Windows PTY fallback via ConPTY
- 🔌 Remote policy include (
extends: github:shellonback/yessir-rules)
Have an idea? Open an issue — PRs warmly welcomed. 💚
Yessir was born as a single module inside PromptOps, the full AI-agent orchestration platform by ShellOnBack. We extracted it because every developer running Claude Code, Codex or Gemini deserves the safety layer — even without the rest of the product. 🫡
| What you need | Use this |
|---|---|
| 🫡 Auto-approve safe commands in your terminal (free, OSS) | yessir-cli (you are here) |
| 🧠 A desktop app for running many agent sessions at once | PromptOps Desktop |
| 🏢 Team policies, audit log, dashboards, trust zones | PromptOps Manager |
| 📚 Prompt library, versioning, multi-provider routing | promptops.it |
| 📖 Guides on prompt engineering & agent orchestration | promptops.it/guide |
| 📰 What's new | promptops.it/changelog |
flowchart TB
subgraph OSS["🫡 yessir-cli (MIT · this repo)"]
A["policy engine + hook + PTY wrapper"]
end
subgraph POM["🧠 PromptOps — full platform by ShellOnBack"]
direction TB
B["Desktop app<br/>multi-session orchestrator"]
C["Manager<br/>teams · audit log · dashboards"]
D["Prompt library<br/>versioning · multi-provider"]
end
A -. same safety loop .-> B
A -. same safety loop .-> C
The policy engine, the PreToolUse hook adapter and the PTY writer are the
exact same building blocks used inside PromptOps — just trimmed down to zero
runtime dependencies and released under MIT so you can drop them into any repo.
🔗 Useful PromptOps links:
- 🌐 Landing — https://promptops.it
- 📥 Desktop download — https://promptops.it/download
- 📚 Guides — https://promptops.it/guide
- 📰 Changelog — https://promptops.it/changelog
- 📄 Docs — https://promptops.it/docs
- 🧰 LLM-friendly docs — https://promptops.it/llms-full.txt
- 🧑💻 Built by ShellOnBack — https://shellonback.com
Where does Yessir come from?
Yessir is the OSS spin-off of the safety module inside
PromptOps, the full
AI-agent orchestration platform by
ShellOnBack
(desktop app, manager, audit log, dashboards, team policies, prompt library,
multi-provider routing, etc).
The policy engine, the PreToolUse hook adapter and the PTY
writer are literally the same building blocks PromptOps uses under the
hood — we just extracted them, dropped every non-essential dependency,
and shipped them under MIT so you can drop the safety layer into any repo
without signing up for anything. If you end up wanting the orchestrator,
the audit log, or team policies on top of it, that lives at
promptops.it.
Should I use Yessir or PromptOps?
Start with Yessir. It's free, local, and takes one command to set up. When you outgrow "one policy file per repo" and start asking for shared team rules, audit log, dashboards, or a desktop app that runs multiple agents in parallel, that's when PromptOps becomes useful — and it keeps the same safety guarantees because it uses the same engine.
Does it send my code to a cloud service?
No. Hook and wrapper modes are entirely local. If you plug in an AI reviewer, you control where the context goes — and secrets are redacted first.
Can I use it without Claude Code?
Yes. yessir -- <any interactive CLI> wraps any terminal tool in a managed PTY
with the same policy engine — Aider, a bare shell, your custom agent, etc.
Is it a sandbox?
No. Yessir is a policy layer. It reduces the blast radius of casual agent misbehavior; it does not replace OS-level sandboxing (Docker, seatbelt, bubblewrap). Defence in depth is welcome.
What if the policy file is missing or broken?
Yessir refuses to silently degrade. A malformed policy causes the hook to
return ask (escalates to you) with a clear error in
.yessir/yessir.log. Unknown commands in quick mode
also default to escalation.
Issues, discussions and PRs are welcome. See CONTRIBUTING.md for project layout and conventions. Security reports? see SECURITY.md.
MIT © ShellOnBack
—
Made with 🫡 and a healthy fear of rm -rf by ShellOnBack.
Part of the PromptOps family —
the AI-agent orchestration platform.
promptops.it ·
download ·
guides ·
changelog ·
shellonback.com