Adam Bandel


Code Context Builder

Aug 2025
Type: desktop
Code: 5k lines
Files: 35
Active: May 2025 — Aug 2025
Stack:
TypeScriptReactRustTauriSQLitetree-sitter
Tags:
aideveloper-toolsprompt-engineering

Overview

Code Context Builder is a keyboard-driven desktop application that streamlines the creation of high-quality, token-efficient prompts from source code for LLMs like GPT-4 and Claude. When working with expensive API calls, every token counts.

The app allows developers to scan and index project folders, interactively select files, and generate well-formatted prompts in multiple output formats. A standout feature is AST-based smart compression using tree-sitter, which can significantly reduce token counts while preserving code structure and semantics.

Screenshots

Main Interface

Settings Modal

File Viewer

Problem

Preparing code context for LLMs is tedious and error-prone. Developers often resort to manually copying files, losing track of what’s included, and exceeding token limits unexpectedly. Existing tools either lack precision in file selection or don’t optimize for token efficiency. There was no keyboard-driven workflow for power users who iterate quickly with LLMs.

Approach

Built a native desktop app using Tauri to combine a responsive React UI with high-performance Rust backend processing. The architecture separates concerns cleanly: React handles interactivity while Rust does the heavy lifting of file I/O, parsing, and tokenization.

Stack

Challenges

Outcomes

The app successfully reduces the friction of LLM-assisted development. Key achievements:

Implementation Notes

The compression system uses tree-sitter to parse source files into ASTs, then walks the tree to identify collapsible regions:

// Compressor trait allows extensible language support
pub trait Compressor: Send + Sync {
    fn compress(&self, content: &str, options: &CompressionOptions) -> String;
}

// Python implementation collapses function bodies while preserving signatures
fn collapse_body(source: &str, node: Node, options: &CompressionOptions) -> String {
    // Preserve docstrings, collapse implementation
    // Result: def process(data: List[str]) -> Dict: ...
}

The frontend uses useImperativeHandle to expose tree control methods, enabling parent components to programmatically expand, collapse, and search the file tree without prop drilling:

export interface FileTreeRef {
  expandAll: () => void;
  collapseAll: () => void;
  expandToLevel: (level: number) => void;
  focusSearch: () => void;
}

State persistence splits between SQLite (projects, file cache, settings) and localStorage (UI preferences, selected files, expanded paths), ensuring the database remains portable while user preferences roam with the browser profile.

View on GitHub →


Related Posts