Skip to content
Merged
191 changes: 77 additions & 114 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,89 +1,67 @@
# NeoCode
# NeoCode

> 基于 Go + Bubble Tea 的本地 Coding Agent
> 鍩轰簬 Go + Bubble Tea 鐨勬湰鍦?Coding Agent

## NeoCode 是什么
## NeoCode 鏄粈涔?
NeoCode 鏄竴涓湪缁堢涓繍琛岀殑 AI 缂栫爜鍔╂墜锛岄噰鐢?ReAct锛圧eason-Act-Observe锛夊惊鐜ā寮忥紝鍥寸粫浠ヤ笅涓婚摼璺伐浣滐細

NeoCode 是一个在终端中运行的 AI 编码助手,采用 ReAct(Reason-Act-Observe)循环模式,围绕以下主链路工作:
`鐢ㄦ埛杈撳叆 -> Agent 鎺ㄧ悊 -> 璋冪敤宸ュ叿 -> 鑾峰彇缁撴灉 -> 缁х画鎺ㄧ悊 -> UI 灞曠ず`

`用户输入 -> Agent 推理 -> 调用工具 -> 获取结果 -> 继续推理 -> UI 展示`
瀹冮€傚悎甯屾湜鍦ㄦ湰鍦板伐浣滄祦涓畬鎴愪唬鐮佺悊瑙c€佷慨鏀广€佽皟璇曚笌鑷姩鍖栨搷浣滅殑寮€鍙戣€呫€?
## 鏈変粈涔堣兘鍔?
- 缁堢鍘熺敓 TUI 浜や簰浣撻獙锛圔ubble Tea锛?- Agent 鍙皟鐢ㄥ唴缃伐鍏峰畬鎴愭枃浠朵笌鍛戒护鐩稿叧浠诲姟
- 鏀寔 Provider/Model 鍒囨崲锛堝唴寤?`openai`銆乣gemini`銆乣openll`銆乣qiniu`锛?- 鏀寔涓婁笅鏂囧帇缂╋紙`/compact`锛夛紝甯姪闀夸細璇濅繚鎸佸彲鐢?- 鏀寔宸ヤ綔鍖洪殧绂伙紙`--workdir`銆乣/cwd`锛?- 浼氳瘽鎸佷箙鍖栦笌鎭㈠锛岄檷浣庨噸澶嶆矡閫氭垚鏈?- 鏀寔鎸佷箙璁板繂鏌ョ湅銆佹樉寮忓啓鍏ヤ笌鍚庡彴鑷姩鎻愬彇锛屼繚鐣欒法浼氳瘽鍋忓ソ涓庨」鐩簨瀹?
## 鎬庝箞鐢紙蹇€熷紑濮嬶級

它适合希望在本地工作流中完成代码理解、修改、调试与自动化操作的开发者。

## 有什么能力

- 终端原生 TUI 交互体验(Bubble Tea)
- Agent 可调用内置工具完成文件与命令相关任务
- 支持 Provider/Model 切换(内建 `openai`、`gemini`、`openll`、`qiniu`)
- 支持上下文压缩(`/compact`),帮助长会话保持可用
- 支持工作区隔离(`--workdir`、`/cwd`)
- 会话持久化与恢复,降低重复沟通成本
- 支持持久记忆查看、显式写入与后台自动提取,保留跨会话偏好与项目事实

## 怎么用(快速开始)

### 1) 环境要求
### 1) 鐜瑕佹眰

- Go `1.25+`
- 可用的 API Key(如 OpenAI、Gemini、OpenLL、Qiniu)

### 2) 一键安装

macOS / Linux:

- 鍙敤鐨?API Key锛堝 OpenAI銆丟emini銆丱penLL銆丵iniu锛?
### 2) 涓€閿畨瑁?
macOS / Linux锛?
```bash
curl -fsSL https://raw.githubusercontent.com/1024XEngineer/neo-code/main/scripts/install.sh | bash
```

Windows PowerShell:

Windows PowerShell锛?
```powershell
irm https://raw.githubusercontent.com/1024XEngineer/neo-code/main/scripts/install.ps1 | iex
```

### 3) 从源码运行

### 3) 浠庢簮鐮佽繍琛?
```bash
git clone https://github.com/1024XEngineer/neo-code.git
cd neo-code
go run ./cmd/neocode
```

Gateway 子命令(Step 1 骨架):
Gateway 瀛愬懡浠わ紙Step 1 楠ㄦ灦锛夛細

```bash
go run ./cmd/neocode gateway
```

指定网络访问面监听地址(默认 `127.0.0.1:8080`,仅允许 Loopback):
鎸囧畾缃戠粶璁块棶闈㈢洃鍚湴鍧€锛堥粯璁?`127.0.0.1:8080`锛屼粎鍏佽 Loopback锛夛細

```bash
go run ./cmd/neocode gateway --http-listen 127.0.0.1:8080
```

网络访问面骨架端点(EPIC-GW-04):
缃戠粶璁块棶闈㈤鏋剁鐐癸紙EPIC-GW-04锛夛細

- `POST /rpc`:单次 JSON-RPC 请求入口
- `GET /ws`:WebSocket 流式入口(含心跳)
- `GET /sse`:SSE 流式入口(MVP 默认触发 `gateway.ping`,含心跳)

安全限制:为防止跨站攻击,网关网络面默认开启严格的 Origin 校验。当前仅允许
`http://localhost`、`http://127.0.0.1`、`http://[::1]` 以及 `app://` 前缀来源连入;
非允许来源的跨域调用会被拦截并返回 `403`。
注:上述白名单机制仅针对携带 `Origin` 头的浏览器跨站请求生效。若请求不携带 `Origin` 头
(例如 `cURL`、Postman 或本地后端脚本直连),网关默认放行。

URL Scheme 派发骨架命令(EPIC-GW-02A):
- `POST /rpc`锛氬崟娆?JSON-RPC 璇锋眰鍏ュ彛
- `GET /ws`锛歐ebSocket 娴佸紡鍏ュ彛锛堝惈蹇冭烦锛?- `GET /sse`锛歋SE 娴佸紡鍏ュ彛锛圡VP 榛樿瑙﹀彂 `gateway.ping`锛屽惈蹇冭烦锛?
瀹夊叏闄愬埗锛氫负闃叉璺ㄧ珯鏀诲嚮锛岀綉鍏崇綉缁滈潰榛樿寮€鍚弗鏍肩殑 Origin 鏍¢獙銆傚綋鍓嶄粎鍏佽
`http://localhost`銆乣http://127.0.0.1`銆乣http://[::1]` 浠ュ強 `app://` 鍓嶇紑鏉ユ簮杩炲叆锛?闈炲厑璁告潵婧愮殑璺ㄥ煙璋冪敤浼氳鎷︽埅骞惰繑鍥?`403`銆?娉細涓婅堪鐧藉悕鍗曟満鍒朵粎閽堝鎼哄甫 `Origin` 澶寸殑娴忚鍣ㄨ法绔欒姹傜敓鏁堛€傝嫢璇锋眰涓嶆惡甯?`Origin` 澶?锛堜緥濡?`cURL`銆丳ostman 鎴栨湰鍦板悗绔剼鏈洿杩烇級锛岀綉鍏抽粯璁ゆ斁琛屻€?
URL Scheme 娲惧彂楠ㄦ灦鍛戒护锛圗PIC-GW-02A锛夛細

```bash
go run ./cmd/neocode url-dispatch --url "neocode://review?path=README.md"
```

> `url-dispatch` 会将 `neocode://` URL 转发到本地 Gateway,并输出结构化响应。
>
> 注意:当前 MVP 版本仅支持 `review` 动作,且必须携带 `path` 参数(如 `neocode://review?path=README.md`);其余动作会在网关侧被拦截拒绝。

设置 API Key 示例(按你使用的 provider 选择):
> `url-dispatch` 浼氬皢 `neocode://` URL 杞彂鍒版湰鍦?Gateway锛屽苟杈撳嚭缁撴瀯鍖栧搷搴斻€?>
> 娉ㄦ剰锛氬綋鍓?MVP 鐗堟湰浠呮敮鎸?`review` 鍔ㄤ綔锛屼笖蹇呴』鎼哄甫 `path` 鍙傛暟锛堝 `neocode://review?path=README.md`锛夛紱鍏朵綑鍔ㄤ綔浼氬湪缃戝叧渚ц鎷︽埅鎷掔粷銆?
璁剧疆 API Key 绀轰緥锛堟寜浣犱娇鐢ㄧ殑 provider 閫夋嫨锛夛細

```bash
export OPENAI_API_KEY="your_key_here"
Expand All @@ -92,107 +70,92 @@ export AI_API_KEY="your_key_here"
export QINIU_API_KEY="your_key_here"
```

Windows PowerShell:

Windows PowerShell锛?
```powershell
$env:OPENAI_API_KEY = "your_key_here"
$env:GEMINI_API_KEY = "your_key_here"
$env:AI_API_KEY = "your_key_here"
$env:QINIU_API_KEY = "your_key_here"
```

按工作区启动(仅当前进程生效):
鎸夊伐浣滃尯鍚姩锛堜粎褰撳墠杩涚▼鐢熸晥锛夛細

```bash
go run ./cmd/neocode --workdir /path/to/workspace
```

### 4) 首次使用与常用命令

- `/help`:查看命令帮助
- `/provider`:打开 provider 选择器
- `/model`:打开 model 选择器
- `/compact`:压缩当前会话上下文
- `/status`:查看当前会话与运行状态
- `/cwd [path]`:查看或设置当前会话工作区
- `/memo`:查看记忆索引
- `/remember <text>`:保存记忆
- `/forget <keyword>`:按关键词删除记忆
- `& <command>`:在当前工作区执行本地命令

示例输入:

### 4) 棣栨浣跨敤涓庡父鐢ㄥ懡浠?
- `/help`锛氭煡鐪嬪懡浠ゅ府鍔?- `/provider`锛氭墦寮€ provider 閫夋嫨鍣?- `/model`锛氭墦寮€ model 閫夋嫨鍣?- `/compact`锛氬帇缂╁綋鍓嶄細璇濅笂涓嬫枃
- `/status`锛氭煡鐪嬪綋鍓嶄細璇濅笌杩愯鐘舵€?- `/cwd [path]`锛氭煡鐪嬫垨璁剧疆褰撳墠浼氳瘽宸ヤ綔鍖?- `/memo`锛氭煡鐪嬭蹇嗙储寮?- `/remember <text>`锛氫繚瀛樿蹇?- `/forget <keyword>`锛氭寜鍏抽敭璇嶅垹闄よ蹇?- `& <command>`锛氬湪褰撳墠宸ヤ綔鍖烘墽琛屾湰鍦板懡浠?
绀轰緥杈撳叆锛?
```text
请先阅读当前项目目录结构并给出模块职责摘要
帮我在 internal/runtime 下定位与 tool result 回灌相关逻辑
璇峰厛闃呰褰撳墠椤圭洰鐩綍缁撴瀯骞剁粰鍑烘ā鍧楄亴璐f憳瑕?甯垜鍦?internal/runtime 涓嬪畾浣嶄笌 tool result 鍥炵亴鐩稿叧閫昏緫
```

## 配置入口

- 主配置文件:`~/.neocode/config.yaml`
- 自定义 Provider:`~/.neocode/providers/<provider-name>/provider.yaml`

配置原则(用户侧重点):
## 閰嶇疆鍏ュ彛

- API Key 通过环境变量注入,不写入 `config.yaml`
- `--workdir` 只影响当前运行,不会回写到配置文件
- 涓婚厤缃枃浠讹細`~/.neocode/config.yaml`
- 鑷畾涔?Provider锛歚~/.neocode/providers/<provider-name>/provider.yaml`

详细配置请参考:[docs/guides/configuration.md](docs/guides/configuration.md)
閰嶇疆鍘熷垯锛堢敤鎴蜂晶閲嶇偣锛夛細

## 文档导航
- API Key 閫氳繃鐜鍙橀噺娉ㄥ叆锛屼笉鍐欏叆 `config.yaml`
- `--workdir` 鍙奖鍝嶅綋鍓嶈繍琛岋紝涓嶄細鍥炲啓鍒伴厤缃枃浠?
璇︾粏閰嶇疆璇峰弬鑰冿細[docs/guides/configuration.md](docs/guides/configuration.md)

- [配置指南](docs/guides/configuration.md)
- [扩展 Provider](docs/guides/adding-providers.md)
- [Runtime/Provider 事件流](docs/runtime-provider-event-flow.md)
- [Session 持久化设计](docs/session-persistence-design.md)
- [Context Compact 说明](docs/context-compact.md)
- [Tools 与 TUI 集成](docs/tools-and-tui-integration.md)
- [MCP 配置指南](docs/guides/mcp-configuration.md)
- [更新与升级](docs/guides/update.md)
## 鏂囨。瀵艰埅

## 如何参与
- [閰嶇疆鎸囧崡](docs/guides/configuration.md)
- [鎵╁睍 Provider](docs/guides/adding-providers.md)
- [Runtime/Provider 浜嬩欢娴乚(docs/runtime-provider-event-flow.md)
- [Session 鎸佷箙鍖栬璁(docs/session-persistence-design.md)
- [Context Compact 璇存槑](docs/context-compact.md)
- [Tools 涓?TUI 闆嗘垚](docs/tools-and-tui-integration.md)
- [MCP 閰嶇疆鎸囧崡](docs/guides/mcp-configuration.md)
- [鏇存柊涓庡崌绾(docs/guides/update.md)

欢迎通过 Issue 和 PR 参与共建。

1. 在 [Issues](https://github.com/1024XEngineer/neo-code/issues) 先沟通问题或需求。
2. Fork 仓库并创建功能分支。
3. 完成开发并确保改动聚焦、边界清晰。
4. 本地自检:
## 濡備綍鍙備笌

娆㈣繋閫氳繃 Issue 鍜?PR 鍙備笌鍏卞缓銆?
1. 鍦?[Issues](https://github.com/1024XEngineer/neo-code/issues) 鍏堟矡閫氶棶棰樻垨闇€姹傘€?2. Fork 浠撳簱骞跺垱寤哄姛鑳藉垎鏀€?3. 瀹屾垚寮€鍙戝苟纭繚鏀瑰姩鑱氱劍銆佽竟鐣屾竻鏅般€?4. 鏈湴鑷锛?
```bash
gofmt -w ./cmd ./internal
go test ./...
go build ./...
```

5. 提交 PR 到主仓库并说明变更目的、影响范围和验证方式。

提交前请确认:

- 不提交明文密钥、个人配置或会话数据
- 不提交无关改动与临时文件
5. 鎻愪氦 PR 鍒颁富浠撳簱骞惰鏄庡彉鏇寸洰鐨勩€佸奖鍝嶈寖鍥村拰楠岃瘉鏂瑰紡銆?
鎻愪氦鍓嶈纭锛?
- 涓嶆彁浜ゆ槑鏂囧瘑閽ャ€佷釜浜洪厤缃垨浼氳瘽鏁版嵁
- 涓嶆彁浜ゆ棤鍏虫敼鍔ㄤ笌涓存椂鏂囦欢

## 网关运维与安全(GW-06)

- 静默认证(Silent Auth):
- 启动 `neocode gateway` 时会自动读取 `~/.neocode/auth.json`。
- 若凭证不存在或损坏,会自动生成高强度 token 并写回该文件。
- `url-dispatch` 会自动读取同一 token 并先发送 `gateway.authenticate`,再发送业务请求。
- 认证与授权顺序:`Auth -> ACL -> Dispatch`。
- 未认证返回 `unauthorized`。
- 已认证但不允许的方法返回 `access_denied`。
- 运维端点:
- 免鉴权:`GET /healthz`、`GET /version`
- 需鉴权:`GET /metrics`、`GET /metrics.json`(`Authorization: Bearer <token>`)
- 关键默认治理参数(可通过 `config.yaml` 的 `gateway.*` 配置):
## 缃戝叧杩愮淮涓庡畨鍏紙GW-06锛?
- 闈欓粯璁よ瘉锛圫ilent Auth锛夛細
- 鍚姩 `neocode gateway` 鏃朵細鑷姩璇诲彇 `~/.neocode/auth.json`銆? - 鑻ュ嚟璇佷笉瀛樺湪鎴栨崯鍧忥紝浼氳嚜鍔ㄧ敓鎴愰珮寮哄害 token 骞跺啓鍥炶鏂囦欢銆? - `url-dispatch` 浼氳嚜鍔ㄨ鍙栧悓涓€ token 骞跺厛鍙戦€?`gateway.authenticate`锛屽啀鍙戦€佷笟鍔¤姹傘€?- 璁よ瘉涓庢巿鏉冮『搴忥細`Auth -> ACL -> Dispatch`銆? - 鏈璇佽繑鍥?`unauthorized`銆? - 宸茶璇佷絾涓嶅厑璁哥殑鏂规硶杩斿洖 `access_denied`銆?- 杩愮淮绔偣锛? - 鍏嶉壌鏉冿細`GET /healthz`銆乣GET /version`
- 闇€閴存潈锛歚GET /metrics`銆乣GET /metrics.json`锛坄Authorization: Bearer <token>`锛?- 鍏抽敭榛樿娌荤悊鍙傛暟锛堝彲閫氳繃 `config.yaml` 鐨?`gateway.*` 閰嶇疆锛夛細
- `max_frame_bytes=1MiB`
- `ipc_max_connections=128`
- `http_max_request_bytes=1MiB`
- `http_max_stream_connections=128`
- `ipc_read/write_sec=30/30`
- `http_read/write/shutdown_sec=15/15/2`
- 详细设计文档:[`docs/gateway-detailed-design.md`](docs/gateway-detailed-design.md)
- 璇︾粏璁捐鏂囨。锛歔`docs/gateway-detailed-design.md`](docs/gateway-detailed-design.md)

### Gateway JSON-RPC 方法清单(当前实现)

- `gateway.authenticate`:连接级鉴权握手
- `gateway.ping`:探活
- `gateway.bindStream`:会话流绑定
- `gateway.run`:发起一次运行(Accepted-ACK,异步执行)
- `gateway.compact`:触发会话压缩
- `gateway.cancel`:按 `run_id` 精确取消目标运行(`run_id` 必填)
- `gateway.listSessions`:查询会话摘要列表
- `gateway.loadSession`:加载单个会话详情
- `gateway.resolvePermission`:提交权限审批结果
- `wake.openUrl`:处理 `neocode://` 唤醒请求
- `gateway.event`:网关推送通知事件(notification)

## License

MIT

12 changes: 9 additions & 3 deletions docs/gateway-detailed-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ sequenceDiagram
| `gateway.authenticate` | request/response | 连接级鉴权,成功后复用认证态 |
| `gateway.ping` | request/response | 健康探针 |
| `gateway.bindStream` | request/response | 会话流绑定 |
| `gateway.run` | request/response | 发起一次运行请求 |
| `gateway.compact` | request/response | 触发一次会话压缩 |
| `gateway.cancel` | request/response | 按 `run_id` 精确取消目标运行(`run_id` 必填) |
| `gateway.listSessions` | request/response | 查询会话摘要列表 |
| `gateway.loadSession` | request/response | 加载单个会话详情 |
| `gateway.resolvePermission` | request/response | 提交权限审批决策 |
| `wake.openUrl` | request/response | URL Scheme 唤醒入口 |
| `gateway.event` | notification | Gateway 推送运行时事件 |

Expand All @@ -156,10 +162,10 @@ sequenceDiagram
| `Run(ctx, input)` | 发起一次运行编排 |
| `Compact(ctx, input)` | 执行会话压缩 |
| `ResolvePermission(ctx, input)` | 回填权限审批结果 |
| `CancelActiveRun()` | 取消活动运行 |
| `CancelRun(ctx, input)` | 按 `run_id` 精确取消目标运行 |
| `Events()` | 订阅运行时事件流 |
| `ListSessions(ctx)` | 获取会话摘要 |
| `LoadSession(ctx, id)` | 加载会话详情 |
| `LoadSession(ctx, input)` | 按 `session_id` 加载会话详情(含主体信息) |

## 6. 安全与治理基线

Expand All @@ -175,7 +181,7 @@ sequenceDiagram
- 错误返回统一:
- JSON-RPC:`error.code`
- Gateway 稳定码:`error.data.gateway_code`
- 关键稳定码:`unauthorized`, `access_denied`, `invalid_frame`, `unsupported_action`
- 关键稳定码:`unauthorized`, `access_denied`, `invalid_frame`, `unsupported_action`, `timeout`(runtime 调用超时)

### 6.3 默认治理参数

Expand Down
Loading
Loading