@zhushanwen/zcode-subagent-cli 0.1.2 → 0.2.1

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.
@@ -28,6 +28,9 @@ var ZCODE_APPSERVER_ABORT_GRACE_MS = 3e3;
28
28
  var ZCODE_APPSERVER_ERR_MODEL_CONFIG_MISSING = -32603;
29
29
  var ZCODE_APPSERVER_ERR_BUSY_SESSION = -32010;
30
30
  var ZCODE_APPSERVER_HARVEST_GRACE_MS = 1e3;
31
+ function isFailedTerminalStatus(status) {
32
+ return status === "failed" || status === "error";
33
+ }
31
34
 
32
35
  // src/db-path.ts
33
36
  import * as os from "os";
@@ -680,6 +683,11 @@ var AppServerConnection = class {
680
683
  reqSeq = 0;
681
684
  /** stderr 滚动缓冲(代级:崩溃诊断用)。 */
682
685
  stderrTail = "";
686
+ /**
687
+ * stderr tee 落盘流(D6-⑦;merge 裁决:旋转走 logs/stderr-rotation 的路径式
688
+ * rotateStderrLogIfNeeded——W5 边界禁 import subagent-core 的 SizeRotatedAppendStream,
689
+ * 常驻流改裸 WriteStream + 按次轮转检查,帽语义等价)。
690
+ */
683
691
  stderrStream = null;
684
692
  stderrStreamFailed = false;
685
693
  /**
@@ -1366,7 +1374,13 @@ var SessionChannel = class {
1366
1374
  });
1367
1375
  const turn = {
1368
1376
  sessionId,
1369
- callbacks: { onTextDelta: opts.onTextDelta, onThinkingDelta: opts.onThinkingDelta },
1377
+ callbacks: {
1378
+ onTextDelta: opts.onTextDelta,
1379
+ onThinkingDelta: opts.onThinkingDelta,
1380
+ // [PR3] tool 执行期活性回调(SessionTurnCallbacks.onActivity 注释——宿主侧
1381
+ // 无进展守护的工具执行期刷新面)
1382
+ onActivity: opts.onActivity
1383
+ },
1370
1384
  settled: false,
1371
1385
  deltas: [],
1372
1386
  finalText: void 0,
@@ -1482,7 +1496,9 @@ var SessionChannel = class {
1482
1496
  if (payload === void 0) return;
1483
1497
  this.refreshIdle(turn);
1484
1498
  if (this.applyFinalFrame(turn, payload)) return;
1485
- this.applyStreamDelta(turn, payload);
1499
+ if (!this.applyStreamDelta(turn, payload) && !turn.settled) {
1500
+ turn.callbacks.onActivity?.();
1501
+ }
1486
1502
  }
1487
1503
  /**
1488
1504
  * 收尾帧判定与吸收(A.2 ⑤ 两种形态:payload.response / stopReason+content 变体)。
@@ -1506,9 +1522,12 @@ var SessionChannel = class {
1506
1522
  /** 增量 delta 分发:非空 delta 入账 + 回调;终态后迟到丢弃(不变量 2)。
1507
1523
  * kind 区分两通道(F2):reasoning_delta 只走 thinking 回调(不入 deltas 账本
1508
1524
  * ——deltas 是 response 兜底聚合,推理文本不是答案正文);text_delta / kind
1509
- * 缺席走 text 路径。 */
1525
+ * 缺席走 text 路径。
1526
+ * 返回值([PR3]):帧被 delta 路径消费(thinking 或 text,回调若注册则已触发)
1527
+ * → true;无 delta / 空 delta / 终态后迟到丢弃 → false(handleSessionEvent 据
1528
+ * 此分流 onActivity——delta 帧已是宿主可见进展,不双发活性信号)。 */
1510
1529
  applyStreamDelta(turn, payload) {
1511
- if (typeof payload.delta !== "string" || payload.delta === "") return;
1530
+ if (typeof payload.delta !== "string" || payload.delta === "") return false;
1512
1531
  if (turn.settled) {
1513
1532
  logger2.warn(
1514
1533
  `\u7EC8\u6001\u540E\u8FDF\u5230\u7684 delta \u4E22\u5F03\uFF08\u4F1A\u8BDD ${turn.sessionId}\uFF0C\u4E0D\u53D8\u91CF 2\uFF1Aresolve \u540E\u4E0D\u518D\u53D1\u4E8B\u4EF6\uFF09: ${payload.delta.slice(
@@ -1516,14 +1535,15 @@ var SessionChannel = class {
1516
1535
  DELTA_LOG_CHARS
1517
1536
  )}`
1518
1537
  );
1519
- return;
1538
+ return false;
1520
1539
  }
1521
1540
  if (payload.kind === "reasoning_delta") {
1522
1541
  turn.callbacks.onThinkingDelta?.(payload.delta);
1523
- return;
1542
+ return true;
1524
1543
  }
1525
1544
  turn.deltas.push(payload.delta);
1526
1545
  turn.callbacks.onTextDelta?.(payload.delta);
1546
+ return true;
1527
1547
  }
1528
1548
  handleTelemetry(params) {
1529
1549
  if (!isRecord3(params)) return;
@@ -1543,13 +1563,38 @@ var SessionChannel = class {
1543
1563
  turn.lastTerminalStatus = status;
1544
1564
  this.recordTerminalError(turn, params);
1545
1565
  if (turn.settled) {
1546
- logger2.warn(
1547
- `\u6743\u5A01\u7EC8\u6001\u665A\u4E8E\u843D\u5B9A\u7ED3\u679C\u5230\u8FBE\uFF08\u4F1A\u8BDD ${turn.sessionId}\uFF0C\u5DF2\u843D\u5B9A source=${turn.terminal?.source}\uFF09\uFF1Aturn.terminal status="${status}" \u4EC5\u8BB0\u5F55\u4E0D\u6539\u5199\uFF08P0-1 D5\u2460\uFF09`
1548
- );
1566
+ this.logLateTerminal(turn, status);
1549
1567
  return;
1550
1568
  }
1551
1569
  turn.settle({ status, source: "turn.terminal" });
1552
1570
  }
1571
+ /**
1572
+ * 已落定 turn 的迟到权威终态分级日志(P-Z2 后续:常态迟到降噪)。真机实证该
1573
+ * 形态的唯一可达路径是 success 终态常态迟到(final-frame 先落定 + 权威
1574
+ * turn.terminal 迟到)——即每个成功任务必经;原无条件 warn 经 SDK cli-entry
1575
+ * 的 stderr 兜底 → runtime [rpc:stderr] 全量 console.error 链路,每个成功任务
1576
+ * 产一条零异常区分度的 ERROR 级日志。按权威 status 分级(落定语义不动——
1577
+ * lastTerminalStatus/lastTerminalError 的入账在上游无条件路径完成):
1578
+ * - "success":常态迟到,零日志;
1579
+ * - "interrupted":用户中断形态,debug(stderr 兜底对 debug no-op——对齐
1580
+ * SDK logger CONSOLE_SINK 语义,host/log 反向请求侧仍可观测);
1581
+ * - 失败类(isFailedTerminalStatus,与引擎失败分流同口径)与 unknown/未识别
1582
+ * status:保守 warn(原样 status 已写入文案)——假成功识破的防御面,理论
1583
+ * 不可达但保留,宁可误报不静默。
1584
+ */
1585
+ logLateTerminal(turn, status) {
1586
+ if (status === "success") return;
1587
+ const message = `\u6743\u5A01\u7EC8\u6001\u665A\u4E8E\u843D\u5B9A\u7ED3\u679C\u5230\u8FBE\uFF08\u4F1A\u8BDD ${turn.sessionId}\uFF0C\u5DF2\u843D\u5B9A source=${turn.terminal?.source}\uFF09\uFF1Aturn.terminal status="${status}" \u4EC5\u8BB0\u5F55\u4E0D\u6539\u5199\uFF08P0-1 D5\u2460\uFF09`;
1588
+ if (isFailedTerminalStatus(status)) {
1589
+ logger2.warn(message);
1590
+ return;
1591
+ }
1592
+ if (status === "interrupted") {
1593
+ logger2.debug(message);
1594
+ return;
1595
+ }
1596
+ logger2.warn(message);
1597
+ }
1553
1598
  /** terminal 帧专属错误信息入账(⛔P-Z2 实证:真实 failed 终态的 errorCode/errorMessage
1554
1599
  * 只在 terminal 帧携带,read/delta 拿不到——先到/迟到都记录,消费层合成失败
1555
1600
  * 文案时优先采信)。二者均缺失时不挂 lastTerminalError 字段。 */
@@ -1835,6 +1880,11 @@ var ZcodeEngine = class {
1835
1880
  // 不变量 3a 的拼接比对不含 reasoning)
1836
1881
  onTextDelta: (delta) => ctx.onEvent?.({ type: "text_delta", delta }),
1837
1882
  onThinkingDelta: (delta) => ctx.onEvent?.({ type: "thinking_delta", delta }),
1883
+ // [PR3] 工具执行期活性:非终态非增量的 session/event 帧(tool.updated progress
1884
+ // 等,真机探针实证每 ~1s 一帧)→ activity 事件(零载荷纯活性信号——宿主无进展
1885
+ // 守护对任何事件类型刷新;reducer no-op、不落 journal)。zcode 引擎
1886
+ // conversation:"unsupported",run 域是唯一发射面(无 chat 域接线)。
1887
+ onActivity: () => ctx.onEvent?.({ type: "activity" }),
1838
1888
  onSessionCreated: (sessionId) => {
1839
1889
  currentSessionId = sessionId;
1840
1890
  rt.activeSessions.add(sessionId);
@@ -2061,6 +2111,17 @@ var ZcodeEngine = class {
2061
2111
  }
2062
2112
  await this.shutdownRuntimeAndDisposeChannel(rt);
2063
2113
  }
2114
+ /**
2115
+ * [u7a D5] 引擎在途只读快照:activeSessions 非空才算在途——poolKey 'shared' 的
2116
+ * app-server **空闲常驻进程恒活,禁止按进程存在判定**(进程在 ≠ 在途,否则推迟
2117
+ * 判定恒真、30min 上限从兜底变常态路径,设计 §3.3 D5 显式排除)。计数权威 =
2118
+ * activeSessions(attempt 入 create 应答后 add / finally settle 后 delete,与
2119
+ * dispose 的 close 帧目标集同一状态源,无双记账)。运行时未初始化(从未 run /
2120
+ * 已 dispose)→ 恒 0。
2121
+ */
2122
+ inFlightSnapshot() {
2123
+ return { inFlight: this.appserverRuntime?.activeSessions.size ?? 0 };
2124
+ }
2064
2125
  /** 终态合成(extension-conventions 函数 80 行上限,从 run 提取):aborted / run-failed / parsed 三分支。 */
2065
2126
  finalizeOutcome(task, ctx, final, usageAcc, startedAt) {
2066
2127
  const outcome = {
@@ -2129,17 +2190,6 @@ var ZcodeEngine = class {
2129
2190
  }
2130
2191
  for (const ev of synthesizeCoarseEvents(payload.response, payload.usage)) emit(ev);
2131
2192
  }
2132
- /**
2133
- * D1 可选面:zcode 首期不支持 conversation(capabilities 声明)——同步拒绝、
2134
- * 不创建进程,文案给可操作建议(A11)。
2135
- */
2136
- async interact(_handle, _action) {
2137
- return {
2138
- ok: false,
2139
- code: "engine_capability_unsupported",
2140
- message: "zcode \u5F15\u64CE\u4E0D\u652F\u6301 conversation \u4EA4\u4E92\u63A7\u5236\u9762\uFF08capabilities.conversation = 'unsupported'\uFF0C\u6BCF\u4EFB\u52A1\u81EA\u5305\u542B\u4F1A\u8BDD\uFF0C\u65E0\u540C\u8FDB\u7A0B idle \u590D\u7528\uFF09\u3002\u6062\u590D\u6307\u5F15\uFF1A\u6539\u7528\u5355\u6B21 subagent \u8C03\u7528\u91CD\u65B0\u6D3E\u53D1\u4EFB\u52A1\uFF0C\u6216\u4F7F\u7528 engine: 'pi'\uFF08chatMode idle \u590D\u7528\uFF0C\u652F\u6301 message/close/cancel\uFF09\u3002"
2141
- };
2142
- }
2143
2193
  /** [U7] 模型可发现性:v2 桌面登录态聚合(带凭据 provider × models),失败安全返回清单本身可能为空。 */
2144
2194
  listModels() {
2145
2195
  return listZcodeModels(this.deps.sources);
@@ -2339,9 +2389,6 @@ function authoritativeTerminalStatus(r) {
2339
2389
  if (r.lastTerminalStatus !== void 0) return r.lastTerminalStatus;
2340
2390
  return r.terminal.source === "turn.terminal" ? r.terminal.status : void 0;
2341
2391
  }
2342
- function isFailedTerminalStatus(status) {
2343
- return status === "failed" || status === "error";
2344
- }
2345
2392
  function parsedAppServerAttempt(task, r) {
2346
2393
  if (isFailedTerminalStatus(authoritativeTerminalStatus(r))) {
2347
2394
  return failedTerminalAppServerAttempt(r);
@@ -2526,7 +2573,7 @@ var EngineProtocolServer = class {
2526
2573
  }
2527
2574
  }
2528
2575
  }
2529
- /** 10 正向方法分发(表驱动:method → 处理器;未知方法 → engine_protocol_unknown_method)。 */
2576
+ /** 9 正向方法分发(表驱动:method → 处理器;未知方法 → engine_protocol_unknown_method)。 */
2530
2577
  async dispatch(id, method, params) {
2531
2578
  const handler = this.methodHandlers[method];
2532
2579
  if (handler === void 0) {
@@ -2539,7 +2586,7 @@ var EngineProtocolServer = class {
2539
2586
  return handler(params);
2540
2587
  }
2541
2588
  /**
2542
- * 10 正向方法 → 处理器映射(每个处理器消费原始 params 并自行收敛类型——
2589
+ * 9 正向方法 → 处理器映射(每个处理器消费原始 params 并自行收敛类型——
2543
2590
  * 与原 switch case 表达式一一对应)。
2544
2591
  */
2545
2592
  methodHandlers = {
@@ -2547,7 +2594,6 @@ var EngineProtocolServer = class {
2547
2594
  probe: (p) => this.engine.probe(probeParamsOf(p)),
2548
2595
  run: (p) => this.run(p),
2549
2596
  cancel: (p) => this.cancel(p),
2550
- interact: (p) => this.interact(p),
2551
2597
  read: (p) => this.read(p),
2552
2598
  listModels: () => ({ models: this.engine.listModels?.() ?? null }),
2553
2599
  validateModel: (p) => this.validateModel(p),
@@ -2623,9 +2669,6 @@ var EngineProtocolServer = class {
2623
2669
  if (active !== void 0) active.controller.abort(new Error(`cancelled by host: ${params.reason}`));
2624
2670
  return { ok: true };
2625
2671
  }
2626
- async interact(params) {
2627
- return this.engine.interact({ data: params.handle }, params.action);
2628
- }
2629
2672
  read(params) {
2630
2673
  return this.engine.read({ data: params.handle });
2631
2674
  }
package/dist/index.cjs CHANGED
@@ -78,6 +78,9 @@ var ZCODE_APPSERVER_ABORT_GRACE_MS = 3e3;
78
78
  var ZCODE_APPSERVER_ERR_MODEL_CONFIG_MISSING = -32603;
79
79
  var ZCODE_APPSERVER_ERR_BUSY_SESSION = -32010;
80
80
  var ZCODE_APPSERVER_HARVEST_GRACE_MS = 1e3;
81
+ function isFailedTerminalStatus(status) {
82
+ return status === "failed" || status === "error";
83
+ }
81
84
 
82
85
  // src/registration.ts
83
86
  var import_subagent_engine_sdk10 = require("@zhushanwen/subagent-engine-sdk");
@@ -702,6 +705,11 @@ var AppServerConnection = class {
702
705
  reqSeq = 0;
703
706
  /** stderr 滚动缓冲(代级:崩溃诊断用)。 */
704
707
  stderrTail = "";
708
+ /**
709
+ * stderr tee 落盘流(D6-⑦;merge 裁决:旋转走 logs/stderr-rotation 的路径式
710
+ * rotateStderrLogIfNeeded——W5 边界禁 import subagent-core 的 SizeRotatedAppendStream,
711
+ * 常驻流改裸 WriteStream + 按次轮转检查,帽语义等价)。
712
+ */
705
713
  stderrStream = null;
706
714
  stderrStreamFailed = false;
707
715
  /**
@@ -1388,7 +1396,13 @@ var SessionChannel = class {
1388
1396
  });
1389
1397
  const turn = {
1390
1398
  sessionId,
1391
- callbacks: { onTextDelta: opts.onTextDelta, onThinkingDelta: opts.onThinkingDelta },
1399
+ callbacks: {
1400
+ onTextDelta: opts.onTextDelta,
1401
+ onThinkingDelta: opts.onThinkingDelta,
1402
+ // [PR3] tool 执行期活性回调(SessionTurnCallbacks.onActivity 注释——宿主侧
1403
+ // 无进展守护的工具执行期刷新面)
1404
+ onActivity: opts.onActivity
1405
+ },
1392
1406
  settled: false,
1393
1407
  deltas: [],
1394
1408
  finalText: void 0,
@@ -1504,7 +1518,9 @@ var SessionChannel = class {
1504
1518
  if (payload === void 0) return;
1505
1519
  this.refreshIdle(turn);
1506
1520
  if (this.applyFinalFrame(turn, payload)) return;
1507
- this.applyStreamDelta(turn, payload);
1521
+ if (!this.applyStreamDelta(turn, payload) && !turn.settled) {
1522
+ turn.callbacks.onActivity?.();
1523
+ }
1508
1524
  }
1509
1525
  /**
1510
1526
  * 收尾帧判定与吸收(A.2 ⑤ 两种形态:payload.response / stopReason+content 变体)。
@@ -1528,9 +1544,12 @@ var SessionChannel = class {
1528
1544
  /** 增量 delta 分发:非空 delta 入账 + 回调;终态后迟到丢弃(不变量 2)。
1529
1545
  * kind 区分两通道(F2):reasoning_delta 只走 thinking 回调(不入 deltas 账本
1530
1546
  * ——deltas 是 response 兜底聚合,推理文本不是答案正文);text_delta / kind
1531
- * 缺席走 text 路径。 */
1547
+ * 缺席走 text 路径。
1548
+ * 返回值([PR3]):帧被 delta 路径消费(thinking 或 text,回调若注册则已触发)
1549
+ * → true;无 delta / 空 delta / 终态后迟到丢弃 → false(handleSessionEvent 据
1550
+ * 此分流 onActivity——delta 帧已是宿主可见进展,不双发活性信号)。 */
1532
1551
  applyStreamDelta(turn, payload) {
1533
- if (typeof payload.delta !== "string" || payload.delta === "") return;
1552
+ if (typeof payload.delta !== "string" || payload.delta === "") return false;
1534
1553
  if (turn.settled) {
1535
1554
  logger2.warn(
1536
1555
  `\u7EC8\u6001\u540E\u8FDF\u5230\u7684 delta \u4E22\u5F03\uFF08\u4F1A\u8BDD ${turn.sessionId}\uFF0C\u4E0D\u53D8\u91CF 2\uFF1Aresolve \u540E\u4E0D\u518D\u53D1\u4E8B\u4EF6\uFF09: ${payload.delta.slice(
@@ -1538,14 +1557,15 @@ var SessionChannel = class {
1538
1557
  DELTA_LOG_CHARS
1539
1558
  )}`
1540
1559
  );
1541
- return;
1560
+ return false;
1542
1561
  }
1543
1562
  if (payload.kind === "reasoning_delta") {
1544
1563
  turn.callbacks.onThinkingDelta?.(payload.delta);
1545
- return;
1564
+ return true;
1546
1565
  }
1547
1566
  turn.deltas.push(payload.delta);
1548
1567
  turn.callbacks.onTextDelta?.(payload.delta);
1568
+ return true;
1549
1569
  }
1550
1570
  handleTelemetry(params) {
1551
1571
  if (!isRecord3(params)) return;
@@ -1565,13 +1585,38 @@ var SessionChannel = class {
1565
1585
  turn.lastTerminalStatus = status;
1566
1586
  this.recordTerminalError(turn, params);
1567
1587
  if (turn.settled) {
1568
- logger2.warn(
1569
- `\u6743\u5A01\u7EC8\u6001\u665A\u4E8E\u843D\u5B9A\u7ED3\u679C\u5230\u8FBE\uFF08\u4F1A\u8BDD ${turn.sessionId}\uFF0C\u5DF2\u843D\u5B9A source=${turn.terminal?.source}\uFF09\uFF1Aturn.terminal status="${status}" \u4EC5\u8BB0\u5F55\u4E0D\u6539\u5199\uFF08P0-1 D5\u2460\uFF09`
1570
- );
1588
+ this.logLateTerminal(turn, status);
1571
1589
  return;
1572
1590
  }
1573
1591
  turn.settle({ status, source: "turn.terminal" });
1574
1592
  }
1593
+ /**
1594
+ * 已落定 turn 的迟到权威终态分级日志(P-Z2 后续:常态迟到降噪)。真机实证该
1595
+ * 形态的唯一可达路径是 success 终态常态迟到(final-frame 先落定 + 权威
1596
+ * turn.terminal 迟到)——即每个成功任务必经;原无条件 warn 经 SDK cli-entry
1597
+ * 的 stderr 兜底 → runtime [rpc:stderr] 全量 console.error 链路,每个成功任务
1598
+ * 产一条零异常区分度的 ERROR 级日志。按权威 status 分级(落定语义不动——
1599
+ * lastTerminalStatus/lastTerminalError 的入账在上游无条件路径完成):
1600
+ * - "success":常态迟到,零日志;
1601
+ * - "interrupted":用户中断形态,debug(stderr 兜底对 debug no-op——对齐
1602
+ * SDK logger CONSOLE_SINK 语义,host/log 反向请求侧仍可观测);
1603
+ * - 失败类(isFailedTerminalStatus,与引擎失败分流同口径)与 unknown/未识别
1604
+ * status:保守 warn(原样 status 已写入文案)——假成功识破的防御面,理论
1605
+ * 不可达但保留,宁可误报不静默。
1606
+ */
1607
+ logLateTerminal(turn, status) {
1608
+ if (status === "success") return;
1609
+ const message = `\u6743\u5A01\u7EC8\u6001\u665A\u4E8E\u843D\u5B9A\u7ED3\u679C\u5230\u8FBE\uFF08\u4F1A\u8BDD ${turn.sessionId}\uFF0C\u5DF2\u843D\u5B9A source=${turn.terminal?.source}\uFF09\uFF1Aturn.terminal status="${status}" \u4EC5\u8BB0\u5F55\u4E0D\u6539\u5199\uFF08P0-1 D5\u2460\uFF09`;
1610
+ if (isFailedTerminalStatus(status)) {
1611
+ logger2.warn(message);
1612
+ return;
1613
+ }
1614
+ if (status === "interrupted") {
1615
+ logger2.debug(message);
1616
+ return;
1617
+ }
1618
+ logger2.warn(message);
1619
+ }
1575
1620
  /** terminal 帧专属错误信息入账(⛔P-Z2 实证:真实 failed 终态的 errorCode/errorMessage
1576
1621
  * 只在 terminal 帧携带,read/delta 拿不到——先到/迟到都记录,消费层合成失败
1577
1622
  * 文案时优先采信)。二者均缺失时不挂 lastTerminalError 字段。 */
@@ -1857,6 +1902,11 @@ var ZcodeEngine = class {
1857
1902
  // 不变量 3a 的拼接比对不含 reasoning)
1858
1903
  onTextDelta: (delta) => ctx.onEvent?.({ type: "text_delta", delta }),
1859
1904
  onThinkingDelta: (delta) => ctx.onEvent?.({ type: "thinking_delta", delta }),
1905
+ // [PR3] 工具执行期活性:非终态非增量的 session/event 帧(tool.updated progress
1906
+ // 等,真机探针实证每 ~1s 一帧)→ activity 事件(零载荷纯活性信号——宿主无进展
1907
+ // 守护对任何事件类型刷新;reducer no-op、不落 journal)。zcode 引擎
1908
+ // conversation:"unsupported",run 域是唯一发射面(无 chat 域接线)。
1909
+ onActivity: () => ctx.onEvent?.({ type: "activity" }),
1860
1910
  onSessionCreated: (sessionId) => {
1861
1911
  currentSessionId = sessionId;
1862
1912
  rt.activeSessions.add(sessionId);
@@ -2083,6 +2133,17 @@ var ZcodeEngine = class {
2083
2133
  }
2084
2134
  await this.shutdownRuntimeAndDisposeChannel(rt);
2085
2135
  }
2136
+ /**
2137
+ * [u7a D5] 引擎在途只读快照:activeSessions 非空才算在途——poolKey 'shared' 的
2138
+ * app-server **空闲常驻进程恒活,禁止按进程存在判定**(进程在 ≠ 在途,否则推迟
2139
+ * 判定恒真、30min 上限从兜底变常态路径,设计 §3.3 D5 显式排除)。计数权威 =
2140
+ * activeSessions(attempt 入 create 应答后 add / finally settle 后 delete,与
2141
+ * dispose 的 close 帧目标集同一状态源,无双记账)。运行时未初始化(从未 run /
2142
+ * 已 dispose)→ 恒 0。
2143
+ */
2144
+ inFlightSnapshot() {
2145
+ return { inFlight: this.appserverRuntime?.activeSessions.size ?? 0 };
2146
+ }
2086
2147
  /** 终态合成(extension-conventions 函数 80 行上限,从 run 提取):aborted / run-failed / parsed 三分支。 */
2087
2148
  finalizeOutcome(task, ctx, final, usageAcc, startedAt) {
2088
2149
  const outcome = {
@@ -2151,17 +2212,6 @@ var ZcodeEngine = class {
2151
2212
  }
2152
2213
  for (const ev of synthesizeCoarseEvents(payload.response, payload.usage)) emit(ev);
2153
2214
  }
2154
- /**
2155
- * D1 可选面:zcode 首期不支持 conversation(capabilities 声明)——同步拒绝、
2156
- * 不创建进程,文案给可操作建议(A11)。
2157
- */
2158
- async interact(_handle, _action) {
2159
- return {
2160
- ok: false,
2161
- code: "engine_capability_unsupported",
2162
- message: "zcode \u5F15\u64CE\u4E0D\u652F\u6301 conversation \u4EA4\u4E92\u63A7\u5236\u9762\uFF08capabilities.conversation = 'unsupported'\uFF0C\u6BCF\u4EFB\u52A1\u81EA\u5305\u542B\u4F1A\u8BDD\uFF0C\u65E0\u540C\u8FDB\u7A0B idle \u590D\u7528\uFF09\u3002\u6062\u590D\u6307\u5F15\uFF1A\u6539\u7528\u5355\u6B21 subagent \u8C03\u7528\u91CD\u65B0\u6D3E\u53D1\u4EFB\u52A1\uFF0C\u6216\u4F7F\u7528 engine: 'pi'\uFF08chatMode idle \u590D\u7528\uFF0C\u652F\u6301 message/close/cancel\uFF09\u3002"
2163
- };
2164
- }
2165
2215
  /** [U7] 模型可发现性:v2 桌面登录态聚合(带凭据 provider × models),失败安全返回清单本身可能为空。 */
2166
2216
  listModels() {
2167
2217
  return listZcodeModels(this.deps.sources);
@@ -2361,9 +2411,6 @@ function authoritativeTerminalStatus(r) {
2361
2411
  if (r.lastTerminalStatus !== void 0) return r.lastTerminalStatus;
2362
2412
  return r.terminal.source === "turn.terminal" ? r.terminal.status : void 0;
2363
2413
  }
2364
- function isFailedTerminalStatus(status) {
2365
- return status === "failed" || status === "error";
2366
- }
2367
2414
  function parsedAppServerAttempt(task, r) {
2368
2415
  if (isFailedTerminalStatus(authoritativeTerminalStatus(r))) {
2369
2416
  return failedTerminalAppServerAttempt(r);
@@ -2539,7 +2586,7 @@ var EngineProtocolServer = class {
2539
2586
  }
2540
2587
  }
2541
2588
  }
2542
- /** 10 正向方法分发(表驱动:method → 处理器;未知方法 → engine_protocol_unknown_method)。 */
2589
+ /** 9 正向方法分发(表驱动:method → 处理器;未知方法 → engine_protocol_unknown_method)。 */
2543
2590
  async dispatch(id, method, params) {
2544
2591
  const handler = this.methodHandlers[method];
2545
2592
  if (handler === void 0) {
@@ -2552,7 +2599,7 @@ var EngineProtocolServer = class {
2552
2599
  return handler(params);
2553
2600
  }
2554
2601
  /**
2555
- * 10 正向方法 → 处理器映射(每个处理器消费原始 params 并自行收敛类型——
2602
+ * 9 正向方法 → 处理器映射(每个处理器消费原始 params 并自行收敛类型——
2556
2603
  * 与原 switch case 表达式一一对应)。
2557
2604
  */
2558
2605
  methodHandlers = {
@@ -2560,7 +2607,6 @@ var EngineProtocolServer = class {
2560
2607
  probe: (p) => this.engine.probe(probeParamsOf(p)),
2561
2608
  run: (p) => this.run(p),
2562
2609
  cancel: (p) => this.cancel(p),
2563
- interact: (p) => this.interact(p),
2564
2610
  read: (p) => this.read(p),
2565
2611
  listModels: () => ({ models: this.engine.listModels?.() ?? null }),
2566
2612
  validateModel: (p) => this.validateModel(p),
@@ -2636,9 +2682,6 @@ var EngineProtocolServer = class {
2636
2682
  if (active !== void 0) active.controller.abort(new Error(`cancelled by host: ${params.reason}`));
2637
2683
  return { ok: true };
2638
2684
  }
2639
- async interact(params) {
2640
- return this.engine.interact({ data: params.handle }, params.action);
2641
- }
2642
2685
  read(params) {
2643
2686
  return this.engine.read({ data: params.handle });
2644
2687
  }
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { EnginePort, ReverseRequestClock, EngineCapabilities, ProbeReport, EngineAgentCallOpts, RunContext, EngineRunResult, EngineHandle, InteractAction, InteractResult, SessionView } from '@zhushanwen/subagent-engine-sdk';
1
+ import { EnginePort, ReverseRequestClock, EngineCapabilities, ProbeReport, EngineAgentCallOpts, RunContext, EngineRunResult, EngineHandle, SessionView } from '@zhushanwen/subagent-engine-sdk';
2
2
 
3
3
  /** 出站帧写入面(main.ts 注入 process.stdout;测试注入内存缓冲)。 */
4
4
  type FrameWriter = (frame: unknown) => void;
@@ -30,17 +30,16 @@ declare class EngineProtocolServer {
30
30
  constructor(opts: EngineProtocolServerOptions);
31
31
  /** 入站帧消费(请求帧 + 反向请求应答帧;main.ts 的行解析器拆行后喂入)。 */
32
32
  handleFrame(frame: unknown): void;
33
- /** 10 正向方法分发(表驱动:method → 处理器;未知方法 → engine_protocol_unknown_method)。 */
33
+ /** 9 正向方法分发(表驱动:method → 处理器;未知方法 → engine_protocol_unknown_method)。 */
34
34
  private dispatch;
35
35
  /**
36
- * 10 正向方法 → 处理器映射(每个处理器消费原始 params 并自行收敛类型——
36
+ * 9 正向方法 → 处理器映射(每个处理器消费原始 params 并自行收敛类型——
37
37
  * 与原 switch case 表达式一一对应)。
38
38
  */
39
39
  private readonly methodHandlers;
40
40
  private initialize;
41
41
  private run;
42
42
  private cancel;
43
- private interact;
44
43
  private read;
45
44
  private validateModel;
46
45
  private emitEvent;
@@ -214,6 +213,17 @@ declare class ZcodeEngine implements EnginePort {
214
213
  * ensureAppServerRuntime 自动重建(与崩溃重建同一代码路径,不变量 4)。
215
214
  */
216
215
  dispose(): Promise<void>;
216
+ /**
217
+ * [u7a D5] 引擎在途只读快照:activeSessions 非空才算在途——poolKey 'shared' 的
218
+ * app-server **空闲常驻进程恒活,禁止按进程存在判定**(进程在 ≠ 在途,否则推迟
219
+ * 判定恒真、30min 上限从兜底变常态路径,设计 §3.3 D5 显式排除)。计数权威 =
220
+ * activeSessions(attempt 入 create 应答后 add / finally settle 后 delete,与
221
+ * dispose 的 close 帧目标集同一状态源,无双记账)。运行时未初始化(从未 run /
222
+ * 已 dispose)→ 恒 0。
223
+ */
224
+ inFlightSnapshot(): {
225
+ inFlight: number;
226
+ };
217
227
  /** 终态合成(extension-conventions 函数 80 行上限,从 run 提取):aborted / run-failed / parsed 三分支。 */
218
228
  private finalizeOutcome;
219
229
  /** abort 合成终态:exitCode=null(record 正常收尾,不留僵尸)。 */
@@ -226,11 +236,6 @@ declare class ZcodeEngine implements EnginePort {
226
236
  private applyRunFailedOutcome;
227
237
  /** parsed 合成终态:content/sessionId/usage 落位 + schema 校验分流 + coarse 事件。 */
228
238
  private applyParsedOutcome;
229
- /**
230
- * D1 可选面:zcode 首期不支持 conversation(capabilities 声明)——同步拒绝、
231
- * 不创建进程,文案给可操作建议(A11)。
232
- */
233
- interact(_handle: EngineHandle, _action: InteractAction): Promise<InteractResult>;
234
239
  /** [U7] 模型可发现性:v2 桌面登录态聚合(带凭据 provider × models),失败安全返回清单本身可能为空。 */
235
240
  listModels(): Array<{
236
241
  id: string;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { EnginePort, ReverseRequestClock, EngineCapabilities, ProbeReport, EngineAgentCallOpts, RunContext, EngineRunResult, EngineHandle, InteractAction, InteractResult, SessionView } from '@zhushanwen/subagent-engine-sdk';
1
+ import { EnginePort, ReverseRequestClock, EngineCapabilities, ProbeReport, EngineAgentCallOpts, RunContext, EngineRunResult, EngineHandle, SessionView } from '@zhushanwen/subagent-engine-sdk';
2
2
 
3
3
  /** 出站帧写入面(main.ts 注入 process.stdout;测试注入内存缓冲)。 */
4
4
  type FrameWriter = (frame: unknown) => void;
@@ -30,17 +30,16 @@ declare class EngineProtocolServer {
30
30
  constructor(opts: EngineProtocolServerOptions);
31
31
  /** 入站帧消费(请求帧 + 反向请求应答帧;main.ts 的行解析器拆行后喂入)。 */
32
32
  handleFrame(frame: unknown): void;
33
- /** 10 正向方法分发(表驱动:method → 处理器;未知方法 → engine_protocol_unknown_method)。 */
33
+ /** 9 正向方法分发(表驱动:method → 处理器;未知方法 → engine_protocol_unknown_method)。 */
34
34
  private dispatch;
35
35
  /**
36
- * 10 正向方法 → 处理器映射(每个处理器消费原始 params 并自行收敛类型——
36
+ * 9 正向方法 → 处理器映射(每个处理器消费原始 params 并自行收敛类型——
37
37
  * 与原 switch case 表达式一一对应)。
38
38
  */
39
39
  private readonly methodHandlers;
40
40
  private initialize;
41
41
  private run;
42
42
  private cancel;
43
- private interact;
44
43
  private read;
45
44
  private validateModel;
46
45
  private emitEvent;
@@ -214,6 +213,17 @@ declare class ZcodeEngine implements EnginePort {
214
213
  * ensureAppServerRuntime 自动重建(与崩溃重建同一代码路径,不变量 4)。
215
214
  */
216
215
  dispose(): Promise<void>;
216
+ /**
217
+ * [u7a D5] 引擎在途只读快照:activeSessions 非空才算在途——poolKey 'shared' 的
218
+ * app-server **空闲常驻进程恒活,禁止按进程存在判定**(进程在 ≠ 在途,否则推迟
219
+ * 判定恒真、30min 上限从兜底变常态路径,设计 §3.3 D5 显式排除)。计数权威 =
220
+ * activeSessions(attempt 入 create 应答后 add / finally settle 后 delete,与
221
+ * dispose 的 close 帧目标集同一状态源,无双记账)。运行时未初始化(从未 run /
222
+ * 已 dispose)→ 恒 0。
223
+ */
224
+ inFlightSnapshot(): {
225
+ inFlight: number;
226
+ };
217
227
  /** 终态合成(extension-conventions 函数 80 行上限,从 run 提取):aborted / run-failed / parsed 三分支。 */
218
228
  private finalizeOutcome;
219
229
  /** abort 合成终态:exitCode=null(record 正常收尾,不留僵尸)。 */
@@ -226,11 +236,6 @@ declare class ZcodeEngine implements EnginePort {
226
236
  private applyRunFailedOutcome;
227
237
  /** parsed 合成终态:content/sessionId/usage 落位 + schema 校验分流 + coarse 事件。 */
228
238
  private applyParsedOutcome;
229
- /**
230
- * D1 可选面:zcode 首期不支持 conversation(capabilities 声明)——同步拒绝、
231
- * 不创建进程,文案给可操作建议(A11)。
232
- */
233
- interact(_handle: EngineHandle, _action: InteractAction): Promise<InteractResult>;
234
239
  /** [U7] 模型可发现性:v2 桌面登录态聚合(带凭据 provider × models),失败安全返回清单本身可能为空。 */
235
240
  listModels(): Array<{
236
241
  id: string;
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  readZcodeSessionView,
11
11
  zcodeDbPathAllowlist,
12
12
  zcodeSessionDbPath
13
- } from "./chunk-IIAABOER.js";
13
+ } from "./chunk-WQ7NVGKB.js";
14
14
 
15
15
  // src/golden-sample.ts
16
16
  var ZCODE_APPSERVER_GOLDEN = {
package/dist/main.cjs CHANGED
@@ -58,6 +58,9 @@ var ZCODE_APPSERVER_ABORT_GRACE_MS = 3e3;
58
58
  var ZCODE_APPSERVER_ERR_MODEL_CONFIG_MISSING = -32603;
59
59
  var ZCODE_APPSERVER_ERR_BUSY_SESSION = -32010;
60
60
  var ZCODE_APPSERVER_HARVEST_GRACE_MS = 1e3;
61
+ function isFailedTerminalStatus(status) {
62
+ return status === "failed" || status === "error";
63
+ }
61
64
 
62
65
  // src/registration.ts
63
66
  var import_subagent_engine_sdk10 = require("@zhushanwen/subagent-engine-sdk");
@@ -682,6 +685,11 @@ var AppServerConnection = class {
682
685
  reqSeq = 0;
683
686
  /** stderr 滚动缓冲(代级:崩溃诊断用)。 */
684
687
  stderrTail = "";
688
+ /**
689
+ * stderr tee 落盘流(D6-⑦;merge 裁决:旋转走 logs/stderr-rotation 的路径式
690
+ * rotateStderrLogIfNeeded——W5 边界禁 import subagent-core 的 SizeRotatedAppendStream,
691
+ * 常驻流改裸 WriteStream + 按次轮转检查,帽语义等价)。
692
+ */
685
693
  stderrStream = null;
686
694
  stderrStreamFailed = false;
687
695
  /**
@@ -1368,7 +1376,13 @@ var SessionChannel = class {
1368
1376
  });
1369
1377
  const turn = {
1370
1378
  sessionId,
1371
- callbacks: { onTextDelta: opts.onTextDelta, onThinkingDelta: opts.onThinkingDelta },
1379
+ callbacks: {
1380
+ onTextDelta: opts.onTextDelta,
1381
+ onThinkingDelta: opts.onThinkingDelta,
1382
+ // [PR3] tool 执行期活性回调(SessionTurnCallbacks.onActivity 注释——宿主侧
1383
+ // 无进展守护的工具执行期刷新面)
1384
+ onActivity: opts.onActivity
1385
+ },
1372
1386
  settled: false,
1373
1387
  deltas: [],
1374
1388
  finalText: void 0,
@@ -1484,7 +1498,9 @@ var SessionChannel = class {
1484
1498
  if (payload === void 0) return;
1485
1499
  this.refreshIdle(turn);
1486
1500
  if (this.applyFinalFrame(turn, payload)) return;
1487
- this.applyStreamDelta(turn, payload);
1501
+ if (!this.applyStreamDelta(turn, payload) && !turn.settled) {
1502
+ turn.callbacks.onActivity?.();
1503
+ }
1488
1504
  }
1489
1505
  /**
1490
1506
  * 收尾帧判定与吸收(A.2 ⑤ 两种形态:payload.response / stopReason+content 变体)。
@@ -1508,9 +1524,12 @@ var SessionChannel = class {
1508
1524
  /** 增量 delta 分发:非空 delta 入账 + 回调;终态后迟到丢弃(不变量 2)。
1509
1525
  * kind 区分两通道(F2):reasoning_delta 只走 thinking 回调(不入 deltas 账本
1510
1526
  * ——deltas 是 response 兜底聚合,推理文本不是答案正文);text_delta / kind
1511
- * 缺席走 text 路径。 */
1527
+ * 缺席走 text 路径。
1528
+ * 返回值([PR3]):帧被 delta 路径消费(thinking 或 text,回调若注册则已触发)
1529
+ * → true;无 delta / 空 delta / 终态后迟到丢弃 → false(handleSessionEvent 据
1530
+ * 此分流 onActivity——delta 帧已是宿主可见进展,不双发活性信号)。 */
1512
1531
  applyStreamDelta(turn, payload) {
1513
- if (typeof payload.delta !== "string" || payload.delta === "") return;
1532
+ if (typeof payload.delta !== "string" || payload.delta === "") return false;
1514
1533
  if (turn.settled) {
1515
1534
  logger2.warn(
1516
1535
  `\u7EC8\u6001\u540E\u8FDF\u5230\u7684 delta \u4E22\u5F03\uFF08\u4F1A\u8BDD ${turn.sessionId}\uFF0C\u4E0D\u53D8\u91CF 2\uFF1Aresolve \u540E\u4E0D\u518D\u53D1\u4E8B\u4EF6\uFF09: ${payload.delta.slice(
@@ -1518,14 +1537,15 @@ var SessionChannel = class {
1518
1537
  DELTA_LOG_CHARS
1519
1538
  )}`
1520
1539
  );
1521
- return;
1540
+ return false;
1522
1541
  }
1523
1542
  if (payload.kind === "reasoning_delta") {
1524
1543
  turn.callbacks.onThinkingDelta?.(payload.delta);
1525
- return;
1544
+ return true;
1526
1545
  }
1527
1546
  turn.deltas.push(payload.delta);
1528
1547
  turn.callbacks.onTextDelta?.(payload.delta);
1548
+ return true;
1529
1549
  }
1530
1550
  handleTelemetry(params) {
1531
1551
  if (!isRecord3(params)) return;
@@ -1545,13 +1565,38 @@ var SessionChannel = class {
1545
1565
  turn.lastTerminalStatus = status;
1546
1566
  this.recordTerminalError(turn, params);
1547
1567
  if (turn.settled) {
1548
- logger2.warn(
1549
- `\u6743\u5A01\u7EC8\u6001\u665A\u4E8E\u843D\u5B9A\u7ED3\u679C\u5230\u8FBE\uFF08\u4F1A\u8BDD ${turn.sessionId}\uFF0C\u5DF2\u843D\u5B9A source=${turn.terminal?.source}\uFF09\uFF1Aturn.terminal status="${status}" \u4EC5\u8BB0\u5F55\u4E0D\u6539\u5199\uFF08P0-1 D5\u2460\uFF09`
1550
- );
1568
+ this.logLateTerminal(turn, status);
1551
1569
  return;
1552
1570
  }
1553
1571
  turn.settle({ status, source: "turn.terminal" });
1554
1572
  }
1573
+ /**
1574
+ * 已落定 turn 的迟到权威终态分级日志(P-Z2 后续:常态迟到降噪)。真机实证该
1575
+ * 形态的唯一可达路径是 success 终态常态迟到(final-frame 先落定 + 权威
1576
+ * turn.terminal 迟到)——即每个成功任务必经;原无条件 warn 经 SDK cli-entry
1577
+ * 的 stderr 兜底 → runtime [rpc:stderr] 全量 console.error 链路,每个成功任务
1578
+ * 产一条零异常区分度的 ERROR 级日志。按权威 status 分级(落定语义不动——
1579
+ * lastTerminalStatus/lastTerminalError 的入账在上游无条件路径完成):
1580
+ * - "success":常态迟到,零日志;
1581
+ * - "interrupted":用户中断形态,debug(stderr 兜底对 debug no-op——对齐
1582
+ * SDK logger CONSOLE_SINK 语义,host/log 反向请求侧仍可观测);
1583
+ * - 失败类(isFailedTerminalStatus,与引擎失败分流同口径)与 unknown/未识别
1584
+ * status:保守 warn(原样 status 已写入文案)——假成功识破的防御面,理论
1585
+ * 不可达但保留,宁可误报不静默。
1586
+ */
1587
+ logLateTerminal(turn, status) {
1588
+ if (status === "success") return;
1589
+ const message = `\u6743\u5A01\u7EC8\u6001\u665A\u4E8E\u843D\u5B9A\u7ED3\u679C\u5230\u8FBE\uFF08\u4F1A\u8BDD ${turn.sessionId}\uFF0C\u5DF2\u843D\u5B9A source=${turn.terminal?.source}\uFF09\uFF1Aturn.terminal status="${status}" \u4EC5\u8BB0\u5F55\u4E0D\u6539\u5199\uFF08P0-1 D5\u2460\uFF09`;
1590
+ if (isFailedTerminalStatus(status)) {
1591
+ logger2.warn(message);
1592
+ return;
1593
+ }
1594
+ if (status === "interrupted") {
1595
+ logger2.debug(message);
1596
+ return;
1597
+ }
1598
+ logger2.warn(message);
1599
+ }
1555
1600
  /** terminal 帧专属错误信息入账(⛔P-Z2 实证:真实 failed 终态的 errorCode/errorMessage
1556
1601
  * 只在 terminal 帧携带,read/delta 拿不到——先到/迟到都记录,消费层合成失败
1557
1602
  * 文案时优先采信)。二者均缺失时不挂 lastTerminalError 字段。 */
@@ -1837,6 +1882,11 @@ var ZcodeEngine = class {
1837
1882
  // 不变量 3a 的拼接比对不含 reasoning)
1838
1883
  onTextDelta: (delta) => ctx.onEvent?.({ type: "text_delta", delta }),
1839
1884
  onThinkingDelta: (delta) => ctx.onEvent?.({ type: "thinking_delta", delta }),
1885
+ // [PR3] 工具执行期活性:非终态非增量的 session/event 帧(tool.updated progress
1886
+ // 等,真机探针实证每 ~1s 一帧)→ activity 事件(零载荷纯活性信号——宿主无进展
1887
+ // 守护对任何事件类型刷新;reducer no-op、不落 journal)。zcode 引擎
1888
+ // conversation:"unsupported",run 域是唯一发射面(无 chat 域接线)。
1889
+ onActivity: () => ctx.onEvent?.({ type: "activity" }),
1840
1890
  onSessionCreated: (sessionId) => {
1841
1891
  currentSessionId = sessionId;
1842
1892
  rt.activeSessions.add(sessionId);
@@ -2063,6 +2113,17 @@ var ZcodeEngine = class {
2063
2113
  }
2064
2114
  await this.shutdownRuntimeAndDisposeChannel(rt);
2065
2115
  }
2116
+ /**
2117
+ * [u7a D5] 引擎在途只读快照:activeSessions 非空才算在途——poolKey 'shared' 的
2118
+ * app-server **空闲常驻进程恒活,禁止按进程存在判定**(进程在 ≠ 在途,否则推迟
2119
+ * 判定恒真、30min 上限从兜底变常态路径,设计 §3.3 D5 显式排除)。计数权威 =
2120
+ * activeSessions(attempt 入 create 应答后 add / finally settle 后 delete,与
2121
+ * dispose 的 close 帧目标集同一状态源,无双记账)。运行时未初始化(从未 run /
2122
+ * 已 dispose)→ 恒 0。
2123
+ */
2124
+ inFlightSnapshot() {
2125
+ return { inFlight: this.appserverRuntime?.activeSessions.size ?? 0 };
2126
+ }
2066
2127
  /** 终态合成(extension-conventions 函数 80 行上限,从 run 提取):aborted / run-failed / parsed 三分支。 */
2067
2128
  finalizeOutcome(task, ctx, final, usageAcc, startedAt) {
2068
2129
  const outcome = {
@@ -2131,17 +2192,6 @@ var ZcodeEngine = class {
2131
2192
  }
2132
2193
  for (const ev of synthesizeCoarseEvents(payload.response, payload.usage)) emit(ev);
2133
2194
  }
2134
- /**
2135
- * D1 可选面:zcode 首期不支持 conversation(capabilities 声明)——同步拒绝、
2136
- * 不创建进程,文案给可操作建议(A11)。
2137
- */
2138
- async interact(_handle, _action) {
2139
- return {
2140
- ok: false,
2141
- code: "engine_capability_unsupported",
2142
- message: "zcode \u5F15\u64CE\u4E0D\u652F\u6301 conversation \u4EA4\u4E92\u63A7\u5236\u9762\uFF08capabilities.conversation = 'unsupported'\uFF0C\u6BCF\u4EFB\u52A1\u81EA\u5305\u542B\u4F1A\u8BDD\uFF0C\u65E0\u540C\u8FDB\u7A0B idle \u590D\u7528\uFF09\u3002\u6062\u590D\u6307\u5F15\uFF1A\u6539\u7528\u5355\u6B21 subagent \u8C03\u7528\u91CD\u65B0\u6D3E\u53D1\u4EFB\u52A1\uFF0C\u6216\u4F7F\u7528 engine: 'pi'\uFF08chatMode idle \u590D\u7528\uFF0C\u652F\u6301 message/close/cancel\uFF09\u3002"
2143
- };
2144
- }
2145
2195
  /** [U7] 模型可发现性:v2 桌面登录态聚合(带凭据 provider × models),失败安全返回清单本身可能为空。 */
2146
2196
  listModels() {
2147
2197
  return listZcodeModels(this.deps.sources);
@@ -2341,9 +2391,6 @@ function authoritativeTerminalStatus(r) {
2341
2391
  if (r.lastTerminalStatus !== void 0) return r.lastTerminalStatus;
2342
2392
  return r.terminal.source === "turn.terminal" ? r.terminal.status : void 0;
2343
2393
  }
2344
- function isFailedTerminalStatus(status) {
2345
- return status === "failed" || status === "error";
2346
- }
2347
2394
  function parsedAppServerAttempt(task, r) {
2348
2395
  if (isFailedTerminalStatus(authoritativeTerminalStatus(r))) {
2349
2396
  return failedTerminalAppServerAttempt(r);
@@ -2519,7 +2566,7 @@ var EngineProtocolServer = class {
2519
2566
  }
2520
2567
  }
2521
2568
  }
2522
- /** 10 正向方法分发(表驱动:method → 处理器;未知方法 → engine_protocol_unknown_method)。 */
2569
+ /** 9 正向方法分发(表驱动:method → 处理器;未知方法 → engine_protocol_unknown_method)。 */
2523
2570
  async dispatch(id, method, params) {
2524
2571
  const handler = this.methodHandlers[method];
2525
2572
  if (handler === void 0) {
@@ -2532,7 +2579,7 @@ var EngineProtocolServer = class {
2532
2579
  return handler(params);
2533
2580
  }
2534
2581
  /**
2535
- * 10 正向方法 → 处理器映射(每个处理器消费原始 params 并自行收敛类型——
2582
+ * 9 正向方法 → 处理器映射(每个处理器消费原始 params 并自行收敛类型——
2536
2583
  * 与原 switch case 表达式一一对应)。
2537
2584
  */
2538
2585
  methodHandlers = {
@@ -2540,7 +2587,6 @@ var EngineProtocolServer = class {
2540
2587
  probe: (p) => this.engine.probe(probeParamsOf(p)),
2541
2588
  run: (p) => this.run(p),
2542
2589
  cancel: (p) => this.cancel(p),
2543
- interact: (p) => this.interact(p),
2544
2590
  read: (p) => this.read(p),
2545
2591
  listModels: () => ({ models: this.engine.listModels?.() ?? null }),
2546
2592
  validateModel: (p) => this.validateModel(p),
@@ -2616,9 +2662,6 @@ var EngineProtocolServer = class {
2616
2662
  if (active !== void 0) active.controller.abort(new Error(`cancelled by host: ${params.reason}`));
2617
2663
  return { ok: true };
2618
2664
  }
2619
- async interact(params) {
2620
- return this.engine.interact({ data: params.handle }, params.action);
2621
- }
2622
2665
  read(params) {
2623
2666
  return this.engine.read({ data: params.handle });
2624
2667
  }
package/dist/main.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  EngineProtocolServer
3
- } from "./chunk-IIAABOER.js";
3
+ } from "./chunk-WQ7NVGKB.js";
4
4
 
5
5
  // src/main.ts
6
6
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhushanwen/zcode-subagent-cli",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "description": "zcode subagent engine as an independent CLI package (W5 of subagent-engine-protocolization): speaks engine-protocol v1 over NDJSON stdio, depends only on @zhushanwen/subagent-engine-sdk (never subagent-core)",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -61,7 +61,7 @@
61
61
  "dist/"
62
62
  ],
63
63
  "dependencies": {
64
- "@zhushanwen/subagent-engine-sdk": "0.2.1"
64
+ "@zhushanwen/subagent-engine-sdk": "0.3.0"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@types/node": "^24.0.0",