Skip to content

daneb/forgiven

Repository files navigation

                               ┃┃┃
                               ┃┃┃
                               ┃┃┃
           ━━━━━━━━━━━━━━━━━━━━╋╋╋━━━━━━━━━━━━━━━━━━━━
                               ┃┃┃
                               ┃┃┃
                               ┃┃┃
                               ┃┃┃
                               ┃┃┃

███████╗ ██████╗ ██████╗  ██████╗ ██╗██╗   ██╗███████╗███╗   ██╗
██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██║██║   ██║██╔════╝████╗  ██║
█████╗  ██║   ██║██████╔╝██║  ███╗██║██║   ██║█████╗  ██╔██╗ ██║
██╔══╝  ██║   ██║██╔══██╗██║   ██║██║╚██╗ ██╔╝██╔══╝  ██║╚██╗██║
██║     ╚██████╔╝██║  ██║╚██████╔╝██║ ╚████╔╝ ███████╗██║ ╚████║
╚═╝      ╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═══╝  ╚══════╝╚═╝  ╚═══╝

              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.


Design Philosophy

Forgiven is built around a small set of deliberate choices. Every feature decision — including what not to implement — flows from these principles.

1. AI-first, not AI-assisted

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.

2. Code as a black box

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.

3. Terminal-native, not a GUI in a terminal

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.

4. Lightweight by design

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.

5. Security-first posture

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.


Features

Modal editing (Vim-style)

  • 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 with n/N next/prev match navigation

Navigation & editing

  • h/j/k/l, arrows, w/b, 0/^/$, gg/G
  • x delete char, dd/D/dw delete line/EOL/word, cc/cw change
  • dt{c}/df{c} delete till/find char; yt{c}/yf{c} yank; ct{c}/cf{c} change
  • f{c}/t{c} jump to/before char forward; F{c}/T{c} jump backward
  • yy/yw/y$ yank; p/P paste; multi-line block yank/paste
  • u undo, Ctrl+R redo (snapshot-based history)
  • Numeric count prefix: 3dd, 5j, etc.

Tree-sitter text objects

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.

Spacemacs-style leader key (SPC)

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)

Language Server Protocol

  • Auto-connects to rust-analyzer and copilot-language-server on startup
  • Inline diagnostics gutter (● errors, warnings)
  • Hover, go-to-definition, references, rename, document symbols

GitHub Copilot integration

  • 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+A in Agent mode) — full-screen LCS diff overlay targeting the correct file; y/Enter to apply, n/Esc to discard

Syntax highlighting & AST

  • syntect with 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

File explorer

  • Left-sidebar tree (SPC e e); lazy directory loading
  • j/k or arrows navigate; Enter/l expands a dir or opens a file
  • n — new file (pre-fills Command mode with the target directory path)
  • m — new folder (inline popup, Enter confirms, Esc cancels)
  • r — rename selected entry (inline popup, Enter confirms, Esc cancels)
  • d — delete selected entry (confirmation popup, y confirms, n/Esc cancels)
  • h — toggle hidden files (SPC e h from Normal mode)
  • R — reload/refresh the tree from disk
  • Esc/Tab — blur explorer and return to editor
  • Hides target/, node_modules/, dist/, build/ and dotfiles by default

Project-wide search (SPC s g)

  • Opens a centred popup overlay in SEARCH mode
  • Query field: text to search (ripgrep regex, smart-case)
  • File filter field: optional glob pattern (e.g. *.rs, src/**/*.ts) — Tab switches focus
  • Results update live with a 300 ms debounce; up to 500 matches displayed
  • / or j/k navigate the list; Enter opens the file at the matched line
  • Esc closes the panel and returns to Normal mode

In-file search (/)

  • / enters search mode; type a pattern and press Enter to highlight all matches
  • n / N jump to next / previous match in Normal mode
  • Esc cancels the search prompt without running

Markdown (SPC m p / SPC m b)

  • 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 PREVIEW in Magenta when preview is active

Other

  • 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)

forgiven editor

Quick Start

# 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/forgiven

Configuration

forgiven 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.

Context management

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

Optional runtime dependencies

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)

Keybinding Reference

Normal mode

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)

Insert mode

Key Action
Esc Return to Normal mode
Tab Accept ghost-text completion (if visible)
Backspace/Delete Delete before / after cursor
Arrows Move cursor

Visual / Visual-line mode

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

File explorer (Mode::Explorer)

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

Rename popup (Mode::RenameFile)

Key Action
(type) Edit the filename
Backspace Delete last character
Enter Confirm rename
Esc Cancel, return to explorer

Delete confirmation (Mode::DeleteFile)

Key Action
y or Y Confirm deletion (permanent)
n, N or Esc Cancel, return to explorer

New folder popup (Mode::NewFolder)

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

In-file search (Mode::InFileSearch)

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

Markdown preview (Mode::MarkdownPreview)

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

Agent panel (Mode::Agent)

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

Apply-diff overlay (Mode::ApplyDiff)

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

Search panel (Mode::Search, SPC s g)

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

Project Structure

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

Dependencies

Runtime crates

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

Dev crates

Crate Version Purpose
pretty_assertions 1 Coloured diff output in test failures

Optional runtime tools (not in Cargo.toml)

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

Architecture Decision Records

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.)

Development

# Debug build
cargo build

# Watch logs while running
tail -f ~/.local/share/forgiven/forgiven.log

# Run tests
cargo test

Security & Privacy

forgiven 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.


License

MIT — see LICENSE.

About

An AI-first terminal-based IDE

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors