@feng0531/dsh-execution-bus 0.7.0 → 0.9.0

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.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  “萧何”是产品与模式显示名,执行总线是其技术功能;不新增人物 Agent,不进行角色扮演。仓库 dsh-execution-bus、npm 包名、execution_bus 工具名及 execution-bus-test 预设 ID 保持不变。历史版本发布说明保留当时名称。
6
6
 
7
- DSH 独立插件:`@feng0531/dsh-execution-bus` · 当前版本 **0.7.0**
7
+ DSH 独立插件:`@feng0531/dsh-execution-bus` · 当前版本 **0.9.0**
8
8
 
9
9
  > 萧何模式从宿主已声明的 PTC 组合派生,保留日常工具,再叠加可选执行总线。已验证隔离的真实 Node PTC → 原 read + 总线调用,以及脚本模型内存会话;真实模型、桌面界面与实际沙箱仍未验收。**不支持重启后恢复任务。**
10
10
 
@@ -19,6 +19,7 @@ DSH 独立插件:`@feng0531/dsh-execution-bus` · 当前版本 **0.7.0**
19
19
  | 同一次请求重复提交 | 在同一会话、同一存活实例和保存期内,共用一次执行 |
20
20
  | 重复或迟到的进度到达 | 按序号处理,忽略旧进度和终态后的进度 |
21
21
  | 取消时不确定任务是否真的停了 | 区分“已请求取消”和“已确认取消” |
22
+ | 长任务超出 `run_code` 的时间预算 | PTC 程序结束时只停止等待,已受理执行继续;用同一 requestId 的 `status`/`result` 取回,或用 `cancel` 取消 |
22
23
 
23
24
  它只是**执行协调层**,不是新的模型或 Agent,不是工作流引擎,也不是对所有工具的全局拦截器。它不能解决模型理解错误、反复改变方案等推理问题。
24
25
 
@@ -85,10 +86,13 @@ flowchart TD
85
86
  |---|---|---|
86
87
  | `test`(诊断,非业务) | 仅在明确诊断时检查延迟、进度、成功、失败和取消 | `delayMs`:0–30000;`fail`:布尔值 |
87
88
  | `host.read` | 经由 DSH 现有 `read` 工具读取文本 | `file_path`;可选 `offset` 和 `limit`,最多 100 行 |
89
+ | `host.glob` | 经由 DSH 现有 `glob` 工具按路径模式查找文件(只读) | `pattern`;可选 `path` |
90
+ | `host.grep` | 经由 DSH 现有 `grep` 工具检索文件内容(只读) | `pattern`;可选 `path`、`include`(单个正向 glob) |
88
91
  | `host.edit` | 经由 DSH 现有 `edit` 工具替换文本(有副作用) | `file_path`、`old_string`、`new_string`;可选 `replace_all` |
89
92
  | `host.write` | 经由 DSH 现有 `write` 工具写入文本(有副作用) | `file_path`、`content` |
93
+ | `host.pwsh` | 经由 DSH 现有 `pwsh` 工具执行 PowerShell 命令(有副作用) | `description`、`command`;可选 `timeoutMs`、`workdir`、`run_in_background`、`sandbox_permissions`、`justification` |
90
94
 
91
- `host.read`、`host.edit` 与 `host.write` 在出队时重新进入宿主工具管线,沿用宿主当前权限、会话工作目录及输出限制。`host.edit`/`host.write` 有副作用,显式声明非幂等:同一 requestId 的终态结果不可复用,重复提交返回 `MUTATING_REUSE_DENIED`。插件不自行启动命令、不提供任意远程执行服务,也不会强制将现有工具改成总线调用。
95
+ `host.*` 在出队时重新进入宿主工具管线,沿用宿主当前权限、会话工作目录、沙箱与输出限制。`host.read`/`host.glob`/`host.grep` 只读且幂等,同一 requestId 的终态结果可复用;`host.edit`/`host.write`/`host.pwsh` 有副作用,显式声明非幂等:同一 requestId 的终态结果不可复用,重复提交返回 `MUTATING_REUSE_DENIED`。`host.pwsh` 的后台模式只返回宿主 Job ID,不代表命令完成。插件不自行实现文件或命令执行端,只转发到宿主现有工具;也不提供任意远程执行服务,不会强制将现有工具改成总线调用。
92
96
 
93
97
  ## 选择“萧何”预设
94
98
 
@@ -105,7 +109,7 @@ flowchart TD
105
109
 
106
110
  **0.3.0 起不再是只读验证模式。** 加载时读取宿主 `ptc` 预设的组合声明快照,保留原工具、平台表达式、禁用项和配置,只追加萧何总线与说明。不再强制 native 呈现或添加只读白名单;终端、写入、搜索、技能等能力是否可用,取决于原 PTC 配置和宿主服务。其他预设和默认模式不被修改,原 PTC 会话看不到新增总线。
107
111
 
108
- 普通任务仍通过 `run_code` 调用原工具;**总线目前只支持 test、host.read、host.edit 和 host.write,不接管任意命令、安装或全部工具**。例如更新插件应使用原终端能力并遵守宿主授权;专用插件管理工具若在源 PTC 中禁用,萧何不会擅自启用。命令受理、返回 Job ID 不等于执行完成。
112
+ 普通任务仍通过 `run_code` 调用原工具;**总线目前只支持 test 与 host.read/host.glob/host.grep/host.edit/host.write/host.pwsh,不接管其他工具、安装或全部能力**。例如更新插件应使用原终端能力并遵守宿主授权;专用插件管理工具若在源 PTC 中禁用,萧何不会擅自启用。命令受理或返回 Job ID 不等于执行完成。
109
113
 
110
114
  升级提示:预设 ID 保持兼容,但从旧版只读模式升级后能力范围扩大,使用者须审阅后加载;本次不自动升级日常配置。它不是进程沙箱,同一预设会话共享总线容量,结果按会话隔离。派生是加载时快照,不自动跟随源预设热编辑;源 PTC 更新后应按宿主正常流程重新加载派生行,旧会话遵循宿主版本保留规则。
111
115
 
@@ -115,9 +119,9 @@ flowchart TD
115
119
 
116
120
  ## 安装前先确认
117
121
 
118
- - 兼容目标:**DSH 0.2.0-rc.2 / Cordis 4.0.4**,Node.js 22 或以上。其他宿主版本未承诺兼容。
122
+ - 兼容目标:**DSH 0.2.1-rc.2 / Cordis 4.0.4**,Node.js 22 或以上。其他宿主版本未承诺兼容。
119
123
  - 建议先选择**隔离的 DSH 配置**试用,不直接更改日常环境。
120
- - 目标组合需要可见的工具注册表、Job 服务、现有 Job 控制工具;读取任务还需要宿主 `read`。
124
+ - 目标组合需要可见的工具注册表、Job 服务、现有 Job 控制工具;读取、搜索、编辑、写入或命令任务还需要宿主对应的 `read`/`glob`/`grep`/`edit`/`write`/`pwsh` 工具。
121
125
  - 安装 npm 包不等于插件已经加载;**只有当前会话能看到 `execution_bus` 工具,才可直接调用。**
122
126
 
123
127
  ### 安装步骤
@@ -126,7 +130,7 @@ flowchart TD
126
130
  2. 在你选定的隔离 DSH 配置依赖目录安装固定版本,不要在 DSH 程序安装目录执行:
127
131
 
128
132
  ```powershell
129
- npm install --ignore-scripts @feng0531/dsh-execution-bus@0.7.0
133
+ npm install --ignore-scripts @feng0531/dsh-execution-bus@0.9.0
130
134
  ```
131
135
 
132
136
  这是 npm 目录示例。若目标配置使用 pnpm,应沿用其包管理器,不混用锁文件。遇到宿主 peer 版本冲突就停止,不用强制安装绕过。
@@ -197,6 +201,8 @@ flowchart TD
197
201
 
198
202
  PTC 是 DSH 的程序化工具调用入口。在 `run_code` 内使用 `await tools.execution_bus(请求对象)`,而不是直接调用折叠后的工具名。执行总线不会解除 `run_code` 自身的时间预算。已有真实 Node PTC 隔离进程读文件和调用总线的验证,但尚未进行实际模型/桌面沙箱全链路验收。
199
203
 
204
+ **0.9.0 起,预算到期不再连带取消已受理执行。** `run_code` 因时间预算到期或程序结束时,宿主会中断其中的工具子调用;总线把这种中断视为**只停止等待**:已受理执行与宿主 Job 继续,程序返回预算错误后,可在后续 `run_code` 中用同一 `requestId` 的 `status`/`result` 取回结果,或用 `cancel` 取消。用户主动中断、会话取消、沙箱模式变化等其他原因仍会请求取消整个执行。该识别依赖 DSH 0.2.1-rc.2 的中断原因字符串(见[宿主兼容性](<docs/host-compatibility.md>)),不是宿主公开稳定契约;进程退出仍会丢失全部内存状态,保留期一小时。
205
+
200
206
  ## 如何理解任务状态?
201
207
 
202
208
  ```mermaid
@@ -238,6 +244,7 @@ core 开发者可用 `new ExecutionBus(options, {sessionQueueLimit:16,maxQueueWa
238
244
  宿主插件默认并发 **2**,全局排队上限 **32**,每会话排队上限 **16**;排队超过 **120 秒**且尚未开始执行时结算为 `failed / QUEUE_WAIT_TIMEOUT`,不调用 Handler。运行后不会被该排队期限中止,PTC 外层仍有独立时间预算。最多保存 **256** 条任务记录,单结果最多 **64 KiB**,完成结果保留期 **1 小时**,在新请求和查询时惰性清理;不是一小时一到即定时删除。队列或记录满时拒绝新任务;宿主 Job 自身也有容量限制。
239
245
 
240
246
  - **全部状态在内存中。** 受理没有落盘,插件关闭或进程崩溃后,不能依靠它恢复原调用或保证请求不丢失。
247
+ - **预算分离等待不是持久化。** PTC 程序结束后继续执行的任务只在当前插件实例存活期间有效;进程关闭即丢失,结果最多保留一小时,不保证模型一定取回。
241
248
  - **不自动重跑任务。** 通信超时不等于执行失败,取消不等于回滚。Job 等待服务异常会在原执行排空后返回服务错误,执行可能已成功;应核对原 requestId 的状态,不要换编号盲目重跑。
242
249
  - **不承诺端到端 exactly-once。** 当前实例的请求复用不能代替外部副作用对账。
243
250
  - 当前没有远端执行端、跨插件 Handler 注册服务或非幂等操作对账能力。
@@ -269,7 +276,7 @@ npm run test:install # 临时目录安装,不操作日常 DSH
269
276
 
270
277
  - [协议和投递语义](<docs/protocol.md>):字段、状态、重复处理与取消规则。
271
278
  - [宿主兼容性与源码调用链](<docs/host-compatibility.md>):为什么可以等待,为什么不能跨重启恢复。
272
- - [验证记录](<docs/validation.md>)、[0.7.0 发布说明](<docs/releases/0.7.0.md>):已验证与未验证范围。
279
+ - [验证记录](<docs/validation.md>)、[0.9.0 发布说明](<docs/releases/0.9.0.md>):已验证与未验证范围。
273
280
  - [同类项目源码整合](<docs/INTEGRATION.md>):固定来源、采用范围、许可与验证边界。
274
281
  - [维护者发布流程](<docs/RELEASING.md>):标签 CI、安装包校验与正式发布门禁。
275
282
 
package/dist/bus.d.ts CHANGED
@@ -65,6 +65,8 @@ export declare class ExecutionBus {
65
65
  submit(owner: Owner, raw: unknown, onEvent?: (e: Event) => void, invoke?: Capability): {
66
66
  accepted: Event;
67
67
  done: Promise<RecordView>;
68
+ /** 当前快照:供仅在停止等待时使用,不改变交付标记。 */
69
+ snapshot: () => RecordView;
68
70
  cancel: () => void;
69
71
  detach: () => void;
70
72
  returned: () => void;
package/dist/bus.js CHANGED
@@ -282,6 +282,8 @@ export class ExecutionBus {
282
282
  return {
283
283
  accepted,
284
284
  done: e.done,
285
+ /** 当前快照:供仅在停止等待时使用,不改变交付标记。 */
286
+ snapshot: () => this.view(e),
285
287
  cancel: () => this.cancel(e),
286
288
  detach: () => {
287
289
  if (listener)
@@ -51,6 +51,9 @@ export declare const ERRORS: Readonly<{
51
51
  INVALID_READ_INPUT: "INVALID_READ_INPUT";
52
52
  INVALID_EDIT_INPUT: "INVALID_EDIT_INPUT";
53
53
  INVALID_WRITE_INPUT: "INVALID_WRITE_INPUT";
54
+ INVALID_GLOB_INPUT: "INVALID_GLOB_INPUT";
55
+ INVALID_GREP_INPUT: "INVALID_GREP_INPUT";
56
+ INVALID_PWSH_INPUT: "INVALID_PWSH_INPUT";
54
57
  READ_LIMIT: "READ_LIMIT";
55
58
  CONTROLLED_FAILURE: "CONTROLLED_FAILURE";
56
59
  HOST_CAPABILITY_REQUIRED: "HOST_CAPABILITY_REQUIRED";
@@ -57,6 +57,9 @@ export const ERRORS = Object.freeze({
57
57
  INVALID_READ_INPUT: "INVALID_READ_INPUT",
58
58
  INVALID_EDIT_INPUT: "INVALID_EDIT_INPUT",
59
59
  INVALID_WRITE_INPUT: "INVALID_WRITE_INPUT",
60
+ INVALID_GLOB_INPUT: "INVALID_GLOB_INPUT",
61
+ INVALID_GREP_INPUT: "INVALID_GREP_INPUT",
62
+ INVALID_PWSH_INPUT: "INVALID_PWSH_INPUT",
60
63
  READ_LIMIT: "READ_LIMIT",
61
64
  CONTROLLED_FAILURE: "CONTROLLED_FAILURE",
62
65
  HOST_CAPABILITY_REQUIRED: "HOST_CAPABILITY_REQUIRED",
@@ -9,7 +9,13 @@ export declare function hostToolHandler(toolName: string, opts: {
9
9
  export declare const testHandler: Handler;
10
10
  /** 读取:无副作用,幂等,终态结果可复用。 */
11
11
  export declare const readHandler: Handler;
12
+ /** 文件名搜索:只读,幂等,终态结果可复用;搜索基数由宿主工具限制。 */
13
+ export declare const globHandler: Handler;
14
+ /** 内容搜索:只读,幂等,终态结果可复用;匹配上限由宿主工具限制。 */
15
+ export declare const grepHandler: Handler;
12
16
  /** 写入:有副作用,非幂等,终态结果不可复用。 */
13
17
  export declare const writeHandler: Handler;
14
18
  /** 编辑:有副作用,非幂等,终态结果不可复用。 */
15
19
  export declare const editHandler: Handler;
20
+ /** 命令执行:有副作用,非幂等,终态结果不可复用;后台模式返回 Job ID 不等于完成。 */
21
+ export declare const pwshHandler: Handler;
package/dist/handlers.js CHANGED
@@ -70,6 +70,49 @@ export const readHandler = hostToolHandler("read", {
70
70
  limit: input.limit ?? HANDLER_LIMITS.readLines,
71
71
  }),
72
72
  });
73
+ function validateGlob(input) {
74
+ if (Object.keys(input).some((k) => !["pattern", "path"].includes(k)) ||
75
+ typeof input.pattern !== "string" ||
76
+ input.pattern.trim().length === 0 ||
77
+ (input.path !== undefined &&
78
+ (typeof input.path !== "string" || input.path.trim().length === 0)))
79
+ throw Error(ERRORS.INVALID_GLOB_INPUT);
80
+ }
81
+ /** 文件名搜索:只读,幂等,终态结果可复用;搜索基数由宿主工具限制。 */
82
+ export const globHandler = hostToolHandler("glob", {
83
+ idempotent: true,
84
+ validate: validateGlob,
85
+ });
86
+ function validateGrep(input) {
87
+ if (Object.keys(input).some((k) => !["pattern", "path", "include"].includes(k)) ||
88
+ typeof input.pattern !== "string" ||
89
+ input.pattern.length === 0 ||
90
+ (input.path !== undefined &&
91
+ (typeof input.path !== "string" || input.path.trim().length === 0)))
92
+ throw Error(ERRORS.INVALID_GREP_INPUT);
93
+ if (input.include === undefined)
94
+ return;
95
+ const include = input.include;
96
+ if (typeof include !== "string" || include.trim().length === 0)
97
+ throw Error(ERRORS.INVALID_GREP_INPUT);
98
+ // 与宿主 grep 契约一致:只接受单个正向 glob,不支持取反或顶层逗号列表。
99
+ if (include.startsWith("!"))
100
+ throw Error(ERRORS.INVALID_GREP_INPUT);
101
+ let braceDepth = 0;
102
+ for (const char of include) {
103
+ if (char === "{")
104
+ braceDepth++;
105
+ else if (char === "}")
106
+ braceDepth = Math.max(0, braceDepth - 1);
107
+ else if (char === "," && braceDepth === 0)
108
+ throw Error(ERRORS.INVALID_GREP_INPUT);
109
+ }
110
+ }
111
+ /** 内容搜索:只读,幂等,终态结果可复用;匹配上限由宿主工具限制。 */
112
+ export const grepHandler = hostToolHandler("grep", {
113
+ idempotent: true,
114
+ validate: validateGrep,
115
+ });
73
116
  function validateWrite(input) {
74
117
  if (Object.keys(input).some((k) => !["file_path", "content"].includes(k)) ||
75
118
  typeof input.file_path !== "string" ||
@@ -88,3 +131,44 @@ export const editHandler = hostToolHandler("edit", {
88
131
  idempotent: false,
89
132
  validate: validateEdit,
90
133
  });
134
+ /** 与宿主 pwsh 工具一致的提权目标;沙箱组合未提供提权面时由宿主拒绝。 */
135
+ const PWSH_ESCALATION_TARGETS = Object.freeze([
136
+ "workspace-write",
137
+ "danger-full-access",
138
+ ]);
139
+ function validatePwsh(input) {
140
+ if (Object.keys(input).some((k) => ![
141
+ "description",
142
+ "command",
143
+ "timeoutMs",
144
+ "workdir",
145
+ "run_in_background",
146
+ "sandbox_permissions",
147
+ "justification",
148
+ ].includes(k)) ||
149
+ typeof input.command !== "string" ||
150
+ input.command.trim().length === 0 ||
151
+ typeof input.description !== "string" ||
152
+ input.description.trim().length === 0 ||
153
+ (input.timeoutMs !== undefined &&
154
+ (!Number.isFinite(input.timeoutMs) || Number(input.timeoutMs) <= 0)) ||
155
+ (input.workdir !== undefined && typeof input.workdir !== "string") ||
156
+ (input.run_in_background !== undefined &&
157
+ typeof input.run_in_background !== "boolean"))
158
+ throw Error(ERRORS.INVALID_PWSH_INPUT);
159
+ const permissions = input.sandbox_permissions, justification = input.justification;
160
+ if ((permissions !== undefined && justification === undefined) ||
161
+ (justification !== undefined && permissions === undefined) ||
162
+ (permissions !== undefined &&
163
+ (typeof permissions !== "string" ||
164
+ !PWSH_ESCALATION_TARGETS.includes(permissions))) ||
165
+ (justification !== undefined &&
166
+ (typeof justification !== "string" ||
167
+ justification.trim().length === 0)))
168
+ throw Error(ERRORS.INVALID_PWSH_INPUT);
169
+ }
170
+ /** 命令执行:有副作用,非幂等,终态结果不可复用;后台模式返回 Job ID 不等于完成。 */
171
+ export const pwshHandler = hostToolHandler("pwsh", {
172
+ idempotent: false,
173
+ validate: validatePwsh,
174
+ });
package/dist/plugin.js CHANGED
@@ -3,15 +3,24 @@ import { ADMISSION_DEFAULTS, REQUEST_DESCRIPTION, REQUEST_PARAMETERS, STATE_PARA
3
3
  import { ExecutionOwner } from "./execution.js";
4
4
  import { ExecutionBus, parse } from "./bus.js";
5
5
  import { ERRORS } from "./error-codes.js";
6
- import { testHandler, readHandler, editHandler, writeHandler, } from "./handlers.js";
6
+ import { testHandler, readHandler, globHandler, grepHandler, editHandler, writeHandler, pwshHandler, } from "./handlers.js";
7
+ /** DSH 0.2.1-rc.2 的 PTC 在程序结束(含时间预算到期)时用它作为子调用中断原因;
8
+ * 用户/会话取消使用调用方提供的原因,不匹配该固定字符串。 */
9
+ const PTC_PROGRAM_SETTLED = "run_code settled";
10
+ function isPtcProgramEnd(signal) {
11
+ return signal.aborted && signal.reason === PTC_PROGRAM_SETTLED;
12
+ }
7
13
  export const name = "execution-bus";
8
14
  export const inject = ["tools", "jobs"];
9
15
  export function apply(ctx) {
10
16
  const bus = new ExecutionBus(undefined, ADMISSION_DEFAULTS);
11
17
  bus.register("test", testHandler);
12
18
  bus.register("host.read", readHandler);
19
+ bus.register("host.glob", globHandler);
20
+ bus.register("host.grep", grepHandler);
13
21
  bus.register("host.edit", editHandler);
14
22
  bus.register("host.write", writeHandler);
23
+ bus.register("host.pwsh", pwshHandler);
15
24
  const executions = new ExecutionOwner();
16
25
  ctx.effect(() => () => executions.close(() => bus.close()));
17
26
  ctx.tools.register({
@@ -145,14 +154,33 @@ export function apply(ctx) {
145
154
  throw Error(ERRORS.HOST_JOB_UNAVAILABLE);
146
155
  }
147
156
  }
148
- /** 把宿主工具调用的取消映射到执行,并等待投影结算后返回快照。 */
157
+ /** 外层取消映射:PTC 程序结束(含预算到期)只停止本次等待,已受理执行与
158
+ * 宿主 Job 保留,同会话可用同 requestId 的 status/result 取回;其他取消原因
159
+ * (用户/会话中断)仍请求取消整个执行。 */
149
160
  async function awaitProjection(exec, attached, execution) {
150
- const abort = () => attached.cancel();
161
+ let release;
162
+ const detachedView = new Promise((resolve) => (release = resolve));
163
+ const abort = () => {
164
+ if (!isPtcProgramEnd(exec.signal)) {
165
+ attached.cancel();
166
+ return;
167
+ }
168
+ attached.detach();
169
+ release(attached.snapshot());
170
+ };
151
171
  exec.signal.addEventListener("abort", abort, { once: true });
152
172
  if (exec.signal.aborted)
153
173
  abort();
174
+ const settled = execution.settled.then(() => ({ kind: "settled" }), (error) => ({ kind: "error", error }));
154
175
  try {
155
- await execution.settled;
176
+ const outcome = await Promise.race([
177
+ settled,
178
+ detachedView.then((view) => ({ kind: "detached", view })),
179
+ ]);
180
+ if (outcome.kind === "detached")
181
+ return outcome.view;
182
+ if (outcome.kind === "error")
183
+ throw outcome.error;
156
184
  const value = await attached.done;
157
185
  attached.returned();
158
186
  return value;
package/dist/product.d.ts CHANGED
@@ -52,5 +52,5 @@ export declare const STATE_PARAMETERS: {
52
52
  readonly properties: {};
53
53
  readonly additionalProperties: false;
54
54
  };
55
- export declare const REQUEST_DESCRIPTION = "\u8427\u4F55 / Xiao He. Submit a version 1 request and WAIT for its terminal result in this tool call. Reuse requestId only for the same logical operation. Business handlers: host.read {file_path,offset?,limit?<=100}; host.edit {file_path,old_string,new_string,replace_all?}; host.write {file_path,content} (mutating, terminal reuse denied). Diagnostic handler only: test {delayMs:0..30000,fail:boolean}; never use it to perform real work. Control status/result/cancel use empty payload. Acceptance is volatile, not success. No polling or restart resume.";
55
+ export declare const REQUEST_DESCRIPTION = "\u8427\u4F55 / Xiao He. Submit a version 1 request and WAIT for its terminal result in this tool call. Reuse requestId only for the same logical operation. Business handlers: host.read {file_path,offset?,limit?<=100}, host.glob {pattern,path?}, host.grep {pattern,path?,include?} (read-only, terminal reuse allowed); host.edit {file_path,old_string,new_string,replace_all?}, host.write {file_path,content}, host.pwsh {description,command,timeoutMs?,workdir?,run_in_background?,sandbox_permissions?,justification?} (mutating, terminal reuse denied). Diagnostic handler only: test {delayMs:0..30000,fail:boolean}; never use it to perform real work. Control status/result/cancel use empty payload. A PTC program end (including run_code budget expiry) only stops waiting: accepted work continues and the same requestId can be retrieved with status/result or cancelled. Acceptance is volatile, not success. No polling or restart resume.";
56
56
  export declare const MODE_INSTRUCTIONS: string;
package/dist/product.js CHANGED
@@ -40,9 +40,9 @@ export const STATE_PARAMETERS = {
40
40
  properties: {},
41
41
  additionalProperties: false,
42
42
  };
43
- export const REQUEST_DESCRIPTION = "萧何 / Xiao He. Submit a version 1 request and WAIT for its terminal result in this tool call. Reuse requestId only for the same logical operation. Business handlers: host.read {file_path,offset?,limit?<=100}; host.edit {file_path,old_string,new_string,replace_all?}; host.write {file_path,content} (mutating, terminal reuse denied). Diagnostic handler only: test {delayMs:0..30000,fail:boolean}; never use it to perform real work. Control status/result/cancel use empty payload. Acceptance is volatile, not success. No polling or restart resume.";
44
- export const MODE_INSTRUCTIONS = "你正在萧何模式中。这不是角色扮演。保留宿主 PTC 的日常工具能力与权限规则。普通编辑、搜索、命令、安装和其他工作使用原工具,不要声称此模式只读。execution_bus 是可选协调入口,实际业务 Handler 为 host.read、host.edit 与 host.write(host.edit/host.write 有副作用,终态结果不可复用);test 仅用于用户明确要求的诊断,不做真实工作,不要强制所有任务走总线。通过 run_code 调用 await tools.execution_bus(...),受原有时间预算约束。每会话排队上限 " +
43
+ export const REQUEST_DESCRIPTION = "萧何 / Xiao He. Submit a version 1 request and WAIT for its terminal result in this tool call. Reuse requestId only for the same logical operation. Business handlers: host.read {file_path,offset?,limit?<=100}, host.glob {pattern,path?}, host.grep {pattern,path?,include?} (read-only, terminal reuse allowed); host.edit {file_path,old_string,new_string,replace_all?}, host.write {file_path,content}, host.pwsh {description,command,timeoutMs?,workdir?,run_in_background?,sandbox_permissions?,justification?} (mutating, terminal reuse denied). Diagnostic handler only: test {delayMs:0..30000,fail:boolean}; never use it to perform real work. Control status/result/cancel use empty payload. A PTC program end (including run_code budget expiry) only stops waiting: accepted work continues and the same requestId can be retrieved with status/result or cancelled. Acceptance is volatile, not success. No polling or restart resume.";
44
+ export const MODE_INSTRUCTIONS = "你正在萧何模式中。这不是角色扮演。保留宿主 PTC 的日常工具能力与权限规则。普通编辑、搜索、命令、安装和其他工作使用原工具,不要声称此模式只读。execution_bus 是可选协调入口,实际业务 Handler 为 host.read、host.glob、host.grep(只读,可复用终态结果)与 host.edit、host.write、host.pwsh(有副作用,终态结果不可复用);test 仅用于用户明确要求的诊断,不做真实工作,不要强制所有任务走总线。通过 run_code 调用 await tools.execution_bus(...),受原有时间预算约束。每会话排队上限 " +
45
45
  ADMISSION_DEFAULTS.sessionQueueLimit +
46
46
  ",排队超过 " +
47
47
  ADMISSION_DEFAULTS.maxQueueWaitMs / 1000 +
48
- " 秒且未执行会返回 QUEUE_WAIT_TIMEOUT,不自动重试。execution_bus_state 只用于用户明确诊断本会话元数据,不循环查询。请求只提交一次并等待结果,同一逻辑操作重发沿用 requestId。cancelRequested 不等于已取消,unknown 不代表执行失败,不承诺跨重启恢复。后台命令返回 Job ID 不代表已经完成。";
48
+ " 秒且未执行会返回 QUEUE_WAIT_TIMEOUT,不自动重试。execution_bus_state 只用于用户明确诊断本会话元数据,不循环查询。请求只提交一次并等待结果,同一逻辑操作重发沿用 requestId。PTC 程序结束或 run_code 时间预算到期时,已受理请求只停止等待、继续执行;用同一 requestId 的 status/result 取回,或用 cancel 取消;用户/会话中断仍会请求取消执行。cancelRequested 不等于已取消,unknown 不代表执行失败,不承诺跨重启恢复。后台命令返回 Job ID 不代表已经完成。";
package/docs/FLOW-TEST.md CHANGED
@@ -33,18 +33,20 @@ npm run test:install
33
33
  - 合作取消、晚取消、未知结果不自动重跑。
34
34
  - 深层/非 JSON 结果拒绝,结果和通知不可变,异步观察者拒绝隔离。
35
35
  - 已受理 Handler 与替换注册并存,旧注销函数不破坏新注册。
36
- - 宿主 read 真正经过工具管线;前置拒绝仍生效。
36
+ - 宿主 read/glob/grep/edit/write/pwsh 真正经过工具管线;前置拒绝仍生效(搜索与命令的转发测试使用宿主工具桩,不代表真实工具实现)。
37
37
  - Job 先行移除、等待/清理异常与卸载交错。
38
38
  - 派生预设成功激活、原 ptc 声明不变、普通 Agent 不可见总线、write/edit 保留且宿主策略可拒绝。
39
39
  - 真实 Node PTC 进程调用原 read 与总线;测试使用显式非约束策略,不代表桌面沙箱通过。
40
+ - 真实 Node PTC 预算到期后,已受理总线执行继续并可同 requestId 取回;外部中断仍请求取消执行。
40
41
 
41
42
  以上是场景摘要,不表示真实模型/宿主 GUI 已通过。
42
43
 
43
44
  ## 测试之外仍需注意
44
45
 
45
- - 宿主 read 的错误目前被适配层统一映射为 `HOST_READ_FAILED`;在取消后可能保守记为 `unknown`,不能把它当作取消已确认。
46
+ - 宿主工具调用失败在转发层使用固定码(host.read 为 `HOST_READ_FAILED`,其余为 `HOST_TOOL_FAILED`),进入总线后统一结算为 `failed` / `HANDLER_FAILED`,错误原文不保存;取消后可能保守记为 `unknown`,不能把它当作取消已确认。
46
47
  - 相同逻辑请求的取消是请求级取消,不能简单用 Promise.race 放弃执行来改成等待者级取消。
47
48
  - 当前没有远端 Handler 传输或持久化恢复;测试没有提供这些能力。
49
+ - 预算分离等待依据 DSH 0.2.1-rc.2 的内部中断原因字符串;换宿主版本需重新验证,未知原因保守按取消处理。
48
50
 
49
51
  ## 要直接在聊天会话中试用
50
52
 
package/docs/PRODUCT.md CHANGED
@@ -2,9 +2,11 @@
2
2
 
3
3
  ## 产品边界
4
4
 
5
- 萧何是 DSH 内的可选执行协调插件,提供独立可选择的 PTC 派生预设,不是 PTC 替代传输层,也不全局接管终端、编辑或其他工具。实际业务 Handler 为 host.read、host.edit 与 host.write(host.edit/host.write 有副作用、非幂等);test 是兼容保留的诊断 Handler,只有明确诊断需求时使用。测试能力存在不代表其他命令已接入总线。
5
+ 萧何是 DSH 内的可选执行协调插件,提供独立可选择的 PTC 派生预设,不是 PTC 替代传输层,也不全局接管终端、编辑或其他工具。实际业务 Handler 为 host.read、host.glob、host.grep(只读、幂等)与 host.edit、host.write、host.pwsh(有副作用、非幂等);test 是兼容保留的诊断 Handler,只有明确诊断需求时使用。测试能力存在不代表其他工具或命令已接入总线。
6
6
 
7
- 0.7.0 在 DSH 0.2.1-rc.2 基线上接入 host.edit 与 host.write,并以幂等声明约束有副作用 Handler 的结果复用,不以更名宣称完成生产环境认证。当前真实模型、桌面 UI 和实际沙箱尚未完整验收;同进程内存状态不支持跨重启恢复。
7
+ 0.8.0 在 DSH 0.2.1-rc.2 基线上补入只读搜索 Handler host.glob / host.grep 与有副作用命令 Handler host.pwsh,沿用 0.7.0 的幂等声明与宿主工具工厂,不以更名宣称完成生产环境认证。当前真实模型、桌面 UI 和实际沙箱尚未完整验收;同进程内存状态不支持跨重启恢复。
8
+
9
+ 0.9.0 增加 PTC 预算到期后的分离等待:宿主中断 PTC 子调用时,已受理执行只解除等待、继续运行,可用同 requestId 的 status/result 取回或用 cancel 取消;其他中断原因仍按取消处理。该区分依据 DSH 0.2.1-rc.2 的中断原因字符串,不是公开稳定契约,宿主升级需复核。
8
10
 
9
11
  ## 入口及配置层次
10
12
 
@@ -25,10 +27,10 @@
25
27
  | product | 固定身份、容量/准入默认值、工具参数与提示契约 | 不提供用户可覆盖的运行时配置入口 |
26
28
  | preset | 声明派生、兼容检查和宿主注册 | 不偷偷重写源 ptc 或持久配置 |
27
29
  | mode / test-mode 兼容层 | 作用域说明与工具安装 | 不改宿主权限/沙箱/呈现,不加载第二套 PTC |
28
- | plugin | 工具身份校验、可信执行上下文和宿主 read 派发 | 不自行文件读取或创建通用命令执行端 |
30
+ | plugin | 工具身份校验、可信执行上下文和宿主工具派发 | 不自行文件读取、搜索或创建通用命令执行端 |
29
31
  | bus / json | 请求校验、幂等冲突、调度、取消、终态与有界状态 | 不以超时推定副作用失败、不自动重跑 |
30
32
  | execution | Job 投影、活跃工具交付与关闭所有权 | 不作为第二个执行状态机 |
31
- | handlers | 实际读取适配和明确诊断 Handler | 不把测试当成通用业务执行 |
33
+ | handlers | 宿主工具转发(read/glob/grep/edit/write/pwsh)和明确诊断 Handler | 不把测试当成通用业务执行 |
32
34
  | diagnostics | 有界数值轨迹 | 不保留请求内容、错误原文或充当授权审计 |
33
35
 
34
36
  ## 兼容和错误规则
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## 兼容目标
4
4
 
5
- 源码调查基线为 **2026-10-15 的 DSH 0.2.0-rc.2、Cordis 4.0.4**。本项目用同版本 npm 组件编译和隔离测试;这不是对任意旧版、新版宿主的兼容保证,也不是对读者当前安装版本的自动检测。Node.js 要求为 22 或以上;CI 使用 Node 22、24。
5
+ 源码调查基线为 **2026-10-15 的 DSH 0.2.0-rc.2、Cordis 4.0.4**;0.6.0 起兼容目标与 npm 依赖升级为 **DSH 0.2.1-rc.2**(Cordis ~4.0.4),本文调用链行号仍来自 0.2.0-rc.2 调查快照,宿主升级后可能已变化,需按实际安装包复核。本项目用兼容目标版本的 npm 组件编译和隔离测试;这不是对任意旧版、新版宿主的兼容保证,也不是对读者当前安装版本的自动检测。Node.js 要求为 22 或以上;CI 使用 Node 22、24。
6
6
 
7
7
  本项目只做插件,没有修改宿主源码、ASAR 或其他插件。
8
8
 
@@ -13,7 +13,7 @@ AgentLoop 发起工具调用
13
13
  → ToolRuntime 校验、策略与可信身份绑定
14
14
  → execution_bus 工具体
15
15
  → 内存去重/排队,宿主 Job 记录和程序等待
16
- → test Handler 或经 ToolRuntime 再调用宿主 read
16
+ → test Handler 或经 ToolRuntime 再调用宿主工具(read/glob/grep/edit/write/pwsh)
17
17
  → 保存执行结果,清理 Job
18
18
  → 工具体返回
19
19
  → AgentLoop 关联原工具调用并继续会话
@@ -35,6 +35,7 @@ PTC 是可选入口:外层 `run_code` 可以调用同一个工具。它不是
35
35
  | 注册与卸载 | `@deepseek-ai/dsh-tools`:2878–2886,工具注册;3294–3331,`dispatchToolBody` | 注册为作用域副作用,工具体可异步等待 |
36
36
  | 身份与策略 | `@deepseek-ai/dsh-tools`:3131–3175、3225、3504、3417 | 生成可信 token、保留 agent/callId/rootCallId,执行前后策略及结果通知 |
37
37
  | PTC 子调用 | `@deepseek-ai/dsh-tools`:1294–1307 | 子调用携带 agent、rootCallId 和 parent token;不是任意身份注入 |
38
+ | PTC 子调用中断 | `@deepseek-ai/dsh-tools`:1282–1285 外层中断转发;1376、1508 子调用信号取自 `runController`;1514 程序结束/预算到期后以固定字符串中断残留子调用 | 外层中断原因与程序结束原因可区分;固定字符串是 rc.2 构建细节,不是公开稳定契约 |
38
39
  | 文件读取 | `@deepseek-ai/dsh-tool-fs`:174、348,read 注册/执行路径 | 工作目录来自会话;输出和文件边界由宿主组合决定 |
39
40
  | 任务与等待 | `@deepseek-ai/dsh-jobs-local`:412–491 `start`、510 `wait`、717–729 `updateProgress` | 所属访问、容量、进度、取消、首终态与程序等待可复用 |
40
41
  | 完成通知 | `@deepseek-ai/dsh-tool-jobs`:268–270 | 正常已等待的完成通知不再额外报告;异常等待通道不承诺这一抑制仍完整生效 |
@@ -52,6 +53,7 @@ PTC 是可选入口:外层 `run_code` 可以调用同一个工具。它不是
52
53
  - 复用宿主工具管线和 Job 服务,不自行启动进程或实现独立 HTTP 执行服务。
53
54
  - bundle patch 加载派生注册器,从已声明 ptc 读取组合快照并注册可选预设,由宿主既有 Agent 预设界面消费元数据,不需要自定义前端。readDocument 在宿主注释中用于查看声明,本插件只读取其序列化数据再注册独立预设,并不认领源预设的运行实例或私有基准地址。
54
55
  - 同预设范围内共享有界总线,但查询/取消按宿主 Agent 的会话身份分隔。
56
+ - PTC 预算到期后的分离等待(0.9.0):程序结束只停止等待,已受理执行与宿主 Job 继续,同会话可用同一 requestId 取回结果;其他中断原因仍取消。该识别依赖 rc.2 固定中断原因,未知原因保守按取消处理。
55
57
 
56
58
  旧版只读 guard 在 0.3.0 移除,预设保留源 ptc 的工具与权限,不再削减普通写入/命令能力,也不自动启用源组合禁用行。它不是进程或权限沙箱,不隔离进程资源消耗。宿主 cwd 只是路径解析基准,不是文件访问围栏。
57
59
 
@@ -63,6 +65,7 @@ PTC 是可选入口:外层 `run_code` 可以调用同一个工具。它不是
63
65
  - 持久化受理、跨重启恢复或重新认领原工具调用。
64
66
  - 工具结果已写入会话磁盘日志的持久化回执。
65
67
  - 远端执行端、通用工作流或有副作用操作的对账能力。
68
+ - 跨宿主版本稳定的 PTC 中断原因契约;0.9.0 的预算分离等待只按 rc.2 实际使用的固定字符串识别,宿主升级后需复核。
66
69
 
67
70
  若未来要跨重启接续,需要宿主公开稳定的认领/提交契约;本项目不虚构这样的 API,也不通过聊天消息绕过。
68
71
 
package/docs/protocol.md CHANGED
@@ -40,7 +40,7 @@
40
40
 
41
41
  快照字段:`requestId`、`state`、`sequence`、`cancelRequested`、`delivery`,以及可选 `result`、`error`、`progress`。`status`、`result`、`cancel` 均返回当前快照;`result` 在运行中也只返回当前状态,不额外等待。
42
42
 
43
- core 的 `submit()` 返回 `accepted`、`done` Promise 和取消/解除通知/返回标记句柄。accepted 只是内存受理或已有记录的快照,`durable:false`,不代表执行成功;终态重取也不代表重新执行。
43
+ core 的 `submit()` 返回 `accepted`、`done` Promise、只读 `snapshot()` 及取消/解除通知/返回标记句柄。accepted 只是内存受理或已有记录的快照,`durable:false`,不代表执行成功;终态重取也不代表重新执行。0.9.0 的 `snapshot()` 只供停止等待时读取当前视图,不改变交付标记。
44
44
 
45
45
  通知包含版本、消息 ID、请求 ID、关联 ID(correlationId)、请求内序号、类型与 payload。accepted 的 correlationId 对应本次提交消息,序号是当前快照;后续事件关联首次请求 messageId,新增序号。类型包括 started、progress、cancel_requested 和 succeeded、failed、cancelled、unknown 四种终态事件。
46
46
 
@@ -68,6 +68,12 @@ queued → running → succeeded / failed / cancelled / unknown
68
68
 
69
69
  执行完成与结果交付分开。`pending`/`returned` 只是插件返回路径的标记;done 快照保留当时值,后续查询可看到更新。**returned 不证明宿主磁盘提交或模型已消费**。外层取消/后置策略仍可能改变返回值。
70
70
 
71
+ ### 外层调用结束与时间预算(0.9.0)
72
+
73
+ PTC 程序结束(含 `run_code` 时间预算到期)时,宿主以固定原因中断其中的工具子调用。总线对**已受理**请求只解除本次等待,不请求取消:执行与宿主 Job 继续,同一会话可用同一 requestId 的 `status`/`result` 取回(受记录保留期限制),或发送 `cancel`。用户/会话主动中断、沙箱模式变化等其他原因仍请求取消整个执行。
74
+
75
+ 这条区分依据 DSH 0.2.1-rc.2 的内部中断原因字符串(`run_code settled`),不是宿主公开稳定契约;未知原因按取消处理。分离等待不改变内存与保留期边界:进程退出仍丢失全部状态,`returned` 仍不证明模型已取回结果。
76
+
71
77
  错误也须分层:Handler 异常原文不进入保存结果,使用 HANDLER_FAILED 等固定码;不合法、过大或快照不可保存结果为 unknown / RESULT_NOT_RETAINED。宿主 wait/remove 等服务错误可能作为外层工具错误传出,不能笼统声称所有错误都已脱敏或都是固定码。不要把宿主服务错误文本当成业务执行失败凭据。
72
78
 
73
79
  ## 4. 容量、保存与关闭
@@ -116,4 +122,4 @@ core 实例的 `diagnostics()` 返回只读用途的独立快照:阶段计数
116
122
 
117
123
  包的 `./core` 导出 ExecutionBus、Handler、Capability 类型。Handler 只接收输入、requestId、signal、progress 和可选最小 capability,不接收聊天历史。register 返回绑定唯一注册令牌的幂等注销函数,不会误删后来同名注册;已受理请求继续持有原 Handler。
118
124
 
119
- 内置 test 与 host.read 没有副作用;host.edit 与 host.write 是非幂等写 Handler,通过 `Handler.idempotent=false` 显式声明,其终态结果复用被 `MUTATING_REUSE_DENIED` 拒绝,运行中的重复附着仍只等待同一执行。当前没有 ctx.executionBus 服务、远端传输、跨插件动态注册或外部副作用对账契约。扩展有副作用 Handler 前必须显式声明幂等并另行设计授权与崩溃对账,不能仅依赖本版请求键。
125
+ 内置 test、host.read、host.glob 与 host.grep 没有副作用;host.edit、host.write 与 host.pwsh 是非幂等写/命令 Handler,通过 `Handler.idempotent=false` 显式声明,其终态结果复用被 `MUTATING_REUSE_DENIED` 拒绝,运行中的重复附着仍只等待同一执行。0.8.0 新增宿主工具输入错误码 INVALID_GLOB_INPUT、INVALID_GREP_INPUT 与 INVALID_PWSH_INPUT;协议既有错误码不改名。host.pwsh 的后台结果只是宿主 Job ID,不是完成回执。当前没有 ctx.executionBus 服务、远端传输、跨插件动态注册或外部副作用对账契约。扩展有副作用 Handler 前必须显式声明幂等并另行设计授权与崩溃对账,不能仅依赖本版请求键。
@@ -0,0 +1,18 @@
1
+ # 萧何 / Xiao He 0.8.0
2
+
3
+ ## 宿主工具覆盖面扩展:搜索与命令
4
+
5
+ 本版沿用 0.7.0 的通用 `hostToolHandler` 工厂与 `makeHostInvoke` 抽象,新增三个宿主工具 Handler。
6
+
7
+ - 新增 `host.glob`(`pattern` / `path?`)与 `host.grep`(`pattern` / `path?` / `include?`):只读、幂等,终态结果可复用;沿用宿主工具的工作目录、忽略规则与结果上限。`include` 只接受单个正向 glob,不支持取反(`!`)或顶层逗号列表。
8
+ - 新增 `host.pwsh`(`description` / `command` / `timeoutMs?` / `workdir?` / `run_in_background?` / `sandbox_permissions?` / `justification?`):有副作用、非幂等,同一 requestId 的终态结果不可复用,重复提交返回 `MUTATING_REUSE_DENIED`;运行中的重复附着仍只等待同一执行。`sandbox_permissions` 只接受 `workspace-write` / `danger-full-access`,且必须与 `justification` 成对出现,与宿主 pwsh/sandbox 契约一致。
9
+ - 命令仍由宿主 `pwsh` 工具经 shell 执行器、沙箱与审批链执行;插件不自行启动进程。后台模式只返回宿主 Job ID,不等于命令完成。
10
+ - 新增错误码 `INVALID_GLOB_INPUT`、`INVALID_GREP_INPUT`、`INVALID_PWSH_INPUT`;既有错误码、协议字段与 `host.read` / `host.edit` / `host.write` 行为不变。
11
+
12
+ ## 升级说明
13
+
14
+ 需要 DSH 0.2.1-rc.2。本版不强制把原工具改成总线调用,普通任务仍使用原工具;`host.glob` / `host.grep` / `host.pwsh` 只在你显式提交总线请求时执行。不自动安装、重写日常配置或重启 DSH。历史预设、配置行、工具名、协议字段与既有错误码均不变。
15
+
16
+ ## 验证与限制
17
+
18
+ 本地全量 93 项测试通过(含 host.glob / host.grep / host.pwsh 的转发、参数校验与幂等分流回归;搜索与命令 Handler 的转发测试使用宿主工具桩,不是真实搜索/命令实现),包白名单校验通过。真实 glob/grep/pwsh 工具实现、真实模型、桌面 UI 与实际沙箱仍未完整验收;状态为进程内存,不支持跨重启恢复。有副作用 Handler 的外部副作用对账仍不在本版范围。
@@ -0,0 +1,19 @@
1
+ # 萧何 / Xiao He 0.9.0
2
+
3
+ ## PTC 预算到期后的分离等待
4
+
5
+ 本版解决“长任务超出 `run_code` 时间预算就被连带取消”的问题:程序结束只停止等待,已受理执行继续。
6
+
7
+ - PTC 程序结束或 `run_code` 时间预算到期时,宿主会以固定原因中断其中的工具子调用。总线对已受理请求只解除本次等待:执行与宿主 Job 继续,同一会话可用同一 requestId 的 `status`/`result` 取回结果(受 1 小时保留期与 256 条记录上限约束),或发送 `cancel` 取消。
8
+ - 用户/会话主动中断、沙箱模式变化等其他中断原因仍请求取消整个执行;未知原因保守按取消处理。
9
+ - 该区分依赖 DSH 0.2.1-rc.2 实际使用的内部中断原因字符串(`@deepseek-ai/dsh-tools` 构建中的 `run_code settled`),不是宿主公开稳定契约;宿主升级后需复核。
10
+ - core 的 `submit()` 附着新增只读 `snapshot()`,供停止等待时返回当前快照;不改变既有状态机、幂等与结果保留语义。
11
+ - 模式提示与工具体描述同步说明取回与取消方式。
12
+
13
+ ## 升级说明
14
+
15
+ 需要 DSH 0.2.1-rc.2。行为变化:**PTC 程序结束不再连带取消已受理执行**。若需要旧行为(程序结束即取消),应在程序结束前显式发送 `cancel` 控制消息。不自动安装、重写日常配置或重启 DSH。历史预设、配置行、工具名、协议字段与既有错误码均不变;状态仍为进程内存,不支持跨重启恢复。
16
+
17
+ ## 验证与限制
18
+
19
+ 本地全量 101 项测试通过(新增 6 项分离等待回归、2 项真实 Node PTC 预算/中断回归,覆盖宿主 Job 生命周期、重附着与分离后的宿主工具续调用)。真实模型、桌面 UI 与实际沙箱仍未完整验收;分离等待只在同一插件实例存活期间有效,进程退出即丢失状态;跨宿主版本的中断原因识别未验证。
@@ -1,14 +1,15 @@
1
1
  # 验证范围与使用限制
2
2
 
3
- 本文说明当前版本的证据边界,不是生产环境认证。当前能力基线为 **v0.5.0**,在此前生命周期、数值诊断及轮转上新增会话准入配额、排队期限和隔离状态工具;预设沿用 v0.3.0 的宿主 PTC 声明派生方式。验证环境为 Windows、Node.js 24.21.0,宿主组件锁定 DSH 0.2.0-rc.2、Cordis 4.0.4。
3
+ 本文说明当前版本的证据边界,不是生产环境认证。当前能力基线为 **v0.9.0**,在 0.5.0 的会话准入/排队、0.7.0 的宿主工具转发与 0.8.0 的搜索/命令 Handler 上,补入 PTC 预算到期后的分离等待;预设沿用 v0.3.0 的宿主 PTC 声明派生方式。验证环境为 Windows、Node.js 24.21.0,宿主组件锁定 DSH 0.2.1-rc.2、Cordis 4.0.4。
4
4
 
5
5
  ## 已验证什么?
6
6
 
7
7
  | 层次 | 检查内容 | 能说明什么 |
8
8
  |---|---|---|
9
9
  | 总线核心 | 参数、队列、并发、重复请求、冲突、取消竞争、结果保存、TTL、监听与注销 | 程序内部约束及已覆盖异常路径可重复检查 |
10
- | 真实宿主组件 | Cordis、ToolRuntime、LocalJobs、LocalFS、文件工具 | 请求经过真实工具管线;权限拒绝、Job 进度、共享任务与清理逻辑有效;Agent 身份为夹具 |
10
+ | 真实宿主组件 | Cordis、ToolRuntime、LocalJobs、LocalFS、文件工具;host.glob/host.grep/host.pwsh 的转发测试使用宿主工具桩 | 请求经过真实工具管线;权限拒绝、Job 进度、共享任务、参数校验、幂等分流与清理逻辑有效;Agent 身份与工具实现为夹具,桩不证明真实搜索/命令工具实现 |
11
11
  | 真实会话循环 | AgentLoop、AgentRegistry、SessionStore;脚本模型适配器 | 内存会话中原工具结果只提交一次,完成后再进入下一次适配器调用 |
12
+ | PTC 预算分离等待 | 真实 Node PTC `run_code` 以 2 秒预算等待 5 秒总线执行:预算到期后执行继续、宿主 Job 保留、同 requestId 取回结果;外部中断仍取消执行 | 在 DSH 0.2.1-rc.2 实际中断原因下成立;固定字符串不是跨版本契约 |
12
13
  | 预设隔离 | AgentPresetRegistry 与 Loader | 派生预设可激活;源 ptc 声明不变、普通 Agent 不可见总线;原 write/edit/Job 工具保留,宿主前置策略拒绝仍有效 |
13
14
  | 故障注入 | 克隆失败、观察者拒绝、Job 等待/清理异常、先行移除与卸载交错 | 指定故障下的回归约束;不证明所有故障组合都已覆盖 |
14
15
  | 候选包 | 严格文件白名单、临时目录生产依赖安装、入口注册 | 包可安装和加载;安装验证使用简化宿主夹具,不是桌面插件管理器验收 |
@@ -42,6 +43,8 @@ eb95b4e51675f5f1821275e0812ef4dd4984b1aba45a52fbc6bab3518bbf6f38
42
43
  | 当前桌面预设卡片、进度界面、授权提示和实际沙箱 | 未验收;组件事件和 LocalFS 测试不等于桌面 UI/沙箱 |
43
44
  | 实际模型/桌面 PTC 与时间预算、沙箱行为 | 真实 Node PTC 隔离子进程已调用原 read 和总线;使用显式 danger-full-access 测试策略与测试 Agent,不是桌面沙箱/真实模型验收 |
44
45
  | 从真实 tgz 经宿主插件管理器加载预设、卸载与回滚 | 未完成完整桌面流程;源码工作区的 Loader 测试不能替代 |
46
+ | 真实 glob/grep/pwsh 工具实现 | 未在测试环境启用:真实搜索工具依赖打包 ripgrep 与 subprocess 服务,真实 pwsh 依赖 shell/sandbox/审批组合;本版只验证按 handler 名转发、输入校验、幂等分流与失败固定码 |
47
+ | 跨版本 PTC 中断原因 | 分离等待只识别 DSH 0.2.1-rc.2 实际使用的固定中断原因字符串;宿主升级后未知原因保守按取消处理,需复核 |
45
48
  | 磁盘会话结果提交及重启恢复原调用 | 未验收磁盘提交;本插件不支持跨重启恢复 |
46
49
  | 减少真实模型轮次、状态查询或总耗时的对照 | 未验证,不给提升比例 |
47
50
  | 长期运行、所有卸载/服务故障组合 | 未穷尽;持续故障仍有清理限制 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feng0531/dsh-execution-bus",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "license": "SEE LICENSE IN LICENSE",