andreasjansson/github-code-understander 📝 → 📝
About
Agent that reads a public github repo and analyzes it based on a prompt
Example Output
"What's interesting about this repo compared to Cursor or Windsurf?"
Output
Short list of things that make this repo stand out (vs. Cursor / Windsurf):
Native Emacs-first design
- The entire chat is an editable Emacs buffer (markdown-like), not a locked UI panel — you can edit assistant output, thinking blocks, tool calls, save chats as files and continue them.
- Tree‑sitter grammar for the chat format: syntax/highlighting, folding, clickable citations/URLs, TAB-based expansion.
Tooling as Emacs Lisp
- Tools are ordinary Emacs Lisp functions you register; you can write and register arbitrary tools (file ops, ripgrep, shell, web read/search, etc.) and pass buffer/callback/metadata/streaming hooks.
- Server tools (e.g., web_search) are modeled and registered too (JSON schema strings).
Safe, auditable file editing workflow
- File edits are done by explicit named tools (str-replace, replace-file, write-new-file, etc.) with checks (e.g., paren-balance for .el).
- Greger stages/commits changes to git automatically (and can commit the chat file) so every agent edit has git provenance.
Streaming + tool execution model
- Assistant text is streamed incrementally; tool calls are recognized and executed (in parallel) with placeholders inserted and streaming/tool callbacks that fill results back into the buffer.
- Terminal/control‑sequence processing so CLI progress bars and streaming outputs render sensibly in the buffer.
Rich UI transformations
- Tool inputs/results get syntax highlighting (creates a temp buffer with appropriate major-mode based on file path), unified-diff generation for str-replace, and “undiff” parsing back to original/new content.
- Folding/invisibility of tags, citation folding, and clickable links all implemented with tree‑sitter + text properties.
Claude & Anthropic features baked in
- Built specifically for Claude models, uses prompt-caching/ephemeral cache-control, explicit "thinking" blocks (separable internal reasoning budget).
- Uses curl-based streaming client with fine-grained content-block callbacks.
Security / UX choices
- Shell-command tool asks for permission unless a safe-command allowlist or allow-all flag is set; metadata carries safe-shell-commands.
- Minimal external deps (only curl + common CLI tools) — Emacs-native instead of requiring a separate service.
Extensibility & tests
- Easy to add custom tools (three-step process) and many examples.
- Large test suite and emphasis on correctness (parsing, diffing, tool plumbing).
In short: Greger is built as an Emacs-native, fully-text, tree‑sitter‑aware agent framework where tools are first‑class Emacs Lisp functions and every change is tracked and reviewable in git. That combination (editable chat-as-file, Emacs Lisp tool extensibility, tree‑sitter UI/diffing, git provenance, and streaming/tool plumbing) is the repo’s primary differentiator compared to web/IDE‑centric agents like Cursor or Windsurf.
Performance Metrics
All Input Parameters
{ "prompt": "What's interesting about this repo compared to Cursor or Windsurf?", "github_url": "https://github.com/andreasjansson/greger.el" }
Input Parameters
- prompt (required)
- Analysis prompt for the code
- github_url (required)
- GitHub URL to clone and analyze
Output Schema
Output
Example Execution Logs
🔗 Downloading repository: https://github.com/andreasjansson/greger.el ✅ Successfully downloaded repository 🧠 Starting tool calling loop with prompt: What's interesting about this repo compared to Cursor or Windsurf? 🔄 Conversation turn 1 Turn 1: Got 1 function calls, message length: 0 🔧 Executing tool: list_files 📥 Input: {'directory': '/tmp/project-src', 'max_entries': 1000, 'recursive': True} 📤 Output: {'files': [{'path': 'DEVELOPMENT.md', 'size': '2.1KB', 'size_bytes': 2135}, {'path': 'Eldev', 'size': '676B', 'size_bytes': 676}, {'path': 'LICENSE', 'size': '1.0KB', 'size_bytes': 1071}, {'path': 'README.md', 'size': '17.0KB', 'size_bytes': 17420}, {'path': 'greger-client.el', 'size': '21.4KB', 'size_bytes': 21864}, {'path': 'greger-parser.el', 'size': '33.3KB', 'size_bytes': 34087}, {'path': 'greger-stdlib.el', 'size': '53.5KB', 'size_bytes': 54823}, {'path': 'greger-tools.el', 'size': '14.6KB', 'size_bytes': 14942}, {'path': 'greger-ui.el', 'size': '36.0KB', 'size_bytes': 36911}, {'path': 'greger-web.el', 'size': '4.0KB', 'size_bytes': 4095}, {'path': 'greger.el', 'size': '38.7KB', 'size_bytes': 39667}, {'path': 'assets/greger-icon-logo.png', 'size': '108.0KB', 'size_bytes': 110633}, {'path': 'assets/greger-text-logo.png', 'size': '190.6KB', 'size_bytes': 195222}, {'path': 'assets/screencap.gif', 'size': '8.7MB', 'size_bytes': 9116512}, {'path': 'assets/screenshot-20250618-154320.png', 'size': '237.4KB', 'size_bytes': 243057}, {'path': 'assets/screenshot-20250618-154453.png', 'size': '261.3KB', 'size_bytes': 267548}, {'path': 'assets/screenshot-20250618-154809.png', 'size': '306.6KB', 'size_bytes': 313916}, {'path': 'assets/screenshot-20250618-155332.png', 'size': '548.8KB', 'size_bytes': 561938}, {'path': 'assets/screenshot-20250618-155502.png', 'size': '528.3KB', 'size_bytes': 541003}, {'path': 'assets/screenshot-20250618-155601.png', 'size': '579.9KB', 'size_bytes': 593839}, {'path': 'examples/emacs-quiz.greger', 'size': '415.3KB', 'size_bytes': 425281}, {'path': 'examples/greger-logo.greger', 'size': '160.2KB', 'size_bytes': 164064}, {'path': 'examples/readme-markdown.greger', 'size': '26.9KB', 'size_bytes': 27546}, {'path': 'examples/emacs-quiz/README.md', 'size': '5.5KB', 'size_bytes': 5675}, {'path': 'examples/emacs-quiz/index.html', 'size': '6.6KB', 'size_bytes': 6766}, {'path': 'examples/emacs-quiz/questions.js', 'size': '67.7KB', 'size_bytes': 69338}, {'path': 'examples/emacs-quiz/quiz.js', 'size': '24.4KB', 'size_bytes': 24963}, {'path': 'examples/emacs-quiz/style.css', 'size': '10.2KB', 'size_bytes': 10394}, {'path': 'examples/greger-logo/generate_logos.py', 'size': '12.7KB', 'size_bytes': 13017}, {'path': 'examples/greger-logo/process_logo.py', 'size': '2.5KB', 'size_bytes': 2603}, {'path': 'recipes/greger', 'size': '59B', 'size_bytes': 59}, {'path': 'script/format', 'size': '7.3KB', 'size_bytes': 7454}, {'path': 'script/melpazoid', 'size': '1.4KB', 'size_bytes': 1383}, {'path': 'test/greger-client-test.el', 'size': '17.0KB', 'size_bytes': 17445}, {'path': 'test/greger-end-to-end-test.el', 'size': '22.9KB', 'size_bytes': 23487}, {'path': 'test/greger-parser-test.el', 'size': '30.1KB', 'size_bytes': 30778}, {'path': 'test/greger-stdlib-test.el', 'size': '106.2KB', 'size_bytes': 108764}, {'path': 'test/greger-test.el', 'size': '33.9KB', 'size_bytes': 34736}, {'path': 'test/greger-tools-test.el', 'size': '39.4KB', 'size_bytes': 40345}, {'path': 'test/greger-ui-test.el', 'size': '24.8KB', 'size_bytes': 25397}], 'count': 40, 'truncated': False} 📦 Tool output prepared Tool continuation: Got 1 function calls, message length: 0 New tool call 1: read_file 🔧 Executing tool: read_file 📥 Input: {'end_line': -1, 'path': 'README.md', 'start_line': 1} 📤 Output: {'content': '<div align="center">\n\n\n\n</div>\n... (490 more lines)', 'total_lines': 495, 'start_line': 1, 'end_line': 495, 'lines_returned': 495} 📦 Tool output prepared Tool continuation: Got 1 function calls, message length: 0 New tool call 1: read_file 🔧 Executing tool: read_file 📥 Input: {'end_line': -1, 'path': 'greger.el', 'start_line': 1} 📤 Output: {'content': ';;; greger.el --- Agentic coding environment with tool use, using Claude -*- lexical-binding: t -*-\n\n;; Copyright (C) 2025 Andreas Jansson\n\n;; Author: Andreas Jansson <andreas@jansson.me.uk>\n... (935 more lines)', 'total_lines': 940, 'start_line': 1, 'end_line': 940, 'lines_returned': 940} 📦 Tool output prepared Tool continuation: Got 1 function calls, message length: 0 New tool call 1: read_file 🔧 Executing tool: read_file 📥 Input: {'end_line': -1, 'path': 'greger-client.el', 'start_line': 1} 📤 Output: {'content': ';;; greger-client.el --- Claude client for greger -*- lexical-binding: t -*-\n\n;; Copyright (C) 2025 Andreas Jansson\n\n;; Author: Andreas Jansson <andreas@jansson.me.uk>\n... (504 more lines)', 'total_lines': 509, 'start_line': 1, 'end_line': 509, 'lines_returned': 509} 📦 Tool output prepared Tool continuation: Got 1 function calls, message length: 0 New tool call 1: read_file 🔧 Executing tool: read_file 📥 Input: {'end_line': -1, 'path': 'greger-tools.el', 'start_line': 1} 📤 Output: {'content': ';;; greger-tools.el --- Tool registry for greger agent -*- lexical-binding: t -*-\n\n;; Copyright (C) 2025 Andreas Jansson\n\n;; Author: Andreas Jansson <andreas@jansson.me.uk>\n... (322 more lines)', 'total_lines': 327, 'start_line': 1, 'end_line': 327, 'lines_returned': 327} 📦 Tool output prepared Tool continuation: Got 1 function calls, message length: 0 New tool call 1: read_file 🔧 Executing tool: read_file 📥 Input: {'end_line': -1, 'path': 'greger-stdlib.el', 'start_line': 1} 📤 Output: {'content': ';;; greger-stdlib.el --- Tool definitions for greger agent -*- lexical-binding: t -*-\n\n;; Copyright (C) 2025 Andreas Jansson\n\n;; Author: Andreas Jansson <andreas@jansson.me.uk>\n... (1027 more lines)', 'total_lines': 1032, 'start_line': 1, 'end_line': 1032, 'lines_returned': 1032} 📦 Tool output prepared Tool continuation: Got 1 function calls, message length: 0 New tool call 1: read_file 🔧 Executing tool: read_file 📥 Input: {'end_line': -1, 'path': 'greger-ui.el', 'start_line': 1} 📤 Output: {'content': ';;; greger-ui.el --- Claude client for greger -*- lexical-binding: t -*-\n\n;; Copyright (C) 2025 Andreas Jansson\n\n;; Author: Andreas Jansson <andreas@jansson.me.uk>\n... (770 more lines)', 'total_lines': 775, 'start_line': 1, 'end_line': 775, 'lines_returned': 775} 📦 Tool output prepared Tool continuation: Got 1 function calls, message length: 0 New tool call 1: read_file 🔧 Executing tool: read_file 📥 Input: {'end_line': -1, 'path': 'greger-parser.el', 'start_line': 1} 📤 Output: {'content': ';;; greger-parser.el --- Parser for greger dialog format -*- lexical-binding: t -*-\n\n;; Copyright (C) 2025 Andreas Jansson\n\n;; Author: Andreas Jansson <andreas@jansson.me.uk>\n... (830 more lines)', 'total_lines': 835, 'start_line': 1, 'end_line': 835, 'lines_returned': 835} 📦 Tool output prepared
Version Details
- Version ID
fd14c9da4625927f98f7a40715ccea52f7280221f77907517dc4afb7064e03c7
- Version Created
- August 22, 2025