Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
08321a8
<docs>:新增flow完成方案和todo优化方案
phantom5099 Mar 25, 2026
1bc8751
Merge remote-tracking branch 'upstream/main'
phantom5099 Mar 27, 2026
589d6d2
pref:优化TUI界面和热键绑定
phantom5099 Mar 28, 2026
262b069
feat(provider): narrow MVP provider support surface
creatang Mar 28, 2026
4a946ae
ci: skip codecov upload when token is unavailable
creatang Mar 28, 2026
34db085
ci: make codecov upload non-blocking
creatang Mar 28, 2026
f7bf1c7
feat(config): add provider presets
creatang Mar 28, 2026
b4da678
Merge pull request #1 from creatang/codex/provider-mvp-support-surface
creatang Mar 28, 2026
aafe13a
Merge remote-tracking branch 'txl/main'
phantom5099 Mar 28, 2026
5c0918c
pref:修正TUI界面的背景色错误
phantom5099 Mar 28, 2026
72322f2
pref:优化provide模块
phantom5099 Mar 28, 2026
a429bc4
docs:去除冗余文档
phantom5099 Mar 28, 2026
a8c21c4
Merge branch 'main' into main
phantom5099 Mar 28, 2026
b6e1599
<fix>:修改config/model.go合并后的变量名错误
phantom5099 Mar 28, 2026
30a8bad
fix:修复合并错误
phantom5099 Mar 28, 2026
afd2cea
Merge remote-tracking branch 'origin/main'
phantom5099 Mar 28, 2026
98760c5
Merge remote-tracking branch 'upstream/main'
phantom5099 Mar 28, 2026
6a13a35
fix:修复url来源错误问题
phantom5099 Mar 28, 2026
5692d0b
pref:为TUI层增加中止思考入口
phantom5099 Mar 28, 2026
e941f63
fix:修复测试断言有误问题
phantom5099 Mar 28, 2026
1285e6c
test:补充openll测试文件
phantom5099 Mar 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ jobs:
run: go test ./... -covermode=atomic -coverprofile=coverage.out

- name: Upload coverage to Codecov
continue-on-error: true
uses: codecov/codecov-action@v5
with:
files: ./coverage.out
flags: unittests
fail_ci_if_error: true
fail_ci_if_error: false
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ config.local.yaml

# Local data
data/
.cache/

# Editor/IDE
.idea/
Expand Down
96 changes: 49 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,63 @@
# NeoCode
NeoCode 是一个基于 Go 和 Bubble Tea 构建的本地 Coding Agent MVP。它把 Provider 防腐层、工具调用闭环、本地会话持久化和沉浸式瀑布流 TUI 组合在一起,用于日常代码理解、修改和终端内协作。

## 功能特性
- 基于防腐层的 Provider 架构,当前支持 OpenAI 兼容流式接口,并为 Anthropic、Gemini 预留了扩展位置。
- ReAct 风格的 runtime 主循环,能够读取模型输出、执行工具调用、回灌结果并继续推理。
- 瀑布流终端界面,支持流式 transcript、内联工具事件、Slash Command 和会话侧边栏。
- 本地 YAML 配置、`.env` 加载与并发安全的热更新能力。
- 本地 JSON 会话持久化,不依赖远端服务即可恢复历史上下文。
- 文件系统高级工具:读取、写入、搜索、Glob 探测和精准替换。
NeoCode 是一个基于 Go 和 Bubble Tea 的本地编码 Agent。它在终端中运行 ReAct 闭环,能够对话、调用工具、持久化会话,并以流式方式展示模型输出。

## 环境要求
- Go 1.21 及以上
- 至少一个可用的模型 Provider API Key,例如 `OPENAI_API_KEY`
## 当前 Provider 策略

## 快速开始
1. 克隆仓库。
2. 准备 Provider 的 API Key,可以通过环境变量或 NeoCode 托管的 `.env` 文件提供。
3. 运行应用:
- 内建 provider 定义随代码版本发布。
- `config.yaml` 不再持久化完整 `providers` 列表。
- `config.yaml` 只保存当前选择状态和通用运行配置。
- 运行时的 `providers` 完全来自代码内建定义。
- API Key 只从环境变量读取,不写入 YAML。
- 当前内建 provider 包括 `openai` 和 `gemini`。
- `gemini` 复用 OpenAI-compatible driver,请求地址指向 Gemini 的兼容接口。
- provider 实例自己定义 `base_url`、默认模型、可选模型列表和 `api_key_env`。
- `base_url` 不在 TUI 中展示给用户。
- driver 只负责协议构造与响应解析,不决定 `models`、`base_url` 或 `api_key_env`。

```bash
go run ./cmd/neocode
这意味着:

- 新用户启动后会自动拿到当前版本最新的内建 provider。
- 未来代码新增 provider 时,新用户不需要修改 YAML。
- 老配置文件中的 `providers` / `provider_overrides` 会在加载时被清理为新的最小状态格式。

## 配置文件

默认路径:
[`~/.neocode/config.yaml`](~/.neocode/config.yaml)

当前落盘结构示例:

```yaml
selected_provider: openai
current_model: gpt-5.4
workdir: .
shell: powershell
max_loops: 8
tool_timeout_sec: 20
```

首次启动时,NeoCode 会在当前用户主目录下创建自己的托管目录、默认配置和会话存储结构。
其中:

- `selected_provider` 和 `current_model` 是用户当前选择。
- provider 的 `base_url`、`models`、`api_key_env` 和 `driver` 都由开发者在代码中预设。
- `openai` 默认读取 `OPENAI_API_KEY`,`gemini` 默认读取 `GEMINI_API_KEY`。
- 完整 provider 列表不落盘,用户不需要在 YAML 中维护供应商元数据。

## Slash Commands

## Slash Command
- `/set url <url>`:更新当前选中 Provider 的 Base URL。
- `/set key <key>`:将当前 Provider 的密钥写入托管 `.env` 并立即重新加载。
- `/model`:打开交互式模型选择列表。
- `/provider`:打开 provider 选择器。
- `/model`:打开当前 provider 的模型选择器。

## 开发与验证
在提交 Pull Request 前建议至少执行以下命令:
## 运行

```bash
gofmt -w ./cmd ./internal
go test ./...
go run ./cmd/neocode
```

## 架构概览
- `internal/config`:负责 YAML 加载、`.env` 集成、默认值管理和并发安全更新。
- `internal/provider`:将厂商特定的请求和流式响应抹平成统一领域模型。
- `internal/runtime`:负责事件总线、ReAct loop、Provider 动态构建和会话持久化。
- `internal/tools`:提供工具注册表以及各类具体工具实现。
- `internal/tui`:负责终端交互体验,以及 runtime 事件到 Bubble Tea 消息的桥接。

## 目录结构
```text
.
|-- cmd/neocode
|-- docs
|-- internal/app
|-- internal/config
|-- internal/provider
|-- internal/runtime
|-- internal/tools
`-- internal/tui
```
## 开发

## 当前状态
NeoCode 目前聚焦于 MVP 闭环:本地对话、工具调用、Session 持久化和终端交互体验。当前版本正在继续向“高质量开源项目”标准收敛,重点补强文档、测试覆盖率和工具能力。
```bash
gofmt -w ./cmd ./internal
go test ./...
```
109 changes: 109 additions & 0 deletions agents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# NeoCode Agent Rules

本文件是本仓库的 AI 协作规则。任何 AI 在本项目中进行改写、续写、重构、修复、补测试或补文档时,都应优先遵守本文件。

## 1. 任务目标
- 本仓库的目标是实现 `NeoCode Coding Agent MVP`。
- 当前主链路必须始终围绕以下闭环保持可用:
`用户输入 -> Agent 推理 -> 调用工具 -> 获取结果 -> 继续推理 -> UI 展示`
- 做改动时,优先保证主链路可运行、模块边界清晰、实现可验证。

## 2. 最高优先级规则
- 不要为了“可能兼容旧版本”破坏当前架构;若新设计已确定,优先直接切换到新实现。
- 不要跨层直连;新功能默认沿 `TUI -> Runtime -> Provider / Tool Manager` 主链路设计。
- 不要把模型厂商差异泄漏到 `runtime`、`tui` 或上层调用方。
- 不要在 `runtime` 或 `tui` 里直接写工具执行逻辑;所有可被模型调用的能力必须进入 `internal/tools`。
- 不要把会话状态、消息历史、工具调用记录散落到 UI;这些状态优先由 `runtime` 管理。
- 不要把明文 API Key 写入 YAML、样例配置、测试快照或提交内容。
- 修改 `config`、`provider`、`runtime`、`tools` 时,默认应同时评估并补充测试。

## 3. 代码结构与职责边界

### 3.1 关键目录
- `cmd/neocode`:CLI 入口。
- `internal/app`:应用装配与 bootstrap,负责连接 config、provider、tools、runtime、tui。
- `internal/config`:配置模型、YAML 加载、环境变量管理、配置校验和并发安全访问。
- `internal/provider`:provider 抽象、领域模型和各厂商适配器。
- `internal/runtime`:ReAct 主循环、事件流、Prompt 编排、Session 持久化。
- `internal/tools`:工具契约、注册表、参数校验和具体工具实现。
- `internal/tui`:Bubble Tea 状态机、渲染层、Slash Command 和事件桥接。
- `docs`:架构、配置、事件流、会话持久化等说明文档。

### 3.2 模块职责
- `app` 只负责装配和依赖注入,不承载业务规则。
- `config` 负责 provider 列表、当前 provider、当前 model、workdir、shell 的管理和校验。
- `provider` 只处理模型协议差异、请求组装、响应解析、流式输出、超时与重试。
- `runtime` 负责会话、消息上下文、tool schema 传递、tool call 识别、tool result 回灌和停止条件。
- `tools` 负责统一的 `schema + execute + result` 协议,以及参数校验、错误包装和输出格式收敛。
- `tui` 只消费 runtime 事件并负责展示,不直接调用 provider,不直接执行 tools。

## 4. AI 修改代码时的执行流程
- 先定位改动所属模块,再检查是否会破坏职责边界。
- 优先做最小闭环改动,避免无关重构。
- 如果新增能力会被模型调用,先设计 `tools` 抽象,再接入 `runtime`。
- 如果改动涉及 provider 协议,差异收敛在 `internal/provider` 内,不向外扩散特定厂商字段。
- 如果改动涉及配置,统一经由 `ConfigManager` 或现有配置管理入口处理。
- 如果新增目录、命令、配置项或模块职责,必须同步更新 `README.md`、`docs/` 或本文件。

## 5. 测试规则
- 测试文件命名为 `*_test.go`,测试函数命名为 `TestXxx`。
- 优先覆盖以下边界:
- 配置校验
- provider 请求/响应转换
- tool 参数校验
- runtime loop 停止条件
- 事件派发
- 修改 `runtime` 时,重点覆盖:
- 最大轮数停止
- tool result 回灌
- 最终响应输出
- 错误事件派发
- 修改 `tools` 时,重点覆盖:
- schema 校验
- 超时控制
- 错误包装
- 工作目录限制
- 修改 `provider` 时,重点覆盖:
- 请求组装
- tool call 解析
- 异常响应处理
- 认证或限流错误映射

## 6. 编码与实现规则
- 遵循 Go 惯用风格。
- 包名使用短小、全小写名词。
- 导出标识符使用 `PascalCase`,未导出使用 `camelCase`。
- 使用制表符缩进,尽量将单行控制在约 120 字符内。
- 核心抽象上的导出类型、函数、接口应补充清晰注释,尤其是 `provider`、`runtime`、`tools`。
- 避免硬编码路径、URL、模型名、超时、输出长度限制和环境差异项,优先通过配置、参数或具名常量注入。
- 优先写清晰、可替换的实现,不要为了“未来可能需要”提前引入复杂泛化。

## 7. 配置与安全规则
- 配置文件默认路径为 `~/.neocode/config.yaml`。
- 配置中只保存环境变量名,不保存明文 API Key。
- `selected_provider`、`current_model`、`workdir`、`shell` 必须在启动阶段完成校验,非法配置应尽早失败。
- `filesystem` 工具默认限制在工作目录内,禁止越界访问。
- `bash` 工具必须限制超时、输出长度,并避免交互式阻塞命令。
- `webfetch` 工具必须限制协议范围和响应大小,防止拉取不受控内容。
- 本地运行数据、会话数据和真实密钥不得默认入库;相关目录和配置文件应加入 `.gitignore`。

## 8. 文档规则
- 修改说明性文档时,沿用目标文档当前已有的主语言。
- 当前文档如果以中文为主,则继续使用中文;若以英文为主,则继续使用英文。
- 仅在代码标识符、命令、路径、协议名、库名等不可避免的场景下保留英文原词。
- 文档必须反映真实实现;如果实现和文档冲突,修代码或修文档时至少修正其中一个,不要放任失真。

## 9. 提交前最低检查
- 确认改动没有破坏 `TUI / Runtime / Provider / Tools / Config` 的职责分工。
- 确认新增能力已经接到正确层级,而不是临时跨层实现。
- 运行必要的格式化和测试。
- 检查 `git status`,确保没有无关文件、密钥、本地配置或临时数据混入。

## 10. 常用命令
- 启动应用:`go run ./cmd/neocode`
- 编译全部包:`go build ./...`
- 运行测试:`go test ./...`
- 格式化代码:`gofmt -w ./cmd ./internal`

## 11. 一句话原则
- 任何 AI 在此仓库中工作时,都应优先保持主链路可用、边界清晰、配置安全、测试可验证,而不是追求无关的大改或过度设计。
2 changes: 1 addition & 1 deletion cmd/neocode/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
"os"

"github.com/dust/neo-code/internal/app"
"neo-code/internal/app"
)

func main() {
Expand Down
17 changes: 9 additions & 8 deletions docs/config-management-detail-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,26 @@
- 向运行中的系统提供并发安全的配置读写能力

## 核心类型
- `Config`:顶层应用配置,包含 Provider 列表、当前选中 Provider、当前模型、工作目录、Shell 和循环限制等信息
- `ProviderConfig`:单个 Provider 的配置项,包括 Base URL、默认模型和 API Key 环境变量名
- `Config`:顶层应用配置,运行时包含 Provider 列表、当前选中 Provider、当前模型、工作目录、Shell 和循环限制等信息
- `ProviderConfig`:单个 Provider 的内建定义,包括 Base URL、默认模型、实例级模型列表和 API Key 环境变量名
- `Manager`:使用 `sync.RWMutex` 保护的配置访问器与修改器
- `Loader`:对 YAML 文件和托管 `.env` 文件的文件系统封装

## 环境变量策略
- YAML 只保存 `api_key_env`,不保存真实密钥
- YAML 不保存 `api_key_env`,只保存 `selected_provider`、`current_model` 和通用运行配置
- `Loader.LoadEnvironment` 会尝试加载当前工作目录下的 `.env` 和 NeoCode 托管目录中的 `.env`。
- `ProviderConfig.ResolveAPIKey` 在真正发起请求前通过 `os.Getenv` 读取密钥。

## 运行时更新
- TUI 只能通过 `ConfigManager.Update` 修改配置。
- 修改 Base URL 时只更新当前选中 Provider,并立即持久化
- 修改 API Key 时写入托管 `.env`,然后重新加载环境变量并刷新配置快照
- 修改模型时,同时更新 `current_model` 和当前 Provider 的 `model` 字段,保持状态一致
- TUI 只负责切换当前 Provider 和当前模型,不直接修改 Provider 元数据
- `base_url`、`api_key_env`、`driver` 和 `models` 由代码内建定义提供,不从 YAML 读写
- 修改模型时,只更新 `current_model`;当前 Provider 的 `model` 仍表示默认模型,`models` 负责描述该实例可选模型列表

## 默认值治理
- 默认 Provider 名称、URL、模型和环境变量名统一定义在 `internal/config/model.go` 中。
- 内建模型目录也收口在 `config` 包中,避免 TUI 自己维护一套零散的临时常量。
- 默认 Provider 名称、URL、默认模型、模型列表和环境变量名统一由内建 Provider 定义提供。
- `Loader` 在加载旧配置时会丢弃 `providers` / `provider_overrides`,重新回到“YAML 只保存选择状态”的最小结构。
- Provider 的可选模型目录属于实例配置,进入运行时 `Config` 后再提供给 TUI 和 runtime,避免 TUI 或 driver 自己维护一套零散常量。

## 安全约束
- 读操作统一走 `Get`,并返回拷贝后的配置快照。
Expand Down
18 changes: 9 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
module github.com/dust/neo-code
module neo-code

go 1.24.2
go 1.25.0

require (
github.com/charmbracelet/bubbles v1.0.0
github.com/charmbracelet/bubbletea v1.3.10
github.com/charmbracelet/lipgloss v1.1.0
github.com/joho/godotenv v1.5.1
golang.org/x/net v0.50.0
golang.org/x/net v0.52.0
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/colorprofile v0.4.1 // indirect
github.com/charmbracelet/colorprofile v0.4.3 // indirect
github.com/charmbracelet/x/ansi v0.11.6 // indirect
github.com/charmbracelet/x/cellbuf v0.0.15 // indirect
github.com/charmbracelet/x/term v0.2.2 // indirect
github.com/clipperhouse/displaywidth v0.9.0 // indirect
github.com/clipperhouse/displaywidth v0.11.0 // indirect
github.com/clipperhouse/stringish v0.1.1 // indirect
github.com/clipperhouse/uax29/v2 v2.5.0 // indirect
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
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.19 // indirect
github.com/mattn/go-runewidth v0.0.21 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/sahilm/fuzzy v0.1.1 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/sys v0.41.0 // indirect
golang.org/x/text v0.34.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/text v0.35.0 // indirect
)
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlv
github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk=
github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk=
github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q=
github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q=
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.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8=
Expand All @@ -24,10 +26,14 @@ github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSg
github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
github.com/clipperhouse/displaywidth v0.9.0 h1:Qb4KOhYwRiN3viMv1v/3cTBlz3AcAZX3+y9OLhMtAtA=
github.com/clipperhouse/displaywidth v0.9.0/go.mod h1:aCAAqTlh4GIVkhQnJpbL0T/WfcrJXHcj8C0yjYcjOZA=
github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8=
github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0=
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U=
github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk=
github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
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/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
Expand All @@ -42,6 +48,8 @@ github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2J
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-runewidth v0.0.21 h1:jJKAZiQH+2mIinzCJIaIG9Be1+0NR+5sz/lYEEjdM8w=
github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
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=
Expand All @@ -58,6 +66,8 @@ golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
Expand Down
Loading
Loading