{"id":50916463,"url":"https://github.com/michaelasper/hackpi","last_synced_at":"2026-06-16T15:32:17.849Z","repository":{"id":358514350,"uuid":"1241659278","full_name":"michaelasper/hackpi","owner":"michaelasper","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-17T19:05:01.000Z","size":43253,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-17T19:55:17.327Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/michaelasper.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.MD","dco":null,"cla":null}},"created_at":"2026-05-17T16:57:42.000Z","updated_at":"2026-05-17T19:05:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/michaelasper/hackpi","commit_stats":null,"previous_names":["michaelasper/hackpi"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/michaelasper/hackpi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelasper%2Fhackpi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelasper%2Fhackpi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelasper%2Fhackpi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelasper%2Fhackpi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/michaelasper","download_url":"https://codeload.github.com/michaelasper/hackpi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelasper%2Fhackpi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34412788,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-16T15:32:17.749Z","updated_at":"2026-06-16T15:32:17.841Z","avatar_url":"https://github.com/michaelasper.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cb\u003ehackpi\u003c/b\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ci\u003eA local-first coding agent with hash-anchored edits, sandboxed execution, and a full terminal UI.\u003c/i\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.rust-lang.org/\"\u003e\u003cimg src=\"https://img.shields.io/badge/rust-2021-orange?logo=rust\" alt=\"Rust 2021\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://crates.io/\"\u003e\u003cimg src=\"https://img.shields.io/badge/version-0.1.0-blue\" alt=\"v0.1.0\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## TL;DR\n\n**Problem:** Coding agents that edit files silently relocate changes, run arbitrary shell commands, and require cloud APIs.\n\n**Solution:** hackpi is a Rust coding agent that anchors every edit to a hash of the line being replaced, runs bash in a virtual filesystem with no network access, and streams everything through a terminal UI built on ratatui.\n\n| Feature | Benefit |\n|---------|---------|\n| Hash-anchored edits | Refuses stale anchors — no silent relocations |\n| Virtual bash filesystem | Sandboxed execution, no arbitrary exec |\n| Context-aware ripgrep | Search with `context_lines` built in |\n| 256 KB result cap + overflow to temp files | Prevents context blowup on long outputs |\n| Streaming TUI | Watch the agent think and act in real time |\n| Local-first API client | Works with DeepSeek V4 Flash on localhost |\n| **Task board** | Create, view, and transition tasks across workflow states |\n| **Guardrails** | Configurable allow/deny rules, permission prompts, session caching |\n| **Git \u0026 GitHub** | View git status, log, and list PRs directly from the TUI |\n| **Conversation export** | Export full conversation history to a text file |\n\n## Quick Start\n\n```bash\n# 1. Install (requires Rust)\ncurl -sSL https://raw.githubusercontent.com/michaelasper/hackpi/main/install.sh | bash\n\n# 2. Set your endpoint\nexport HACKPI_ENDPOINT=http://localhost:11434/api/chat\nexport HACKPI_MODEL=llama3.2\n\n# 3. Run\nhackpi\n```\n\nOr build from source:\n\n```bash\ngit clone https://github.com/michaelasper/hackpi.git\ncd hackpi\ncargo build --release -p hackpi-tui\ncp target/release/hackpi /usr/local/bin/\n```\n\n## Commands\n\nhackpi is a TUI application — launch it and type natural-language requests.\n\n### Global keys (always available)\n\n| Key | Action |\n|-----|--------|\n| `Ctrl+C` | Interrupt current generation |\n| `Ctrl+L` | Clear conversation |\n| `Ctrl+D` | Exit hackpi |\n| `?` | Show contextual help overlay |\n| `Tab` | Cycle views (Conversation → Tasks → Graph → Conversation) |\n\n### Context-specific keys\n\n| Context | Key | Action |\n|---------|-----|--------|\n| **Composer** (input) | `Enter` | Submit message |\n| | `Shift+Enter` | Insert newline |\n| | `/` | Start slash command (opens autocomplete) |\n| **Conversation** (scrollback) | `Up` / `Down` | Scroll conversation |\n| | `PgUp` / `PgDn` | Scroll faster |\n| | `Home` | Scroll to top |\n| | `End` | Scroll to bottom |\n| **Task board** | `Up` / `Down` | Navigate tasks |\n| | `Enter` | View task detail |\n| | `n` | Create task |\n| | `Esc` | Go back to conversation |\n| **Task detail** | `Up` / `Down` | Navigate fields |\n| | `Esc` | Go back to task board |\n\n### Slash Commands\n\nType `/` in the input to open the autocomplete popover, then type to filter:\n\n| Command | Description |\n|---------|-------------|\n| `/help` | Show available commands |\n| `/clear` | Clear the conversation |\n| `/quit` | Exit the application |\n| `/guardrails:status` | Show guardrails status |\n| `/guardrails:clean` | Clear session cache |\n| `/guardrails:onboarding [preset]` | Write a preset guardrails config (strict, balanced, permissive) |\n| `/git:status` | Show git status |\n| `/git:log` | Show recent git log |\n| `/github:pr-list` | List open pull requests |\n| `/task create \u003ctitle\u003e` | Create a new task |\n| `/task list` | List all tasks |\n| `/task show \u003cid\u003e` | Show task details |\n| `/task move \u003cid\u003e \u003cstate\u003e` | Move task to a new state |\n| `/task done \u003cid\u003e` | Mark task as done |\n| `/task block \u003cid\u003e \u003cblocked_by\u003e` | Add blocking dependency |\n| `/task unblock \u003cid\u003e \u003cblocked_by\u003e` | Remove blocking dependency |\n| `/task label \u003cid\u003e \u003clabel\u003e` | Add a label to a task |\n| `/task assign \u003cid\u003e \u003cassignee\u003e` | Assign task to someone |\n| `/tasks` | Alias for `/task list` |\n| `/export [path]` | Export conversation to text file |\n\n### Configuration\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `HACKPI_ENDPOINT` | `http://localhost:11434/api/chat` | LLM API endpoint |\n| `HACKPI_MODEL` | `llama3.2` | Model name |\n| `HACKPI_MAX_TOKENS` | `4096` | Maximum tokens per response |\n\n## Architecture\n\n```\n┌──────────┐     ┌──────────────┐     ┌───────────┐\n│  TUI     │────▶│  Agent Loop  │────▶│  API      │\n│  Events  │     │ (hackpi-core) │     │  Client   │\n└──────────┘     └──────┬───────┘     └───────────┘\n                        │\n                   ┌────▼───────┐\n                   │   Tool     │\n                   │  Registry  │\n                   └────┬───────┘\n                        │\n              ┌─────────┼─────────┐\n              │         │         │\n         ┌────▼───┐ ┌──▼───┐ ┌───▼────┐\n         │ bash   │ │ edit │ │ read   │\n         │(tools) │ │(tools)│ │(tools) │\n         └────────┘ └──────┘ └────────┘\n```\n\n### Crates\n\n| Crate | Purpose |\n|-------|---------|\n| `hackpi-core` | Agent loop, API client, tool registry, shared types |\n| `hackpi-tools` | `read`, `search_grep`, `edit`, `write`, `bash` |\n| `hackpi-tui` | ratatui terminal interface, event channels, input handling |\n| `hackpi-guardrails` | Path validation, file protection, command gating with permission prompt system |\n| `hackpi-tasks` | Task store, workflow state machine, slash-command task management |\n| `hackpi-vcs` | Git read operations and GitHub PR listing via slash commands |\n\n### Tool system\n\n| Tool | Description |\n|------|-------------|\n| `read` | Read files with hash-anchored line numbers |\n| `search_grep` | Context-aware ripgrep wrapper with `context_lines` |\n| `edit` | Replace/append/prepend lines anchored to hashes — rejects stale anchors |\n| `write` | Atomic file creation jailed to workspace root |\n| `bash` | Virtual shell with in-memory filesystem, built-in commands, pipes, and redirects |\n| `git_read` | Read-only git operations: status, diff, log, branches, remotes |\n| `git_write` | Mutating git operations: add, commit, push, merge, branch, rebase, stash |\n| `github` | GitHub operations: PRs, issues, labels, and releases |\n| `task` | Task management with workflow-defined states and blocking dependencies |\n| `bash` | Virtual filesystem with command registry — no network, no arbitrary exec |\n| `git_read` | Read git status and log |\n| `github` | List GitHub pull requests |\n| `task` | Create, list, show, move, and manage tasks |\n\n### Design decisions\n\n- **Hash-anchored edits**: Every `read` output includes a hash per line. Edits reference those hashes. If the file changed since the read, the edit is rejected rather than silently relocated.\n- **Streaming tool results**: Tool output streams back to the LLM in the same turn. No batched delivery.\n- **Turn limit**: Hard cap at 25 tool-use rounds per request. After that, the agent returns what it has.\n- **Deterministic**: `temperature=0`, flat tool schemas, minimal system prompt overhead.\n\n## Installation\n\n### Quick install (recommended)\n\n```bash\ncurl -sSL https://raw.githubusercontent.com/michaelasper/hackpi/main/install.sh | bash\n```\n\n### Cargo install\n\n```bash\ncargo install --git https://github.com/michaelasper/hackpi hackpi-tui\n```\n\n### Build from source\n\n```bash\ngit clone https://github.com/michaelasper/hackpi.git\ncd hackpi\ncargo build --release -p hackpi-tui\ncp target/release/hackpi /usr/local/bin/\n```\n\n### Custom install location\n\n```bash\nINSTALL_DIR=\"$HOME/.local/bin\" ./install.sh\n```\n\n## Troubleshooting\n\n### Error: \"Rust is not installed\"\n\n```bash\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n```\n\n### Error: \"Permission denied\" during install\n\n```bash\nsudo INSTALL_DIR=\"/usr/local/bin\" ./install.sh\n# Or use a user-writable directory:\nINSTALL_DIR=\"$HOME/.local/bin\" ./install.sh\n```\n\n### Error: \"Binary not found in PATH\"\n\n```bash\nexport PATH=\"$PATH:/usr/local/bin\"\n# Add to ~/.bashrc or ~/.zshrc for persistence\n```\n\n## Limitations\n\n| Limitation | Detail | Workaround |\n|------------|--------|------------|\n| Local LLM only | Optimized for DeepSeek V4 Flash on localhost | Other Anthropic-format APIs may work |\n| No arbitrary shell exec | Bash tool uses a virtual filesystem | Use `write` + external terminal for untrusted commands |\n| 256 KB per tool result | Large outputs truncated to temp file | Re-read the temp file with `read` |\n| 25-turn cap | Agent stops after 25 rounds | Continue in a new request |\n\n## Documentation\n\n### Tutorials (learn by doing)\n- [Getting Started](docs/tutorials/getting-started.md) — Install hackpi, connect to an LLM, make your first edit\n\n### How-to Guides (solve a problem)\n- [Configure Guardrails](docs/how-to/configure-guardrails.md) — Set up allow/deny rules, respond to permission prompts\n- [Edit Files with Hash Anchors](docs/how-to/edit-files.md) — Read, edit, and chain operations\n- [Connect to Different LLM Providers](docs/how-to/connect-llm.md) — Point hackpi at different API endpoints\n\n### Reference (look things up)\n- [Tools Reference](docs/reference/tools.md) — Full schemas and parameters for all five tools\n- [Key Bindings](docs/reference/key-bindings.md) — TUI keyboard shortcuts\n- [Guardrails Reference](docs/reference/guardrails.md) — Rule format, evaluation order, persistence\n- [Environment Variables](docs/reference/environment-variables.md) — Configuration variables\n\n### Explanation (understand concepts)\n- [Why Hash Anchors?](docs/explanation/hash-anchors.md) — The motivation and design behind hash-anchored editing\n- [Security Model](docs/explanation/security-model.md) — Sandboxed execution, path jails, and guardrails\n- [Architecture](docs/explanation/architecture.md) — Crate structure, data flow, and streaming tool results\n\n### Specification files\n\nDetailed implementation specs for each subsystem:\n\n- [hashline.spec.md](hashline.spec.md) — Edit system, LINE#HASH anchoring, diff preview\n- [tui.spec.md](tui.spec.md) — TUI layout, key bindings, event channels\n- [read-tool.spec.md](read-tool.spec.md) — `read` and `search_grep` tools\n- [write-tool.spec.md](write-tool.spec.md) — `write_file` tool, atomic writes, path jail\n- [bash-tool.spec.md](bash-tool.spec.md) — Virtual bash, filesystem trait, command registry\n\n## Contributing\n\nIssues and pull requests are welcome at [github.com/michaelasper/hackpi](https://github.com/michaelasper/hackpi).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelasper%2Fhackpi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichaelasper%2Fhackpi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelasper%2Fhackpi/lists"}