@sema-agent/client-core 0.98.0 → 0.100.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.
Files changed (236) hide show
  1. package/CHANGELOG.md +376 -0
  2. package/README.md +61 -35
  3. package/dist/adapt/arms.js +120 -55
  4. package/dist/adapt/panelTasks.d.ts +3 -2
  5. package/dist/adapt/panelTasks.js +34 -11
  6. package/dist/adapt/textStream.d.ts +1 -1
  7. package/dist/adapt/textStream.js +51 -28
  8. package/dist/adapter/activeRunSelfHeal.d.ts +11 -3
  9. package/dist/adapter/activeRunSelfHeal.js +210 -294
  10. package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
  11. package/dist/adapter/downstream/eventToSdkMessage.js +176 -12
  12. package/dist/adapter/downstream/terminalToSdkResult.js +10 -0
  13. package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
  14. package/dist/adapter/downstream/wiringManifestView.js +1 -0
  15. package/dist/adapter/runStream.js +82 -40
  16. package/dist/adapter/types.d.ts +2 -0
  17. package/dist/adapter/types.js +2 -1
  18. package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
  19. package/dist/agentsWireCaps.d.ts +7 -3
  20. package/dist/agentsWireCaps.js +133 -39
  21. package/dist/cloudConfigWireCaps.d.ts +10 -1
  22. package/dist/cloudConfigWireCaps.js +181 -65
  23. package/dist/compactionStatus.d.ts +34 -0
  24. package/dist/compactionStatus.js +196 -0
  25. package/dist/controlRouter.d.ts +4 -2
  26. package/dist/controlRouter.js +39 -51
  27. package/dist/coreValuePorts.d.ts +26 -1
  28. package/dist/coreValuePorts.js +10 -0
  29. package/dist/corruptSessionCopy.d.ts +2 -1
  30. package/dist/corruptSessionCopy.js +3 -3
  31. package/dist/decideFailureNote.js +3 -3
  32. package/dist/declared/supportFloorDeclared.js +1 -1
  33. package/dist/detachWire.js +3 -2
  34. package/dist/devicesFace.d.ts +34 -0
  35. package/dist/devicesFace.js +90 -0
  36. package/dist/displayUntrusted.d.ts +1 -0
  37. package/dist/displayUntrusted.js +153 -5
  38. package/dist/engineAgentPanelStore.d.ts +14 -4
  39. package/dist/engineAgentPanelStore.js +14 -0
  40. package/dist/engineCapReader.d.ts +2 -1
  41. package/dist/engineCapReader.js +7 -5
  42. package/dist/engineCapsCache.d.ts +8 -0
  43. package/dist/engineCapsCache.js +59 -6
  44. package/dist/engineCapsChange.d.ts +2 -0
  45. package/dist/engineCapsChange.js +9 -0
  46. package/dist/engineErrorCodes.d.ts +11 -2
  47. package/dist/engineErrorCodes.js +11 -12
  48. package/dist/engineRowRef.js +4 -0
  49. package/dist/engineSessionMessages.d.ts +1 -0
  50. package/dist/engineSessionMessages.js +7 -1
  51. package/dist/engineTargetSeat.d.ts +27 -0
  52. package/dist/engineTargetSeat.js +199 -0
  53. package/dist/engineToolDirectory.d.ts +3 -0
  54. package/dist/engineToolDirectory.js +4 -2
  55. package/dist/engineWireFor.js +3 -8
  56. package/dist/env/uiLanguage.d.ts +2 -1
  57. package/dist/env/uiLanguage.js +3 -2
  58. package/dist/eventLeg.d.ts +7 -5
  59. package/dist/eventLeg.js +68 -49
  60. package/dist/fileHistoryCaptureCapability.d.ts +2 -4
  61. package/dist/fileHistoryCaptureCapability.js +12 -22
  62. package/dist/fileHistoryLegNotice.d.ts +2 -1
  63. package/dist/fileHistoryLegNotice.js +3 -3
  64. package/dist/frameBinding.d.ts +3 -0
  65. package/dist/frameBinding.js +12 -0
  66. package/dist/gateOutcome.js +16 -2
  67. package/dist/gateVocabulary.d.ts +8 -7
  68. package/dist/gateVocabulary.js +71 -73
  69. package/dist/generated/engineFactTables.d.ts +18 -1
  70. package/dist/generated/engineFactTables.js +56 -0
  71. package/dist/generated/engineNoticeTables.js +12 -3
  72. package/dist/generated/settingsSchemaFns.d.ts +18 -0
  73. package/dist/generated/settingsSchemaFns.js +70 -0
  74. package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
  75. package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
  76. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
  77. package/dist/generated/settingsSchemaMcpRequestEntry.js +162 -0
  78. package/dist/generated/settingsSchemaTables.d.ts +2 -0
  79. package/dist/generated/settingsSchemaTables.js +9 -0
  80. package/dist/generated/settingsSchemaTypes.d.ts +133 -0
  81. package/dist/generated/settingsSchemaTypes.js +1 -0
  82. package/dist/hitl/allowRuleShadow.d.ts +2 -1
  83. package/dist/hitl/allowRuleShadow.js +18 -15
  84. package/dist/hitl/approvalCardReasons.d.ts +3 -2
  85. package/dist/hitl/approvalCardReasons.js +29 -30
  86. package/dist/hitl/approvalHolds.d.ts +17 -0
  87. package/dist/hitl/approvalHolds.js +114 -29
  88. package/dist/hitl/askClassPair.d.ts +2 -2
  89. package/dist/hitl/askClassPair.js +16 -0
  90. package/dist/hitl/askGateWire.js +2 -1
  91. package/dist/hitl/askSettlementLine.d.ts +14 -4
  92. package/dist/hitl/askSettlementLine.js +67 -47
  93. package/dist/hitl/attributionLadder.d.ts +23 -0
  94. package/dist/hitl/attributionLadder.js +67 -0
  95. package/dist/hitl/automaticAnswerVerdict.d.ts +2 -1
  96. package/dist/hitl/automaticAnswerVerdict.js +8 -8
  97. package/dist/hitl/crashConvergedNotice.d.ts +5 -4
  98. package/dist/hitl/crashConvergedNotice.js +28 -41
  99. package/dist/hitl/decisionLedger.d.ts +55 -0
  100. package/dist/hitl/decisionLedger.js +156 -0
  101. package/dist/hitl/decisionRefusal.d.ts +1 -0
  102. package/dist/hitl/decisionRefusal.js +1 -1
  103. package/dist/hitl/decisionSend.d.ts +113 -0
  104. package/dist/hitl/decisionSend.js +579 -0
  105. package/dist/hitl/frameRouter.js +7 -8
  106. package/dist/hitl/hitlBridge.d.ts +1 -0
  107. package/dist/hitl/hitlBridge.js +21 -9
  108. package/dist/hitl/persistedRulesWire.d.ts +6 -5
  109. package/dist/hitl/persistedRulesWire.js +55 -73
  110. package/dist/hitl/planReviewWire.d.ts +5 -0
  111. package/dist/hitl/planReviewWire.js +53 -76
  112. package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
  113. package/dist/hitl/sessionPolicyDeliverable.js +49 -9
  114. package/dist/hitl/sessionPolicyWire.d.ts +2 -1
  115. package/dist/hitl/sessionPolicyWire.js +23 -24
  116. package/dist/hitl/suspendedReopen.d.ts +2 -1
  117. package/dist/hitl/suspendedReopen.js +7 -10
  118. package/dist/hitl/toolApprovalWire.d.ts +17 -5
  119. package/dist/hitl/toolApprovalWire.js +120 -147
  120. package/dist/hooksWireCaps.js +145 -56
  121. package/dist/host.d.ts +21 -0
  122. package/dist/hostTurnSettings.d.ts +110 -0
  123. package/dist/hostTurnSettings.js +692 -0
  124. package/dist/humanTurn.d.ts +15 -1
  125. package/dist/humanTurn.js +100 -12
  126. package/dist/humanTurnRead.d.ts +2 -0
  127. package/dist/humanTurnRead.js +22 -1
  128. package/dist/i18n/messages.en.d.ts +713 -0
  129. package/dist/i18n/messages.en.js +713 -0
  130. package/dist/i18n/messages.zh.js +854 -1
  131. package/dist/index.d.ts +45 -13
  132. package/dist/index.js +27 -9
  133. package/dist/inheritEnvCapability.d.ts +4 -2
  134. package/dist/inheritEnvCapability.js +12 -5
  135. package/dist/inheritEnvWire.d.ts +3 -2
  136. package/dist/inheritEnvWire.js +14 -16
  137. package/dist/injectionLaneNotice.d.ts +5 -0
  138. package/dist/injectionLaneNotice.js +46 -0
  139. package/dist/interactiveHalt.js +17 -6
  140. package/dist/liveModelCatalog.d.ts +2 -1
  141. package/dist/liveModelCatalog.js +14 -8
  142. package/dist/mcpPanel.d.ts +10 -1
  143. package/dist/mcpPanel.js +42 -13
  144. package/dist/mcpProbeCapability.d.ts +2 -1
  145. package/dist/mcpProbeCapability.js +7 -11
  146. package/dist/mcpProbeWire.d.ts +3 -1
  147. package/dist/mcpProbeWire.js +5 -0
  148. package/dist/mcpReconnect.js +2 -2
  149. package/dist/mcpToolToggles.d.ts +6 -0
  150. package/dist/mcpToolToggles.js +46 -0
  151. package/dist/mcpWireCaps.d.ts +43 -3
  152. package/dist/mcpWireCaps.js +194 -59
  153. package/dist/mcpWireTransport.d.ts +4 -0
  154. package/dist/mcpWireTransport.js +18 -0
  155. package/dist/memoryEntriesWire.js +5 -10
  156. package/dist/model/onboardJudgement.d.ts +93 -0
  157. package/dist/model/onboardJudgement.js +415 -0
  158. package/dist/model/tierVocabulary.d.ts +2 -0
  159. package/dist/model/tierVocabulary.js +17 -5
  160. package/dist/modelCapabilityProbe.d.ts +65 -0
  161. package/dist/modelCapabilityProbe.js +601 -0
  162. package/dist/modelIdentityResolvability.d.ts +5 -0
  163. package/dist/modelIdentityResolvability.js +49 -22
  164. package/dist/ownKey.d.ts +33 -0
  165. package/dist/ownKey.js +109 -0
  166. package/dist/panelReduce.d.ts +11 -1
  167. package/dist/panelReduce.js +95 -16
  168. package/dist/panelStateHolder.d.ts +1 -0
  169. package/dist/panelStateHolder.js +10 -1
  170. package/dist/permissionRuleIssue.d.ts +2 -1
  171. package/dist/permissionRuleIssue.js +23 -20
  172. package/dist/permissionRulesWriteCapability.d.ts +2 -1
  173. package/dist/permissionRulesWriteCapability.js +8 -6
  174. package/dist/pluginHooksWire.d.ts +46 -3
  175. package/dist/pluginHooksWire.js +220 -12
  176. package/dist/prepareRefusal.d.ts +8 -0
  177. package/dist/prepareRefusal.js +72 -0
  178. package/dist/printModelStatus.d.ts +63 -0
  179. package/dist/printModelStatus.js +155 -0
  180. package/dist/request/taskRequest.d.ts +16 -10
  181. package/dist/request/taskRequest.js +195 -58
  182. package/dist/resumeRefusalCopy.d.ts +14 -9
  183. package/dist/resumeRefusalCopy.js +89 -144
  184. package/dist/retryStatus.d.ts +55 -0
  185. package/dist/retryStatus.js +155 -19
  186. package/dist/ruleRefusalSentence.d.ts +4 -0
  187. package/dist/ruleRefusalSentence.js +58 -0
  188. package/dist/sandboxWire.d.ts +2 -1
  189. package/dist/sandboxWire.js +55 -21
  190. package/dist/scenarioRefusal.d.ts +10 -0
  191. package/dist/scenarioRefusal.js +111 -0
  192. package/dist/seam.d.ts +48 -9
  193. package/dist/seam.js +54 -5
  194. package/dist/seatContract.d.ts +272 -14
  195. package/dist/seatContract.js +711 -23
  196. package/dist/selfOrchestrationDenial.js +7 -19
  197. package/dist/sessionIdSegment.d.ts +6 -0
  198. package/dist/sessionIdSegment.js +24 -0
  199. package/dist/sessionMemoryStatus.js +6 -11
  200. package/dist/sessionPolicyCapability.d.ts +2 -1
  201. package/dist/sessionPolicyCapability.js +8 -6
  202. package/dist/settingsCredentialKeyPaths.d.ts +8 -0
  203. package/dist/settingsCredentialKeyPaths.js +219 -0
  204. package/dist/settingsHooksSalvage.d.ts +44 -0
  205. package/dist/settingsHooksSalvage.js +211 -0
  206. package/dist/skillToolListsCapability.d.ts +2 -1
  207. package/dist/skillToolListsCapability.js +8 -6
  208. package/dist/skillsWireCaps.d.ts +0 -3
  209. package/dist/skillsWireCaps.js +1 -2
  210. package/dist/sseIdleTriage.js +3 -2
  211. package/dist/subagent/engineSubagentResume.js +15 -9
  212. package/dist/subagentContentStore.d.ts +4 -0
  213. package/dist/subagentContentStore.js +157 -27
  214. package/dist/toolHistoryMismatch.js +3 -2
  215. package/dist/toolRoster.d.ts +3 -2
  216. package/dist/toolRoster.js +21 -20
  217. package/dist/toolsFlagNames.d.ts +8 -0
  218. package/dist/toolsFlagNames.js +110 -0
  219. package/dist/turnFailurePresentation.d.ts +12 -1
  220. package/dist/turnFailurePresentation.js +220 -15
  221. package/dist/usageAnalytics.js +6 -11
  222. package/dist/userAttachmentEnvelope.d.ts +1 -0
  223. package/dist/userAttachmentEnvelope.js +37 -7
  224. package/dist/userAttachmentSeat.d.ts +21 -0
  225. package/dist/userAttachmentSeat.js +75 -0
  226. package/dist/userInvokedSkillsCapability.d.ts +11 -1
  227. package/dist/userInvokedSkillsCapability.js +31 -7
  228. package/dist/wireErrorTriage.d.ts +7 -0
  229. package/dist/wireErrorTriage.js +23 -1
  230. package/dist/wireFailureShape.js +2 -1
  231. package/dist/wireRefusalCopy.d.ts +62 -16
  232. package/dist/wireRefusalCopy.js +307 -148
  233. package/dist/workflowsJournalCapability.d.ts +2 -1
  234. package/dist/workflowsJournalCapability.js +8 -6
  235. package/docs/INTEGRATION-CLIENTS.md +951 -42
  236. package/package.json +5 -5
package/dist/seam.js CHANGED
@@ -76,6 +76,20 @@ const CHROME_ARM_TABLE = {
76
76
  duty: 'CC-89(0.75.0):一次压缩的非 compacted 结局(作废 / 失败等),给用户一条可见提示。`outcome` / `trigger` 是引擎开集原词,按成员渲染必带 default 臂、认不得照原词显示;' +
77
77
  '🔴 不是终态 —— 任务还在跑,别据它收 spinner;`laneProof.lane` 为 subagent = 子代的压缩结局,别渲成主会话的;成功压缩不走本臂(权威是转录的 compact_boundary)。不接 = 压缩失败对用户不可见。',
78
78
  },
79
+ compaction_started: {
80
+ required: false,
81
+ duty: '可选:一次压缩 pass 宣告开始(服务端 ≥ 7.132.0)—— 要显示「正在压缩」的宿主接它。🔴 别自己配对开 / 收:把本臂、`compaction_outcome` 臂与转录 `compact_boundary` 行喂给' +
82
+ ' `createCompactionStatusTracker()`(按 `pass` 开收、子代车道不点亮主车道、流结束收口),交互车道读它的 `reading()`,print 车道把它的变化转成 CC 同形 `system/status` 帧;' +
83
+ '`trigger` 开集原词(按成员渲染带 default 臂);`startedAt` 缺席 = 没报;本臂不是终态,`laneProof.lane` 为 subagent = 子代的压缩,别渲成主会话的。',
84
+ },
85
+ subagent_started: {
86
+ required: false,
87
+ duty: '可选:委派子代每周期一帧的起跑事实(sdk `task_started`,服务端 ≥ 7.127.0)—— 要「起跑时就开子代行」的宿主接它(不接 = 首个 task_progress 才开行,与 0.98.0 同)。' +
88
+ '🔴 面板的起跑时刻证据:把本事件原样交 `publishEngineAgentPanelStart(event)`(只补行上缺的 `startedAt`、从不建行 / 不改身份归并;workflow 车道自报 `workflowRunId` 的帧它自己忽略)。' +
89
+ '🔴 `taskType` 开集读(缺席 = 前台同步子代,没有 fleet 行);`seq` 缺席 = 没有 a* 行,禁读作第 1 周期;`name` / `workflowAgentLabel` 是 UNTRUSTED 展示文本(渲前过展示出口);' +
90
+ '`laneProof.lane` 为 subagent = 挂在那张委派卡上(`parentToolCallId`),主车道 = 后台代理(卡已收口);workflow 车道的子代别开前台子代行(带 `workflowRunId` 即是);' +
91
+ '本事件不是 spinner / run 终态证据;缺席键 = 服务端没说,不是 0 / 空串。',
92
+ },
79
93
  prompt_assembled: {
80
94
  required: false,
81
95
  duty: 'CC-91(0.76.0):这一次 prepare 的提示词装配清单(每段 / 块多大、挂了哪些工具),/context 类面板的引擎侧真值来源。🔴 一次任务可能多条(cascade / verify / resume 各自 re-prepare)' +
@@ -136,7 +150,8 @@ const CHROME_ARM_TABLE = {
136
150
  approval_request: {
137
151
  required: true,
138
152
  duty: '用 sdk isApprovalRequestFrameV1 窄化 frame 才取 card/askId/窗三键;窄不下来 ⇒ 呈通用卡(安全元数据 + 人工 approve/deny),' +
139
- '🔴 永不 auto-deny;按 approvalId 与 legacy tool_approval 帧去重(同一只 ask 出两帧,优先渲本帧);' +
153
+ '🔴 永不 auto-deny;开卡前调 claimApprovalCard(身份, { signal }):joined / aborted ⇒ 不开卡,held ⇒ 开卡且每条出口恰调一次 hold.release(settled?)' +
154
+ '(去重判定归包 —— legacy 帧那一路的持有与结局在进程级持有表 / 已结表里,宿主不自持 legacy 已收口集);流上下文经 approvalFrameContextOf(这只 chrome 事件) 查,查不到不开卡;' +
140
155
  '🔴 账本重放的历史帧只用于时间线渲染,卡集的全量对账基准是开流 preamble(它带的 expiresInMs 是铸帧时刻的旧值);' +
141
156
  'card 的 message/args 是模型/工具产文,只渲染永不回喂模型',
142
157
  },
@@ -158,13 +173,13 @@ const CHROME_ARM_TABLE = {
158
173
  duty: '🔴 引擎明报的 assistant 散文段边界 + **该段权威全文**(#323/core #447;server ≥7.75.3 起 content 经脱敏器、' +
159
174
  'text_delta 仍逐字 ⇒ 两者**可以不相等**)。①`diverged` 在场(never false)⇒ 你按增量拼出来的那一段是过期的,' +
160
175
  '必须用 content **重渲该段**并以它为该段 committed 文本,不许保留增量拼文;②`committedPrefixDiverged` 在场' +
161
- '(never false)⇒ 这一段此前已 committed 上屏的正文**也**过期了,🔴 本包在这一形上**一个字节都不再交**' +
176
+ '(never false)⇒ 这一段此前已 committed 上屏的正文**也**过期了,🔴 本包在这一形上**一个字节都不再交**(唯一不同:本段已提交行的归属说不出 —— 上游两行同 uuid,`committedUuids` 整键缺席 —— 时本包一个字节不动,还押着的原始那截在本事件之后照旧作为本段末行交出)' +
162
177
  '(撤不回的那截拼不出 content)⇒ 把 committedPrefixLen 指的那一截换成 content,这一条**所有宿主都要做**;' +
163
178
  '缺席 ⇒ 本包交的是尾段,前缀+尾段=content,什么都不用丢;③`committedPrefixLen`(never 0)= 定位量,' +
164
179
  '🔴 **单位 = JS 字符串长度(UTF-16 代码单元),不是 UTF-8 字节、也不是几条消息**' +
165
- '(按 UTF-8 字节截会在非 ASCII 正文上截错位置把凭据留在屏上;按消息丢会连合并在同一条消息里的上一段定稿一起删掉),' +
166
- '照抄 `已committed正文.slice(0, 长度 - committedPrefixLen) + content`;按**增量拼文**计长、不是 content 上的偏移;④三键全缺席 ⇒ 照旧只当对账/定界,拿 content 再渲一行 = 同一段上屏两遍;⑤`segmentId`(恒在场)= 段身份,与本段已过境的 committed 文本行顶层 `_sema_segment_id` 同值 —— 换掉已提交那截时认行的钥匙是**两把**:行 uuid ∧ 段身份(按字节相等找行会被同后缀的独立行冒充)。' +
167
- '🔴 缺席只表示「没报」,绝不等于「段没结束」——要退回自家启发式必须按整条流判、不按单帧判;⑥`committedUuids[]`(0.71.0 起,在场 = 本窗口已提交行按序、`[]` = 零行、整键缺席 = 本包说不出):`committedPrefixDiverged` ⇒ **按 `committedRows[]` 逐行写回正文**(包已算好:首行 = 前段定稿前缀 + content、其余行空;别整行换首行,提交行可能带上一段定稿),端不再自己数窗口里过境的行,也不再对多行段整发放弃;`committedUuid` = 末条兼容位;' +
180
+ '(按 UTF-8 字节截会在非 ASCII 正文上截错位置把凭据留在屏上;按消息丢会连同一条消息里别的段的正文一起删掉),' +
181
+ '照抄 `已committed正文.slice(0, 长度 - committedPrefixLen) + content`;按**增量拼文**计长、不是 content 上的偏移;④三键全缺席 ⇒ 照旧只当对账/定界,拿 content 再渲一行 = 同一段上屏两遍;⑤`segmentId`(恒在场)= 段身份,与本段**全部** committed 文本行顶层 `_sema_segment_id` 同值(一行恰属一个段;本事件之后紧跟本段末行;段只按这一位认,不按消息界 / 相邻猜)—— 换掉已提交那截时认行的钥匙是**两把**:行 uuid ∧ 段身份(按字节相等找行会被同后缀的独立行冒充)。' +
182
+ '🔴 缺席只表示「没报」,绝不等于「段没结束」——要退回自家启发式必须按整条流判、不按单帧判;⑥`committedUuids[]`(0.71.0 起,在场 = 本窗口已提交行按序、`[]` = 零行、整键缺席 = 本包说不出):`committedPrefixDiverged` ⇒ **按 `committedRows[]` 逐行写回正文**(包已算好:首行 = content、其余行空),端不再自己数窗口里过境的行,也不再对多行段整发放弃;`committedUuid` = 末条兼容位;' +
168
183
  '⑦序:该段尾部的活体增量(`stream_delta`)一律先于本事件到达,本事件之后不再有同段增量(下一条增量属于下一段)。',
169
184
  },
170
185
  };
@@ -180,3 +195,37 @@ export function deriveTranscriptId(frame, ctx, suffix) {
180
195
  }
181
196
  return ctx.uuid();
182
197
  }
198
+ export const SEMA_TERMINAL_OWNER_KEY = '_sema_terminal_owner';
199
+ export function terminalOwnerOf(row) {
200
+ try {
201
+ if (typeof row !== 'object' || row === null)
202
+ return undefined;
203
+ const d = Object.getOwnPropertyDescriptor(row, SEMA_TERMINAL_OWNER_KEY);
204
+ if (d === undefined || !('value' in d))
205
+ return undefined;
206
+ const v = d.value;
207
+ if (typeof v !== 'object' || v === null)
208
+ return undefined;
209
+ const own = (k) => {
210
+ const pd = Object.getOwnPropertyDescriptor(v, k);
211
+ return pd !== undefined && 'value' in pd && typeof pd.value === 'string' && pd.value.length > 0 ? pd.value : undefined;
212
+ };
213
+ const kind = own('kind');
214
+ if (kind === 'request-not-sent') {
215
+ const requestId = own('requestId');
216
+ const heldBy = own('heldBy');
217
+ return { kind, ...(requestId !== undefined ? { requestId } : {}), ...(heldBy !== undefined ? { heldBy } : {}) };
218
+ }
219
+ if (kind === 'followed-run') {
220
+ const taskId = own('taskId');
221
+ if (taskId === undefined)
222
+ return undefined;
223
+ const runId = own('runId');
224
+ return { kind, taskId, ...(runId !== undefined ? { runId } : {}) };
225
+ }
226
+ return undefined;
227
+ }
228
+ catch {
229
+ return undefined;
230
+ }
231
+ }
@@ -8,6 +8,11 @@ import type { ApprovalMandateWord } from "./gateVocabulary.js";
8
8
  import type { ModelApiWord } from "./model/providerPresets.js";
9
9
  import type { LiveModelCatalog } from "./liveModelCatalog.js";
10
10
  import { type RewindMode } from "./rewindWireCaps.js";
11
+ import { type ProbeVerdictWord } from "./modelCapabilityProbe.js";
12
+ import type { SubagentContentEvent } from "./subagentContentStore.js";
13
+ import type { DeviceEnrollTokenOutcome, DeviceListOutcome, DeviceRebindOutcome, DeviceRevokeOutcome, DeviceSessionBindingOutcome, DeviceTransport, DeviceUnarmed, DeviceUnreadable } from "./deviceRebind.js";
14
+ import type { McpPanelView } from "./mcpPanel.js";
15
+ import type { McpToolToggleKey } from "./mcpToolToggles.js";
11
16
  export interface SeatValidationFailure {
12
17
  reason: string;
13
18
  field?: string;
@@ -71,7 +76,7 @@ export interface ToolPermissionRequest {
71
76
  classes?: readonly string[];
72
77
  sessionRow?: true;
73
78
  }
74
- declare const SEAT_EVENT_TYPE_TUPLE: readonly ["start", "close", "session_updated", "message", "stream_event", "chrome_event", "error", "tool_permission_resolved"];
79
+ declare const SEAT_EVENT_TYPE_TUPLE: readonly ["start", "close", "session_updated", "message", "stream_event", "chrome_event", "error", "tool_permission_resolved", "subagent_content"];
75
80
  export type SeatEventType = (typeof SEAT_EVENT_TYPE_TUPLE)[number];
76
81
  export declare const SEAT_EVENT_TYPES: readonly SeatEventType[];
77
82
  declare const CHROME_EVENT_KIND_TUPLE: readonly ["panel_task", "notification_terminal", "prompt_suggestions", "subagent_lifecycle", "text_segment_end", "thinking_segment_end", "retry_status", "context_usage", "last_turn_usage", "bgshell_register", "bgshell_settle", "memory_saved", "result_replayed", "tool_parked"];
@@ -93,14 +98,13 @@ export interface LocalSessionEvent {
93
98
  errorCategory?: string;
94
99
  _sema_turnFailure?: SeatTurnFailure;
95
100
  code?: number;
96
- request?: ToolPermissionRequest;
97
- sources?: string[];
98
101
  session?: LocalSessionRecord;
99
102
  userMessageUuid?: string;
100
103
  requestId?: string;
101
104
  outcome?: string;
102
105
  parked?: true;
103
106
  chrome?: SeatChromeEnvelope;
107
+ subagentContent?: SubagentContentEvent;
104
108
  }
105
109
  export declare const HITL_RESOLUTION_OUTCOMES: readonly string[];
106
110
  export declare const SEAT_STREAM_DELTA_TYPE_OF_CHANNEL: Readonly<{
@@ -141,13 +145,17 @@ export type SeatStreamReading = {
141
145
  };
142
146
  export declare function seatStreamDeltaMessage(event: SeatStreamDeltaSource, ids: SeatStreamDeltaIds): SeatStreamEventMessage | undefined;
143
147
  export declare function readSeatStreamDelta(message: object): SeatStreamReading;
144
- export declare const SEAT_CAPABILITY_NAMES: readonly ["pickFolder", "rewind", "recents", "patchSession"];
148
+ export declare const SEAT_CAPABILITY_NAMES: readonly ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles"];
145
149
  export type SeatCapabilityName = (typeof SEAT_CAPABILITY_NAMES)[number];
146
150
  export interface SeatCapabilitiesState {
147
151
  pickFolder?: boolean;
148
152
  rewind?: boolean;
149
153
  recents?: boolean;
150
154
  patchSession?: boolean;
155
+ devices?: boolean;
156
+ engineTarget?: boolean;
157
+ onboard?: boolean;
158
+ mcpToolToggles?: boolean;
151
159
  }
152
160
  export type SeatCapabilityReading = {
153
161
  readonly kind: "reported";
@@ -201,16 +209,16 @@ export declare const SEAT_TURN_SETTINGS_ORIGINS: Readonly<{
201
209
  carriedBy: "renderer";
202
210
  }>;
203
211
  webSearch: Readonly<{
204
- hostSupplied: "联网检索的每请求配置来自宿主的设置源(可能带检索服务的凭据与私网地址);渲染端没有设置文件,也不该持有凭据";
212
+ hostSupplied: "settings.webSearch";
205
213
  }>;
206
214
  hooks: Readonly<{
207
- hostSupplied: "hooks 表来自宿主的设置文件(宿主经设置端口与 hooksForWire 投影);渲染端没有设置文件、也不执行本机 hook";
215
+ hostSupplied: "settings.hooks";
208
216
  }>;
209
217
  resolved: Readonly<{
210
- hostSupplied: "设置解析器的生效快照(hooks / env / model / 已解析权限)由宿主跑解析器得出;渲染端没有设置源可解析";
218
+ hostSupplied: "settings.resolved";
211
219
  }>;
212
220
  outputStyle: Readonly<{
213
- hostSupplied: "输出风格正文由宿主的兜底层随请求带(风格文件在宿主);渲染端只选名字,不持正文";
221
+ hostSupplied: "settings.outputStyle";
214
222
  }>;
215
223
  }>;
216
224
  export interface SeatRewindIntent {
@@ -318,6 +326,228 @@ export interface RecentFolderRow {
318
326
  export interface RecentFoldersResult {
319
327
  folders: RecentFolderRow[];
320
328
  }
329
+ export interface SeatDeviceRebindRequest {
330
+ sessionId: string;
331
+ toDeviceId: string;
332
+ expectedRev: number;
333
+ fromDeviceId: string;
334
+ }
335
+ export interface SeatDeviceRevokeRequest {
336
+ deviceId: string;
337
+ reason?: string;
338
+ }
339
+ export declare const checkSeatDeviceRebindRequest: (v: unknown) => SeatValidation;
340
+ export declare const checkSeatDeviceRevokeRequest: (v: unknown) => SeatValidation;
341
+ export declare const ENGINE_TARGET_REFUSALS: readonly ["busy", "switching", "not_configured", "not_signed_in", "probe_failed", "org_policy", "url_refused", "login_failed", "storage_unavailable", "no_local_runtime", "input"];
342
+ export type EngineTargetRefusal = (typeof ENGINE_TARGET_REFUSALS)[number];
343
+ export declare const CLOUD_LOGIN_FAILURES: readonly ["access_denied", "expired_token", "invalid_grant", "cancelled", "transport", "refused", "no_tokens", "other"];
344
+ export type CloudLoginFailure = (typeof CLOUD_LOGIN_FAILURES)[number];
345
+ export interface CloudLoginFailureReading {
346
+ failure: CloudLoginFailure;
347
+ status?: number;
348
+ }
349
+ export interface EngineProbeReading {
350
+ ok: boolean;
351
+ version?: string;
352
+ detail?: string;
353
+ at: string;
354
+ }
355
+ export type EngineTargetCloudAuth = {
356
+ kind: "registry";
357
+ registryUrl: string;
358
+ principal?: string;
359
+ role?: string;
360
+ scope?: string;
361
+ } | {
362
+ kind: "token";
363
+ };
364
+ export type CloudLoginState = {
365
+ state: "pending";
366
+ registryUrl: string;
367
+ userCode: string;
368
+ verificationUri: string;
369
+ verificationUriComplete?: string;
370
+ expiresAt: string;
371
+ } | {
372
+ state: "failed";
373
+ failure: CloudLoginFailure;
374
+ status?: number;
375
+ at: string;
376
+ };
377
+ export interface CloudAuthErrorState {
378
+ failure: CloudLoginFailure;
379
+ status?: number;
380
+ at: string;
381
+ }
382
+ export interface EngineTargetCloud {
383
+ configured: boolean;
384
+ url?: string;
385
+ label?: string;
386
+ auth?: EngineTargetCloudAuth;
387
+ login?: CloudLoginState;
388
+ lastProbe?: EngineProbeReading;
389
+ authError?: CloudAuthErrorState;
390
+ orgEngine?: {
391
+ url: string;
392
+ required: boolean;
393
+ };
394
+ }
395
+ export interface SeatLocalMcpRow {
396
+ name: string;
397
+ status: string;
398
+ toolCount?: number;
399
+ liveness?: string;
400
+ errorCode?: string;
401
+ forcedAsk?: string[];
402
+ }
403
+ export type SeatLocalMcpReading = {
404
+ status: "listed";
405
+ servers: SeatLocalMcpRow[];
406
+ readAt: string;
407
+ restartRequired?: true;
408
+ } | {
409
+ status: "unreadable";
410
+ cause: string;
411
+ detail?: string;
412
+ readAt: string;
413
+ restartRequired?: true;
414
+ };
415
+ export interface EngineTargetLocal {
416
+ lastBootError?: string;
417
+ mcp?: SeatLocalMcpReading;
418
+ }
419
+ export interface EngineTargetState {
420
+ mode: "local" | "cloud";
421
+ generation: number;
422
+ cloud: EngineTargetCloud;
423
+ local: EngineTargetLocal;
424
+ }
425
+ export interface EngineTargetRefused {
426
+ ok: false;
427
+ refusal: EngineTargetRefusal;
428
+ failure?: CloudLoginFailure;
429
+ status?: number;
430
+ detail?: string;
431
+ }
432
+ export type EngineTargetResult = {
433
+ ok: true;
434
+ } | EngineTargetRefused;
435
+ export type CloudLoginStart = {
436
+ ok: true;
437
+ verificationUri: string;
438
+ verificationUriComplete?: string;
439
+ userCode: string;
440
+ expiresAt: string;
441
+ } | EngineTargetRefused;
442
+ export type CloudConnectResult = {
443
+ ok: true;
444
+ probe: {
445
+ version?: string;
446
+ };
447
+ } | EngineTargetRefused;
448
+ export interface CloudLoginRequest {
449
+ registryUrl: string;
450
+ }
451
+ export interface CloudEngineConnectRequest {
452
+ url: string;
453
+ }
454
+ export interface CloudEngineConfigureRequest {
455
+ url: string;
456
+ token: string;
457
+ }
458
+ export declare const checkCloudLoginRequest: (v: unknown) => SeatValidation;
459
+ export declare const checkCloudEngineConnectRequest: (v: unknown) => SeatValidation;
460
+ export declare const checkCloudEngineConfigureRequest: (v: unknown) => SeatValidation;
461
+ export type OnboardProbeVerdict = ProbeVerdictWord;
462
+ export declare const ONBOARD_REFUSALS: readonly ["input", "probe_failed", "probe_unverified", "credential_unpaired", "catalog_unreadable", "write_conflict", "write_failed", "engine_is_remote", "env_catalog_present"];
463
+ export type OnboardRefusal = (typeof ONBOARD_REFUSALS)[number];
464
+ export type EngineRestartOutcome = {
465
+ state: "started" | "restarted";
466
+ model: string | null;
467
+ } | {
468
+ state: "pending" | "failed" | "skipped";
469
+ reason: string;
470
+ };
471
+ export type OnboardSource = {
472
+ kind: "preset";
473
+ providerId: string;
474
+ } | {
475
+ kind: "custom";
476
+ } | {
477
+ kind: "imported";
478
+ profileId: string;
479
+ };
480
+ export interface OnboardEntryRequest {
481
+ source: OnboardSource;
482
+ modelId: string;
483
+ baseUrl?: string;
484
+ api?: ModelApiWord;
485
+ apiKey?: string;
486
+ contextWindow?: number;
487
+ maxTokens?: number;
488
+ }
489
+ export interface OnboardApplyRequest extends OnboardEntryRequest {
490
+ makeDefault?: boolean;
491
+ acceptUnverified?: boolean;
492
+ }
493
+ export interface OnboardProbeResult {
494
+ verdict: OnboardProbeVerdict;
495
+ detail: string;
496
+ thinking?: string;
497
+ }
498
+ export interface OnboardCatalogIssue {
499
+ name: string;
500
+ modelId: string;
501
+ issue: string;
502
+ }
503
+ export type OnboardApplyResult = {
504
+ ok: true;
505
+ entryName: string;
506
+ modelId: string;
507
+ keyEnv: string;
508
+ updatedExisting: boolean;
509
+ probe: OnboardProbeResult;
510
+ otherIssues: OnboardCatalogIssue[];
511
+ engine: EngineRestartOutcome;
512
+ } | {
513
+ ok: false;
514
+ refusal: OnboardRefusal;
515
+ detail?: string;
516
+ probe?: OnboardProbeResult;
517
+ };
518
+ export interface OnboardProviderModel {
519
+ id: string;
520
+ contextWindow: number;
521
+ maxTokens: number;
522
+ }
523
+ export interface OnboardProviderRow {
524
+ id: string;
525
+ name: string;
526
+ baseUrl: string;
527
+ api: ModelApiWord;
528
+ keyAuth: boolean;
529
+ authEnv: string;
530
+ models: OnboardProviderModel[];
531
+ consoleUrl?: string;
532
+ }
533
+ export interface OnboardImportableProfile {
534
+ id: string;
535
+ name: string;
536
+ baseUrl: string;
537
+ api: ModelApiWord;
538
+ hasKey: boolean;
539
+ models: string[];
540
+ }
541
+ export interface OnboardProvidersResult {
542
+ providers: OnboardProviderRow[];
543
+ importable?: OnboardImportableProfile[];
544
+ }
545
+ export declare const checkOnboardEntryRequest: (v: unknown) => SeatValidation;
546
+ export declare const checkOnboardApplyRequest: (v: unknown) => SeatValidation;
547
+ export declare const checkMcpToolToggleKey: (v: unknown) => SeatValidation;
548
+ export interface McpToolTogglesResult {
549
+ off: McpToolToggleKey[];
550
+ }
321
551
  export interface LocalSessionsApi {
322
552
  start(opts?: StartSessionOptions): Promise<LocalSessionRecord>;
323
553
  sendMessage(req: SendMessageRequest): Promise<SendMessageAck>;
@@ -338,15 +568,34 @@ export interface LocalSessionsApi {
338
568
  listRecentFolders(): Promise<RecentFoldersResult>;
339
569
  noteRecentFolder(path: string): Promise<OkAck>;
340
570
  patchSession(req: SessionRowPatchRequest): Promise<LocalSessionRecord>;
571
+ listDevices(): Promise<DeviceListOutcome>;
572
+ readSessionBinding(sessionId: string): Promise<DeviceSessionBindingOutcome>;
573
+ rebindSession(req: SeatDeviceRebindRequest): Promise<DeviceRebindOutcome>;
574
+ issueEnrollToken(): Promise<DeviceEnrollTokenOutcome>;
575
+ revokeDevice(req: SeatDeviceRevokeRequest): Promise<DeviceRevokeOutcome>;
576
+ setEngineMode(mode: "local" | "cloud"): Promise<EngineTargetResult>;
577
+ startCloudLogin(req: CloudLoginRequest): Promise<CloudLoginStart>;
578
+ cancelCloudLogin(): Promise<OkAck>;
579
+ connectCloudEngine(req: CloudEngineConnectRequest): Promise<CloudConnectResult>;
580
+ configureCloudEngine(req: CloudEngineConfigureRequest): Promise<CloudConnectResult>;
581
+ clearCloudEngine(): Promise<EngineTargetResult>;
582
+ listOnboardProviders(): Promise<OnboardProvidersResult>;
583
+ probeOnboardEntry(req: OnboardEntryRequest): Promise<OnboardProbeResult>;
584
+ applyOnboardEntry(req: OnboardApplyRequest): Promise<OnboardApplyResult>;
585
+ readSessionMcpPanel(sessionId: string): Promise<McpPanelView | DeviceUnreadable | DeviceTransport | DeviceUnarmed>;
586
+ listMcpToolToggles(): Promise<McpToolTogglesResult>;
587
+ setMcpToolToggle(key: McpToolToggleKey, enabled: boolean): Promise<OkAck>;
341
588
  onEvent(cb: (ev: LocalSessionEvent) => void): () => void;
342
589
  onToolPermissionRequest(cb: (req: ToolPermissionRequest) => void): () => void;
343
590
  sessionsStateStore: EipcStoreClient<SessionsState>;
344
591
  focusedSessionStateStore: EipcStoreClient<FocusedSessionState>;
345
592
  settingsStateStore: EipcStoreClient<SettingsState>;
346
593
  seatCapabilitiesStateStore: EipcStoreClient<SeatCapabilitiesState>;
594
+ engineTargetStateStore: EipcStoreClient<EngineTargetState>;
347
595
  }
348
596
  export declare function isLocalSessionRecord(s: unknown): s is LocalSessionRecord;
349
597
  export declare function isToolPermissionRequest(r: unknown): r is ToolPermissionRequest;
598
+ export declare function readSeatSubagentContent(event: object): SubagentContentEvent | undefined;
350
599
  export declare function isLocalSessionEvent(v: unknown): v is LocalSessionEvent;
351
600
  export declare function isAttachmentUploadReceipt(v: unknown): v is AttachmentUploadReceipt;
352
601
  export interface SeatCatalogEntry {
@@ -379,10 +628,10 @@ export declare const checkSessionRowPatchRequest: (v: unknown) => SeatValidation
379
628
  export declare function isSessionRowPatchRequest(v: unknown): v is SessionRowPatchRequest;
380
629
  export declare function isSendMessageAck(v: unknown): v is SendMessageAck;
381
630
  export declare const LOCAL_SESSIONS_SPEC: EipcServiceSpec;
382
- export declare const SEAT_METHOD_NAMES: readonly ["start", "sendMessage", "interrupt", "stop", "respondToToolPermission", "cancelQueuedMessage", "reorderQueuedMessage", "promoteQueuedMessage", "setFocusedSession", "setModel", "getTranscript", "searchSessions", "uploadAttachment", "listModels", "applyModelConfig", "pickFolder", "listRecentFolders", "noteRecentFolder", "patchSession", "onEvent", "onToolPermissionRequest"];
383
- export declare const SEAT_STORE_PROPS: readonly ["sessionsStateStore", "focusedSessionStateStore", "settingsStateStore", "seatCapabilitiesStateStore"];
631
+ export declare const SEAT_METHOD_NAMES: readonly ["start", "sendMessage", "interrupt", "stop", "respondToToolPermission", "cancelQueuedMessage", "reorderQueuedMessage", "promoteQueuedMessage", "setFocusedSession", "setModel", "getTranscript", "searchSessions", "uploadAttachment", "listModels", "applyModelConfig", "pickFolder", "listRecentFolders", "noteRecentFolder", "patchSession", "listDevices", "readSessionBinding", "rebindSession", "issueEnrollToken", "revokeDevice", "setEngineMode", "startCloudLogin", "cancelCloudLogin", "connectCloudEngine", "configureCloudEngine", "clearCloudEngine", "listOnboardProviders", "probeOnboardEntry", "applyOnboardEntry", "readSessionMcpPanel", "listMcpToolToggles", "setMcpToolToggle", "onEvent", "onToolPermissionRequest"];
632
+ export declare const SEAT_STORE_PROPS: readonly ["sessionsStateStore", "focusedSessionStateStore", "settingsStateStore", "seatCapabilitiesStateStore", "engineTargetStateStore"];
384
633
  export declare const SEAT_EVENT_METHOD_NAMES: readonly ["onEvent", "onToolPermissionRequest"];
385
- export declare const LOCAL_SESSION_EVENT_KEYS: readonly ["type", "sessionId", "message", "error", "errorCategory", "code", "request", "sources", "session", "userMessageUuid", "requestId", "outcome", "parked", "chrome", "_sema_turnFailure"];
634
+ export declare const LOCAL_SESSION_EVENT_KEYS: readonly ["type", "sessionId", "message", "error", "errorCategory", "code", "session", "userMessageUuid", "requestId", "outcome", "parked", "chrome", "_sema_turnFailure", "subagentContent"];
386
635
  export declare const TOOL_PERMISSION_REQUEST_KEYS: readonly ["requestId", "sessionId", "toolName", "toolCallId", "input", "message", "toctouBinding", "createdAtMs", "governanceForced", "delegation", "mandated", "mandate", "origin", "ruleOffersAbsence", "askClass", "classes", "sessionRow"];
387
636
  export declare const LOCAL_SESSION_RECORD_KEYS: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned"];
388
637
  export declare const SEND_MESSAGE_REQUEST_KEYS: readonly ["sessionId", "text", "model", "userMessageUuid", "permissionMode", "attachmentIds", "reasoningEffort", "retainBackgroundProcesses", "forwardSubagentEvents", "retainSubagentSessions", "settings", "scenario", "rewind"];
@@ -476,7 +725,7 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
476
725
  readonly LocalSessionEvent: {
477
726
  readonly guard: "isLocalSessionEvent";
478
727
  readonly check: (v: unknown) => SeatValidation;
479
- readonly validated: readonly ["type", "sessionId", "error", "errorCategory", "code", "request", "sources", "session", "userMessageUuid", "requestId", "outcome", "parked", "chrome"];
728
+ readonly validated: readonly ["type", "sessionId", "error", "errorCategory", "code", "session", "userMessageUuid", "requestId", "outcome", "parked", "chrome", "subagentContent"];
480
729
  readonly unchecked: readonly [{
481
730
  readonly key: "message";
482
731
  readonly why: "transcript 面直通位(CC fQe 逐字姿态:SDKMessage 体不做 schema 校验)—— 校它 = 引擎加一种消息体的那天整条转录被门吃掉。";
@@ -567,7 +816,7 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
567
816
  };
568
817
  readonly SeatCapabilitiesState: {
569
818
  readonly check: (v: unknown) => SeatValidation;
570
- readonly validated: readonly ["pickFolder", "rewind", "recents", "patchSession"];
819
+ readonly validated: readonly ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles"];
571
820
  readonly unchecked: readonly [];
572
821
  };
573
822
  readonly RecentFoldersResult: {
@@ -600,8 +849,17 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
600
849
  readonly validated: readonly ["kind", "laneProof"];
601
850
  readonly unchecked: readonly [];
602
851
  };
852
+ readonly SessionMcpPanelResult: {
853
+ readonly check: (v: unknown) => SeatValidation;
854
+ readonly validated: readonly ["kind", "why", "detail", "asOf", "servers", "lastLegMcp", "lastLegMcpUnreadable", "degraded", "scenarioRefusal"];
855
+ readonly unchecked: readonly [];
856
+ };
603
857
  };
604
- export declare const SEAT_VALIDATOR_COVERAGE_EXEMPT: readonly [{
858
+ export declare const SEAT_VALIDATOR_COVERAGE_EXEMPT: readonly [...{
859
+ label: "DeviceListOutcome" | "DeviceSessionBindingOutcome" | "DeviceRebindOutcome" | "DeviceEnrollTokenOutcome" | "DeviceRevokeOutcome" | "SeatDeviceRebindRequest" | "SeatDeviceRevokeRequest" | "EngineTargetState" | "EngineTargetResult" | "CloudLoginStart" | "CloudLoginCancelAck" | "CloudConnectResult" | "CloudLoginRequest" | "CloudEngineConnectRequest" | "CloudEngineConfigureRequest" | "OnboardProvidersResult" | "OnboardProbeResult" | "OnboardApplyResult" | "OnboardEntryRequest" | "OnboardApplyRequest" | "McpToolTogglesResult" | "McpToolToggleKey";
860
+ check: (v: unknown) => SeatValidation;
861
+ why: string;
862
+ }[], {
605
863
  readonly label: "PickFolderResult";
606
864
  readonly check: (v: unknown) => SeatValidation;
607
865
  readonly why: "载荷是**串或 null**(选中的路径 / 用户取消,CC-469),没有键面 ⇒ `keyof` 覆盖表在它身上无从谈起。判别力由 run-seat-wave2-test.mjs ST1-1 承担:认 null 与非空串、拒空串 / 数 / undefined / 对象 / 布尔五形。";