looprs
A Rust LLM agent loop CLI. Tools, loops, and conditions — no convoluted markdown parsing system.
Install
# or: cargo install --path crates/looprs-cli
Configure
Pick a provider:
# Anthropic
# OpenAI
# Local (Ollama)
# SDK-backed providers
# openai-sdk | anthropic-sdk | claude-sdk
Persistent config: .looprs/provider.json. All env options: .env.example.
Built-in Tools
| Tool | Description |
|---|---|
/read |
Read files with line pagination |
/write |
Create or overwrite files |
/edit |
Replace text in files |
/glob |
Find files by name pattern (faster with fd) |
/grep |
Search file contents (faster with rg) |
/nu |
Execute a Nushell command |
/bash |
Execute shell commands |
Optional speedups (auto-detected, falls back to pure Rust):
File References
Reference files in prompts with @filename syntax — contents are injected into the conversation.
Refactor @crates/looprs-cli/src/main.rs for better error handling
Compare @crates/looprs/src/agent.rs and @crates/looprs/src/api.rs
Extensibility
The .looprs/ directory defines repo-local agent configuration. All extension points support dual-source loading: user-level (~/.looprs/) and repo-level (.looprs/), with repo taking precedence.
.looprs/
├── provider.json # Provider/model settings
├── config.json # Runtime defaults, file refs, pipeline, agents, paths
├── commands/ # Custom slash commands (/)
├── hooks/ # Event-driven hooks (YAML)
├── skills/ # Skills with progressive disclosure ($)
├── agents/ # Agent role definitions (YAML)
└── rules/ # Constraints and guidelines (Markdown)
config.json is loaded into AppConfig and supports:
defaults: runtime limits such as context tokens, temperature, and timeout.file_references: allowed@filereference extensions and maximum file size.onboarding: onboarding state, with.looprs/state.jsontaking precedence at runtime.pipeline: optional pipeline checks, compaction settings, and log directory.agents: delegation defaults, filesystem mode, parallelism, and orchestration strategy.paths: repo-local directories for agents, commands, hooks, rules, and skills.
Provider selection and model settings are separate. Put provider, provider-specific model, max_tokens, and timeout_secs in .looprs/provider.json.
Commands
Define slash commands in .looprs/commands/<name>.yaml:
name: test
description: Run tests
action:
type: shell
command: cargo nextest run
inject_output: true
Action types: prompt (send to LLM), shell (run command with Nushell), message (print to console).
Built-in repo commands: /help, /refactor, /test, /lint.
Skills
Skills follow progressive disclosure: YAML frontmatter with name/description/triggers, invoked with $skill-name or via keyword match. Loaded from ~/.looprs/skills/ and .looprs/skills/.
Agents
YAML role definitions in .looprs/agents/. Agent dispatcher switches roles during a session.
Rules
Markdown constraint files in .looprs/rules/. Evaluated against agent behavior.
Hooks
YAML hooks fire on session lifecycle events. Define in .looprs/hooks/<EventName>.yaml:
name: show_status
trigger: SessionStart
condition: has_tool:jj
actions:
- type: command
command: "jj log -r 'main::' | head -3"
inject_as: recent_commits
- type: command
command: "git status --short"
requires_approval: true
approval_prompt: "Inject git status into context?"
Events: SessionStart, UserPromptSubmit, InferenceComplete, PreToolUse, PostToolUse, OnError, OnWarning, SessionEnd.
Action types: command (Nushell command, optional inject_as and requires_approval), message, conditional.
Observability
looprs writes structured JSONL traces and events:
.looprs/observability/traces/*.jsonl— turn traces.looprs/observability/ui_events.jsonl— UI/machine events
Redirect to an external path:
Live LLM tests are gated by:
Architecture
Workspace
The repository is a Cargo workspace:
crates/looprs-core/— core API, types, ports, events, and lightweight adapterscrates/looprs/— agent runtime, providers, tools, hooks, skills, plugins, configuration, and observabilitycrates/looprs-cli/—looprsbinary, CLI argument parsing, REPL, and runtime facadextask/— local automation shim that delegates totaskittests/— workspace integration testsfuzz/— fuzz targets, excluded from the default workspace
See docs/ownership-model.md for canonical ownership boundaries.
Dev
The Makefile is still available for common shortcuts such as make build, make lint, and make all. Use cargo xtask pre-push before pushing; the installed .githooks/pre-push delegates to the same command and includes the looprs-cli binary test suite that library-only shortcuts do not cover.
License
MIT