Gopher Code

repository·main·Indexed 21 days ago

https://github.com/projectbarks/gopher-code

A high-performance, native Go rewrite of an agentic coding assistant. It replaces a TypeScript/Node.js/Electron stack with a single static binary for fast startup and low memory usage. Features include an interactive REPL, headless mode for scripting, and CLI tools for authentication, agent management, auto-mode rule configuration, and diff session tracking.

Tokens
34.7K
Snippets
92
Records
142
Agent score
74%

What's inside gopher-code

  1. Understand the TUI Parity Validation Process

    main

    The project uses a parity validation strategy to ensure the Terminal User Interface (TUI) behaves correctly across various scenarios. This process is divided into phases:

    1. Phase 1: Capture Scenarios: Re-running failures to build a dataset of passing/failing scenarios.
    2. Phase 2: Parity Tests: Executing specific functional tests (e.g., TestParity_...) to validate UI behaviors like state machines, input handling, and layout responsiveness.
    3. Phase 3: Fixes and Refinement: Addressing discrepancies found during parity testing (e.g., incorrect characters, layout issues, or missing prefixes).

    Developers can monitor progress via the progress.md file, which tracks test categories such as area-01-welcome, area-02-prompt, and various functional test blocks (B1-B66).

  2. Visual parity test categories and coverage

    main

    The visual parity validation is organized into several functional areas. Use these categories to identify which parts of the UI require testing or have existing gaps:

    • Area 01 (Welcome): Validates the welcome box, including border characters, title formatting, width responsiveness (narrow/wide), mascot art, and dismissal behavior (on keypress or submit).
    • Area 02 (Prompt): Validates the input prompt, including character glyphs (e.g., ), backspace, history navigation (up/down), and keyboard shortcuts (Ctrl+A, Ctrl+E, Ctrl+C, Ctrl+U, Ctrl+W).
    • Area 03 (Streaming): Validates the streaming response experience, including text arrival, code block rendering, spinner glyphs, and cancellation behavior.
    • Area 04 (Tools): Validates tool execution UI, such as file reading, error displays, and the use of connector characters (e.g., for streaming tools, / for results).
    • Area 05 (Permissions): Validates permission dialogs (e.g., Bash dialogs) and the visibility of results.
    • Area 06 (Status): Validates the status line, including idle shortcuts and streaming interrupt indicators.
    • Area 07 (Commands): Validates slash commands (e.g., /model, /clear, /help).
    • Area 09 (Thinking): Validates the display of model thinking effort.
    • Area 11 (Layout): Validates layout elements like dividers and double dividers.
    • Area 12 (Diff): Validates the diff preview dialog, including content rendering and approval/rejection controls.
    • Area 20 (Multiturn): Validates message ordering and prefixing in multi-turn conversations.
  3. Run tests and update golden files

    main

    Developers can run the test suite using standard Go testing commands. To ensure parity with the original implementation, the project uses golden file tests.

    # Run all tests
    go test ./...
    
    # Run tests with the race detector enabled
    go test -race ./...
    
    # Update golden files (use with caution)
    go test ./... -update
  4. Run Gopher Code in REPL or Headless mode

    main

    After building, you can run Gopher Code in two primary modes:

    1. Interactive REPL: Launches a terminal UI (TUI) for conversational use.
    2. Headless Mode: Executes a single query and exits, useful for scripting or CI.
    # Run interactive REPL
    ./gopher
    
    # Run a single query in headless mode
    ./gopher -p "explain this codebase"
  5. Implement TUI visual parity tests

    main

    To ensure the Gopher TUI matches the visual output of Claude, implement Go tests in pkg/ui/visual_parity_test.go.

    Strategy:

    1. Use the existing test framework consisting of NewAppModel, Update, and View to render Gopher's output.
    2. Compare the rendered output against the reference snapshots stored in data/claude/.
    3. Validate specific visual elements, structural integrity (e.g., borders, column separators), and state transitions.

    Avoid writing "superficial" tests that only check for single characters using strings.Contains. Instead, write structural tests that validate complete UI components (e.g., ensuring a welcome box has consistent borders and width).

    // Implementation pattern for parity tests
    // Use NewAppModel + Update + View to render output
    // Compare against snapshots in data/claude/
  6. Install and build Gopher Code

    main

    To use Gopher Code, clone the repository and build the binary using the Go toolchain. The project requires Go 1.24 or higher.

    # Clone the repository
    git clone https://github.com/projectbarks/gopher.git
    cd gopher
    
    # Build the binary
    go build -o gopher ./cmd/gopher
    git clone https://github.com/projectbarks/gopher.git
    cd gopher
    
    go build -o gopher ./cmd/gopher
  7. Manage session diffs with DiffSession

    main

    The DiffSession struct is the primary integration point for managing diff-related operations within a session. It orchestrates three main capabilities:

    1. Working-tree diff computation: Using the Computer to get current file changes.
    2. Per-turn diff tracking: Using the Tracker to record edits made during specific user turns.
    3. PR status polling: Using the Poller to monitor Pull Request status in the background.

    You initialize a session using NewDiffSession(repoPath), which roots all diff operations at the specified repository path.

    import "github.com/projectbarks/gopher-code/cmd/gopher-code/handlers"
    
    // Initialize a session for a specific repository
    session := handlers.NewDiffSession("/path/to/your/repo")
  8. How the TUI application state works

    main

    The TUI operates using a state machine defined by the AppState type. Understanding these states is key to knowing how the interface behaves:

    • StateIdle: The application is waiting for user input. In this state, the input prompt is visible and active.
    • StateRunning: A query is currently executing. The interface displays a loading indicator (e.g., ⟳ thinking...) and prevents new input.
    • StateExiting: The user has requested to close the application.

    Transitions occur via key presses (like enter to move from StateIdle to StateRunning) or internal messages (like QueryCompleteMsg which returns the app to StateIdle).

  9. How the BridgeOrchestrator lifecycle works

    main

    The BridgeOrchestrator follows a specific lifecycle to ensure reliable operation and clean resource management:

    1. Registration: Upon Start(), the orchestrator calls API.RegisterBridgeEnvironment to obtain an EnvironmentID and EnvironmentSecret.
    2. Polling Loop: The orchestrator enters a loop calling API.PollForWork.
      • If no work is found, it sleeps based on the PollConfig.
      • If work is found, it dispatches it.
    3. Work Dispatching:
      • Healthchecks: Acknowledged immediately.
      • Sessions: The orchestrator validates the session ID, decodes the secret, checks against MaxSessions capacity, acknowledges the work to the server, and uses the Spawner to launch the session.
    4. Session Monitoring: Each spawned session is watched in a background goroutine. When a session completes (Success, Failure, or Interrupted), the orchestrator cleans up local state and notifies the server via API.StopWork (unless the session was interrupted by the server).
    5. Shutdown: When Stop() is called or a fatal error occurs, the orchestrator kills all active sessions (SIGTERM $\rightarrow$ SIGKILL), stops all work on the server, and finally deregisters the environment.
  10. How RemoteIO manages remote bidirectional I/O

    main

    The RemoteIO struct is a bidirectional stream-JSON I/O wrapper designed for remote sessions (such as bridge or CCR connections). It abstracts the underlying network transport, allowing a developer to treat a remote connection as a standard io.Reader for incoming data and a Write method for outgoing messages.

    Key Responsibilities:

    • Transport Abstraction: Supports two versions: TransportV1 (WebSocket) and TransportV2 (SSE + POST/CCR v2).
    • Authentication: Automatically manages Authorization: Bearer <token> headers using a provided TokenSource and includes the x-environment-runner-version header.
    • Keep-Alive: If running in a bridge environment (detected via CLAUDE_CODE_ENVIRONMENT_KIND), it automatically sends keep_alive messages at a configured interval.
    • Data Framing: Ensures incoming data is framed with trailing newlines for NDJSON consumption via the Reader() method.
    // Example conceptual usage
    cfg := cli.RemoteIOConfig{
        StreamURL: "wss://example.com/session",
        SessionID: "session-123",
        TokenSource: func() string { return "my-token" },
        TransportFactory: myTransportFactory,
        PollConfig: bridge.PollIntervalConfig{SessionKeepaliveInterval: 30 * time.Second},
    }
    
    rio, _ := cli.NewRemoteIO(cfg)
    rio.Connect()
    
    // Read incoming NDJSON lines
    scanner := bufio.NewScanner(rio.Reader())
    for scanner.Scan() {
        fmt.Println("Received:", scanner.Text())
    }
    
    // Send a message
    rio.Write(map[string]string{"type": "command", "payload": "hello"})
  11. Understand the StructuredIO SDK protocol

    main

    The StructuredIO system implements a line-delimited JSON (NDJSON) protocol for communication between an SDK host and a client (like Claude Code) via stdin and stdout.

    Communication Flow

    1. Inbound (stdin): The system parses StdinMessage objects. These can be user/assistant/system messages or control_request messages from the host.
    2. Outbound (stdout): The system writes StdoutMessage (NDJSON lines) to the output stream. This includes responses to requests or new control requests (like permission prompts).

    Message Types (StdinMessage.Type)

    • user: A message from the user.
    • assistant: A message from the assistant.
    • system: A system instruction.
    • control_request: A command or request from the host (e.g., asking for permission).
    • control_response: A response to a previously sent control_request.
    • keep_alive: A heartbeat message (silently ignored).
    • update_environment_variables: A request to update environment state (currently not implemented in Go).