@zhushanwen/extension-protocol 0.21.0 → 0.22.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
@@ -9,12 +9,12 @@ pi extension 跨层契约包:类型 + helper 函数 + 共享行为原语,零
9
9
  - `ask-user/` —— 富交互(select 通道 + marker)
10
10
  - `plan/` —— plan 生命周期状态机 + 审阅回传值域契约 + 旧 entry legacy 读取(纯函数零 pi 依赖,扩展 / runtime / renderer 三层共用)
11
11
  - `scheduler/` —— scheduler 任务条目契约 + entry 重放折叠(replayFoldEntries)+ 时间格式化(纯契约与纯函数,零 pi/node 依赖)
12
- - `scheduler-create/` —— scheduler 创建确认共享资产(ScheduleDraft / ScheduleFormResult 类型 + 形状与时间折叠守卫 + marker)
12
+ - `scheduler-create/` —— scheduler 创建确认共享资产(ScheduleDraft / ScheduleFormResult 类型 + 形状与时间折叠检查 + marker)
13
13
  - `session-manager/` —— agent-managed session 嵌套 `{action, params}` 契约(select 通道 + marker)
14
14
  - `subagent-engine/` —— 引擎可发现性(`engines.json` 状态文件 + 引擎配置视图)
15
15
  - `subagent-inflight/` —— subagent 在途聚合上报(绝对计数报告 + marker,select 通道)
16
16
  - `subagent-notify/` —— subagent-workflow 通知通道 customType 常量唯一来源(workflow 结果 / 后台通知 / subagent 指令三类)
17
- - `ui-form/` —— 统一提问表单协议(ask-user / scheduler / plan 三方提问统一入口:类型 + marker + 交互 helper + 守卫)
17
+ - `ui-form/` —— 统一提问表单协议(ask-user / scheduler / plan 三方提问统一入口:类型 + marker + 交互 helper + 检查)
18
18
  - 完整子协议清单以 `src/index.ts` 导出为准
19
19
  - `pending-entries` —— pending 事件流差集核心(register 去重 + unregister 抵消,纯算法)
20
20
  - `background-task` —— base-tool-enhance 后台任务 `registry.json` 文件契约
@@ -10,20 +10,26 @@
10
10
  * 字段注释),orphaned 终态由 runtime 写入(收殓下沉,设计
11
11
  * docs/architecture/file-lock-unification-and-reaper-sink.md D2)。
12
12
  *
13
- * 目录布局(per-session 隔离):
14
- * <agentDir>/base-tool-enhance/<sessionId>/registry.json
15
- * (agentDir = pi getAgentDir() 同源 dataDir,由调用方解析传入,不硬编码)
13
+ * 目录布局(per-session 隔离,session 存储树域 5):
14
+ * <dataDir>/ext-sessions/<sessionId>/background-tasks/registry.json
15
+ * (shared 推导单点 = getSessionBackgroundTasksDir;写侧 extension 不 import
16
+ * shared,以同公式镜像推导——SESSION_STORE_DIR_SEGMENT / BACKGROUND_TASKS_DIR_SEGMENT
17
+ * 段常量,字面量一致性由 scripts/check-artifact-dir-formula-sync.mjs 对拍守护)
16
18
  *
17
19
  * 字段名/语义/枚举值与写侧现状逐字段一致(基线:extensions/universal/
18
20
  * base-tool-enhance/src/background/types.ts + registry.ts),禁止在此单侧改名。
19
21
  */
20
- /** registry 文件名(<agentDir>/base-tool-enhance/<sessionId>/ 下)。 */
22
+ /** registry 文件名(<dataDir>/ext-sessions/<sessionId>/background-tasks/ 下)。 */
21
23
  declare const BACKGROUND_TASK_REGISTRY_FILENAME: "registry.json";
22
- /** 后台任务根目录名(<agentDir>/ 下,内含 per-sessionId 子目录)。 */
24
+ /**
25
+ * [遗留] 旧布局(<agentDir>/base-tool-enhance/<sessionId>/registry.json)的根目录名
26
+ * 段——换根到 session 存储树后布局不再经过该目录(现行布局见文件头「目录布局」),
27
+ * 仓内生产代码零消费(仅测试保活断言 + npm 出口 re-export 保留);退役待出口面裁决。
28
+ */
23
29
  declare const BASE_TOOL_ENHANCE_DIRNAME: "base-tool-enhance";
24
30
  /**
25
31
  * 任务 id 前缀(taskId 契约注释已约定:bt- 前缀,对账差集只认该前缀——区别于
26
- * subagent-workflow 的 bg-/run-)。升级为导出常量:对账/守卫的前缀过滤从此引用
32
+ * subagent-workflow 的 bg-/run-)。升级为导出常量:对账/检查的前缀过滤从此引用
27
33
  * 同一常量,禁止各侧字面量重写。
28
34
  */
29
35
  declare const BACKGROUND_TASK_ID_PREFIX: "bt-";
@@ -1,4 +1,4 @@
1
- import { B as BackgroundTaskState, a as BackgroundTaskRegistryEntry } from './background-task-B6pdI5nq.js';
1
+ import { B as BackgroundTaskState, a as BackgroundTaskRegistryEntry } from './background-task-B53rQ-4Q.js';
2
2
 
3
3
  /**
4
4
  * 后台任务进程原语(pid 判活 / 进程树处置 / start time 身份判据)——跨端单一实现。
@@ -9,8 +9,8 @@ import { B as BackgroundTaskState, a as BackgroundTaskRegistryEntry } from './ba
9
9
  * - runtime 侧:taiji background-task-reaper(孤儿收殓三分支判定),原实现在
10
10
  * background-task-reaper.ts 原语区
11
11
  *
12
- * 分支语义(与 pi 实装对齐,勿单侧擅改):Windows `taskkill /F /T`;POSIX 杀进程组
13
- * `kill -- -<pgid>`(后台任务 detached spawn 自成进程组,pgid = pid);进程组杀不到时
12
+ * 分支语义(与 pi 实装对齐,勿单侧擅改):Windows `taskkill /F /T`;POSIX 按进程组终止
13
+ * `kill -- -<pgid>`(后台任务 detached spawn 自成进程组,pgid = pid);按进程组终止不到时
14
14
  * 回退单 pid + `pgrep -P` 递归杀残留子进程。
15
15
  *
16
16
  * 日志通道:本模块零日志依赖(protocol 零运行时依赖纪律)——回退路径的诊断经可选
@@ -31,7 +31,7 @@ type ProcessFallbackLogger = (step: string, err: unknown) => void;
31
31
  declare function isPidAlive(pid: number): boolean;
32
32
  /**
33
33
  * 杀整棵进程树(同步;收殓路径在 process.on("exit") 里跑,必须同步)。
34
- * POSIX 杀进程组(pgid = pid)一次性覆盖全部子孙;进程组杀不到(组长已死)回退
34
+ * POSIX 按进程组终止(pgid = pid)一次性覆盖全部子孙;按进程组终止不到(组长已死)回退
35
35
  * 单 pid + pgrep -P 递归清理残留子进程(先杀孙辈再杀子辈,防孙辈在父死后被
36
36
  * reparent 逃逸枚举)。Windows taskkill /F /T。幂等:目标已死时静默成功
37
37
  * (回退路径的诊断经 onFallback 上报,无回调则静默)。
@@ -93,7 +93,7 @@ declare function parseRegistryContent(raw: string): BackgroundTaskRegistryEntry[
93
93
  declare function corruptPathFor(registryPath: string): string;
94
94
  /**
95
95
  * 读取 registry 全量条目 + 损坏标记(runtime 现形态为超集;extension 侧 Map 形态
96
- * 由各侧薄壳投影)。UI 读侧需要区分「真的空表」与「损坏被隔离的空表」。
96
+ * 由各侧薄壳派生)。UI 读侧需要区分「真的空表」与「损坏被隔离的空表」。
97
97
  *
98
98
  * 文件不存在 / 读失败 → 空表 + corrupted:false(常态/降级,非损坏);解析失败 →
99
99
  * 重命名 .corrupt 保留现场 + onLog warn + 空表 + corrupted:true(「空表重建」由
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { b as BACKGROUND_TASK_ID_PREFIX, c as BACKGROUND_TASK_REGISTRY_FILENAME, d as BACKGROUND_TASK_REGISTRY_VERSION, e as BASE_TOOL_ENHANCE_DIRNAME, f as BackgroundTaskEndReason, a as BackgroundTaskRegistryEntry, g as BackgroundTaskRegistryFile, B as BackgroundTaskState, M as MAX_TERMINAL_REGISTRY_ENTRIES, i as isActiveBackgroundTaskState, h as isBackgroundTaskRegistryEntry, j as isTerminalBackgroundTaskState } from './background-task-B6pdI5nq.js';
1
+ export { b as BACKGROUND_TASK_ID_PREFIX, c as BACKGROUND_TASK_REGISTRY_FILENAME, d as BACKGROUND_TASK_REGISTRY_VERSION, e as BASE_TOOL_ENHANCE_DIRNAME, f as BackgroundTaskEndReason, a as BackgroundTaskRegistryEntry, g as BackgroundTaskRegistryFile, B as BackgroundTaskState, M as MAX_TERMINAL_REGISTRY_ENTRIES, i as isActiveBackgroundTaskState, h as isBackgroundTaskRegistryEntry, j as isTerminalBackgroundTaskState } from './background-task-B53rQ-4Q.js';
2
2
 
3
3
  /**
4
4
  * GUI 渲染协议核心类型定义。
@@ -168,7 +168,7 @@ type TreeItemIcon = 'arrow' | 'check' | 'cross' | 'circle' | 'dot' | 'pause' | '
168
168
  /**
169
169
  * 计划产物文档元数据——agent 调 register-doc 登记的一份产物。
170
170
  * version 由 extension 侧维护:修订后重写文档须重调 register-doc(version+1),
171
- * 前端凭 version 变化重拉 file.read 刷新渲染。
171
+ * 前端凭 version 变化重新拉取 file.read 刷新渲染。
172
172
  */
173
173
  interface PlanDocMeta {
174
174
  /** 文件名(drawer L2 文档 tab 标题,不含目录) */
@@ -184,7 +184,7 @@ interface PlanDocMeta {
184
184
  * submit-review 挂起审批时的 select payload(序列化为 options[0] JSON)。
185
185
  * extension 侧解析失败走 E5(logger.warn + tool result 报错提示重挂,垃圾数据不进对话流)。
186
186
  *
187
- * selfReview(自审结论,D9①③):agent 提交审批前的自审摘要,投影面到审批请求帧为止
187
+ * selfReview(自审结论,D9①③):agent 提交审批前的自审摘要,派生范围到审批请求帧为止
188
188
  * (不进 PlanStateView / session.planState 帧);有界性由写侧 4KB 单点截断保证
189
189
  * (canonical 上限与截断 = src/extensions/plan/review-contract.ts,R3)。**optional 是兼容契约**:
190
190
  * 旧扩展不携带 → 宿主自审行不渲染的降级形态;submit-review 的必填硬门在 tool 层执行
@@ -197,7 +197,7 @@ interface PlanReviewRequest {
197
197
  /**
198
198
  * 审批三键裁决(D3):approve 确认执行 / revise 提交修订(必带评论)/ dismiss 搁置
199
199
  * (非破坏:不杀 turn、不丢状态,计划进度保留)。revise 携带评论、approve/dismiss
200
- * 不携带(结构上不可混带)。值域守卫 canonical 版 = src/extensions/plan/review-contract.ts
200
+ * 不携带(结构上不可混带)。值域检查 canonical 版 = src/extensions/plan/review-contract.ts
201
201
  * (运行时判别 TS 穷尽性管不到——未知值域降级语义见该模块「降级双分源」)。
202
202
  */
203
203
  type PlanReviewDecision = 'approve' | 'revise' | 'dismiss';
@@ -295,7 +295,7 @@ declare function guiComponent<T extends GuiComponentType>(type: T, props: GuiCom
295
295
  /**
296
296
  * 设置 GUI widget。RPC 模式下用 marker 编码 GuiRenderResult JSON 进 string[],
297
297
  * runtime event-adapter 检测 marker 解码为结构化 WS 帧(component + meta)。
298
- * 本函数无 isGui 守卫(仅查 ctx.ui?.setWidget 存在性),调用方需先判定
298
+ * 本函数无 isGui 检查(仅查 ctx.ui?.setWidget 存在性),调用方需先判定
299
299
  * isGuiCapable(ctx)——TUI 模式误调会把 marker 编码行推给原生 widget 造成乱码。
300
300
  *
301
301
  * meta(标题/状态/进度)由宿主壳层渲染成统一 head;extension 不再用 card 原语
@@ -303,12 +303,12 @@ declare function guiComponent<T extends GuiComponentType>(type: T, props: GuiCom
303
303
  */
304
304
  declare function guiSetWidget(ctx: GuiContext, key: string, result: GuiRenderResult | undefined): void;
305
305
  /**
306
- * [守卫单点化——本约束的说明全仓只写这一处,调用方不得再各自复写]
306
+ * [检查单点化——本约束的说明全仓只写这一处,调用方不得再各自复写]
307
307
  * 「isGuiCapable 外层判定不可省略,否则 TUI 误调 marker 乱码」:guiSetWidget 无
308
- * isGui 守卫(仅查 ctx.ui?.setWidget 存在性),TUI 模式误调会把 marker 编码行推
308
+ * isGui 检查(仅查 ctx.ui?.setWidget 存在性),TUI 模式误调会把 marker 编码行推
309
309
  * 给原生 widget 造成乱码。带双模内容的 widget 推送一律走 setWidgetDual,由本
310
310
  * helper 内化模式分派——消费方(todo/goal 及后续带 widget 的 extension)不再
311
- * 自持 isGui 判定与守卫注释。
311
+ * 自持 isGui 判定与检查注释。
312
312
  */
313
313
  /** 双模 widget 内容:按值立即构造两侧(构造均为廉价纯函数,成本可忽略)。 */
314
314
  interface DualWidgetContent {
@@ -322,8 +322,8 @@ interface DualWidgetContent {
322
322
  * - content 为 undefined → 清屏 ctx.ui.setWidget(key, undefined),模式无关
323
323
  * (guiSetWidget 的清屏分支本就两臂同落 setWidget,判别是死分支)
324
324
  * - 有内容 → isGuiCapable(ctx) ? guiSetWidget(gui) : setWidget(text)——TUI 分支
325
- * 推原生文本行,结构性不触达 marker(见上方守卫单点化说明)
326
- * hasUI 守卫留在调用方(goal FR-6.6 语义,本 helper 不感知)。
325
+ * 推原生文本行,结构性不触达 marker(见上方检查单点化说明)
326
+ * hasUI 检查留在调用方(goal FR-6.6 语义,本 helper 不感知)。
327
327
  */
328
328
  declare function setWidgetDual(ctx: GuiContext, key: string, content: DualWidgetContent | undefined): void;
329
329
  /** 拒绝原因(宿主 warn 文案与 fallback 分诊用;判定顺序同 validateWidgetIconPaths 实现)。 */
@@ -434,7 +434,7 @@ interface ChannelErrorResult {
434
434
  error: string;
435
435
  hint?: string;
436
436
  }
437
- /** 运行时形状守卫:{error: string}(hint 可选,不校验其类型;排数组) */
437
+ /** 运行时形状检查:{error: string}(hint 可选,不校验其类型;排数组) */
438
438
  declare function isChannelErrorResult(v: unknown): v is ChannelErrorResult;
439
439
  /** error + hint 文本拼接(hint 缺席只回 error)——plugin-bridge errorResult 与
440
440
  * session-manager 错误闭环文本的共用单源 */
@@ -537,7 +537,7 @@ declare function getAskUserAnswer(answers: AskUserAnswers, question: AskUserQues
537
537
  /** 从 answers 中提取 Other 自由文本 */
538
538
  declare function getAskUserOther(answers: AskUserAnswers, question: AskUserQuestion): string | undefined;
539
539
  /**
540
- * 类型守卫:验证 unknown 是否为合法的 AskUserQuestion。
540
+ * 类型检查:验证 unknown 是否为合法的 AskUserQuestion。
541
541
  * 供 legacy 帧消费方(runtime marker 分支侧形状参照 / 扩展自测)收窄 unknown[] 用。
542
542
  */
543
543
  declare function isAskUserQuestion(value: unknown): value is AskUserQuestion;
@@ -797,8 +797,8 @@ declare const SCHEDULE_CREATE_MARKER = "\0TAIJI_SCHEDULE_CREATE";
797
797
  * 交互入口在 extensions/universal/scheduler/src/tool.ts。
798
798
  *
799
799
  * 本模块保留三类跨端共享资产:
800
- * - isScheduleDraft / isScheduleFormResult 形状守卫:前者供 runtime event-adapter
801
- * legacy 分支(SCHEDULE_CREATE_MARKER 帧 payload 判定)与 ui-form 守卫的
800
+ * - isScheduleDraft / isScheduleFormResult 形状检查:前者供 runtime event-adapter
801
+ * legacy 分支(SCHEDULE_CREATE_MARKER 帧 payload 判定)与 ui-form 检查的
802
802
  * schedule 分支(initial 深度校验)消费;后者供 scheduler 包回包判别
803
803
  * (uiFormInteract answers[key] 解包后收窄为 ScheduleFormResult)。
804
804
  * - dateToOnceCron / onceCronToDate 时间折叠单点(D2):GUI(ScheduleForm 渲染器)
@@ -810,13 +810,13 @@ declare const SCHEDULE_CREATE_MARKER = "\0TAIJI_SCHEDULE_CREATE";
810
810
  */
811
811
 
812
812
  /**
813
- * 类型守卫:验证 unknown 是否为合法的 ScheduleDraft。
813
+ * 类型检查:验证 unknown 是否为合法的 ScheduleDraft。
814
814
  * 用于 runtime event-adapter 判定 marker select 的 payload 是否为本协议 draft
815
815
  * (检测失败降级普通 select),以及前端从 runtime 透传值中安全收窄。
816
816
  * 字段白名单校验(与 isAskUserQuestion 同构):可选字段校验类型,未知附加字段忽略。
817
817
  */
818
818
  declare function isScheduleDraft(value: unknown): value is ScheduleDraft;
819
- /** 回传形状守卫(导出消费:scheduler 包对 uiFormInteract answers[key] 解包值收窄;
819
+ /** 回传形状检查(导出消费:scheduler 包对 uiFormInteract answers[key] 解包值收窄;
820
820
  * FormOverlay schedule 渲染器提交的 value = JSON.stringify(ScheduleFormResult)) */
821
821
  declare function isScheduleFormResult(value: unknown): value is ScheduleFormResult;
822
822
  /**
@@ -833,7 +833,7 @@ declare function onceCronToDate(cron: string, now?: Date): Date | null;
833
833
  *
834
834
  * plan 模式的状态散落在 pi 扩展 entry / runtime 挂起注册表 / renderer 派生公式三处时,
835
835
  * 任意两者漂移即产「僵尸/谎言」UI(F1-F5)。本模块是全链路共享的单一状态契约:
836
- * 8 值状态集 + 9 事件边表 + `transition` 纯函数(守卫集中一处)+ `derivePhase` 呈现映射。
836
+ * 8 值状态集 + 9 事件边表 + `transition` 纯函数(检查集中一处)+ `derivePhase` 呈现映射。
837
837
  *
838
838
  * 语义要点(设计 D1 逐条锚定):
839
839
  * - 非法转移返回 `{ ok: false }`,由调用方降级(**不 throw 炸 turn**);副作用不进返回值
@@ -850,7 +850,7 @@ declare function onceCronToDate(cron: string, now?: Date): Date | null;
850
850
  * - `approved --approve--> dispatching`:批准后 agent 再调 `complete` 重新选择执行方式
851
851
  * (D1「approved 上 agent 再调 complete → dispatching」)。事件命名裁决:9 事件表无
852
852
  * `complete` 员,本边取「执行确认」语义族最近员 `approve`(用户点确认执行与批准后重选
853
- * 执行方式同为「确认执行、进入执行方式选择」的决策事件)——消费面接线见 consumers.md。
853
+ * 执行方式同为「确认执行、进入执行方式选择」的决策事件)——消费方接线见 consumers.md。
854
854
  * - `approved` 其余转移仅 `exit`;活跃族非终态 `--exit--> exited`;idle 从未进入,
855
855
  * exit 非法(防从未进 plan 的会话落噪音 exited entry);终态 `--enter--> planning`
856
856
  * (新一轮);`revising` 保留独立态(E3 恢复文案分叉依赖,前提 P-7)。
@@ -879,13 +879,13 @@ type PlanTransitionResult = {
879
879
  *
880
880
  * 非法转移(含运行时垃圾 state/event 值——跨版本帧、坏反序列化)返回 `{ ok: false }`
881
881
  * 且**不携带 next 键**,由调用方降级(不 throw 炸 turn)。调用方义务:`ok:false` 时
882
- * 不落盘、不执行副作用(终态上 `ok:false` 不落盘即 D3 归口点的兜底保险)。
882
+ * 不落盘、不执行副作用(终态上 `ok:false` 不落盘即 D3 归属划分点的兜底保险)。
883
883
  *
884
- * 入口白名单守卫(与 derivePhase 同一机制):普通对象字面量查表会沿原型链命中继承键——
884
+ * 入口白名单检查(与 derivePhase 同一机制):普通对象字面量查表会沿原型链命中继承键——
885
885
  * `transition('reviewing', '__proto__')` 取出 Object.prototype、`('__proto__', 'valueOf')`
886
886
  * 取出函数,均被误判为合法 next(违背本契约)。故垃圾键必须先挡在查表前。
887
887
  * **选「枚举 includes 白名单」而非 null-prototype 表 / Object.hasOwn**:① transition 与
888
- * derivePhase 共用同一守卫形态(单一机制,不并存两种写法);② PLAN_LIFECYCLE_STATES /
888
+ * derivePhase 共用同一检查形态(单一机制,不并存两种写法);② PLAN_LIFECYCLE_STATES /
889
889
  * PLAN_LIFECYCLE_EVENTS 就是值域 SSOT(测试穷举同源),includes 判定与之同源,
890
890
  * 原型键天然不在白名单内。
891
891
  */
@@ -904,21 +904,21 @@ type PlanPhase = 'idle' | 'planning' | 'reviewing' | 'approved' | 'terminal';
904
904
  * 8 存储态 → 5 呈现相位的单点映射(renderer 阶段指示/状态带共用,禁止消费方各自 if 拼)。
905
905
  * 运行时垃圾 state(混装格坏帧)降级 'idle'(无 plan 缺省,fail-safe 不误示进行中)。
906
906
  *
907
- * 入口白名单守卫(理由同 transition,见彼处):裸查表对继承键 'constructor' / 'toString'
907
+ * 入口白名单检查(理由同 transition,见彼处):裸查表对继承键 'constructor' / 'toString'
908
908
  * 会取出 Object 构造函数等并经 `?? 'idle'` 流出(非 nullish 不落兜底)——垃圾 state
909
909
  * 必须精确落 'idle',函数/对象不得作为相位流入 renderer。
910
910
  */
911
911
  declare function derivePhase(state: PlanLifecycleState): PlanPhase;
912
912
 
913
913
  /**
914
- * plan 审阅回传值域契约(plan 模式状态机显式化 D3①⑤ / D9③)——纯函数守卫,零依赖。
914
+ * plan 审阅回传值域契约(plan 模式状态机显式化 D3①⑤ / D9③)——纯函数检查,零依赖。
915
915
  *
916
- * 为什么守卫是契约级承重:TS 判别联合的穷尽性(switch/never 断言)管不到运行时值域——
917
- * respond 通道透传的是任意字符串 parse 出的 unknown(P-2),值域守卫漏改即「搁置应答被判
918
- * 垃圾 → bad-response 引导重挂」再入循环(F1 复活路径)。canonical 守卫与判别联合同住
919
- * 契约包,消费面(extensions/universal/plan tool.ts)接线见同目录 consumers.md。
916
+ * 为什么检查是契约级承重:TS 判别联合的穷尽性(switch/never 断言)管不到运行时值域——
917
+ * respond 通道透传的是任意字符串 parse 出的 unknown(P-2),值域检查漏改即「搁置应答被判
918
+ * 垃圾 → bad-response 引导重挂」再入循环(F1 复活路径)。canonical 检查与判别联合同住
919
+ * 契约包,消费方(extensions/universal/plan tool.ts)接线见同目录 consumers.md。
920
920
  *
921
- * 降级双分源(D3①)——parse 失败必须区分两类(envelope 判别保留),消费面出口同款:
921
+ * 降级双分源(D3①)——parse 失败必须区分两类(envelope 判别保留),消费方出口同款:
922
922
  * - `unknown-decision`(对象合法但 decision 不在值域):版本错配信号(R2),消费方
923
923
  * 额外 logger.warn 留痕;出口与文案与 malformed 同款——bad-response 报错提示重挂。
924
924
  * 裁决与重审触发(候选替代 = 恢复独立 version-mismatch 不重挂出口)登记于消费方
@@ -928,7 +928,7 @@ declare function derivePhase(state: PlanLifecycleState): PlanPhase;
928
928
  *
929
929
  * selfReview 有界字段(D9③ / R3):有界性由**写侧单点截断**保证(截断点 = 扩展 payload
930
930
  * 构造处),4KB 上限与 UTF-8 字节界安全截断的唯一权威在本模块;透传层(runtime)不截、
931
- * 入站守卫不二次截(上限已在写侧达成)。
931
+ * 入站检查不二次截(上限已在写侧达成)。
932
932
  */
933
933
 
934
934
  /** selfReview 上限:4KB(UTF-8 字节)。超限即截(全文可要求 agent 贴对话流,R3)。 */
@@ -939,7 +939,7 @@ declare const PLAN_SELF_REVIEW_MAX_BYTES = 4096;
939
939
  */
940
940
  declare function truncateSelfReview(text: string): string;
941
941
  /**
942
- * `PlanReviewRequest` 形状守卫(E5 垃圾数据判据):
942
+ * `PlanReviewRequest` 形状检查(E5 垃圾数据判据):
943
943
  * docs 必为 `PlanDocMeta[]`(逐项形状);selfReview 缺省或 string——**optional 是兼容契约**
944
944
  * (旧扩展不携带 → 自审行不渲染的降级形态,D9③),值域上限不在此拒绝(写侧截断已界)。
945
945
  * 空载荷(undefined/null/非对象/缺 docs)与非法形态(docs 非数组 / 元素形状不合法 /
@@ -966,19 +966,19 @@ type PlanReviewResponseEnvelope = {
966
966
  code: 'malformed';
967
967
  };
968
968
  /**
969
- * respond 回传解析(值域守卫的判别版):dismiss 样本必通(D3 主干),未知 decision 值域
970
- * 落降级枚举而非垃圾(两类降级可判别分离;消费面出口同款引导重挂,见文件头「降级双分源」)。
969
+ * respond 回传解析(值域检查的判别版):dismiss 样本必通(D3 主干),未知 decision 值域
970
+ * 落降级枚举而非垃圾(两类降级可判别分离;消费方出口同款引导重挂,见文件头「降级双分源」)。
971
971
  */
972
972
  declare function parsePlanReviewResponse(value: unknown): PlanReviewResponseEnvelope;
973
973
  /**
974
- * `PlanReviewResponse` 值域守卫(含 dismiss 员,D3①)——`parsePlanReviewResponse` 的谓词形。
974
+ * `PlanReviewResponse` 值域检查(含 dismiss 员,D3①)——`parsePlanReviewResponse` 的谓词形。
975
975
  * 消费方需要区分 unknown-decision / malformed 两类降级时用 parse 版。
976
976
  */
977
977
  declare function isPlanReviewResponse(value: unknown): value is PlanReviewResponse;
978
978
 
979
979
  /**
980
980
  * plan-state entry 的 customType(pi appendEntry custom entry 判别键)。磁盘形态冻结:
981
- * 扩展写读两侧(persistPlanState / isPlanStateEntry)与 runtime 投影链(plan-state-extractor /
981
+ * 扩展写读两侧(persistPlanState / isPlanStateEntry)与 runtime 派生视图链(plan-state-extractor /
982
982
  * session-records)均消费本常量,值同源——改值即历史会话全部失联,禁改(冻结锚测试见
983
983
  * 本目录 legacy-entries.test.ts)。
984
984
  */
@@ -986,7 +986,7 @@ declare const PLAN_STATE_CUSTOM_TYPE = "plan-state";
986
986
  /**
987
987
  * 生命周期状态读取(D2 读方①②共用映射,原扩展 state.ts / runtime extractor 内联拷贝的
988
988
  * 单源归并):
989
- * ① 新字段直读(值域守卫:PLAN_LIFECYCLE_STATES 之外的垃圾值按缺失处理,落映射——
989
+ * ① 新字段直读(值域检查:PLAN_LIFECYCLE_STATES 之外的垃圾值按缺失处理,落映射——
990
990
  * 不信任外部写入);
991
991
  * ② 旧 entry 无 state(或垃圾 state)时映射 reviewState(awaiting→reviewing /
992
992
  * revising→revising / 其余值→planning|idle 按 isActive)。
@@ -1008,7 +1008,7 @@ declare function readResumeHint(data: {
1008
1008
  /**
1009
1009
  * 统一提问表单协议(ui-form)的类型定义。
1010
1010
  *
1011
- * 把 plan / scheduler / ask-user 三个 extension 的提问交互收口为一个表单协议:
1011
+ * 把 plan / scheduler / ask-user 三个 extension 的提问交互收敛为一个表单协议:
1012
1012
  * 问题即数据(类型化问题集),GUI 链路统一(wire 协议 + 渲染器)——多问 = 多 tab,
1013
1013
  * 单问 = 单视图。extension 侧经 uiFormInteract() 序列化进 select 的 options[0],
1014
1014
  * runtime event-adapter 检测 UI_FORM_MARKER 广播 form 帧,前端 FormOverlay
@@ -1131,7 +1131,7 @@ interface UiFormInteractOptions {
1131
1131
  * (undefined 为缺省态:存量扩展与未声明者,桥接 = 现状,方向安全);
1132
1132
  * `false` = 无 turn 预期——命令 handler 内 select(提交后结构性无 turn),respond 侧
1133
1133
  * 提交即收尾,消除 30s 假忙。消费方判定必须是 `=== false` 显式式:truthy 简化
1134
- * (`!expectTurn`)会把 undefined 也当无 turn、误清桥接(D2 被否谱系)。
1134
+ * (`!expectTurn`)会把 undefined 也当无 turn、误清桥接(D2 不采用其余方案的理由)。
1135
1135
  *
1136
1136
  * 缺省(undefined)经 stripUndefined 剥键——未声明者的 wire payload 逐字节不变,
1137
1137
  * 旧 runtime 读不到即忽略(JSON.parse 容忍未知键)。
@@ -1152,14 +1152,14 @@ interface UiFormInteractOptions {
1152
1152
  declare function uiFormInteract(ctx: GuiContext, form: FormQuestion[], opts?: UiFormInteractOptions): Promise<UiFormInteractResult>;
1153
1153
 
1154
1154
  /**
1155
- * 统一提问表单(ui-form)的形状守卫。
1155
+ * 统一提问表单(ui-form)的形状检查。
1156
1156
  *
1157
1157
  * isFormQuestion 按 type 判别分支逐项校验(白名单风格:必填字段类型校验、可选
1158
1158
  * 字段校验、未知字段忽略——与 isAskUserQuestion / isScheduleDraft 同构语义)。
1159
1159
  * 三个消费点失败策略各异(设计 D2):
1160
1160
  * - 发送侧(uiFormInteract 内):不合法项抛错(调用方编码 bug,fail-fast);
1161
1161
  * - event-adapter:逐项过滤,合法项 ≥1 才产 form 帧、全不合法降级普通 select;
1162
- * - renderer:复核守卫,不合法项跳过 + warn,全部不合法 → overlay 错误占位仅取消可点。
1162
+ * - renderer:复核检查,不合法项跳过 + warn,全部不合法 → overlay 错误占位仅取消可点。
1163
1163
  *
1164
1164
  * isFormAnswers 校验回包形状(Record<string, string>):键动态(key = header ??
1165
1165
  * question)无法枚举白名单,故只校验值域全 string;JSON 合法但非本形状由
@@ -1167,11 +1167,11 @@ declare function uiFormInteract(ctx: GuiContext, form: FormQuestion[], opts?: Ui
1167
1167
  */
1168
1168
 
1169
1169
  /**
1170
- * 类型守卫:验证 unknown 是否为合法的 FormQuestion(choice / text / schedule 三分支)。
1170
+ * 类型检查:验证 unknown 是否为合法的 FormQuestion(choice / text / schedule 三分支)。
1171
1171
  * 用于发送侧 fail-fast、event-adapter 逐项过滤与 renderer 复核(三消费点见文件头)。
1172
1172
  */
1173
1173
  declare function isFormQuestion(value: unknown): value is FormQuestion;
1174
- /** 类型守卫:验证 unknown 是否为合法的 FormAnswers(值域全 string 的普通对象) */
1174
+ /** 类型检查:验证 unknown 是否为合法的 FormAnswers(值域全 string 的普通对象) */
1175
1175
  declare function isFormAnswers(value: unknown): value is FormAnswers;
1176
1176
 
1177
1177
  /**
@@ -1225,7 +1225,7 @@ interface SessionManagerCreateParams {
1225
1225
  * 完成通知债权的幂等键(optional,notify-once D2/D6):extension 侧
1226
1226
  * `crypto.randomUUID()` 前缀 `sm-` 生成。缺省/畸形 → runtime 不 arm、
1227
1227
  * `willNotify:false`、零完成通知——兼容判据从版本二分改为字段有无。
1228
- * 形态判定不在 params 守卫(畸形不构成 params 错误、动作照常执行),
1228
+ * 形态判定不在 params 检查(畸形不构成 params 错误、动作照常执行),
1229
1229
  * 由 runtime 受理点消费 `isSessionManagerNotifyId` 作 arm 判据。
1230
1230
  */
1231
1231
  notifyId?: string;
@@ -1256,7 +1256,7 @@ interface SessionManagerAbortParams {
1256
1256
  /**
1257
1257
  * watch action 参数(notify-once D2/D6):通知债权的纯应答通道,**单键寻址**——
1258
1258
  * runtime 按 `(调用方 parentSid, notifyId)` 反查 claim,parentSid 取自调用方连接身份、
1259
- * **协议面不定义不携带**(可推导字段免传,多余字段被守卫拒绝)。不传 timeout、
1259
+ * **协议范围不定义不携带**(可推导字段免传,多余字段被检查拒绝)。不传 timeout、
1260
1260
  * fire-and-forget 长挂 select;每 claim 单 watch 槽(新覆盖旧,runtime 只 respond 最新)。
1261
1261
  */
1262
1262
  interface SessionManagerWatchParams {
@@ -1264,9 +1264,9 @@ interface SessionManagerWatchParams {
1264
1264
  notifyId: string;
1265
1265
  }
1266
1266
  declare function isSessionManagerNotifyId(v: unknown): v is string;
1267
- /** create:字段可选 string + optional notifyId(类型面,sm- 形态判定归 arm 判据) */
1267
+ /** create:字段可选 string + optional notifyId(类型范围,sm- 形态判定归 arm 判据) */
1268
1268
  declare function isSessionManagerCreateParams(v: unknown): v is SessionManagerCreateParams;
1269
- /** send:sessionId + prompt 必填,notifyId optional(类型面校验同 create) */
1269
+ /** send:sessionId + prompt 必填,notifyId optional(类型范围校验同 create) */
1270
1270
  declare function isSessionManagerSendParams(v: unknown): v is SessionManagerSendParams;
1271
1271
  /** history:sessionId 必填、tailTurns 可选 number */
1272
1272
  declare function isSessionManagerHistoryParams(v: unknown): v is SessionManagerHistoryParams;
@@ -1276,9 +1276,9 @@ declare function isSessionManagerAbortParams(v: unknown): v is SessionManagerAbo
1276
1276
  /** list:无参数(过滤由 handler 固化,params 不携带任何过滤字段) */
1277
1277
  declare function isSessionManagerListParams(v: unknown): v is SessionManagerListParams;
1278
1278
  /**
1279
- * watch:**封闭单键** `{notifyId}` 守卫(notify-once D2 形态入站自检)——
1279
+ * watch:**封闭单键** `{notifyId}` 检查(notify-once D2 形态入站自检)——
1280
1280
  * 空载荷 / 缺字段 / 夹带任何额外字段(如 parentSid:归属由 runtime 取连接身份,
1281
- * 协议面不定义)/ notifyId 非 string / 形态不符(缺 `sm-` 前缀、非 UUID 体、超长)
1281
+ * 协议范围不定义)/ notifyId 非 string / 形态不符(缺 `sm-` 前缀、非 UUID 体、超长)
1282
1282
  * → false → handler dispatch 抛错走 respond({error}) 错误闭环(error envelope)。
1283
1283
  * 形态函数与 lifetimeNotifyId 同一实现(防自检拒掉 runtime 生成的 lifetime watch)。
1284
1284
  */
@@ -1289,7 +1289,7 @@ interface SessionManagerCreateResult {
1289
1289
  status: 'created';
1290
1290
  modelId?: string;
1291
1291
  /**
1292
- * 完成通知债权是否已 arm(notify-once D6,LLM 契约面显式化):create 无 prompt /
1292
+ * 完成通知债权是否已 arm(notify-once D6,LLM 契约范围显式化):create 无 prompt /
1293
1293
  * notifyId 缺省或畸形 → false(零完成通知);true 时首次完成恰回一条通知。
1294
1294
  * 注意与 lifetimeNotifyId 正交——后者恒存在(死亡通知与债权无关)。
1295
1295
  */
@@ -1365,15 +1365,15 @@ type SessionManagerWatchReason =
1365
1365
  * 折叠 cancelled——null 不在本类型内,消费方须同时处理。
1366
1366
  */
1367
1367
  interface SessionManagerWatchRespondPayload {
1368
- /** 分拣键 (sessionId, reason) 的 reason 腿(D3 两层模型:cancelled/orphaned → 仅
1368
+ /** 分拣键 (sessionId, reason) 的 reason 路径(D3 两层模型:cancelled/orphaned → 仅
1369
1369
  * unregister;exited/deleted → 死亡新闻槽;completed/failed/stopped → 结果新闻) */
1370
1370
  reason: SessionManagerWatchReason;
1371
1371
  /**
1372
1372
  * claim 所属子会话 id 回带——D3 槽键 (sessionId, deathSeq) / 分拣键 (sessionId,
1373
- * reason) / D9 文案 `<sid>` 的唯一数据源(收口腿闭包仅有父 sid,缺此字段则同父
1373
+ * reason) / D9 文案 `<sid>` 的唯一数据源(收敛路径闭包仅有父 sid,缺此字段则同父
1374
1374
  * 多子 deathSeq 跨 child 碰撞)。claim 命中路径(settle/death/orphaned/二次校验)
1375
1375
  * 恒带;fail-closed(查无 claim)无 claim 可回带 → 缺席——该路径 reason 恒
1376
- * 'cancelled',extension 静默收口不消费 sessionId。
1376
+ * 'cancelled',extension 静默收尾不消费 sessionId。
1377
1377
  */
1378
1378
  sessionId?: string;
1379
1379
  /** death 批身份(per session 递增;同一死亡事件循环 respond 时 runtime 直供) */
@@ -1382,7 +1382,7 @@ interface SessionManagerWatchRespondPayload {
1382
1382
  settleSeq?: number;
1383
1383
  /** 本批兑现总笔数(同批每条应答携带同值);death 侧 = 同 deathSeq 的 claim 数(D3 合批口径,runtime 直供,死亡/结果新闻正文消费 fulfills N) */
1384
1384
  fulfillsN?: number;
1385
- /** death 应答携带:exit 腿诊断数据通路复刻(400 字截尾沿用现值),extension 文案构造消费 */
1385
+ /** death 应答携带:exit 路径诊断数据通路复刻(400 字截尾沿用现值),extension 文案构造消费 */
1386
1386
  exitCode?: number | null;
1387
1387
  stderrTail?: string;
1388
1388
  /**
@@ -1393,7 +1393,7 @@ interface SessionManagerWatchRespondPayload {
1393
1393
  sessionFilePath?: string;
1394
1394
  }
1395
1395
  /**
1396
- * watch respond payload 运行时守卫(extension 读侧不信任外部格式——AGENTS 关键规则 5):
1396
+ * watch respond payload 运行时检查(extension 读侧不信任外部格式——AGENTS 关键规则 5):
1397
1397
  * null(旧 runtime 象限)/ 非 record / reason 缺失、非 string 或词表外 / 可选 meta
1398
1398
  * 类型不符 → false(可选字段缺席一律放行——含 sessionFilePath)。消费方对 false 与
1399
1399
  * null 同路折叠静默 unregister(fail-safe:未知 reason 不得落 default 误标)。
@@ -1408,7 +1408,7 @@ type SessionManagerErrorResult = ChannelErrorResult & {
1408
1408
  };
1409
1409
 
1410
1410
  /**
1411
- * subagent 在途上报的类型定义(u7a 协议面)。
1411
+ * subagent 在途上报的类型定义(u7a 协议范围)。
1412
1412
  *
1413
1413
  * 契约两端:
1414
1414
  * - 写侧(生产):@zhushanwen/pi-subagent-workflow 壳层(src/host/inflight-reporter.ts)
@@ -1452,12 +1452,12 @@ interface SubagentInFlightReport {
1452
1452
  */
1453
1453
  declare const INFLIGHT_REPORT_ACK: "{\"ack\":true}";
1454
1454
  /**
1455
- * SubagentInFlightReport 形状守卫:inFlight 非负整数、emittedAt 数字、sessionId
1455
+ * SubagentInFlightReport 形状检查:inFlight 非负整数、emittedAt 数字、sessionId
1456
1456
  * 缺席或 string。event-adapter(u7b)路由分支消费;非法帧返回 false(调用方丢弃,
1457
1457
  * 不抛错不镜像)。
1458
1458
  */
1459
1459
  declare function isSubagentInFlightReport(v: unknown): v is SubagentInFlightReport;
1460
- /** 确认回包形状守卫(pi 侧 reporter 消费——非本字符串即未确认,折叠重试)。 */
1460
+ /** 确认回包形状检查(pi 侧 reporter 消费——非本字符串即未确认,折叠重试)。 */
1461
1461
  declare function isInFlightReportAck(v: unknown): v is typeof INFLIGHT_REPORT_ACK;
1462
1462
 
1463
1463
  /**
@@ -1470,12 +1470,12 @@ declare function isInFlightReportAck(v: unknown): v is typeof INFLIGHT_REPORT_AC
1470
1470
  * 与 ASK_USER_MARKER / SESSION_MANAGER_MARKER / BRIDGE_MARKER 同理。
1471
1471
  *
1472
1472
  * 设计权威源:docs/architecture/crash-forensics-and-watchdog.md §3.3 D5
1473
- * 「在途判定谓词 + 求值位置」——extension 聚合上报通道的协议面(u7a)。
1473
+ * 「在途判定谓词 + 求值位置」——extension 聚合上报通道的协议范围(u7a)。
1474
1474
  */
1475
1475
  declare const SUBAGENT_INFLIGHT_MARKER = "\0TAIJI_SUBAGENT_INFLIGHT";
1476
1476
 
1477
1477
  /**
1478
- * journal 事件推送的类型定义(event-push-channel 协议面)。
1478
+ * journal 事件推送的类型定义(event-push-channel 协议范围)。
1479
1479
  *
1480
1480
  * 契约两端:
1481
1481
  * - 写侧(生产):@zhushanwen/pi-subagent-workflow 壳层(src/host/journal-reporter.ts)
@@ -1537,12 +1537,12 @@ interface SubagentJournalReport {
1537
1537
  */
1538
1538
  declare const JOURNAL_REPORT_ACK: "{\"ack\":true}";
1539
1539
  /**
1540
- * SubagentJournalReport 形状守卫:domain 落两域词表、fileKey 非空串、events 逐条
1541
- * 过信封守卫、sessionId 缺席或 string。event-adapter 路由分支消费;非法帧返回
1540
+ * SubagentJournalReport 形状检查:domain 落两域词表、fileKey 非空串、events 逐条
1541
+ * 过信封检查、sessionId 缺席或 string。event-adapter 路由分支消费;非法帧返回
1542
1542
  * false(调用方丢弃,不 fold 不 ack)。
1543
1543
  */
1544
1544
  declare function isSubagentJournalReport(v: unknown): v is SubagentJournalReport;
1545
- /** 确认回包形状守卫(pi 侧 reporter 消费——非本字符串即未确认)。 */
1545
+ /** 确认回包形状检查(pi 侧 reporter 消费——非本字符串即未确认)。 */
1546
1546
  declare function isJournalReportAck(v: unknown): v is typeof JOURNAL_REPORT_ACK;
1547
1547
 
1548
1548
  /**
@@ -1564,7 +1564,7 @@ declare const SUBAGENT_JOURNAL_MARKER = "\0TAIJI_SUBAGENT_JOURNAL";
1564
1564
  * subagent-workflow 通知通道的 custom_message customType 词表(单源)。
1565
1565
  *
1566
1566
  * 契约两端(值逐字节依赖,改名 = 跨侧破坏性变更):
1567
- * - 写侧:@zhushanwen/pi-subagent-workflow extension(workflow 收口通知 / bg-notify
1567
+ * - 写侧:@zhushanwen/pi-subagent-workflow extension(workflow 收敛通知 / bg-notify
1568
1568
  * 送达 / 定向消息留痕,经 pi.sendMessage 落 custom_message entry 进 session JSONL)
1569
1569
  * 与 @zhushanwen/subagent-core(notifier 送达 + notify ledger 默认通道);
1570
1570
  * - 读侧:taiji 三层——@taiji/shared(COMPLETE_NOTIFY_CUSTOM_TYPES display 覆写
@@ -1579,7 +1579,7 @@ declare const SUBAGENT_JOURNAL_MARKER = "\0TAIJI_SUBAGENT_JOURNAL";
1579
1579
  * worker-script-builder 的 postMessage 帧 type)是同名不同域——那是引擎进程内 RPC 形状,
1580
1580
  * 不跨 pi session 边界,不进本词表。
1581
1581
  */
1582
- /** workflow run 收口通知的送达 customType。runtime event-interpreter 按它识别 run 完成
1582
+ /** workflow run 收敛通知的送达 customType。runtime event-interpreter 按它识别 run 完成
1583
1583
  * 并驱动 W18 workflow-record 失效信号;shared 完成通知 display 覆写集合亦按它收录。
1584
1584
  * 与 SUBAGENT_BG_NOTIFY_CUSTOM_TYPE 通道互斥(互用会让失效信号误判通道语义)。 */
1585
1585
  declare const WORKFLOW_RESULT_CUSTOM_TYPE: "workflow-result";
@@ -1656,10 +1656,11 @@ interface SubagentEngineConfigView {
1656
1656
  * per-action × actor 权限矩阵按此建制(matrix.ts)。
1657
1657
  * - CANVAS_MARKER_ACTIONS(16 + 'enter'):marker 通道(extension select 挂起)
1658
1658
  * 的 action 域。'enter' 是 canvas_enter 工具「打开已有画布」形态的通道动作:
1659
- * 读全量 + 登记绑定(sessionId ↔ canvasId),非画布 mutation——不产事件、
1659
+ * 读全量(归属校验在 readState,非 owner → forbidden);回推对象 = 归属会话
1660
+ * 本身(owner 持久在落盘路径),无登记动作、不产事件——非画布 mutation、
1660
1661
  * 不在权限矩阵内(marker 通道调用方恒为 agent 工具)。创建形态走 'create'
1661
- * (marker 通道的 create 只可能来自 canvas_enter 工具,runtime 在该通道
1662
- * create 成功时一并登记绑定;GUI 托盘新建走 WS RPC 通道、不登记绑定)。
1662
+ * (marker 通道的 create 只可能来自 canvas_enter 工具;GUI 托盘新建走 WS RPC
1663
+ * 通道,两通道行为无分叉)。
1663
1664
  */
1664
1665
  /**
1665
1666
  * canvas 工具请求的 title marker。runtime event-adapter / CanvasHandler 检测此
@@ -1846,6 +1847,14 @@ interface ReviewReport {
1846
1847
  /** 画布状态(聚合 1 全量投影;canvas.get reply 与 canvas.json 快照共用形状)。 */
1847
1848
  interface CanvasState {
1848
1849
  canvasId: string;
1850
+ /**
1851
+ * 归属会话 id(画布归属 = 创建它的 session,1:N——一个 session 可有多张画布)。
1852
+ * 归属即落盘路径(`<dataDir>/ext-sessions/<ownerSessionId>/canvases/<canvasId>/`),
1853
+ * 路径即归属的构造性承载:该字段由 runtime 从落盘路径推导填充(服务层唯一写入点),
1854
+ * 领域事件流不承载归属(CanvasCreated 事件 data 不含 sessionId——事件流内容与格式
1855
+ * 不随布局反转变化,只挪位置);跨会话访问按本字段归属校验拒绝(forbidden)。
1856
+ */
1857
+ ownerSessionId: string;
1849
1858
  /** 画布名(canvasId = 短随机 id;重命名属第二版多画布管理,MVP 只读)。 */
1850
1859
  name: string;
1851
1860
  /** 根问题三要素(不变量 1:有且仅有一个根节点,类型 question,带完成判据与范围排除)。 */
@@ -1895,9 +1904,12 @@ interface CanvasState {
1895
1904
  }
1896
1905
  /** canvas.list 条目:托盘画布列表的数据源(名称 + 阶段徽标 + must-fix 计数)。
1897
1906
  * 阶段徽标本身是 renderer 派生值(开放 must-fix 或审查进行中 = 审查中;
1898
- * converged = 已收敛;其余 = 生长中),契约只给派生输入。 */
1907
+ * converged = 已收敛;其余 = 生长中),契约只给派生输入。清单按请求 sessionId
1908
+ * 过滤(只返回归属该会话的画布),ownerSessionId 即过滤判据的回显。 */
1899
1909
  interface CanvasListEntry {
1900
1910
  canvasId: string;
1911
+ /** 归属会话 id(= 请求的过滤 sessionId;语义同 CanvasState.ownerSessionId)。 */
1912
+ ownerSessionId: string;
1901
1913
  name: string;
1902
1914
  statement: string;
1903
1915
  converged: boolean;
@@ -1960,17 +1972,18 @@ interface CanvasError {
1960
1972
  recover: string;
1961
1973
  }
1962
1974
  /**
1963
- * 错误码词表(封闭 15 值)。分组:
1975
+ * 错误码词表(封闭 16 值)。分组:
1964
1976
  * - 寻址 / 形状:canvas_not_found / node_not_found / edge_not_found /
1965
1977
  * invalid_params / unknown_action
1966
- * - 权限:actor_not_allowed(矩阵表外组合 fail-fast)
1978
+ * - 权限:actor_not_allowed(矩阵表外组合 fail-fast)/ forbidden(画布不属当前会话——
1979
+ * 归属校验拒绝,画布归属 = 创建它的 session,跨会话访问一律结构化拒绝)
1967
1980
  * - 不变量拦截:selection_conflict(不变量 3 双选定)/ cycle_detected(不变量 2 成环)/
1968
1981
  * unverified_fact(不变量 5)/ dispatch_blocked(不变量 7)/ not_converged(不变量 10)/
1969
1982
  * lifecycle_transition_illegal(状态机表外转移)
1970
1983
  * - 审查聚合:entry_ref_missing(聚合 2 不变量 1)/ already_resolved(first-writer-wins)/
1971
1984
  * review_max_rounds(轮次上限后再发起)
1972
1985
  */
1973
- declare const CANVAS_ERROR_CODES: readonly ["canvas_not_found", "node_not_found", "invalid_params", "unknown_action", "actor_not_allowed", "selection_conflict", "cycle_detected", "unverified_fact", "dispatch_blocked", "not_converged", "lifecycle_transition_illegal", "entry_ref_missing", "already_resolved", "review_max_rounds", "edge_not_found"];
1986
+ declare const CANVAS_ERROR_CODES: readonly ["canvas_not_found", "node_not_found", "invalid_params", "unknown_action", "actor_not_allowed", "forbidden", "selection_conflict", "cycle_detected", "unverified_fact", "dispatch_blocked", "not_converged", "lifecycle_transition_illegal", "entry_ref_missing", "already_resolved", "review_max_rounds", "edge_not_found"];
1974
1987
  type CanvasErrorCode = (typeof CANVAS_ERROR_CODES)[number];
1975
1988
  /**
1976
1989
  * 每码一句恢复动作文案(SSOT;runtime 构造 CanvasError 时 recover 字段取此处
@@ -2159,7 +2172,10 @@ interface CanvasReadParams {
2159
2172
  /** 子树读取:从该节点 id 向下的主干子树;缺省读全量。 */
2160
2173
  subtree?: string;
2161
2174
  }
2162
- /** list:无参数(全量画布清单;过滤无字段——Record 结构性拒绝夹带)。 */
2175
+ /** list:无参数(全量画布清单的 action 侧形状——归属过滤字段不在共享 params 内:
2176
+ * sessionId 是**通道级字段**(WS payload 携带、marker 通道由 dispatch 上下文的发起
2177
+ * 会话注入,与 canvas.mutate 的 actor/sessionId 同款通道字段模式),runtime 按归属
2178
+ * 会话过滤(D4 裁决 3)。Record 结构性拒绝夹带任何过滤字段)。 */
2163
2179
  type CanvasListParams = Record<string, never>;
2164
2180
  /** 16 action 的 params 映射(SSOT;两通道共用——WS RPC 与 marker 的 params 同构)。 */
2165
2181
  interface CanvasActionParams {
@@ -2189,7 +2205,7 @@ type CanvasMutateRequest = {
2189
2205
  };
2190
2206
  }[CanvasAction];
2191
2207
  type CanvasMarkerAction = (typeof CANVAS_MARKER_ACTIONS)[number];
2192
- /** enter(canvas_enter 打开形态):读全量 + 登记绑定;非画布 mutation、不产事件。 */
2208
+ /** enter(canvas_enter 打开形态):读全量(归属校验在 readState,非 owner → forbidden);非画布 mutation、不产事件、无登记动作。 */
2193
2209
  interface CanvasEnterParams {
2194
2210
  canvasId: string;
2195
2211
  }
@@ -2234,7 +2250,8 @@ declare function isCanvasConvergeCheckParams(v: unknown): v is CanvasConvergeChe
2234
2250
  declare function isCanvasExportParams(v: unknown): v is CanvasExportParams;
2235
2251
  declare function isCanvasDispatchParams(v: unknown): v is CanvasDispatchParams;
2236
2252
  declare function isCanvasReadParams(v: unknown): v is CanvasReadParams;
2237
- /** list:无参数——Record 结构性拒绝夹带任何过滤字段(session-manager list 同款)。 */
2253
+ /** list:无参数——Record 结构性拒绝夹带任何过滤字段(session-manager list 同款;
2254
+ * 归属过滤字段是通道级的,见 CanvasListParams 注释)。 */
2238
2255
  declare function isCanvasListParams(v: unknown): v is CanvasListParams;
2239
2256
  /** enter(canvas_enter 打开形态):封闭单键 canvasId。 */
2240
2257
  declare function isCanvasEnterParams(v: unknown): v is CanvasEnterParams;
@@ -2308,7 +2325,7 @@ declare function allCanvasActions(): readonly CanvasAction[];
2308
2325
  * 契约两端(此前各持一份同构差集实现,对齐手段是注释):
2309
2326
  * - extension 侧:@zhushanwen/pi-base-tool-enhance 对账(原 collectUnsettledTaskIds:
2310
2327
  * session_start 时对「entries 显示活跃但任务已终态」的 bt- 任务补写注销)
2311
- * - extension 侧:@zhushanwen/pi-pending-notifications 守卫判据(原
2328
+ * - extension 侧:@zhushanwen/pi-pending-notifications 检查判据(原
2312
2329
  * scanPendingEntries + filterActiveRegisters;其 types/currentSessionId/normalize
2313
2330
  * 过滤是 pending 产品语义,留在 pending 侧,不在本模块)
2314
2331
  *
@@ -2328,19 +2345,48 @@ interface CollectPendingIdsOptions {
2328
2345
  /** 只保留该前缀的 id(如 'bt-');缺省不过滤。 */
2329
2346
  idPrefix?: string;
2330
2347
  }
2331
- /** scanPendingEntries 的结果:register 原始 data 列表 + 已注销 id 集合。 */
2348
+ /** scanPendingEntries 的结果:register 原始 data 列表 + 已注销 id 集 + collect 字段映射视图。 */
2332
2349
  interface PendingEntriesScan {
2333
2350
  registerEntries: Array<{
2334
2351
  data: Record<string, unknown>;
2335
2352
  }>;
2336
2353
  unregisteredIds: Set<string>;
2354
+ /**
2355
+ * register 首见字段视图(MF-2-1 单点):id → type(string 才收,原样透传——归一化
2356
+ * 归消费方)。首见规则 = 首条 register 胜出:同 id 重复条目不覆盖;首条无 type
2357
+ * 则该 id 恒无映射(不被后续重复条目补位——与 applyPendingDiff 的首条 data 语义
2358
+ * 同口径,工具侧旧「首条带 type 胜出」的补位行为是漂移,收敛时已废除)。
2359
+ */
2360
+ registerTypes: Map<string, string>;
2361
+ /**
2362
+ * 注销条目 status 视图:id → status(写侧经 mapReasonToStatus 已映射落盘)。仅收
2363
+ * MAPPED_PENDING_STATUSES 成员(词表外/畸形不收,不虚构终态);同 id 多条注销取
2364
+ * 末次合法值(后条非法不抹除前条合法值)。
2365
+ */
2366
+ unregisterStatuses: Map<string, MappedPendingStatus>;
2337
2367
  }
2338
2368
  /**
2339
2369
  * 单趟扫描 entries 按 customType 分流(容错对齐 pending 侧 S-10:null/非对象
2340
- * 元素先守卫再访问字段)。register 侧不校验 id(合法性判定归差集层);unregister
2341
- * 仅收 string id。data 用最小结构类型 Record<string, unknown>,消费方自行窄化。
2370
+ * 元素先检查再访问字段)。register 侧 registerEntries 不校验 id(合法性判定归差集
2371
+ * 层);unregister 仅收 string id。data 用最小结构类型 Record<string, unknown>,
2372
+ * 消费方自行窄化。字段映射视图(registerTypes / unregisterStatuses)顺路产出:
2373
+ * collect 链路的 type/outcome 映射规则单点在本次扫描(delivery-port 快照基线与
2374
+ * pending-notifications 终局回填此前各持一份同构扫描器且首见语义已分歧,MF-2-1
2375
+ * 收敛——消费方禁止本地复制映射段)。
2342
2376
  */
2343
- declare function scanPendingEntries(entries: unknown[]): PendingEntriesScan;
2377
+ declare function scanPendingEntries(entries: readonly unknown[]): PendingEntriesScan;
2378
+ /** scanPendingFields 的结果:collect 链路消费的字段映射投影(首见 type + 注销 status)。 */
2379
+ interface PendingFieldsScan {
2380
+ registerTypes: Map<string, string>;
2381
+ unregisterStatuses: Map<string, MappedPendingStatus>;
2382
+ }
2383
+ /**
2384
+ * collect 终局回填的字段视图(MF-2-1 单点入口):scanPendingEntries 产物中
2385
+ * register 首见 type + 全部注销 status 的 MAPPED 成员投影。消费方(delivery-port
2386
+ * 快照基线 / pending-notifications consume 后回填)按 id 查表补 type/outcome,
2387
+ * 查无保持 undefined(诚实缺省,不虚构终态)。
2388
+ */
2389
+ declare function scanPendingFields(entries: readonly unknown[]): PendingFieldsScan;
2344
2390
  /**
2345
2391
  * 差集本体(规则单点):register 首见去重 + unregister 全局抵消 + id 非法跳过。
2346
2392
  * 首见判定先于任何消费方过滤(seen.add 后即使调用方对首个 data 过滤丢弃,后续
@@ -2382,5 +2428,14 @@ declare function collectActivePendingIds(entries: unknown[], opts?: CollectPendi
2382
2428
  * 字面量联合锁定值域,switch 分支编译期受限。 */
2383
2429
  type MappedPendingStatus = 'completed' | 'failed' | 'cancelled' | 'expired' | 'time_limited' | 'aborted';
2384
2430
  declare function mapReasonToStatus(reason: string): MappedPendingStatus;
2431
+ /**
2432
+ * MappedPendingStatus 的值集(MF-1-5 词表单源):由 REASON_STATUS_MAP 派生——映射表
2433
+ * 演化(新增 reason / 改映射目标)时值集构造性跟随,无第二份手工词表可漂移。消费方
2434
+ * (delivery-port / pending-notifications 读取侧)按成员资格判定落盘 status 合法性时
2435
+ * import 本常量,禁止本地复制六值 Set(曾两包各持一份本地拷贝注释自认「同步维护」)。
2436
+ * Set 成员与 MappedPendingStatus 联合的相等性由 pending-entries.test.ts 断言锁定。
2437
+ * string 元素类型是消费面要求(对任意落盘 status 做成员判定,窄化前的原始值)。
2438
+ */
2439
+ declare const MAPPED_PENDING_STATUSES: ReadonlySet<string>;
2385
2440
 
2386
- export { ACTION_EVENT_MAP, ASK_USER_MARKER, type ArgumentMateriality, type ArgumentPolarity, type AskUserAnswers, type AskUserOption, type AskUserQuestion, CANVAS_ACTIONS, CANVAS_ACTOR_MATRIX, CANVAS_ERROR_CODES, CANVAS_ERROR_RECOVERY, CANVAS_EVENT_TYPES, CANVAS_MARKER, CANVAS_MARKER_ACTIONS, CANVAS_TOOL_NAMES, type CanvasAction, type CanvasActionParams, type CanvasActor, type CanvasComment, type CanvasCommentParams, type CanvasCommentRespondParams, type CanvasConvergeCheckParams, type CanvasCreateParams, type CanvasDecideDirectionParams, type CanvasDirectionDecision, type CanvasDispatchParams, type CanvasEdge, type CanvasEdgeType, type CanvasEnterParams, type CanvasError, type CanvasErrorCode, type CanvasEventType, type CanvasExportParams, type CanvasExportTarget, type CanvasGrowItem, type CanvasGrowParams, type CanvasListEntry, type CanvasListParams, type CanvasListReply, type CanvasMarkerAction, type CanvasMarkerParams, type CanvasMarkerRequest, type CanvasMutateReply, type CanvasMutateRequest, type CanvasNode, type CanvasNodeLifecycle, type CanvasNodeType, type CanvasPatchParams, type CanvasReadParams, type CanvasReadReply, type CanvasReviewAppendParams, type CanvasReviewEntryInput, type CanvasReviewRequestParams, type CanvasReviewResolveParams, type CanvasSelectParams, type CanvasState, type CanvasToolName, type CanvasTransitionParams, type ChannelErrorResult, type ChoiceQuestion, type CollectPendingIdsOptions, type DualWidgetContent, type ExecutionRecord, type FormAnswers, type FormOption, type FormQuestion, GUI_WIDGET_MARKER, type GuiComponent, type GuiComponentProps, type GuiComponentType, type GuiContext, type GuiRenderResult, HISTORY_LIMIT, INFLIGHT_REPORT_ACK, JOURNAL_REPORT_ACK, MS_PER_DAY, MS_PER_HOUR, MS_PER_MINUTE, MS_PER_SECOND, type MappedPendingStatus, type MarkerRpcOptions, type MarkerRpcResult, NON_TOOL_ACTIONS, PENDING_REGISTER_ENTRY_TYPE, PENDING_UNREGISTER_ENTRY_TYPE, PLAN_LIFECYCLE_EVENTS, PLAN_LIFECYCLE_STATES, PLAN_REVIEW_MARKER, PLAN_SELF_REVIEW_MAX_BYTES, PLAN_STATE_CUSTOM_TYPE, PROTOCOL_VERSION, type PendingEntriesScan, type PlanDocMeta, type PlanLifecycleEvent, type PlanLifecycleState, type PlanPhase, type PlanReviewComment, type PlanReviewDecision, type PlanReviewRequest, type PlanReviewResponse, type PlanReviewResponseEnvelope, type PlanTransitionResult, type ReplayFoldOptions, type ReviewDimension, type ReviewEntry, type ReviewReport, type ReviewReportStatus, type ReviewResolutionDisposition, type ReviewSeverity, SCHEDULER_MODAL_VIEW_ID, SCHEDULE_CREATE_MARKER, SESSION_MANAGER_ACTIONS, SESSION_MANAGER_MARKER, SUBAGENTS_ENGINES_FILENAME, SUBAGENT_BG_NOTIFY_CUSTOM_TYPE, SUBAGENT_DIRECTIVE_CUSTOM_TYPE, SUBAGENT_INFLIGHT_MARKER, SUBAGENT_JOURNAL_MARKER, type ScheduleDraft, type ScheduleFormResult, type ScheduleKind, type ScheduleQuestion, type ScheduleSpec, type ScheduledTask, type SchedulerEntryLike, type SchedulerEntryOp, type SessionManagerAbortParams, type SessionManagerAbortResult, type SessionManagerAction, type SessionManagerCreateParams, type SessionManagerCreateResult, type SessionManagerErrorResult, type SessionManagerHistoryParams, type SessionManagerHistoryResult, type SessionManagerListParams, type SessionManagerListResult, type SessionManagerParams, type SessionManagerSendParams, type SessionManagerSendResult, type SessionManagerSessionSummary, type SessionManagerStatusParams, type SessionManagerStatusResult, type SessionManagerWatchParams, type SessionManagerWatchReason, type SessionManagerWatchRespondPayload, type StatItem, type SubagentEngineConfigView, type SubagentEngineModelInfo, type SubagentEnginesFile, type SubagentInFlightReport, type SubagentJournalDomain, type SubagentJournalEvent, type SubagentJournalReport, type SupportRating, TASK_ENTRY_TYPE, TOOL_ACTION_MAP, type TaskKind, type TaskSnapshot, type TaskStatus, type TextQuestion, type TreeItem, type TreeItemIcon, UI_FORM_MARKER, type UiFormInteractOptions, type UiFormInteractResult, WORKFLOW_RESULT_CUSTOM_TYPE, type WidgetIconPathsRejection, type WidgetIconPathsValidation, type WidgetMeta, allCanvasActions, allToolActions, appendExecutionRecord, applyPendingDiff, callMarkerRpc, canvasError, collectActivePendingIds, dateToOnceCron, derivePhase, extractGui, firstContentText, formatChannelErrorText, formatDuration, formatRelativeTime, formatSchedule, getAskUserAnswer, getAskUserOther, guiComponent, guiResult, guiSetWidget, isActionAllowed, isArgumentMateriality, isArgumentPolarity, isAskUserQuestion, isCanvasCommentParams, isCanvasCommentRespondParams, isCanvasConvergeCheckParams, isCanvasCreateParams, isCanvasDecideDirectionParams, isCanvasDispatchParams, isCanvasEnterParams, isCanvasExportParams, isCanvasGrowParams, isCanvasListParams, isCanvasMarkerRequest, isCanvasPatchParams, isCanvasReadParams, isCanvasReviewAppendParams, isCanvasReviewRequestParams, isCanvasReviewResolveParams, isCanvasSelectParams, isCanvasTransitionParams, isChannelErrorResult, isFormAnswers, isFormQuestion, isGuiCapable, isGuiComponent, isGuiRenderResult, isInFlightReportAck, isJournalReportAck, isPlanReviewRequest, isPlanReviewResponse, isScheduleDraft, isScheduleFormResult, isSessionManagerAbortParams, isSessionManagerCreateParams, isSessionManagerHistoryParams, isSessionManagerListParams, isSessionManagerNotifyId, isSessionManagerSendParams, isSessionManagerStatusParams, isSessionManagerWatchParams, isSessionManagerWatchRespondPayload, isSubagentInFlightReport, isSubagentJournalReport, mapReasonToStatus, onceCronToDate, parsePlanReviewResponse, readLifecycleState, readResumeHint, replayFoldEntries, scanPendingEntries, setWidgetDual, snapshotToTask, toolOfAction, transition, truncateSelfReview, uiFormInteract, validateWidgetIconPaths };
2441
+ export { ACTION_EVENT_MAP, ASK_USER_MARKER, type ArgumentMateriality, type ArgumentPolarity, type AskUserAnswers, type AskUserOption, type AskUserQuestion, CANVAS_ACTIONS, CANVAS_ACTOR_MATRIX, CANVAS_ERROR_CODES, CANVAS_ERROR_RECOVERY, CANVAS_EVENT_TYPES, CANVAS_MARKER, CANVAS_MARKER_ACTIONS, CANVAS_TOOL_NAMES, type CanvasAction, type CanvasActionParams, type CanvasActor, type CanvasComment, type CanvasCommentParams, type CanvasCommentRespondParams, type CanvasConvergeCheckParams, type CanvasCreateParams, type CanvasDecideDirectionParams, type CanvasDirectionDecision, type CanvasDispatchParams, type CanvasEdge, type CanvasEdgeType, type CanvasEnterParams, type CanvasError, type CanvasErrorCode, type CanvasEventType, type CanvasExportParams, type CanvasExportTarget, type CanvasGrowItem, type CanvasGrowParams, type CanvasListEntry, type CanvasListParams, type CanvasListReply, type CanvasMarkerAction, type CanvasMarkerParams, type CanvasMarkerRequest, type CanvasMutateReply, type CanvasMutateRequest, type CanvasNode, type CanvasNodeLifecycle, type CanvasNodeType, type CanvasPatchParams, type CanvasReadParams, type CanvasReadReply, type CanvasReviewAppendParams, type CanvasReviewEntryInput, type CanvasReviewRequestParams, type CanvasReviewResolveParams, type CanvasSelectParams, type CanvasState, type CanvasToolName, type CanvasTransitionParams, type ChannelErrorResult, type ChoiceQuestion, type CollectPendingIdsOptions, type DualWidgetContent, type ExecutionRecord, type FormAnswers, type FormOption, type FormQuestion, GUI_WIDGET_MARKER, type GuiComponent, type GuiComponentProps, type GuiComponentType, type GuiContext, type GuiRenderResult, HISTORY_LIMIT, INFLIGHT_REPORT_ACK, JOURNAL_REPORT_ACK, MAPPED_PENDING_STATUSES, MS_PER_DAY, MS_PER_HOUR, MS_PER_MINUTE, MS_PER_SECOND, type MappedPendingStatus, type MarkerRpcOptions, type MarkerRpcResult, NON_TOOL_ACTIONS, PENDING_REGISTER_ENTRY_TYPE, PENDING_UNREGISTER_ENTRY_TYPE, PLAN_LIFECYCLE_EVENTS, PLAN_LIFECYCLE_STATES, PLAN_REVIEW_MARKER, PLAN_SELF_REVIEW_MAX_BYTES, PLAN_STATE_CUSTOM_TYPE, PROTOCOL_VERSION, type PendingEntriesScan, type PendingFieldsScan, type PlanDocMeta, type PlanLifecycleEvent, type PlanLifecycleState, type PlanPhase, type PlanReviewComment, type PlanReviewDecision, type PlanReviewRequest, type PlanReviewResponse, type PlanReviewResponseEnvelope, type PlanTransitionResult, type ReplayFoldOptions, type ReviewDimension, type ReviewEntry, type ReviewReport, type ReviewReportStatus, type ReviewResolutionDisposition, type ReviewSeverity, SCHEDULER_MODAL_VIEW_ID, SCHEDULE_CREATE_MARKER, SESSION_MANAGER_ACTIONS, SESSION_MANAGER_MARKER, SUBAGENTS_ENGINES_FILENAME, SUBAGENT_BG_NOTIFY_CUSTOM_TYPE, SUBAGENT_DIRECTIVE_CUSTOM_TYPE, SUBAGENT_INFLIGHT_MARKER, SUBAGENT_JOURNAL_MARKER, type ScheduleDraft, type ScheduleFormResult, type ScheduleKind, type ScheduleQuestion, type ScheduleSpec, type ScheduledTask, type SchedulerEntryLike, type SchedulerEntryOp, type SessionManagerAbortParams, type SessionManagerAbortResult, type SessionManagerAction, type SessionManagerCreateParams, type SessionManagerCreateResult, type SessionManagerErrorResult, type SessionManagerHistoryParams, type SessionManagerHistoryResult, type SessionManagerListParams, type SessionManagerListResult, type SessionManagerParams, type SessionManagerSendParams, type SessionManagerSendResult, type SessionManagerSessionSummary, type SessionManagerStatusParams, type SessionManagerStatusResult, type SessionManagerWatchParams, type SessionManagerWatchReason, type SessionManagerWatchRespondPayload, type StatItem, type SubagentEngineConfigView, type SubagentEngineModelInfo, type SubagentEnginesFile, type SubagentInFlightReport, type SubagentJournalDomain, type SubagentJournalEvent, type SubagentJournalReport, type SupportRating, TASK_ENTRY_TYPE, TOOL_ACTION_MAP, type TaskKind, type TaskSnapshot, type TaskStatus, type TextQuestion, type TreeItem, type TreeItemIcon, UI_FORM_MARKER, type UiFormInteractOptions, type UiFormInteractResult, WORKFLOW_RESULT_CUSTOM_TYPE, type WidgetIconPathsRejection, type WidgetIconPathsValidation, type WidgetMeta, allCanvasActions, allToolActions, appendExecutionRecord, applyPendingDiff, callMarkerRpc, canvasError, collectActivePendingIds, dateToOnceCron, derivePhase, extractGui, firstContentText, formatChannelErrorText, formatDuration, formatRelativeTime, formatSchedule, getAskUserAnswer, getAskUserOther, guiComponent, guiResult, guiSetWidget, isActionAllowed, isArgumentMateriality, isArgumentPolarity, isAskUserQuestion, isCanvasCommentParams, isCanvasCommentRespondParams, isCanvasConvergeCheckParams, isCanvasCreateParams, isCanvasDecideDirectionParams, isCanvasDispatchParams, isCanvasEnterParams, isCanvasExportParams, isCanvasGrowParams, isCanvasListParams, isCanvasMarkerRequest, isCanvasPatchParams, isCanvasReadParams, isCanvasReviewAppendParams, isCanvasReviewRequestParams, isCanvasReviewResolveParams, isCanvasSelectParams, isCanvasTransitionParams, isChannelErrorResult, isFormAnswers, isFormQuestion, isGuiCapable, isGuiComponent, isGuiRenderResult, isInFlightReportAck, isJournalReportAck, isPlanReviewRequest, isPlanReviewResponse, isScheduleDraft, isScheduleFormResult, isSessionManagerAbortParams, isSessionManagerCreateParams, isSessionManagerHistoryParams, isSessionManagerListParams, isSessionManagerNotifyId, isSessionManagerSendParams, isSessionManagerStatusParams, isSessionManagerWatchParams, isSessionManagerWatchRespondPayload, isSubagentInFlightReport, isSubagentJournalReport, mapReasonToStatus, onceCronToDate, parsePlanReviewResponse, readLifecycleState, readResumeHint, replayFoldEntries, scanPendingEntries, scanPendingFields, setWidgetDual, snapshotToTask, toolOfAction, transition, truncateSelfReview, uiFormInteract, validateWidgetIconPaths };
package/dist/index.js CHANGED
@@ -1009,6 +1009,7 @@ var CANVAS_ERROR_CODES = [
1009
1009
  "invalid_params",
1010
1010
  "unknown_action",
1011
1011
  "actor_not_allowed",
1012
+ "forbidden",
1012
1013
  "selection_conflict",
1013
1014
  "cycle_detected",
1014
1015
  "unverified_fact",
@@ -1027,6 +1028,7 @@ var CANVAS_ERROR_RECOVERY = {
1027
1028
  invalid_params: "\u8BF7\u6C42\u53C2\u6570\u5F62\u72B6\u975E\u6CD5\uFF1A\u5BF9\u7167\u8BE5 action \u7684 params \u5951\u7EA6\u4FEE\u6B63\u5B57\u6BB5\u540E\u91CD\u8BD5",
1028
1029
  unknown_action: "action \u4E0D\u5728\u8BCD\u8868\uFF1A\u5BF9\u7167 CANVAS_ACTIONS \u8BCD\u8868\u4FEE\u6B63 action \u540D",
1029
1030
  actor_not_allowed: "\u5F53\u524D\u64CD\u4F5C\u65B9\u65E0\u6B64\u52A8\u4F5C\u6743\u9650\uFF1A\u67E5\u6743\u9650\u77E9\u9635\uFF08\u8BE5\u52A8\u4F5C\u4EC5\u9650\u7279\u5B9A\u64CD\u4F5C\u65B9\uFF09\uFF0C\u6539\u7531\u6709\u6743\u65B9\u6267\u884C",
1031
+ forbidden: "\u753B\u5E03\u4E0D\u5C5E\u4E8E\u5F53\u524D\u4F1A\u8BDD\uFF08\u753B\u5E03\u5F52\u5C5E\u521B\u5EFA\u5B83\u7684\u4F1A\u8BDD\uFF0C\u8DE8\u4F1A\u8BDD\u8BBF\u95EE\u88AB\u62D2\u7EDD\uFF09\uFF1A\u8BF7\u8BA9\u7528\u6237\u5207\u6362\u5230\u753B\u5E03\u5F52\u5C5E\u4F1A\u8BDD\u540E\u91CD\u8BD5\uFF0C\u6216\u7ECF canvas_list \u67E5\u770B\u5F53\u524D\u4F1A\u8BDD\u53EF\u7528\u7684\u753B\u5E03",
1030
1032
  selection_conflict: "\u8BE5\u95EE\u9898\u5DF2\u6709\u9009\u5B9A\u65B9\u6848\uFF1A\u6362\u9009\u8D70 select \u7684 replace \u53C2\u6570\uFF08\u540C\u4E00\u8C03\u7528\u5185\u8FC1\u79FB\u65E7\u9009\u5B9A\uFF09\u5E76\u9644\u5BF9\u6BD4\u7406\u7531",
1031
1033
  cycle_detected: "\u8BE5\u8FB9\u4F1A\u4F7F\u4E3B\u5E72\u6210\u73AF\uFF1A\u5206\u89E3/\u89E3\u8FB9\u53EA\u80FD\u6307\u5411\u4E0A\u5C42\u8282\u70B9\u7684\u4E0B\u5C42\uFF0C\u53BB\u6389\u56DE\u8FB9\u540E\u91CD\u8BD5",
1032
1034
  unverified_fact: "\u672A\u6838\u5B9E\u7684 fact \u8BBA\u636E\u4E0D\u5F97\u4F5C\u4E3A\u901A\u8FC7\u4F9D\u636E\uFF1A\u5148\u8865\u6838\u5B9E\u72B6\u6001\uFF08factVerified\uFF09\u518D\u91CD\u8BD5",
@@ -1102,19 +1104,39 @@ function allCanvasActions() {
1102
1104
  var PENDING_REGISTER_ENTRY_TYPE = "pending:register";
1103
1105
  var PENDING_UNREGISTER_ENTRY_TYPE = "pending:unregister";
1104
1106
  function scanPendingEntries(entries) {
1105
- const scan = { registerEntries: [], unregisteredIds: /* @__PURE__ */ new Set() };
1107
+ const scan = {
1108
+ registerEntries: [],
1109
+ unregisteredIds: /* @__PURE__ */ new Set(),
1110
+ registerTypes: /* @__PURE__ */ new Map(),
1111
+ unregisterStatuses: /* @__PURE__ */ new Map()
1112
+ };
1113
+ const seenRegisterIds = /* @__PURE__ */ new Set();
1106
1114
  for (const raw of entries) {
1107
1115
  if (!raw || typeof raw !== "object") continue;
1108
1116
  const entry = raw;
1117
+ const data = entry.data ?? {};
1109
1118
  if (entry.customType === PENDING_REGISTER_ENTRY_TYPE) {
1110
- scan.registerEntries.push({ data: entry.data ?? {} });
1119
+ scan.registerEntries.push({ data });
1120
+ if (typeof data.id === "string" && data.id !== "" && !seenRegisterIds.has(data.id)) {
1121
+ seenRegisterIds.add(data.id);
1122
+ if (typeof data.type === "string") scan.registerTypes.set(data.id, data.type);
1123
+ }
1111
1124
  } else if (entry.customType === PENDING_UNREGISTER_ENTRY_TYPE) {
1112
- const data = entry.data ?? {};
1113
- if (typeof data.id === "string") scan.unregisteredIds.add(data.id);
1125
+ if (typeof data.id === "string") {
1126
+ scan.unregisteredIds.add(data.id);
1127
+ const status = data.status;
1128
+ if (data.id !== "" && typeof status === "string" && MAPPED_PENDING_STATUSES.has(status)) {
1129
+ scan.unregisterStatuses.set(data.id, status);
1130
+ }
1131
+ }
1114
1132
  }
1115
1133
  }
1116
1134
  return scan;
1117
1135
  }
1136
+ function scanPendingFields(entries) {
1137
+ const { registerTypes, unregisterStatuses } = scanPendingEntries(entries);
1138
+ return { registerTypes, unregisterStatuses };
1139
+ }
1118
1140
  function applyPendingDiff(scan) {
1119
1141
  const active = [];
1120
1142
  const seen = /* @__PURE__ */ new Set();
@@ -1157,6 +1179,7 @@ var REASON_STATUS_MAP = {
1157
1179
  function mapReasonToStatus(reason) {
1158
1180
  return REASON_STATUS_MAP[reason] ?? "completed";
1159
1181
  }
1182
+ var MAPPED_PENDING_STATUSES = new Set(Object.values(REASON_STATUS_MAP));
1160
1183
  export {
1161
1184
  ACTION_EVENT_MAP,
1162
1185
  ASK_USER_MARKER,
@@ -1176,6 +1199,7 @@ export {
1176
1199
  HISTORY_LIMIT,
1177
1200
  INFLIGHT_REPORT_ACK,
1178
1201
  JOURNAL_REPORT_ACK,
1202
+ MAPPED_PENDING_STATUSES,
1179
1203
  MAX_TERMINAL_REGISTRY_ENTRIES,
1180
1204
  MS_PER_DAY,
1181
1205
  MS_PER_HOUR,
@@ -1278,6 +1302,7 @@ export {
1278
1302
  readResumeHint,
1279
1303
  replayFoldEntries,
1280
1304
  scanPendingEntries,
1305
+ scanPendingFields,
1281
1306
  setWidgetDual,
1282
1307
  snapshotToTask,
1283
1308
  toolOfAction,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhushanwen/extension-protocol",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Cross-layer pi extension contract package: dual-mode (TUI/GUI) rendering helpers, session/background-task/pending-entries protocols, and shared behavior primitives",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",