@zhushanwen/extension-protocol 0.21.0 → 0.23.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 实现)。 */
@@ -404,8 +404,9 @@ declare function firstContentText(result: {
404
404
  * {action,params} / 快照帧,不引入内部 stringify 异常面);
405
405
  * - mode 门控留调用方(inflight 在 attachSession 处 / session-manager 无门控——
406
406
  * 四态 reason 无 non-rpc 语义);
407
- * - `ui.select` 缺席(非 GUI ctx)由调用方前置判定(沿 ask-user askUserInteract 的
408
- * `isGuiCapable(ctx) && ctx.ui?.select` 先例);误用即 throw 明确错误。
407
+ * - `ui.select` 缺席(非 GUI ctx)由调用方前置判定(沿已退役的 ask-user askUserInteract
408
+ * 先例——`isGuiCapable(ctx) && ctx.ui?.select`,git 历史可溯;isGuiCapable 现存于本包
409
+ * core/helpers 并经包入口导出);误用即 throw 明确错误。
409
410
  *
410
411
  * 设计权威源:docs/architecture/ext-simplify-17-shared-extraction.md §3.3 D8(v7 冻结形态)。
411
412
  */
@@ -429,15 +430,24 @@ interface MarkerRpcOptions {
429
430
  }
430
431
  /** 错误回包底层形状:select+marker 通道各协议(session-manager)
431
432
  * runtime 侧异常折叠的共用单源(不裸 reject,error 闭环走同一回包通道)。
432
- * SessionManagerErrorResult 是本形状的 alias(D8 单源化)。 */
433
+ * SessionManagerErrorResult 是本形状的 alias(D8 单源化)。
434
+ *
435
+ * `code`(session-manager-archive-delete U2,additive optional):结构化错误码
436
+ * 透传通道(如 ArchiveError 的 `archive_generating`)——旧 runtime 不产出、旧
437
+ * extension 不消费,只加字段不破坏现有消费方。 */
433
438
  interface ChannelErrorResult {
434
439
  error: string;
435
440
  hint?: string;
441
+ code?: string;
436
442
  }
437
- /** 运行时形状守卫:{error: string}(hint 可选,不校验其类型;排数组) */
443
+ /** 运行时形状检查:{error: string}(hint 可选,不校验其类型;code additive 宽容
444
+ * ——缺席放行(旧 runtime 兼容象限)、present 须为 string;排数组) */
438
445
  declare function isChannelErrorResult(v: unknown): v is ChannelErrorResult;
439
- /** error + hint 文本拼接(hint 缺席只回 error)——plugin-bridge errorResult 与
440
- * session-manager 错误闭环文本的共用单源 */
446
+ /** error + code + hint 文本拼接(code/hint 缺席各自省略对应行)——plugin-bridge
447
+ * errorResult 与 session-manager 错误闭环文本的共用单源。code present 时以
448
+ * `error_code: <code>` 行拼入(session-manager-archive-delete 决策 5:结构化错误码
449
+ * 对模型可见——工具 description 教 agent 认的码词在 throw 文本里在场,善后层恢复
450
+ * 指引的第一跳不断链);code 缺席(旧 runtime 回包 / canvas 等无码消费方)行为不变 */
441
451
  declare function formatChannelErrorText(err: ChannelErrorResult): string;
442
452
  /**
443
453
  * 经 select 通道发起一次 marker RPC。
@@ -537,7 +547,7 @@ declare function getAskUserAnswer(answers: AskUserAnswers, question: AskUserQues
537
547
  /** 从 answers 中提取 Other 自由文本 */
538
548
  declare function getAskUserOther(answers: AskUserAnswers, question: AskUserQuestion): string | undefined;
539
549
  /**
540
- * 类型守卫:验证 unknown 是否为合法的 AskUserQuestion。
550
+ * 类型检查:验证 unknown 是否为合法的 AskUserQuestion。
541
551
  * 供 legacy 帧消费方(runtime marker 分支侧形状参照 / 扩展自测)收窄 unknown[] 用。
542
552
  */
543
553
  declare function isAskUserQuestion(value: unknown): value is AskUserQuestion;
@@ -797,8 +807,8 @@ declare const SCHEDULE_CREATE_MARKER = "\0TAIJI_SCHEDULE_CREATE";
797
807
  * 交互入口在 extensions/universal/scheduler/src/tool.ts。
798
808
  *
799
809
  * 本模块保留三类跨端共享资产:
800
- * - isScheduleDraft / isScheduleFormResult 形状守卫:前者供 runtime event-adapter
801
- * legacy 分支(SCHEDULE_CREATE_MARKER 帧 payload 判定)与 ui-form 守卫的
810
+ * - isScheduleDraft / isScheduleFormResult 形状检查:前者供 runtime event-adapter
811
+ * legacy 分支(SCHEDULE_CREATE_MARKER 帧 payload 判定)与 ui-form 检查的
802
812
  * schedule 分支(initial 深度校验)消费;后者供 scheduler 包回包判别
803
813
  * (uiFormInteract answers[key] 解包后收窄为 ScheduleFormResult)。
804
814
  * - dateToOnceCron / onceCronToDate 时间折叠单点(D2):GUI(ScheduleForm 渲染器)
@@ -810,13 +820,13 @@ declare const SCHEDULE_CREATE_MARKER = "\0TAIJI_SCHEDULE_CREATE";
810
820
  */
811
821
 
812
822
  /**
813
- * 类型守卫:验证 unknown 是否为合法的 ScheduleDraft。
823
+ * 类型检查:验证 unknown 是否为合法的 ScheduleDraft。
814
824
  * 用于 runtime event-adapter 判定 marker select 的 payload 是否为本协议 draft
815
825
  * (检测失败降级普通 select),以及前端从 runtime 透传值中安全收窄。
816
826
  * 字段白名单校验(与 isAskUserQuestion 同构):可选字段校验类型,未知附加字段忽略。
817
827
  */
818
828
  declare function isScheduleDraft(value: unknown): value is ScheduleDraft;
819
- /** 回传形状守卫(导出消费:scheduler 包对 uiFormInteract answers[key] 解包值收窄;
829
+ /** 回传形状检查(导出消费:scheduler 包对 uiFormInteract answers[key] 解包值收窄;
820
830
  * FormOverlay schedule 渲染器提交的 value = JSON.stringify(ScheduleFormResult)) */
821
831
  declare function isScheduleFormResult(value: unknown): value is ScheduleFormResult;
822
832
  /**
@@ -829,14 +839,20 @@ declare function dateToOnceCron(date: Date): string;
829
839
  declare function onceCronToDate(cron: string, now?: Date): Date | null;
830
840
 
831
841
  /**
832
- * plan 模式生命周期状态机(plan 模式状态机显式化 D1)——纯数据 + 纯函数,零依赖。
842
+ * plan 模式生命周期状态机(plan 模式状态机显式化 D1)——8 值状态集 + 9 事件
843
+ * 边表的单一状态契约。表与判定迁移 @zhushanwen/state-machine 基建承载(M4):
844
+ * 矩阵改行式声明 + errorPolicy:'result'(表外 `{ ok: false }` 不炸 turn)+ 原型链
845
+ * 白名单口径统一到机器 coerceState(域内枚举 includes 白名单先例被基建吸收,
846
+ * V10);对外 `transition` / `derivePhase` 签名与返回形态保形(消费方零改动,
847
+ * 消费方清单 = consumers.md)。
833
848
  *
834
849
  * plan 模式的状态散落在 pi 扩展 entry / runtime 挂起注册表 / renderer 派生公式三处时,
835
850
  * 任意两者漂移即产「僵尸/谎言」UI(F1-F5)。本模块是全链路共享的单一状态契约:
836
- * 8 值状态集 + 9 事件边表 + `transition` 纯函数(守卫集中一处)+ `derivePhase` 呈现映射。
851
+ * 8 值状态集 + 9 事件边表 + `transition` 纯函数(检查集中一处)+ `derivePhase` 呈现映射。
837
852
  *
838
853
  * 语义要点(设计 D1 逐条锚定):
839
- * - 非法转移返回 `{ ok: false }`,由调用方降级(**不 throw 炸 turn**);副作用不进返回值
854
+ * - 非法转移返回 `{ ok: false }`(机器 errorPolicy:'result' 的表外分支转译——不携带
855
+ * next 键、不 throw),由调用方降级(**不 throw 炸 turn**);副作用不进返回值
840
856
  * (effects-as-data 无已登记消费方属投机间接层),各 action 在转移成功后内联执行自身副作用。
841
857
  * - `reviewing --dismiss--> planning`:用户「搁置」(协议级 dismiss 决策,D3)——落盘即
842
858
  * planning,被搁置的审批不复活(F1/F2/F3 构造性消除)。
@@ -850,17 +866,17 @@ declare function onceCronToDate(cron: string, now?: Date): Date | null;
850
866
  * - `approved --approve--> dispatching`:批准后 agent 再调 `complete` 重新选择执行方式
851
867
  * (D1「approved 上 agent 再调 complete → dispatching」)。事件命名裁决:9 事件表无
852
868
  * `complete` 员,本边取「执行确认」语义族最近员 `approve`(用户点确认执行与批准后重选
853
- * 执行方式同为「确认执行、进入执行方式选择」的决策事件)——消费面接线见 consumers.md。
869
+ * 执行方式同为「确认执行、进入执行方式选择」的决策事件)——消费方接线见 consumers.md。
854
870
  * - `approved` 其余转移仅 `exit`;活跃族非终态 `--exit--> exited`;idle 从未进入,
855
871
  * exit 非法(防从未进 plan 的会话落噪音 exited entry);终态 `--enter--> planning`
856
872
  * (新一轮);`revising` 保留独立态(E3 恢复文案分叉依赖,前提 P-7)。
857
873
  * - `reviewing --submit--> reviewing`:审批重挂自环(E3 会话重启恢复 / D8「重新提交审批」
858
874
  * 按钮——重提交不推进生命周期,落盘回 reviewing 重挂即等价于旧调用方特判放行形态)。
859
875
  *
860
- * 呈现映射(derivePhase):用户视角四主态 + idle 缺省——四主态是呈现,不是存储
861
- * (用户口述模型 = 呈现层,reviewing/dispatching 两个挂起态是崩溃恢复的真实分叉点,
862
- * 存储层保留 8 值)。终态两值(completed = 批准并派发执行 / exited = 主动退出)共享
863
- * 全部终态规则,呈现层同映 'terminal'(诊断/审计语义保留存储区分)。
876
+ * 发布位次登记(D7③):本包(@zhushanwen/extension-protocol)自 M4 起依赖
877
+ * @zhushanwen/state-machine(workspace 协议),npm 发布顺序必须基建包在先——
878
+ * 位次断链时 npm 消费者会装到缺依赖的 extension-protocol(changeset 依赖图
879
+ * 自然保证,发布 PR 人工核对本条)。
864
880
  */
865
881
  type PlanLifecycleState = 'idle' | 'planning' | 'reviewing' | 'revising' | 'approved' | 'dispatching' | 'completed' | 'exited';
866
882
  /** 状态穷举表(运行时消费:E3 恢复查表 / 测试穷举基座)——顺序 = 生命周期自然序。 */
@@ -875,19 +891,20 @@ type PlanTransitionResult = {
875
891
  ok: false;
876
892
  };
877
893
  /**
878
- * 纯函数转移:`(state, event) → { ok: true, next } | { ok: false }`。
894
+ * 纯函数转移:`(state, event) → { ok: true, next } | { ok: false }`——机器
895
+ * errorPolicy:'result' 判定的保形包装(签名与返回形态不变,消费方零改动)。
879
896
  *
880
897
  * 非法转移(含运行时垃圾 state/event 值——跨版本帧、坏反序列化)返回 `{ ok: false }`
881
898
  * 且**不携带 next 键**,由调用方降级(不 throw 炸 turn)。调用方义务:`ok:false` 时
882
- * 不落盘、不执行副作用(终态上 `ok:false` 不落盘即 D3 归口点的兜底保险)。
899
+ * 不落盘、不执行副作用(终态上 `ok:false` 不落盘即 D3 归属划分点的兜底保险)。
883
900
  *
884
- * 入口白名单守卫(与 derivePhase 同一机制):普通对象字面量查表会沿原型链命中继承键——
885
- * `transition('reviewing', '__proto__')` 取出 Object.prototype、`('__proto__', 'valueOf')`
886
- * 取出函数,均被误判为合法 next(违背本契约)。故垃圾键必须先挡在查表前。
887
- * **选「枚举 includes 白名单」而非 null-prototype 表 / Object.hasOwn**:① transition 与
888
- * derivePhase 共用同一守卫形态(单一机制,不并存两种写法);② PLAN_LIFECYCLE_STATES /
889
- * PLAN_LIFECYCLE_EVENTS 就是值域 SSOT(测试穷举同源),includes 判定与之同源,
890
- * 原型键天然不在白名单内。
901
+ * 垃圾输入的分层判定(原型链白名单口径已统一到基建 coerceState 的同族机制):
902
+ * 词表外 state 由机器词表集合拒绝(Set 查询不走原型链);词表外 event 字符串由
903
+ * 机器 (from, on) 行索引拒绝(Map 复合键查询不走原型链);非字符串 event 由基建
904
+ * 归一 undefined 落入表外拒绝(§5.2 失败路径表第 3 行,不 crash),下方前置守卫
905
+ * 是域内显式等价拒绝(同结果先行返回,「不炸 turn」契约双保险)。plan 表无
906
+ * to:null 消亡行(基建 null 语义 = 实体离开机器,plan 8 态全在机器内),state 为
907
+ * null 的分支运行时不可达,收窄仅为类型完备。
891
908
  */
892
909
  declare function transition(state: PlanLifecycleState, event: PlanLifecycleEvent): PlanTransitionResult;
893
910
  /**
@@ -904,21 +921,22 @@ type PlanPhase = 'idle' | 'planning' | 'reviewing' | 'approved' | 'terminal';
904
921
  * 8 存储态 → 5 呈现相位的单点映射(renderer 阶段指示/状态带共用,禁止消费方各自 if 拼)。
905
922
  * 运行时垃圾 state(混装格坏帧)降级 'idle'(无 plan 缺省,fail-safe 不误示进行中)。
906
923
  *
907
- * 入口白名单守卫(理由同 transition,见彼处):裸查表对继承键 'constructor' / 'toString'
908
- * 会取出 Object 构造函数等并经 `?? 'idle'` 流出(非 nullish 不落兜底)——垃圾 state
909
- * 必须精确落 'idle',函数/对象不得作为相位流入 renderer。
924
+ * 入口白名单检查 = 机器 coerceState(原型链白名单口径统一到基建,V10):裸查表对
925
+ * 继承键 'constructor' / 'toString' 会取出 Object 构造函数等并经 `?? 'idle'` 流出
926
+ * (非 nullish 不落兜底)——垃圾 state 必须精确落 'idle',函数/对象不得作为相位
927
+ * 流入 renderer。
910
928
  */
911
929
  declare function derivePhase(state: PlanLifecycleState): PlanPhase;
912
930
 
913
931
  /**
914
- * plan 审阅回传值域契约(plan 模式状态机显式化 D3①⑤ / D9③)——纯函数守卫,零依赖。
932
+ * plan 审阅回传值域契约(plan 模式状态机显式化 D3①⑤ / D9③)——纯函数检查,零依赖。
915
933
  *
916
- * 为什么守卫是契约级承重:TS 判别联合的穷尽性(switch/never 断言)管不到运行时值域——
917
- * respond 通道透传的是任意字符串 parse 出的 unknown(P-2),值域守卫漏改即「搁置应答被判
918
- * 垃圾 → bad-response 引导重挂」再入循环(F1 复活路径)。canonical 守卫与判别联合同住
919
- * 契约包,消费面(extensions/universal/plan tool.ts)接线见同目录 consumers.md。
934
+ * 为什么检查是契约级承重:TS 判别联合的穷尽性(switch/never 断言)管不到运行时值域——
935
+ * respond 通道透传的是任意字符串 parse 出的 unknown(P-2),值域检查漏改即「搁置应答被判
936
+ * 垃圾 → bad-response 引导重挂」再入循环(F1 复活路径)。canonical 检查与判别联合同住
937
+ * 契约包,消费方(extensions/universal/plan tool.ts)接线见同目录 consumers.md。
920
938
  *
921
- * 降级双分源(D3①)——parse 失败必须区分两类(envelope 判别保留),消费面出口同款:
939
+ * 降级双分源(D3①)——parse 失败必须区分两类(envelope 判别保留),消费方出口同款:
922
940
  * - `unknown-decision`(对象合法但 decision 不在值域):版本错配信号(R2),消费方
923
941
  * 额外 logger.warn 留痕;出口与文案与 malformed 同款——bad-response 报错提示重挂。
924
942
  * 裁决与重审触发(候选替代 = 恢复独立 version-mismatch 不重挂出口)登记于消费方
@@ -928,7 +946,7 @@ declare function derivePhase(state: PlanLifecycleState): PlanPhase;
928
946
  *
929
947
  * selfReview 有界字段(D9③ / R3):有界性由**写侧单点截断**保证(截断点 = 扩展 payload
930
948
  * 构造处),4KB 上限与 UTF-8 字节界安全截断的唯一权威在本模块;透传层(runtime)不截、
931
- * 入站守卫不二次截(上限已在写侧达成)。
949
+ * 入站检查不二次截(上限已在写侧达成)。
932
950
  */
933
951
 
934
952
  /** selfReview 上限:4KB(UTF-8 字节)。超限即截(全文可要求 agent 贴对话流,R3)。 */
@@ -939,7 +957,7 @@ declare const PLAN_SELF_REVIEW_MAX_BYTES = 4096;
939
957
  */
940
958
  declare function truncateSelfReview(text: string): string;
941
959
  /**
942
- * `PlanReviewRequest` 形状守卫(E5 垃圾数据判据):
960
+ * `PlanReviewRequest` 形状检查(E5 垃圾数据判据):
943
961
  * docs 必为 `PlanDocMeta[]`(逐项形状);selfReview 缺省或 string——**optional 是兼容契约**
944
962
  * (旧扩展不携带 → 自审行不渲染的降级形态,D9③),值域上限不在此拒绝(写侧截断已界)。
945
963
  * 空载荷(undefined/null/非对象/缺 docs)与非法形态(docs 非数组 / 元素形状不合法 /
@@ -966,19 +984,19 @@ type PlanReviewResponseEnvelope = {
966
984
  code: 'malformed';
967
985
  };
968
986
  /**
969
- * respond 回传解析(值域守卫的判别版):dismiss 样本必通(D3 主干),未知 decision 值域
970
- * 落降级枚举而非垃圾(两类降级可判别分离;消费面出口同款引导重挂,见文件头「降级双分源」)。
987
+ * respond 回传解析(值域检查的判别版):dismiss 样本必通(D3 主干),未知 decision 值域
988
+ * 落降级枚举而非垃圾(两类降级可判别分离;消费方出口同款引导重挂,见文件头「降级双分源」)。
971
989
  */
972
990
  declare function parsePlanReviewResponse(value: unknown): PlanReviewResponseEnvelope;
973
991
  /**
974
- * `PlanReviewResponse` 值域守卫(含 dismiss 员,D3①)——`parsePlanReviewResponse` 的谓词形。
992
+ * `PlanReviewResponse` 值域检查(含 dismiss 员,D3①)——`parsePlanReviewResponse` 的谓词形。
975
993
  * 消费方需要区分 unknown-decision / malformed 两类降级时用 parse 版。
976
994
  */
977
995
  declare function isPlanReviewResponse(value: unknown): value is PlanReviewResponse;
978
996
 
979
997
  /**
980
998
  * plan-state entry 的 customType(pi appendEntry custom entry 判别键)。磁盘形态冻结:
981
- * 扩展写读两侧(persistPlanState / isPlanStateEntry)与 runtime 投影链(plan-state-extractor /
999
+ * 扩展写读两侧(persistPlanState / isPlanStateEntry)与 runtime 派生视图链(plan-state-extractor /
982
1000
  * session-records)均消费本常量,值同源——改值即历史会话全部失联,禁改(冻结锚测试见
983
1001
  * 本目录 legacy-entries.test.ts)。
984
1002
  */
@@ -986,8 +1004,8 @@ declare const PLAN_STATE_CUSTOM_TYPE = "plan-state";
986
1004
  /**
987
1005
  * 生命周期状态读取(D2 读方①②共用映射,原扩展 state.ts / runtime extractor 内联拷贝的
988
1006
  * 单源归并):
989
- * ① 新字段直读(值域守卫:PLAN_LIFECYCLE_STATES 之外的垃圾值按缺失处理,落映射——
990
- * 不信任外部写入);
1007
+ * ① 新字段直读(值域检查 = 机器 coerceState 归化,词表外/原型链键垃圾值按缺失处理,
1008
+ * 落映射——不信任外部写入;M4 白名单口径统一);
991
1009
  * ② 旧 entry 无 state(或垃圾 state)时映射 reviewState(awaiting→reviewing /
992
1010
  * revising→revising / 其余值→planning|idle 按 isActive)。
993
1011
  */
@@ -1008,7 +1026,7 @@ declare function readResumeHint(data: {
1008
1026
  /**
1009
1027
  * 统一提问表单协议(ui-form)的类型定义。
1010
1028
  *
1011
- * 把 plan / scheduler / ask-user 三个 extension 的提问交互收口为一个表单协议:
1029
+ * 把 plan / scheduler / ask-user 三个 extension 的提问交互收敛为一个表单协议:
1012
1030
  * 问题即数据(类型化问题集),GUI 链路统一(wire 协议 + 渲染器)——多问 = 多 tab,
1013
1031
  * 单问 = 单视图。extension 侧经 uiFormInteract() 序列化进 select 的 options[0],
1014
1032
  * runtime event-adapter 检测 UI_FORM_MARKER 广播 form 帧,前端 FormOverlay
@@ -1131,7 +1149,7 @@ interface UiFormInteractOptions {
1131
1149
  * (undefined 为缺省态:存量扩展与未声明者,桥接 = 现状,方向安全);
1132
1150
  * `false` = 无 turn 预期——命令 handler 内 select(提交后结构性无 turn),respond 侧
1133
1151
  * 提交即收尾,消除 30s 假忙。消费方判定必须是 `=== false` 显式式:truthy 简化
1134
- * (`!expectTurn`)会把 undefined 也当无 turn、误清桥接(D2 被否谱系)。
1152
+ * (`!expectTurn`)会把 undefined 也当无 turn、误清桥接(D2 不采用其余方案的理由)。
1135
1153
  *
1136
1154
  * 缺省(undefined)经 stripUndefined 剥键——未声明者的 wire payload 逐字节不变,
1137
1155
  * 旧 runtime 读不到即忽略(JSON.parse 容忍未知键)。
@@ -1152,14 +1170,14 @@ interface UiFormInteractOptions {
1152
1170
  declare function uiFormInteract(ctx: GuiContext, form: FormQuestion[], opts?: UiFormInteractOptions): Promise<UiFormInteractResult>;
1153
1171
 
1154
1172
  /**
1155
- * 统一提问表单(ui-form)的形状守卫。
1173
+ * 统一提问表单(ui-form)的形状检查。
1156
1174
  *
1157
1175
  * isFormQuestion 按 type 判别分支逐项校验(白名单风格:必填字段类型校验、可选
1158
1176
  * 字段校验、未知字段忽略——与 isAskUserQuestion / isScheduleDraft 同构语义)。
1159
1177
  * 三个消费点失败策略各异(设计 D2):
1160
1178
  * - 发送侧(uiFormInteract 内):不合法项抛错(调用方编码 bug,fail-fast);
1161
1179
  * - event-adapter:逐项过滤,合法项 ≥1 才产 form 帧、全不合法降级普通 select;
1162
- * - renderer:复核守卫,不合法项跳过 + warn,全部不合法 → overlay 错误占位仅取消可点。
1180
+ * - renderer:复核检查,不合法项跳过 + warn,全部不合法 → overlay 错误占位仅取消可点。
1163
1181
  *
1164
1182
  * isFormAnswers 校验回包形状(Record<string, string>):键动态(key = header ??
1165
1183
  * question)无法枚举白名单,故只校验值域全 string;JSON 合法但非本形状由
@@ -1167,11 +1185,11 @@ declare function uiFormInteract(ctx: GuiContext, form: FormQuestion[], opts?: Ui
1167
1185
  */
1168
1186
 
1169
1187
  /**
1170
- * 类型守卫:验证 unknown 是否为合法的 FormQuestion(choice / text / schedule 三分支)。
1188
+ * 类型检查:验证 unknown 是否为合法的 FormQuestion(choice / text / schedule 三分支)。
1171
1189
  * 用于发送侧 fail-fast、event-adapter 逐项过滤与 renderer 复核(三消费点见文件头)。
1172
1190
  */
1173
1191
  declare function isFormQuestion(value: unknown): value is FormQuestion;
1174
- /** 类型守卫:验证 unknown 是否为合法的 FormAnswers(值域全 string 的普通对象) */
1192
+ /** 类型检查:验证 unknown 是否为合法的 FormAnswers(值域全 string 的普通对象) */
1175
1193
  declare function isFormAnswers(value: unknown): value is FormAnswers;
1176
1194
 
1177
1195
  /**
@@ -1183,25 +1201,29 @@ declare function isFormAnswers(value: unknown): value is FormAnswers;
1183
1201
  */
1184
1202
  declare const SESSION_MANAGER_MARKER = "\0TAIJI_SESSION_MANAGER";
1185
1203
  /**
1186
- * 7 个 action 的运行时集合(与 SessionManagerAction 类型同源——types.ts 从此派生)。
1204
+ * 9 个 action 的运行时集合(与 SessionManagerAction 类型同源——types.ts 从此派生)。
1187
1205
  * event-adapter 用它把 JSON 解析出的 action 字符串收窄为联合类型,
1188
1206
  * 非法值折叠为 '__malformed__' 哨兵(与 handler default 分支同走 cancelled)。
1189
1207
  *
1208
+ * 'delete' / 'archive'(session-manager-archive-delete U2):终局操作双 action——
1209
+ * delete 整树废纸篓不可恢复(USER-INITIATED ONLY,约束承载在 extension 工具文案层)、
1210
+ * archive 归档退场可由用户恢复;扩展归属校验在 runtime handler 侧(协议层只定契约)。
1211
+ *
1190
1212
  * 'watch'(notify-once D6):通知债权的纯应答通道——单键 params={notifyId} 寻址、
1191
1213
  * 不传 timeout、fire-and-forget 长挂 select;必须在本集合内,否则 event-adapter
1192
1214
  * 把它折叠成 '__malformed__'(旧 runtime 兼容象限的静默降级形态),watch 永远到不了
1193
1215
  * handler 路由。
1194
1216
  */
1195
- declare const SESSION_MANAGER_ACTIONS: readonly ["create", "send", "history", "status", "list", "abort", "watch"];
1217
+ declare const SESSION_MANAGER_ACTIONS: readonly ["create", "send", "history", "status", "list", "abort", "delete", "archive", "watch"];
1196
1218
 
1197
1219
  /**
1198
1220
  * session-manager extension 的类型定义。
1199
1221
  *
1200
- * 7 个 action 的请求 params 和结果类型,供 handler 和 extension 共用。
1222
+ * 9 个 action 的请求 params 和结果类型,供 handler 和 extension 共用。
1201
1223
  * marker 检测后按 action 分发到对应 handler 分支。
1202
1224
  */
1203
1225
 
1204
- /** session-manager 支持的 7 个 action(从 SESSION_MANAGER_ACTIONS 集合派生,值与类型同源) */
1226
+ /** session-manager 支持的 9 个 action(从 SESSION_MANAGER_ACTIONS 集合派生,值与类型同源) */
1205
1227
  type SessionManagerAction = (typeof SESSION_MANAGER_ACTIONS)[number];
1206
1228
  /** 各 action 的请求参数映射 */
1207
1229
  interface SessionManagerParams {
@@ -1211,6 +1233,8 @@ interface SessionManagerParams {
1211
1233
  status: SessionManagerStatusParams;
1212
1234
  list: SessionManagerListParams;
1213
1235
  abort: SessionManagerAbortParams;
1236
+ delete: SessionManagerDeleteParams;
1237
+ archive: SessionManagerArchiveParams;
1214
1238
  watch: SessionManagerWatchParams;
1215
1239
  }
1216
1240
  /** create action 参数 */
@@ -1225,7 +1249,7 @@ interface SessionManagerCreateParams {
1225
1249
  * 完成通知债权的幂等键(optional,notify-once D2/D6):extension 侧
1226
1250
  * `crypto.randomUUID()` 前缀 `sm-` 生成。缺省/畸形 → runtime 不 arm、
1227
1251
  * `willNotify:false`、零完成通知——兼容判据从版本二分改为字段有无。
1228
- * 形态判定不在 params 守卫(畸形不构成 params 错误、动作照常执行),
1252
+ * 形态判定不在 params 检查(畸形不构成 params 错误、动作照常执行),
1229
1253
  * 由 runtime 受理点消费 `isSessionManagerNotifyId` 作 arm 判据。
1230
1254
  */
1231
1255
  notifyId?: string;
@@ -1253,10 +1277,27 @@ type SessionManagerListParams = Record<string, never>;
1253
1277
  interface SessionManagerAbortParams {
1254
1278
  sessionId: string;
1255
1279
  }
1280
+ /**
1281
+ * delete action 参数(session-manager-archive-delete U2):彻底删除目标会话
1282
+ * (进程 + 历史 + 衍生数据整树废纸篓,不可恢复)。人身约束(USER-INITIATED ONLY)
1283
+ * 承载在 extension 工具文案层,协议层只定契约。归属校验用扩展归属校验
1284
+ * (含磁盘回退)在 runtime handler 侧执行。
1285
+ */
1286
+ interface SessionManagerDeleteParams {
1287
+ sessionId: string;
1288
+ }
1289
+ /**
1290
+ * archive action 参数(session-manager-archive-delete U2):归档目标会话——
1291
+ * 退场进归档区、文件压缩搬移、可由用户恢复。生成中会话拒绝(错误码
1292
+ * archive_generating 经 ChannelErrorResult.code 透传)。
1293
+ */
1294
+ interface SessionManagerArchiveParams {
1295
+ sessionId: string;
1296
+ }
1256
1297
  /**
1257
1298
  * watch action 参数(notify-once D2/D6):通知债权的纯应答通道,**单键寻址**——
1258
1299
  * runtime 按 `(调用方 parentSid, notifyId)` 反查 claim,parentSid 取自调用方连接身份、
1259
- * **协议面不定义不携带**(可推导字段免传,多余字段被守卫拒绝)。不传 timeout、
1300
+ * **协议范围不定义不携带**(可推导字段免传,多余字段被检查拒绝)。不传 timeout、
1260
1301
  * fire-and-forget 长挂 select;每 claim 单 watch 槽(新覆盖旧,runtime 只 respond 最新)。
1261
1302
  */
1262
1303
  interface SessionManagerWatchParams {
@@ -1264,21 +1305,23 @@ interface SessionManagerWatchParams {
1264
1305
  notifyId: string;
1265
1306
  }
1266
1307
  declare function isSessionManagerNotifyId(v: unknown): v is string;
1267
- /** create:字段可选 string + optional notifyId(类型面,sm- 形态判定归 arm 判据) */
1308
+ /** create:字段可选 string + optional notifyId(类型范围,sm- 形态判定归 arm 判据) */
1268
1309
  declare function isSessionManagerCreateParams(v: unknown): v is SessionManagerCreateParams;
1269
- /** send:sessionId + prompt 必填,notifyId optional(类型面校验同 create) */
1310
+ /** send:sessionId + prompt 必填,notifyId optional(类型范围校验同 create) */
1270
1311
  declare function isSessionManagerSendParams(v: unknown): v is SessionManagerSendParams;
1271
1312
  /** history:sessionId 必填、tailTurns 可选 number */
1272
1313
  declare function isSessionManagerHistoryParams(v: unknown): v is SessionManagerHistoryParams;
1273
- /** status / abort:sessionId 必填 */
1314
+ /** status / abort / delete / archive:sessionId 必填 */
1274
1315
  declare function isSessionManagerStatusParams(v: unknown): v is SessionManagerStatusParams;
1275
1316
  declare function isSessionManagerAbortParams(v: unknown): v is SessionManagerAbortParams;
1317
+ declare function isSessionManagerDeleteParams(v: unknown): v is SessionManagerDeleteParams;
1318
+ declare function isSessionManagerArchiveParams(v: unknown): v is SessionManagerArchiveParams;
1276
1319
  /** list:无参数(过滤由 handler 固化,params 不携带任何过滤字段) */
1277
1320
  declare function isSessionManagerListParams(v: unknown): v is SessionManagerListParams;
1278
1321
  /**
1279
- * watch:**封闭单键** `{notifyId}` 守卫(notify-once D2 形态入站自检)——
1322
+ * watch:**封闭单键** `{notifyId}` 检查(notify-once D2 形态入站自检)——
1280
1323
  * 空载荷 / 缺字段 / 夹带任何额外字段(如 parentSid:归属由 runtime 取连接身份,
1281
- * 协议面不定义)/ notifyId 非 string / 形态不符(缺 `sm-` 前缀、非 UUID 体、超长)
1324
+ * 协议范围不定义)/ notifyId 非 string / 形态不符(缺 `sm-` 前缀、非 UUID 体、超长)
1282
1325
  * → false → handler dispatch 抛错走 respond({error}) 错误闭环(error envelope)。
1283
1326
  * 形态函数与 lifetimeNotifyId 同一实现(防自检拒掉 runtime 生成的 lifetime watch)。
1284
1327
  */
@@ -1289,7 +1332,7 @@ interface SessionManagerCreateResult {
1289
1332
  status: 'created';
1290
1333
  modelId?: string;
1291
1334
  /**
1292
- * 完成通知债权是否已 arm(notify-once D6,LLM 契约面显式化):create 无 prompt /
1335
+ * 完成通知债权是否已 arm(notify-once D6,LLM 契约范围显式化):create 无 prompt /
1293
1336
  * notifyId 缺省或畸形 → false(零完成通知);true 时首次完成恰回一条通知。
1294
1337
  * 注意与 lifetimeNotifyId 正交——后者恒存在(死亡通知与债权无关)。
1295
1338
  */
@@ -1345,6 +1388,24 @@ interface SessionManagerSessionSummary {
1345
1388
  interface SessionManagerAbortResult {
1346
1389
  success: boolean;
1347
1390
  }
1391
+ /**
1392
+ * delete 结果(session-manager-archive-delete U2):字段名以设计 §3.1 交互样例为权威
1393
+ * ——成功回包 `{sessionId, deleted:true}`。侧栏消失 + 整树废纸篓由 runtime delete 链
1394
+ * 内建,协议回包只做完成陈述。
1395
+ */
1396
+ interface SessionManagerDeleteResult {
1397
+ deleted: true;
1398
+ sessionId: string;
1399
+ }
1400
+ /**
1401
+ * archive 结果(session-manager-archive-delete U2):字段名以设计 §3.1 交互样例为权威
1402
+ * ——成功回包 `{sessionId, archived:true}`。归档成功后该会话全部通知债权由 runtime
1403
+ * handler 三步收尾统一应答 'exited'(协议范围外,契约属 handler 编排)。
1404
+ */
1405
+ interface SessionManagerArchiveResult {
1406
+ archived: true;
1407
+ sessionId: string;
1408
+ }
1348
1409
  /**
1349
1410
  * watch 应答 reason 词表(封闭 7 值)——与 pending-entries `mapReasonToStatus` 的
1350
1411
  * 4 个新 case 同词形(stopped→aborted、exited/deleted/orphaned→cancelled),
@@ -1365,15 +1426,15 @@ type SessionManagerWatchReason =
1365
1426
  * 折叠 cancelled——null 不在本类型内,消费方须同时处理。
1366
1427
  */
1367
1428
  interface SessionManagerWatchRespondPayload {
1368
- /** 分拣键 (sessionId, reason) 的 reason 腿(D3 两层模型:cancelled/orphaned → 仅
1429
+ /** 分拣键 (sessionId, reason) 的 reason 路径(D3 两层模型:cancelled/orphaned → 仅
1369
1430
  * unregister;exited/deleted → 死亡新闻槽;completed/failed/stopped → 结果新闻) */
1370
1431
  reason: SessionManagerWatchReason;
1371
1432
  /**
1372
1433
  * claim 所属子会话 id 回带——D3 槽键 (sessionId, deathSeq) / 分拣键 (sessionId,
1373
- * reason) / D9 文案 `<sid>` 的唯一数据源(收口腿闭包仅有父 sid,缺此字段则同父
1434
+ * reason) / D9 文案 `<sid>` 的唯一数据源(收敛路径闭包仅有父 sid,缺此字段则同父
1374
1435
  * 多子 deathSeq 跨 child 碰撞)。claim 命中路径(settle/death/orphaned/二次校验)
1375
1436
  * 恒带;fail-closed(查无 claim)无 claim 可回带 → 缺席——该路径 reason 恒
1376
- * 'cancelled',extension 静默收口不消费 sessionId。
1437
+ * 'cancelled',extension 静默收尾不消费 sessionId。
1377
1438
  */
1378
1439
  sessionId?: string;
1379
1440
  /** death 批身份(per session 递增;同一死亡事件循环 respond 时 runtime 直供) */
@@ -1382,7 +1443,7 @@ interface SessionManagerWatchRespondPayload {
1382
1443
  settleSeq?: number;
1383
1444
  /** 本批兑现总笔数(同批每条应答携带同值);death 侧 = 同 deathSeq 的 claim 数(D3 合批口径,runtime 直供,死亡/结果新闻正文消费 fulfills N) */
1384
1445
  fulfillsN?: number;
1385
- /** death 应答携带:exit 腿诊断数据通路复刻(400 字截尾沿用现值),extension 文案构造消费 */
1446
+ /** death 应答携带:exit 路径诊断数据通路复刻(400 字截尾沿用现值),extension 文案构造消费 */
1386
1447
  exitCode?: number | null;
1387
1448
  stderrTail?: string;
1388
1449
  /**
@@ -1393,7 +1454,7 @@ interface SessionManagerWatchRespondPayload {
1393
1454
  sessionFilePath?: string;
1394
1455
  }
1395
1456
  /**
1396
- * watch respond payload 运行时守卫(extension 读侧不信任外部格式——AGENTS 关键规则 5):
1457
+ * watch respond payload 运行时检查(extension 读侧不信任外部格式——AGENTS 关键规则 5):
1397
1458
  * null(旧 runtime 象限)/ 非 record / reason 缺失、非 string 或词表外 / 可选 meta
1398
1459
  * 类型不符 → false(可选字段缺席一律放行——含 sessionFilePath)。消费方对 false 与
1399
1460
  * null 同路折叠静默 unregister(fail-safe:未知 reason 不得落 default 误标)。
@@ -1408,7 +1469,7 @@ type SessionManagerErrorResult = ChannelErrorResult & {
1408
1469
  };
1409
1470
 
1410
1471
  /**
1411
- * subagent 在途上报的类型定义(u7a 协议面)。
1472
+ * subagent 在途上报的类型定义(u7a 协议范围)。
1412
1473
  *
1413
1474
  * 契约两端:
1414
1475
  * - 写侧(生产):@zhushanwen/pi-subagent-workflow 壳层(src/host/inflight-reporter.ts)
@@ -1452,12 +1513,12 @@ interface SubagentInFlightReport {
1452
1513
  */
1453
1514
  declare const INFLIGHT_REPORT_ACK: "{\"ack\":true}";
1454
1515
  /**
1455
- * SubagentInFlightReport 形状守卫:inFlight 非负整数、emittedAt 数字、sessionId
1516
+ * SubagentInFlightReport 形状检查:inFlight 非负整数、emittedAt 数字、sessionId
1456
1517
  * 缺席或 string。event-adapter(u7b)路由分支消费;非法帧返回 false(调用方丢弃,
1457
1518
  * 不抛错不镜像)。
1458
1519
  */
1459
1520
  declare function isSubagentInFlightReport(v: unknown): v is SubagentInFlightReport;
1460
- /** 确认回包形状守卫(pi 侧 reporter 消费——非本字符串即未确认,折叠重试)。 */
1521
+ /** 确认回包形状检查(pi 侧 reporter 消费——非本字符串即未确认,折叠重试)。 */
1461
1522
  declare function isInFlightReportAck(v: unknown): v is typeof INFLIGHT_REPORT_ACK;
1462
1523
 
1463
1524
  /**
@@ -1470,12 +1531,12 @@ declare function isInFlightReportAck(v: unknown): v is typeof INFLIGHT_REPORT_AC
1470
1531
  * 与 ASK_USER_MARKER / SESSION_MANAGER_MARKER / BRIDGE_MARKER 同理。
1471
1532
  *
1472
1533
  * 设计权威源:docs/architecture/crash-forensics-and-watchdog.md §3.3 D5
1473
- * 「在途判定谓词 + 求值位置」——extension 聚合上报通道的协议面(u7a)。
1534
+ * 「在途判定谓词 + 求值位置」——extension 聚合上报通道的协议范围(u7a)。
1474
1535
  */
1475
1536
  declare const SUBAGENT_INFLIGHT_MARKER = "\0TAIJI_SUBAGENT_INFLIGHT";
1476
1537
 
1477
1538
  /**
1478
- * journal 事件推送的类型定义(event-push-channel 协议面)。
1539
+ * journal 事件推送的类型定义(event-push-channel 协议范围)。
1479
1540
  *
1480
1541
  * 契约两端:
1481
1542
  * - 写侧(生产):@zhushanwen/pi-subagent-workflow 壳层(src/host/journal-reporter.ts)
@@ -1537,12 +1598,12 @@ interface SubagentJournalReport {
1537
1598
  */
1538
1599
  declare const JOURNAL_REPORT_ACK: "{\"ack\":true}";
1539
1600
  /**
1540
- * SubagentJournalReport 形状守卫:domain 落两域词表、fileKey 非空串、events 逐条
1541
- * 过信封守卫、sessionId 缺席或 string。event-adapter 路由分支消费;非法帧返回
1601
+ * SubagentJournalReport 形状检查:domain 落两域词表、fileKey 非空串、events 逐条
1602
+ * 过信封检查、sessionId 缺席或 string。event-adapter 路由分支消费;非法帧返回
1542
1603
  * false(调用方丢弃,不 fold 不 ack)。
1543
1604
  */
1544
1605
  declare function isSubagentJournalReport(v: unknown): v is SubagentJournalReport;
1545
- /** 确认回包形状守卫(pi 侧 reporter 消费——非本字符串即未确认)。 */
1606
+ /** 确认回包形状检查(pi 侧 reporter 消费——非本字符串即未确认)。 */
1546
1607
  declare function isJournalReportAck(v: unknown): v is typeof JOURNAL_REPORT_ACK;
1547
1608
 
1548
1609
  /**
@@ -1564,7 +1625,7 @@ declare const SUBAGENT_JOURNAL_MARKER = "\0TAIJI_SUBAGENT_JOURNAL";
1564
1625
  * subagent-workflow 通知通道的 custom_message customType 词表(单源)。
1565
1626
  *
1566
1627
  * 契约两端(值逐字节依赖,改名 = 跨侧破坏性变更):
1567
- * - 写侧:@zhushanwen/pi-subagent-workflow extension(workflow 收口通知 / bg-notify
1628
+ * - 写侧:@zhushanwen/pi-subagent-workflow extension(workflow 收敛通知 / bg-notify
1568
1629
  * 送达 / 定向消息留痕,经 pi.sendMessage 落 custom_message entry 进 session JSONL)
1569
1630
  * 与 @zhushanwen/subagent-core(notifier 送达 + notify ledger 默认通道);
1570
1631
  * - 读侧:taiji 三层——@taiji/shared(COMPLETE_NOTIFY_CUSTOM_TYPES display 覆写
@@ -1579,7 +1640,7 @@ declare const SUBAGENT_JOURNAL_MARKER = "\0TAIJI_SUBAGENT_JOURNAL";
1579
1640
  * worker-script-builder 的 postMessage 帧 type)是同名不同域——那是引擎进程内 RPC 形状,
1580
1641
  * 不跨 pi session 边界,不进本词表。
1581
1642
  */
1582
- /** workflow run 收口通知的送达 customType。runtime event-interpreter 按它识别 run 完成
1643
+ /** workflow run 收敛通知的送达 customType。runtime event-interpreter 按它识别 run 完成
1583
1644
  * 并驱动 W18 workflow-record 失效信号;shared 完成通知 display 覆写集合亦按它收录。
1584
1645
  * 与 SUBAGENT_BG_NOTIFY_CUSTOM_TYPE 通道互斥(互用会让失效信号误判通道语义)。 */
1585
1646
  declare const WORKFLOW_RESULT_CUSTOM_TYPE: "workflow-result";
@@ -1656,10 +1717,11 @@ interface SubagentEngineConfigView {
1656
1717
  * per-action × actor 权限矩阵按此建制(matrix.ts)。
1657
1718
  * - CANVAS_MARKER_ACTIONS(16 + 'enter'):marker 通道(extension select 挂起)
1658
1719
  * 的 action 域。'enter' 是 canvas_enter 工具「打开已有画布」形态的通道动作:
1659
- * 读全量 + 登记绑定(sessionId ↔ canvasId),非画布 mutation——不产事件、
1720
+ * 读全量(归属校验在 readState,非 owner → forbidden);回推对象 = 归属会话
1721
+ * 本身(owner 持久在落盘路径),无登记动作、不产事件——非画布 mutation、
1660
1722
  * 不在权限矩阵内(marker 通道调用方恒为 agent 工具)。创建形态走 'create'
1661
- * (marker 通道的 create 只可能来自 canvas_enter 工具,runtime 在该通道
1662
- * create 成功时一并登记绑定;GUI 托盘新建走 WS RPC 通道、不登记绑定)。
1723
+ * (marker 通道的 create 只可能来自 canvas_enter 工具;GUI 托盘新建走 WS RPC
1724
+ * 通道,两通道行为无分叉)。
1663
1725
  */
1664
1726
  /**
1665
1727
  * canvas 工具请求的 title marker。runtime event-adapter / CanvasHandler 检测此
@@ -1846,6 +1908,14 @@ interface ReviewReport {
1846
1908
  /** 画布状态(聚合 1 全量投影;canvas.get reply 与 canvas.json 快照共用形状)。 */
1847
1909
  interface CanvasState {
1848
1910
  canvasId: string;
1911
+ /**
1912
+ * 归属会话 id(画布归属 = 创建它的 session,1:N——一个 session 可有多张画布)。
1913
+ * 归属即落盘路径(`<dataDir>/ext-sessions/<ownerSessionId>/canvases/<canvasId>/`),
1914
+ * 路径即归属的构造性承载:该字段由 runtime 从落盘路径推导填充(服务层唯一写入点),
1915
+ * 领域事件流不承载归属(CanvasCreated 事件 data 不含 sessionId——事件流内容与格式
1916
+ * 不随布局反转变化,只挪位置);跨会话访问按本字段归属校验拒绝(forbidden)。
1917
+ */
1918
+ ownerSessionId: string;
1849
1919
  /** 画布名(canvasId = 短随机 id;重命名属第二版多画布管理,MVP 只读)。 */
1850
1920
  name: string;
1851
1921
  /** 根问题三要素(不变量 1:有且仅有一个根节点,类型 question,带完成判据与范围排除)。 */
@@ -1895,9 +1965,12 @@ interface CanvasState {
1895
1965
  }
1896
1966
  /** canvas.list 条目:托盘画布列表的数据源(名称 + 阶段徽标 + must-fix 计数)。
1897
1967
  * 阶段徽标本身是 renderer 派生值(开放 must-fix 或审查进行中 = 审查中;
1898
- * converged = 已收敛;其余 = 生长中),契约只给派生输入。 */
1968
+ * converged = 已收敛;其余 = 生长中),契约只给派生输入。清单按请求 sessionId
1969
+ * 过滤(只返回归属该会话的画布),ownerSessionId 即过滤判据的回显。 */
1899
1970
  interface CanvasListEntry {
1900
1971
  canvasId: string;
1972
+ /** 归属会话 id(= 请求的过滤 sessionId;语义同 CanvasState.ownerSessionId)。 */
1973
+ ownerSessionId: string;
1901
1974
  name: string;
1902
1975
  statement: string;
1903
1976
  converged: boolean;
@@ -1960,17 +2033,18 @@ interface CanvasError {
1960
2033
  recover: string;
1961
2034
  }
1962
2035
  /**
1963
- * 错误码词表(封闭 15 值)。分组:
2036
+ * 错误码词表(封闭 16 值)。分组:
1964
2037
  * - 寻址 / 形状:canvas_not_found / node_not_found / edge_not_found /
1965
2038
  * invalid_params / unknown_action
1966
- * - 权限:actor_not_allowed(矩阵表外组合 fail-fast)
2039
+ * - 权限:actor_not_allowed(矩阵表外组合 fail-fast)/ forbidden(画布不属当前会话——
2040
+ * 归属校验拒绝,画布归属 = 创建它的 session,跨会话访问一律结构化拒绝)
1967
2041
  * - 不变量拦截:selection_conflict(不变量 3 双选定)/ cycle_detected(不变量 2 成环)/
1968
2042
  * unverified_fact(不变量 5)/ dispatch_blocked(不变量 7)/ not_converged(不变量 10)/
1969
2043
  * lifecycle_transition_illegal(状态机表外转移)
1970
2044
  * - 审查聚合:entry_ref_missing(聚合 2 不变量 1)/ already_resolved(first-writer-wins)/
1971
2045
  * review_max_rounds(轮次上限后再发起)
1972
2046
  */
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"];
2047
+ 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
2048
  type CanvasErrorCode = (typeof CANVAS_ERROR_CODES)[number];
1975
2049
  /**
1976
2050
  * 每码一句恢复动作文案(SSOT;runtime 构造 CanvasError 时 recover 字段取此处
@@ -2159,7 +2233,10 @@ interface CanvasReadParams {
2159
2233
  /** 子树读取:从该节点 id 向下的主干子树;缺省读全量。 */
2160
2234
  subtree?: string;
2161
2235
  }
2162
- /** list:无参数(全量画布清单;过滤无字段——Record 结构性拒绝夹带)。 */
2236
+ /** list:无参数(全量画布清单的 action 侧形状——归属过滤字段不在共享 params 内:
2237
+ * sessionId 是**通道级字段**(WS payload 携带、marker 通道由 dispatch 上下文的发起
2238
+ * 会话注入,与 canvas.mutate 的 actor/sessionId 同款通道字段模式),runtime 按归属
2239
+ * 会话过滤(D4 裁决 3)。Record 结构性拒绝夹带任何过滤字段)。 */
2163
2240
  type CanvasListParams = Record<string, never>;
2164
2241
  /** 16 action 的 params 映射(SSOT;两通道共用——WS RPC 与 marker 的 params 同构)。 */
2165
2242
  interface CanvasActionParams {
@@ -2189,7 +2266,7 @@ type CanvasMutateRequest = {
2189
2266
  };
2190
2267
  }[CanvasAction];
2191
2268
  type CanvasMarkerAction = (typeof CANVAS_MARKER_ACTIONS)[number];
2192
- /** enter(canvas_enter 打开形态):读全量 + 登记绑定;非画布 mutation、不产事件。 */
2269
+ /** enter(canvas_enter 打开形态):读全量(归属校验在 readState,非 owner → forbidden);非画布 mutation、不产事件、无登记动作。 */
2193
2270
  interface CanvasEnterParams {
2194
2271
  canvasId: string;
2195
2272
  }
@@ -2234,7 +2311,8 @@ declare function isCanvasConvergeCheckParams(v: unknown): v is CanvasConvergeChe
2234
2311
  declare function isCanvasExportParams(v: unknown): v is CanvasExportParams;
2235
2312
  declare function isCanvasDispatchParams(v: unknown): v is CanvasDispatchParams;
2236
2313
  declare function isCanvasReadParams(v: unknown): v is CanvasReadParams;
2237
- /** list:无参数——Record 结构性拒绝夹带任何过滤字段(session-manager list 同款)。 */
2314
+ /** list:无参数——Record 结构性拒绝夹带任何过滤字段(session-manager list 同款;
2315
+ * 归属过滤字段是通道级的,见 CanvasListParams 注释)。 */
2238
2316
  declare function isCanvasListParams(v: unknown): v is CanvasListParams;
2239
2317
  /** enter(canvas_enter 打开形态):封闭单键 canvasId。 */
2240
2318
  declare function isCanvasEnterParams(v: unknown): v is CanvasEnterParams;
@@ -2308,7 +2386,7 @@ declare function allCanvasActions(): readonly CanvasAction[];
2308
2386
  * 契约两端(此前各持一份同构差集实现,对齐手段是注释):
2309
2387
  * - extension 侧:@zhushanwen/pi-base-tool-enhance 对账(原 collectUnsettledTaskIds:
2310
2388
  * session_start 时对「entries 显示活跃但任务已终态」的 bt- 任务补写注销)
2311
- * - extension 侧:@zhushanwen/pi-pending-notifications 守卫判据(原
2389
+ * - extension 侧:@zhushanwen/pi-pending-notifications 检查判据(原
2312
2390
  * scanPendingEntries + filterActiveRegisters;其 types/currentSessionId/normalize
2313
2391
  * 过滤是 pending 产品语义,留在 pending 侧,不在本模块)
2314
2392
  *
@@ -2328,19 +2406,48 @@ interface CollectPendingIdsOptions {
2328
2406
  /** 只保留该前缀的 id(如 'bt-');缺省不过滤。 */
2329
2407
  idPrefix?: string;
2330
2408
  }
2331
- /** scanPendingEntries 的结果:register 原始 data 列表 + 已注销 id 集合。 */
2409
+ /** scanPendingEntries 的结果:register 原始 data 列表 + 已注销 id 集 + collect 字段映射视图。 */
2332
2410
  interface PendingEntriesScan {
2333
2411
  registerEntries: Array<{
2334
2412
  data: Record<string, unknown>;
2335
2413
  }>;
2336
2414
  unregisteredIds: Set<string>;
2415
+ /**
2416
+ * register 首见字段视图(MF-2-1 单点):id → type(string 才收,原样透传——归一化
2417
+ * 归消费方)。首见规则 = 首条 register 胜出:同 id 重复条目不覆盖;首条无 type
2418
+ * 则该 id 恒无映射(不被后续重复条目补位——与 applyPendingDiff 的首条 data 语义
2419
+ * 同口径,工具侧旧「首条带 type 胜出」的补位行为是漂移,收敛时已废除)。
2420
+ */
2421
+ registerTypes: Map<string, string>;
2422
+ /**
2423
+ * 注销条目 status 视图:id → status(写侧经 mapReasonToStatus 已映射落盘)。仅收
2424
+ * MAPPED_PENDING_STATUSES 成员(词表外/畸形不收,不虚构终态);同 id 多条注销取
2425
+ * 末次合法值(后条非法不抹除前条合法值)。
2426
+ */
2427
+ unregisterStatuses: Map<string, MappedPendingStatus>;
2337
2428
  }
2338
2429
  /**
2339
2430
  * 单趟扫描 entries 按 customType 分流(容错对齐 pending 侧 S-10:null/非对象
2340
- * 元素先守卫再访问字段)。register 侧不校验 id(合法性判定归差集层);unregister
2341
- * 仅收 string id。data 用最小结构类型 Record<string, unknown>,消费方自行窄化。
2431
+ * 元素先检查再访问字段)。register 侧 registerEntries 不校验 id(合法性判定归差集
2432
+ * 层);unregister 仅收 string id。data 用最小结构类型 Record<string, unknown>,
2433
+ * 消费方自行窄化。字段映射视图(registerTypes / unregisterStatuses)顺路产出:
2434
+ * collect 链路的 type/outcome 映射规则单点在本次扫描(delivery-port 快照基线与
2435
+ * pending-notifications 终局回填此前各持一份同构扫描器且首见语义已分歧,MF-2-1
2436
+ * 收敛——消费方禁止本地复制映射段)。
2342
2437
  */
2343
- declare function scanPendingEntries(entries: unknown[]): PendingEntriesScan;
2438
+ declare function scanPendingEntries(entries: readonly unknown[]): PendingEntriesScan;
2439
+ /** scanPendingFields 的结果:collect 链路消费的字段映射投影(首见 type + 注销 status)。 */
2440
+ interface PendingFieldsScan {
2441
+ registerTypes: Map<string, string>;
2442
+ unregisterStatuses: Map<string, MappedPendingStatus>;
2443
+ }
2444
+ /**
2445
+ * collect 终局回填的字段视图(MF-2-1 单点入口):scanPendingEntries 产物中
2446
+ * register 首见 type + 全部注销 status 的 MAPPED 成员投影。消费方(delivery-port
2447
+ * 快照基线 / pending-notifications consume 后回填)按 id 查表补 type/outcome,
2448
+ * 查无保持 undefined(诚实缺省,不虚构终态)。
2449
+ */
2450
+ declare function scanPendingFields(entries: readonly unknown[]): PendingFieldsScan;
2344
2451
  /**
2345
2452
  * 差集本体(规则单点):register 首见去重 + unregister 全局抵消 + id 非法跳过。
2346
2453
  * 首见判定先于任何消费方过滤(seen.add 后即使调用方对首个 data 过滤丢弃,后续
@@ -2382,5 +2489,14 @@ declare function collectActivePendingIds(entries: unknown[], opts?: CollectPendi
2382
2489
  * 字面量联合锁定值域,switch 分支编译期受限。 */
2383
2490
  type MappedPendingStatus = 'completed' | 'failed' | 'cancelled' | 'expired' | 'time_limited' | 'aborted';
2384
2491
  declare function mapReasonToStatus(reason: string): MappedPendingStatus;
2492
+ /**
2493
+ * MappedPendingStatus 的值集(MF-1-5 词表单源):由 REASON_STATUS_MAP 派生——映射表
2494
+ * 演化(新增 reason / 改映射目标)时值集构造性跟随,无第二份手工词表可漂移。消费方
2495
+ * (delivery-port / pending-notifications 读取侧)按成员资格判定落盘 status 合法性时
2496
+ * import 本常量,禁止本地复制六值 Set(曾两包各持一份本地拷贝注释自认「同步维护」)。
2497
+ * Set 成员与 MappedPendingStatus 联合的相等性由 pending-entries.test.ts 断言锁定。
2498
+ * string 元素类型是消费面要求(对任意落盘 status 做成员判定,窄化前的原始值)。
2499
+ */
2500
+ declare const MAPPED_PENDING_STATUSES: ReadonlySet<string>;
2385
2501
 
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 };
2502
+ 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 SessionManagerArchiveParams, type SessionManagerArchiveResult, type SessionManagerCreateParams, type SessionManagerCreateResult, type SessionManagerDeleteParams, type SessionManagerDeleteResult, 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, isSessionManagerArchiveParams, isSessionManagerCreateParams, isSessionManagerDeleteParams, 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
@@ -110,11 +110,14 @@ function stripUndefined(obj) {
110
110
  // src/core/select-rpc.ts
111
111
  var RESPONSE_PREVIEW_LENGTH = 200;
112
112
  function isChannelErrorResult(v) {
113
- return typeof v === "object" && v !== null && !Array.isArray(v) && typeof v.error === "string";
113
+ const rec = v;
114
+ return typeof v === "object" && v !== null && !Array.isArray(v) && typeof rec.error === "string" && (rec.code === void 0 || typeof rec.code === "string");
114
115
  }
115
116
  function formatChannelErrorText(err) {
116
- return err.hint ? `${err.error}
117
- hint: ${err.hint}` : err.error;
117
+ const lines = [err.error];
118
+ if (err.code) lines.push(`error_code: ${err.code}`);
119
+ if (err.hint) lines.push(`hint: ${err.hint}`);
120
+ return lines.join("\n");
118
121
  }
119
122
  function emitRpcLog(opts, msg, detail) {
120
123
  opts?.log?.(msg, detail);
@@ -123,7 +126,7 @@ async function callMarkerRpc(ctx, marker, payload, opts) {
123
126
  const select = ctx.ui?.select;
124
127
  if (!select) {
125
128
  throw new Error(
126
- `callMarkerRpc() requires ctx.ui.select (marker ${JSON.stringify(marker)}). Non-GUI ctx must be gated by the caller first \u2014 see askUserInteract precedent (isGuiCapable(ctx) && ctx.ui?.select, or a mode check).`
129
+ `callMarkerRpc() requires ctx.ui.select (marker ${JSON.stringify(marker)}). Non-GUI ctx must be gated by the caller first \u2014 gate with isGuiCapable(ctx) && ctx.ui?.select (exported from @zhushanwen/extension-protocol), or a mode check.`
127
130
  );
128
131
  }
129
132
  let value;
@@ -415,6 +418,7 @@ function onceCronToDate(cron, now = /* @__PURE__ */ new Date()) {
415
418
  }
416
419
 
417
420
  // src/extensions/plan/state-machine.ts
421
+ import { defineStateMachine } from "@zhushanwen/state-machine";
418
422
  var PLAN_LIFECYCLE_STATES = [
419
423
  "idle",
420
424
  "planning",
@@ -436,34 +440,57 @@ var PLAN_LIFECYCLE_EVENTS = [
436
440
  "later",
437
441
  "exit"
438
442
  ];
439
- var TRANSITION_TABLE = {
440
- idle: { enter: "planning" },
441
- planning: { submit: "reviewing", exit: "exited" },
442
- reviewing: {
443
- submit: "reviewing",
444
- revise: "revising",
445
- dismiss: "planning",
446
- review_aborted: "planning",
447
- approve: "dispatching",
448
- exit: "exited"
443
+ var PLAN_MACHINE = defineStateMachine({
444
+ name: "plan-lifecycle",
445
+ states: {
446
+ idle: {},
447
+ planning: {},
448
+ reviewing: {},
449
+ revising: {},
450
+ approved: {},
451
+ dispatching: {},
452
+ completed: { terminal: true },
453
+ exited: { terminal: true }
449
454
  },
450
- revising: { submit: "reviewing", exit: "exited" },
451
- approved: { approve: "dispatching", exit: "exited" },
452
- dispatching: {
453
- review_aborted: "approved",
454
- exec_chosen: "completed",
455
- later: "approved",
456
- exit: "exited"
455
+ initial: "idle",
456
+ events: {
457
+ enter: {},
458
+ submit: {},
459
+ revise: {},
460
+ dismiss: {},
461
+ review_aborted: {},
462
+ approve: {},
463
+ exec_chosen: {},
464
+ later: {},
465
+ exit: {}
457
466
  },
458
- completed: { enter: "planning" },
459
- exited: { enter: "planning" }
460
- };
467
+ transitions: [
468
+ { from: "idle", on: "enter", to: "planning" },
469
+ { from: "planning", on: "submit", to: "reviewing" },
470
+ { from: "planning", on: "exit", to: "exited" },
471
+ { from: "reviewing", on: "submit", to: "reviewing" },
472
+ { from: "reviewing", on: "revise", to: "revising" },
473
+ { from: "reviewing", on: "dismiss", to: "planning" },
474
+ { from: "reviewing", on: "review_aborted", to: "planning" },
475
+ { from: "reviewing", on: "approve", to: "dispatching" },
476
+ { from: "reviewing", on: "exit", to: "exited" },
477
+ { from: "revising", on: "submit", to: "reviewing" },
478
+ { from: "revising", on: "exit", to: "exited" },
479
+ { from: "approved", on: "approve", to: "dispatching" },
480
+ { from: "approved", on: "exit", to: "exited" },
481
+ { from: "dispatching", on: "review_aborted", to: "approved" },
482
+ { from: "dispatching", on: "exec_chosen", to: "completed" },
483
+ { from: "dispatching", on: "later", to: "approved" },
484
+ { from: "dispatching", on: "exit", to: "exited" },
485
+ { from: ["completed", "exited"], on: "enter", to: "planning" }
486
+ ],
487
+ errorPolicy: "result"
488
+ });
461
489
  function transition(state, event) {
462
- if (!PLAN_LIFECYCLE_STATES.includes(state) || !PLAN_LIFECYCLE_EVENTS.includes(event)) {
463
- return { ok: false };
464
- }
465
- const next = TRANSITION_TABLE[state][event];
466
- return next === void 0 ? { ok: false } : { ok: true, next };
490
+ if (typeof event !== "string") return { ok: false };
491
+ const result = PLAN_MACHINE.transition(state, event);
492
+ if (!result.ok) return { ok: false };
493
+ return result.state === null ? { ok: false } : { ok: true, next: result.state };
467
494
  }
468
495
  var PHASE_OF_STATE = {
469
496
  idle: "idle",
@@ -476,8 +503,9 @@ var PHASE_OF_STATE = {
476
503
  exited: "terminal"
477
504
  };
478
505
  function derivePhase(state) {
479
- if (!PLAN_LIFECYCLE_STATES.includes(state)) return "idle";
480
- return PHASE_OF_STATE[state];
506
+ const coerced = PLAN_MACHINE.coerceState(state);
507
+ if (coerced === null) return "idle";
508
+ return PHASE_OF_STATE[coerced];
481
509
  }
482
510
 
483
511
  // src/extensions/plan/review-contract.ts
@@ -552,10 +580,8 @@ function isPlanReviewResponse(value) {
552
580
  // src/extensions/plan/legacy-entries.ts
553
581
  var PLAN_STATE_CUSTOM_TYPE = "plan-state";
554
582
  function readLifecycleState(data, isActive) {
555
- const raw = data.state;
556
- if (typeof raw === "string" && PLAN_LIFECYCLE_STATES.includes(raw)) {
557
- return raw;
558
- }
583
+ const coerced = PLAN_MACHINE.coerceState(data.state);
584
+ if (coerced !== null) return coerced;
559
585
  if (data.reviewState === "awaiting") return "reviewing";
560
586
  if (data.reviewState === "revising") return "revising";
561
587
  return isActive ? "planning" : "idle";
@@ -700,6 +726,12 @@ function isSessionManagerStatusParams(v) {
700
726
  function isSessionManagerAbortParams(v) {
701
727
  return isSessionIdParams(v);
702
728
  }
729
+ function isSessionManagerDeleteParams(v) {
730
+ return isSessionIdParams(v);
731
+ }
732
+ function isSessionManagerArchiveParams(v) {
733
+ return isSessionIdParams(v);
734
+ }
703
735
  function isSessionManagerListParams(v) {
704
736
  return isRecord(v);
705
737
  }
@@ -732,7 +764,17 @@ function isSessionManagerWatchRespondPayload(v) {
732
764
 
733
765
  // src/extensions/session-manager/marker.ts
734
766
  var SESSION_MANAGER_MARKER = "\0TAIJI_SESSION_MANAGER";
735
- var SESSION_MANAGER_ACTIONS = ["create", "send", "history", "status", "list", "abort", "watch"];
767
+ var SESSION_MANAGER_ACTIONS = [
768
+ "create",
769
+ "send",
770
+ "history",
771
+ "status",
772
+ "list",
773
+ "abort",
774
+ "delete",
775
+ "archive",
776
+ "watch"
777
+ ];
736
778
 
737
779
  // src/extensions/subagent-inflight/marker.ts
738
780
  var SUBAGENT_INFLIGHT_MARKER = "\0TAIJI_SUBAGENT_INFLIGHT";
@@ -1009,6 +1051,7 @@ var CANVAS_ERROR_CODES = [
1009
1051
  "invalid_params",
1010
1052
  "unknown_action",
1011
1053
  "actor_not_allowed",
1054
+ "forbidden",
1012
1055
  "selection_conflict",
1013
1056
  "cycle_detected",
1014
1057
  "unverified_fact",
@@ -1027,6 +1070,7 @@ var CANVAS_ERROR_RECOVERY = {
1027
1070
  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
1071
  unknown_action: "action \u4E0D\u5728\u8BCD\u8868\uFF1A\u5BF9\u7167 CANVAS_ACTIONS \u8BCD\u8868\u4FEE\u6B63 action \u540D",
1029
1072
  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",
1073
+ 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
1074
  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
1075
  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
1076
  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 +1146,39 @@ function allCanvasActions() {
1102
1146
  var PENDING_REGISTER_ENTRY_TYPE = "pending:register";
1103
1147
  var PENDING_UNREGISTER_ENTRY_TYPE = "pending:unregister";
1104
1148
  function scanPendingEntries(entries) {
1105
- const scan = { registerEntries: [], unregisteredIds: /* @__PURE__ */ new Set() };
1149
+ const scan = {
1150
+ registerEntries: [],
1151
+ unregisteredIds: /* @__PURE__ */ new Set(),
1152
+ registerTypes: /* @__PURE__ */ new Map(),
1153
+ unregisterStatuses: /* @__PURE__ */ new Map()
1154
+ };
1155
+ const seenRegisterIds = /* @__PURE__ */ new Set();
1106
1156
  for (const raw of entries) {
1107
1157
  if (!raw || typeof raw !== "object") continue;
1108
1158
  const entry = raw;
1159
+ const data = entry.data ?? {};
1109
1160
  if (entry.customType === PENDING_REGISTER_ENTRY_TYPE) {
1110
- scan.registerEntries.push({ data: entry.data ?? {} });
1161
+ scan.registerEntries.push({ data });
1162
+ if (typeof data.id === "string" && data.id !== "" && !seenRegisterIds.has(data.id)) {
1163
+ seenRegisterIds.add(data.id);
1164
+ if (typeof data.type === "string") scan.registerTypes.set(data.id, data.type);
1165
+ }
1111
1166
  } else if (entry.customType === PENDING_UNREGISTER_ENTRY_TYPE) {
1112
- const data = entry.data ?? {};
1113
- if (typeof data.id === "string") scan.unregisteredIds.add(data.id);
1167
+ if (typeof data.id === "string") {
1168
+ scan.unregisteredIds.add(data.id);
1169
+ const status = data.status;
1170
+ if (data.id !== "" && typeof status === "string" && MAPPED_PENDING_STATUSES.has(status)) {
1171
+ scan.unregisterStatuses.set(data.id, status);
1172
+ }
1173
+ }
1114
1174
  }
1115
1175
  }
1116
1176
  return scan;
1117
1177
  }
1178
+ function scanPendingFields(entries) {
1179
+ const { registerTypes, unregisterStatuses } = scanPendingEntries(entries);
1180
+ return { registerTypes, unregisterStatuses };
1181
+ }
1118
1182
  function applyPendingDiff(scan) {
1119
1183
  const active = [];
1120
1184
  const seen = /* @__PURE__ */ new Set();
@@ -1157,6 +1221,7 @@ var REASON_STATUS_MAP = {
1157
1221
  function mapReasonToStatus(reason) {
1158
1222
  return REASON_STATUS_MAP[reason] ?? "completed";
1159
1223
  }
1224
+ var MAPPED_PENDING_STATUSES = new Set(Object.values(REASON_STATUS_MAP));
1160
1225
  export {
1161
1226
  ACTION_EVENT_MAP,
1162
1227
  ASK_USER_MARKER,
@@ -1176,6 +1241,7 @@ export {
1176
1241
  HISTORY_LIMIT,
1177
1242
  INFLIGHT_REPORT_ACK,
1178
1243
  JOURNAL_REPORT_ACK,
1244
+ MAPPED_PENDING_STATUSES,
1179
1245
  MAX_TERMINAL_REGISTRY_ENTRIES,
1180
1246
  MS_PER_DAY,
1181
1247
  MS_PER_HOUR,
@@ -1260,7 +1326,9 @@ export {
1260
1326
  isScheduleDraft,
1261
1327
  isScheduleFormResult,
1262
1328
  isSessionManagerAbortParams,
1329
+ isSessionManagerArchiveParams,
1263
1330
  isSessionManagerCreateParams,
1331
+ isSessionManagerDeleteParams,
1264
1332
  isSessionManagerHistoryParams,
1265
1333
  isSessionManagerListParams,
1266
1334
  isSessionManagerNotifyId,
@@ -1278,6 +1346,7 @@ export {
1278
1346
  readResumeHint,
1279
1347
  replayFoldEntries,
1280
1348
  scanPendingEntries,
1349
+ scanPendingFields,
1281
1350
  setWidgetDual,
1282
1351
  snapshotToTask,
1283
1352
  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.23.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",
@@ -21,6 +21,9 @@
21
21
  "README.md"
22
22
  ],
23
23
  "license": "MIT",
24
+ "dependencies": {
25
+ "@zhushanwen/state-machine": "0.2.0"
26
+ },
24
27
  "devDependencies": {
25
28
  "@vitest/coverage-v8": "^4.1.9",
26
29
  "tsup": "^8.5.1",