@tencent-ai/agent-sdk 0.3.157 → 0.3.159

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 (65) hide show
  1. package/cli/CHANGELOG.md +58 -0
  2. package/cli/README.md +2 -0
  3. package/cli/dist/codebuddy-headless.js +862 -790
  4. package/cli/dist/web-ui/assets/index-DOB9MrWi.css +32 -0
  5. package/cli/dist/web-ui/assets/{index-bVNRRvKC.js → index-DlV6l3G1.js} +191 -168
  6. package/cli/dist/web-ui/assets/workbox-window.prod.es5-BBnX5xw4.js +2 -0
  7. package/cli/dist/web-ui/docs/cn/cli/goal.md +161 -0
  8. package/cli/dist/web-ui/docs/cn/cli/hooks.md +12 -4
  9. package/cli/dist/web-ui/docs/cn/cli/monitoring.md +117 -29
  10. package/cli/dist/web-ui/docs/cn/cli/release-notes/README.md +3 -0
  11. package/cli/dist/web-ui/docs/cn/cli/release-notes/v2.98.0.md +48 -0
  12. package/cli/dist/web-ui/docs/cn/cli/release-notes/v2.98.1.md +19 -0
  13. package/cli/dist/web-ui/docs/cn/cli/release-notes/v2.99.0.md +39 -0
  14. package/cli/dist/web-ui/docs/cn/cli/slash-commands.md +1 -0
  15. package/cli/dist/web-ui/docs/en/cli/goal.md +161 -0
  16. package/cli/dist/web-ui/docs/en/cli/hooks.md +10 -2
  17. package/cli/dist/web-ui/docs/en/cli/monitoring.md +118 -30
  18. package/cli/dist/web-ui/docs/en/cli/release-notes/README.md +3 -0
  19. package/cli/dist/web-ui/docs/en/cli/release-notes/v2.98.0.md +48 -0
  20. package/cli/dist/web-ui/docs/en/cli/release-notes/v2.98.1.md +19 -0
  21. package/cli/dist/web-ui/docs/en/cli/release-notes/v2.99.0.md +39 -0
  22. package/cli/dist/web-ui/docs/en/cli/slash-commands.md +1 -0
  23. package/cli/dist/web-ui/docs/search-index-en.json +1 -1
  24. package/cli/dist/web-ui/docs/search-index-zh.json +1 -1
  25. package/cli/dist/web-ui/docs/sidebar-en.json +1 -1
  26. package/cli/dist/web-ui/docs/sidebar-zh.json +1 -1
  27. package/cli/dist/web-ui/index.html +2 -2
  28. package/cli/dist/web-ui/sw.js +1 -1
  29. package/cli/dist/web-ui/{workbox-e082a648.js → workbox-fed2bdfe.js} +1 -1
  30. package/cli/package.json +3 -2
  31. package/cli/product.cloudhosted.json +4 -3
  32. package/cli/product.internal.json +6 -3
  33. package/cli/product.ioa.json +25 -3
  34. package/cli/product.json +31 -7
  35. package/cli/product.selfhosted.json +4 -3
  36. package/cli/vendor/sandbox/sandbox-cli +0 -0
  37. package/lib/auth.js +3 -2
  38. package/lib/auth.js.map +1 -1
  39. package/lib/connect.js +3 -2
  40. package/lib/connect.js.map +1 -1
  41. package/lib/index.js +1 -1
  42. package/lib/mcp/create-sdk-mcp-server.js +3 -2
  43. package/lib/mcp/create-sdk-mcp-server.js.map +1 -1
  44. package/lib/plugin.js +13 -22
  45. package/lib/plugin.js.map +1 -1
  46. package/lib/query.d.ts.map +1 -1
  47. package/lib/query.js +2 -2
  48. package/lib/query.js.map +1 -1
  49. package/lib/session.js +4 -4
  50. package/lib/session.js.map +1 -1
  51. package/lib/transport/index.js +2 -2
  52. package/lib/transport/index.js.map +1 -1
  53. package/lib/transport/process-transport.js +7 -17
  54. package/lib/transport/process-transport.js.map +1 -1
  55. package/lib/utils/cli-resolver.js +6 -6
  56. package/lib/utils/cli-resolver.js.map +1 -1
  57. package/lib/utils/env-utils.js +2 -1
  58. package/lib/utils/env-utils.js.map +1 -1
  59. package/lib/utils/process.js +2 -1
  60. package/lib/utils/process.js.map +1 -1
  61. package/lib/utils/type-guards.js +2 -1
  62. package/lib/utils/type-guards.js.map +1 -1
  63. package/package.json +1 -1
  64. package/cli/dist/web-ui/assets/index-CY6b2fbj.css +0 -32
  65. package/cli/dist/web-ui/assets/workbox-window.prod.es5-BIl4cyR9.js +0 -2
@@ -0,0 +1,2 @@
1
+ try{self["workbox:window:7.4.0"]&&_()}catch{}function b(t,r){return new Promise((function(n){var u=new MessageChannel;u.port1.onmessage=function(s){n(s.data)},t.postMessage(r,[u.port2])}))}function P(t,r){(r==null||r>t.length)&&(r=t.length);for(var n=0,u=Array(r);n<r;n++)u[n]=t[n];return u}function j(t,r,n){return r&&(function(u,s){for(var c=0;c<s.length;c++){var o=s[c];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(u,W(o.key),o)}})(t.prototype,r),Object.defineProperty(t,"prototype",{writable:!1}),t}function S(t,r){var n=typeof Symbol<"u"&&t[Symbol.iterator]||t["@@iterator"];if(n)return(n=n.call(t)).next.bind(n);if(Array.isArray(t)||(n=(function(s,c){if(s){if(typeof s=="string")return P(s,c);var o={}.toString.call(s).slice(8,-1);return o==="Object"&&s.constructor&&(o=s.constructor.name),o==="Map"||o==="Set"?Array.from(s):o==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o)?P(s,c):void 0}})(t))||r){n&&(t=n);var u=0;return function(){return u>=t.length?{done:!0}:{done:!1,value:t[u++]}}}throw new TypeError(`Invalid attempt to iterate non-iterable instance.
2
+ In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function w(t,r){return w=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(n,u){return n.__proto__=u,n},w(t,r)}function W(t){var r=(function(n,u){if(typeof n!="object"||!n)return n;var s=n[Symbol.toPrimitive];if(s!==void 0){var c=s.call(n,u);if(typeof c!="object")return c;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(n)})(t,"string");return typeof r=="symbol"?r:r+""}try{self["workbox:core:7.4.0"]&&_()}catch{}var m=function(){var t=this;this.promise=new Promise((function(r,n){t.resolve=r,t.reject=n}))};function y(t,r){var n=location.href;return new URL(t,n).href===new URL(r,n).href}var d=function(t,r){this.type=t,Object.assign(this,r)};function l(t,r,n){return t&&t.then||(t=Promise.resolve(t)),r?t.then(r):t}function k(){}var L={type:"SKIP_WAITING"};function E(t,r){return t&&t.then?t.then(k):Promise.resolve()}var O=(function(t){function r(c,o){var e,i;return o===void 0&&(o={}),(e=t.call(this)||this).nn={},e.tn=0,e.rn=new m,e.en=new m,e.on=new m,e.un=0,e.an=new Set,e.cn=function(){var f=e.fn,a=f.installing;e.tn>0||!y(a.scriptURL,e.sn.toString())||performance.now()>e.un+6e4?(e.vn=a,f.removeEventListener("updatefound",e.cn)):(e.hn=a,e.an.add(a),e.rn.resolve(a)),++e.tn,a.addEventListener("statechange",e.ln)},e.ln=function(f){var a=e.fn,v=f.target,h=v.state,p=v===e.vn,g={sw:v,isExternal:p,originalEvent:f};!p&&e.mn&&(g.isUpdate=!0),e.dispatchEvent(new d(h,g)),h==="installed"?e.wn=self.setTimeout((function(){h==="installed"&&a.waiting===v&&e.dispatchEvent(new d("waiting",g))}),200):h==="activating"&&(clearTimeout(e.wn),p||e.en.resolve(v))},e.yn=function(f){var a=e.hn,v=a!==navigator.serviceWorker.controller;e.dispatchEvent(new d("controlling",{isExternal:v,originalEvent:f,sw:a,isUpdate:e.mn})),v||e.on.resolve(a)},e.gn=(i=function(f){var a=f.data,v=f.ports,h=f.source;return l(e.getSW(),(function(){e.an.has(h)&&e.dispatchEvent(new d("message",{data:a,originalEvent:f,ports:v,sw:h}))}))},function(){for(var f=[],a=0;a<arguments.length;a++)f[a]=arguments[a];try{return Promise.resolve(i.apply(this,f))}catch(v){return Promise.reject(v)}}),e.sn=c,e.nn=o,navigator.serviceWorker.addEventListener("message",e.gn),e}var n,u;u=t,(n=r).prototype=Object.create(u.prototype),n.prototype.constructor=n,w(n,u);var s=r.prototype;return s.register=function(c){var o=(c===void 0?{}:c).immediate,e=o!==void 0&&o;try{var i=this;return l((function(f,a){var v=f();return v&&v.then?v.then(a):a(v)})((function(){if(!e&&document.readyState!=="complete")return E(new Promise((function(f){return window.addEventListener("load",f)})))}),(function(){return i.mn=!!navigator.serviceWorker.controller,i.dn=i.pn(),l(i.bn(),(function(f){i.fn=f,i.dn&&(i.hn=i.dn,i.en.resolve(i.dn),i.on.resolve(i.dn),i.dn.addEventListener("statechange",i.ln,{once:!0}));var a=i.fn.waiting;return a&&y(a.scriptURL,i.sn.toString())&&(i.hn=a,Promise.resolve().then((function(){i.dispatchEvent(new d("waiting",{sw:a,wasWaitingBeforeRegister:!0}))})).then((function(){}))),i.hn&&(i.rn.resolve(i.hn),i.an.add(i.hn)),i.fn.addEventListener("updatefound",i.cn),navigator.serviceWorker.addEventListener("controllerchange",i.yn),i.fn}))})))}catch(f){return Promise.reject(f)}},s.update=function(){try{return this.fn?l(E(this.fn.update())):l()}catch(c){return Promise.reject(c)}},s.getSW=function(){return this.hn!==void 0?Promise.resolve(this.hn):this.rn.promise},s.messageSW=function(c){try{return l(this.getSW(),(function(o){return b(o,c)}))}catch(o){return Promise.reject(o)}},s.messageSkipWaiting=function(){this.fn&&this.fn.waiting&&b(this.fn.waiting,L)},s.pn=function(){var c=navigator.serviceWorker.controller;return c&&y(c.scriptURL,this.sn.toString())?c:void 0},s.bn=function(){try{var c=this;return l((function(o,e){try{var i=o()}catch(f){return e(f)}return i&&i.then?i.then(void 0,e):i})((function(){return l(navigator.serviceWorker.register(c.sn,c.nn),(function(o){return c.un=performance.now(),o}))}),(function(o){throw o})))}catch(o){return Promise.reject(o)}},j(r,[{key:"active",get:function(){return this.en.promise}},{key:"controlling",get:function(){return this.on.promise}}])})((function(){function t(){this.Pn=new Map}var r=t.prototype;return r.addEventListener=function(n,u){this.jn(n).add(u)},r.removeEventListener=function(n,u){this.jn(n).delete(u)},r.dispatchEvent=function(n){n.target=this;for(var u,s=S(this.jn(n.type));!(u=s()).done;)(0,u.value)(n)},r.jn=function(n){return this.Pn.has(n)||this.Pn.set(n,new Set),this.Pn.get(n)},t})());export{O as Workbox,d as WorkboxEvent,b as messageSW};
@@ -0,0 +1,161 @@
1
+ # 让 CodeBuddy 持续工作直到达成目标
2
+
3
+ > 用 `/goal` 设置一个完成条件,CodeBuddy 会跨多轮持续工作,直到条件满足才把控制权交还给你。
4
+
5
+ > **版本要求**:`/goal` 命令要求 `@tencent-ai/codebuddy-code` 已包含 goal 功能(agent-cli 的 `GoalService` 模块)。
6
+
7
+ `/goal` 命令设置一个完成条件,CodeBuddy 持续向其推进而无需你逐步催促。每轮(turn)结束时,由小模型(small-fast model)评估器判断条件是否成立——若不成立,CodeBuddy 自动开始下一轮,而不是把控制权交回给你。一旦条件满足,目标自动清除。
8
+
9
+ 适合用 `/goal` 跟踪有可验证终态的实质性工作:
10
+
11
+ - 把一个模块迁到新 API,直到所有调用点都能编译且测试通过
12
+ - 实施一份设计文档,直到所有验收条件成立
13
+ - 把一个大文件拆成若干聚焦模块,直到每个模块都不超过尺寸预算
14
+ - 处理打了某个标签的 issue 列表,直到队列清空
15
+
16
+ 本文涵盖:
17
+
18
+ - [与其他自治工作流对比](#与其他自治工作流对比):`/goal`、`/loop`、Stop hook 三者怎么选
19
+ - [设置目标](#设置目标)与[写好条件的要点](#写好一个有效的-condition)
20
+ - [查看状态](#查看状态)、[提前清除](#提前清除目标)、[非交互模式运行](#非交互模式运行)
21
+ - [评估机制](#评估机制如何工作)
22
+ - [实现说明与已知限制](#实现说明与已知限制)
23
+
24
+
25
+ ## 使用 `/goal`
26
+
27
+ 每个会话同时只能有一个 active goal。同一个命令根据参数差异承担"设置 / 查看 / 清除"三种角色。
28
+
29
+ ### 设置目标
30
+
31
+ 在 `/goal` 后跟你想满足的条件即可。如果当前已有 active goal,新的会替换旧的(旧 goal 的 hook 自动注销)。
32
+
33
+ ```text
34
+ /goal all tests in test/auth pass and the lint step is clean
35
+ ```
36
+
37
+ 设置完成后,CodeBuddy 会**立即开始一轮**,把"条件本身"作为指令交给主 agent——不需要你再额外发 prompt。同时输入框右下方会出现一行 `⊚ /goal active (Xs)` 指示器,每秒刷新已运行时长,让你随时知道当前处于 goal 模式。
38
+
39
+ 每轮结束后,评估器会返回一段简短的 reason 解释"为什么条件还没/已满足"。这段 reason 会以 `isMeta=true` 的内部消息形式注入对话历史,让模型在下一轮看到 evaluator 的视角,从而精准补做欠缺的部分——这是模型能"知道还差哪几步"的关键。
40
+
41
+ > **会话级行为**:goal 持续运行直到条件满足或你执行 `/goal clear`。运行 `/goal`(无参数)查看 turns / tokens 等统计。
42
+
43
+ ### 写好一个有效的 condition
44
+
45
+ [评估器](#评估机制如何工作)只会基于 CodeBuddy 在对话中**已经表达出来**的内容来判断条件,它不会自己跑命令、读文件。所以条件要写成"CodeBuddy 自己的输出能证明"的形式。"All tests in `test/auth` pass" 之所以可行,是因为 CodeBuddy 会自己跑测试,结果落在 transcript 里供评估器阅读。
46
+
47
+ 一个能稳健支撑多轮工作的条件通常包含:
48
+
49
+ - **一个可度量的终态**:测试结果、构建退出码、文件数、空队列……
50
+ - **一种可证明方式**:例如 ``\`npm test\` exits 0`` 或 ``\`git status\` is clean``
51
+ - **不可破坏的约束**:路上不能改的东西,比如 "no other test file is modified"
52
+
53
+ condition 长度上限 **4000 字符**。
54
+
55
+ 如果想给 goal 设置兜底上限,可以在 condition 里加上轮数 / 时间从句,例如 `or stop after 20 turns`,CodeBuddy 会在每轮里把当前进度对照该从句,evaluator 也能从对话中读出。
56
+
57
+ ### 查看状态
58
+
59
+ 不带参数运行 `/goal`:
60
+
61
+ ```text
62
+ /goal
63
+ ```
64
+
65
+ 在 TUI 中会打开 goal recap 面板;在 Web UI / ACP 客户端中会通过 ACP 广播打开同等面板;在 headless / SDK 等没有 UI 的环境降级为纯文本输出。
66
+
67
+ 面板内容包括:
68
+ - 条件
69
+ - 已运行时长
70
+ - 已评估的 turn 数
71
+ - token 消耗(goal 期间增量)
72
+ - 评估器最近一次给出的 reason
73
+
74
+ 如果当前没有 active goal、但本会话内之前曾达成过一次 goal,面板会展示那次的 condition、duration、turn 数和 token 数。
75
+
76
+ ### 提前清除目标
77
+
78
+ ```text
79
+ /goal clear
80
+ ```
81
+
82
+ 下面这些 token 都视为 `clear` 的同义词:`stop`、`off`、`reset`、`none`、`cancel`。仅在**单 token 完全匹配**时识别为清除指令——`/goal stop using deprecated API` 仍按"设置新 condition"处理,不会被吞掉。
83
+
84
+ 执行 `/clear` 重启会话也会一并移除 active goal(hook 注销 + meta 清理)。
85
+
86
+ ### 在恢复会话时携带 goal
87
+
88
+ 通过 `--resume` / `--continue` 恢复会话时,未完成的 goal 会被恢复(condition 与 scope 都还原)。
89
+
90
+ > **当前限制**:恢复时会沿用原 goal 的 createdAt / turnCount / token 起点,不重置计时器与计数器。如果你希望"重新计时",请先 `/goal clear` 再重新 `/goal <condition>`。已经达成或已被清除的 goal 不会被恢复(meta 已删)。
91
+
92
+ ### 非交互模式运行
93
+
94
+ `/goal` 在[非交互模式(headless)](./headless.md)、[Remote Control](./remote-control.md) 中均可用。在 `-p` 模式下设置 goal 会让 evaluator 循环跑到完成:
95
+
96
+ ```bash
97
+ codebuddy -p "/goal CHANGELOG.md has an entry for every PR merged this week"
98
+ ```
99
+
100
+ 需要在条件满足前提早终止,按 `Ctrl+C`。
101
+
102
+ ---
103
+
104
+ ## 评估机制如何工作
105
+
106
+ `/goal` 是对会话级 [prompt-based Stop hook](./hooks.md) 的一层封装。每当 CodeBuddy 主 agent 跑完一轮,**当前 condition + 当前对话** 会被一并发给配置好的小模型评估器。评估器返回一个"是 / 否 / 不可达"三态结果与简短 reason:
107
+
108
+ - **是(`ok: true`)**:清除 goal、记录"已达成"事件,UI 显示 `✔ Goal achieved` 状态条。
109
+ - **否(`ok: false`)**:把 reason 作为 `isMeta=true` 的 user message 注入 history(让主模型看到下一步该补什么),让 CodeBuddy 继续工作。同时写入一条 `goal-progress` UI 状态条 `◯ Goal not yet met… continuing`。
110
+ - **不可达(`ok: false, impossible: true`)**:用于评估器判断"在当前会话里这个目标根本不可能完成"(条件自相矛盾、依赖的能力/资源不可用、模型已经穷尽合理尝试)。立即清除 goal,UI 显示 `✕ Goal could not be achieved`,避免把循环陷死。
111
+
112
+ 评估器使用 product 配置中绑定到 **`lite` 槽位**的小模型(在不同 model provider 上分别映射到 `gpt-5.1-codex-mini` / `gemini-2.5-flash` / DeepSeek `deepseek-v4-flash` 等)。评估只看现有 transcript、不调用工具,所以走小模型既快又便宜。
113
+
114
+ > **计费**:评估器消耗的 token 计在小模型账单上,相对主 turn 通常可忽略。
115
+
116
+ ### 评估窗口约束
117
+
118
+ 为了避免"刚 set 完就 achieved"——同一会话曾经达成过的目标会在 transcript 里留下成功响应——我们会把当前 goal 的 `createdAt`(ISO 8601)注入评估器的 user prompt,并明确指示:
119
+
120
+ > Evaluate ONLY the conversation that happened AFTER this timestamp. Earlier messages MUST NOT be used as evidence.
121
+
122
+ 如果设置后还没有合格活动发生,evaluator 必须返回 `{"ok": false, "reason": "Goal was just set; no work has been done yet against the new condition."}`。
123
+
124
+ ### 给 evaluator 的 history 干净化
125
+
126
+ 我们会在把 history 喂给 evaluator 前过滤掉以下扩展 item type(它们是项目自定义、SDK 不认识的):
127
+
128
+ - `goal-result` / `goal-progress`(goal 自身的 UI 状态项)
129
+ - `summary` / `topic` / `ai-title` / `custom-title`
130
+ - `file-history-snapshot`
131
+
132
+ 这些 item 既不是用户输入也不是 assistant 响应,对 evaluator 没有判断价值,且会触发 SDK 的 `Unknown item type` 警告。
133
+
134
+ ---
135
+
136
+ ## 实现说明与已知限制
137
+
138
+ 下表汇总当前实现的关键行为与已知限制,便于排错时定位:
139
+
140
+ | 行为 | 状态 | 备注 |
141
+ | :--- | :--- | :--- |
142
+ | 设置 / 替换 / kick-off | ✅ | 设置后立即开始一轮,已有 active goal 时自动替换 |
143
+ | `/goal clear` 别名 | ✅ | 支持 stop / off / reset / none / cancel 五种单 token 同义词 |
144
+ | `/clear` 同步清除 active goal | ✅ | 重启会话时一并注销 goal hook 并清理 meta |
145
+ | condition 上限 | ✅ | 4000 字符 |
146
+ | reason 反馈进 history | ✅ | 注入格式:`Stop hook feedback: [<condition>]: <reason>` |
147
+ | 三态语义(ok / not-yet / impossible) | ✅ | 不可达时立即清除 goal,避免无效循环 |
148
+ | evaluator 走小模型 | ✅ | 使用 `lite` 槽位绑定的模型(按 provider 分别映射) |
149
+ | `/goal` 无参 → 状态视图 | ✅ | TUI / Web UI 面板 + headless 文本降级 |
150
+ | 持续运行指示器 `⊚ /goal active (Xs)` | ✅ | 输入框右下方常驻显示运行时长,1Hz 刷新 |
151
+ | `--resume` 时 turn / timer / token 重置 | ❌ 待补 | 当前沿用原 createdAt / turnCount,需"重新计时"请先 `/goal clear` |
152
+
153
+ ---
154
+
155
+ ## 参见
156
+
157
+ - [`/loop` 创建循环任务](./scheduled-tasks.md#使用-loop-创建循环任务):按时间间隔重复触发,而不是直到条件满足
158
+ - [Hook 入门](./hooks-guide.md) / [Hook 参考](./hooks.md):理解 prompt-based Stop hook 的底层机制;当你需要更复杂的评估逻辑时可以自己写一个
159
+ - [非交互(headless)模式](./headless.md):在 CI / 脚本中通过 `-p` 跑 `/goal`
160
+ - [Remote Control](./remote-control.md):在 Web UI / 微信通道中触发 goal
161
+ - [斜杠命令一览](./slash-commands.md):所有内置 slash 命令的索引
@@ -1,9 +1,9 @@
1
1
  # Hook 参考指南
2
2
 
3
- > **版本要求**:本文档针对 CodeBuddy Code v1.16.0 及以上版本中提供的 Claude Code Hooks 兼容实现。
3
+ > **版本要求**:本文档针对 CodeBuddy Code v1.16.0 及以上版本中提供的 Hooks 实现。
4
4
  > **功能状态**:Hook 功能当前处于 **Beta** 阶段,接口和行为可能在未来版本中调整。
5
5
 
6
- Hook(钩子)允许你在 CodeBuddy Code 的会话生命周期内插入自定义脚本或命令,实现自动化校验、环境初始化、合规检查等高级能力。我们的实现完全兼容 Claude Code Hooks 规范,支持相同的事件类型、输入输出结构以及安全特性。
6
+ Hook(钩子)允许你在 CodeBuddy Code 的会话生命周期内插入自定义脚本或命令,实现自动化校验、环境初始化、合规检查等高级能力。
7
7
 
8
8
 
9
9
  ## 配置
@@ -142,11 +142,13 @@ Hooks 按匹配器组织,每个匹配器可以有多个 hooks:
142
142
 
143
143
  > **支持的事件**:目前仅支持 `Stop`、`UserPromptSubmit` 和 `PreToolUse` 三种事件。
144
144
 
145
+ > **会话级捷径**:内置斜杠命令 [`/goal`](./goal.md) 是 prompt-based Stop hook 的开箱即用封装——直接输入 `/goal <condition>` 即可让 CodeBuddy 持续工作直到条件满足,无需手写 hook 配置。如果你的判定逻辑可以靠条件文本表达,优先用 `/goal`;只有需要更复杂的 prompt 编排或跨多事件协作时才回到本节自己写 prompt hook。
146
+
145
147
  ### 基于提示词的 hooks 如何工作
146
148
 
147
149
  基于提示词的 hooks 不是执行 bash 命令,而是:
148
150
 
149
- 1. 将 hook 输入和你的提示词发送给快速 LLM(Haiku)
151
+ 1. 将 hook 输入和你的提示词发送给快速小模型(绑定到 `lite` 槽位的小模型,按 model provider 分别映射)
150
152
  2. LLM 使用包含决策的结构化 JSON 响应
151
153
  3. CodeBuddy Code 自动处理决策
152
154
 
@@ -203,7 +205,8 @@ LLM 必须使用包含以下内容的 JSON 响应:
203
205
  ```jsonc
204
206
  {
205
207
  "ok": true | false,
206
- "reason": "Explanation for the decision" // 当 ok 为 false 时必需
208
+ "reason": "Explanation for the decision", // 当 ok 为 false 时必需
209
+ "impossible": false // 可选,仅 Stop 事件下生效
207
210
  }
208
211
  ```
209
212
 
@@ -211,6 +214,9 @@ LLM 必须使用包含以下内容的 JSON 响应:
211
214
 
212
215
  - `ok`:`true` 允许操作,`false` 阻止操作
213
216
  - `reason`:当 `ok` 为 `false` 时必需,显示给 CodeBuddy 的解释
217
+ - `impossible`:可选布尔值,仅 `Stop` hook 下有意义。`{ok: false, impossible: true}` 表示评估器判断"在当前会话里这个目标根本不可能完成"(条件自相矛盾、依赖资源不可用、模型已穷尽合理尝试)。CodeBuddy 不再继续循环,UI 显示"无法达成"终态。普通 `{ok: false}` 仍按"未达成、继续工作"处理。
218
+
219
+ **reason 注入 history 的语义**:`Stop` hook 返回 `{ok: false}` 时,`reason` 文本不是简单地"显示给 CodeBuddy"——它会以 `isMeta=true` 的内部 user message 形式注入到对话 history 中,让主模型在下一轮看到评估器的视角,从而精准补做欠缺的部分。这是 prompt-based Stop hook 能驱动多轮迭代收敛的核心机制(`/goal` 命令底层就是依赖这条链路)。
214
220
 
215
221
  ### 示例:智能 Stop Hook
216
222
 
@@ -362,6 +368,8 @@ LLM 必须使用包含以下内容的 JSON 响应:
362
368
 
363
369
  在主 CodeBuddy Code 代理完成响应时运行。如果停止是由于用户中断而发生的,则不会运行。
364
370
 
371
+ > **会话级捷径**:内置斜杠命令 [`/goal`](./goal.md) 是 session-scoped prompt-based Stop hook 的封装——`/goal <condition>` 一行即可注册一个让 CodeBuddy 持续工作到条件满足为止的 Stop hook,并自动处理三态评估(达成 / 未达成继续 / 不可达成)、turn 计数、token 统计、`/resume` 自动恢复等细节。需要会话级"持续工作直到 X"时优先考虑 `/goal`,不必手写 hook 配置。
372
+
365
373
  ### SubagentStop
366
374
 
367
375
  在 CodeBuddy Code 子代理(Agent 工具调用)完成响应时运行。
@@ -1,44 +1,117 @@
1
1
  # Monitoring CodeBuddy Code with OpenTelemetry
2
2
 
3
- CodeBuddy Code 支持把内部 traces 通过标准 OTLP 协议上报到用户自有的 OpenTelemetry Collector,便于企业自建可观测性平台对接。
3
+ CodeBuddy Code 支持把 traces 通过标准 OTLP 协议上报到用户自有的 OpenTelemetry Collector,便于企业自建可观测性平台对接。
4
4
 
5
- > **MVP 范围**:当前仅支持 **traces**(链路追踪),暂不支持 metrics 与 logs 的自定义上报。后续会按需扩展。
5
+ > **当前范围**:支持 **traces**(链路追踪)+ 4 个隐私 opt-in 开关。暂不支持 metrics 与 logs 的自定义上报。
6
6
 
7
- ## 启用方式
8
-
9
- 设置启用开关后,traces 会按 OTel 标准环境变量上报:
7
+ ## 快速开始
10
8
 
11
9
  ```bash
10
+ # 1. 启用 telemetry
12
11
  export CODEBUDDY_CODE_ENABLE_TELEMETRY=1
13
- export OTEL_EXPORTER_OTLP_ENDPOINT=https://otel-collector.example.com
12
+
13
+ # 2. 配置 OTLP endpoint
14
+ export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
15
+
16
+ # 3. (可选) 启用隐私 opt-in 内容记录
17
+ export OTEL_LOG_USER_PROMPTS=1
18
+ export OTEL_LOG_TOOL_DETAILS=1
19
+ export OTEL_LOG_TOOL_CONTENT=1
20
+
21
+ # 4. 运行
14
22
  codebuddy
15
23
  ```
16
24
 
17
- > 兼容 Claude Code 已有配置:`CLAUDE_CODE_ENABLE_TELEMETRY` 与 `CODEBUDDY_CODE_ENABLE_TELEMETRY` 等价。
25
+ > 兼容 Claude Code 配置:`CLAUDE_CODE_ENABLE_TELEMETRY` 与 `CODEBUDDY_CODE_ENABLE_TELEMETRY` 等价。
18
26
 
19
- ## 关键环境变量
27
+ ## 配置变量
20
28
 
21
- 完整清单见 [env-vars.md](env-vars.md#opentelemetry-自定义上报traces),常用项:
29
+ ### 基础配置
22
30
 
23
- | 变量 | 用途 |
24
- |------|------|
25
- | `CODEBUDDY_CODE_ENABLE_TELEMETRY=1` | 启用 OTel 上报开关 |
26
- | `OTEL_TRACES_EXPORTER` | `otlp`(默认)/ `console` / `none` |
27
- | `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP Collector 地址,会自动追加 `/v1/traces` |
28
- | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | traces 专用完整 URL,优先级更高 |
29
- | `OTEL_EXPORTER_OTLP_HEADERS` | 请求头 `k1=v1,k2=v2`,value 支持 URL 编码 |
30
- | `OTEL_SERVICE_NAME` | 覆盖默认 `service.name` |
31
- | `OTEL_RESOURCE_ATTRIBUTES` | 附加 resource 属性 |
31
+ | 变量 | 用途 | 示例 |
32
+ |------|------|------|
33
+ | `CODEBUDDY_CODE_ENABLE_TELEMETRY` | 启用 OTel 上报(必需) | `1` |
34
+ | `OTEL_TRACES_EXPORTER` | Exporter 类型 | `otlp`(默认)、`console`、`none` |
35
+ | `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP Collector 地址,自动追加 `/v1/traces` | `http://localhost:4318` |
36
+ | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Traces 专用完整 URL,优先级更高 | `http://localhost:4318/v1/traces` |
37
+ | `OTEL_EXPORTER_OTLP_HEADERS` | 请求头 `k1=v1,k2=v2`,value 支持 URL 编码 | `Authorization=Bearer%20token` |
38
+ | `OTEL_EXPORTER_OTLP_TRACES_PROTOCOL` | 传输协议 | `http/protobuf`(仅支持) |
39
+ | `OTEL_SERVICE_NAME` | 覆盖默认 `service.name` | `codebuddy-code` |
40
+ | `OTEL_RESOURCE_ATTRIBUTES` | 附加 resource 属性 | `team=platform,env=prod` |
32
41
 
33
- ## 协议支持
42
+ ### 隐私 opt-in 开关
34
43
 
35
- 仅支持 **`http/protobuf`**(OTLP/HTTP + Protobuf 编码),与 Claude Code 默认一致。
44
+ Span 默认不记录任何敏感信息(prompt 内容、工具参数、工具输出等),需要通过以下环境变量逐级 opt-in:
36
45
 
37
- 设置 `OTEL_EXPORTER_OTLP_PROTOCOL=grpc` `http/json` 会被忽略并写入告警日志,回退到默认 protobuf。
46
+ | 变量 | 用途 | 记录的内容 |
47
+ |------|------|-----------|
48
+ | `OTEL_LOG_USER_PROMPTS=1` | 记录用户 prompt | `user_prompt` 属性(默认为不记录,仅记录 `user_prompt_length`) |
49
+ | `OTEL_LOG_TOOL_DETAILS=1` | 记录工具参数 | `tool_input` 属性(~4KB 截断)+ 工具特定属性(`file.path`、`command` 等) |
50
+ | `OTEL_LOG_TOOL_CONTENT=1` | 记录工具输入输出全文 | `tool_input`/`tool_result` span events(60KB 截断) |
51
+ | `OTEL_LOG_RAW_API_BODIES=1` | 记录完整 API 请求/响应体 | 预留,暂未实现 |
52
+
53
+ ## Span 结构
54
+
55
+ 每个用户 prompt 产生一个 `codebuddy_code.interaction` 根 span。工具调用记录为其子 span:
56
+
57
+ ```
58
+ codebuddy_code.interaction
59
+ ├── codebuddy_code.tool (Read)
60
+ ├── codebuddy_code.tool (Bash)
61
+ └── codebuddy_code.tool (Agent -> 子 agent 的 tool spans)
62
+ ```
63
+
64
+ ### Span 属性
65
+
66
+ 所有 span 都包含 `span.type` 属性标识类型。
67
+
68
+ **`codebuddy_code.interaction`**
69
+
70
+ | 属性 | 描述 | 受控于 |
71
+ |------|------|--------|
72
+ | `span.type` | 固定值 `"interaction"` | |
73
+ | `conversation.id` | 会话 ID | |
74
+ | `conversation.agent` | Agent 名称 | |
75
+ | `user_prompt` | 用户 prompt 内容(未启用时不记录) | `OTEL_LOG_USER_PROMPTS` |
76
+ | `user_prompt_length` | Prompt 长度(始终记录) | |
77
+ | `conversation.cancelled` | 会话被取消时为 `true` | |
78
+
79
+ **`codebuddy_code.tool`**
80
+
81
+ | 属性 | 描述 | 受控于 |
82
+ |------|------|--------|
83
+ | `span.type` | 固定值 `"tool"` | |
84
+ | `tool_name` | 工具名称 | |
85
+ | `tool.call_id` | 工具调用 ID(始终记录) | |
86
+ | `file.path` | 文件路径(Read/Write/Edit) | `OTEL_LOG_TOOL_DETAILS` |
87
+ | `command` | Bash 命令 | `OTEL_LOG_TOOL_DETAILS` |
88
+ | `command.timeout` | 命令超时(毫秒) | `OTEL_LOG_TOOL_DETAILS` |
89
+ | `glob.pattern` | Glob 搜索模式 | `OTEL_LOG_TOOL_DETAILS` |
90
+ | `grep.pattern` | Grep 正则模式 | `OTEL_LOG_TOOL_DETAILS` |
91
+ | `http.url` | WebFetch URL | `OTEL_LOG_TOOL_DETAILS` |
92
+ | `search.query` | WebSearch 查询 | `OTEL_LOG_TOOL_DETAILS` |
93
+ | `agent.prompt` | 子 Agent prompt | `OTEL_LOG_TOOL_DETAILS` |
94
+ | `agent.type` | 子 Agent 类型 | `OTEL_LOG_TOOL_DETAILS` |
95
+ | `mcp.server` | MCP 服务器名 | `OTEL_LOG_TOOL_DETAILS` |
96
+ | `mcp.tool` | MCP 工具名 | `OTEL_LOG_TOOL_DETAILS` |
97
+ | `tool_input` | 工具输入 JSON(~4KB 截断) | `OTEL_LOG_TOOL_DETAILS` |
98
+ | `tool_input_truncated` | 输入是否被截断 | `OTEL_LOG_TOOL_DETAILS` |
99
+ | `tool_input_original_length` | 截断前原始长度 | `OTEL_LOG_TOOL_DETAILS` |
100
+
101
+ **`codebuddy_code.tool` span events**(需要 `OTEL_LOG_TOOL_CONTENT=1`)
102
+
103
+ | 事件名 | 属性 | 描述 |
104
+ |--------|------|------|
105
+ | `tool_input` | `content` | 完整工具输入(60KB 截断) |
106
+ | `tool_input` | `content_truncated` | 是否被截断 |
107
+ | `tool_input` | `content_original_length` | 截断前长度 |
108
+ | `tool_result` | `content` | 完整工具输出(60KB 截断) |
109
+ | `tool_result` | `content_truncated` | 是否被截断 |
110
+ | `tool_result` | `content_original_length` | 截断前长度 |
38
111
 
39
112
  ## 典型场景
40
113
 
41
- ### 1. 上报到企业自建 Collector
114
+ ### 上报到企业自建 Collector
42
115
 
43
116
  ```bash
44
117
  export CODEBUDDY_CODE_ENABLE_TELEMETRY=1
@@ -48,16 +121,17 @@ export OTEL_SERVICE_NAME=codebuddy-code
48
121
  export OTEL_RESOURCE_ATTRIBUTES=deployment.environment=prod,team=copilot
49
122
  ```
50
123
 
51
- ### 2. 本地调试 trace 输出
52
-
53
- 调试时让 traces 直接打到 stdout:
124
+ ### 本地调试(console 输出)
54
125
 
55
126
  ```bash
56
127
  export CODEBUDDY_CODE_ENABLE_TELEMETRY=1
57
128
  export OTEL_TRACES_EXPORTER=console
129
+ export OTEL_LOG_USER_PROMPTS=1
130
+ export OTEL_LOG_TOOL_DETAILS=1
131
+ export OTEL_LOG_TOOL_CONTENT=1
58
132
  ```
59
133
 
60
- ### 3. 临时关闭
134
+ ### 关闭 telemetry
61
135
 
62
136
  ```bash
63
137
  export OTEL_TRACES_EXPORTER=none
@@ -72,11 +146,21 @@ export DISABLE_TELEMETRY=1
72
146
  3. Endpoint 优先级:`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` > `OTEL_EXPORTER_OTLP_ENDPOINT` > 内置 product 配置中的 `telemetry.tracing.url`。
73
147
  4. Headers:env 与 product 配置合并,env 同名 key 覆盖 product。
74
148
 
75
- ## FAQ
149
+ ## 协议支持
150
+
151
+ 仅支持 **`http/protobuf`**(OTLP/HTTP + Protobuf 编码),与 Claude Code 默认一致。
76
152
 
77
- ### 是否会把 prompt / 代码内容写到 trace?
153
+ 设置 `OTEL_EXPORTER_OTLP_PROTOCOL=grpc` `http/json` 会被忽略并写入告警日志,回退到默认 protobuf。
154
+
155
+ ## 安全与隐私
156
+
157
+ - Span 默认只记录工具名称和调用 ID,**不包含**用户 prompt、工具参数、文件内容或源代码
158
+ - `user_prompt_length` 始终记录(仅长度),prompt 文本需要 `OTEL_LOG_USER_PROMPTS=1` 才会写入
159
+ - 工具参数(文件路径、命令等)需要 `OTEL_LOG_TOOL_DETAILS=1`,个别值超过 512 字符会被截断,总量限制 ~4KB
160
+ - 工具输入输出全文需要 `OTEL_LOG_TOOL_CONTENT=1`,通过 span events 记录,截断于 60KB
161
+ - 所有 opt-in 开关默认关闭,企业管理员可通过 managed settings 统一配置
78
162
 
79
- 不会。CodeBuddy Code 的 trace 仅记录工具调用、模型调用、耗时等结构化指标,不包含用户对话内容或源代码。如果需要记录代码片段需另行启用 standard 报告通道(不在本特性范围)。
163
+ ## FAQ
80
164
 
81
165
  ### 与企业内部上报通道是否冲突?
82
166
 
@@ -85,3 +169,7 @@ export DISABLE_TELEMETRY=1
85
169
  ### 是否支持 metrics / logs?
86
170
 
87
171
  暂不支持,规划中。如有强诉求请反馈到对应 Issue。
172
+
173
+ ### 与 Claude Code 的 OTEL 格式兼容吗?
174
+
175
+ 是的。Span 命名、属性命名、截断策略均对齐 Claude Code 的约定(`{product}.interaction` / `{product}.tool`),确保上游分析平台可统一处理。
@@ -17,6 +17,9 @@ Release Notes 记录了每个版本的用户可见变更,包括:
17
17
 
18
18
  <!-- 新版本自动添加到此处 -->
19
19
 
20
+ - [v2.99.0](./v2.99.0.md) - 2026-05-27
21
+ - [v2.98.1](./v2.98.1.md) - 2026-05-25
22
+ - [v2.98.0](./v2.98.0.md) - 2026-05-24
20
23
  - [v2.97.5](./v2.97.5.md) - 2026-05-22
21
24
  - [v2.97.4](./v2.97.4.md) - 2026-05-21
22
25
  - [v2.97.3](./v2.97.3.md) - 2026-05-19
@@ -0,0 +1,48 @@
1
+ # 🚀 CodeBuddy Code v2.98.0 发布
2
+
3
+ ## 📦 版本信息
4
+
5
+ | 组件 | 版本 |
6
+ |------|------|
7
+ | CodeBuddy Code CLI | v2.98.0 |
8
+ | Agent SDK JS | v0.3.156 |
9
+ | Agent SDK Python | v0.3.155 |
10
+
11
+ ## ✨ 新功能
12
+
13
+ ### OpenTelemetry 自定义上报(traces)
14
+
15
+ 支持通过 OTel 标准环境变量将内部 traces 上报到自有 Collector,便于和企业可观测平台集成:
16
+
17
+ ```bash
18
+ export CODEBUDDY_CODE_ENABLE_TELEMETRY=1
19
+ export OTEL_EXPORTER_OTLP_ENDPOINT=https://otel.corp.example.com
20
+ export OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer%20<TOKEN>
21
+ ```
22
+
23
+ 支持 `OTEL_TRACES_EXPORTER` / `OTEL_SERVICE_NAME` / `OTEL_RESOURCE_ATTRIBUTES` 等标准变量。详见 `docs/monitoring.md`。
24
+
25
+ ### 沙箱生态资产目录白名单
26
+
27
+ 沙箱安全策略默认允许 WorkBuddy 生态资产目录和跨平台技能目录写入,减少插件、技能与连接器在沙箱环境中的访问受限问题。
28
+
29
+ ## 🔧 改进优化
30
+
31
+ - **自动压缩窗口提升**:未配置 `maxInputTokens` 的模型,默认 auto-compact 窗口从 100k 提升到 200k token
32
+ - **Hooks 注入 agent_id / agent_type**:所有 hook 事件 payload 补齐触发源标识,方便在全局 hook 里区分主会话与子 agent
33
+ - **Hook 去重精细化**:解决"同事件触发两次"问题,settings 跨 scope 同一 command 折叠成一份,不同插件 / 子 agent scope 各自保留一份
34
+ - **多源 hook 命中可观测**:同一事件命中 ≥ 2 条不同 hook 时,日志列出所有命中命令,方便自查冲突
35
+ - **CLI 文档补齐**:新增 `monitoring.md` 与 `codebuddy-dir.md`,完成 v2.96.1 ~ v2.97.5 release notes 中英文同步与导航更新
36
+
37
+ ## 🐛 问题修复
38
+
39
+ - **后台 Bash 僵尸进程**:修复 `nohup` 等后台命令残留僵尸进程。stdout/stderr 改为直接写文件 fd;新增 50MB 输出看门狗(`CODEBUDDY_BASH_BG_MAX_OUTPUT_BYTES` 可调)和 `CODEBUDDY_BASH_BG_PIPE_MODE=1` 回滚开关
40
+ - **官方 Copilot 网关保留 thinking 字段**:修复 `auto` 模型开启思考后,请求发往官方网关时 thinking 字段被过早清理的问题
41
+ - **压缩类型透传**:修复自动压缩与手动 `/compact` 在 ACP `_meta` 中无法区分的问题
42
+ - **进程终止可靠性**:修复 `dispose()` 后 `kill()` 被 `_disposed` 标志拦截、以及 `disposeAll()` exit 事件路由丢失的问题
43
+
44
+ ## 📝 文档更新
45
+
46
+ - **CLI 监控文档**:新增 `monitoring.md` 介绍 OpenTelemetry 自定义上报
47
+ - **目录结构说明**:新增 `codebuddy-dir.md` 说明 `~/.codebuddy/` 与 `.codebuddy/` 目录结构、配置优先级与记忆加载顺序
48
+ - **Release Notes 索引**:补齐 v2.96.1 ~ v2.97.5 共 7 个版本的中英文 release notes
@@ -0,0 +1,19 @@
1
+ # 🚀 CodeBuddy Code v2.98.1 发布
2
+
3
+ ## 📦 版本信息
4
+
5
+ | 组件 | 版本 |
6
+ |------|------|
7
+ | CodeBuddy Code CLI | v2.98.1 |
8
+ | Agent SDK JS | v0.3.157 |
9
+ | Agent SDK Python | v0.3.156 |
10
+
11
+ ## 📌 概述
12
+
13
+ v2.98.0 因发版流水线 OOM 未能成功发布到 npm,本次以 v2.98.1 补发。**功能与 v2.98.0 完全等价**,所有 v2.98.0 的新功能、改进与修复均包含在本版本中。如果你已尝试安装 v2.98.0 失败,请直接升级到 v2.98.1。
14
+
15
+ 完整变更详情请参考 [v2.98.0 发布说明](./v2.98.0.md)。
16
+
17
+ ## 🐛 问题修复
18
+
19
+ - **修复 agent-cli 正式发版流水线 OOM**:调高发版构建阶段 Node 堆内存上限至 8GB,解决 v2.98.0 在 `yarn build` 阶段被 OOM Killer 终止、导致 npm 包未能发布的问题,让后续版本能够稳定发布。
@@ -0,0 +1,39 @@
1
+ # 🚀 CodeBuddy Code v2.99.0 发布
2
+
3
+ ## 📦 版本信息
4
+
5
+ | 组件 | 版本 |
6
+ |------|------|
7
+ | CodeBuddy Code CLI | v2.99.0 |
8
+ | Agent SDK JS | v0.3.158 |
9
+ | Agent SDK Python | v0.3.157 |
10
+
11
+ ## ✨ 新功能
12
+
13
+ ### `/goal` 命令:让 CodeBuddy 持续工作直到达成目标
14
+
15
+ 新增 `/goal` 斜杠命令,设置一个完成条件后,CodeBuddy 会跨多轮持续工作直到条件满足:
16
+
17
+ - `/goal all tests pass` — 每轮结束时由小模型评估器判断条件是否成立,未成立则自动继续
18
+ - `/goal` — 查看当前目标状态(已运行时长、turn 数、token 消耗)
19
+ - `/goal clear` — 提前结束目标
20
+
21
+ 支持三态评估:达成(停止)、未达成(继续工作)、不可达成(避免无效循环)。通过 `/resume` 恢复会话时目标自动重新装载。Web UI 同步支持进度条和终态浮层。
22
+
23
+ ### Credit 实际消耗推送
24
+
25
+ 在标准 ACP `usage_update` 上附加含 `credit` 字段的 `usage` 明细,支持上层按轮次累计与展示已消耗 Credit。
26
+
27
+ ### Gemini-3.5-Flash 模型
28
+
29
+ 新增 Gemini-3.5-Flash 模型支持,百万 token 上下文,推理能力均衡,适合日常使用。
30
+
31
+ ## 🐛 问题修复
32
+
33
+ - **安全修复(RCE)**:修复 `apiKeyHelper` 配置在目录信任对话框弹出之前被执行的远程代码执行漏洞,项目作用域配置现在必须等待目录信任完成后才执行
34
+ - **Hook Input 修复**:`agent_type` 现在正确反映配置的 agent 名称;SubagentStop 的 `agent_transcript_path` 指向正确路径
35
+ - **Plan Mode 权限恢复**:修复 ExitPlanMode 在 session 已退出 Plan Mode 时仍错误降级权限的问题
36
+ - **团队任务停止可靠性**:修复成员刚启动时点击停止偶发无法中止、以及成员被强制结束后仍显示运行中的问题
37
+ - **插件热监控无限循环**:修复 PluginsProductProvider 中变更事件无限循环问题
38
+ - **多行输入方向键**:修复后台任务运行时多行输入后方向下键被快捷键拦截的问题
39
+ - **自定义模型 tool call**:新增 `SkipToolCallSupportCheck` 开关,专享版不再移除 tools/tool_choice 字段
@@ -30,6 +30,7 @@ CodeBuddy Code 支持斜杠命令,允许您在聊天中执行特殊操作、
30
30
  | `/model:image-to-image` | `[list \| model-id]` | ✅ 支持 | 切换或查看当前使用的图生图模型。不带参数时打开交互式选择界面,`list` 列出可用模型,带模型 ID 参数时直接切换到指定模型。 |
31
31
  | `/permissions` | | ✅ 支持 | 管理工具权限和工作区目录访问权限。 |
32
32
  | `/plan` | | ✅ 支持 | 预览当前计划模式下的计划文件内容。 |
33
+ | `/goal` | `<condition> \| clear` | ✅ 支持 | 持续工作直到达成条件。`/goal <condition>` 设定一个目标条件(例:`/goal all tests pass`),会话级注册一个 prompt 类型的 Stop hook,模型每次想停下来时由小模型评估器判断条件是否满足;不满足则把 reason 注入 history 让模型继续工作。`/goal` 不带参数打开 recap 面板,`/goal clear`(别名:`stop` / `off` / `reset` / `none` / `cancel`)提前结束目标。详见 [goal 文档](./goal.md)。 |
33
34
  | `/upgrade` | | ✅ 支持 | 在浏览器中打开升级页面,查看高级功能和订阅选项。 |
34
35
  | `/bashes` | | ✅ 支持 | 列出和管理后台任务。 |
35
36
  | `/terminal-setup` | | ✅ 支持 | 配置 Shift+Enter 快捷键绑定,用于在输入框中插入换行符。 |