┃┃┃
┃┃┃
┃┃┃
━━━━━━━━━━━━━━━━━━━━╋╋╋━━━━━━━━━━━━━━━━━━━━
┃┃┃
┃┃┃
┃┃┃
┃┃┃
┃┃┃
███████╗ ██████╗ ██████╗ ██████╗ ██╗██╗ ██╗███████╗███╗ ██╗
██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██║██║ ██║██╔════╝████╗ ██║
█████╗ ██║ ██║██████╔╝██║ ███╗██║██║ ██║█████╗ ██╔██╗ ██║
██╔══╝ ██║ ██║██╔══██╗██║ ██║██║╚██╗ ██╔╝██╔══╝ ██║╚██╗██║
██║ ╚██████╔╝██║ ██║╚██████╔╝██║ ╚████╔╝ ███████╗██║ ╚████║
╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚═══╝
an AI-first terminal code editor · MIT License
Alpha release — forgiven is under active development. Expect rough edges, breaking keybinding changes, and missing polish. Feedback and bug reports are welcome via GitHub Issues.
An AI-first, terminal-based code editor with GitHub Copilot agent integration, inspired by Emacs / Spacemacs key philosophy and Vim modal editing.
Forgiven is built around a small set of deliberate choices. Every feature decision — including what not to implement — flows from these principles.
The agent is the primary editing surface. The goal is not to make manual editing faster; it is to make manual editing rarely necessary. You describe intent; forgiven and the agent act on it.
You read code when there is a specific, concrete problem that cannot be resolved otherwise. You do not browse, navigate, or refactor it habitually. This means features optimised purely for manual code manipulation (multi-cursor, complex refactor motions, structural navigation for navigation's sake) are low value and add weight the editor does not need to carry.
Forgiven runs inside your shell. It does not replicate features the shell already
provides. An embedded terminal pane, for example, would recreate a problem that
terminal multiplexers (tmux, zellij) already solve better — and the agent panel
already streams tool output inline. The TUI is a first-class citizen of the terminal
ecosystem, not an island within it.
Feature parity with VS Code or Zed is not the goal. Each addition is weighed against the complexity it introduces. Forgiven should remain fast, auditable, and hackable by a single developer. Deliberate exclusions are documented as ADRs so the reasoning is preserved.
Zero telemetry. No background network calls outside of explicitly user-initiated
agent requests. The agent is sandboxed to the project root. unsafe code is
forbidden project-wide. Dependencies are audited with cargo-audit and cargo-deny
in CI.
- Normal — navigation, operators, leader-key commands
- Insert — full text insertion and deletion
- Visual / Visual-Line — character and line-wise selection with yank/delete
- Command — colon commands (
:w,:q,:wq,:q!,:e <file>,:bn,:bp) - PickBuffer / PickFile — fuzzy-style buffer and file pickers
- Explorer — file tree navigation with create / rename / delete
- RenameFile — inline name editor with confirmation (
Enter) or cancel (Esc) - DeleteFile — delete confirmation popup (
y= confirm,n/Esc= cancel) - NewFolder — inline folder name editor with confirmation (
Enter) or cancel (Esc) - InFileSearch —
/search withn/Nnext/prev match navigation
h/j/k/l, arrows,w/b,0/^/$,gg/Gxdelete char,dd/D/dwdelete line/EOL/word,cc/cwchangedt{c}/df{c}delete till/find char;yt{c}/yf{c}yank;ct{c}/cf{c}changef{c}/t{c}jump to/before char forward;F{c}/T{c}jump backwardyy/yw/y$yank;p/Ppaste; multi-line block yank/pasteuundo,Ctrl+Rredo (snapshot-based history)- Numeric count prefix:
3dd,5j, etc.
AST-aware text objects powered by Tree-sitter. Works in Normal mode (operate immediately) and Visual mode (select first, then operate).
| Sequence | Meaning |
|---|---|
vif / vaf |
Visual-select function body / entire function (incl. signature) |
vic / vac |
Visual-select class/struct/impl body / entire node |
vib / vab |
Visual-select inner / outer {} block |
dif / daf |
Delete inner / outer function |
yif / yaf |
Yank inner / outer function |
cif / caf |
Change inner / outer function (delete + enter Insert) |
dic / dac |
Delete inner / outer class/struct/impl |
dib / dab |
Delete inner / outer block |
The same i/a + f/c/b suffix applies to y, d, and c operators uniformly.
In Visual mode, pressing i or a followed by a kind character replaces the current selection.
Supported languages: Rust, Python, JavaScript, TypeScript, TypeScript TSX, Go, JSON, Bash. Falls back gracefully (status message) for unsupported file types.
Which-key popup shows available bindings after a 500 ms pause.
| Prefix | Binding | Action |
|---|---|---|
SPC b |
b/n/p/d |
List / next / previous / close buffer |
SPC f |
f/n/s |
Find file / new file / save |
SPC q |
q |
Quit |
SPC l |
h/d/r/f/s |
LSP hover / definition / rename / references / symbols |
SPC a |
a/f |
Toggle / focus agent panel |
SPC e |
e/f/h |
Toggle / focus file explorer / toggle hidden files |
SPC g |
g |
Open lazygit |
SPC m |
p/b |
Markdown preview toggle / open in browser |
SPC s |
g |
Search text in project (ripgrep) |
- Auto-connects to
rust-analyzerandcopilot-language-serveron startup - Inline diagnostics gutter (● errors, warnings)
- Hover, go-to-definition, references, rename, document symbols
- Ghost-text inline completions (streamed, Tab to accept)
- Agent chat panel (
SPC a a) — streaming SSE responses, scrollable history with full CommonMark rendering - Diff+apply (
Ctrl+Ain Agent mode) — full-screen LCS diff overlay targeting the correct file;y/Enterto apply,n/Escto discard
syntectwith Base16 Ocean Dark theme; highlights the visible viewport only- Incremental cache keyed on buffer version — no re-highlight on cursor movement
- Tree-sitter AST parsed lazily per buffer; cache invalidated on each edit — powers text objects and (upcoming) code folding and sticky scroll
- Left-sidebar tree (
SPC e e); lazy directory loading j/kor arrows navigate;Enter/lexpands a dir or opens a filen— new file (pre-fills Command mode with the target directory path)m— new folder (inline popup,Enterconfirms,Esccancels)r— rename selected entry (inline popup,Enterconfirms,Esccancels)d— delete selected entry (confirmation popup,yconfirms,n/Esccancels)h— toggle hidden files (SPC e hfrom Normal mode)R— reload/refresh the tree from diskEsc/Tab— blur explorer and return to editor- Hides
target/,node_modules/,dist/,build/and dotfiles by default
- Opens a centred popup overlay in
SEARCHmode - Query field: text to search (ripgrep regex, smart-case)
- File filter field: optional glob pattern (e.g.
*.rs,src/**/*.ts) —Tabswitches focus - Results update live with a 300 ms debounce; up to 500 matches displayed
↑/↓orj/knavigate the list;Enteropens the file at the matched lineEsccloses the panel and returns to Normal mode
/enters search mode; type a pattern and pressEnterto highlight all matchesn/Njump to next / previous match in Normal modeEsccancels the search prompt without running
SPC m p— toggle a read-only rendered preview for any buffer- Full CommonMark: headings, bold/italic, inline code, fenced code blocks, lists, blockquotes, horizontal rules; Mermaid blocks shown with a hint to open in browser
SPC m b— render the current buffer to HTML and open in the system browser; Mermaid diagrams are rendered via Mermaid.js (CDN)- Status bar shows
PREVIEWin Magenta when preview is active
- lazygit full-screen overlay (
SPC g g) - System clipboard integration via
arboard - Log output to
~/.local/share/forgiven/forgiven.log(XDG-aware, append mode; never pollutes the TUI)
# Build
cargo build --release
# Open a project directory
./target/release/forgiven /path/to/project
# Open specific files
./target/release/forgiven src/main.rs
# Start with a scratch buffer
./target/release/forgivenforgiven loads its configuration from ~/.config/forgiven/config.toml (or
$XDG_CONFIG_HOME/forgiven/config.toml if XDG_CONFIG_HOME is set). If the
file does not exist, sensible defaults are used. The config is TOML and
supports the following sections:
# ── Editor ────────────────────────────────────────────────────────────────
tab_width = 4 # spaces per tab (default: 4)
use_spaces = true # expand tabs to spaces (default: true)
default_copilot_model = "gpt-4o" # preferred Copilot model ID
max_agent_rounds = 20 # agentic tool rounds before pause (default: 20)
agent_warning_threshold = 3 # warn N rounds before the limit (default: 3)
# ── Agent / prompt framework ─────────────────────────────────────────────
[agent]
# "none" — disabled (default)
# "spec-kit" — built-in Spec-Driven Development workflow
# "/path/dir" — custom framework: directory of .md template files
spec_framework = "none"
# Automatically compress eligible tool results via LLMLingua before they
# enter the conversation history. Requires the "llmlingua" MCP server to
# be connected (see mcp_servers/llmlingua_server.py).
# Code-reading tools (read_file, get_file_outline, get_symbol_context) are
# always excluded — compressing source code corrupts identifiers and
# operators that edit_file relies on for exact matching.
# Only results > 2 000 chars are compressed; adds ~100 ms–1.5 s per call.
# Recommended for heavy agent sessions where context pressure is the bottleneck.
auto_compress_tool_results = false
# ── LSP servers ──────────────────────────────────────────────────────────
# Each [[lsp.servers]] entry registers a language server.
# forgiven ships built-in defaults for rust-analyzer and copilot-language-server;
# add your own or override them here.
[[lsp.servers]]
language = "rust"
command = "rust-analyzer"
args = []
[[lsp.servers]]
language = "python"
command = "pylsp"
args = []
# Optional: env vars (values starting with $ are resolved from the host env)
# [lsp.servers.env]
# RUSTUP_TOOLCHAIN = "stable"
# Optional: custom initialization_options forwarded to the LSP server
# [lsp.servers.initialization_options]
# some_key = "some_value"
# ── MCP servers ──────────────────────────────────────────────────────────
# Each [[mcp.servers]] entry registers a Model Context Protocol server.
# Servers connect over stdio and provide additional tools to the agent.
[[mcp.servers]]
name = "filesystem"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
[[mcp.servers]]
name = "github"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]
# Env vars starting with $ are resolved from the host environment at startup.
[mcp.servers.env]
GITHUB_TOKEN = "$GITHUB_PERSONAL_ACCESS_TOKEN"
# ── Optional: persistent agent memory (knowledge graph) ─────────────────
# The memory server lets the agent store and retrieve facts across sessions.
# Eliminates the need to replay conversation history for project context.
# Tools exposed: create_entities, add_observations, search_nodes, read_graph.
[[mcp.servers]]
name = "memory"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-memory"]Use SPC d (Diagnostics overlay) to inspect running LSP and MCP servers,
view connection errors, check recent log entries, and see token usage broken
down by segment: system rules, open file, chat history, and user message — with
a per-segment percentage bar for each. A compact fuel gauge ([████░░ 38%])
also appears in the status bar after the first agent invocation.
The agent panel title shows a live context gauge (tokens used / model limit). For heavy sessions, two additional tools help manage context pressure:
SPC a n— start a new conversation (clears history, resets session token counters). Use this at natural task boundaries before beginning unrelated work.SPC d— the Diagnostics overlay shows a per-session token summary and recent[ctx]/[usage]/[llmlingua]log lines that break down exactly where tokens are going each round.
Common sources of context bloat and their mitigations:
| Source | Mitigation |
|---|---|
| Large file open in editor | Open a smaller file or close the buffer before starting an agent session; the open file is injected into every system prompt |
| Long conversation history | SPC a n to start fresh at task boundaries |
| Verbose tool results (grep, test output) | Enable auto_compress_tool_results = true with the LLMLingua MCP sidecar |
| Small model context window | Switch to a model with a larger window via Ctrl+T in the agent panel |
| Tool | Install | Required for |
|---|---|---|
rg (ripgrep) |
brew install ripgrep / cargo install ripgrep |
Project-wide search (SPC s g) |
lazygit |
brew install lazygit / distro package |
Git UI (SPC g g) |
rust-analyzer |
rustup component add rust-analyzer |
Rust LSP |
mmdc |
npm install -g @mermaid-js/mermaid-cli |
Mermaid diagram rendering (SPC m d) |
llmlingua |
pip install llmlingua then configure mcp_servers/llmlingua_server.py |
Automatic tool-result compression (auto_compress_tool_results) |
| Key | Action |
|---|---|
i/a/I/A/o/O |
Enter Insert mode (at / after / line-start / line-end / new-below / new-above) |
h/j/k/l |
Move left / down / up / right (no line-wrap) |
w/b |
Word forward / backward |
0/^/$ |
Line start / first non-blank / line end |
gg/G |
File top / bottom |
x |
Delete char at cursor |
dd/D/dw |
Delete line / to EOL / word (into clipboard) |
dt{c} / df{c} |
Delete till (exclusive) / find (inclusive) next occurrence of {c} |
yy/yw/y$ |
Yank line / word / to EOL |
yt{c} / yf{c} |
Yank till / find next occurrence of {c} |
cc/cw |
Change line / word |
ct{c} / cf{c} |
Change till / find next occurrence of {c} (delete + Insert) |
f{c} / t{c} |
Move cursor to / before next occurrence of {c} on line |
F{c} / T{c} |
Move cursor to / after previous occurrence of {c} on line |
v + i/a + f/c/b |
Visual-select text object (inner/outer function/class/block) |
d + i/a + f/c/b |
Delete text object (e.g. daf = delete outer function) |
y + i/a + f/c/b |
Yank text object |
c + i/a + f/c/b |
Change text object (delete + Insert) |
p/P |
Paste after / before cursor |
u/Ctrl+R |
Undo / redo |
v/V |
Visual / Visual-line selection |
/ |
In-file search (enter InFileSearch mode) |
n/N |
Next / previous search match |
: |
Command mode |
SPC |
Leader key (see table above) |
| Key | Action |
|---|---|
Esc |
Return to Normal mode |
Tab |
Accept ghost-text completion (if visible) |
Backspace/Delete |
Delete before / after cursor |
| Arrows | Move cursor |
| Key | Action |
|---|---|
h/j/k/l / arrows |
Extend selection |
w/b |
Extend selection by word |
0/^/$ |
Extend selection to line start / first non-blank / line end |
G |
Extend selection to file bottom |
i + f/c/b |
Replace selection with inner text object (function/class/block) |
a + f/c/b |
Replace selection with outer text object |
y |
Yank selection |
d/x |
Delete selection |
c |
Delete selection and enter Insert mode |
Tab / Shift+Tab |
Indent / dedent selected lines |
Esc |
Cancel |
| Key | Action |
|---|---|
j/k or ↓/↑ |
Move cursor down / up |
Enter or l |
Expand directory / open file (returns to Normal mode) |
n |
New file — pre-fills Command mode with e <dir>/ |
m |
New folder — opens new-folder popup |
r |
Rename selected entry (opens rename popup) |
d |
Delete selected entry (opens confirmation popup) |
h |
Toggle hidden files visibility |
R |
Reload / refresh tree from disk |
Esc or Tab |
Blur explorer, return to editor |
| Key | Action |
|---|---|
| (type) | Edit the filename |
Backspace |
Delete last character |
Enter |
Confirm rename |
Esc |
Cancel, return to explorer |
| Key | Action |
|---|---|
y or Y |
Confirm deletion (permanent) |
n, N or Esc |
Cancel, return to explorer |
| Key | Action |
|---|---|
| (type) | Edit the folder name |
Backspace |
Delete last character |
Enter |
Confirm — creates the directory (and any missing parents) |
Esc |
Cancel, return to explorer |
| Key | Action |
|---|---|
| (type) | Build search pattern |
Backspace |
Delete last character |
Enter |
Run search, return to Normal mode; n/N jump between matches |
Esc |
Cancel, return to Normal mode |
| Key | Action |
|---|---|
j/k or ↓/↑ |
Scroll down / up one line |
Ctrl+D / Ctrl+U |
Scroll down / up half-page |
g / G |
Jump to top / bottom |
q or Esc |
Exit preview, return to Normal mode |
| Key | Action |
|---|---|
Enter |
Send message |
Alt+Enter |
Insert newline in message |
Backspace |
Delete last character |
j / k |
Scroll history up / down |
Ctrl+C |
Abort running stream (safe at any point) |
Ctrl+K |
Copy next code block from last reply (cycles through all blocks) |
Ctrl+M |
Open next mermaid diagram from last reply in browser (cycles; auto-fixes parens) |
Ctrl+Y |
Yank full last reply to system clipboard |
Ctrl+A |
Open apply-diff overlay for the last code block |
Ctrl+P |
Attach a file to the next message (context picker) |
Ctrl+T |
Cycle model; loads model list from API on first press |
Esc |
Blur panel, return to editor |
| Key | Action |
|---|---|
y / Enter |
Apply change to target file / buffer |
n / Esc |
Discard, return to agent panel |
j / k |
Scroll down / up one line |
Ctrl+D / Ctrl+U |
Scroll down / up half-page |
| Key | Action |
|---|---|
| (type) | Update search query (or glob if glob field focused) |
Tab |
Switch focus between query and file-glob fields |
↑ / k |
Select previous result |
↓ / j |
Select next result |
Enter |
Open selected file at matched line |
Esc |
Close panel, return to Normal mode |
forgiven/
├── src/
│ ├── main.rs # Entry point, CLI parsing, project-root setup
│ ├── agent/ # Copilot agent chat panel (streaming SSE, tool calls)
│ │ ├── mod.rs
│ │ └── tools.rs
│ ├── buffer/ # Buffer management
│ │ ├── buffer.rs # Core text buffer, cursor, edit operations
│ │ ├── cursor.rs # Cursor position
│ │ └── history.rs # Snapshot undo/redo
│ ├── config/ # TOML config loader
│ │ └── mod.rs
│ ├── editor/ # Main event loop and editor state
│ │ └── mod.rs
│ ├── explorer/ # File explorer tree sidebar
│ │ └── mod.rs
│ ├── highlight/ # Syntax highlighting (syntect, Base16 Ocean Dark)
│ │ └── mod.rs
│ ├── treesitter/ # Tree-sitter AST engine (text objects, folding)
│ │ ├── mod.rs # TsEngine, TsLang, TsSnapshot
│ │ └── query.rs # Node-finding helpers, text_object_range()
│ ├── keymap/ # Modal keybinding system + which-key
│ │ └── mod.rs
│ ├── lsp/ # LSP client (rust-analyzer, copilot-language-server)
│ │ └── mod.rs
│ ├── markdown/ # CommonMark → ratatui Lines renderer
│ │ └── mod.rs
│ ├── search/ # Project-wide ripgrep search (SPC s g)
│ │ └── mod.rs
│ └── ui/ # Terminal rendering (ratatui)
│ └── mod.rs
├── docs/
│ └── adr/ # Architecture Decision Records (0001 – 0084)
└── Cargo.toml
| Crate | Version | Purpose |
|---|---|---|
ratatui |
0.30 | TUI framework — layout, widgets, rendering |
crossterm |
0.28 | Cross-platform terminal backend for ratatui |
tokio |
1 | Async runtime (full feature set) |
serde |
1 | Serialisation derive macros |
serde_json |
1 | JSON encode/decode (LSP messages, Copilot API) |
toml |
0.8 | Config file parsing |
clap |
4 | CLI argument parsing (derive API) |
anyhow |
1 | Ergonomic error propagation |
thiserror |
2 | Typed error enum derive |
tracing |
0.1 | Structured logging |
tracing-subscriber |
0.3 | Log filtering and file output |
notify |
7 | File system watching |
unicode-width |
0.2 | Display-width of Unicode characters |
unicode-segmentation |
1 | Grapheme cluster iteration |
lsp-types |
0.97 | LSP protocol type definitions |
lsp-server |
0.7 | LSP server transport primitives |
url |
2 | URI handling for LSP |
reqwest |
0.12 | HTTP client for Copilot API (JSON + streaming) |
futures-util |
0.3 | Async stream utilities (SSE response streaming) |
syntect |
5 | Syntax highlighting engine (Base16 Ocean Dark) |
tree-sitter |
0.22 | Incremental AST parser — foundation for text objects, folding, sticky scroll |
tree-sitter-rust |
0.21 | Rust grammar for Tree-sitter |
tree-sitter-python |
0.21 | Python grammar |
tree-sitter-javascript |
0.21 | JavaScript grammar |
tree-sitter-typescript |
0.21 | TypeScript and TSX grammars |
tree-sitter-go |
0.21 | Go grammar |
tree-sitter-json |
0.21 | JSON grammar |
tree-sitter-bash |
0.21 | Bash/shell grammar |
arboard |
3 | System clipboard read/write |
pulldown-cmark |
0.12 | CommonMark parser for markdown rendering |
tiktoken-rs |
0.5 | GPT-4 tokeniser (cl100k_base) for accurate per-segment token counts |
| Crate | Version | Purpose |
|---|---|---|
pretty_assertions |
1 | Coloured diff output in test failures |
| Tool | Purpose |
|---|---|
rg (ripgrep) |
Project-wide text search — rg must be on $PATH; install via brew install ripgrep or cargo install ripgrep |
lazygit |
Full-screen Git UI overlay (SPC g g) |
rust-analyzer |
Rust language server |
copilot-language-server |
GitHub Copilot LSP server |
All design decisions are documented in docs/adr/.
| ADR | Title |
|---|---|
| 0001 | Terminal UI Framework |
| 0002 | Async Runtime and Event Loop |
| 0003 | LSP Integration Architecture |
| 0004 | Copilot Authentication |
| 0005 | Copilot Inline Completions / Ghost Text |
| 0006 | Agent Chat Panel |
| 0007 | Vim Modal Keybindings |
| 0008 | Normal Mode Editing Operations |
| 0009 | Syntax Highlighting (syntect) |
| 0010 | File Explorer Tree Sidebar |
| 0011 | Agentic Tool-Calling Loop |
| 0012 | Agent UX: Context and File Refresh |
| 0013 | Project Folder Argument |
| 0014 | Agent Model Selection |
| 0015 | File Creation and Explorer Enhancements |
| 0016 | Vim Yank / Paste Register |
| 0017 | Multi-line Yank / Delete / Visual Line |
| 0018 | Horizontal Scroll Viewport Fix |
| 0019 | Snapshot Undo / Redo |
| 0020 | Lazygit Integration |
| 0021 | Render Loop Performance |
| 0022 | Markdown Rendering (Agent Panel + Editor Preview) |
| 0023 | Which-Key Popup Render Timer |
| 0024 | Project-wide Text Search |
| 0025 | Explorer Hidden Files Toggle |
| 0026 | Copilot Stream Resilience |
| 0027 | Agent Round Limits and Continuation Prompts |
| 0028 | Model Selection Persistence |
| 0029 | Task Panel for Work Tracking |
| 0030 | In-File Search and Replace |
| 0031 | Agent-Driven Plan Strip |
| 0032 | Recent Files in the Find File Picker |
| 0033 | Mermaid Diagrams and Markdown Browser Export |
| 0034 | Explorer File Deletion |
| 0035 | Agent Apply-Diff Overlay |
| 0036 | Multi-line Agent Panel Input |
| 0037 | Think-Block Rendering in the Agent Panel |
| 0038 | Unified Model Selection: Removing the model_picker_enabled Filter |
| 0039 | Agent Status Indicator: Live Phase Tracking in the Agent Panel Title |
| 0040 | Context Gauge: Token Usage Display in the Agent Panel Title |
| 0041 | Agent Panel Clipboard Shortcuts (Ctrl+K / Ctrl+Y) |
| 0042 | Agent Panel Paste Summary |
| 0043 | Vertical Split Screen |
| 0044 | Explorer New Folder |
| 0045 | MCP Client Integration |
| 0046 | Agent Retry Visibility |
| 0047 | Git Commit Message Generation |
| 0048 | MCP Server Status Visualisation |
| 0049 | Diagnostics Overlay (SPC d) |
| 0050 | MCP Server Environment Variable Secret Resolution |
| 0051 | Startup Loading Indicator and Service Parallelisation |
| 0052 | .NET LSP — Switch Default to csharp-ls |
| 0053 | MCP Non-blocking Startup (isolation superseded) |
| 0054 | Editor Quality-of-Life Improvements |
| 0055 | Release Notes Generation (SPC g n) |
| 0056 | Pluggable Prompt-Framework Integration (spec-kit) |
| 0057 | Agent ask_user Tool |
| 0058 | Agent Panel Rendering Performance |
| 0059 | Agent File Context Picker (Ctrl+P) |
| 0060 | Vim Character Motions (f/t/F/T, dt/df/yt/yf/ct/cf) |
| 0061 | Agent Stream Abort (Ctrl+C) and Ctrl-Chord Keybinding Migration |
| 0062 | Offline Resilience: Request Timeouts, MCP Startup Bound, and Error Visibility |
| 0063 | Structural Refactor: Buffer Combinator, RenderContext, and Editor Sub-states |
| 0064 | Filesystem Watcher: External Change Detection and Auto-Reload |
| 0065 | Terminal Redraw on Resume (Resize, SIGCONT, Ctrl+L) |
| 0066 | Agent Image Clipboard Paste |
| 0067 | Agent Input Box Scroll-to-Cursor |
| 0068 | Which-Key Dynamic Height and Ask-User Dialog Formatting |
| 0069 | Model Loading Modernisation |
| 0076 | Mermaid Diagram Browser Preview (Ctrl+M) |
| 0077 | Agent Context Window Management |
| 0078 | Prompt Caching — Cached Token Tracking |
| 0079 | Diff-Only Tool Results for File Write/Edit |
| 0080 | Tool Call Batching (read_files, search_files) |
| 0081 | Importance-Scored History Retention |
| 0082 | Symbol-Aware Context Tools (get_file_outline, get_symbol_context) |
| 0083 | MCP Memory Server for Cross-Session Context |
| 0084 | LLMLingua MCP Sidecar for Tool Result Compression |
| 0085 | LSP Navigation (Goto Definition, Find References, Symbols) and C# Revival |
| 0086 | Copilot Model-Switch Detection and 429 Rate-Limit Handling |
| 0087 | Context Bloat Audit and Session Token Instrumentation |
| 0088 | Automatic Tool-Result Compression via LLMLingua |
| 0095 | Persistent XDG-Aware Log File |
| 0096 | Session Rounds Counter and Average Tokens per Invocation |
| 0097 | SpecKit Auto-Clear Context per Phase |
| 0098 | Ollama Local Provider |
| 0099 | Context Breakdown: Per-Segment Token Awareness (Phase 1) |
| 0104 | Tree-sitter Core Integration (AST engine foundation) |
| 0105 | Tree-sitter Text Objects (vif, daf, yic, etc.) |
# Debug build
cargo build
# Watch logs while running
tail -f ~/.local/share/forgiven/forgiven.log
# Run tests
cargo testforgiven makes no background network calls. The only outbound connections are to GitHub's official Copilot endpoints and only when you actively use Copilot features:
| Endpoint | Triggered by |
|---|---|
api.github.com/copilot_internal/v2/token |
First Copilot action per session |
api.githubcopilot.com/models |
Ctrl+T in agent panel |
api.githubcopilot.com/chat/completions |
Sending a message to the agent |
No telemetry. No analytics. No crash reporting. The agent is sandboxed to your project root — it cannot read or write files outside the directory you opened.
The CI pipeline runs cargo-audit (CVE scanning), cargo-deny (licence
checks), and GitHub code scanning on every push. unsafe code is forbidden
project-wide via Cargo.toml.
Full details — including how to audit the codebase yourself — are in SECURITY.md.
MIT — see LICENSE.
