std::slop is a persistent, SQLite-driven C++ CLI coding agent. It exposes direct, schema-validated tools for repository inspection, exact edits, unified patches, shell validation, database access, scratchpad state, and mail-mode git workflows.
Direct tools keep ordinary operations explicit and individually reviewable. Mail workflow tools enforce staging, review, approval, and finalization protections server-side.
- π Personas & Skills: Define global agent instructions via
AGENTS.mdand extend capabilities using modular, on-demandSKILL.mdfiles. - π Ledger-Driven: All interactions and tool calls are stored in SQLite for persistence and auditability.
- π Session Scratchpad: Maintain a per-session planning buffer with
/scratchpad edit,/scratchpad save, andread_scratchpad/write_scratchpadtools. - ποΈ Context Control: SQL-backed, per-session accordion history preserves an append-only prompt prefix between resets, so sessions can grow independently while retaining cache-friendly context.
- πͺ Accordion context: Use
/context <retain_groups> [watermark_tokens]to grow a cache-friendly prompt prefix, then reset to complete recent groups after the latest actual prompt usage reaches the watermark (defaults:2,350000). Tool results remain full fidelity up to their configured per-result limit. - Mail workflows: Use docs/mail_mode.md for patch-based delivery.
- Models: Supports OpenAI-compatible Responses endpoints and ChatGPT Plus/Pro OAuth.
- Hotwords: Activate a skill for one turn with
hey <skill> <query>.
The project ships Linux x86-64 and macOS binaries every release. You can directly use them.
- C++17 compiler (Clang/GCC)
- Bazel (Bazelisk recommended)
- Git: Targets must be valid git repositories. Usually, a git add and an initial commit is sufficient to trigger all the git enabled features.
# Build the binary
bazel build //:std_slop
# Optional: Add to your PATH
cp ./bazel-bin/app/std_slop /usr/local/bin/std::slop works best when it can track a specific project. Initialize a git repository and run it from the root:
mkdir my-project && cd my-project
git init
std_slopFor quick one-off tasks, you can use Batch Mode:
std_slop --prompt "Refactor main.cpp to remove all unused includes"Batch mode accepts exactly one instruction source, and optional piped stdin is prepended as context:
std_slop --prompt_file task.md
ls *.cc | std_slop --prompt "sort these files in alphabetical order"Use exactly one instruction source: --prompt or --prompt_file. Piped stdin is optional context. Batch mode uses an in-memory database unless --prompt_db is set.
For scripts, --output=json writes run metadata:
std_slop --prompt_file task.md --output=json | jq -r .assistant_messageThe JSON object contains ok, session, model, active_skills, assistant_message, structured_output, error, and duration_ms.
Use --format or --format_file to require a JSON Schema-constrained final value. The raw validated value is the only stdout payload, so structured output cannot be combined with --output=json:
std_slop --prompt "Extract the name" \
--format '{"type":"object","properties":{"name":{"type":"string"}},"required":["name"],"additionalProperties":false}'
cat incident.log | std_slop \
--prompt_file summarize_incident.md \
--format_file incident_summary.schema.json \
--model gpt-5.4-mini:high \
--session incident-2026-07-19 \
--prompt_db /tmp/slop-incident.dbThe supported schema subset is a root object plus nested object, array, string, number, integer, boolean, and null types; properties, required, boolean additionalProperties, items, and non-empty enum arrays.
Read the Walkthrough first for the recommended getting-started flow, authentication setup paths, config.ini setup, docs-folder navigation, and llm_query subquery/persona configuration. Then use docs/README.md as the docs index for deeper reference material.
- OpenAI-compatible: set
OPENAI_API_KEYor put it in~/.config/slop/config.ini - OpenAI-compatible API key: set
OPENAI_API_KEY, optionally combine with--openai_base_url, or put both inconfig.ini - OpenAI OAuth (Responses API): run
std_slop --fetch_openai_oauth_tokenorstd_slop --fetch_openai_oauth_device_token, then start with--openai_oauth
You can configure std::slop using environment variables or a configuration file.
The agent looks for a configuration file at ~/.config/slop/config.ini. You can also specify a custom path using the --config flag.
It is STRONGLY RECOMMENDED that slop.db lies in a central directory or outside the codebase. It generates 2 other artifact files, at least ensure that
your .gitignore contains this. The context ledger is completely stored in the database, and it can inadvertently capture information from your environment if you are not careful. Eg Environment Variables.
For a getting-started walkthrough that covers config methods end-to-end, see docs/WALKTHROUGH.md.
[slop]
model = your-model-name
# OR
openai_api_key = sk-...
openai_base_url = https://api.openai.com/v1
# openai_oauth = true # optional: use OpenAI OAuth token + Responses API
# openai_oauth_token_path = /custom/path/chatgpt_plus_token.jsonSee docs/example_config.ini for a full list of options.
You can define config-based llm_query specializations as first-class tools. This
is useful for role-focused delegation (for example: code review, repo exploration)
without rewriting prompts each time.
Add one INI section per specialization using the llm_tool_ prefix:
[llm_tool_code_review_llm]
system_prompt_patch = You are a strict code reviewer focused on correctness and regressions.
session_id = code_review
skill = code_reviewer
context_window = 8After startup, call the specialized tool directly by name (for example
llm_tool_code_review_llm) with a query argument.
For a complete multi-specialization example, see docs/example_subqueries.ini. Detailed behavior and policy constraints are documented in docs/impl/subqueries.md.
SLOP_DEBUG_HTTP=1: Enable full verbose logging of all HTTP traffic (headers & bodies).
- C++ Standard: C++17.
- Style: Google C++ Style Guide.
- Exceptions: Disabled (-fno-exceptions).
- Memory: RAII and std::unique_ptr exclusively.
- Error Handling: absl::Status and absl::StatusOr.
- Asan and Tsan clean at all times.
- Personas & Skills: Understanding global context injection and modular skills.
- Documentation Guide: Entry point and reading order for the documentation set.
- Architecture & Schema: Understanding the database-driven engine.
- Sessions: How context isolation and management work.
- Context Management: The history and strategy for managing model memory.
- Walkthrough: A step-by-step example of using the agent.
- Subquery Implementation Notes: Design and policy notes for INI-configured
llm_queryspecializations. - Fuzzing: FuzzTest targets, invariants, and how to run/extend the fuzz suite.
- Contributing: Code style, formatting, and linting guidelines.
The core logic is divided into modules:
database.h: Manages the SQLite-backed ledger. Handles persistence for messages, memos, tools, and skills.tool_dispatcher.h: Implements a thread-safe execution engine. It dispatches multiple tool calls concurrently while ensuring results are returned in the proper order for the LLM.cancellation.h: Provides a mechanism for interrupting tasks. It supports registering callbacks to kill shell processes or abort HTTP requests.orchestrator.h: high-level interface for model interaction. The Responses API orchestrator manages history windowing and response parsing.shell_util.h: Executes shell commands in a separate process group, with support for live output polling and termination on cancellation.http_client.h: A minimalist, cancellation-aware HTTP client used for all model API calls.
interface/: Implements the terminal UI. The UI is minimal but clean, uses readline for user input, color codes and ASCII Codes.markdown/: Usestree-sitter-markdownto provide syntax highlighting (C++, Python, Go, JS, Rust, Bash) and structured rendering for agent responses. This is a stand alone Markdown parser / renderer library in C++.app/main.cpp: The primary event loop. Coordinates between the Orchestrator, ToolDispatcher, and UI.
