Metadata-Version: 2.4
Name: andromity
Version: 0.2.0
Summary: AI coding agent with a beautiful terminal UI. Works with Claude, Gemini, GPT, Ollama and more.
Author-email: Agentic Market <hello@agenticmarket.dev>
License: MIT
Project-URL: Homepage, https://agenticmarket.dev
Project-URL: Repository, https://github.com/agenticmarket/andromity
Project-URL: Bug Tracker, https://github.com/agenticmarket/andromity/issues
Keywords: ai,coding-agent,tui,terminal,llm,claude,gemini,mcp,cli
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development
Classifier: Topic :: Terminals
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: textual<9.0,>=8.2.8
Requires-Dist: pillow>=10.0
Requires-Dist: litellm<2.0,>=1.50
Requires-Dist: tomli>=2.0; python_version < "3.12"
Requires-Dist: tomli-w>=1.0
Requires-Dist: gitpython>=3.1
Requires-Dist: rich>=13.0
Requires-Dist: click>=8.0
Requires-Dist: mcp<2.0,>=1.0.0
Requires-Dist: httpx>=0.28.0
Requires-Dist: httpx-sse>=0.4.0
Requires-Dist: watchdog>=3.0
Requires-Dist: markdownify>=0.14.0
Requires-Dist: ddgs>=1.0.0
Requires-Dist: textual-plotext>=0.2.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
Dynamic: license-file

<div align="center">

  <h1>
    <img src="andromity.png" alt="Andromity Logo" width="50" height="50" valign="middle" />
    Andromity
    <br>
  <strong>The coding agent that never clocks out.</strong>
  </h1>

  <img src="screen_shot.png" alt="Andromity Screenshot" width="100%" />


  <p align="center">
    <a href="https://pypi.org/project/andromity/"><img src="https://img.shields.io/pypi/v/andromity" alt="PyPI version" /></a>
    <img src="https://img.shields.io/badge/version-0.2.0-blueviolet" alt="Version 0.2.0" />
    <img src="https://img.shields.io/badge/python-3.11+-blue" alt="Python" />
    <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License: MIT" /></a>
  </p>
  <p align="center">
    <strong>One command to install. One command to run. No browser. No IDE. No lock-in.</strong>
  </p>
  <p align="center">
    Andromity is an open-source terminal AI coding agent with a built-in cron scheduler and MCP support.<br>
    Schedule it to run while you sleep, connect any MCP server, and approve every change before it lands.
  </p>



  <br />

  
</div>



## Why Andromity?

Most AI coding agents are interactive only: you start them, prompt them, and wait.

Andromity is built for **autonomous, scheduled work**.

- **Cron jobs** — run fixes, reviews, and tests on a timer, even while you sleep
- **MCP support** — connect external tools without writing integrations
- **Approval modes** — from full manual control to full autonomy (SAFE → YOLO)
- **Terminal-native** — no IDE, no browser, no cloud lock-in
- **Local-first** — your code, your keys, your machine
- **Model-agnostic** — LiteLLM under the hood: Anthropic, OpenAI, Gemini, Groq, OpenRouter, Ollama, NVIDIA NIM, and more

---

## What's New in v0.2.0

### ⚡ Instant Startup — Blank Screen Eliminated

- **Removed dead `litellm` import** in the settings module that forced a full `litellm` dependency-graph load at startup, adding 3–18 seconds of blank screen before the TUI appeared.
- **Lazy-loaded `SettingsScreen`** — the 87KB settings module is now imported only when you open Settings, not at app boot.

### 🏃 Long-Session Performance & Memory Stability

A full audit and remediation of runtime bottlenecks that accumulate over long, multi-turn sessions:

| Fix | What was wrong | What changed |
|-----|---------------|--------------|
| **Debounced Session I/O** | Every streamed token wrote synchronously to disk | 1.5s debounced background save with `flush()` on switch/exit |
| **Widget Timer Teardown** | `set_interval()` timers kept firing after message widgets were removed | `on_unmount()` hooks cancel all timers on every sub-widget |
| **DOM History Serialization** | Pruned chat messages stayed in memory as live Textual Widget trees | Messages beyond 60 in view are serialized to dicts; re-inflated on scroll |
| **File Watcher Thread Churn** | Every filesystem event spawned a new `threading.Timer` thread | Single persistent daemon worker thread with `threading.Condition` |
| **Undo Stack Capping** | Large pastes accumulated megabytes in undo history | Prompt previews capped at 20,000 chars per checkpoint |
| **Accurate Auto-Compaction** | Context threshold used character-math estimates | Uses real `context_tokens` from provider usage reports when available |
| **Daemon Threads for Warmup** | Background import warmup blocked test pilots and app teardown | `threading.Thread(daemon=True)` used for warmup and git init |

### ✅ Test Suite

68 tests across session, agent, file tree, undo, status bar, interactive questions, and config — all green.

---

## Install

### Easiest — one-line installer (recommended)

**Linux / macOS:**
```bash
curl -fsSL https://raw.githubusercontent.com/agenticmarket/andromity/main/install.sh | bash
```

**Windows (PowerShell):**
```powershell
irm https://raw.githubusercontent.com/agenticmarket/andromity/main/install.ps1 | iex
```

> The scripts auto-install [pipx](https://pipx.pypa.io) if needed, install andromity globally, and patch your `PATH` — no manual steps.

### Manual — pipx

```bash
pipx install andromity
```

> Don't have `pipx`? Install it first: `pip install pipx && pipx ensurepath`, then open a new terminal.

**Requirements:** Python 3.11+

---

## Quick Start

```bash
andromity
```

That's it. The TUI opens. Point it at any codebase and start building. No model configured yet? The model picker opens automatically — hit **Ctrl+L** anytime to switch provider or model.

### Headless / Scripted

```bash
andromity run "refactor this module to use async"
andromity run "add error handling to tools.py" --yes       # auto-approve all
andromity run "write tests for session.py" --dry-run       # preview only
```

---

## Run it on a schedule

Most agents stop when you close the terminal. Andromity doesn't have to.

Type `/cron` in the TUI to open the Cron Manager and schedule the agent to work in the background:

- **Every morning at 2am** — "Run the test suite and fix any failing tests"
- **Every 30 minutes** — "Check for dependency vulnerabilities and open a PR"
- **Every day** — "Review uncommitted changes and summarize them"
- **Every 2 hours** — "Tail the error log and investigate new exceptions"

Each job gets its own model, permission mode (use `yolo` for fully autonomous background work), and prompt. Jobs run asynchronously and only interrupt you when they need attention.

Jobs are stored locally in your project at `.andromity/crons.json`.

---

## MCP (Model Context Protocol) Support

Andromity supports [MCP](https://modelcontextprotocol.io/) to connect external tools and APIs natively.

**Smart lazy-loading:** MCP tool schemas are injected into the system prompt as a compact index and loaded fully only when the LLM requests them — preventing token exhaustion with 50+ tools connected.

**Usage:**
- Configure servers in `.andromity/mcp.json` or `.vscode/mcp.json`
- Type `/mcp` in the chat to view connected servers and available tools

---

## Benchmarks (SWE-bench Lite)

Andromity solves complex, real-world GitHub issues autonomously. We benchmarked it against a random subset of [SWE-bench Lite](https://www.swebench.com/) — a dataset of real Python issues from major open-source projects.

**Setup:**
- **Dataset:** SWE-bench Lite (random subset of 25 tasks)
- **Model:** DeepSeek V4 Flash (via OpenRouter)
- **Mode:** Headless (`andromity run --file prompt.txt --yes --profile coder`)

**Results (official SWE-bench Docker evaluation):**
- **Resolve rate: 73.7%** — **14 of 19** generated patches passed the official SWE-bench test suite (FAIL_TO_PASS + PASS_TO_PASS, run with the official `swebench.harness` Docker evaluator)
- **End-to-end: 56%** — 14 of the 25 sampled tasks fully resolved, including the 6 tasks where no patch was produced
- **Patch generation rate: 76%** — 19 of 25 tasks produced a valid git diff autonomously; all 19 applied cleanly to their base commits
- **Speed:** ~167 seconds per successful task on average
- The agent consistently used standard UNIX tools to navigate, search, and patch each repo

> **Honest comparison:** published SWE-bench resolve rates for leading agent frameworks are roughly Aider ~26% (SWE-bench Lite), Cursor ~38–42%, and Claude Code ~45–53% (mostly reported on SWE-bench *Verified*; figures vary by source and are frequently updated). Andromity's 56% end-to-end on this 25-task sample (95% confidence interval roughly 35–75%) is competitive with or ahead of those — achieved with **DeepSeek V4 Flash**, a commodity model costing a small fraction of proprietary equivalents. Caveat: 25 tasks is a small sample; run the full 300-task benchmark before drawing strong conclusions.

### Example Fixes

The agent navigated large codebases, isolated root causes, and generated correct diffs for complex bugs:

**Astropy Issue #12907 (separable models logic):**
The agent correctly identified the hardcoded `1` and replaced it with the `right` matrix object in `astropy/modeling/separable.py`.
```diff
--- a/astropy/modeling/separable.py
+++ b/astropy/modeling/separable.py
@@ -242,7 +242,7 @@ def _cstack(left, right):
         cright = _coord_matrix(right, 'right', noutp)
     else:
         cright = np.zeros((noutp, right.shape[1]))
-        cright[-right.shape[0]:, -right.shape[1]:] = 1
+        cright[-right.shape[0]:, -right.shape[1]:] = right
 
     return np.hstack([cleft, cright])
```

**Astropy Issue #14995 (NDData arithmetic with masked operand):**
The agent spotted the missing `operand.mask is None` case in `astropy/nddata/mixins/ndarithmetic.py` and generalized the condition — verified to pass the official test suite.
```diff
--- a/astropy/nddata/mixins/ndarithmetic.py
+++ b/astropy/nddata/mixins/ndarithmetic.py
@@ -520,7 +520,7 @@ class NDArithmeticMixin:
         elif self.mask is None and operand is not None:
             # Make a copy so there is no reference in the result.
             return deepcopy(operand.mask)
-        elif operand is None:
+        elif operand is None or operand.mask is None:
             return deepcopy(self.mask)
```

---

## Modes & Permissions

| Mode | Plan Required? | Plan Gate | File Writes |
|------|---------------|-----------|-------------|
| **SAFE** (default) | Yes (for complex) | 🔴 User must approve | 🔴 Batch review overlay after turn |
| **TRUST** | Yes (for complex) | 🔴 User must approve | ✅ Written directly, no review |
| **FULL** | Yes (for complex) | ✅ Auto-approved | ✅ Written directly, no review |
| **YOLO** | Yes (shown as FYI) | ✅ Auto-approved | ✅ Silent, no review |

---

## Privacy & Security

Andromity is local-first: **code never leaves your machine except to the LLM provider you configure.**

- API keys stored locally in `~/.andromity/config.toml`
- Sessions stored locally in `~/.andromity/sessions/`
- Anonymous ping on first launch and session start — no file paths, code, API keys, or personal data collected. Full details in the [Telemetry Privacy Policy](telemetry-worker/README.md)
- Opt out via the TUI (**Ctrl+E → Advanced → Telemetry**), `export DO_NOT_TRACK=1`, or `telemetry = false` in `config.toml`

**Security notes:**
- Session files are stored in plaintext — don't use Andromity on shared machines with sensitive codebases
- Cron jobs in `.andromity/crons.json` auto-load from the project directory — review via `/cron` before trusting a cloned repo

---

## Profiles

Switch the agent's role with `--profile` (CLI) or `/profile` (TUI) or via the **Ctrl+J** menu in the TUI:

| Profile | What it does | Tools available |
|---------|-------------|-----------------|
| `builder` (default) | Plans and implements step-by-step | read, search, write, edit, shell, web, tools, plans |
| `coder` | Direct implementation, no planning phase | read, search, write, edit, shell, web, tools |
| `reviewer` | Read-only audit producing HIGH/MED/LOW findings | read, search, list, web, tools |
| `planner` | Produces step-by-step plans without modifying code | read, search, list, tools, write_plan |

---

## Agent Tools

| Tool | What it does |
|------|-------------|
| `read_file` | Reads a file or specific line range (protected against path traversal) |
| `write_file` | Creates or overwrites a file in the workspace |
| `edit_file` | Replaces a specific string inside a file |
| `edit_file_multi` | Applies multiple non-contiguous edits to a file in one call |
| `shell_exec` | Executes a shell command in the project directory |
| `list_dir` | Lists directory contents |
| `grep_search` | Ripgrep-style search across the codebase |
| `find_files` | Find files matching a glob pattern |
| `write_plan` | Creates a step-by-step plan for approval |
| `create_todo` | Creates a todo item |
| `update_todo` | Updates a todo status (active / done / failed) |
| `list_todos` | Shows active todos and progress |
| `list_tools` | Discovers connected MCP servers and lazy-loaded plugins |
| `web_search` | Searches the internet for up-to-date documentation and fixes |
| `fetch_url` | Downloads and converts a webpage to readable markdown |

In `SAFE` mode (default), all write, edit, and shell operations require explicit user approval.

---

## Chat Commands

Type these directly in the chat bar to manage the agent and session:

| Command | Description |
|---------|-------------|
| `/model` | Switch provider & model (or **Ctrl+L**) |
| `/profile [name]` | Switch profile (`builder`/`reviewer`/`planner`) (or **Ctrl+J**) |
| `/mode [safe\|trust\|full\|yolo]` | Set permission mode for file/shell approvals |
| `/undo` | Undo the last prompt and revert all file changes |
| `/mcp` | Show MCP server status and available tools |
| `/sessions` | Browse and switch sessions (or **Ctrl+O**) |
| `/new` | Start a new session |
| `/rename <name>` | Rename the current session |
| `/compact` | Summarize & compress old context to free up token space |
| `/settings` | Open the master settings panel (or **Ctrl+E**) |
| `/keys` | View status of all provider API keys |
| `/keys set <prov> <key>` | Save an API key securely to your universal config |
| `/trust` | Trust the current folder (enables file writes + shell) |
| `/untrust` | Remove trust for the current folder |
| `/dry-run` | Toggle dry-run mode (simulates tools without writing/running) |
| `/debug` | Toggle debug mode (shows tool calls inline) |
| `/logs` | Display log file location and trailing instructions |
| `/cron` | Open the background task scheduler |
| `/plan clear` | Clear the active session plan |
| `/clear` | Clear the chat history |

---

## Configuration

Config lives at `~/.andromity/config.toml` (created automatically on first run).

```toml
[default]
provider = "anthropic"
model    = "claude-sonnet-4-5"
profile  = "builder"

[[providers]]
name = "anthropic"
type = "anthropic"
api_key = "sk-ant-..."

[[providers]]
name = "openai"
type = "openai"
api_key = "sk-..."

[[providers]]
name = "gemini"
type = "google"
api_key = "AI..."

[[providers]]
name = "openrouter"
type = "openrouter"
api_key = "sk-or-..."

[[providers]]
name = "ollama"
type = "ollama"
base_url = "http://localhost:11434"
```

API keys can also be set via environment variables (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, `OPENROUTER_API_KEY`, etc.).

**Provider support:** Andromity uses [LiteLLM](https://github.com/BerriAI/litellm) under the hood, so it works with any LiteLLM-supported provider — Anthropic, OpenAI, Gemini, Groq, OpenRouter, Ollama, NVIDIA NIM, and more. Currently tested with Ollama, NVIDIA NIM, Groq, OpenRouter, and Google Gemini.

---

## Sound Notifications

Andromity plays a sound when:
- **Attention needed** — the AI is paused waiting for you to approve or reject a tool call
- **Response done** — the AI has finished its full response turn

Both sounds can be toggled independently under **Ctrl+E → Advanced → Sounds**.

---

## 📁 Data & Logs Location

All local configuration, session history, and logs are stored locally on your machine.

**Default Location:**
```bash
# macOS / Linux
~/.andromity/

# Windows
%APPDATA%\andromity\
```

**⚠️ Windows Store Python Users:**
If you installed Python via the Microsoft Store, Windows heavily virtualizes application data. Your files will NOT be in the standard `%APPDATA%` directory. Instead, you can find your `config.toml`, logs, and sessions at:
```bash
%LOCALAPPDATA%\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\Roaming\andromity\
```
*(Note: The exact path changes slightly depending on your Python version, e.g., `Python.3.11...` or `Python.3.13...`)*

---

## Project Structure

```
src/andromity/
├── cli.py              # CLI commands (run, tui)
├── config.py           # Configuration and trust management
├── assets/
│   └── sounds/         # Bundled notification sounds
├── core/
│   ├── agent.py        # Main agent execution loop and streaming
│   ├── audio.py        # Cross-platform sound notifications
│   ├── profiles.py     # AI profiles and dynamic system prompt builder
│   ├── tools.py        # Core tool implementations with safety guards
│   ├── provider.py     # LiteLLM client wrapper
│   ├── session.py      # Session persistence and token tracking
│   ├── models.py       # Model catalog and context limits
│   ├── git_ops.py      # Git snapshots and rollback operations
│   ├── cron.py         # Project-level background task scheduler
│   ├── mcp.py          # MCP server discovery and tool loading
│   ├── planner.py      # Plan generation and approval flow
│   ├── security.py     # Path traversal and shell safety guards
│   └── web.py          # Web search and page fetching
└── tui/
    ├── app.py          # Textual-based interactive UI
    ├── footer.py       # Input bar and status bar
    ├── panels/
    │   ├── chat.py     # Message history and markdown rendering
    │   ├── diff.py     # Side-by-side diffs and tool approval dialogs
    │   └── plan.py     # Real-time plan tracking and todo list
    └── overlays/
        ├── settings.py # Settings UI (model, profiles, MCP, advanced)
        ├── model.py    # Model picker overlay
        └── profile.py  # Profile picker overlay
```

---

## Development Setup

Clone the repo and install in editable mode — changes to source files take effect immediately without reinstalling:

```bash
git clone https://github.com/agenticmarket/andromity
cd andromity
python3 -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate
pip install -e ".[dev]"
andromity
```

> **Ubuntu/Debian users:** A venv is required — these systems use PEP 668 to protect the system Python. The commands above handle this correctly.

**Run tests:**
```bash
pytest tests
```

**Project layout follows `src/` layout** — all source lives under `src/andromity/`.

---

## Contributing

Open an issue or PR. Bug reports and honest feedback are more useful than feature requests at this stage.

---

## License

MIT — see [LICENSE](LICENSE).
