@sema-agent/client-core 0.94.0 → 0.96.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 (332) hide show
  1. package/CHANGELOG.md +521 -0
  2. package/README.md +104 -57
  3. package/dist/adapt/arms.js +12 -7
  4. package/dist/adapt/panelTasks.js +4 -10
  5. package/dist/adapt/toolCards.d.ts +1 -0
  6. package/dist/adapt/toolCards.js +18 -5
  7. package/dist/adapt/wireShapes.js +5 -24
  8. package/dist/adapter/activeRunSelfHeal.d.ts +12 -3
  9. package/dist/adapter/activeRunSelfHeal.js +50 -16
  10. package/dist/adapter/downstream/eventToSdkMessage.js +33 -18
  11. package/dist/adapter/downstream/terminalToSdkResult.js +19 -12
  12. package/dist/adapter/runStream.js +30 -46
  13. package/dist/adapter/types.d.ts +7 -0
  14. package/dist/adapter/types.js +15 -0
  15. package/dist/agentSession/backgroundView.js +5 -1
  16. package/dist/agentSession/engineAgentRegistryRead.js +7 -5
  17. package/dist/agentSession/engineSessionBackgroundStop.js +25 -17
  18. package/dist/agentsWireCaps.d.ts +2 -0
  19. package/dist/agentsWireCaps.js +13 -2
  20. package/dist/approvalDecidedByCapability.d.ts +0 -1
  21. package/dist/approvalDecidedByCapability.js +2 -7
  22. package/dist/approvalsStreamLiveCapability.d.ts +0 -1
  23. package/dist/approvalsStreamLiveCapability.js +2 -6
  24. package/dist/atMostOnce.d.ts +8 -0
  25. package/dist/atMostOnce.js +36 -0
  26. package/dist/attachmentSeatCapability.d.ts +0 -1
  27. package/dist/attachmentSeatCapability.js +0 -3
  28. package/dist/attachmentsWireCaps.js +11 -6
  29. package/dist/bashExitReading.d.ts +10 -0
  30. package/dist/bashExitReading.js +12 -0
  31. package/dist/callerCwdCapability.d.ts +0 -5
  32. package/dist/callerCwdCapability.js +2 -13
  33. package/dist/centerWiringCapability.d.ts +1 -7
  34. package/dist/centerWiringCapability.js +18 -27
  35. package/dist/classifierStatus.js +4 -4
  36. package/dist/classifierVerdictWire.js +4 -16
  37. package/dist/clientSlice.js +1 -1
  38. package/dist/cloudConfigWireCaps.d.ts +3 -3
  39. package/dist/cloudConfigWireCaps.js +85 -43
  40. package/dist/compensations.js +1 -1
  41. package/dist/coreValuePorts.d.ts +11 -7
  42. package/dist/coreValuePorts.js +5 -8
  43. package/dist/credentialProvenance.d.ts +28 -0
  44. package/dist/credentialProvenance.js +76 -0
  45. package/dist/cycleOrder.d.ts +15 -0
  46. package/dist/cycleOrder.js +45 -0
  47. package/dist/decideFailureNote.js +7 -2
  48. package/dist/decideReceipt.d.ts +2 -1
  49. package/dist/decideReceipt.js +39 -14
  50. package/dist/declared/supportFloorDeclared.d.ts +1 -0
  51. package/dist/declared/supportFloorDeclared.js +5 -0
  52. package/dist/deviceExecutorManagementCapability.d.ts +0 -1
  53. package/dist/deviceExecutorManagementCapability.js +7 -16
  54. package/dist/deviceRebind.d.ts +88 -0
  55. package/dist/deviceRebind.js +242 -0
  56. package/dist/displayUntrusted.d.ts +8 -3
  57. package/dist/displayUntrusted.js +661 -63
  58. package/dist/engineAgentAbsence.d.ts +2 -2
  59. package/dist/engineAgentPanelStore.d.ts +8 -18
  60. package/dist/engineAgentPanelStore.js +19 -537
  61. package/dist/engineCapReader.d.ts +6 -6
  62. package/dist/engineCapReader.js +30 -43
  63. package/dist/engineCapsCache.d.ts +13 -2
  64. package/dist/engineCapsCache.js +276 -44
  65. package/dist/engineCredentialRequirement.d.ts +9 -0
  66. package/dist/engineCredentialRequirement.js +23 -0
  67. package/dist/engineDirectory.d.ts +79 -0
  68. package/dist/engineDirectory.js +186 -0
  69. package/dist/engineEnvSourcing.d.ts +53 -0
  70. package/dist/engineEnvSourcing.js +81 -0
  71. package/dist/engineErrorCodes.d.ts +28 -4
  72. package/dist/engineErrorCodes.js +68 -25
  73. package/dist/engineIdentity.js +2 -0
  74. package/dist/engineNoticeCodes.d.ts +17 -0
  75. package/dist/engineNoticeCodes.js +57 -3
  76. package/dist/engineWireSdk.js +2 -2
  77. package/dist/engineWordRenames.d.ts +8 -0
  78. package/dist/engineWordRenames.js +13 -0
  79. package/dist/executionLaneCapability.d.ts +2 -3
  80. package/dist/executionLaneCapability.js +18 -23
  81. package/dist/fileHistoryCaptureCapability.d.ts +14 -1
  82. package/dist/fileHistoryCaptureCapability.js +72 -6
  83. package/dist/fileHistoryLegNotice.d.ts +3 -2
  84. package/dist/fileHistoryLegNotice.js +51 -2
  85. package/dist/fleet/bgSubagentRow.d.ts +15 -0
  86. package/dist/fleet/bgSubagentRow.js +67 -0
  87. package/dist/fleet/fleetLedger.d.ts +3 -0
  88. package/dist/fleet/fleetLedger.js +153 -122
  89. package/dist/fleet/fleetProjection.d.ts +1 -3
  90. package/dist/fleet/fleetProjection.js +19 -19
  91. package/dist/fleetAgentPanelProjection.d.ts +4 -17
  92. package/dist/fleetAgentPanelProjection.js +7 -197
  93. package/dist/fleetAgentRowLike.d.ts +16 -0
  94. package/dist/fleetAgentRowLike.js +1 -0
  95. package/dist/fleetTaskDesc.js +4 -17
  96. package/dist/gateOutcome.d.ts +12 -1
  97. package/dist/gateOutcome.js +87 -18
  98. package/dist/gateVocabulary.d.ts +7 -2
  99. package/dist/gateVocabulary.js +5 -1
  100. package/dist/generated/engineAskFaceTables.js +1 -1
  101. package/dist/generated/engineFactTables.d.ts +5 -3
  102. package/dist/generated/engineFactTables.js +17 -4
  103. package/dist/generated/engineNoticeTables.js +12 -3
  104. package/dist/generated/sdkFactTables.d.ts +2 -0
  105. package/dist/generated/sdkFactTables.js +17 -0
  106. package/dist/generated/settingsSchemaFns.d.ts +13 -0
  107. package/dist/generated/settingsSchemaFns.js +75 -0
  108. package/dist/generated/toolNameTables.d.ts +1 -0
  109. package/dist/generated/toolNameTables.js +1 -0
  110. package/dist/headlessPermissionModeWire.d.ts +1 -1
  111. package/dist/headlessPermissionModeWire.js +1 -1
  112. package/dist/headlessReconnectWire.js +49 -20
  113. package/dist/hitl/allowRuleShadow.d.ts +1 -1
  114. package/dist/hitl/allowRuleShadow.js +49 -8
  115. package/dist/hitl/approvalCompleteParked.d.ts +1 -0
  116. package/dist/hitl/approvalCompleteParked.js +14 -0
  117. package/dist/hitl/approvalEndingCause.d.ts +7 -0
  118. package/dist/hitl/approvalEndingCause.js +71 -0
  119. package/dist/hitl/approvalHolds.d.ts +12 -2
  120. package/dist/hitl/approvalHolds.js +53 -2
  121. package/dist/hitl/approvalsFeed.js +23 -11
  122. package/dist/hitl/askGateWire.d.ts +2 -1
  123. package/dist/hitl/askGateWire.js +26 -1
  124. package/dist/hitl/askParkRowRouting.js +1 -1
  125. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  126. package/dist/hitl/automaticAnswerVerdict.js +15 -10
  127. package/dist/hitl/crashConverged.js +2 -0
  128. package/dist/hitl/decisionConflict.d.ts +3 -0
  129. package/dist/hitl/decisionConflict.js +41 -0
  130. package/dist/hitl/decisionRefusal.d.ts +12 -0
  131. package/dist/hitl/decisionRefusal.js +63 -4
  132. package/dist/hitl/frameRouter.d.ts +0 -1
  133. package/dist/hitl/frameRouter.js +32 -57
  134. package/dist/hitl/gateLedger.d.ts +5 -0
  135. package/dist/hitl/gateLedger.js +21 -0
  136. package/dist/hitl/hitlBridge.d.ts +17 -2
  137. package/dist/hitl/hitlBridge.js +91 -55
  138. package/dist/hitl/hitlHostSurface.js +3 -11
  139. package/dist/hitl/livePendingAsk.d.ts +16 -6
  140. package/dist/hitl/livePendingAsk.js +36 -4
  141. package/dist/hitl/localAllowRule.d.ts +1 -0
  142. package/dist/hitl/localAllowRule.js +2 -2
  143. package/dist/hitl/noAllowCause.d.ts +2 -1
  144. package/dist/hitl/noAllowCause.js +3 -2
  145. package/dist/hitl/parkExpiryJudgements.d.ts +19 -0
  146. package/dist/hitl/parkExpiryJudgements.js +46 -0
  147. package/dist/hitl/parkResolver.d.ts +4 -7
  148. package/dist/hitl/parkResolver.js +12 -34
  149. package/dist/hitl/parkRowBirthWait.d.ts +1 -0
  150. package/dist/hitl/parkRowBirthWait.js +2 -2
  151. package/dist/hitl/persistedRulesWire.js +5 -1
  152. package/dist/hitl/planReviewWire.d.ts +3 -2
  153. package/dist/hitl/planReviewWire.js +154 -50
  154. package/dist/hitl/replayedApproval.d.ts +9 -0
  155. package/dist/hitl/replayedApproval.js +139 -10
  156. package/dist/hitl/resumeRunningCard.d.ts +2 -0
  157. package/dist/hitl/resumeRunningCard.js +15 -4
  158. package/dist/hitl/sessionPolicyDeliverable.js +8 -6
  159. package/dist/hitl/standingRows.d.ts +18 -0
  160. package/dist/hitl/standingRows.js +127 -0
  161. package/dist/hitl/toolApprovalWire.d.ts +39 -7
  162. package/dist/hitl/toolApprovalWire.js +351 -61
  163. package/dist/hookMatcherVerdict.d.ts +1 -9
  164. package/dist/hookMatcherVerdict.js +21 -61
  165. package/dist/hooksWireCaps.js +40 -8
  166. package/dist/host.d.ts +5 -0
  167. package/dist/host.js +3 -1
  168. package/dist/hostCallbackGuard.d.ts +2 -0
  169. package/dist/hostCallbackGuard.js +31 -0
  170. package/dist/index.d.ts +48 -17
  171. package/dist/index.js +36 -15
  172. package/dist/interactiveInterrupt.d.ts +8 -0
  173. package/dist/interactiveInterrupt.js +54 -0
  174. package/dist/limitsWire.d.ts +5 -0
  175. package/dist/limitsWire.js +49 -3
  176. package/dist/liveModelCatalog.d.ts +95 -0
  177. package/dist/liveModelCatalog.js +297 -32
  178. package/dist/mcpEngineLeg.d.ts +25 -0
  179. package/dist/mcpEngineLeg.js +71 -15
  180. package/dist/mcpPanel.js +2 -1
  181. package/dist/mcpProbeCapability.d.ts +0 -5
  182. package/dist/mcpProbeCapability.js +2 -12
  183. package/dist/mcpReconnect.d.ts +1 -3
  184. package/dist/mcpReconnect.js +10 -5
  185. package/dist/memoryComplianceCapability.d.ts +0 -5
  186. package/dist/memoryComplianceCapability.js +2 -12
  187. package/dist/memoryOriginCapability.d.ts +0 -5
  188. package/dist/memoryOriginCapability.js +2 -12
  189. package/dist/memorySpecWire.js +2 -2
  190. package/dist/memoryVerbsWire.d.ts +1 -1
  191. package/dist/memoryVerbsWire.js +4 -0
  192. package/dist/model/liveCatalogShape.d.ts +14 -0
  193. package/dist/model/liveCatalogShape.js +71 -0
  194. package/dist/model/modelSupplyRules.d.ts +1 -0
  195. package/dist/model/modelSupplyRules.js +30 -9
  196. package/dist/model/modelsPolicy.d.ts +21 -0
  197. package/dist/model/modelsPolicy.js +90 -0
  198. package/dist/modelIdentityResolvability.d.ts +2 -2
  199. package/dist/modelIdentityResolvability.js +14 -12
  200. package/dist/modelSwitchFallback.d.ts +69 -0
  201. package/dist/modelSwitchFallback.js +206 -0
  202. package/dist/noticePresentation.d.ts +68 -0
  203. package/dist/noticePresentation.js +247 -0
  204. package/dist/notifications.js +12 -11
  205. package/dist/outputStyleSeatCapability.d.ts +0 -2
  206. package/dist/outputStyleSeatCapability.js +2 -10
  207. package/dist/ownKey.d.ts +8 -0
  208. package/dist/ownKey.js +66 -0
  209. package/dist/panelReduce.d.ts +114 -0
  210. package/dist/panelReduce.js +1135 -0
  211. package/dist/panelStateHolder.d.ts +17 -0
  212. package/dist/panelStateHolder.js +201 -0
  213. package/dist/peerFrames.js +13 -9
  214. package/dist/peerLaneCapability.d.ts +0 -1
  215. package/dist/peerLaneCapability.js +2 -6
  216. package/dist/permissionModesCapability.d.ts +0 -5
  217. package/dist/permissionModesCapability.js +5 -16
  218. package/dist/permissionRuleIssue.js +0 -3
  219. package/dist/permissionRulesWriteCapability.d.ts +0 -1
  220. package/dist/permissionRulesWriteCapability.js +2 -6
  221. package/dist/permissionsAllowGrantCapability.d.ts +0 -1
  222. package/dist/permissionsAllowGrantCapability.js +3 -9
  223. package/dist/permissionsDeclaration.d.ts +8 -0
  224. package/dist/permissionsDeclaration.js +101 -41
  225. package/dist/printPermissionOutcome.d.ts +12 -0
  226. package/dist/printPermissionOutcome.js +50 -0
  227. package/dist/printToolResultFrame.d.ts +1 -0
  228. package/dist/printToolResultFrame.js +5 -17
  229. package/dist/promptBlockedCopy.d.ts +5 -0
  230. package/dist/promptBlockedCopy.js +35 -0
  231. package/dist/promptDelivery.js +0 -8
  232. package/dist/protocolSegment.d.ts +9 -6
  233. package/dist/protocolSegment.js +31 -21
  234. package/dist/providerRejection.d.ts +4 -0
  235. package/dist/providerRejection.js +75 -14
  236. package/dist/replayBody.d.ts +12 -0
  237. package/dist/replayBody.js +25 -0
  238. package/dist/resumeRefusalCopy.d.ts +18 -1
  239. package/dist/resumeRefusalCopy.js +127 -32
  240. package/dist/retryStatus.d.ts +9 -1
  241. package/dist/retryStatus.js +9 -2
  242. package/dist/rewindArchiveCapability.d.ts +5 -14
  243. package/dist/rewindArchiveCapability.js +18 -61
  244. package/dist/rewindArchiveReading.d.ts +15 -0
  245. package/dist/rewindArchiveReading.js +56 -0
  246. package/dist/rewindEngineAction.d.ts +21 -0
  247. package/dist/rewindEngineAction.js +36 -0
  248. package/dist/rewindWireCaps.d.ts +2 -1
  249. package/dist/rewindWireCaps.js +1 -0
  250. package/dist/ruleCompileVerdict.d.ts +9 -1
  251. package/dist/ruleCompileVerdict.js +29 -4
  252. package/dist/runTerminal.d.ts +15 -12
  253. package/dist/runTerminal.js +60 -35
  254. package/dist/sandboxWire.js +13 -0
  255. package/dist/sdkRegistryTransit.d.ts +2 -1
  256. package/dist/sdkRegistryTransit.js +1 -0
  257. package/dist/sealedKeyCapability.d.ts +0 -5
  258. package/dist/sealedKeyCapability.js +3 -15
  259. package/dist/seam.js +4 -2
  260. package/dist/seatContract.d.ts +125 -34
  261. package/dist/seatContract.js +583 -179
  262. package/dist/sessionIdSegment.d.ts +1 -0
  263. package/dist/sessionIdSegment.js +11 -0
  264. package/dist/sessionMemoryErase.d.ts +1 -1
  265. package/dist/sessionMemoryErase.js +6 -1
  266. package/dist/sessionMemoryStatus.js +3 -2
  267. package/dist/sessionPolicyCapability.d.ts +0 -1
  268. package/dist/sessionPolicyCapability.js +2 -6
  269. package/dist/sessionReadRedactionCapability.d.ts +0 -5
  270. package/dist/sessionReadRedactionCapability.js +2 -13
  271. package/dist/sessionSyncFileHistory.d.ts +4 -0
  272. package/dist/sessionSyncFileHistory.js +66 -0
  273. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -2
  274. package/dist/sessionSyncFileHistoryCapability.js +2 -9
  275. package/dist/skillToolListsCapability.d.ts +0 -2
  276. package/dist/skillToolListsCapability.js +2 -9
  277. package/dist/skillsWireCaps.d.ts +4 -0
  278. package/dist/skillsWireCaps.js +66 -1
  279. package/dist/sqlEngineCapability.d.ts +0 -1
  280. package/dist/sqlEngineCapability.js +9 -14
  281. package/dist/steerPriorityCapability.d.ts +0 -2
  282. package/dist/steerPriorityCapability.js +3 -12
  283. package/dist/storePostureCapability.d.ts +1 -5
  284. package/dist/storePostureCapability.js +16 -22
  285. package/dist/streamDrainingLegs.d.ts +6 -0
  286. package/dist/streamDrainingLegs.js +23 -0
  287. package/dist/subagent/engineCompactWire.js +13 -38
  288. package/dist/subagent/engineDelegatedPrompt.js +10 -6
  289. package/dist/subagent/engineSubagentOutput.d.ts +0 -1
  290. package/dist/subagent/engineSubagentOutput.js +5 -20
  291. package/dist/subagent/engineSubagentSteer.js +7 -5
  292. package/dist/subagent/engineSubagentTail.d.ts +0 -1
  293. package/dist/subagent/engineSubagentTail.js +7 -32
  294. package/dist/subagentContentStore.js +7 -18
  295. package/dist/supportFloor.d.ts +1 -0
  296. package/dist/supportFloor.js +15 -14
  297. package/dist/systemReminderTag.d.ts +1 -0
  298. package/dist/systemReminderTag.js +8 -0
  299. package/dist/terminalStatuses.d.ts +30 -0
  300. package/dist/terminalStatuses.js +67 -0
  301. package/dist/toolHistoryMismatch.d.ts +0 -3
  302. package/dist/toolHistoryMismatch.js +3 -7
  303. package/dist/toolResult.d.ts +6 -1
  304. package/dist/toolResult.js +90 -37
  305. package/dist/toolResultContent.d.ts +2 -0
  306. package/dist/toolResultContent.js +63 -0
  307. package/dist/types/engineState.d.ts +2 -1
  308. package/dist/usageAnalytics.d.ts +146 -0
  309. package/dist/usageAnalytics.js +335 -0
  310. package/dist/userInvokedSkillsCapability.d.ts +0 -2
  311. package/dist/userInvokedSkillsCapability.js +2 -9
  312. package/dist/webSearchBackendCapability.d.ts +0 -1
  313. package/dist/webSearchBackendCapability.js +3 -7
  314. package/dist/webSearchWireCaps.js +3 -11
  315. package/dist/wireErrorTriage.d.ts +2 -0
  316. package/dist/wireErrorTriage.js +34 -5
  317. package/dist/wireFailureShape.d.ts +23 -2
  318. package/dist/wireFailureShape.js +88 -43
  319. package/dist/wireRefusalCopy.js +2 -18
  320. package/dist/workflowClient.js +7 -11
  321. package/dist/workflowsJournalCapability.d.ts +0 -1
  322. package/dist/workflowsJournalCapability.js +2 -6
  323. package/dist/writeProtectionCapability.d.ts +0 -1
  324. package/dist/writeProtectionCapability.js +5 -10
  325. package/docs/INTEGRATION-CLIENTS.md +2279 -27
  326. package/package.json +5 -5
  327. package/dist/engineCapsGenerationGuard.d.ts +0 -4
  328. package/dist/engineCapsGenerationGuard.js +0 -19
  329. package/dist/panelRunningHistory.d.ts +0 -22
  330. package/dist/panelRunningHistory.js +0 -82
  331. package/dist/registryConflict.d.ts +0 -3
  332. package/dist/registryConflict.js +0 -44
@@ -1,4 +1,7 @@
1
1
  import { PERMISSION_MODE_WORDS, REASONING_EFFORT_WORDS } from "./taskRequestWords.js";
2
+ import { liveDefaultModelCopy, liveModelRowCopy } from "./model/liveCatalogShape.js";
3
+ import { REWIND_MODES } from "./rewindWireCaps.js";
4
+ import { guardedRead, ownDataField, ownDataRefusalKeyOf, ownSendableField, readOwnDataValue } from "./ownKey.js";
2
5
  const bad = (reason, field) => field === undefined ? { reason } : { reason, field };
3
6
  const nested = (prefix, verdict) => {
4
7
  const path = verdict.field === undefined
@@ -10,9 +13,73 @@ const nested = (prefix, verdict) => {
10
13
  return bad(reason, path);
11
14
  };
12
15
  const isObject = (v) => typeof v === "object" && v !== null;
16
+ const isPlainRecord = (v) => {
17
+ if (!isObject(v) || Array.isArray(v))
18
+ return false;
19
+ const proto = Object.getPrototypeOf(v);
20
+ return proto === Object.prototype || proto === null;
21
+ };
13
22
  const isAbsent = (v) => typeof v === "undefined";
14
23
  const optionalString = (v) => isAbsent(v) || typeof v === "string";
24
+ const isFolderPath = (v) => typeof v === "string" && v.length > 0;
15
25
  const inTuple = (tuple, v) => tuple.includes(v);
26
+ const own = (o, k) => ownSendableField(o, k);
27
+ const ownItems = (a) => {
28
+ const n = ownDataField(a, "length");
29
+ const out = [];
30
+ if (typeof n !== "number")
31
+ return out;
32
+ for (let i = 0; i < n; i += 1)
33
+ out.push(own(a, String(i)));
34
+ return out;
35
+ };
36
+ const firstAccessorPath = (root) => {
37
+ const seen = new Set();
38
+ const stack = [[root, ""]];
39
+ while (stack.length > 0) {
40
+ const [v, path] = stack.pop();
41
+ if (typeof v !== "object" || v === null || seen.has(v))
42
+ continue;
43
+ seen.add(v);
44
+ for (const k of Reflect.ownKeys(v)) {
45
+ if (typeof k !== "string")
46
+ continue;
47
+ const d = Reflect.getOwnPropertyDescriptor(v, k);
48
+ if (d === undefined)
49
+ continue;
50
+ const at = path === "" ? k : `${path}.${k}`;
51
+ if (!Object.hasOwn(d, "value"))
52
+ return at;
53
+ stack.push([d.value, at]);
54
+ }
55
+ }
56
+ return undefined;
57
+ };
58
+ const NOT_PLAIN_DATA = "must be a plain enumerable data property (accessors are refused and never executed)";
59
+ const seatCheck = (fn) => (v) => {
60
+ try {
61
+ const at = firstAccessorPath(v);
62
+ if (at !== undefined)
63
+ return bad(NOT_PLAIN_DATA, at);
64
+ return fn(v);
65
+ }
66
+ catch (e) {
67
+ const key = ownDataRefusalKeyOf(e);
68
+ return key !== undefined ? bad(NOT_PLAIN_DATA, key) : bad("payload could not be read");
69
+ }
70
+ };
71
+ const seatCheckAt = (fn) => (v, field) => {
72
+ try {
73
+ const at = firstAccessorPath(v);
74
+ if (at !== undefined)
75
+ return bad(NOT_PLAIN_DATA, `${field}.${at}`);
76
+ return fn(v, field);
77
+ }
78
+ catch (e) {
79
+ const key = ownDataRefusalKeyOf(e);
80
+ return key !== undefined ? bad(NOT_PLAIN_DATA, `${field}.${key}`) : bad("payload could not be read", field);
81
+ }
82
+ };
16
83
  export const TOOL_PERMISSION_REQUEST_ID_DOMAINS = Object.freeze([
17
84
  "live:",
18
85
  "durable:",
@@ -52,14 +119,16 @@ const SEAT_EVENT_TYPE_TUPLE = [
52
119
  "error",
53
120
  "tool_permission_resolved",
54
121
  ];
55
- export const SEAT_EVENT_TYPES = SEAT_EVENT_TYPE_TUPLE;
122
+ export const SEAT_EVENT_TYPES = Object.freeze(SEAT_EVENT_TYPE_TUPLE);
56
123
  const CHROME_EVENT_KIND_TUPLE = [
57
124
  "panel_task",
58
125
  "notification_terminal",
59
126
  "prompt_suggestions",
60
127
  "subagent_lifecycle",
128
+ "text_segment_end",
129
+ "thinking_segment_end",
61
130
  ];
62
- export const CHROME_EVENT_KINDS = CHROME_EVENT_KIND_TUPLE;
131
+ export const CHROME_EVENT_KINDS = Object.freeze(CHROME_EVENT_KIND_TUPLE);
63
132
  const LANE_PROOF_LANE_TUPLE = ["main", "subagent", "workflow"];
64
133
  export const SEAT_CHROME_ENVELOPE_KEYS = ["kind", "laneProof"];
65
134
  export const HITL_RESOLUTION_OUTCOMES = [
@@ -72,7 +141,7 @@ export const HITL_RESOLUTION_OUTCOMES = [
72
141
  "decline",
73
142
  "cancel",
74
143
  ];
75
- export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder"]);
144
+ export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession"]);
76
145
  const notReported = () => Object.freeze({ kind: "not_reported" });
77
146
  const malformedReading = () => Object.freeze({ kind: "malformed" });
78
147
  const reported = (available) => Object.freeze({ kind: "reported", available });
@@ -145,6 +214,8 @@ export function watchSeatCapability(store, name, onReading) {
145
214
  }
146
215
  const SEAT_CAPABILITY_PHRASES = Object.freeze({
147
216
  pickFolder: Object.freeze({ action: "Opening a folder", ability: "show a folder picker", support: "folder picker support" }),
217
+ rewind: Object.freeze({ action: "Rewinding to an earlier message", ability: "rewind this session", support: "rewind support" }),
218
+ recents: Object.freeze({ action: "Remembering recent folders", ability: "remember recent folders", support: "recent folders support" }), patchSession: Object.freeze({ action: "Renaming or pinning a conversation", ability: "rename or pin conversations", support: "rename and pin support" }),
148
219
  });
149
220
  export function seatCapabilityUnavailableDetail(name, reading) {
150
221
  const phrase = Object.hasOwn(SEAT_CAPABILITY_PHRASES, name)
@@ -167,355 +238,629 @@ export function seatCapabilityUnavailableDetail(name, reading) {
167
238
  return `${phrase.action} isn't available: this app hasn't reported ${phrase.support}.`;
168
239
  return `${phrase.action} isn't available: this app's support report couldn't be read.`;
169
240
  }
241
+ const NO_TIME = Number.NEGATIVE_INFINITY;
242
+ const stampMs = (v) => {
243
+ if (typeof v !== "string")
244
+ return NO_TIME;
245
+ const t = Date.parse(v);
246
+ return Number.isFinite(t) ? t : NO_TIME;
247
+ };
248
+ const softField = (o, key) => typeof o === "object" && o !== null ? guardedRead(() => readOwnDataValue(o, key)) : undefined;
249
+ const softItems = (a) => {
250
+ const isArray = guardedRead(() => Array.isArray(a));
251
+ if (isArray !== true)
252
+ return undefined;
253
+ const n = softField(a, "length");
254
+ if (typeof n !== "number" || !Number.isSafeInteger(n) || n < 0)
255
+ return undefined;
256
+ const out = [];
257
+ for (let i = 0; i < n; i += 1)
258
+ out.push(softField(a, String(i)));
259
+ return out;
260
+ };
261
+ export function recentFoldersOf(input) {
262
+ const sessions = softItems(softField(input, "sessions"));
263
+ const registered = softItems(softField(input, "registered"));
264
+ if (sessions === undefined && registered === undefined)
265
+ return null;
266
+ const byPath = new Map();
267
+ let order = 0;
268
+ const place = (path, at) => {
269
+ const cur = byPath.get(path);
270
+ order += 1;
271
+ if (cur === undefined)
272
+ byPath.set(path, { at, order });
273
+ else if (at > cur.at)
274
+ cur.at = at;
275
+ };
276
+ for (const row of registered ?? []) {
277
+ const path = softField(row, "path");
278
+ if (isFolderPath(path))
279
+ place(path, stampMs(softField(row, "lastUsedAt")));
280
+ }
281
+ for (const rec of sessions ?? []) {
282
+ const cwd = softField(rec, "cwd");
283
+ if (!isFolderPath(cwd))
284
+ continue;
285
+ const active = stampMs(softField(rec, "lastActivityAt"));
286
+ place(cwd, active !== NO_TIME ? active : stampMs(softField(rec, "createdAt")));
287
+ }
288
+ return [...byPath.entries()]
289
+ .sort(([, x], [, y]) => (x.at === y.at ? x.order - y.order : x.at > y.at ? -1 : 1))
290
+ .map(([path]) => path);
291
+ }
292
+ export async function readRecentFolders(input) {
293
+ const capability = guardedRead(() => input.capability);
294
+ const list = guardedRead(() => input.list);
295
+ const sessions = guardedRead(() => input.sessions);
296
+ let registered;
297
+ let host = "skipped";
298
+ let unreadableRows = 0;
299
+ if (capability !== undefined && seatCapabilityUnavailableDetail("recents", capability) === undefined) {
300
+ try {
301
+ const items = softItems(softField(await list(), "folders"));
302
+ if (items === undefined) {
303
+ host = "unreadable";
304
+ }
305
+ else {
306
+ const rows = [];
307
+ for (const item of items) {
308
+ const path = softField(item, "path");
309
+ if (!isFolderPath(path)) {
310
+ unreadableRows += 1;
311
+ continue;
312
+ }
313
+ const lastUsedAt = softField(item, "lastUsedAt");
314
+ rows.push(typeof lastUsedAt === "string" ? { path, lastUsedAt } : { path });
315
+ }
316
+ if (items.length > 0 && rows.length === 0) {
317
+ host = "unreadable";
318
+ }
319
+ else {
320
+ registered = rows;
321
+ host = "listed";
322
+ }
323
+ }
324
+ }
325
+ catch {
326
+ host = "unreadable";
327
+ }
328
+ }
329
+ return Object.freeze({ folders: recentFoldersOf({ sessions, registered }), host, unreadableRows });
330
+ }
170
331
  export const PERMISSION_MODE_INTENTS = [...PERMISSION_MODE_WORDS];
171
332
  export const ATTACHMENT_IDS_PER_TASK_CAP = 16;
172
333
  export const SEAT_REASONING_EFFORTS = [...REASONING_EFFORT_WORDS];
173
334
  export const SEAT_TURN_SETTINGS_KEYS = ["ultracode"];
335
+ export const SEAT_TURN_SETTINGS_ORIGINS = Object.freeze({
336
+ ultracode: Object.freeze({ carriedBy: "renderer" }),
337
+ webSearch: Object.freeze({ hostSupplied: "联网检索的每请求配置来自宿主的设置源(可能带检索服务的凭据与私网地址);渲染端没有设置文件,也不该持有凭据" }),
338
+ hooks: Object.freeze({ hostSupplied: "hooks 表来自宿主的设置文件(宿主经设置端口与 hooksForWire 投影);渲染端没有设置文件、也不执行本机 hook" }),
339
+ resolved: Object.freeze({ hostSupplied: "设置解析器的生效快照(hooks / env / model / 已解析权限)由宿主跑解析器得出;渲染端没有设置源可解析" }),
340
+ outputStyle: Object.freeze({ hostSupplied: "输出风格正文由宿主的兜底层随请求带(风格文件在宿主);渲染端只选名字,不持正文" }),
341
+ });
342
+ export const SEAT_REWIND_INTENT_KEYS = ["mode", "targetMessageUuid"];
174
343
  export const ATTACHMENT_UPLOAD_REQUEST_KEYS = ["name", "mimeType", "bytes"];
344
+ export const SESSION_ROW_PATCH_REQUEST_KEYS = Object.freeze(["sessionId", "title", "pinned"]);
175
345
  export const SESSION_SEARCH_RESULT_KEYS = ["sessionId", "title", "matches"];
176
346
  export const GET_TRANSCRIPT_RESULT_KEYS = ["sessionId", "messages"];
177
- const checkLocalSessionRecord = (s) => {
347
+ const checkLocalSessionRecord = seatCheck((s) => {
178
348
  if (!isObject(s))
179
349
  return bad("session record is not an object");
180
- if (typeof s.sessionId !== "string")
350
+ if (typeof own(s, "sessionId") !== "string")
181
351
  return bad("sessionId must be a string", "sessionId");
182
- if (!optionalString(s.engineSessionId))
352
+ if (!optionalString(own(s, "engineSessionId")))
183
353
  return bad("engineSessionId must be a string when present", "engineSessionId");
184
- if (!optionalString(s.model))
354
+ if (!optionalString(own(s, "model")))
185
355
  return bad("model must be a string when present", "model");
186
- if (!optionalString(s.title))
356
+ if (!optionalString(own(s, "title")))
187
357
  return bad("title must be a string when present", "title");
188
- if (!isAbsent(s.cwd) && (typeof s.cwd !== "string" || s.cwd.length === 0)) {
358
+ const cwd = own(s, "cwd");
359
+ if (!isAbsent(cwd) && !isFolderPath(cwd)) {
189
360
  return bad("cwd must be a non-empty path string when present (absent = no folder chosen)", "cwd");
190
361
  }
191
- if (typeof s.isRunning !== "boolean")
362
+ if (typeof own(s, "isRunning") !== "boolean")
192
363
  return bad("isRunning must be a boolean", "isRunning");
193
- if (typeof s.createdAt !== "string")
364
+ if (typeof own(s, "createdAt") !== "string")
194
365
  return bad("createdAt must be an ISO-8601 string", "createdAt");
195
- if (!optionalString(s.lastActivityAt))
366
+ if (!optionalString(own(s, "lastActivityAt")))
196
367
  return bad("lastActivityAt must be a string when present", "lastActivityAt");
197
- if (!isAbsent(s.queuedMessages)) {
198
- const q = s.queuedMessages;
199
- const okQueue = Array.isArray(q) && q.every((row) => isObject(row) && typeof row.uuid === "string" && typeof row.text === "string");
368
+ const q = own(s, "queuedMessages");
369
+ if (!isAbsent(q)) {
370
+ const okQueue = Array.isArray(q) && ownItems(q).every((row) => isObject(row) && typeof own(row, "uuid") === "string" && typeof own(row, "text") === "string");
200
371
  if (!okQueue)
201
372
  return bad("queuedMessages must be an array of {uuid,text}", "queuedMessages");
202
373
  }
203
- if (!isAbsent(s.parked) && typeof s.parked !== "boolean") {
374
+ const parked = own(s, "parked");
375
+ if (!isAbsent(parked) && typeof parked !== "boolean") {
204
376
  return bad("parked must be a boolean when present", "parked");
205
377
  }
378
+ const pinned = own(s, "pinned");
379
+ if (!isAbsent(pinned) && typeof pinned !== "boolean") {
380
+ return bad("pinned must be a boolean when present (absent = not pinned or unknown)", "pinned");
381
+ }
206
382
  return true;
207
- };
383
+ });
208
384
  export function isLocalSessionRecord(s) {
209
385
  return checkLocalSessionRecord(s) === true;
210
386
  }
211
- const checkToctouBinding = (v) => {
387
+ const checkToctouBinding = seatCheck((v) => {
212
388
  if (!isObject(v))
213
389
  return bad("toctouBinding must be an object", "toctouBinding");
214
- if (typeof v.callId !== "string")
390
+ if (typeof own(v, "callId") !== "string")
215
391
  return bad("toctouBinding.callId must be a string", "toctouBinding.callId");
216
- if (typeof v.inputHash !== "string")
392
+ if (typeof own(v, "inputHash") !== "string")
217
393
  return bad("toctouBinding.inputHash must be a string", "toctouBinding.inputHash");
218
394
  return true;
219
- };
220
- const checkToolPermissionRequest = (r) => {
395
+ });
396
+ const checkToolPermissionRequest = seatCheck((r) => {
221
397
  if (!isObject(r))
222
398
  return bad("tool permission request is not an object");
223
- if (typeof r.requestId !== "string")
399
+ const requestId = own(r, "requestId");
400
+ if (typeof requestId !== "string")
224
401
  return bad("requestId must be a string", "requestId");
225
- if (toolPermissionRequestIdDomain(r.requestId) === undefined) {
402
+ if (toolPermissionRequestIdDomain(requestId) === undefined) {
226
403
  return bad(`requestId must carry a registered domain prefix (${TOOL_PERMISSION_REQUEST_ID_DOMAINS.join("|")})`, "requestId");
227
404
  }
228
- if (typeof r.sessionId !== "string")
405
+ if (typeof own(r, "sessionId") !== "string")
229
406
  return bad("sessionId must be a string", "sessionId");
230
- if (!isAbsent(r.toolName) && r.toolName !== null && typeof r.toolName !== "string") {
407
+ const toolName = own(r, "toolName");
408
+ if (!isAbsent(toolName) && toolName !== null && typeof toolName !== "string") {
231
409
  return bad("toolName must be a string or null when present", "toolName");
232
410
  }
233
- if (!isAbsent(r.toolCallId) && r.toolCallId !== null && typeof r.toolCallId !== "string") {
411
+ const toolCallId = own(r, "toolCallId");
412
+ if (!isAbsent(toolCallId) && toolCallId !== null && typeof toolCallId !== "string") {
234
413
  return bad("toolCallId must be a string or null when present", "toolCallId");
235
414
  }
236
- if (!optionalString(r.message))
415
+ if (!optionalString(own(r, "message")))
237
416
  return bad("message must be a string when present", "message");
238
- if (!isAbsent(r.toctouBinding)) {
239
- const verdict = checkToctouBinding(r.toctouBinding);
417
+ const toctouBinding = own(r, "toctouBinding");
418
+ if (!isAbsent(toctouBinding)) {
419
+ const verdict = checkToctouBinding(toctouBinding);
240
420
  if (verdict !== true)
241
421
  return verdict;
242
422
  }
243
- if (!isAbsent(r.createdAtMs) && typeof r.createdAtMs !== "number") {
423
+ const createdAtMs = own(r, "createdAtMs");
424
+ if (!isAbsent(createdAtMs) && typeof createdAtMs !== "number") {
244
425
  return bad("createdAtMs must be a number (epoch ms) when present", "createdAtMs");
245
426
  }
246
427
  return true;
247
- };
428
+ });
248
429
  export function isToolPermissionRequest(r) {
249
430
  return checkToolPermissionRequest(r) === true;
250
431
  }
251
- const checkLaneProof = (v, field) => {
432
+ const checkLaneProof = seatCheckAt((v, field) => {
252
433
  if (!isObject(v))
253
434
  return bad("laneProof must be an object", field);
254
- const lane = v.lane;
435
+ const lane = own(v, "lane");
255
436
  if (typeof lane !== "string" || !inTuple(LANE_PROOF_LANE_TUPLE, lane)) {
256
437
  return bad(`laneProof.lane must be one of ${LANE_PROOF_LANE_TUPLE.join("|")}`, `${field}.lane`);
257
438
  }
258
- if (lane === "subagent" && typeof v.parentToolCallId !== "string") {
439
+ if (lane === "subagent" && typeof own(v, "parentToolCallId") !== "string") {
259
440
  return bad("subagent laneProof needs parentToolCallId", `${field}.parentToolCallId`);
260
441
  }
261
- if (lane === "workflow" && (typeof v.via !== "string" || typeof v.key !== "string")) {
442
+ if (lane === "workflow" && (typeof own(v, "via") !== "string" || typeof own(v, "key") !== "string")) {
262
443
  return bad("workflow laneProof needs via + key", `${field}.via`);
263
444
  }
264
445
  return true;
265
- };
266
- const checkSeatChromeEnvelope = (v, field) => {
446
+ });
447
+ const checkSeatChromeEnvelope = seatCheckAt((v, field) => {
267
448
  if (!isObject(v))
268
449
  return bad("chrome must be an object", field);
269
- const kind = v.kind;
450
+ const kind = own(v, "kind");
270
451
  if (typeof kind !== "string")
271
452
  return bad("chrome.kind must be a string", `${field}.kind`);
272
453
  if (!inTuple(CHROME_EVENT_KIND_TUPLE, kind)) {
273
454
  return bad(`chrome.kind is not a renderer-wired arm (${CHROME_EVENT_KIND_TUPLE.join("|")})`, `${field}.kind`);
274
455
  }
275
- return checkLaneProof(v.laneProof, `${field}.laneProof`);
276
- };
277
- const checkLocalSessionEvent = (v) => {
456
+ return checkLaneProof(own(v, "laneProof"), `${field}.laneProof`);
457
+ });
458
+ const checkLocalSessionEvent = seatCheck((v) => {
278
459
  if (!isObject(v))
279
460
  return bad("event is not an object");
280
- const type = v.type;
461
+ const type = own(v, "type");
281
462
  if (typeof type !== "string")
282
463
  return bad("type must be a string", "type");
283
464
  if (!inTuple(SEAT_EVENT_TYPE_TUPLE, type)) {
284
465
  return bad(`type is not a registered seat event name (${SEAT_EVENT_TYPE_TUPLE.join("|")})`, "type");
285
466
  }
286
- if (typeof v.sessionId !== "string")
467
+ if (typeof own(v, "sessionId") !== "string")
287
468
  return bad("sessionId must be a string", "sessionId");
288
- if (!isAbsent(v.messages) && !Array.isArray(v.messages))
469
+ const messages = own(v, "messages");
470
+ if (!isAbsent(messages) && !Array.isArray(messages))
289
471
  return bad("messages must be an array", "messages");
290
- if (!optionalString(v.error))
472
+ if (!optionalString(own(v, "error")))
291
473
  return bad("error must be a string when present", "error");
292
- if (!optionalString(v.errorCategory))
474
+ if (!optionalString(own(v, "errorCategory")))
293
475
  return bad("errorCategory must be a string when present", "errorCategory");
294
- if (!isAbsent(v.code) && typeof v.code !== "number")
476
+ const code = own(v, "code");
477
+ if (!isAbsent(code) && typeof code !== "number")
295
478
  return bad("code must be a number when present", "code");
296
- if (!isAbsent(v.request)) {
297
- const verdict = checkToolPermissionRequest(v.request);
479
+ const request = own(v, "request");
480
+ if (!isAbsent(request)) {
481
+ const verdict = checkToolPermissionRequest(request);
298
482
  if (verdict !== true)
299
483
  return nested("request", verdict);
300
484
  }
301
- if (!optionalString(v.data))
485
+ if (!optionalString(own(v, "data")))
302
486
  return bad("data must be a string when present", "data");
303
- if (!isAbsent(v.sources)) {
304
- const okSources = Array.isArray(v.sources) && v.sources.every((t) => typeof t === "string");
487
+ const sources = own(v, "sources");
488
+ if (!isAbsent(sources)) {
489
+ const okSources = Array.isArray(sources) && ownItems(sources).every((t) => typeof t === "string");
305
490
  if (!okSources)
306
491
  return bad("sources must be a string[]", "sources");
307
492
  }
308
- if (!isAbsent(v.permissionMode)) {
309
- const mode = v.permissionMode;
493
+ const mode = own(v, "permissionMode");
494
+ if (!isAbsent(mode)) {
310
495
  if (typeof mode !== "string" || !inTuple(PERMISSION_MODE_INTENTS, mode)) {
311
496
  return bad(`permissionMode must be one of ${PERMISSION_MODE_INTENTS.join("|")}`, "permissionMode");
312
497
  }
313
498
  }
314
- if (!isAbsent(v.session)) {
315
- const verdict = checkLocalSessionRecord(v.session);
499
+ const session = own(v, "session");
500
+ if (!isAbsent(session)) {
501
+ const verdict = checkLocalSessionRecord(session);
316
502
  if (verdict !== true)
317
503
  return nested("session", verdict);
318
504
  }
319
- if (!optionalString(v.userMessageUuid))
505
+ if (!optionalString(own(v, "userMessageUuid")))
320
506
  return bad("userMessageUuid must be a string when present", "userMessageUuid");
321
- if (!isAbsent(v.hasPreClearSession) && typeof v.hasPreClearSession !== "boolean") {
507
+ const hasPreClearSession = own(v, "hasPreClearSession");
508
+ if (!isAbsent(hasPreClearSession) && typeof hasPreClearSession !== "boolean") {
322
509
  return bad("hasPreClearSession must be a boolean when present", "hasPreClearSession");
323
510
  }
324
- if (!optionalString(v.requestId))
511
+ if (!optionalString(own(v, "requestId")))
325
512
  return bad("requestId must be a string when present", "requestId");
326
- if (!optionalString(v.outcome))
513
+ const outcome = own(v, "outcome");
514
+ if (!optionalString(outcome))
327
515
  return bad("outcome must be a string when present", "outcome");
328
- if (!isAbsent(v.chrome)) {
329
- const verdict = checkSeatChromeEnvelope(v.chrome, "chrome");
516
+ const parked = own(v, "parked");
517
+ if (!isAbsent(parked)) {
518
+ if (parked !== true)
519
+ return bad("parked must be the literal true when present (absent = no park evidence)", "parked");
520
+ if (type !== "tool_permission_resolved" || outcome !== "expired") {
521
+ return bad('parked is only allowed on a tool_permission_resolved event whose outcome is "expired"', "parked");
522
+ }
523
+ }
524
+ const chrome = own(v, "chrome");
525
+ if (!isAbsent(chrome)) {
526
+ const verdict = checkSeatChromeEnvelope(chrome, "chrome");
330
527
  if (verdict !== true)
331
528
  return nested("chrome", verdict);
332
529
  }
333
530
  return true;
334
- };
531
+ });
335
532
  export function isLocalSessionEvent(v) {
336
533
  return checkLocalSessionEvent(v) === true;
337
534
  }
338
- const checkAttachmentUploadReceipt = (v) => {
535
+ const checkAttachmentUploadReceipt = seatCheck((v) => {
339
536
  if (!isObject(v))
340
537
  return bad("upload receipt is not an object");
341
- if (typeof v.id !== "string")
538
+ if (typeof own(v, "id") !== "string")
342
539
  return bad("id must be a string", "id");
343
- if (typeof v.name !== "string")
540
+ if (typeof own(v, "name") !== "string")
344
541
  return bad("name must be a string", "name");
345
- if (typeof v.mime !== "string")
542
+ if (typeof own(v, "mime") !== "string")
346
543
  return bad("mime must be a string", "mime");
347
- if (typeof v.sha256 !== "string")
544
+ if (typeof own(v, "sha256") !== "string")
348
545
  return bad("sha256 must be a string", "sha256");
349
- if (typeof v.sizeBytes !== "number")
546
+ if (typeof own(v, "sizeBytes") !== "number")
350
547
  return bad("sizeBytes must be a number", "sizeBytes");
351
548
  return true;
352
- };
549
+ });
353
550
  export function isAttachmentUploadReceipt(v) {
354
551
  return checkAttachmentUploadReceipt(v) === true;
355
552
  }
356
- const checkSeatModelInfo = (m, index) => {
357
- if (!isObject(m))
358
- return bad(`models[${index}] is not an object`, "models");
359
- if (typeof m.id !== "string")
360
- return bad(`models[${index}].id must be a string`, "models");
361
- if (!optionalString(m.name))
362
- return bad(`models[${index}].name must be a string when present`, "models");
363
- if (!optionalString(m.provider))
364
- return bad(`models[${index}].provider must be a string when present`, "models");
365
- if (!isAbsent(m.contextWindow) && typeof m.contextWindow !== "number") {
366
- return bad(`models[${index}].contextWindow must be a number when present`, "models");
367
- }
368
- if (!isAbsent(m.maxOutputTokens) && typeof m.maxOutputTokens !== "number") {
369
- return bad(`models[${index}].maxOutputTokens must be a number when present`, "models");
370
- }
371
- return true;
372
- };
373
- const checkApplyModelConfigResult = (v) => {
553
+ const checkApplyModelConfigResult = seatCheck((v) => {
374
554
  if (!isObject(v))
375
555
  return bad("applyModelConfig result is not an object");
376
- if (typeof v.ok !== "boolean")
556
+ const ok = own(v, "ok");
557
+ if (typeof ok !== "boolean")
377
558
  return bad("ok must be a boolean", "ok");
378
- if (typeof v.requiresRestart !== "boolean")
559
+ if (typeof own(v, "requiresRestart") !== "boolean")
379
560
  return bad("requiresRestart must be a boolean", "requiresRestart");
380
- if (v.ok === false && (typeof v.reason !== "string" || v.reason.length === 0)) {
561
+ const reason = own(v, "reason");
562
+ if (ok === false && (typeof reason !== "string" || reason.length === 0)) {
381
563
  return bad("reason must be a non-empty string when ok is false", "reason");
382
564
  }
383
- if (v.reason !== undefined && typeof v.reason !== "string")
565
+ if (reason !== undefined && typeof reason !== "string")
384
566
  return bad("reason must be a string when present", "reason");
385
567
  return true;
386
- };
387
- const checkSeatModelCatalog = (v) => {
388
- if (!isObject(v))
568
+ });
569
+ const checkLiveModelCatalog = seatCheck((v) => {
570
+ if (!isObject(v) || Array.isArray(v))
389
571
  return bad("model catalog is not an object");
390
- const models = v.models;
572
+ const models = own(v, "models");
391
573
  if (!Array.isArray(models))
392
574
  return bad("models must be an array", "models");
393
- for (let i = 0; i < models.length; i += 1) {
394
- const verdict = checkSeatModelInfo(models[i], i);
395
- if (verdict !== true)
396
- return verdict;
575
+ const rows = ownItems(models);
576
+ const names = new Set();
577
+ for (let i = 0; i < rows.length; i += 1) {
578
+ const row = liveModelRowCopy(rows[i]);
579
+ if (row === undefined)
580
+ return bad(`models[${i}] is not a catalog row (an object whose name is a non-empty string, JSON values only)`, `models[${i}]`);
581
+ if (names.has(row.name))
582
+ return bad(`models[${i}] repeats the name of an earlier row`, `models[${i}].name`);
583
+ names.add(row.name);
584
+ }
585
+ const dflt = own(v, "default");
586
+ if (typeof dflt !== "string" || dflt.length === 0)
587
+ return bad("default must be a non-empty string", "default");
588
+ const defaultModel = own(v, "defaultModel");
589
+ if (!isAbsent(defaultModel) && liveDefaultModelCopy(defaultModel) === undefined) {
590
+ return bad("defaultModel must be {id: non-empty string, name?: non-empty string} when present", "defaultModel");
397
591
  }
398
- if (!optionalString(v.defaultId))
399
- return bad("defaultId must be a string when present", "defaultId");
400
592
  return true;
401
- };
402
- export function isSeatModelCatalog(v) {
403
- return checkSeatModelCatalog(v) === true;
593
+ });
594
+ const checkSeatRewindIntent = seatCheck((v) => {
595
+ if (!isObject(v) || Array.isArray(v))
596
+ return bad("rewind must be an object {mode, targetMessageUuid}");
597
+ for (const k of Object.keys(v)) {
598
+ if (!inTuple(SEAT_REWIND_INTENT_KEYS, k))
599
+ return bad(`unknown key (closed shape: ${SEAT_REWIND_INTENT_KEYS.join(", ")})`, k);
600
+ }
601
+ const mode = own(v, "mode");
602
+ if (typeof mode !== "string" || !inTuple(REWIND_MODES, mode))
603
+ return bad(`mode must be one of ${REWIND_MODES.join("|")}`, "mode");
604
+ const target = own(v, "targetMessageUuid");
605
+ if (typeof target !== "string" || target.length === 0) {
606
+ return bad("targetMessageUuid must be a non-empty string", "targetMessageUuid");
607
+ }
608
+ return true;
609
+ });
610
+ const checkSeatTurnSettings = seatCheck((v) => {
611
+ if (!isObject(v) || Array.isArray(v))
612
+ return bad("settings must be an object");
613
+ for (const k of Object.keys(v)) {
614
+ if (!inTuple(SEAT_TURN_SETTINGS_KEYS, k)) {
615
+ const host = Object.hasOwn(SEAT_TURN_SETTINGS_ORIGINS, k);
616
+ return bad(host ? "this settings key is supplied by the host, not carried by the seat" : `unknown key (closed shape: ${SEAT_TURN_SETTINGS_KEYS.join(", ")})`, k);
617
+ }
618
+ }
619
+ const ultracode = own(v, "ultracode");
620
+ if (!isAbsent(ultracode) && typeof ultracode !== "boolean")
621
+ return bad("ultracode must be a boolean when present", "ultracode");
622
+ return true;
623
+ });
624
+ const checkRetainSubagentSessions = seatCheck((v) => {
625
+ if (typeof v === "boolean")
626
+ return true;
627
+ if (!isObject(v) || Array.isArray(v))
628
+ return bad("retainSubagentSessions must be a boolean or {ttlMs?, max?}");
629
+ for (const k of Object.keys(v)) {
630
+ if (k !== "ttlMs" && k !== "max")
631
+ return bad("unknown key (closed shape: ttlMs, max)", k);
632
+ const n = own(v, k);
633
+ if (!isAbsent(n) && (typeof n !== "number" || !Number.isSafeInteger(n) || n < 0))
634
+ return bad(`${k} must be a non-negative integer when present`, k);
635
+ }
636
+ return true;
637
+ });
638
+ export function checkSendMessageRequest(v) {
639
+ try {
640
+ if (!isObject(v) || Array.isArray(v))
641
+ return bad("sendMessage request is not an object");
642
+ const at = firstAccessorPath(v);
643
+ if (at !== undefined)
644
+ return bad(NOT_PLAIN_DATA, at);
645
+ const body = {};
646
+ for (const k of Object.keys(v)) {
647
+ if (!inTuple(SEND_MESSAGE_REQUEST_KEYS, k))
648
+ return bad(`unknown key (closed shape: ${SEND_MESSAGE_REQUEST_KEYS.join(", ")})`, k);
649
+ body[k] = own(v, k);
650
+ }
651
+ if (typeof body.sessionId !== "string" || body.sessionId.length === 0)
652
+ return bad("sessionId must be a non-empty string", "sessionId");
653
+ if (typeof body.text !== "string")
654
+ return bad("text must be a string", "text");
655
+ if (!optionalString(body.model))
656
+ return bad("model must be a string when present", "model");
657
+ if (!optionalString(body.userMessageUuid))
658
+ return bad("userMessageUuid must be a string when present", "userMessageUuid");
659
+ if (!isAbsent(body.permissionMode) && (typeof body.permissionMode !== "string" || !inTuple(PERMISSION_MODE_INTENTS, body.permissionMode))) {
660
+ return bad(`permissionMode must be one of ${PERMISSION_MODE_INTENTS.join("|")}`, "permissionMode");
661
+ }
662
+ if (!isAbsent(body.attachmentIds)) {
663
+ const raw = body.attachmentIds;
664
+ const ids = Array.isArray(raw) ? ownItems(raw) : undefined;
665
+ if (ids === undefined || !ids.every((id) => typeof id === "string" && id.length > 0)) {
666
+ return bad("attachmentIds must be an array of non-empty attachment ids", "attachmentIds");
667
+ }
668
+ if (ids.length > ATTACHMENT_IDS_PER_TASK_CAP)
669
+ return bad(`attachmentIds exceeds the per-task limit (${ATTACHMENT_IDS_PER_TASK_CAP})`, "attachmentIds");
670
+ }
671
+ if (!isAbsent(body.reasoningEffort) && (typeof body.reasoningEffort !== "string" || !inTuple(SEAT_REASONING_EFFORTS, body.reasoningEffort))) {
672
+ return bad(`reasoningEffort must be one of ${SEAT_REASONING_EFFORTS.join("|")}`, "reasoningEffort");
673
+ }
674
+ for (const k of ["retainBackgroundProcesses", "forwardSubagentEvents"]) {
675
+ if (!isAbsent(body[k]) && typeof body[k] !== "boolean")
676
+ return bad(`${k} must be a boolean when present`, k);
677
+ }
678
+ if (!isAbsent(body.retainSubagentSessions)) {
679
+ const verdict = checkRetainSubagentSessions(body.retainSubagentSessions);
680
+ if (verdict !== true)
681
+ return nested("retainSubagentSessions", verdict);
682
+ }
683
+ if (!isAbsent(body.settings)) {
684
+ const verdict = checkSeatTurnSettings(body.settings);
685
+ if (verdict !== true)
686
+ return nested("settings", verdict);
687
+ }
688
+ if (!optionalString(body.scenario))
689
+ return bad("scenario must be a string when present", "scenario");
690
+ if (!isAbsent(body.rewind)) {
691
+ const verdict = checkSeatRewindIntent(body.rewind);
692
+ if (verdict !== true)
693
+ return nested("rewind", verdict);
694
+ }
695
+ return true;
696
+ }
697
+ catch (e) {
698
+ const key = ownDataRefusalKeyOf(e);
699
+ return key !== undefined ? bad(NOT_PLAIN_DATA, key) : bad("sendMessage request could not be read");
700
+ }
701
+ }
702
+ export function isSendMessageRequest(v) {
703
+ return checkSendMessageRequest(v) === true;
404
704
  }
405
- const checkSendMessageAck = (v) => {
705
+ export const checkSessionRowPatchRequest = seatCheck((v) => {
706
+ if (!isObject(v) || Array.isArray(v))
707
+ return bad("patchSession request is not an object");
708
+ const body = {};
709
+ for (const k of Object.keys(v)) {
710
+ if (!inTuple(SESSION_ROW_PATCH_REQUEST_KEYS, k))
711
+ return bad(`unknown key (closed shape: ${SESSION_ROW_PATCH_REQUEST_KEYS.join(", ")})`, k);
712
+ body[k] = own(v, k);
713
+ }
714
+ if (typeof body.sessionId !== "string" || body.sessionId.length === 0)
715
+ return bad("sessionId must be a non-empty string", "sessionId");
716
+ const { title, pinned } = body;
717
+ if (!isAbsent(title) && title !== null && (typeof title !== "string" || title.length === 0)) {
718
+ return bad('title must be a non-empty string, or null to clear it back to the automatic title (an empty string is not a way to clear)', "title");
719
+ }
720
+ if (!isAbsent(pinned) && typeof pinned !== "boolean")
721
+ return bad("pinned must be a boolean when present", "pinned");
722
+ if (isAbsent(title) && isAbsent(pinned))
723
+ return bad("nothing to change: carry at least one of title / pinned");
724
+ return true;
725
+ });
726
+ export function isSessionRowPatchRequest(v) {
727
+ return checkSessionRowPatchRequest(v) === true;
728
+ }
729
+ const checkSendMessageAck = seatCheck((v) => {
406
730
  if (!isObject(v))
407
731
  return bad("sendMessage ack is not an object");
408
- if (typeof v.sessionId !== "string")
732
+ if (typeof own(v, "sessionId") !== "string")
409
733
  return bad("sessionId must be a string", "sessionId");
410
- if (typeof v.userMessageUuid !== "string")
734
+ if (typeof own(v, "userMessageUuid") !== "string")
411
735
  return bad("userMessageUuid must be a string", "userMessageUuid");
412
- if (!isAbsent(v.queued) && typeof v.queued !== "boolean")
736
+ const queued = own(v, "queued");
737
+ if (!isAbsent(queued) && typeof queued !== "boolean")
413
738
  return bad("queued must be a boolean when present", "queued");
414
739
  return true;
415
- };
740
+ });
416
741
  export function isSendMessageAck(v) {
417
742
  return checkSendMessageAck(v) === true;
418
743
  }
419
- const checkInterruptAck = (v) => isObject(v) && typeof v.interrupted === "boolean" ? true : bad("interrupt ack needs boolean `interrupted`", "interrupted");
420
- const checkStopAck = (v) => isObject(v) && typeof v.stopped === "boolean" ? true : bad("stop ack needs boolean `stopped`", "stopped");
421
- const checkOkAck = (v) => isObject(v) && typeof v.ok === "boolean" ? true : bad("ack needs boolean `ok`", "ok");
744
+ const checkInterruptAck = seatCheck((v) => isObject(v) && typeof own(v, "interrupted") === "boolean" ? true : bad("interrupt ack needs boolean `interrupted`", "interrupted"));
745
+ const checkStopAck = seatCheck((v) => isObject(v) && typeof own(v, "stopped") === "boolean" ? true : bad("stop ack needs boolean `stopped`", "stopped"));
746
+ const checkOkAck = seatCheck((v) => isObject(v) && typeof own(v, "ok") === "boolean" ? true : bad("ack needs boolean `ok`", "ok"));
422
747
  const checkBooleanAck = (v) => typeof v === "boolean" ? true : bad("expected a bare boolean result");
423
- const checkGetTranscriptResult = (v) => {
748
+ const checkGetTranscriptResult = seatCheck((v) => {
424
749
  if (!isObject(v))
425
750
  return bad("transcript envelope is not an object");
426
- if (typeof v.sessionId !== "string")
751
+ if (typeof own(v, "sessionId") !== "string")
427
752
  return bad("sessionId must be a string", "sessionId");
428
- if (!Array.isArray(v.messages))
753
+ if (!Array.isArray(own(v, "messages")))
429
754
  return bad("messages must be an array", "messages");
430
755
  return true;
431
- };
432
- const checkSessionSearchResult = (v) => {
756
+ });
757
+ const checkSessionSearchResult = seatCheck((v) => {
433
758
  if (!isObject(v))
434
759
  return bad("search result row is not an object");
435
- if (typeof v.sessionId !== "string")
760
+ if (typeof own(v, "sessionId") !== "string")
436
761
  return bad("sessionId must be a string", "sessionId");
437
- if (!optionalString(v.title))
762
+ if (!optionalString(own(v, "title")))
438
763
  return bad("title must be a string when present", "title");
439
- if (!Array.isArray(v.matches))
764
+ const matches = own(v, "matches");
765
+ if (!Array.isArray(matches))
440
766
  return bad("matches must be an array", "matches");
441
- const okMatches = v.matches.every((m) => isObject(m) && typeof m.snippet === "string");
767
+ const okMatches = ownItems(matches).every((m) => isObject(m) && typeof own(m, "snippet") === "string");
442
768
  if (!okMatches)
443
769
  return bad("matches must be {snippet:string}[]", "matches");
444
770
  return true;
445
- };
446
- const checkSessionSearchEnvelope = (v) => {
771
+ });
772
+ const checkSessionSearchEnvelope = seatCheck((v) => {
447
773
  if (!isObject(v))
448
774
  return bad("search envelope is not an object");
449
- const results = v.results;
775
+ const results = own(v, "results");
450
776
  if (!Array.isArray(results))
451
777
  return bad("results must be an array", "results");
452
- for (let i = 0; i < results.length; i += 1) {
453
- const verdict = checkSessionSearchResult(results[i]);
778
+ const rows = ownItems(results);
779
+ for (let i = 0; i < rows.length; i += 1) {
780
+ const verdict = checkSessionSearchResult(rows[i]);
454
781
  if (verdict !== true)
455
782
  return nested(`results[${i}]`, verdict);
456
783
  }
457
784
  return true;
458
- };
459
- const checkSessionsState = (v) => {
785
+ });
786
+ const checkSessionsState = seatCheck((v) => {
460
787
  if (!isObject(v))
461
788
  return bad("sessions state is not an object");
462
- const sessions = v.sessions;
789
+ const sessions = own(v, "sessions");
463
790
  if (!Array.isArray(sessions))
464
791
  return bad("sessions must be an array", "sessions");
465
- for (let i = 0; i < sessions.length; i += 1) {
466
- const verdict = checkLocalSessionRecord(sessions[i]);
792
+ const rows = ownItems(sessions);
793
+ for (let i = 0; i < rows.length; i += 1) {
794
+ const verdict = checkLocalSessionRecord(rows[i]);
467
795
  if (verdict !== true)
468
796
  return nested(`sessions[${i}]`, verdict);
469
797
  }
470
798
  return true;
471
- };
472
- const checkFocusedSessionState = (v) => {
799
+ });
800
+ const checkFocusedSessionState = seatCheck((v) => {
473
801
  if (!isObject(v))
474
802
  return bad("focused session state is not an object");
475
- if (v.sessionId !== null && typeof v.sessionId !== "string") {
803
+ const sessionId = own(v, "sessionId");
804
+ if (sessionId !== null && typeof sessionId !== "string") {
476
805
  return bad("sessionId must be a string or null", "sessionId");
477
806
  }
478
807
  return true;
479
- };
480
- const checkSettingsState = (v) => {
481
- if (!isObject(v))
482
- return bad("settings state is not an object");
483
- if (v.defaultModel !== null && typeof v.defaultModel !== "string") {
484
- return bad("defaultModel must be a string or null", "defaultModel");
808
+ });
809
+ const checkSettingsState = seatCheck((v) => {
810
+ if (!isPlainRecord(v))
811
+ return bad("settings state is not a plain object");
812
+ if (Object.hasOwn(v, "defaultModel")) {
813
+ return bad("defaultModel is not carried in settings state: read the deployment default model from the model catalog (liveDefaultModelOf over the listModels() result)", "defaultModel");
485
814
  }
486
- if (!optionalString(v.engineVersion))
815
+ if (!optionalString(own(v, "engineVersion")))
487
816
  return bad("engineVersion must be a string when present", "engineVersion");
488
- if (!optionalString(v.dataRoot))
817
+ if (!optionalString(own(v, "dataRoot")))
489
818
  return bad("dataRoot must be a string when present", "dataRoot");
490
819
  return true;
491
- };
492
- const checkPickFolderResult = (v) => v === null || (typeof v === "string" && v.length > 0)
820
+ });
821
+ const checkPickFolderResult = (v) => v === null || isFolderPath(v)
493
822
  ? true
494
823
  : bad("pickFolder result must be null (cancelled) or a non-empty path string");
495
- const checkSeatCapabilitiesState = (v) => {
496
- try {
497
- if (!isObject(v) || Array.isArray(v))
498
- return bad("seat capabilities state is not an object");
499
- const proto = Object.getPrototypeOf(v);
500
- if (proto !== Object.prototype && proto !== null)
501
- return bad("seat capabilities state is not a plain object");
502
- for (const k of Reflect.ownKeys(v)) {
503
- const name = typeof k === "string" ? k : String(k);
504
- if (typeof k !== "string" || !inTuple(SEAT_CAPABILITY_NAMES, k)) {
505
- return bad(`${name} is not a registered seat capability (${SEAT_CAPABILITY_NAMES.join("|")})`, name);
506
- }
507
- const desc = Object.getOwnPropertyDescriptor(v, k);
508
- if (desc === undefined || !("value" in desc))
509
- return bad(`${k} must be a plain data property (accessors are refused)`, k);
510
- if (!isAbsent(desc.value) && typeof desc.value !== "boolean")
511
- return bad(`${k} must be a boolean when present`, k);
512
- }
513
- return true;
824
+ const checkRecentFolderRow = seatCheck((v) => {
825
+ if (!isPlainRecord(v))
826
+ return bad("recent folder row is not a plain object");
827
+ if (!isFolderPath(own(v, "path")))
828
+ return bad("path must be a non-empty path string", "path");
829
+ if (!optionalString(own(v, "lastUsedAt")))
830
+ return bad("lastUsedAt must be a string when present", "lastUsedAt");
831
+ return true;
832
+ });
833
+ const checkRecentFoldersResult = seatCheck((v) => {
834
+ if (!isPlainRecord(v))
835
+ return bad("recent folders result is not a plain object");
836
+ const folders = own(v, "folders");
837
+ if (!Array.isArray(folders))
838
+ return bad("folders must be an array", "folders");
839
+ const rows = ownItems(folders);
840
+ for (let i = 0; i < rows.length; i += 1) {
841
+ const verdict = checkRecentFolderRow(rows[i]);
842
+ if (verdict !== true)
843
+ return nested(`folders[${i}]`, verdict);
514
844
  }
515
- catch {
516
- return bad("seat capabilities state could not be read");
845
+ return true;
846
+ });
847
+ const checkSeatCapabilitiesState = seatCheck((v) => {
848
+ if (!isObject(v) || Array.isArray(v))
849
+ return bad("seat capabilities state is not an object");
850
+ const proto = Object.getPrototypeOf(v);
851
+ if (proto !== Object.prototype && proto !== null)
852
+ return bad("seat capabilities state is not a plain object");
853
+ for (const k of Reflect.ownKeys(v)) {
854
+ const name = typeof k === "string" ? k : String(k);
855
+ if (typeof k !== "string" || !inTuple(SEAT_CAPABILITY_NAMES, k)) {
856
+ return bad(`${name} is not a registered seat capability (${SEAT_CAPABILITY_NAMES.join("|")})`, name);
857
+ }
858
+ const value = own(v, k);
859
+ if (!isAbsent(value) && typeof value !== "boolean")
860
+ return bad(`${k} must be a boolean when present`, k);
517
861
  }
518
- };
862
+ return true;
863
+ });
519
864
  export const LOCAL_SESSIONS_SPEC = {
520
865
  ns: "sema.web",
521
866
  service: "LocalSessions",
@@ -533,9 +878,11 @@ export const LOCAL_SESSIONS_SPEC = {
533
878
  getTranscript: { kind: "invoke", check: checkGetTranscriptResult },
534
879
  searchSessions: { kind: "invoke", check: checkSessionSearchEnvelope },
535
880
  uploadAttachment: { kind: "invoke", check: checkAttachmentUploadReceipt },
536
- listModels: { kind: "invoke", check: checkSeatModelCatalog },
881
+ listModels: { kind: "invoke", check: checkLiveModelCatalog },
537
882
  applyModelConfig: { kind: "invoke", check: checkApplyModelConfigResult },
538
883
  pickFolder: { kind: "invoke", check: checkPickFolderResult },
884
+ listRecentFolders: { kind: "invoke", check: checkRecentFoldersResult },
885
+ noteRecentFolder: { kind: "invoke", check: checkOkAck }, patchSession: { kind: "invoke", check: checkLocalSessionRecord },
539
886
  onEvent: { kind: "event", check: checkLocalSessionEvent },
540
887
  onToolPermissionRequest: { kind: "event", check: checkToolPermissionRequest },
541
888
  },
@@ -563,6 +910,8 @@ export const SEAT_METHOD_NAMES = [
563
910
  "listModels",
564
911
  "applyModelConfig",
565
912
  "pickFolder",
913
+ "listRecentFolders",
914
+ "noteRecentFolder", "patchSession",
566
915
  "onEvent",
567
916
  "onToolPermissionRequest",
568
917
  ];
@@ -590,6 +939,7 @@ export const LOCAL_SESSION_EVENT_KEYS = [
590
939
  "hasPreClearSession",
591
940
  "requestId",
592
941
  "outcome",
942
+ "parked",
593
943
  "chrome",
594
944
  ];
595
945
  export const TOOL_PERMISSION_REQUEST_KEYS = [
@@ -609,6 +959,7 @@ export const TOOL_PERMISSION_REQUEST_KEYS = [
609
959
  "ruleOffersAbsence",
610
960
  "askClass",
611
961
  "classes",
962
+ "rememberRefused",
612
963
  ];
613
964
  export const LOCAL_SESSION_RECORD_KEYS = [
614
965
  "sessionId",
@@ -621,6 +972,7 @@ export const LOCAL_SESSION_RECORD_KEYS = [
621
972
  "lastActivityAt",
622
973
  "queuedMessages",
623
974
  "parked",
975
+ "pinned",
624
976
  ];
625
977
  export const SEND_MESSAGE_REQUEST_KEYS = [
626
978
  "sessionId",
@@ -635,6 +987,7 @@ export const SEND_MESSAGE_REQUEST_KEYS = [
635
987
  "retainSubagentSessions",
636
988
  "settings",
637
989
  "scenario",
990
+ "rewind",
638
991
  ];
639
992
  export const SEAT_SEND_MESSAGE_KEY_ORIGINS = {
640
993
  sessionId: { seatOnly: "座位会话句柄(渲染端持有的本地 id);引擎会话 id 由座位记录的 `engineSessionId` 承载 —— 与引擎请求体上的同名位**同名不同义**,绝不直传" },
@@ -649,6 +1002,7 @@ export const SEAT_SEND_MESSAGE_KEY_ORIGINS = {
649
1002
  retainSubagentSessions: { taskRequestKey: "retainSubagentSessions" },
650
1003
  settings: { taskRequestKey: "settings" },
651
1004
  scenario: { taskRequestKey: "scenario" },
1005
+ rewind: { projectedBy: "rewindSpecForMode", taskRequestKeys: ["resumeAt", "resumeAtMode", "restoreFiles", "rewindFilesTo"] },
652
1006
  };
653
1007
  export const TOOL_PERMISSION_DECISION_KEYS = [
654
1008
  "sessionId",
@@ -663,7 +1017,7 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
663
1017
  LocalSessionRecord: {
664
1018
  guard: "isLocalSessionRecord",
665
1019
  check: checkLocalSessionRecord,
666
- validated: ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked"],
1020
+ validated: ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned"],
667
1021
  unchecked: [],
668
1022
  },
669
1023
  ToolPermissionRequest: {
@@ -703,6 +1057,10 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
703
1057
  key: "classes",
704
1058
  why: "与 askClass 同一对(CC-284),同在同缺、同一只成对窄读(非空、每员非空串、无重复、首员等于 askClass;开集、原样顺序);座位门不设第二判官,理由同 askClass。",
705
1059
  },
1060
+ {
1061
+ key: "rememberRefused",
1062
+ why: "展示增强位(CC-642),权威窄读在卡口两条腿与过境口 toolPermissionRequestAskBits(同一只 readApprovalRememberRefused:自有键 ∧ 严格 true 才上座,永不铸 false);座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。消费端 `=== true` 读,其余(缺席 / 坏形)一律当缺席 ⇒ 照旧渲「本会话放行」。缺席 = 服务端没说(记得住或老服务端),不是 false。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
1063
+ },
706
1064
  {
707
1065
  key: "ruleOffersAbsence",
708
1066
  why: "喂强制判据口 approvalIsMandated 的位(CC-203;寄存行那条腿的强制只以缺席词 mandated 表达),按开集读(非空串原文字节、词表不校);权威窄读在卡口与过境口,座位门不设第二判官,理由同 mandated。坏形读成缺席 ⇒ 这一路不判强制(放宽方向:寄存行上的强制就丢了;另两路 mandated / mandate 照判);表外串只是不等于 mandated。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
@@ -728,6 +1086,7 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
728
1086
  "hasPreClearSession",
729
1087
  "requestId",
730
1088
  "outcome",
1089
+ "parked",
731
1090
  "chrome",
732
1091
  ],
733
1092
  unchecked: [
@@ -743,10 +1102,40 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
743
1102
  validated: ["id", "name", "mime", "sha256", "sizeBytes"],
744
1103
  unchecked: [],
745
1104
  },
746
- SeatModelCatalog: {
747
- guard: "isSeatModelCatalog",
748
- check: checkSeatModelCatalog,
749
- validated: ["models", "defaultId"],
1105
+ LiveModelCatalog: {
1106
+ check: checkLiveModelCatalog,
1107
+ validated: ["models", "default", "defaultModel"],
1108
+ unchecked: [
1109
+ {
1110
+ key: "droppedEntries",
1111
+ why: "诊断面(哪些目录条目没被引擎收下),三态读法归 droppedModelEntriesOf(含坏形 malformed);出站门为它拒掉整份目录 = 选单为一行诊断整个消失。",
1112
+ },
1113
+ ],
1114
+ },
1115
+ SendMessageRequest: {
1116
+ guard: "isSendMessageRequest",
1117
+ check: checkSendMessageRequest,
1118
+ validated: [
1119
+ "sessionId",
1120
+ "text",
1121
+ "model",
1122
+ "userMessageUuid",
1123
+ "permissionMode",
1124
+ "attachmentIds",
1125
+ "reasoningEffort",
1126
+ "retainBackgroundProcesses",
1127
+ "forwardSubagentEvents",
1128
+ "retainSubagentSessions",
1129
+ "settings",
1130
+ "scenario",
1131
+ "rewind",
1132
+ ],
1133
+ unchecked: [],
1134
+ },
1135
+ SessionRowPatchRequest: {
1136
+ guard: "isSessionRowPatchRequest",
1137
+ check: checkSessionRowPatchRequest,
1138
+ validated: ["sessionId", "title", "pinned"],
750
1139
  unchecked: [],
751
1140
  },
752
1141
  ApplyModelConfigResult: {
@@ -797,17 +1186,27 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
797
1186
  },
798
1187
  SettingsState: {
799
1188
  check: checkSettingsState,
800
- validated: ["defaultModel", "engineVersion", "dataRoot"],
1189
+ validated: ["engineVersion", "dataRoot"],
801
1190
  unchecked: [],
802
1191
  },
803
1192
  SeatCapabilitiesState: {
804
1193
  check: checkSeatCapabilitiesState,
805
- validated: ["pickFolder"],
1194
+ validated: ["pickFolder", "rewind", "recents", "patchSession"],
806
1195
  unchecked: [],
807
1196
  },
808
- SeatModelInfo: {
809
- check: (v) => checkSeatModelInfo(v, 0),
810
- validated: ["id", "name", "provider", "contextWindow", "maxOutputTokens"],
1197
+ RecentFoldersResult: {
1198
+ check: checkRecentFoldersResult,
1199
+ validated: ["folders"],
1200
+ unchecked: [],
1201
+ },
1202
+ RecentFolderRow: {
1203
+ check: checkRecentFolderRow,
1204
+ validated: ["path", "lastUsedAt"],
1205
+ unchecked: [],
1206
+ },
1207
+ SeatRewindIntent: {
1208
+ check: checkSeatRewindIntent,
1209
+ validated: ["mode", "targetMessageUuid"],
811
1210
  unchecked: [],
812
1211
  },
813
1212
  SessionSearchResult: {
@@ -864,5 +1263,10 @@ const _seatContractPins = [
864
1263
  true, true, true, true, true, true, true, true,
865
1264
  true, true, true, true, true, true, true, true,
866
1265
  true, true, true, true, true,
1266
+ true, true, true, true, true, true, true, true,
1267
+ true, true,
1268
+ true, true,
1269
+ true, true, true, true,
1270
+ true, true, true, true, true, true,
867
1271
  ];
868
1272
  void _seatContractPins;