@sema-agent/client-core 0.77.0 → 0.77.2

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 (382) hide show
  1. package/CHANGELOG.md +23 -1
  2. package/README.md +5 -4
  3. package/dist/abortableSleep.d.ts +0 -28
  4. package/dist/abortableSleep.js +0 -28
  5. package/dist/adapt/arms.d.ts +0 -46
  6. package/dist/adapt/arms.js +9 -544
  7. package/dist/adapt/ids.d.ts +0 -58
  8. package/dist/adapt/ids.js +0 -63
  9. package/dist/adapt/instanceLedger.d.ts +0 -25
  10. package/dist/adapt/instanceLedger.js +0 -20
  11. package/dist/adapt/panelTasks.d.ts +0 -69
  12. package/dist/adapt/panelTasks.js +0 -95
  13. package/dist/adapt/textSegmentAuthority.d.ts +1 -137
  14. package/dist/adapt/textSegmentAuthority.js +0 -54
  15. package/dist/adapt/textStream.d.ts +0 -252
  16. package/dist/adapt/textStream.js +2 -281
  17. package/dist/adapt/toolCards.d.ts +0 -46
  18. package/dist/adapt/toolCards.js +0 -23
  19. package/dist/adapt/turnFlags.d.ts +0 -54
  20. package/dist/adapt/turnFlags.js +1 -17
  21. package/dist/adapt/wireShapes.d.ts +0 -92
  22. package/dist/adapt/wireShapes.js +0 -83
  23. package/dist/adapt.d.ts +0 -55
  24. package/dist/adapt.js +1 -120
  25. package/dist/adapter/activeRunSelfHeal.d.ts +22 -515
  26. package/dist/adapter/activeRunSelfHeal.js +10 -625
  27. package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -305
  28. package/dist/adapter/downstream/eventToSdkMessage.js +2 -867
  29. package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -314
  30. package/dist/adapter/downstream/terminalToSdkResult.js +13 -560
  31. package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +0 -95
  32. package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -31
  33. package/dist/adapter/runStream.d.ts +0 -206
  34. package/dist/adapter/runStream.js +6 -596
  35. package/dist/adapter/types.d.ts +0 -111
  36. package/dist/adapter/types.js +0 -29
  37. package/dist/agentSession/backgroundView.d.ts +0 -106
  38. package/dist/agentSession/backgroundView.js +3 -49
  39. package/dist/agentSession/contract.d.ts +0 -98
  40. package/dist/agentSession/contract.js +0 -12
  41. package/dist/agentsWireCaps.d.ts +0 -72
  42. package/dist/agentsWireCaps.js +4 -72
  43. package/dist/approvalsStreamLiveCapability.d.ts +0 -25
  44. package/dist/approvalsStreamLiveCapability.js +0 -31
  45. package/dist/argvFlagValue.d.ts +0 -33
  46. package/dist/argvFlagValue.js +3 -35
  47. package/dist/attachmentsWireCaps.d.ts +0 -127
  48. package/dist/attachmentsWireCaps.js +0 -144
  49. package/dist/autoModeUnavailable.d.ts +0 -120
  50. package/dist/autoModeUnavailable.js +0 -144
  51. package/dist/classifierStatus.d.ts +0 -72
  52. package/dist/classifierStatus.js +0 -167
  53. package/dist/classifierVerdictWire.d.ts +0 -54
  54. package/dist/classifierVerdictWire.js +0 -133
  55. package/dist/clientContextWireCaps.d.ts +0 -37
  56. package/dist/clientContextWireCaps.js +0 -36
  57. package/dist/clientSlice.d.ts +0 -63
  58. package/dist/clientSlice.js +0 -45
  59. package/dist/cloudConfigWireCaps.d.ts +0 -86
  60. package/dist/cloudConfigWireCaps.js +2 -65
  61. package/dist/compensations.d.ts +0 -52
  62. package/dist/compensations.js +2 -63
  63. package/dist/controlRouter.d.ts +2 -208
  64. package/dist/controlRouter.js +1 -129
  65. package/dist/coreValuePorts.d.ts +0 -84
  66. package/dist/coreValuePorts.js +0 -29
  67. package/dist/decideReceipt.d.ts +0 -110
  68. package/dist/decideReceipt.js +0 -84
  69. package/dist/detachWire.d.ts +0 -130
  70. package/dist/detachWire.js +1 -130
  71. package/dist/deviceExecutorManagementCapability.d.ts +2 -35
  72. package/dist/deviceExecutorManagementCapability.js +1 -37
  73. package/dist/diagnostics.d.ts +0 -8
  74. package/dist/diagnostics.js +0 -8
  75. package/dist/diff/patch.d.ts +0 -17
  76. package/dist/diff/patch.js +0 -19
  77. package/dist/effectiveFacts.d.ts +0 -40
  78. package/dist/effectiveFacts.js +0 -22
  79. package/dist/effortWire.d.ts +0 -11
  80. package/dist/effortWire.js +0 -12
  81. package/dist/engineAgentPanelStore.d.ts +0 -169
  82. package/dist/engineAgentPanelStore.js +13 -293
  83. package/dist/engineCapReader.d.ts +0 -62
  84. package/dist/engineCapReader.js +1 -43
  85. package/dist/engineCapsCache.d.ts +0 -177
  86. package/dist/engineCapsCache.js +0 -199
  87. package/dist/engineCapsGenerationGuard.d.ts +0 -2
  88. package/dist/engineCapsGenerationGuard.js +0 -11
  89. package/dist/engineErrorCodes.d.ts +1 -316
  90. package/dist/engineErrorCodes.js +0 -427
  91. package/dist/engineHttpTools.d.ts +0 -29
  92. package/dist/engineHttpTools.js +0 -29
  93. package/dist/engineIdentity.d.ts +0 -83
  94. package/dist/engineIdentity.js +0 -88
  95. package/dist/engineInlineTaskStats.d.ts +0 -57
  96. package/dist/engineInlineTaskStats.js +1 -42
  97. package/dist/engineNoticeCodes.d.ts +0 -190
  98. package/dist/engineNoticeCodes.js +0 -182
  99. package/dist/engineSessionParam.d.ts +0 -30
  100. package/dist/engineSessionParam.js +0 -52
  101. package/dist/engineToolLabelStore.d.ts +0 -29
  102. package/dist/engineToolLabelStore.js +0 -31
  103. package/dist/engineWireSdk.d.ts +0 -90
  104. package/dist/engineWireSdk.js +0 -74
  105. package/dist/engineWireTarget.d.ts +0 -14
  106. package/dist/engineWireTarget.js +0 -39
  107. package/dist/env/localeGeo.d.ts +0 -12
  108. package/dist/env/localeGeo.js +2 -77
  109. package/dist/env/localeTag.d.ts +0 -34
  110. package/dist/env/localeTag.js +0 -32
  111. package/dist/env/uiLanguage.d.ts +0 -13
  112. package/dist/env/uiLanguage.js +0 -25
  113. package/dist/envFlag.d.ts +0 -37
  114. package/dist/envFlag.js +0 -40
  115. package/dist/executionLaneCapability.d.ts +0 -48
  116. package/dist/executionLaneCapability.js +0 -54
  117. package/dist/finalVerifyWire.d.ts +0 -67
  118. package/dist/finalVerifyWire.js +3 -43
  119. package/dist/fleet/fleetLedger.d.ts +0 -308
  120. package/dist/fleet/fleetLedger.js +10 -429
  121. package/dist/fleet/fleetProjection.d.ts +0 -240
  122. package/dist/fleet/fleetProjection.js +0 -189
  123. package/dist/fleet/fleetRowAgentType.d.ts +0 -6
  124. package/dist/fleet/fleetRowAgentType.js +1 -32
  125. package/dist/fleet/workflowSizeWarning.d.ts +0 -47
  126. package/dist/fleet/workflowSizeWarning.js +1 -46
  127. package/dist/fleetAgentPanelProjection.d.ts +0 -48
  128. package/dist/fleetAgentPanelProjection.js +8 -173
  129. package/dist/fleetTaskDesc.d.ts +0 -39
  130. package/dist/fleetTaskDesc.js +0 -69
  131. package/dist/forkWireCaps.d.ts +0 -23
  132. package/dist/forkWireCaps.js +1 -24
  133. package/dist/gateOutcome.d.ts +0 -140
  134. package/dist/gateOutcome.js +0 -85
  135. package/dist/gateVocabulary.d.ts +0 -114
  136. package/dist/gateVocabulary.js +1 -161
  137. package/dist/goalStopHook.d.ts +0 -127
  138. package/dist/goalStopHook.js +0 -178
  139. package/dist/headlessPermissionModeWire.d.ts +0 -76
  140. package/dist/headlessPermissionModeWire.js +1 -155
  141. package/dist/headlessReconnectWire.d.ts +0 -84
  142. package/dist/headlessReconnectWire.js +13 -67
  143. package/dist/hitl/approvalDecisionNoteAudit.d.ts +0 -49
  144. package/dist/hitl/approvalDecisionNoteAudit.js +0 -56
  145. package/dist/hitl/approvalOutcomeNote.d.ts +0 -2
  146. package/dist/hitl/approvalOutcomeNote.js +0 -20
  147. package/dist/hitl/approvalResolution.d.ts +0 -113
  148. package/dist/hitl/approvalResolution.js +0 -66
  149. package/dist/hitl/approvalsFeed.d.ts +0 -183
  150. package/dist/hitl/approvalsFeed.js +12 -243
  151. package/dist/hitl/armedGateRegistry.d.ts +0 -55
  152. package/dist/hitl/armedGateRegistry.js +0 -146
  153. package/dist/hitl/askGateWire.d.ts +0 -86
  154. package/dist/hitl/askGateWire.js +1 -95
  155. package/dist/hitl/askParkRowRouting.d.ts +0 -123
  156. package/dist/hitl/askParkRowRouting.js +1 -89
  157. package/dist/hitl/crashConverged.d.ts +0 -148
  158. package/dist/hitl/crashConverged.js +0 -214
  159. package/dist/hitl/editedRuleTextPrecheck.d.ts +0 -109
  160. package/dist/hitl/editedRuleTextPrecheck.js +0 -71
  161. package/dist/hitl/frameRouter.d.ts +0 -134
  162. package/dist/hitl/frameRouter.js +6 -378
  163. package/dist/hitl/gateIdentity.d.ts +0 -39
  164. package/dist/hitl/gateIdentity.js +0 -41
  165. package/dist/hitl/gateLedger.d.ts +0 -267
  166. package/dist/hitl/gateLedger.js +0 -121
  167. package/dist/hitl/hitlBridge.d.ts +7 -431
  168. package/dist/hitl/hitlBridge.js +7 -476
  169. package/dist/hitl/hitlHostSurface.d.ts +0 -150
  170. package/dist/hitl/hitlHostSurface.js +0 -169
  171. package/dist/hitl/livePendingAsk.d.ts +0 -91
  172. package/dist/hitl/livePendingAsk.js +0 -74
  173. package/dist/hitl/localAllowRule.d.ts +0 -62
  174. package/dist/hitl/localAllowRule.js +1 -33
  175. package/dist/hitl/parkOwnership.d.ts +0 -56
  176. package/dist/hitl/parkOwnership.js +0 -22
  177. package/dist/hitl/parkResolver.d.ts +3 -88
  178. package/dist/hitl/parkResolver.js +8 -349
  179. package/dist/hitl/parkRowBirthWait.d.ts +2 -26
  180. package/dist/hitl/parkRowBirthWait.js +3 -93
  181. package/dist/hitl/persistedRulesWire.d.ts +13 -358
  182. package/dist/hitl/persistedRulesWire.js +0 -310
  183. package/dist/hitl/planReviewWire.d.ts +4 -176
  184. package/dist/hitl/planReviewWire.js +9 -312
  185. package/dist/hitl/resumeRunningCard.d.ts +0 -105
  186. package/dist/hitl/resumeRunningCard.js +0 -105
  187. package/dist/hitl/sessionPolicyWire.d.ts +11 -191
  188. package/dist/hitl/sessionPolicyWire.js +0 -149
  189. package/dist/hitl/suspendedReopen.d.ts +3 -24
  190. package/dist/hitl/suspendedReopen.js +0 -14
  191. package/dist/hitl/toolApprovalWire.d.ts +5 -1308
  192. package/dist/hitl/toolApprovalWire.js +5 -945
  193. package/dist/hooksWireCaps.d.ts +0 -38
  194. package/dist/hooksWireCaps.js +0 -190
  195. package/dist/host.d.ts +0 -105
  196. package/dist/host.js +0 -33
  197. package/dist/hostEnv.d.ts +0 -14
  198. package/dist/hostEnv.js +0 -13
  199. package/dist/imagesWireCaps.d.ts +0 -21
  200. package/dist/imagesWireCaps.js +0 -22
  201. package/dist/index.d.ts +0 -134
  202. package/dist/index.js +0 -476
  203. package/dist/interactiveHalt.d.ts +5 -153
  204. package/dist/interactiveHalt.js +0 -111
  205. package/dist/interactiveToolsWire.d.ts +0 -62
  206. package/dist/interactiveToolsWire.js +1 -67
  207. package/dist/leaderConflict.d.ts +0 -59
  208. package/dist/leaderConflict.js +0 -48
  209. package/dist/limitsWire.d.ts +0 -125
  210. package/dist/limitsWire.js +2 -120
  211. package/dist/liveInitToolFace.d.ts +0 -77
  212. package/dist/liveInitToolFace.js +1 -109
  213. package/dist/liveModelCatalog.d.ts +0 -52
  214. package/dist/liveModelCatalog.js +0 -48
  215. package/dist/liveQuestionStore.d.ts +0 -87
  216. package/dist/liveQuestionStore.js +1 -56
  217. package/dist/mcpLiveness.d.ts +0 -151
  218. package/dist/mcpLiveness.js +0 -122
  219. package/dist/mcpPanel.d.ts +0 -104
  220. package/dist/mcpPanel.js +0 -49
  221. package/dist/mcpReconnect.d.ts +0 -58
  222. package/dist/mcpReconnect.js +1 -69
  223. package/dist/mcpWireCaps.d.ts +0 -55
  224. package/dist/mcpWireCaps.js +1 -13
  225. package/dist/memoryComplianceCapability.d.ts +3 -57
  226. package/dist/memoryComplianceCapability.js +0 -57
  227. package/dist/memoryEntriesWire.d.ts +6 -198
  228. package/dist/memoryEntriesWire.js +0 -144
  229. package/dist/memoryOriginCapability.d.ts +3 -53
  230. package/dist/memoryOriginCapability.js +0 -50
  231. package/dist/memorySpecWire.d.ts +0 -116
  232. package/dist/memorySpecWire.js +0 -150
  233. package/dist/model/catalog.d.ts +0 -111
  234. package/dist/model/catalog.js +0 -87
  235. package/dist/model/catalogLoader.d.ts +0 -114
  236. package/dist/model/catalogLoader.js +2 -139
  237. package/dist/model/modelSupplyRules.d.ts +1 -55
  238. package/dist/model/modelSupplyRules.js +0 -62
  239. package/dist/model/providerAuth.d.ts +0 -103
  240. package/dist/model/providerAuth.js +2 -38
  241. package/dist/model/providerCatalog.d.ts +0 -45
  242. package/dist/model/providerCatalog.js +0 -37
  243. package/dist/model/providerPresets.d.ts +0 -33
  244. package/dist/model/providerPresets.js +2 -91
  245. package/dist/model/tierVocabulary.d.ts +0 -31
  246. package/dist/model/tierVocabulary.js +0 -27
  247. package/dist/modelBudgetRule.d.ts +0 -39
  248. package/dist/modelBudgetRule.js +0 -39
  249. package/dist/modelCapabilityProbe.d.ts +0 -175
  250. package/dist/modelCapabilityProbe.js +0 -147
  251. package/dist/modelWireCaps.d.ts +0 -13
  252. package/dist/modelWireCaps.js +0 -13
  253. package/dist/notifications.d.ts +0 -233
  254. package/dist/notifications.js +14 -492
  255. package/dist/oneShotWireCaps.d.ts +0 -34
  256. package/dist/oneShotWireCaps.js +0 -35
  257. package/dist/ownKey.d.ts +0 -33
  258. package/dist/ownKey.js +0 -33
  259. package/dist/panelRunningHistory.d.ts +0 -28
  260. package/dist/panelRunningHistory.js +0 -43
  261. package/dist/peerFrames.d.ts +0 -71
  262. package/dist/peerFrames.js +0 -168
  263. package/dist/peerLaneCapability.d.ts +0 -44
  264. package/dist/peerLaneCapability.js +0 -52
  265. package/dist/permissionRuleIssue.d.ts +0 -30
  266. package/dist/permissionRuleIssue.js +0 -78
  267. package/dist/permissionRulesWriteCapability.d.ts +0 -46
  268. package/dist/permissionRulesWriteCapability.js +0 -54
  269. package/dist/permissionWireCaps.d.ts +0 -37
  270. package/dist/permissionWireCaps.js +0 -37
  271. package/dist/postureKnob.d.ts +0 -71
  272. package/dist/postureKnob.js +0 -86
  273. package/dist/principalWire.d.ts +0 -17
  274. package/dist/principalWire.js +0 -17
  275. package/dist/printToolResultFrame.d.ts +0 -100
  276. package/dist/printToolResultFrame.js +0 -33
  277. package/dist/promptProfileWireCaps.d.ts +0 -13
  278. package/dist/promptProfileWireCaps.js +0 -13
  279. package/dist/readFacePosture.d.ts +0 -43
  280. package/dist/readFacePosture.js +0 -46
  281. package/dist/request/printNotification.d.ts +0 -20
  282. package/dist/request/printNotification.js +0 -55
  283. package/dist/request/taskRequest.d.ts +0 -249
  284. package/dist/request/taskRequest.js +10 -496
  285. package/dist/resumeRefusalCopy.d.ts +0 -136
  286. package/dist/resumeRefusalCopy.js +1 -117
  287. package/dist/retainBackgroundWireCaps.d.ts +0 -48
  288. package/dist/retainBackgroundWireCaps.js +0 -48
  289. package/dist/retryStatus.d.ts +2 -221
  290. package/dist/retryStatus.js +0 -107
  291. package/dist/rewindWireCaps.d.ts +0 -27
  292. package/dist/rewindWireCaps.js +0 -24
  293. package/dist/runCancelContext.d.ts +1 -20
  294. package/dist/runCancelContext.js +0 -34
  295. package/dist/runTerminal.d.ts +0 -273
  296. package/dist/runTerminal.js +0 -177
  297. package/dist/sandboxWire.d.ts +0 -38
  298. package/dist/sandboxWire.js +0 -82
  299. package/dist/scenarioWire.d.ts +0 -60
  300. package/dist/scenarioWire.js +0 -68
  301. package/dist/scratchpadWireCaps.d.ts +0 -11
  302. package/dist/scratchpadWireCaps.js +0 -32
  303. package/dist/sdkWireTransit.d.ts +0 -38
  304. package/dist/sdkWireTransit.js +0 -30
  305. package/dist/seam.d.ts +18 -853
  306. package/dist/seam.js +0 -52
  307. package/dist/seatContract.d.ts +0 -555
  308. package/dist/seatContract.js +5 -304
  309. package/dist/selfOrchestrationDenial.d.ts +0 -189
  310. package/dist/selfOrchestrationDenial.js +0 -162
  311. package/dist/selfOrchestrationWireCaps.d.ts +0 -38
  312. package/dist/selfOrchestrationWireCaps.js +0 -38
  313. package/dist/sessionMap.d.ts +0 -60
  314. package/dist/sessionMap.js +0 -37
  315. package/dist/sessionMemoryStatus.d.ts +11 -114
  316. package/dist/sessionMemoryStatus.js +0 -112
  317. package/dist/sessionModelLatch.d.ts +0 -29
  318. package/dist/sessionModelLatch.js +0 -40
  319. package/dist/sessionPolicyCapability.d.ts +3 -53
  320. package/dist/sessionPolicyCapability.js +0 -52
  321. package/dist/sessionSlot.d.ts +0 -26
  322. package/dist/sessionSlot.js +0 -17
  323. package/dist/skillsWireCaps.d.ts +0 -87
  324. package/dist/skillsWireCaps.js +0 -38
  325. package/dist/sqlEngineCapability.d.ts +0 -118
  326. package/dist/sqlEngineCapability.js +0 -134
  327. package/dist/sseIdleTriage.d.ts +0 -79
  328. package/dist/sseIdleTriage.js +1 -80
  329. package/dist/steering.d.ts +0 -54
  330. package/dist/steering.js +0 -63
  331. package/dist/subagent/engineCompactWire.d.ts +0 -34
  332. package/dist/subagent/engineCompactWire.js +4 -134
  333. package/dist/subagent/engineDelegatedPrompt.d.ts +0 -31
  334. package/dist/subagent/engineDelegatedPrompt.js +1 -103
  335. package/dist/subagent/engineRowStopGate.d.ts +0 -20
  336. package/dist/subagent/engineRowStopGate.js +0 -49
  337. package/dist/subagent/engineSubagentOutput.d.ts +0 -7
  338. package/dist/subagent/engineSubagentOutput.js +1 -51
  339. package/dist/subagent/engineSubagentResume.d.ts +2 -279
  340. package/dist/subagent/engineSubagentResume.js +2 -129
  341. package/dist/subagent/engineSubagentSteer.d.ts +0 -26
  342. package/dist/subagent/engineSubagentSteer.js +0 -63
  343. package/dist/subagent/engineSubagentTail.d.ts +0 -38
  344. package/dist/subagent/engineSubagentTail.js +2 -110
  345. package/dist/subagent/engineTaskHandleWire.d.ts +11 -65
  346. package/dist/subagent/engineTaskHandleWire.js +20 -131
  347. package/dist/subagent/subagentOwnerAbsence.d.ts +0 -2
  348. package/dist/subagent/subagentOwnerAbsence.js +0 -25
  349. package/dist/subagentContentStore.d.ts +3 -260
  350. package/dist/subagentContentStore.js +7 -540
  351. package/dist/systemReminderTag.d.ts +0 -49
  352. package/dist/systemReminderTag.js +0 -61
  353. package/dist/toolResult.d.ts +1 -211
  354. package/dist/toolResult.js +1 -358
  355. package/dist/toolRoster.d.ts +0 -140
  356. package/dist/toolRoster.js +0 -66
  357. package/dist/typePins.d.ts +0 -46
  358. package/dist/types/engineState.d.ts +0 -71
  359. package/dist/types/engineState.js +0 -16
  360. package/dist/ultracodeWireCaps.d.ts +0 -75
  361. package/dist/ultracodeWireCaps.js +0 -92
  362. package/dist/unrefTimer.d.ts +0 -27
  363. package/dist/webSearchBackendCapability.d.ts +0 -72
  364. package/dist/webSearchBackendCapability.js +0 -79
  365. package/dist/webSearchWireCaps.d.ts +0 -37
  366. package/dist/webSearchWireCaps.js +0 -34
  367. package/dist/websearch/searchProviderPresets.d.ts +0 -81
  368. package/dist/websearch/searchProviderPresets.js +0 -27
  369. package/dist/wireErrorTriage.d.ts +4 -160
  370. package/dist/wireErrorTriage.js +0 -171
  371. package/dist/wireRefusalCopy.d.ts +0 -28
  372. package/dist/wireRefusalCopy.js +0 -28
  373. package/dist/workflow.d.ts +0 -40
  374. package/dist/workflow.js +0 -52
  375. package/dist/workflowClient.d.ts +0 -122
  376. package/dist/workflowClient.js +8 -360
  377. package/dist/workflowMonitor.d.ts +2 -72
  378. package/dist/workflowMonitor.js +0 -26
  379. package/dist/writeProtectionCapability.d.ts +0 -112
  380. package/dist/writeProtectionCapability.js +0 -109
  381. package/docs/INTEGRATION-CLIENTS.md +62 -1
  382. package/package.json +1 -1
@@ -1,574 +1,135 @@
1
- /**
2
- * seatContract — desktop/web **座位 IPC 契约的单一真源**(design/159 B18,2026-07-29)。
3
- *
4
- * 搬迁前的形:同一份契约有**两份声明**,而且跨仓名字零重合 ——
5
- * · `sema-desktop/src/shared/localSessions.ts` = 15 个类型 + 3 个词表常量 + 6 个校验器 + SPEC(生产端)
6
- * · `sema-web-client/ui/lib/desktop/local-sessions-transport.ts` = 9 个 `Seat*` 本地重声明(消费端)
7
- * 两边名字不同 ⇒ **编译器永远不会告诉你它们漂了**。实测已经漂了(见下「漂移清单」),其中
8
- * `LocalSessionEvent.outcome` 那一条是真 bug:宿主发了词、消费端的镜像里根本没有这个位,
9
- * 于是「拒绝 / TTL 到点 / 人点了允许」在屏上长得一模一样 —— 正是 localSessions 自己在
10
- * 「接缝记账」里写下的第 1 条,它一直没被销账的原因就是没有任何机制会让它红。
11
- *
12
- * 落点为什么是本包:desktop 与 web 都已经依赖 `@sema-agent/client-core`(0.11.5),而本文件是
13
- * **纯类型 + 常量 + 纯谓词**,零值级 import、零 Node 内建 ⇒ 不动本包的可移植闭包(portability 门的
14
- * `EXPECTED_PACKAGES_INDEX` 一个字不变)。
15
- * ⚠️ 两条 `import type`(`./effortWire.js` 的 `ReasoningEffort`、`./seam.js` 的 `LaneProof`)都是
16
- * **类型边**:portability 门走值级传递闭包时按规则剥掉 type-only import(门里 `/^\s*type\b/` 那一跳),
17
- * bundle 里一个字节都不多。写成 import 而不是就地复刻,是因为「座位闭集」与「wire 投影闭集」必须是
18
- * **同一套词**——复刻一份就等于埋一条只有真用户能发现的漂移(拨盘上的档在座位 lane 上静默到不了引擎;
19
- * 车道证明在座位面变成一个「有位无证」的空对象)。
20
- *
21
- * ── 搬迁时按「真源为准」收敛的漂移(逐条,web 侧镜像 → 本文件)────────────────────────────
22
- * 🔴 D1 `LocalSessionEvent.outcome` —— web 镜像整位缺席 ⇒ `tool_permission_resolved` 只会清面,
23
- * 不会告诉用户为什么工具没跑。**真 bug**,本批只做「位补回来」;把词渲成可见痕迹是渲染面的活。
24
- * D2 `SendMessageRequest.permissionMode` —— web 镜像是裸 `string`,真源是闭集 `PermissionModeIntent`,
25
- * 而宿主入站门 `requireOptionalPermissionMode` 是**会抛的闭集门**。今日两边词表逐字相等
26
- * (web `ComposerMode` 五档 ≡ `PERMISSION_MODE_INTENTS` 五档,已核),所以是**潜伏**不是现症:
27
- * ComposerMode 哪天加一档,裸 string 一路放行到宿主门口才抛。收敛成闭集后当天编译红。
28
- * D3 `AttachmentUploadReceipt.sha256` / `ToolPermissionRequest.createdAtMs` / `StartSessionOptions.cwd`
29
- * / `.excludeTools` / `LocalSessionRecord.queuedMessages`·`model`·`engineSessionId` ——
30
- * web 镜像缺位。都是「没接线」不是「接错线」(web 侧今日无消费点,已核),收敛后位在、待接。
31
- * D4 `LocalSessionEvent.request` —— 真源有这个位,**宿主从不发**(session-host 零处写 `request:`);
32
- * web 镜像没有它反而与运行时事实一致。真源保留该位(CC `fQe` 的 form 位),记在这里免得
33
- * 下一棒把「web 没有」当成漏。
34
- * D5 `EipcStoreClient.getStateSync` web 侧是 optional、真源是 required;`SeatSessionDirectoryRow.createdAt`
35
- * web 侧 optional、真源 required。两条都是「更弱」方向,收敛到真源即可(宿主校验器
36
- * `isLocalSessionRecord` 本来就要求 createdAt 在场,运行时保证一直成立)。
37
- * · web 侧**没有**镜像、因而至今拿不到的面:队列三动词 / setFocusedSession / setModel /
38
- * focusedSessionState / settingsState / `CHROME_EVENT_KINDS` / `ATTACHMENT_IDS_PER_TASK_CAP`。
39
- * 本文件导出后它们对 web 首次可见(接不接线是渲染面的决定)。
40
- *
41
- * ── 🔴 wave2 卡E-seat 的**破坏性契约变更**(2026-08-02,REF-CC-064~070/072~074;发包说明点名)──
42
- * ① `EipcMethodSpec.validate` / `EipcStoreSpec.validate` → **改名 `check`**,返回形从 `boolean`
43
- * 升成 `true | SeatValidationFailure`(REF-CC-069)。改名是**安全机制不是洁癖**:老消费点写的是
44
- * `if (m.validate && !m.validate(v))`,而失败**对象是真值** ⇒ 那一行会把「不合格」读成「合格」,
45
- * 门从 fail-closed 静默变成 fail-open。改名让每个旧调用点在编译期红,而不是在运行期悄悄放行。
46
- * ② `ToolPermissionRequest.createdAt: number` → **`createdAtMs`**(REF-CC-067):同一文件里
47
- * `LocalSessionRecord.createdAt` 是 ISO 串,两个同名位两种域两种类型;epoch 单位入名(A4)。
48
- * ③ `ToolPermissionRequest.boundCallId` + `.boundInputHash` → **合成 `toctouBinding`**
49
- * (REF-CC-070):注释一直把它称作 pair,而类型/门此前各查各的,半个 pair 照样过门。
50
- * ④ `LocalSessionEvent.chrome.laneProof` **可选 → 必填**且升成命名类型 `LaneProof`(REF-CC-064)——
51
- * 出站门本来就要求它在场,类型却说可以缺席:一个照着这份「单一真源」写的宿主编译全绿、
52
- * 事件被整条丢掉、而门只回 boolean 说不出为什么。这条是本卡的 bug 修复位。
53
- * ⑤ `LocalSessionEvent.type` / `.chrome.kind` / `.permissionMode` 三个位闭集化(REF-CC-065)。
54
- * ⑥ `uploadAttachment` 入参、`getTranscript`/`searchSessions` 返回形、三个 store 状态形全部提成
55
- * 具名 interface(REF-CC-072/073/074),SPEC 里 13 个内联匿名 validator 收成具名 `check*`。
56
- * 三端消费坐标见本批 commit message 的「候提货单」节。
57
- *
58
- * ── 沿革(以下正文自 sema-desktop/src/shared/localSessions.ts 逐字迁入)──────────────────────
59
- * LocalSessions — the desktop host's session service contract, FORM-ported from the CC desktop
60
- * app's `claude.web / LocalSessions` eipc interface (212 methods there; FIRST BATCH here = the four
61
- * families clay scoped: session lifecycle / event subscription / interrupt / approvals).
62
- *
63
- * Naming: CC ns `claude.web` → `sema.web` (brand table). Method names kept verbatim where the CC
64
- * method exists (`start`/`stop`/`interrupt`/`sendMessage`/`onEvent`/`onToolPermissionRequest`/
65
- * `respondToToolPermission` are all real CC LocalSessions methods — see the 854-channel census).
66
- *
67
- * ══ 🔴 证据等级标注:本文件的 CC 断言取自**桌面 unpack**,本地语料库不可复验 ════════════════
68
- *
69
- * (test [5087] 提出的「语料**种类**缺口」,cli [5088] 认领三件之①,随 0.42.0 落;判据形见下)
70
- *
71
- * 本文件里所有以「CC 如何如何」为形的断言 —— 上面那句「212 methods / 854-channel census /
72
- * 方法名逐字保留」、下面 `checkLocalSessionEvent` 的「CC 的 `fQe` 逐字段对照」、以及一切引
73
- * `.vite/build/index.chunk-*.js` 坐标的句子 —— **证据等级 = 桌面 unpack(CC Electron app 的
74
- * `.vite/build` 产物),本地语料库不可复验**。
75
- *
76
- * 为什么这一条必须写在这里(而不是只写进台账):
77
- * · 本仓手边可复验的参照语料**只覆盖终端 CLI 形态**的静态产物,**没有**桌面壳的 unpack 产物。
78
- * 这不是「语料版本旧」,是**产物形态不对** —— 拿 CLI 形态的语料去 grep 桌面壳里的符号只会得到
79
- * 零命中,而零命中在这里**既不能证真也不能证伪**;
80
- * · 「CC 取证纪律」要求 CC 断言的合法证据只有两种:本机 claude 实测,或语料二进制直证。本文件
81
- * 的这一批两种都够不着 ⇒ 断言**保留**(它当初是照着真产物写的),但**必须带着这个等级一起读**;
82
- * · 🔴 **这段注释随 `dist/*.d.ts` 出包**,三端读到的就是它。只把等级写进不进 tarball 的台账,
83
- * 消费端读到的仍是一句看起来可复验、实际不可复验的断言(与本文件 `workerBadge` 出身订正
84
- * 同一条理由)。
85
- *
86
- * **对下游的判据**:凡要对这些断言做「CC 到底是不是这样」的复核,**别拿终端 CLI 形态的语料当反证**
87
- * ——零命中是语料形态缺口的必然结果,不是断言错。真正的复核路只有一条:取一份 CC 桌面版
88
- * unpack 产物再对照(已在册为独立小件,做成后参照语料库增桌面形态子目录)。
89
- *
90
- * Event payload contract: ported in FORM from CC's `onEvent` runtime validator `fQe`
91
- * (unpack `.vite/build/index.chunk-CnWKsyE_.js:369773`;**证据等级:桌面 unpack,本地语料库
92
- * 不可复验** —— 见上方标注段). The load-bearing property we keep
93
- * byte-faithful ([1832] axiom 2, independently proven by CC's own code): on an otherwise
94
- * fully-schema'd IPC surface, the `message`/`messages` fields (= CC session-vocabulary SDKMessage
95
- * bodies, our transcript plane) are UNVALIDATED passthrough positions, while every other field is a
96
- * neutral typed position. Our implementation体 differs (sema wire via @sema-agent/sdk +
97
- * @sema-agent/client-core), the contract shape does not.
98
- */
99
1
  import type { ReasoningEffort } from "./effortWire.js";
100
2
  import type { LaneProof } from "./seam.js";
101
3
  import type { QuestionAnswer } from "./liveQuestionStore.js";
102
4
  import type { ToolApprovalDelegation } from "./hitl/toolApprovalWire.js";
103
- /** 一次门校验的失败说明。 */
104
5
  export interface SeatValidationFailure {
105
- /** 人可读的失败原因,恒在场且非空(宿主日志里那一行的正文)。 */
106
6
  reason: string;
107
- /** 出错的那个键名(嵌套位用点号,如 `chrome.laneProof`)。
108
- * 缺席 = 这次失败**不归属某一个字段**(整体不是对象 / 是跨字段的联合判据)⇒ 宿主日志只打
109
- * `service.method` + `reason`,**绝不**回落成 `"unknown"` 或空串当字段名 —— 编出来的字段名会把
110
- * 排查引到一个根本没出问题的位上(§B10 同族:缺席要如实渲缺席,不是造一个值)。 */
111
7
  field?: string;
112
8
  }
113
- /**
114
- * 门的返回形:成功恰是 `true`(**只有一种写法**,消费端 `=== true` 判定即可),失败带原因。
115
- *
116
- * 🔴 为什么不是 `boolean`:这一族门是 fail-closed 的(见 `EipcMethodSpec.check` 的头注),false 时
117
- * 整条事件/结果都不发。而 boolean 里没有任何位能说出是哪个字段哪条规则不过 —— 渲染端的现象是
118
- * 「这个面偶尔什么都不来」,宿主端的现象是零日志,两端都无从下手(REF-CC-064 就是这么被埋住的)。
119
- * 🔴 为什么消费端必须写 `=== true` 而不是 `if (!check(v))`:失败是**对象**(真值)。老写法会把
120
- * 不合格读成合格 —— 这正是本批把位名从 `validate` 改成 `check` 的原因:让老写法编译期就红。
121
- */
122
9
  export type SeatValidation = true | SeatValidationFailure;
123
10
  export type EipcMethodKind = "invoke" | "event";
124
11
  export interface EipcMethodSpec {
125
12
  kind: EipcMethodKind;
126
- /** invoke: validates the impl's RESULT before it crosses back to the renderer (CC's outbound
127
- * schema gate — `Result from method "<m>" in interface "<S>" failed to pass validation`).
128
- * event: validates the PAYLOAD before `webContents.send` (CC's dispatcher-side validator, the
129
- * `fQe` position for `LocalSessions.onEvent`). Absent = any result/payload passes (CC has
130
- * `void`-returning methods with trivially-true validators).
131
- * 🔴 位名 `check`(REF-CC-069,原 `validate`):返回 `true | SeatValidationFailure`,消费端必须
132
- * 写 `if (verdict !== true)` 并把 `reason`/`field` 打进宿主日志 —— 一条被门吃掉的事件从此可诊断。 */
133
13
  check?: (value: unknown) => SeatValidation;
134
14
  }
135
15
  export interface EipcStoreSpec {
136
- /** Validates the STATE payload both on read replies and on update pushes (fail-closed like the
137
- * method gates). Absent = any state passes. 位名与返回形同 `EipcMethodSpec.check`。 */
138
16
  check?: (state: unknown) => SeatValidation;
139
17
  }
140
18
  export interface EipcServiceSpec {
141
19
  ns: string;
142
20
  service: string;
143
21
  methods: Record<string, EipcMethodSpec>;
144
- /** `$store$` reactive states owned by this service (CC codegen form; see eipcStoreChannel). */
145
22
  stores?: Record<string, EipcStoreSpec>;
146
23
  }
147
- /** Neutral session record (CC's `session` position is schema-gated by `aM`; ours is this shape). */
148
24
  export interface LocalSessionRecord {
149
- /** Host-minted stable session id — the id every event carries (CC form: sessionId on every event). */
150
25
  sessionId: string;
151
- /** Engine (service)-minted session id, known after the first reply; absent before it. */
152
26
  engineSessionId?: string;
153
- /** 这条会话钉住的模型 id。缺席 = 宿主没为它钉模型 ⇒ 每轮走部署默认(`SeatModelCatalog.defaultId`);
154
- * 消费端渲那个默认名,**不要**渲空串或「未知模型」(部署默认是一个真实存在的答案)。 */
155
27
  model?: string;
156
- /** 会话标题。缺席 = 还没有标题(首轮之前 / 摘要未回)⇒ 消费端渲「新会话」占位,不要渲空行。 */
157
28
  title?: string;
158
29
  isRunning: boolean;
159
- /** ISO-8601 串(host clock)。与 `ToolPermissionRequest.createdAtMs` **不同域**:那一位是 epoch 毫秒数
160
- * (REF-CC-067 给它加了单位后缀,免得渲染端写出跨两种行复用的 `formatCreatedAt`)。 */
161
30
  createdAt: string;
162
- /** 最近一次活动时刻(ISO-8601)。缺席 = 自建起没有任何活动 ⇒ 列表按 `createdAt` 排序,
163
- * **不要**把缺席当成 0 时刻(那会把新会话排到列表最底)。 */
164
31
  lastActivityAt?: string;
165
- /** Host-side deferred queue (CC `deferredSends` seat, in submit order — drives the queued-message
166
- * bar). Present (possibly empty) whenever the host projects the record during a running turn. */
167
32
  queuedMessages?: Array<{
168
33
  uuid: string;
169
34
  text: string;
170
35
  }>;
171
- /** [C111] B1(clay 裁「加」,2026-08-08):**快照提示位** —— `true` = 写入方(session-host)当时
172
- * 确知该会话停在人门上(enterPark/reparkIfStillPending 盖戳,settleTurn 清);缺席 = **未知**
173
- * (旧账本/旧端写的记录),**不是** `false` 的断言。消费端(recents/会话列表)只在 `true` 渲
174
- * 「等审批」徽标,缺席/false 不渲 —— 绝不把未知渲成安全。重启恢复端必须先按引擎 approvals
175
- * registry 对账再回写:盘上的 `parked` 是过去的声明,不直接当现势渲。 */
176
36
  parked?: boolean;
177
37
  }
178
- /**
179
- * `ToolPermissionRequest.requestId` 的**域词表**(FIX⑥,2026-08-07)—— 三端唯一真源。
180
- *
181
- * 🔴 前缀不是装饰:它**就是**决断的路由依据(session-host 按它挑 wire 动词)。一个域外的 requestId
182
- * 意味着「这条决断无处可去」,所以校验器对它 fail-loud 而不是放行(此前门只校「是不是串」,
183
- * 于是 desktop 早就在用的 `plan:` 既不在枚举里、也不会被任何一处说出来)。
184
- */
185
38
  export declare const TOOL_PERMISSION_REQUEST_ID_DOMAINS: readonly ["live:", "durable:", "question:", "elicit:", "plan:"];
186
39
  export type ToolPermissionRequestIdDomain = (typeof TOOL_PERMISSION_REQUEST_ID_DOMAINS)[number];
187
- /** 读口:requestId → 它的域。未登记前缀 / 非串 ⇒ `undefined`(诚实缺席,绝不猜一个域)。 */
188
40
  export declare function toolPermissionRequestIdDomain(requestId: unknown): ToolPermissionRequestIdDomain | undefined;
189
- /**
190
- * **正向铸口**:域 + 域内 id → `ToolPermissionRequest.requestId`(P-26,2026-08-12)。
191
- *
192
- * 沿革:此前本文件只有域表与读口 {@link toolPermissionRequestIdDomain},**没有铸口** —— 于是每个
193
- * 铸方(session-host 的五条 park 臂、各端的合成行)各自手抄 `` `live:${id}` `` 这样的模板串。手抄
194
- * 模板串的失效形不是编译红,是**运行期路由到一个不存在的目标**:少个冒号 / 抄错域 / id 是
195
- * `undefined` 时静默铸出 `"live:undefined"`,而读口对这三种坏键里的后两种照样「认得出域」,所以
196
- * 谁都不会响。铸口在场之后,这一类错在**铸的那一行**就被拒。
197
- *
198
- * 🔴 **往返性**(本口的契约,门里有断言):对任何登记域 `d` 与合法 id,
199
- * `toolPermissionRequestIdDomain(toolPermissionRequestId(d, id)) === d` 恒成立 ——
200
- * 铸出来的键必被读口认回**同一个**域,`isToolPermissionRequest` / `LOCAL_SESSIONS_SPEC` 的
201
- * 域校验也必然放行(三处读的是同一张 {@link TOOL_PERMISSION_REQUEST_ID_DOMAINS})。
202
- *
203
- * 🔴 **坏入参一律 throw,绝不静默吐坏键**:铸口的整个价值就在于「坏键铸不出来」,返回
204
- * `undefined` 只会把 `${undefined}` 推到下一行的模板串里(与 `honest-absence` 同族的取舍:
205
- * 缺席要说出来,而这里连「缺席」都不该发生 —— 调用方手上没有合法 id 就不该走到铸这一步)。
206
- * 三条拒绝各自对应一个真实误用:
207
- * ① 域不在词表(含忘了尾冒号的 `"live"`)—— 域外键 = 这条决断无处可去,与读口/校验器同判据;
208
- * ② id 非串 / 空串 —— `"live:"` 是半截键,读口却照样认出 `live:` 域,故必须在铸时拦;
209
- * ③ id **本身**已经带着某个登记域前缀 —— 典型误用 = 把一条铸好的 requestId 当 id 再喂进来,
210
- * 得到 `"live:live:ap-1"`(往返性仍成立、校验器仍放行,只有决断落地时才发现目标不存在)。
211
- * ⚠️ 这条不拦「id 里含冒号」:`durable:<engineSessionId>:<callId>` 的 id 段天生带冒号。
212
- *
213
- * 错误文本只带**域**与判据,不回显 id 原文(id 段可能含 session/call 标识,错误路径也是外溢面)。
214
- */
215
41
  export declare function toolPermissionRequestId(domain: ToolPermissionRequestIdDomain, id: string): string;
216
- /** design/80 D-1 的 TOCTOU 绑定**对**(REF-CC-070:此前是两个互不相干的 optional,半个 pair 照样过门)。
217
- * 一位承载整对 ⇒「只有 callId 没有 inputHash」在类型层不可表达,门里也不用再补联合判据。 */
218
42
  export interface ToctouBinding {
219
43
  callId: string;
220
44
  inputHash: string;
221
45
  }
222
46
  export declare const TOCTOU_BINDING_KEYS: readonly ["callId", "inputHash"];
223
- /** HITL request row (CC's `request` position is schema-gated by `S1`; ours is this shape, projected
224
- * from the sema wire's PendingCheckpoint — see session-host). */
225
47
  export interface ToolPermissionRequest {
226
- /** Stable request key — echo back on respondToToolPermission. FIVE id domains, prefix-tagged
227
- * (the prefix is what routes the decision back to the right wire verb — see session-host);
228
- * 词表真源 = {@link TOOL_PERMISSION_REQUEST_ID_DOMAINS},读口 = {@link toolPermissionRequestIdDomain}:
229
- * `live:<approvalId>` = LIVE in-band tool-approval face (frame rides the token
230
- * stream; unanswered → engine fail-CLOSED deny at its TTL);
231
- * `durable:<engineSessionId>:<callId>` = the durable checkpoint class (approvals inbox);
232
- * `question:<questionId>` = LIVE `AskUserQuestion` (the agent's own structured ask;
233
- * unanswered → engine fail-OPEN: the model takes the
234
- * headless default `{answers:[]}` at the 5-min TTL, which is
235
- * why leaving this family unrendered is silent, [1947] 红④);
236
- * `elicit:<elicitationId>` = LIVE inbound-MCP elicitation (a server asks the user for
237
- * form input mid-tool-call);
238
- * `plan:<checkpointId>` = plan-review park(FIX⑥ 2026-08-07 补登记)—— 决断路由到
239
- * `assistant.planReview`,**不是** `/decide`(server 对走错
240
- * 门的调用回 409 `gate_not_plan_review`)。desktop 的
241
- * session-host 早已在铸这个前缀,而本枚举只写了四域:
242
- * 域表说四个、现实跑五个,靠「域外的行长什么样」做判断的
243
- * 消费端于是各猜各的。
244
- * The LIVE domains are same-replica + non-durable: a late/duplicate decision 404s, which the
245
- * host treats as "already released" (dismiss), never as a retryable error. */
246
48
  requestId: string;
247
49
  sessionId: string;
248
- /** For the two ask families this is the CC tool vocabulary name the renderer branches on:
249
- * `AskUserQuestion` (question domain) / `McpElicitation` (elicit domain).
250
- * 缺席或 `null` = wire 没给工具名(旧 server / 通用审批行)⇒ 消费端走**通用**审批卡,
251
- * 绝不猜工具名(猜错就是把 Bash 的确认框渲成别的工具的)。 */
252
50
  toolName?: string | null;
253
- /** The ENGINE's tool-call id (`call_…`) — the SAME id the assistant message's `tool_use` block
254
- * carries, so a renderer can key the approval onto the tool card that actually raised it.
255
- * Present on tool-approval rows from server ≥1.307; `null` when the wire did not offer one
256
- * (old server, or the ask families, which have no tool call of their own). NEVER synthesized. */
257
51
  toolCallId?: string | null;
258
- /** UNTRUSTED, service-redacted tool args / question payload (render-only, never re-fed).
259
- * 🔴 缺席语义(REF-CC-066):门**刻意不校验**这一位(见 SEAT_VALIDATOR_KEY_COVERAGE 的豁免登记),
260
- * 所以消费端拿到的可能是 undefined、也可能是任意形状。`question:` 域的整张卡押在 `input.questions`
261
- * 上 ⇒ 缺席/畸形时渲染端必须显式渲「问题内容不可用」并把决断按钮留给 deny 侧,
262
- * **绝不**渲一张空卡(空卡看起来像「没有问题要问」,而真相是「问题丢了」)。 */
263
52
  input?: unknown;
264
- /** UNTRUSTED, service-redacted engine ask text (live face only) — display only.
265
- * 缺席 = 这一族(durable 行)本来就没有引擎问句 ⇒ 渲染端用工具名 + 参数摘要成句,不要留空。 */
266
53
  message?: string;
267
- /** design/80 D-1 TOCTOU binding pair (durable face only) — echo VERBATIM into the decision.
268
- * 🔴 出站**只读**位:回程的 verbatim 回显由宿主自己的登记表做(session-host 的
269
- * `row.boundCallId/boundInputHash`),`ToolPermissionDecision` 因此没有对应席位 —— 渲染端
270
- * 拿到它只为展示,绝不需要(也不该)自己回传。
271
- * 缺席 = 这一行不是 durable 域(live/question/elicit 三域没有绑定对)⇒ 消费端不渲绑定摘要。 */
272
54
  toctouBinding?: ToctouBinding;
273
- /** 行的诞生时刻,**epoch 毫秒**(单位入名,A4;时钟来源 = 宿主本地 `Date.now()`,不是引擎时钟 ⇒
274
- * 与转录里的引擎时间戳不可直接相减)。缺席 = wire 那一行没带时间(旧 server 的 durable 行)⇒
275
- * 消费端渲「刚刚」或不渲时间,**绝不**回落成 0(那会渲成 1970)。 */
276
55
  createdAtMs?: number;
277
- /** 治理强制位([C130] 补键,2026-08-08;server ≥7.5.0,语义原样来自
278
- * `ApprovalCardRequest.governanceForced`):此门来自部署治理层,「permission-mode overrides
279
- * do not apply」。🔴 缺席 ≠ `false`:键**只在为真时在场**,缺席 = 无治理来源证据(真的非治理
280
- * ask 与 server 判据够不着的形共用缺席)⇒ 渲染端绝不渲「可用表态绕开」,也绝不合成治理徽标。
281
- * 唯一合法供给 = 宿主(session-host)从已过 hitl wire 门的 `ApprovalCardRequest` **透传**,
282
- * 绝不自铸;为 `false` 的值不该出现在座位面上(条件 stamp 纪律与 wire 门同款)。 */
283
56
  governanceForced?: true;
284
- /** 委派出处链([C130] 补键;core 5.9.0 W1,原样来自 `ApprovalCardRequest.delegation`,形 =
285
- * hitl 的命名类型,单一真源)。只读展示增强——卡说清这只 ask 从哪一层子代浮上来;`agentName`
286
- * UNTRUSTED-for-display(纯文本渲染,零注入面)。缺席 = 非子代 ask 或 wire 没给 ⇒ 不渲委派行。
287
- * 坏形处置与 hitl wire 门同款纪律:**读坏形降缺席**,绝不因展示键拒掉整条审批行。 */
288
57
  delegation?: ToolApprovalDelegation;
289
58
  }
290
- /**
291
- * 座位事件名的**闭集**(REF-CC-065):这是三端唯一的事件名真源。
292
- *
293
- * 方向判据(本文件 `PERMISSION_MODE_INTENTS` 头注立的那条):词由**我们自己的宿主**铸出、发往渲染端,
294
- * 因此闭集 —— 拼错一个字母在编译期红,而不是变成一条谁也不认识、被 switch 默默丢掉的事件。
295
- * 与 `outcome`(wire 铸词,开集)的区别正是「谁铸的词」,不是「字段像不像枚举」。
296
- * 词表 = sema-desktop `session-host` 的 emit 面实测八词。
297
- */
298
59
  declare const SEAT_EVENT_TYPE_TUPLE: readonly ["start", "close", "session_updated", "message", "stream_event", "chrome_event", "error", "tool_permission_resolved"];
299
60
  export type SeatEventType = (typeof SEAT_EVENT_TYPE_TUPLE)[number];
300
61
  export declare const SEAT_EVENT_TYPES: readonly SeatEventType[];
301
- /** Chrome arms wired to the renderer position (batch 4); other arms stay host-side on the ring. */
302
62
  declare const CHROME_EVENT_KIND_TUPLE: readonly ["panel_task", "notification_terminal", "prompt_suggestions", "subagent_lifecycle"];
303
63
  export type ChromeEventKind = (typeof CHROME_EVENT_KIND_TUPLE)[number];
304
- /**
305
- * 🔴 BREAKING(REF-CC-065,2026-08-02):公开面类型从 `readonly string[]` **收窄**成
306
- * `readonly ChromeEventKind[]`。与 `PERMISSION_MODE_INTENTS` / `SEAT_REASONING_EFFORTS` 那两条
307
- * **不同**:那两个本来就已经是闭集类型,加元组只是补「类型→常量」那半边、公开面一个字没变;
308
- * 这一个的公开面**真的变了**,所以它是本批第四处破坏性契约变更,不是「同上理由」的搭车项。
309
- *
310
- * 谁受影响(实测消费坐标,提货单同条):`sema-desktop/src/main/session-host.ts:1752`
311
- * `CHROME_EVENT_KINDS.includes(event.kind)` —— 那里的 `event: ChromeEvent` 是 seam.ts 的 17 词
312
- * 判别式联合,收窄后 `includes()` 的入参类型只认这 4 个词 ⇒ TS2345,提货当天编译红。
313
- * 迁移形:`(CHROME_EVENT_KINDS as readonly string[]).includes(event.kind)`,或先按 `ChromeEventKind`
314
- * 做一次显式收窄再进这一支。sema-web-client / sema-cli 实测零命中。
315
- */
316
64
  export declare const CHROME_EVENT_KINDS: readonly ChromeEventKind[];
317
- /** chrome 信封的**必填**键(REF-CC-064:`laneProof` 此前类型可选、门必填,两边说的不是一句话)。 */
318
65
  export interface SeatChromeEnvelopeBase {
319
66
  kind: ChromeEventKind;
320
- /** 车道证明([1617] 家族一等公民)。**必填**:出站门本来就要求它在场,类型说可选 = 一个合规的
321
- * 生产者编译全绿、事件被整条静默丢弃。缺席在这条 lane 上不是「降级」,是「这帧不该发出来」。 */
322
67
  laneProof: LaneProof;
323
68
  }
324
- /** 臂自身的载荷键随 `kind` 变(client-core `ChromeEvent` 的判别式联合),故留 index 位;
325
- * 必填两位由 `SeatChromeEnvelopeBase` 承载,键集钉也钉在它上面。 */
326
69
  export interface SeatChromeEnvelope extends SeatChromeEnvelopeBase {
327
70
  [k: string]: unknown;
328
71
  }
329
72
  export declare const SEAT_CHROME_ENVELOPE_KEYS: readonly ["kind", "laneProof"];
330
73
  export interface LocalSessionEvent {
331
- /** 事件名(闭集 `SEAT_EVENT_TYPES`)—— 消费端的判别位,switch 可穷举。 */
332
74
  type: SeatEventType;
333
75
  sessionId: string;
334
- /** 🔴 transcript-plane passthrough (SDKMessage body) — deliberately UNVALIDATED (fQe posture). */
335
76
  message?: unknown;
336
- /** 🔴 transcript-plane passthrough batch — array-checked only, elements unvalidated (fQe posture). */
337
77
  messages?: unknown[];
338
- /** 人可读的失败说明(仅 `error` 事件)。缺席 = 这条事件不是失败事件 ⇒ 渲染端不要因为「没有 error」
339
- * 就把一次真失败渲成成功;判失败看的是 `type === "error"`,不是这一位在不在。 */
340
78
  error?: string;
341
- /** 失败的**类别**(宿主自铸:`turn_failed` / `plan_review_failed` …)。缺席 = 宿主没有给这次失败分类
342
- * ⇒ 渲染端只渲 `error` 文本,不要猜类别、也不要按文案分类(§B8)。 */
343
79
  errorCategory?: string;
344
- /** 引擎/传输层状态码(有则透传)。缺席 = 这次失败没有码可报(本地异常)⇒ 不渲码位,**绝不**渲 0。 */
345
80
  code?: number;
346
- /** CC `fQe` 的 form 位。🔴 **本宿主从不发这个位**(session-host 零处写 `request:`;HITL 行走
347
- * 独立的 `onToolPermissionRequest` 通道)—— 位保留是为了与 CC 的 fQe 逐位同形,消费端不该
348
- * 为它写分支(见文件头 D4)。 */
349
81
  request?: ToolPermissionRequest;
350
- /** 自由文本载荷(CC fQe 的 `data` 位,本宿主目前不发)。缺席 = 没有附带文本,消费端不渲这一行。 */
351
82
  data?: string;
352
- /** 引用来源列表(CC fQe 的 `sources` 位,本宿主目前不发)。缺席 = 没有来源可标 ⇒ 不渲来源脚注;
353
- * 空数组与缺席同义(都表示「没有来源」),渲染端不必区分。 */
354
83
  sources?: string[];
355
- /** 本轮生效的权限模式回显(闭集,与入站 `SendMessageRequest.permissionMode` 同一套词)。
356
- * 缺席 = 宿主没有回显模式(今日常态:session-host 零处发这一位)⇒ 渲染端继续显示 composer 自己的
357
- * 模式徽标,**不要**因为缺席就把徽标降回 `default`(那是把「没说」渲成「说了 default」)。
358
- * 🔴 闭集的前提是「词由我们自己铸」:哪天改成回显**引擎的** effective mode(wire 铸的词),
359
- * 必须同批把这一位降级成开集,理由与 `outcome` 逐字相同。 */
360
84
  permissionMode?: PermissionModeIntent;
361
- /** 会话行快照(`start`/`close`/`session_updated` 带)。缺席 = 这条事件不携带会话态 ⇒ 消费端
362
- * 沿用 store 里的现有行,**不要**当成「会话没了」。 */
363
85
  session?: LocalSessionRecord;
364
- /** 触发这条事件的用户消息 uuid(`message` 事件带)。缺席 = 这条事件不属于某条用户消息(引擎侧自发)
365
- * ⇒ 渲染端把它挂在当前 turn 上,不要另开一条用户气泡。 */
366
86
  userMessageUuid?: string;
367
- /** CC form:本条 `message` 之前宿主已清过屏(`/clear` 语义)。缺席 ≡ false(没清过)——
368
- * 这一位只在为真时出现,消费端按「缺席 = 不清屏」处理即可。 */
369
87
  hasPreClearSession?: boolean;
370
- /** On `tool_permission_resolved`: which request settled (so a native notification for it can be
371
- * dismissed — CC `closePermissionNotification(requestId)`). 缺席 = 这条不是审批收面事件。 */
372
88
  requestId?: string;
373
- /**
374
- * On `tool_permission_resolved`: HOW it settled ([1947] 红③). Without this the renderer only ever
375
- * learned that a card should disappear — a TTL expiry, a disconnect-settle and a human's own
376
- * "allow" were indistinguishable, so a REFUSAL rendered as a card silently vanishing and the user
377
- * was never told why the tool did not run.
378
- *
379
- * Words currently emitted (see HITL_RESOLUTION_OUTCOMES): the tool-approval wire's own
380
- * `allowed`/`denied`/`expired`, the question wire's `answered`/`unanswered`, the elicitation
381
- * wire's `accept`/`decline`/`cancel`. ABSENT is meaningful and honest: the durable inbox sweep
382
- * learns only that a row is gone, never why.
383
- *
384
- * 🔴 Validated as a plain string, NOT against a closed set, deliberately: the words originate on
385
- * the wire, and a fail-closed gate keyed to today's vocabulary would DROP THE WHOLE EVENT (card
386
- * stuck on screen forever) the day the server adds an outcome word. Renderers branch on the words
387
- * they know and treat an unknown one as "settled, reason unknown".
388
- */
389
89
  outcome?: string;
390
- /** On `chrome_event`: one client-core ChromeEvent arm (the NEUTRAL typed chrome vocabulary —
391
- * [1832] axiom 2's non-transcript half). Only the renderer-wired arm kinds cross the wire
392
- * (see CHROME_EVENT_KINDS); the outbound gate checks kind membership + the laneProof discipline.
393
- * 缺席 = 这条不是 chrome 事件(按 `type` 判别,不要按这一位在不在判别)。 */
394
90
  chrome?: SeatChromeEnvelope;
395
91
  }
396
- /**
397
- * The resolution words the host currently puts on `tool_permission_resolved.outcome` ([1947] 红③).
398
- * DOCUMENTARY + test anchor only — the gate does NOT enforce membership (see the field's doc: a
399
- * closed set would fail-close the whole event on the day the wire grows a word). Grouped by family:
400
- * - tool approval (wire `ToolApprovalFrame.outcome`, + our own settle sweep): allowed/denied/expired
401
- * - question (wire `QuestionFrame.outcome`): answered/unanswered
402
- * - elicitation (wire `ElicitationFrame.action`): accept/decline/cancel
403
- */
404
92
  export declare const HITL_RESOLUTION_OUTCOMES: readonly string[];
405
- /**
406
- * 接缝记账 — what the HOST now guarantees vs what a RENDERER still owes ([1947] 红③/红④ split).
407
- *
408
- * The host half is done and pinned by desktop's `scripts/run-hitl-frame-transit-fence-test.mjs`:
409
- * every live ask family reaches `onToolPermissionRequest` with its own requestId domain, every
410
- * resolution reaches `onEvent` with an `outcome`, and every decision routes to the right wire verb.
411
- *
412
- * The renderer half is where these become VISIBLE, and until it lands the data is present but
413
- * unread (stating it plainly so nobody reads "the host emits it" as "the user sees it"):
414
- * 1. `tool_permission_resolved.outcome` — an `expired` / `denied` / `unanswered` resolution must
415
- * leave a visible refusal trace. Today the seat transport clears the surface and drops the
416
- * word, so a refusal is still indistinguishable from an approval on screen.
417
- * 🔴 B18(2026-07-29)查明这条一直不销账的**机制原因**:web 侧的镜像类型里连 `outcome` 这个
418
- * 位都没有,所以「没读」在两边都编译得过。本批把位收进真源 = 让它至少可见于类型面。
419
- * 2. `toolCallId` — now real (not null), so an approval can be anchored to the tool card that
420
- * raised it instead of "the most recent tool_start" (an anchor that lands on the wrong card
421
- * when a prior tool is still running).
422
- * 3. `question:` rows need NO new renderer code: they arrive as `toolName: "AskUserQuestion"` with
423
- * `input.questions`, which is exactly what the seat's ask-user-question surface already reads,
424
- * and its answer envelope is exactly what this host expects back.
425
- * 4. 座位 wire 补齐批 (2026-07-28) closed two entries that used to live here as "如实,未做":
426
- * `permissionMode` now has a seat on `sendMessage` (was: the composer's Plan badge never
427
- * crossed and the turn ran with the engine default), and the attachment BYTE channel exists
428
- * (`uploadAttachment` + `sendMessage.attachmentIds`) — so a seat renderer no longer has to
429
- * simulate "attachment ready" for a file nothing received. What is still NOT here, stated
430
- * plainly: plan REVISE feedback text (the decide face has no `reason` seat, so revise maps to
431
- * a bare deny) and a per-session `permissionMode` write (the wire's is per-TURN only).
432
- * 5. `elicit:` rows have no dedicated surface yet: they fall through to the generic approval card,
433
- * which shows the MCP server's prompt and can accept/decline but CANNOT collect form values.
434
- * A real form surface (built from `input.requestedSchema`) is the renderer's remaining piece;
435
- * until then an approve carries no content — the host never invents form values. That generic
436
- * card also offers "Always allow (this session)", which this domain has no concept of: the host
437
- * ignores `remember` here rather than pretend, so the renderer should hide that control for
438
- * `elicit:` rows (a button that changes nothing is the false-affordance family again).
439
- */
440
93
  export interface StartSessionOptions {
441
- /** 起会话时钉的模型 id。缺席 = 用部署默认(`SeatModelCatalog.defaultId`),这是一个真实答案而不是错误。 */
442
94
  model?: string;
443
- /** 起会话时给的标题。缺席 = 宿主不铸标题(记录里的 `title` 随后也缺席,渲染端渲「新会话」)。 */
444
95
  title?: string;
445
- /** Working directory for the session's hand tools (TaskRequest.cwd). Default = a per-session dir
446
- * under the host's workspace base. A UI that picks a project directory passes it here — CC desktop
447
- * form (session.cwd / worktreePath). Honored only on the local host-adapter engine. */
448
96
  cwd?: string;
449
- /** Wire TRUE-UNMOUNT list (TaskRequest.excludeTools, server ≥1.221): named tools' schemas never
450
- * reach the model for ANY turn of this session. Tighten-only. */
451
97
  excludeTools?: string[];
452
98
  }
453
- /**
454
- * PERMISSION MODE INTENT — the RAW mode the composer is showing, carried verbatim to the engine as
455
- * `TaskRequest.permissionMode` (SDK types.d.ts:259; the SERVICE interprets it, axis-aware and
456
- * tighten-only: `plan` ⇒ mount `present_plan` + read-only hands = CC EnterPlanMode).
457
- *
458
- * 🔴 Why this seat exists at all (红批注 web#1): without it, a user who switched the composer to
459
- * Plan mode inside the desktop seat got a turn that ran with the engine's DEFAULT mode — the badge
460
- * said "plan", the engine was never told, and the agent happily edited files. A mode the UI shows
461
- * but never sends is the false-affordance family with teeth.
462
- *
463
- * The vocabulary is the wire's own (identical to the web client's `ComposerMode`), so the seat
464
- * passes the word through unchanged rather than re-deriving core fields locally — one interpretation
465
- * across TUI + web + desktop. 🔴 B18 起 web 侧的镜像位也是这个闭集(此前是裸 `string`):
466
- * ComposerMode 加一档而宿主闭集门不认的那天,红在编译期而不是用户提交那一刻。
467
- */
468
99
  export type PermissionModeIntent = "default" | "plan" | "acceptEdits" | "bypassPermissions" | "auto";
469
100
  export declare const PERMISSION_MODE_INTENTS: readonly PermissionModeIntent[];
470
- /** Per-task attachment cap — the server's own limit (`attachmentIds` > 16 ⇒ 400). Gated here so the
471
- * seat gets a precise local error instead of a wire 400 halfway through a turn. */
472
101
  export declare const ATTACHMENT_IDS_PER_TASK_CAP = 16;
473
102
  export declare const SEAT_REASONING_EFFORTS: readonly ReasoningEffort[];
474
- /** The `settings` sub-object a seat turn may carry. A CLOSED set with its own name list + pin,
475
- * exactly like the top-level request: `SEND_MESSAGE_REQUEST_KEYS` checks `keyof SendMessageRequest`
476
- * (top-level names), so a dotted `"settings.ultracode"` entry could never be pinned by `Covers` —
477
- * the shape that stays consistent with the existing closed sets is one top-level key plus a nested
478
- * closed set of its own. */
479
103
  export interface SeatTurnSettings {
480
- /** CC's `settings.ultracode` PRESET boolean (max thinking × workflow orchestration, service ≥1.48.0
481
- * reads `body.settings.ultracode` and expands it). NOT a seventh effort tier — the dial separately
482
- * coerces the reasoning axis to `xhigh`, and collapsing the two loses the orchestration half
483
- * (`ultracodeWireCaps` in this package records that semantics verbatim).
484
- * 缺席 = 没开这个预设(≡ false);渲染端按缺席渲「关」,不必区分缺席与显式 false。 */
485
104
  ultracode?: boolean;
486
105
  }
487
106
  export declare const SEAT_TURN_SETTINGS_KEYS: readonly ["ultracode"];
488
107
  export interface SendMessageRequest {
489
108
  sessionId: string;
490
109
  text: string;
491
- /** 本轮临时换模型。缺席 = 用会话钉住的模型(`LocalSessionRecord.model`),再缺席才是部署默认。 */
492
110
  model?: string;
493
- /** Client-supplied echo key for the user message (CC form: userMessageUuid); minted if absent. */
494
111
  userMessageUuid?: string;
495
- /** Composer permission mode for THIS turn → `TaskRequest.permissionMode`. Omit/`default` ⇒ no stamp. */
496
112
  permissionMode?: PermissionModeIntent;
497
- /** Pre-uploaded attachment handles (`uploadAttachment` receipts) → `TaskRequest.attachmentIds`.
498
- * Bytes never ride this call: they went up once through the dedicated verb and the engine
499
- * materializes them into the run's `attachments/` dir. */
500
113
  attachmentIds?: string[];
501
- /** Per-turn `/effort` dial pick → `TaskRequest.reasoningEffort`. Omit ⇒ the engine's own default.
502
- * Closed set (`SEAT_REASONING_EFFORTS`) — gate it at the host's door, not at the wire.
503
- *
504
- * 🔴 Why this position exists (web 收编第一批, 2026-07-29): it did NOT, and the absence was
505
- * STRUCTURAL — the seat lane's only payload is this closed-set interface, so the composer's effort
506
- * dial had nowhere to put the user's pick and the web client honestly disabled the control on the
507
- * desktop seat lane. "The control is missing" was the visible symptom; the missing wire position
508
- * was the cause. */
509
114
  reasoningEffort?: ReasoningEffort;
510
- /** Keep this turn's background processes alive past the turn boundary → `TaskRequest.
511
- * retainBackgroundProcesses`. Same structural-absence story as `reasoningEffort` above; the
512
- * shell's lane defaults it ON (2026-07-26 flip), so a seat that cannot send it is not "defaulting
513
- * to the same thing" — it is letting the ENGINE's default decide, which is a different decision. */
514
115
  retainBackgroundProcesses?: boolean;
515
- /**
516
- * 这一轮把**子代的正文帧**转发到父流上 → `TaskRequest.forwardSubagentEvents`。缺席 = 不开
517
- * (父流只有进度帧,没有子代的 text/reasoning/tool 帧)。
518
- *
519
- * 🔴 **能力位说的是「这个键被接受」,不是「它已经开着」**:引擎的 `capabilities.forwardSubagentEvents`
520
- * 是一个恒真的**受理位**,把它读成「转发已生效」的消费方会接出一个**永远空着**的子代转录面,
521
- * 而能力面一直在回答「是」。⇒ 想要子代正文,**每一轮都得自己带这个键**。
522
- * 🔴 结构性缺席故事与 `reasoningEffort` 同款:闭集载体就是这条 lane 本身,不在集里 = 「这一轮要不要
523
- * 看子代正文」这个决定在座位 lane 上**没有位置可放**。座位端此前只能整条放弃子代转录面
524
- * (或绕开闭集从逃生口塞一个没登记的键上 wire —— 那是本包整张契约存在的理由所要消灭的形)。
525
- */
526
116
  forwardSubagentEvents?: boolean;
527
- /**
528
- * 这一轮**保留已结束的子代会话**以便日后续跑 → `TaskRequest.retainSubagentSessions`。
529
- * `true` = 按引擎默认保留;对象形调保留**窗口**(`ttlMs`)与**条数**(`max`)。缺席 = 不保留。
530
- *
531
- * 🔴 **过大的请求会被引擎悄悄收紧、而不是拒绝**(server 侧 clamp:窗口上限 24 小时、条数上限 64)。
532
- * ⇒ 渲染端**不许**把自己请求的值当成生效值回显 —— 那是替引擎说了一句它没说的话;要显示生效值
533
- * 就去读引擎那一面,读不到就诚实留白。
534
- * 🔴 它是「子代续跑」那条路的**另一半**:续跑能力位可以是真、路由可以在,调用照样会被拒 ——
535
- * 因为保留是**逐 run**的、且默认关。只看能力位就渲一个「继续这个子代」的入口 = 假 affordance。
536
- * 🔴 结构性缺席故事同上:此前座位 lane 没有这一位,于是「这条会话要不要留子代」只能由部署默认决定,
537
- * 而那与「端替用户做了这个决定」不是一回事。
538
- */
539
117
  retainSubagentSessions?: boolean | {
540
118
  ttlMs?: number;
541
119
  max?: number;
542
120
  };
543
- /** Per-turn settings sub-object → `TaskRequest.settings`. Closed shape (`SeatTurnSettings`);
544
- * today's only member is the `ultracode` preset boolean. */
545
121
  settings?: SeatTurnSettings;
546
- /** 本轮 scenario 拨盘选择([C131] 补载体,2026-08-08)→ `TaskRequest.scenario`。**开集**(SDK
547
- * `Scenario = KnownScenario | (string & {})` 同姿态——部署可注册自有场景,座位面不替它闭集)。
548
- * 缺席 = 不 stamp,由部署解析默认场景(assignment 链)。错误面是响亮的 typed 400:名字不在
549
- * 部署词表 ⇒ `scenario_unknown`(body 带 live 词表 `known`);在词表但不在本 principal
550
- * allowlist ⇒ `scenario_not_allowed`(带 allowlist)——渲染端可据此渲有效选项,不猜不折叠。
551
- * 此前的结构性缺席与 `reasoningEffort` 同款:闭集载体就是 lane 本身,不在集里 = 拨盘的选择
552
- * 在座位 lane 上没有位置可放(web [C131]① 记账的九键无载体形)。 */
553
122
  scenario?: string;
554
123
  }
555
- /** `uploadAttachment` 入参(REF-CC-074:此前是导出方法签名里的 3 成员内联匿名形,直接命中 B4)。 */
556
124
  export interface AttachmentUploadRequest {
557
- /** 本地文件名。服务端会自己 sanitize 出 `AttachmentUploadReceipt.name`,渲染端显示的是**回执**那个。 */
558
125
  name: string;
559
- /** MIME 类型。缺席 = 让服务端自己嗅探(它有权拒 415);消费端不要自己编一个 `application/octet-stream`
560
- * —— 编出来的类型会让服务端把本可识别的文件当二进制。 */
561
126
  mimeType?: string;
562
127
  bytes: Uint8Array;
563
128
  }
564
129
  export declare const ATTACHMENT_UPLOAD_REQUEST_KEYS: readonly ["name", "mimeType", "bytes"];
565
- /** 只带会话 id 的入参(interrupt/stop 共用;REF-CC-074 同族,1 成员形也统一成具名)。 */
566
130
  export interface SessionScopedRequest {
567
131
  sessionId: string;
568
132
  }
569
- /** `uploadAttachment` receipt — the SDK's `AttachmentInfo` verbatim (server POST /v1/attachments 201).
570
- * `name` is the SERVER's sanitized basename, not the local filename: it is the name the engine
571
- * materializes, so the renderer must display THAT one. */
572
133
  export interface AttachmentUploadReceipt {
573
134
  id: string;
574
135
  name: string;
@@ -576,64 +137,30 @@ export interface AttachmentUploadReceipt {
576
137
  sha256: string;
577
138
  sizeBytes: number;
578
139
  }
579
- /** One row of the seat's model catalog (`GET /v1/models`, non-secret projection: the service already
580
- * strips baseUrl/apiKey/headers). `contextWindow`/`maxOutputTokens` are soft-degrade extras. */
581
140
  export interface SeatModelInfo {
582
141
  id: string;
583
- /** 展示名。缺席 = 部署没给展示名 ⇒ 渲染端显示 `id` 本身(不要显示空串)。 */
584
142
  name?: string;
585
- /** 供应商名。缺席 = 部署没标供应商 ⇒ 不渲供应商标签,**不要**回落成 "unknown"。 */
586
143
  provider?: string;
587
- /** 上下文窗口 token 数(statusline 的 Context 环分母)。缺席 = 引擎没报这个量 ⇒ 环渲不确定态,
588
- * 绝不按某个猜测值算百分比([honest-absence-not-fabricated-zero])。 */
589
144
  contextWindow?: number;
590
- /** 单次回复上限 token 数。缺席 = 引擎没报 ⇒ 不渲这一行。 */
591
145
  maxOutputTokens?: number;
592
146
  }
593
- /** `listModels` envelope. `defaultId` = the deployment's resolved default model id (display only —
594
- * the per-turn choice always rides `sendMessage({model})`). */
595
147
  export interface SeatModelCatalog {
596
148
  models: SeatModelInfo[];
597
- /** 缺席 = 部署没有解析出默认模型 ⇒ 渲染端不要给「默认」打勾,也不要自己挑第一行冒充默认。 */
598
149
  defaultId?: string;
599
150
  }
600
151
  export interface SendMessageAck {
601
152
  sessionId: string;
602
153
  userMessageUuid: string;
603
- /** true = a turn was running, the message entered the deferred queue (CC sendMessage semantics)
604
- * instead of starting a turn; absent/false = the turn started immediately. */
605
154
  queued?: boolean;
606
155
  }
607
- /**
608
- * One decision, four wire verbs — the requestId's domain picks which (session-host routes it):
609
- * `live:` → POST /v1/tool-approvals/:id/respond (allow | allow_session | deny)
610
- * `durable:` → POST /v1/approvals/:sessionId/decide (+ the TOCTOU binding pair, echoed verbatim)
611
- * `question:` → POST /v1/questions/:id/respond (approve ⇒ `answer`; deny ⇒ `{answers:[]}`,
612
- * the wire's own NO_HUMAN — releases the ask NOW instead of hanging it to its TTL)
613
- * `elicit:` → POST /v1/elicitations/:id/respond (approve ⇒ accept + `updatedInput` as the
614
- * form content; deny ⇒ decline)
615
- */
616
156
  export interface ToolPermissionDecision {
617
157
  sessionId: string;
618
158
  requestId: string;
619
159
  decision: "approve" | "deny";
620
- /** AskUserQuestion answer (approve only) — `{answers:[{header, selected: string[], note?}]}`,
621
- * keyed by the question's HEADER, `selected` echoing the EXACT option labels the user saw (core
622
- * fences `selected ⊆ options`). Malformed shapes are refused at the door, never coerced: a
623
- * silently emptied answer is the user's choice being thrown away without anyone noticing.
624
- * REF-CC-038(2026-08-02):typed as `QuestionAnswer`(hitlBridge's `AskAnswer` at the entry
625
- * level) — this was `unknown` before, the 4th of 4 divergent copies of the same shape.
626
- * 缺席 = 这不是 question 域的决断(或是 deny)⇒ 宿主发 wire 自己的 NO_HUMAN 形(REF-CC-066)。 */
627
160
  answer?: QuestionAnswer;
628
- /** Approve-with-edit rewritten args (design/37 last-wins). On the `elicit:` domain this position
629
- * carries the submitted FORM CONTENT — a flat record of `string|number|boolean|string[]`
630
- * (the only shape the wire accepts; anything else is refused, not filtered).
631
- * 缺席 = 原样批准(不改参数);`elicit:` 域缺席 = 没有表单内容,宿主绝不代填。 */
632
161
  updatedInput?: unknown;
633
- /** "Don't ask again this session" (approve only). 缺席 = 只批这一次。 */
634
162
  remember?: "session";
635
163
  }
636
- /** Renderer-side `$store$` client (CC form: read + subscribe; `update` channel is the push). */
637
164
  export interface EipcStoreClient<T> {
638
165
  getState(): Promise<T>;
639
166
  getStateSync(): T;
@@ -641,87 +168,58 @@ export interface EipcStoreClient<T> {
641
168
  }
642
169
  export interface SettingsState {
643
170
  defaultModel: string | null;
644
- /** 引擎版本串。缺席 = 宿主还没连上引擎(启动窗口)⇒ 渲染端渲「连接中」,不要渲空版本号。 */
645
171
  engineVersion?: string;
646
- /** 引擎数据根目录。缺席 = 同上(还不知道)⇒ 不渲路径行,不要渲 "~" 之类的猜测值。 */
647
172
  dataRoot?: string;
648
173
  }
649
174
  export interface SessionSearchResult {
650
175
  sessionId: string;
651
- /** 命中会话的标题。缺席 = 该会话没有标题 ⇒ 结果行渲「新会话」+ 片段,不要渲空标题行。 */
652
176
  title?: string;
653
177
  matches: Array<{
654
178
  snippet: string;
655
179
  }>;
656
180
  }
657
181
  export declare const SESSION_SEARCH_RESULT_KEYS: readonly ["sessionId", "title", "matches"];
658
- /** `searchSessions` 返回形(REF-CC-072:此前是 SPEC 里的内联匿名 validator 之一;
659
- * 它从不校 `title` 那一半归 REF-CC-073,见 `SESSION_SEARCH_RESULT_KEYS`)。 */
660
182
  export interface SessionSearchEnvelope {
661
183
  results: SessionSearchResult[];
662
184
  }
663
- /** `getTranscript` 返回形(REF-CC-073:此前内联匿名、无 interface、无键集、无钉)。
664
- * `messages` = transcript 面直通批(fQe 姿态:只校数组形,元素是 CC SDKMessage 体,刻意不校)。 */
665
185
  export interface GetTranscriptResult {
666
186
  sessionId: string;
667
187
  messages: unknown[];
668
188
  }
669
189
  export declare const GET_TRANSCRIPT_RESULT_KEYS: readonly ["sessionId", "messages"];
670
- /** interrupt 回执(CC form:true = 真打断了一轮在跑的 turn,false = 当时没有在跑的 turn)。 */
671
190
  export interface InterruptAck {
672
191
  interrupted: boolean;
673
192
  }
674
- /** stop 回执(false = 会话本来就不在跑,不是错误)。 */
675
193
  export interface StopAck {
676
194
  stopped: boolean;
677
195
  }
678
- /** 通用「收到了」回执(respondToToolPermission / setFocusedSession)。 */
679
196
  export interface OkAck {
680
197
  ok: boolean;
681
198
  }
682
- /** `sessionsState` store 的状态形。 */
683
199
  export interface SessionsState {
684
200
  sessions: LocalSessionRecord[];
685
201
  }
686
- /** `focusedSessionState` store 的状态形(`null` = 没有会话被聚焦,是一个真实状态不是缺席)。 */
687
202
  export interface FocusedSessionState {
688
203
  sessionId: string | null;
689
204
  }
690
- /** Renderer-facing surface exposed by the mainView preload as `sema.web.LocalSessions`. */
691
205
  export interface LocalSessionsApi {
692
206
  start(opts?: StartSessionOptions): Promise<LocalSessionRecord>;
693
207
  sendMessage(req: SendMessageRequest): Promise<SendMessageAck>;
694
208
  interrupt(req: SessionScopedRequest): Promise<InterruptAck>;
695
209
  stop(req: SessionScopedRequest): Promise<StopAck>;
696
210
  respondToToolPermission(req: ToolPermissionDecision): Promise<OkAck>;
697
- /** Queue family (CC LocalSessionManager semantics; booleans, false = too-late/no-op form). */
698
211
  cancelQueuedMessage(sessionId: string, userMessageUuid: string): Promise<boolean>;
699
- /** CC signature: (sessionId, uuid, TARGET uuid) — position the message relative to the target
700
- * (after it when moving down, before it when moving up); NOT an index. */
701
212
  reorderQueuedMessage(sessionId: string, userMessageUuid: string, targetUserMessageUuid: string): Promise<boolean>;
702
213
  promoteQueuedMessage(sessionId: string, userMessageUuid: string): Promise<boolean>;
703
- /** CC census verbs (batch 4). setFocusedSession(null) clears focus. */
704
214
  setFocusedSession(sessionId: string | null): Promise<OkAck>;
705
215
  setModel(sessionId: string, model: string): Promise<boolean>;
706
216
  getTranscript(sessionId: string): Promise<GetTranscriptResult>;
707
217
  searchSessions(query: string): Promise<SessionSearchEnvelope>;
708
- /** Attachment BYTE channel (红批注 web#1 的另一半). Upload first, then reference the receipt id
709
- * from `sendMessage({attachmentIds})`. Rejects (413/415/501 → thrown typed error) surface to the
710
- * renderer as-is: a shelf row that says "ready" for a file the engine never received is the
711
- * same lie as a mode badge that never crossed the wire. */
712
218
  uploadAttachment(req: AttachmentUploadRequest): Promise<AttachmentUploadReceipt>;
713
- /** Read-only model catalog (engine `GET /v1/models`). Empty `models` = the deployment offers no
714
- * catalog; the renderer must degrade honestly rather than fall back to a fixture list. */
715
219
  listModels(): Promise<SeatModelCatalog>;
716
- /** [C115]/[C117] 模型配置写 verb:把选定的 catalog 条目落成宿主配置(settings.json env 块)。
717
- * 写盘语义归宿主实现(desktop main 复用 cli buildModelEnv 键映射+updateSettingsForSource 锁形+
718
- * RETIRED_MODEL_ENV_TOMBSTONES 墓碑);契约只定形与诚实位。🔴 req.apiKey 是敏感位:validator
719
- * 校形不校值,任何 throw/log/ack 绝不回显 req(错误消息只说哪个键缺/形错,不带值);
720
- * requiresRestart 必须如实渲(改完不重启=假 affordance)。 */
721
220
  applyModelConfig(req: ApplyModelConfigRequest): Promise<ApplyModelConfigResult>;
722
221
  onEvent(cb: (ev: LocalSessionEvent) => void): () => void;
723
222
  onToolPermissionRequest(cb: (req: ToolPermissionRequest) => void): () => void;
724
- /** `$store$` reactive states (read + subscribe; writes go through the verbs above). */
725
223
  sessionsStateStore: EipcStoreClient<SessionsState>;
726
224
  focusedSessionStateStore: EipcStoreClient<FocusedSessionState>;
727
225
  settingsStateStore: EipcStoreClient<SettingsState>;
@@ -730,8 +228,6 @@ export declare function isLocalSessionRecord(s: unknown): s is LocalSessionRecor
730
228
  export declare function isToolPermissionRequest(r: unknown): r is ToolPermissionRequest;
731
229
  export declare function isLocalSessionEvent(v: unknown): v is LocalSessionEvent;
732
230
  export declare function isAttachmentUploadReceipt(v: unknown): v is AttachmentUploadReceipt;
733
- /** 与 cli applyOnboard.CatalogEntry 逐键同形(真源对齐:cli 侧以 satisfies 断言钉住两形不漂——
734
- * 包不反向依赖壳,故此处独立铸型)。api 闭集;apiKey 敏感位(校形不校值,零回显)。 */
735
231
  export interface SeatCatalogEntry {
736
232
  providerId: string;
737
233
  providerName: string;
@@ -745,46 +241,23 @@ export interface SeatCatalogEntry {
745
241
  }
746
242
  export interface ApplyModelConfigRequest {
747
243
  defaultModel: SeatCatalogEntry;
748
- /** 缺席 = 与 default 同(宿主不写 MODEL_CHEAP_ID)。 */
749
244
  cheapModel?: SeatCatalogEntry;
750
245
  }
751
246
  export interface ApplyModelConfigResult {
752
247
  ok: boolean;
753
- /** ok:false 时必在(GUI 要能渲原因);同样零敏感值回显。 */
754
248
  reason?: string;
755
- /** 必须如实渲(改完不重启=假 affordance,[C115] 预登记)。 */
756
249
  requiresRestart: boolean;
757
250
  }
758
251
  export declare function isSeatModelCatalog(v: unknown): v is SeatModelCatalog;
759
252
  export declare function isSendMessageAck(v: unknown): v is SendMessageAck;
760
253
  export declare const LOCAL_SESSIONS_SPEC: EipcServiceSpec;
761
- /** verb 名清单 = `LOCAL_SESSIONS_SPEC.methods` 应有的键集(逐元素相等,门里断言)。 */
762
254
  export declare const SEAT_METHOD_NAMES: readonly ["start", "sendMessage", "interrupt", "stop", "respondToToolPermission", "cancelQueuedMessage", "reorderQueuedMessage", "promoteQueuedMessage", "setFocusedSession", "setModel", "getTranscript", "searchSessions", "uploadAttachment", "listModels", "applyModelConfig", "onEvent", "onToolPermissionRequest"];
763
- /** `$store$` 属性名清单;SPEC 的 store 键 + `"Store"` 必须逐条等于这里的名字(门里断言)。 */
764
255
  export declare const SEAT_STORE_PROPS: readonly ["sessionsStateStore", "focusedSessionStateStore", "settingsStateStore"];
765
- /** 事件式(main→renderer push)的 verb —— SPEC 里 `kind: "event"` 的那一撮,门里逐元素对账。 */
766
256
  export declare const SEAT_EVENT_METHOD_NAMES: readonly ["onEvent", "onToolPermissionRequest"];
767
257
  export declare const LOCAL_SESSION_EVENT_KEYS: readonly ["type", "sessionId", "message", "messages", "error", "errorCategory", "code", "request", "data", "sources", "permissionMode", "session", "userMessageUuid", "hasPreClearSession", "requestId", "outcome", "chrome"];
768
258
  export declare const TOOL_PERMISSION_REQUEST_KEYS: readonly ["requestId", "sessionId", "toolName", "toolCallId", "input", "message", "toctouBinding", "createdAtMs", "governanceForced", "delegation"];
769
259
  export declare const LOCAL_SESSION_RECORD_KEYS: readonly ["sessionId", "engineSessionId", "model", "title", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked"];
770
260
  export declare const SEND_MESSAGE_REQUEST_KEYS: readonly ["sessionId", "text", "model", "userMessageUuid", "permissionMode", "attachmentIds", "reasoningEffort", "retainBackgroundProcesses", "forwardSubagentEvents", "retainSubagentSessions", "settings", "scenario"];
771
- /**
772
- * **座位键 → 引擎请求位**的出身表(0.62.0;`SEND_MESSAGE_REQUEST_KEYS` 的逐键出身登记)。
773
- *
774
- * 为什么要有它:座位 lane 的载荷是一个**闭集接口**,而它的绝大多数位最终是要**原样落到引擎请求
775
- * 体上**的。这两件事此前没有任何东西把它们接起来 —— 一个座位位可以叫一个引擎请求体上**根本不存在**
776
- * 的名字(端照着它写、上了 wire 被引擎整键忽略,面上是「开关点了没反应」这类静默缺席),而引擎请求
777
- * 体新长出一个位时,也没有任何信号说「座位 lane 还没有它的席位」。本表把每个座位键的出身写成**数据**:
778
- * · `taskRequestKey` —— 这个位**原样转投**引擎请求体的同名/异名位。常驻门拿它对**装在盘上的**
779
- * sdk 型面逐名核(型直读,不手抄):名字不在引擎请求体上 ⇒ 当天红。
780
- * · `seatOnly` —— 这个位**不上 wire**,只活在座位 lane 上;字符串写清它是什么、为什么不转投。
781
- *
782
- * 🔴 `sessionId` 是**同名不同义**的典型:座位这一位是**座位会话句柄**(渲染端持有的本地 id),而引擎
783
- * 请求体上那个同名位是**引擎会话 id**(座位记录里另有 `engineSessionId` 承载)。两者恰好同名,
784
- * 把它登记成「转投」会让下一个人以为直接透传就行 —— 那是把本地句柄当引擎会话送上 wire。
785
- * 🔴 `text` 是**异名转投**:座位说 `text`,引擎请求体那一位叫 `objective`。异名不是问题,**没记账**
786
- * 才是;本表就是那本账。
787
- */
788
261
  export declare const SEAT_SEND_MESSAGE_KEY_ORIGINS: {
789
262
  readonly sessionId: {
790
263
  readonly seatOnly: "座位会话句柄(渲染端持有的本地 id);引擎会话 id 由座位记录的 `engineSessionId` 承载 —— 与引擎请求体上的同名位**同名不同义**,绝不直传";
@@ -825,29 +298,6 @@ export declare const SEAT_SEND_MESSAGE_KEY_ORIGINS: {
825
298
  };
826
299
  export declare const TOOL_PERMISSION_DECISION_KEYS: readonly ["sessionId", "requestId", "decision", "answer", "updatedInput", "remember"];
827
300
  export declare const START_SESSION_OPTION_KEYS: readonly ["model", "title", "cwd", "excludeTools"];
828
- /**
829
- * 校验器覆盖表(REF-CC-068)—— 每个校验器**逐键**声明:哪些位真被校验、哪些位**刻意**不校验。
830
- *
831
- * 为什么需要它:`防再漂钉` 封的是「interface ↔ 名字常量 ↔ SPEC」两跳,**校验器这条链此前没人钉**。
832
- * 给一个 interface 加一个必填位,门全绿,而新位从此不过校验(fail-closed 面出现缺口)。
833
- * 正确做法不是「全键必查」—— 本文件有真正**刻意不查**的位(transcript 面直通),所以豁免必须显式登记
834
- * 并带理由。门里对每个位投毒:说校验的必拒、说豁免的必过 ⇒ 这张表不可能变成一段过期的说明文字。
835
- *
836
- * 🔴 覆盖范围(wave2 回炉批 2026-08-02 补齐,首版只登了 6 个而发包说明写的是「每个校验器」——
837
- * 那 8 个没登的恰好就是 REF-CC-072 本批新提名的那批 `check*`,实测「加一个必填位、全门照绿」在它们
838
- * 身上仍然全开,即这张表自称堵死的失效形当时并没有被堵死):
839
- * · **SPEC 面 15 个具名 `check`,14 个对象形在本表登记**,余下 1 个(裸布尔回执)逐形豁免;
840
- * · 另加 4 个**嵌套**形(SeatModelInfo / SessionSearchResult / ToctouBinding /
841
- * SeatChromeEnvelopeBase)—— 它们不是 SPEC 面的直接 check,但父校验器的覆盖表只登记得到
842
- * `models` / `results` / `toctouBinding` / `chrome` 这一个顶层键,给**子形**加必填位同样全绿;
843
- * · 合计 **18 条**。两个不适用的形逐形写在 `SEAT_VALIDATOR_COVERAGE_EXEMPT` 里。
844
- * 完备性不靠这段话:门里逐条比对 `LOCAL_SESSIONS_SPEC` 每个 method/store 的 `check` **函数引用**
845
- * 必须落在「本表 ∪ 豁免表」里 —— 再加一条 verb 而不登记,门当场红。
846
- *
847
- * `check` 位存的是**函数引用本身**(不是名字):名字查表要靠一张 guards 映射,而那张映射漏一行
848
- * 就是又一个没人看见的缺口;引用相等是机械的。`guard` 位只在该形另有公开面 `is*` 谓词时登记,
849
- * 门里额外校「谓词与 check 判决一致」。
850
- */
851
301
  export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
852
302
  readonly LocalSessionRecord: {
853
303
  readonly guard: "isLocalSessionRecord";
@@ -963,11 +413,6 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
963
413
  readonly unchecked: readonly [];
964
414
  };
965
415
  };
966
- /**
967
- * 逐形豁免(REF-CC-068 的另一半):**不适用**覆盖表的具名校验器 —— 每条写清为什么,以及它的判别力
968
- * 由谁承担。这张表存在的唯一理由是让「本表 ∪ 覆盖表 ⊇ SPEC 面全部 check」这条完备性钉能机械成立:
969
- * 没有它,「某个 check 没登记」和「某个 check 不该登记」在门里长得一模一样。
970
- */
971
416
  export declare const SEAT_VALIDATOR_COVERAGE_EXEMPT: readonly [{
972
417
  readonly label: "BooleanAck";
973
418
  readonly check: (v: unknown) => SeatValidation;