Full Code of opencode-ai/opencode for AI

main 73ee493265ac cached
162 files
1.3 MB
369.9k tokens
2589 symbols
1 requests
Download .txt
Showing preview only (1,399K chars total). Download the full file or copy to clipboard to get everything.
Repository: opencode-ai/opencode
Branch: main
Commit: 73ee493265ac
Files: 162
Total size: 1.3 MB

Directory structure:
gitextract_5ee_h7l1/

├── .github/
│   └── workflows/
│       ├── build.yml
│       └── release.yml
├── .gitignore
├── .goreleaser.yml
├── .opencode.json
├── LICENSE
├── README.md
├── cmd/
│   ├── root.go
│   └── schema/
│       ├── README.md
│       └── main.go
├── go.mod
├── go.sum
├── install
├── internal/
│   ├── app/
│   │   ├── app.go
│   │   └── lsp.go
│   ├── completions/
│   │   └── files-folders.go
│   ├── config/
│   │   ├── config.go
│   │   └── init.go
│   ├── db/
│   │   ├── connect.go
│   │   ├── db.go
│   │   ├── embed.go
│   │   ├── files.sql.go
│   │   ├── messages.sql.go
│   │   ├── migrations/
│   │   │   ├── 20250424200609_initial.sql
│   │   │   └── 20250515105448_add_summary_message_id.sql
│   │   ├── models.go
│   │   ├── querier.go
│   │   ├── sessions.sql.go
│   │   └── sql/
│   │       ├── files.sql
│   │       ├── messages.sql
│   │       └── sessions.sql
│   ├── diff/
│   │   ├── diff.go
│   │   └── patch.go
│   ├── fileutil/
│   │   └── fileutil.go
│   ├── format/
│   │   ├── format.go
│   │   └── spinner.go
│   ├── history/
│   │   └── file.go
│   ├── llm/
│   │   ├── agent/
│   │   │   ├── agent-tool.go
│   │   │   ├── agent.go
│   │   │   ├── mcp-tools.go
│   │   │   └── tools.go
│   │   ├── models/
│   │   │   ├── anthropic.go
│   │   │   ├── azure.go
│   │   │   ├── copilot.go
│   │   │   ├── gemini.go
│   │   │   ├── groq.go
│   │   │   ├── local.go
│   │   │   ├── models.go
│   │   │   ├── openai.go
│   │   │   ├── openrouter.go
│   │   │   ├── vertexai.go
│   │   │   └── xai.go
│   │   ├── prompt/
│   │   │   ├── coder.go
│   │   │   ├── prompt.go
│   │   │   ├── prompt_test.go
│   │   │   ├── summarizer.go
│   │   │   ├── task.go
│   │   │   └── title.go
│   │   ├── provider/
│   │   │   ├── anthropic.go
│   │   │   ├── azure.go
│   │   │   ├── bedrock.go
│   │   │   ├── copilot.go
│   │   │   ├── gemini.go
│   │   │   ├── openai.go
│   │   │   ├── provider.go
│   │   │   └── vertexai.go
│   │   └── tools/
│   │       ├── bash.go
│   │       ├── diagnostics.go
│   │       ├── edit.go
│   │       ├── fetch.go
│   │       ├── file.go
│   │       ├── glob.go
│   │       ├── grep.go
│   │       ├── ls.go
│   │       ├── ls_test.go
│   │       ├── patch.go
│   │       ├── shell/
│   │       │   └── shell.go
│   │       ├── sourcegraph.go
│   │       ├── tools.go
│   │       ├── view.go
│   │       └── write.go
│   ├── logging/
│   │   ├── logger.go
│   │   ├── message.go
│   │   └── writer.go
│   ├── lsp/
│   │   ├── client.go
│   │   ├── handlers.go
│   │   ├── language.go
│   │   ├── methods.go
│   │   ├── protocol/
│   │   │   ├── LICENSE
│   │   │   ├── interface.go
│   │   │   ├── pattern_interfaces.go
│   │   │   ├── tables.go
│   │   │   ├── tsdocument-changes.go
│   │   │   ├── tsjson.go
│   │   │   ├── tsprotocol.go
│   │   │   └── uri.go
│   │   ├── protocol.go
│   │   ├── transport.go
│   │   ├── util/
│   │   │   └── edit.go
│   │   └── watcher/
│   │       └── watcher.go
│   ├── message/
│   │   ├── attachment.go
│   │   ├── content.go
│   │   └── message.go
│   ├── permission/
│   │   └── permission.go
│   ├── pubsub/
│   │   ├── broker.go
│   │   └── events.go
│   ├── session/
│   │   └── session.go
│   ├── tui/
│   │   ├── components/
│   │   │   ├── chat/
│   │   │   │   ├── chat.go
│   │   │   │   ├── editor.go
│   │   │   │   ├── list.go
│   │   │   │   ├── message.go
│   │   │   │   └── sidebar.go
│   │   │   ├── core/
│   │   │   │   └── status.go
│   │   │   ├── dialog/
│   │   │   │   ├── arguments.go
│   │   │   │   ├── commands.go
│   │   │   │   ├── complete.go
│   │   │   │   ├── custom_commands.go
│   │   │   │   ├── custom_commands_test.go
│   │   │   │   ├── filepicker.go
│   │   │   │   ├── help.go
│   │   │   │   ├── init.go
│   │   │   │   ├── models.go
│   │   │   │   ├── permission.go
│   │   │   │   ├── quit.go
│   │   │   │   ├── session.go
│   │   │   │   └── theme.go
│   │   │   ├── logs/
│   │   │   │   ├── details.go
│   │   │   │   └── table.go
│   │   │   └── util/
│   │   │       └── simple-list.go
│   │   ├── image/
│   │   │   └── images.go
│   │   ├── layout/
│   │   │   ├── container.go
│   │   │   ├── layout.go
│   │   │   ├── overlay.go
│   │   │   └── split.go
│   │   ├── page/
│   │   │   ├── chat.go
│   │   │   ├── logs.go
│   │   │   └── page.go
│   │   ├── styles/
│   │   │   ├── background.go
│   │   │   ├── icons.go
│   │   │   ├── markdown.go
│   │   │   └── styles.go
│   │   ├── theme/
│   │   │   ├── catppuccin.go
│   │   │   ├── dracula.go
│   │   │   ├── flexoki.go
│   │   │   ├── gruvbox.go
│   │   │   ├── manager.go
│   │   │   ├── monokai.go
│   │   │   ├── onedark.go
│   │   │   ├── opencode.go
│   │   │   ├── theme.go
│   │   │   ├── theme_test.go
│   │   │   ├── tokyonight.go
│   │   │   └── tron.go
│   │   ├── tui.go
│   │   └── util/
│   │       └── util.go
│   └── version/
│       └── version.go
├── main.go
├── opencode-schema.json
├── scripts/
│   ├── check_hidden_chars.sh
│   ├── release
│   └── snapshot
└── sqlc.yaml

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/build.yml
================================================
name: build

on:
  workflow_dispatch:
  push:
    branches:
      - main

concurrency: ${{ github.workflow }}-${{ github.ref }}

permissions:
  contents: write
  packages: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - run: git fetch --force --tags

      - uses: actions/setup-go@v5
        with:
          go-version: ">=1.23.2"
          cache: true
          cache-dependency-path: go.sum

      - run: go mod download

      - uses: goreleaser/goreleaser-action@v6
        with:
          distribution: goreleaser
          version: latest
          args: build --snapshot --clean


================================================
FILE: .github/workflows/release.yml
================================================
name: release

on:
  workflow_dispatch:
  push:
    tags:
      - "*"

concurrency: ${{ github.workflow }}-${{ github.ref }}

permissions:
  contents: write
  packages: write

jobs:
  goreleaser:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - run: git fetch --force --tags

      - uses: actions/setup-go@v5
        with:
          go-version: ">=1.23.2"
          cache: true
          cache-dependency-path: go.sum

      - run: go mod download

      - uses: goreleaser/goreleaser-action@v6
        with:
          distribution: goreleaser
          version: latest
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_TOKEN }}
          AUR_KEY: ${{ secrets.AUR_KEY }}


================================================
FILE: .gitignore
================================================
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work

# IDE specific files
.idea/
.vscode/
*.swp
*.swo

# OS specific files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
*.log

# Binary output directory
/bin/
/dist/

# Local environment variables
.env
.env.local

.opencode/

opencode
opencode.md


================================================
FILE: .goreleaser.yml
================================================
version: 2
project_name: opencode
before:
  hooks:
builds:
  - env:
      - CGO_ENABLED=0
    goos:
      - linux
      - darwin
    goarch:
      - amd64
      - arm64
    ldflags:
      - -s -w -X github.com/opencode-ai/opencode/internal/version.Version={{.Version}}
    main: ./main.go

archives:
  - format: tar.gz
    name_template: >-
      opencode-
      {{- if eq .Os "darwin" }}mac-
      {{- else if eq .Os "windows" }}windows-
      {{- else if eq .Os "linux" }}linux-{{end}}
      {{- if eq .Arch "amd64" }}x86_64
      {{- else if eq .Arch "#86" }}i386
      {{- else }}{{ .Arch }}{{ end }}
      {{- if .Arm }}v{{ .Arm }}{{ end }}
    format_overrides:
      - goos: windows
        format: zip
checksum:
  name_template: "checksums.txt"
snapshot:
  name_template: "0.0.0-{{ .Timestamp }}"
aurs:
  - name: opencode-ai
    homepage: "https://github.com/opencode-ai/opencode"
    description: "terminal based agent that can build anything"
    maintainers:
      - "kujtimiihoxha <kujtimii.h@gmail.com>"
    license: "MIT"
    private_key: "{{ .Env.AUR_KEY }}"
    git_url: "ssh://aur@aur.archlinux.org/opencode-ai-bin.git"
    provides:
      - opencode
    conflicts:
      - opencode
    package: |-
      install -Dm755 ./opencode "${pkgdir}/usr/bin/opencode"
brews:
  - repository:
      owner: opencode-ai
      name: homebrew-tap
nfpms:
  - maintainer: kujtimiihoxha
    description: terminal based agent that can build anything
    formats:
      - deb
      - rpm
    file_name_template: >-
      {{ .ProjectName }}-
      {{- if eq .Os "darwin" }}mac
      {{- else }}{{ .Os }}{{ end }}-{{ .Arch }}

changelog:
  sort: asc
  filters:
    exclude:
      - "^docs:"
      - "^doc:"
      - "^test:"
      - "^ci:"
      - "^ignore:"
      - "^example:"
      - "^wip:"


================================================
FILE: .opencode.json
================================================
{
  "$schema": "./opencode-schema.json",
  "lsp": {
    "gopls": {
      "command": "gopls"
    }
  }
}


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2025 Kujtim Hoxha

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Archived: Project has Moved

This repository is no longer maintained and has been archived for provenance.

The project has continued under the name [Crush][crush], developed by the original author and the Charm team.

Please follow [Crush][crush] for ongoing development.

[crush]: https://github.com/charmbracelet/crush


# ⌬ OpenCode

<p align="center"><img src="https://github.com/user-attachments/assets/9ae61ef6-70e5-4876-bc45-5bcb4e52c714" width="800"></p>

> **⚠️ Early Development Notice:** This project is in early development and is not yet ready for production use. Features may change, break, or be incomplete. Use at your own risk.

A powerful terminal-based AI assistant for developers, providing intelligent coding assistance directly in your terminal.

## Overview

OpenCode is a Go-based CLI application that brings AI assistance to your terminal. It provides a TUI (Terminal User Interface) for interacting with various AI models to help with coding tasks, debugging, and more.

<p>For a quick video overview, check out
<a href="https://www.youtube.com/watch?v=P8luPmEa1QI"><img width="25" src="https://upload.wikimedia.org/wikipedia/commons/0/09/YouTube_full-color_icon_%282017%29.svg"> OpenCode + Gemini 2.5 Pro: BYE Claude Code! I'm SWITCHING To the FASTEST AI Coder!</a></p>

<a href="https://www.youtube.com/watch?v=P8luPmEa1QI"><img width="550" src="https://i3.ytimg.com/vi/P8luPmEa1QI/maxresdefault.jpg"></a><p>

## Features

- **Interactive TUI**: Built with [Bubble Tea](https://github.com/charmbracelet/bubbletea) for a smooth terminal experience
- **Multiple AI Providers**: Support for OpenAI, Anthropic Claude, Google Gemini, AWS Bedrock, Groq, Azure OpenAI, and OpenRouter
- **Session Management**: Save and manage multiple conversation sessions
- **Tool Integration**: AI can execute commands, search files, and modify code
- **Vim-like Editor**: Integrated editor with text input capabilities
- **Persistent Storage**: SQLite database for storing conversations and sessions
- **LSP Integration**: Language Server Protocol support for code intelligence
- **File Change Tracking**: Track and visualize file changes during sessions
- **External Editor Support**: Open your preferred editor for composing messages
- **Named Arguments for Custom Commands**: Create powerful custom commands with multiple named placeholders

## Installation

### Using the Install Script

```bash
# Install the latest version
curl -fsSL https://raw.githubusercontent.com/opencode-ai/opencode/refs/heads/main/install | bash

# Install a specific version
curl -fsSL https://raw.githubusercontent.com/opencode-ai/opencode/refs/heads/main/install | VERSION=0.1.0 bash
```

### Using Homebrew (macOS and Linux)

```bash
brew install opencode-ai/tap/opencode
```

### Using AUR (Arch Linux)

```bash
# Using yay
yay -S opencode-ai-bin

# Using paru
paru -S opencode-ai-bin
```

### Using Go

```bash
go install github.com/opencode-ai/opencode@latest
```

## Configuration

OpenCode looks for configuration in the following locations:

- `$HOME/.opencode.json`
- `$XDG_CONFIG_HOME/opencode/.opencode.json`
- `./.opencode.json` (local directory)

### Auto Compact Feature

OpenCode includes an auto compact feature that automatically summarizes your conversation when it approaches the model's context window limit. When enabled (default setting), this feature:

- Monitors token usage during your conversation
- Automatically triggers summarization when usage reaches 95% of the model's context window
- Creates a new session with the summary, allowing you to continue your work without losing context
- Helps prevent "out of context" errors that can occur with long conversations

You can enable or disable this feature in your configuration file:

```json
{
  "autoCompact": true // default is true
}
```

### Environment Variables

You can configure OpenCode using environment variables:

| Environment Variable       | Purpose                                                                          |
| -------------------------- | -------------------------------------------------------------------------------- |
| `ANTHROPIC_API_KEY`        | For Claude models                                                                |
| `OPENAI_API_KEY`           | For OpenAI models                                                                |
| `GEMINI_API_KEY`           | For Google Gemini models                                                         |
| `GITHUB_TOKEN`             | For Github Copilot models (see [Using Github Copilot](#using-github-copilot))    |
| `VERTEXAI_PROJECT`         | For Google Cloud VertexAI (Gemini)                                               |
| `VERTEXAI_LOCATION`        | For Google Cloud VertexAI (Gemini)                                               |
| `GROQ_API_KEY`             | For Groq models                                                                  |
| `AWS_ACCESS_KEY_ID`        | For AWS Bedrock (Claude)                                                         |
| `AWS_SECRET_ACCESS_KEY`    | For AWS Bedrock (Claude)                                                         |
| `AWS_REGION`               | For AWS Bedrock (Claude)                                                         |
| `AZURE_OPENAI_ENDPOINT`    | For Azure OpenAI models                                                          |
| `AZURE_OPENAI_API_KEY`     | For Azure OpenAI models (optional when using Entra ID)                           |
| `AZURE_OPENAI_API_VERSION` | For Azure OpenAI models                                                          |
| `LOCAL_ENDPOINT`           | For self-hosted models                                                           |
| `SHELL`                    | Default shell to use (if not specified in config)                                |

### Shell Configuration

OpenCode allows you to configure the shell used by the bash tool. By default, it uses the shell specified in the `SHELL` environment variable, or falls back to `/bin/bash` if not set.

You can override this in your configuration file:

```json
{
  "shell": {
    "path": "/bin/zsh",
    "args": ["-l"]
  }
}
```

This is useful if you want to use a different shell than your default system shell, or if you need to pass specific arguments to the shell.

### Configuration File Structure

```json
{
  "data": {
    "directory": ".opencode"
  },
  "providers": {
    "openai": {
      "apiKey": "your-api-key",
      "disabled": false
    },
    "anthropic": {
      "apiKey": "your-api-key",
      "disabled": false
    },
    "copilot": {
      "disabled": false
    },
    "groq": {
      "apiKey": "your-api-key",
      "disabled": false
    },
    "openrouter": {
      "apiKey": "your-api-key",
      "disabled": false
    }
  },
  "agents": {
    "coder": {
      "model": "claude-3.7-sonnet",
      "maxTokens": 5000
    },
    "task": {
      "model": "claude-3.7-sonnet",
      "maxTokens": 5000
    },
    "title": {
      "model": "claude-3.7-sonnet",
      "maxTokens": 80
    }
  },
  "shell": {
    "path": "/bin/bash",
    "args": ["-l"]
  },
  "mcpServers": {
    "example": {
      "type": "stdio",
      "command": "path/to/mcp-server",
      "env": [],
      "args": []
    }
  },
  "lsp": {
    "go": {
      "disabled": false,
      "command": "gopls"
    }
  },
  "debug": false,
  "debugLSP": false,
  "autoCompact": true
}
```

## Supported AI Models

OpenCode supports a variety of AI models from different providers:

### OpenAI

- GPT-4.1 family (gpt-4.1, gpt-4.1-mini, gpt-4.1-nano)
- GPT-4.5 Preview
- GPT-4o family (gpt-4o, gpt-4o-mini)
- O1 family (o1, o1-pro, o1-mini)
- O3 family (o3, o3-mini)
- O4 Mini

### Anthropic

- Claude 4 Sonnet
- Claude 4 Opus
- Claude 3.5 Sonnet
- Claude 3.5 Haiku
- Claude 3.7 Sonnet
- Claude 3 Haiku
- Claude 3 Opus

### GitHub Copilot

- GPT-3.5 Turbo
- GPT-4
- GPT-4o
- GPT-4o Mini
- GPT-4.1
- Claude 3.5 Sonnet
- Claude 3.7 Sonnet
- Claude 3.7 Sonnet Thinking
- Claude Sonnet 4
- O1
- O3 Mini
- O4 Mini
- Gemini 2.0 Flash
- Gemini 2.5 Pro

### Google

- Gemini 2.5
- Gemini 2.5 Flash
- Gemini 2.0 Flash
- Gemini 2.0 Flash Lite

### AWS Bedrock

- Claude 3.7 Sonnet

### Groq

- Llama 4 Maverick (17b-128e-instruct)
- Llama 4 Scout (17b-16e-instruct)
- QWEN QWQ-32b
- Deepseek R1 distill Llama 70b
- Llama 3.3 70b Versatile

### Azure OpenAI

- GPT-4.1 family (gpt-4.1, gpt-4.1-mini, gpt-4.1-nano)
- GPT-4.5 Preview
- GPT-4o family (gpt-4o, gpt-4o-mini)
- O1 family (o1, o1-mini)
- O3 family (o3, o3-mini)
- O4 Mini

### Google Cloud VertexAI

- Gemini 2.5
- Gemini 2.5 Flash

## Usage

```bash
# Start OpenCode
opencode

# Start with debug logging
opencode -d

# Start with a specific working directory
opencode -c /path/to/project
```

## Non-interactive Prompt Mode

You can run OpenCode in non-interactive mode by passing a prompt directly as a command-line argument. This is useful for scripting, automation, or when you want a quick answer without launching the full TUI.

```bash
# Run a single prompt and print the AI's response to the terminal
opencode -p "Explain the use of context in Go"

# Get response in JSON format
opencode -p "Explain the use of context in Go" -f json

# Run without showing the spinner (useful for scripts)
opencode -p "Explain the use of context in Go" -q
```

In this mode, OpenCode will process your prompt, print the result to standard output, and then exit. All permissions are auto-approved for the session.

By default, a spinner animation is displayed while the model is processing your query. You can disable this spinner with the `-q` or `--quiet` flag, which is particularly useful when running OpenCode from scripts or automated workflows.

### Output Formats

OpenCode supports the following output formats in non-interactive mode:

| Format | Description                     |
| ------ | ------------------------------- |
| `text` | Plain text output (default)     |
| `json` | Output wrapped in a JSON object |

The output format is implemented as a strongly-typed `OutputFormat` in the codebase, ensuring type safety and validation when processing outputs.

## Command-line Flags

| Flag              | Short | Description                                         |
| ----------------- | ----- | --------------------------------------------------- |
| `--help`          | `-h`  | Display help information                            |
| `--debug`         | `-d`  | Enable debug mode                                   |
| `--cwd`           | `-c`  | Set current working directory                       |
| `--prompt`        | `-p`  | Run a single prompt in non-interactive mode         |
| `--output-format` | `-f`  | Output format for non-interactive mode (text, json) |
| `--quiet`         | `-q`  | Hide spinner in non-interactive mode                |

## Keyboard Shortcuts

### Global Shortcuts

| Shortcut | Action                                                  |
| -------- | ------------------------------------------------------- |
| `Ctrl+C` | Quit application                                        |
| `Ctrl+?` | Toggle help dialog                                      |
| `?`      | Toggle help dialog (when not in editing mode)           |
| `Ctrl+L` | View logs                                               |
| `Ctrl+A` | Switch session                                          |
| `Ctrl+K` | Command dialog                                          |
| `Ctrl+O` | Toggle model selection dialog                           |
| `Esc`    | Close current overlay/dialog or return to previous mode |

### Chat Page Shortcuts

| Shortcut | Action                                  |
| -------- | --------------------------------------- |
| `Ctrl+N` | Create new session                      |
| `Ctrl+X` | Cancel current operation/generation     |
| `i`      | Focus editor (when not in writing mode) |
| `Esc`    | Exit writing mode and focus messages    |

### Editor Shortcuts

| Shortcut            | Action                                    |
| ------------------- | ----------------------------------------- |
| `Ctrl+S`            | Send message (when editor is focused)     |
| `Enter` or `Ctrl+S` | Send message (when editor is not focused) |
| `Ctrl+E`            | Open external editor                      |
| `Esc`               | Blur editor and focus messages            |

### Session Dialog Shortcuts

| Shortcut   | Action           |
| ---------- | ---------------- |
| `↑` or `k` | Previous session |
| `↓` or `j` | Next session     |
| `Enter`    | Select session   |
| `Esc`      | Close dialog     |

### Model Dialog Shortcuts

| Shortcut   | Action            |
| ---------- | ----------------- |
| `↑` or `k` | Move up           |
| `↓` or `j` | Move down         |
| `←` or `h` | Previous provider |
| `→` or `l` | Next provider     |
| `Esc`      | Close dialog      |

### Permission Dialog Shortcuts

| Shortcut                | Action                       |
| ----------------------- | ---------------------------- |
| `←` or `left`           | Switch options left          |
| `→` or `right` or `tab` | Switch options right         |
| `Enter` or `space`      | Confirm selection            |
| `a`                     | Allow permission             |
| `A`                     | Allow permission for session |
| `d`                     | Deny permission              |

### Logs Page Shortcuts

| Shortcut           | Action              |
| ------------------ | ------------------- |
| `Backspace` or `q` | Return to chat page |

## AI Assistant Tools

OpenCode's AI assistant has access to various tools to help with coding tasks:

### File and Code Tools

| Tool          | Description                 | Parameters                                                                               |
| ------------- | --------------------------- | ---------------------------------------------------------------------------------------- |
| `glob`        | Find files by pattern       | `pattern` (required), `path` (optional)                                                  |
| `grep`        | Search file contents        | `pattern` (required), `path` (optional), `include` (optional), `literal_text` (optional) |
| `ls`          | List directory contents     | `path` (optional), `ignore` (optional array of patterns)                                 |
| `view`        | View file contents          | `file_path` (required), `offset` (optional), `limit` (optional)                          |
| `write`       | Write to files              | `file_path` (required), `content` (required)                                             |
| `edit`        | Edit files                  | Various parameters for file editing                                                      |
| `patch`       | Apply patches to files      | `file_path` (required), `diff` (required)                                                |
| `diagnostics` | Get diagnostics information | `file_path` (optional)                                                                   |

### Other Tools

| Tool          | Description                            | Parameters                                                                                |
| ------------- | -------------------------------------- | ----------------------------------------------------------------------------------------- |
| `bash`        | Execute shell commands                 | `command` (required), `timeout` (optional)                                                |
| `fetch`       | Fetch data from URLs                   | `url` (required), `format` (required), `timeout` (optional)                               |
| `sourcegraph` | Search code across public repositories | `query` (required), `count` (optional), `context_window` (optional), `timeout` (optional) |
| `agent`       | Run sub-tasks with the AI agent        | `prompt` (required)                                                                       |

## Architecture

OpenCode is built with a modular architecture:

- **cmd**: Command-line interface using Cobra
- **internal/app**: Core application services
- **internal/config**: Configuration management
- **internal/db**: Database operations and migrations
- **internal/llm**: LLM providers and tools integration
- **internal/tui**: Terminal UI components and layouts
- **internal/logging**: Logging infrastructure
- **internal/message**: Message handling
- **internal/session**: Session management
- **internal/lsp**: Language Server Protocol integration

## Custom Commands

OpenCode supports custom commands that can be created by users to quickly send predefined prompts to the AI assistant.

### Creating Custom Commands

Custom commands are predefined prompts stored as Markdown files in one of three locations:

1. **User Commands** (prefixed with `user:`):

   ```
   $XDG_CONFIG_HOME/opencode/commands/
   ```

   (typically `~/.config/opencode/commands/` on Linux/macOS)

   or

   ```
   $HOME/.opencode/commands/
   ```

2. **Project Commands** (prefixed with `project:`):

   ```
   <PROJECT DIR>/.opencode/commands/
   ```

Each `.md` file in these directories becomes a custom command. The file name (without extension) becomes the command ID.

For example, creating a file at `~/.config/opencode/commands/prime-context.md` with content:

```markdown
RUN git ls-files
READ README.md
```

This creates a command called `user:prime-context`.

### Command Arguments

OpenCode supports named arguments in custom commands using placeholders in the format `$NAME` (where NAME consists of uppercase letters, numbers, and underscores, and must start with a letter).

For example:

```markdown
# Fetch Context for Issue $ISSUE_NUMBER

RUN gh issue view $ISSUE_NUMBER --json title,body,comments
RUN git grep --author="$AUTHOR_NAME" -n .
RUN grep -R "$SEARCH_PATTERN" $DIRECTORY
```

When you run a command with arguments, OpenCode will prompt you to enter values for each unique placeholder. Named arguments provide several benefits:

- Clear identification of what each argument represents
- Ability to use the same argument multiple times
- Better organization for commands with multiple inputs

### Organizing Commands

You can organize commands in subdirectories:

```
~/.config/opencode/commands/git/commit.md
```

This creates a command with ID `user:git:commit`.

### Using Custom Commands

1. Press `Ctrl+K` to open the command dialog
2. Select your custom command (prefixed with either `user:` or `project:`)
3. Press Enter to execute the command

The content of the command file will be sent as a message to the AI assistant.

### Built-in Commands

OpenCode includes several built-in commands:

| Command            | Description                                                                                         |
| ------------------ | --------------------------------------------------------------------------------------------------- |
| Initialize Project | Creates or updates the OpenCode.md memory file with project-specific information                    |
| Compact Session    | Manually triggers the summarization of the current session, creating a new session with the summary |

## MCP (Model Context Protocol)

OpenCode implements the Model Context Protocol (MCP) to extend its capabilities through external tools. MCP provides a standardized way for the AI assistant to interact with external services and tools.

### MCP Features

- **External Tool Integration**: Connect to external tools and services via a standardized protocol
- **Tool Discovery**: Automatically discover available tools from MCP servers
- **Multiple Connection Types**:
  - **Stdio**: Communicate with tools via standard input/output
  - **SSE**: Communicate with tools via Server-Sent Events
- **Security**: Permission system for controlling access to MCP tools

### Configuring MCP Servers

MCP servers are defined in the configuration file under the `mcpServers` section:

```json
{
  "mcpServers": {
    "example": {
      "type": "stdio",
      "command": "path/to/mcp-server",
      "env": [],
      "args": []
    },
    "web-example": {
      "type": "sse",
      "url": "https://example.com/mcp",
      "headers": {
        "Authorization": "Bearer token"
      }
    }
  }
}
```

### MCP Tool Usage

Once configured, MCP tools are automatically available to the AI assistant alongside built-in tools. They follow the same permission model as other tools, requiring user approval before execution.

## LSP (Language Server Protocol)

OpenCode integrates with Language Server Protocol to provide code intelligence features across multiple programming languages.

### LSP Features

- **Multi-language Support**: Connect to language servers for different programming languages
- **Diagnostics**: Receive error checking and linting information
- **File Watching**: Automatically notify language servers of file changes

### Configuring LSP

Language servers are configured in the configuration file under the `lsp` section:

```json
{
  "lsp": {
    "go": {
      "disabled": false,
      "command": "gopls"
    },
    "typescript": {
      "disabled": false,
      "command": "typescript-language-server",
      "args": ["--stdio"]
    }
  }
}
```

### LSP Integration with AI

The AI assistant can access LSP features through the `diagnostics` tool, allowing it to:

- Check for errors in your code
- Suggest fixes based on diagnostics

While the LSP client implementation supports the full LSP protocol (including completions, hover, definition, etc.), currently only diagnostics are exposed to the AI assistant.

## Using Github Copilot

_Copilot support is currently experimental._

### Requirements
- [Copilot chat in the IDE](https://github.com/settings/copilot) enabled in GitHub settings
- One of:
  - VSCode Github Copilot chat extension
  - Github `gh` CLI
  - Neovim Github Copilot plugin (`copilot.vim` or `copilot.lua`)
  - Github token with copilot permissions

If using one of the above plugins or cli tools, make sure you use the authenticate
the tool with your github account. This should create a github token at one of the following locations:
- ~/.config/github-copilot/[hosts,apps].json
- $XDG_CONFIG_HOME/github-copilot/[hosts,apps].json

If using an explicit github token, you may either set the $GITHUB_TOKEN environment variable or add it to the opencode.json config file at `providers.copilot.apiKey`.

## Using a self-hosted model provider

OpenCode can also load and use models from a self-hosted (OpenAI-like) provider.
This is useful for developers who want to experiment with custom models.

### Configuring a self-hosted provider

You can use a self-hosted model by setting the `LOCAL_ENDPOINT` environment variable.
This will cause OpenCode to load and use the models from the specified endpoint.

```bash
LOCAL_ENDPOINT=http://localhost:1235/v1
```

### Configuring a self-hosted model

You can also configure a self-hosted model in the configuration file under the `agents` section:

```json
{
  "agents": {
    "coder": {
      "model": "local.granite-3.3-2b-instruct@q8_0",
      "reasoningEffort": "high"
    }
  }
}
```

## Development

### Prerequisites

- Go 1.24.0 or higher

### Building from Source

```bash
# Clone the repository
git clone https://github.com/opencode-ai/opencode.git
cd opencode

# Build
go build -o opencode

# Run
./opencode
```

## Acknowledgments

OpenCode gratefully acknowledges the contributions and support from these key individuals:

- [@isaacphi](https://github.com/isaacphi) - For the [mcp-language-server](https://github.com/isaacphi/mcp-language-server) project which provided the foundation for our LSP client implementation
- [@adamdottv](https://github.com/adamdottv) - For the design direction and UI/UX architecture

Special thanks to the broader open source community whose tools and libraries have made this project possible.

## License

OpenCode is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

## Contributing

Contributions are welcome! Here's how you can contribute:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

Please make sure to update tests as appropriate and follow the existing code style.


================================================
FILE: cmd/root.go
================================================
package cmd

import (
	"context"
	"fmt"
	"os"
	"sync"
	"time"

	tea "github.com/charmbracelet/bubbletea"
	zone "github.com/lrstanley/bubblezone"
	"github.com/opencode-ai/opencode/internal/app"
	"github.com/opencode-ai/opencode/internal/config"
	"github.com/opencode-ai/opencode/internal/db"
	"github.com/opencode-ai/opencode/internal/format"
	"github.com/opencode-ai/opencode/internal/llm/agent"
	"github.com/opencode-ai/opencode/internal/logging"
	"github.com/opencode-ai/opencode/internal/pubsub"
	"github.com/opencode-ai/opencode/internal/tui"
	"github.com/opencode-ai/opencode/internal/version"
	"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
	Use:   "opencode",
	Short: "Terminal-based AI assistant for software development",
	Long: `OpenCode is a powerful terminal-based AI assistant that helps with software development tasks.
It provides an interactive chat interface with AI capabilities, code analysis, and LSP integration
to assist developers in writing, debugging, and understanding code directly from the terminal.`,
	Example: `
  # Run in interactive mode
  opencode

  # Run with debug logging
  opencode -d

  # Run with debug logging in a specific directory
  opencode -d -c /path/to/project

  # Print version
  opencode -v

  # Run a single non-interactive prompt
  opencode -p "Explain the use of context in Go"

  # Run a single non-interactive prompt with JSON output format
  opencode -p "Explain the use of context in Go" -f json
  `,
	RunE: func(cmd *cobra.Command, args []string) error {
		// If the help flag is set, show the help message
		if cmd.Flag("help").Changed {
			cmd.Help()
			return nil
		}
		if cmd.Flag("version").Changed {
			fmt.Println(version.Version)
			return nil
		}

		// Load the config
		debug, _ := cmd.Flags().GetBool("debug")
		cwd, _ := cmd.Flags().GetString("cwd")
		prompt, _ := cmd.Flags().GetString("prompt")
		outputFormat, _ := cmd.Flags().GetString("output-format")
		quiet, _ := cmd.Flags().GetBool("quiet")

		// Validate format option
		if !format.IsValid(outputFormat) {
			return fmt.Errorf("invalid format option: %s\n%s", outputFormat, format.GetHelpText())
		}

		if cwd != "" {
			err := os.Chdir(cwd)
			if err != nil {
				return fmt.Errorf("failed to change directory: %v", err)
			}
		}
		if cwd == "" {
			c, err := os.Getwd()
			if err != nil {
				return fmt.Errorf("failed to get current working directory: %v", err)
			}
			cwd = c
		}
		_, err := config.Load(cwd, debug)
		if err != nil {
			return err
		}

		// Connect DB, this will also run migrations
		conn, err := db.Connect()
		if err != nil {
			return err
		}

		// Create main context for the application
		ctx, cancel := context.WithCancel(context.Background())
		defer cancel()

		app, err := app.New(ctx, conn)
		if err != nil {
			logging.Error("Failed to create app: %v", err)
			return err
		}
		// Defer shutdown here so it runs for both interactive and non-interactive modes
		defer app.Shutdown()

		// Initialize MCP tools early for both modes
		initMCPTools(ctx, app)

		// Non-interactive mode
		if prompt != "" {
			// Run non-interactive flow using the App method
			return app.RunNonInteractive(ctx, prompt, outputFormat, quiet)
		}

		// Interactive mode
		// Set up the TUI
		zone.NewGlobal()
		program := tea.NewProgram(
			tui.New(app),
			tea.WithAltScreen(),
		)

		// Setup the subscriptions, this will send services events to the TUI
		ch, cancelSubs := setupSubscriptions(app, ctx)

		// Create a context for the TUI message handler
		tuiCtx, tuiCancel := context.WithCancel(ctx)
		var tuiWg sync.WaitGroup
		tuiWg.Add(1)

		// Set up message handling for the TUI
		go func() {
			defer tuiWg.Done()
			defer logging.RecoverPanic("TUI-message-handler", func() {
				attemptTUIRecovery(program)
			})

			for {
				select {
				case <-tuiCtx.Done():
					logging.Info("TUI message handler shutting down")
					return
				case msg, ok := <-ch:
					if !ok {
						logging.Info("TUI message channel closed")
						return
					}
					program.Send(msg)
				}
			}
		}()

		// Cleanup function for when the program exits
		cleanup := func() {
			// Shutdown the app
			app.Shutdown()

			// Cancel subscriptions first
			cancelSubs()

			// Then cancel TUI message handler
			tuiCancel()

			// Wait for TUI message handler to finish
			tuiWg.Wait()

			logging.Info("All goroutines cleaned up")
		}

		// Run the TUI
		result, err := program.Run()
		cleanup()

		if err != nil {
			logging.Error("TUI error: %v", err)
			return fmt.Errorf("TUI error: %v", err)
		}

		logging.Info("TUI exited with result: %v", result)
		return nil
	},
}

// attemptTUIRecovery tries to recover the TUI after a panic
func attemptTUIRecovery(program *tea.Program) {
	logging.Info("Attempting to recover TUI after panic")

	// We could try to restart the TUI or gracefully exit
	// For now, we'll just quit the program to avoid further issues
	program.Quit()
}

func initMCPTools(ctx context.Context, app *app.App) {
	go func() {
		defer logging.RecoverPanic("MCP-goroutine", nil)

		// Create a context with timeout for the initial MCP tools fetch
		ctxWithTimeout, cancel := context.WithTimeout(ctx, 30*time.Second)
		defer cancel()

		// Set this up once with proper error handling
		agent.GetMcpTools(ctxWithTimeout, app.Permissions)
		logging.Info("MCP message handling goroutine exiting")
	}()
}

func setupSubscriber[T any](
	ctx context.Context,
	wg *sync.WaitGroup,
	name string,
	subscriber func(context.Context) <-chan pubsub.Event[T],
	outputCh chan<- tea.Msg,
) {
	wg.Add(1)
	go func() {
		defer wg.Done()
		defer logging.RecoverPanic(fmt.Sprintf("subscription-%s", name), nil)

		subCh := subscriber(ctx)

		for {
			select {
			case event, ok := <-subCh:
				if !ok {
					logging.Info("subscription channel closed", "name", name)
					return
				}

				var msg tea.Msg = event

				select {
				case outputCh <- msg:
				case <-time.After(2 * time.Second):
					logging.Warn("message dropped due to slow consumer", "name", name)
				case <-ctx.Done():
					logging.Info("subscription cancelled", "name", name)
					return
				}
			case <-ctx.Done():
				logging.Info("subscription cancelled", "name", name)
				return
			}
		}
	}()
}

func setupSubscriptions(app *app.App, parentCtx context.Context) (chan tea.Msg, func()) {
	ch := make(chan tea.Msg, 100)

	wg := sync.WaitGroup{}
	ctx, cancel := context.WithCancel(parentCtx) // Inherit from parent context

	setupSubscriber(ctx, &wg, "logging", logging.Subscribe, ch)
	setupSubscriber(ctx, &wg, "sessions", app.Sessions.Subscribe, ch)
	setupSubscriber(ctx, &wg, "messages", app.Messages.Subscribe, ch)
	setupSubscriber(ctx, &wg, "permissions", app.Permissions.Subscribe, ch)
	setupSubscriber(ctx, &wg, "coderAgent", app.CoderAgent.Subscribe, ch)

	cleanupFunc := func() {
		logging.Info("Cancelling all subscriptions")
		cancel() // Signal all goroutines to stop

		waitCh := make(chan struct{})
		go func() {
			defer logging.RecoverPanic("subscription-cleanup", nil)
			wg.Wait()
			close(waitCh)
		}()

		select {
		case <-waitCh:
			logging.Info("All subscription goroutines completed successfully")
			close(ch) // Only close after all writers are confirmed done
		case <-time.After(5 * time.Second):
			logging.Warn("Timed out waiting for some subscription goroutines to complete")
			close(ch)
		}
	}
	return ch, cleanupFunc
}

func Execute() {
	err := rootCmd.Execute()
	if err != nil {
		os.Exit(1)
	}
}

func init() {
	rootCmd.Flags().BoolP("help", "h", false, "Help")
	rootCmd.Flags().BoolP("version", "v", false, "Version")
	rootCmd.Flags().BoolP("debug", "d", false, "Debug")
	rootCmd.Flags().StringP("cwd", "c", "", "Current working directory")
	rootCmd.Flags().StringP("prompt", "p", "", "Prompt to run in non-interactive mode")

	// Add format flag with validation logic
	rootCmd.Flags().StringP("output-format", "f", format.Text.String(),
		"Output format for non-interactive mode (text, json)")

	// Add quiet flag to hide spinner in non-interactive mode
	rootCmd.Flags().BoolP("quiet", "q", false, "Hide spinner in non-interactive mode")

	// Register custom validation for the format flag
	rootCmd.RegisterFlagCompletionFunc("output-format", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return format.SupportedFormats, cobra.ShellCompDirectiveNoFileComp
	})
}


================================================
FILE: cmd/schema/README.md
================================================
# OpenCode Configuration Schema Generator

This tool generates a JSON Schema for the OpenCode configuration file. The schema can be used to validate configuration files and provide autocompletion in editors that support JSON Schema.

## Usage

```bash
go run cmd/schema/main.go > opencode-schema.json
```

This will generate a JSON Schema file that can be used to validate configuration files.

## Schema Features

The generated schema includes:

- All configuration options with descriptions
- Default values where applicable
- Validation for enum values (e.g., model IDs, provider types)
- Required fields
- Type checking

## Using the Schema

You can use the generated schema in several ways:

1. **Editor Integration**: Many editors (VS Code, JetBrains IDEs, etc.) support JSON Schema for validation and autocompletion. You can configure your editor to use the generated schema for `.opencode.json` files.

2. **Validation Tools**: You can use tools like [jsonschema](https://github.com/Julian/jsonschema) to validate your configuration files against the schema.

3. **Documentation**: The schema serves as documentation for the configuration options.

## Example Configuration

Here's an example configuration that conforms to the schema:

```json
{
  "data": {
    "directory": ".opencode"
  },
  "debug": false,
  "providers": {
    "anthropic": {
      "apiKey": "your-api-key"
    }
  },
  "agents": {
    "coder": {
      "model": "claude-3.7-sonnet",
      "maxTokens": 5000,
      "reasoningEffort": "medium"
    },
    "task": {
      "model": "claude-3.7-sonnet",
      "maxTokens": 5000
    },
    "title": {
      "model": "claude-3.7-sonnet",
      "maxTokens": 80
    }
  }
}
```


================================================
FILE: cmd/schema/main.go
================================================
package main

import (
	"encoding/json"
	"fmt"
	"os"

	"github.com/opencode-ai/opencode/internal/config"
	"github.com/opencode-ai/opencode/internal/llm/models"
)

// JSONSchemaType represents a JSON Schema type
type JSONSchemaType struct {
	Type                 string           `json:"type,omitempty"`
	Description          string           `json:"description,omitempty"`
	Properties           map[string]any   `json:"properties,omitempty"`
	Required             []string         `json:"required,omitempty"`
	AdditionalProperties any              `json:"additionalProperties,omitempty"`
	Enum                 []any            `json:"enum,omitempty"`
	Items                map[string]any   `json:"items,omitempty"`
	OneOf                []map[string]any `json:"oneOf,omitempty"`
	AnyOf                []map[string]any `json:"anyOf,omitempty"`
	Default              any              `json:"default,omitempty"`
}

func main() {
	schema := generateSchema()

	// Pretty print the schema
	encoder := json.NewEncoder(os.Stdout)
	encoder.SetIndent("", "  ")
	if err := encoder.Encode(schema); err != nil {
		fmt.Fprintf(os.Stderr, "Error encoding schema: %v\n", err)
		os.Exit(1)
	}
}

func generateSchema() map[string]any {
	schema := map[string]any{
		"$schema":     "http://json-schema.org/draft-07/schema#",
		"title":       "OpenCode Configuration",
		"description": "Configuration schema for the OpenCode application",
		"type":        "object",
		"properties":  map[string]any{},
	}

	// Add Data configuration
	schema["properties"].(map[string]any)["data"] = map[string]any{
		"type":        "object",
		"description": "Storage configuration",
		"properties": map[string]any{
			"directory": map[string]any{
				"type":        "string",
				"description": "Directory where application data is stored",
				"default":     ".opencode",
			},
		},
		"required": []string{"directory"},
	}

	// Add working directory
	schema["properties"].(map[string]any)["wd"] = map[string]any{
		"type":        "string",
		"description": "Working directory for the application",
	}

	// Add debug flags
	schema["properties"].(map[string]any)["debug"] = map[string]any{
		"type":        "boolean",
		"description": "Enable debug mode",
		"default":     false,
	}

	schema["properties"].(map[string]any)["debugLSP"] = map[string]any{
		"type":        "boolean",
		"description": "Enable LSP debug mode",
		"default":     false,
	}

	schema["properties"].(map[string]any)["contextPaths"] = map[string]any{
		"type":        "array",
		"description": "Context paths for the application",
		"items": map[string]any{
			"type": "string",
		},
		"default": []string{
			".github/copilot-instructions.md",
			".cursorrules",
			".cursor/rules/",
			"CLAUDE.md",
			"CLAUDE.local.md",
			"opencode.md",
			"opencode.local.md",
			"OpenCode.md",
			"OpenCode.local.md",
			"OPENCODE.md",
			"OPENCODE.local.md",
		},
	}

	schema["properties"].(map[string]any)["tui"] = map[string]any{
		"type":        "object",
		"description": "Terminal User Interface configuration",
		"properties": map[string]any{
			"theme": map[string]any{
				"type":        "string",
				"description": "TUI theme name",
				"default":     "opencode",
				"enum": []string{
					"opencode",
					"catppuccin",
					"dracula",
					"flexoki",
					"gruvbox",
					"monokai",
					"onedark",
					"tokyonight",
					"tron",
				},
			},
		},
	}

	// Add MCP servers
	schema["properties"].(map[string]any)["mcpServers"] = map[string]any{
		"type":        "object",
		"description": "Model Control Protocol server configurations",
		"additionalProperties": map[string]any{
			"type":        "object",
			"description": "MCP server configuration",
			"properties": map[string]any{
				"command": map[string]any{
					"type":        "string",
					"description": "Command to execute for the MCP server",
				},
				"env": map[string]any{
					"type":        "array",
					"description": "Environment variables for the MCP server",
					"items": map[string]any{
						"type": "string",
					},
				},
				"args": map[string]any{
					"type":        "array",
					"description": "Command arguments for the MCP server",
					"items": map[string]any{
						"type": "string",
					},
				},
				"type": map[string]any{
					"type":        "string",
					"description": "Type of MCP server",
					"enum":        []string{"stdio", "sse"},
					"default":     "stdio",
				},
				"url": map[string]any{
					"type":        "string",
					"description": "URL for SSE type MCP servers",
				},
				"headers": map[string]any{
					"type":        "object",
					"description": "HTTP headers for SSE type MCP servers",
					"additionalProperties": map[string]any{
						"type": "string",
					},
				},
			},
			"required": []string{"command"},
		},
	}

	// Add providers
	providerSchema := map[string]any{
		"type":        "object",
		"description": "LLM provider configurations",
		"additionalProperties": map[string]any{
			"type":        "object",
			"description": "Provider configuration",
			"properties": map[string]any{
				"apiKey": map[string]any{
					"type":        "string",
					"description": "API key for the provider",
				},
				"disabled": map[string]any{
					"type":        "boolean",
					"description": "Whether the provider is disabled",
					"default":     false,
				},
			},
		},
	}

	// Add known providers
	knownProviders := []string{
		string(models.ProviderAnthropic),
		string(models.ProviderOpenAI),
		string(models.ProviderGemini),
		string(models.ProviderGROQ),
		string(models.ProviderOpenRouter),
		string(models.ProviderBedrock),
		string(models.ProviderAzure),
		string(models.ProviderVertexAI),
	}

	providerSchema["additionalProperties"].(map[string]any)["properties"].(map[string]any)["provider"] = map[string]any{
		"type":        "string",
		"description": "Provider type",
		"enum":        knownProviders,
	}

	schema["properties"].(map[string]any)["providers"] = providerSchema

	// Add agents
	agentSchema := map[string]any{
		"type":        "object",
		"description": "Agent configurations",
		"additionalProperties": map[string]any{
			"type":        "object",
			"description": "Agent configuration",
			"properties": map[string]any{
				"model": map[string]any{
					"type":        "string",
					"description": "Model ID for the agent",
				},
				"maxTokens": map[string]any{
					"type":        "integer",
					"description": "Maximum tokens for the agent",
					"minimum":     1,
				},
				"reasoningEffort": map[string]any{
					"type":        "string",
					"description": "Reasoning effort for models that support it (OpenAI, Anthropic)",
					"enum":        []string{"low", "medium", "high"},
				},
			},
			"required": []string{"model"},
		},
	}

	// Add model enum
	modelEnum := []string{}
	for modelID := range models.SupportedModels {
		modelEnum = append(modelEnum, string(modelID))
	}
	agentSchema["additionalProperties"].(map[string]any)["properties"].(map[string]any)["model"].(map[string]any)["enum"] = modelEnum

	// Add specific agent properties
	agentProperties := map[string]any{}
	knownAgents := []string{
		string(config.AgentCoder),
		string(config.AgentTask),
		string(config.AgentTitle),
	}

	for _, agentName := range knownAgents {
		agentProperties[agentName] = map[string]any{
			"$ref": "#/definitions/agent",
		}
	}

	// Create a combined schema that allows both specific agents and additional ones
	combinedAgentSchema := map[string]any{
		"type":                 "object",
		"description":          "Agent configurations",
		"properties":           agentProperties,
		"additionalProperties": agentSchema["additionalProperties"],
	}

	schema["properties"].(map[string]any)["agents"] = combinedAgentSchema
	schema["definitions"] = map[string]any{
		"agent": agentSchema["additionalProperties"],
	}

	// Add LSP configuration
	schema["properties"].(map[string]any)["lsp"] = map[string]any{
		"type":        "object",
		"description": "Language Server Protocol configurations",
		"additionalProperties": map[string]any{
			"type":        "object",
			"description": "LSP configuration for a language",
			"properties": map[string]any{
				"disabled": map[string]any{
					"type":        "boolean",
					"description": "Whether the LSP is disabled",
					"default":     false,
				},
				"command": map[string]any{
					"type":        "string",
					"description": "Command to execute for the LSP server",
				},
				"args": map[string]any{
					"type":        "array",
					"description": "Command arguments for the LSP server",
					"items": map[string]any{
						"type": "string",
					},
				},
				"options": map[string]any{
					"type":        "object",
					"description": "Additional options for the LSP server",
				},
			},
			"required": []string{"command"},
		},
	}

	return schema
}


================================================
FILE: go.mod
================================================
module github.com/opencode-ai/opencode

go 1.24.0

require (
	github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0
	github.com/JohannesKaufmann/html-to-markdown v1.6.0
	github.com/PuerkitoBio/goquery v1.9.2
	github.com/alecthomas/chroma/v2 v2.15.0
	github.com/anthropics/anthropic-sdk-go v1.4.0
	github.com/aymanbagabas/go-udiff v0.2.0
	github.com/bmatcuk/doublestar/v4 v4.8.1
	github.com/catppuccin/go v0.3.0
	github.com/charmbracelet/bubbles v0.21.0
	github.com/charmbracelet/bubbletea v1.3.5
	github.com/charmbracelet/glamour v0.9.1
	github.com/charmbracelet/lipgloss v1.1.0
	github.com/charmbracelet/x/ansi v0.8.0
	github.com/fsnotify/fsnotify v1.8.0
	github.com/go-logfmt/logfmt v0.6.0
	github.com/google/uuid v1.6.0
	github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231
	github.com/mark3labs/mcp-go v0.17.0
	github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6
	github.com/muesli/reflow v0.3.0
	github.com/muesli/termenv v0.16.0
	github.com/ncruces/go-sqlite3 v0.25.0
	github.com/openai/openai-go v0.1.0-beta.2
	github.com/pressly/goose/v3 v3.24.2
	github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3
	github.com/spf13/cobra v1.9.1
	github.com/spf13/viper v1.20.0
	github.com/stretchr/testify v1.10.0
)

require (
	cloud.google.com/go v0.116.0 // indirect
	cloud.google.com/go/auth v0.13.0 // indirect
	cloud.google.com/go/compute/metadata v0.6.0 // indirect
	github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect
	github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
	github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
	github.com/andybalholm/cascadia v1.3.2 // indirect
	github.com/atotto/clipboard v0.1.4 // indirect
	github.com/aws/aws-sdk-go-v2 v1.30.3 // indirect
	github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 // indirect
	github.com/aws/aws-sdk-go-v2/config v1.27.27 // indirect
	github.com/aws/aws-sdk-go-v2/credentials v1.17.27 // indirect
	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 // indirect
	github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 // indirect
	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 // indirect
	github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect
	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 // indirect
	github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 // indirect
	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect
	github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 // indirect
	github.com/aws/smithy-go v1.20.3 // indirect
	github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
	github.com/aymerick/douceur v0.2.0 // indirect
	github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
	github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
	github.com/charmbracelet/x/term v0.2.1 // indirect
	github.com/davecgh/go-spew v1.1.1 // indirect
	github.com/disintegration/imaging v1.6.2
	github.com/dlclark/regexp2 v1.11.4 // indirect
	github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
	github.com/felixge/httpsnoop v1.0.4 // indirect
	github.com/go-logr/logr v1.4.2 // indirect
	github.com/go-logr/stdr v1.2.2 // indirect
	github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
	github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
	github.com/google/go-cmp v0.7.0 // indirect
	github.com/google/s2a-go v0.1.8 // indirect
	github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
	github.com/googleapis/gax-go/v2 v2.14.1 // indirect
	github.com/gorilla/css v1.0.1 // indirect
	github.com/gorilla/websocket v1.5.3 // indirect
	github.com/inconshreveable/mousetrap v1.1.0 // indirect
	github.com/kylelemons/godebug v1.1.0 // indirect
	github.com/lithammer/fuzzysearch v1.1.8
	github.com/lucasb-eyer/go-colorful v1.2.0
	github.com/mattn/go-isatty v0.0.20 // indirect
	github.com/mattn/go-localereader v0.0.1 // indirect
	github.com/mattn/go-runewidth v0.0.16 // indirect
	github.com/mfridman/interpolate v0.0.2 // indirect
	github.com/microcosm-cc/bluemonday v1.0.27 // indirect
	github.com/muesli/cancelreader v0.2.2 // indirect
	github.com/ncruces/julianday v1.0.0 // indirect
	github.com/pelletier/go-toml/v2 v2.2.3 // indirect
	github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
	github.com/pmezard/go-difflib v1.0.0 // indirect
	github.com/rivo/uniseg v0.4.7 // indirect
	github.com/rogpeppe/go-internal v1.14.1 // indirect
	github.com/sagikazarmark/locafero v0.7.0 // indirect
	github.com/sethvargo/go-retry v0.3.0 // indirect
	github.com/sourcegraph/conc v0.3.0 // indirect
	github.com/spf13/afero v1.12.0 // indirect
	github.com/spf13/cast v1.7.1 // indirect
	github.com/spf13/pflag v1.0.6 // indirect
	github.com/subosito/gotenv v1.6.0 // indirect
	github.com/tetratelabs/wazero v1.9.0 // indirect
	github.com/tidwall/gjson v1.18.0 // indirect
	github.com/tidwall/match v1.1.1 // indirect
	github.com/tidwall/pretty v1.2.1 // indirect
	github.com/tidwall/sjson v1.2.5 // indirect
	github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
	github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
	github.com/yuin/goldmark v1.7.8 // indirect
	github.com/yuin/goldmark-emoji v1.0.5 // indirect
	go.opentelemetry.io/auto/sdk v1.1.0 // indirect
	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
	go.opentelemetry.io/otel v1.35.0 // indirect
	go.opentelemetry.io/otel/metric v1.35.0 // indirect
	go.opentelemetry.io/otel/trace v1.35.0 // indirect
	go.uber.org/multierr v1.11.0 // indirect
	golang.org/x/crypto v0.37.0 // indirect
	golang.org/x/image v0.26.0 // indirect
	golang.org/x/net v0.39.0 // indirect
	golang.org/x/sync v0.13.0 // indirect
	golang.org/x/sys v0.32.0 // indirect
	golang.org/x/term v0.31.0 // indirect
	golang.org/x/text v0.24.0 // indirect
	google.golang.org/genai v1.3.0
	google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect
	google.golang.org/grpc v1.71.0 // indirect
	google.golang.org/protobuf v1.36.6 // indirect
	gopkg.in/yaml.v3 v3.0.1 // indirect
)


================================================
FILE: go.sum
================================================
cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE=
cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U=
cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs=
cloud.google.com/go/auth v0.13.0/go.mod h1:COOjD9gwfKNKz+IIduatIhYJQIc0mG3H102r/EMxX6Q=
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/JohannesKaufmann/html-to-markdown v1.6.0 h1:04VXMiE50YYfCfLboJCLcgqF5x+rHJnb1ssNmqpLH/k=
github.com/JohannesKaufmann/html-to-markdown v1.6.0/go.mod h1:NUI78lGg/a7vpEJTz/0uOcYMaibytE4BUOQS8k78yPQ=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/PuerkitoBio/goquery v1.9.2 h1:4/wZksC3KgkQw7SQgkKotmKljk0M6V8TUvA8Wb4yPeE=
github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk=
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/chroma/v2 v2.15.0 h1:LxXTQHFoYrstG2nnV9y2X5O94sOBzf0CIUpSTbpxvMc=
github.com/alecthomas/chroma/v2 v2.15.0/go.mod h1:gUhVLrPDXPtp/f+L1jo9xepo9gL4eLwRuGAunSZMkio=
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/anthropics/anthropic-sdk-go v1.4.0 h1:fU1jKxYbQdQDiEXCxeW5XZRIOwKevn/PMg8Ay1nnUx0=
github.com/anthropics/anthropic-sdk-go v1.4.0/go.mod h1:AapDW22irxK2PSumZiQXYUFvsdQgkwIWlpESweWZI/c=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY=
github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 h1:tW1/Rkad38LA15X4UQtjXZXNKsCgkshC3EbmcUmghTg=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3/go.mod h1:UbnqO+zjqk3uIt9yCACHJ9IVNhyhOCnYk8yA19SAWrM=
github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90=
github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg=
github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI=
github.com/aws/aws-sdk-go-v2/credentials v1.17.27/go.mod h1:gniiwbGahQByxan6YjQUMcW4Aov6bLC3m+evgcoN4r4=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk/UqI9iwMrOx/87PBNIKqw=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 h1:SoNJ4RlFEQEbtDcCEt+QG56MY4fm4W8rYirAmq+/DdU=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15/go.mod h1:U9ke74k1n2bf+RIgoX1SXFed1HLs51OgUSs+Ph0KJP8=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 h1:C6WHdGnTDIYETAm5iErQUiVNsclNx9qbJVPIt03B6bI=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15/go.mod h1:ZQLZqhcu+JhSrA9/NXRm8SkDvsycE+JkV3WGY41e+IM=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII=
github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM=
github.com/aws/aws-sdk-go-v2/service/sso v1.22.4/go.mod h1:ooyCOXjvJEsUw7x+ZDHeISPMhtwI3ZCB7ggFMcFfWLU=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 h1:yiwVzJW2ZxZTurVbYWA7QOrAaCYQR72t0wrSBfoesUE=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5hB7H69YUpFiI1tql6Q6Ne+1bCw=
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE=
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ=
github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE=
github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38=
github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY=
github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
github.com/charmbracelet/bubbletea v1.3.5 h1:JAMNLTbqMOhSwoELIr0qyP4VidFq72/6E9j7HHmRKQc=
github.com/charmbracelet/bubbletea v1.3.5/go.mod h1:TkCnmH+aBd4LrXhXcqrKiYwRs7qyQx5rBgH5fVY3v54=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
github.com/charmbracelet/glamour v0.9.1 h1:11dEfiGP8q1BEqvGoIjivuc2rBk+5qEXdPtaQ2WoiCM=
github.com/charmbracelet/glamour v0.9.1/go.mod h1:+SHvIS8qnwhgTpVMiXwn7OfGomSqff1cHBCI8jLOetk=
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM=
github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw=
github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA=
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231 h1:9rjt7AfnrXKNSZhp36A3/4QAZAwGGCGD/p8Bse26zms=
github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231/go.mod h1:S5etECMx+sZnW0Gm100Ma9J1PgVCTgNyFaqGu2b08b4=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mark3labs/mcp-go v0.17.0 h1:5Ps6T7qXr7De/2QTqs9h6BKeZ/qdeUeGrgM5lPzi930=
github.com/mark3labs/mcp-go v0.17.0/go.mod h1:KmJndYv7GIgcPVwEKJjNcbhVQ+hJGJhrCCB/9xITzpE=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY=
github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg=
github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/ncruces/go-sqlite3 v0.25.0 h1:trugKUs98Zwy9KwRr/EUxZHL92LYt7UqcKqAfpGpK+I=
github.com/ncruces/go-sqlite3 v0.25.0/go.mod h1:n6Z7036yFilJx04yV0mi5JWaF66rUmXn1It9Ux8dx68=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g=
github.com/openai/openai-go v0.1.0-beta.2 h1:Ra5nCFkbEl9w+UJwAciC4kqnIBUCcJazhmMA0/YN894=
github.com/openai/openai-go v0.1.0-beta.2/go.mod h1:g461MYGXEXBVdV5SaR/5tNzNbSfwTBBefwc+LlDCK0Y=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pressly/goose/v3 v3.24.2 h1:c/ie0Gm8rnIVKvnDQ/scHErv46jrDv9b4I0WRcFJzYU=
github.com/pressly/goose/v3 v3.24.2/go.mod h1:kjefwFB0eR4w30Td2Gj2Mznyw94vSP+2jJYkOVNbD1k=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y=
github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE=
github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.20.0 h1:zrxIyR3RQIOsarIrgL8+sAvALXul9jeEPa06Y0Ph6vY=
github.com/spf13/viper v1.20.0/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
github.com/yuin/goldmark-emoji v1.0.5 h1:EMVWyCGPlXJfUXBXpuMu+ii3TIaxbVBnEX9uaDC4cIk=
github.com/yuin/goldmark-emoji v1.0.5/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.26.0 h1:4XjIFEZWQmCZi6Wv8BoxsDhRU3RVnLX04dToTDAEPlY=
golang.org/x/image v0.26.0/go.mod h1:lcxbMFAovzpnJxzXS3nyL83K27tmqtKzIJpctK8YO5c=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genai v1.3.0 h1:tXhPJF30skOjnnDY7ZnjK3q7IKy4PuAlEA0fk7uEaEI=
google.golang.org/genai v1.3.0/go.mod h1:TyfOKRz/QyCaj6f/ZDt505x+YreXnY40l2I6k8TvgqY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/libc v1.61.13 h1:3LRd6ZO1ezsFiX1y+bHd1ipyEHIJKvuprv0sLTBwLW8=
modernc.org/libc v1.61.13/go.mod h1:8F/uJWL/3nNil0Lgt1Dpz+GgkApWh04N3el3hxJcA6E=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.9.1 h1:V/Z1solwAVmMW1yttq3nDdZPJqV1rM05Ccq6KMSZ34g=
modernc.org/memory v1.9.1/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/sqlite v1.36.2 h1:vjcSazuoFve9Wm0IVNHgmJECoOXLZM1KfMXbcX2axHA=
modernc.org/sqlite v1.36.2/go.mod h1:ADySlx7K4FdY5MaJcEv86hTJ0PjedAloTUuif0YS3ws=


================================================
FILE: install
================================================
#!/usr/bin/env bash
set -euo pipefail
APP=opencode

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
ORANGE='\033[38;2;255;140;0m'
NC='\033[0m' # No Color

requested_version=${VERSION:-}

os=$(uname -s | tr '[:upper:]' '[:lower:]')
if [[ "$os" == "darwin" ]]; then
    os="mac"
fi
arch=$(uname -m)

if [[ "$arch" == "aarch64" ]]; then
  arch="arm64"
fi

filename="$APP-$os-$arch.tar.gz"


case "$filename" in
    *"-linux-"*)
        [[ "$arch" == "x86_64" || "$arch" == "arm64" || "$arch" == "i386" ]] || exit 1
    ;;
    *"-mac-"*)
        [[ "$arch" == "x86_64" || "$arch" == "arm64" ]] || exit 1
    ;;
    *)
        echo "${RED}Unsupported OS/Arch: $os/$arch${NC}"
        exit 1
    ;;
esac

INSTALL_DIR=$HOME/.opencode/bin
mkdir -p "$INSTALL_DIR"

if [ -z "$requested_version" ]; then
    url="https://github.com/opencode-ai/opencode/releases/latest/download/$filename"
    specific_version=$(curl -s https://api.github.com/repos/opencode-ai/opencode/releases/latest | awk -F'"' '/"tag_name": "/ {gsub(/^v/, "", $4); print $4}')

    if [[ $? -ne 0 ]]; then
        echo "${RED}Failed to fetch version information${NC}"
        exit 1
    fi
else
    url="https://github.com/opencode-ai/opencode/releases/download/v${requested_version}/$filename"
    specific_version=$requested_version
fi

print_message() {
    local level=$1
    local message=$2
    local color=""

    case $level in
        info) color="${GREEN}" ;;
        warning) color="${YELLOW}" ;;
        error) color="${RED}" ;;
    esac

    echo -e "${color}${message}${NC}"
}

check_version() {
    if command -v opencode >/dev/null 2>&1; then
        opencode_path=$(which opencode)


        ## TODO: check if version is installed
        # installed_version=$(opencode version)
        installed_version="0.0.1"
        installed_version=$(echo $installed_version | awk '{print $2}')

        if [[ "$installed_version" != "$specific_version" ]]; then
            print_message info "Installed version: ${YELLOW}$installed_version."
        else
            print_message info "Version ${YELLOW}$specific_version${GREEN} already installed"
            exit 0
        fi
    fi
}

download_and_install() {
    print_message info "Downloading ${ORANGE}opencode ${GREEN}version: ${YELLOW}$specific_version ${GREEN}..."
    mkdir -p opencodetmp && cd opencodetmp
    curl -# -L $url | tar xz
    mv opencode $INSTALL_DIR
    cd .. && rm -rf opencodetmp 
}

check_version
download_and_install


add_to_path() {
    local config_file=$1
    local command=$2

    if [[ -w $config_file ]]; then
        echo -e "\n# opencode" >> "$config_file"
        echo "$command" >> "$config_file"
        print_message info "Successfully added ${ORANGE}opencode ${GREEN}to \$PATH in $config_file"
    else
        print_message warning "Manually add the directory to $config_file (or similar):"
        print_message info "  $command"
    fi
}

XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-$HOME/.config}

current_shell=$(basename "$SHELL")
case $current_shell in
    fish)
        config_files="$HOME/.config/fish/config.fish"
    ;;
    zsh)
        config_files="$HOME/.zshrc $HOME/.zshenv $XDG_CONFIG_HOME/zsh/.zshrc $XDG_CONFIG_HOME/zsh/.zshenv"
    ;;
    bash)
        config_files="$HOME/.bashrc $HOME/.bash_profile $HOME/.profile $XDG_CONFIG_HOME/bash/.bashrc $XDG_CONFIG_HOME/bash/.bash_profile"
    ;;
    ash)
        config_files="$HOME/.ashrc $HOME/.profile /etc/profile"
    ;;
    sh)
        config_files="$HOME/.ashrc $HOME/.profile /etc/profile"
    ;;
    *)
        # Default case if none of the above matches
        config_files="$HOME/.bashrc $HOME/.bash_profile $XDG_CONFIG_HOME/bash/.bashrc $XDG_CONFIG_HOME/bash/.bash_profile"
    ;;
esac

config_file=""
for file in $config_files; do
    if [[ -f $file ]]; then
        config_file=$file
        break
    fi
done

if [[ -z $config_file ]]; then
    print_message error "No config file found for $current_shell. Checked files: ${config_files[@]}"
    exit 1
fi

if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then
    case $current_shell in
        fish)
            add_to_path "$config_file" "fish_add_path $INSTALL_DIR"
        ;;
        zsh)
            add_to_path "$config_file" "export PATH=$INSTALL_DIR:\$PATH"
        ;;
        bash)
            add_to_path "$config_file" "export PATH=$INSTALL_DIR:\$PATH"
        ;;
        ash)
            add_to_path "$config_file" "export PATH=$INSTALL_DIR:\$PATH"
        ;;
        sh)
            add_to_path "$config_file" "export PATH=$INSTALL_DIR:\$PATH"
        ;;
        *)
            print_message warning "Manually add the directory to $config_file (or similar):"
            print_message info "  export PATH=$INSTALL_DIR:\$PATH"
        ;;
    esac
fi

if [ -n "${GITHUB_ACTIONS-}" ] && [ "${GITHUB_ACTIONS}" == "true" ]; then
    echo "$INSTALL_DIR" >> $GITHUB_PATH
    print_message info "Added $INSTALL_DIR to \$GITHUB_PATH"
fi



================================================
FILE: internal/app/app.go
================================================
package app

import (
	"context"
	"database/sql"
	"errors"
	"fmt"
	"maps"
	"sync"
	"time"

	"github.com/opencode-ai/opencode/internal/config"
	"github.com/opencode-ai/opencode/internal/db"
	"github.com/opencode-ai/opencode/internal/format"
	"github.com/opencode-ai/opencode/internal/history"
	"github.com/opencode-ai/opencode/internal/llm/agent"
	"github.com/opencode-ai/opencode/internal/logging"
	"github.com/opencode-ai/opencode/internal/lsp"
	"github.com/opencode-ai/opencode/internal/message"
	"github.com/opencode-ai/opencode/internal/permission"
	"github.com/opencode-ai/opencode/internal/session"
	"github.com/opencode-ai/opencode/internal/tui/theme"
)

type App struct {
	Sessions    session.Service
	Messages    message.Service
	History     history.Service
	Permissions permission.Service

	CoderAgent agent.Service

	LSPClients map[string]*lsp.Client

	clientsMutex sync.RWMutex

	watcherCancelFuncs []context.CancelFunc
	cancelFuncsMutex   sync.Mutex
	watcherWG          sync.WaitGroup
}

func New(ctx context.Context, conn *sql.DB) (*App, error) {
	q := db.New(conn)
	sessions := session.NewService(q)
	messages := message.NewService(q)
	files := history.NewService(q, conn)

	app := &App{
		Sessions:    sessions,
		Messages:    messages,
		History:     files,
		Permissions: permission.NewPermissionService(),
		LSPClients:  make(map[string]*lsp.Client),
	}

	// Initialize theme based on configuration
	app.initTheme()

	// Initialize LSP clients in the background
	go app.initLSPClients(ctx)

	var err error
	app.CoderAgent, err = agent.NewAgent(
		config.AgentCoder,
		app.Sessions,
		app.Messages,
		agent.CoderAgentTools(
			app.Permissions,
			app.Sessions,
			app.Messages,
			app.History,
			app.LSPClients,
		),
	)
	if err != nil {
		logging.Error("Failed to create coder agent", err)
		return nil, err
	}

	return app, nil
}

// initTheme sets the application theme based on the configuration
func (app *App) initTheme() {
	cfg := config.Get()
	if cfg == nil || cfg.TUI.Theme == "" {
		return // Use default theme
	}

	// Try to set the theme from config
	err := theme.SetTheme(cfg.TUI.Theme)
	if err != nil {
		logging.Warn("Failed to set theme from config, using default theme", "theme", cfg.TUI.Theme, "error", err)
	} else {
		logging.Debug("Set theme from config", "theme", cfg.TUI.Theme)
	}
}

// RunNonInteractive handles the execution flow when a prompt is provided via CLI flag.
func (a *App) RunNonInteractive(ctx context.Context, prompt string, outputFormat string, quiet bool) error {
	logging.Info("Running in non-interactive mode")

	// Start spinner if not in quiet mode
	var spinner *format.Spinner
	if !quiet {
		spinner = format.NewSpinner("Thinking...")
		spinner.Start()
		defer spinner.Stop()
	}

	const maxPromptLengthForTitle = 100
	titlePrefix := "Non-interactive: "
	var titleSuffix string

	if len(prompt) > maxPromptLengthForTitle {
		titleSuffix = prompt[:maxPromptLengthForTitle] + "..."
	} else {
		titleSuffix = prompt
	}
	title := titlePrefix + titleSuffix

	sess, err := a.Sessions.Create(ctx, title)
	if err != nil {
		return fmt.Errorf("failed to create session for non-interactive mode: %w", err)
	}
	logging.Info("Created session for non-interactive run", "session_id", sess.ID)

	// Automatically approve all permission requests for this non-interactive session
	a.Permissions.AutoApproveSession(sess.ID)

	done, err := a.CoderAgent.Run(ctx, sess.ID, prompt)
	if err != nil {
		return fmt.Errorf("failed to start agent processing stream: %w", err)
	}

	result := <-done
	if result.Error != nil {
		if errors.Is(result.Error, context.Canceled) || errors.Is(result.Error, agent.ErrRequestCancelled) {
			logging.Info("Agent processing cancelled", "session_id", sess.ID)
			return nil
		}
		return fmt.Errorf("agent processing failed: %w", result.Error)
	}

	// Stop spinner before printing output
	if !quiet && spinner != nil {
		spinner.Stop()
	}

	// Get the text content from the response
	content := "No content available"
	if result.Message.Content().String() != "" {
		content = result.Message.Content().String()
	}

	fmt.Println(format.FormatOutput(content, outputFormat))

	logging.Info("Non-interactive run completed", "session_id", sess.ID)

	return nil
}

// Shutdown performs a clean shutdown of the application
func (app *App) Shutdown() {
	// Cancel all watcher goroutines
	app.cancelFuncsMutex.Lock()
	for _, cancel := range app.watcherCancelFuncs {
		cancel()
	}
	app.cancelFuncsMutex.Unlock()
	app.watcherWG.Wait()

	// Perform additional cleanup for LSP clients
	app.clientsMutex.RLock()
	clients := make(map[string]*lsp.Client, len(app.LSPClients))
	maps.Copy(clients, app.LSPClients)
	app.clientsMutex.RUnlock()

	for name, client := range clients {
		shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		if err := client.Shutdown(shutdownCtx); err != nil {
			logging.Error("Failed to shutdown LSP client", "name", name, "error", err)
		}
		cancel()
	}
}


================================================
FILE: internal/app/lsp.go
================================================
package app

import (
	"context"
	"time"

	"github.com/opencode-ai/opencode/internal/config"
	"github.com/opencode-ai/opencode/internal/logging"
	"github.com/opencode-ai/opencode/internal/lsp"
	"github.com/opencode-ai/opencode/internal/lsp/watcher"
)

func (app *App) initLSPClients(ctx context.Context) {
	cfg := config.Get()

	// Initialize LSP clients
	for name, clientConfig := range cfg.LSP {
		// Start each client initialization in its own goroutine
		go app.createAndStartLSPClient(ctx, name, clientConfig.Command, clientConfig.Args...)
	}
	logging.Info("LSP clients initialization started in background")
}

// createAndStartLSPClient creates a new LSP client, initializes it, and starts its workspace watcher
func (app *App) createAndStartLSPClient(ctx context.Context, name string, command string, args ...string) {
	// Create a specific context for initialization with a timeout
	logging.Info("Creating LSP client", "name", name, "command", command, "args", args)
	
	// Create the LSP client
	lspClient, err := lsp.NewClient(ctx, command, args...)
	if err != nil {
		logging.Error("Failed to create LSP client for", name, err)
		return
	}

	// Create a longer timeout for initialization (some servers take time to start)
	initCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
	defer cancel()
	
	// Initialize with the initialization context
	_, err = lspClient.InitializeLSPClient(initCtx, config.WorkingDirectory())
	if err != nil {
		logging.Error("Initialize failed", "name", name, "error", err)
		// Clean up the client to prevent resource leaks
		lspClient.Close()
		return
	}

	// Wait for the server to be ready
	if err := lspClient.WaitForServerReady(initCtx); err != nil {
		logging.Error("Server failed to become ready", "name", name, "error", err)
		// We'll continue anyway, as some functionality might still work
		lspClient.SetServerState(lsp.StateError)
	} else {
		logging.Info("LSP server is ready", "name", name)
		lspClient.SetServerState(lsp.StateReady)
	}

	logging.Info("LSP client initialized", "name", name)
	
	// Create a child context that can be canceled when the app is shutting down
	watchCtx, cancelFunc := context.WithCancel(ctx)
	
	// Create a context with the server name for better identification
	watchCtx = context.WithValue(watchCtx, "serverName", name)
	
	// Create the workspace watcher
	workspaceWatcher := watcher.NewWorkspaceWatcher(lspClient)

	// Store the cancel function to be called during cleanup
	app.cancelFuncsMutex.Lock()
	app.watcherCancelFuncs = append(app.watcherCancelFuncs, cancelFunc)
	app.cancelFuncsMutex.Unlock()

	// Add the watcher to a WaitGroup to track active goroutines
	app.watcherWG.Add(1)

	// Add to map with mutex protection before starting goroutine
	app.clientsMutex.Lock()
	app.LSPClients[name] = lspClient
	app.clientsMutex.Unlock()

	go app.runWorkspaceWatcher(watchCtx, name, workspaceWatcher)
}

// runWorkspaceWatcher executes the workspace watcher for an LSP client
func (app *App) runWorkspaceWatcher(ctx context.Context, name string, workspaceWatcher *watcher.WorkspaceWatcher) {
	defer app.watcherWG.Done()
	defer logging.RecoverPanic("LSP-"+name, func() {
		// Try to restart the client
		app.restartLSPClient(ctx, name)
	})

	workspaceWatcher.WatchWorkspace(ctx, config.WorkingDirectory())
	logging.Info("Workspace watcher stopped", "client", name)
}

// restartLSPClient attempts to restart a crashed or failed LSP client
func (app *App) restartLSPClient(ctx context.Context, name string) {
	// Get the original configuration
	cfg := config.Get()
	clientConfig, exists := cfg.LSP[name]
	if !exists {
		logging.Error("Cannot restart client, configuration not found", "client", name)
		return
	}

	// Clean up the old client if it exists
	app.clientsMutex.Lock()
	oldClient, exists := app.LSPClients[name]
	if exists {
		delete(app.LSPClients, name) // Remove from map before potentially slow shutdown
	}
	app.clientsMutex.Unlock()

	if exists && oldClient != nil {
		// Try to shut it down gracefully, but don't block on errors
		shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		_ = oldClient.Shutdown(shutdownCtx)
		cancel()
	}

	// Create a new client using the shared function
	app.createAndStartLSPClient(ctx, name, clientConfig.Command, clientConfig.Args...)
	logging.Info("Successfully restarted LSP client", "client", name)
}


================================================
FILE: internal/completions/files-folders.go
================================================
package completions

import (
	"bytes"
	"fmt"
	"os/exec"
	"path/filepath"

	"github.com/lithammer/fuzzysearch/fuzzy"
	"github.com/opencode-ai/opencode/internal/fileutil"
	"github.com/opencode-ai/opencode/internal/logging"
	"github.com/opencode-ai/opencode/internal/tui/components/dialog"
)

type filesAndFoldersContextGroup struct {
	prefix string
}

func (cg *filesAndFoldersContextGroup) GetId() string {
	return cg.prefix
}

func (cg *filesAndFoldersContextGroup) GetEntry() dialog.CompletionItemI {
	return dialog.NewCompletionItem(dialog.CompletionItem{
		Title: "Files & Folders",
		Value: "files",
	})
}

func processNullTerminatedOutput(outputBytes []byte) []string {
	if len(outputBytes) > 0 && outputBytes[len(outputBytes)-1] == 0 {
		outputBytes = outputBytes[:len(outputBytes)-1]
	}

	if len(outputBytes) == 0 {
		return []string{}
	}

	split := bytes.Split(outputBytes, []byte{0})
	matches := make([]string, 0, len(split))

	for _, p := range split {
		if len(p) == 0 {
			continue
		}

		path := string(p)
		path = filepath.Join(".", path)

		if !fileutil.SkipHidden(path) {
			matches = append(matches, path)
		}
	}

	return matches
}

func (cg *filesAndFoldersContextGroup) getFiles(query string) ([]string, error) {
	cmdRg := fileutil.GetRgCmd("") // No glob pattern for this use case
	cmdFzf := fileutil.GetFzfCmd(query)

	var matches []string
	// Case 1: Both rg and fzf available
	if cmdRg != nil && cmdFzf != nil {
		rgPipe, err := cmdRg.StdoutPipe()
		if err != nil {
			return nil, fmt.Errorf("failed to get rg stdout pipe: %w", err)
		}
		defer rgPipe.Close()

		cmdFzf.Stdin = rgPipe
		var fzfOut bytes.Buffer
		var fzfErr bytes.Buffer
		cmdFzf.Stdout = &fzfOut
		cmdFzf.Stderr = &fzfErr

		if err := cmdFzf.Start(); err != nil {
			return nil, fmt.Errorf("failed to start fzf: %w", err)
		}

		errRg := cmdRg.Run()
		errFzf := cmdFzf.Wait()

		if errRg != nil {
			logging.Warn(fmt.Sprintf("rg command failed during pipe: %v", errRg))
		}

		if errFzf != nil {
			if exitErr, ok := errFzf.(*exec.ExitError); ok && exitErr.ExitCode() == 1 {
				return []string{}, nil // No matches from fzf
			}
			return nil, fmt.Errorf("fzf command failed: %w\nStderr: %s", errFzf, fzfErr.String())
		}

		matches = processNullTerminatedOutput(fzfOut.Bytes())

		// Case 2: Only rg available
	} else if cmdRg != nil {
		logging.Debug("Using Ripgrep with fuzzy match fallback for file completions")
		var rgOut bytes.Buffer
		var rgErr bytes.Buffer
		cmdRg.Stdout = &rgOut
		cmdRg.Stderr = &rgErr

		if err := cmdRg.Run(); err != nil {
			return nil, fmt.Errorf("rg command failed: %w\nStderr: %s", err, rgErr.String())
		}

		allFiles := processNullTerminatedOutput(rgOut.Bytes())
		matches = fuzzy.Find(query, allFiles)

		// Case 3: Only fzf available
	} else if cmdFzf != nil {
		logging.Debug("Using FZF with doublestar fallback for file completions")
		files, _, err := fileutil.GlobWithDoublestar("**/*", ".", 0)
		if err != nil {
			return nil, fmt.Errorf("failed to list files for fzf: %w", err)
		}

		allFiles := make([]string, 0, len(files))
		for _, file := range files {
			if !fileutil.SkipHidden(file) {
				allFiles = append(allFiles, file)
			}
		}

		var fzfIn bytes.Buffer
		for _, file := range allFiles {
			fzfIn.WriteString(file)
			fzfIn.WriteByte(0)
		}

		cmdFzf.Stdin = &fzfIn
		var fzfOut bytes.Buffer
		var fzfErr bytes.Buffer
		cmdFzf.Stdout = &fzfOut
		cmdFzf.Stderr = &fzfErr

		if err := cmdFzf.Run(); err != nil {
			if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == 1 {
				return []string{}, nil
			}
			return nil, fmt.Errorf("fzf command failed: %w\nStderr: %s", err, fzfErr.String())
		}

		matches = processNullTerminatedOutput(fzfOut.Bytes())

		// Case 4: Fallback to doublestar with fuzzy match
	} else {
		logging.Debug("Using doublestar with fuzzy match for file completions")
		allFiles, _, err := fileutil.GlobWithDoublestar("**/*", ".", 0)
		if err != nil {
			return nil, fmt.Errorf("failed to glob files: %w", err)
		}

		filteredFiles := make([]string, 0, len(allFiles))
		for _, file := range allFiles {
			if !fileutil.SkipHidden(file) {
				filteredFiles = append(filteredFiles, file)
			}
		}

		matches = fuzzy.Find(query, filteredFiles)
	}

	return matches, nil
}

func (cg *filesAndFoldersContextGroup) GetChildEntries(query string) ([]dialog.CompletionItemI, error) {
	matches, err := cg.getFiles(query)
	if err != nil {
		return nil, err
	}

	items := make([]dialog.CompletionItemI, 0, len(matches))
	for _, file := range matches {
		item := dialog.NewCompletionItem(dialog.CompletionItem{
			Title: file,
			Value: file,
		})
		items = append(items, item)
	}

	return items, nil
}

func NewFileAndFolderContextGroup() dialog.CompletionProvider {
	return &filesAndFoldersContextGroup{
		prefix: "file",
	}
}


================================================
FILE: internal/config/config.go
================================================
// Package config manages application configuration from various sources.
package config

import (
	"encoding/json"
	"fmt"
	"log/slog"
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/opencode-ai/opencode/internal/llm/models"
	"github.com/opencode-ai/opencode/internal/logging"
	"github.com/spf13/viper"
)

// MCPType defines the type of MCP (Model Control Protocol) server.
type MCPType string

// Supported MCP types
const (
	MCPStdio MCPType = "stdio"
	MCPSse   MCPType = "sse"
)

// MCPServer defines the configuration for a Model Control Protocol server.
type MCPServer struct {
	Command string            `json:"command"`
	Env     []string          `json:"env"`
	Args    []string          `json:"args"`
	Type    MCPType           `json:"type"`
	URL     string            `json:"url"`
	Headers map[string]string `json:"headers"`
}

type AgentName string

const (
	AgentCoder      AgentName = "coder"
	AgentSummarizer AgentName = "summarizer"
	AgentTask       AgentName = "task"
	AgentTitle      AgentName = "title"
)

// Agent defines configuration for different LLM models and their token limits.
type Agent struct {
	Model           models.ModelID `json:"model"`
	MaxTokens       int64          `json:"maxTokens"`
	ReasoningEffort string         `json:"reasoningEffort"` // For openai models low,medium,heigh
}

// Provider defines configuration for an LLM provider.
type Provider struct {
	APIKey   string `json:"apiKey"`
	Disabled bool   `json:"disabled"`
}

// Data defines storage configuration.
type Data struct {
	Directory string `json:"directory,omitempty"`
}

// LSPConfig defines configuration for Language Server Protocol integration.
type LSPConfig struct {
	Disabled bool     `json:"enabled"`
	Command  string   `json:"command"`
	Args     []string `json:"args"`
	Options  any      `json:"options"`
}

// TUIConfig defines the configuration for the Terminal User Interface.
type TUIConfig struct {
	Theme string `json:"theme,omitempty"`
}

// ShellConfig defines the configuration for the shell used by the bash tool.
type ShellConfig struct {
	Path string   `json:"path,omitempty"`
	Args []string `json:"args,omitempty"`
}

// Config is the main configuration structure for the application.
type Config struct {
	Data         Data                              `json:"data"`
	WorkingDir   string                            `json:"wd,omitempty"`
	MCPServers   map[string]MCPServer              `json:"mcpServers,omitempty"`
	Providers    map[models.ModelProvider]Provider `json:"providers,omitempty"`
	LSP          map[string]LSPConfig              `json:"lsp,omitempty"`
	Agents       map[AgentName]Agent               `json:"agents,omitempty"`
	Debug        bool                              `json:"debug,omitempty"`
	DebugLSP     bool                              `json:"debugLSP,omitempty"`
	ContextPaths []string                          `json:"contextPaths,omitempty"`
	TUI          TUIConfig                         `json:"tui"`
	Shell        ShellConfig                       `json:"shell,omitempty"`
	AutoCompact  bool                              `json:"autoCompact,omitempty"`
}

// Application constants
const (
	defaultDataDirectory = ".opencode"
	defaultLogLevel      = "info"
	appName              = "opencode"

	MaxTokensFallbackDefault = 4096
)

var defaultContextPaths = []string{
	".github/copilot-instructions.md",
	".cursorrules",
	".cursor/rules/",
	"CLAUDE.md",
	"CLAUDE.local.md",
	"opencode.md",
	"opencode.local.md",
	"OpenCode.md",
	"OpenCode.local.md",
	"OPENCODE.md",
	"OPENCODE.local.md",
}

// Global configuration instance
var cfg *Config

// Load initializes the configuration from environment variables and config files.
// If debug is true, debug mode is enabled and log level is set to debug.
// It returns an error if configuration loading fails.
func Load(workingDir string, debug bool) (*Config, error) {
	if cfg != nil {
		return cfg, nil
	}

	cfg = &Config{
		WorkingDir: workingDir,
		MCPServers: make(map[string]MCPServer),
		Providers:  make(map[models.ModelProvider]Provider),
		LSP:        make(map[string]LSPConfig),
	}

	configureViper()
	setDefaults(debug)

	// Read global config
	if err := readConfig(viper.ReadInConfig()); err != nil {
		return cfg, err
	}

	// Load and merge local config
	mergeLocalConfig(workingDir)

	setProviderDefaults()

	// Apply configuration to the struct
	if err := viper.Unmarshal(cfg); err != nil {
		return cfg, fmt.Errorf("failed to unmarshal config: %w", err)
	}

	applyDefaultValues()
	defaultLevel := slog.LevelInfo
	if cfg.Debug {
		defaultLevel = slog.LevelDebug
	}
	if os.Getenv("OPENCODE_DEV_DEBUG") == "true" {
		loggingFile := fmt.Sprintf("%s/%s", cfg.Data.Directory, "debug.log")
		messagesPath := fmt.Sprintf("%s/%s", cfg.Data.Directory, "messages")

		// if file does not exist create it
		if _, err := os.Stat(loggingFile); os.IsNotExist(err) {
			if err := os.MkdirAll(cfg.Data.Directory, 0o755); err != nil {
				return cfg, fmt.Errorf("failed to create directory: %w", err)
			}
			if _, err := os.Create(loggingFile); err != nil {
				return cfg, fmt.Errorf("failed to create log file: %w", err)
			}
		}

		if _, err := os.Stat(messagesPath); os.IsNotExist(err) {
			if err := os.MkdirAll(messagesPath, 0o756); err != nil {
				return cfg, fmt.Errorf("failed to create directory: %w", err)
			}
		}
		logging.MessageDir = messagesPath

		sloggingFileWriter, err := os.OpenFile(loggingFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o666)
		if err != nil {
			return cfg, fmt.Errorf("failed to open log file: %w", err)
		}
		// Configure logger
		logger := slog.New(slog.NewTextHandler(sloggingFileWriter, &slog.HandlerOptions{
			Level: defaultLevel,
		}))
		slog.SetDefault(logger)
	} else {
		// Configure logger
		logger := slog.New(slog.NewTextHandler(logging.NewWriter(), &slog.HandlerOptions{
			Level: defaultLevel,
		}))
		slog.SetDefault(logger)
	}

	// Validate configuration
	if err := Validate(); err != nil {
		return cfg, fmt.Errorf("config validation failed: %w", err)
	}

	if cfg.Agents == nil {
		cfg.Agents = make(map[AgentName]Agent)
	}

	// Override the max tokens for title agent
	cfg.Agents[AgentTitle] = Agent{
		Model:     cfg.Agents[AgentTitle].Model,
		MaxTokens: 80,
	}
	return cfg, nil
}

// configureViper sets up viper's configuration paths and environment variables.
func configureViper() {
	viper.SetConfigName(fmt.Sprintf(".%s", appName))
	viper.SetConfigType("json")
	viper.AddConfigPath("$HOME")
	viper.AddConfigPath(fmt.Sprintf("$XDG_CONFIG_HOME/%s", appName))
	viper.AddConfigPath(fmt.Sprintf("$HOME/.config/%s", appName))
	viper.SetEnvPrefix(strings.ToUpper(appName))
	viper.AutomaticEnv()
}

// setDefaults configures default values for configuration options.
func setDefaults(debug bool) {
	viper.SetDefault("data.directory", defaultDataDirectory)
	viper.SetDefault("contextPaths", defaultContextPaths)
	viper.SetDefault("tui.theme", "opencode")
	viper.SetDefault("autoCompact", true)

	// Set default shell from environment or fallback to /bin/bash
	shellPath := os.Getenv("SHELL")
	if shellPath == "" {
		shellPath = "/bin/bash"
	}
	viper.SetDefault("shell.path", shellPath)
	viper.SetDefault("shell.args", []string{"-l"})

	if debug {
		viper.SetDefault("debug", true)
		viper.Set("log.level", "debug")
	} else {
		viper.SetDefault("debug", false)
		viper.SetDefault("log.level", defaultLogLevel)
	}
}

// setProviderDefaults configures LLM provider defaults based on provider provided by
// environment variables and configuration file.
func setProviderDefaults() {
	// Set all API keys we can find in the environment
	// Note: Viper does not default if the json apiKey is ""
	if apiKey := os.Getenv("ANTHROPIC_API_KEY"); apiKey != "" {
		viper.SetDefault("providers.anthropic.apiKey", apiKey)
	}
	if apiKey := os.Getenv("OPENAI_API_KEY"); apiKey != "" {
		viper.SetDefault("providers.openai.apiKey", apiKey)
	}
	if apiKey := os.Getenv("GEMINI_API_KEY"); apiKey != "" {
		viper.SetDefault("providers.gemini.apiKey", apiKey)
	}
	if apiKey := os.Getenv("GROQ_API_KEY"); apiKey != "" {
		viper.SetDefault("providers.groq.apiKey", apiKey)
	}
	if apiKey := os.Getenv("OPENROUTER_API_KEY"); apiKey != "" {
		viper.SetDefault("providers.openrouter.apiKey", apiKey)
	}
	if apiKey := os.Getenv("XAI_API_KEY"); apiKey != "" {
		viper.SetDefault("providers.xai.apiKey", apiKey)
	}
	if apiKey := os.Getenv("AZURE_OPENAI_ENDPOINT"); apiKey != "" {
		// api-key may be empty when using Entra ID credentials – that's okay
		viper.SetDefault("providers.azure.apiKey", os.Getenv("AZURE_OPENAI_API_KEY"))
	}
	if apiKey, err := LoadGitHubToken(); err == nil && apiKey != "" {
		viper.SetDefault("providers.copilot.apiKey", apiKey)
		if viper.GetString("providers.copilot.apiKey") == "" {
			viper.Set("providers.copilot.apiKey", apiKey)
		}
	}

	// Use this order to set the default models
	// 1. Copilot
	// 2. Anthropic
	// 3. OpenAI
	// 4. Google Gemini
	// 5. Groq
	// 6. OpenRouter
	// 7. AWS Bedrock
	// 8. Azure
	// 9. Google Cloud VertexAI

	// copilot configuration
	if key := viper.GetString("providers.copilot.apiKey"); strings.TrimSpace(key) != "" {
		viper.SetDefault("agents.coder.model", models.CopilotGPT4o)
		viper.SetDefault("agents.summarizer.model", models.CopilotGPT4o)
		viper.SetDefault("agents.task.model", models.CopilotGPT4o)
		viper.SetDefault("agents.title.model", models.CopilotGPT4o)
		return
	}

	// Anthropic configuration
	if key := viper.GetString("providers.anthropic.apiKey"); strings.TrimSpace(key) != "" {
		viper.SetDefault("agents.coder.model", models.Claude4Sonnet)
		viper.SetDefault("agents.summarizer.model", models.Claude4Sonnet)
		viper.SetDefault("agents.task.model", models.Claude4Sonnet)
		viper.SetDefault("agents.title.model", models.Claude4Sonnet)
		return
	}

	// OpenAI configuration
	if key := viper.GetString("providers.openai.apiKey"); strings.TrimSpace(key) != "" {
		viper.SetDefault("agents.coder.model", models.GPT41)
		viper.SetDefault("agents.summarizer.model", models.GPT41)
		viper.SetDefault("agents.task.model", models.GPT41Mini)
		viper.SetDefault("agents.title.model", models.GPT41Mini)
		return
	}

	// Google Gemini configuration
	if key := viper.GetString("providers.gemini.apiKey"); strings.TrimSpace(key) != "" {
		viper.SetDefault("agents.coder.model", models.Gemini25)
		viper.SetDefault("agents.summarizer.model", models.Gemini25)
		viper.SetDefault("agents.task.model", models.Gemini25Flash)
		viper.SetDefault("agents.title.model", models.Gemini25Flash)
		return
	}

	// Groq configuration
	if key := viper.GetString("providers.groq.apiKey"); strings.TrimSpace(key) != "" {
		viper.SetDefault("agents.coder.model", models.QWENQwq)
		viper.SetDefault("agents.summarizer.model", models.QWENQwq)
		viper.SetDefault("agents.task.model", models.QWENQwq)
		viper.SetDefault("agents.title.model", models.QWENQwq)
		return
	}

	// OpenRouter configuration
	if key := viper.GetString("providers.openrouter.apiKey"); strings.TrimSpace(key) != "" {
		viper.SetDefault("agents.coder.model", models.OpenRouterClaude37Sonnet)
		viper.SetDefault("agents.summarizer.model", models.OpenRouterClaude37Sonnet)
		viper.SetDefault("agents.task.model", models.OpenRouterClaude37Sonnet)
		viper.SetDefault("agents.title.model", models.OpenRouterClaude35Haiku)
		return
	}

	// XAI configuration
	if key := viper.GetString("providers.xai.apiKey"); strings.TrimSpace(key) != "" {
		viper.SetDefault("agents.coder.model", models.XAIGrok3Beta)
		viper.SetDefault("agents.summarizer.model", models.XAIGrok3Beta)
		viper.SetDefault("agents.task.model", models.XAIGrok3Beta)
		viper.SetDefault("agents.title.model", models.XAiGrok3MiniFastBeta)
		return
	}

	// AWS Bedrock configuration
	if hasAWSCredentials() {
		viper.SetDefault("agents.coder.model", models.BedrockClaude37Sonnet)
		viper.SetDefault("agents.summarizer.model", models.BedrockClaude37Sonnet)
		viper.SetDefault("agents.task.model", models.BedrockClaude37Sonnet)
		viper.SetDefault("agents.title.model", models.BedrockClaude37Sonnet)
		return
	}

	// Azure OpenAI configuration
	if os.Getenv("AZURE_OPENAI_ENDPOINT") != "" {
		viper.SetDefault("agents.coder.model", models.AzureGPT41)
		viper.SetDefault("agents.summarizer.model", models.AzureGPT41)
		viper.SetDefault("agents.task.model", models.AzureGPT41Mini)
		viper.SetDefault("agents.title.model", models.AzureGPT41Mini)
		return
	}

	// Google Cloud VertexAI configuration
	if hasVertexAICredentials() {
		viper.SetDefault("agents.coder.model", models.VertexAIGemini25)
		viper.SetDefault("agents.summarizer.model", models.VertexAIGemini25)
		viper.SetDefault("agents.task.model", models.VertexAIGemini25Flash)
		viper.SetDefault("agents.title.model", models.VertexAIGemini25Flash)
		return
	}
}

// hasAWSCredentials checks if AWS credentials are available in the environment.
func hasAWSCredentials() bool {
	// Check for explicit AWS credentials
	if os.Getenv("AWS_ACCESS_KEY_ID") != "" && os.Getenv("AWS_SECRET_ACCESS_KEY") != "" {
		return true
	}

	// Check for AWS profile
	if os.Getenv("AWS_PROFILE") != "" || os.Getenv("AWS_DEFAULT_PROFILE") != "" {
		return true
	}

	// Check for AWS region
	if os.Getenv("AWS_REGION") != "" || os.Getenv("AWS_DEFAULT_REGION") != "" {
		return true
	}

	// Check if running on EC2 with instance profile
	if os.Getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI") != "" ||
		os.Getenv("AWS_CONTAINER_CREDENTIALS_FULL_URI") != "" {
		return true
	}

	return false
}

// hasVertexAICredentials checks if VertexAI credentials are available in the environment.
func hasVertexAICredentials() bool {
	// Check for explicit VertexAI parameters
	if os.Getenv("VERTEXAI_PROJECT") != "" && os.Getenv("VERTEXAI_LOCATION") != "" {
		return true
	}
	// Check for Google Cloud project and location
	if os.Getenv("GOOGLE_CLOUD_PROJECT") != "" && (os.Getenv("GOOGLE_CLOUD_REGION") != "" || os.Getenv("GOOGLE_CLOUD_LOCATION") != "") {
		return true
	}
	return false
}

func hasCopilotCredentials() bool {
	// Check for explicit Copilot parameters
	if token, _ := LoadGitHubToken(); token != "" {
		return true
	}
	return false
}

// readConfig handles the result of reading a configuration file.
func readConfig(err error) error {
	if err == nil {
		return nil
	}

	// It's okay if the config file doesn't exist
	if _, ok := err.(viper.ConfigFileNotFoundError); ok {
		return nil
	}

	return fmt.Errorf("failed to read config: %w", err)
}

// mergeLocalConfig loads and merges configuration from the local directory.
func mergeLocalConfig(workingDir string) {
	local := viper.New()
	local.SetConfigName(fmt.Sprintf(".%s", appName))
	local.SetConfigType("json")
	local.AddConfigPath(workingDir)

	// Merge local config if it exists
	if err := local.ReadInConfig(); err == nil {
		viper.MergeConfigMap(local.AllSettings())
	}
}

// applyDefaultValues sets default values for configuration fields that need processing.
func applyDefaultValues() {
	// Set default MCP type if not specified
	for k, v := range cfg.MCPServers {
		if v.Type == "" {
			v.Type = MCPStdio
			cfg.MCPServers[k] = v
		}
	}
}

// It validates model IDs and providers, ensuring they are supported.
func validateAgent(cfg *Config, name AgentName, agent Agent) error {
	// Check if model exists
	// TODO:	If a copilot model is specified, but model is not found,
	// 		 	it might be new model. The https://api.githubcopilot.com/models
	// 		 	endpoint should be queried to validate if the model is supported.
	model, modelExists := models.SupportedModels[agent.Model]
	if !modelExists {
		logging.Warn("unsupported model configured, reverting to default",
			"agent", name,
			"configured_model", agent.Model)

		// Set default model based on available providers
		if setDefaultModelForAgent(name) {
			logging.Info("set default model for agent", "agent", name, "model", cfg.Agents[name].Model)
		} else {
			return fmt.Errorf("no valid provider available for agent %s", name)
		}
		return nil
	}

	// Check if provider for the model is configured
	provider := model.Provider
	providerCfg, providerExists := cfg.Providers[provider]

	if !providerExists {
		// Provider not configured, check if we have environment variables
		apiKey := getProviderAPIKey(provider)
		if apiKey == "" {
			logging.Warn("provider not configured for model, reverting to default",
				"agent", name,
				"model", agent.Model,
				"provider", provider)

			// Set default model based on available providers
			if setDefaultModelForAgent(name) {
				logging.Info("set default model for agent", "agent", name, "model", cfg.Agents[name].Model)
			} else {
				return fmt.Errorf("no valid provider available for agent %s", name)
			}
		} else {
			// Add provider with API key from environment
			cfg.Providers[provider] = Provider{
				APIKey: apiKey,
			}
			logging.Info("added provider from environment", "provider", provider)
		}
	} else if providerCfg.Disabled || providerCfg.APIKey == "" {
		// Provider is disabled or has no API key
		logging.Warn("provider is disabled or has no API key, reverting to default",
			"agent", name,
			"model", agent.Model,
			"provider", provider)

		// Set default model based on available providers
		if setDefaultModelForAgent(name) {
			logging.Info("set default model for agent", "agent", name, "model", cfg.Agents[name].Model)
		} else {
			return fmt.Errorf("no valid provider available for agent %s", name)
		}
	}

	// Validate max tokens
	if agent.MaxTokens <= 0 {
		logging.Warn("invalid max tokens, setting to default",
			"agent", name,
			"model", agent.Model,
			"max_tokens", agent.MaxTokens)

		// Update the agent with default max tokens
		updatedAgent := cfg.Agents[name]
		if model.DefaultMaxTokens > 0 {
			updatedAgent.MaxTokens = model.DefaultMaxTokens
		} else {
			updatedAgent.MaxTokens = MaxTokensFallbackDefault
		}
		cfg.Agents[name] = updatedAgent
	} else if model.ContextWindow > 0 && agent.MaxTokens > model.ContextWindow/2 {
		// Ensure max tokens doesn't exceed half the context window (reasonable limit)
		logging.Warn("max tokens exceeds half the context window, adjusting",
			"agent", name,
			"model", agent.Model,
			"max_tokens", agent.MaxTokens,
			"context_window", model.ContextWindow)

		// Update the agent with adjusted max tokens
		updatedAgent := cfg.Agents[name]
		updatedAgent.MaxTokens = model.ContextWindow / 2
		cfg.Agents[name] = updatedAgent
	}

	// Validate reasoning effort for models that support reasoning
	if model.CanReason && provider == models.ProviderOpenAI || provider == models.ProviderLocal {
		if agent.ReasoningEffort == "" {
			// Set default reasoning effort for models that support it
			logging.Info("setting default reasoning effort for model that supports reasoning",
				"agent", name,
				"model", agent.Model)

			// Update the agent with default reasoning effort
			updatedAgent := cfg.Agents[name]
			updatedAgent.ReasoningEffort = "medium"
			cfg.Agents[name] = updatedAgent
		} else {
			// Check if reasoning effort is valid (low, medium, high)
			effort := strings.ToLower(agent.ReasoningEffort)
			if effort != "low" && effort != "medium" && effort != "high" {
				logging.Warn("invalid reasoning effort, setting to medium",
					"agent", name,
					"model", agent.Model,
					"reasoning_effort", agent.ReasoningEffort)

				// Update the agent with valid reasoning effort
				updatedAgent := cfg.Agents[name]
				updatedAgent.ReasoningEffort = "medium"
				cfg.Agents[name] = updatedAgent
			}
		}
	} else if !model.CanReason && agent.ReasoningEffort != "" {
		// Model doesn't support reasoning but reasoning effort is set
		logging.Warn("model doesn't support reasoning but reasoning effort is set, ignoring",
			"agent", name,
			"model", agent.Model,
			"reasoning_effort", agent.ReasoningEffort)

		// Update the agent to remove reasoning effort
		updatedAgent := cfg.Agents[name]
		updatedAgent.ReasoningEffort = ""
		cfg.Agents[name] = updatedAgent
	}

	return nil
}

// Validate checks if the configuration is valid and applies defaults where needed.
func Validate() error {
	if cfg == nil {
		return fmt.Errorf("config not loaded")
	}

	// Validate agent models
	for name, agent := range cfg.Agents {
		if err := validateAgent(cfg, name, agent); err != nil {
			return err
		}
	}

	// Validate providers
	for provider, providerCfg := range cfg.Providers {
		if providerCfg.APIKey == "" && !providerCfg.Disabled {
			fmt.Printf("provider has no API key, marking as disabled %s", provider)
			logging.Warn("provider has no API key, marking as disabled", "provider", provider)
			providerCfg.Disabled = true
			cfg.Providers[provider] = providerCfg
		}
	}

	// Validate LSP configurations
	for language, lspConfig := range cfg.LSP {
		if lspConfig.Command == "" && !lspConfig.Disabled {
			logging.Warn("LSP configuration has no command, marking as disabled", "language", language)
			lspConfig.Disabled = true
			cfg.LSP[language] = lspConfig
		}
	}

	return nil
}

// getProviderAPIKey gets the API key for a provider from environment variables
func getProviderAPIKey(provider models.ModelProvider) string {
	switch provider {
	case models.ProviderAnthropic:
		return os.Getenv("ANTHROPIC_API_KEY")
	case models.ProviderOpenAI:
		return os.Getenv("OPENAI_API_KEY")
	case models.ProviderGemini:
		return os.Getenv("GEMINI_API_KEY")
	case models.ProviderGROQ:
		return os.Getenv("GROQ_API_KEY")
	case models.ProviderAzure:
		return os.Getenv("AZURE_OPENAI_API_KEY")
	case models.ProviderOpenRouter:
		return os.Getenv("OPENROUTER_API_KEY")
	case models.ProviderBedrock:
		if hasAWSCredentials() {
			return "aws-credentials-available"
		}
	case models.ProviderVertexAI:
		if hasVertexAICredentials() {
			return "vertex-ai-credentials-available"
		}
	}
	return ""
}

// setDefaultModelForAgent sets a default model for an agent based on available providers
func setDefaultModelForAgent(agent AgentName) bool {
	if hasCopilotCredentials() {
		maxTokens := int64(5000)
		if agent == AgentTitle {
			maxTokens = 80
		}

		cfg.Agents[agent] = Agent{
			Model:     models.CopilotGPT4o,
			MaxTokens: maxTokens,
		}
		return true
	}
	// Check providers in order of preference
	if apiKey := os.Getenv("ANTHROPIC_API_KEY"); apiKey != "" {
		maxTokens := int64(5000)
		if agent == AgentTitle {
			maxTokens = 80
		}
		cfg.Agents[agent] = Agent{
			Model:     models.Claude37Sonnet,
			MaxTokens: maxTokens,
		}
		return true
	}

	if apiKey := os.Getenv("OPENAI_API_KEY"); apiKey != "" {
		var model models.ModelID
		maxTokens := int64(5000)
		reasoningEffort := ""

		switch agent {
		case AgentTitle:
			model = models.GPT41Mini
			maxTokens = 80
		case AgentTask:
			model = models.GPT41Mini
		default:
			model = models.GPT41
		}

		// Check if model supports reasoning
		if modelInfo, ok := models.SupportedModels[model]; ok && modelInfo.CanReason {
			reasoningEffort = "medium"
		}

		cfg.Agents[agent] = Agent{
			Model:           model,
			MaxTokens:       maxTokens,
			ReasoningEffort: reasoningEffort,
		}
		return true
	}

	if apiKey := os.Getenv("OPENROUTER_API_KEY"); apiKey != "" {
		var model models.ModelID
		maxTokens := int64(5000)
		reasoningEffort := ""

		switch agent {
		case AgentTitle:
			model = models.OpenRouterClaude35Haiku
			maxTokens = 80
		case AgentTask:
			model = models.OpenRouterClaude37Sonnet
		default:
			model = models.OpenRouterClaude37Sonnet
		}

		// Check if model supports reasoning
		if modelInfo, ok := models.SupportedModels[model]; ok && modelInfo.CanReason {
			reasoningEffort = "medium"
		}

		cfg.Agents[agent] = Agent{
			Model:           model,
			MaxTokens:       maxTokens,
			ReasoningEffort: reasoningEffort,
		}
		return true
	}

	if apiKey := os.Getenv("GEMINI_API_KEY"); apiKey != "" {
		var model models.ModelID
		maxTokens := int64(5000)

		if agent == AgentTitle {
			model = models.Gemini25Flash
			maxTokens = 80
		} else {
			model = models.Gemini25
		}

		cfg.Agents[agent] = Agent{
			Model:     model,
			MaxTokens: maxTokens,
		}
		return true
	}

	if apiKey := os.Getenv("GROQ_API_KEY"); apiKey != "" {
		maxTokens := int64(5000)
		if agent == AgentTitle {
			maxTokens = 80
		}

		cfg.Agents[agent] = Agent{
			Model:     models.QWENQwq,
			MaxTokens: maxTokens,
		}
		return true
	}

	if hasAWSCredentials() {
		maxTokens := int64(5000)
		if agent == AgentTitle {
			maxTokens = 80
		}

		cfg.Agents[agent] = Agent{
			Model:           models.BedrockClaude37Sonnet,
			MaxTokens:       maxTokens,
			ReasoningEffort: "medium", // Claude models support reasoning
		}
		return true
	}

	if hasVertexAICredentials() {
		var model models.ModelID
		maxTokens := int64(5000)

		if agent == AgentTitle {
			model = models.VertexAIGemini25Flash
			maxTokens = 80
		} else {
			model = models.VertexAIGemini25
		}

		cfg.Agents[agent] = Agent{
			Model:     model,
			MaxTokens: maxTokens,
		}
		return true
	}

	return false
}

func updateCfgFile(updateCfg func(config *Config)) error {
	if cfg == nil {
		return fmt.Errorf("config not loaded")
	}

	// Get the config file path
	configFile := viper.ConfigFileUsed()
	var configData []byte
	if configFile == "" {
		homeDir, err := os.UserHomeDir()
		if err != nil {
			return fmt.Errorf("failed to get home directory: %w", err)
		}
		configFile = filepath.Join(homeDir, fmt.Sprintf(".%s.json", appName))
		logging.Info("config file not found, creating new one", "path", configFile)
		configData = []byte(`{}`)
	} else {
		// Read the existing config file
		data, err := os.ReadFile(configFile)
		if err != nil {
			return fmt.Errorf("failed to read config file: %w", err)
		}
		configData = data
	}

	// Parse the JSON
	var userCfg *Config
	if err := json.Unmarshal(configData, &userCfg); err != nil {
		return fmt.Errorf("failed to parse config file: %w", err)
	}

	updateCfg(userCfg)

	// Write the updated config back to file
	updatedData, err := json.MarshalIndent(userCfg, "", "  ")
	if err != nil {
		return fmt.Errorf("failed to marshal config: %w", err)
	}

	if err := os.WriteFile(configFile, updatedData, 0o644); err != nil {
		return fmt.Errorf("failed to write config file: %w", err)
	}

	return nil
}

// Get returns the current configuration.
// It's safe to call this function multiple times.
func Get() *Config {
	return cfg
}

// WorkingDirectory returns the current working directory from the configuration.
func WorkingDirectory() string {
	if cfg == nil {
		panic("config not loaded")
	}
	return cfg.WorkingDir
}

func UpdateAgentModel(agentName AgentName, modelID models.ModelID) error {
	if cfg == nil {
		panic("config not loaded")
	}

	existingAgentCfg := cfg.Agents[agentName]

	model, ok := models.SupportedModels[modelID]
	if !ok {
		return fmt.Errorf("model %s not supported", modelID)
	}

	maxTokens := existingAgentCfg.MaxTokens
	if model.DefaultMaxTokens > 0 {
		maxTokens = model.DefaultMaxTokens
	}

	newAgentCfg := Agent{
		Model:           modelID,
		MaxTokens:       maxTokens,
		ReasoningEffort: existingAgentCfg.ReasoningEffort,
	}
	cfg.Agents[agentName] = newAgentCfg

	if err := validateAgent(cfg, agentName, newAgentCfg); err != nil {
		// revert config update on failure
		cfg.Agents[agentName] = existingAgentCfg
		return fmt.Errorf("failed to update agent model: %w", err)
	}

	return updateCfgFile(func(config *Config) {
		if config.Agents == nil {
			config.Agents = make(map[AgentName]Agent)
		}
		config.Agents[agentName] = newAgentCfg
	})
}

// UpdateTheme updates the theme in the configuration and writes it to the config file.
func UpdateTheme(themeName string) error {
	if cfg == nil {
		return fmt.Errorf("config not loaded")
	}

	// Update the in-memory config
	cfg.TUI.Theme = themeName

	// Update the file config
	return updateCfgFile(func(config *Config) {
		config.TUI.Theme = themeName
	})
}

// Tries to load Github token from all possible locations
func LoadGitHubToken() (string, error) {
	// First check environment variable
	if token := os.Getenv("GITHUB_TOKEN"); token != "" {
		return token, nil
	}

	// Get config directory
	var configDir string
	if xdgConfig := os.Getenv("XDG_CONFIG_HOME"); xdgConfig != "" {
		configDir = xdgConfig
	} else if runtime.GOOS == "windows" {
		if localAppData := os.Getenv("LOCALAPPDATA"); localAppData != "" {
			configDir = localAppData
		} else {
			configDir = filepath.Join(os.Getenv("HOME"), "AppData", "Local")
		}
	} else {
		configDir = filepath.Join(os.Getenv("HOME"), ".config")
	}

	// Try both hosts.json and apps.json files
	filePaths := []string{
		filepath.Join(configDir, "github-copilot", "hosts.json"),
		filepath.Join(configDir, "github-copilot", "apps.json"),
	}

	for _, filePath := range filePaths {
		data, err := os.ReadFile(filePath)
		if err != nil {
			continue
		}

		var config map[string]map[string]interface{}
		if err := json.Unmarshal(data, &config); err != nil {
			continue
		}

		for key, value := range config {
			if strings.Contains(key, "github.com") {
				if oauthToken, ok := value["oauth_token"].(string); ok {
					return oauthToken, nil
				}
			}
		}
	}

	return "", fmt.Errorf("GitHub token not found in standard locations")
}


================================================
FILE: internal/config/init.go
================================================
package config

import (
	"fmt"
	"os"
	"path/filepath"
)

const (
	// InitFlagFilename is the name of the file that indicates whether the project has been initialized
	InitFlagFilename = "init"
)

// ProjectInitFlag represents the initialization status for a project directory
type ProjectInitFlag struct {
	Initialized bool `json:"initialized"`
}

// ShouldShowInitDialog checks if the initialization dialog should be shown for the current directory
func ShouldShowInitDialog() (bool, error) {
	if cfg == nil {
		return false, fmt.Errorf("config not loaded")
	}

	// Create the flag file path
	flagFilePath := filepath.Join(cfg.Data.Directory, InitFlagFilename)

	// Check if the flag file exists
	_, err := os.Stat(flagFilePath)
	if err == nil {
		// File exists, don't show the dialog
		return false, nil
	}

	// If the error is not "file not found", return the error
	if !os.IsNotExist(err) {
		return false, fmt.Errorf("failed to check init flag file: %w", err)
	}

	// File doesn't exist, show the dialog
	return true, nil
}

// MarkProjectInitialized marks the current project as initialized
func MarkProjectInitialized() error {
	if cfg == nil {
		return fmt.Errorf("config not loaded")
	}
	// Create the flag file path
	flagFilePath := filepath.Join(cfg.Data.Directory, InitFlagFilename)

	// Create an empty file to mark the project as initialized
	file, err := os.Create(flagFilePath)
	if err != nil {
		return fmt.Errorf("failed to create init flag file: %w", err)
	}
	defer file.Close()

	return nil
}



================================================
FILE: internal/db/connect.go
================================================
package db

import (
	"database/sql"
	"fmt"
	"os"
	"path/filepath"

	_ "github.com/ncruces/go-sqlite3/driver"
	_ "github.com/ncruces/go-sqlite3/embed"

	"github.com/opencode-ai/opencode/internal/config"
	"github.com/opencode-ai/opencode/internal/logging"

	"github.com/pressly/goose/v3"
)

func Connect() (*sql.DB, error) {
	dataDir := config.Get().Data.Directory
	if dataDir == "" {
		return nil, fmt.Errorf("data.dir is not set")
	}
	if err := os.MkdirAll(dataDir, 0o700); err != nil {
		return nil, fmt.Errorf("failed to create data directory: %w", err)
	}
	dbPath := filepath.Join(dataDir, "opencode.db")
	// Open the SQLite database
	db, err := sql.Open("sqlite3", dbPath)
	if err != nil {
		return nil, fmt.Errorf("failed to open database: %w", err)
	}

	// Verify connection
	if err = db.Ping(); err != nil {
		db.Close()
		return nil, fmt.Errorf("failed to connect to database: %w", err)
	}

	// Set pragmas for better performance
	pragmas := []string{
		"PRAGMA foreign_keys = ON;",
		"PRAGMA journal_mode = WAL;",
		"PRAGMA page_size = 4096;",
		"PRAGMA cache_size = -8000;",
		"PRAGMA synchronous = NORMAL;",
	}

	for _, pragma := range pragmas {
		if _, err = db.Exec(pragma); err != nil {
			logging.Error("Failed to set pragma", pragma, err)
		} else {
			logging.Debug("Set pragma", "pragma", pragma)
		}
	}

	goose.SetBaseFS(FS)

	if err := goose.SetDialect("sqlite3"); err != nil {
		logging.Error("Failed to set dialect", "error", err)
		return nil, fmt.Errorf("failed to set dialect: %w", err)
	}

	if err := goose.Up(db, "migrations"); err != nil {
		logging.Error("Failed to apply migrations", "error", err)
		return nil, fmt.Errorf("failed to apply migrations: %w", err)
	}
	return db, nil
}


================================================
FILE: internal/db/db.go
================================================
// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.29.0

package db

import (
	"context"
	"database/sql"
	"fmt"
)

type DBTX interface {
	ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
	PrepareContext(context.Context, string) (*sql.Stmt, error)
	QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
	QueryRowContext(context.Context, string, ...interface{}) *sql.Row
}

func New(db DBTX) *Queries {
	return &Queries{db: db}
}

func Prepare(ctx context.Context, db DBTX) (*Queries, error) {
	q := Queries{db: db}
	var err error
	if q.createFileStmt, err = db.PrepareContext(ctx, createFile); err != nil {
		return nil, fmt.Errorf("error preparing query CreateFile: %w", err)
	}
	if q.createMessageStmt, err = db.PrepareContext(ctx, createMessage); err != nil {
		return nil, fmt.Errorf("error preparing query CreateMessage: %w", err)
	}
	if q.createSessionStmt, err = db.PrepareContext(ctx, createSession); err != nil {
		return nil, fmt.Errorf("error preparing query CreateSession: %w", err)
	}
	if q.deleteFileStmt, err = db.PrepareContext(ctx, deleteFile); err != nil {
		return nil, fmt.Errorf("error preparing query DeleteFile: %w", err)
	}
	if q.deleteMessageStmt, err = db.PrepareContext(ctx, deleteMessage); err != nil {
		return nil, fmt.Errorf("error preparing query DeleteMessage: %w", err)
	}
	if q.deleteSessionStmt, err = db.PrepareContext(ctx, deleteSession); err != nil {
		return nil, fmt.Errorf("error preparing query DeleteSession: %w", err)
	}
	if q.deleteSessionFilesStmt, err = db.PrepareContext(ctx, deleteSessionFiles); err != nil {
		return nil, fmt.Errorf("error preparing query DeleteSessionFiles: %w", err)
	}
	if q.deleteSessionMessagesStmt, err = db.PrepareContext(ctx, deleteSessionMessages); err != nil {
		return nil, fmt.Errorf("error preparing query DeleteSessionMessages: %w", err)
	}
	if q.getFileStmt, err = db.PrepareContext(ctx, getFile); err != nil {
		return nil, fmt.Errorf("error preparing query GetFile: %w", err)
	}
	if q.getFileByPathAndSessionStmt, err = db.PrepareContext(ctx, getFileByPathAndSession); err != nil {
		return nil, fmt.Errorf("error preparing query GetFileByPathAndSession: %w", err)
	}
	if q.getMessageStmt, err = db.PrepareContext(ctx, getMessage); err != nil {
		return nil, fmt.Errorf("error preparing query GetMessage: %w", err)
	}
	if q.getSessionByIDStmt, err = db.PrepareContext(ctx, getSessionByID); err != nil {
		return nil, fmt.Errorf("error preparing query GetSessionByID: %w", err)
	}
	if q.listFilesByPathStmt, err = db.PrepareContext(ctx, listFilesByPath); err != nil {
		return nil, fmt.Errorf("error preparing query ListFilesByPath: %w", err)
	}
	if q.listFilesBySessionStmt, err = db.PrepareContext(ctx, listFilesBySession); err != nil {
		return nil, fmt.Errorf("error preparing query ListFilesBySession: %w", err)
	}
	if q.listLatestSessionFilesStmt, err = db.PrepareContext(ctx, listLatestSessionFiles); err != nil {
		return nil, fmt.Errorf("error preparing query ListLatestSessionFiles: %w", err)
	}
	if q.listMessagesBySessionStmt, err = db.PrepareContext(ctx, listMessagesBySession); err != nil {
		return nil, fmt.Errorf("error preparing query ListMessagesBySession: %w", err)
	}
	if q.listNewFilesStmt, err = db.PrepareContext(ctx, listNewFiles); err != nil {
		return nil, fmt.Errorf("error preparing query ListNewFiles: %w", err)
	}
	if q.listSessionsStmt, err = db.PrepareContext(ctx, listSessions); err != nil {
		return nil, fmt.Errorf("error preparing query ListSessions: %w", err)
	}
	if q.updateFileStmt, err = db.PrepareContext(ctx, updateFile); err != nil {
		return nil, fmt.Errorf("error preparing query UpdateFile: %w", err)
	}
	if q.updateMessageStmt, err = db.PrepareContext(ctx, updateMessage); err != nil {
		return nil, fmt.Errorf("error preparing query UpdateMessage: %w", err)
	}
	if q.updateSessionStmt, err = db.PrepareContext(ctx, updateSession); err != nil {
		return nil, fmt.Errorf("error preparing query UpdateSession: %w", err)
	}
	return &q, nil
}

func (q *Queries) Close() error {
	var err error
	if q.createFileStmt != nil {
		if cerr := q.createFileStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing createFileStmt: %w", cerr)
		}
	}
	if q.createMessageStmt != nil {
		if cerr := q.createMessageStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing createMessageStmt: %w", cerr)
		}
	}
	if q.createSessionStmt != nil {
		if cerr := q.createSessionStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing createSessionStmt: %w", cerr)
		}
	}
	if q.deleteFileStmt != nil {
		if cerr := q.deleteFileStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing deleteFileStmt: %w", cerr)
		}
	}
	if q.deleteMessageStmt != nil {
		if cerr := q.deleteMessageStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing deleteMessageStmt: %w", cerr)
		}
	}
	if q.deleteSessionStmt != nil {
		if cerr := q.deleteSessionStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing deleteSessionStmt: %w", cerr)
		}
	}
	if q.deleteSessionFilesStmt != nil {
		if cerr := q.deleteSessionFilesStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing deleteSessionFilesStmt: %w", cerr)
		}
	}
	if q.deleteSessionMessagesStmt != nil {
		if cerr := q.deleteSessionMessagesStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing deleteSessionMessagesStmt: %w", cerr)
		}
	}
	if q.getFileStmt != nil {
		if cerr := q.getFileStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing getFileStmt: %w", cerr)
		}
	}
	if q.getFileByPathAndSessionStmt != nil {
		if cerr := q.getFileByPathAndSessionStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing getFileByPathAndSessionStmt: %w", cerr)
		}
	}
	if q.getMessageStmt != nil {
		if cerr := q.getMessageStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing getMessageStmt: %w", cerr)
		}
	}
	if q.getSessionByIDStmt != nil {
		if cerr := q.getSessionByIDStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing getSessionByIDStmt: %w", cerr)
		}
	}
	if q.listFilesByPathStmt != nil {
		if cerr := q.listFilesByPathStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing listFilesByPathStmt: %w", cerr)
		}
	}
	if q.listFilesBySessionStmt != nil {
		if cerr := q.listFilesBySessionStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing listFilesBySessionStmt: %w", cerr)
		}
	}
	if q.listLatestSessionFilesStmt != nil {
		if cerr := q.listLatestSessionFilesStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing listLatestSessionFilesStmt: %w", cerr)
		}
	}
	if q.listMessagesBySessionStmt != nil {
		if cerr := q.listMessagesBySessionStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing listMessagesBySessionStmt: %w", cerr)
		}
	}
	if q.listNewFilesStmt != nil {
		if cerr := q.listNewFilesStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing listNewFilesStmt: %w", cerr)
		}
	}
	if q.listSessionsStmt != nil {
		if cerr := q.listSessionsStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing listSessionsStmt: %w", cerr)
		}
	}
	if q.updateFileStmt != nil {
		if cerr := q.updateFileStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing updateFileStmt: %w", cerr)
		}
	}
	if q.updateMessageStmt != nil {
		if cerr := q.updateMessageStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing updateMessageStmt: %w", cerr)
		}
	}
	if q.updateSessionStmt != nil {
		if cerr := q.updateSessionStmt.Close(); cerr != nil {
			err = fmt.Errorf("error closing updateSessionStmt: %w", cerr)
		}
	}
	return err
}

func (q *Queries) exec(ctx context.Context, stmt *sql.Stmt, query string, args ...interface{}) (sql.Result, error) {
	switch {
	case stmt != nil && q.tx != nil:
		return q.tx.StmtContext(ctx, stmt).ExecContext(ctx, args...)
	case stmt != nil:
		return stmt.ExecContext(ctx, args...)
	default:
		return q.db.ExecContext(ctx, query, args...)
	}
}

func (q *Queries) query(ctx context.Context, stmt *sql.Stmt, query string, args ...interface{}) (*sql.Rows, error) {
	switch {
	case stmt != nil && q.tx != nil:
		return q.tx.StmtContext(ctx, stmt).QueryContext(ctx, args...)
	case stmt != nil:
		return stmt.QueryContext(ctx, args...)
	default:
		return q.db.QueryContext(ctx, query, args...)
	}
}

func (q *Queries) queryRow(ctx context.Context, stmt *sql.Stmt, query string, args ...interface{}) *sql.Row {
	switch {
	case stmt != nil && q.tx != nil:
		return q.tx.StmtContext(ctx, stmt).QueryRowContext(ctx, args...)
	case stmt != nil:
		return stmt.QueryRowContext(ctx, args...)
	default:
		return q.db.QueryRowContext(ctx, query, args...)
	}
}

type Queries struct {
	db                          DBTX
	tx                          *sql.Tx
	createFileStmt              *sql.Stmt
	createMessageStmt           *sql.Stmt
	createSessionStmt           *sql.Stmt
	deleteFileStmt              *sql.Stmt
	deleteMessageStmt           *sql.Stmt
	deleteSessionStmt           *sql.Stmt
	deleteSessionFilesStmt      *sql.Stmt
	deleteSessionMessagesStmt   *sql.Stmt
	getFileStmt                 *sql.Stmt
	getFileByPathAndSessionStmt *sql.Stmt
	getMessageStmt              *sql.Stmt
	getSessionByIDStmt          *sql.Stmt
	listFilesByPathStmt         *sql.Stmt
	listFilesBySessionStmt      *sql.Stmt
	listLatestSessionFilesStmt  *sql.Stmt
	listMessagesBySessionStmt   *sql.Stmt
	listNewFilesStmt            *sql.Stmt
	listSessionsStmt            *sql.Stmt
	updateFileStmt              *sql.Stmt
	updateMessageStmt           *sql.Stmt
	updateSessionStmt           *sql.Stmt
}

func (q *Queries) WithTx(tx *sql.Tx) *Queries {
	return &Queries{
		db:                          tx,
		tx:                          tx,
		createFileStmt:              q.createFileStmt,
		createMessageStmt:           q.createMessageStmt,
		createSessionStmt:           q.createSessionStmt,
		deleteFileStmt:              q.deleteFileStmt,
		deleteMessageStmt:           q.deleteMessageStmt,
		deleteSessionStmt:           q.deleteSessionStmt,
		deleteSessionFilesStmt:      q.deleteSessionFilesStmt,
		deleteSessionMessagesStmt:   q.deleteSessionMessagesStmt,
		getFileStmt:                 q.getFileStmt,
		getFileByPathAndSessionStmt: q.getFileByPathAndSessionStmt,
		getMessageStmt:              q.getMessageStmt,
		getSessionByIDStmt:          q.getSessionByIDStmt,
		listFilesByPathStmt:         q.listFilesByPathStmt,
		listFilesBySessionStmt:      q.listFilesBySessionStmt,
		listLatestSessionFilesStmt:  q.listLatestSessionFilesStmt,
		listMessagesBySessionStmt:   q.listMessagesBySessionStmt,
		listNewFilesStmt:            q.listNewFilesStmt,
		listSessionsStmt:            q.listSessionsStmt,
		updateFileStmt:              q.updateFileStmt,
		updateMessageStmt:           q.updateMessageStmt,
		updateSessionStmt:           q.updateSessionStmt,
	}
}


================================================
FILE: internal/db/embed.go
================================================
package db

import "embed"

//go:embed migrations/*.sql
var FS embed.FS


================================================
FILE: internal/db/files.sql.go
================================================
// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.29.0
// source: files.sql

package db

import (
	"context"
)

const createFile = `-- name: CreateFile :one
INSERT INTO files (
    id,
    session_id,
    path,
    content,
    version,
    created_at,
    updated_at
) VALUES (
    ?, ?, ?, ?, ?, strftime('%s', 'now'), strftime('%s', 'now')
)
RETURNING id, session_id, path, content, version, created_at, updated_at
`

type CreateFileParams struct {
	ID        string `json:"id"`
	SessionID string `json:"session_id"`
	Path      string `json:"path"`
	Content   string `json:"content"`
	Version   string `json:"version"`
}

func (q *Queries) CreateFile(ctx context.Context, arg CreateFileParams) (File, error) {
	row := q.queryRow(ctx, q.createFileStmt, createFile,
		arg.ID,
		arg.SessionID,
		arg.Path,
		arg.Content,
		arg.Version,
	)
	var i File
	err := row.Scan(
		&i.ID,
		&i.SessionID,
		&i.Path,
		&i.Content,
		&i.Version,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const deleteFile = `-- name: DeleteFile :exec
DELETE FROM files
WHERE id = ?
`

func (q *Queries) DeleteFile(ctx context.Context, id string) error {
	_, err := q.exec(ctx, q.deleteFileStmt, deleteFile, id)
	return err
}

const deleteSessionFiles = `-- name: DeleteSessionFiles :exec
DELETE FROM files
WHERE session_id = ?
`

func (q *Queries) DeleteSessionFiles(ctx context.Context, sessionID string) error {
	_, err := q.exec(ctx, q.deleteSessionFilesStmt, deleteSessionFiles, sessionID)
	return err
}

const getFile = `-- name: GetFile :one
SELECT id, session_id, path, content, version, created_at, updated_at
FROM files
WHERE id = ? LIMIT 1
`

func (q *Queries) GetFile(ctx context.Context, id string) (File, error) {
	row := q.queryRow(ctx, q.getFileStmt, getFile, id)
	var i File
	err := row.Scan(
		&i.ID,
		&i.SessionID,
		&i.Path,
		&i.Content,
		&i.Version,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const getFileByPathAndSession = `-- name: GetFileByPathAndSession :one
SELECT id, session_id, path, content, version, created_at, updated_at
FROM files
WHERE path = ? AND session_id = ?
ORDER BY created_at DESC
LIMIT 1
`

type GetFileByPathAndSessionParams struct {
	Path      string `json:"path"`
	SessionID string `json:"session_id"`
}

func (q *Queries) GetFileByPathAndSession(ctx context.Context, arg GetFileByPathAndSessionParams) (File, error) {
	row := q.queryRow(ctx, q.getFileByPathAndSessionStmt, getFileByPathAndSession, arg.Path, arg.SessionID)
	var i File
	err := row.Scan(
		&i.ID,
		&i.SessionID,
		&i.Path,
		&i.Content,
		&i.Version,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const listFilesByPath = `-- name: ListFilesByPath :many
SELECT id, session_id, path, content, version, created_at, updated_at
FROM files
WHERE path = ?
ORDER BY created_at DESC
`

func (q *Queries) ListFilesByPath(ctx context.Context, path string) ([]File, error) {
	rows, err := q.query(ctx, q.listFilesByPathStmt, listFilesByPath, path)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []File{}
	for rows.Next() {
		var i File
		if err := rows.Scan(
			&i.ID,
			&i.SessionID,
			&i.Path,
			&i.Content,
			&i.Version,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listFilesBySession = `-- name: ListFilesBySession :many
SELECT id, session_id, path, content, version, created_at, updated_at
FROM files
WHERE session_id = ?
ORDER BY created_at ASC
`

func (q *Queries) ListFilesBySession(ctx context.Context, sessionID string) ([]File, error) {
	rows, err := q.query(ctx, q.listFilesBySessionStmt, listFilesBySession, sessionID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []File{}
	for rows.Next() {
		var i File
		if err := rows.Scan(
			&i.ID,
			&i.SessionID,
			&i.Path,
			&i.Content,
			&i.Version,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listLatestSessionFiles = `-- name: ListLatestSessionFiles :many
SELECT f.id, f.session_id, f.path, f.content, f.version, f.created_at, f.updated_at
FROM files f
INNER JOIN (
    SELECT path, MAX(created_at) as max_created_at
    FROM files
    GROUP BY path
) latest ON f.path = latest.path AND f.created_at = latest.max_created_at
WHERE f.session_id = ?
ORDER BY f.path
`

func (q *Queries) ListLatestSessionFiles(ctx context.Context, sessionID string) ([]File, error) {
	rows, err := q.query(ctx, q.listLatestSessionFilesStmt, listLatestSessionFiles, sessionID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []File{}
	for rows.Next() {
		var i File
		if err := rows.Scan(
			&i.ID,
			&i.SessionID,
			&i.Path,
			&i.Content,
			&i.Version,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listNewFiles = `-- name: ListNewFiles :many
SELECT id, session_id, path, content, version, created_at, updated_at
FROM files
WHERE is_new = 1
ORDER BY created_at DESC
`

func (q *Queries) ListNewFiles(ctx context.Context) ([]File, error) {
	rows, err := q.query(ctx, q.listNewFilesStmt, listNewFiles)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []File{}
	for rows.Next() {
		var i File
		if err := rows.Scan(
			&i.ID,
			&i.SessionID,
			&i.Path,
			&i.Content,
			&i.Version,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const updateFile = `-- name: UpdateFile :one
UPDATE files
SET
    content = ?,
    version = ?,
    updated_at = strftime('%s', 'now')
WHERE id = ?
RETURNING id, session_id, path, content, version, created_at, updated_at
`

type UpdateFileParams struct {
	Content string `json:"content"`
	Version string `json:"version"`
	ID      string `json:"id"`
}

func (q *Queries) UpdateFile(ctx context.Context, arg UpdateFileParams) (File, error) {
	row := q.queryRow(ctx, q.updateFileStmt, updateFile, arg.Content, arg.Version, arg.ID)
	var i File
	err := row.Scan(
		&i.ID,
		&i.SessionID,
		&i.Path,
		&i.Content,
		&i.Version,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}


================================================
FILE: internal/db/messages.sql.go
================================================
// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.29.0
// source: messages.sql

package db

import (
	"context"
	"database/sql"
)

const createMessage = `-- name: CreateMessage :one
INSERT INTO messages (
    id,
    session_id,
    role,
    parts,
    model,
    created_at,
    updated_at
) VALUES (
    ?, ?, ?, ?, ?, strftime('%s', 'now'), strftime('%s', 'now')
)
RETURNING id, session_id, role, parts, model, created_at, updated_at, finished_at
`

type CreateMessageParams struct {
	ID        string         `json:"id"`
	SessionID string         `json:"session_id"`
	Role      string         `json:"role"`
	Parts     string         `json:"parts"`
	Model     sql.NullString `json:"model"`
}

func (q *Queries) CreateMessage(ctx context.Context, arg CreateMessageParams) (Message, error) {
	row := q.queryRow(ctx, q.createMessageStmt, createMessage,
		arg.ID,
		arg.SessionID,
		arg.Role,
		arg.Parts,
		arg.Model,
	)
	var i Message
	err := row.Scan(
		&i.ID,
		&i.SessionID,
		&i.Role,
		&i.Parts,
		&i.Model,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.FinishedAt,
	)
	return i, err
}

const deleteMessage = `-- name: DeleteMessage :exec
DELETE FROM messages
WHERE id = ?
`

func (q *Queries) DeleteMessage(ctx context.Context, id string) error {
	_, err := q.exec(ctx, q.deleteMessageStmt, deleteMessage, id)
	return err
}

const deleteSessionMessages = `-- name: DeleteSessionMessages :exec
DELETE FROM messages
WHERE session_id = ?
`

func (q *Queries) DeleteSessionMessages(ctx context.Context, sessionID string) error {
	_, err := q.exec(ctx, q.deleteSessionMessagesStmt, deleteSessionMessages, sessionID)
	return err
}

const getMessage = `-- name: GetMessage :one
SELECT id, session_id, role, parts, model, created_at, updated_at, finished_at
FROM messages
WHERE id = ? LIMIT 1
`

func (q *Queries) GetMessage(ctx context.Context, id string) (Message, error) {
	row := q.queryRow(ctx, q.getMessageStmt, getMessage, id)
	var i Message
	err := row.Scan(
		&i.ID,
		&i.SessionID,
		&i.Role,
		&i.Parts,
		&i.Model,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.FinishedAt,
	)
	return i, err
}

const listMessagesBySession = `-- name: ListMessagesBySession :many
SELECT id, session_id, role, parts, model, created_at, updated_at, finished_at
FROM messages
WHERE session_id = ?
ORDER BY created_at ASC
`

func (q *Queries) ListMessagesBySession(ctx context.Context, sessionID string) ([]Message, error) {
	rows, err := q.query(ctx, q.listMessagesBySessionStmt, listMessagesBySession, sessionID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Message{}
	for rows.Next() {
		var i Message
		if err := rows.Scan(
			&i.ID,
			&i.SessionID,
			&i.Role,
			&i.Parts,
			&i.Model,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.FinishedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const updateMessage = `-- name: UpdateMessage :exec
UPDATE messages
SET
    parts = ?,
    finished_at = ?,
    updated_at = strftime('%s', 'now')
WHERE id = ?
`

type UpdateMessageParams struct {
	Parts      string        `json:"parts"`
	FinishedAt sql.NullInt64 `json:"finished_at"`
	ID         string        `json:"id"`
}

func (q *Queries) UpdateMessage(ctx context.Context, arg UpdateMessageParams) error {
	_, err := q.exec(ctx, q.updateMessageStmt, updateMessage, arg.Parts, arg.FinishedAt, arg.ID)
	return err
}


================================================
FILE: internal/db/migrations/20250424200609_initial.sql
================================================
-- +goose Up
-- +goose StatementBegin
-- Sessions
CREATE TABLE IF NOT EXISTS sessions (
    id TEXT PRIMARY KEY,
    parent_session_id TEXT,
    title TEXT NOT NULL,
    message_count INTEGER NOT NULL DEFAULT 0 CHECK (message_count >= 0),
    prompt_tokens  INTEGER NOT NULL DEFAULT 0 CHECK (prompt_tokens >= 0),
    completion_tokens  INTEGER NOT NULL DEFAULT 0 CHECK (completion_tokens>= 0),
    cost REAL NOT NULL DEFAULT 0.0 CHECK (cost >= 0.0),
    updated_at INTEGER NOT NULL,  -- Unix timestamp in milliseconds
    created_at INTEGER NOT NULL   -- Unix timestamp in milliseconds
);

CREATE TRIGGER IF NOT EXISTS update_sessions_updated_at
AFTER UPDATE ON sessions
BEGIN
UPDATE sessions SET updated_at = strftime('%s', 'now')
WHERE id = new.id;
END;

-- Files
CREATE TABLE IF NOT EXISTS files (
    id TEXT PRIMARY KEY,
    session_id TEXT NOT NULL,
    path TEXT NOT NULL,
    content TEXT NOT NULL,
    version TEXT NOT NULL,
    created_at INTEGER NOT NULL,  -- Unix timestamp in milliseconds
    updated_at INTEGER NOT NULL,  -- Unix timestamp in milliseconds
    FOREIGN KEY (session_id) REFERENCES sessions (id) ON DELETE CASCADE,
    UNIQUE(path, session_id, version)
);

CREATE INDEX IF NOT EXISTS idx_files_session_id ON files (session_id);
CREATE INDEX IF NOT EXISTS idx_files_path ON files (path);

CREATE TRIGGER IF NOT EXISTS update_files_updated_at
AFTER UPDATE ON files
BEGIN
UPDATE files SET updated_at = strftime('%s', 'now')
WHERE id = new.id;
END;

-- Messages
CREATE TABLE IF NOT EXISTS messages (
    id TEXT PRIMARY KEY,
    session_id TEXT NOT NULL,
    role TEXT NOT NULL,
    parts TEXT NOT NULL default '[]',
    model TEXT,
    created_at INTEGER NOT NULL,  -- Unix timestamp in milliseconds
    updated_at INTEGER NOT NULL,  -- Unix timestamp in milliseconds
    finished_at INTEGER,  -- Unix timestamp in milliseconds
    FOREIGN KEY (session_id) REFERENCES sessions (id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS idx_messages_session_id ON messages (session_id);

CREATE TRIGGER IF NOT EXISTS update_messages_updated_at
AFTER UPDATE ON messages
BEGIN
UPDATE messages SET updated_at = strftime('%s', 'now')
WHERE id = new.id;
END;

CREATE TRIGGER IF NOT EXISTS update_session_message_count_on_insert
AFTER INSERT ON messages
BEGIN
UPDATE sessions SET
    message_count = message_count + 1
WHERE id = new.session_id;
END;

CREATE TRIGGER IF NOT EXISTS update_session_message_count_on_delete
AFTER DELETE ON messages
BEGIN
UPDATE sessions SET
    message_count = message_count - 1
WHERE id = old.session_id;
END;

-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
DROP TRIGGER IF EXISTS update_sessions_updated_at;
DROP TRIGGER IF EXISTS update_messages_updated_at;
DROP TRIGGER IF EXISTS update_files_updated_at;

DROP TRIGGER IF EXISTS update_session_message_count_on_delete;
DROP TRIGGER IF EXISTS update_session_message_count_on_insert;

DROP TABLE IF EXISTS sessions;
DROP TABLE IF EXISTS messages;
DROP TABLE IF EXISTS files;
-- +goose StatementEnd


================================================
FILE: internal/db/migrations/20250515105448_add_summary_message_id.sql
================================================
-- +goose Up
-- +goose StatementBegin
ALTER TABLE sessions ADD COLUMN summary_message_id TEXT;
-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
ALTER TABLE sessions DROP COLUMN summary_message_id;
-- +goose StatementEnd


================================================
FILE: internal/db/models.go
================================================
// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.29.0

package db

import (
	"database/sql"
)

type File struct {
	ID        string `json:"id"`
	SessionID string `json:"session_id"`
	Path      string `json:"path"`
	Content   string `json:"content"`
	Version   string `json:"version"`
	CreatedAt int64  `json:"created_at"`
	UpdatedAt int64  `json:"updated_at"`
}

type Message struct {
	ID         string         `json:"id"`
	SessionID  string         `json:"session_id"`
	Role       string         `json:"role"`
	Parts      string         `json:"parts"`
	Model      sql.NullString `json:"model"`
	CreatedAt  int64          `json:"created_at"`
	UpdatedAt  int64          `json:"updated_at"`
	FinishedAt sql.NullInt64  `json:"finished_at"`
}

type Session struct {
	ID               string         `json:"id"`
	ParentSessionID  sql.NullString `json:"parent_session_id"`
	Title            string         `json:"title"`
	MessageCount     int64          `json:"message_count"`
	PromptTokens     int64          `json:"prompt_tokens"`
	CompletionTokens int64          `json:"completion_tokens"`
	Cost             float64        `json:"cost"`
	UpdatedAt        int64          `json:"updated_at"`
	CreatedAt        int64          `json:"created_at"`
	SummaryMessageID sql.NullString `json:"summary_message_id"`
}


================================================
FILE: internal/db/querier.go
================================================
// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.29.0

package db

import (
	"context"
)

type Querier interface {
	CreateFile(ctx context.Context, arg CreateFileParams) (File, error)
	CreateMessage(ctx context.Context, arg CreateMessageParams) (Message, error)
	CreateSession(ctx context.Context, arg CreateSessionParams) (Session, error)
	DeleteFile(ctx context.Context, id string) error
	DeleteMessage(ctx context.Context, id string) error
	DeleteSession(ctx context.Context, id string) error
	DeleteSessionFiles(ctx context.Context, sessionID string) error
	DeleteSessionMessages(ctx context.Context, sessionID string) error
	GetFile(ctx context.Context, id string) (File, error)
	GetFileByPathAndSession(ctx context.Context, arg GetFileByPathAndSessionParams) (File, error)
	GetMessage(ctx context.Context, id string) (Message, error)
	GetSessionByID(ctx context.Context, id string) (Session, error)
	ListFilesByPath(ctx context.Context, path string) ([]File, error)
	ListFilesBySession(ctx context.Context, sessionID string) ([]File, error)
	ListLatestSessionFiles(ctx context.Context, sessionID string) ([]File, error)
	ListMessagesBySession(ctx context.Context, sessionID string) ([]Message, error)
	ListNewFiles(ctx context.Context) ([]File, error)
	ListSessions(ctx context.Context) ([]Session, error)
	UpdateFile(ctx context.Context, arg UpdateFileParams) (File, error)
	UpdateMessage(ctx context.Context, arg UpdateMessageParams) error
	UpdateSession(ctx context.Context, arg UpdateSessionParams) (Session, error)
}

var _ Querier = (*Queries)(nil)


================================================
FILE: internal/db/sessions.sql.go
================================================
// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.29.0
// source: sessions.sql

package db

import (
	"context"
	"database/sql"
)

const createSession = `-- name: CreateSession :one
INSERT INTO sessions (
    id,
    parent_session_id,
    title,
    message_count,
    prompt_tokens,
    completion_tokens,
    cost,
    summary_message_id,
    updated_at,
    created_at
) VALUES (
    ?,
    ?,
    ?,
    ?,
    ?,
    ?,
    ?,
    null,
    strftime('%s', 'now'),
    strftime('%s', 'now')
) RETURNING id, parent_session_id, title, message_count, prompt_tokens, completion_tokens, cost, updated_at, created_at, summary_message_id
`

type CreateSessionParams struct {
	ID               string         `json:"id"`
	ParentSessionID  sql.NullString `json:"parent_session_id"`
	Title            string         `json:"title"`
	MessageCount     int64          `json:"message_count"`
	PromptTokens     int64          `json:"prompt_tokens"`
	CompletionTokens int64          `json:"completion_tokens"`
	Cost             float64        `json:"cost"`
}

func (q *Queries) CreateSession(ctx context.Context, arg CreateSessionParams) (Session, error) {
	row := q.queryRow(ctx, q.createSessionStmt, createSession,
		arg.ID,
		arg.ParentSessionID,
		arg.Title,
		arg.MessageCount,
		arg.PromptTokens,
		arg.CompletionTokens,
		arg.Cost,
	)
	var i Session
	err := row.Scan(
		&i.ID,
		&i.ParentSessionID,
		&i.Title,
		&i.MessageCount,
		&i.PromptTokens,
		&i.CompletionTokens,
		&i.Cost,
		&i.UpdatedAt,
		&i.CreatedAt,
		&i.SummaryMessageID,
	)
	return i, err
}

const deleteSession = `-- name: DeleteSession :exec
DELETE FROM sessions
WHERE id = ?
`

func (q *Queries) DeleteSession(ctx context.Context, id string) error {
	_, err := q.exec(ctx, q.deleteSessionStmt, deleteSession, id)
	return err
}

const getSessionByID = `-- name: GetSessionByID :one
SELECT id, parent_session_id, title, message_count, prompt_tokens, completion_tokens, cost, updated_at, created_at, summary_message_id
FROM sessions
WHERE id = ? LIMIT 1
`

func (q *Queries) GetSessionByID(ctx context.Context, id string) (Session, error) {
	row := q.queryRow(ctx, q.getSessionByIDStmt, getSessionByID, id)
	var i Session
	err := row.Scan(
		&i.ID,
		&i.ParentSessionID,
		&i.Title,
		&i.MessageCount,
		&i.PromptTokens,
		&i.CompletionTokens,
		&i.Cost,
		&i.UpdatedAt,
		&i.CreatedAt,
		&i.SummaryMessageID,
	)
	return i, err
}

const listSessions = `-- name: ListSessions :many
SELECT id, parent_session_id, title, message_count, prompt_tokens, completion_tokens, cost, updated_at, created_at, summary_message_id
FROM sessions
WHERE parent_session_id is NULL
ORDER BY created_at DESC
`

func (q *Queries) ListSessions(ctx context.Context) ([]Session, error) {
	rows, err := q.query(ctx, q.listSessionsStmt, listSessions)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Session{}
	for rows.Next() {
		var i Session
		if err := rows.Scan(
			&i.ID,
			&i.ParentSessionID,
			&i.Title,
			&i.MessageCount,
			&i.PromptTokens,
			&i.CompletionTokens,
			&i.Cost,
			&i.UpdatedAt,
			&i.CreatedAt,
			&i.SummaryMessageID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const updateSession = `-- name: UpdateSession :one
UPDATE sessions
SET
    title = ?,
    prompt_tokens = ?,
    completion_tokens = ?,
    summary_message_id = ?,
    cost = ?
WHERE id = ?
RETURNING id, parent_session_id, title, message_count, prompt_tokens, completion_tokens, cost, updated_at, created_at, summary_message_id
`

type UpdateSessionParams struct {
	Title            string         `json:"title"`
	PromptTokens     int64          `json:"prompt_tokens"`
	CompletionTokens int64          `json:"completion_tokens"`
	SummaryMessageID sql.NullString `json:"summary_message_id"`
	Cost             float64        `json:"cost"`
	ID               string         `json:"id"`
}

func (q *Queries) UpdateSession(ctx context.Context, arg UpdateSessionParams) (Session, error) {
	row := q.queryRow(ctx, q.updateSessionStmt, updateSession,
		arg.Title,
		arg.PromptTokens,
		arg.CompletionTokens,
		arg.SummaryMessageID,
		arg.Cost,
		arg.ID,
	)
	var i Session
	err := row.Scan(
		&i.ID,
		&i.ParentSessionID,
		&i.Title,
		&i.MessageCount,
		&i.PromptTokens,
		&i.CompletionTokens,
		&i.Cost,
		&i.UpdatedAt,
		&i.CreatedAt,
		&i.SummaryMessageID,
	)
	return i, err
}


================================================
FILE: internal/db/sql/files.sql
================================================
-- name: GetFile :one
SELECT *
FROM files
WHERE id = ? LIMIT 1;

-- name: GetFileByPathAndSession :one
SELECT *
FROM files
WHERE path = ? AND session_id = ?
ORDER BY created_at DESC
LIMIT 1;

-- name: ListFilesBySession :many
SELECT *
FROM files
WHERE session_id = ?
ORDER BY created_at ASC;

-- name: ListFilesByPath :many
SELECT *
FROM files
WHERE path = ?
ORDER BY created_at DESC;

-- name: CreateFile :one
INSERT INTO files (
    id,
    session_id,
    path,
    content,
    version,
    created_at,
    updated_at
) VALUES (
    ?, ?, ?, ?, ?, strftime('%s', 'now'), strftime('%s', 'now')
)
RETURNING *;

-- name: UpdateFile :one
UPDATE files
SET
    content = ?,
    version = ?,
    updated_at = strftime('%s', 'now')
WHERE id = ?
RETURNING *;

-- name: DeleteFile :exec
DELETE FROM files
WHERE id = ?;

-- name: DeleteSessionFiles :exec
DELETE FROM files
WHERE session_id = ?;

-- name: ListLatestSessionFiles :many
SELECT f.*
FROM files f
INNER JOIN (
    SELECT path, MAX(created_at) as max_created_at
    FROM files
    GROUP BY path
) latest ON f.path = latest.path AND f.created_at = latest.max_created_at
WHERE f.session_id = ?
ORDER BY f.path;

-- name: ListNewFiles :many
SELECT *
FROM files
WHERE is_new = 1
ORDER BY created_at DESC;


================================================
FILE: internal/db/sql/messages.sql
================================================
-- name: GetMessage :one
SELECT *
FROM messages
WHERE id = ? LIMIT 1;

-- name: ListMessagesBySession :many
SELECT *
FROM messages
WHERE session_id = ?
ORDER BY created_at ASC;

-- name: CreateMessage :one
INSERT INTO messages (
    id,
    session_id,
    role,
    parts,
    model,
    created_at,
    updated_at
) VALUES (
    ?, ?, ?, ?, ?, strftime('%s', 'now'), strftime('%s', 'now')
)
RETURNING *;

-- name: UpdateMessage :exec
UPDATE messages
SET
    parts = ?,
    finished_at = ?,
    updated_at = strftime('%s', 'now')
WHERE id = ?;


-- name: DeleteMessage :exec
DELETE FROM messages
WHERE id = ?;

-- name: DeleteSessionMessages :exec
DELETE FROM messages
WHERE session_id = ?;


================================================
FILE: internal/db/sql/sessions.sql
================================================
-- name: CreateSession :one
INSERT INTO sessions (
    id,
    parent_session_id,
    title,
    message_count,
    prompt_tokens,
    completion_tokens,
    cost,
    summary_message_id,
    updated_at,
    created_at
) VALUES (
    ?,
    ?,
    ?,
    ?,
    ?,
    ?,
    ?,
    null,
    strftime('%s', 'now'),
    strftime('%s', 'now')
) RETURNING *;

-- name: GetSessionByID :one
SELECT *
FROM sessions
WHERE id = ? LIMIT 1;

-- name: ListSessions :many
SELECT *
FROM sessions
WHERE parent_session_id is NULL
ORDER BY created_at DESC;

-- name: UpdateSession :one
UPDATE sessions
SET
    title = ?,
    prompt_tokens = ?,
    completion_tokens = ?,
    summary_message_id = ?,
    cost = ?
WHERE id = ?
RETURNING *;


-- name: DeleteSession :exec
DELETE FROM sessions
WHERE id = ?;


================================================
FILE: internal/diff/diff.go
================================================
package diff

import (
	"bytes"
	"fmt"
	"io"
	"regexp"
	"strconv"
	"strings"

	"github.com/alecthomas/chroma/v2"
	"github.com/alecthomas/chroma/v2/formatters"
	"github.com/alecthomas/chroma/v2/lexers"
	"github.com/alecthomas/chroma/v2/styles"
	"github.com/aymanbagabas/go-udiff"
	"github.com/charmbracelet/lipgloss"
	"github.com/charmbracelet/x/ansi"
	"github.com/opencode-ai/opencode/internal/config"
	"github.com/opencode-ai/opencode/internal/tui/theme"
	"github.com/sergi/go-diff/diffmatchpatch"
)

// -------------------------------------------------------------------------
// Core Types
// -------------------------------------------------------------------------

// LineType represents the kind of line in a diff.
type LineType int

const (
	LineContext LineType = iota // Line exists in both files
	LineAdded                   // Line added in the new file
	LineRemoved                 // Line removed from the old file
)

// Segment represents a portion of a line for intra-line highlighting
type Segment struct {
	Start int
	End   int
	Type  LineType
	Text  string
}

// DiffLine represents a single line in a diff
type DiffLine struct {
	OldLineNo int       // Line number in old file (0 for added lines)
	NewLineNo int       // Line number in new file (0 for removed lines)
	Kind      LineType  // Type of line (added, removed, context)
	Content   string    // Content of the line
	Segments  []Segment // Segments for intraline highlighting
}

// Hunk represents a section of changes in a diff
type Hunk struct {
	Header string
	Lines  []DiffLine
}

// DiffResult contains the parsed result of a diff
type DiffResult struct {
	OldFile string
	NewFile string
	Hunks   []Hunk
}

// linePair represents a pair of lines for side-by-side display
type linePair struct {
	left  *DiffLine
	right *DiffLine
}

// -------------------------------------------------------------------------
// Parse Configuration
// -------------------------------------------------------------------------

// ParseConfig configures the behavior of diff parsing
type ParseConfig struct {
	ContextSize int // Number of context lines to include
}

// ParseOption modifies a ParseConfig
type ParseOption func(*ParseConfig)

// WithContextSize sets the number of context lines to include
func WithContextSize(size int) ParseOption {
	return func(p *ParseConfig) {
		if size >= 0 {
			p.ContextSize = size
		}
	}
}

// -------------------------------------------------------------------------
// Side-by-Side Configuration
// -------------------------------------------------------------------------

// SideBySideConfig configures the rendering of side-by-side diffs
type SideBySideConfig struct {
	TotalWidth int
}

// SideBySideOption modifies a SideBySideConfig
type SideBySideOption func(*SideBySideConfig)

// NewSideBySideConfig creates a SideBySideConfig with default values
func NewSideBySideConfig(opts ...SideBySideOption) SideBySideConfig {
	config := SideBySideConfig{
		TotalWidth: 160, // Default width for side-by-side view
	}

	for _, opt := range opts {
		opt(&config)
	}

	return config
}

// WithTotalWidth sets the total width for side-by-side view
func WithTotalWidth(width int) SideBySideOption {
	return func(s *SideBySideConfig) {
		if width > 0 {
			s.TotalWidth = width
		}
	}
}

// -------------------------------------------------------------------------
// Diff Parsing
// -------------------------------------------------------------------------

// ParseUnifiedDiff parses a unified diff format string into structured data
func ParseUnifiedDiff(diff string) (DiffResult, error) {
	var result DiffResult
	var currentHunk *Hunk

	hunkHeaderRe := regexp.MustCompile(`^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@`)
	lines := strings.Split(diff, "\n")

	var oldLine, newLine int
	inFileHeader := true

	for _, line := range lines {
		// Parse file headers
		if inFileHeader {
			if strings.HasPrefix(line, "--- a/") {
				result.OldFile = strings.TrimPrefix(line, "--- a/")
				continue
			}
			if strings.HasPrefix(line, "+++ b/") {
				result.NewFile = strings.TrimPrefix(line, "+++ b/")
				inFileHeader = false
				continue
			}
		}

		// Parse hunk headers
		if matches := hunkHeaderRe.FindStringSubmatch(line); matches != nil {
			if currentHunk != nil {
				result.Hunks = append(result.Hunks, *currentHunk)
			}
			currentHunk = &Hunk{
				Header: line,
				Lines:  []DiffLine{},
			}

			oldStart, _ := strconv.Atoi(matches[1])
			newStart, _ := strconv.Atoi(matches[3])
			oldLine = oldStart
			newLine = newStart
			continue
		}

		// Ignore "No newline at end of file" markers
		if strings.HasPrefix(line, "\\ No newline at end of file") {
			continue
		}

		if currentHunk == nil {
			continue
		}

		// Process the line based on its prefix
		if len(line) > 0 {
			switch line[0] {
			case '+':
				currentHunk.Lines = append(currentHunk.Lines, DiffLine{
					OldLineNo: 0,
					NewLineNo: newLine,
					Kind:      LineAdded,
					Content:   line[1:],
				})
				newLine++
			case '-':
				currentHunk.Lines = append(currentHunk.Lines, DiffLine{
					OldLineNo: oldLine,
					NewLineNo: 0,
					Kind:      LineRemoved,
					Content:   line[1:],
				})
				oldLine++
			default:
				currentHunk.Lines = append(currentHunk.Lines, DiffLine{
					OldLineNo: oldLine,
					NewLineNo: newLine,
					Kind:      LineContext,
					Content:   line,
				})
				oldLine++
				newLine++
			}
		} else {
			// Handle empty lines
			currentHunk.Lines = append(currentHunk.Lines, DiffLine{
				OldLineNo: oldLine,
				NewLineNo: newLine,
				Kind:      LineContext,
				Content:   "",
			})
			oldLine++
			newLine++
		}
	}

	// Add the last hunk if there is one
	if currentHunk != nil {
		result.Hunks = append(result.Hunks, *currentHunk)
	}

	return result, nil
}

// HighlightIntralineChanges updates lines in a hunk to show character-level differences
func HighlightIntralineChanges(h *Hunk) {
	var updated []DiffLine
	dmp := diffmatchpatch.New()

	for i := 0; i < len(h.Lines); i++ {
		// Look for removed line followed by added line
		if i+1 < len(h.Lines) &&
			h.Lines[i].Kind == LineRemoved &&
			h.Lines[i+1].Kind == LineAdded {

			oldLine := h.Lines[i]
			newLine := h.Lines[i+1]

			// Find character-level differences
			patches := dmp.DiffMain(oldLine.Content, newLine.Content, false)
			patches = dmp.DiffCleanupSemantic(patches)
			patches = dmp.DiffCleanupMerge(patches)
			patches = dmp.DiffCleanupEfficiency(patches)

			segments := make([]Segment, 0)

			removeStart := 0
			addStart := 0
			for _, patch := range patches {
				switch patch.Type {
				case diffmatchpatch.DiffDelete:
					segments = append(segments, Segment{
						Start: removeStart,
						End:   removeStart + len(patch.Text),
						Type:  LineRemoved,
						Text:  patch.Text,
					})
					removeStart += len(patch.Text)
				case diffmatchpatch.DiffInsert:
					segments = append(segments, Segment{
						Start: addStart,
						End:   addStart + len(patch.Text),
						Type:  LineAdded,
						Text:  patch.Text,
					})
					addStart += len(patch.Text)
				default:
					// Context text, no highlighting needed
					removeStart += len(patch.Text)
					addStart += len(patch.Text)
				}
			}
			oldLine.Segments = segments
			newLine.Segments = segments

			updated = append(updated, oldLine, newLine)
			i++ // Skip the next line as we've already processed it
		} else {
			updated = append(updated, h.Lines[i])
		}
	}

	h.Lines = updated
}

// pairLines converts a flat list of diff lines to pairs for side-by-side display
func pairLines(lines []DiffLine) []linePair {
	var pairs []linePair
	i := 0

	for i < len(lines) {
		switch lines[i].Kind {
		case LineRemoved:
			// Check if the next line is an addition, if so pair them
			if i+1 < len(lines) && lines[i+1].Kind == LineAdded {
				pairs = append(pairs, linePair{left: &lines[i], right: &lines[i+1]})
				i += 2
			} else {
				pairs = append(pairs, linePair{left: &lines[i], right: nil})
				i++
			}
		case LineAdded:
			pairs = append(pairs, linePair{left: nil, right: &lines[i]})
			i++
		case LineContext:
			pairs = append(pairs, linePair{left: &lines[i], right: &lines[i]})
			i++
		}
	}

	return pairs
}

// -------------------------------------------------------------------------
// Syntax Highlighting
// -------------------------------------------------------------------------

// SyntaxHighlight applies syntax highlighting to text based on file extension
func SyntaxHighlight(w io.Writer, source, fileName, formatter string, bg lipgloss.TerminalColor) error {
	t := theme.CurrentTheme()

	// Determine the language lexer to use
	l := lexers.Match(fileName)
	if l == nil {
		l = lexers.Analyse(source)
	}
	if l == nil {
		l = lexers.Fallback
	}
	l = chroma.Coalesce(l)

	// Get the formatter
	f := formatters.Get(formatter)
	if f == nil {
		f = formatters.Fallback
	}

	// Dynamic theme based on current theme values
	syntaxThemeXml := fmt.Sprintf(`
	<style name="opencode-theme">
	<!-- Base colors -->
	<entry type="Background" style="bg:%s"/>
	<entry type="Text" style="%s"/>
	<entry type="Other" style="%s"/>
	<entry type="Error" style="%s"/>
	<!-- Keywords -->
	<entry type="Keyword" style="%s"/>
	<entry type="KeywordConstant" style="%s"/>
	<entry type="KeywordDeclaration" style="%s"/>
	<entry type="KeywordNamespace" style="%s"/>
	<entry type="KeywordPseudo" style="%s"/>
	<entry type="KeywordReserved" style="%s"/>
	<entry type="KeywordType" style="%s"/>
	<!-- Names -->
	<entry type="Name" style="%s"/>
	<entry type="NameAttribute" style="%s"/>
	<entry type="NameBuiltin" style="%s"/>
	<entry type="NameBuiltinPseudo" style="%s"/>
	<entry type="NameClass" style="%s"/>
	<entry type="NameConstant" style="%s"/>
	<entry type="NameDecorator" style="%s"/>
	<entry type="NameEntity" style="%s"/>
	<entry type="NameException" style="%s"/>
	<entry type="NameFunction" style="%s"/>
	<entry type="NameLabel" style="%s"/>
	<entry type="NameNamespace" style="%s"/>
	<entry type="NameOther" style="%s"/>
	<entry type="NameTag" style="%s"/>
	<entry type="NameVariable" style="%s"/>
	<entry type="NameVariableClass" style="%s"/>
	<entry type="NameVariableGlobal" style="%s"/>
	<entry type="NameVariableInstance" style="%s"/>
	<!-- Literals -->
	<entry type="Literal" style="%s"/>
	<entry type="LiteralDate" style="%s"/>
	<entry type="LiteralString" style="%s"/>
	<entry type="LiteralStringBacktick" style="%s"/>
	<entry type="LiteralStringChar" style="%s"/>
	<entry type="LiteralStringDoc" style="%s"/>
	<entry type="LiteralStringDouble" style="%s"/>
	<entry type="LiteralStringEscape" style="%s"/>
	<entry type="LiteralStringHeredoc" style="%s"/>
	<entry type="LiteralStringInterpol" style="%s"/>
	<entry type="LiteralStringOther" style="%s"/>
	<entry type="LiteralStringRegex" style="%s"/>
	<entry type="LiteralStringSingle" style="%s"/>
	<entry type="LiteralStringSymbol" style="%s"/>
	<!-- Numbers -->
	<entry type="LiteralNumber" style="%s"/>
	<entry type="LiteralNumberBin" style="%s"/>
	<entry type="LiteralNumberFloat" style="%s"/>
	<entry type="LiteralNumberHex" style="%s"/>
	<entry type="LiteralNumberInteger" style="%s"/>
	<entry type="LiteralNumberIntegerLong" style="%s"/>
	<entry type="LiteralNumberOct" style="%s"/>
	<!-- Operators -->
	<entry type="Operator" style="%s"/>
	<entry type="OperatorWord" style="%s"/>
	<entry type="Punctuation" style="%s"/>
	<!-- Comments -->
	<entry type="Comment" style="%s"/>
	<entry type="CommentHashbang" style="%s"/>
	<entry type="CommentMultiline" style="%s"/>
	<entry type="CommentSingle" style="%s"/>
	<entry type="CommentSpecial" style="%s"/>
	<entry type="CommentPreproc" style="%s"/>
	<!-- Generic styles -->
	<entry type="Generic" style="%s"/>
	<entry type="GenericDeleted" style="%s"/>
	<entry type="GenericEmph" style="italic %s"/>
	<entry type="GenericError" style="%s"/>
	<entry type="GenericHeading" style="bold %s"/>
	<entry type="GenericInserted" style="%s"/>
	<entry type="GenericOutput" style="%s"/>
	<entry type="GenericPrompt" style="%s"/>
	<entry type="GenericStrong" style="bold %s"/>
	<entry type="GenericSubheading" style="bold %s"/>
	<entry type="GenericTraceback" style="%s"/>
	<entry type="GenericUnderline" style="underline"/>
	<entry type="TextWhitespace" style="%s"/>
</style>
`,
		getColor(t.Background()), // Background
		getColor(t.Text()),       // Text
		getColor(t.Text()),       // Other
		getColor(t.Error()),      // Error

		getColor(t.SyntaxKeyword()), // Keyword
		getColor(t.SyntaxKeyword()), // KeywordConstant
		getColor(t.SyntaxKeyword()), // KeywordDeclaration
		getColor(t.SyntaxKeyword()), // KeywordNamespace
		getColor(t.SyntaxKeyword()), // KeywordPseudo
		getColor(t.SyntaxKeyword()), // KeywordReserved
		getColor(t.SyntaxType()),    // KeywordType

		getColor(t.Text()),           // Name
		getColor(t.SyntaxVariable()), // NameAttribute
		getColor(t.SyntaxType()),     // NameBuiltin
		getColor(t.SyntaxVariable()), // NameBuiltinPseudo
		getColor(t.SyntaxType()),     // NameClass
		getColor(t.SyntaxVariable()), // NameConstant
		getColor(t.SyntaxFunction()), // NameDecorator
		getColor(t.SyntaxVariable()), // NameEntity
		getColor(t.SyntaxType()),     // NameException
		getColor(t.SyntaxFunction()), // NameFunction
		getColor(t.Text()),           // NameLabel
		getColor(t.SyntaxType()),     // NameNamespace
		getColor(t.SyntaxVariable()), // NameOther
		getColor(t.SyntaxKeyword()),  // NameTag
		getColor(t.SyntaxVariable()), // NameVariable
		getColor(t.SyntaxVariable()), // NameVariableClass
		getColor(t.SyntaxVariable()), // NameVariableGlobal
		getColor(t.SyntaxVariable()), // NameVariableInstance

		getColor(t.SyntaxString()), // Literal
		getColor(t.SyntaxString()), // LiteralDate
		getColor(t.SyntaxString()), // LiteralString
		getColor(t.SyntaxString()), // LiteralStringBacktick
		getColor(t.SyntaxString()), // LiteralStringChar
		getColor(t.SyntaxString()), // LiteralStringDoc
		getColor(t.SyntaxString()), // LiteralStringDouble
		getColor(t.SyntaxString()), // LiteralStringEscape
		getColor(t.SyntaxString()), // LiteralStringHeredoc
		getColor(t.SyntaxString()), // LiteralStringInterpol
		getColor(t.SyntaxString()), // LiteralStringOther
		getColor(t.SyntaxString()), // LiteralStringRegex
		getColor(t.SyntaxString()), // LiteralStringSingle
		getColor(t.SyntaxString()), // LiteralStringSymbol

		getColor(t.SyntaxNumber()), // LiteralNumber
		getColor(t.SyntaxNumber()), // LiteralNumberBin
		getColor(t.SyntaxNumber()), // LiteralNumberFloat
		getColor(t.SyntaxNumber()), // LiteralNumberHex
		getColor(t.SyntaxNumber()), // LiteralNumberInteger
		getColor(t.SyntaxNumber()), // LiteralNumberIntegerLong
		getColor(t.SyntaxNumber()), // LiteralNumberOct

		getColor(t.SyntaxOperator()),    // Operator
		getColor(t.SyntaxKeyword()),     // OperatorWord
		getColor(t.SyntaxPunctuation()), // Punctuation

		getColor(t.SyntaxComment()), // Comment
		getColor(t.SyntaxComment()), // CommentHashbang
		getColor(t.SyntaxComment()), // CommentMultiline
		getColor(t.SyntaxComment()), // CommentSingle
		getColor(t.SyntaxComment()), // CommentSpecial
		getColor(t.SyntaxKeyword()), // CommentPreproc

		getColor(t.Text()),      // Generic
		getColor(t.Error()),     // GenericDeleted
		getColor(t.Text()),      // GenericEmph
		getColor(t.Error()),     // GenericError
		getColor(t.Text()),      // GenericHeading
		getColor(t.Success()),   // GenericInserted
		getColor(t.TextMuted()), // GenericOutput
		getColor(t.Text()),      // GenericPrompt
		getColor(t.Text()),      // GenericStrong
		getColor(t.Text()),      // GenericSubheading
		getColor(t.Error()),     // GenericTraceback
		getColor(t.Text()),      // TextWhitespace
	)

	r := strings.NewReader(syntaxThemeXml)
	style := chroma.MustNewXMLStyle(r)

	// Modify the style to use the provided background
	s, err := style.Builder().Transform(
		func(t chroma.StyleEntry) chroma.StyleEntry {
			r, g, b, _ := bg.RGBA()
			t.Background = chroma.NewColour(uint8(r>>8), uint8(g>>8), uint8(b>>8))
			return t
		},
	).Build()
	if err != nil {
		s = styles.Fallback
	}

	// Tokenize and format
	it, err := l.Tokenise(nil, source)
	if err != nil {
		return err
	}

	return f.Format(w, s, it)
}

// getColor returns the appropriate hex color string based on terminal background
func getColor(adaptiveColor lipgloss.AdaptiveColor) string {
	if lipgloss.HasDarkBackground() {
		return adaptiveColor.Dark
	}
	return adaptiveColor.Light
}

// highlightLine applies syntax highlighting to a single line
func highlightLine(fileName string, line string, bg lipgloss.TerminalColor) string {
	var buf bytes.Buffer
	err := SyntaxHighlight(&buf, line, fileName, "terminal16m", bg)
	if err != nil {
		return line
	}
	return buf.String()
}

// createStyles generates the lipgloss styles needed for rendering diffs
func createStyles(t theme.Theme) (removedLineStyle, addedLineStyle, contextLineStyle, lineNumberStyle lipgloss.Style) {
	removedLineStyle = lipgloss.NewStyle().Background(t.DiffRemovedBg())
	addedLineStyle = lipgloss.NewStyle().Background(t.DiffAddedBg())
	contextLineStyle = lipgloss.NewStyle().Background(t.DiffContextBg())
	lineNumberStyle = lipgloss.NewStyle().Foreground(t.DiffLineNumber())

	return
}

// -------------------------------------------------------------------------
// Rendering Functions
// -------------------------------------------------------------------------

func lipglossToHex(color lipgloss.Color) string {
	r, g, b, a := color.RGBA()

	// Scale uint32 values (0-65535) to uint8 (0-255).
	r8 := uint8(r >> 8)
	g8 := uint8(g >> 8)
	b8 := uint8(b >> 8)
	a8 := uint8(a >> 8)

	return fmt.Sprintf("#%02x%02x%02x%02x", r8, g8, b8, a8)
}

// applyHighlighting applies intra-line highlighting to a piece of text
func applyHighlighting(content string, segments []Segment, segmentType LineType, highlightBg lipgloss.AdaptiveColor) string {
	// Find all ANSI sequences in the content
	ansiRegex := regexp.MustCompile(`\x1b(?:[@-Z\\-_]|\[[0-9?]*(?:;[0-9?]*)*[@-~])`)
	ansiMatches := ansiRegex.FindAllStringIndex(content, -1)

	// Build a mapping of visible character positions to their actual indices
	visibleIdx := 0
	ansiSequences := make(map[int]string)
	lastAnsiSeq := "\x1b[0m" // Default reset sequence

	for i := 0; i < len(content); {
		isAnsi := false
		for _, match := range ansiMatches {
			if match[0] == i {
				ansiSequences[visibleIdx] = content[match[0]:match[1]]
				lastAnsiSeq = content[match[0]:match[1]]
				i = match[1]
				isAnsi = true
				break
			}
		}
		if isAnsi {
			continue
		}

		// For non-ANSI positions, store the last ANSI sequence
		if _, exists := ansiSequences[visibleIdx]; !exists {
			ansiSequences[visibleIdx] = lastAnsiSeq
		}
		visibleIdx++
		i++
	}

	// Apply highlighting
	var sb strings.Builder
	inSelection := false
	currentPos := 0

	// Get the appropriate color based on terminal background
	bgColor := lipgloss.Color(getColor(highlightBg))
	fgColor := lipgloss.Color(getColor(theme.CurrentTheme().Background()))

	for i := 0; i < len(content); {
		// Check if we're at an ANSI sequence
		isAnsi := false
		for _, match := range ansiMatches {
			if match[0] == i {
				sb.WriteString(content[match[0]:match[1]]) // Preserve ANSI sequence
				i = match[1]
				isAnsi = true
				break
			}
		}
		if isAnsi {
			continue
		}

		// Check for segment boundaries
		for _, seg := range segments {
			if seg.Type == segmentType {
				if currentPos == seg.Start {
					inSelection = true
				}
				if currentPos == seg.End {
					inSelection = false
				}
			}
		}

		// Get current character
		char := string(content[i])

		if inSelection {
			// Get the current styling
			currentStyle := ansiSequences[currentPos]

			// Apply foreground and background highlight
			sb.WriteString("\x1b[38;2;")
			r, g, b, _ := fgColor.RGBA()
			sb.WriteString(fmt.Sprintf("%d;%d;%dm", r>>8, g>>8, b>>8))
			sb.WriteString("\x1b[48;2;")
			r, g, b, _ = bgColor.RGBA()
			sb.WriteString(fmt.Sprintf("%d;%d;%dm", r>>8, g>>8, b>>8))
			sb.WriteString(char)
			// Reset foreground and background
			sb.WriteString("\x1b[39m")

			// Reapply the original ANSI sequence
			sb.WriteString(currentStyle)
		} else {
			// Not in selection, just copy the character
			sb.WriteString(char)
		}

		currentPos++
		i++
	}

	return sb.String()
}

// renderLeftColumn formats the left side of a side-by-side diff
func renderLeftColumn(fileName string, dl *DiffLine, colWidth int) string {
	t := theme.CurrentTheme()

	if dl == nil {
		contextLineStyle := lipgloss.NewStyle().Background(t.DiffContextBg())
		return contextLineStyle.Width(colWidth).Render("")
	}

	removedLineStyle, _, contextLineStyle, lineNumberStyle := createStyles(t)

	// Determine line style based on line type
	var marker string
	var bgStyle lipgloss.Style
	switch dl.Kind {
	case LineRemoved:
		marker = removedLineStyle.Foreground(t.DiffRemoved()).Render("-")
		bgStyle = removedLineStyle
		lineNumberStyle = lineNumberStyle.Foreground(t.DiffRemoved()).Background(t.DiffRemovedLineNumberBg())
	case LineAdded:
		marker = "?"
		bgStyle = contextLineStyle
	case LineContext:
		marker = contextLineStyle.Render(" ")
		bgStyle = contextLineStyle
	}

	// Format line number
	lineNum := ""
	if dl.OldLineNo > 0 {
		lineNum = fmt.Sprintf("%6d", dl.OldLineNo)
	}

	// Create the line prefix
	prefix := lineNumberStyle.Render(lineNum + " " + marker)

	// Apply syntax highlighting
	content := highlightLine(fileName, dl.Content, bgStyle.GetBackground())

	// Apply intra-line highlighting for removed lines
	if dl.Kind == LineRemoved && len(dl.Segments) > 0 {
		content = applyHighlighting(content, dl.Segments, LineRemoved, t.DiffHighlightRemoved())
	}

	// Add a padding space for removed lines
	if dl.Kind == LineRemoved {
		content = bgStyle.Render(" ") + content
	}

	// Create the final line and truncate if needed
	lineText := prefix + content
	return bgStyle.MaxHeight(1).Width(colWidth).Render(
		ansi.Truncate(
			lineText,
			colWidth,
			lipgloss.NewStyle().Background(bgStyle.GetBackground()).Foreground(t.TextMuted()).Render("..."),
		),
	)
}

// renderRightColumn formats the right side of a side-by-side diff
func renderRightColumn(fileName string, dl *DiffLine, colWidth int) string {
	t := theme.CurrentTheme()

	if dl == nil {
		contextLineStyle := lipgloss.NewStyle().Background(t.DiffContextBg())
		return contextLineStyle.Width(colWidth).Render("")
	}

	_, addedLineStyle, contextLineStyle, lineNumberStyle := createStyles(t)

	// Determine line style based on line type
	var marker string
	var bgStyle lipgloss.Style
	switch dl.Kind {
	case LineAdded:
		marker = addedLineStyle.Foreground(t.DiffAdded()).Render("+")
		bgStyle = addedLineStyle
		lineNumberStyle = lineN
Download .txt
gitextract_5ee_h7l1/

├── .github/
│   └── workflows/
│       ├── build.yml
│       └── release.yml
├── .gitignore
├── .goreleaser.yml
├── .opencode.json
├── LICENSE
├── README.md
├── cmd/
│   ├── root.go
│   └── schema/
│       ├── README.md
│       └── main.go
├── go.mod
├── go.sum
├── install
├── internal/
│   ├── app/
│   │   ├── app.go
│   │   └── lsp.go
│   ├── completions/
│   │   └── files-folders.go
│   ├── config/
│   │   ├── config.go
│   │   └── init.go
│   ├── db/
│   │   ├── connect.go
│   │   ├── db.go
│   │   ├── embed.go
│   │   ├── files.sql.go
│   │   ├── messages.sql.go
│   │   ├── migrations/
│   │   │   ├── 20250424200609_initial.sql
│   │   │   └── 20250515105448_add_summary_message_id.sql
│   │   ├── models.go
│   │   ├── querier.go
│   │   ├── sessions.sql.go
│   │   └── sql/
│   │       ├── files.sql
│   │       ├── messages.sql
│   │       └── sessions.sql
│   ├── diff/
│   │   ├── diff.go
│   │   └── patch.go
│   ├── fileutil/
│   │   └── fileutil.go
│   ├── format/
│   │   ├── format.go
│   │   └── spinner.go
│   ├── history/
│   │   └── file.go
│   ├── llm/
│   │   ├── agent/
│   │   │   ├── agent-tool.go
│   │   │   ├── agent.go
│   │   │   ├── mcp-tools.go
│   │   │   └── tools.go
│   │   ├── models/
│   │   │   ├── anthropic.go
│   │   │   ├── azure.go
│   │   │   ├── copilot.go
│   │   │   ├── gemini.go
│   │   │   ├── groq.go
│   │   │   ├── local.go
│   │   │   ├── models.go
│   │   │   ├── openai.go
│   │   │   ├── openrouter.go
│   │   │   ├── vertexai.go
│   │   │   └── xai.go
│   │   ├── prompt/
│   │   │   ├── coder.go
│   │   │   ├── prompt.go
│   │   │   ├── prompt_test.go
│   │   │   ├── summarizer.go
│   │   │   ├── task.go
│   │   │   └── title.go
│   │   ├── provider/
│   │   │   ├── anthropic.go
│   │   │   ├── azure.go
│   │   │   ├── bedrock.go
│   │   │   ├── copilot.go
│   │   │   ├── gemini.go
│   │   │   ├── openai.go
│   │   │   ├── provider.go
│   │   │   └── vertexai.go
│   │   └── tools/
│   │       ├── bash.go
│   │       ├── diagnostics.go
│   │       ├── edit.go
│   │       ├── fetch.go
│   │       ├── file.go
│   │       ├── glob.go
│   │       ├── grep.go
│   │       ├── ls.go
│   │       ├── ls_test.go
│   │       ├── patch.go
│   │       ├── shell/
│   │       │   └── shell.go
│   │       ├── sourcegraph.go
│   │       ├── tools.go
│   │       ├── view.go
│   │       └── write.go
│   ├── logging/
│   │   ├── logger.go
│   │   ├── message.go
│   │   └── writer.go
│   ├── lsp/
│   │   ├── client.go
│   │   ├── handlers.go
│   │   ├── language.go
│   │   ├── methods.go
│   │   ├── protocol/
│   │   │   ├── LICENSE
│   │   │   ├── interface.go
│   │   │   ├── pattern_interfaces.go
│   │   │   ├── tables.go
│   │   │   ├── tsdocument-changes.go
│   │   │   ├── tsjson.go
│   │   │   ├── tsprotocol.go
│   │   │   └── uri.go
│   │   ├── protocol.go
│   │   ├── transport.go
│   │   ├── util/
│   │   │   └── edit.go
│   │   └── watcher/
│   │       └── watcher.go
│   ├── message/
│   │   ├── attachment.go
│   │   ├── content.go
│   │   └── message.go
│   ├── permission/
│   │   └── permission.go
│   ├── pubsub/
│   │   ├── broker.go
│   │   └── events.go
│   ├── session/
│   │   └── session.go
│   ├── tui/
│   │   ├── components/
│   │   │   ├── chat/
│   │   │   │   ├── chat.go
│   │   │   │   ├── editor.go
│   │   │   │   ├── list.go
│   │   │   │   ├── message.go
│   │   │   │   └── sidebar.go
│   │   │   ├── core/
│   │   │   │   └── status.go
│   │   │   ├── dialog/
│   │   │   │   ├── arguments.go
│   │   │   │   ├── commands.go
│   │   │   │   ├── complete.go
│   │   │   │   ├── custom_commands.go
│   │   │   │   ├── custom_commands_test.go
│   │   │   │   ├── filepicker.go
│   │   │   │   ├── help.go
│   │   │   │   ├── init.go
│   │   │   │   ├── models.go
│   │   │   │   ├── permission.go
│   │   │   │   ├── quit.go
│   │   │   │   ├── session.go
│   │   │   │   └── theme.go
│   │   │   ├── logs/
│   │   │   │   ├── details.go
│   │   │   │   └── table.go
│   │   │   └── util/
│   │   │       └── simple-list.go
│   │   ├── image/
│   │   │   └── images.go
│   │   ├── layout/
│   │   │   ├── container.go
│   │   │   ├── layout.go
│   │   │   ├── overlay.go
│   │   │   └── split.go
│   │   ├── page/
│   │   │   ├── chat.go
│   │   │   ├── logs.go
│   │   │   └── page.go
│   │   ├── styles/
│   │   │   ├── background.go
│   │   │   ├── icons.go
│   │   │   ├── markdown.go
│   │   │   └── styles.go
│   │   ├── theme/
│   │   │   ├── catppuccin.go
│   │   │   ├── dracula.go
│   │   │   ├── flexoki.go
│   │   │   ├── gruvbox.go
│   │   │   ├── manager.go
│   │   │   ├── monokai.go
│   │   │   ├── onedark.go
│   │   │   ├── opencode.go
│   │   │   ├── theme.go
│   │   │   ├── theme_test.go
│   │   │   ├── tokyonight.go
│   │   │   └── tron.go
│   │   ├── tui.go
│   │   └── util/
│   │       └── util.go
│   └── version/
│       └── version.go
├── main.go
├── opencode-schema.json
├── scripts/
│   ├── check_hidden_chars.sh
│   ├── release
│   └── snapshot
└── sqlc.yaml
Download .txt
Showing preview only (226K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2589 symbols across 139 files)

FILE: cmd/root.go
  function attemptTUIRecovery (line 187) | func attemptTUIRecovery(program *tea.Program) {
  function initMCPTools (line 195) | func initMCPTools(ctx context.Context, app *app.App) {
  function setupSubscriber (line 209) | func setupSubscriber[T any](
  function setupSubscriptions (line 249) | func setupSubscriptions(app *app.App, parentCtx context.Context) (chan t...
  function Execute (line 284) | func Execute() {
  function init (line 291) | func init() {

FILE: cmd/schema/main.go
  type JSONSchemaType (line 13) | type JSONSchemaType struct
  function main (line 26) | func main() {
  function generateSchema (line 38) | func generateSchema() map[string]any {

FILE: internal/app/app.go
  type App (line 25) | type App struct
    method initTheme (line 84) | func (app *App) initTheme() {
    method RunNonInteractive (line 100) | func (a *App) RunNonInteractive(ctx context.Context, prompt string, ou...
    method Shutdown (line 164) | func (app *App) Shutdown() {
  function New (line 42) | func New(ctx context.Context, conn *sql.DB) (*App, error) {

FILE: internal/app/lsp.go
  method initLSPClients (line 13) | func (app *App) initLSPClients(ctx context.Context) {
  method createAndStartLSPClient (line 25) | func (app *App) createAndStartLSPClient(ctx context.Context, name string...
  method runWorkspaceWatcher (line 87) | func (app *App) runWorkspaceWatcher(ctx context.Context, name string, wo...
  method restartLSPClient (line 99) | func (app *App) restartLSPClient(ctx context.Context, name string) {

FILE: internal/completions/files-folders.go
  type filesAndFoldersContextGroup (line 15) | type filesAndFoldersContextGroup struct
    method GetId (line 19) | func (cg *filesAndFoldersContextGroup) GetId() string {
    method GetEntry (line 23) | func (cg *filesAndFoldersContextGroup) GetEntry() dialog.CompletionIte...
    method getFiles (line 58) | func (cg *filesAndFoldersContextGroup) getFiles(query string) ([]strin...
    method GetChildEntries (line 169) | func (cg *filesAndFoldersContextGroup) GetChildEntries(query string) (...
  function processNullTerminatedOutput (line 30) | func processNullTerminatedOutput(outputBytes []byte) []string {
  function NewFileAndFolderContextGroup (line 187) | func NewFileAndFolderContextGroup() dialog.CompletionProvider {

FILE: internal/config/config.go
  type MCPType (line 19) | type MCPType
  constant MCPStdio (line 23) | MCPStdio MCPType = "stdio"
  constant MCPSse (line 24) | MCPSse   MCPType = "sse"
  type MCPServer (line 28) | type MCPServer struct
  type AgentName (line 37) | type AgentName
  constant AgentCoder (line 40) | AgentCoder      AgentName = "coder"
  constant AgentSummarizer (line 41) | AgentSummarizer AgentName = "summarizer"
  constant AgentTask (line 42) | AgentTask       AgentName = "task"
  constant AgentTitle (line 43) | AgentTitle      AgentName = "title"
  type Agent (line 47) | type Agent struct
  type Provider (line 54) | type Provider struct
  type Data (line 60) | type Data struct
  type LSPConfig (line 65) | type LSPConfig struct
  type TUIConfig (line 73) | type TUIConfig struct
  type ShellConfig (line 78) | type ShellConfig struct
  type Config (line 84) | type Config struct
  constant defaultDataDirectory (line 101) | defaultDataDirectory = ".opencode"
  constant defaultLogLevel (line 102) | defaultLogLevel      = "info"
  constant appName (line 103) | appName              = "opencode"
  constant MaxTokensFallbackDefault (line 105) | MaxTokensFallbackDefault = 4096
  function Load (line 128) | func Load(workingDir string, debug bool) (*Config, error) {
  function configureViper (line 219) | func configureViper() {
  function setDefaults (line 230) | func setDefaults(debug bool) {
  function setProviderDefaults (line 255) | func setProviderDefaults() {
  function hasAWSCredentials (line 390) | func hasAWSCredentials() bool {
  function hasVertexAICredentials (line 416) | func hasVertexAICredentials() bool {
  function hasCopilotCredentials (line 428) | func hasCopilotCredentials() bool {
  function readConfig (line 437) | func readConfig(err error) error {
  function mergeLocalConfig (line 451) | func mergeLocalConfig(workingDir string) {
  function applyDefaultValues (line 464) | func applyDefaultValues() {
  function validateAgent (line 475) | func validateAgent(cfg *Config, name AgentName, agent Agent) error {
  function Validate (line 609) | func Validate() error {
  function getProviderAPIKey (line 644) | func getProviderAPIKey(provider models.ModelProvider) string {
  function setDefaultModelForAgent (line 671) | func setDefaultModelForAgent(agent AgentName) bool {
  function updateCfgFile (line 819) | func updateCfgFile(updateCfg func(config *Config)) error {
  function Get (line 867) | func Get() *Config {
  function WorkingDirectory (line 872) | func WorkingDirectory() string {
  function UpdateAgentModel (line 879) | func UpdateAgentModel(agentName AgentName, modelID models.ModelID) error {
  function UpdateTheme (line 918) | func UpdateTheme(themeName string) error {
  function LoadGitHubToken (line 933) | func LoadGitHubToken() (string, error) {

FILE: internal/config/init.go
  constant InitFlagFilename (line 11) | InitFlagFilename = "init"
  type ProjectInitFlag (line 15) | type ProjectInitFlag struct
  function ShouldShowInitDialog (line 20) | func ShouldShowInitDialog() (bool, error) {
  function MarkProjectInitialized (line 45) | func MarkProjectInitialized() error {

FILE: internal/db/connect.go
  function Connect (line 18) | func Connect() (*sql.DB, error) {

FILE: internal/db/db.go
  type DBTX (line 13) | type DBTX interface
  function New (line 20) | func New(db DBTX) *Queries {
  function Prepare (line 24) | func Prepare(ctx context.Context, db DBTX) (*Queries, error) {
  type Queries (line 236) | type Queries struct
    method Close (line 93) | func (q *Queries) Close() error {
    method exec (line 203) | func (q *Queries) exec(ctx context.Context, stmt *sql.Stmt, query stri...
    method query (line 214) | func (q *Queries) query(ctx context.Context, stmt *sql.Stmt, query str...
    method queryRow (line 225) | func (q *Queries) queryRow(ctx context.Context, stmt *sql.Stmt, query ...
    method WithTx (line 262) | func (q *Queries) WithTx(tx *sql.Tx) *Queries {

FILE: internal/db/files.sql.go
  constant createFile (line 12) | createFile = `-- name: CreateFile :one
  type CreateFileParams (line 27) | type CreateFileParams struct
  method CreateFile (line 35) | func (q *Queries) CreateFile(ctx context.Context, arg CreateFileParams) ...
  constant deleteFile (line 56) | deleteFile = `-- name: DeleteFile :exec
  method DeleteFile (line 61) | func (q *Queries) DeleteFile(ctx context.Context, id string) error {
  constant deleteSessionFiles (line 66) | deleteSessionFiles = `-- name: DeleteSessionFiles :exec
  method DeleteSessionFiles (line 71) | func (q *Queries) DeleteSessionFiles(ctx context.Context, sessionID stri...
  constant getFile (line 76) | getFile = `-- name: GetFile :one
  method GetFile (line 82) | func (q *Queries) GetFile(ctx context.Context, id string) (File, error) {
  constant getFileByPathAndSession (line 97) | getFileByPathAndSession = `-- name: GetFileByPathAndSession :one
  type GetFileByPathAndSessionParams (line 105) | type GetFileByPathAndSessionParams struct
  method GetFileByPathAndSession (line 110) | func (q *Queries) GetFileByPathAndSession(ctx context.Context, arg GetFi...
  constant listFilesByPath (line 125) | listFilesByPath = `-- name: ListFilesByPath :many
  method ListFilesByPath (line 132) | func (q *Queries) ListFilesByPath(ctx context.Context, path string) ([]F...
  constant listFilesBySession (line 163) | listFilesBySession = `-- name: ListFilesBySession :many
  method ListFilesBySession (line 170) | func (q *Queries) ListFilesBySession(ctx context.Context, sessionID stri...
  constant listLatestSessionFiles (line 201) | listLatestSessionFiles = `-- name: ListLatestSessionFiles :many
  method ListLatestSessionFiles (line 213) | func (q *Queries) ListLatestSessionFiles(ctx context.Context, sessionID ...
  constant listNewFiles (line 244) | listNewFiles = `-- name: ListNewFiles :many
  method ListNewFiles (line 251) | func (q *Queries) ListNewFiles(ctx context.Context) ([]File, error) {
  constant updateFile (line 282) | updateFile = `-- name: UpdateFile :one
  type UpdateFileParams (line 292) | type UpdateFileParams struct
  method UpdateFile (line 298) | func (q *Queries) UpdateFile(ctx context.Context, arg UpdateFileParams) ...

FILE: internal/db/messages.sql.go
  constant createMessage (line 13) | createMessage = `-- name: CreateMessage :one
  type CreateMessageParams (line 28) | type CreateMessageParams struct
  method CreateMessage (line 36) | func (q *Queries) CreateMessage(ctx context.Context, arg CreateMessagePa...
  constant deleteMessage (line 58) | deleteMessage = `-- name: DeleteMessage :exec
  method DeleteMessage (line 63) | func (q *Queries) DeleteMessage(ctx context.Context, id string) error {
  constant deleteSessionMessages (line 68) | deleteSessionMessages = `-- name: DeleteSessionMessages :exec
  method DeleteSessionMessages (line 73) | func (q *Queries) DeleteSessionMessages(ctx context.Context, sessionID s...
  constant getMessage (line 78) | getMessage = `-- name: GetMessage :one
  method GetMessage (line 84) | func (q *Queries) GetMessage(ctx context.Context, id string) (Message, e...
  constant listMessagesBySession (line 100) | listMessagesBySession = `-- name: ListMessagesBySession :many
  method ListMessagesBySession (line 107) | func (q *Queries) ListMessagesBySession(ctx context.Context, sessionID s...
  constant updateMessage (line 139) | updateMessage = `-- name: UpdateMessage :exec
  type UpdateMessageParams (line 148) | type UpdateMessageParams struct
  method UpdateMessage (line 154) | func (q *Queries) UpdateMessage(ctx context.Context, arg UpdateMessagePa...

FILE: internal/db/migrations/20250424200609_initial.sql
  type sessions (line 4) | CREATE TABLE IF NOT EXISTS sessions (

FILE: internal/db/models.go
  type File (line 11) | type File struct
  type Message (line 21) | type Message struct
  type Session (line 32) | type Session struct

FILE: internal/db/querier.go
  type Querier (line 11) | type Querier interface

FILE: internal/db/sessions.sql.go
  constant createSession (line 13) | createSession = `-- name: CreateSession :one
  type CreateSessionParams (line 39) | type CreateSessionParams struct
  method CreateSession (line 49) | func (q *Queries) CreateSession(ctx context.Context, arg CreateSessionPa...
  constant deleteSession (line 75) | deleteSession = `-- name: DeleteSession :exec
  method DeleteSession (line 80) | func (q *Queries) DeleteSession(ctx context.Context, id string) error {
  constant getSessionByID (line 85) | getSessionByID = `-- name: GetSessionByID :one
  method GetSessionByID (line 91) | func (q *Queries) GetSessionByID(ctx context.Context, id string) (Sessio...
  constant listSessions (line 109) | listSessions = `-- name: ListSessions :many
  method ListSessions (line 116) | func (q *Queries) ListSessions(ctx context.Context) ([]Session, error) {
  constant updateSession (line 150) | updateSession = `-- name: UpdateSession :one
  type UpdateSessionParams (line 162) | type UpdateSessionParams struct
  method UpdateSession (line 171) | func (q *Queries) UpdateSession(ctx context.Context, arg UpdateSessionPa...

FILE: internal/diff/diff.go
  type LineType (line 28) | type LineType
  constant LineContext (line 31) | LineContext LineType = iota
  constant LineAdded (line 32) | LineAdded
  constant LineRemoved (line 33) | LineRemoved
  type Segment (line 37) | type Segment struct
  type DiffLine (line 45) | type DiffLine struct
  type Hunk (line 54) | type Hunk struct
  type DiffResult (line 60) | type DiffResult struct
  type linePair (line 67) | type linePair struct
  type ParseConfig (line 77) | type ParseConfig struct
  type ParseOption (line 82) | type ParseOption
  function WithContextSize (line 85) | func WithContextSize(size int) ParseOption {
  type SideBySideConfig (line 98) | type SideBySideConfig struct
  type SideBySideOption (line 103) | type SideBySideOption
  function NewSideBySideConfig (line 106) | func NewSideBySideConfig(opts ...SideBySideOption) SideBySideConfig {
  function WithTotalWidth (line 119) | func WithTotalWidth(width int) SideBySideOption {
  function ParseUnifiedDiff (line 132) | func ParseUnifiedDiff(diff string) (DiffResult, error) {
  function HighlightIntralineChanges (line 233) | func HighlightIntralineChanges(h *Hunk) {
  function pairLines (line 294) | func pairLines(lines []DiffLine) []linePair {
  function SyntaxHighlight (line 326) | func SyntaxHighlight(w io.Writer, source, fileName, formatter string, bg...
  function getColor (line 535) | func getColor(adaptiveColor lipgloss.AdaptiveColor) string {
  function highlightLine (line 543) | func highlightLine(fileName string, line string, bg lipgloss.TerminalCol...
  function createStyles (line 553) | func createStyles(t theme.Theme) (removedLineStyle, addedLineStyle, cont...
  function lipglossToHex (line 566) | func lipglossToHex(color lipgloss.Color) string {
  function applyHighlighting (line 579) | func applyHighlighting(content string, segments []Segment, segmentType L...
  function renderLeftColumn (line 681) | func renderLeftColumn(fileName string, dl *DiffLine, colWidth int) string {
  function renderRightColumn (line 741) | func renderRightColumn(fileName string, dl *DiffLine, colWidth int) stri...
  function RenderSideBySideHunk (line 805) | func RenderSideBySideHunk(fileName string, h Hunk, opts ...SideBySideOpt...
  function FormatDiff (line 835) | func FormatDiff(diffText string, opts ...SideBySideOption) (string, erro...
  function GenerateDiff (line 850) | func GenerateDiff(beforeContent, afterContent, fileName string) (string,...

FILE: internal/diff/patch.go
  type ActionType (line 11) | type ActionType
  constant ActionAdd (line 14) | ActionAdd    ActionType = "add"
  constant ActionDelete (line 15) | ActionDelete ActionType = "delete"
  constant ActionUpdate (line 16) | ActionUpdate ActionType = "update"
  type FileChange (line 19) | type FileChange struct
  type Commit (line 26) | type Commit struct
  type Chunk (line 30) | type Chunk struct
  type PatchAction (line 36) | type PatchAction struct
  type Patch (line 43) | type Patch struct
  type DiffError (line 47) | type DiffError struct
    method Error (line 51) | func (e DiffError) Error() string {
  function NewDiffError (line 56) | func NewDiffError(message string) DiffError {
  function fileError (line 60) | func fileError(action, reason, path string) DiffError {
  function contextError (line 64) | func contextError(index int, context string, isEOF bool) DiffError {
  type Parser (line 72) | type Parser struct
    method isDone (line 90) | func (p *Parser) isDone(prefixes []string) bool {
    method startsWith (line 102) | func (p *Parser) startsWith(prefix any) bool {
    method readStr (line 119) | func (p *Parser) readStr(prefix string, returnEverything bool) string {
    method Parse (line 136) | func (p *Parser) Parse() error {
    method parseUpdateFile (line 200) | func (p *Parser) parseUpdateFile(text string) (PatchAction, error) {
    method parseAddFile (line 281) | func (p *Parser) parseAddFile() (PatchAction, error) {
  function NewParser (line 80) | func NewParser(currentFiles map[string]string, lines []string) *Parser {
  function findContextCore (line 307) | func findContextCore(lines []string, context []string, start int) (int, ...
  function tryFindMatch (line 337) | func tryFindMatch(lines []string, context []string, start int,
  function findContext (line 364) | func findContext(lines []string, context []string, start int, eof bool) ...
  function peekNextSection (line 376) | func peekNextSection(lines []string, initialIndex int) ([]string, []Chun...
  function TextToPatch (line 460) | func TextToPatch(text string, orig map[string]string) (Patch, int, error) {
  function IdentifyFilesNeeded (line 474) | func IdentifyFilesNeeded(text string) []string {
  function IdentifyFilesAdded (line 495) | func IdentifyFilesAdded(text string) []string {
  function getUpdatedFile (line 513) | func getUpdatedFile(text string, action PatchAction, path string) (strin...
  function PatchToCommit (line 542) | func PatchToCommit(patch Patch, orig map[string]string) (Commit, error) {
  function AssembleChanges (line 577) | func AssembleChanges(orig map[string]string, updatedFiles map[string]str...
  function LoadFiles (line 608) | func LoadFiles(paths []string, openFn func(string) (string, error)) (map...
  function ApplyCommit (line 620) | func ApplyCommit(commit Commit, writeFn func(string, string) error, remo...
  function ProcessPatch (line 655) | func ProcessPatch(text string, openFn func(string) (string, error), writ...
  function OpenFile (line 686) | func OpenFile(p string) (string, error) {
  function WriteFile (line 694) | func WriteFile(p string, content string) error {
  function RemoveFile (line 709) | func RemoveFile(p string) error {
  function ValidatePatch (line 713) | func ValidatePatch(patchText string, files map[string]string) (bool, str...

FILE: internal/fileutil/fileutil.go
  function init (line 22) | func init() {
  function GetRgCmd (line 36) | func GetRgCmd(globPattern string) *exec.Cmd {
  function GetFzfCmd (line 56) | func GetFzfCmd(query string) *exec.Cmd {
  type FileInfo (line 71) | type FileInfo struct
  function SkipHidden (line 76) | func SkipHidden(path string) bool {
  function GlobWithDoublestar (line 115) | func GlobWithDoublestar(pattern, searchPath string, limit int) ([]string...

FILE: internal/format/format.go
  type OutputFormat (line 10) | type OutputFormat
    method String (line 21) | func (f OutputFormat) String() string {
  constant Text (line 14) | Text OutputFormat = "text"
  constant JSON (line 17) | JSON OutputFormat = "json"
  function Parse (line 32) | func Parse(s string) (OutputFormat, error) {
  function IsValid (line 46) | func IsValid(s string) bool {
  function GetHelpText (line 52) | func GetHelpText() string {
  function FormatOutput (line 60) | func FormatOutput(content string, formatStr string) string {
  function formatAsJSON (line 78) | func formatAsJSON(content string) string {

FILE: internal/format/spinner.go
  type Spinner (line 13) | type Spinner struct
    method Start (line 84) | func (s *Spinner) Start() {
    method Stop (line 99) | func (s *Spinner) Stop() {
  type spinnerModel (line 22) | type spinnerModel struct
    method Init (line 28) | func (m spinnerModel) Init() tea.Cmd {
    method Update (line 32) | func (m spinnerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 49) | func (m spinnerModel) View() string {
  type quitMsg (line 57) | type quitMsg struct
  function NewSpinner (line 60) | func NewSpinner(message string) *Spinner {

FILE: internal/history/file.go
  constant InitialVersion (line 17) | InitialVersion = "initial"
  type File (line 20) | type File struct
  type Service (line 30) | type Service interface
  type service (line 43) | type service struct
    method Create (line 57) | func (s *service) Create(ctx context.Context, sessionID, path, content...
    method CreateVersion (line 61) | func (s *service) CreateVersion(ctx context.Context, sessionID, path, ...
    method createWithVersion (line 97) | func (s *service) createWithVersion(ctx context.Context, sessionID, pa...
    method Get (line 158) | func (s *service) Get(ctx context.Context, id string) (File, error) {
    method GetByPathAndSession (line 166) | func (s *service) GetByPathAndSession(ctx context.Context, path, sessi...
    method ListBySession (line 177) | func (s *service) ListBySession(ctx context.Context, sessionID string)...
    method ListLatestSessionFiles (line 189) | func (s *service) ListLatestSessionFiles(ctx context.Context, sessionI...
    method Update (line 201) | func (s *service) Update(ctx context.Context, file File) (File, error) {
    method Delete (line 215) | func (s *service) Delete(ctx context.Context, id string) error {
    method DeleteSessionFiles (line 228) | func (s *service) DeleteSessionFiles(ctx context.Context, sessionID st...
    method fromDBItem (line 242) | func (s *service) fromDBItem(item db.File) File {
  function NewService (line 49) | func NewService(q *db.Queries, db *sql.DB) Service {

FILE: internal/llm/agent/agent-tool.go
  type agentTool (line 15) | type agentTool struct
    method Info (line 29) | func (b *agentTool) Info() tools.ToolInfo {
    method Run (line 43) | func (b *agentTool) Run(ctx context.Context, call tools.ToolCall) (too...
  constant AgentToolName (line 22) | AgentToolName = "agent"
  type AgentParams (line 25) | type AgentParams struct
  function NewAgentTool (line 99) | func NewAgentTool(

FILE: internal/llm/agent/agent.go
  type AgentEventType (line 29) | type AgentEventType
  constant AgentEventTypeError (line 32) | AgentEventTypeError     AgentEventType = "error"
  constant AgentEventTypeResponse (line 33) | AgentEventTypeResponse  AgentEventType = "response"
  constant AgentEventTypeSummarize (line 34) | AgentEventTypeSummarize AgentEventType = "summarize"
  type AgentEvent (line 37) | type AgentEvent struct
  type Service (line 48) | type Service interface
  type agent (line 59) | type agent struct
    method Model (line 113) | func (a *agent) Model() models.Model {
    method Cancel (line 117) | func (a *agent) Cancel(sessionID string) {
    method IsBusy (line 135) | func (a *agent) IsBusy() bool {
    method IsSessionBusy (line 149) | func (a *agent) IsSessionBusy(sessionID string) bool {
    method generateTitle (line 154) | func (a *agent) generateTitle(ctx context.Context, sessionID string, c...
    method err (line 191) | func (a *agent) err(err error) AgentEvent {
    method Run (line 198) | func (a *agent) Run(ctx context.Context, sessionID string, content str...
    method processGeneration (line 233) | func (a *agent) processGeneration(ctx context.Context, sessionID, cont...
    method createUserMessage (line 313) | func (a *agent) createUserMessage(ctx context.Context, sessionID, cont...
    method streamAndHandleEvents (line 322) | func (a *agent) streamAndHandleEvents(ctx context.Context, sessionID s...
    method finishMessage (line 440) | func (a *agent) finishMessage(ctx context.Context, msg *message.Messag...
    method processEvent (line 445) | func (a *agent) processEvent(ctx context.Context, sessionID string, as...
    method TrackUsage (line 494) | func (a *agent) TrackUsage(ctx context.Context, sessionID string, mode...
    method Update (line 516) | func (a *agent) Update(agentName config.AgentName, modelID models.Mode...
    method Summarize (line 535) | func (a *agent) Summarize(ctx context.Context, sessionID string) error {
  function NewAgent (line 73) | func NewAgent(
  function createAgentProvider (line 706) | func createAgentProvider(agentName config.AgentName) (provider.Provider,...

FILE: internal/llm/agent/mcp-tools.go
  type mcpTool (line 18) | type mcpTool struct
    method Info (line 35) | func (b *mcpTool) Info() tools.ToolInfo {
    method Run (line 86) | func (b *mcpTool) Run(ctx context.Context, params tools.ToolCall) (too...
  type MCPClient (line 25) | type MCPClient interface
  function runTool (line 48) | func runTool(ctx context.Context, c MCPClient, toolName string, input st...
  function NewMcpTool (line 131) | func NewMcpTool(name string, tool mcp.Tool, permissions permission.Servi...
  function getTools (line 142) | func getTools(ctx context.Context, name string, m config.MCPServer, perm...
  function GetMcpTools (line 169) | func GetMcpTools(ctx context.Context, permissions permission.Service) []...

FILE: internal/llm/agent/tools.go
  function CoderAgentTools (line 14) | func CoderAgentTools(
  function TaskAgentTools (line 43) | func TaskAgentTools(lspClients map[string]*lsp.Client) []tools.BaseTool {

FILE: internal/llm/models/anthropic.go
  constant ProviderAnthropic (line 4) | ProviderAnthropic ModelProvider = "anthropic"
  constant Claude35Sonnet (line 7) | Claude35Sonnet ModelID = "claude-3.5-sonnet"
  constant Claude3Haiku (line 8) | Claude3Haiku   ModelID = "claude-3-haiku"
  constant Claude37Sonnet (line 9) | Claude37Sonnet ModelID = "claude-3.7-sonnet"
  constant Claude35Haiku (line 10) | Claude35Haiku  ModelID = "claude-3.5-haiku"
  constant Claude3Opus (line 11) | Claude3Opus    ModelID = "claude-3-opus"
  constant Claude4Opus (line 12) | Claude4Opus    ModelID = "claude-4-opus"
  constant Claude4Sonnet (line 13) | Claude4Sonnet  ModelID = "claude-4-sonnet"

FILE: internal/llm/models/azure.go
  constant ProviderAzure (line 3) | ProviderAzure ModelProvider = "azure"
  constant AzureGPT41 (line 6) | AzureGPT41        ModelID = "azure.gpt-4.1"
  constant AzureGPT41Mini (line 7) | AzureGPT41Mini    ModelID = "azure.gpt-4.1-mini"
  constant AzureGPT41Nano (line 8) | AzureGPT41Nano    ModelID = "azure.gpt-4.1-nano"
  constant AzureGPT45Preview (line 9) | AzureGPT45Preview ModelID = "azure.gpt-4.5-preview"
  constant AzureGPT4o (line 10) | AzureGPT4o        ModelID = "azure.gpt-4o"
  constant AzureGPT4oMini (line 11) | AzureGPT4oMini    ModelID = "azure.gpt-4o-mini"
  constant AzureO1 (line 12) | AzureO1           ModelID = "azure.o1"
  constant AzureO1Mini (line 13) | AzureO1Mini       ModelID = "azure.o1-mini"
  constant AzureO3 (line 14) | AzureO3           ModelID = "azure.o3"
  constant AzureO3Mini (line 15) | AzureO3Mini       ModelID = "azure.o3-mini"
  constant AzureO4Mini (line 16) | AzureO4Mini       ModelID = "azure.o4-mini"

FILE: internal/llm/models/copilot.go
  constant ProviderCopilot (line 4) | ProviderCopilot ModelProvider = "copilot"
  constant CopilotGTP35Turbo (line 7) | CopilotGTP35Turbo      ModelID = "copilot.gpt-3.5-turbo"
  constant CopilotGPT4o (line 8) | CopilotGPT4o           ModelID = "copilot.gpt-4o"
  constant CopilotGPT4oMini (line 9) | CopilotGPT4oMini       ModelID = "copilot.gpt-4o-mini"
  constant CopilotGPT41 (line 10) | CopilotGPT41           ModelID = "copilot.gpt-4.1"
  constant CopilotClaude35 (line 11) | CopilotClaude35        ModelID = "copilot.claude-3.5-sonnet"
  constant CopilotClaude37 (line 12) | CopilotClaude37        ModelID = "copilot.claude-3.7-sonnet"
  constant CopilotClaude4 (line 13) | CopilotClaude4         ModelID = "copilot.claude-sonnet-4"
  constant CopilotO1 (line 14) | CopilotO1              ModelID = "copilot.o1"
  constant CopilotO3Mini (line 15) | CopilotO3Mini          ModelID = "copilot.o3-mini"
  constant CopilotO4Mini (line 16) | CopilotO4Mini          ModelID = "copilot.o4-mini"
  constant CopilotGemini20 (line 17) | CopilotGemini20        ModelID = "copilot.gemini-2.0-flash"
  constant CopilotGemini25 (line 18) | CopilotGemini25        ModelID = "copilot.gemini-2.5-pro"
  constant CopilotGPT4 (line 19) | CopilotGPT4            ModelID = "copilot.gpt-4"
  constant CopilotClaude37Thought (line 20) | CopilotClaude37Thought ModelID = "copilot.claude-3.7-sonnet-thought"

FILE: internal/llm/models/gemini.go
  constant ProviderGemini (line 4) | ProviderGemini ModelProvider = "gemini"
  constant Gemini25Flash (line 7) | Gemini25Flash     ModelID = "gemini-2.5-flash"
  constant Gemini25 (line 8) | Gemini25          ModelID = "gemini-2.5"
  constant Gemini20Flash (line 9) | Gemini20Flash     ModelID = "gemini-2.0-flash"
  constant Gemini20FlashLite (line 10) | Gemini20FlashLite ModelID = "gemini-2.0-flash-lite"

FILE: internal/llm/models/groq.go
  constant ProviderGROQ (line 4) | ProviderGROQ ModelProvider = "groq"
  constant QWENQwq (line 7) | QWENQwq ModelID = "qwen-qwq"
  constant Llama4Scout (line 10) | Llama4Scout               ModelID = "meta-llama/llama-4-scout-17b-16e-in...
  constant Llama4Maverick (line 11) | Llama4Maverick            ModelID = "meta-llama/llama-4-maverick-17b-128...
  constant Llama3_3_70BVersatile (line 12) | Llama3_3_70BVersatile     ModelID = "llama-3.3-70b-versatile"
  constant DeepseekR1DistillLlama70b (line 13) | DeepseekR1DistillLlama70b ModelID = "deepseek-r1-distill-llama-70b"

FILE: internal/llm/models/local.go
  constant ProviderLocal (line 18) | ProviderLocal ModelProvider = "local"
  constant localModelsPath (line 20) | localModelsPath        = "v1/models"
  constant lmStudioBetaModelsPath (line 21) | lmStudioBetaModelsPath = "api/v0/models"
  function init (line 24) | func init() {
  type localModelList (line 60) | type localModelList struct
  type localModel (line 64) | type localModel struct
  function listLocalModels (line 77) | func listLocalModels(modelsEndpoint string) []localModel {
  function loadLocalModels (line 126) | func loadLocalModels(models []localModel) {
  function convertLocalModel (line 140) | func convertLocalModel(model localModel) Model {
  function friendlyModelName (line 155) | func friendlyModelName(modelID string) string {

FILE: internal/llm/models/models.go
  type ModelID (line 6) | type ModelID
  type ModelProvider (line 7) | type ModelProvider
  type Model (line 10) | type Model struct
  constant BedrockClaude37Sonnet (line 28) | BedrockClaude37Sonnet ModelID = "bedrock.claude-3.7-sonnet"
  constant ProviderBedrock (line 32) | ProviderBedrock ModelProvider = "bedrock"
  constant ProviderMock (line 34) | ProviderMock ModelProvider = "__mock"
  function init (line 88) | func init() {

FILE: internal/llm/models/openai.go
  constant ProviderOpenAI (line 4) | ProviderOpenAI ModelProvider = "openai"
  constant GPT41 (line 6) | GPT41        ModelID = "gpt-4.1"
  constant GPT41Mini (line 7) | GPT41Mini    ModelID = "gpt-4.1-mini"
  constant GPT41Nano (line 8) | GPT41Nano    ModelID = "gpt-4.1-nano"
  constant GPT45Preview (line 9) | GPT45Preview ModelID = "gpt-4.5-preview"
  constant GPT4o (line 10) | GPT4o        ModelID = "gpt-4o"
  constant GPT4oMini (line 11) | GPT4oMini    ModelID = "gpt-4o-mini"
  constant O1 (line 12) | O1           ModelID = "o1"
  constant O1Pro (line 13) | O1Pro        ModelID = "o1-pro"
  constant O1Mini (line 14) | O1Mini       ModelID = "o1-mini"
  constant O3 (line 15) | O3           ModelID = "o3"
  constant O3Mini (line 16) | O3Mini       ModelID = "o3-mini"
  constant O4Mini (line 17) | O4Mini       ModelID = "o4-mini"

FILE: internal/llm/models/openrouter.go
  constant ProviderOpenRouter (line 4) | ProviderOpenRouter ModelProvider = "openrouter"
  constant OpenRouterGPT41 (line 6) | OpenRouterGPT41          ModelID = "openrouter.gpt-4.1"
  constant OpenRouterGPT41Mini (line 7) | OpenRouterGPT41Mini      ModelID = "openrouter.gpt-4.1-mini"
  constant OpenRouterGPT41Nano (line 8) | OpenRouterGPT41Nano      ModelID = "openrouter.gpt-4.1-nano"
  constant OpenRouterGPT45Preview (line 9) | OpenRouterGPT45Preview   ModelID = "openrouter.gpt-4.5-preview"
  constant OpenRouterGPT4o (line 10) | OpenRouterGPT4o          ModelID = "openrouter.gpt-4o"
  constant OpenRouterGPT4oMini (line 11) | OpenRouterGPT4oMini      ModelID = "openrouter.gpt-4o-mini"
  constant OpenRouterO1 (line 12) | OpenRouterO1             ModelID = "openrouter.o1"
  constant OpenRouterO1Pro (line 13) | OpenRouterO1Pro          ModelID = "openrouter.o1-pro"
  constant OpenRouterO1Mini (line 14) | OpenRouterO1Mini         ModelID = "openrouter.o1-mini"
  constant OpenRouterO3 (line 15) | OpenRouterO3             ModelID = "openrouter.o3"
  constant OpenRouterO3Mini (line 16) | OpenRouterO3Mini         ModelID = "openrouter.o3-mini"
  constant OpenRouterO4Mini (line 17) | OpenRouterO4Mini         ModelID = "openrouter.o4-mini"
  constant OpenRouterGemini25Flash (line 18) | OpenRouterGemini25Flash  ModelID = "openrouter.gemini-2.5-flash"
  constant OpenRouterGemini25 (line 19) | OpenRouterGemini25       ModelID = "openrouter.gemini-2.5"
  constant OpenRouterClaude35Sonnet (line 20) | OpenRouterClaude35Sonnet ModelID = "openrouter.claude-3.5-sonnet"
  constant OpenRouterClaude3Haiku (line 21) | OpenRouterClaude3Haiku   ModelID = "openrouter.claude-3-haiku"
  constant OpenRouterClaude37Sonnet (line 22) | OpenRouterClaude37Sonnet ModelID = "openrouter.claude-3.7-sonnet"
  constant OpenRouterClaude35Haiku (line 23) | OpenRouterClaude35Haiku  ModelID = "openrouter.claude-3.5-haiku"
  constant OpenRouterClaude3Opus (line 24) | OpenRouterClaude3Opus    ModelID = "openrouter.claude-3-opus"
  constant OpenRouterDeepSeekR1Free (line 25) | OpenRouterDeepSeekR1Free ModelID = "openrouter.deepseek-r1-free"

FILE: internal/llm/models/vertexai.go
  constant ProviderVertexAI (line 4) | ProviderVertexAI ModelProvider = "vertexai"
  constant VertexAIGemini25Flash (line 7) | VertexAIGemini25Flash ModelID = "vertexai.gemini-2.5-flash"
  constant VertexAIGemini25 (line 8) | VertexAIGemini25      ModelID = "vertexai.gemini-2.5"

FILE: internal/llm/models/xai.go
  constant ProviderXAI (line 4) | ProviderXAI ModelProvider = "xai"
  constant XAIGrok3Beta (line 6) | XAIGrok3Beta         ModelID = "grok-3-beta"
  constant XAIGrok3MiniBeta (line 7) | XAIGrok3MiniBeta     ModelID = "grok-3-mini-beta"
  constant XAIGrok3FastBeta (line 8) | XAIGrok3FastBeta     ModelID = "grok-3-fast-beta"
  constant XAiGrok3MiniFastBeta (line 9) | XAiGrok3MiniFastBeta ModelID = "grok-3-mini-fast-beta"

FILE: internal/llm/prompt/coder.go
  function CoderPrompt (line 16) | func CoderPrompt(provider models.ModelProvider) string {
  constant baseOpenAICoderPrompt (line 27) | baseOpenAICoderPrompt = `
  constant baseAnthropicCoderPrompt (line 74) | baseAnthropicCoderPrompt = `You are OpenCode, an interactive CLI tool th...
  function getEnvironmentInfo (line 170) | func getEnvironmentInfo() string {
  function isGitRepo (line 192) | func isGitRepo(dir string) bool {
  function lspInformation (line 197) | func lspInformation() string {
  function boolToYesNo (line 217) | func boolToYesNo(b bool) string {

FILE: internal/llm/prompt/prompt.go
  function GetAgentPrompt (line 15) | func GetAgentPrompt(agentName config.AgentName, provider models.ModelPro...
  function getContextFromPaths (line 46) | func getContextFromPaths() string {
  function processContextPaths (line 60) | func processContextPaths(workDir string, paths []string) string {
  function processFile (line 131) | func processFile(filePath string) string {

FILE: internal/llm/prompt/prompt_test.go
  function TestGetContextFromPaths (line 14) | func TestGetContextFromPaths(t *testing.T) {
  function createTestFiles (line 42) | func createTestFiles(t *testing.T, tmpDir string, testFiles []string) {

FILE: internal/llm/prompt/summarizer.go
  function SummarizerPrompt (line 5) | func SummarizerPrompt(_ models.ModelProvider) string {

FILE: internal/llm/prompt/task.go
  function TaskPrompt (line 9) | func TaskPrompt(_ models.ModelProvider) string {

FILE: internal/llm/prompt/title.go
  function TitlePrompt (line 5) | func TitlePrompt(_ models.ModelProvider) string {

FILE: internal/llm/provider/anthropic.go
  type anthropicOptions (line 22) | type anthropicOptions struct
  type AnthropicOption (line 28) | type AnthropicOption
  type anthropicClient (line 30) | type anthropicClient struct
    method convertMessages (line 60) | func (a *anthropicClient) convertMessages(messages []message.Message) ...
    method convertTools (line 121) | func (a *anthropicClient) convertTools(tools []toolsPkg.BaseTool) []an...
    method finishReason (line 147) | func (a *anthropicClient) finishReason(reason string) message.FinishRe...
    method preparedMessages (line 162) | func (a *anthropicClient) preparedMessages(messages []anthropic.Messag...
    method send (line 198) | func (a *anthropicClient) send(ctx context.Context, messages []message...
    method stream (line 247) | func (a *anthropicClient) stream(ctx context.Context, messages []messa...
    method shouldRetry (line 395) | func (a *anthropicClient) shouldRetry(attempts int, err error) (bool, ...
    method toolCalls (line 423) | func (a *anthropicClient) toolCalls(msg anthropic.Message) []message.T...
    method usage (line 443) | func (a *anthropicClient) usage(msg anthropic.Message) TokenUsage {
  type AnthropicClient (line 36) | type AnthropicClient
  function newAnthropicClient (line 38) | func newAnthropicClient(opts providerClientOptions) AnthropicClient {
  function WithAnthropicBedrock (line 452) | func WithAnthropicBedrock(useBedrock bool) AnthropicOption {
  function WithAnthropicDisableCache (line 458) | func WithAnthropicDisableCache() AnthropicOption {
  function DefaultShouldThinkFn (line 464) | func DefaultShouldThinkFn(s string) bool {
  function WithAnthropicShouldThinkFn (line 468) | func WithAnthropicShouldThinkFn(fn func(string) bool) AnthropicOption {

FILE: internal/llm/provider/azure.go
  type azureClient (line 12) | type azureClient struct
  type AzureClient (line 16) | type AzureClient
  function newAzureClient (line 18) | func newAzureClient(opts providerClientOptions) AzureClient {

FILE: internal/llm/provider/bedrock.go
  type bedrockOptions (line 14) | type bedrockOptions struct
  type BedrockOption (line 18) | type BedrockOption
  type bedrockClient (line 20) | type bedrockClient struct
    method send (line 78) | func (b *bedrockClient) send(ctx context.Context, messages []message.M...
    method stream (line 85) | func (b *bedrockClient) stream(ctx context.Context, messages []message...
  type BedrockClient (line 26) | type BedrockClient
  function newBedrockClient (line 28) | func newBedrockClient(opts providerClientOptions) BedrockClient {

FILE: internal/llm/provider/copilot.go
  type copilotOptions (line 23) | type copilotOptions struct
  type CopilotOption (line 29) | type CopilotOption
  type copilotClient (line 31) | type copilotClient struct
    method isAnthropicModel (line 46) | func (c *copilotClient) isAnthropicModel() bool {
    method exchangeGitHubToken (line 58) | func (c *copilotClient) exchangeGitHubToken(githubToken string) (strin...
    method convertMessages (line 189) | func (c *copilotClient) convertMessages(messages []message.Message) (c...
    method convertTools (line 249) | func (c *copilotClient) convertTools(tools []toolsPkg.BaseTool) []open...
    method finishReason (line 270) | func (c *copilotClient) finishReason(reason string) message.FinishReas...
    method preparedParams (line 283) | func (c *copilotClient) preparedParams(messages []openai.ChatCompletio...
    method send (line 309) | func (c *copilotClient) send(ctx context.Context, messages []message.M...
    method stream (line 376) | func (c *copilotClient) stream(ctx context.Context, messages []message...
    method shouldRetry (line 546) | func (c *copilotClient) shouldRetry(attempts int, err error) (bool, in...
    method toolCalls (line 616) | func (c *copilotClient) toolCalls(completion openai.ChatCompletion) []...
    method usage (line 635) | func (c *copilotClient) usage(completion openai.ChatCompletion) TokenU...
  type CopilotClient (line 38) | type CopilotClient
  type CopilotTokenResponse (line 41) | type CopilotTokenResponse struct
  function newCopilotClient (line 86) | func newCopilotClient(opts providerClientOptions) CopilotClient {
  function WithCopilotReasoningEffort (line 647) | func WithCopilotReasoningEffort(effort string) CopilotOption {
  function WithCopilotExtraHeaders (line 660) | func WithCopilotExtraHeaders(headers map[string]string) CopilotOption {
  function WithCopilotBearerToken (line 666) | func WithCopilotBearerToken(bearerToken string) CopilotOption {

FILE: internal/llm/provider/gemini.go
  type geminiOptions (line 20) | type geminiOptions struct
  type GeminiOption (line 24) | type GeminiOption
  type geminiClient (line 26) | type geminiClient struct
    method convertMessages (line 53) | func (g *geminiClient) convertMessages(messages []message.Message) []*...
    method convertTools (line 135) | func (g *geminiClient) convertTools(tools []tools.BaseTool) []*genai.T...
    method finishReason (line 157) | func (g *geminiClient) finishReason(reason genai.FinishReason) message...
    method send (line 168) | func (g *geminiClient) send(ctx context.Context, messages []message.Me...
    method stream (line 256) | func (g *geminiClient) stream(ctx context.Context, messages []message....
    method shouldRetry (line 394) | func (g *geminiClient) shouldRetry(attempts int, err error) (bool, int...
    method toolCalls (line 426) | func (g *geminiClient) toolCalls(resp *genai.GenerateContentResponse) ...
    method usage (line 447) | func (g *geminiClient) usage(resp *genai.GenerateContentResponse) Toke...
  type GeminiClient (line 32) | type GeminiClient
  function newGeminiClient (line 34) | func newGeminiClient(opts providerClientOptions) GeminiClient {
  function WithGeminiDisableCache (line 460) | func WithGeminiDisableCache() GeminiOption {
  function parseJsonToMap (line 467) | func parseJsonToMap(jsonStr string) (map[string]interface{}, error) {
  function convertSchemaProperties (line 473) | func convertSchemaProperties(parameters map[string]interface{}) map[stri...
  function convertToSchema (line 483) | func convertToSchema(param interface{}) *genai.Schema {
  function processArrayItems (line 519) | func processArrayItems(paramMap map[string]interface{}) *genai.Schema {
  function mapJSONTypeToGenAI (line 528) | func mapJSONTypeToGenAI(jsonType string) genai.Type {
  function contains (line 547) | func contains(s string, substrs ...string) bool {

FILE: internal/llm/provider/openai.go
  type openaiOptions (line 21) | type openaiOptions struct
  type OpenAIOption (line 28) | type OpenAIOption
  type openaiClient (line 30) | type openaiClient struct
    method convertMessages (line 68) | func (o *openaiClient) convertMessages(messages []message.Message) (op...
    method convertTools (line 128) | func (o *openaiClient) convertTools(tools []tools.BaseTool) []openai.C...
    method finishReason (line 149) | func (o *openaiClient) finishReason(reason string) message.FinishReason {
    method preparedParams (line 162) | func (o *openaiClient) preparedParams(messages []openai.ChatCompletion...
    method send (line 188) | func (o *openaiClient) send(ctx context.Context, messages []message.Me...
    method stream (line 241) | func (o *openaiClient) stream(ctx context.Context, messages []message....
    method shouldRetry (line 337) | func (o *openaiClient) shouldRetry(attempts int, err error) (bool, int...
    method toolCalls (line 365) | func (o *openaiClient) toolCalls(completion openai.ChatCompletion) []m...
    method usage (line 384) | func (o *openaiClient) usage(completion openai.ChatCompletion) TokenUs...
  type OpenAIClient (line 36) | type OpenAIClient
  function newOpenAIClient (line 38) | func newOpenAIClient(opts providerClientOptions) OpenAIClient {
  function WithOpenAIBaseURL (line 396) | func WithOpenAIBaseURL(baseURL string) OpenAIOption {
  function WithOpenAIExtraHeaders (line 402) | func WithOpenAIExtraHeaders(headers map[string]string) OpenAIOption {
  function WithOpenAIDisableCache (line 408) | func WithOpenAIDisableCache() OpenAIOption {
  function WithReasoningEffort (line 414) | func WithReasoningEffort(effort string) OpenAIOption {

FILE: internal/llm/provider/provider.go
  type EventType (line 13) | type EventType
  constant maxRetries (line 15) | maxRetries = 8
  constant EventContentStart (line 18) | EventContentStart  EventType = "content_start"
  constant EventToolUseStart (line 19) | EventToolUseStart  EventType = "tool_use_start"
  constant EventToolUseDelta (line 20) | EventToolUseDelta  EventType = "tool_use_delta"
  constant EventToolUseStop (line 21) | EventToolUseStop   EventType = "tool_use_stop"
  constant EventContentDelta (line 22) | EventContentDelta  EventType = "content_delta"
  constant EventThinkingDelta (line 23) | EventThinkingDelta EventType = "thinking_delta"
  constant EventContentStop (line 24) | EventContentStop   EventType = "content_stop"
  constant EventComplete (line 25) | EventComplete      EventType = "complete"
  constant EventError (line 26) | EventError         EventType = "error"
  constant EventWarning (line 27) | EventWarning       EventType = "warning"
  type TokenUsage (line 30) | type TokenUsage struct
  type ProviderResponse (line 37) | type ProviderResponse struct
  type ProviderEvent (line 44) | type ProviderEvent struct
  type Provider (line 53) | type Provider interface
  type providerClientOptions (line 61) | type providerClientOptions struct
  type ProviderClientOption (line 74) | type ProviderClientOption
  type ProviderClient (line 76) | type ProviderClient interface
  type baseProvider (line 81) | type baseProvider struct
  function NewProvider (line 86) | func NewProvider(providerName models.ModelProvider, opts ...ProviderClie...
  method cleanMessages (line 170) | func (p *baseProvider[C]) cleanMessages(messages []message.Message) (cle...
  method SendMessages (line 181) | func (p *baseProvider[C]) SendMessages(ctx context.Context, messages []m...
  method Model (line 186) | func (p *baseProvider[C]) Model() models.Model {
  method StreamResponse (line 190) | func (p *baseProvider[C]) StreamResponse(ctx context.Context, messages [...
  function WithAPIKey (line 195) | func WithAPIKey(apiKey string) ProviderClientOption {
  function WithModel (line 201) | func WithModel(model models.Model) ProviderClientOption {
  function WithMaxTokens (line 207) | func WithMaxTokens(maxTokens int64) ProviderClientOption {
  function WithSystemMessage (line 213) | func WithSystemMessage(systemMessage string) ProviderClientOption {
  function WithAnthropicOptions (line 219) | func WithAnthropicOptions(anthropicOptions ...AnthropicOption) ProviderC...
  function WithOpenAIOptions (line 225) | func WithOpenAIOptions(openaiOptions ...OpenAIOption) ProviderClientOpti...
  function WithGeminiOptions (line 231) | func WithGeminiOptions(geminiOptions ...GeminiOption) ProviderClientOpti...
  function WithBedrockOptions (line 237) | func WithBedrockOptions(bedrockOptions ...BedrockOption) ProviderClientO...
  function WithCopilotOptions (line 243) | func WithCopilotOptions(copilotOptions ...CopilotOption) ProviderClientO...

FILE: internal/llm/provider/vertexai.go
  type VertexAIClient (line 11) | type VertexAIClient
  function newVertexAIClient (line 13) | func newVertexAIClient(opts providerClientOptions) VertexAIClient {

FILE: internal/llm/tools/bash.go
  type BashParams (line 15) | type BashParams struct
  type BashPermissionsParams (line 20) | type BashPermissionsParams struct
  type BashResponseMetadata (line 25) | type BashResponseMetadata struct
  type bashTool (line 29) | type bashTool struct
    method Info (line 212) | func (b *bashTool) Info() ToolInfo {
    method Run (line 230) | func (b *bashTool) Run(ctx context.Context, call ToolCall) (ToolRespon...
  constant BashToolName (line 34) | BashToolName = "bash"
  constant DefaultTimeout (line 36) | DefaultTimeout  = 1 * 60 * 1000
  constant MaxTimeout (line 37) | MaxTimeout      = 10 * 60 * 1000
  constant MaxOutputLength (line 38) | MaxOutputLength = 30000
  function bashDescription (line 57) | func bashDescription() string {
  function NewBashTool (line 206) | func NewBashTool(permission permission.Service) BaseTool {
  function truncateOutput (line 329) | func truncateOutput(content string) string {
  function countLines (line 342) | func countLines(s string) int {

FILE: internal/llm/tools/diagnostics.go
  type DiagnosticsParams (line 16) | type DiagnosticsParams struct
  type diagnosticsTool (line 19) | type diagnosticsTool struct
    method Info (line 54) | func (b *diagnosticsTool) Info() ToolInfo {
    method Run (line 68) | func (b *diagnosticsTool) Run(ctx context.Context, call ToolCall) (Too...
  constant DiagnosticsToolName (line 24) | DiagnosticsToolName    = "diagnostics"
  constant diagnosticsDescription (line 25) | diagnosticsDescription = `Get diagnostics for a file and/or project.
  function NewDiagnosticsTool (line 48) | func NewDiagnosticsTool(lspClients map[string]*lsp.Client) BaseTool {
  function notifyLspOpenFile (line 90) | func notifyLspOpenFile(ctx context.Context, filePath string, lsps map[st...
  function waitForLspDiagnostics (line 99) | func waitForLspDiagnostics(ctx context.Context, filePath string, lsps ma...
  function hasDiagnosticsChanged (line 147) | func hasDiagnosticsChanged(current, original map[protocol.DocumentUri][]...
  function getDiagnostics (line 157) | func getDiagnostics(filePath string, lsps map[string]*lsp.Client) string {
  function countSeverity (line 287) | func countSeverity(diagnostics []string, severity string) int {

FILE: internal/llm/tools/edit.go
  type EditParams (line 20) | type EditParams struct
  type EditPermissionsParams (line 26) | type EditPermissionsParams struct
  type EditResponseMetadata (line 31) | type EditResponseMetadata struct
  type editTool (line 37) | type editTool struct
    method Info (line 102) | func (e *editTool) Info() ToolInfo {
    method Run (line 124) | func (e *editTool) Run(ctx context.Context, call ToolCall) (ToolRespon...
    method createNewFile (line 173) | func (e *editTool) createNewFile(ctx context.Context, filePath, conten...
    method deleteContent (line 253) | func (e *editTool) deleteContent(ctx context.Context, filePath, oldStr...
    method replaceContent (line 372) | func (e *editTool) replaceContent(ctx context.Context, filePath, oldSt...
  constant EditToolName (line 44) | EditToolName    = "edit"
  constant editDescription (line 45) | editDescription = `Edits files by replacing text, creating new files, or...
  function NewEditTool (line 94) | func NewEditTool(lspClients map[string]*lsp.Client, permissions permissi...

FILE: internal/llm/tools/fetch.go
  type FetchParams (line 18) | type FetchParams struct
  type FetchPermissionsParams (line 24) | type FetchPermissionsParams struct
  type fetchTool (line 30) | type fetchTool struct
    method Info (line 77) | func (t *fetchTool) Info() ToolInfo {
    method Run (line 100) | func (t *fetchTool) Run(ctx context.Context, call ToolCall) (ToolRespo...
  constant FetchToolName (line 36) | FetchToolName        = "fetch"
  constant fetchToolDescription (line 37) | fetchToolDescription = `Fetches content from a URL and returns it in the...
  function NewFetchTool (line 68) | func NewFetchTool(permissions permission.Service) BaseTool {
  function extractTextFromHTML (line 206) | func extractTextFromHTML(html string) (string, error) {
  function convertHTMLToMarkdown (line 218) | func convertHTMLToMarkdown(html string) (string, error) {

FILE: internal/llm/tools/file.go
  type fileRecord (line 9) | type fileRecord struct
  function recordFileRead (line 20) | func recordFileRead(path string) {
  function getLastReadTime (line 32) | func getLastReadTime(path string) time.Time {
  function recordFileWrite (line 43) | func recordFileWrite(path string) {

FILE: internal/llm/tools/glob.go
  constant GlobToolName (line 19) | GlobToolName    = "glob"
  constant globDescription (line 20) | globDescription = `Fast file pattern matching tool that finds files by n...
  type GlobParams (line 56) | type GlobParams struct
  type GlobResponseMetadata (line 61) | type GlobResponseMetadata struct
  type globTool (line 66) | type globTool struct
    method Info (line 72) | func (g *globTool) Info() ToolInfo {
    method Run (line 90) | func (g *globTool) Run(ctx context.Context, call ToolCall) (ToolRespon...
  function NewGlobTool (line 68) | func NewGlobTool() BaseTool {
  function globFiles (line 129) | func globFiles(pattern, searchPath string, limit int) ([]string, bool, e...
  function runRipgrep (line 143) | func runRipgrep(cmd *exec.Cmd, searchRoot string, limit int) ([]string, ...

FILE: internal/llm/tools/grep.go
  type GrepParams (line 21) | type GrepParams struct
  type grepMatch (line 28) | type grepMatch struct
  type GrepResponseMetadata (line 35) | type GrepResponseMetadata struct
  type grepTool (line 40) | type grepTool struct
    method Info (line 86) | func (g *grepTool) Info() ToolInfo {
    method Run (line 124) | func (g *grepTool) Run(ctx context.Context, call ToolCall) (ToolRespon...
  constant GrepToolName (line 43) | GrepToolName    = "grep"
  constant grepDescription (line 44) | grepDescription = `Fast content search tool that finds files containing ...
  function NewGrepTool (line 82) | func NewGrepTool() BaseTool {
  function escapeRegexPattern (line 113) | func escapeRegexPattern(pattern string) string {
  function searchFiles (line 186) | func searchFiles(pattern, rootPath, include string, limit int) ([]grepMa...
  function searchWithRipgrep (line 207) | func searchWithRipgrep(pattern, path, include string) ([]grepMatch, erro...
  function searchFilesWithRegex (line 266) | func searchFilesWithRegex(pattern, rootPath, include string) ([]grepMatc...
  function fileContainsPattern (line 327) | func fileContainsPattern(filePath string, pattern *regexp.Regexp) (bool,...
  function globToRegex (line 347) | func globToRegex(glob string) string {

FILE: internal/llm/tools/ls.go
  type LSParams (line 14) | type LSParams struct
  type TreeNode (line 19) | type TreeNode struct
  type LSResponseMetadata (line 26) | type LSResponseMetadata struct
  type lsTool (line 31) | type lsTool struct
    method Info (line 70) | func (l *lsTool) Info() ToolInfo {
    method Run (line 91) | func (l *lsTool) Run(ctx context.Context, call ToolCall) (ToolResponse...
  constant LSToolName (line 34) | LSToolName    = "ls"
  constant MaxLSFiles (line 35) | MaxLSFiles    = 1000
  constant lsDescription (line 36) | lsDescription = `Directory listing tool that shows files and subdirector...
  function NewLsTool (line 66) | func NewLsTool() BaseTool {
  function listDirectory (line 131) | func listDirectory(initialPath string, ignorePatterns []string, limit in...
  function shouldSkip (line 168) | func shouldSkip(path string, ignorePatterns []string) bool {
  function createFileTree (line 226) | func createFileTree(sortedPaths []string) []*TreeNode {
  function printTree (line 289) | func printTree(tree []*TreeNode, rootPath string) string {
  function printNode (line 301) | func printNode(builder *strings.Builder, node *TreeNode, level int) {

FILE: internal/llm/tools/ls_test.go
  function TestLsTool_Info (line 15) | func TestLsTool_Info(t *testing.T) {
  function TestLsTool_Run (line 26) | func TestLsTool_Run(t *testing.T) {
  function TestShouldSkip (line 220) | func TestShouldSkip(t *testing.T) {
  function TestCreateFileTree (line 285) | func TestCreateFileTree(t *testing.T) {
  function TestPrintTree (line 324) | func TestPrintTree(t *testing.T) {
  function TestListDirectory (line 369) | func TestListDirectory(t *testing.T) {

FILE: internal/llm/tools/patch.go
  type PatchParams (line 19) | type PatchParams struct
  type PatchResponseMetadata (line 23) | type PatchResponseMetadata struct
  type patchTool (line 29) | type patchTool struct
    method Info (line 75) | func (p *patchTool) Info() ToolInfo {
    method Run (line 89) | func (p *patchTool) Run(ctx context.Context, call ToolCall) (ToolRespo...
  constant PatchToolName (line 36) | PatchToolName    = "patch"
  constant patchDescription (line 37) | patchDescription = `Applies a patch to multiple files in one operation. ...
  function NewPatchTool (line 67) | func NewPatchTool(lspClients map[string]*lsp.Client, permissions permiss...

FILE: internal/llm/tools/shell/shell.go
  type PersistentShell (line 18) | type PersistentShell struct
    method processCommands (line 132) | func (s *PersistentShell) processCommands() {
    method execCommand (line 139) | func (s *PersistentShell) execCommand(command string, timeout time.Dur...
    method killChildren (line 246) | func (s *PersistentShell) killChildren() {
    method Exec (line 271) | func (s *PersistentShell) Exec(ctx context.Context, command string, ti...
    method Close (line 290) | func (s *PersistentShell) Close() {
  type commandExecution (line 27) | type commandExecution struct
  type commandResult (line 34) | type commandResult struct
  function GetPersistentShell (line 47) | func GetPersistentShell(workingDir string) *PersistentShell {
  function newPersistentShell (line 61) | func newPersistentShell(cwd string) *PersistentShell {
  function shellQuote (line 304) | func shellQuote(s string) string {
  function readFileOrEmpty (line 308) | func readFileOrEmpty(path string) string {
  function fileExists (line 316) | func fileExists(path string) bool {
  function fileSize (line 321) | func fileSize(path string) int64 {

FILE: internal/llm/tools/sourcegraph.go
  type SourcegraphParams (line 14) | type SourcegraphParams struct
  type SourcegraphResponseMetadata (line 21) | type SourcegraphResponseMetadata struct
  type sourcegraphTool (line 26) | type sourcegraphTool struct
    method Info (line 136) | func (t *sourcegraphTool) Info() ToolInfo {
    method Run (line 162) | func (t *sourcegraphTool) Run(ctx context.Context, call ToolCall) (Too...
  constant SourcegraphToolName (line 31) | SourcegraphToolName        = "sourcegraph"
  constant sourcegraphToolDescription (line 32) | sourcegraphToolDescription = `Search code across public repositories usi...
  function NewSourcegraphTool (line 128) | func NewSourcegraphTool() BaseTool {
  function formatSourcegraphResults (line 255) | func formatSourcegraphResults(result map[string]any, contextWindow int) ...

FILE: internal/llm/tools/tools.go
  type ToolInfo (line 8) | type ToolInfo struct
  type toolResponseType (line 15) | type toolResponseType
  type sessionIDContextKey (line 18) | type sessionIDContextKey
  type messageIDContextKey (line 19) | type messageIDContextKey
  constant ToolResponseTypeText (line 23) | ToolResponseTypeText  toolResponseType = "text"
  constant ToolResponseTypeImage (line 24) | ToolResponseTypeImage toolResponseType = "image"
  constant SessionIDContextKey (line 26) | SessionIDContextKey sessionIDContextKey = "session_id"
  constant MessageIDContextKey (line 27) | MessageIDContextKey messageIDContextKey = "message_id"
  type ToolResponse (line 30) | type ToolResponse struct
  function NewTextResponse (line 37) | func NewTextResponse(content string) ToolResponse {
  function WithResponseMetadata (line 44) | func WithResponseMetadata(response ToolResponse, metadata any) ToolRespo...
  function NewTextErrorResponse (line 55) | func NewTextErrorResponse(content string) ToolResponse {
  type ToolCall (line 63) | type ToolCall struct
  type BaseTool (line 69) | type BaseTool interface
  function GetContextValues (line 74) | func GetContextValues(ctx context.Context) (string, string) {

FILE: internal/llm/tools/view.go
  type ViewParams (line 18) | type ViewParams struct
  type viewTool (line 24) | type viewTool struct
    method Info (line 76) | func (v *viewTool) Info() ToolInfo {
    method Run (line 99) | func (v *viewTool) Run(ctx context.Context, call ToolCall) (ToolRespon...
  type ViewResponseMetadata (line 28) | type ViewResponseMetadata struct
  constant ViewToolName (line 34) | ViewToolName     = "view"
  constant MaxReadSize (line 35) | MaxReadSize      = 250 * 1024
  constant DefaultReadLimit (line 36) | DefaultReadLimit = 2000
  constant MaxLineLength (line 37) | MaxLineLength    = 2000
  constant viewDescription (line 38) | viewDescription  = `File viewing tool that reads and displays the conten...
  function NewViewTool (line 70) | func NewViewTool(lspClients map[string]*lsp.Client) BaseTool {
  function addLineNumbers (line 199) | func addLineNumbers(content string, startLine int) string {
  function readTextFile (line 224) | func readTextFile(filePath string, offset, limit int) (string, int, erro...
  function isImageFile (line 274) | func isImageFile(filePath string) (bool, string) {
  type LineScanner (line 294) | type LineScanner struct
    method Scan (line 304) | func (s *LineScanner) Scan() bool {
    method Text (line 308) | func (s *LineScanner) Text() string {
    method Err (line 312) | func (s *LineScanner) Err() error {
  function NewLineScanner (line 298) | func NewLineScanner(r io.Reader) *LineScanner {

FILE: internal/llm/tools/write.go
  type WriteParams (line 20) | type WriteParams struct
  type WritePermissionsParams (line 25) | type WritePermissionsParams struct
  type writeTool (line 30) | type writeTool struct
    method Info (line 82) | func (w *writeTool) Info() ToolInfo {
    method Run (line 100) | func (w *writeTool) Run(ctx context.Context, call ToolCall) (ToolRespo...
  type WriteResponseMetadata (line 36) | type WriteResponseMetadata struct
  constant WriteToolName (line 43) | WriteToolName    = "write"
  constant writeDescription (line 44) | writeDescription = `File writing tool that creates or updates files in t...
  function NewWriteTool (line 74) | func NewWriteTool(lspClients map[string]*lsp.Client, permissions permiss...

FILE: internal/logging/logger.go
  function getCaller (line 15) | func getCaller() string {
  function Info (line 25) | func Info(msg string, args ...any) {
  function Debug (line 30) | func Debug(msg string, args ...any) {
  function Warn (line 36) | func Warn(msg string, args ...any) {
  function Error (line 40) | func Error(msg string, args ...any) {
  function InfoPersist (line 44) | func InfoPersist(msg string, args ...any) {
  function DebugPersist (line 49) | func DebugPersist(msg string, args ...any) {
  function WarnPersist (line 54) | func WarnPersist(msg string, args ...any) {
  function ErrorPersist (line 59) | func ErrorPersist(msg string, args ...any) {
  function RecoverPanic (line 67) | func RecoverPanic(name string, cleanup func()) {
  function GetSessionPrefix (line 100) | func GetSessionPrefix(sessionId string) string {
  function AppendToSessionLogFile (line 106) | func AppendToSessionLogFile(sessionId string, filename string, content s...
  function WriteRequestMessageJson (line 141) | func WriteRequestMessageJson(sessionId string, requestSeqId int, message...
  function WriteRequestMessage (line 153) | func WriteRequestMessage(sessionId string, requestSeqId int, message str...
  function AppendToStreamSessionLogJson (line 162) | func AppendToStreamSessionLogJson(sessionId string, requestSeqId int, js...
  function AppendToStreamSessionLog (line 174) | func AppendToStreamSessionLog(sessionId string, requestSeqId int, chunk ...
  function WriteChatResponseJson (line 182) | func WriteChatResponseJson(sessionId string, requestSeqId int, response ...
  function WriteToolResultsJson (line 196) | func WriteToolResultsJson(sessionId string, requestSeqId int, toolResult...

FILE: internal/logging/message.go
  type LogMessage (line 8) | type LogMessage struct
  type Attr (line 18) | type Attr struct

FILE: internal/logging/writer.go
  constant persistKeyArg (line 16) | persistKeyArg  = "$_persist"
  constant PersistTimeArg (line 17) | PersistTimeArg = "$_persist_time"
  type LogData (line 20) | type LogData struct
    method Add (line 26) | func (l *LogData) Add(msg LogMessage) {
    method List (line 33) | func (l *LogData) List() []LogMessage {
  type writer (line 44) | type writer struct
    method Write (line 46) | func (w *writer) Write(p []byte) (int, error) {
  function NewWriter (line 91) | func NewWriter() *writer {
  function Subscribe (line 96) | func Subscribe(ctx context.Context) <-chan pubsub.Event[LogMessage] {
  function List (line 100) | func List() []LogMessage {

FILE: internal/lsp/client.go
  type Client (line 22) | type Client struct
    method RegisterNotificationHandler (line 117) | func (c *Client) RegisterNotificationHandler(method string, handler No...
    method RegisterServerRequestHandler (line 123) | func (c *Client) RegisterServerRequestHandler(method string, handler S...
    method InitializeLSPClient (line 129) | func (c *Client) InitializeLSPClient(ctx context.Context, workspaceDir...
    method Close (line 233) | func (c *Client) Close() error {
    method GetServerState (line 274) | func (c *Client) GetServerState() ServerState {
    method SetServerState (line 282) | func (c *Client) SetServerState(state ServerState) {
    method WaitForServerReady (line 288) | func (c *Client) WaitForServerReady(ctx context.Context) error {
    method detectServerType (line 356) | func (c *Client) detectServerType() ServerType {
    method openKeyConfigFiles (line 378) | func (c *Client) openKeyConfigFiles(ctx context.Context) {
    method pingServerByType (line 421) | func (c *Client) pingServerByType(ctx context.Context, serverType Serv...
    method pingTypeScriptServer (line 439) | func (c *Client) pingTypeScriptServer(ctx context.Context) error {
    method openTypeScriptFiles (line 498) | func (c *Client) openTypeScriptFiles(ctx context.Context, workDir stri...
    method pingWithWorkspaceSymbol (line 570) | func (c *Client) pingWithWorkspaceSymbol(ctx context.Context) error {
    method pingWithServerCapabilities (line 578) | func (c *Client) pingWithServerCapabilities(ctx context.Context) error {
    method OpenFile (line 588) | func (c *Client) OpenFile(ctx context.Context, filepath string) error {
    method NotifyChange (line 627) | func (c *Client) NotifyChange(ctx context.Context, filepath string) er...
    method CloseFile (line 666) | func (c *Client) CloseFile(ctx context.Context, filepath string) error {
    method IsFileOpen (line 697) | func (c *Client) IsFileOpen(filepath string) bool {
    method CloseAllFiles (line 706) | func (c *Client) CloseAllFiles(ctx context.Context) {
    method GetFileDiagnostics (line 732) | func (c *Client) GetFileDiagnostics(uri protocol.DocumentUri) []protoc...
    method GetDiagnostics (line 740) | func (c *Client) GetDiagnostics() map[protocol.DocumentUri][]protocol....
    method OpenFileOnDemand (line 746) | func (c *Client) OpenFileOnDemand(ctx context.Context, filepath string...
    method GetDiagnosticsForFile (line 758) | func (c *Client) GetDiagnosticsForFile(ctx context.Context, filepath s...
    method ClearDiagnosticsForURI (line 781) | func (c *Client) ClearDiagnosticsForURI(uri protocol.DocumentUri) {
  function NewClient (line 55) | func NewClient(ctx context.Context, command string, args ...string) (*Cl...
  type ServerState (line 265) | type ServerState
  constant StateStarting (line 268) | StateStarting ServerState = iota
  constant StateReady (line 269) | StateReady
  constant StateError (line 270) | StateError
  type ServerType (line 344) | type ServerType
  constant ServerTypeUnknown (line 347) | ServerTypeUnknown ServerType = iota
  constant ServerTypeGo (line 348) | ServerTypeGo
  constant ServerTypeTypeScript (line 349) | ServerTypeTypeScript
  constant ServerTypeRust (line 350) | ServerTypeRust
  constant ServerTypePython (line 351) | ServerTypePython
  constant ServerTypeGeneric (line 352) | ServerTypeGeneric
  function shouldSkipDir (line 548) | func shouldSkipDir(path string) bool {
  type OpenFileInfo (line 583) | type OpenFileInfo struct

FILE: internal/lsp/handlers.go
  function HandleWorkspaceConfiguration (line 14) | func HandleWorkspaceConfiguration(params json.RawMessage) (any, error) {
  function HandleRegisterCapability (line 18) | func HandleRegisterCapability(params json.RawMessage) (any, error) {
  function HandleApplyEdit (line 49) | func HandleApplyEdit(params json.RawMessage) (any, error) {
  type FileWatchRegistrationHandler (line 65) | type FileWatchRegistrationHandler
  function RegisterFileWatchHandler (line 71) | func RegisterFileWatchHandler(handler FileWatchRegistrationHandler) {
  function notifyFileWatchRegistration (line 76) | func notifyFileWatchRegistration(id string, watchers []protocol.FileSyst...
  function HandleServerMessage (line 84) | func HandleServerMessage(params json.RawMessage) {
  function HandleDiagnostics (line 97) | func HandleDiagnostics(client *Client, params json.RawMessage) {

FILE: internal/lsp/language.go
  function DetectLanguageID (line 10) | func DetectLanguageID(uri string) protocol.LanguageKind {

FILE: internal/lsp/methods.go
  method Implementation (line 12) | func (c *Client) Implementation(ctx context.Context, params protocol.Imp...
  method TypeDefinition (line 20) | func (c *Client) TypeDefinition(ctx context.Context, params protocol.Typ...
  method DocumentColor (line 28) | func (c *Client) DocumentColor(ctx context.Context, params protocol.Docu...
  method ColorPresentation (line 36) | func (c *Client) ColorPresentation(ctx context.Context, params protocol....
  method FoldingRange (line 44) | func (c *Client) FoldingRange(ctx context.Context, params protocol.Foldi...
  method Declaration (line 52) | func (c *Client) Declaration(ctx context.Context, params protocol.Declar...
  method SelectionRange (line 60) | func (c *Client) SelectionRange(ctx context.Context, params protocol.Sel...
  method PrepareCallHierarchy (line 68) | func (c *Client) PrepareCallHierarchy(ctx context.Context, params protoc...
  method IncomingCalls (line 76) | func (c *Client) IncomingCalls(ctx context.Context, params protocol.Call...
  method OutgoingCalls (line 84) | func (c *Client) OutgoingCalls(ctx context.Context, params protocol.Call...
  method SemanticTokensFull (line 92) | func (c *Client) SemanticTokensFull(ctx context.Context, params protocol...
  method SemanticTokensFullDelta (line 100) | func (c *Client) SemanticTokensFullDelta(ctx context.Context, params pro...
  method SemanticTokensRange (line 108) | func (c *Client) SemanticTokensRange(ctx context.Context, params protoco...
  method LinkedEditingRange (line 116) | func (c *Client) LinkedEditingRange(ctx context.Context, params protocol...
  method WillCreateFiles (line 124) | func (c *Client) WillCreateFiles(ctx context.Context, params protocol.Cr...
  method WillRenameFiles (line 132) | func (c *Client) WillRenameFiles(ctx context.Context, params protocol.Re...
  method WillDeleteFiles (line 140) | func (c *Client) WillDeleteFiles(ctx context.Context, params protocol.De...
  method Moniker (line 148) | func (c *Client) Moniker(ctx context.Context, params protocol.MonikerPar...
  method PrepareTypeHierarchy (line 156) | func (c *Client) PrepareTypeHierarchy(ctx context.Context, params protoc...
  method Supertypes (line 164) | func (c *Client) Supertypes(ctx context.Context, params protocol.TypeHie...
  method Subtypes (line 172) | func (c *Client) Subtypes(ctx context.Context, params protocol.TypeHiera...
  method InlineValue (line 180) | func (c *Client) InlineValue(ctx context.Context, params protocol.Inline...
  method InlayHint (line 188) | func (c *Client) InlayHint(ctx context.Context, params protocol.InlayHin...
  method Resolve (line 196) | func (c *Client) Resolve(ctx context.Context, params protocol.InlayHint)...
  method Diagnostic (line 204) | func (c *Client) Diagnostic(ctx context.Context, params protocol.Documen...
  method DiagnosticWorkspace (line 212) | func (c *Client) DiagnosticWorkspace(ctx context.Context, params protoco...
  method InlineCompletion (line 220) | func (c *Client) InlineCompletion(ctx context.Context, params protocol.I...
  method TextDocumentContent (line 228) | func (c *Client) TextDocumentContent(ctx context.Context, params protoco...
  method Initialize (line 236) | func (c *Client) Initialize(ctx context.Context, params protocol.ParamIn...
  method Shutdown (line 244) | func (c *Client) Shutdown(ctx context.Context) error {
  method WillSaveWaitUntil (line 250) | func (c *Client) WillSaveWaitUntil(ctx context.Context, params protocol....
  method Completion (line 258) | func (c *Client) Completion(ctx context.Context, params protocol.Complet...
  method ResolveCompletionItem (line 266) | func (c *Client) ResolveCompletionItem(ctx context.Context, params proto...
  method Hover (line 274) | func (c *Client) Hover(ctx context.Context, params protocol.HoverParams)...
  method SignatureHelp (line 281) | func (c *Client) SignatureHelp(ctx context.Context, params protocol.Sign...
  method Definition (line 289) | func (c *Client) Definition(ctx context.Context, params protocol.Definit...
  method References (line 297) | func (c *Client) References(ctx context.Context, params protocol.Referen...
  method DocumentHighlight (line 305) | func (c *Client) DocumentHighlight(ctx context.Context, params protocol....
  method DocumentSymbol (line 313) | func (c *Client) DocumentSymbol(ctx context.Context, params protocol.Doc...
  method CodeAction (line 321) | func (c *Client) CodeAction(ctx context.Context, params protocol.CodeAct...
  method ResolveCodeAction (line 329) | func (c *Client) ResolveCodeAction(ctx context.Context, params protocol....
  method Symbol (line 337) | func (c *Client) Symbol(ctx context.Context, params protocol.WorkspaceSy...
  method ResolveWorkspaceSymbol (line 345) | func (c *Client) ResolveWorkspaceSymbol(ctx context.Context, params prot...
  method CodeLens (line 353) | func (c *Client) CodeLens(ctx context.Context, params protocol.CodeLensP...
  method ResolveCodeLens (line 361) | func (c *Client) ResolveCodeLens(ctx context.Context, params protocol.Co...
  method DocumentLink (line 369) | func (c *Client) DocumentLink(ctx context.Context, params protocol.Docum...
  method ResolveDocumentLink (line 377) | func (c *Client) ResolveDocumentLink(ctx context.Context, params protoco...
  method Formatting (line 385) | func (c *Client) Formatting(ctx context.Context, params protocol.Documen...
  method RangeFormatting (line 393) | func (c *Client) RangeFormatting(ctx context.Context, params protocol.Do...
  method RangesFormatting (line 401) | func (c *Client) RangesFormatting(ctx context.Context, params protocol.D...
  method OnTypeFormatting (line 409) | func (c *Client) OnTypeFormatting(ctx context.Context, params protocol.D...
  method Rename (line 417) | func (c *Client) Rename(ctx context.Context, params protocol.RenameParam...
  method PrepareRename (line 425) | func (c *Client) PrepareRename(ctx context.Context, params protocol.Prep...
  method ExecuteCommand (line 433) | func (c *Client) ExecuteCommand(ctx context.Context, params protocol.Exe...
  method DidChangeWorkspaceFolders (line 441) | func (c *Client) DidChangeWorkspaceFolders(ctx context.Context, params p...
  method WorkDoneProgressCancel (line 447) | func (c *Client) WorkDoneProgressCancel(ctx context.Context, params prot...
  method DidCreateFiles (line 453) | func (c *Client) DidCreateFiles(ctx context.Context, params protocol.Cre...
  method DidRenameFiles (line 459) | func (c *Client) DidRenameFiles(ctx context.Context, params protocol.Ren...
  method DidDeleteFiles (line 465) | func (c *Client) DidDeleteFiles(ctx context.Context, params protocol.Del...
  method DidOpenNotebookDocument (line 471) | func (c *Client) DidOpenNotebookDocument(ctx context.Context, params pro...
  method DidChangeNotebookDocument (line 476) | func (c *Client) DidChangeNotebookDocument(ctx context.Context, params p...
  method DidSaveNotebookDocument (line 482) | func (c *Client) DidSaveNotebookDocument(ctx context.Context, params pro...
  method DidCloseNotebookDocument (line 488) | func (c *Client) DidCloseNotebookDocument(ctx context.Context, params pr...
  method Initialized (line 494) | func (c *Client) Initialized(ctx context.Context, params protocol.Initia...
  method Exit (line 500) | func (c *Client) Exit(ctx context.Context) error {
  method DidChangeConfiguration (line 506) | func (c *Client) DidChangeConfiguration(ctx context.Context, params prot...
  method DidOpen (line 512) | func (c *Client) DidOpen(ctx context.Context, params protocol.DidOpenTex...
  method DidChange (line 518) | func (c *Client) DidChange(ctx context.Context, params protocol.DidChang...
  method DidClose (line 524) | func (c *Client) DidClose(ctx context.Context, params protocol.DidCloseT...
  method DidSave (line 530) | func (c *Client) DidSave(ctx context.Context, params protocol.DidSaveTex...
  method WillSave (line 536) | func (c *Client) WillSave(ctx context.Context, params protocol.WillSaveT...
  method DidChangeWatchedFiles (line 542) | func (c *Client) DidChangeWatchedFiles(ctx context.Context, params proto...
  method SetTrace (line 547) | func (c *Client) SetTrace(ctx context.Context, params protocol.SetTraceP...
  method Progress (line 552) | func (c *Client) Progress(ctx context.Context, params protocol.ProgressP...

FILE: internal/lsp/protocol.go
  type Message (line 8) | type Message struct
  type ResponseError (line 18) | type ResponseError struct
  function NewRequest (line 23) | func NewRequest(id int32, method string, params any) (*Message, error) {
  function NewNotification (line 37) | func NewNotification(method string, params any) (*Message, error) {

FILE: internal/lsp/protocol/interface.go
  type WorkspaceSymbolResult (line 6) | type WorkspaceSymbolResult interface
  method GetName (line 12) | func (ws *WorkspaceSymbol) GetName() string { return ws.Name }
  method GetLocation (line 13) | func (ws *WorkspaceSymbol) GetLocation() Location {
  method isWorkspaceSymbol (line 22) | func (ws *WorkspaceSymbol) isWorkspaceSymbol() {}
  method GetName (line 24) | func (si *SymbolInformation) GetName() string       { return si.Name }
  method GetLocation (line 25) | func (si *SymbolInformation) GetLocation() Location { return si.Location }
  method isWorkspaceSymbol (line 26) | func (si *SymbolInformation) isWorkspaceSymbol()    {}
  method Results (line 29) | func (r Or_Result_workspace_symbol) Results() ([]WorkspaceSymbolResult, ...
  type DocumentSymbolResult (line 52) | type DocumentSymbolResult interface
  method GetRange (line 58) | func (ds *DocumentSymbol) GetRange() Range   { return ds.Range }
  method GetName (line 59) | func (ds *DocumentSymbol) GetName() string   { return ds.Name }
  method isDocumentSymbol (line 60) | func (ds *DocumentSymbol) isDocumentSymbol() {}
  method GetRange (line 62) | func (si *SymbolInformation) GetRange() Range { return si.Location.Range }
  method isDocumentSymbol (line 65) | func (si *SymbolInformation) isDocumentSymbol() {}
  method Results (line 68) | func (r Or_Result_textDocument_documentSymbol) Results() ([]DocumentSymb...
  type TextEditResult (line 91) | type TextEditResult interface
  method GetRange (line 97) | func (te *TextEdit) GetRange() Range    { return te.Range }
  method GetNewText (line 98) | func (te *TextEdit) GetNewText() string { return te.NewText }
  method isTextEdit (line 99) | func (te *TextEdit) isTextEdit()        {}
  method AsTextEdit (line 102) | func (e Or_TextDocumentEdit_edits_Elem) AsTextEdit() (TextEdit, error) {

FILE: internal/lsp/protocol/pattern_interfaces.go
  type PatternInfo (line 9) | type PatternInfo interface
  type StringPattern (line 16) | type StringPattern struct
    method GetPattern (line 20) | func (p StringPattern) GetPattern() string  { return p.Pattern }
    method GetBasePath (line 21) | func (p StringPattern) GetBasePath() string { return "" }
    method isPattern (line 22) | func (p StringPattern) isPattern()          {}
  type RelativePatternInfo (line 25) | type RelativePatternInfo struct
    method GetPattern (line 30) | func (p RelativePatternInfo) GetPattern() string  { return string(p.RP...
    method GetBasePath (line 31) | func (p RelativePatternInfo) GetBasePath() string { return p.BasePath }
    method isPattern (line 32) | func (p RelativePatternInfo) isPattern()          {}
  method AsPattern (line 35) | func (g *GlobPattern) AsPattern() (PatternInfo, error) {

FILE: internal/lsp/protocol/tsdocument-changes.go
  type DocumentChange (line 17) | type DocumentChange struct
    method Valid (line 26) | func (ch DocumentChange) Valid() bool {
    method UnmarshalJSON (line 43) | func (d *DocumentChange) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 70) | func (d *DocumentChange) MarshalJSON() ([]byte, error) {

FILE: internal/lsp/protocol/tsjson.go
  type UnmarshalError (line 20) | type UnmarshalError struct
    method Error (line 24) | func (e UnmarshalError) Error() string {
  method MarshalJSON (line 27) | func (t Or_CancelParams_id) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 39) | func (t *Or_CancelParams_id) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 61) | func (t Or_ClientSemanticTokensRequestOptions_full) MarshalJSON() ([]byt...
  method UnmarshalJSON (line 73) | func (t *Or_ClientSemanticTokensRequestOptions_full) UnmarshalJSON(x []b...
  method MarshalJSON (line 95) | func (t Or_ClientSemanticTokensRequestOptions_range) MarshalJSON() ([]by...
  method UnmarshalJSON (line 107) | func (t *Or_ClientSemanticTokensRequestOptions_range) UnmarshalJSON(x []...
  method MarshalJSON (line 129) | func (t Or_CompletionItemDefaults_editRange) MarshalJSON() ([]byte, erro...
  method UnmarshalJSON (line 141) | func (t *Or_CompletionItemDefaults_editRange) UnmarshalJSON(x []byte) er...
  method MarshalJSON (line 163) | func (t Or_CompletionItem_documentation) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 175) | func (t *Or_CompletionItem_documentation) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 197) | func (t Or_CompletionItem_textEdit) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 209) | func (t *Or_CompletionItem_textEdit) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 231) | func (t Or_Declaration) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 243) | func (t *Or_Declaration) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 265) | func (t Or_Definition) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 277) | func (t *Or_Definition) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 299) | func (t Or_Diagnostic_code) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 311) | func (t *Or_Diagnostic_code) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 333) | func (t Or_DidChangeConfigurationRegistrationOptions_section) MarshalJSO...
  method UnmarshalJSON (line 345) | func (t *Or_DidChangeConfigurationRegistrationOptions_section) Unmarshal...
  method MarshalJSON (line 367) | func (t Or_DocumentDiagnosticReport) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 379) | func (t *Or_DocumentDiagnosticReport) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 401) | func (t Or_DocumentDiagnosticReportPartialResult_relatedDocuments_Value)...
  method UnmarshalJSON (line 413) | func (t *Or_DocumentDiagnosticReportPartialResult_relatedDocuments_Value...
  method MarshalJSON (line 435) | func (t Or_DocumentFilter) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 447) | func (t *Or_DocumentFilter) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 469) | func (t Or_GlobPattern) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 481) | func (t *Or_GlobPattern) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 503) | func (t Or_Hover_contents) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 517) | func (t *Or_Hover_contents) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 546) | func (t Or_InlayHintLabelPart_tooltip) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 558) | func (t *Or_InlayHintLabelPart_tooltip) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 580) | func (t Or_InlayHint_label) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 592) | func (t *Or_InlayHint_label) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 614) | func (t Or_InlayHint_tooltip) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 626) | func (t *Or_InlayHint_tooltip) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 648) | func (t Or_InlineCompletionItem_insertText) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 660) | func (t *Or_InlineCompletionItem_insertText) UnmarshalJSON(x []byte) err...
  method MarshalJSON (line 682) | func (t Or_InlineValue) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 696) | func (t *Or_InlineValue) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 725) | func (t Or_LSPAny) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 747) | func (t *Or_LSPAny) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 804) | func (t Or_MarkedString) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 816) | func (t *Or_MarkedString) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 838) | func (t Or_NotebookCellTextDocumentFilter_notebook) MarshalJSON() ([]byt...
  method UnmarshalJSON (line 850) | func (t *Or_NotebookCellTextDocumentFilter_notebook) UnmarshalJSON(x []b...
  method MarshalJSON (line 872) | func (t Or_NotebookDocumentFilter) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 886) | func (t *Or_NotebookDocumentFilter) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 915) | func (t Or_NotebookDocumentFilterWithCells_notebook) MarshalJSON() ([]by...
  method UnmarshalJSON (line 927) | func (t *Or_NotebookDocumentFilterWithCells_notebook) UnmarshalJSON(x []...
  method MarshalJSON (line 949) | func (t Or_NotebookDocumentFilterWithNotebook_notebook) MarshalJSON() ([...
  method UnmarshalJSON (line 961) | func (t *Or_NotebookDocumentFilterWithNotebook_notebook) UnmarshalJSON(x...
  method MarshalJSON (line 983) | func (t Or_NotebookDocumentSyncOptions_notebookSelector_Elem) MarshalJSO...
  method UnmarshalJSON (line 995) | func (t *Or_NotebookDocumentSyncOptions_notebookSelector_Elem) Unmarshal...
  method MarshalJSON (line 1017) | func (t Or_ParameterInformation_documentation) MarshalJSON() ([]byte, er...
  method UnmarshalJSON (line 1029) | func (t *Or_ParameterInformation_documentation) UnmarshalJSON(x []byte) ...
  method MarshalJSON (line 1051) | func (t Or_ParameterInformation_label) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 1063) | func (t *Or_ParameterInformation_label) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 1085) | func (t Or_PrepareRenameResult) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 1099) | func (t *Or_PrepareRenameResult) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 1128) | func (t Or_ProgressToken) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 1140) | func (t *Or_ProgressToken) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 1162) | func (t Or_RelatedFullDocumentDiagnosticReport_relatedDocuments_Value) M...
  method UnmarshalJSON (line 1174) | func (t *Or_RelatedFullDocumentDiagnosticReport_relatedDocuments_Value) ...
  method MarshalJSON (line 1196) | func (t Or_RelatedUnchangedDocumentDiagnosticReport_relatedDocuments_Val...
  method UnmarshalJSON (line 1208) | func (t *Or_RelatedUnchangedDocumentDiagnosticReport_relatedDocuments_Va...
  method MarshalJSON (line 1230) | func (t Or_RelativePattern_baseUri) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 1242) | func (t *Or_RelativePattern_baseUri) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 1264) | func (t Or_Result_textDocument_codeAction_Item0_Elem) MarshalJSON() ([]b...
  method UnmarshalJSON (line 1276) | func (t *Or_Result_textDocument_codeAction_Item0_Elem) UnmarshalJSON(x [...
  method MarshalJSON (line 1298) | func (t Or_Result_textDocument_completion) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 1310) | func (t *Or_Result_textDocument_completion) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 1332) | func (t Or_Result_textDocument_declaration) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 1344) | func (t *Or_Result_textDocument_declaration) UnmarshalJSON(x []byte) err...
  method MarshalJSON (line 1366) | func (t Or_Result_textDocument_definition) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 1378) | func (t *Or_Result_textDocument_definition) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 1400) | func (t Or_Result_textDocument_documentSymbol) MarshalJSON() ([]byte, er...
  method UnmarshalJSON (line 1412) | func (t *Or_Result_textDocument_documentSymbol) UnmarshalJSON(x []byte) ...
  method MarshalJSON (line 1434) | func (t Or_Result_textDocument_implementation) MarshalJSON() ([]byte, er...
  method UnmarshalJSON (line 1446) | func (t *Or_Result_textDocument_implementation) UnmarshalJSON(x []byte) ...
  method MarshalJSON (line 1468) | func (t Or_Result_textDocument_inlineCompletion) MarshalJSON() ([]byte, ...
  method UnmarshalJSON (line 1480) | func (t *Or_Result_textDocument_inlineCompletion) UnmarshalJSON(x []byte...
  method MarshalJSON (line 1502) | func (t Or_Result_textDocument_semanticTokens_full_delta) MarshalJSON() ...
  method UnmarshalJSON (line 1514) | func (t *Or_Result_textDocument_semanticTokens_full_delta) UnmarshalJSON...
  method MarshalJSON (line 1536) | func (t Or_Result_textDocument_typeDefinition) MarshalJSON() ([]byte, er...
  method UnmarshalJSON (line 1548) | func (t *Or_Result_textDocument_typeDefinition) UnmarshalJSON(x []byte) ...
  method MarshalJSON (line 1570) | func (t Or_Result_workspace_symbol) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 1582) | func (t *Or_Result_workspace_symbol) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 1604) | func (t Or_SemanticTokensOptions_full) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 1616) | func (t *Or_SemanticTokensOptions_full) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 1638) | func (t Or_SemanticTokensOptions_range) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 1650) | func (t *Or_SemanticTokensOptions_range) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 1672) | func (t Or_ServerCapabilities_callHierarchyProvider) MarshalJSON() ([]by...
  method UnmarshalJSON (line 1686) | func (t *Or_ServerCapabilities_callHierarchyProvider) UnmarshalJSON(x []...
  method MarshalJSON (line 1715) | func (t Or_ServerCapabilities_codeActionProvider) MarshalJSON() ([]byte,...
  method UnmarshalJSON (line 1727) | func (t *Or_ServerCapabilities_codeActionProvider) UnmarshalJSON(x []byt...
  method MarshalJSON (line 1749) | func (t Or_ServerCapabilities_colorProvider) MarshalJSON() ([]byte, erro...
  method UnmarshalJSON (line 1763) | func (t *Or_ServerCapabilities_colorProvider) UnmarshalJSON(x []byte) er...
  method MarshalJSON (line 1792) | func (t Or_ServerCapabilities_declarationProvider) MarshalJSON() ([]byte...
  method UnmarshalJSON (line 1806) | func (t *Or_ServerCapabilities_declarationProvider) UnmarshalJSON(x []by...
  method MarshalJSON (line 1835) | func (t Or_ServerCapabilities_definitionProvider) MarshalJSON() ([]byte,...
  method UnmarshalJSON (line 1847) | func (t *Or_ServerCapabilities_definitionProvider) UnmarshalJSON(x []byt...
  method MarshalJSON (line 1869) | func (t Or_ServerCapabilities_diagnosticProvider) MarshalJSON() ([]byte,...
  method UnmarshalJSON (line 1881) | func (t *Or_ServerCapabilities_diagnosticProvider) UnmarshalJSON(x []byt...
  method MarshalJSON (line 1903) | func (t Or_ServerCapabilities_documentFormattingProvider) MarshalJSON() ...
  method UnmarshalJSON (line 1915) | func (t *Or_ServerCapabilities_documentFormattingProvider) UnmarshalJSON...
  method MarshalJSON (line 1937) | func (t Or_ServerCapabilities_documentHighlightProvider) MarshalJSON() (...
  method UnmarshalJSON (line 1949) | func (t *Or_ServerCapabilities_documentHighlightProvider) UnmarshalJSON(...
  method MarshalJSON (line 1971) | func (t Or_ServerCapabilities_documentRangeFormattingProvider) MarshalJS...
  method UnmarshalJSON (line 1983) | func (t *Or_ServerCapabilities_documentRangeFormattingProvider) Unmarsha...
  method MarshalJSON (line 2005) | func (t Or_ServerCapabilities_documentSymbolProvider) MarshalJSON() ([]b...
  method UnmarshalJSON (line 2017) | func (t *Or_ServerCapabilities_documentSymbolProvider) UnmarshalJSON(x [...
  method MarshalJSON (line 2039) | func (t Or_ServerCapabilities_foldingRangeProvider) MarshalJSON() ([]byt...
  method UnmarshalJSON (line 2053) | func (t *Or_ServerCapabilities_foldingRangeProvider) UnmarshalJSON(x []b...
  method MarshalJSON (line 2082) | func (t Or_ServerCapabilities_hoverProvider) MarshalJSON() ([]byte, erro...
  method UnmarshalJSON (line 2094) | func (t *Or_ServerCapabilities_hoverProvider) UnmarshalJSON(x []byte) er...
  method MarshalJSON (line 2116) | func (t Or_ServerCapabilities_implementationProvider) MarshalJSON() ([]b...
  method UnmarshalJSON (line 2130) | func (t *Or_ServerCapabilities_implementationProvider) UnmarshalJSON(x [...
  method MarshalJSON (line 2159) | func (t Or_ServerCapabilities_inlayHintProvider) MarshalJSON() ([]byte, ...
  method UnmarshalJSON (line 2173) | func (t *Or_ServerCapabilities_inlayHintProvider) UnmarshalJSON(x []byte...
  method MarshalJSON (line 2202) | func (t Or_ServerCapabilities_inlineCompletionProvider) MarshalJSON() ([...
  method UnmarshalJSON (line 2214) | func (t *Or_ServerCapabilities_inlineCompletionProvider) UnmarshalJSON(x...
  method MarshalJSON (line 2236) | func (t Or_ServerCapabilities_inlineValueProvider) MarshalJSON() ([]byte...
  method UnmarshalJSON (line 2250) | func (t *Or_ServerCapabilities_inlineValueProvider) UnmarshalJSON(x []by...
  method MarshalJSON (line 2279) | func (t Or_ServerCapabilities_linkedEditingRangeProvider) MarshalJSON() ...
  method UnmarshalJSON (line 2293) | func (t *Or_ServerCapabilities_linkedEditingRangeProvider) UnmarshalJSON...
  method MarshalJSON (line 2322) | func (t Or_ServerCapabilities_monikerProvider) MarshalJSON() ([]byte, er...
  method UnmarshalJSON (line 2336) | func (t *Or_ServerCapabilities_monikerProvider) UnmarshalJSON(x []byte) ...
  method MarshalJSON (line 2365) | func (t Or_ServerCapabilities_notebookDocumentSync) MarshalJSON() ([]byt...
  method UnmarshalJSON (line 2377) | func (t *Or_ServerCapabilities_notebookDocumentSync) UnmarshalJSON(x []b...
  method MarshalJSON (line 2399) | func (t Or_ServerCapabilities_referencesProvider) MarshalJSON() ([]byte,...
  method UnmarshalJSON (line 2411) | func (t *Or_ServerCapabilities_referencesProvider) UnmarshalJSON(x []byt...
  method MarshalJSON (line 2433) | func (t Or_ServerCapabilities_renameProvider) MarshalJSON() ([]byte, err...
  method UnmarshalJSON (line 2445) | func (t *Or_ServerCapabilities_renameProvider) UnmarshalJSON(x []byte) e...
  method MarshalJSON (line 2467) | func (t Or_ServerCapabilities_selectionRangeProvider) MarshalJSON() ([]b...
  method UnmarshalJSON (line 2481) | func (t *Or_ServerCapabilities_selectionRangeProvider) UnmarshalJSON(x [...
  method MarshalJSON (line 2510) | func (t Or_ServerCapabilities_semanticTokensProvider) MarshalJSON() ([]b...
  method UnmarshalJSON (line 2522) | func (t *Or_ServerCapabilities_semanticTokensProvider) UnmarshalJSON(x [...
  method MarshalJSON (line 2544) | func (t Or_ServerCapabilities_textDocumentSync) MarshalJSON() ([]byte, e...
  method UnmarshalJSON (line 2556) | func (t *Or_ServerCapabilities_textDocumentSync) UnmarshalJSON(x []byte)...
  method MarshalJSON (line 2578) | func (t Or_ServerCapabilities_typeDefinitionProvider) MarshalJSON() ([]b...
  method UnmarshalJSON (line 2592) | func (t *Or_ServerCapabilities_typeDefinitionProvider) UnmarshalJSON(x [...
  method MarshalJSON (line 2621) | func (t Or_ServerCapabilities_typeHierarchyProvider) MarshalJSON() ([]by...
  method UnmarshalJSON (line 2635) | func (t *Or_ServerCapabilities_typeHierarchyProvider) UnmarshalJSON(x []...
  method MarshalJSON (line 2664) | func (t Or_ServerCapabilities_workspaceSymbolProvider) MarshalJSON() ([]...
  method UnmarshalJSON (line 2676) | func (t *Or_ServerCapabilities_workspaceSymbolProvider) UnmarshalJSON(x ...
  method MarshalJSON (line 2698) | func (t Or_SignatureInformation_documentation) MarshalJSON() ([]byte, er...
  method UnmarshalJSON (line 2710) | func (t *Or_SignatureInformation_documentation) UnmarshalJSON(x []byte) ...
  method MarshalJSON (line 2732) | func (t Or_TextDocumentContentChangeEvent) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 2744) | func (t *Or_TextDocumentContentChangeEvent) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 2766) | func (t Or_TextDocumentEdit_edits_Elem) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 2780) | func (t *Or_TextDocumentEdit_edits_Elem) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 2809) | func (t Or_TextDocumentFilter) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 2823) | func (t *Or_TextDocumentFilter) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 2852) | func (t Or_TextDocumentSyncOptions_save) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 2864) | func (t *Or_TextDocumentSyncOptions_save) UnmarshalJSON(x []byte) error {
  method MarshalJSON (line 2886) | func (t Or_WorkspaceDocumentDiagnosticReport) MarshalJSON() ([]byte, err...
  method UnmarshalJSON (line 2898) | func (t *Or_WorkspaceDocumentDiagnosticReport) UnmarshalJSON(x []byte) e...
  method MarshalJSON (line 2920) | func (t Or_WorkspaceEdit_documentChanges_Elem) MarshalJSON() ([]byte, er...
  method UnmarshalJSON (line 2936) | func (t *Or_WorkspaceEdit_documentChanges_Elem) UnmarshalJSON(x []byte) ...
  method MarshalJSON (line 2972) | func (t Or_WorkspaceFoldersServerCapabilities_changeNotifications) Marsh...
  method UnmarshalJSON (line 2984) | func (t *Or_WorkspaceFoldersServerCapabilities_changeNotifications) Unma...
  method MarshalJSON (line 3006) | func (t Or_WorkspaceOptions_textDocumentContent) MarshalJSON() ([]byte, ...
  method UnmarshalJSON (line 3018) | func (t *Or_WorkspaceOptions_textDocumentContent) UnmarshalJSON(x []byte...
  method MarshalJSON (line 3040) | func (t Or_WorkspaceSymbol_location) MarshalJSON() ([]byte, error) {
  method UnmarshalJSON (line 3052) | func (t *Or_WorkspaceSymbol_location) UnmarshalJSON(x []byte) error {

FILE: internal/lsp/protocol/tsprotocol.go
  type And_RegOpt_textDocument_colorPresentation (line 16) | type And_RegOpt_textDocument_colorPresentation struct
  type AnnotatedTextEdit (line 26) | type AnnotatedTextEdit struct
  type ApplyWorkspaceEditParams (line 35) | type ApplyWorkspaceEditParams struct
  type ApplyWorkspaceEditResult (line 54) | type ApplyWorkspaceEditResult struct
  type BaseSymbolInformation (line 70) | type BaseSymbolInformation struct
  type CallHierarchyClientCapabilities (line 89) | type CallHierarchyClientCapabilities struct
  type CallHierarchyIncomingCall (line 101) | type CallHierarchyIncomingCall struct
  type CallHierarchyIncomingCallsParams (line 114) | type CallHierarchyIncomingCallsParams struct
  type CallHierarchyItem (line 126) | type CallHierarchyItem struct
  type CallHierarchyOptions (line 152) | type CallHierarchyOptions struct
  type CallHierarchyOutgoingCall (line 161) | type CallHierarchyOutgoingCall struct
  type CallHierarchyOutgoingCallsParams (line 175) | type CallHierarchyOutgoingCallsParams struct
  type CallHierarchyPrepareParams (line 186) | type CallHierarchyPrepareParams struct
  type CallHierarchyRegistrationOptions (line 196) | type CallHierarchyRegistrationOptions struct
  type CancelParams (line 203) | type CancelParams struct
  type ChangeAnnotation (line 213) | type ChangeAnnotation struct
  type ChangeAnnotationsSupportOptions (line 232) | type ChangeAnnotationsSupportOptions struct
  type ClientCapabilities (line 242) | type ClientCapabilities struct
  type ClientCodeActionKindOptions (line 264) | type ClientCodeActionKindOptions struct
  type ClientCodeActionLiteralOptions (line 275) | type ClientCodeActionLiteralOptions struct
  type ClientCodeActionResolveOptions (line 284) | type ClientCodeActionResolveOptions struct
  type ClientCodeLensResolveOptions (line 292) | type ClientCodeLensResolveOptions struct
  type ClientCompletionItemInsertTextModeOptions (line 300) | type ClientCompletionItemInsertTextModeOptions struct
  type ClientCompletionItemOptions (line 307) | type ClientCompletionItemOptions struct
  type ClientCompletionItemOptionsKind (line 358) | type ClientCompletionItemOptionsKind struct
  type ClientCompletionItemResolveOptions (line 373) | type ClientCompletionItemResolveOptions struct
  type ClientDiagnosticsTagOptions (line 381) | type ClientDiagnosticsTagOptions struct
  type ClientFoldingRangeKindOptions (line 389) | type ClientFoldingRangeKindOptions struct
  type ClientFoldingRangeOptions (line 400) | type ClientFoldingRangeOptions struct
  type ClientInfo (line 414) | type ClientInfo struct
  type ClientInlayHintResolveOptions (line 424) | type ClientInlayHintResolveOptions struct
  type ClientSemanticTokensRequestFullDelta (line 432) | type ClientSemanticTokensRequestFullDelta struct
  type ClientSemanticTokensRequestOptions (line 441) | type ClientSemanticTokensRequestOptions struct
  type ClientShowMessageActionItemOptions (line 453) | type ClientShowMessageActionItemOptions struct
  type ClientSignatureInformationOptions (line 463) | type ClientSignatureInformationOptions struct
  type ClientSignatureParameterInformationOptions (line 486) | type ClientSignatureParameterInformationOptions struct
  type ClientSymbolKindOptions (line 497) | type ClientSymbolKindOptions struct
  type ClientSymbolResolveOptions (line 512) | type ClientSymbolResolveOptions struct
  type ClientSymbolTagOptions (line 521) | type ClientSymbolTagOptions struct
  type CodeAction (line 532) | type CodeAction struct
  type CodeActionClientCapabilities (line 581) | type CodeActionClientCapabilities struct
  type CodeActionContext (line 629) | type CodeActionContext struct
  type CodeActionDisabled (line 652) | type CodeActionDisabled struct
  type CodeActionKind (line 660) | type CodeActionKind
  type CodeActionKindDocumentation (line 668) | type CodeActionKindDocumentation struct
  type CodeActionOptions (line 684) | type CodeActionOptions struct
  type CodeActionParams (line 719) | type CodeActionParams struct
  type CodeActionRegistrationOptions (line 733) | type CodeActionRegistrationOptions struct
  type CodeActionTriggerKind (line 741) | type CodeActionTriggerKind
  type CodeDescription (line 748) | type CodeDescription struct
  type CodeLens (line 760) | type CodeLens struct
  type CodeLensClientCapabilities (line 773) | type CodeLensClientCapabilities struct
  type CodeLensOptions (line 786) | type CodeLensOptions struct
  type CodeLensParams (line 795) | type CodeLensParams struct
  type CodeLensRegistrationOptions (line 805) | type CodeLensRegistrationOptions struct
  type CodeLensWorkspaceClientCapabilities (line 813) | type CodeLensWorkspaceClientCapabilities struct
  type Color (line 827) | type Color struct
  type ColorInformation (line 841) | type ColorInformation struct
  type ColorPresentation (line 849) | type ColorPresentation struct
  type ColorPresentationParams (line 866) | type ColorPresentationParams struct
  type Command (line 883) | type Command struct
  type CompletionClientCapabilities (line 901) | type CompletionClientCapabilities struct
  type CompletionContext (line 927) | type CompletionContext struct
  type CompletionItem (line 939) | type CompletionItem struct
  type CompletionItemDefaults (line 1074) | type CompletionItemDefaults struct
  type CompletionItemKind (line 1098) | type CompletionItemKind
  type CompletionItemLabelDetails (line 1105) | type CompletionItemLabelDetails struct
  type CompletionItemTag (line 1118) | type CompletionItemTag
  type CompletionItemTagOptions (line 1123) | type CompletionItemTagOptions struct
  type CompletionList (line 1132) | type CompletionList struct
  type CompletionListCapabilities (line 1162) | type CompletionListCapabilities struct
  type CompletionOptions (line 1177) | type CompletionOptions struct
  type CompletionParams (line 1210) | type CompletionParams struct
  type CompletionRegistrationOptions (line 1222) | type CompletionRegistrationOptions struct
  type CompletionTriggerKind (line 1228) | type CompletionTriggerKind
  type ConfigurationItem (line 1231) | type ConfigurationItem struct
  type ConfigurationParams (line 1241) | type ConfigurationParams struct
  type CreateFile (line 1248) | type CreateFile struct
  type CreateFileOptions (line 1261) | type CreateFileOptions struct
  type CreateFilesParams (line 1274) | type CreateFilesParams struct
  type DeclarationClientCapabilities (line 1286) | type DeclarationClientCapabilities struct
  type DeclarationOptions (line 1306) | type DeclarationOptions struct
  type DeclarationParams (line 1311) | type DeclarationParams struct
  type DeclarationRegistrationOptions (line 1318) | type DeclarationRegistrationOptions struct
  type DefinitionClientCapabilities (line 1336) | type DefinitionClientCapabilities struct
  type DefinitionOptions (line 1355) | type DefinitionOptions struct
  type DefinitionParams (line 1362) | type DefinitionParams struct
  type DefinitionRegistrationOptions (line 1371) | type DefinitionRegistrationOptions struct
  type DeleteFile (line 1379) | type DeleteFile struct
  type DeleteFileOptions (line 1392) | type DeleteFileOptions struct
  type DeleteFilesParams (line 1405) | type DeleteFilesParams struct
  type Diagnostic (line 1414) | type Diagnostic struct
  type DiagnosticClientCapabilities (line 1453) | type DiagnosticClientCapabilities struct
  type DiagnosticOptions (line 1468) | type DiagnosticOptions struct
  type DiagnosticRegistrationOptions (line 1487) | type DiagnosticRegistrationOptions struct
  type DiagnosticRelatedInformation (line 1498) | type DiagnosticRelatedInformation struct
  type DiagnosticServerCancellationData (line 1510) | type DiagnosticServerCancellationData struct
  type DiagnosticSeverity (line 1515) | type DiagnosticSeverity
  type DiagnosticTag (line 1520) | type DiagnosticTag
  type DiagnosticWorkspaceClientCapabilities (line 1527) | type DiagnosticWorkspaceClientCapabilities struct
  type DiagnosticsCapabilities (line 1541) | type DiagnosticsCapabilities struct
  type DidChangeConfigurationClientCapabilities (line 1562) | type DidChangeConfigurationClientCapabilities struct
  type DidChangeConfigurationParams (line 1570) | type DidChangeConfigurationParams struct
  type DidChangeConfigurationRegistrationOptions (line 1576) | type DidChangeConfigurationRegistrationOptions struct
  type DidChangeNotebookDocumentParams (line 1585) | type DidChangeNotebookDocumentParams struct
  type DidChangeTextDocumentParams (line 1611) | type DidChangeTextDocumentParams struct
  type DidChangeWatchedFilesClientCapabilities (line 1632) | type DidChangeWatchedFilesClientCapabilities struct
  type DidChangeWatchedFilesParams (line 1647) | type DidChangeWatchedFilesParams struct
  type DidChangeWatchedFilesRegistrationOptions (line 1655) | type DidChangeWatchedFilesRegistrationOptions struct
  type DidChangeWorkspaceFoldersParams (line 1663) | type DidChangeWorkspaceFoldersParams struct
  type DidCloseNotebookDocumentParams (line 1673) | type DidCloseNotebookDocumentParams struct
  type DidCloseTextDocumentParams (line 1684) | type DidCloseTextDocumentParams struct
  type DidOpenNotebookDocumentParams (line 1694) | type DidOpenNotebookDocumentParams struct
  type DidOpenTextDocumentParams (line 1705) | type DidOpenTextDocumentParams struct
  type DidSaveNotebookDocumentParams (line 1715) | type DidSaveNotebookDocumentParams struct
  type DidSaveTextDocumentParams (line 1723) | type DidSaveTextDocumentParams struct
  type DocumentColorClientCapabilities (line 1732) | type DocumentColorClientCapabilities struct
  type DocumentColorOptions (line 1740) | type DocumentColorOptions struct
  type DocumentColorParams (line 1747) | type DocumentColorParams struct
  type DocumentColorRegistrationOptions (line 1755) | type DocumentColorRegistrationOptions struct
  type DocumentDiagnosticParams (line 1766) | type DocumentDiagnosticParams struct
  type DocumentDiagnosticReportKind (line 1790) | type DocumentDiagnosticReportKind
  type DocumentDiagnosticReportPartialResult (line 1797) | type DocumentDiagnosticReportPartialResult struct
  type DocumentFormattingClientCapabilities (line 1811) | type DocumentFormattingClientCapabilities struct
  type DocumentFormattingOptions (line 1819) | type DocumentFormattingOptions struct
  type DocumentFormattingParams (line 1826) | type DocumentFormattingParams struct
  type DocumentFormattingRegistrationOptions (line 1837) | type DocumentFormattingRegistrationOptions struct
  type DocumentHighlight (line 1847) | type DocumentHighlight struct
  type DocumentHighlightClientCapabilities (line 1857) | type DocumentHighlightClientCapabilities struct
  type DocumentHighlightKind (line 1863) | type DocumentHighlightKind
  type DocumentHighlightOptions (line 1868) | type DocumentHighlightOptions struct
  type DocumentHighlightParams (line 1875) | type DocumentHighlightParams struct
  type DocumentHighlightRegistrationOptions (line 1884) | type DocumentHighlightRegistrationOptions struct
  type DocumentLink (line 1893) | type DocumentLink struct
  type DocumentLinkClientCapabilities (line 1914) | type DocumentLinkClientCapabilities struct
  type DocumentLinkOptions (line 1926) | type DocumentLinkOptions struct
  type DocumentLinkParams (line 1935) | type DocumentLinkParams struct
  type DocumentLinkRegistrationOptions (line 1945) | type DocumentLinkRegistrationOptions struct
  type DocumentOnTypeFormattingClientCapabilities (line 1953) | type DocumentOnTypeFormattingClientCapabilities struct
  type DocumentOnTypeFormattingOptions (line 1961) | type DocumentOnTypeFormattingOptions struct
  type DocumentOnTypeFormattingParams (line 1971) | type DocumentOnTypeFormattingParams struct
  type DocumentOnTypeFormattingRegistrationOptions (line 1990) | type DocumentOnTypeFormattingRegistrationOptions struct
  type DocumentRangeFormattingClientCapabilities (line 1998) | type DocumentRangeFormattingClientCapabilities struct
  type DocumentRangeFormattingOptions (line 2011) | type DocumentRangeFormattingOptions struct
  type DocumentRangeFormattingParams (line 2023) | type DocumentRangeFormattingParams struct
  type DocumentRangeFormattingRegistrationOptions (line 2036) | type DocumentRangeFormattingRegistrationOptions struct
  type DocumentRangesFormattingParams (line 2047) | type DocumentRangesFormattingParams struct
  type DocumentSymbol (line 2071) | type DocumentSymbol struct
  type DocumentSymbolClientCapabilities (line 2101) | type DocumentSymbolClientCapabilities struct
  type DocumentSymbolOptions (line 2125) | type DocumentSymbolOptions struct
  type DocumentSymbolParams (line 2137) | type DocumentSymbolParams struct
  type DocumentSymbolRegistrationOptions (line 2147) | type DocumentSymbolRegistrationOptions struct
  type EditRangeWithInsertReplace (line 2157) | type EditRangeWithInsertReplace struct
  type ErrorCodes (line 2163) | type ErrorCodes
  type ExecuteCommandClientCapabilities (line 2168) | type ExecuteCommandClientCapabilities struct
  type ExecuteCommandOptions (line 2176) | type ExecuteCommandOptions struct
  type ExecuteCommandParams (line 2185) | type ExecuteCommandParams struct
  type ExecuteCommandRegistrationOptions (line 2196) | type ExecuteCommandRegistrationOptions struct
  type ExecutionSummary (line 2201) | type ExecutionSummary struct
  type FailureHandlingKind (line 2210) | type FailureHandlingKind
  type FileChangeType (line 2213) | type FileChangeType
  type FileCreate (line 2220) | type FileCreate struct
  type FileDelete (line 2230) | type FileDelete struct
  type FileEvent (line 2238) | type FileEvent struct
  type FileOperationClientCapabilities (line 2253) | type FileOperationClientCapabilities struct
  type FileOperationFilter (line 2276) | type FileOperationFilter struct
  type FileOperationOptions (line 2288) | type FileOperationOptions struct
  type FileOperationPattern (line 2309) | type FileOperationPattern struct
  type FileOperationPatternKind (line 2331) | type FileOperationPatternKind
  type FileOperationPatternOptions (line 2338) | type FileOperationPatternOptions struct
  type FileOperationRegistrationOptions (line 2348) | type FileOperationRegistrationOptions struct
  type FileRename (line 2358) | type FileRename struct
  type FileSystemWatcher (line 2366) | type FileSystemWatcher struct
  type FoldingRange (line 2381) | type FoldingRange struct
  type FoldingRangeClientCapabilities (line 2405) | type FoldingRangeClientCapabilities struct
  type FoldingRangeKind (line 2430) | type FoldingRangeKind
  type FoldingRangeOptions (line 2433) | type FoldingRangeOptions struct
  type FoldingRangeParams (line 2440) | type FoldingRangeParams struct
  type FoldingRangeRegistrationOptions (line 2448) | type FoldingRangeRegistrationOptions struct
  type FoldingRangeWorkspaceClientCapabilities (line 2460) | type FoldingRangeWorkspaceClientCapabilities struct
  type FormattingOptions (line 2477) | type FormattingOptions struct
  type FullDocumentDiagnosticReport (line 2501) | type FullDocumentDiagnosticReport struct
  type GeneralClientCapabilities (line 2517) | type GeneralClientCapabilities struct
  type Hover (line 2563) | type Hover struct
  type HoverClientCapabilities (line 2572) | type HoverClientCapabilities struct
  type HoverOptions (line 2583) | type HoverOptions struct
  type HoverParams (line 2590) | type HoverParams struct
  type HoverRegistrationOptions (line 2598) | type HoverRegistrationOptions struct
  type ImplementationClientCapabilities (line 2606) | type ImplementationClientCapabilities struct
  type ImplementationOptions (line 2618) | type ImplementationOptions struct
  type ImplementationParams (line 2623) | type ImplementationParams struct
  type ImplementationRegistrationOptions (line 2630) | type ImplementationRegistrationOptions struct
  type InitializeError (line 2640) | type InitializeError struct
  type InitializeParams (line 2649) | type InitializeParams struct
  type InitializeResult (line 2657) | type InitializeResult struct
  type InitializedParams (line 2667) | type InitializedParams struct
  type InlayHint (line 2675) | type InlayHint struct
  type InlayHintClientCapabilities (line 2719) | type InlayHintClientCapabilities struct
  type InlayHintKind (line 2730) | type InlayHintKind
  type InlayHintLabelPart (line 2738) | type InlayHintLabelPart struct
  type InlayHintOptions (line 2769) | type InlayHintOptions struct
  type InlayHintParams (line 2781) | type InlayHintParams struct
  type InlayHintRegistrationOptions (line 2794) | type InlayHintRegistrationOptions struct
  type InlayHintWorkspaceClientCapabilities (line 2805) | type InlayHintWorkspaceClientCapabilities struct
  type InlineCompletionClientCapabilities (line 2822) | type InlineCompletionClientCapabilities struct
  type InlineCompletionContext (line 2833) | type InlineCompletionContext struct
  type InlineCompletionItem (line 2846) | type InlineCompletionItem struct
  type InlineCompletionList (line 2863) | type InlineCompletionList struct
  type InlineCompletionOptions (line 2874) | type InlineCompletionOptions struct
  type InlineCompletionParams (line 2884) | type InlineCompletionParams struct
  type InlineCompletionRegistrationOptions (line 2898) | type InlineCompletionRegistrationOptions struct
  type InlineCompletionTriggerKind (line 2908) | type InlineCompletionTriggerKind
  type InlineValueClientCapabilities (line 2927) | type InlineValueClientCapabilities struct
  type InlineValueContext (line 2935) | type InlineValueContext struct
  type InlineValueEvaluatableExpression (line 2950) | type InlineValueEvaluatableExpression struct
  type InlineValueOptions (line 2963) | type InlineValueOptions struct
  type InlineValueParams (line 2972) | type InlineValueParams struct
  type InlineValueRegistrationOptions (line 2988) | type InlineValueRegistrationOptions struct
  type InlineValueText (line 2999) | type InlineValueText struct
  type InlineValueVariableLookup (line 3013) | type InlineValueVariableLookup struct
  type InlineValueWorkspaceClientCapabilities (line 3028) | type InlineValueWorkspaceClientCapabilities struct
  type InsertReplaceEdit (line 3044) | type InsertReplaceEdit struct
  type InsertTextFormat (line 3055) | type InsertTextFormat
  type InsertTextMode (line 3061) | type InsertTextMode
  type LSPErrorCodes (line 3069) | type LSPErrorCodes
  type LanguageKind (line 3079) | type LanguageKind
  type LinkedEditingRangeClientCapabilities (line 3086) | type LinkedEditingRangeClientCapabilities struct
  type LinkedEditingRangeOptions (line 3094) | type LinkedEditingRangeOptions struct
  type LinkedEditingRangeParams (line 3099) | type LinkedEditingRangeParams struct
  type LinkedEditingRangeRegistrationOptions (line 3105) | type LinkedEditingRangeRegistrationOptions struct
  type LinkedEditingRanges (line 3116) | type LinkedEditingRanges struct
  type Lit_ClientSemanticTokensRequestOptions_range_Item1 (line 3127) | type Lit_ClientSemanticTokensRequestOptions_range_Item1 struct
  type Lit_SemanticTokensOptions_range_Item1 (line 3131) | type Lit_SemanticTokensOptions_range_Item1 struct
  type Location (line 3138) | type Location struct
  type LocationLink (line 3147) | type LocationLink struct
  type LocationUriOnly (line 3169) | type LocationUriOnly struct
  type LogMessageParams (line 3176) | type LogMessageParams struct
  type LogTraceParams (line 3184) | type LogTraceParams struct
  type MarkdownClientCapabilities (line 3194) | type MarkdownClientCapabilities struct
  type MarkedStringWithLanguage (line 3225) | type MarkedStringWithLanguage struct
  type MarkupContent (line 3256) | type MarkupContent struct
  type MarkupKind (line 3268) | type MarkupKind
  type MessageActionItem (line 3271) | type MessageActionItem struct
  type MessageType (line 3277) | type MessageType
  type Moniker (line 3284) | type Moniker struct
  type MonikerClientCapabilities (line 3301) | type MonikerClientCapabilities struct
  type MonikerKind (line 3311) | type MonikerKind
  type MonikerOptions (line 3314) | type MonikerOptions struct
  type MonikerParams (line 3319) | type MonikerParams struct
  type MonikerRegistrationOptions (line 3326) | type MonikerRegistrationOptions struct
  type NotebookCell (line 3340) | type NotebookCell struct
  type NotebookCellArrayChange (line 3361) | type NotebookCellArrayChange struct
  type NotebookCellKind (line 3373) | type NotebookCellKind
  type NotebookCellLanguage (line 3378) | type NotebookCellLanguage struct
  type NotebookCellTextDocumentFilter (line 3388) | type NotebookCellTextDocumentFilter struct
  type NotebookDocument (line 3406) | type NotebookDocument struct
  type NotebookDocumentCellChangeStructure (line 3428) | type NotebookDocumentCellChangeStructure struct
  type NotebookDocumentCellChanges (line 3442) | type NotebookDocumentCellChanges struct
  type NotebookDocumentCellContentChanges (line 3458) | type NotebookDocumentCellContentChanges struct
  type NotebookDocumentChangeEvent (line 3468) | type NotebookDocumentChangeEvent struct
  type NotebookDocumentClientCapabilities (line 3482) | type NotebookDocumentClientCapabilities struct
  type NotebookDocumentFilterNotebookType (line 3502) | type NotebookDocumentFilterNotebookType struct
  type NotebookDocumentFilterPattern (line 3516) | type NotebookDocumentFilterPattern struct
  type NotebookDocumentFilterScheme (line 3530) | type NotebookDocumentFilterScheme struct
  type NotebookDocumentFilterWithCells (line 3542) | type NotebookDocumentFilterWithCells struct
  type NotebookDocumentFilterWithNotebook (line 3554) | type NotebookDocumentFilterWithNotebook struct
  type NotebookDocumentIdentifier (line 3568) | type NotebookDocumentIdentifier struct
  type NotebookDocumentSyncClientCapabilities (line 3578) | type NotebookDocumentSyncClientCapabilities struct
  type NotebookDocumentSyncOptions (line 3603) | type NotebookDocumentSyncOptions struct
  type NotebookDocumentSyncRegistrationOptions (line 3616) | type NotebookDocumentSyncRegistrationOptions struct
  type OptionalVersionedTextDocumentIdentifier (line 3624) | type OptionalVersionedTextDocumentIdentifier struct
  type Or_CancelParams_id (line 3635) | type Or_CancelParams_id struct
  type Or_ClientSemanticTokensRequestOptions_full (line 3640) | type Or_ClientSemanticTokensRequestOptions_full struct
  type Or_ClientSemanticTokensRequestOptions_range (line 3645) | type Or_ClientSemanticTokensRequestOptions_range struct
  type Or_CompletionItemDefaults_editRange (line 3650) | type Or_CompletionItemDefaults_editRange struct
  type Or_CompletionItem_documentation (line 3655) | type Or_CompletionItem_documentation struct
  type Or_CompletionItem_textEdit (line 3660) | type Or_CompletionItem_textEdit struct
  type Or_Declaration (line 3665) | type Or_Declaration struct
  type Or_Definition (line 3670) | type Or_Definition struct
  type Or_Diagnostic_code (line 3675) | type Or_Diagnostic_code struct
  type Or_DidChangeConfigurationRegistrationOptions_section (line 3680) | type Or_DidChangeConfigurationRegistrationOptions_section struct
  type Or_DocumentDiagnosticReport (line 3685) | type Or_DocumentDiagnosticReport struct
  type Or_DocumentDiagnosticReportPartialResult_relatedDocuments_Value (line 3690) | type Or_DocumentDiagnosticReportPartialResult_relatedDocuments_Value struct
  type Or_DocumentFilter (line 3695) | type Or_DocumentFilter struct
  type Or_GlobPattern (line 3700) | type Or_GlobPattern struct
  type Or_Hover_contents (line 3705) | type Or_Hover_contents struct
  type Or_InlayHintLabelPart_tooltip (line 3710) | type Or_InlayHintLabelPart_tooltip struct
  type Or_InlayHint_label (line 3715) | type Or_InlayHint_label struct
  type Or_InlayHint_tooltip (line 3720) | type Or_InlayHint_tooltip struct
  type Or_InlineCompletionItem_insertText (line 3725) | type Or_InlineCompletionItem_insertText struct
  type Or_InlineValue (line 3730) | type Or_InlineValue struct
  type Or_LSPAny (line 3735) | type Or_LSPAny struct
  type Or_MarkedString (line 3740) | type Or_MarkedString struct
  type Or_NotebookCellTextDocumentFilter_notebook (line 3745) | type Or_NotebookCellTextDocumentFilter_notebook struct
  type Or_NotebookDocumentFilter (line 3750) | type Or_NotebookDocumentFilter struct
  type Or_NotebookDocumentFilterWithCells_notebook (line 3755) | type Or_NotebookDocumentFilterWithCells_notebook struct
  type Or_NotebookDocumentFilterWithNotebook_notebook (line 3760) | type Or_NotebookDocumentFilterWithNotebook_notebook struct
  type Or_NotebookDocumentSyncOptions_notebookSelector_Elem (line 3765) | type Or_NotebookDocumentSyncOptions_notebookSelector_Elem struct
  type Or_ParameterInformation_documentation (line 3770) | type Or_ParameterInformation_documentation struct
  type Or_ParameterInformation_label (line 3775) | type Or_ParameterInformation_label struct
  type Or_PrepareRenameResult (line 3780) | type Or_PrepareRenameResult struct
  type Or_ProgressToken (line 3785) | type Or_ProgressToken struct
  type Or_RelatedFullDocumentDiagnosticReport_relatedDocuments_Value (line 3790) | type Or_RelatedFullDocumentDiagnosticReport_relatedDocuments_Value struct
  type Or_RelatedUnchangedDocumentDiagnosticReport_relatedDocuments_Value (line 3795) | type Or_RelatedUnchangedDocumentDiagnosticReport_relatedDocuments_Value ...
  type Or_RelativePattern_baseUri (line 3800) | type Or_RelativePattern_baseUri struct
  type Or_Result_textDocument_codeAction_Item0_Elem (line 3805) | type Or_Result_textDocument_codeAction_Item0_Elem struct
  type Or_Result_textDocument_completion (line 3810) | type Or_Result_textDocument_completion struct
  type Or_Result_textDocument_declaration (line 3815) | type Or_Result_textDocument_declaration struct
  type Or_Result_textDocument_definition (line 3820) | type Or_Result_textDocument_definition struct
  type Or_Result_textDocument_documentSymbol (line 3825) | type Or_Result_textDocument_documentSymbol struct
  type Or_Result_textDocument_implementation (line 3830) | type Or_Result_textDocument_implementation struct
  type Or_Result_textDocument_inlineCompletion (line 3835) | type Or_Result_textDocument_inlineCompletion struct
  type Or_Result_textDocument_semanticTokens_full_delta (line 3840) | type Or_Result_textDocument_semanticTokens_full_delta struct
  type Or_Result_textDocument_typeDefinition (line 3845) | type Or_Result_textDocument_typeDefinition struct
  type Or_Result_workspace_symbol (line 3850) | type Or_Result_workspace_symbol struct
  type Or_SemanticTokensOptions_full (line 3855) | type Or_SemanticTokensOptions_full struct
  type Or_SemanticTokensOptions_range (line 3860) | type Or_SemanticTokensOptions_range struct
  type Or_ServerCapabilities_callHierarchyProvider (line 3865) | type Or_ServerCapabilities_callHierarchyProvider struct
  type Or_ServerCapabilities_codeActionProvider (line 3870) | type Or_ServerCapabilities_codeActionProvider struct
  type Or_ServerCapabilities_colorProvider (line 3875) | type Or_ServerCapabilities_colorProvider struct
  type Or_ServerCapabilities_declarationProvider (line 3880) | type Or_ServerCapabilities_declarationProvider struct
  type Or_ServerCapabilities_definitionProvider (line 3885) | type Or_ServerCapabilities_definitionProvider struct
  type Or_ServerCapabilities_diagnosticProvider (line 3890) | type Or_ServerCapabilities_diagnosticProvider struct
  type Or_ServerCapabilities_documentFormattingProvider (line 3895) | type Or_ServerCapabilities_documentFormattingProvider struct
  type Or_ServerCapabilities_documentHighlightProvider (line 3900) | type Or_ServerCapabilities_documentHighlightProvider struct
  type Or_ServerCapabilities_documentRangeFormattingProvider (line 3905) | type Or_ServerCapabilities_documentRangeFormattingProvider struct
  type Or_ServerCapabilities_documentSymbolProvider (line 3910) | type Or_ServerCapabilities_documentSymbolProvider struct
  type Or_ServerCapabilities_foldingRangeProvider (line 3915) | type Or_ServerCapabilities_foldingRangeProvider struct
  type Or_ServerCapabilities_hoverProvider (line 3920) | type Or_ServerCapabilities_hoverProvider struct
  type Or_ServerCapabilities_implementationProvider (line 3925) | type Or_ServerCapabilities_implementationProvider struct
  type Or_ServerCapabilities_inlayHintProvider (line 3930) | type Or_ServerCapabilities_inlayHintProvider struct
  type Or_ServerCapabilities_inlineCompletionProvider (line 3935) | type Or_ServerCapabilities_inlineCompletionProvider struct
  type Or_ServerCapabilities_inlineValueProvider (line 3940) | type Or_ServerCapabilities_inlineValueProvider struct
  type Or_ServerCapabilities_linkedEditingRangeProvider (line 3945) | type Or_ServerCapabilities_linkedEditingRangeProvider struct
  type Or_ServerCapabilities_monikerProvider (line 3950) | type Or_ServerCapabilities_monikerProvider struct
  type Or_ServerCapabilities_notebookDocumentSync (line 3955) | type Or_ServerCapabilities_notebookDocumentSync struct
  type Or_ServerCapabilities_referencesProvider (line 3960) | type Or_ServerCapabilities_referencesProvider struct
  type Or_ServerCapabilities_renameProvider (line 3965) | type Or_ServerCapabilities_renameProvider struct
  type Or_ServerCapabilities_selectionRangeProvider (line 3970) | type Or_ServerCapabilities_selectionRangeProvider struct
  type Or_ServerCapabilities_semanticTokensProvider (line 3975) | type Or_ServerCapabilities_semanticTokensProvider struct
  type Or_ServerCapabilities_textDocumentSync (line 3980) | type Or_ServerCapabilities_textDocumentSync struct
  type Or_ServerCapabilities_typeDefinitionProvider (line 3985) | type Or_ServerCapabilities_typeDefinitionProvider struct
  type Or_ServerCapabilities_typeHierarchyProvider (line 3990) | type Or_ServerCapabilities_typeHierarchyProvider struct
  type Or_ServerCapabilities_workspaceSymbolProvider (line 3995) | type Or_ServerCapabilities_workspaceSymbolProvider struct
  type Or_SignatureInformation_documentation (line 4000) | type Or_SignatureInformation_documentation struct
  type Or_TextDocumentContentChangeEvent (line 4005) | type Or_TextDocumentContentChangeEvent struct
  type Or_TextDocumentEdit_edits_Elem (line 4010) | type Or_TextDocumentEdit_edits_Elem struct
  type Or_TextDocumentFilter (line 4015) | type Or_TextDocumentFilter struct
  type Or_TextDocumentSyncOptions_save (line 4020) | type Or_TextDocumentSyncOptions_save struct
  type Or_WorkspaceDocumentDiagnosticReport (line 4025) | type Or_WorkspaceDocumentDiagnosticReport struct
  type Or_WorkspaceEdit_documentChanges_Elem (line 4030) | type Or_WorkspaceEdit_documentChanges_Elem struct
  type Or_WorkspaceFoldersServerCapabilities_changeNotifications (line 4035) | type Or_WorkspaceFoldersServerCapabilities_changeNotifications struct
  type Or_WorkspaceOptions_textDocumentContent (line 4040) | type Or_WorkspaceOptions_textDocumentContent struct
  type Or_WorkspaceSymbol_location (line 4045) | type Or_WorkspaceSymbol_location struct
  type ParamConfiguration (line 4052) | type ParamConfiguration struct
  type ParamInitialize (line 4057) | type ParamInitialize struct
  type ParameterInformation (line 4066) | type ParameterInformation struct
  type PartialResultParams (line 4086) | type PartialResultParams struct
  type Position (line 4134) | type Position struct
  type PositionEncodingKind (line 4153) | type PositionEncodingKind
  type PrepareRenameDefaultBehavior (line 4158) | type PrepareRenameDefaultBehavior struct
  type PrepareRenameParams (line 4163) | type PrepareRenameParams struct
  type PrepareRenamePlaceholder (line 4171) | type PrepareRenamePlaceholder struct
  type PrepareSupportDefaultBehavior (line 4178) | type PrepareSupportDefaultBehavior
  type PreviousResultID (line 4185) | type PreviousResultID struct
  type PreviousResultId (line 4198) | type PreviousResultId struct
  type ProgressParams (line 4207) | type ProgressParams struct
  type PublishDiagnosticsClientCapabilities (line 4219) | type PublishDiagnosticsClientCapabilities struct
  type PublishDiagnosticsParams (line 4231) | type PublishDiagnosticsParams struct
  type Range (line 4257) | type Range struct
  type ReferenceClientCapabilities (line 4267) | type ReferenceClientCapabilities struct
  type ReferenceContext (line 4276) | type ReferenceContext struct
  type ReferenceOptions (line 4284) | type ReferenceOptions struct
  type ReferenceParams (line 4291) | type ReferenceParams struct
  type ReferenceRegistrationOptions (line 4301) | type ReferenceRegistrationOptions struct
  type Registration (line 4309) | type Registration struct
  type RegistrationParams (line 4320) | type RegistrationParams struct
  type RegularExpressionsClientCapabilities (line 4331) | type RegularExpressionsClientCapabilities struct
  type RelatedFullDocumentDiagnosticReport (line 4343) | type RelatedFullDocumentDiagnosticReport struct
  type RelatedUnchangedDocumentDiagnosticReport (line 4360) | type RelatedUnchangedDocumentDiagnosticReport struct
  type RelativePattern (line 4379) | type RelativePattern struct
  type RenameClientCapabilities (line 4388) | type RenameClientCapabilities struct
  type RenameFile (line 4416) | type RenameFile struct
  type RenameFileOptions (line 4431) | type RenameFileOptions struct
  type RenameFilesParams (line 4444) | type RenameFilesParams struct
  type RenameOptions (line 4453) | type RenameOptions struct
  type RenameParams (line 4464) | type RenameParams struct
  type RenameRegistrationOptions (line 4479) | type RenameRegistrationOptions struct
  type ResourceOperation (line 4487) | type ResourceOperation struct
  type ResourceOperationKind (line 4495) | type ResourceOperationKind
  type SaveOptions (line 4500) | type SaveOptions struct
  type SelectedCompletionInfo (line 4511) | type SelectedCompletionInfo struct
  type SelectionRange (line 4522) | type SelectionRange struct
  type SelectionRangeClientCapabilities (line 4530) | type SelectionRangeClientCapabilities struct
  type SelectionRangeOptions (line 4538) | type SelectionRangeOptions struct
  type SelectionRangeParams (line 4545) | type SelectionRangeParams struct
  type SelectionRangeRegistrationOptions (line 4555) | type SelectionRangeRegistrationOptions struct
  type SemanticTokenModifiers (line 4566) | type SemanticTokenModifiers
  type SemanticTokenTypes (line 4573) | type SemanticTokenTypes
  type SemanticTokens (line 4578) | type SemanticTokens struct
  type SemanticTokensClientCapabilities (line 4591) | type SemanticTokensClientCapabilities struct
  type SemanticTokensDelta (line 4638) | type SemanticTokensDelta struct
  type SemanticTokensDeltaParams (line 4647) | type SemanticTokensDeltaParams struct
  type SemanticTokensDeltaPartialResult (line 4660) | type SemanticTokensDeltaPartialResult struct
  type SemanticTokensEdit (line 4667) | type SemanticTokensEdit struct
  type SemanticTokensFullDelta (line 4681) | type SemanticTokensFullDelta struct
  type SemanticTokensLegend (line 4689) | type SemanticTokensLegend struct
  type SemanticTokensOptions (line 4699) | type SemanticTokensOptions struct
  type SemanticTokensParams (line 4713) | type SemanticTokensParams struct
  type SemanticTokensPartialResult (line 4723) | type SemanticTokensPartialResult struct
  type SemanticTokensRangeParams (line 4730) | type SemanticTokensRangeParams struct
  type SemanticTokensRegistrationOptions (line 4742) | type SemanticTokensRegistrationOptions struct
  type SemanticTokensWorkspaceClientCapabilities (line 4751) | type SemanticTokensWorkspaceClientCapabilities struct
  type ServerCapabilities (line 4766) | type ServerCapabilities struct
  type ServerCompletionItemOptions (line 4879) | type ServerCompletionItemOptions struct
  type ServerInfo (line 4894) | type ServerInfo struct
  type SetTraceParams (line 4902) | type SetTraceParams struct
  type ShowDocumentClientCapabilities (line 4911) | type ShowDocumentClientCapabilities struct
  type ShowDocumentParams (line 4922) | type ShowDocumentParams struct
  type ShowDocumentResult (line 4946) | type ShowDocumentResult struct
  type ShowMessageParams (line 4954) | type ShowMessageParams struct
  type ShowMessageRequestClientCapabilities (line 4964) | type ShowMessageRequestClientCapabilities struct
  type ShowMessageRequestParams (line 4970) | type ShowMessageRequestParams struct
  type SignatureHelp (line 4984) | type SignatureHelp struct
  type SignatureHelpClientCapabilities (line 5019) | type SignatureHelpClientCapabilities struct
  type SignatureHelpContext (line 5039) | type SignatureHelpContext struct
  type SignatureHelpOptions (line 5061) | type SignatureHelpOptions struct
  type SignatureHelpParams (line 5077) | type SignatureHelpParams struct
  type SignatureHelpRegistrationOptions (line 5090) | type SignatureHelpRegistrationOptions struct
  type SignatureHelpTriggerKind (line 5098) | type SignatureHelpTriggerKind
  type SignatureInformation (line 5105) | type SignatureInformation struct
  type SnippetTextEdit (line 5134) | type SnippetTextEdit struct
  type StaleRequestSupportOptions (line 5146) | type StaleRequestSupportOptions struct
  type StaticRegistrationOptions (line 5159) | type StaticRegistrationOptions struct
  type StringValue (line 5177) | type StringValue struct
  type SymbolInformation (line 5188) | type SymbolInformation struct
  type SymbolKind (line 5220) | type SymbolKind
  type SymbolTag (line 5225) | type SymbolTag
  type TextDocumentChangeRegistrationOptions (line 5230) | type TextDocumentChangeRegistrationOptions struct
  type TextDocumentClientCapabilities (line 5239) | type TextDocumentClientCapabilities struct
  type TextDocumentContentChangePartial (line 5344) | type TextDocumentContentChangePartial struct
  type TextDocumentContentChangeWholeDocument (line 5358) | type TextDocumentContentChangeWholeDocument struct
  type TextDocumentContentClientCapabilities (line 5369) | type TextDocumentContentClientCapabilities struct
  type TextDocumentContentOptions (line 5380) | type TextDocumentContentOptions struct
  type TextDocumentContentParams (line 5391) | type TextDocumentContentParams struct
  type TextDocumentContentRefreshParams (line 5402) | type TextDocumentContentRefreshParams struct
  type TextDocumentContentRegistrationOptions (line 5413) | type TextDocumentContentRegistrationOptions struct
  type TextDocumentEdit (line 5424) | type TextDocumentEdit struct
  type TextDocumentFilterLanguage (line 5462) | type TextDocumentFilterLanguage struct
  type TextDocumentFilterPattern (line 5478) | type TextDocumentFilterPattern struct
  type TextDocumentFilterScheme (line 5494) | type TextDocumentFilterScheme struct
  type TextDocumentIdentifier (line 5508) | type TextDocumentIdentifier struct
  type TextDocumentItem (line 5517) | type TextDocumentItem struct
  type TextDocumentPositionParams (line 5533) | type TextDocumentPositionParams struct
  type TextDocumentRegistrationOptions (line 5543) | type TextDocumentRegistrationOptions struct
  type TextDocumentSaveReason (line 5550) | type TextDocumentSaveReason
  type TextDocumentSaveRegistrationOptions (line 5555) | type TextDocumentSaveRegistrationOptions struct
  type TextDocumentSyncClientCapabilities (line 5561) | type TextDocumentSyncClientCapabilities struct
  type TextDocumentSyncKind (line 5576) | type TextDocumentSyncKind
  type TextDocumentSyncOptions (line 5579) | type TextDocumentSyncOptions struct
  type TextEdit (line 5600) | type TextEdit struct
  type TokenFormat (line 5608) | type TokenFormat
  type TraceValue (line 5609) | type TraceValue
  type Tuple_ParameterInformation_label_Item1 (line 5612) | type Tuple_ParameterInformation_label_Item1 struct
  type TypeDefinitionClientCapabilities (line 5620) | type TypeDefinitionClientCapabilities struct
  type TypeDefinitionOptions (line 5632) | type TypeDefinitionOptions struct
  type TypeDefinitionParams (line 5637) | type TypeDefinitionParams struct
  type TypeDefinitionRegistrationOptions (line 5644) | type TypeDefinitionRegistrationOptions struct
  type TypeHierarchyClientCapabilities (line 5653) | type TypeHierarchyClientCapabilities struct
  type TypeHierarchyItem (line 5663) | type TypeHierarchyItem struct
  type TypeHierarchyOptions (line 5693) | type TypeHierarchyOptions struct
  type TypeHierarchyPrepareParams (line 5702) | type TypeHierarchyPrepareParams struct
  type TypeHierarchyRegistrationOptions (line 5712) | type TypeHierarchyRegistrationOptions struct
  type TypeHierarchySubtypesParams (line 5723) | type TypeHierarchySubtypesParams struct
  type TypeHierarchySupertypesParams (line 5734) | type TypeHierarchySupertypesParams struct
  type UnchangedDocumentDiagnosticReport (line 5746) | type UnchangedDocumentDiagnosticReport struct
  type UniquenessLevel (line 5760) | type UniquenessLevel
  type Unregistration (line 5765) | type Unregistration struct
  type UnregistrationParams (line 5774) | type UnregistrationParams struct
  type VersionedNotebookDocumentIdentifier (line 5783) | type VersionedNotebookDocumentIdentifier struct
  type VersionedTextDocumentIdentifier (line 5793) | type VersionedTextDocumentIdentifier struct
  type WillSaveTextDocumentParams (line 5800) | type WillSaveTextDocumentParams struct
  type WindowClientCapabilities (line 5808) | type WindowClientCapabilities struct
  type WorkDoneProgressBegin (line 5830) | type WorkDoneProgressBegin struct
  type WorkDoneProgressCancelParams (line 5857) | type WorkDoneProgressCancelParams struct
  type WorkDoneProgressCreateParams (line 5863) | type WorkDoneProgressCreateParams struct
  type WorkDoneProgressEnd (line 5869) | type WorkDoneProgressEnd struct
  type WorkDoneProgressOptions (line 5877) | type WorkDoneProgressOptions struct
  type WorkDoneProgressParams (line 5882) | type WorkDoneProgressParams struct
  type WorkDoneProgressReport (line 5888) | type WorkDoneProgressReport struct
  type WorkspaceClientCapabilities (line 5913) | type WorkspaceClientCapabilities struct
  type WorkspaceDiagnosticParams (line 5982) | type WorkspaceDiagnosticParams struct
  type WorkspaceDiagnosticReport (line 5997) | type WorkspaceDiagnosticReport struct
  type WorkspaceDiagnosticReportPartialResult (line 6006) | type WorkspaceDiagnosticReportPartialResult struct
  type WorkspaceEdit (line 6030) | type WorkspaceEdit struct
  type WorkspaceEditClientCapabilities (line 6054) | type WorkspaceEditClientCapabilities struct
  type WorkspaceEditMetadata (line 6098) | type WorkspaceEditMetadata struct
  type WorkspaceFolder (line 6106) | type WorkspaceFolder struct
  type WorkspaceFoldersChangeEvent (line 6117) | type WorkspaceFoldersChangeEvent struct
  type WorkspaceFoldersInitializeParams (line 6125) | type WorkspaceFoldersInitializeParams struct
  type WorkspaceFoldersServerCapabilities (line 6137) | type WorkspaceFoldersServerCapabilities struct
  type WorkspaceFullDocumentDiagnosticReport (line 6155) | type WorkspaceFullDocumentDiagnosticReport struct
  type WorkspaceOptions (line 6169) | type WorkspaceOptions struct
  type WorkspaceSymbol (line 6192) | type WorkspaceSymbol struct
  type WorkspaceSymbolClientCapabilities (line 6208) | type WorkspaceSymbolClientCapabilities struct
  type WorkspaceSymbolOptions (line 6229) | type WorkspaceSymbolOptions struct
  type WorkspaceSymbolParams (line 6241) | type WorkspaceSymbolParams struct
  type WorkspaceSymbolRegistrationOptions (line 6258) | type WorkspaceSymbolRegistrationOptions struct
  type WorkspaceUnchangedDocumentDiagnosticReport (line 6267) | type WorkspaceUnchangedDocumentDiagnosticReport struct
  type XInitializeParams (line 6279) | type XInitializeParams struct
  type _InitializeParams (line 6322) | type _InitializeParams struct
  constant Empty (line 6365) | Empty CodeActionKind = ""
  constant QuickFix (line 6367) | QuickFix CodeActionKind = "quickfix"
  constant Refactor (line 6369) | Refactor CodeActionKind = "refactor"
  constant RefactorExtract (line 6380) | RefactorExtract CodeActionKind = "refactor.extract"
  constant RefactorInline (line 6390) | RefactorInline CodeActionKind = "refactor.inline"
  constant RefactorMove (line 6403) | RefactorMove CodeActionKind = "refactor.move"
  constant RefactorRewrite (line 6415) | RefactorRewrite CodeActionKind = "refactor.rewrite"
  constant Source (line 6419) | Source CodeActionKind = "source"
  constant SourceOrganizeImports (line 6421) | SourceOrganizeImports CodeActionKind = "source.organizeImports"
  constant SourceFixAll (line 6428) | SourceFixAll CodeActionKind = "source.fixAll"
  constant Notebook (line 6433) | Notebook CodeActionKind = "notebook"
  constant CodeActionInvoked (line 6438) | CodeActionInvoked CodeActionTriggerKind = 1
  constant CodeActionAutomatic (line 6443) | CodeActionAutomatic CodeActionTriggerKind = 2
  constant TextCompletion (line 6445) | TextCompletion          CompletionItemKind = 1
  constant MethodCompletion (line 6446) | MethodCompletion        CompletionItemKind = 2
  constant FunctionCompletion (line 6447) | FunctionCompletion      CompletionItemKind = 3
  constant ConstructorCompletion (line 6448) | ConstructorCompletion   CompletionItemKind = 4
  constant FieldCompletion (line 6449) | FieldCompletion         CompletionItemKind = 5
  constant VariableCompletion (line 6450) | VariableCompletion      CompletionItemKind = 6
  constant ClassCompletion (line 6451) | ClassCompletion         CompletionItemKind = 7
  constant InterfaceCompletion (line 6452) | InterfaceCompletion     CompletionItemKind = 8
  constant ModuleCompletion (line 6453) | ModuleCompletion        CompletionItemKind = 9
  constant PropertyCompletion (line 6454) | PropertyCompletion      CompletionItemKind = 10
  constant UnitCompletion (line 6455) | UnitCompletion          CompletionItemKind = 11
  constant ValueCompletion (line 6456) | ValueCompletion         CompletionItemKind = 12
  constant EnumCompletion (line 6457) | EnumCompletion          CompletionItemKind = 13
  constant KeywordCompletion (line 6458) | KeywordCompletion       CompletionItemKind = 14
  constant SnippetCompletion (line 6459) | SnippetCompletion       CompletionItemKind = 15
  constant ColorCompletion (line 6460) | ColorCompletion         CompletionItemKind = 16
  constant FileCompletion (line 6461) | FileCompletion          CompletionItemKind = 17
  constant ReferenceCompletion (line 6462) | ReferenceCompletion     CompletionItemKind = 18
  constant FolderCompletion (line 6463) | FolderCompletion        CompletionItemKind = 19
  constant EnumMemberCompletion (line 6464) | EnumMemberCompletion    CompletionItemKind = 20
  constant ConstantCompletion (line 6465) | ConstantCompletion      CompletionItemKind = 21
  constant StructCompletion (line 6466) | StructCompletion        CompletionItemKind = 22
  constant EventCompletion (line 6467) | EventCompletion         CompletionItemKind = 23
  constant OperatorCompletion (line 6468) | OperatorCompletion      CompletionItemKind = 24
  constant TypeParameterCompletion (line 6469) | TypeParameterCompletion CompletionItemKind = 25
  constant ComplDeprecated (line 6475) | ComplDeprecated CompletionItemTag = 1
  constant Invoked (line 6479) | Invoked CompletionTriggerKind = 1
  constant TriggerCharacter (line 6482) | TriggerCharacter CompletionTriggerKind = 2
  constant TriggerForIncompleteCompletions (line 6484) | TriggerForIncompleteCompletions CompletionTriggerKind = 3
  constant SeverityError (line 6487) | SeverityError DiagnosticSeverity = 1
  constant SeverityWarning (line 6489) | SeverityWarning DiagnosticSeverity = 2
  constant SeverityInformation (line 6491) | SeverityInformation DiagnosticSeverity = 3
  constant SeverityHint (line 6493) | SeverityHint DiagnosticSeverity = 4
  constant Unnecessary (line 6501) | Unnecessary DiagnosticTag = 1
  constant Deprecated (line 6505) | Deprecated DiagnosticTag = 2
  constant DiagnosticFull (line 6511) | DiagnosticFull DocumentDiagnosticReportKind = "full"
  constant DiagnosticUnchanged (line 6514) | DiagnosticUnchanged DocumentDiagnosticReportKind = "unchanged"
  constant Text (line 6517) | Text DocumentHighlightKind = 1
  constant Read (line 6519) | Read DocumentHighlightKind = 2
  constant Write (line 6521) | Write DocumentHighlightKind = 3
  constant ParseError (line 6523) | ParseError     ErrorCodes = -32700
  constant InvalidRequest (line 6524) | InvalidRequest ErrorCodes = -32600
  constant MethodNotFound (line 6525) | MethodNotFound ErrorCodes = -32601
  constant InvalidParams (line 6526) | InvalidParams  ErrorCodes = -32602
  constant InternalError (line 6527) | InternalError  ErrorCodes = -32603
  constant ServerNotInitialized (line 6530) | ServerNotInitialized ErrorCodes = -32002
  constant UnknownErrorCode (line 6531) | UnknownErrorCode     ErrorCodes = -32001
  constant Abort (line 6534) | Abort FailureHandlingKind = "abort"
  constant Transactional (line 6537) | Transactional FailureHandlingKind = "transactional"
  constant TextOnlyTransactional (line 6541) | TextOnlyTransactional FailureHandlingKind = "textOnlyTransactional"
  constant Undo (line 6544) | Undo FailureHandlingKind = "undo"
  constant Created (line 6547) | Created FileChangeType = 1
  constant Changed (line 6549) | Changed FileChangeType = 2
  constant Deleted (line 6551) | Deleted FileChangeType = 3
  constant FilePattern (line 6557) | FilePattern FileOperationPatternKind = "file"
  constant FolderPattern (line 6559) | FolderPattern FileOperationPatternKind = "folder"
  constant Comment (line 6562) | Comment FoldingRangeKind = "comment"
  constant Imports (line 6564) | Imports FoldingRangeKind = "imports"
  constant Region (line 6566) | Region FoldingRangeKind = "region"
  constant Type (line 6571) | Type InlayHintKind = 1
  constant Parameter (line 6573) | Parameter InlayHintKind = 2
  constant InlineInvoked (line 6579) | InlineInvoked InlineCompletionTriggerKind = 1
  constant InlineAutomatic (line 6581) | InlineAutomatic InlineCompletionTriggerKind = 2
  constant PlainTextTextFormat (line 6585) | PlainTextTextFormat InsertTextFormat = 1
  constant SnippetTextFormat (line 6594) | SnippetTextFormat InsertTextFormat = 2
  constant AsIs (line 6604) | AsIs InsertTextMode = 1
  constant AdjustIndentation (line 6612) | AdjustIndentation InsertTextMode = 2
  constant RequestFailed (line 6619) | RequestFailed LSPErrorCodes = -32803
  constant ServerCancelled (line 6625) | ServerCancelled LSPErrorCodes = -32802
  constant ContentModified (line 6634) | ContentModified LSPErrorCodes = -32801
  constant RequestCancelled (line 6637) | RequestCancelled LSPErrorCodes = -32800
  constant LangABAP (line 6641) | LangABAP         LanguageKind = "abap"
  constant LangWindowsBat (line 6642) | LangWindowsBat   LanguageKind = "bat"
  constant LangBibTeX (line 6643) | LangBibTeX       LanguageKind = "bibtex"
  constant LangClojure (line 6644) | LangClojure      LanguageKind = "clojure"
  constant LangCoffeescript (line 6645) | LangCoffeescript LanguageKind = "coffeescript"
  constant LangC (line 6646) | LangC            LanguageKind = "c"
  constant LangCPP (line 6647) | LangCPP          LanguageKind = "cpp"
  constant LangCSharp (line 6648) | LangCSharp       LanguageKind = "csharp"
  constant LangCSS (line 6649) | LangCSS          LanguageKind = "css"
  constant LangD (line 6652) | LangD LanguageKind = "d"
  constant LangDelphi (line 6655) | LangDelphi          LanguageKind = "pascal"
  constant LangDiff (line 6656) | LangDiff            LanguageKind = "diff"
  constant LangDart (line 6657) | LangDart            LanguageKind = "dart"
  constant LangDockerfile (line 6658) | LangDockerfile      LanguageKind = "dockerfile"
  constant LangElixir (line 6659) | LangElixir          LanguageKind = "elixir"
  constant LangErlang (line 6660) | LangErlang          LanguageKind = "erlang"
  constant LangFSharp (line 6661) | LangFSharp          LanguageKind = "fsharp"
  constant LangGitCommit (line 6662) | LangGitCommit       LanguageKind = "git-commit"
  constant LangGitRebase (line 6663) | LangGitRebase       LanguageKind = "rebase"
  constant LangGo (line 6664) | LangGo              LanguageKind = "go"
  constant LangGroovy (line 6665) | LangGroovy          LanguageKind = "groovy"
  constant LangHandlebars (line 6666) | LangHandlebars      LanguageKind = "handlebars"
  constant LangHaskell (line 6667) | LangHaskell         LanguageKind = "haskell"
  constant LangHTML (line 6668) | LangHTML            LanguageKind = "html"
  constant LangIni (line 6669) | LangIni             LanguageKind = "ini"
  constant LangJava (line 6670) | LangJava            LanguageKind = "java"
  constant LangJavaScript (line 6671) | LangJavaScript      LanguageKind = "javascript"
  constant LangJavaScriptReact (line 6672) | LangJavaScriptReact LanguageKind = "javascriptreact"
  constant LangJSON (line 6673) | LangJSON            LanguageKind = "json"
  constant LangLaTeX (line 6674) | LangLaTeX           LanguageKind = "latex"
  constant LangLess (line 6675) | LangLess            LanguageKind = "less"
  constant LangLua (line 6676) | LangLua             LanguageKind = "lua"
  constant LangMakefile (line 6677) | LangMakefile        LanguageKind = "makefile"
  constant LangMarkdown (line 6678) | LangMarkdown        LanguageKind = "markdown"
  constant LangObjectiveC (line 6679) | LangObjectiveC      LanguageKind = "objective-c"
  constant LangObjectiveCPP (line 6680) | LangObjectiveCPP    LanguageKind = "objective-cpp"
  constant LangPascal (line 6683) | LangPascal          LanguageKind = "pascal"
  constant LangPerl (line 6684) | LangPerl            LanguageKind = "perl"
  constant LangPerl6 (line 6685) | LangPerl6           LanguageKind = "perl6"
  constant LangPHP (line 6686) | LangPHP             LanguageKind = "php"
  constant LangPowershell (line 6687) | LangPowershell      LanguageKind = "powershell"
  constant LangPug (line 6688) | LangPug             LanguageKind = "jade"
  constant LangPython (line 6689) | LangPython          LanguageKind = "python"
  constant LangR (line 6690) | LangR               LanguageKind = "r"
  constant LangRazor (line 6691) | LangRazor           LanguageKind = "razor"
  constant LangRuby (line 6692) | LangRuby            LanguageKind = "ruby"
  constant LangRust (line 6693) | LangRust            LanguageKind = "rust"
  constant LangSCSS (line 6694) | LangSCSS            LanguageKind = "scss"
  constant LangSASS (line 6695) | LangSASS            LanguageKind = "sass"
  constant LangScala (line 6696) | LangScala           LanguageKind = "scala"
  constant LangShaderLab (line 6697) | LangShaderLab       LanguageKind = "shaderlab"
  constant LangShellScript (line 6698) | LangShellScript     LanguageKind = "shellscript"
  constant LangSQL (line 6699) | LangSQL             LanguageKind = "sql"
  constant LangSwift (line 6700) | LangSwift           LanguageKind = "swift"
  constant LangTypeScript (line 6701) | LangTypeScript      LanguageKind = "typescript"
  constant LangTypeScriptReact (line 6702) | LangTypeScriptReact LanguageKind = "typescriptreact"
  constant LangTeX (line 6703) | LangTeX             LanguageKind = "tex"
  constant LangVisualBasic (line 6704) | LangVisualBasic     LanguageKind = "vb"
  constant LangXML (line 6705) | LangXML             LanguageKind = "xml"
  constant LangXSL (line 6706) | LangXSL             LanguageKind = "xsl"
  constant LangYAML (line 6707) | LangYAML            LanguageKind = "yaml"
  constant PlainText (line 6714) | PlainText MarkupKind = "plaintext"
  constant Markdown (line 6716) | Markdown MarkupKind = "markdown"
  constant Error (line 6719) | Error MessageType = 1
  constant Warning (line 6721) | Warning MessageType = 2
  constant Info (line 6723) | Info MessageType = 3
  constant Log (line 6725) | Log MessageType = 4
  constant Debug (line 6730) | Debug MessageType = 5
  constant Import (line 6735) | Import MonikerKind = "import"
  constant Export (line 6737) | Export MonikerKind = "export"
  constant Local (line 6740) | Local MonikerKind = "local"
  constant Markup (line 6745) | Markup NotebookCellKind = 1
  constant Code (line 6747) | Code NotebookCellKind = 2
  constant UTF8 (line 6752) | UTF8 PositionEncodingKind = "utf-8"
  constant UTF16 (line 6757) | UTF16 PositionEncodingKind = "utf-16"
  constant UTF32 (line 6763) | UTF32 PositionEncodingKind = "utf-32"
  constant Identifier (line 6766) | Identifier PrepareSupportDefaultBehavior = 1
  constant Create (line 6768) | Create ResourceOperationKind = "create"
  constant Rename (line 6770) | Rename ResourceOperationKind = "rename"
  constant Delete (line 6772) | Delete ResourceOperationKind = "delete"
  constant ModDeclaration (line 6778) | ModDeclaration    SemanticTokenModifiers = "declaration"
  constant ModDefinition (line 6779) | ModDefinition     SemanticTokenModifiers = "definition"
  constant ModReadonly (line 6780) | ModReadonly       SemanticTokenModifiers = "readonly"
  constant ModStatic (line 6781) | ModStatic         SemanticTokenModifiers = "static"
  constant ModDeprecated (line 6782) | ModDeprecated     SemanticTokenModifiers = "deprecated"
  constant ModAbstract (line 6783) | ModAbstract       SemanticTokenModifiers = "abstract"
  constant ModAsync (line 6784) | ModAsync          SemanticTokenModifiers = "async"
  constant ModModification (line 6785) | ModModification   SemanticTokenModifiers = "modification"
  constant ModDocumentation (line 6786) | ModDocumentation  SemanticTokenModifiers = "documentation"
  constant ModDefaultLibrary (line 6787) | ModDefaultLibrary SemanticTokenModifiers = "defaultLibrary"
  constant NamespaceType (line 6793) | NamespaceType SemanticTokenTypes = "namespace"
  constant TypeType (line 6796) | TypeType          SemanticTokenTypes = "type"
  constant ClassType (line 6797) | ClassType         SemanticTokenTypes = "class"
  constant EnumType (line 6798) | EnumType          SemanticTokenTypes = "enum"
  constant InterfaceType (line 6799) | InterfaceType     SemanticTokenTypes = "interface"
  constant StructType (line 6800) | StructType        SemanticTokenTypes = "struct"
  constant TypeParameterType (line 6801) | TypeParameterType SemanticTokenTypes = "typeParameter"
  constant ParameterType (line 6802) | ParameterType     SemanticTokenTypes = "parameter"
  constant VariableType (line 6803) | VariableType      SemanticTokenTypes = "variable"
  constant PropertyType (line 6804) | PropertyType      SemanticTokenTypes = "property"
  constant EnumMemberType (line 6805) | EnumMemberType    SemanticTokenTypes = "enumMember"
  constant EventType (line 6806) | EventType         SemanticTokenTypes = "event"
  constant FunctionType (line 6807) | FunctionType      SemanticTokenTypes = "function"
  constant MethodType (line 6808) | MethodType        SemanticTokenTypes = "method"
  constant MacroType (line 6809) | MacroType         SemanticTokenTypes = "macro"
  constant KeywordType (line 6810) | KeywordType       SemanticTokenTypes = "keyword"
  constant ModifierType (line 6811) | ModifierType      SemanticTokenTypes = "modifier"
  constant CommentType (line 6812) | CommentType       SemanticTokenTypes = "comment"
  constant StringType (line 6813) | StringType        SemanticTokenTypes = "string"
  constant NumberType (line 6814) | NumberType        SemanticTokenTypes = "number"
  constant RegexpType (line 6815) | RegexpType        SemanticTokenTypes = "regexp"
  constant OperatorType (line 6816) | OperatorType      SemanticTokenTypes = "operator"
  constant DecoratorType (line 6818) | DecoratorType SemanticTokenTypes = "decorator"
  constant LabelType (line 6820) | LabelType SemanticTokenTypes = "label"
  constant SigInvoked (line 6825) | SigInvoked SignatureHelpTriggerKind = 1
  constant SigTriggerCharacter (line 6827) | SigTriggerCharacter SignatureHelpTriggerKind = 2
  constant SigContentChange (line 6829) | SigContentChange SignatureHelpTriggerKind = 3
  constant File (line 6831) | File          SymbolKind = 1
  constant Module (line 6832) | Module        SymbolKind = 2
  constant Namespace (line 6833) | Namespace     SymbolKind = 3
  constant Package (line 6834) | Package       SymbolKind = 4
  constant Class (line 6835) | Class         SymbolKind = 5
  constant Method (line 6836) | Method        SymbolKind = 6
  constant Property (line 6837) | Property      SymbolKind = 7
  constant Field (line 6838) | Field         SymbolKind = 8
  constant Constructor (line 6839) | Constructor   SymbolKind = 9
  constant Enum (line 6840) | Enum          SymbolKind = 10
  constant Interface (line 6841) | Interface     SymbolKind = 11
  constant Function (line 6842) | Function      SymbolKind = 12
  constant Variable (line 6843) | Variable      SymbolKind = 13
  constant Constant (line 6844) | Constant      SymbolKind = 14
  constant String (line 6845) | String        SymbolKind = 15
  constant Number (line 6846) | Number        SymbolKind = 16
  constant Boolean (line 6847) | Boolean       SymbolKind = 17
  constant Array (line 6848) | Array         SymbolKind = 18
  constant Object (line 6849) | Object        SymbolKind = 19
  constant Key (line 6850) | Key           SymbolKind = 20
  constant Null (line 6851) | Null          SymbolKind = 21
  constant EnumMember (line 6852) | EnumMember    SymbolKind = 22
  constant Struct (line 6853) | Struct        SymbolKind = 23
  constant Event (line 6854) | Event         SymbolKind = 24
  constant Operator (line 6855) | Operator      SymbolKind = 25
  constant TypeParameter (line 6856) | TypeParameter SymbolKind = 26
  constant DeprecatedSymbol (line 6861) | DeprecatedSymbol SymbolTag = 1
  constant Manual (line 6865) | Manual TextDocumentSaveReason = 1
  constant AfterDelay (line 6867) | AfterDelay TextDocumentSaveReason = 2
  constant FocusOut (line 6869) | FocusOut TextDocumentSaveReason = 3
  constant None (line 6873) | None TextDocumentSyncKind = 0
  constant Full (line 6876) | Full TextDocumentSyncKind = 1
  constant Incremental (line 6880) | Incremental TextDocumentSyncKind = 2
  constant Relative (line 6881) | Relative    TokenFormat          = "relative"
  constant Off (line 6883) | Off TraceValue = "off"
  constant Messages (line 6885) | Messages TraceValue = "messages"
  constant Verbose (line 6887) | Verbose TraceValue = "verbose"
  constant Document (line 6892) | Document UniquenessLevel = "document"
  constant Project (line 6894) | Project UniquenessLevel = "project"
  constant Group (line 6896) | Group UniquenessLevel = "group"
  constant Scheme (line 6898) | Scheme UniquenessLevel = "scheme"
  constant Global (line 6900) | Global UniquenessLevel = "global"
  constant WatchCreate (line 6902) | WatchCreate WatchKind = 1
  constant WatchChange (line 6904) | WatchChange WatchKind = 2
  constant WatchDelete (line 6906) | WatchDelete WatchKind = 4

FILE: internal/lsp/protocol/uri.go
  type DocumentUri (line 42) | type DocumentUri
    method UnmarshalText (line 63) | func (uri *DocumentUri) UnmarshalText(data []byte) (err error) {
    method Path (line 73) | func (uri DocumentUri) Path() string {
    method Dir (line 88) | func (uri DocumentUri) Dir() DocumentUri {
    method DirPath (line 96) | func (uri DocumentUri) DirPath() string {
  function filename (line 100) | func filename(uri DocumentUri) (string, error) {
  function ParseDocumentUri (line 142) | func ParseDocumentUri(s string) (DocumentUri, error) {
  function URIFromPath (line 177) | func URIFromPath(path string) DocumentUri {
  constant fileScheme (line 198) | fileScheme = "file"
  function isWindowsDrivePath (line 203) | func isWindowsDrivePath(path string) bool {
  function isWindowsDriveURIPath (line 213) | func isWindowsDriveURIPath(uri string) bool {

FILE: internal/lsp/transport.go
  function WriteMessage (line 16) | func WriteMessage(w io.Writer, msg *Message) error {
  function ReadMessage (line 41) | func ReadMessage(r *bufio.Reader) (*Message, error) {
  method handleMessages (line 93) | func (c *Client) handleMessages() {
  method Call (line 190) | func (c *Client) Call(ctx context.Context, method string, params any, re...
  method Notify (line 251) | func (c *Client) Notify(ctx context.Context, method string, params any) ...
  type NotificationHandler (line 270) | type NotificationHandler
  type ServerRequestHandler (line 271) | type ServerRequestHandler

FILE: internal/lsp/util/edit.go
  function applyTextEdits (line 13) | func applyTextEdits(uri protocol.DocumentUri, edits []protocol.TextEdit)...
  function applyTextEdit (line 85) | func applyTextEdit(lines []string, edit protocol.TextEdit) ([]string, er...
  function applyDocumentChange (line 149) | func applyDocumentChange(change protocol.DocumentChange) error {
  function ApplyWorkspaceEdit (line 210) | func ApplyWorkspaceEdit(edit protocol.WorkspaceEdit) error {
  function rangesOverlap (line 228) | func rangesOverlap(r1, r2 protocol.Range) bool {

FILE: internal/lsp/watcher/watcher.go
  type WorkspaceWatcher (line 21) | type WorkspaceWatcher struct
    method AddRegistrations (line 45) | func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id st...
    method openHighPriorityFiles (line 199) | func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, ...
    method WatchWorkspace (line 307) | func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspa...
    method isPathWatched (line 453) | func (w *WorkspaceWatcher) isPathWatched(path string) (bool, protocol....
    method matchesPattern (line 580) | func (w *WorkspaceWatcher) matchesPattern(path string, pattern protoco...
    method debounceHandleFileEvent (line 619) | func (w *WorkspaceWatcher) debounceHandleFileEvent(ctx context.Context...
    method handleFileEvent (line 643) | func (w *WorkspaceWatcher) handleFileEvent(ctx context.Context, uri st...
    method notifyFileEvent (line 663) | func (w *WorkspaceWatcher) notifyFileEvent(ctx context.Context, uri st...
    method openMatchingFile (line 857) | func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path ...
  function NewWorkspaceWatcher (line 35) | func NewWorkspaceWatcher(client *lsp.Client) *WorkspaceWatcher {
  function matchesGlob (line 478) | func matchesGlob(pattern, path string) bool {
  function matchesSimpleGlob (line 507) | func matchesSimpleGlob(pattern, path string) bool {
  function getServerNameFromContext (line 686) | func getServerNameFromContext(ctx context.Context) string {
  function shouldPreloadFiles (line 720) | func shouldPreloadFiles(serverName string) bool {
  function shouldExcludeDir (line 795) | func shouldExcludeDir(dirPath string) bool {
  function shouldExcludeFile (line 812) | func shouldExcludeFile(filePath string) bool {
  function isHighPriorityFile (line 935) | func isHighPriorityFile(path string, serverName string) bool {

FILE: internal/message/attachment.go
  type Attachment (line 3) | type Attachment struct

FILE: internal/message/content.go
  type MessageRole (line 11) | type MessageRole
  constant Assistant (line 14) | Assistant MessageRole = "assistant"
  constant User (line 15) | User      MessageRole = "user"
  constant System (line 16) | System    MessageRole = "system"
  constant Tool (line 17) | Tool      MessageRole = "tool"
  type FinishReason (line 20) | type FinishReason
  constant FinishReasonEndTurn (line 23) | FinishReasonEndTurn          FinishReason = "end_turn"
  constant FinishReasonMaxTokens (line 24) | FinishReasonMaxTokens        FinishReason = "max_tokens"
  constant FinishReasonToolUse (line 25) | FinishReasonToolUse          FinishReason = "tool_use"
  constant FinishReasonCanceled (line 26) | FinishReasonCanceled         FinishReason = "canceled"
  constant FinishReasonError (line 27) | FinishReasonError            FinishReason = "error"
  constant FinishReasonPermissionDenied (line 28) | FinishReasonPermissionDenied FinishReason = "permission_denied"
  constant FinishReasonUnknown (line 31) | FinishReasonUnknown FinishReason = "unknown"
  type ContentPart (line 34) | type ContentPart interface
  type ReasoningContent (line 38) | type ReasoningContent struct
    method String (line 42) | func (tc ReasoningContent) String() string {
    method isPart (line 45) | func (ReasoningContent) isPart() {}
  type TextContent (line 47) | type TextContent struct
    method String (line 51) | func (tc TextContent) String() string {
    method isPart (line 55) | func (TextContent) isPart() {}
  type ImageURLContent (line 57) | type ImageURLContent struct
    method String (line 62) | func (iuc ImageURLContent) String() string {
    method isPart (line 66) | func (ImageURLContent) isPart() {}
  type BinaryContent (line 68) | type BinaryContent struct
    method String (line 74) | func (bc BinaryContent) String(provider models.ModelProvider) string {
    method isPart (line 82) | func (BinaryContent) isPart() {}
  type ToolCall (line 84) | type ToolCall struct
    method isPart (line 92) | func (ToolCall) isPart() {}
  type ToolResult (line 94) | type ToolResult struct
    method isPart (line 102) | func (ToolResult) isPart() {}
  type Finish (line 104) | type Finish struct
    method isPart (line 109) | func (Finish) isPart() {}
  type Message (line 111) | type Message struct
    method Content (line 121) | func (m *Message) Content() TextContent {
    method ReasoningContent (line 130) | func (m *Message) ReasoningContent() ReasoningContent {
    method ImageURLContent (line 139) | func (m *Message) ImageURLContent() []ImageURLContent {
    method BinaryContent (line 149) | func (m *Message) BinaryContent() []BinaryContent {
    method ToolCalls (line 159) | func (m *Message) ToolCalls() []ToolCall {
    method ToolResults (line 169) | func (m *Message) ToolResults() []ToolResult {
    method IsFinished (line 179) | func (m *Message) IsFinished() bool {
    method FinishPart (line 188) | func (m *Message) FinishPart() *Finish {
    method FinishReason (line 197) | func (m *Message) FinishReason() FinishReason {
    method IsThinking (line 206) | func (m *Message) IsThinking() bool {
    method AppendContent (line 213) | func (m *Message) AppendContent(delta string) {
    method AppendReasoningContent (line 226) | func (m *Message) AppendReasoningContent(delta string) {
    method FinishToolCall (line 239) | func (m *Message) FinishToolCall(toolCallID string) {
    method AppendToolCallInput (line 256) | func (m *Message) AppendToolCallInput(toolCallID string, inputDelta st...
    method AddToolCall (line 273) | func (m *Message) AddToolCall(tc ToolCall) {
    method SetToolCalls (line 285) | func (m *Message) SetToolCalls(tc []ToolCall) {
    method AddToolResult (line 300) | func (m *Message) AddToolResult(tr ToolResult) {
    method SetToolResults (line 304) | func (m *Message) SetToolResults(tr []ToolResult) {
    method AddFinish (line 310) | func (m *Message) AddFinish(reason FinishReason) {
    method AddImageURL (line 321) | func (m *Message) AddImageURL(url, detail string) {
    method AddBinary (line 325) | func (m *Message) AddBinary(mimeType string, data []byte) {

FILE: internal/message/message.go
  type CreateMessageParams (line 16) | type CreateMessageParams struct
  type Service (line 22) | type Service interface
  type service (line 32) | type service struct
    method Delete (line 44) | func (s *service) Delete(ctx context.Context, id string) error {
    method Create (line 57) | func (s *service) Create(ctx context.Context, sessionID string, params...
    method DeleteSessionMessages (line 85) | func (s *service) DeleteSessionMessages(ctx context.Context, sessionID...
    method Update (line 101) | func (s *service) Update(ctx context.Context, message Message) error {
    method Get (line 124) | func (s *service) Get(ctx context.Context, id string) (Message, error) {
    method List (line 132) | func (s *service) List(ctx context.Context, sessionID string) ([]Messa...
    method fromDBItem (line 147) | func (s *service) fromDBItem(item db.Message) (Message, error) {
  function NewService (line 37) | func NewService(q db.Querier) Service {
  type partType (line 163) | type partType
  constant reasoningType (line 166) | reasoningType  partType = "reasoning"
  constant textType (line 167) | textType       partType = "text"
  constant imageURLType (line 168) | imageURLType   partType = "image_url"
  constant binaryType (line 169) | binaryType     partType = "binary"
  constant toolCallType (line 170) | toolCallType   partType = "tool_call"
  constant toolResultType (line 171) | toolResultType partType = "tool_result"
  constant finishType (line 172) | finishType     partType = "finish"
  type partWrapper (line 175) | type partWrapper struct
  function marshallParts (line 180) | func marshallParts(parts []ContentPart) ([]byte, error) {
  function unmarshallParts (line 213) | func unmarshallParts(data []byte) ([]ContentPart, error) {

FILE: internal/permission/permission.go
  type CreatePermissionRequest (line 16) | type CreatePermissionRequest struct
  type PermissionRequest (line 25) | type PermissionRequest struct
  type Service (line 35) | type Service interface
  type permissionService (line 44) | type permissionService struct
    method GrantPersistant (line 52) | func (s *permissionService) GrantPersistant(permission PermissionReque...
    method Grant (line 60) | func (s *permissionService) Grant(permission PermissionRequest) {
    method Deny (line 67) | func (s *permissionService) Deny(permission PermissionRequest) {
    method Request (line 74) | func (s *permissionService) Request(opts CreatePermissionRequest) bool {
    method AutoApproveSession (line 110) | func (s *permissionService) AutoApproveSession(sessionID string) {
  function NewPermissionService (line 114) | func NewPermissionService() Service {

FILE: internal/pubsub/broker.go
  constant bufferSize (line 8) | bufferSize = 64
  type Broker (line 10) | type Broker struct
  function NewBroker (line 18) | func NewBroker[T any]() *Broker[T] {
  function NewBrokerWithOptions (line 22) | func NewBrokerWithOptions[T any](channelBufferSize, maxEvents int) *Brok...
  method Shutdown (line 32) | func (b *Broker[T]) Shutdown() {
  method Subscribe (line 51) | func (b *Broker[T]) Subscribe(ctx context.Context) <-chan Event[T] {
  method GetSubscriberCount (line 87) | func (b *Broker[T]) GetSubscriberCount() int {
  method Publish (line 93) | func (b *Broker[T]) Publish(t EventType, payload T) {

FILE: internal/pubsub/events.go
  constant CreatedEvent (line 6) | CreatedEvent EventType = "created"
  constant UpdatedEvent (line 7) | UpdatedEvent EventType = "updated"
  constant DeletedEvent (line 8) | DeletedEvent EventType = "deleted"
  type Suscriber (line 11) | type Suscriber interface
  type EventType (line 17) | type EventType
  type Event (line 20) | type Event struct
  type Publisher (line 25) | type Publisher interface

FILE: internal/session/session.go
  type Session (line 12) | type Session struct
  type Service (line 25) | type Service interface
  type service (line 36) | type service struct
    method Create (line 41) | func (s *service) Create(ctx context.Context, title string) (Session, ...
    method CreateTaskSession (line 54) | func (s *service) CreateTaskSession(ctx context.Context, toolCallID, p...
    method CreateTitleSession (line 68) | func (s *service) CreateTitleSession(ctx context.Context, parentSessio...
    method Delete (line 82) | func (s *service) Delete(ctx context.Context, id string) error {
    method Get (line 95) | func (s *service) Get(ctx context.Context, id string) (Session, error) {
    method Save (line 103) | func (s *service) Save(ctx context.Context, session Session) (Session,...
    method List (line 123) | func (s *service) List(ctx context.Context) ([]Session, error) {
    method fromDBItem (line 135) | func (s service) fromDBItem(item db.Session) Session {
  function NewService (line 150) | func NewService(q db.Querier) Service {

FILE: internal/tui/components/chat/chat.go
  type SendMsg (line 17) | type SendMsg struct
  type SessionClearedMsg (line 24) | type SessionClearedMsg struct
  type EditorFocusMsg (line 26) | type EditorFocusMsg
  function header (line 28) | func header(width int) string {
  function lspsConfigured (line 38) | func lspsConfigured(width int) string {
  function logo (line 100) | func logo(width int) string {
  function repo (line 122) | func repo(width int) string {
  function cwd (line 132) | func cwd(width int) string {

FILE: internal/tui/components/chat/editor.go
  type editorCmp (line 26) | type editorCmp struct
    method openEditor (line 82) | func (m *editorCmp) openEditor() tea.Cmd {
    method Init (line 118) | func (m *editorCmp) Init() tea.Cmd {
    method send (line 122) | func (m *editorCmp) send() tea.Cmd {
    method Update (line 143) | func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 219) | func (m *editorCmp) View() string {
    method SetSize (line 239) | func (m *editorCmp) SetSize(width, height int) tea.Cmd {
    method GetSize (line 248) | func (m *editorCmp) GetSize() (int, int) {
    method attachmentsContent (line 252) | func (m *editorCmp) attachmentsContent() string {
    method BindingKeys (line 275) | func (m *editorCmp) BindingKeys() []key.Binding {
  type EditorKeyMaps (line 36) | type EditorKeyMaps struct
  type bluredEditorKeyMaps (line 41) | type bluredEditorKeyMaps struct
  type DeleteAttachmentKeyMaps (line 46) | type DeleteAttachmentKeyMaps struct
  constant maxAttachments (line 79) | maxAttachments = 5
  function CreateTextArea (line 282) | func CreateTextArea(existing *textarea.Model) textarea.Model {
  function NewEditorCmp (line 312) | func NewEditorCmp(app *app.App) tea.Model {

FILE: internal/tui/components/chat/list.go
  type cacheItem (line 23) | type cacheItem struct
  type messagesCmp (line 27) | type messagesCmp struct
    method Init (line 68) | func (m *messagesCmp) Init() tea.Cmd {
    method Update (line 72) | func (m *messagesCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method IsAgentWorking (line 171) | func (m *messagesCmp) IsAgentWorking() bool {
    method renderView (line 187) | func (m *messagesCmp) renderView() {
    method View (line 265) | func (m *messagesCmp) View() string {
    method working (line 348) | func (m *messagesCmp) working() string {
    method help (line 374) | func (m *messagesCmp) help() string {
    method initialScreen (line 403) | func (m *messagesCmp) initialScreen() string {
    method rerender (line 416) | func (m *messagesCmp) rerender() {
    method SetSize (line 423) | func (m *messagesCmp) SetSize(width, height int) tea.Cmd {
    method GetSize (line 437) | func (m *messagesCmp) GetSize() (int, int) {
    method SetSession (line 441) | func (m *messagesCmp) SetSession(session session.Session) tea.Cmd {
    method BindingKeys (line 462) | func (m *messagesCmp) BindingKeys() []key.Binding {
  type renderFinishedMsg (line 40) | type renderFinishedMsg struct
  type MessageKeys (line 42) | type MessageKeys struct
  function formatTimeDifference (line 175) | func formatTimeDifference(unixTime1, unixTime2 int64) string {
  function hasToolsWithoutResponse (line 312) | func hasToolsWithoutResponse(messages []message.Message) bool {
  function hasUnfinishedToolCalls (line 335) | func hasUnfinishedToolCalls(messages []message.Message) bool {
  function NewMessagesCmp (line 471) | func NewMessagesCmp(app *app.App) tea.Model {

FILE: internal/tui/components/chat/message.go
  type uiMessageType (line 23) | type uiMessageType
  constant userMessageType (line 26) | userMessageType uiMessageType = iota
  constant assistantMessageType (line 27) | assistantMessageType
  constant toolMessageType (line 28) | toolMessageType
  constant maxResultHeight (line 30) | maxResultHeight = 10
  type uiMessage (line 33) | type uiMessage struct
  function toMarkdown (line 41) | func toMarkdown(content string, focused bool, width int) string {
  function renderMessage (line 47) | func renderMessage(msg string, isUser bool, isFocused bool, width int, i...
  function renderUserMessage (line 82) | func renderUserMessage(msg message.Message, isFocused bool, width int, p...
  function renderAssistantMessage (line 117) | func renderAssistantMessage(
  function findToolResponse (line 208) | func findToolResponse(toolCallID string, futureMessages []message.Messag...
  function toolName (line 219) | func toolName(name string) string {
  function getToolAction (line 247) | func getToolAction(name string) string {
  function renderParams (line 276) | func renderParams(paramsWidth int, params ...string) string {
  function removeWorkingDirPrefix (line 318) | func removeWorkingDirPrefix(path string) string {
  function renderToolParams (line 335) | func renderToolParams(paramWidth int, toolCall message.ToolCall) string {
  function truncateHeight (line 433) | func truncateHeight(content string, height int) string {
  function renderToolResponse (line 441) | func renderToolResponse(toolCall message.ToolCall, response message.Tool...
  function renderToolMessage (line 535) | func renderToolMessage(
  function formatTimestampDiff (line 650) | func formatTimestampDiff(start, end int64) string {

FILE: internal/tui/components/chat/sidebar.go
  type sidebarCmp (line 20) | type sidebarCmp struct
    method Init (line 30) | func (m *sidebarCmp) Init() tea.Cmd {
    method Update (line 53) | func (m *sidebarCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 84) | func (m *sidebarCmp) View() string {
    method sessionSection (line 106) | func (m *sidebarCmp) sessionSection() string {
    method modifiedFile (line 127) | func (m *sidebarCmp) modifiedFile(filePath string, additions, removals...
    method modifiedFiles (line 172) | func (m *sidebarCmp) modifiedFiles() string {
    method SetSize (line 228) | func (m *sidebarCmp) SetSize(width, height int) tea.Cmd {
    method GetSize (line 234) | func (m *sidebarCmp) GetSize() (int, int) {
    method loadModifiedFiles (line 245) | func (m *sidebarCmp) loadModifiedFiles(ctx context.Context) {
    method processFileChanges (line 314) | func (m *sidebarCmp) processFileChanges(ctx context.Context, file hist...
    method findInitialVersion (line 356) | func (m *sidebarCmp) findInitialVersion(ctx context.Context, path stri...
  function NewSidebarCmp (line 238) | func NewSidebarCmp(session session.Session, history history.Service) tea...
  function getDisplayPath (line 374) | func getDisplayPath(path string) string {

FILE: internal/tui/components/core/status.go
  type StatusCmp (line 22) | type StatusCmp interface
  type statusCmp (line 26) | type statusCmp struct
    method clearMessageCmd (line 35) | func (m statusCmp) clearMessageCmd(ttl time.Duration) tea.Cmd {
    method Init (line 41) | func (m statusCmp) Init() tea.Cmd {
    method Update (line 45) | func (m statusCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 119) | func (m statusCmp) View() string {
    method projectDiagnostics (line 182) | func (m *statusCmp) projectDiagnostics() string {
    method availableFooterMsgWidth (line 261) | func (m statusCmp) availableFooterMsgWidth(diagnostics, tokenInfo stri...
    method model (line 269) | func (m statusCmp) model() string {
  function getHelpWidget (line 76) | func getHelpWidget() string {
  function formatTokensAndCost (line 87) | func formatTokensAndCost(tokens, contextWindow int64, cost float64) stri...
  function NewStatusCmp (line 286) | func NewStatusCmp(lspClients map[string]*lsp.Client) StatusCmp {

FILE: internal/tui/components/dialog/arguments.go
  type argumentsDialogKeyMap (line 15) | type argumentsDialogKeyMap struct
    method ShortHelp (line 21) | func (k argumentsDialogKeyMap) ShortHelp() []key.Binding {
    method FullHelp (line 35) | func (k argumentsDialogKeyMap) FullHelp() [][]key.Binding {
  type ShowMultiArgumentsDialogMsg (line 40) | type ShowMultiArgumentsDialogMsg struct
  type CloseMultiArgumentsDialogMsg (line 47) | type CloseMultiArgumentsDialogMsg struct
  type MultiArgumentsDialogCmp (line 55) | type MultiArgumentsDialogCmp struct
    method Init (line 102) | func (m MultiArgumentsDialogCmp) Init() tea.Cmd {
    method Update (line 116) | func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.C...
    method View (line 179) | func (m MultiArgumentsDialogCmp) View() string {
    method SetSize (line 249) | func (m *MultiArgumentsDialogCmp) SetSize(width, height int) {
    method Bindings (line 255) | func (m MultiArgumentsDialogCmp) Bindings() []key.Binding {
  function NewMultiArgumentsDialogCmp (line 66) | func NewMultiArgumentsDialogCmp(commandID, content string, argNames []st...

FILE: internal/tui/components/dialog/commands.go
  type Command (line 15) | type Command struct
    method Render (line 22) | func (ci Command) Render(selected bool, width int) string {
  type CommandSelectedMsg (line 50) | type CommandSelectedMsg struct
  type CloseCommandDialogMsg (line 55) | type CloseCommandDialogMsg struct
  type CommandDialog (line 58) | type CommandDialog interface
  type commandDialogCmp (line 64) | type commandDialogCmp struct
    method Init (line 86) | func (c *commandDialogCmp) Init() tea.Cmd {
    method Update (line 90) | func (c *commandDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 117) | func (c *commandDialogCmp) View() string {
    method BindingKeys (line 161) | func (c *commandDialogCmp) BindingKeys() []key.Binding {
    method SetCommands (line 165) | func (c *commandDialogCmp) SetCommands(commands []Command) {
  type commandKeyMap (line 70) | type commandKeyMap struct
  function NewCommandDialogCmp (line 170) | func NewCommandDialogCmp() CommandDialog {

FILE: internal/tui/components/dialog/complete.go
  type CompletionItem (line 16) | type CompletionItem struct
    method Render (line 28) | func (ci *CompletionItem) Render(selected bool, width int) string {
    method DisplayValue (line 50) | func (ci *CompletionItem) DisplayValue() string {
    method GetValue (line 54) | func (ci *CompletionItem) GetValue() string {
  type CompletionItemI (line 22) | type CompletionItemI interface
  function NewCompletionItem (line 58) | func NewCompletionItem(completionItem CompletionItem) CompletionItemI {
  type CompletionProvider (line 62) | type CompletionProvider interface
  type CompletionSelectedMsg (line 68) | type CompletionSelectedMsg struct
  type CompletionDialogCompleteItemMsg (line 73) | type CompletionDialogCompleteItemMsg struct
  type CompletionDialogCloseMsg (line 77) | type CompletionDialogCloseMsg struct
  type CompletionDialog (line 79) | type CompletionDialog interface
  type completionDialogCmp (line 85) | type completionDialogCmp struct
    method Init (line 108) | func (c *completionDialogCmp) Init() tea.Cmd {
    method complete (line 112) | func (c *completionDialogCmp) complete(item CompletionItemI) tea.Cmd {
    method close (line 128) | func (c *completionDialogCmp) close() tea.Cmd {
    method Update (line 136) | func (c *completionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 207) | func (c *completionDialogCmp) View() string {
    method SetWidth (line 235) | func (c *completionDialogCmp) SetWidth(width int) {
    method BindingKeys (line 239) | func (c *completionDialogCmp) BindingKeys() []key.Binding {
  type completionDialogKeyMap (line 94) | type completionDialogKeyMap struct
  function NewCompletionDialogCmp (line 243) | func NewCompletionDialogCmp(completionProvider CompletionProvider) Compl...

FILE: internal/tui/components/dialog/custom_commands.go
  constant UserCommandPrefix (line 17) | UserCommandPrefix    = "user:"
  constant ProjectCommandPrefix (line 18) | ProjectCommandPrefix = "project:"
  function LoadCustomCommands (line 25) | func LoadCustomCommands() ([]Command, error) {
  function loadCommandsFromDir (line 81) | func loadCommandsFromDir(commandsDir string, prefix string) ([]Command, ...
  type CommandRunCustomMsg (line 183) | type CommandRunCustomMsg struct

FILE: internal/tui/components/dialog/custom_commands_test.go
  function TestNamedArgPattern (line 8) | func TestNamedArgPattern(t *testing.T) {
  function TestRegexPattern (line 76) | func TestRegexPattern(t *testing.T) {

FILE: internal/tui/components/dialog/filepicker.go
  constant maxAttachmentSize (line 28) | maxAttachmentSize = int64(5 * 1024 * 1024)
  constant downArrow (line 29) | downArrow         = "down"
  constant upArrow (line 30) | upArrow           = "up"
  type FilePrickerKeyMap (line 33) | type FilePrickerKeyMap struct
  type filepickerCmp (line 79) | type filepickerCmp struct
    method Init (line 115) | func (f *filepickerCmp) Init() tea.Cmd {
    method Update (line 119) | func (f *filepickerCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method addAttachmentToMessage (line 224) | func (f *filepickerCmp) addAttachmentToMessage() (tea.Model, tea.Cmd) {
    method View (line 261) | func (f *filepickerCmp) View() string {
    method ToggleFilepicker (line 361) | func (f *filepickerCmp) ToggleFilepicker(showFilepicker bool) {
    method IsCWDFocused (line 365) | func (f *filepickerCmp) IsCWDFocused() bool {
    method getCurrentFileBelowCursor (line 386) | func (f *filepickerCmp) getCurrentFileBelowCursor() {
  type DirNode (line 95) | type DirNode struct
  type stack (line 100) | type stack
    method Push (line 102) | func (s stack) Push(v int) stack {
    method Pop (line 106) | func (s stack) Pop() (stack, int) {
  type AttachmentAddedMsg (line 111) | type AttachmentAddedMsg struct
  type FilepickerCmp (line 355) | type FilepickerCmp interface
  function NewFilepickerCmp (line 369) | func NewFilepickerCmp(app *app.App) FilepickerCmp {
  function readDir (line 413) | func readDir(path string, showHidden bool) []os.DirEntry {
  function IsHidden (line 464) | func IsHidden(file string) (bool, error) {
  function isExtSupported (line 468) | func isExtSupported(path string) bool {

FILE: internal/tui/components/dialog/help.go
  type helpCmp (line 13) | type helpCmp struct
    method Init (line 19) | func (h *helpCmp) Init() tea.Cmd {
    method SetBindings (line 23) | func (h *helpCmp) SetBindings(k []key.Binding) {
    method Update (line 27) | func (h *helpCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method render (line 56) | func (h *helpCmp) render() string {
    method View (line 168) | func (h *helpCmp) View() string {
  function removeDuplicateBindings (line 36) | func removeDuplicateBindings(bindings []key.Binding) []key.Binding {
  type HelpCmp (line 193) | type HelpCmp interface
  function NewHelpCmp (line 198) | func NewHelpCmp() HelpCmp {

FILE: internal/tui/components/dialog/init.go
  type InitDialogCmp (line 14) | type InitDialogCmp struct
    method Init (line 66) | func (m InitDialogCmp) Init() tea.Cmd {
    method Update (line 71) | func (m InitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 95) | func (m InitDialogCmp) View() string {
    method SetSize (line 171) | func (m *InitDialogCmp) SetSize(width, height int) {
    method Bindings (line 177) | func (m InitDialogCmp) Bindings() []key.Binding {
  function NewInitDialogCmp (line 21) | func NewInitDialogCmp() InitDialogCmp {
  type initDialogKeyMap (line 28) | type initDialogKeyMap struct
    method ShortHelp (line 39) | func (k initDialogKeyMap) ShortHelp() []key.Binding {
    method FullHelp (line 61) | func (k initDialogKeyMap) FullHelp() [][]key.Binding {
  type CloseInitDialogMsg (line 182) | type CloseInitDialogMsg struct
  type ShowInitDialogMsg (line 187) | type ShowInitDialogMsg struct

FILE: internal/tui/components/dialog/models.go
  constant numVisibleModels (line 20) | numVisibleModels = 10
  constant maxDialogWidth (line 21) | maxDialogWidth   = 40
  type ModelSelectedMsg (line 25) | type ModelSelectedMsg struct
  type CloseModelDialogMsg (line 30) | type CloseModelDialogMsg struct
  type ModelDialog (line 33) | type ModelDialog interface
  type modelDialogCmp (line 38) | type modelDialogCmp struct
    method Init (line 107) | func (m *modelDialogCmp) Init() tea.Cmd {
    method Update (line 112) | func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method moveSelectionUp (line 143) | func (m *modelDialogCmp) moveSelectionUp() {
    method moveSelectionDown (line 158) | func (m *modelDialogCmp) moveSelectionDown() {
    method switchProvider (line 172) | func (m *modelDialogCmp) switchProvider(offset int) {
    method View (line 188) | func (m *modelDialogCmp) View() string {
    method getScrollIndicators (line 231) | func (m *modelDialogCmp) getScrollIndicators(maxWidth int) string {
    method BindingKeys (line 267) | func (m *modelDialogCmp) BindingKeys() []key.Binding {
    method setupModels (line 271) | func (m *modelDialogCmp) setupModels() {
    method setupModelsForProvider (line 325) | func (m *modelDialogCmp) setupModelsForProvider(provider models.ModelP...
  type modelKeyMap (line 51) | type modelKeyMap struct
  function GetSelectedModel (line 283) | func GetSelectedModel(cfg *config.Config) models.Model {
  function getEnabledProviders (line 290) | func getEnabledProviders(cfg *config.Config) []models.ModelProvider {
  function findProviderIndex (line 316) | func findProviderIndex(providers []models.ModelProvider, provider models...
  function getModelsForProvider (line 350) | func getModelsForProvider(provider models.ModelProvider) []models.Model {
  function NewModelDialogCmp (line 371) | func NewModelDialogCmp() ModelDialog {

FILE: internal/tui/components/dialog/permission.go
  type PermissionAction (line 20) | type PermissionAction
  constant PermissionAllow (line 24) | PermissionAllow           PermissionAction = "allow"
  constant PermissionAllowForSession (line 25) | PermissionAllowForSession PermissionAction = "allow_session"
  constant PermissionDeny (line 26) | PermissionDeny            PermissionAction = "deny"
  type PermissionResponseMsg (line 30) | type PermissionResponseMsg struct
  type PermissionDialogCmp (line 36) | type PermissionDialogCmp interface
  type permissionsMapping (line 42) | type permissionsMapping struct
  type permissionDialogCmp (line 84) | type permissionDialogCmp struct
    method Init (line 96) | func (p *permissionDialogCmp) Init() tea.Cmd {
    method Update (line 100) | func (p *permissionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method selectCurrentOption (line 136) | func (p *permissionDialogCmp) selectCurrentOption() tea.Cmd {
    method renderButtons (line 151) | func (p *permissionDialogCmp) renderButtons() string {
    method renderHeader (line 197) | func (p *permissionDialogCmp) renderHeader() string {
    method renderBashContent (line 270) | func (p *permissionDialogCmp) renderBashContent() string {
    method renderEditContent (line 293) | func (p *permissionDialogCmp) renderEditContent() string {
    method renderPatchContent (line 305) | func (p *permissionDialogCmp) renderPatchContent() string {
    method renderWriteContent (line 317) | func (p *permissionDialogCmp) renderWriteContent() string {
    method renderFetchContent (line 330) | func (p *permissionDialogCmp) renderFetchContent() string {
    method renderDefaultContent (line 353) | func (p *permissionDialogCmp) renderDefaultContent() string {
    method styleViewport (line 378) | func (p *permissionDialogCmp) styleViewport() string {
    method render (line 386) | func (p *permissionDialogCmp) render() string {
    method View (line 443) | func (p *permissionDialogCmp) View() string {
    method BindingKeys (line 447) | func (p *permissionDialogCmp) BindingKeys() []key.Binding {
    method SetSize (line 451) | func (p *permissionDialogCmp) SetSize() tea.Cmd {
    method SetPermissions (line 475) | func (p *permissionDialogCmp) SetPermissions(permission permission.Per...
    method GetOrSetDiff (line 481) | func (c *permissionDialogCmp) GetOrSetDiff(key string, generator func(...
    method GetOrSetMarkdown (line 497) | func (c *permissionDialogCmp) GetOrSetMarkdown(key string, generator f...
  function NewPermissionDialogCmp (line 512) | func NewPermissionDialogCmp() PermissionDialogCmp {

FILE: internal/tui/components/dialog/quit.go
  constant question (line 15) | question = "Are you sure you want to quit?"
  type CloseQuitMsg (line 17) | type CloseQuitMsg struct
  type QuitDialog (line 19) | type QuitDialog interface
  type quitDialogCmp (line 24) | type quitDialogCmp struct
    method Init (line 59) | func (q *quitDialogCmp) Init() tea.Cmd {
    method Update (line 63) | func (q *quitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 84) | func (q *quitDialogCmp) View() string {
    method BindingKeys (line 128) | func (q *quitDialogCmp) BindingKeys() []key.Binding {
  type helpMapping (line 28) | type helpMapping struct
  function NewQuitCmp (line 132) | func NewQuitCmp() QuitDialog {

FILE: internal/tui/components/dialog/session.go
  type SessionSelectedMsg (line 15) | type SessionSelectedMsg struct
  type CloseSessionDialogMsg (line 20) | type CloseSessionDialogMsg struct
  type SessionDialog (line 23) | type SessionDialog interface
  type sessionDialogCmp (line 30) | type sessionDialogCmp struct
    method Init (line 74) | func (s *sessionDialogCmp) Init() tea.Cmd {
    method Update (line 78) | func (s *sessionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 108) | func (s *sessionDialogCmp) View() string {
    method BindingKeys (line 188) | func (s *sessionDialogCmp) BindingKeys() []key.Binding {
    method SetSessions (line 192) | func (s *sessionDialogCmp) SetSessions(sessions []session.Session) {
    method SetSelectedSession (line 209) | func (s *sessionDialogCmp) SetSelectedSession(sessionID string) {
  type sessionKeyMap (line 38) | type sessionKeyMap struct
  function NewSessionDialogCmp (line 224) | func NewSessionDialogCmp() SessionDialog {

FILE: internal/tui/components/dialog/theme.go
  type ThemeChangedMsg (line 14) | type ThemeChangedMsg struct
  type CloseThemeDialogMsg (line 19) | type CloseThemeDialogMsg struct
  type ThemeDialog (line 22) | type ThemeDialog interface
  type themeDialogCmp (line 27) | type themeDialogCmp struct
    method Init (line 71) | func (t *themeDialogCmp) Init() tea.Cmd {
    method Update (line 87) | func (t *themeDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 125) | func (t *themeDialogCmp) View() string {
    method BindingKeys (line 186) | func (t *themeDialogCmp) BindingKeys() []key.Binding {
  type themeKeyMap (line 35) | type themeKeyMap struct
  function NewThemeDialogCmp (line 191) | func NewThemeDialogCmp() ThemeDialog {

FILE: internal/tui/components/logs/details.go
  type DetailComponent (line 18) | type DetailComponent interface
  type detailCmp (line 24) | type detailCmp struct
    method Init (line 30) | func (i *detailCmp) Init() tea.Cmd {
    method Update (line 39) | func (i *detailCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method updateContent (line 51) | func (i *detailCmp) updateContent() {
    method View (line 117) | func (i *detailCmp) View() string {
    method GetSize (line 122) | func (i *detailCmp) GetSize() (int, int) {
    method SetSize (line 126) | func (i *detailCmp) SetSize(width int, height int) tea.Cmd {
    method BindingKeys (line 135) | func (i *detailCmp) BindingKeys() []key.Binding {
  function getLevelStyle (line 99) | func getLevelStyle(level string) lipgloss.Style {
  function NewLogsDetails (line 139) | func NewLogsDetails() DetailComponent {

FILE: internal/tui/components/logs/table.go
  type TableComponent (line 18) | type TableComponent interface
  type tableCmp (line 24) | type tableCmp struct
    method Init (line 30) | func (i *tableCmp) Init() tea.Cmd {
    method Update (line 35) | func (i *tableCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 64) | func (i *tableCmp) View() string {
    method GetSize (line 72) | func (i *tableCmp) GetSize() (int, int) {
    method SetSize (line 76) | func (i *tableCmp) SetSize(width int, height int) tea.Cmd {
    method BindingKeys (line 88) | func (i *tableCmp) BindingKeys() []key.Binding {
    method setRows (line 92) | func (i *tableCmp) setRows() {
  type selectedLogMsg (line 28) | type selectedLogMsg
  function NewLogsTable (line 121) | func NewLogsTable() TableComponent {

FILE: internal/tui/components/util/simple-list.go
  type SimpleListItem (line 12) | type SimpleListItem interface
  type SimpleList (line 16) | type SimpleList interface
  type simpleListCmp (line 25) | type simpleListCmp struct
  type simpleListKeyMap (line 36) | type simpleListKeyMap struct
  method Init (line 62) | func (c *simpleListCmp[T]) Init() tea.Cmd {
  method Update (line 66) | func (c *simpleListCmp[T]) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
  method BindingKeys (line 86) | func (c *simpleListCmp[T]) BindingKeys() []key.Binding {
  method GetSelectedItem (line 90) | func (c *simpleListCmp[T]) GetSelectedItem() (T, int) {
  method SetItems (line 99) | func (c *simpleListCmp[T]) SetItems(items []T) {
  method GetItems (line 104) | func (c *simpleListCmp[T]) GetItems() []T {
  method SetMaxWidth (line 108) | func (c *simpleListCmp[T]) SetMaxWidth(width int) {
  method View (line 112) | func (c *simpleListCmp[T]) View() string {
  function NewSimpleList (line 151) | func NewSimpleList[T SimpleListItem](items []T, maxVisibleItems int, fal...

FILE: internal/tui/image/images.go
  function ValidateFileSize (line 14) | func ValidateFileSize(filePath string, sizeLimit int64) (bool, error) {
  function ToString (line 27) | func ToString(width int, img image.Image) string {
  function ImagePreview (line 57) | func ImagePreview(width int, filename string) (string, error) {

FILE: internal/tui/layout/container.go
  type Container (line 10) | type Container interface
  type container (line 15) | type container struct
    method Init (line 34) | func (c *container) Init() tea.Cmd {
    method Update (line 38) | func (c *container) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 44) | func (c *container) View() string {
    method SetSize (line 81) | func (c *container) SetSize(width, height int) tea
Condensed preview — 162 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,496K chars).
[
  {
    "path": ".github/workflows/build.yml",
    "chars": 681,
    "preview": "name: build\n\non:\n  workflow_dispatch:\n  push:\n    branches:\n      - main\n\nconcurrency: ${{ github.workflow }}-${{ github"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 790,
    "preview": "name: release\n\non:\n  workflow_dispatch:\n  push:\n    tags:\n      - \"*\"\n\nconcurrency: ${{ github.workflow }}-${{ github.re"
  },
  {
    "path": ".gitignore",
    "chars": 568,
    "preview": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, built with `go test -c`\n*.test\n\n# Ou"
  },
  {
    "path": ".goreleaser.yml",
    "chars": 1790,
    "preview": "version: 2\nproject_name: opencode\nbefore:\n  hooks:\nbuilds:\n  - env:\n      - CGO_ENABLED=0\n    goos:\n      - linux\n      "
  },
  {
    "path": ".opencode.json",
    "chars": 104,
    "preview": "{\n  \"$schema\": \"./opencode-schema.json\",\n  \"lsp\": {\n    \"gopls\": {\n      \"command\": \"gopls\"\n    }\n  }\n}\n"
  },
  {
    "path": "LICENSE",
    "chars": 1069,
    "preview": "MIT License\n\nCopyright (c) 2025 Kujtim Hoxha\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
  },
  {
    "path": "README.md",
    "chars": 24434,
    "preview": "# Archived: Project has Moved\n\nThis repository is no longer maintained and has been archived for provenance.\n\nThe projec"
  },
  {
    "path": "cmd/root.go",
    "chars": 8355,
    "preview": "package cmd\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\tzone \"github.c"
  },
  {
    "path": "cmd/schema/README.md",
    "chars": 1698,
    "preview": "# OpenCode Configuration Schema Generator\n\nThis tool generates a JSON Schema for the OpenCode configuration file. The sc"
  },
  {
    "path": "cmd/schema/main.go",
    "chars": 8805,
    "preview": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/opencode-ai/opencode/internal/config\"\n\t\"github.com/op"
  },
  {
    "path": "go.mod",
    "chars": 6179,
    "preview": "module github.com/opencode-ai/opencode\n\ngo 1.24.0\n\nrequire (\n\tgithub.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0\n\tg"
  },
  {
    "path": "go.sum",
    "chars": 33104,
    "preview": "cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE=\ncloud.google.com/go v0.116.0/go.mod h1:cEPS"
  },
  {
    "path": "install",
    "chars": 4927,
    "preview": "#!/usr/bin/env bash\nset -euo pipefail\nAPP=opencode\n\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nORANGE='\\033"
  },
  {
    "path": "internal/app/app.go",
    "chars": 4966,
    "preview": "package app\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"errors\"\n\t\"fmt\"\n\t\"maps\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/opencode-ai/open"
  },
  {
    "path": "internal/app/lsp.go",
    "chars": 4370,
    "preview": "package app\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/opencode-ai/opencode/internal/config\"\n\t\"github.com/opencode-ai/op"
  },
  {
    "path": "internal/completions/files-folders.go",
    "chars": 4798,
    "preview": "package completions\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\n\t\"github.com/lithammer/fuzzysearch/fuzzy\"\n\t\"g"
  },
  {
    "path": "internal/config/config.go",
    "chars": 29005,
    "preview": "// Package config manages application configuration from various sources.\npackage config\n\nimport (\n\t\"encoding/json\"\n\t\"fm"
  },
  {
    "path": "internal/config/init.go",
    "chars": 1516,
    "preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n)\n\nconst (\n\t// InitFlagFilename is the name of the file that indi"
  },
  {
    "path": "internal/db/connect.go",
    "chars": 1714,
    "preview": "package db\n\nimport (\n\t\"database/sql\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t_ \"github.com/ncruces/go-sqlite3/driver\"\n\t_ \"github"
  },
  {
    "path": "internal/db/db.go",
    "chars": 10780,
    "preview": "// Code generated by sqlc. DO NOT EDIT.\n// versions:\n//   sqlc v1.29.0\n\npackage db\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n"
  },
  {
    "path": "internal/db/embed.go",
    "chars": 72,
    "preview": "package db\n\nimport \"embed\"\n\n//go:embed migrations/*.sql\nvar FS embed.FS\n"
  },
  {
    "path": "internal/db/files.sql.go",
    "chars": 6663,
    "preview": "// Code generated by sqlc. DO NOT EDIT.\n// versions:\n//   sqlc v1.29.0\n// source: files.sql\n\npackage db\n\nimport (\n\t\"cont"
  },
  {
    "path": "internal/db/messages.sql.go",
    "chars": 3487,
    "preview": "// Code generated by sqlc. DO NOT EDIT.\n// versions:\n//   sqlc v1.29.0\n// source: messages.sql\n\npackage db\n\nimport (\n\t\"c"
  },
  {
    "path": "internal/db/migrations/20250424200609_initial.sql",
    "chars": 3009,
    "preview": "-- +goose Up\n-- +goose StatementBegin\n-- Sessions\nCREATE TABLE IF NOT EXISTS sessions (\n    id TEXT PRIMARY KEY,\n    par"
  },
  {
    "path": "internal/db/migrations/20250515105448_add_summary_message_id.sql",
    "chars": 235,
    "preview": "-- +goose Up\n-- +goose StatementBegin\nALTER TABLE sessions ADD COLUMN summary_message_id TEXT;\n-- +goose StatementEnd\n\n-"
  },
  {
    "path": "internal/db/models.go",
    "chars": 1321,
    "preview": "// Code generated by sqlc. DO NOT EDIT.\n// versions:\n//   sqlc v1.29.0\n\npackage db\n\nimport (\n\t\"database/sql\"\n)\n\ntype Fil"
  },
  {
    "path": "internal/db/querier.go",
    "chars": 1578,
    "preview": "// Code generated by sqlc. DO NOT EDIT.\n// versions:\n//   sqlc v1.29.0\n\npackage db\n\nimport (\n\t\"context\"\n)\n\ntype Querier "
  },
  {
    "path": "internal/db/sessions.sql.go",
    "chars": 4500,
    "preview": "// Code generated by sqlc. DO NOT EDIT.\n// versions:\n//   sqlc v1.29.0\n// source: sessions.sql\n\npackage db\n\nimport (\n\t\"c"
  },
  {
    "path": "internal/db/sql/files.sql",
    "chars": 1254,
    "preview": "-- name: GetFile :one\nSELECT *\nFROM files\nWHERE id = ? LIMIT 1;\n\n-- name: GetFileByPathAndSession :one\nSELECT *\nFROM fil"
  },
  {
    "path": "internal/db/sql/messages.sql",
    "chars": 692,
    "preview": "-- name: GetMessage :one\nSELECT *\nFROM messages\nWHERE id = ? LIMIT 1;\n\n-- name: ListMessagesBySession :many\nSELECT *\nFRO"
  },
  {
    "path": "internal/db/sql/sessions.sql",
    "chars": 789,
    "preview": "-- name: CreateSession :one\nINSERT INTO sessions (\n    id,\n    parent_session_id,\n    title,\n    message_count,\n    prom"
  },
  {
    "path": "internal/diff/diff.go",
    "chars": 26047,
    "preview": "package diff\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/alecthomas/chroma/v2\"\n\t\"githu"
  },
  {
    "path": "internal/diff/patch.go",
    "chars": 17912,
    "preview": "package diff\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\ntype ActionType string\n\nconst (\n\tActionAdd "
  },
  {
    "path": "internal/fileutil/fileutil.go",
    "chars": 3516,
    "preview": "package fileutil\n\nimport (\n\t\"fmt\"\n\t\"io/fs\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/bm"
  },
  {
    "path": "internal/format/format.go",
    "chars": 2429,
    "preview": "package format\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n)\n\n// OutputFormat represents the output format type for non"
  },
  {
    "path": "internal/format/spinner.go",
    "chars": 1979,
    "preview": "package format\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/charmbracelet/bubbles/spinner\"\n\ttea \"github.com/charmbrac"
  },
  {
    "path": "internal/history/file.go",
    "chars": 6546,
    "preview": "package history\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"g"
  },
  {
    "path": "internal/llm/agent/agent-tool.go",
    "chars": 4737,
    "preview": "package agent\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/opencode-ai/opencode/internal/config\"\n\t\"github."
  },
  {
    "path": "internal/llm/agent/agent.go",
    "chars": 22638,
    "preview": "package agent\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/opencode-ai/opencode/intern"
  },
  {
    "path": "internal/llm/agent/mcp-tools.go",
    "chars": 5554,
    "preview": "package agent\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/opencode-ai/opencode/internal/config\"\n\t\"github."
  },
  {
    "path": "internal/llm/agent/tools.go",
    "chars": 1441,
    "preview": "package agent\n\nimport (\n\t\"context\"\n\n\t\"github.com/opencode-ai/opencode/internal/history\"\n\t\"github.com/opencode-ai/opencod"
  },
  {
    "path": "internal/llm/models/anthropic.go",
    "chars": 3378,
    "preview": "package models\n\nconst (\n\tProviderAnthropic ModelProvider = \"anthropic\"\n\n\t// Models\n\tClaude35Sonnet ModelID = \"claude-3.5"
  },
  {
    "path": "internal/llm/models/azure.go",
    "chars": 7206,
    "preview": "package models\n\nconst ProviderAzure ModelProvider = \"azure\"\n\nconst (\n\tAzureGPT41        ModelID = \"azure.gpt-4.1\"\n\tAzure"
  },
  {
    "path": "internal/llm/models/copilot.go",
    "chars": 7426,
    "preview": "package models\n\nconst (\n\tProviderCopilot ModelProvider = \"copilot\"\n\n\t// GitHub Copilot models\n\tCopilotGTP35Turbo      Mo"
  },
  {
    "path": "internal/llm/models/gemini.go",
    "chars": 1884,
    "preview": "package models\n\nconst (\n\tProviderGemini ModelProvider = \"gemini\"\n\n\t// Models\n\tGemini25Flash     ModelID = \"gemini-2.5-fl"
  },
  {
    "path": "internal/llm/models/groq.go",
    "chars": 2526,
    "preview": "package models\n\nconst (\n\tProviderGROQ ModelProvider = \"groq\"\n\n\t// GROQ\n\tQWENQwq ModelID = \"qwen-qwq\"\n\n\t// GROQ preview m"
  },
  {
    "path": "internal/llm/models/local.go",
    "chars": 4724,
    "preview": "package models\n\nimport (\n\t\"cmp\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"regexp\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github."
  },
  {
    "path": "internal/llm/models/models.go",
    "chars": 2780,
    "preview": "package models\n\nimport \"maps\"\n\ntype (\n\tModelID       string\n\tModelProvider string\n)\n\ntype Model struct {\n\tID            "
  },
  {
    "path": "internal/llm/models/openai.go",
    "chars": 4991,
    "preview": "package models\n\nconst (\n\tProviderOpenAI ModelProvider = \"openai\"\n\n\tGPT41        ModelID = \"gpt-4.1\"\n\tGPT41Mini    ModelI"
  },
  {
    "path": "internal/llm/models/openrouter.go",
    "chars": 13153,
    "preview": "package models\n\nconst (\n\tProviderOpenRouter ModelProvider = \"openrouter\"\n\n\tOpenRouterGPT41          ModelID = \"openroute"
  },
  {
    "path": "internal/llm/models/vertexai.go",
    "chars": 1526,
    "preview": "package models\n\nconst (\n\tProviderVertexAI ModelProvider = \"vertexai\"\n\n\t// Models\n\tVertexAIGemini25Flash ModelID = \"verte"
  },
  {
    "path": "internal/llm/models/xai.go",
    "chars": 1692,
    "preview": "package models\n\nconst (\n\tProviderXAI ModelProvider = \"xai\"\n\n\tXAIGrok3Beta         ModelID = \"grok-3-beta\"\n\tXAIGrok3MiniB"
  },
  {
    "path": "internal/llm/prompt/coder.go",
    "chars": 14449,
    "preview": "package prompt\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"time\"\n\n\t\"github.com/opencode-ai/opencode/"
  },
  {
    "path": "internal/llm/prompt/prompt.go",
    "chars": 3230,
    "preview": "package prompt\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/opencode-ai/opencode/internal/co"
  },
  {
    "path": "internal/llm/prompt/prompt_test.go",
    "chars": 1513,
    "preview": "package prompt\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/opencode-ai/opencode/internal/config\"\n\t\""
  },
  {
    "path": "internal/llm/prompt/summarizer.go",
    "chars": 612,
    "preview": "package prompt\n\nimport \"github.com/opencode-ai/opencode/internal/llm/models\"\n\nfunc SummarizerPrompt(_ models.ModelProvid"
  },
  {
    "path": "internal/llm/prompt/task.go",
    "chars": 1043,
    "preview": "package prompt\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/opencode-ai/opencode/internal/llm/models\"\n)\n\nfunc TaskPrompt(_ models.Mode"
  },
  {
    "path": "internal/llm/prompt/title.go",
    "chars": 520,
    "preview": "package prompt\n\nimport \"github.com/opencode-ai/opencode/internal/llm/models\"\n\nfunc TitlePrompt(_ models.ModelProvider) s"
  },
  {
    "path": "internal/llm/provider/anthropic.go",
    "chars": 13942,
    "preview": "package provider\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/anthropic"
  },
  {
    "path": "internal/llm/provider/azure.go",
    "chars": 1201,
    "preview": "package provider\n\nimport (\n\t\"os\"\n\n\t\"github.com/Azure/azure-sdk-for-go/sdk/azidentity\"\n\t\"github.com/openai/openai-go\"\n\t\"g"
  },
  {
    "path": "internal/llm/provider/bedrock.go",
    "chars": 2609,
    "preview": "package provider\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/opencode-ai/opencode/internal/llm/"
  },
  {
    "path": "internal/llm/provider/copilot.go",
    "chars": 20250,
    "preview": "package provider\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/op"
  },
  {
    "path": "internal/llm/provider/gemini.go",
    "chars": 14365,
    "preview": "package provider\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/uu"
  },
  {
    "path": "internal/llm/provider/openai.go",
    "chars": 12132,
    "preview": "package provider\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/openai/openai-go\"\n\t\""
  },
  {
    "path": "internal/llm/provider/provider.go",
    "chars": 6998,
    "preview": "package provider\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/opencode-ai/opencode/internal/llm/models\"\n\t\"github.com/"
  },
  {
    "path": "internal/llm/provider/vertexai.go",
    "chars": 735,
    "preview": "package provider\n\nimport (\n\t\"context\"\n\t\"os\"\n\n\t\"github.com/opencode-ai/opencode/internal/logging\"\n\t\"google.golang.org/gen"
  },
  {
    "path": "internal/llm/tools/bash.go",
    "chars": 14563,
    "preview": "package tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/opencode-ai/opencode/interna"
  },
  {
    "path": "internal/llm/tools/diagnostics.go",
    "chars": 7921,
    "preview": "package tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"maps\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/opencode-ai/"
  },
  {
    "path": "internal/llm/tools/edit.go",
    "chars": 15526,
    "preview": "package tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/openc"
  },
  {
    "path": "internal/llm/tools/fetch.go",
    "chars": 6182,
    "preview": "package tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\tmd \"github.com/Johanne"
  },
  {
    "path": "internal/llm/tools/file.go",
    "chars": 960,
    "preview": "package tools\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\n// File record to track when files were read/written\ntype fileRecord struct {"
  },
  {
    "path": "internal/llm/tools/glob.go",
    "chars": 4967,
    "preview": "package tools\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"gi"
  },
  {
    "path": "internal/llm/tools/grep.go",
    "chars": 9421,
    "preview": "package tools\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"sort\"\n"
  },
  {
    "path": "internal/llm/tools/ls.go",
    "chars": 7317,
    "preview": "package tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/opencode-ai/o"
  },
  {
    "path": "internal/llm/tools/ls_test.go",
    "chars": 11358,
    "preview": "package tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/"
  },
  {
    "path": "internal/llm/tools/patch.go",
    "chars": 10869,
    "preview": "package tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"time\"\n\n\t\"github.com/opencode-ai/open"
  },
  {
    "path": "internal/llm/tools/shell/shell.go",
    "chars": 6597,
    "preview": "package shell\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n\t\"ti"
  },
  {
    "path": "internal/llm/tools/sourcegraph.go",
    "chars": 11952,
    "preview": "package tools\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype Sourceg"
  },
  {
    "path": "internal/llm/tools/tools.go",
    "chars": 1769,
    "preview": "package tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n)\n\ntype ToolInfo struct {\n\tName        string\n\tDescription string\n\tP"
  },
  {
    "path": "internal/llm/tools/view.go",
    "chars": 8071,
    "preview": "package tools\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.co"
  },
  {
    "path": "internal/llm/tools/write.go",
    "chars": 6759,
    "preview": "package tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/openc"
  },
  {
    "path": "internal/logging/logger.go",
    "chars": 5902,
    "preview": "package logging\n\nimport (\n\t\"fmt\"\n\t\"log/slog\"\n\t\"os\"\n\t// \"path/filepath\"\n\t\"encoding/json\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"sy"
  },
  {
    "path": "internal/logging/message.go",
    "chars": 460,
    "preview": "package logging\n\nimport (\n\t\"time\"\n)\n\n// LogMessage is the event payload for a log message\ntype LogMessage struct {\n\tID  "
  },
  {
    "path": "internal/logging/writer.go",
    "chars": 2014,
    "preview": "package logging\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/go-logfmt/logfmt\"\n\t\"github"
  },
  {
    "path": "internal/lsp/client.go",
    "chars": 22089,
    "preview": "package lsp\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"s"
  },
  {
    "path": "internal/lsp/handlers.go",
    "chars": 3262,
    "preview": "package lsp\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/opencode-ai/opencode/internal/config\"\n\t\"github.com/opencode-ai/open"
  },
  {
    "path": "internal/lsp/language.go",
    "chars": 3037,
    "preview": "package lsp\n\nimport (\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/opencode-ai/opencode/internal/lsp/protocol\"\n)\n\nfunc Dete"
  },
  {
    "path": "internal/lsp/methods.go",
    "chars": 34665,
    "preview": "// Generated code. Do not edit\npackage lsp\n\nimport (\n\t\"context\"\n\n\t\"github.com/opencode-ai/opencode/internal/lsp/protocol"
  },
  {
    "path": "internal/lsp/protocol/LICENSE",
    "chars": 1453,
    "preview": "Copyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are per"
  },
  {
    "path": "internal/lsp/protocol/interface.go",
    "chars": 3339,
    "preview": "package protocol\n\nimport \"fmt\"\n\n// TextEditResult is an interface for types that represent workspace symbols\ntype Worksp"
  },
  {
    "path": "internal/lsp/protocol/pattern_interfaces.go",
    "chars": 1634,
    "preview": "package protocol\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// PatternInfo is an interface for types that represent glob patterns\nty"
  },
  {
    "path": "internal/lsp/protocol/tables.go",
    "chars": 759,
    "preview": "package protocol\n\nvar TableKindMap = map[SymbolKind]string{\n\tFile:          \"File\",\n\tModule:        \"Module\",\n\tNamespace"
  },
  {
    "path": "internal/lsp/protocol/tsdocument-changes.go",
    "chars": 2116,
    "preview": "// Copyright 2022 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "internal/lsp/protocol/tsjson.go",
    "chars": 88686,
    "preview": "// Copyright 2023 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "internal/lsp/protocol/tsprotocol.go",
    "chars": 278638,
    "preview": "// Copyright 2023 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "internal/lsp/protocol/uri.go",
    "chars": 7001,
    "preview": "// Copyright 2023 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "internal/lsp/protocol.go",
    "chars": 1040,
    "preview": "package lsp\n\nimport (\n\t\"encoding/json\"\n)\n\n// Message represents a JSON-RPC 2.0 message\ntype Message struct {\n\tJSONRPC st"
  },
  {
    "path": "internal/lsp/transport.go",
    "chars": 6400,
    "preview": "package lsp\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/opencode-ai/opencode/in"
  },
  {
    "path": "internal/lsp/util/edit.go",
    "chars": 6873,
    "preview": "package util\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/opencode-ai/opencode/internal/lsp/protocol"
  },
  {
    "path": "internal/lsp/watcher/watcher.go",
    "chars": 28504,
    "preview": "package watcher\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/bmatcuk/doub"
  },
  {
    "path": "internal/message/attachment.go",
    "chars": 112,
    "preview": "package message\n\ntype Attachment struct {\n\tFilePath string\n\tFileName string\n\tMimeType string\n\tContent  []byte\n}\n"
  },
  {
    "path": "internal/message/content.go",
    "chars": 6927,
    "preview": "package message\n\nimport (\n\t\"encoding/base64\"\n\t\"slices\"\n\t\"time\"\n\n\t\"github.com/opencode-ai/opencode/internal/llm/models\"\n)"
  },
  {
    "path": "internal/message/message.go",
    "chars": 6572,
    "preview": "package message\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github"
  },
  {
    "path": "internal/permission/permission.go",
    "chars": 3085,
    "preview": "package permission\n\nimport (\n\t\"errors\"\n\t\"path/filepath\"\n\t\"slices\"\n\t\"sync\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/openco"
  },
  {
    "path": "internal/pubsub/broker.go",
    "chars": 1759,
    "preview": "package pubsub\n\nimport (\n\t\"context\"\n\t\"sync\"\n)\n\nconst bufferSize = 64\n\ntype Broker[T any] struct {\n\tsubs      map[chan Ev"
  },
  {
    "path": "internal/pubsub/events.go",
    "chars": 482,
    "preview": "package pubsub\n\nimport \"context\"\n\nconst (\n\tCreatedEvent EventType = \"created\"\n\tUpdatedEvent EventType = \"updated\"\n\tDelet"
  },
  {
    "path": "internal/session/session.go",
    "chars": 4234,
    "preview": "package session\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/opencode-ai/opencode/intern"
  },
  {
    "path": "internal/tui/components/chat/chat.go",
    "chars": 2712,
    "preview": "package chat\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/charmbracelet/x/ansi\"\n\t\"github."
  },
  {
    "path": "internal/tui/components/chat/editor.go",
    "chars": 8531,
    "preview": "package chat\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"slices\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/charmbracelet/bubbles/key\"\n"
  },
  {
    "path": "internal/tui/components/chat/list.go",
    "chars": 11497,
    "preview": "package chat\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"math\"\n\n\t\"github.com/charmbracelet/bubbles/key\"\n\t\"github.com/charmbracelet/bub"
  },
  {
    "path": "internal/tui/components/chat/message.go",
    "chars": 18772,
    "preview": "package chat\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/charmbracele"
  },
  {
    "path": "internal/tui/components/chat/sidebar.go",
    "chars": 9315,
    "preview": "package chat\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/char"
  },
  {
    "path": "internal/tui/components/core/status.go",
    "chars": 8151,
    "preview": "package core\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/charmbracelet/l"
  },
  {
    "path": "internal/tui/components/dialog/arguments.go",
    "chars": 7211,
    "preview": "package dialog\n\nimport (\n\t\"fmt\"\n\t\"github.com/charmbracelet/bubbles/key\"\n\t\"github.com/charmbracelet/bubbles/textinput\"\n\tt"
  },
  {
    "path": "internal/tui/components/dialog/commands.go",
    "chars": 4243,
    "preview": "package dialog\n\nimport (\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/"
  },
  {
    "path": "internal/tui/components/dialog/complete.go",
    "chars": 5839,
    "preview": "package dialog\n\nimport (\n\t\"github.com/charmbracelet/bubbles/key\"\n\t\"github.com/charmbracelet/bubbles/textarea\"\n\ttea \"gith"
  },
  {
    "path": "internal/tui/components/dialog/custom_commands.go",
    "chars": 5541,
    "preview": "package dialog\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t"
  },
  {
    "path": "internal/tui/components/dialog/custom_commands_test.go",
    "chars": 2305,
    "preview": "package dialog\n\nimport (\n\t\"testing\"\n\t\"regexp\"\n)\n\nfunc TestNamedArgPattern(t *testing.T) {\n\ttestCases := []struct {\n\t\tinp"
  },
  {
    "path": "internal/tui/components/dialog/filepicker.go",
    "chars": 12617,
    "preview": "package dialog\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/charmbracele"
  },
  {
    "path": "internal/tui/components/dialog/help.go",
    "chars": 4716,
    "preview": "package dialog\n\nimport (\n\t\"strings\"\n\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t"
  },
  {
    "path": "internal/tui/components/dialog/init.go",
    "chars": 4865,
    "preview": "package dialog\n\nimport (\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/"
  },
  {
    "path": "internal/tui/components/dialog/models.go",
    "chars": 9116,
    "preview": "package dialog\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbrac"
  },
  {
    "path": "internal/tui/components/dialog/permission.go",
    "chars": 15207,
    "preview": "package dialog\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/bubbles/key\"\n\t\"github.com/charmbracelet/bubbles/v"
  },
  {
    "path": "internal/tui/components/dialog/quit.go",
    "chars": 3228,
    "preview": "package dialog\n\nimport (\n\t\"strings\"\n\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t"
  },
  {
    "path": "internal/tui/components/dialog/session.go",
    "chars": 5803,
    "preview": "package dialog\n\nimport (\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/"
  },
  {
    "path": "internal/tui/components/dialog/theme.go",
    "chars": 4843,
    "preview": "package dialog\n\nimport (\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/"
  },
  {
    "path": "internal/tui/components/logs/details.go",
    "chars": 3571,
    "preview": "package logs\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/charmbracelet/bubbles/key\"\n\t\"github.com/charmbracelet/bub"
  },
  {
    "path": "internal/tui/components/logs/table.go",
    "chars": 3005,
    "preview": "package logs\n\nimport (\n\t\"encoding/json\"\n\t\"slices\"\n\n\t\"github.com/charmbracelet/bubbles/key\"\n\t\"github.com/charmbracelet/bu"
  },
  {
    "path": "internal/tui/components/util/simple-list.go",
    "chars": 3760,
    "preview": "package utilComponents\n\nimport (\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"git"
  },
  {
    "path": "internal/tui/image/images.go",
    "chars": 1484,
    "preview": "package image\n\nimport (\n\t\"fmt\"\n\t\"image\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/disintegrati"
  },
  {
    "path": "internal/tui/layout/container.go",
    "chars": 4409,
    "preview": "package layout\n\nimport (\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/"
  },
  {
    "path": "internal/tui/layout/layout.go",
    "chars": 618,
    "preview": "package layout\n\nimport (\n\t\"reflect\"\n\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n)"
  },
  {
    "path": "internal/tui/layout/overlay.go",
    "chars": 3816,
    "preview": "package layout\n\nimport (\n\t\"strings\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\tchAnsi \"github.com/charmbracelet/x/ansi\"\n\t\"gi"
  },
  {
    "path": "internal/tui/layout/split.go",
    "chars": 5995,
    "preview": "package layout\n\nimport (\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/"
  },
  {
    "path": "internal/tui/page/chat.go",
    "chars": 6213,
    "preview": "package page\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracelet/bub"
  },
  {
    "path": "internal/tui/page/logs.go",
    "chars": 1912,
    "preview": "package page\n\nimport (\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/ch"
  },
  {
    "path": "internal/tui/page/page.go",
    "chars": 127,
    "preview": "package page\n\ntype PageID string\n\n// PageChangeMsg is used to change the current page\ntype PageChangeMsg struct {\n\tID Pa"
  },
  {
    "path": "internal/tui/styles/background.go",
    "chars": 2673,
    "preview": "package styles\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\nvar ansiEscape = regexp.Mu"
  },
  {
    "path": "internal/tui/styles/icons.go",
    "chars": 271,
    "preview": "package styles\n\nconst (\n\tOpenCodeIcon string = \"⌬\"\n\n\tCheckIcon    string = \"✓\"\n\tErrorIcon    string = \"✖\"\n\tWarningIcon  "
  },
  {
    "path": "internal/tui/styles/markdown.go",
    "chars": 8803,
    "preview": "package styles\n\nimport (\n\t\"github.com/charmbracelet/glamour\"\n\t\"github.com/charmbracelet/glamour/ansi\"\n\t\"github.com/charm"
  },
  {
    "path": "internal/tui/styles/styles.go",
    "chars": 4426,
    "preview": "package styles\n\nimport (\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/opencode-ai/opencode/internal/tui/theme\"\n)\n\nv"
  },
  {
    "path": "internal/tui/theme/catppuccin.go",
    "chars": 6945,
    "preview": "package theme\n\nimport (\n\tcatppuccin \"github.com/catppuccin/go\"\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\n// CatppuccinThem"
  },
  {
    "path": "internal/tui/theme/dracula.go",
    "chars": 6582,
    "preview": "package theme\n\nimport (\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\n// DraculaTheme implements the Theme interface with Drac"
  },
  {
    "path": "internal/tui/theme/flexoki.go",
    "chars": 7605,
    "preview": "package theme\n\nimport (\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\n// Flexoki color palette constants\nconst (\n\t// Base colo"
  },
  {
    "path": "internal/tui/theme/gruvbox.go",
    "chars": 8719,
    "preview": "package theme\n\nimport (\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\n// Gruvbox color palette constants\nconst (\n\t// Dark them"
  },
  {
    "path": "internal/tui/theme/manager.go",
    "chars": 3012,
    "preview": "package theme\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/alecthomas/chroma/v2/styles\"\n\t\"github.com/open"
  },
  {
    "path": "internal/tui/theme/monokai.go",
    "chars": 6502,
    "preview": "package theme\n\nimport (\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\n// MonokaiProTheme implements the Theme interface with M"
  },
  {
    "path": "internal/tui/theme/onedark.go",
    "chars": 6496,
    "preview": "package theme\n\nimport (\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\n// OneDarkTheme implements the Theme interface with Atom"
  },
  {
    "path": "internal/tui/theme/opencode.go",
    "chars": 6949,
    "preview": "package theme\n\nimport (\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\n// OpenCodeTheme implements the Theme interface with Ope"
  },
  {
    "path": "internal/tui/theme/theme.go",
    "chars": 9794,
    "preview": "package theme\n\nimport (\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\n// Theme defines the interface for all UI themes in the "
  },
  {
    "path": "internal/tui/theme/theme_test.go",
    "chars": 1805,
    "preview": "package theme\n\nimport (\n\t\"testing\"\n)\n\nfunc TestThemeRegistration(t *testing.T) {\n\t// Get list of available themes\n\tavail"
  },
  {
    "path": "internal/tui/theme/tokyonight.go",
    "chars": 6666,
    "preview": "package theme\n\nimport (\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\n// TokyoNightTheme implements the Theme interface with T"
  },
  {
    "path": "internal/tui/theme/tron.go",
    "chars": 6540,
    "preview": "package theme\n\nimport (\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\n// TronTheme implements the Theme interface with Tron-in"
  },
  {
    "path": "internal/tui/tui.go",
    "chars": 25545,
    "preview": "package tui\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/bubbles/key\"\n\ttea \"github.com/charmbracel"
  },
  {
    "path": "internal/tui/util/util.go",
    "chars": 805,
    "preview": "package util\n\nimport (\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n)\n\nfunc CmdHandler(msg tea.Msg) tea.Cmd {\n\tret"
  },
  {
    "path": "internal/version/version.go",
    "chars": 690,
    "preview": "package version\n\nimport \"runtime/debug\"\n\n// Build-time parameters set via -ldflags\nvar Version = \"unknown\"\n\n// A user ma"
  },
  {
    "path": "main.go",
    "chars": 270,
    "preview": "package main\n\nimport (\n\t\"github.com/opencode-ai/opencode/cmd\"\n\t\"github.com/opencode-ai/opencode/internal/logging\"\n)\n\nfun"
  },
  {
    "path": "opencode-schema.json",
    "chars": 12234,
    "preview": "{\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"definitions\": {\n    \"agent\": {\n      \"description\": \"Agent "
  },
  {
    "path": "scripts/check_hidden_chars.sh",
    "chars": 1511,
    "preview": "#!/bin/bash\n\n# Script to check for hidden/invisible characters in Go files\n# This helps detect potential prompt injectio"
  },
  {
    "path": "scripts/release",
    "chars": 976,
    "preview": "#!/usr/bin/env bash\n\n# Parse command line arguments\nminor=false\nwhile [ \"$#\" -gt 0 ]; do\n  case \"$1\" in\n    --minor) min"
  },
  {
    "path": "scripts/snapshot",
    "chars": 79,
    "preview": "#!/usr/bin/env bash\nset -e\ngoreleaser build --clean --snapshot --skip validate\n"
  },
  {
    "path": "sqlc.yaml",
    "chars": 339,
    "preview": "version: \"2\"\nsql:\n  - engine: \"sqlite\"\n    schema: \"internal/db/migrations\"\n    queries: \"internal/db/sql\"\n    gen:\n    "
  }
]

About this extraction

This page contains the full source code of the opencode-ai/opencode GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 162 files (1.3 MB), approximately 369.9k tokens, and a symbol index with 2589 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!