SpanCoder is a cutting-edge, high-performance, extensibility-first Integrated Development Environment (IDE) built on .NET 10 and Avalonia UI. Designed from the ground up for sub-millisecond startup, Native AOT compilation compatibility, and out-of-process resilience, SpanCoder aims to deliver a modern, premium experience for professional software developers.
Rather than relying on a traditional monolithic architecture where a heavy UI thread handles rendering, file buffer parsing, compiler services, and extensions, SpanCoder isolates critical subsystems into dedicated, decoupled processes. These processes communicate over low-latency binary-serialized TCP channels and standard stream-based redirects.
graph TD
%% Styling
classDef main fill:#2b2d42,stroke:#8d99ae,stroke-width:2px,color:#edf2f4;
classDef engine fill:#3a86c8,stroke:#00509d,stroke-width:2px,color:#edf2f4;
classDef ext fill:#38b000,stroke:#007200,stroke-width:2px,color:#edf2f4;
classDef lspdap fill:#f77f00,stroke:#d62828,stroke-width:2px,color:#edf2f4;
UI[SpanCoder.App / Shell UI] <-->|Low-Latency TCP Socket| Eng[SpanCoder.Engine / Text Engine]
UI <-->|TCP Plugin Sockets| ExtManager[Extension Manager]
ExtManager <-->|Spawn & Monitor| Ext1[Plugin Process 1]
ExtManager <-->|Spawn & Monitor| Ext2[Plugin Process 2]
Eng <-->|Stdio Redirects / JSON-RPC 2.0| LSP[Language Server - LSP]
Eng <-->|Stdio Redirects / DAP| DAP[Debug Adapter - DAP]
class UI main;
class Eng engine;
class ExtManager,Ext1,Ext2 ext;
class LSP,DAP lspdap;
| Process | Primary Responsibility | Host Technologies | Threading & I/O Model |
|---|---|---|---|
| SpanCoder.App (Shell UI) | UI layout, input events, custom canvas rendering, window positioning, and layout orchestration. | Avalonia 11.1, .NET 10 | Single UI thread + multi-threaded command dispatch and TCP message reader loops. |
| SpanCoder.Engine | Piece-table text buffer representation, SIMD line indexing, syntax lexing, coordinates translations. | .NET 10 (AOT-compatible) | Single worker thread processing sequential buffer transactions via System.Threading.Channels. |
| Extension Host Processes | Executing third-party code, registering workspace items, creating custom sidebar panel content. | Language agnostic | Independent plugin runtimes communicating via JSON/binary socket interfaces. |
| Language Server (LSP) | Semantic syntax analysis, diagnostics, code completion list generation, hovers, and refactoring. | Node.js, .NET, Go, Rust, etc. | Spawned subprocess using standard I/O (stdin/stdout/stderr) redirection. |
| Debug Adapter (DAP) | Translating debugging UI commands into native debugger events (breakpoints, stepping, frame inspections). | Platform-specific engines | Spawned subprocess using standard I/O redirection. |
-
Piece Table Buffer (
PieceTable.cs): Represents document text modifications as a sequence of span descriptors pointing back to either the immutable original buffer or a thread-safe, pooled added-text character array (ArrayPool<char>). Edits (insertions and deletions) are$O(\text{edits})$ rather than$O(\text{document length})$ , permitting instant operations on multi-gigabyte files. -
Zero-Allocation Line Retrieval (
Document.cs): Line slicing checks if the requested segment lies contiguously in memory. If so, it yields aReadOnlySpan<char>pointing directly to the underlying buffers without executing any heap allocations. For non-contiguous segments, a thread-local/rented buffer is used.
- Intrinsics Shifting (
LineIndex.cs): Maps absolute byte offsets to document line boundaries. On document edits, the starting offsets of all subsequent lines must shift by the net change length. SpanCoder accelerates this using hardware-accelerated SIMD instructions (Vector<long>fromSystem.Numerics), processing line array adjustments in parallel blocks (up to 8 lines per instruction on AVX-512) instead of O(N) linear loops.
- Active Replay Ledger (
IpcEngineConnection.cs): The UI Shell is isolated from the editing engine via a local TCP socket. In addition to processing edits, the App writes all edit transactions to an in-memory ledger. - Automatic Crash Recovery: If
SpanCoder.Enginecrashes (e.g., due to out-of-memory or external process termination), the App immediately re-spawns a new engine instance, establishes the socket handshake, and replays the ledger in sequence to restore the editor state. The developer loses zero keystrokes and encounters no UI lockup.
- Extension Isolation (
ExtensionManager.cs): Third-party extensions run as separate processes, connecting to the App's plugin socket. Extensions register commands, keybindings, and panel descriptors using a standardized JSON manifest. - Resilient Commands: Commands are executed asynchronously over the socket. If a plugin halts or enters an infinite loop, the primary IDE window remains fully active and responsive.
- Secure IPC Handshake: Protects the local loopback socket boundary by enforcing a cryptographically secure token verification handshake. Connections are dropped immediately if verification fails or times out within 2 seconds.
- Zero-Reflection Dispatch (
CommandGenerator.cs): A custom incremental Source Generator processes any method or class annotated with[Command]or[MenuItem]. During compilation, it generates static dispatch branches mapping Command IDs to their execution pointers. This eliminates runtime reflection overhead, ensuring Native AOT trimmer safety and sub-millisecond IDE startup times.
- Overlay Gutter (
TextEditorCanvas.cs): Implements custom Skia-based text rendering in Avalonia. Features a stationary Line Numbers Gutter that acts as an overlay mask. When text is scrolled horizontally, it scrolls under the gutter. - Auto-Scrolling Viewport: Automatically calculates viewport boundaries during cursor movement, scrolling the horizontal and vertical scrollbars to guarantee the caret remains visible (
EnsureCaretVisible()). - Visual Carets: Configurable caret thickness, drawing cursors using hardware-rendered animations.
- Premium Window-Anchored Overlay (
CommandPalette.cs): Located at the top center of the window, rendered with subtle drop shadows (BoxShadows) and a modern blurred backdrop. - Multi-Tab Mode: Employs JetBrains-style tabs to switch contexts:
- All: Merged results from files, commands, and active symbol declarations.
- Files: Rapid file navigation.
- Actions: Command execution with shortcuts.
- Symbols: Local symbols parsing.
- Workspace Background Indexing: Traverses the workspace folder using background workers, building relative path caches to support instant keypress searching.
- Local Symbols Parser: Parses current document structures dynamically to locate namespaces, classes, methods, and variables.
- JSON-RPC Over Stdio (
LspClient.cs): Connects standard language servers by launching them as subprocesses and piping JSON-RPC payloads through their standard input and output streams. - Handshake Handlers: Handles standard
initializecapability negotiations. - Synchronization Protocols: Automatically broadcasts document changes using incremental synchronization packets (
textDocument/didOpenandtextDocument/didChange). - Diagnostic Coordinate Translators (
EngineHost.cs): Translates standard LSP 0-indexed line/character coordinates into absolute document character offsets, passingDiagnosticsReportpackets to the Shell to render inline squiggly underlines. - Interactive Requests: Queries servers dynamically for Autocompletes (
textDocument/completion), Hover Tooltips (textDocument/hover), and Semantic Code Navigation (textDocument/definition).
- Visual Studio Solutions & Projects (
SidebarFileTree.cs): Native support for classic Visual Studio Solutions (.sln), modern Solution XML files (.slnx), and C# projects (.csproj). - Interactive Project Browsing: The sidebar displays nested file and folder hierarchies matching the solution layout, allowing developers to add projects or folders directly and double-click to load any file into the editor viewport.
- Directory Namespace Resolution: Automatically computes namespace structures based on the target folder position relative to the
.csprojfile.
- Resilient Extensibility (
SpanCoder.Extensions.Languages): Contributes rich language metadata (keywords, syntax coloring, line and block comment structures) and custom commands out-of-process. - Dynamic Sidebar Toolbar Contribution: Seamlessly registers and mounts buttons onto the Shell UI's workspace toolbar, communicating exclusively via structured JSON-RPC packets over low-latency socket buffers.
- Theme & Custom Settings (
SettingsWindow.cs,SettingsManager.cs): Modal options dialog (Ctrl+,orTools -> Options) permitting changes to theme, typography, line height, and editor behavior. - Extension Configuration Registration: Extensions dynamically register custom configuration schemas via JSON manifests, allowing developers to configure third-party plugins in a unified interface. Settings persist locally in
%APPDATA%/SpanCoder/settings.json.
- Rolling Performance Profiler (
PerformanceGraphsControl.cs): Renders dynamic CPU utilization (%) and Working Set RAM consumption (MB) line charts using custom Skia brushes with beautiful neon gradients. - Visual Diagnostics: Dedicated "Performance" tab in the bottom panel for profiling code hot-paths, execution trees, and heap/GC allocations in real-time.
- Simulated User Interactions (
UiTests.cs): UsesAvalonia.Headless.XUnitto bootstrap the editor shell in a headless environment, asserting viewport coordinates, command palette inputs, settings applications, and tree navigation rendering. - State Cleanliness: Prevents cross-test state leakages via dynamic unregistration and cleanups of extension descriptors.
- PTY Terminal Emulator (
TerminalControl.cs,PtyHost.cs): Provides a built-in terminal control inSpanCoder.Shellhandling standard pseudo-terminal (PTY) streams (ConPTY on Windows,/dev/ptmxon Unix), rendering native shells inside the IDE with zero input lag.
- Gutter Markers & Staging: Background Git worker queries status, displaying color-coded line modifications (added, modified, deleted) directly inside the canvas gutter. Includes a sidebar panel for staging files, writing commit messages, and managing branches.
- Out-of-Process Coordination: Coordinates LLM chat, reasoning, and tool executions (running build/test scripts, reading/writing workspace files, running shell commands) entirely asynchronously in the
SpanCoder.Enginedaemon process. - API Key Encryption (DPAPI): Automatically encrypts all API keys using Windows DPAPI before persisting them to
%APPDATA%/SpanCoder/settings.json. Falls back to secure AES encryption on Unix/WSL, utilizing a cryptographically secure random IV and a magic header to maintain seamless backward compatibility with legacy keys. - Interactive Command Confirmation Gate: Enforces a strict user-authorization step (dual Approve/Reject buttons) in the UI chat feed when running shell commands via
execute_terminal_commandwith YOLO Mode turned off. - Workspace Path Traversal Safeguards: Protects file tools (
read_file,write_file,edit_file_replace) with path validation bounds checking, throwingUnauthorizedAccessExceptionand rejecting any operations that resolve outside the workspace root. - Chronological Chat & Sizing: Streams text tokens and tool steps in the exact chronological order of execution. Uses a non-virtualized scrolling list to prevent text clipping and display log outputs at full height.
- Auto-Collapsing Tool Cards: Automatically collapses tool log boxes when execution finishes, keeping the chat feed neat and scan-friendly while allowing one-click manual expansion.
- Native Markdown Rendering: Upgrades plain text output with dynamic block and inline runs, styling headers, horizontal rules, lists, bold/italics, and custom Consolas block code scrollable boxes.
- Binary File Safety Guards: Auto-detects null bytes in files to block the AI agent from accidentally reading or modifying binary DLLs, EXEs, or images.
- Dynamic Split Layouts: Split the editor horizontally or vertically to view and edit multiple files concurrently, or multiple views of the same file at different scroll/caret positions.
- Real-Time Synchronization: Edits to a shared document inside one pane reflect instantly in all other visible panes displaying that document.
- Active Pane Visual Highlight: Active focused editor is visually distinguished with a blue border highlight (
#007ACC). - Focus Overlay Migration: Automatically shifts overlays (such as autocompletions, code hovers, and debugging controls) to the active editor pane's visual tree.
- Compile-Time Command Routing: Configured with compile-time source-generated shortcut keys (
Ctrl+E, Hto split horizontally,Ctrl+E, Vto split vertically, andCtrl+E, Uto unsplit).
- Zero-Latency Scanner: Real-time parser scans the document for
{/}braces and#region/#endregionpreprocessor blocks, automatically excluding comment and string tokens. - LSP Integration: Background tasks query the Language Server via
textDocument/foldingRangeto obtain richer semantic blocks. - Line Mapping Engine: Mappings translate document line indexes to visual lines. Hidden (folded) lines are collapsed, updating editor scrollbar metrics and gutter folding indicator icons (
▾/▸) in real time. - Interactive Gutter Toggles: Click folding indicators directly in the gutter margin to expand or collapse blocks.
- Smart Caret Navigation: caret position calculation and arrow key movements automatically jump over hidden (folded) lines.
- Zero-Config Local AI: Auto-detects a local Ollama instance on startup. If the optimized
qwen2.5-coder:1.5bmodel is missing, the editor pulls it automatically in the background. - Fill-in-the-Middle (FIM): Queries the local model using prefix and suffix document context surrounding the caret, generating accurate code completions in less than 100ms.
- Inline Ghost Text: Renders suggestions inline in a faded, non-intrusive gray color (
#707070) using monospace-aligned font formatting. - Smart Interaction Keybindings: Press
Tabto accept and insert the suggestion, orEsc(or type any key) to dismiss it. - Offline Privacy Protection: Completely offline—zero API subscriptions, cloud costs, or tracking.
- Asynchronous Formatting (
SpanCoder.Extensions.Prettier): Out-of-process extension that supports manual formatting (Alt+Shift+For via context menu/command palette) and asynchronous Format-on-Save. - Process Boundary Security: Passes active buffers over the secure loopback TCP connection, utilizing a 3-second timeout guard to ensure host UI responsiveness.
- Fallback Smart Indenting: Attempts to invoke
npx prettierunder the hood, with a built-in smart brace indenter fallback for JSON/JS/CSS to ensure instant formatting even without Node.js installed.
- Real-Time Document Preview: Allows developers to launch a live rendering pane that renders active HTML documents inside the main tab workspace.
- Typing Synchronization: The preview pane automatically listens to editor updates, refreshing in real-time as the developer modifies the code, without requiring manual saves or page reloads.
- In-Tab Extension Details: Clicking on any marketplace extension in the sidebar list opens a dedicated, interactive "Extension Details" document tab.
- Live Installation Management: Provides instant "Install" and "Uninstall" action buttons that load or terminate out-of-process extension daemons dynamically.
- Dynamic Configuration Bindings: Parses registered extension settings automatically, rendering interactive checkboxes for boolean toggles and input textboxes for string settings. Configuration changes are synchronized and written to
%APPDATA%/SpanCoder/settings.jsonin real-time.
- Real-Time Git Annotations: Displays inline Git blame information (commit author, date, message) directly at the end of the active cursor line using faded, hardware-accelerated Skia text overlay brushes.
- Inline Compiler Feedback: Renders full compiler diagnostics description, warnings, and errors directly at the end of the problematic line, minimizing layout shifting and visual context switching.
- Distraction-Free Workspace: Instantly collapses side panels, the status bar, status indicators, and margin areas to maximize vertical and horizontal canvas code space for focused programming (
Ctrl+K, Z).
- Split Diff Viewport: Side-by-side split Diff pane to review local Git changes, compare branch history, and walk through pull request code changes directly inside the editor tab.
- Custom Remapper UI: Filtered settings search bar and interactive key mapper that dynamically captures key combinations (including modifier keys) to customize IDE gestures. Offers built-in conflict alerts and persists customizations to
%APPDATA%/SpanCoder/keybindings.jsonto overwrite default commands and plugin bindings at runtime.
- Out-of-Process Syntax Highlight: Registers keyword syntax coloring, lines/block comment configurations, and type sets for
.c,.cc,.h,.hpp, and.javafiles out-of-process via the core languages extension. - LSP Integration: Dynamically routes and spawns
clangdLSP for C/C++ files andjdtlsLSP for Java files, providing code actions, completions, definitions, and compiler diagnostics.
- Serial REPL Connection Manager: Built-in interactive console pane at the bottom of the editor that connects to serial ports (COM/TTY). When connected, keys typed are sent over serial and responses from the board are printed to the terminal.
- Auto-Detection Probing: Scans active ports, sends a query, and matches
>>>to automatically detect a MicroPython/CircuitPython device. - Interactive UF2 Flashing Dialog: Search for bootloader-ready storage volumes (like
RPI-RP2drives) and flashes target microcontrollers with specific MicroPython runtimes using a progress bar. - Interruption Controls: Toolbar buttons to easily send Ctrl+C (KeyboardInterrupt) or Ctrl+D (soft reboot) to control board execution.
- Graphical Target Manager (
HardwareDeployWindow.cs): Visual board presets (RP2040/RP2350 Pico, STM32, ESP32), debugger probe selectors (CMSIS-DAP, J-Link, ST-Link, ESP-Prog), custom compilation/upload commands, and target remote connections saved directly tospancoder_debug.json. - Integrated Background Runner: Custom shell processes executing builds and upload commands in the background, redirecting stdout/stderr streams to the multi-channel Output pane in real-time.
- Microcontroller GDB DAP Debugger: Automatically launches native ARM debuggers using
--interpreter=dapflags, or falls back to a simulated Cortex-M mock silicon debugger providing stepping, local variables, and CPU register maps (pc,sp,lr,r0-r3) for testing without hardware.
- Non-Blocking Background Service: Decoupled LLM integration hosted in the background
SpanCoder.Engineservice, interfacing with local (Ollama) or cloud-based (Gemini, OpenAI) models without blocking the primary Avalonia UI thread.
- Embedded AI Chat Panel (
AiChatPanel.cs): Interactive sidebar supporting rich Markdown rendering, encrypted credentials storage, and auto-collapsing tool cards. Renders tool executions (e.g. running scripts, file editing) in real-time.
- Modal Keyboard Layouts: Zero-dependency keyboard layout adapter providing Vim-style Normal and Insert modes. Supports navigation (
h,j,k,l,w,b), edit actions (x,dd,o), and state transitions toggled via user settings.
- Buffer State Tracking: Tracks unsaved edits on document buffers (
IsDirty), appending asterisk markers (*) to editor tab titles. Warns developers with modal confirmation dialogs when closing unsaved files or exiting the IDE.
- Context-Driven Actions: Custom right-click context menu in the editor canvas providing Cut/Copy/Paste, Breakpoint toggles, Go to Definition, Find References, and Rename. Supports custom menu items registered dynamically by out-of-process extensions, alongside double/triple-click text selection.
- Decoupled Remote Hosting: Run the
SpanCoder.Appshell locally while connecting to a remoteSpanCoder.Enginedaemon over TCP sockets. Supports secure SSH port-forwarding tunnels, mapping file system watchers, and building/deploying remotely on Unix/Linux VMs. - Path Mapping: Includes configurable path mapping (
--map-path) to resolve workspace directories between different operating systems (such as Windows to WSL/Linux).
- Low-Latency Sequence CRDT: Syncs editor buffers between developers using a low-latency Conflict-free Replicated Data Type (CRDT) protocol over WebSockets. Displays remote cursor positions, selections, and user labels in real-time.
- Interactive CodeLens: Displays inline references and author information ("X references | author, Y hours ago") directly above class, struct, interface, and method declarations, automatically aligned with the code's indentation.
SpanCoder uses the Language Server Protocol (LSP) to support syntax analysis, code completion, error diagnostics, and source navigation.
To contribute language support, an extension provides a manifest defining activation triggers and the server launch command:
{
"id": "csharp-lang-support",
"displayName": "C# Development Kit",
"version": "1.0.0",
"activationEvents": [
"onLanguage:csharp"
],
"contributes": {
"languages": [
{
"id": "csharp",
"extensions": [".cs", ".csx"]
}
],
"lsp": {
"command": "csharp-ls",
"args": ["--stdio"],
"initializationOptions": {
"solution": "${workspaceFolder}"
}
}
}
}The following sequence highlights how the UI Shell, Text Engine, and Language Server subprocess synchronize text and request services:
sequenceDiagram
autonumber
participant UI as Shell UI (App)
participant Eng as Engine (Text Buffer)
participant LSP as Language Server (LSP Process)
Note over UI,Eng: User types text into the editor canvas
UI->>Eng: TCP: InsertText(docId, offset, "Console.WriteLine")
Eng->>Eng: Update Piece Table & SIMD Line Index
Eng->>LSP: Stdio: textDocument/didChange (URI, Text Changes)
Note over LSP: Re-evaluates code semantics in background
LSP-->>Eng: Stdio: textDocument/publishDiagnostics (URI, line/char coordinates)
Eng->>Eng: Translate line/char coordinates to absolute offsets
Eng->>UI: TCP: DiagnosticsReport(docId, List of DiagnosticItems)
Note over UI: UI Canvas redraws with red error squiggles
Note over UI,Eng: User hovers mouse over a symbol or triggers completion
UI->>Eng: TCP: AutocompleteRequest(docId, offset)
Eng->>Eng: Map offset to line & character coordinates
Eng->>LSP: Stdio: textDocument/completion (URI, line, character)
LSP-->>Eng: Stdio: completion response (List of AutocompleteItems)
Eng->>UI: TCP: AutocompleteResponse(docId, offset, items)
Note over UI: UI displays autocompletion popup list
SpanCoder implements debugging support using the Debug Adapter Protocol (DAP). DAP decouples the IDE UI from specific debuggers (e.g. LLDB, GDB, Node-Debug, .NET CoreCLR Debugger) by defining standard JSON-RPC messages to control process execution, read memory, and handle breakpoints.
A debugger session proceeds through the following lifecycle states:
stateDiagram-v2
[*] --> Uninitialized : Debug Session Created
Uninitialized --> Initializing : Handshake started
Initializing --> Configured : 'initialize' request & capabilities exchanged
Configured --> Running : 'launch' or 'attach' request sent
Running --> Stopped : Target hits breakpoint, exception, or pause event
Stopped --> Running : 'continue', 'next' (step over), or 'stepIn' command
Running --> Terminated : Target exits or 'disconnect' sent
Stopped --> Terminated : Session stopped by developer
Terminated --> [*] : Resources Disposed
When a developer sets breakpoints and launches a debugger, the following communication takes place:
sequenceDiagram
autonumber
participant UI as Shell UI (App)
participant Eng as Engine (DapClient)
participant DA as Debug Adapter (DAP Process)
participant Target as Target Application
UI->>Eng: Start Debugging Command
Eng->>DA: Spawn Debugger Subprocess & redirect stdio
Eng->>DA: initialize request (Adapter configuration exchange)
DA-->>Eng: initialize response (Supported features: e.g. supportsStepBack=false)
UI->>Eng: Get Breakpoints from Shell Window state
Eng->>DA: setBreakpoints request (File paths, line numbers)
DA-->>Eng: setBreakpoints response (Validated breakpoint locations)
Eng->>DA: launch or attach request (Arguments, paths, cwd)
DA->>Target: Spawns application process with debugger attached
DA-->>Eng: launch/attach response (Success confirmation)
Eng->>DA: configurationDone request (Signal startup complete)
DA-->>Eng: configurationDone response
Note over Target: Application runs and hits the breakpoint
Target->>DA: Trap Breakpoint Exception
DA-->>Eng: stopped event (reason: "breakpoint", threadId: 1)
Eng->>UI: TCP: StoppedEvent (docId, lineOffset, reason)
Note over UI: UI highlights paused line and displays Debug Toolbar
UI->>Eng: Request state updates for Sidebar
Eng->>DA: threads request
DA-->>Eng: threads response (Active Thread IDs)
Eng->>DA: stackTrace request (threadId: 1)
DA-->>Eng: stackTrace response (List of StackFrames)
Eng->>DA: scopes request (frameId: 1)
DA-->>Eng: scopes response (List of Scopes: e.g., Local, Global)
Eng->>DA: variables request (variablesReference: 101)
DA-->>Eng: variables response (Name, value, type of locals)
Eng->>UI: TCP: DebugStateReport (Threads, StackFrames, Variables)
Note over UI: UI updates Call Stack panel and Variables tree view
Workspace launch behaviors are declared inside a .spancoder/launch.json file in the root workspace folder:
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (Console)",
"type": "coreclr",
"request": "launch",
"program": "${workspaceFolder}/bin/Debug/net10.0/MyApp.dll",
"args": ["--verbose", "input.txt"],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
{
"name": "Attach to Local Python Process",
"type": "python",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app"
}
]
}
]
}Interactive debugging features are integrated into the main shell via several dedicated UI components:
+-----------------------------------+-----------------------------------------+
| [Menu: File Edit Debug] | [Floating Debug Toolbar: |> || || ->] |
+-----------------+-----------------+-----------------------------------------+
| [Sidebar Tab] | [File Explorer] | TextEditorCanvas.cs |
| | | |
| [X] Debug | MyApp.cs | 10 using System; |
| - Variables | | 11 class Program { |
| - args: [] | | 12 static void Main() { |
| > locals: | | 13*==> Console.WriteLine("Debug"); |
| | | 14 } |
| - Call Stack | | 15 } |
| - Main() | | |
| | | |
| - Breakpoints | | |
| [x] 13: MyApp | | |
+-----------------+-----------------+-----------------------------------------+
- Floating Debug Toolbar: An overlay control positioned at the top of the editor canvas:
- Start / Continue (F5): Begins execution or resumes a paused thread.
- Step Over (F10): Executes the current line of code and stops at the next line in the same file.
- Step Into (F11): Steps inside function definitions.
- Step Out (Shift + F11): Executes remainder of current function, returning to the caller.
- Stop / Terminate (Shift + F5): Disconnects the debugger and kills the target process.
- Restart (Ctrl + Shift + F5): Rebuilds and re-launches the application under the debugger.
- Interactive Editor Gutter:
- Clicking in the gutter area left of the line numbers creates a Breakpoint Marker (visualized as a red dot).
- Right-clicking a breakpoint marker displays an input box to set Conditional Breakpoints (e.g.
count > 10) or Hit Counts.
- Debug Side Panels (Sidebar Layout):
- Call Stack View: Displays active threads. Expanding a thread lists stack frames. Clicking a frame loads that frame's source file and positions the caret on the active line.
- Variables Tree View: Displays a hierarchical tree of variables in the selected frame scope. Handles nested objects and arrays using lazy evaluation.
- Breakpoints Registry: Displays a list of all breakpoints. Permits quick enabling, disabling, or batch deleting of targets.
- Inline Diagnostics & Hover Inspection:
- During stopped states, hovering the mouse cursor over a variable queries DAP for its current evaluation and displays the value inline as a premium dark-themed tooltip.
- Execution indicators show the active instruction pointer using a highlighted background line and an arrow icon.
- .NET 10.0 SDK (Preview or Release matching project specifications)
- Ollama (Required for local offline autocomplete/Ghost Text; no subscriptions or external API keys required!)
SpanCoder features built-in, offline-friendly inline code completions (Ghost Text) powered by a local instance of Ollama.
To enable this feature:
- Download and Install Ollama from the official website: ollama.com.
- Start Ollama (ensure the Ollama service is running on its default port
11434). - Launch SpanCoder. The editor will automatically check for the local Ollama instance on startup.
- Auto-Downloading the Model: If the optimized
qwen2.5-coder:1.5bmodel is missing, the application will automatically pull (download) it in the background. Progress will be displayed in the status bar (e.g.,AI: Downloading qwen2.5-coder:1.5b (900MB)...). - Start Typing: Once the model is ready, pause typing for 250ms in any code file to see light-gray ghost text suggestions. Press
Tabto accept and insert the suggestion, orEsc(or keep typing) to dismiss it.
Note
All model files are stored locally in your user profile under Ollama's model directory (~/.ollama/models or %USERPROFILE%\.ollama\models), meaning they are never checked into the Git repository.
Build the solution files using the .NET CLI:
dotnet build SpanCoder.slnxRun the primary UI application process:
dotnet run --project src/SpanCoder.App/SpanCoder.App.csprojExecute the xUnit tests suite:
dotnet testSpanCoder supports running the frontend app locally while connecting to a remote engine daemon (e.g. inside a Docker container, WSL, or on a remote Linux server).
- Start the Engine Daemon (Remote Host / WSL / Linux):
Launch the engine process in listening mode:
./SpanCoder.Engine --listen --port 5001
- Start the App (Local Host):
Launch the shell UI in connection mode, specifying the target host and port, along with local-to-remote path mapping:
dotnet run --project src/SpanCoder.App/SpanCoder.App.csproj -- --connect 127.0.0.1:5001 --map-path "C:\local\workspace=/remote/workspace"- The
--map-pathspec allows the client UI to operate on a local folder mount or volume while the remote engine executes compilations, LSP checks, and debugging commands on the remote Linux paths seamlessly.
- The
SpanCoder allows multiple developers to edit the same file simultaneously using a low-latency, conflict-free sequence CRDT protocol over WebSockets.
-
Host a Session:
- In the menu bar, navigate to Collab -> Host Collaboration Session.
- Input your username and a port to listen on (e.g.,
5080). - Click Host. The editor will start the collaboration server and automatically connect your local editor instance.
-
Join a Session:
- In the menu bar, navigate to Collab -> Join Collaboration Session.
- Input your username and the host's IP address and port (e.g.,
127.0.0.1:5080). - Click Join. Your document buffer will immediately synchronize with the host.
-
Collaboration Features:
- Real-Time Cursor/Selection Rendering: Remote cursors appear as colored carets with floating username badges, and selections render as semi-transparent highlights in real time.
- Conflict-free Edits: The document remains responsive with local edits applied immediately, while remote concurrent updates merge using fractional indexing CRDT to guarantee convergent document states.
- Disconnect: Terminate or leave a session at any time via Collab -> Disconnect.
To compile a single, zero-dependency executable file with sub-millisecond cold start times, run:
dotnet publish src/SpanCoder.App/SpanCoder.App.csproj -c Release -r win-x64 --self-contained -p:PublishAot=true -p:OptimizationPreference=Speed -p:TrimMode=linkThis produces a fully compiled native binary in the publish folder, ready for distribution.
Important
Extensibility Core Promise: Every component inside SpanCoder is designed to communicate via messages, ensuring no shared memory exists between plugins, debuggers, or the main application thread. This ensures the IDE remains operational even when external language services or debugger sessions encounter severe errors.
Developed by Ian Cowley and Antigravity (Google DeepMind).