Skip to content

shellonback/yessir-cli

Repository files navigation

             ██╗   ██╗███████╗███████╗███████╗██╗██████╗
             ╚██╗ ██╔╝██╔════╝██╔════╝██╔════╝██║██╔══██╗
              ╚████╔╝ █████╗  ███████╗███████╗██║██████╔╝
               ╚██╔╝  ██╔══╝  ╚════██║╚════██║██║██╔══██╗
                ██║   ███████╗███████║███████║██║██║  ██║
                ╚═╝   ╚══════╝╚══════╝╚══════╝╚═╝╚═╝  ╚═╝
                the safety layer for autonomous coding agents

🫡 yessir-cli

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.

CI npm version npm downloads node license tests zero deps PromptOps by ShellOnBack

Quick start · How it works · Policy · Modes · PromptOps · FAQ


✨ Why Yessir?

Coding agents are fast — until they stop every 30 seconds to ask:

🤖 “Can I run npm test?” 🤖 “Should I read package.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. 🎯


🚀 Quick start

npx yessir-cli init --hook

That's it. Now:

  1. 📝 .yessir/yessir.yml is a conservative default policy (editable, commit it).
  2. 🪝 .claude/settings.json wires a PreToolUse hook into Claude Code.
  3. 🏃 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 (for npx / npm install), the binary is yessir (after global install). So use npx yessir-cli <cmd> without a global install, or npm install -g yessir-cli once and then yessir <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 agent

Useful when a provider doesn't support hooks, or when you want the wrapper to also tail the terminal for heuristic detection.


🎬 What it looks like

$ 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)

🧠 How it works

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
Loading

Precedence (highest wins):

  1. 🔴 deny
  2. 🟡 require_manual
  3. 🧨 destructive heuristics — rm -rf, sudo, curl | bash, shell metacharacters
  4. 🟢 allow
  5. ❓ unknown → AI reviewer in hybrid/ai mode, otherwise escalated to you

🧱 Deny rules always override allow rules. Unknown destructive commands are never silently approved.


📜 Policy

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

Pattern rules (short version)

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

⚙️ Modes

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 anything

🪵 Live log — see every decision as it happens

Every 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.


🧩 Plugging your own AI reviewer

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).


🛡️ Safety principles

  • 🏠 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.

🗺️ Architecture

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)

🧪 Tests

git clone https://github.com/shellonback/yessir-cli.git
cd yessir-cli
npm install
npm test

86 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.


🗓️ Roadmap

  • Claude Code PreToolUse hook 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 --fix auto-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. 💚


🧬 Part of the PromptOps family

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
Loading

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:


❓ FAQ

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.


🤝 Contributing

Issues, discussions and PRs are welcome. See CONTRIBUTING.md for project layout and conventions. Security reports? see SECURITY.md.

📜 License

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

About

No description, website, or topics provided.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors