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-D_UDhcs2.js'; /** * GUI 渲染协议核心类型定义。 * * GuiComponent 是 pi Component { render(width): string[] } 的可序列化镜像。 * extension 按 ctx.mode 分支:TUI 走原生 Component,RPC 走 GuiComponent(放进 details.__gui__)。 * * GuiComponentProps 是类型路由的聚合点:通用布局原语 + extension 专属组件 * 全部在此声明键值,子类型直接内联本文件(纯类型,无运行时逻辑)。 * * @see docs/architecture/extension-gui-protocol.md */ declare const PROTOCOL_VERSION: 1; /** * GUI 渲染组件——pi Component 的可序列化镜像。 * * pi: Component { render(width): string[] } ← ANSI 文本行 * gui: GuiComponent = { type, props } ← 结构化数据 */ interface GuiComponent { /** 组件类型,前端按此路由到 Vue 组件 */ type: T; /** 组件 props,类型由 type 决定 */ props: GuiComponentProps[T]; } type GuiComponentType = keyof GuiComponentProps; interface GuiComponentProps { /** ANSI 文本兜底——保留原始 ANSI 序列,前端用 ansi_up 渲染 */ 'ansi-text': { lines: string[]; }; /** 卡片容器——替代 TUI 的 ┌─┐││└─┘ box 边框 */ 'card': { variant?: 'default' | 'elevated' | 'danger' | 'success'; header?: GuiComponent | string; body: GuiComponent[]; }; /** 统计行——替代 TUI 的 "N turns · Nk · Ns" */ 'stats-line': { items: StatItem[]; }; /** 进度条——替代 TUI 的 ████░░░░ */ 'progress-bar': { label?: string; current: number; total: number; unit?: string; severity?: 'ok' | 'warn' | 'danger'; }; /** 列表树——替代 TUI 的 ⎿ ├─ └─ 缩进 */ 'list-tree': { items: TreeItem[]; /** 行首显示弱化序号(1/2/3…,mono tabular-nums)。扁平有序清单用(todo); * 自带编号的文本(goal criteria "1. xxx")不要开,避免双重编号 */ numbered?: boolean; }; /** 垂直组合容器——无视觉样式的透明分组。宿主壳层(WidgetArea)承担卡壳/head/折叠 * 后,widget 内容需要多组件组合时的组合根(替代「无头 card」的语义滥用) */ 'group': { children: GuiComponent[]; }; /** 双列网格——替代 TUI 的 │ 列分隔 */ 'columns': { children: GuiComponent[]; ratios?: number[]; }; /** 标签栏——替代 TUI 的 tab │ 分隔 */ 'tab-bar': { tabs: { label: string; active?: boolean; status?: 'done' | 'pending'; }[]; }; /** 自定义组件——逃生口(仅限内置 extension 编译期注册) */ 'custom': { component: string; props: Record; }; } interface GuiRenderResult { /** 版本协商,前端检测,不认识降级 ansi-text */ v: typeof PROTOCOL_VERSION; component: GuiComponent; /** * widget 宿主元数据(M17 对话流 widget 面板消费):标题/状态点/进度计数由 * 宿主壳层统一渲染成单一 head(含折叠交互),extension 不再用 card 原语 * 的 header 表达这些(壳层 head 与 payload card header 双头重复的根因修复)。 * 可选:不发时宿主 fallback 到 viewId 标题、无状态点/进度。 */ meta?: WidgetMeta; } /** widget 宿主元数据——head 渲染契约(title + 状态点 + 进度 + 折叠 chevron)。 */ interface WidgetMeta { /** head 标题(todo → "Todo";goal → slug) */ title: string; /** head 状态点语义:running=accent / done=success / failed=danger / idle=neutral 弱点 */ status?: 'running' | 'done' | 'failed' | 'idle'; /** head 进度(mini bar + 计数文本);progress-bar 原语从 body 移入 head 的承载 */ progress?: { /** fill 比例 = current/total */ current: number; total: number; /** 计数显示文本(head 空间有限,extension 全权格式化:todo "2/5"、goal "42%")。 * 缺省 `${current}/${total}` */ label?: string; /** fill 语义色(预算阈值映射);缺省按 meta.status(done→success,否则 accent) */ severity?: 'ok' | 'warn' | 'danger'; }; } interface StatItem { label?: string; value: string; severity?: 'ok' | 'warn' | 'danger'; icon?: string; } interface TreeItem { icon?: TreeItemIcon; label: string; status?: 'running' | 'done' | 'failed'; depth?: number; children?: TreeItem[]; } type TreeItemIcon = 'arrow' | 'check' | 'cross' | 'circle' | 'dot' | 'pause' | 'branch'; /** * 通用传输 marker。extension 用 guiSetWidget 编码进 string[], * runtime event-adapter 检测 marker 解码为结构化 WS 帧。 * * NUL 字符开头的 marker,不会出现在正常文本中。 */ declare const GUI_WIDGET_MARKER = "\0XYZ_GUI_WIDGET:"; /** * helpers 需要的 ctx 最小接口。 * pi 的 ExtensionContext 天然满足此结构(有 mode/hasUI/ui 字段)。 * 用结构化类型而非 import pi SDK,保持协议包零依赖。 */ interface GuiContext { mode: 'tui' | 'rpc' | 'json' | 'print'; hasUI: boolean; ui?: { setWidget?: (key: string, lines: string[] | undefined) => void; select?: (header: string, options: string[], opts?: { signal?: AbortSignal; timeout?: number; }) => Promise; input?: (header: string, prompt: string, opts?: { signal?: AbortSignal; }) => Promise; confirm?: (header: string, prompt: string, opts?: { signal?: AbortSignal; }) => Promise; custom?: (factory: unknown, opts?: unknown) => Promise | undefined>; }; } /** * Extension GUI 渲染协议 helper 函数(通用层)+ toolResult 通用形状提取。 * * 设计原则: * - 零运行时依赖(不依赖 pi SDK) * - helpers 接受最小化的 ctx 结构(结构化类型),pi 的 ExtensionContext 天然满足 * - extension 开发者只需调这些 helper,不需要了解底层编码细节 */ /** * 检测当前环境是否支持 GUI 渲染(RPC 模式 = GUI 渲染通道有效)。 * TUI/json/print 模式走 pi 原生渲染,不需要 GuiComponent。 */ declare function isGuiCapable(ctx: GuiContext): boolean; /** * 构造 GuiRenderResult。当前主用途是 guiSetWidget 的载荷(M17 对话流 widget 面板); * details.__gui__(tool result 通道)为遗留兼容路径,todo/goal 已不再使用。 * stripUndefined 确保序列化不含 undefined(JSON.stringify 会丢弃 undefined 字段)。 */ declare function guiResult(component: GuiComponent, meta?: WidgetMeta): GuiRenderResult; /** * 构造 GuiComponent,带类型推断。 * 类型参数 T 约束 props 到对应类型的 props 形状。 */ declare function guiComponent(type: T, props: GuiComponentProps[T]): GuiComponent; /** * 设置 GUI widget。RPC 模式下用 marker 编码 GuiRenderResult JSON 进 string[], * runtime event-adapter 检测 marker 解码为结构化 WS 帧(component + meta)。 * 本函数无 isGui 守卫(仅查 ctx.ui?.setWidget 存在性),调用方需先判定 * isGuiCapable(ctx)——TUI 模式误调会把 marker 编码行推给原生 widget 造成乱码。 * * meta(标题/状态/进度)由宿主壳层渲染成统一 head;extension 不再用 card 原语 * header 表达这些。传 undefined 清除 widget。 */ declare function guiSetWidget(ctx: GuiContext, key: string, result: GuiRenderResult | undefined): void; /** * [守卫单点化——本约束的说明全仓只写这一处,调用方不得再各自复写] * 「isGuiCapable 外层判定不可省略,否则 TUI 误调 marker 乱码」:guiSetWidget 无 * isGui 守卫(仅查 ctx.ui?.setWidget 存在性),TUI 模式误调会把 marker 编码行推 * 给原生 widget 造成乱码。带双模内容的 widget 推送一律走 setWidgetDual,由本 * helper 内化模式分派——消费方(todo/goal 及后续带 widget 的 extension)不再 * 自持 isGui 判定与守卫注释。 */ /** 双模 widget 内容:按值立即构造两侧(构造均为廉价纯函数,成本可忽略)。 */ interface DualWidgetContent { /** RPC 模式经 marker 通道推送的 GUI 渲染结果(guiResult 产物)。 */ gui: GuiRenderResult; /** TUI/json/print 模式推送给 pi 原生渲染的文本行。 */ text: string[]; } /** * 双模 widget 推送(清屏/推送 × GUI/TUI 四分支的协议侧收敛,模式分派单点): * - content 为 undefined → 清屏 ctx.ui.setWidget(key, undefined),模式无关 * (guiSetWidget 的清屏分支本就两臂同落 setWidget,判别是死分支) * - 有内容 → isGuiCapable(ctx) ? guiSetWidget(gui) : setWidget(text)——TUI 分支 * 推原生文本行,结构性不触达 marker(见上方守卫单点化说明) * hasUI 守卫留在调用方(goal FR-6.6 语义,本 helper 不感知)。 */ declare function setWidgetDual(ctx: GuiContext, key: string, content: DualWidgetContent | undefined): void; /** * 从 details 中提取 GuiRenderResult。前端统一用此函数读取 __gui__, * 集中校验版本号,避免散落的 as 断言。 */ declare function extractGui(details: Record | undefined): GuiRenderResult | undefined; /** * 最小形状校验:判断 unknown 值是否为合法 GuiComponent(有 type 字符串 + props 对象)。 * 用于 widgetGui marker 解码后防止异常结构进入渲染层。 * 不校验 type 是否为已知值(GuiComponentRenderer 对未知 type 有 AnsiText 降级)。 */ declare function isGuiComponent(value: unknown): value is GuiComponent; /** * v1.1 wire 格式校验:判断 unknown 值是否为合法 GuiRenderResult 信封 * (v === PROTOCOL_VERSION + component 是合法 GuiComponent)。meta 可选不校验深度。 * event-adapter 据此区分 v1.1 信封(解包 component + meta)与 v1 裸 component * (旧版 extension 发出的 wire 格式,兼容窗口内两种并存)。 */ declare function isGuiRenderResult(value: unknown): value is GuiRenderResult; /** * pi toolResult 通用形状提取:content[0] 为 text 块时取其 text,否则空串。 * pi 通用形状(非 extension 领域结构),renderResult 文本兜底的共用内核。 */ declare function firstContentText(result: { content: Array<{ type: string; text?: string; }>; }): string; /** * select+marker 通道 RPC 原语(D8)。 * * 三消费方(plugin-bridge / session-manager / subagent-workflow inflight-reporter) * 此前各自手写「ctx.ui.select(marker, [payload], opts) + 失败折叠 + JSON 检测」传输核, * 形态同构、留痕/超时策略各异。本原语只收敛传输核与失败折叠契约,真差异留在调用方: * * - 判别结果而非抛错(调用方统一按 reason 折叠 isError / 重试); * - 回包只做 JSON 合法性检测(`non-json` 判别 + 留痕),parsed 结果的消费留调用方—— * value 恒 raw string(session-manager raw 透传 / plugin-bridge 各形状守卫 / inflight * ack 全等匹配,三态回包消费是真差异,不进原语); * - payload 调用方已序列化(原语不 stringify——各协议序列化形状各异:嵌套 * {action,params} / BridgeRequest / 快照帧,不引入内部 stringify 异常面); * - mode 门控留调用方(三方现状各异:plugin-bridge 在 callBridge 内 / inflight 在 * attachSession 处 / session-manager 无门控——四态 reason 无 non-rpc 语义); * - `ui.select` 缺席(非 GUI ctx)由调用方前置判定(沿 ask-user askUserInteract 的 * `isGuiCapable(ctx) && ctx.ui?.select` 先例);误用即 throw 明确错误。 * * 设计权威源:docs/architecture/ext-simplify-17-shared-extraction.md §3.3 D8(v7 冻结形态)。 */ /** marker 通道 RPC 的判别结果:成功恒 raw string(不 parse 消费);失败四态 reason */ type MarkerRpcResult = { ok: true; value: string; } | { ok: false; reason: 'cancelled' | 'timeout' | 'channel-error' | 'non-json'; }; interface MarkerRpcOptions { /** 透传给 select dialog:abort 后 pi 本地 resolve(undefined) */ signal?: AbortSignal; /** 透传给 select dialog(pi 本地计时,到期 resolve(undefined)) */ timeout?: number; /** 失败留痕注入(channel-error / non-json 两态调用,msg + detail 由原语产出)。 * 日志策略(级别 / 前缀 / 防刷屏)归调用方——真差异保留。 */ log?: (msg: string, detail?: object) => void; } /** 错误回包底层形状:select+marker 通道各协议(plugin-bridge / session-manager) * runtime 侧异常折叠的共用单源(不裸 reject,error 闭环走同一回包通道)。 * BridgeErrorResponse / SessionManagerErrorResult 是本形状的 alias(D8 单源化)。 */ interface ChannelErrorResult { error: string; hint?: string; } /** 运行时形状守卫:{error: string}(hint 可选,不校验其类型;排数组) */ declare function isChannelErrorResult(v: unknown): v is ChannelErrorResult; /** error + hint 文本拼接(hint 缺席只回 error)——plugin-bridge errorResult 与 * session-manager 错误闭环文本的共用单源 */ declare function formatChannelErrorText(err: ChannelErrorResult): string; /** * 经 select 通道发起一次 marker RPC。 * * @param ctx 满足 GuiContext 结构化类型的 ctx(pi ExtensionContext 天然满足; * 调用方须已判定 ui.select 在场,缺席即 throw) * @param marker select title(各协议的 NUL 前缀 marker,runtime 据此路由) * @param payload 调用方已序列化的请求体(原语原样进 options[0]) * @param opts signal / timeout 透传 select dialog;log 承担失败留痕 */ declare function callMarkerRpc(ctx: GuiContext, marker: string, payload: string, opts?: MarkerRpcOptions): Promise; /** * ask-user extension 的富交互类型定义。 * * custom() 在 RPC 模式不可用(Component 是代码不是数据),ask-user 的「表单类」 * 交互改走 select 通道:askUserInteract() 把 AskUserQuestion[] 序列化进 select 的 * options[0],runtime event-adapter 检测 ASK_USER_MARKER 透传 questions, * 前端 AskUserOverlay 渲染富交互 UI。 * * 这是 ask-user 的定制协议,不是通用富交互协议。 * 设计参考 ask-user 的 Question 结构。 */ /** * ask-user 富交互问题声明。 */ interface AskUserQuestion { /** Tab 标签 / 简短标题。多问题时用于 tab 切换,≤12 字符。 * 可选——未提供时前端用 question 文本作为 tab 标签(前 12 字符截断显示) * 和 answers key(完整 question 文本,不截断)。 */ header?: string; /** 完整问题文本。也作为 answers 的 fallback key(header 缺失时) */ question: string; /** 上下文摘要(可选)。显示在问题上方,帮用户理解背景 */ context?: string; /** 互斥选项列表(可选)。无 options = 纯自由文本输入 */ options?: AskUserOption[]; /** 是否允许多选。仅 options 存在时有效 */ multiSelect?: boolean; /** 是否允许自由文本输入(Other)。 * - 有 options 时:默认 true,前端在选项末尾追加 Other 输入框;设 false 则不追加 * - 无 options 时:整个问题就是自由输入,此字段被忽略 */ allowOther?: boolean; } interface AskUserOption { /** 显示标签,回传时作为选中值(D1:proto 无独立 value,选中值统一用 label) */ label: string; /** 描述(可选)。显示在 label 下方,解释 tradeoff */ description?: string; } /** * ask-user 富交互回传结果。key = question.header(header 缺失时用 question 文本)。 * * 答案编码规则(避免逗号歧义): * - 单选:value = 选中项的 label * - 多选:value = JSON.stringify(选中项 label 数组),如 '["pg","mysql"]' * (不用逗号 join——option label 可能含逗号导致 split 歧义) * - Other 文本:单独 key `${header}__other`,value = 自由文本(不混进选中项数组) * * extension 解析示例: * const selected = JSON.parse(answers[header]) // 多选 → string[] * const other = answers[`${header}__other`] // Other 自由文本 */ type AskUserAnswers = Record; /** * ask-user 富交互请求的 title marker。runtime event-adapter 和前端 useExtensionUI * 检测此 marker 区分 ask-user 请求与普通 select。 * * NUL 前缀确保不会与 extension 正常的 select title 冲突。 * 与 GUI_WIDGET_MARKER 同理(见 core/markers.ts)。 */ declare const ASK_USER_MARKER = "\0XYZ_ASK_USER"; /** * ask-user extension 的富交互 helper(定制层)。 * * askUserInteract() 是 ask-user extension 在 RPC 模式下的交互入口。 * TUI 模式下 extension 必须自行调 ctx.ui.custom()。 * * 走 select 通道 + marker(ASK_USER_MARKER),复用 select 的全部管道逻辑 * (队列 / 超时 / 回传 / abort),零重复代码。 */ /** * ask-user 富交互入口(RPC 模式专用)。 * * RPC 模式:用 select 通道携带 questions 数据,前端渲染富交互 UI。 * TUI 模式:抛错。extension 必须自行调 ctx.ui.custom()。 * * @param ctx ExtensionContext(pi 提供) * @param questions 交互问题声明 * @param options 可选:signal(abort)、allowCancel(前端是否显示取消按钮) * @returns answers(key=header/question, value=JSON编码的答案),用户取消返回 null */ declare function askUserInteract(ctx: GuiContext, questions: AskUserQuestion[], options?: { signal?: AbortSignal; allowCancel?: boolean; }): Promise; /** * 从 answers 中提取某个问题的选中值(单选返回 string,多选返回 string[])。 * * 多选 answers 的 value 是 JSON.stringify(string[]),此 helper 自动 parse。 * parse 失败时降级返回 [raw](兼容非标准格式的回传)。 */ declare function getAskUserAnswer(answers: AskUserAnswers, question: AskUserQuestion): string | string[] | undefined; /** 从 answers 中提取 Other 自由文本 */ declare function getAskUserOther(answers: AskUserAnswers, question: AskUserQuestion): string | undefined; /** * 类型守卫:验证 unknown 是否为合法的 AskUserQuestion。 * 用于前端从 runtime 透传的 askUserQuestions(unknown[])中安全收窄。 */ declare function isAskUserQuestion(value: unknown): value is AskUserQuestion; /** * session-manager 请求的 title marker。runtime event-adapter 和 handler * 检测此 marker 区分 session-manager 请求与普通 select。 * * NUL 前缀确保不会与 extension 正常的 select title 冲突。 * 与 ASK_USER_MARKER / GUI_WIDGET_MARKER 同理。 */ declare const SESSION_MANAGER_MARKER = "\0XYZ_SESSION_MANAGER"; /** * 6 个 action 的运行时集合(与 SessionManagerAction 类型同源——types.ts 从此派生)。 * event-adapter 用它把 JSON 解析出的 action 字符串收窄为联合类型, * 非法值折叠为 '__malformed__' 哨兵(与 handler default 分支同走 cancelled)。 */ declare const SESSION_MANAGER_ACTIONS: readonly ["create", "send", "history", "status", "list", "abort"]; /** * session-manager extension 的类型定义。 * * 6 个 action 的请求 params 和结果类型,供 handler 和 extension 共用。 * marker 检测后按 action 分发到对应 handler 分支。 */ /** session-manager 支持的 6 个 action(从 SESSION_MANAGER_ACTIONS 集合派生,值与类型同源) */ type SessionManagerAction = (typeof SESSION_MANAGER_ACTIONS)[number]; /** 各 action 的请求参数映射 */ interface SessionManagerParams { create: SessionManagerCreateParams; send: SessionManagerSendParams; history: SessionManagerHistoryParams; status: SessionManagerStatusParams; list: SessionManagerListParams; abort: SessionManagerAbortParams; } /** create action 参数 */ interface SessionManagerCreateParams { /** session 工作目录 */ cwd?: string; /** session 标签 */ label?: string; /** 初始 prompt(可选;提供时 create 后立即注入——设计文档 §5.2 原子性决策) */ prompt?: string; } /** send action 参数 */ interface SessionManagerSendParams { sessionId: string; prompt: string; } /** history action 参数 */ interface SessionManagerHistoryParams { sessionId: string; /** 截断尾部 turn 数(0 = 不截断) */ tailTurns?: number; } /** status action 参数 */ interface SessionManagerStatusParams { sessionId: string; } /** list action 参数(无字段:过滤由 handler 固化——spawnSource='agent' + 路由上下文父 id;Record 结构性拒绝任何请求字段) */ type SessionManagerListParams = Record; /** abort action 参数 */ interface SessionManagerAbortParams { sessionId: string; } /** create:全字段可选 string */ declare function isSessionManagerCreateParams(v: unknown): v is SessionManagerCreateParams; /** send:sessionId + prompt 必填 */ declare function isSessionManagerSendParams(v: unknown): v is SessionManagerSendParams; /** history:sessionId 必填、tailTurns 可选 number */ declare function isSessionManagerHistoryParams(v: unknown): v is SessionManagerHistoryParams; /** status / abort:sessionId 必填 */ declare function isSessionManagerStatusParams(v: unknown): v is SessionManagerStatusParams; declare function isSessionManagerAbortParams(v: unknown): v is SessionManagerAbortParams; /** list:无参数(过滤由 handler 固化,params 不携带任何过滤字段) */ declare function isSessionManagerListParams(v: unknown): v is SessionManagerListParams; /** create 结果 */ interface SessionManagerCreateResult { sessionId: string; status: 'created'; modelId?: string; } /** * send 结果(sd-u5 起):消息已入队/已投递——目标 busy 时在下一 turn 边界注入。 * 失败形状走 SessionManagerErrorResult(error + hint),不再出现旧的 {blocked, rejected}。 */ interface SessionManagerSendResult { queued: true; } /** history 结果 */ interface SessionManagerHistoryResult { messages: unknown[]; truncated: boolean; } /** status 结果 */ interface SessionManagerStatusResult { status: string; modelId?: string; } /** list 结果 */ interface SessionManagerListResult { sessions: SessionManagerSessionSummary[]; } /** list 返回的 session 摘要(精简版) */ interface SessionManagerSessionSummary { id: string; label: string; cwd: string; status: string; spawnSource?: 'user' | 'agent'; parentAgentSessionId?: string; } /** abort 结果 */ interface SessionManagerAbortResult { success: boolean; } /** 错误响应形状(send 同步失败时 = { error, hint };create 已成功时另附 sessionId)。 * D8 单源化:交集扩展 alias——error/hint 单源于 core 的 ChannelErrorResult,sessionId * 为本协议独有扩展(runtime session-manager-handler 活构造:create 已成功但后续步骤 * 失败时附 sessionId + hint 恢复路径)。导出名与文件位置不变,public API 零破坏。 */ type SessionManagerErrorResult = ChannelErrorResult & { sessionId?: string; }; /** * subagent 在途上报的类型定义(u7a 协议面)。 * * 契约两端: * - 写侧(生产):@zhushanwen/pi-subagent-workflow 壳层(src/host/inflight-reporter.ts) * 监听 subagent-core 的 core→壳在途事件出口,经 select 通道 fire-and-forget 推送; * - 读侧(消费):xyz-agent runtime event-adapter 的 marker 路由分支(u7b 领地) * → inflight-mirror per-session 镜像。 * * 语义锚点(设计 §3.3 D5):每帧携带该 session 的**绝对计数**(当前非 idle 句柄数, * 谓词 = hasLiveProcessHandle && !hasIdleTimer),非增量 delta——任何后续事件都能 * 纠正镜像,单帧丢失不累积误差。初始上报触发时点 = extension 加载完成(session * 就绪),使「从未收到上报」可判别「reporter/通道结构性故障」与「在场且无在途」 * (D5 缺席语义,2026-09-13 oe-audit 修订:原「旧版 extension 组合」立论被同 * bundle 发布 + pi 随 runtime 退出销毁两条事实证伪,errs 兜底对象收敛为结构性故障)。 */ /** * 单帧在途上报(pi 进程 → runtime,经 select 通道,title = SUBAGENT_INFLIGHT_MARKER, * options = [JSON.stringify(本形状)])。 */ interface SubagentInFlightReport { /** * 绝对计数:该 pi 进程当前「非 idle 句柄数」(hasLiveProcessHandle && !hasIdleTimer * 双谓词过滤,与 notify-host.ts hasRunningBackground 同源)。非增量——消费方整帧 * 覆盖镜像,不做加减。 */ inFlight: number; /** * 上报所属 session(ctx.sessionManager.getSessionId())。pi 延迟写入窗口内可能取 * 不到(plugin-bridge getSessionId 同款防御)——缺席时消费方按无法归属丢弃整帧 * (不镜像),不视为协议错误。 */ sessionId?: string; /** 产生时点(ms epoch,pi 进程内取值)。诊断/乱序排查用,消费方不依赖其单调性。 */ emittedAt: number; } /** * select 通道的确认回包(runtime event-adapter 处理完帧后 resolve 给 pi 侧的 * JSON 字符串)。fire-and-forget 语义下「已送达」与「超时/通道失败」在 promise 层 * 都表现为 resolve(undefined)——必须靠显式 ack 帧区分送达与否,reporter 据此停止 * 初始重试(有界,见 inflight-reporter)。无 ack 的运行环境(裸 pi TUI——marker * select 弹真框超时;经 xyz-agent runtime 恒为 rpc 模式必回 ack)由 reporter 侧 * mode 门控不启动上报。 */ declare const INFLIGHT_REPORT_ACK: "{\"ack\":true}"; /** * SubagentInFlightReport 形状守卫:inFlight 非负整数、emittedAt 数字、sessionId * 缺席或 string。event-adapter(u7b)路由分支消费;非法帧返回 false(调用方丢弃, * 不抛错不镜像)。 */ declare function isSubagentInFlightReport(v: unknown): v is SubagentInFlightReport; /** 确认回包形状守卫(pi 侧 reporter 消费——非本字符串即未确认,折叠重试)。 */ declare function isInFlightReportAck(v: unknown): v is typeof INFLIGHT_REPORT_ACK; /** * subagent 在途上报的 title marker。runtime event-adapter(u7b)检测此 marker * 区分在途上报与普通 select;pi 侧壳层(@zhushanwen/pi-subagent-workflow 的 * host/inflight-reporter)经同一 marker 以 fire-and-forget 语义推送 * SubagentInFlightReport 帧(单一来源,两端口径必然一致)。 * * NUL 前缀确保不会与 extension 正常的 select title 冲突。 * 与 ASK_USER_MARKER / SESSION_MANAGER_MARKER / BRIDGE_MARKER 同理。 * * 设计权威源:docs/architecture/crash-forensics-and-watchdog.md §3.3 D5 * 「在途判定谓词 + 求值位置」——extension 聚合上报通道的协议面(u7a)。 */ declare const SUBAGENT_INFLIGHT_MARKER = "\0XYZ_SUBAGENT_INFLIGHT"; /** * plugin-bridge 请求的 title marker。runtime event-adapter 和 pi 侧 * bridge extension(@zhushanwen/pi-plugin-bridge)双端消费此 marker, * 在 select 通道上区分 bridge 帧与普通 select(单一来源,两端口径必然一致)。 * * NUL 前缀确保不会与 extension 正常的 select title 冲突。 * 与 ASK_USER_MARKER / SESSION_MANAGER_MARKER / GUI_WIDGET_MARKER 同理。 */ declare const BRIDGE_MARKER = "\0XYZ_BRIDGE"; /** * 协议 v2 的 4 个 method 运行时集合(与 BridgeMethod 类型同源——types.ts 从此派生)。 * event-adapter 用它校验 marker 帧的 method 合法性, * 非法值折叠为 'bridge:malformed' 哨兵(handler 回 malformed 错误,不静默丢弃)。 */ declare const BRIDGE_METHODS: readonly ["bridge:sync", "bridge:tool_execute", "bridge:event", "bridge:intercept"]; /** * plugin-bridge 协议 v2 的类型定义。 * * select + BRIDGE_MARKER 通道上的请求/回包形状,pi 侧 bridge extension * (序列化发送方)与 runtime bridge-handler(解析与回包方)共用。 * 向后不兼容旧 bridge:* method 承载(旧链路本来就不通,改名无收益)。 * marker 检测后按 method 分发到对应 handler 分支。 */ /** 协议 v2 的 4 个 method(从 BRIDGE_METHODS 集合派生,值与类型同源) */ type BridgeMethod = (typeof BRIDGE_METHODS)[number]; /** bridge 请求的统一形状(pi bridge extension → runtime via select 通道) */ interface BridgeRequest { method: BridgeMethod; /** tool_execute 专属:工具名 */ toolName?: string; /** tool_execute 专属:工具调用 id */ toolCallId?: string; /** tool_execute 专属:工具入参 */ params?: Record; /** 发起请求的 session(tool_execute/event/intercept 携带,供 runtime 按 session 路由 * 防跨 session 串台;bridge:sync 全局快照请求不带) */ sessionId?: string; /** event / intercept 专属:pi 原生事件名 */ eventName?: string; /** event / intercept 专属:事件负载 */ data?: unknown; } /** tool_execute 回包:插件工具执行结果 */ interface BridgeToolExecuteResponse { content: string; isError?: boolean; } /** sync 回包:工具清单快照(pi 侧命令发现不走本协议,另走 getCommands 通路) */ interface BridgeSyncPayload { tools: Array<{ name: string; description: string; parameters: Record; }>; success: true; } /** intercept 回包:before_agent_start 拦截决策(bridge 侧把 injectedMessages 映射为单条 CustomMessage) */ interface BridgeInterceptResponse { blocked?: boolean; reason?: string; injectedMessages: unknown[]; } /** 错误回包:runtime 侧异常折叠(不裸 reject;bridge 侧解析后以 isError 返回)。 * D8 单源化:底层形状 alias 到 core 的 ChannelErrorResult(导出名与文件位置不变, * public API 零破坏)。 */ type BridgeErrorResponse = ChannelErrorResult; /** * plugin-bridge 回包形状守卫族(D11 自 extensions/taiji/plugin-bridge index.ts 零改动迁入)。 * * 「marker + types + 守卫」同住惯例(session-manager / subagent-inflight 先例): * 回包形状的运行时检测与类型定义同源维护。当前唯一消费方 = pi 侧 bridge * extension;runtime bridge-handler 的 5 处 `as string` 断言是后续批次的第二 * 消费方(换校验的铺路,设计 D11 登记项)。 * * isRecord 为模块内私有副本(排数组严版——与 subagent-inflight / session-manager * 副本同款同义):protocol 不依赖 extensions 层的 ext-guards(分层边界裁决,D3 * 明确排除),包内三份私有副本并存是裁决下的既有惯例,语义必须一致。 * * 设计权威源:docs/architecture/ext-simplify-17-shared-extraction.md §3.3 D11。 */ /** runtime 错误闭环形状 {error, hint?}(设计 §3.3-D1:不裸 reject)——检测逻辑单源于 * core 的 isChannelErrorResult(D8),本名保留为守卫族整体成员(D11 迁移) */ declare function isBridgeErrorResponse(v: unknown): v is BridgeErrorResponse; declare function isBridgeToolExecuteResponse(v: unknown): v is BridgeToolExecuteResponse; declare function isBridgeSyncPayload(v: unknown): v is BridgeSyncPayload; declare function isBridgeInterceptResponse(v: unknown): v is BridgeInterceptResponse; /** sync 清单里的单个工具条目(parameters 顶层必须 type:'object'——OpenAI 兼容红线) */ declare function isSyncedTool(v: unknown): v is BridgeSyncPayload['tools'][number]; /** * 子代理引擎契约(U7 引擎可发现性 + GUI 引擎选择)。 * * 契约两端: * - 写侧:@zhushanwen/pi-subagent-workflow extension(pi 进程内,engine registry 权威) * 在 session_start 时把注册引擎列表同步到 /subagents/engines.json; * - 读侧:xyz-agent runtime(subagent.getEngineConfig / subagent.setDefaultEngine RPC) * → renderer Settings「子代理」页引擎下拉(动态选项,不硬编码)。 * * defaultEngine 的权威存储仍是 /subagents/config.json(extension 的 * ModelConfigService 读同文件——GUI 写入经 runtime 读改写,单一文件双端共识)。 */ /** 引擎列表状态文件名(相对 /subagents/,与 config.json 同目录)。 */ declare const SUBAGENTS_ENGINES_FILENAME: "engines.json"; /** 引擎列表状态文件形状(写侧 extension 权威;读侧运行时 guard,坏形状降级空列表)。 */ interface SubagentEnginesFile { v: 1; /** 已注册引擎 id 清单(注册序稳定;展示名即 id——'pi'/'zcode' 本身是品牌名)。 */ engines: string[]; /** 写入时间(ms epoch;诊断用,读侧不依赖)。 */ updatedAt: number; } /** getEngineConfig RPC 返回形状(engines.json + config.json defaultEngine 的合成视图)。 */ interface SubagentEngineConfigView { /** 可选引擎 id(动态发现;engines.json 缺失/损坏时为 ['pi'] 兜底——pi 恒可用)。 */ engines: string[]; /** 当前 defaultEngine(config.json 值;缺省 'pi')。 */ defaultEngine: string; } /** * pending entries 差集核心(落盘形态语义:customType 字符串 + 抵消/去重规则)—— * 跨端单一实现(ext-simplify-13 D3)。 * * 契约两端(此前各持一份同构差集实现,对齐手段是注释): * - extension 侧:@zhushanwen/pi-base-tool-enhance 对账(原 collectUnsettledTaskIds: * session_start 时对「entries 显示活跃但任务已终态」的 bt- 任务补写注销) * - extension 侧:@zhushanwen/pi-pending-notifications 守卫判据(原 * scanPendingEntries + filterActiveRegisters;其 types/currentSessionId/normalize * 过滤是 pending 产品语义,留在 pending 侧,不在本模块) * * 规则本体(单点):register 首见去重 + unregister 全局抵消 + id 非法跳过, * id 全局唯一(时间戳+随机)是前提。unregister 全局抵消 = 注销 entry 在 entries * 任意位置均抵消同 id(含「register→unregister→register 同 id」复用序列——id 唯一 * 前提下真实数据不复现,语义锁定为已注销)。 * * 零 node 依赖(纯算法),进 index 桶出口。 */ /** pending register entry 的 customType 落盘字符串(协议 SSOT)。 */ declare const PENDING_REGISTER_ENTRY_TYPE: "pending:register"; /** pending unregister entry 的 customType 落盘字符串(协议 SSOT)。 */ declare const PENDING_UNREGISTER_ENTRY_TYPE: "pending:unregister"; /** collectActivePendingIds 的可选过滤(bte 对账便利入口用前缀过滤)。 */ interface CollectPendingIdsOptions { /** 只保留该前缀的 id(如 'bt-');缺省不过滤。 */ idPrefix?: string; } /** scanPendingEntries 的结果:register 原始 data 列表 + 已注销 id 集合。 */ interface PendingEntriesScan { registerEntries: Array<{ data: Record; }>; unregisteredIds: Set; } /** * 单趟扫描 entries 按 customType 分流(容错对齐 pending 侧 S-10:null/非对象 * 元素先守卫再访问字段)。register 侧不校验 id(合法性判定归差集层);unregister * 仅收 string id。data 用最小结构类型 Record,消费方自行窄化。 */ declare function scanPendingEntries(entries: unknown[]): PendingEntriesScan; /** * 差集本体(规则单点):register 首见去重 + unregister 全局抵消 + id 非法跳过。 * 首见判定先于任何消费方过滤(seen.add 后即使调用方对首个 data 过滤丢弃,后续 * 重复条目也不会顶上——与 pending 侧 filterActiveRegisters 的 seen 语义一致)。 * 返回活跃 register 的原始 data 列表(按 entries 出现序)。 */ declare function applyPendingDiff(scan: PendingEntriesScan): Array<{ data: Record; }>; /** * 上层差集组合(bte 对账便利入口):scan + diff + 可选前缀过滤 → 活跃 id 集。 * 前缀过滤是差集之后的独立层(先抵消/去重,再按 id 字符串过滤)。 */ declare function collectActivePendingIds(entries: unknown[], opts?: CollectPendingIdsOptions): Set; /** * 将 pending:unregister 的 reason 映射为 entry 的 status 字段(落盘契约组成部分、 * 权威单点)——pending-notifications index.ts 委托此处(仅做 PendingStatus 类型 * 收窄包装),bte pending-reconcile 写侧同引,两侧映射不再可能漂移(ext-simplify-17 * D10:bte 原以 status === reason 的 identity 假设落盘,映射表演化时会静默漂移)。 * * [U5 / 永久会话模型 §3.2.5 通知词表对齐] subagent-core 新 stopReason 展示值经注销 * reason 通道到达(interrupted/interrupted-by-restart/interrupted-by-parent → aborted、 * reopened → completed)——防新词落 default 被记为 completed 的误标(cancelled 同族 * 事故先例:新枚举值漏映射静默落兜底)。 * * 返回值 MappedPendingStatus(本文件封闭字面量联合):PendingStatus 枚举留在 * pending-notifications(本包不引 extension 侧类型),本联合是其终态子集——消费方 * 免 as 收窄直接赋值。 */ /** mapReasonToStatus 的封闭返回值域:pending-notifications PendingStatus 的终态子集 * (不含初始态 active)。protocol 不引 extension 侧类型(分层裁决不变),以自有 * 字面量联合锁定值域,switch 分支编译期受限。 */ type MappedPendingStatus = 'completed' | 'failed' | 'cancelled' | 'expired' | 'time_limited' | 'aborted'; declare function mapReasonToStatus(reason: string): MappedPendingStatus; export { ASK_USER_MARKER, type AskUserAnswers, type AskUserOption, type AskUserQuestion, BRIDGE_MARKER, BRIDGE_METHODS, type BridgeErrorResponse, type BridgeInterceptResponse, type BridgeMethod, type BridgeRequest, type BridgeSyncPayload, type BridgeToolExecuteResponse, type ChannelErrorResult, type CollectPendingIdsOptions, type DualWidgetContent, GUI_WIDGET_MARKER, type GuiComponent, type GuiComponentProps, type GuiComponentType, type GuiContext, type GuiRenderResult, INFLIGHT_REPORT_ACK, type MappedPendingStatus, type MarkerRpcOptions, type MarkerRpcResult, PENDING_REGISTER_ENTRY_TYPE, PENDING_UNREGISTER_ENTRY_TYPE, PROTOCOL_VERSION, type PendingEntriesScan, SESSION_MANAGER_ACTIONS, SESSION_MANAGER_MARKER, SUBAGENTS_ENGINES_FILENAME, SUBAGENT_INFLIGHT_MARKER, 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 StatItem, type SubagentEngineConfigView, type SubagentEnginesFile, type SubagentInFlightReport, type TreeItem, type TreeItemIcon, type WidgetMeta, applyPendingDiff, askUserInteract, callMarkerRpc, collectActivePendingIds, extractGui, firstContentText, formatChannelErrorText, getAskUserAnswer, getAskUserOther, guiComponent, guiResult, guiSetWidget, isAskUserQuestion, isBridgeErrorResponse, isBridgeInterceptResponse, isBridgeSyncPayload, isBridgeToolExecuteResponse, isChannelErrorResult, isGuiCapable, isGuiComponent, isGuiRenderResult, isInFlightReportAck, isSessionManagerAbortParams, isSessionManagerCreateParams, isSessionManagerHistoryParams, isSessionManagerListParams, isSessionManagerSendParams, isSessionManagerStatusParams, isSubagentInFlightReport, isSyncedTool, mapReasonToStatus, scanPendingEntries, setWidgetDual };