@zhushanwen/extension-protocol 0.16.0 → 0.18.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 +7 -1
- package/dist/index.d.ts +297 -110
- package/dist/index.js +197 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,9 +7,15 @@ pi extension 跨层契约包:类型 + helper 函数 + 共享行为原语,零
|
|
|
7
7
|
- `core/` —— 通用协议层(所有 extension 共用:`GuiComponent` + 布局原语 + 传输编码 + 双模 widget helper)
|
|
8
8
|
- `extensions/` —— 有运行时定制逻辑的 extension(marker + helper)
|
|
9
9
|
- `ask-user/` —— 富交互(select 通道 + marker)
|
|
10
|
+
- `plan/` —— plan 生命周期状态机 + 审阅回传值域契约 + 旧 entry legacy 读取(纯函数零 pi 依赖,扩展 / runtime / renderer 三层共用)
|
|
11
|
+
- `scheduler/` —— scheduler 任务条目契约 + entry 重放折叠(replayFoldEntries)+ 时间格式化(纯契约与纯函数,零 pi/node 依赖)
|
|
12
|
+
- `scheduler-create/` —— scheduler 创建确认共享资产(ScheduleDraft / ScheduleFormResult 类型 + 形状与时间折叠守卫 + marker)
|
|
10
13
|
- `session-manager/` —— agent-managed session 嵌套 `{action, params}` 契约(select 通道 + marker)
|
|
11
|
-
- `plugin-bridge/` —— plugin system bridge(插件工具/事件/拦截经 select 通道 + marker 桥接)
|
|
12
14
|
- `subagent-engine/` —— 引擎可发现性(`engines.json` 状态文件 + 引擎配置视图)
|
|
15
|
+
- `subagent-inflight/` —— subagent 在途聚合上报(绝对计数报告 + marker,select 通道)
|
|
16
|
+
- `subagent-notify/` —— subagent-workflow 通知通道 customType 常量唯一来源(workflow 结果 / 后台通知 / subagent 指令三类)
|
|
17
|
+
- `ui-form/` —— 统一提问表单协议(ask-user / scheduler / plan 三方提问统一入口:类型 + marker + 交互 helper + 守卫)
|
|
18
|
+
- 完整子协议清单以 `src/index.ts` 导出为准
|
|
13
19
|
- `pending-entries` —— pending 事件流差集核心(register 去重 + unregister 抵消,纯算法)
|
|
14
20
|
- `background-task` —— base-tool-enhance 后台任务 `registry.json` 文件契约
|
|
15
21
|
- 子出口 `@zhushanwen/extension-protocol/background-task` —— 后台任务行为原语(进程处置 / registry 文件 IO / output tail,含 node 内建依赖,不进 index 桶出口)
|
package/dist/index.d.ts
CHANGED
|
@@ -183,27 +183,45 @@ interface PlanDocMeta {
|
|
|
183
183
|
/**
|
|
184
184
|
* submit-review 挂起审批时的 select payload(序列化为 options[0] JSON)。
|
|
185
185
|
* extension 侧解析失败走 E5(logger.warn + tool result 报错提示重挂,垃圾数据不进对话流)。
|
|
186
|
+
*
|
|
187
|
+
* selfReview(自审结论,D9①③):agent 提交审批前的自审摘要,投影面到审批请求帧为止
|
|
188
|
+
* (不进 PlanStateView / session.planState 帧);有界性由写侧 4KB 单点截断保证
|
|
189
|
+
* (canonical 上限与截断 = src/extensions/plan/review-contract.ts,R3)。**optional 是兼容契约**:
|
|
190
|
+
* 旧扩展不携带 → 宿主自审行不渲染的降级形态;submit-review 的必填硬门在 tool 层执行
|
|
191
|
+
* (缺失/空 → tool result 错误纠偏,不 throw),wire 帧不设必填。
|
|
186
192
|
*/
|
|
187
193
|
interface PlanReviewRequest {
|
|
188
194
|
docs: PlanDocMeta[];
|
|
195
|
+
selfReview?: string;
|
|
189
196
|
}
|
|
190
|
-
/**
|
|
191
|
-
|
|
197
|
+
/**
|
|
198
|
+
* 审批三键裁决(D3):approve 确认执行 / revise 提交修订(必带评论)/ dismiss 搁置
|
|
199
|
+
* (非破坏:不杀 turn、不丢状态,计划进度保留)。revise 携带评论、approve/dismiss
|
|
200
|
+
* 不携带(结构上不可混带)。值域守卫 canonical 版 = src/extensions/plan/review-contract.ts
|
|
201
|
+
* (运行时判别 TS 穷尽性管不到——未知值域降级语义见该模块「降级双分源」)。
|
|
202
|
+
*/
|
|
203
|
+
type PlanReviewDecision = 'approve' | 'revise' | 'dismiss';
|
|
192
204
|
/** 用户对某文档划选段落的一条评论:quote 是划选引文(agent 定位段落用),comment 是评语。 */
|
|
193
205
|
interface PlanReviewComment {
|
|
194
206
|
quote: string;
|
|
195
207
|
comment: string;
|
|
196
208
|
}
|
|
197
209
|
/**
|
|
198
|
-
* 审批条 respond 回传(判别联合:approve 无评论字段,revise 必带评论数组)。
|
|
199
|
-
* extension 消费:approve →
|
|
200
|
-
*
|
|
210
|
+
* 审批条 respond 回传(判别联合:approve/dismiss 无评论字段,revise 必带评论数组)。
|
|
211
|
+
* extension 消费:approve → 走 complete 执行方式 select(transfer:reviewing→dispatching);
|
|
212
|
+
* revise → 评论清单以显式 deliverAs:'steer' 注入 + 转移 reviewing→revising;
|
|
213
|
+
* dismiss(D3 搁置)→ 转移 reviewing→planning 落盘,tool result 告知 agent「用户搁置了
|
|
214
|
+
* 本次审阅:plan 模式保持、文档与进度不变;简短告知用户已搁置并询问下一步,不要实施改动」。
|
|
215
|
+
* 未知 decision 值域降级 = 版本错配信号:与 malformed 同款 bad-response 出口引导重挂,
|
|
216
|
+
* 消费方额外 logger.warn 留痕(D3①)——判别与降级枚举见 src/extensions/plan/review-contract.ts。
|
|
201
217
|
*/
|
|
202
218
|
type PlanReviewResponse = {
|
|
203
219
|
decision: 'approve';
|
|
204
220
|
} | {
|
|
205
221
|
decision: 'revise';
|
|
206
222
|
comments: PlanReviewComment[];
|
|
223
|
+
} | {
|
|
224
|
+
decision: 'dismiss';
|
|
207
225
|
};
|
|
208
226
|
|
|
209
227
|
/**
|
|
@@ -374,18 +392,18 @@ declare function firstContentText(result: {
|
|
|
374
392
|
/**
|
|
375
393
|
* select+marker 通道 RPC 原语(D8)。
|
|
376
394
|
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
395
|
+
* 消费方(session-manager / subagent-workflow inflight-reporter)各自手写过
|
|
396
|
+
* 「ctx.ui.select(marker, [payload], opts) + 失败折叠 + JSON 检测」传输核,
|
|
379
397
|
* 形态同构、留痕/超时策略各异。本原语只收敛传输核与失败折叠契约,真差异留在调用方:
|
|
380
398
|
*
|
|
381
399
|
* - 判别结果而非抛错(调用方统一按 reason 折叠 isError / 重试);
|
|
382
400
|
* - 回包只做 JSON 合法性检测(`non-json` 判别 + 留痕),parsed 结果的消费留调用方——
|
|
383
|
-
* value 恒 raw string(session-manager raw 透传 /
|
|
384
|
-
*
|
|
401
|
+
* value 恒 raw string(session-manager raw 透传 / inflight ack 全等匹配,回包消费
|
|
402
|
+
* 是真差异,不进原语);
|
|
385
403
|
* - payload 调用方已序列化(原语不 stringify——各协议序列化形状各异:嵌套
|
|
386
|
-
* {action,params} /
|
|
387
|
-
* - mode
|
|
388
|
-
*
|
|
404
|
+
* {action,params} / 快照帧,不引入内部 stringify 异常面);
|
|
405
|
+
* - mode 门控留调用方(inflight 在 attachSession 处 / session-manager 无门控——
|
|
406
|
+
* 四态 reason 无 non-rpc 语义);
|
|
389
407
|
* - `ui.select` 缺席(非 GUI ctx)由调用方前置判定(沿 ask-user askUserInteract 的
|
|
390
408
|
* `isGuiCapable(ctx) && ctx.ui?.select` 先例);误用即 throw 明确错误。
|
|
391
409
|
*
|
|
@@ -409,9 +427,9 @@ interface MarkerRpcOptions {
|
|
|
409
427
|
* 日志策略(级别 / 前缀 / 防刷屏)归调用方——真差异保留。 */
|
|
410
428
|
log?: (msg: string, detail?: object) => void;
|
|
411
429
|
}
|
|
412
|
-
/** 错误回包底层形状:select+marker 通道各协议(
|
|
430
|
+
/** 错误回包底层形状:select+marker 通道各协议(session-manager)
|
|
413
431
|
* runtime 侧异常折叠的共用单源(不裸 reject,error 闭环走同一回包通道)。
|
|
414
|
-
*
|
|
432
|
+
* SessionManagerErrorResult 是本形状的 alias(D8 单源化)。 */
|
|
415
433
|
interface ChannelErrorResult {
|
|
416
434
|
error: string;
|
|
417
435
|
hint?: string;
|
|
@@ -803,6 +821,183 @@ declare function isScheduleFormResult(value: unknown): value is ScheduleFormResu
|
|
|
803
821
|
declare function dateToOnceCron(date: Date): string;
|
|
804
822
|
declare function onceCronToDate(cron: string, now?: Date): Date | null;
|
|
805
823
|
|
|
824
|
+
/**
|
|
825
|
+
* plan 模式生命周期状态机(plan 模式状态机显式化 D1)——纯数据 + 纯函数,零依赖。
|
|
826
|
+
*
|
|
827
|
+
* plan 模式的状态散落在 pi 扩展 entry / runtime 挂起注册表 / renderer 派生公式三处时,
|
|
828
|
+
* 任意两者漂移即产「僵尸/谎言」UI(F1-F5)。本模块是全链路共享的单一状态契约:
|
|
829
|
+
* 8 值状态集 + 9 事件边表 + `transition` 纯函数(守卫集中一处)+ `derivePhase` 呈现映射。
|
|
830
|
+
*
|
|
831
|
+
* 语义要点(设计 D1 逐条锚定):
|
|
832
|
+
* - 非法转移返回 `{ ok: false }`,由调用方降级(**不 throw 炸 turn**);副作用不进返回值
|
|
833
|
+
* (effects-as-data 无已登记消费方属投机间接层),各 action 在转移成功后内联执行自身副作用。
|
|
834
|
+
* - `reviewing --dismiss--> planning`:用户「搁置」(协议级 dismiss 决策,D3)——落盘即
|
|
835
|
+
* planning,被搁置的审批不复活(F1/F2/F3 构造性消除)。
|
|
836
|
+
* - `reviewing --review_aborted--> planning`:挂起期外部 turn abort / TUI 取消(D3 连带)。
|
|
837
|
+
* - `dispatching --review_aborted--> approved`:批准事实保留——任一「无选择解散」出口
|
|
838
|
+
* (外部 turn abort 级联 / 表单取消 / 超时 / 交互通道故障折叠)统一落 approved,
|
|
839
|
+
* 不把「已批准」打回规划期(F5 不复活)。
|
|
840
|
+
* - `dispatching --later--> approved`:用户显式选「暂不执行」——是明确选择不是解散,
|
|
841
|
+
* 不得进 review_aborted 文案桶(A9 反向)。
|
|
842
|
+
* - `dispatching --exec_chosen--> completed`:选定执行方式并派发执行(终态)。
|
|
843
|
+
* - `approved --approve--> dispatching`:批准后 agent 再调 `complete` 重新选择执行方式
|
|
844
|
+
* (D1「approved 上 agent 再调 complete → dispatching」)。事件命名裁决:9 事件表无
|
|
845
|
+
* `complete` 员,本边取「执行确认」语义族最近员 `approve`(用户点确认执行与批准后重选
|
|
846
|
+
* 执行方式同为「确认执行、进入执行方式选择」的决策事件)——消费面接线见 consumers.md。
|
|
847
|
+
* - `approved` 其余转移仅 `exit`;活跃族非终态 `--exit--> exited`;idle 从未进入,
|
|
848
|
+
* exit 非法(防从未进 plan 的会话落噪音 exited entry);终态 `--enter--> planning`
|
|
849
|
+
* (新一轮);`revising` 保留独立态(E3 恢复文案分叉依赖,前提 P-7)。
|
|
850
|
+
* - `reviewing --submit--> reviewing`:审批重挂自环(E3 会话重启恢复 / D8「重新提交审批」
|
|
851
|
+
* 按钮——重提交不推进生命周期,落盘回 reviewing 重挂即等价于旧调用方特判放行形态)。
|
|
852
|
+
*
|
|
853
|
+
* 呈现映射(derivePhase):用户视角四主态 + idle 缺省——四主态是呈现,不是存储
|
|
854
|
+
* (用户口述模型 = 呈现层,reviewing/dispatching 两个挂起态是崩溃恢复的真实分叉点,
|
|
855
|
+
* 存储层保留 8 值)。终态两值(completed = 批准并派发执行 / exited = 主动退出)共享
|
|
856
|
+
* 全部终态规则,呈现层同映 'terminal'(诊断/审计语义保留存储区分)。
|
|
857
|
+
*/
|
|
858
|
+
type PlanLifecycleState = 'idle' | 'planning' | 'reviewing' | 'revising' | 'approved' | 'dispatching' | 'completed' | 'exited';
|
|
859
|
+
/** 状态穷举表(运行时消费:E3 恢复查表 / 测试穷举基座)——顺序 = 生命周期自然序。 */
|
|
860
|
+
declare const PLAN_LIFECYCLE_STATES: readonly ["idle", "planning", "reviewing", "revising", "approved", "dispatching", "completed", "exited"];
|
|
861
|
+
type PlanLifecycleEvent = 'enter' | 'submit' | 'revise' | 'dismiss' | 'review_aborted' | 'approve' | 'exec_chosen' | 'later' | 'exit';
|
|
862
|
+
/** 事件穷举表——顺序 = 设计 D1 枚举序。 */
|
|
863
|
+
declare const PLAN_LIFECYCLE_EVENTS: readonly ["enter", "submit", "revise", "dismiss", "review_aborted", "approve", "exec_chosen", "later", "exit"];
|
|
864
|
+
type PlanTransitionResult = {
|
|
865
|
+
ok: true;
|
|
866
|
+
next: PlanLifecycleState;
|
|
867
|
+
} | {
|
|
868
|
+
ok: false;
|
|
869
|
+
};
|
|
870
|
+
/**
|
|
871
|
+
* 纯函数转移:`(state, event) → { ok: true, next } | { ok: false }`。
|
|
872
|
+
*
|
|
873
|
+
* 非法转移(含运行时垃圾 state/event 值——跨版本帧、坏反序列化)返回 `{ ok: false }`
|
|
874
|
+
* 且**不携带 next 键**,由调用方降级(不 throw 炸 turn)。调用方义务:`ok:false` 时
|
|
875
|
+
* 不落盘、不执行副作用(终态上 `ok:false` 不落盘即 D3 归口点的兜底保险)。
|
|
876
|
+
*
|
|
877
|
+
* 入口白名单守卫(与 derivePhase 同一机制):普通对象字面量查表会沿原型链命中继承键——
|
|
878
|
+
* `transition('reviewing', '__proto__')` 取出 Object.prototype、`('__proto__', 'valueOf')`
|
|
879
|
+
* 取出函数,均被误判为合法 next(违背本契约)。故垃圾键必须先挡在查表前。
|
|
880
|
+
* **选「枚举 includes 白名单」而非 null-prototype 表 / Object.hasOwn**:① transition 与
|
|
881
|
+
* derivePhase 共用同一守卫形态(单一机制,不并存两种写法);② PLAN_LIFECYCLE_STATES /
|
|
882
|
+
* PLAN_LIFECYCLE_EVENTS 就是值域 SSOT(测试穷举同源),includes 判定与之同源,
|
|
883
|
+
* 原型键天然不在白名单内。
|
|
884
|
+
*/
|
|
885
|
+
declare function transition(state: PlanLifecycleState, event: PlanLifecycleEvent): PlanTransitionResult;
|
|
886
|
+
/**
|
|
887
|
+
* 用户视角呈现相位(四主态 + idle):
|
|
888
|
+
* - 'planning'(规划中)= planning | revising
|
|
889
|
+
* - 'reviewing'(待审批)= reviewing
|
|
890
|
+
* - 'approved'(已批准)= approved | dispatching(dispatching 呈「③审阅确认 · 已完成」,
|
|
891
|
+
* 阶段不倒退——F5 修正;细化渲染由消费方查 state,不另造相位)
|
|
892
|
+
* - 'terminal'(终态)= completed | exited(两值同映,区分只留存储/审计层)
|
|
893
|
+
* - 'idle'(无 plan)= idle
|
|
894
|
+
*/
|
|
895
|
+
type PlanPhase = 'idle' | 'planning' | 'reviewing' | 'approved' | 'terminal';
|
|
896
|
+
/**
|
|
897
|
+
* 8 存储态 → 5 呈现相位的单点映射(renderer 阶段指示/状态带共用,禁止消费方各自 if 拼)。
|
|
898
|
+
* 运行时垃圾 state(混装格坏帧)降级 'idle'(无 plan 缺省,fail-safe 不误示进行中)。
|
|
899
|
+
*
|
|
900
|
+
* 入口白名单守卫(理由同 transition,见彼处):裸查表对继承键 'constructor' / 'toString'
|
|
901
|
+
* 会取出 Object 构造函数等并经 `?? 'idle'` 流出(非 nullish 不落兜底)——垃圾 state
|
|
902
|
+
* 必须精确落 'idle',函数/对象不得作为相位流入 renderer。
|
|
903
|
+
*/
|
|
904
|
+
declare function derivePhase(state: PlanLifecycleState): PlanPhase;
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* plan 审阅回传值域契约(plan 模式状态机显式化 D3①⑤ / D9③)——纯函数守卫,零依赖。
|
|
908
|
+
*
|
|
909
|
+
* 为什么守卫是契约级承重:TS 判别联合的穷尽性(switch/never 断言)管不到运行时值域——
|
|
910
|
+
* respond 通道透传的是任意字符串 parse 出的 unknown(P-2),值域守卫漏改即「搁置应答被判
|
|
911
|
+
* 垃圾 → bad-response 引导重挂」再入循环(F1 复活路径)。canonical 守卫与判别联合同住
|
|
912
|
+
* 契约包,消费面(extensions/universal/plan tool.ts)接线见同目录 consumers.md。
|
|
913
|
+
*
|
|
914
|
+
* 降级双分源(D3①)——parse 失败必须区分两类(envelope 判别保留),消费面出口同款:
|
|
915
|
+
* - `unknown-decision`(对象合法但 decision 不在值域):版本错配信号(R2),消费方
|
|
916
|
+
* 额外 logger.warn 留痕;出口与文案与 malformed 同款——bad-response 报错提示重挂。
|
|
917
|
+
* 裁决与重审触发(候选替代 = 恢复独立 version-mismatch 不重挂出口)登记于消费方
|
|
918
|
+
* extensions/universal/plan/src/tool.ts「条目 7 降级」注释段。
|
|
919
|
+
* - `malformed`(非对象 / 缺 decision / 形状不合法):垃圾数据(E5 判据),bad-response
|
|
920
|
+
* 报错提示重挂。
|
|
921
|
+
*
|
|
922
|
+
* selfReview 有界字段(D9③ / R3):有界性由**写侧单点截断**保证(截断点 = 扩展 payload
|
|
923
|
+
* 构造处),4KB 上限与 UTF-8 字节界安全截断的唯一权威在本模块;透传层(runtime)不截、
|
|
924
|
+
* 入站守卫不二次截(上限已在写侧达成)。
|
|
925
|
+
*/
|
|
926
|
+
|
|
927
|
+
/** selfReview 上限:4KB(UTF-8 字节)。超限即截(全文可要求 agent 贴对话流,R3)。 */
|
|
928
|
+
declare const PLAN_SELF_REVIEW_MAX_BYTES = 4096;
|
|
929
|
+
/**
|
|
930
|
+
* selfReview 写侧单点截断:按 UTF-8 字节预算截到**完整码点边界**(多字节字符不截半,
|
|
931
|
+
* 无替换字符噪音)。预算内原样返回;不追加省略号(消费方渲染时自行提示截断)。
|
|
932
|
+
*/
|
|
933
|
+
declare function truncateSelfReview(text: string): string;
|
|
934
|
+
/**
|
|
935
|
+
* `PlanReviewRequest` 形状守卫(E5 垃圾数据判据):
|
|
936
|
+
* docs 必为 `PlanDocMeta[]`(逐项形状);selfReview 缺省或 string——**optional 是兼容契约**
|
|
937
|
+
* (旧扩展不携带 → 自审行不渲染的降级形态,D9③),值域上限不在此拒绝(写侧截断已界)。
|
|
938
|
+
* 空载荷(undefined/null/非对象/缺 docs)与非法形态(docs 非数组 / 元素形状不合法 /
|
|
939
|
+
* selfReview 非 string)一律 false,不 throw。
|
|
940
|
+
*/
|
|
941
|
+
declare function isPlanReviewRequest(value: unknown): value is PlanReviewRequest;
|
|
942
|
+
/**
|
|
943
|
+
* respond 回传解析结果(error envelope 单源):
|
|
944
|
+
* - ok:归一化后的合法 `PlanReviewResponse`(多余键已剥——approve/dismiss 不携带评论是
|
|
945
|
+
* 结构保证,不信任宿主回传的附加形态)。
|
|
946
|
+
* - `unknown-decision`:decision 是 string 但不在值域 → 版本错配信号(消费方额外
|
|
947
|
+
* logger.warn 留痕;出口与 malformed 同款 bad-response 引导重挂,见文件头「降级双分源」)。
|
|
948
|
+
* - `malformed`:空载荷 / 非对象 / 形状不合法 → E5 判据,报错提示重挂。
|
|
949
|
+
*/
|
|
950
|
+
type PlanReviewResponseEnvelope = {
|
|
951
|
+
ok: true;
|
|
952
|
+
response: PlanReviewResponse;
|
|
953
|
+
} | {
|
|
954
|
+
ok: false;
|
|
955
|
+
code: 'unknown-decision';
|
|
956
|
+
decision: string;
|
|
957
|
+
} | {
|
|
958
|
+
ok: false;
|
|
959
|
+
code: 'malformed';
|
|
960
|
+
};
|
|
961
|
+
/**
|
|
962
|
+
* respond 回传解析(值域守卫的判别版):dismiss 样本必通(D3 主干),未知 decision 值域
|
|
963
|
+
* 落降级枚举而非垃圾(两类降级可判别分离;消费面出口同款引导重挂,见文件头「降级双分源」)。
|
|
964
|
+
*/
|
|
965
|
+
declare function parsePlanReviewResponse(value: unknown): PlanReviewResponseEnvelope;
|
|
966
|
+
/**
|
|
967
|
+
* `PlanReviewResponse` 值域守卫(含 dismiss 员,D3①)——`parsePlanReviewResponse` 的谓词形。
|
|
968
|
+
* 消费方需要区分 unknown-decision / malformed 两类降级时用 parse 版。
|
|
969
|
+
*/
|
|
970
|
+
declare function isPlanReviewResponse(value: unknown): value is PlanReviewResponse;
|
|
971
|
+
|
|
972
|
+
/**
|
|
973
|
+
* plan-state entry 的 customType(pi appendEntry custom entry 判别键)。磁盘形态冻结:
|
|
974
|
+
* 扩展写读两侧(persistPlanState / isPlanStateEntry)与 runtime 投影链(plan-state-extractor /
|
|
975
|
+
* session-records)均消费本常量,值同源——改值即历史会话全部失联,禁改(冻结锚测试见
|
|
976
|
+
* 本目录 legacy-entries.test.ts)。
|
|
977
|
+
*/
|
|
978
|
+
declare const PLAN_STATE_CUSTOM_TYPE = "plan-state";
|
|
979
|
+
/**
|
|
980
|
+
* 生命周期状态读取(D2 读方①②共用映射,原扩展 state.ts / runtime extractor 内联拷贝的
|
|
981
|
+
* 单源归并):
|
|
982
|
+
* ① 新字段直读(值域守卫:PLAN_LIFECYCLE_STATES 之外的垃圾值按缺失处理,落映射——
|
|
983
|
+
* 不信任外部写入);
|
|
984
|
+
* ② 旧 entry 无 state(或垃圾 state)时映射 reviewState(awaiting→reviewing /
|
|
985
|
+
* revising→revising / 其余值→planning|idle 按 isActive)。
|
|
986
|
+
*/
|
|
987
|
+
declare function readLifecycleState(data: {
|
|
988
|
+
state?: unknown;
|
|
989
|
+
reviewState?: unknown;
|
|
990
|
+
}, isActive: boolean): PlanLifecycleState;
|
|
991
|
+
/**
|
|
992
|
+
* resumeHint 读取(D2 读方①②共用映射):新字段直读(只认 'resubmit' 一字面量)+
|
|
993
|
+
* 旧 reviewStateSource 同义映射('explain' 等存量值归无值——explain 交互已删);
|
|
994
|
+
* resumeHint 存在但非法(垃圾值)时不挡 reviewStateSource 映射(与原两份拷贝逐字同构)。
|
|
995
|
+
*/
|
|
996
|
+
declare function readResumeHint(data: {
|
|
997
|
+
resumeHint?: unknown;
|
|
998
|
+
reviewStateSource?: unknown;
|
|
999
|
+
}): 'resubmit' | undefined;
|
|
1000
|
+
|
|
806
1001
|
/**
|
|
807
1002
|
* 统一提问表单协议(ui-form)的类型定义。
|
|
808
1003
|
*
|
|
@@ -1234,8 +1429,7 @@ interface SubagentInFlightReport {
|
|
|
1234
1429
|
inFlight: number;
|
|
1235
1430
|
/**
|
|
1236
1431
|
* 上报所属 session(ctx.sessionManager.getSessionId())。pi 延迟写入窗口内可能取
|
|
1237
|
-
*
|
|
1238
|
-
* (不镜像),不视为协议错误。
|
|
1432
|
+
* 不到——缺席时消费方按无法归属丢弃整帧(不镜像),不视为协议错误。
|
|
1239
1433
|
*/
|
|
1240
1434
|
sessionId?: string;
|
|
1241
1435
|
/** 产生时点(ms epoch,pi 进程内取值)。诊断/乱序排查用,消费方不依赖其单调性。 */
|
|
@@ -1273,6 +1467,92 @@ declare function isInFlightReportAck(v: unknown): v is typeof INFLIGHT_REPORT_AC
|
|
|
1273
1467
|
*/
|
|
1274
1468
|
declare const SUBAGENT_INFLIGHT_MARKER = "\0TAIJI_SUBAGENT_INFLIGHT";
|
|
1275
1469
|
|
|
1470
|
+
/**
|
|
1471
|
+
* journal 事件推送的类型定义(event-push-channel 协议面)。
|
|
1472
|
+
*
|
|
1473
|
+
* 契约两端:
|
|
1474
|
+
* - 写侧(生产):@zhushanwen/pi-subagent-workflow 壳层(src/host/journal-reporter.ts)
|
|
1475
|
+
* 监听 subagent-core 的 journal 落盘出口回调(notifyJournalAppended),经 select
|
|
1476
|
+
* 通道带回执推送;
|
|
1477
|
+
* - 读侧(消费):taiji runtime event-adapter 的 marker 路由分支 → journal-report-router
|
|
1478
|
+
* → SessionEventProjection(applyJournalReport:seq 缺口判定 → 缺口触发本地补读 → fold)。
|
|
1479
|
+
*
|
|
1480
|
+
* 语义锚点(设计 §3.3):推送报告只携带事件本体(事件信封自带 seq),不另设水位协商
|
|
1481
|
+
* ——消费方 per 文件持两个水位(字节偏移 = 补读起点、已折叠最大 seq = 去重判据),
|
|
1482
|
+
* 重复投递由域 fold 的 seq 单调检查构造性幂等。确认回执 = runtime 同步 fold 应用后
|
|
1483
|
+
* resolve(回执 = 「已应用」而非「已接收」)。
|
|
1484
|
+
*/
|
|
1485
|
+
/** journal 两域(单 marker 载荷判别字段——设计 §3.4 D2:两域推送方/接收方/通道语义同构,不拆双 marker)。 */
|
|
1486
|
+
type SubagentJournalDomain = 'run' | 'record';
|
|
1487
|
+
/**
|
|
1488
|
+
* 单条 journal 事件(run 域 = run journal 行 / record 域 = record 事件行——域内
|
|
1489
|
+
* 词表校验归读侧与文件行同一解析器,本层只校验跨域共同信封)。
|
|
1490
|
+
*/
|
|
1491
|
+
interface SubagentJournalEvent {
|
|
1492
|
+
/** 事件类型(域词表成员资格由读侧按域校验)。 */
|
|
1493
|
+
type: string;
|
|
1494
|
+
/** 事件时点(ms epoch;信封必填)。 */
|
|
1495
|
+
ts: number;
|
|
1496
|
+
/**
|
|
1497
|
+
* journal 行序号(写入方 JsonlEventStream.append 统一分配)。缺省 = W1 前存量
|
|
1498
|
+
* 无 seq 行(设计 §3.3 兼容条款:无 seq 事件不参与缺口判定,fold 按状态机语义幂等)。
|
|
1499
|
+
*/
|
|
1500
|
+
seq?: number;
|
|
1501
|
+
/** 域内载荷字段原样透传(写侧 = 刚落盘的行对象,无二次塑形)。 */
|
|
1502
|
+
[key: string]: unknown;
|
|
1503
|
+
}
|
|
1504
|
+
/**
|
|
1505
|
+
* 单帧 journal 事件报告(pi 进程 → runtime,经 select 通道,title = SUBAGENT_JOURNAL_MARKER,
|
|
1506
|
+
* options = [JSON.stringify(本形状)])。单帧只覆盖一个文件(fileKey 单数——设计 §3.4:
|
|
1507
|
+
* fileKey = runId 或 sa-id;多文件积压由写侧按组逐帧发送)。
|
|
1508
|
+
*/
|
|
1509
|
+
interface SubagentJournalReport {
|
|
1510
|
+
/** 事件所属域(run / record 判别)。 */
|
|
1511
|
+
domain: SubagentJournalDomain;
|
|
1512
|
+
/** 文件键:run 域 = runId,record 域 = record id(sa-id)。 */
|
|
1513
|
+
fileKey: string;
|
|
1514
|
+
/** 本帧事件(写入序;写侧落盘提交点之后的增量批次)。 */
|
|
1515
|
+
events: SubagentJournalEvent[];
|
|
1516
|
+
/**
|
|
1517
|
+
* 上报所属 session(ctx.sessionManager.getSessionId())。pi 延迟写入窗口内可能取
|
|
1518
|
+
* 不到——缺席时消费方按无法归属丢弃整帧(不 fold 不 ack),不视为协议错误
|
|
1519
|
+
* (归属权威 = 连接的 sessionId,本字段只作在场性判据——inflight 同款先例)。
|
|
1520
|
+
*/
|
|
1521
|
+
sessionId?: string;
|
|
1522
|
+
/** 产生时点(ms epoch,pi 进程内取值)。诊断/乱序排查用,消费方不依赖其单调性。 */
|
|
1523
|
+
emittedAt: number;
|
|
1524
|
+
}
|
|
1525
|
+
/**
|
|
1526
|
+
* select 通道的确认回包(runtime event-adapter 处理完帧后 resolve 给 pi 侧的
|
|
1527
|
+
* JSON 字符串)。回执语义 = 「已应用」(runtime 同步完成 fold 应用后 resolve,
|
|
1528
|
+
* 设计 §3.4 D7 生效回执)——写侧非本字符串即未确认:首败 warn 留证 + 缓冲丢弃
|
|
1529
|
+
* 不重推(完整性由消费方 seq 缺口补读收敛,设计 §3.3 D5)。
|
|
1530
|
+
*/
|
|
1531
|
+
declare const JOURNAL_REPORT_ACK: "{\"ack\":true}";
|
|
1532
|
+
/**
|
|
1533
|
+
* SubagentJournalReport 形状守卫:domain 落两域词表、fileKey 非空串、events 逐条
|
|
1534
|
+
* 过信封守卫、sessionId 缺席或 string。event-adapter 路由分支消费;非法帧返回
|
|
1535
|
+
* false(调用方丢弃,不 fold 不 ack)。
|
|
1536
|
+
*/
|
|
1537
|
+
declare function isSubagentJournalReport(v: unknown): v is SubagentJournalReport;
|
|
1538
|
+
/** 确认回包形状守卫(pi 侧 reporter 消费——非本字符串即未确认)。 */
|
|
1539
|
+
declare function isJournalReportAck(v: unknown): v is typeof JOURNAL_REPORT_ACK;
|
|
1540
|
+
|
|
1541
|
+
/**
|
|
1542
|
+
* journal 事件推送的 title marker。runtime event-adapter 检测此 marker 区分
|
|
1543
|
+
* journal 事件报告与普通 select;pi 侧壳层(@zhushanwen/pi-subagent-workflow 的
|
|
1544
|
+
* host/journal-reporter)经同一 marker 以带回执语义推送 SubagentJournalReport
|
|
1545
|
+
* 帧(单一来源,两端口径必然一致)。
|
|
1546
|
+
*
|
|
1547
|
+
* NUL 前缀确保不会与 extension 正常的 select title 冲突。
|
|
1548
|
+
* 与 SUBAGENT_INFLIGHT_MARKER / ASK_USER_MARKER / SESSION_MANAGER_MARKER 同理。
|
|
1549
|
+
*
|
|
1550
|
+
* 设计权威源:.tmp/tech-design/event-push-channel.md §3.1/§3.4(journal 写入方
|
|
1551
|
+
* subagent-core 在落盘提交点经本 marker 通道把新事件批量推给 runtime,通道数量
|
|
1552
|
+
* = 1 个,载荷内 domain 字段判别 run/record 两域)。
|
|
1553
|
+
*/
|
|
1554
|
+
declare const SUBAGENT_JOURNAL_MARKER = "\0TAIJI_SUBAGENT_JOURNAL";
|
|
1555
|
+
|
|
1276
1556
|
/**
|
|
1277
1557
|
* subagent-workflow 通知通道的 custom_message customType 词表(单源)。
|
|
1278
1558
|
*
|
|
@@ -1305,99 +1585,6 @@ declare const SUBAGENT_BG_NOTIFY_CUSTOM_TYPE: "subagent-bg-notify";
|
|
|
1305
1585
|
* 上下文 + renderer 定向气泡)。shared parseSubagentDirective / runtime display 覆写消费。 */
|
|
1306
1586
|
declare const SUBAGENT_DIRECTIVE_CUSTOM_TYPE: "subagent-directive";
|
|
1307
1587
|
|
|
1308
|
-
/**
|
|
1309
|
-
* plugin-bridge 请求的 title marker。runtime event-adapter 和 pi 侧
|
|
1310
|
-
* bridge extension(@zhushanwen/pi-plugin-bridge)双端消费此 marker,
|
|
1311
|
-
* 在 select 通道上区分 bridge 帧与普通 select(单一来源,两端口径必然一致)。
|
|
1312
|
-
*
|
|
1313
|
-
* NUL 前缀确保不会与 extension 正常的 select title 冲突。
|
|
1314
|
-
* 与 ASK_USER_MARKER / SESSION_MANAGER_MARKER / GUI_WIDGET_MARKER 同理。
|
|
1315
|
-
*/
|
|
1316
|
-
declare const BRIDGE_MARKER = "\0TAIJI_BRIDGE";
|
|
1317
|
-
/**
|
|
1318
|
-
* 协议 v2 的 4 个 method 运行时集合(与 BridgeMethod 类型同源——types.ts 从此派生)。
|
|
1319
|
-
* event-adapter 用它校验 marker 帧的 method 合法性,
|
|
1320
|
-
* 非法值折叠为 'bridge:malformed' 哨兵(handler 回 malformed 错误,不静默丢弃)。
|
|
1321
|
-
*/
|
|
1322
|
-
declare const BRIDGE_METHODS: readonly ["bridge:sync", "bridge:tool_execute", "bridge:event", "bridge:intercept"];
|
|
1323
|
-
|
|
1324
|
-
/**
|
|
1325
|
-
* plugin-bridge 协议 v2 的类型定义。
|
|
1326
|
-
*
|
|
1327
|
-
* select + BRIDGE_MARKER 通道上的请求/回包形状,pi 侧 bridge extension
|
|
1328
|
-
* (序列化发送方)与 runtime bridge-handler(解析与回包方)共用。
|
|
1329
|
-
* 向后不兼容旧 bridge:* method 承载(旧链路本来就不通,改名无收益)。
|
|
1330
|
-
* marker 检测后按 method 分发到对应 handler 分支。
|
|
1331
|
-
*/
|
|
1332
|
-
|
|
1333
|
-
/** 协议 v2 的 4 个 method(从 BRIDGE_METHODS 集合派生,值与类型同源) */
|
|
1334
|
-
type BridgeMethod = (typeof BRIDGE_METHODS)[number];
|
|
1335
|
-
/** bridge 请求的统一形状(pi bridge extension → runtime via select 通道) */
|
|
1336
|
-
interface BridgeRequest {
|
|
1337
|
-
method: BridgeMethod;
|
|
1338
|
-
/** tool_execute 专属:工具名 */
|
|
1339
|
-
toolName?: string;
|
|
1340
|
-
/** tool_execute 专属:工具调用 id */
|
|
1341
|
-
toolCallId?: string;
|
|
1342
|
-
/** tool_execute 专属:工具入参 */
|
|
1343
|
-
params?: Record<string, unknown>;
|
|
1344
|
-
/** 发起请求的 session(tool_execute/event/intercept 携带,供 runtime 按 session 路由
|
|
1345
|
-
* 防跨 session 串台;bridge:sync 全局快照请求不带) */
|
|
1346
|
-
sessionId?: string;
|
|
1347
|
-
/** event / intercept 专属:pi 原生事件名 */
|
|
1348
|
-
eventName?: string;
|
|
1349
|
-
/** event / intercept 专属:事件负载 */
|
|
1350
|
-
data?: unknown;
|
|
1351
|
-
}
|
|
1352
|
-
/** tool_execute 回包:插件工具执行结果 */
|
|
1353
|
-
interface BridgeToolExecuteResponse {
|
|
1354
|
-
content: string;
|
|
1355
|
-
isError?: boolean;
|
|
1356
|
-
}
|
|
1357
|
-
/** sync 回包:工具清单快照(pi 侧命令发现不走本协议,另走 getCommands 通路) */
|
|
1358
|
-
interface BridgeSyncPayload {
|
|
1359
|
-
tools: Array<{
|
|
1360
|
-
name: string;
|
|
1361
|
-
description: string;
|
|
1362
|
-
parameters: Record<string, unknown>;
|
|
1363
|
-
}>;
|
|
1364
|
-
success: true;
|
|
1365
|
-
}
|
|
1366
|
-
/** intercept 回包:before_agent_start 拦截决策(bridge 侧把 injectedMessages 映射为单条 CustomMessage) */
|
|
1367
|
-
interface BridgeInterceptResponse {
|
|
1368
|
-
blocked?: boolean;
|
|
1369
|
-
reason?: string;
|
|
1370
|
-
injectedMessages: unknown[];
|
|
1371
|
-
}
|
|
1372
|
-
/** 错误回包:runtime 侧异常折叠(不裸 reject;bridge 侧解析后以 isError 返回)。
|
|
1373
|
-
* D8 单源化:底层形状 alias 到 core 的 ChannelErrorResult(导出名与文件位置不变,
|
|
1374
|
-
* public API 零破坏)。 */
|
|
1375
|
-
type BridgeErrorResponse = ChannelErrorResult;
|
|
1376
|
-
|
|
1377
|
-
/**
|
|
1378
|
-
* plugin-bridge 回包形状守卫族(D11 自 extensions/taiji/plugin-bridge index.ts 零改动迁入)。
|
|
1379
|
-
*
|
|
1380
|
-
* 「marker + types + 守卫」同住惯例(session-manager / subagent-inflight 先例):
|
|
1381
|
-
* 回包形状的运行时检测与类型定义同源维护。当前唯一消费方 = pi 侧 bridge
|
|
1382
|
-
* extension;runtime bridge-handler 的 5 处 `as string` 断言是后续批次的第二
|
|
1383
|
-
* 消费方(换校验的铺路,设计 D11 登记项)。
|
|
1384
|
-
*
|
|
1385
|
-
* isRecord 为模块内私有副本(排数组严版——与 subagent-inflight / session-manager
|
|
1386
|
-
* 副本同款同义):protocol 不依赖 extensions 层的 ext-guards(分层边界裁决,D3
|
|
1387
|
-
* 明确排除),包内三份私有副本并存是裁决下的既有惯例,语义必须一致。
|
|
1388
|
-
*
|
|
1389
|
-
* 设计权威源:docs/architecture/ext-simplify-17-shared-extraction.md §3.3 D11。
|
|
1390
|
-
*/
|
|
1391
|
-
|
|
1392
|
-
/** runtime 错误闭环形状 {error, hint?}(设计 §3.3-D1:不裸 reject)——检测逻辑单源于
|
|
1393
|
-
* core 的 isChannelErrorResult(D8),本名保留为守卫族整体成员(D11 迁移) */
|
|
1394
|
-
declare function isBridgeErrorResponse(v: unknown): v is BridgeErrorResponse;
|
|
1395
|
-
declare function isBridgeToolExecuteResponse(v: unknown): v is BridgeToolExecuteResponse;
|
|
1396
|
-
declare function isBridgeSyncPayload(v: unknown): v is BridgeSyncPayload;
|
|
1397
|
-
declare function isBridgeInterceptResponse(v: unknown): v is BridgeInterceptResponse;
|
|
1398
|
-
/** sync 清单里的单个工具条目(parameters 顶层必须 type:'object'——OpenAI 兼容红线) */
|
|
1399
|
-
declare function isSyncedTool(v: unknown): v is BridgeSyncPayload['tools'][number];
|
|
1400
|
-
|
|
1401
1588
|
/**
|
|
1402
1589
|
* 子代理引擎契约(U7 引擎可发现性 + GUI 引擎选择)。
|
|
1403
1590
|
*
|
|
@@ -1510,4 +1697,4 @@ declare function collectActivePendingIds(entries: unknown[], opts?: CollectPendi
|
|
|
1510
1697
|
type MappedPendingStatus = 'completed' | 'failed' | 'cancelled' | 'expired' | 'time_limited' | 'aborted';
|
|
1511
1698
|
declare function mapReasonToStatus(reason: string): MappedPendingStatus;
|
|
1512
1699
|
|
|
1513
|
-
export { ASK_USER_MARKER, type AskUserAnswers, type AskUserOption, type AskUserQuestion,
|
|
1700
|
+
export { ASK_USER_MARKER, type AskUserAnswers, type AskUserOption, type AskUserQuestion, 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, 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, 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 SubagentEnginesFile, type SubagentInFlightReport, type SubagentJournalDomain, type SubagentJournalEvent, type SubagentJournalReport, TASK_ENTRY_TYPE, 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, appendExecutionRecord, applyPendingDiff, callMarkerRpc, collectActivePendingIds, dateToOnceCron, derivePhase, extractGui, firstContentText, formatChannelErrorText, formatDuration, formatRelativeTime, formatSchedule, getAskUserAnswer, getAskUserOther, guiComponent, guiResult, guiSetWidget, isAskUserQuestion, 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, transition, truncateSelfReview, uiFormInteract, validateWidgetIconPaths };
|
package/dist/index.js
CHANGED
|
@@ -413,6 +413,157 @@ function onceCronToDate(cron, now = /* @__PURE__ */ new Date()) {
|
|
|
413
413
|
return null;
|
|
414
414
|
}
|
|
415
415
|
|
|
416
|
+
// src/extensions/plan/state-machine.ts
|
|
417
|
+
var PLAN_LIFECYCLE_STATES = [
|
|
418
|
+
"idle",
|
|
419
|
+
"planning",
|
|
420
|
+
"reviewing",
|
|
421
|
+
"revising",
|
|
422
|
+
"approved",
|
|
423
|
+
"dispatching",
|
|
424
|
+
"completed",
|
|
425
|
+
"exited"
|
|
426
|
+
];
|
|
427
|
+
var PLAN_LIFECYCLE_EVENTS = [
|
|
428
|
+
"enter",
|
|
429
|
+
"submit",
|
|
430
|
+
"revise",
|
|
431
|
+
"dismiss",
|
|
432
|
+
"review_aborted",
|
|
433
|
+
"approve",
|
|
434
|
+
"exec_chosen",
|
|
435
|
+
"later",
|
|
436
|
+
"exit"
|
|
437
|
+
];
|
|
438
|
+
var TRANSITION_TABLE = {
|
|
439
|
+
idle: { enter: "planning" },
|
|
440
|
+
planning: { submit: "reviewing", exit: "exited" },
|
|
441
|
+
reviewing: {
|
|
442
|
+
submit: "reviewing",
|
|
443
|
+
revise: "revising",
|
|
444
|
+
dismiss: "planning",
|
|
445
|
+
review_aborted: "planning",
|
|
446
|
+
approve: "dispatching",
|
|
447
|
+
exit: "exited"
|
|
448
|
+
},
|
|
449
|
+
revising: { submit: "reviewing", exit: "exited" },
|
|
450
|
+
approved: { approve: "dispatching", exit: "exited" },
|
|
451
|
+
dispatching: {
|
|
452
|
+
review_aborted: "approved",
|
|
453
|
+
exec_chosen: "completed",
|
|
454
|
+
later: "approved",
|
|
455
|
+
exit: "exited"
|
|
456
|
+
},
|
|
457
|
+
completed: { enter: "planning" },
|
|
458
|
+
exited: { enter: "planning" }
|
|
459
|
+
};
|
|
460
|
+
function transition(state, event) {
|
|
461
|
+
if (!PLAN_LIFECYCLE_STATES.includes(state) || !PLAN_LIFECYCLE_EVENTS.includes(event)) {
|
|
462
|
+
return { ok: false };
|
|
463
|
+
}
|
|
464
|
+
const next = TRANSITION_TABLE[state][event];
|
|
465
|
+
return next === void 0 ? { ok: false } : { ok: true, next };
|
|
466
|
+
}
|
|
467
|
+
var PHASE_OF_STATE = {
|
|
468
|
+
idle: "idle",
|
|
469
|
+
planning: "planning",
|
|
470
|
+
reviewing: "reviewing",
|
|
471
|
+
revising: "planning",
|
|
472
|
+
approved: "approved",
|
|
473
|
+
dispatching: "approved",
|
|
474
|
+
completed: "terminal",
|
|
475
|
+
exited: "terminal"
|
|
476
|
+
};
|
|
477
|
+
function derivePhase(state) {
|
|
478
|
+
if (!PLAN_LIFECYCLE_STATES.includes(state)) return "idle";
|
|
479
|
+
return PHASE_OF_STATE[state];
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// src/extensions/plan/review-contract.ts
|
|
483
|
+
var PLAN_SELF_REVIEW_MAX_BYTES = 4096;
|
|
484
|
+
var UTF8_1_BYTE_CP_MAX = 127;
|
|
485
|
+
var UTF8_2_BYTE_CP_MAX = 2047;
|
|
486
|
+
var UTF8_3_BYTE_CP_MAX = 65535;
|
|
487
|
+
function utf8ByteLengthOfCodePoint(cp) {
|
|
488
|
+
if (cp <= UTF8_1_BYTE_CP_MAX) return 1;
|
|
489
|
+
if (cp <= UTF8_2_BYTE_CP_MAX) return 2;
|
|
490
|
+
if (cp <= UTF8_3_BYTE_CP_MAX) return 3;
|
|
491
|
+
return 4;
|
|
492
|
+
}
|
|
493
|
+
function truncateSelfReview(text) {
|
|
494
|
+
let bytes = 0;
|
|
495
|
+
let i = 0;
|
|
496
|
+
while (i < text.length) {
|
|
497
|
+
const cp = text.codePointAt(i);
|
|
498
|
+
if (cp === void 0) break;
|
|
499
|
+
const size = utf8ByteLengthOfCodePoint(cp);
|
|
500
|
+
if (bytes + size > PLAN_SELF_REVIEW_MAX_BYTES) break;
|
|
501
|
+
bytes += size;
|
|
502
|
+
i += cp > UTF8_3_BYTE_CP_MAX ? 2 : 1;
|
|
503
|
+
}
|
|
504
|
+
return text.slice(0, i);
|
|
505
|
+
}
|
|
506
|
+
function isPlanDocMeta(value) {
|
|
507
|
+
if (typeof value !== "object" || value === null) return false;
|
|
508
|
+
const doc = value;
|
|
509
|
+
return typeof doc.fileName === "string" && typeof doc.absPath === "string" && typeof doc.sourceSkill === "string" && typeof doc.version === "number";
|
|
510
|
+
}
|
|
511
|
+
function isPlanReviewRequest(value) {
|
|
512
|
+
if (typeof value !== "object" || value === null) return false;
|
|
513
|
+
const req = value;
|
|
514
|
+
if (!Array.isArray(req.docs) || !req.docs.every(isPlanDocMeta)) return false;
|
|
515
|
+
if (req.selfReview !== void 0 && typeof req.selfReview !== "string") return false;
|
|
516
|
+
return true;
|
|
517
|
+
}
|
|
518
|
+
function normalizeComments(value) {
|
|
519
|
+
if (!Array.isArray(value)) return null;
|
|
520
|
+
const comments = [];
|
|
521
|
+
for (const item of value) {
|
|
522
|
+
if (typeof item !== "object" || item === null) return null;
|
|
523
|
+
const c = item;
|
|
524
|
+
if (typeof c.quote !== "string" || typeof c.comment !== "string") return null;
|
|
525
|
+
comments.push({ quote: c.quote, comment: c.comment });
|
|
526
|
+
}
|
|
527
|
+
return { decision: "revise", comments };
|
|
528
|
+
}
|
|
529
|
+
function parsePlanReviewResponse(value) {
|
|
530
|
+
if (typeof value !== "object" || value === null) return { ok: false, code: "malformed" };
|
|
531
|
+
const raw = value;
|
|
532
|
+
const decision = raw.decision;
|
|
533
|
+
if (typeof decision !== "string") return { ok: false, code: "malformed" };
|
|
534
|
+
switch (decision) {
|
|
535
|
+
case "approve":
|
|
536
|
+
return { ok: true, response: { decision: "approve" } };
|
|
537
|
+
case "dismiss":
|
|
538
|
+
return { ok: true, response: { decision: "dismiss" } };
|
|
539
|
+
case "revise": {
|
|
540
|
+
const response = normalizeComments(raw.comments);
|
|
541
|
+
return response === null ? { ok: false, code: "malformed" } : { ok: true, response };
|
|
542
|
+
}
|
|
543
|
+
default:
|
|
544
|
+
return { ok: false, code: "unknown-decision", decision };
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
function isPlanReviewResponse(value) {
|
|
548
|
+
return parsePlanReviewResponse(value).ok;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// src/extensions/plan/legacy-entries.ts
|
|
552
|
+
var PLAN_STATE_CUSTOM_TYPE = "plan-state";
|
|
553
|
+
function readLifecycleState(data, isActive) {
|
|
554
|
+
const raw = data.state;
|
|
555
|
+
if (typeof raw === "string" && PLAN_LIFECYCLE_STATES.includes(raw)) {
|
|
556
|
+
return raw;
|
|
557
|
+
}
|
|
558
|
+
if (data.reviewState === "awaiting") return "reviewing";
|
|
559
|
+
if (data.reviewState === "revising") return "revising";
|
|
560
|
+
return isActive ? "planning" : "idle";
|
|
561
|
+
}
|
|
562
|
+
function readResumeHint(data) {
|
|
563
|
+
if (data.resumeHint === "resubmit") return "resubmit";
|
|
564
|
+
return data.reviewStateSource === "resubmit" ? "resubmit" : void 0;
|
|
565
|
+
}
|
|
566
|
+
|
|
416
567
|
// src/extensions/ui-form/marker.ts
|
|
417
568
|
var UI_FORM_MARKER = "\0TAIJI_UI_FORM";
|
|
418
569
|
|
|
@@ -601,35 +752,44 @@ function isInFlightReportAck(v) {
|
|
|
601
752
|
return v === INFLIGHT_REPORT_ACK;
|
|
602
753
|
}
|
|
603
754
|
|
|
604
|
-
// src/extensions/subagent-
|
|
605
|
-
var
|
|
606
|
-
var SUBAGENT_BG_NOTIFY_CUSTOM_TYPE = "subagent-bg-notify";
|
|
607
|
-
var SUBAGENT_DIRECTIVE_CUSTOM_TYPE = "subagent-directive";
|
|
608
|
-
|
|
609
|
-
// src/extensions/plugin-bridge/marker.ts
|
|
610
|
-
var BRIDGE_MARKER = "\0TAIJI_BRIDGE";
|
|
611
|
-
var BRIDGE_METHODS = ["bridge:sync", "bridge:tool_execute", "bridge:event", "bridge:intercept"];
|
|
755
|
+
// src/extensions/subagent-journal/marker.ts
|
|
756
|
+
var SUBAGENT_JOURNAL_MARKER = "\0TAIJI_SUBAGENT_JOURNAL";
|
|
612
757
|
|
|
613
|
-
// src/extensions/
|
|
758
|
+
// src/extensions/subagent-journal/types.ts
|
|
759
|
+
var JOURNAL_REPORT_ACK = '{"ack":true}';
|
|
614
760
|
function isRecord3(v) {
|
|
615
761
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
616
762
|
}
|
|
617
|
-
function
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
return
|
|
763
|
+
function isSubagentJournalEvent(v) {
|
|
764
|
+
if (!isRecord3(v)) return false;
|
|
765
|
+
if (typeof v.type !== "string" || v.type === "") return false;
|
|
766
|
+
if (typeof v.ts !== "number" || !Number.isFinite(v.ts)) return false;
|
|
767
|
+
if (v.seq !== void 0 && (typeof v.seq !== "number" || !Number.isSafeInteger(v.seq) || v.seq < 1)) {
|
|
768
|
+
return false;
|
|
769
|
+
}
|
|
770
|
+
return true;
|
|
625
771
|
}
|
|
626
|
-
function
|
|
627
|
-
|
|
772
|
+
function isSubagentJournalReport(v) {
|
|
773
|
+
if (!isRecord3(v)) return false;
|
|
774
|
+
if (v.domain !== "run" && v.domain !== "record") return false;
|
|
775
|
+
if (typeof v.fileKey !== "string" || v.fileKey === "") return false;
|
|
776
|
+
if (!Array.isArray(v.events)) return false;
|
|
777
|
+
for (const event of v.events) {
|
|
778
|
+
if (!isSubagentJournalEvent(event)) return false;
|
|
779
|
+
}
|
|
780
|
+
if (typeof v.emittedAt !== "number") return false;
|
|
781
|
+
if (v.sessionId !== void 0 && typeof v.sessionId !== "string") return false;
|
|
782
|
+
return true;
|
|
628
783
|
}
|
|
629
|
-
function
|
|
630
|
-
return
|
|
784
|
+
function isJournalReportAck(v) {
|
|
785
|
+
return v === JOURNAL_REPORT_ACK;
|
|
631
786
|
}
|
|
632
787
|
|
|
788
|
+
// src/extensions/subagent-notify/custom-types.ts
|
|
789
|
+
var WORKFLOW_RESULT_CUSTOM_TYPE = "workflow-result";
|
|
790
|
+
var SUBAGENT_BG_NOTIFY_CUSTOM_TYPE = "subagent-bg-notify";
|
|
791
|
+
var SUBAGENT_DIRECTIVE_CUSTOM_TYPE = "subagent-directive";
|
|
792
|
+
|
|
633
793
|
// src/extensions/subagent-engine/contract.ts
|
|
634
794
|
var SUBAGENTS_ENGINES_FILENAME = "engines.json";
|
|
635
795
|
|
|
@@ -698,11 +858,10 @@ export {
|
|
|
698
858
|
BACKGROUND_TASK_REGISTRY_FILENAME,
|
|
699
859
|
BACKGROUND_TASK_REGISTRY_VERSION,
|
|
700
860
|
BASE_TOOL_ENHANCE_DIRNAME,
|
|
701
|
-
BRIDGE_MARKER,
|
|
702
|
-
BRIDGE_METHODS,
|
|
703
861
|
GUI_WIDGET_MARKER,
|
|
704
862
|
HISTORY_LIMIT,
|
|
705
863
|
INFLIGHT_REPORT_ACK,
|
|
864
|
+
JOURNAL_REPORT_ACK,
|
|
706
865
|
MAX_TERMINAL_REGISTRY_ENTRIES,
|
|
707
866
|
MS_PER_DAY,
|
|
708
867
|
MS_PER_HOUR,
|
|
@@ -710,7 +869,11 @@ export {
|
|
|
710
869
|
MS_PER_SECOND,
|
|
711
870
|
PENDING_REGISTER_ENTRY_TYPE,
|
|
712
871
|
PENDING_UNREGISTER_ENTRY_TYPE,
|
|
872
|
+
PLAN_LIFECYCLE_EVENTS,
|
|
873
|
+
PLAN_LIFECYCLE_STATES,
|
|
713
874
|
PLAN_REVIEW_MARKER,
|
|
875
|
+
PLAN_SELF_REVIEW_MAX_BYTES,
|
|
876
|
+
PLAN_STATE_CUSTOM_TYPE,
|
|
714
877
|
PROTOCOL_VERSION,
|
|
715
878
|
SCHEDULE_CREATE_MARKER,
|
|
716
879
|
SESSION_MANAGER_ACTIONS,
|
|
@@ -719,6 +882,7 @@ export {
|
|
|
719
882
|
SUBAGENT_BG_NOTIFY_CUSTOM_TYPE,
|
|
720
883
|
SUBAGENT_DIRECTIVE_CUSTOM_TYPE,
|
|
721
884
|
SUBAGENT_INFLIGHT_MARKER,
|
|
885
|
+
SUBAGENT_JOURNAL_MARKER,
|
|
722
886
|
TASK_ENTRY_TYPE,
|
|
723
887
|
UI_FORM_MARKER,
|
|
724
888
|
WORKFLOW_RESULT_CUSTOM_TYPE,
|
|
@@ -727,6 +891,7 @@ export {
|
|
|
727
891
|
callMarkerRpc,
|
|
728
892
|
collectActivePendingIds,
|
|
729
893
|
dateToOnceCron,
|
|
894
|
+
derivePhase,
|
|
730
895
|
extractGui,
|
|
731
896
|
firstContentText,
|
|
732
897
|
formatChannelErrorText,
|
|
@@ -741,10 +906,6 @@ export {
|
|
|
741
906
|
isActiveBackgroundTaskState,
|
|
742
907
|
isAskUserQuestion,
|
|
743
908
|
isBackgroundTaskRegistryEntry,
|
|
744
|
-
isBridgeErrorResponse,
|
|
745
|
-
isBridgeInterceptResponse,
|
|
746
|
-
isBridgeSyncPayload,
|
|
747
|
-
isBridgeToolExecuteResponse,
|
|
748
909
|
isChannelErrorResult,
|
|
749
910
|
isFormAnswers,
|
|
750
911
|
isFormQuestion,
|
|
@@ -752,6 +913,9 @@ export {
|
|
|
752
913
|
isGuiComponent,
|
|
753
914
|
isGuiRenderResult,
|
|
754
915
|
isInFlightReportAck,
|
|
916
|
+
isJournalReportAck,
|
|
917
|
+
isPlanReviewRequest,
|
|
918
|
+
isPlanReviewResponse,
|
|
755
919
|
isScheduleDraft,
|
|
756
920
|
isScheduleFormResult,
|
|
757
921
|
isSessionManagerAbortParams,
|
|
@@ -764,14 +928,19 @@ export {
|
|
|
764
928
|
isSessionManagerWatchParams,
|
|
765
929
|
isSessionManagerWatchRespondPayload,
|
|
766
930
|
isSubagentInFlightReport,
|
|
767
|
-
|
|
931
|
+
isSubagentJournalReport,
|
|
768
932
|
isTerminalBackgroundTaskState,
|
|
769
933
|
mapReasonToStatus,
|
|
770
934
|
onceCronToDate,
|
|
935
|
+
parsePlanReviewResponse,
|
|
936
|
+
readLifecycleState,
|
|
937
|
+
readResumeHint,
|
|
771
938
|
replayFoldEntries,
|
|
772
939
|
scanPendingEntries,
|
|
773
940
|
setWidgetDual,
|
|
774
941
|
snapshotToTask,
|
|
942
|
+
transition,
|
|
943
|
+
truncateSelfReview,
|
|
775
944
|
uiFormInteract,
|
|
776
945
|
validateWidgetIconPaths
|
|
777
946
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhushanwen/extension-protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.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",
|