flavor-code 1.2.3 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +369 -1090
  2. package/README.zh-CN.md +369 -0
  3. package/dist/{app-SCHNJSXI.js → app-3DXEGSS7.js} +15 -9
  4. package/dist/{chunk-XGCFBGBB.js → chunk-3TYRDK34.js} +43 -38
  5. package/dist/{chunk-MVIMQEQT.js → chunk-HFR2WS6T.js} +0 -1
  6. package/dist/{chunk-DM64TM4Z.js → chunk-KKIBYDJI.js} +0 -1
  7. package/dist/{chunk-VOCZVFP7.js → chunk-N2S7USST.js} +0 -1
  8. package/dist/{chunk-XS2JU6S3.js → chunk-NVLYFU6P.js} +3 -4
  9. package/dist/{chunk-JZ322RCJ.js → chunk-S32JRDZK.js} +0 -1
  10. package/dist/{chunk-AHUOGT4I.js → chunk-Z3BW52MK.js} +1 -2
  11. package/dist/{claude-ink-ZL4UZMFY.js → claude-ink-WPWPEL5A.js} +3 -4
  12. package/dist/cli.js +9 -10
  13. package/dist/desktop/main.js +41 -36
  14. package/dist/desktop/preload.cjs +0 -1
  15. package/dist/desktop-renderer/assets/index-C66pDvHs.js +1 -2
  16. package/dist/desktop-renderer/index.html +14 -14
  17. package/dist/{devtools-SXJBSV2N.js → devtools-4QTPKBKK.js} +0 -1
  18. package/dist/{load-WQGNTCHC.js → load-XC5JYYBQ.js} +2 -3
  19. package/dist/sdk/index.js +5 -6
  20. package/package.json +7 -1
  21. package//346/212/200/346/234/257/346/226/271/346/241/210/346/212/245/345/221/212.md +1 -1
  22. package/dist/app-SCHNJSXI.js.map +0 -1
  23. package/dist/chunk-AHUOGT4I.js.map +0 -1
  24. package/dist/chunk-DM64TM4Z.js.map +0 -1
  25. package/dist/chunk-JZ322RCJ.js.map +0 -1
  26. package/dist/chunk-MVIMQEQT.js.map +0 -1
  27. package/dist/chunk-VOCZVFP7.js.map +0 -1
  28. package/dist/chunk-XGCFBGBB.js.map +0 -1
  29. package/dist/chunk-XS2JU6S3.js.map +0 -1
  30. package/dist/claude-ink-ZL4UZMFY.js.map +0 -1
  31. package/dist/cli.js.map +0 -1
  32. package/dist/desktop/main.js.map +0 -1
  33. package/dist/desktop/preload.cjs.map +0 -1
  34. package/dist/desktop-renderer/assets/index-C66pDvHs.js.map +0 -1
  35. package/dist/devtools-SXJBSV2N.js.map +0 -1
  36. package/dist/load-WQGNTCHC.js.map +0 -1
  37. package/dist/sdk/index.js.map +0 -1
package/README.md CHANGED
@@ -1,1090 +1,369 @@
1
- <p align="center">
2
- <img src="./assets/icon-transparent.png" alt="flavor-code 辣椒像素吉祥物" width="168" />
3
- </p>
4
-
5
- # flavor-code
6
-
7
- <p align="center">
8
- <b>终端与桌面端的 AI 编程助手</b><br/>
9
- <sub>像和资深程序员结对编程一样,在命令行或 Electron 桌面应用里完成读、写、搜、改</sub>
10
- </p>
11
-
12
- ---
13
-
14
- `flavor-code` 是一个同时提供终端界面与 Electron 桌面应用的 AI 编程助手。它接入大语言模型(OpenAI GPT、Anthropic Claude 或任何兼容服务),能理解你的项目结构,在工作区范围内安全操作文件,甚至能把复杂任务拆成多块,分给多个"小助手"并行处理。
15
-
16
- 当前稳定版本:**1.2.3**
17
-
18
- ## 它能做什么
19
-
20
- - **阅读和理解代码** — 你问"这个函数是干什么的",它读文件然后告诉你
21
- - **修改和创建文件** — "帮我在 `src/` 下新建一个 `utils.ts`",它写出来
22
- - **搜索代码库** — "项目里哪些地方调用了这个函数",它用 ripgrep 帮你搜
23
- - **运行命令** — 在受控范围内执行 shell 命令,比如跑测试、装依赖
24
- - **拆分复杂任务** — 如果需求涉及多个文件,它先列出计划,再按步骤执行,独立子任务并行推进
25
- - **主动提问澄清** — 需求不明确时,先给结构化选项,最后一项始终允许用户自行输入
26
- - **实时进度面板** — 终端里显示任务执行状态:○ 待执行 · ⟳ 执行中 · ✓ 完成 · ✗ 失败
27
- - **恢复完整时间线** — 聊到一半退出,下次 `--resume` 会恢复消息、工具调用、任务步骤、重试、用量和 Diff;旧的已压缩会话会明确展示压缩摘要边界
28
- - **长任务不中断** — 上下文快满时自动压缩旧消息并生成工作摘要,检测到活跃进度时自动扩展迭代上限
29
- - **跨会话长期记忆** — 自动保留少量用户偏好、项目约定和行为反馈,新会话不必重复说明
30
- - **插件和 Skill** — 通过插件扩展功能,通过 Skill(技能包)教它新的工作流
31
- - **Agent 自注册工具** — 任务中用自然语言描述一个可复用能力,Agent 创建 `RegisterTool` 持久工具,同一次任务立刻可用,无需重启
32
- - **MCP 服务管理** — CLI 与 Electron 共享项目级配置,可添加、编辑、启停和删除 stdio / HTTP 服务
33
- - **审计日志** — 所有工具执行失败都会被记录到 `.flavor/audit.jsonl`
34
- - **事故上报与 RCA** — 工具执行失败自动上报到 langgraph-claw 告警管道,P0 级错误触发自动根因分析(Auto-RCA)
35
- - **对抗性审查(/goal)** — 分离"规划 - 执行 - 审查"三角色,3 个独立 AI 质疑者多数投票验证目标是否达成,不通过则打回重做
36
- - **运行中追加任务** — CLI 工作时 Enter 保存一条待发送任务,SSE 结束后自动提交;`/steer` 可立即调整仍在执行的任务
37
- - **可逆会话树** — 为上下文和工作区创建内容寻址 checkpoint,可 rewind、unrevert,并从历史节点继续分支
38
- - **SDK、JSONL RPC 与 Eval** — Node 调用方、IDE 和自动化评测共用同一套生产运行时
39
- - **图片上传与多模态** — CLI 中 Ctrl+V 粘贴剪贴板图片、桌面端文件选择器上传,支持 PNG/JPEG/WebP,每张 ≤5MB,去重存储,作为 user 消息的一部分发送给视觉模型分析 UI 截图、设计稿或错误日志
40
- - **PKCE 运行时 LLM 配置管理** — OAuth 令牌可随登录下发实际模型、网关地址与可用模型列表,运行时动态切换主/子 Agent 模型,`/login` 立即生效无需重启,项目文件不被改写
41
- - **提示词缓存优化与命中率量化** — 稳定前缀(系统提示词 + FLAVOR.md + 用户偏好)与动态段严格分离,缓存断点固定在前缀末尾,任务状态更新、记忆修改、`/model` 切换都不再改写前缀字节;对话历史通过滚动尾部断点整段纳入缓存,稳态命中率可达 90~98%;按 `apiType` / `baseURL` 自动识别缓存策略;命中率日志默认写入 `.flavor/usage.jsonl`(无需任何开关,每个新 session 覆盖上一次),携带 `sessionId`
42
- - **Docker 沙箱** — 可选择让 Shell、自治 loop 及其验证命令在无网络、只读根文件系统的容器中运行
43
-
44
- ### 子 Agent 字节级提示词缓存(0.8.0)
45
-
46
- 同一次 `Task` 调度现在只冻结一次主 Agent 的模型可见上下文。每个子 Agent 都从这份快照创建独立副本,完整复用 system prompt、`FLAVOR.md`、任务状态、压缩摘要和父会话历史,只在最后追加自己的角色约束与任务 directive。共享部分保持消息顺序和 UTF-8 字节一致,可提高 Anthropic Prompt Cache 与 OpenAI Automatic Prompt Caching 的命中机会,同时父子消息、压缩和 usage 状态仍然彼此隔离。
47
-
48
- Anthropic 请求会在 fork 边界发送显式 `cache_control`;OpenAI 与 OpenAI-compatible 服务继续使用自动缓存,不注入可能与旧模型不兼容的专用字段。缓存仍受提供商规则限制:短于最小 token 门槛的前缀不会缓存;主/子 Agent 工具定义或模型不同会阻止整包父子命中;首批完全并发的 Anthropic 子请求也可能在缓存写入可见前同时发生 miss。后续兄弟任务、依赖节点和重试仍可复用相同的父前缀。
49
-
50
- ### OpenAI-compatible 工具调用兼容修复(1.2.3)
51
-
52
- OpenAI Responses 流式适配器现在同时兼容官方事件序列和部分兼容端点的精简事件序列:
53
-
54
- - 官方端点通过 `response.function_call_arguments.done` 完成工具参数时,保持原有解析行为。
55
- - 兼容端点省略参数完成事件、只在 `response.output_item.done` 中返回完整 `function_call` 时,也能正确提取工具名、调用 ID 和参数,不再把本轮误判为“无工具调用”并提前结束。
56
- - 同一工具调用同时出现两种完成事件时,按 `output_index` 去重,避免工具被重复执行。
57
- - 修复仅位于 OpenAI Responses 适配层;Anthropic Messages 请求、`tool_use` / `tool_result` 映射和缓存断点逻辑保持不变。
58
-
59
- ### 提示词缓存优化与命中率量化(1.2.0 / 1.2.1)
60
-
61
- 1.1.9 把字节级缓存思想扩展到**主会话本身**;1.2.0 重新划分了缓存布局,并加入了按 provider 的缓存能力识别;1.2.1 用滚动尾部断点把**整段对话历史**纳入缓存:
62
-
63
- - **主会话滚动缓存断点(1.2.1)** — Anthropic 适配器在每次请求的最后一条消息末尾自动追加 `cache_control` 断点:本轮把全部对话历史写入缓存,下一轮前缀与本轮完全一致、整段命中,只付增量的写入成本。缓存覆盖面从「仅系统前缀」扩展到全部历史,DashScope / Anthropic 兼容端点的命中率从 ~5% 提升到稳态 90~98%,输入成本约为优化前的 1/10。断点固定在请求末尾的 text / tool_result 块上(DashScope 会静默忽略 assistant `tool_use` 块上的标记);单请求标记预算 4 个,满额时自动淘汰价值最低的既有标记(如 fork 边界)
64
- - **命中率日志默认开启(1.2.1)** — 每次模型请求结束的命中率 JSON 默认写入 `.flavor/usage.jsonl`,不再需要设置 `FLAVOR_DEBUG_USAGE`;每条日志携带 `sessionId`,每个新 session(含清空上下文)会覆盖上一次的文件,始终只反映当前会话。`FLAVOR_DEBUG_USAGE=1` 仍可将同一条日志镜像到 stderr(交互式 TUI 下 ink 会拦截 stderr,以文件为准)
65
- - **缓存布局重构(1.2.0)** — 稳定前缀固定为「系统提示词 + FLAVOR.md + User memory(用户偏好)」,缓存断点设在稳定段末尾;Long-term memory(任务记忆)、Task state、`# Runtime environment`(Model、Permission mode)与 `# Current date` 全部移到断点之后。用户偏好跨任务稳定,而任务记忆、任务状态每轮都会变化,因此重新排序后,记忆更新、`/model`、`/permission` 切换和日期变化都不再改写缓存前缀字节——DeepSeek 等自动前缀缓存服务可持续整段命中。
66
- - **缓存能力识别(1.2.0)** — 新增 `resolveCacheProfile`,根据 provider 的 `apiType`(来自 `.flavor/flavor.json` 或 PKCE 令牌 `llm_config`)与 `baseURL` 识别缓存策略:Anthropic → 显式 `cache_control` 断点;OpenAI 通用端点 → 服务端自动前缀缓存;DashScope / MaaS 网关(`dashscope*.aliyuncs.com`、`*.maas.aliyuncs.com`)经 Responses API 调用时提示 Context Cache 不适用、命中率可能偏低。provider 注册信息附带缓存策略,便于定位命中率问题。
67
- - **FLAVOR.md 缓存断点(1.1.9)** — FLAVOR 段携带 `cacheBreakpoint`,把「系统提示词 + FLAVOR.md」固化为独立缓存单元;Task state 每轮变化只影响其后的小段,DeepSeek 等自动前缀缓存服务仍能命中大块稳定前缀。
68
- - **tools 字节序稳定(1.1.9)** — Anthropic / OpenAI 适配器发送 tools 前按名称排序,MCP 工具重连造成的顺序漂移不再破坏请求前缀字节。
69
- - **命中率量化(1.1.9,1.2.1 起默认开启)** — 每次请求输出一行 JSON,默认写入 `.flavor/usage.jsonl`(可用 `FLAVOR_USAGE_FILE` 覆盖路径),无需任何环境变量;设置 `FLAVOR_DEBUG_USAGE=1` 可额外镜像到 `process.stderr`:
70
-
71
- ```bash
72
- set FLAVOR_DEBUG_USAGE=1 && flavor # Windows CMD,仅 stderr 镜像需要
73
- $env:FLAVOR_DEBUG_USAGE="1"; flavor # PowerShell,仅 stderr 镜像需要
74
- ```
75
-
76
- ```json
77
- {"event":"flavor-usage","sessionId":"session-202608050818405-ab12cd34","provider":"anthropic","model":"qwen3.8-max","inputTokens":6,"cacheReadTokens":23965,"cacheCreationTokens":2562,"totalInputTokens":26533,"cacheHitRatio":0.9032,"requestMessages":15,"requestMarkers":3}
78
- ```
79
-
80
- **查看位置**:日志文件每个新 session 覆盖上一次的内容,另开一个终端实时观察:
81
-
82
- ```powershell
83
- Get-Content .flavor\usage.jsonl -Wait
84
- ```
85
-
86
- 命中率 = `cacheReadTokens / totalInputTokens`。同一会话内连续请求应逐步接近 90%+;命中率骤降说明前缀字节发生了变化,可按 `event:flavor-usage` 从文件中检索排查。`requestMessages` / `requestMarkers`(1.2.1)记录本次发送的消息数与实际挂载的缓存标记数,与服务端返回的 `cacheCreationTokens` 对照可快速判定命中率异常是客户端没发标记还是服务端不创建缓存块。OpenAI 侧同时兼容 Responses 的 `input_tokens_details.cached_tokens` 与 DeepSeek 的 `prompt_cache_hit_tokens` / `prompt_cache_miss_tokens`。
87
-
88
- ### 工具结果溢出保护(0.7.0)
89
-
90
- 工具输出现在会在执行层主动控制大小:单个结果最多内联 50,000 字符,同一模型轮次的全部工具结果共用 200,000 字符预算。超过任一限制时,Flavor 保留头尾预览,并把完整结果写入工作区的 `.flavor/tool-results/`;返回给模型的结果会包含原始字符数、截断原因和可直接交给 `Read` 的绝对文件路径。
91
-
92
- 这层保护发生在 `PostToolUse` Hook、UI 事件和上下文入库之前,可避免一次异常大的命令、搜索或 MCP 响应挤占模型窗口。上下文管理器原有的 `toolOutputChars` 截断仍然保留,负责保护恢复的历史会话和外部注入消息。
93
-
94
- ---
95
-
96
- ## 安装
97
-
98
- **前置条件:Node.js ≥ 20**
99
-
100
- ```bash
101
- npm install -g flavor-code
102
- ```
103
-
104
- 进入你的项目,启动:
105
-
106
- ```bash
107
- cd your-project
108
- flavor
109
- ```
110
-
111
- 首次使用时输入 `/init`,Flavor 会自动检测项目(语言、包管理器、源码目录、测试命令),生成 `FLAVOR.md` 项目指南文件。
112
-
113
- ### 从源码运行
114
-
115
- ```bash
116
- git clone <repo-url>
117
- cd flavor-code
118
- npm ci
119
- npm run build
120
- node dist/cli.js
121
- ```
122
-
123
- ---
124
-
125
- ## 配置模型
126
-
127
- Flavor 本身不包含 AI 模型,需要你提供 API Key。支持三种方式:
128
-
129
- ### 环境变量(最快捷)
130
-
131
- ```bash
132
- # macOS / Linux
133
- export OPENAI_API_KEY="sk-你的密钥"
134
- flavor
135
-
136
- # Windows PowerShell
137
- $env:OPENAI_API_KEY = "sk-你的密钥"
138
- flavor
139
- ```
140
-
141
- ### .env 文件
142
-
143
- 在项目根目录放一个 `.env` 文件(记得加入 `.gitignore`):
144
-
145
- ```
146
- OPENAI_API_KEY=sk-你的密钥
147
- ```
148
-
149
- ### 配置文件(最灵活)
150
-
151
- 在项目下创建 `.flavor/flavor.json`:
152
-
153
- ```json
154
- {
155
- "providers": {
156
- "openai": {
157
- "type": "openai",
158
- "baseURL": "https://api.openai.com/v1",
159
- "apiKey": "${OPENAI_API_KEY}",
160
- "defaultModel": "gpt-5",
161
- "cheapModel": "gpt-5-mini"
162
- }
163
- },
164
- "agents": {
165
- "main": { "model": "openai:gpt-5" },
166
- "subagent": { "model": "openai:gpt-5-mini" }
167
- },
168
- "maxSubagents": 3,
169
- "permissionMode": "default",
170
- "language": "zh-CN",
171
- "sleep": true,
172
- "maxIterations": {
173
- "main": 80,
174
- "subagent": 40,
175
- "softLimitFactor": 0.8,
176
- "extendBy": 20
177
- },
178
- "loop": {
179
- "maxCycles": 20,
180
- "maxTokens": 500000,
181
- "isolation": "auto"
182
- }
183
- }
184
- ```
185
-
186
- `sleep` 默认是 `false`。项目配置为 `true` 且 Flavor 进程跨过本地零点时,
187
- Flavor 会调用 subagent/cheap 模型整理刚结束的前一天会话,并将一份
188
- `日期-摘要.md` 报告写入项目的 `.flavor/sleep/`。前一天没有 session 时不会
189
- 调用模型或生成报告;不同项目的 Flavor 进程各自独立整理自己的 workspace。
190
-
191
- - 主 Agent 用大模型,子 Agent 用小模型,兼顾质量和成本
192
- - `${OPENAI_API_KEY}` 自动从环境变量或 `.env` 取值
193
- - `language: "zh-CN"` 让 Flavor 用简体中文回复(也支持 `en-US`、`ja-JP` 等 BCP47 标签)
194
- - 支持 Anthropic(`"type": "anthropic"`)和任何兼容 OpenAI 接口的服务(`"type": "openai-compatible"`)
195
- - 关于 OAuth PKCE 企业级认证,请参阅下方 [PKCE 认证配置](#pkce-认证配置)
196
-
197
- ## MCP 服务器
198
-
199
- Flavor 可以作为 MCP client,在启动时连接配置的 server,并把远端 tools 直接加入 Agent 的工具列表。支持本地 stdio 与远程 Streamable HTTP 两种传输。
200
-
201
- 在项目级 `.flavor/flavor.json`(或全局 `~/.flavor-code/flavor.json`)中添加:
202
-
203
- ```json
204
- {
205
- "mcpServers": {
206
- "mcp-docs": {
207
- "url": "https://modelcontextprotocol.io/mcp"
208
- },
209
- "filesystem": {
210
- "command": "cmd",
211
- "args": ["/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "."],
212
- "cwd": ".",
213
- "timeoutMs": 60000
214
- },
215
- "company-api": {
216
- "url": "https://mcp.example.com/mcp",
217
- "headers": {
218
- "Authorization": "Bearer ${MCP_API_TOKEN}"
219
- },
220
- "timeoutMs": 120000
221
- }
222
- }
223
- }
224
- ```
225
-
226
- - stdio server 使用 `command`,并可配置 `args`、`env`、`cwd`;相对 `cwd` 从工作区解析。
227
- - 上面的 filesystem 配置适用于 Windows;macOS/Linux 可改为 `"command": "npx"`,并从 `args` 删除 `"/c", "npx"`。
228
- - HTTP server 使用 `url`,并可配置 `headers`。鉴权信息建议通过 `.env` 和 `${ENV_NAME}` 插值传入。
229
- - 两种 server 都支持 `disabled: true` 和 `timeoutMs`(默认 60000,范围 100–1800000 毫秒)。
230
- - 远端 tool 暴露为 `mcp__<server>__<tool>`;不兼容模型命名规则的字符会被稳定转义。
231
- - MCP 调用按网络工具处理:`default` / `acceptEdits` 模式会请求批准,`bypassPermissions` 直接允许,`auto` 交给分类器判断;`--print` 不会绕过批准策略。
232
- - MCP tools 只暴露给主 Agent,不会出现在子 Agent 的工具列表中。
233
- - 单个 server 连接失败不会阻止 Flavor 启动,可通过 `/config` 查看已脱敏的 diagnostics。
234
- - 当前版本接入 MCP tools;resources、prompts、sampling、elicitation 与旧式 HTTP+SSE 尚未暴露给 Agent。
235
-
236
- 运行时可以直接管理 MCP 服务:
237
-
238
- ```text
239
- /mcp # 查看服务状态、传输类型和工具数量
240
- /mcp tools <server> # 查看服务暴露的工具及输入 schema
241
- /mcp reconnect <server> # 重新连接服务并刷新模型工具列表
242
- /mcp enable [server|all] # 启用服务,省略名称时处理全部
243
- /mcp disable [server|all] # 禁用服务,省略名称时处理全部
244
- ```
245
-
246
- 启用/禁用状态会写入项目的 `.flavor/flavor.json`,并在当前会话中立即更新,无需重启 Flavor。stdio server 的启动日志不会直接写入交互终端;连接失败可通过 `/mcp` 查看。
247
-
248
- Electron 可从项目栏打开 **MCP 服务** 工作台,以表单添加、编辑、开启/关闭或删除项目级 stdio / HTTP 配置。保存不会打断已经运行的对话,新配置会从下一个任务开始生效。全局 MCP 配置仍会被运行时加载,但工作台只修改当前项目的 `.flavor/flavor.json`。
249
-
250
- 独立 CLI 使用同一配置管理层,适合脚本和不进入交互会话的场景:
251
-
252
- ```text
253
- flavor mcp list [--json]
254
- flavor mcp add local --command npx --arg=-y --arg @modelcontextprotocol/server-filesystem --arg .
255
- flavor mcp add docs --url https://mcp.example.com/mcp --header Authorization="Bearer ${MCP_TOKEN}"
256
- flavor mcp update docs --url https://new.example.com/mcp
257
- flavor mcp enable|disable <name>
258
- flavor mcp delete <name>
259
- flavor mcp path
260
- ```
261
-
262
- `--arg`、`--env KEY=VALUE` 和 `--header KEY=VALUE` 均可重复;`--cwd` 与 `--timeout <毫秒>` 适用于对应传输。CLI 的配置操作从下次运行时启动生效;需要查看连接状态、刷新工具或在当前会话即时启停时,继续使用 `/mcp` 命令。
263
-
264
- ## 事故上报与 RCA(0.4.0)
265
-
266
- Flavor 内置了工具执行失败的事故上报通道,将 `PostToolUseFailure` 事件通过 AlertManager 兼容的 webhook 推送到 langgraph-claw 告警管道,触发自动根因分析(Auto-RCA)。
267
-
268
- ### 告警分级
269
-
270
- 工具失败按错误码自动分级:
271
-
272
- | 级别 | 严重度 | 错误码 | 处理方式 |
273
- |------|--------|--------|----------|
274
- | **P0** | critical | `tool_error` | 自动触发 RCA,通过 agent harness + code-rca skill 分析根因 |
275
- | **P1** | warning | `permission_denied`, `hook_denied`, `unknown_tool`, `user_denied` | 存储 + SSE 广播,需人工分析 |
276
- | **P2** | info | `approval_required`, `invalid_input` | 低优先级记录 |
277
- | **P3** | none | 其他 | 不上报 |
278
-
279
- 每条告警自动附带 Git 上下文(分支、commit、工作区是否脏),无需手动补充现场信息。
280
-
281
- ### 配置方式
282
-
283
- 在 `.flavor/flavor.json` 中添加:
284
-
285
- ```json
286
- {
287
- "incidents": {
288
- "enabled": true,
289
- "webhookUrl": "http://localhost:8000"
290
- }
291
- }
292
- ```
293
-
294
- 或通过环境变量:
295
-
296
- ```bash
297
- export FLAVOR_INCIDENT_ENABLED=true
298
- export FLAVOR_INCIDENT_WEBHOOK_URL="http://localhost:8000"
299
- ```
300
-
301
- - 上报是 fire-and-forget 模式:网络失败不会中断 Agent 循环,仅输出 `[incidents]` 日志
302
- - 默认 webhook 端点:`{webhookUrl}/api/otel/alerts`,兼容 AlertManager v4 格式
303
- - 未启用时,IncidentReporter 为零开销空操作
304
-
305
- ### Loop Engineering
306
-
307
- 使用 `/loop <goal>` 启动经过宿主验证的前台自治循环,例如:
308
-
309
- ```text
310
- /loop 修复当前项目的类型错误并通过测试
311
- ```
312
-
313
- - `loop.maxCycles` 和 `loop.maxTokens` 是每次用户授权的步长;达到门槛后询问是否继续,再按相同步长增加下一道门槛。
314
- - 验证命令从 `package.json` 与 `FLAVOR.md` 自动推断;若启动时没有,则先运行一次 verifier-discovery cycle,让 worker 建立有意义的项目原生检查,再由宿主重新推断。只有宿主执行的确定性验证通过才会结束为 `succeeded`。
315
- - `isolation: "auto"` 对只读目标使用当前目录,对代码修改或不明确目标使用独立 Git worktree;不能安全隔离时进入 `needs_human`。
316
- - 运行状态与证据写入 `.flavor/loops/<loop-id>/`。Ctrl+C 可取消;不会自动 merge、push 或 deploy。
317
-
318
- ### 对抗性审查(/goal)
319
-
320
- `/goal` 提供了一套结构化、多角色对抗验证的质量门禁机制:
321
-
322
- ```text
323
- /goal 修复项目里所有的 TypeScript 类型错误,并确保 npm test 全部通过
324
- ```
325
-
326
- **核心思路:干活的和审查的是不同角色。** 流水线分为三个阶段:
327
-
328
- 1. **Planner(规划者)**:将自然语言目标翻译为结构化验收标准(gating 门槛 + evidence 证据),写入 `.flavor/goal-plan.md`
329
- 2. **Worker(执行者)**:在验收标准约束下执行代码变更并自我验证
330
- 3. **Skeptic Panel(质疑团)**:3 个独立 AI 并行审查工作成果——默认立场是"我不信,证明给我看"
331
-
332
- ```mermaid
333
- flowchart LR
334
- A["/goal objective"] --> B["Planner<br/>生成验收契约"]
335
- B --> C["Worker<br/>执行代码变更"]
336
- C --> D["Skeptic Panel<br/>3 AI 对抗审查"]
337
- D -->|多数通过| E["✓ goal-complete"]
338
- D -->|打回重做| C
339
- D -->|不可修复| F["✗ goal-blocked"]
340
- ```
341
-
342
- **关键机制:**
343
-
344
- - **多数投票**:3 个 Skeptic 独立审查,≥2 个确认才算通过
345
- - **精准反馈**:打回重做时附带具体缺陷清单(哪条验收标准、什么问题、是否模型可修复)
346
- - **停滞熔断**:连续 2 轮修复后 gap 指纹不变 → 自动熔断(`goal-stalled`),避免烧钱死循环
347
- - **契约清晰**:Planner 只描述结果不指定实现,Skeptic 只审查契约不许发明新需求
348
- - **Fail-open**:Skeptic 解析失败按"不通过"处理,宁可多跑一轮也不错过问题
349
-
350
- 当前硬编码参数:`skepticCount: 3`、`maxRounds: 5`、`maxStallStreak: 2`。
351
-
352
- ---
353
-
354
- ## PKCE 认证配置
355
-
356
- > **适用场景**:企业或团队需要通过统一授权体系访问 LLM 服务,且不希望真正的 API Key 暴露给每个开发者。
357
-
358
- ### 什么是 PKCE
359
-
360
- PKCE(Proof Key for Code Exchange,发音 "pixy")是 OAuth 2.0 的一种扩展协议,专为**无法安全存储客户端密钥**的原生应用设计。flavor-code 内置了完整的 PKCE 客户端能力,配合 **flavor-pkce** 项目(授权服务器 + API 网关)实现"无 API Key 暴露"的 LLM 安全访问。
361
-
362
- ### 工作原理
363
-
364
- 一句话概括:**用户浏览器登录授权服务器 → 获取短期 JWT → 用 JWT 通过 API 网关访问 LLM → 网关将 JWT 替换为真正的 API Key 再转发到上游**。
365
-
366
- ```mermaid
367
- sequenceDiagram
368
- participant 用户
369
- participant flavor-code
370
- participant 浏览器
371
- participant 授权服务器
372
- participant API网关
373
- participant LLM
374
-
375
- 用户->>flavor-code: flavor
376
- flavor-code->>flavor-code: 启动时检测 OAuth 配置
377
- flavor-code->>浏览器: 打开授权页面
378
- 浏览器->>授权服务器: 登录 + 授权
379
- 授权服务器-->>浏览器: 重定向到本地回调
380
- 浏览器->>flavor-code: code + state
381
- flavor-code->>授权服务器: code + code_verifier
382
- 授权服务器-->>flavor-code: JWT access_token (3天有效)
383
- Note over flavor-code: Token 缓存到本地文件
384
-
385
- 用户->>flavor-code: 输入 prompt
386
- flavor-code->>API网关: POST + Authorization: Bearer JWT
387
- API网关->>API网关: 验证 JWT 签名
388
- API网关->>LLM: POST + 真实 API Key
389
- LLM-->>API网关: SSE 流式响应
390
- API网关-->>flavor-code: 透明转发 SSE
391
- flavor-code-->>用户: 展示回复
392
- ```
393
-
394
- 真实 API Key **只存在于 API 网关**,在整个授权和调用过程中不会离开网关。
395
-
396
- ### 配置方法
397
-
398
- #### 方式一:显式 OAuth 配置(推荐)
399
-
400
- 在 `.flavor/flavor.json` 中配置完整的 OAuth 参数:
401
-
402
- ```json
403
- {
404
- "providers": {
405
- "openai": {
406
- "type": "oauth-callback",
407
- "apiType": "openai",
408
- "baseURL": "https://api-gateway.your-company.com",
409
- "authorizationUrl": "https://auth.your-company.com/authorize",
410
- "tokenUrl": "https://auth.your-company.com/token",
411
- "clientId": "flavor-code-cli",
412
- "scope": "models:read models:use",
413
- "defaultModel": "gpt-5",
414
- "cheapModel": "gpt-5-mini"
415
- }
416
- }
417
- }
418
- ```
419
-
420
- | 字段 | 必填 | 说明 |
421
- |------|------|------|
422
- | `type` | 是 | 固定为 `"oauth-callback"` |
423
- | `apiType` | 是 | `"openai"` 或 `"anthropic"`,决定上游 API 协议 |
424
- | `baseURL` | 是 | API 网关地址(注意:不是 LLM 服务商的地址) |
425
- | `authorizationUrl` | 是 | 授权服务器的 `/authorize` 端点 |
426
- | `tokenUrl` | 是 | 授权服务器的 `/token` 端点 |
427
- | `clientId` | 是 | 在授权服务器注册的客户端标识 |
428
- | `scope` | 否 | 空格分隔的权限范围,默认 `"models:read models:use"` |
429
- | `defaultModel` | 否 | 主 Agent 的默认模型;PKCE 令牌未下发 `llm_config` 时生效 |
430
- | `cheapModel` | 否 | 子 Agent 的默认模型;PKCE 令牌未下发 `llm_config` 时生效 |
431
-
432
- > **1.1.8 起,`defaultModel` / `cheapModel` 变为可选**:授权服务器可在令牌响应中下发 `llm_config`(模型、网关地址、API 协议等)。登录后这些运行时配置会优先于 `flavor.json` 中的 provider 连接与模型字段,详见下方 [PKCE 运行时配置管理](#pkce-运行时配置管理118)。
433
-
434
- #### 方式二:环境变量内建默认值
435
-
436
- 如果不想在每个项目配置文件里写 OAuth 地址,可以通过环境变量设置全局默认值(`.env` 或 shell 环境变量):
437
-
438
- ```bash
439
- export OAUTH_AUTHORIZATION_URL="https://auth.your-company.com/authorize"
440
- export OAUTH_TOKEN_URL="https://auth.your-company.com/token"
441
- export OAUTH_CLIENT_ID="flavor-code-cli"
442
- export OAUTH_SCOPE="models:read models:use"
443
- ```
444
-
445
- 此时 `.flavor/flavor.json` 只需最简配置:
446
-
447
- ```json
448
- {
449
- "providers": {
450
- "openai": {
451
- "type": "oauth-callback",
452
- "apiType": "openai",
453
- "baseURL": "https://api-gateway.your-company.com",
454
- "defaultModel": "gpt-5",
455
- "cheapModel": "gpt-5-mini"
456
- }
457
- }
458
- }
459
- ```
460
-
461
- ### 首次使用流程
462
-
463
- 1. 按上述方式配置 `.flavor/flavor.json`
464
- 2. 运行 `flavor`
465
- 3. 系统自动打开浏览器,跳转到授权服务器登录页面
466
- 4. 输入用户名和密码登录
467
- 5. 在授权确认页面点击 Approve
468
- 6. 浏览器显示"授权成功,请返回终端"
469
- 7. flavor-code 自动获取 JWT Token 并缓存(3 天有效)
470
- 8. 后续 3 天内重启 flavor 无需再次授权
471
-
472
- Token 缓存文件位于 `~/.flavor-code/auth.json`。
473
-
474
- ### PKCE 运行时配置管理(1.1.8)
475
-
476
- 1.1.8 起,flavor-code 支持由 OAuth 令牌**运行时下发**实际的 LLM 配置:模型、网关地址、API 协议和可用模型列表都可以随 PKCE 登录一并下发,项目文件不会被登录改写。
477
-
478
- **工作原理:**
479
-
480
- 1. 授权服务器在 `/token` 响应中携带 `config_version` 和 `llm_config` 字段,后者包含 `provider_id`、`service_name`、`api_type`、`base_url`、`default_model`、`cheap_model`、`models` 和可选的 `max_output_tokens`
481
- 2. 令牌校验通过后,Flavor 在启动时加载该配置并生成一个**有效运行时 provider**,其优先级高于项目或全局 `flavor.json` 中的 provider 连接与模型字段;主 Agent、子 Agent、重试、权限分类、幻觉检查、记忆提取、上下文压缩、睡眠回顾和 goal 规划全部改用这份动态配置
482
- 3. 每次 SDK 请求使用运行时动态获取的 API Key(即 OAuth access token)和网关 baseURL;`/config` 只暴露脱敏后的有效配置视图
483
- 4. UI 的欢迎卡片同时展示 PKCE 服务名称与生效模型;Desktop 的模型列表优先展示 PKCE 令牌中的可用模型
484
- 5. 切换模型时校验合法性——只能选择 PKCE 令牌 `models` 列表内的模型
485
-
486
- **登录后立即生效:**
487
-
488
- ```text
489
- /login
490
- ```
491
-
492
- 显式执行 `/login` 会绕过有效缓存令牌,重新完成 PKCE 授权,并立即替换适配器、切换主/子 Agent 模型、更新 UI 状态,**无需重启**。
493
-
494
- **会话恢复与兼容:**
495
-
496
- - 恢复会话时,若已存储的模型 ID 与当前令牌的 `config_version` 不一致或模型已不在允许列表内,则该模型 ID 被忽略
497
- - 令牌凭据身份由「令牌端点 + client ID」派生,不同 PKCE 服务互不冲突;旧版以 provider 名称存储的令牌会在启动时自动迁移
498
- - `llm_config` 缺失的令牌保持旧版 OAuth 行为(使用 `flavor.json` 中的模型配置)
499
-
500
- ### 常见问题
501
-
502
- **Q: 和直接用 API Key 有什么区别?**
503
- 从使用体验上几乎没有区别。从安全角度,你的终端从未持有真正的 LLM API Key——它拿到的只是一个 3 天过期的 JWT。即使 JWT 泄露,影响范围也有限(3 天、受 scope 约束、可被服务端撤销)。
504
-
505
- **Q: 缓存过期了怎么办?**
506
- flavor-code 默认在过期前 60 秒自动丢弃缓存,下次启动时自动重新弹出浏览器授权。你也可以手动删除 `~/.flavor-code/auth.json` 强制重新授权。
507
-
508
- **Q: 如何搭建授权服务器和网关?**
509
- 参考 **flavor-pkce** 项目,提供了完整的 Docker Compose 部署方案(FastAPI + SQLite + JWT RS256),一键启动。
510
-
511
- ---
512
-
513
- ## 基本用法
514
-
515
- ### Electron 桌面端(1.1.0)
516
-
517
- 1.0.0 正式提供参考 Codex 交互方式设计的 Electron 桌面端。它不是简单套壳网页:Agent 运行时在 Electron 主进程中工作,桌面界面通过受控 IPC 与运行时通信,因此与 CLI 共享同一套工具、会话和配置能力。
518
-
519
- 桌面端已支持:
520
-
521
- - 项目切换、新建会话、历史会话分组、恢复与安全删除
522
- - 消息流式输出、Markdown、思考过程、工具调用、Diff 和子 Agent 状态展示
523
- - 权限确认、Agent 提问、任务取消,以及模型和权限模式切换
524
- - 顶部“完成任务”入口和右侧非阻塞式长期记忆确认栏
525
- - 全部 `/` 命令,以及 Skills、Plugins、MCP、`/loop` 和 `/goal` 等现有运行时能力
526
- - 可视化 Skill 工作台:项目 Skill 支持新建、查看、编辑、删除,所有来源均可按项目开启或关闭
527
- - 可视化 MCP 工作台:项目服务支持 stdio / HTTP 配置、编辑、开启/关闭和安全删除
528
- - 接近 Codex 的三栏工作台与单层自绘顶栏,并适配窄窗口显示
529
-
530
- 从源码运行或打包:
531
-
532
- ```powershell
533
- npm run desktop:dev # 启动带热更新的桌面开发环境
534
- npm run desktop:start # 构建后启动桌面应用
535
- npm run desktop:pack # 生成 release/win-unpacked(Windows)
536
- npm run desktop:dist # 生成 Windows NSIS 安装包
537
- ```
538
-
539
- Windows 打包产物位于:
540
-
541
- - 免安装目录:`release/win-unpacked/Flavor Code.exe`
542
- - NSIS 安装包:`release/Flavor-Code-1.2.3-x64.exe`
543
-
544
- 模型配置仍读取全局 `~/.flavor-code/flavor.json`、项目 `.flavor/flavor.json`、`.env` 和环境变量,因此 CLI 与桌面端可以共享配置与会话。生产版桌面窗口启用了 `contextIsolation` 和 Chromium 沙箱,关闭了渲染进程的 Node.js 集成;文件、命令和 Agent 操作只通过显式 IPC 接口进入主进程。Windows 的 `desktop:dev` 为兼容工作区内 Chromium 子进程启动,仅在本地开发启动器中使用 `--no-sandbox`,打包产物不携带该参数。
545
-
546
- Electron 的模型菜单默认提供 `deepseek-v4-pro` 与 `deepseek-v4-flash`,也可以通过“新增”接入 OpenAI 兼容或 Anthropic 协议的其他厂商服务。新增时填写厂商名称、模型名称、Base URL 和 API Key;厂商与模型信息会同时写入全局 `~/.flavor-code/flavor.json` 和项目 `.flavor/flavor.json`,同名字段以项目配置为准。API Key 只写入全局配置并使用本机配置密钥加密,项目配置通过合并继承该密钥,避免明文密钥进入项目仓库。保存后桌面端会新建会话并切换到该模型。CLI 继续沿用通用的 `provider:model` 与现有配置优先级。
547
-
548
- ### 交互模式
549
-
550
- ```bash
551
- flavor
552
- ```
553
-
554
- 直接打字聊天:
555
-
556
- - "这个项目的入口文件是什么"
557
- - "帮我在 src/utils 下写一个日期格式化的函数"
558
- - "把所有 console.log 替换成 logger.debug"
559
- - "解释一下 src/config/load.ts 里的配置加载逻辑"
560
-
561
- ### 非交互模式(脚本/CI 调用)
562
-
563
- ```bash
564
- flavor --print "列出 src/ 下所有导出了类的文件"
565
- flavor -p "分析这个项目的依赖关系"
566
- ```
567
-
568
- `--print` 模式下所有需要审批的操作默认拒绝,不会悬挂等待。
569
-
570
- ### 图片上传(多模态)
571
-
572
- Flavor 1.1.1 支持将图片作为提示词的一部分发送给视觉模型,让你可以请 AI 帮忙分析 UI 截图、设计稿、错误日志截图等。
573
-
574
- **CLI 终端:**
575
-
576
- 直接在输入框中 Ctrl+V(macOS 用 Cmd+V)粘贴剪贴板中的图片即可。Flavor 会自动检测剪贴板中的图像数据并作为附件包含在下一轮消息中。
577
-
578
- - 支持 PNG、JPEG、WebP 格式
579
- - 每张图片最大 5MB
580
- - 每次最多附带 5 张
581
- - 图片存储在 `.flavor/session-assets/` 下,SHA-256 去重
582
- - 当前支持 Windows 和 macOS;Linux 暂不支持
583
-
584
- **桌面端:**
585
-
586
- 在输入框上方通过文件选择器选择图片文件,或直接拖拽图片到输入区域。图片会随同 prompt 一起发送。
587
-
588
- **限制:**
589
-
590
- - 图片只能随新提示词发送,不能通过 steering/follow-up 追加
591
- - 不能在使用斜杠命令(以 `/` 开头)时附带图片
592
- - 不在子 Agent 的上下文中自动携带图片
593
-
594
- ### 恢复上次会话
595
-
596
- ```bash
597
- flavor --resume # 恢复最近一次会话
598
- flavor --resume session-20250101 # 恢复指定会话
599
- flavor --resume -p "继续刚才的工作" # 恢复后非交互执行
600
- ```
601
-
602
- 交互式 CLI 与 Electron 历史会话会恢复完整执行时间线。上下文压缩不会删除新格式会话的可见时间线;对于升级前已经压缩、原始步骤已不存在的会话,界面会显示压缩时间和保存的摘要,不会把摘要伪装成原始对话。`--resume -p` 只恢复模型上下文用于继续执行,不会把历史记录重新打印到标准输出。
603
-
604
- ### 长任务与上下文压缩
605
-
606
- Flavor 的压缩是分层执行的:
607
-
608
- 1. **微压缩**:上下文接近阈值时,先把旧的工具结果替换为清理标记,保留最近 5 个
609
- 2. **完整压缩**:仍然超阈值时,调用模型生成结构化工作摘要,包含用户意图、技术决策、文件、错误、待办、当前工作和下一步
610
- 3. **反应式压缩**:模型返回 `context_overflow` 且无可见输出时,强制压缩并重试同一轮
611
-
612
- 压缩后摘要作为"续接消息"注入,保留系统指令、项目指南、任务状态和近期消息。输入 `/compact` 可手动触发。
613
-
614
- ---
615
-
616
- ## 长期记忆
617
-
618
- Flavor 使用“任务级长期记忆”:交互式普通任务在 Agent 正常完成后自动评价,失败、取消、拒绝、斜杠命令和应用退出不会触发。CLI `/finish` 与 Electron 顶部“完成任务”保留为手工完成和失败重试入口,并与自动评价共享幂等校验,不会对同一任务重复调用模型。
619
-
620
- 另有一个用户主动保存的快捷入口:当提示中出现“记住”“帮我记住”“加入长期记忆”“please remember that”等明确表达时,当前回复结束后立即调用 cheap 模型,只分析用户明确要求保存的内容,不必等到 `/finish`,也不受 200 字符下限影响。“不要记住”“不用帮我记住”“别记”“无需保存到长期记忆”等否定表达不会触发。因为保存意图已经由用户明确给出,合格候选通过敏感信息检查和相似度查重后直接写入,不再重复弹出确认栏;`/remember` 仍走不调用模型的精确手工写入。
621
-
622
- 任务中的 user/assistant 可见文本不足 200 个 Unicode 字符时直接跳过,不产生额外 token;达到门槛后才调用配置的 cheap/subagent 模型。模型把候选归入 `user`(用户偏好)、`feedback`(行为反馈)、`project`(项目约定)或 `reference`(外部引用),并分别按“持久性、未来价值、来源权威性、是否难以从仓库重新推导”打 0–3 分。宿主只保留总分至少 9、且前三项都至少 2 分的最重要候选,每个任务最多 1 条;提取模型还被明确要求宁缺毋滥,常规操作、一次性任务细节、通用编程知识等一律不记。总分达到 `autoStoreThreshold`(默认 11)的高置信候选不再询问,直接写入并提示“已记住:…(`/forget` 可撤销)”;只有 9–10 分的候选才会进入确认栏。
623
-
624
- 如果 `flavor.json` 配置了 `language`(例如 `zh-CN`),候选摘要、正文和关键词使用该语言,代码标识符、命令、路径和 URL 保持原样。待确认候选只对当前交互有效:用户不处理候选而直接发送新的普通 query 时,旧候选全部作废并立即从 CLI/Electron 隐藏。
625
-
626
- 确认框也不会无休止打扰:候选默认带 5 秒倒计时(`reviewAutoDismissSeconds`,设 0 可关闭),超时未保存/未忽略会自动静默忽略,倒计时不作为“用户明确忽略”计入学习;连续忽略(CLI `Ctrl+N` 或 Electron 忽略按钮)累计达到 `ignoreStreakLimit`(默认 5)次后,自动评价自动暂停,之后的普通对话不再弹确认栏;暂停状态持久化在 `.flavor/memory/behavior.json`,重启后仍然生效。`/finish`、`/remember` 或显式“记住”成功保存一次即恢复自动提取。
627
-
628
- 对于自动评价或 `/finish` 产生的隐式候选,通过评分仍不等于写入。CLI 使用 `Ctrl+Y` 保存当前候选、`Ctrl+N` 忽略;Electron 在右侧非阻塞审阅栏逐条处理。用户接受后,宿主再使用规范化文本、单词和字符 n-gram/Jaccard 相似度做最终查重;只有没有同类高置信重复时才追加。密钥、Token、私钥、提示词注入、临时进度、原始工具输出和模型猜测会被拒绝。非交互模式不会运行隐式评价,但用户在输入中明确要求“记住”时仍可执行这条主动保存路径。
629
-
630
- 存储分为路由索引和正文:
631
-
632
- ```text
633
- .flavor/memory/
634
- ├── MEMORY.md # 摘要、类型、日期、正文路径、召回次数等路由信息
635
- └── tasks/
636
- └── <task-id>.md # 该任务确认保存的完整记忆正文
637
- ```
638
-
639
- `user` 表示跨任务稳定生效的用户偏好。宿主会读取全部 `user` 正文,将其作为固定系统上下文的最后一段注入,并在该段设置 prompt-cache 断点;它不参与关键词召回。`feedback`、`project` 和 `reference` 仍在每个新任务提示到来时按短摘要做本地相关度排序,再读取最相关的任务文件。相关度综合单词 Jaccard、Unicode 字符三元组和关键词,默认最多召回 5 条,完整注入受 `maxPromptChars` 字符预算限制。一个按需记忆在同一任务中最多计一次召回。滚动 7 天内被 10 个以上不同任务召回会标为 `[hot]` 并小幅加权,超过 3 天未召回会标为 `[cold]` 并降权;标签只代表近期使用频率,不代表更正确或拥有更高权限。当前用户指令、系统规则、`FLAVOR.md` 和仓库证据始终优先。
640
-
641
- Electron 左侧“长期记忆”工作台仍可按四种类型筛选、搜索、新建、编辑或删除记忆;`/remember` 和独立 CLI CRUD 属于用户主动写入,不经过模型评分。
642
-
643
- 交互会话中可以快速维护:
644
-
645
- ```text
646
- /memory
647
- /remember project 所有仓库脚本使用 pnpm
648
- /remember feedback 不要自动提交代码
649
- /forget pnpm
650
- ```
651
-
652
- CLI 还提供适合终端和自动化脚本的精确 CRUD。先进入项目目录,再执行:
653
-
654
- ```bash
655
- flavor memory list
656
- flavor memory list --json
657
- flavor memory add project "所有仓库脚本使用 pnpm"
658
- flavor memory update <12位ID> feedback "不要自动提交代码"
659
- flavor memory delete <12位ID>
660
- flavor memory path
661
- ```
662
-
663
- `list` 会输出后续更新和删除所需的稳定 ID;更新内容或类型后会生成新的 ID。`--json` 适合由脚本读取。
664
-
665
- 项目配置支持:
666
-
667
- ```json
668
- {
669
- "memory": {
670
- "enabled": true,
671
- "autoExtract": true,
672
- "autoExtractMinChars": 200,
673
- "scoreThreshold": 9,
674
- "autoStoreThreshold": 11,
675
- "ignoreStreakLimit": 5,
676
- "reviewAutoDismissSeconds": 5,
677
- "maxCandidatesPerTask": 1,
678
- "retrievalTopK": 5,
679
- "maxEntries": 200,
680
- "maxEntryChars": 1000,
681
- "maxPromptChars": 12000
682
- }
683
- }
684
- ```
685
-
686
- 存储更新使用文件锁、备份和原子替换。召回和去重全部在本地完成,不需要向量数据库,也不会为每次查询增加 embedding 调用;当前版本不包含跨设备同步或团队共享。
687
-
688
- ---
689
-
690
- ## 睡眠整理
691
-
692
- 当 Flavor 进程持续运行跨过本地零点时,如果项目配置了 `"sleep": true`,它会自动调用 cheap 模型回顾前一天的项目会话,并生成一份结构化的 Markdown 回顾报告。
693
-
694
- ### 配置
695
-
696
- 在 `.flavor/flavor.json` 中设置:
697
-
698
- ```json
699
- {
700
- "sleep": true
701
- }
702
- ```
703
-
704
- 默认值为 `false`。设为 `true` 后,进程启动即调度零点回调;如果目标日期没有任何 session,不会调用模型或写文件。不同项目的 Flavor 进程各自独立整理自己的 workspace。
705
-
706
- ### 报告内容
707
-
708
- 每份报告生成到 `.flavor/sleep/YYYY-MM-DD-摘要.md`,由宿主渲染 Markdown,模型只负责生成结构化 JSON。报告包含以下章节:
709
-
710
- | 章节 | 说明 |
711
- |------|------|
712
- | 当天任务摘要 | 当天完成的主要工作 |
713
- | 执行情况反思 | 工作方式的回顾和反思 |
714
- | 📊 量化统计 | 工具调用分布、Token 消耗估算、人工干预统计 |
715
- | 关键决策与收获 | 重要的技术决策和经验 |
716
- | 🛡️ 质量与可信度 | 幻觉告警、失败与重试、代码变更概要、整体评估 |
717
- | 🧠 知识沉淀 | 值得记住的技术发现、陷阱和模式 |
718
- | 未决事项与风险 | 尚待解决的问题和潜在风险 |
719
- | 明日可能规划 | 下一步的工作方向建议 |
720
- | 涉及会话 | 被审查的所有 session ID 列表 |
721
-
722
- 报告由宿主渲染 Markdown,模型只负责生成结构化 JSON。文件名中的不安全字符会被规范化,长度最多 60 个中文字符。
723
-
724
- ### 并发安全
725
-
726
- - 同一日期使用排他锁(`.lock` 文件),防止并发进程重复整理
727
- - 报告通过临时文件 + `fsync` + `rename` 原子写入,不会出现半写文件
728
- - 获取锁后会再次检查报告是否已存在,消除 TOCTOU 竞态
729
- - 整理失败(模型错误、解析失败等)不会留下损坏的报告或永久锁文件,下一个零点的定时器保持调度
730
-
731
- 报告写入 `.flavor/sleep/` 目录,可随时手动查看或删除。
732
-
733
- ---
734
-
735
- ## 内置命令
736
-
737
- 交互模式下,以 `/` 开头触发命令:
738
-
739
- | 命令 | 作用 |
740
- |------|------|
741
- | `/model main <provider:model>` | 切换主 Agent 模型 |
742
- | `/model subagent <provider:model>` | 切换子 Agent 模型 |
743
- | `/permissions default\|acceptEdits\|plan\|bypassPermissions\|auto\|bubble` | 切换权限模式 |
744
- | `/init` | 生成或更新 FLAVOR.md |
745
- | `/config` | 查看当前配置(密钥已脱敏) |
746
- | `/skills` | 列出已发现的 Skill |
747
- | `/plugins` | 列出已加载的插件 |
748
- | `/hooks` | 列出 Hook 状态 |
749
- | `/tasks` | 显示当前任务计划与进度 |
750
- | `/audit [toolFilter]` | 查看工具失败审计日志 |
751
- | `/memory` | 查看长期项目记忆及文件路径 |
752
- | `/remember [user\|feedback\|project\|reference] <text>` | 保存一条长期记忆(默认 `project`) |
753
- | `/forget <text-or-id>` | 删除匹配的长期记忆 |
754
- | `/finish` | 完成当前任务,并在达到门槛时评价长期记忆候选 |
755
- | `/compact` | 强制压缩上下文 |
756
- | `/clear` | 清空终端显示 |
757
- | `/mcp [status\|tools\|reconnect\|enable\|disable]` | 管理 MCP 服务器 |
758
- | `/ide` | 查看 VS Code 连接、活动文件、光标和选区 |
759
- | `/loop <goal>` | 启动经验证的前台自治循环 |
760
- | `/goal <objective>` | 启动对抗性审查流水线(Plan → Execute → Verify) |
761
- | `/help` | 显示帮助 |
762
- | `/exit` | 退出 |
763
-
764
- 输入 `/` 后弹出交互式菜单,列出所有可用命令(内置 + 插件 + Skill),支持模糊匹配和实时过滤。还可以直接输入 `/<skill-name>` 调用某个 Skill,或 `/<plugin-command>` 执行插件命令。
765
-
766
- ---
767
-
768
- ## 权限模式
769
-
770
- 为了安全,Flavor 提供六种权限模式。旧配置会自动迁移:`safe` / `workspace` → `default`,`full` → `bypassPermissions`。
771
-
772
- | 模式 | 读文件 | 写文件 | Shell | 网络 | 破坏性操作 |
773
- |------|--------|--------|-------|------|------------|
774
- | **default**(默认) | 自动放行 | 需确认 | 需确认 | 需确认 | 需确认 |
775
- | **acceptEdits** | 自动放行 | 工作区内自动放行 | 例行验证自动放行 | 需确认 | 需确认 |
776
- | **plan** | 自动放行 | 拒绝 | 拒绝 | 拒绝 | 拒绝 |
777
- | **bypassPermissions** | 自动放行 | 自动放行 | 通过硬安全检查后放行 | 主 Agent 放行 | 通过硬安全检查后放行 |
778
- | **auto** | 自动放行 | 工作区内自动放行 | AI 分类 | AI 分类 | AI 分类 |
779
- | **bubble** | 自动放行 | 冒泡审批 | 例行验证自动放行,其余冒泡 | 冒泡审批 | 冒泡审批 |
780
-
781
- 子 Agent 使用 **bubble** 模式,把无法本地判定的请求交给主会话审批;主会话处于 **plan** 时,子 Agent 同样只读。`auto` 分类器不可用或不确定时会退回人工确认。权限系统是纵深防御,但它不是操作系统级别的沙箱——被批准的命令仍然以你的用户权限运行。
782
-
783
- 配置写入使用排他锁、锁内重读、`.bak` 备份和原子替换。全局 `~/.flavor-code/flavor.json` 的敏感字段与 OAuth `auth.json` 使用 AES-256-GCM 认证加密;旧明文数据会在读取/下一次保存时迁移。
784
-
785
- ---
786
-
787
- ## 任务计划与子 Agent 并行
788
-
789
- 当你提出复杂需求时,Flavor 会先制定任务计划,然后逐步推进。终端显示实时进度面板:
790
-
791
- ```
792
- ── task progress ──
793
- ✓ 分析项目结构
794
- ⟳ 重构配置加载模块 (1.2s)
795
- ○ 更新测试用例
796
- ○ 更新文档
797
- ```
798
-
799
- 独立子任务会被分派给子 Agent **并行处理**:多个子 Agent 同时工作,每个使用独立的上下文窗口和便宜模型,完成后返回结构化结果。一次 DAG 调度中的子 Agent 从同一份父上下文快照 fork,只在末尾追加各自任务,因此可共享字节一致的缓存前缀;任何子 Agent 的后续消息和压缩都不会回写父会话。最大并行数由 `maxSubagents` 配置(默认 3,最大 16)。
800
-
801
- ---
802
-
803
- ## Skill(技能包)
804
-
805
- Skill 是放在 `.flavor/skills/` 或全局 `~/.flavor-code/skills/` 下的 Markdown 包,用来教 Flavor 处理特定场景。每个 Skill 是一个含 `SKILL.md` 的目录:
806
-
807
- ```markdown
808
- ---
809
- name: code-review
810
- description: Review code for common issues
811
- ---
812
-
813
- # Code Review
814
-
815
- 检查代码时关注:
816
- 1. 类型安全
817
- 2. 错误处理
818
- 3. 命名规范
819
- 4. 可测试性
820
-
821
- 参考 `references/checklist.md` 中的详细清单。
822
- ```
823
-
824
- 当你提问时,Flavor 自动匹配相关 Skill 并加载指导。也可以直接输入 `/code-review` 显式调用。Skill 正文中的资源(`assets/`、`references/`、`scripts/`)只有被显式引用才能被访问。
825
-
826
- 桌面端点击侧栏“技能”可打开管理工作台。项目 Skill(`.flavor/skills/`)支持完整增删改查;全局和插件提供的 Skill 以只读方式展示,但仍可为当前项目开启或关闭。关闭后,自动匹配、显式调用和 Skill 资源读取都会拒绝该 Skill。状态保存在当前项目的 `.flavor/flavor.json`:
827
-
828
- ```json
829
- {
830
- "skills": {
831
- "disabled": ["code-review"]
832
- }
833
- }
834
- ```
835
-
836
- CLI 与桌面端共享这套配置语义,并提供轻量的启停命令:
837
-
838
- ```bash
839
- flavor skills list
840
- flavor skills disable code-review
841
- flavor skills enable code-review
842
- ```
843
-
844
- ---
845
-
846
- ## 插件
847
-
848
- 插件放在 `.flavor/plugins/` 下,可以注册自定义命令、工具、Hook、Skill 根目录等。插件命令可以直接通过 `/command-name` 调用。
849
-
850
- > ⚠️ 插件是进程内运行的 Node.js 代码,不是沙箱隔离。请只加载你信任的插件。
851
-
852
- ### Agent 自注册工具与热加载
853
-
854
- CLI 和桌面端都向主 Agent 提供三个管理工具:`RegisterTool`、`RemoveTool` 和 `ListRegisteredTools`。它们是 Agent 可调用的结构化工具,不是 `/registerTool` 斜杠命令。直接用自然语言说明要创建的持久能力即可,例如:
855
-
856
- ```text
857
- 创建一个项目级工具 EchoUpper,参数是字符串 text,返回它的大写形式;创建后马上调用它处理 "flavor code"。
858
- ```
859
-
860
- Agent 会生成 JSON Schema 和 async JavaScript 实现,申请写入权限,然后调用 `RegisterTool`。注册成功后,无需重启或输入 `/reload`,同一次任务的下一次模型调用就能看到并调用 `EchoUpper`。项目工具保存在 `.flavor/tools/`;要求 `scope: "global"` 时保存在 `~/.flavor-code/tools/`,以后启动仍会加载。
861
-
862
- 工具实现接收三个变量:`input` 是已按 JSON Schema 校验的参数,`signal` 用于取消,`context` 包含 `workspace`、`scope` 和 `toolName`。`implementation` 既可以是必须显式 `return` 的函数体,也可以是完整的普通函数、async 函数或箭头函数表达式;这些形式都可以使用 `await import("node:...")`。等价的注册内容示例:
863
-
864
- ```json
865
- {
866
- "name": "EchoUpper",
867
- "description": "Uppercase the provided text",
868
- "inputSchema": {
869
- "type": "object",
870
- "properties": { "text": { "type": "string" } },
871
- "required": ["text"],
872
- "additionalProperties": false
873
- },
874
- "implementation": "return { value: input.text.toUpperCase() };",
875
- "scope": "project",
876
- "agents": ["main"]
877
- }
878
- ```
879
-
880
- 管理同样使用自然语言:
881
-
882
- ```text
883
- 列出你注册过的持久工具。
884
- 删除项目级 EchoUpper 工具。
885
- ```
886
-
887
- 注册是仅新增语义,不会覆盖已有工具。需要修改时,先用 `RemoveTool` 删除,再重新注册。删除只允许作用于这套机制创建的记录,不会删除内置、插件或 MCP 工具。Agent 也可能在长任务中发现明确、可复用的重复操作后建议自动创建工具,但一次性操作不应持久化;写入和删除仍经过正常权限确认。
888
-
889
- > ⚠️ 自注册工具与普通插件一样,是进程内运行的可信 JavaScript,不是安全沙箱。确认注册前应审阅 Agent 展示的用途和权限请求;首次调用自定义工具也会按当前权限策略进行确认。
890
-
891
- ---
892
-
893
- ## 控制面、会话树与自动化
894
-
895
- CLI 运行期间按 Enter 会保存一条待发送任务,显示在输入框上方,并在当前 SSE 完整结束后自动提交;待发送槽最多一条。按 Esc 会取消待发送并把内容回填输入框。运行中输入 `/steer <指令>` 可显式发送 steering。桌面端和 VS Code 继续使用普通发送进行 steering、`Alt+Enter` 排队 follow-up。Steering 不会打断正在传输的单次模型响应;它会在完整工具批次之后、下一次模型请求之前注入。CLI 内可用以下历史命令:
896
-
897
- ```text
898
- /checkpoint [标签] 保存当前上下文和工作区
899
- /tree 查看追加式会话节点
900
- /rewind <节点 ID> 恢复节点的文件、上下文和活动分支
901
- /unrevert 撤销最近一次 rewind
902
- /fork <节点 ID> 只移动上下文和分支,不修改文件
903
- ```
904
-
905
- 非交互调用可通过公开 SDK:
906
-
907
- ```ts
908
- import { createFlavorRuntime } from "flavor-code/sdk";
909
-
910
- const runtime = await createFlavorRuntime({
911
- workspace: process.cwd(),
912
- approvalPolicy: "deny",
913
- output: console.log,
914
- });
915
- await runtime.session.start();
916
- await runtime.session.submit("修复测试");
917
- await runtime.dispose();
918
- ```
919
-
920
- 其他语言和 IDE 可启动严格 JSONL 协议:
921
-
922
- ```bash
923
- flavor --mode rpc --workspace . --trace .flavor/traces/run.jsonl
924
- ```
925
-
926
- RPC 支持 `prompt`、`steer`、`follow_up`、`abort`、队列查询、checkpoint/tree/rewind/fork 和 `shutdown`。每行必须是单个 JSON 对象;输出也是逐行 response/event。
927
-
928
- 评测文件示例:
929
-
930
- ```json
931
- {
932
- "name": "fix-parser",
933
- "workspace": "./fixture",
934
- "prompt": "Fix the parser",
935
- "verification": [{ "command": "npm", "args": ["test"], "timeoutMs": 120000 }],
936
- "maxTokens": 200000
937
- }
938
- ```
939
-
940
- ```bash
941
- flavor eval eval.json --output report.json
942
- ```
943
-
944
- ## Docker 沙箱
945
-
946
- 本地执行仍是默认行为。在项目 `.flavor/flavor.json` 中显式启用 Docker:
947
-
948
- ```json
949
- {
950
- "execution": {
951
- "mode": "docker",
952
- "image": "node:24-bookworm-slim",
953
- "network": false,
954
- "memory": "2g",
955
- "cpus": 2
956
- }
957
- }
958
- ```
959
-
960
- 需要预先安装并启动 Docker。默认容器禁止网络、使用只读根文件系统、移除 capabilities,并限制进程数、内存和 CPU;工作区以 `/workspace` 绑定挂载。Docker 不可用时命令会失败并保持在沙箱模式,不会静默回退到本机。
961
-
962
- ## VS Code
963
-
964
- 从源码安装或更新扩展时,在仓库根目录运行一条命令即可。脚本会构建 CLI 和扩展、生成 VSIX、覆盖安装并核对版本:
965
-
966
- ```bash
967
- npm run qoder:install # 安装到 Qoder
968
- npm run vscode:install # 安装到 VS Code
969
- npm run ide:install # 自动优先选择 Qoder,其次 VS Code
970
- ```
971
-
972
- IDE 已打开时,安装完成后执行一次 **Developer: Reload Window**。生成的 VSIX 会保留在 `release/flavor-code-vscode-<version>.vsix`。
973
-
974
- 扩展源码位于 `extensions/vscode`。仅做开发调试时可手动构建:
975
-
976
- ```bash
977
- npm run build:cli
978
- npm run vscode:build
979
- npm link
980
- ```
981
-
982
- 在 VS Code 的 Extension Development Host 中加载该目录。扩展会在启动完成后注册一个仅监听 loopback、带随机令牌认证的 IDE bridge;从同一工作区启动的 `flavor` 会自动发现它。CLI 中运行 `/ide` 可查看活动文件、光标和选区,普通提示提交时也会自动附带这份最新编辑器上下文。终端底部右侧会实时显示 `In <文件名>`、`1 line selected` 或 `N lines selected`。
983
-
984
- 点击 Activity Bar 中的 Flavor 气泡可打开原生工作台:**Mission Control** 展示任务计划、子 Agent、工具、loop 与 token 状态,**Changes & Health** 聚合 Problems、Git 变更和 Agent 文件足迹,**Time Machine** 提供 checkpoint、rewind、fork 与 undo-rewind。扩展还注册 `@flavor` Chat Participant、诊断 Quick Fix、函数/类 CodeLens、Test Explorer 修复入口、代码导览和对抗性审查命令。从同一工作区终端手动启动的 `flavor` 会通过 IDE bridge v2 注册并把实时任务事件转发到 Mission Control;提示输入和取消操作仍由原终端负责。
985
-
986
- 执行 `Flavor: Start Agent` 仍可由扩展直接启动 RPC Agent;扩展同时支持对选区执行任务、修复 Problems 诊断、steering、follow-up、停止、checkpoint、查看树和 rewind。VS Code 发起的编辑任务默认先创建可恢复 checkpoint,可用 `flavorCode.autoCheckpoint` 关闭。若 `flavor` 不在 `PATH`,请配置 `flavorCode.executable` 为 CLI 的绝对路径。IDE bridge 不包含内联代码补全;补全需要单独的低延迟 completion 服务和 VS Code `InlineCompletionItemProvider`。
987
-
988
- ---
989
-
990
- ## 审计日志
991
-
992
- 每次工具执行失败都会被记录到 `.flavor/audit.jsonl`,包含时间戳、会话 ID、工具名、Agent 角色和错误信息:
993
-
994
- ```bash
995
- /audit # 查看所有工具失败汇总
996
- /audit Shell # 按工具名过滤
997
- ```
998
-
999
- ---
1000
-
1001
- ## 项目文件结构
1002
-
1003
- Flavor 相关的文件都放在 `.flavor/` 目录下:
1004
-
1005
- ```
1006
- .flavor/
1007
- ├── flavor.json # 项目级配置
1008
- ├── goal-plan.md # /goal 生成的验收契约
1009
- ├── sessions/ # 会话存档(v2 JSONL 格式)
1010
- │ └── session-xxx.jsonl
1011
- ├── session-trees/ # 追加式会话分支和上下文节点
1012
- ├── checkpoints/ # 内容寻址的工作区对象与 manifest
1013
- ├── memory/ # 跨会话长期记忆
1014
- │ └── MEMORY.md
1015
- ├── sleep/ # 睡眠整理每日报告
1016
- │ └── YYYY-MM-DD-摘要.md
1017
- ├── audit.jsonl # 工具失败审计日志
1018
- ├── skills/ # 项目 Skill
1019
- └── plugins/ # 项目插件
1020
- ```
1021
-
1022
- ---
1023
-
1024
- ## 安全须知
1025
-
1026
- - AI 模型的输出不一定总是正确或安全的,请审查它生成的代码
1027
- - Skill 和插件中的内容应视为潜在不可信输入
1028
- - 本地模式中,被批准执行的 shell 命令以你的用户身份运行;不可信任务建议启用 Docker 模式
1029
- - 不要将 `.flavor/sessions/` 中的会话文件当作秘密仓库
1030
- - 建议在版本控制下使用、配置最小权限的 API Key
1031
-
1032
- ---
1033
-
1034
- ## 开发
1035
-
1036
- ```bash
1037
- npm ci # 安装依赖
1038
- npm test # 跑测试
1039
- npm run test:watch # 监听模式
1040
- npm run typecheck # 类型检查
1041
- npm run build # 构建
1042
- npm run smoke:install # 验证打包和安装
1043
- ```
1044
-
1045
- - **语言**:TypeScript(strict 模式,ES2022 目标)
1046
- - **构建**:tsup → ESM `dist/cli.js`
1047
- - **测试**:Vitest,零真实凭据
1048
- - **CI**:Windows / macOS × Node 20 / 24
1049
-
1050
- ---
1051
-
1052
- ## 路线图
1053
-
1054
- 后续方向包括(这些是未来规划,非 1.1.0 已交付能力):
1055
-
1056
- - `/loop` 的后台恢复、调度与并发 loop 管理
1057
- - 长期记忆的全文/语义检索和质量整合
1058
- - 更细粒度的任务恢复与重放
1059
- - JetBrains 扩展
1060
- - 系统凭据存储(keychain 集成)
1061
- - 插件隔离/签名验证
1062
- - 跨设备会话
1063
-
1064
- ---
1065
-
1066
- ## 技术架构
1067
-
1068
- 详细技术方案请参阅 [技术方案报告](./技术方案报告.md),涵盖:
1069
-
1070
- - 系统架构拓扑与全链路时序
1071
- - Agent 核心循环(迭代控制、流式处理、工具执行)
1072
- - 三级上下文压缩(微压缩、模型摘要、反应式压缩)
1073
- - 任务系统(TaskPlan 六状态机、子 Agent DAG 并行调度)
1074
- - Provider 适配层与错误标准化
1075
- - **PKCE 到 SSE 全链路(OAuth 授权 → API 网关 → 流式代理)**
1076
- - **事故上报与 RCA(PostToolUseFailure → langgraph-claw → 自动根因分析)**
1077
- - **对抗性审查流水线(Plan → Execute → Skeptic Panel 多数投票 → 停滞检测熔断)**
1078
- - **多模态图片支持(剪贴板/文件选择器 → 验证存储 → Provider-Native 翻译 → 混合内容上下文管理)**
1079
- - 权限引擎决策树与 Shell 安全分析
1080
- - Hook 事件总线(19 个事件)
1081
- - Skill 渐进加载与资源安全
1082
- - 插件生命周期与信任模型
1083
- - 会话 JSONL 持久化与 v1/v2 兼容
1084
- - 安全威胁模型与缓解措施
1085
-
1086
- ---
1087
-
1088
- ## License
1089
-
1090
- 见 [LICENSE](./LICENSE) 文件。
1
+ <p align="center"><b><a href="./README.md">English</a></b> | <a href="./README.zh-CN.md">简体中文</a></p>
2
+
3
+ <div align="center">
4
+ <img src="./assets/icon-transparent-512.png" alt="Flavor Code Logo" width="168" />
5
+ <h1>Flavor Code</h1>
6
+ <p><strong>Local-first, auditable, resumable AI coding assistant</strong></p>
7
+ <p>Read code, edit files, run commands, and complete complex tasks in the terminal, Electron desktop, and VS Code.</p>
8
+
9
+ <p>
10
+ <a href="https://www.npmjs.com/package/flavor-code"><img alt="npm version" src="https://img.shields.io/npm/v/flavor-code?color=cb3837&logo=npm" /></a>
11
+ <a href="https://github.com/YachuanWzh/flavor-code/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/YachuanWzh/flavor-code/actions/workflows/ci.yml/badge.svg?branch=main" /></a>
12
+ <img alt="Node.js 20+" src="https://img.shields.io/badge/Node.js-20%2B-339933?logo=nodedotjs&logoColor=white" />
13
+ <a href="./LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-blue.svg" /></a>
14
+ </p>
15
+
16
+ <p>
17
+ <a href="#quick-start">Quick Start</a> ·
18
+ <a href="#features">Features</a> ·
19
+ <a href="#entry-points">Entry Points</a> ·
20
+ <a href="#permissions--sandbox">Security</a> ·
21
+ <a href="#development">Development</a>
22
+ </p>
23
+ </div>
24
+
25
+ ---
26
+
27
+ Flavor Code connects to OpenAI, Anthropic, or compatible services and works with file, search, Shell, MCP, and custom tools inside a controlled workspace. Complex tasks can be broken into plans and parallel sub-tasks; sessions, diffs, tool calls, checkpoints, and audit records are all stored locally so you can resume, review, and continue at any time.
28
+
29
+ ## Features
30
+
31
+ | | Capability | What you get |
32
+ | --- | --- | --- |
33
+ | 🖥️ | **One runtime, three entry points** | CLI, Electron, and VS Code share model configuration, sessions, and tooling |
34
+ | 🧭 | **Controlled progress on complex tasks** | Task plans, sub-agents, steering, follow-ups, `/loop`, and `/goal` |
35
+ | ⏪ | **Traceable, resumable results** | Full timeline, checkpoints, rewind, traces, diffs, and failure audits |
36
+ | 🧠 | **Local long-term context** | Memory, Skills, plugins, and project guides stored on your machine |
37
+ | 🛡️ | **Clear permission boundaries** | Independent control over read, write, Shell, network, and destructive actions; Docker supported |
38
+
39
+ ## Quick Start
40
+
41
+ > [!IMPORTANT]
42
+ > The CLI requires Node.js 20 or later. Windows desktop builds can also be downloaded directly from [Releases](https://github.com/YachuanWzh/flavor-code/releases).
43
+
44
+ **1. Install**
45
+
46
+ ```bash
47
+ npm install -g flavor-code
48
+ ```
49
+
50
+ **2. Start in your project**
51
+
52
+ ```bash
53
+ cd your-project
54
+ flavor
55
+ ```
56
+
57
+ **3. Initialize project context**
58
+
59
+ Run `/init` the first time you enter a project. Flavor analyzes the language, package manager, source directories, and verification commands, then generates a `FLAVOR.md` project guide.
60
+
61
+ You can also run one-off tasks directly:
62
+
63
+ ```bash
64
+ flavor --print "Analyze this project and list the top three issues worth fixing"
65
+ flavor --resume
66
+ flavor --resume -p "Continue the remaining work"
67
+ ```
68
+
69
+ Non-interactive mode refuses actions that require human approval and never hangs waiting for input.
70
+
71
+ ## Configuring Models
72
+
73
+ The fastest way is to set environment variables:
74
+
75
+ ```bash
76
+ # macOS / Linux
77
+ export OPENAI_API_KEY="sk-..."
78
+
79
+ # Windows PowerShell
80
+ $env:OPENAI_API_KEY = "sk-..."
81
+ ```
82
+
83
+ You can also put the key in a `.env` file at the project root.
84
+
85
+ <details>
86
+ <summary><strong>Configure multiple providers with <code>.flavor/flavor.json</code></strong></summary>
87
+
88
+ Example project configuration:
89
+
90
+ ```json
91
+ {
92
+ "providers": {
93
+ "openai": {
94
+ "type": "openai",
95
+ "apiKey": "${OPENAI_API_KEY}",
96
+ "defaultModel": "gpt-5",
97
+ "cheapModel": "gpt-5-mini"
98
+ }
99
+ },
100
+ "agents": {
101
+ "main": { "model": "openai:gpt-5" },
102
+ "subagent": { "model": "openai:gpt-5-mini" }
103
+ },
104
+ "permissionMode": "default",
105
+ "maxSubagents": 3,
106
+ "language": "zh-CN"
107
+ }
108
+ ```
109
+
110
+ Configuration is merged in the following order, with later sources taking precedence:
111
+
112
+ 1. Global `~/.flavor-code/flavor.json`
113
+ 2. Project `.flavor/flavor.json`
114
+ 3. `.env`
115
+ 4. Process environment variables
116
+
117
+ Commonly supported provider types:
118
+
119
+ - `openai`: OpenAI's official API
120
+ - `anthropic`: Anthropic's official API
121
+ - `openai-compatible`: Services compatible with the OpenAI protocol
122
+
123
+ </details>
124
+
125
+ Runtime behavior and configuration conventions for OAuth PKCE are described in the [PKCE spec](./docs/specs/pkce-runtime-config.md). The [config schema](./src/config/schema.ts) is the source of truth for all fields.
126
+
127
+ ## Entry Points
128
+
129
+ | Entry point | Best for | How to start |
130
+ | --- | --- | --- |
131
+ | **CLI** | Daily development, remote environments, scripting, and CI | `flavor` |
132
+ | **Electron** | Visual sessions, diffs, permissions, and resource management | `npm run desktop:start` |
133
+ | **VS Code / Qoder** | Editor context, diagnostic fixes, and a task control plane | `npm run ide:install` |
134
+
135
+ ### CLI
136
+
137
+ Run `flavor` and type natural language. Typing `/` shows built-in commands, plugin commands, and Skills.
138
+
139
+ Common commands:
140
+
141
+ | Command | Purpose |
142
+ | --- | --- |
143
+ | `/init` | Generate or update `FLAVOR.md` |
144
+ | `/model` | View or switch main/sub-agent models |
145
+ | `/permissions` | Switch permission modes |
146
+ | `/tasks` | View task plans and sub-agent status |
147
+ | `/compact` | Manually compact long session context |
148
+ | `/checkpoint`, `/tree` | Save state, view the session tree |
149
+ | `/rewind`, `/unrevert`, `/fork` | Resume or fork sessions |
150
+ | `/memory`, `/remember`, `/forget` | Manage long-term memory |
151
+ | `/mcp` | View and manage MCP servers |
152
+ | `/loop <goal>` | Run an autonomous loop with verification |
153
+ | `/goal <objective>` | Run the plan, execute, adversarial-review workflow |
154
+ | `/audit` | View tool failure audits |
155
+
156
+ You can submit steering or queue follow-ups while a run is in progress; once the current model response finishes, the task picks up new instructions at safe boundaries.
157
+
158
+ ### Electron Desktop
159
+
160
+ ```bash
161
+ npm run desktop:dev # dev mode
162
+ npm run desktop:start # build and start
163
+ npm run desktop:pack # Windows portable directory
164
+ npm run desktop:dist # Windows NSIS installer
165
+ ```
166
+
167
+ The desktop app provides project and session switching, streaming Markdown, tool and diff views, permission confirmations, task status, and management of Skills, MCP, memory, and models.
168
+
169
+ ### VS Code / Qoder
170
+
171
+ ```bash
172
+ npm run vscode:install # install into VS Code
173
+ npm run qoder:install # install into Qoder
174
+ npm run ide:install # auto-select the installed IDE
175
+ ```
176
+
177
+ The extension includes the `@flavor` Chat Participant, Mission Control, Changes & Health, Time Machine, diagnostic fixes, CodeLens, checkpoints, and rewind. If `flavor` is not on your `PATH`, set `flavorCode.executable`.
178
+
179
+ ## MCP, Skills & Plugins
180
+
181
+ Flavor can connect to stdio or Streamable HTTP MCP servers. Example project configuration:
182
+
183
+ <details>
184
+ <summary><strong>MCP configuration and CLI examples</strong></summary>
185
+
186
+ ```json
187
+ {
188
+ "mcpServers": {
189
+ "docs": {
190
+ "url": "https://example.com/mcp",
191
+ "headers": {
192
+ "Authorization": "Bearer ${MCP_TOKEN}"
193
+ }
194
+ }
195
+ }
196
+ }
197
+ ```
198
+
199
+ MCP configuration can also be managed from the CLI:
200
+
201
+ ```bash
202
+ flavor mcp list
203
+ flavor mcp add docs --url https://example.com/mcp
204
+ flavor mcp disable docs
205
+ ```
206
+
207
+ </details>
208
+
209
+ A Skill is a `SKILL.md` with YAML frontmatter, placed in `.flavor/skills/<name>/` or `~/.flavor-code/skills/<name>/`. Flavor loads skills progressively based on the task, and you can invoke one explicitly with `/<skill-name>`.
210
+
211
+ Plugins live in `.flavor/plugins/` and can register commands, tools, hooks, Skill roots, and model adapters.
212
+
213
+ > [!WARNING]
214
+ > Plugins and agent self-registered tools are in-process JavaScript, not a security sandbox. Only install, enable, and approve code you trust.
215
+
216
+ ## Sessions, Memory & Execution Records
217
+
218
+ Project runtime data lives under `.flavor/`:
219
+
220
+ ```text
221
+ .flavor/
222
+ ├── flavor.json # Project config
223
+ ├── sessions/ # Session timelines
224
+ ├── session-assets/ # Image attachments
225
+ ├── session-trees/ # Session branches
226
+ ├── checkpoints/ # Workspace snapshots
227
+ ├── memory/ # Long-term memory
228
+ ├── traces/ # Optional execution traces
229
+ ├── audit.jsonl # Tool failure audits
230
+ ├── skills/ # Project skills
231
+ └── plugins/ # Project plugins
232
+ ```
233
+
234
+ Long-term memory distinguishes user preferences, behavioral feedback, project conventions, and external references. Automatic extraction only keeps high-confidence candidates and provides confirm, ignore, and delete actions; secrets, tokens, raw tool output, and model guesses are rejected.
235
+
236
+ Image prompts support PNG, JPEG, and WebP, with a 5 MiB per-image maximum and up to 5 images per prompt. The desktop app supports picking or drag-and-drop; CLI clipboard images currently work on Windows and macOS.
237
+
238
+ ## Permissions & Sandbox
239
+
240
+ | Mode | Behavior |
241
+ | --- | --- |
242
+ | `default` | Reads are auto-approved; writes, Shell, network, and destructive actions are confirmed on demand |
243
+ | `acceptEdits` | Workspace writes and routine verification are auto-approved |
244
+ | `plan` | Read-only planning; no modifications or execution |
245
+ | `bypassPermissions` | The main agent executes as much as possible after hard safety checks |
246
+ | `auto` | A classifier decides, falling back to human approval when uncertain |
247
+ | `bubble` | Uncertain operations bubble up to the main session for approval |
248
+
249
+ > [!CAUTION]
250
+ > Local Shell still runs as your current user. Consider enabling Docker when working with untrusted projects.
251
+
252
+ <details>
253
+ <summary><strong>Docker execution environment example</strong></summary>
254
+
255
+ ```json
256
+ {
257
+ "execution": {
258
+ "mode": "docker",
259
+ "image": "node:24-bookworm-slim",
260
+ "network": false,
261
+ "memory": "2g",
262
+ "cpus": 2
263
+ }
264
+ }
265
+ ```
266
+
267
+ If Docker is unavailable, tasks fail rather than silently falling back to the host. Sensitive fields in config files and OAuth tokens are encrypted at rest with AES-256-GCM using a local configuration key.
268
+
269
+ </details>
270
+
271
+ ## SDK, RPC & Evaluation
272
+
273
+ <details>
274
+ <summary><strong>Node.js SDK example</strong></summary>
275
+
276
+ ```ts
277
+ import { createFlavorRuntime } from "flavor-code/sdk";
278
+
279
+ const runtime = await createFlavorRuntime({
280
+ workspace: process.cwd(),
281
+ approvalPolicy: "deny",
282
+ output: console.log,
283
+ });
284
+
285
+ await runtime.session.start();
286
+ await runtime.session.submit("fix the failing tests");
287
+ await runtime.dispose();
288
+ ```
289
+
290
+ </details>
291
+
292
+ Other IDEs or languages can integrate over JSONL RPC:
293
+
294
+ ```bash
295
+ flavor --mode rpc --workspace . --trace .flavor/traces/run.jsonl
296
+ ```
297
+
298
+ Run evaluations:
299
+
300
+ ```bash
301
+ flavor eval eval.json --output report.json
302
+ ```
303
+
304
+ Design constraints for RPC, traces, replay, eval, session trees, and Docker are in the [control-plane spec](./docs/specs/2026-07-29-control-plane-sandbox-vscode.md).
305
+
306
+ ## Development
307
+
308
+ ```bash
309
+ npm ci
310
+ npm test
311
+ npm run typecheck
312
+ npm run vscode:typecheck
313
+ npm run build
314
+ npm run smoke:install
315
+ ```
316
+
317
+ - TypeScript strict, targeting ES2022, Node.js 20+
318
+ - Vitest for unit and integration tests
319
+ - tsup builds the CLI, SDK, Electron main process, and VS Code extension
320
+ - Vite builds the Electron renderer
321
+ - CI covers Windows/macOS with Node 20/24
322
+
323
+ Release builds do not generate or package source maps by default. For a local debugging build, enable them explicitly:
324
+
325
+ ```bash
326
+ # macOS / Linux
327
+ FLAVOR_SOURCEMAP=1 npm run build
328
+
329
+ # Windows PowerShell
330
+ $env:FLAVOR_SOURCEMAP = "1"
331
+ npm run build
332
+ ```
333
+
334
+ ## Documentation
335
+
336
+ - [Technical Design Report](./技术方案报告.md): overall architecture, agent loop, context, permissions, plugins, and security model
337
+ - [Runtime reliability spec](./docs/specs/2026-07-26-runtime-reliability.md)
338
+ - [Control plane, sandbox & VS Code spec](./docs/specs/2026-07-29-control-plane-sandbox-vscode.md)
339
+ - [Multimodal image attachments spec](./docs/specs/2026-07-30-multimodal-image-attachments.md)
340
+ - [VS Code next steps](./docs/specs/2026-08-01-flavor-code-vscode-next.md)
341
+
342
+ ## Security Notes
343
+
344
+ - Review model-generated code and commands, especially dependency installs, scripts, and deletions.
345
+ - Do not treat `.flavor/sessions/`, traces, or long-term memory as secret stores.
346
+ - Use least-privilege API keys and never commit `.env`.
347
+ - Skill content can influence model behavior; plugins and self-registered tools also have in-process Node.js permissions.
348
+ - Work under version control and create checkpoints before high-risk tasks.
349
+
350
+ ## Contributing
351
+
352
+ Issues and Pull Requests are welcome. Please at least run the following before submitting:
353
+
354
+ ```bash
355
+ npm test
356
+ npm run typecheck
357
+ npm run vscode:typecheck
358
+ npm run build
359
+ ```
360
+
361
+ For architecture changes, read the [Technical Design Report](./技术方案报告.md) and the relevant [design specs](./docs/specs/) first.
362
+
363
+ ## License
364
+
365
+ [MIT](./LICENSE)
366
+
367
+ <p align="center">
368
+ Made with 🌶️ by Flavor Code contributors.
369
+ </p>