Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ members = [
]

[workspace.package]
version = "1.20.3"
version = "1.20.4"
edition = "2024"
authors = ["Terraphim Team <team@terraphim.ai>"]
documentation = "https://terraphim.ai"
Expand Down
12 changes: 12 additions & 0 deletions crates/terraphim_agent/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Changelog

All notable changes to terraphim_agent are documented here.

## [1.20.4] - 2026-06-13

### Fixed
- Hermetic integration tests now bootstrap `Terraphim Engineer` via `role_config` in
test settings instead of a missing `terraphim_server/` path from the polyrepo split.

### Added
- Crate-specific `README.md` with install instructions, feature flags, and quick start.
2 changes: 1 addition & 1 deletion crates/terraphim_agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ homepage = "https://terraphim.ai"
repository = "https://github.com/terraphim/terraphim-ai"
keywords = ["cli", "ai", "agent", "search", "repl"]
license = "Apache-2.0"
readme = "../../README.md"
readme = "README.md"

[features]
default = ["repl-interactive", "llm", "repl-sessions"]
Expand Down
140 changes: 140 additions & 0 deletions crates/terraphim_agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# terraphim_agent

Terraphim AI Agent CLI — semantic search, knowledge-graph exploration, and an interactive REPL for AI coding workflows.

## Overview

`terraphim_agent` is the primary command-line interface for Terraphim. It combines offline-capable local search with optional server-backed fullscreen TUI mode, knowledge-graph validation, hook integration for AI coding assistants, and operational learning capture.

Install the binary as `terraphim-agent`.

## Features

- **Semantic search** across configured haystacks with KG-aware ranking
- **Interactive REPL** with markdown-defined commands and autocomplete
- **Knowledge graph tools** — validate, replace, extract, and visualize concepts
- **Session search** — import and query AI coding assistant session history
- **Operational learning** — capture corrections, query learnings, replay procedures
- **Safety guards** — block destructive git/filesystem commands before execution
- **Robot mode** — structured JSON output for automation and agent orchestration

## Installation

### From crates.io

```bash
cargo install terraphim_agent
```

### From source

```bash
git clone https://git.terraphim.cloud/terraphim/terraphim-clients.git
cd terraphim-clients
cargo build -p terraphim_agent --release --bin terraphim-agent
```

The release binary is at `target/release/terraphim-agent`.

### Feature Flags

| Feature | Default | Description |
|---------|---------|-------------|
| `repl-interactive` | Yes | Interactive REPL with rustyline |
| `llm` | Yes | Ollama and LLM router integration |
| `repl-sessions` | Yes | Session import and search |
| `server` | No | HTTP client for server-backed TUI |
| `repl-full` | No | All REPL sub-features (chat, MCP, web, file) |
| `shared-learning` | No | Cross-agent learning store and wiki sync |
| `enrichment` | No | Concept enrichment for session search |

Build with extra features:

```bash
cargo build -p terraphim_agent --release --features repl-full,server
```

## Quick Start

```bash
# Show available commands
terraphim-agent --help

# Semantic search (offline)
terraphim-agent search "async error handling"

# List and select roles
terraphim-agent roles list
terraphim-agent roles select "Terraphim Engineer"

# Validate text against the knowledge graph
terraphim-agent validate --connectivity "haystack service uses automata"

# Start the REPL
terraphim-agent repl

# First-time setup wizard
terraphim-agent setup
```

### Server-backed TUI

When a Terraphim server is running:

```bash
terraphim-agent --server --server-url http://127.0.0.1:8000 interactive
```

### Robot / automation output

```bash
terraphim-agent search "retry policy" --robot --format json
```

## Configuration

On first run, the agent reads `settings.toml` from the platform config directory
(`~/.config/terraphim/` on Linux). Point `role_config` at a JSON role definition
to bootstrap roles and haystacks:

```toml
role_config = "/path/to/terraphim_engineer_config.json"
default_data_path = "~/.local/share/terraphim"
```

Use `terraphim-agent config show` to inspect the active configuration and
`terraphim-agent config validate` to check role definitions.

## Key Commands

| Command | Purpose |
|---------|---------|
| `search` | Semantic document search |
| `graph` | ASCII knowledge-graph visualization |
| `validate` | KG connectivity and checklist validation |
| `replace` | Thesaurus-based text replacement |
| `hook` | Pre/post-tool-use hook handler for AI assistants |
| `guard` | Safety pattern check for shell commands |
| `learn` | Operational learning capture and query |
| `sessions` | Import and search AI coding sessions |

## Testing

```bash
# Unit tests
cargo test -p terraphim_agent --lib

# Integration tests (hermetic, no server required)
cargo test -p terraphim_agent --test offline_mode_tests
cargo test -p terraphim_agent --test exit_codes
```

## Related Crates

- [`terraphim-cli`](https://crates.io/crates/terraphim-cli) — lightweight CLI for scripted search
- [`terraphim_grep`](https://crates.io/crates/terraphim_grep) — hybrid grep with KG boost and LLM fallback
- [`terraphim_mcp_server`](https://crates.io/crates/terraphim_mcp_server) — MCP tools for editor integration

## License

Apache-2.0
13 changes: 8 additions & 5 deletions crates/terraphim_agent/tests/exit_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,17 @@ fn search_succeeds_exits_0() {

#[test]
fn validate_with_no_kg_exits_3() {
// Load a fixture config where the role has kg: null so the service layer
// returns "Knowledge graph not configured", which classify_error maps to
// ErrorIndexMissing (3). This avoids relying on the developer's local KG.
let fixture = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/no_kg_config.json");
// Embed the fixture content at compile time so this test works even when
// compiled from a git worktree that is later deleted (shared target dir).
// Writing to a temp file avoids a runtime path dependency on CARGO_MANIFEST_DIR.
let fixture_content = include_str!("no_kg_config.json");
let dir = tempfile::tempdir().expect("temp dir");
let fixture_path = dir.path().join("no_kg_config.json");
std::fs::write(&fixture_path, fixture_content).expect("write fixture");
cmd()
.args([
"--config",
fixture,
fixture_path.to_str().expect("valid path"),
"validate",
"xyzzy_f1_2_exit_code_test_sentinel",
])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"id": "Server",
"global_shortcut": "Ctrl+Shift+T",
"roles": {
"Terraphim Engineer": {
"shortname": "TerraEng",
"name": "Terraphim Engineer",
"relevance_function": "terraphim-graph",
"terraphim_it": true,
"theme": "lumen",
"kg": {
"automata_path": null,
"knowledge_graph_local": {
"input_type": "markdown",
"path": "crates/terraphim_agent/tests/test_kg"
},
"public": true,
"publish": true
},
"haystacks": [
{
"location": "crates/terraphim_agent/docs/src/kg",
"service": "Ripgrep",
"read_only": true,
"atomic_server_secret": null,
"extra_parameters": {}
}
],
"llm_provider": null,
"llm_auto_summarize": false,
"llm_system_prompt": "You are a Terraphim Engineer assistant.",
"extra": {}
},
"Default": {
"shortname": "Default",
"name": "Default",
"relevance_function": "title-scorer",
"terraphim_it": false,
"theme": "spacelab",
"kg": null,
"haystacks": [
{
"location": "crates/terraphim_agent/docs/src/kg",
"service": "Ripgrep",
"read_only": true,
"atomic_server_secret": null,
"extra_parameters": {}
}
],
"llm_provider": null,
"llm_auto_summarize": false,
"llm_system_prompt": "You are a helpful assistant.",
"extra": {}
}
},
"default_role": "Terraphim Engineer",
"selected_role": "Terraphim Engineer"
}
17 changes: 11 additions & 6 deletions crates/terraphim_agent/tests/support/cli_test_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,14 @@ fn create_unique_test_root() -> Result<PathBuf> {
pub fn apply_hermetic_env(cmd: &mut Command) -> Result<()> {
let root = create_unique_test_root()?;
let home_dir = root.join("home");
let xdg_config_home = root.join("xdg-config");
let xdg_config_home = home_dir.join(".config");
let terraphim_config_dir = xdg_config_home.join("terraphim");
let data_dir = root.join("data");
let dashmap_dir = root.join("dashmap");
let sqlite_dir = root.join("sqlite");

fs::create_dir_all(&home_dir)?;
fs::create_dir_all(&xdg_config_home)?;
fs::create_dir_all(&terraphim_config_dir)?;
fs::create_dir_all(&data_dir)?;
fs::create_dir_all(&dashmap_dir)?;
fs::create_dir_all(&sqlite_dir)?;
Expand All @@ -75,12 +76,16 @@ pub fn apply_hermetic_env(cmd: &mut Command) -> Result<()> {
// Write to all three under the hermetic HOME so whichever runs first
// finds our settings.
let sqlite_db = sqlite_dir.join("terraphim.db");
let role_config = workspace_root()?
.join("crates/terraphim_agent/tests/fixtures/terraphim_engineer_config.json");

let settings_toml = format!(
r#"
server_hostname = "127.0.0.1:8000"
api_endpoint = "http://localhost:8000/api"
initialized = "false"
default_data_path = "{data}"
role_config = "{role_config}"

[profiles.dashmap]
type = "dashmap"
Expand All @@ -96,9 +101,10 @@ table = "terraphim_kv"
dashmap = dashmap_dir.display(),
sqlite = sqlite_dir.display(),
db = sqlite_db.display(),
role_config = role_config.display(),
);
let settings_dirs = [
home_dir.join(".config").join("terraphim"),
terraphim_config_dir.clone(),
home_dir
.join("Library")
.join("Application Support")
Expand All @@ -110,13 +116,12 @@ table = "terraphim_kv"
}

let workspace = workspace_root()?;
let role_config = workspace.join("terraphim_server/default/terraphim_engineer_config.json");

cmd.current_dir(&workspace)
.env("HOME", &home_dir)
.env("XDG_CONFIG_HOME", &xdg_config_home)
.env("TERRAPHIM_DEFAULT_DATA_PATH", &data_dir)
.env("TERRAPHIM_ROLE_CONFIG", &role_config);
.env("TERRAPHIM_SETTINGS_PATH", &terraphim_config_dir)
.env("TERRAPHIM_DEFAULT_DATA_PATH", &data_dir);

Ok(())
}
Loading