@sema-agent/client-core 0.94.0 → 0.95.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 (255) hide show
  1. package/CHANGELOG.md +341 -0
  2. package/README.md +70 -47
  3. package/dist/adapt/arms.js +5 -6
  4. package/dist/adapt/panelTasks.js +4 -10
  5. package/dist/adapt/toolCards.js +2 -2
  6. package/dist/adapt/wireShapes.js +3 -8
  7. package/dist/adapter/activeRunSelfHeal.d.ts +8 -3
  8. package/dist/adapter/activeRunSelfHeal.js +20 -12
  9. package/dist/adapter/downstream/eventToSdkMessage.js +24 -17
  10. package/dist/adapter/downstream/terminalToSdkResult.js +11 -3
  11. package/dist/adapter/runStream.js +2 -1
  12. package/dist/adapter/types.d.ts +7 -0
  13. package/dist/adapter/types.js +15 -0
  14. package/dist/agentSession/backgroundView.js +5 -1
  15. package/dist/agentSession/engineAgentRegistryRead.js +2 -1
  16. package/dist/agentSession/engineSessionBackgroundStop.js +3 -2
  17. package/dist/agentsWireCaps.d.ts +2 -0
  18. package/dist/approvalDecidedByCapability.d.ts +0 -1
  19. package/dist/approvalDecidedByCapability.js +2 -7
  20. package/dist/approvalsStreamLiveCapability.d.ts +0 -1
  21. package/dist/approvalsStreamLiveCapability.js +2 -6
  22. package/dist/atMostOnce.d.ts +8 -0
  23. package/dist/atMostOnce.js +36 -0
  24. package/dist/attachmentSeatCapability.d.ts +0 -1
  25. package/dist/attachmentSeatCapability.js +0 -3
  26. package/dist/attachmentsWireCaps.js +11 -6
  27. package/dist/bashExitReading.d.ts +10 -0
  28. package/dist/bashExitReading.js +12 -0
  29. package/dist/callerCwdCapability.d.ts +0 -1
  30. package/dist/callerCwdCapability.js +2 -7
  31. package/dist/centerWiringCapability.d.ts +1 -3
  32. package/dist/centerWiringCapability.js +18 -21
  33. package/dist/classifierStatus.js +4 -4
  34. package/dist/cloudConfigWireCaps.js +43 -21
  35. package/dist/compensations.js +1 -1
  36. package/dist/cycleOrder.d.ts +15 -0
  37. package/dist/cycleOrder.js +45 -0
  38. package/dist/decideFailureNote.js +4 -1
  39. package/dist/decideReceipt.d.ts +2 -1
  40. package/dist/decideReceipt.js +41 -13
  41. package/dist/declared/supportFloorDeclared.d.ts +1 -0
  42. package/dist/declared/supportFloorDeclared.js +5 -0
  43. package/dist/deviceExecutorManagementCapability.d.ts +0 -1
  44. package/dist/deviceExecutorManagementCapability.js +7 -16
  45. package/dist/deviceRebind.d.ts +88 -0
  46. package/dist/deviceRebind.js +242 -0
  47. package/dist/displayUntrusted.d.ts +1 -0
  48. package/dist/displayUntrusted.js +313 -11
  49. package/dist/engineAgentAbsence.d.ts +2 -2
  50. package/dist/engineAgentPanelStore.d.ts +8 -18
  51. package/dist/engineAgentPanelStore.js +19 -537
  52. package/dist/engineCapReader.d.ts +6 -6
  53. package/dist/engineCapReader.js +30 -43
  54. package/dist/engineCapsCache.d.ts +7 -2
  55. package/dist/engineCapsCache.js +64 -26
  56. package/dist/engineCredentialRequirement.d.ts +9 -0
  57. package/dist/engineCredentialRequirement.js +23 -0
  58. package/dist/engineEnvSourcing.d.ts +53 -0
  59. package/dist/engineEnvSourcing.js +81 -0
  60. package/dist/engineErrorCodes.d.ts +14 -3
  61. package/dist/engineErrorCodes.js +31 -10
  62. package/dist/engineIdentity.js +2 -0
  63. package/dist/engineWireSdk.js +2 -2
  64. package/dist/executionLaneCapability.d.ts +2 -3
  65. package/dist/executionLaneCapability.js +18 -23
  66. package/dist/fileHistoryCaptureCapability.d.ts +0 -1
  67. package/dist/fileHistoryCaptureCapability.js +2 -6
  68. package/dist/fileHistoryLegNotice.d.ts +3 -2
  69. package/dist/fileHistoryLegNotice.js +51 -2
  70. package/dist/fleet/fleetLedger.d.ts +2 -0
  71. package/dist/fleet/fleetLedger.js +69 -52
  72. package/dist/fleet/fleetProjection.d.ts +0 -3
  73. package/dist/fleet/fleetProjection.js +9 -16
  74. package/dist/fleetAgentPanelProjection.d.ts +4 -17
  75. package/dist/fleetAgentPanelProjection.js +7 -197
  76. package/dist/fleetAgentRowLike.d.ts +16 -0
  77. package/dist/fleetAgentRowLike.js +1 -0
  78. package/dist/gateOutcome.js +30 -18
  79. package/dist/generated/sdkFactTables.d.ts +2 -0
  80. package/dist/generated/sdkFactTables.js +17 -0
  81. package/dist/generated/settingsSchemaFns.d.ts +10 -0
  82. package/dist/generated/settingsSchemaFns.js +22 -0
  83. package/dist/headlessPermissionModeWire.d.ts +1 -1
  84. package/dist/headlessPermissionModeWire.js +1 -1
  85. package/dist/headlessReconnectWire.js +49 -20
  86. package/dist/hitl/allowRuleShadow.d.ts +1 -1
  87. package/dist/hitl/allowRuleShadow.js +49 -8
  88. package/dist/hitl/approvalCompleteParked.d.ts +1 -0
  89. package/dist/hitl/approvalCompleteParked.js +14 -0
  90. package/dist/hitl/approvalEndingCause.d.ts +5 -0
  91. package/dist/hitl/approvalEndingCause.js +61 -0
  92. package/dist/hitl/approvalHolds.d.ts +12 -2
  93. package/dist/hitl/approvalHolds.js +53 -2
  94. package/dist/hitl/approvalsFeed.js +23 -11
  95. package/dist/hitl/askGateWire.d.ts +2 -1
  96. package/dist/hitl/askGateWire.js +26 -1
  97. package/dist/hitl/automaticAnswerVerdict.js +2 -2
  98. package/dist/hitl/crashConverged.js +2 -0
  99. package/dist/hitl/decisionConflict.d.ts +3 -0
  100. package/dist/hitl/decisionConflict.js +43 -0
  101. package/dist/hitl/decisionRefusal.d.ts +4 -0
  102. package/dist/hitl/decisionRefusal.js +26 -1
  103. package/dist/hitl/frameRouter.js +26 -43
  104. package/dist/hitl/gateLedger.d.ts +5 -0
  105. package/dist/hitl/gateLedger.js +21 -0
  106. package/dist/hitl/hitlBridge.d.ts +12 -1
  107. package/dist/hitl/hitlBridge.js +68 -53
  108. package/dist/hitl/hitlHostSurface.js +3 -11
  109. package/dist/hitl/livePendingAsk.d.ts +16 -6
  110. package/dist/hitl/livePendingAsk.js +36 -4
  111. package/dist/hitl/parkExpiryJudgements.d.ts +19 -0
  112. package/dist/hitl/parkExpiryJudgements.js +46 -0
  113. package/dist/hitl/parkResolver.d.ts +3 -7
  114. package/dist/hitl/parkResolver.js +50 -26
  115. package/dist/hitl/persistedRulesWire.js +5 -1
  116. package/dist/hitl/planReviewWire.d.ts +2 -2
  117. package/dist/hitl/planReviewWire.js +56 -30
  118. package/dist/hitl/replayedApproval.d.ts +8 -0
  119. package/dist/hitl/replayedApproval.js +125 -10
  120. package/dist/hitl/resumeRunningCard.d.ts +2 -0
  121. package/dist/hitl/resumeRunningCard.js +15 -4
  122. package/dist/hitl/toolApprovalWire.d.ts +24 -4
  123. package/dist/hitl/toolApprovalWire.js +115 -38
  124. package/dist/hooksWireCaps.js +38 -6
  125. package/dist/host.d.ts +5 -0
  126. package/dist/host.js +3 -1
  127. package/dist/hostCallbackGuard.d.ts +1 -0
  128. package/dist/hostCallbackGuard.js +25 -0
  129. package/dist/index.d.ts +30 -11
  130. package/dist/index.js +20 -8
  131. package/dist/interactiveInterrupt.d.ts +8 -0
  132. package/dist/interactiveInterrupt.js +54 -0
  133. package/dist/limitsWire.d.ts +5 -0
  134. package/dist/limitsWire.js +49 -3
  135. package/dist/liveModelCatalog.d.ts +95 -0
  136. package/dist/liveModelCatalog.js +297 -32
  137. package/dist/mcpEngineLeg.d.ts +25 -0
  138. package/dist/mcpEngineLeg.js +71 -15
  139. package/dist/mcpPanel.js +2 -1
  140. package/dist/mcpProbeCapability.d.ts +0 -1
  141. package/dist/mcpProbeCapability.js +2 -6
  142. package/dist/mcpReconnect.d.ts +1 -3
  143. package/dist/mcpReconnect.js +10 -5
  144. package/dist/memoryComplianceCapability.d.ts +0 -1
  145. package/dist/memoryComplianceCapability.js +2 -6
  146. package/dist/memoryOriginCapability.d.ts +0 -1
  147. package/dist/memoryOriginCapability.js +2 -6
  148. package/dist/memoryVerbsWire.d.ts +1 -1
  149. package/dist/memoryVerbsWire.js +4 -0
  150. package/dist/model/liveCatalogShape.d.ts +14 -0
  151. package/dist/model/liveCatalogShape.js +71 -0
  152. package/dist/model/modelSupplyRules.d.ts +1 -0
  153. package/dist/model/modelSupplyRules.js +30 -9
  154. package/dist/model/modelsPolicy.d.ts +21 -0
  155. package/dist/model/modelsPolicy.js +90 -0
  156. package/dist/modelIdentityResolvability.d.ts +1 -1
  157. package/dist/modelIdentityResolvability.js +5 -12
  158. package/dist/modelSwitchFallback.d.ts +69 -0
  159. package/dist/modelSwitchFallback.js +206 -0
  160. package/dist/notifications.js +12 -11
  161. package/dist/outputStyleSeatCapability.d.ts +0 -1
  162. package/dist/outputStyleSeatCapability.js +2 -7
  163. package/dist/ownKey.d.ts +6 -0
  164. package/dist/ownKey.js +48 -0
  165. package/dist/panelReduce.d.ts +114 -0
  166. package/dist/panelReduce.js +1135 -0
  167. package/dist/panelStateHolder.d.ts +17 -0
  168. package/dist/panelStateHolder.js +201 -0
  169. package/dist/peerLaneCapability.d.ts +0 -1
  170. package/dist/peerLaneCapability.js +2 -6
  171. package/dist/permissionModesCapability.d.ts +0 -1
  172. package/dist/permissionModesCapability.js +5 -10
  173. package/dist/permissionRulesWriteCapability.d.ts +0 -1
  174. package/dist/permissionRulesWriteCapability.js +2 -6
  175. package/dist/permissionsAllowGrantCapability.d.ts +0 -1
  176. package/dist/permissionsAllowGrantCapability.js +3 -9
  177. package/dist/permissionsDeclaration.d.ts +6 -0
  178. package/dist/permissionsDeclaration.js +45 -0
  179. package/dist/printToolResultFrame.js +2 -10
  180. package/dist/promptDelivery.js +0 -8
  181. package/dist/resumeRefusalCopy.d.ts +18 -1
  182. package/dist/resumeRefusalCopy.js +126 -15
  183. package/dist/rewindArchiveCapability.d.ts +2 -1
  184. package/dist/rewindArchiveCapability.js +15 -7
  185. package/dist/rewindEngineAction.d.ts +21 -0
  186. package/dist/rewindEngineAction.js +36 -0
  187. package/dist/rewindWireCaps.d.ts +2 -1
  188. package/dist/rewindWireCaps.js +1 -0
  189. package/dist/runTerminal.d.ts +0 -11
  190. package/dist/runTerminal.js +4 -27
  191. package/dist/sdkRegistryTransit.d.ts +2 -1
  192. package/dist/sdkRegistryTransit.js +1 -0
  193. package/dist/sealedKeyCapability.d.ts +0 -1
  194. package/dist/sealedKeyCapability.js +3 -9
  195. package/dist/seatContract.d.ts +54 -25
  196. package/dist/seatContract.js +394 -171
  197. package/dist/sessionIdSegment.d.ts +1 -0
  198. package/dist/sessionIdSegment.js +11 -0
  199. package/dist/sessionMemoryErase.d.ts +1 -1
  200. package/dist/sessionMemoryErase.js +6 -1
  201. package/dist/sessionMemoryStatus.js +3 -2
  202. package/dist/sessionPolicyCapability.d.ts +0 -1
  203. package/dist/sessionPolicyCapability.js +2 -6
  204. package/dist/sessionReadRedactionCapability.d.ts +0 -1
  205. package/dist/sessionReadRedactionCapability.js +2 -7
  206. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -1
  207. package/dist/sessionSyncFileHistoryCapability.js +2 -6
  208. package/dist/skillToolListsCapability.d.ts +0 -1
  209. package/dist/skillToolListsCapability.js +2 -6
  210. package/dist/skillsWireCaps.d.ts +4 -0
  211. package/dist/skillsWireCaps.js +66 -1
  212. package/dist/sqlEngineCapability.d.ts +0 -1
  213. package/dist/sqlEngineCapability.js +9 -14
  214. package/dist/steerPriorityCapability.d.ts +0 -1
  215. package/dist/steerPriorityCapability.js +3 -9
  216. package/dist/storePostureCapability.d.ts +1 -1
  217. package/dist/storePostureCapability.js +16 -16
  218. package/dist/streamDrainingLegs.d.ts +6 -0
  219. package/dist/streamDrainingLegs.js +23 -0
  220. package/dist/subagent/engineCompactWire.js +13 -38
  221. package/dist/subagent/engineDelegatedPrompt.js +10 -6
  222. package/dist/subagent/engineSubagentOutput.d.ts +0 -1
  223. package/dist/subagent/engineSubagentOutput.js +5 -20
  224. package/dist/subagent/engineSubagentTail.d.ts +0 -1
  225. package/dist/subagent/engineSubagentTail.js +7 -32
  226. package/dist/subagentContentStore.js +3 -3
  227. package/dist/supportFloor.js +2 -5
  228. package/dist/terminalStatuses.d.ts +30 -0
  229. package/dist/terminalStatuses.js +67 -0
  230. package/dist/toolResult.d.ts +5 -0
  231. package/dist/toolResult.js +88 -36
  232. package/dist/types/engineState.d.ts +2 -1
  233. package/dist/usageAnalytics.d.ts +146 -0
  234. package/dist/usageAnalytics.js +311 -0
  235. package/dist/userInvokedSkillsCapability.d.ts +0 -1
  236. package/dist/userInvokedSkillsCapability.js +2 -6
  237. package/dist/webSearchBackendCapability.d.ts +0 -1
  238. package/dist/webSearchBackendCapability.js +3 -7
  239. package/dist/webSearchWireCaps.js +3 -11
  240. package/dist/wireFailureShape.d.ts +4 -0
  241. package/dist/wireFailureShape.js +42 -2
  242. package/dist/wireRefusalCopy.js +2 -18
  243. package/dist/workflowClient.js +7 -11
  244. package/dist/workflowsJournalCapability.d.ts +0 -1
  245. package/dist/workflowsJournalCapability.js +2 -6
  246. package/dist/writeProtectionCapability.d.ts +0 -1
  247. package/dist/writeProtectionCapability.js +5 -10
  248. package/docs/INTEGRATION-CLIENTS.md +1033 -26
  249. package/package.json +5 -5
  250. package/dist/engineCapsGenerationGuard.d.ts +0 -4
  251. package/dist/engineCapsGenerationGuard.js +0 -19
  252. package/dist/panelRunningHistory.d.ts +0 -22
  253. package/dist/panelRunningHistory.js +0 -82
  254. package/dist/registryConflict.d.ts +0 -3
  255. 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 { ownDataField, ownDataRefusalKeyOf, ownSendableField } 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
@@ -13,6 +16,63 @@ const isObject = (v) => typeof v === "object" && v !== null;
13
16
  const isAbsent = (v) => typeof v === "undefined";
14
17
  const optionalString = (v) => isAbsent(v) || typeof v === "string";
15
18
  const inTuple = (tuple, v) => tuple.includes(v);
19
+ const own = (o, k) => ownSendableField(o, k);
20
+ const ownItems = (a) => {
21
+ const n = ownDataField(a, "length");
22
+ const out = [];
23
+ if (typeof n !== "number")
24
+ return out;
25
+ for (let i = 0; i < n; i += 1)
26
+ out.push(own(a, String(i)));
27
+ return out;
28
+ };
29
+ const firstAccessorPath = (root) => {
30
+ const seen = new Set();
31
+ const stack = [[root, ""]];
32
+ while (stack.length > 0) {
33
+ const [v, path] = stack.pop();
34
+ if (typeof v !== "object" || v === null || seen.has(v))
35
+ continue;
36
+ seen.add(v);
37
+ for (const k of Reflect.ownKeys(v)) {
38
+ if (typeof k !== "string")
39
+ continue;
40
+ const d = Reflect.getOwnPropertyDescriptor(v, k);
41
+ if (d === undefined)
42
+ continue;
43
+ const at = path === "" ? k : `${path}.${k}`;
44
+ if (!Object.hasOwn(d, "value"))
45
+ return at;
46
+ stack.push([d.value, at]);
47
+ }
48
+ }
49
+ return undefined;
50
+ };
51
+ const NOT_PLAIN_DATA = "must be a plain enumerable data property (accessors are refused and never executed)";
52
+ const seatCheck = (fn) => (v) => {
53
+ try {
54
+ const at = firstAccessorPath(v);
55
+ if (at !== undefined)
56
+ return bad(NOT_PLAIN_DATA, at);
57
+ return fn(v);
58
+ }
59
+ catch (e) {
60
+ const key = ownDataRefusalKeyOf(e);
61
+ return key !== undefined ? bad(NOT_PLAIN_DATA, key) : bad("payload could not be read");
62
+ }
63
+ };
64
+ const seatCheckAt = (fn) => (v, field) => {
65
+ try {
66
+ const at = firstAccessorPath(v);
67
+ if (at !== undefined)
68
+ return bad(NOT_PLAIN_DATA, `${field}.${at}`);
69
+ return fn(v, field);
70
+ }
71
+ catch (e) {
72
+ const key = ownDataRefusalKeyOf(e);
73
+ return key !== undefined ? bad(NOT_PLAIN_DATA, `${field}.${key}`) : bad("payload could not be read", field);
74
+ }
75
+ };
16
76
  export const TOOL_PERMISSION_REQUEST_ID_DOMAINS = Object.freeze([
17
77
  "live:",
18
78
  "durable:",
@@ -72,7 +132,7 @@ export const HITL_RESOLUTION_OUTCOMES = [
72
132
  "decline",
73
133
  "cancel",
74
134
  ];
75
- export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder"]);
135
+ export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind"]);
76
136
  const notReported = () => Object.freeze({ kind: "not_reported" });
77
137
  const malformedReading = () => Object.freeze({ kind: "malformed" });
78
138
  const reported = (available) => Object.freeze({ kind: "reported", available });
@@ -145,6 +205,7 @@ export function watchSeatCapability(store, name, onReading) {
145
205
  }
146
206
  const SEAT_CAPABILITY_PHRASES = Object.freeze({
147
207
  pickFolder: Object.freeze({ action: "Opening a folder", ability: "show a folder picker", support: "folder picker support" }),
208
+ rewind: Object.freeze({ action: "Rewinding to an earlier message", ability: "rewind this session", support: "rewind support" }),
148
209
  });
149
210
  export function seatCapabilityUnavailableDetail(name, reading) {
150
211
  const phrase = Object.hasOwn(SEAT_CAPABILITY_PHRASES, name)
@@ -171,351 +232,484 @@ export const PERMISSION_MODE_INTENTS = [...PERMISSION_MODE_WORDS];
171
232
  export const ATTACHMENT_IDS_PER_TASK_CAP = 16;
172
233
  export const SEAT_REASONING_EFFORTS = [...REASONING_EFFORT_WORDS];
173
234
  export const SEAT_TURN_SETTINGS_KEYS = ["ultracode"];
235
+ export const SEAT_TURN_SETTINGS_ORIGINS = Object.freeze({
236
+ ultracode: Object.freeze({ carriedBy: "renderer" }),
237
+ webSearch: Object.freeze({ hostSupplied: "联网检索的每请求配置来自宿主的设置源(可能带检索服务的凭据与私网地址);渲染端没有设置文件,也不该持有凭据" }),
238
+ hooks: Object.freeze({ hostSupplied: "hooks 表来自宿主的设置文件(宿主经设置端口与 hooksForWire 投影);渲染端没有设置文件、也不执行本机 hook" }),
239
+ resolved: Object.freeze({ hostSupplied: "设置解析器的生效快照(hooks / env / model / 已解析权限)由宿主跑解析器得出;渲染端没有设置源可解析" }),
240
+ outputStyle: Object.freeze({ hostSupplied: "输出风格正文由宿主的兜底层随请求带(风格文件在宿主);渲染端只选名字,不持正文" }),
241
+ });
242
+ export const SEAT_REWIND_INTENT_KEYS = ["mode", "targetMessageUuid"];
174
243
  export const ATTACHMENT_UPLOAD_REQUEST_KEYS = ["name", "mimeType", "bytes"];
175
244
  export const SESSION_SEARCH_RESULT_KEYS = ["sessionId", "title", "matches"];
176
245
  export const GET_TRANSCRIPT_RESULT_KEYS = ["sessionId", "messages"];
177
- const checkLocalSessionRecord = (s) => {
246
+ const checkLocalSessionRecord = seatCheck((s) => {
178
247
  if (!isObject(s))
179
248
  return bad("session record is not an object");
180
- if (typeof s.sessionId !== "string")
249
+ if (typeof own(s, "sessionId") !== "string")
181
250
  return bad("sessionId must be a string", "sessionId");
182
- if (!optionalString(s.engineSessionId))
251
+ if (!optionalString(own(s, "engineSessionId")))
183
252
  return bad("engineSessionId must be a string when present", "engineSessionId");
184
- if (!optionalString(s.model))
253
+ if (!optionalString(own(s, "model")))
185
254
  return bad("model must be a string when present", "model");
186
- if (!optionalString(s.title))
255
+ if (!optionalString(own(s, "title")))
187
256
  return bad("title must be a string when present", "title");
188
- if (!isAbsent(s.cwd) && (typeof s.cwd !== "string" || s.cwd.length === 0)) {
257
+ const cwd = own(s, "cwd");
258
+ if (!isAbsent(cwd) && (typeof cwd !== "string" || cwd.length === 0)) {
189
259
  return bad("cwd must be a non-empty path string when present (absent = no folder chosen)", "cwd");
190
260
  }
191
- if (typeof s.isRunning !== "boolean")
261
+ if (typeof own(s, "isRunning") !== "boolean")
192
262
  return bad("isRunning must be a boolean", "isRunning");
193
- if (typeof s.createdAt !== "string")
263
+ if (typeof own(s, "createdAt") !== "string")
194
264
  return bad("createdAt must be an ISO-8601 string", "createdAt");
195
- if (!optionalString(s.lastActivityAt))
265
+ if (!optionalString(own(s, "lastActivityAt")))
196
266
  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");
267
+ const q = own(s, "queuedMessages");
268
+ if (!isAbsent(q)) {
269
+ const okQueue = Array.isArray(q) && ownItems(q).every((row) => isObject(row) && typeof own(row, "uuid") === "string" && typeof own(row, "text") === "string");
200
270
  if (!okQueue)
201
271
  return bad("queuedMessages must be an array of {uuid,text}", "queuedMessages");
202
272
  }
203
- if (!isAbsent(s.parked) && typeof s.parked !== "boolean") {
273
+ const parked = own(s, "parked");
274
+ if (!isAbsent(parked) && typeof parked !== "boolean") {
204
275
  return bad("parked must be a boolean when present", "parked");
205
276
  }
206
277
  return true;
207
- };
278
+ });
208
279
  export function isLocalSessionRecord(s) {
209
280
  return checkLocalSessionRecord(s) === true;
210
281
  }
211
- const checkToctouBinding = (v) => {
282
+ const checkToctouBinding = seatCheck((v) => {
212
283
  if (!isObject(v))
213
284
  return bad("toctouBinding must be an object", "toctouBinding");
214
- if (typeof v.callId !== "string")
285
+ if (typeof own(v, "callId") !== "string")
215
286
  return bad("toctouBinding.callId must be a string", "toctouBinding.callId");
216
- if (typeof v.inputHash !== "string")
287
+ if (typeof own(v, "inputHash") !== "string")
217
288
  return bad("toctouBinding.inputHash must be a string", "toctouBinding.inputHash");
218
289
  return true;
219
- };
220
- const checkToolPermissionRequest = (r) => {
290
+ });
291
+ const checkToolPermissionRequest = seatCheck((r) => {
221
292
  if (!isObject(r))
222
293
  return bad("tool permission request is not an object");
223
- if (typeof r.requestId !== "string")
294
+ const requestId = own(r, "requestId");
295
+ if (typeof requestId !== "string")
224
296
  return bad("requestId must be a string", "requestId");
225
- if (toolPermissionRequestIdDomain(r.requestId) === undefined) {
297
+ if (toolPermissionRequestIdDomain(requestId) === undefined) {
226
298
  return bad(`requestId must carry a registered domain prefix (${TOOL_PERMISSION_REQUEST_ID_DOMAINS.join("|")})`, "requestId");
227
299
  }
228
- if (typeof r.sessionId !== "string")
300
+ if (typeof own(r, "sessionId") !== "string")
229
301
  return bad("sessionId must be a string", "sessionId");
230
- if (!isAbsent(r.toolName) && r.toolName !== null && typeof r.toolName !== "string") {
302
+ const toolName = own(r, "toolName");
303
+ if (!isAbsent(toolName) && toolName !== null && typeof toolName !== "string") {
231
304
  return bad("toolName must be a string or null when present", "toolName");
232
305
  }
233
- if (!isAbsent(r.toolCallId) && r.toolCallId !== null && typeof r.toolCallId !== "string") {
306
+ const toolCallId = own(r, "toolCallId");
307
+ if (!isAbsent(toolCallId) && toolCallId !== null && typeof toolCallId !== "string") {
234
308
  return bad("toolCallId must be a string or null when present", "toolCallId");
235
309
  }
236
- if (!optionalString(r.message))
310
+ if (!optionalString(own(r, "message")))
237
311
  return bad("message must be a string when present", "message");
238
- if (!isAbsent(r.toctouBinding)) {
239
- const verdict = checkToctouBinding(r.toctouBinding);
312
+ const toctouBinding = own(r, "toctouBinding");
313
+ if (!isAbsent(toctouBinding)) {
314
+ const verdict = checkToctouBinding(toctouBinding);
240
315
  if (verdict !== true)
241
316
  return verdict;
242
317
  }
243
- if (!isAbsent(r.createdAtMs) && typeof r.createdAtMs !== "number") {
318
+ const createdAtMs = own(r, "createdAtMs");
319
+ if (!isAbsent(createdAtMs) && typeof createdAtMs !== "number") {
244
320
  return bad("createdAtMs must be a number (epoch ms) when present", "createdAtMs");
245
321
  }
246
322
  return true;
247
- };
323
+ });
248
324
  export function isToolPermissionRequest(r) {
249
325
  return checkToolPermissionRequest(r) === true;
250
326
  }
251
- const checkLaneProof = (v, field) => {
327
+ const checkLaneProof = seatCheckAt((v, field) => {
252
328
  if (!isObject(v))
253
329
  return bad("laneProof must be an object", field);
254
- const lane = v.lane;
330
+ const lane = own(v, "lane");
255
331
  if (typeof lane !== "string" || !inTuple(LANE_PROOF_LANE_TUPLE, lane)) {
256
332
  return bad(`laneProof.lane must be one of ${LANE_PROOF_LANE_TUPLE.join("|")}`, `${field}.lane`);
257
333
  }
258
- if (lane === "subagent" && typeof v.parentToolCallId !== "string") {
334
+ if (lane === "subagent" && typeof own(v, "parentToolCallId") !== "string") {
259
335
  return bad("subagent laneProof needs parentToolCallId", `${field}.parentToolCallId`);
260
336
  }
261
- if (lane === "workflow" && (typeof v.via !== "string" || typeof v.key !== "string")) {
337
+ if (lane === "workflow" && (typeof own(v, "via") !== "string" || typeof own(v, "key") !== "string")) {
262
338
  return bad("workflow laneProof needs via + key", `${field}.via`);
263
339
  }
264
340
  return true;
265
- };
266
- const checkSeatChromeEnvelope = (v, field) => {
341
+ });
342
+ const checkSeatChromeEnvelope = seatCheckAt((v, field) => {
267
343
  if (!isObject(v))
268
344
  return bad("chrome must be an object", field);
269
- const kind = v.kind;
345
+ const kind = own(v, "kind");
270
346
  if (typeof kind !== "string")
271
347
  return bad("chrome.kind must be a string", `${field}.kind`);
272
348
  if (!inTuple(CHROME_EVENT_KIND_TUPLE, kind)) {
273
349
  return bad(`chrome.kind is not a renderer-wired arm (${CHROME_EVENT_KIND_TUPLE.join("|")})`, `${field}.kind`);
274
350
  }
275
- return checkLaneProof(v.laneProof, `${field}.laneProof`);
276
- };
277
- const checkLocalSessionEvent = (v) => {
351
+ return checkLaneProof(own(v, "laneProof"), `${field}.laneProof`);
352
+ });
353
+ const checkLocalSessionEvent = seatCheck((v) => {
278
354
  if (!isObject(v))
279
355
  return bad("event is not an object");
280
- const type = v.type;
356
+ const type = own(v, "type");
281
357
  if (typeof type !== "string")
282
358
  return bad("type must be a string", "type");
283
359
  if (!inTuple(SEAT_EVENT_TYPE_TUPLE, type)) {
284
360
  return bad(`type is not a registered seat event name (${SEAT_EVENT_TYPE_TUPLE.join("|")})`, "type");
285
361
  }
286
- if (typeof v.sessionId !== "string")
362
+ if (typeof own(v, "sessionId") !== "string")
287
363
  return bad("sessionId must be a string", "sessionId");
288
- if (!isAbsent(v.messages) && !Array.isArray(v.messages))
364
+ const messages = own(v, "messages");
365
+ if (!isAbsent(messages) && !Array.isArray(messages))
289
366
  return bad("messages must be an array", "messages");
290
- if (!optionalString(v.error))
367
+ if (!optionalString(own(v, "error")))
291
368
  return bad("error must be a string when present", "error");
292
- if (!optionalString(v.errorCategory))
369
+ if (!optionalString(own(v, "errorCategory")))
293
370
  return bad("errorCategory must be a string when present", "errorCategory");
294
- if (!isAbsent(v.code) && typeof v.code !== "number")
371
+ const code = own(v, "code");
372
+ if (!isAbsent(code) && typeof code !== "number")
295
373
  return bad("code must be a number when present", "code");
296
- if (!isAbsent(v.request)) {
297
- const verdict = checkToolPermissionRequest(v.request);
374
+ const request = own(v, "request");
375
+ if (!isAbsent(request)) {
376
+ const verdict = checkToolPermissionRequest(request);
298
377
  if (verdict !== true)
299
378
  return nested("request", verdict);
300
379
  }
301
- if (!optionalString(v.data))
380
+ if (!optionalString(own(v, "data")))
302
381
  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");
382
+ const sources = own(v, "sources");
383
+ if (!isAbsent(sources)) {
384
+ const okSources = Array.isArray(sources) && ownItems(sources).every((t) => typeof t === "string");
305
385
  if (!okSources)
306
386
  return bad("sources must be a string[]", "sources");
307
387
  }
308
- if (!isAbsent(v.permissionMode)) {
309
- const mode = v.permissionMode;
388
+ const mode = own(v, "permissionMode");
389
+ if (!isAbsent(mode)) {
310
390
  if (typeof mode !== "string" || !inTuple(PERMISSION_MODE_INTENTS, mode)) {
311
391
  return bad(`permissionMode must be one of ${PERMISSION_MODE_INTENTS.join("|")}`, "permissionMode");
312
392
  }
313
393
  }
314
- if (!isAbsent(v.session)) {
315
- const verdict = checkLocalSessionRecord(v.session);
394
+ const session = own(v, "session");
395
+ if (!isAbsent(session)) {
396
+ const verdict = checkLocalSessionRecord(session);
316
397
  if (verdict !== true)
317
398
  return nested("session", verdict);
318
399
  }
319
- if (!optionalString(v.userMessageUuid))
400
+ if (!optionalString(own(v, "userMessageUuid")))
320
401
  return bad("userMessageUuid must be a string when present", "userMessageUuid");
321
- if (!isAbsent(v.hasPreClearSession) && typeof v.hasPreClearSession !== "boolean") {
402
+ const hasPreClearSession = own(v, "hasPreClearSession");
403
+ if (!isAbsent(hasPreClearSession) && typeof hasPreClearSession !== "boolean") {
322
404
  return bad("hasPreClearSession must be a boolean when present", "hasPreClearSession");
323
405
  }
324
- if (!optionalString(v.requestId))
406
+ if (!optionalString(own(v, "requestId")))
325
407
  return bad("requestId must be a string when present", "requestId");
326
- if (!optionalString(v.outcome))
408
+ const outcome = own(v, "outcome");
409
+ if (!optionalString(outcome))
327
410
  return bad("outcome must be a string when present", "outcome");
328
- if (!isAbsent(v.chrome)) {
329
- const verdict = checkSeatChromeEnvelope(v.chrome, "chrome");
411
+ const parked = own(v, "parked");
412
+ if (!isAbsent(parked)) {
413
+ if (parked !== true)
414
+ return bad("parked must be the literal true when present (absent = no park evidence)", "parked");
415
+ if (type !== "tool_permission_resolved" || outcome !== "expired") {
416
+ return bad('parked is only allowed on a tool_permission_resolved event whose outcome is "expired"', "parked");
417
+ }
418
+ }
419
+ const chrome = own(v, "chrome");
420
+ if (!isAbsent(chrome)) {
421
+ const verdict = checkSeatChromeEnvelope(chrome, "chrome");
330
422
  if (verdict !== true)
331
423
  return nested("chrome", verdict);
332
424
  }
333
425
  return true;
334
- };
426
+ });
335
427
  export function isLocalSessionEvent(v) {
336
428
  return checkLocalSessionEvent(v) === true;
337
429
  }
338
- const checkAttachmentUploadReceipt = (v) => {
430
+ const checkAttachmentUploadReceipt = seatCheck((v) => {
339
431
  if (!isObject(v))
340
432
  return bad("upload receipt is not an object");
341
- if (typeof v.id !== "string")
433
+ if (typeof own(v, "id") !== "string")
342
434
  return bad("id must be a string", "id");
343
- if (typeof v.name !== "string")
435
+ if (typeof own(v, "name") !== "string")
344
436
  return bad("name must be a string", "name");
345
- if (typeof v.mime !== "string")
437
+ if (typeof own(v, "mime") !== "string")
346
438
  return bad("mime must be a string", "mime");
347
- if (typeof v.sha256 !== "string")
439
+ if (typeof own(v, "sha256") !== "string")
348
440
  return bad("sha256 must be a string", "sha256");
349
- if (typeof v.sizeBytes !== "number")
441
+ if (typeof own(v, "sizeBytes") !== "number")
350
442
  return bad("sizeBytes must be a number", "sizeBytes");
351
443
  return true;
352
- };
444
+ });
353
445
  export function isAttachmentUploadReceipt(v) {
354
446
  return checkAttachmentUploadReceipt(v) === true;
355
447
  }
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) => {
448
+ const checkApplyModelConfigResult = seatCheck((v) => {
374
449
  if (!isObject(v))
375
450
  return bad("applyModelConfig result is not an object");
376
- if (typeof v.ok !== "boolean")
451
+ const ok = own(v, "ok");
452
+ if (typeof ok !== "boolean")
377
453
  return bad("ok must be a boolean", "ok");
378
- if (typeof v.requiresRestart !== "boolean")
454
+ if (typeof own(v, "requiresRestart") !== "boolean")
379
455
  return bad("requiresRestart must be a boolean", "requiresRestart");
380
- if (v.ok === false && (typeof v.reason !== "string" || v.reason.length === 0)) {
456
+ const reason = own(v, "reason");
457
+ if (ok === false && (typeof reason !== "string" || reason.length === 0)) {
381
458
  return bad("reason must be a non-empty string when ok is false", "reason");
382
459
  }
383
- if (v.reason !== undefined && typeof v.reason !== "string")
460
+ if (reason !== undefined && typeof reason !== "string")
384
461
  return bad("reason must be a string when present", "reason");
385
462
  return true;
386
- };
387
- const checkSeatModelCatalog = (v) => {
388
- if (!isObject(v))
463
+ });
464
+ const checkLiveModelCatalog = seatCheck((v) => {
465
+ if (!isObject(v) || Array.isArray(v))
389
466
  return bad("model catalog is not an object");
390
- const models = v.models;
467
+ const models = own(v, "models");
391
468
  if (!Array.isArray(models))
392
469
  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;
470
+ const rows = ownItems(models);
471
+ const names = new Set();
472
+ for (let i = 0; i < rows.length; i += 1) {
473
+ const row = liveModelRowCopy(rows[i]);
474
+ if (row === undefined)
475
+ return bad(`models[${i}] is not a catalog row (an object whose name is a non-empty string, JSON values only)`, `models[${i}]`);
476
+ if (names.has(row.name))
477
+ return bad(`models[${i}] repeats the name of an earlier row`, `models[${i}].name`);
478
+ names.add(row.name);
479
+ }
480
+ const dflt = own(v, "default");
481
+ if (typeof dflt !== "string" || dflt.length === 0)
482
+ return bad("default must be a non-empty string", "default");
483
+ const defaultModel = own(v, "defaultModel");
484
+ if (!isAbsent(defaultModel) && liveDefaultModelCopy(defaultModel) === undefined) {
485
+ return bad("defaultModel must be {id: non-empty string, name?: non-empty string} when present", "defaultModel");
397
486
  }
398
- if (!optionalString(v.defaultId))
399
- return bad("defaultId must be a string when present", "defaultId");
400
487
  return true;
401
- };
402
- export function isSeatModelCatalog(v) {
403
- return checkSeatModelCatalog(v) === true;
488
+ });
489
+ const checkSeatRewindIntent = seatCheck((v) => {
490
+ if (!isObject(v) || Array.isArray(v))
491
+ return bad("rewind must be an object {mode, targetMessageUuid}");
492
+ for (const k of Object.keys(v)) {
493
+ if (!inTuple(SEAT_REWIND_INTENT_KEYS, k))
494
+ return bad(`unknown key (closed shape: ${SEAT_REWIND_INTENT_KEYS.join(", ")})`, k);
495
+ }
496
+ const mode = own(v, "mode");
497
+ if (typeof mode !== "string" || !inTuple(REWIND_MODES, mode))
498
+ return bad(`mode must be one of ${REWIND_MODES.join("|")}`, "mode");
499
+ const target = own(v, "targetMessageUuid");
500
+ if (typeof target !== "string" || target.length === 0) {
501
+ return bad("targetMessageUuid must be a non-empty string", "targetMessageUuid");
502
+ }
503
+ return true;
504
+ });
505
+ const checkSeatTurnSettings = seatCheck((v) => {
506
+ if (!isObject(v) || Array.isArray(v))
507
+ return bad("settings must be an object");
508
+ for (const k of Object.keys(v)) {
509
+ if (!inTuple(SEAT_TURN_SETTINGS_KEYS, k)) {
510
+ const host = Object.hasOwn(SEAT_TURN_SETTINGS_ORIGINS, k);
511
+ 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);
512
+ }
513
+ }
514
+ const ultracode = own(v, "ultracode");
515
+ if (!isAbsent(ultracode) && typeof ultracode !== "boolean")
516
+ return bad("ultracode must be a boolean when present", "ultracode");
517
+ return true;
518
+ });
519
+ const checkRetainSubagentSessions = seatCheck((v) => {
520
+ if (typeof v === "boolean")
521
+ return true;
522
+ if (!isObject(v) || Array.isArray(v))
523
+ return bad("retainSubagentSessions must be a boolean or {ttlMs?, max?}");
524
+ for (const k of Object.keys(v)) {
525
+ if (k !== "ttlMs" && k !== "max")
526
+ return bad("unknown key (closed shape: ttlMs, max)", k);
527
+ const n = own(v, k);
528
+ if (!isAbsent(n) && (typeof n !== "number" || !Number.isSafeInteger(n) || n < 0))
529
+ return bad(`${k} must be a non-negative integer when present`, k);
530
+ }
531
+ return true;
532
+ });
533
+ export function checkSendMessageRequest(v) {
534
+ try {
535
+ if (!isObject(v) || Array.isArray(v))
536
+ return bad("sendMessage request is not an object");
537
+ const at = firstAccessorPath(v);
538
+ if (at !== undefined)
539
+ return bad(NOT_PLAIN_DATA, at);
540
+ const body = {};
541
+ for (const k of Object.keys(v)) {
542
+ if (!inTuple(SEND_MESSAGE_REQUEST_KEYS, k))
543
+ return bad(`unknown key (closed shape: ${SEND_MESSAGE_REQUEST_KEYS.join(", ")})`, k);
544
+ body[k] = own(v, k);
545
+ }
546
+ if (typeof body.sessionId !== "string" || body.sessionId.length === 0)
547
+ return bad("sessionId must be a non-empty string", "sessionId");
548
+ if (typeof body.text !== "string")
549
+ return bad("text must be a string", "text");
550
+ if (!optionalString(body.model))
551
+ return bad("model must be a string when present", "model");
552
+ if (!optionalString(body.userMessageUuid))
553
+ return bad("userMessageUuid must be a string when present", "userMessageUuid");
554
+ if (!isAbsent(body.permissionMode) && (typeof body.permissionMode !== "string" || !inTuple(PERMISSION_MODE_INTENTS, body.permissionMode))) {
555
+ return bad(`permissionMode must be one of ${PERMISSION_MODE_INTENTS.join("|")}`, "permissionMode");
556
+ }
557
+ if (!isAbsent(body.attachmentIds)) {
558
+ const raw = body.attachmentIds;
559
+ const ids = Array.isArray(raw) ? ownItems(raw) : undefined;
560
+ if (ids === undefined || !ids.every((id) => typeof id === "string" && id.length > 0)) {
561
+ return bad("attachmentIds must be an array of non-empty attachment ids", "attachmentIds");
562
+ }
563
+ if (ids.length > ATTACHMENT_IDS_PER_TASK_CAP)
564
+ return bad(`attachmentIds exceeds the per-task limit (${ATTACHMENT_IDS_PER_TASK_CAP})`, "attachmentIds");
565
+ }
566
+ if (!isAbsent(body.reasoningEffort) && (typeof body.reasoningEffort !== "string" || !inTuple(SEAT_REASONING_EFFORTS, body.reasoningEffort))) {
567
+ return bad(`reasoningEffort must be one of ${SEAT_REASONING_EFFORTS.join("|")}`, "reasoningEffort");
568
+ }
569
+ for (const k of ["retainBackgroundProcesses", "forwardSubagentEvents"]) {
570
+ if (!isAbsent(body[k]) && typeof body[k] !== "boolean")
571
+ return bad(`${k} must be a boolean when present`, k);
572
+ }
573
+ if (!isAbsent(body.retainSubagentSessions)) {
574
+ const verdict = checkRetainSubagentSessions(body.retainSubagentSessions);
575
+ if (verdict !== true)
576
+ return nested("retainSubagentSessions", verdict);
577
+ }
578
+ if (!isAbsent(body.settings)) {
579
+ const verdict = checkSeatTurnSettings(body.settings);
580
+ if (verdict !== true)
581
+ return nested("settings", verdict);
582
+ }
583
+ if (!optionalString(body.scenario))
584
+ return bad("scenario must be a string when present", "scenario");
585
+ if (!isAbsent(body.rewind)) {
586
+ const verdict = checkSeatRewindIntent(body.rewind);
587
+ if (verdict !== true)
588
+ return nested("rewind", verdict);
589
+ }
590
+ return true;
591
+ }
592
+ catch (e) {
593
+ const key = ownDataRefusalKeyOf(e);
594
+ return key !== undefined ? bad(NOT_PLAIN_DATA, key) : bad("sendMessage request could not be read");
595
+ }
596
+ }
597
+ export function isSendMessageRequest(v) {
598
+ return checkSendMessageRequest(v) === true;
404
599
  }
405
- const checkSendMessageAck = (v) => {
600
+ const checkSendMessageAck = seatCheck((v) => {
406
601
  if (!isObject(v))
407
602
  return bad("sendMessage ack is not an object");
408
- if (typeof v.sessionId !== "string")
603
+ if (typeof own(v, "sessionId") !== "string")
409
604
  return bad("sessionId must be a string", "sessionId");
410
- if (typeof v.userMessageUuid !== "string")
605
+ if (typeof own(v, "userMessageUuid") !== "string")
411
606
  return bad("userMessageUuid must be a string", "userMessageUuid");
412
- if (!isAbsent(v.queued) && typeof v.queued !== "boolean")
607
+ const queued = own(v, "queued");
608
+ if (!isAbsent(queued) && typeof queued !== "boolean")
413
609
  return bad("queued must be a boolean when present", "queued");
414
610
  return true;
415
- };
611
+ });
416
612
  export function isSendMessageAck(v) {
417
613
  return checkSendMessageAck(v) === true;
418
614
  }
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");
615
+ const checkInterruptAck = seatCheck((v) => isObject(v) && typeof own(v, "interrupted") === "boolean" ? true : bad("interrupt ack needs boolean `interrupted`", "interrupted"));
616
+ const checkStopAck = seatCheck((v) => isObject(v) && typeof own(v, "stopped") === "boolean" ? true : bad("stop ack needs boolean `stopped`", "stopped"));
617
+ const checkOkAck = seatCheck((v) => isObject(v) && typeof own(v, "ok") === "boolean" ? true : bad("ack needs boolean `ok`", "ok"));
422
618
  const checkBooleanAck = (v) => typeof v === "boolean" ? true : bad("expected a bare boolean result");
423
- const checkGetTranscriptResult = (v) => {
619
+ const checkGetTranscriptResult = seatCheck((v) => {
424
620
  if (!isObject(v))
425
621
  return bad("transcript envelope is not an object");
426
- if (typeof v.sessionId !== "string")
622
+ if (typeof own(v, "sessionId") !== "string")
427
623
  return bad("sessionId must be a string", "sessionId");
428
- if (!Array.isArray(v.messages))
624
+ if (!Array.isArray(own(v, "messages")))
429
625
  return bad("messages must be an array", "messages");
430
626
  return true;
431
- };
432
- const checkSessionSearchResult = (v) => {
627
+ });
628
+ const checkSessionSearchResult = seatCheck((v) => {
433
629
  if (!isObject(v))
434
630
  return bad("search result row is not an object");
435
- if (typeof v.sessionId !== "string")
631
+ if (typeof own(v, "sessionId") !== "string")
436
632
  return bad("sessionId must be a string", "sessionId");
437
- if (!optionalString(v.title))
633
+ if (!optionalString(own(v, "title")))
438
634
  return bad("title must be a string when present", "title");
439
- if (!Array.isArray(v.matches))
635
+ const matches = own(v, "matches");
636
+ if (!Array.isArray(matches))
440
637
  return bad("matches must be an array", "matches");
441
- const okMatches = v.matches.every((m) => isObject(m) && typeof m.snippet === "string");
638
+ const okMatches = ownItems(matches).every((m) => isObject(m) && typeof own(m, "snippet") === "string");
442
639
  if (!okMatches)
443
640
  return bad("matches must be {snippet:string}[]", "matches");
444
641
  return true;
445
- };
446
- const checkSessionSearchEnvelope = (v) => {
642
+ });
643
+ const checkSessionSearchEnvelope = seatCheck((v) => {
447
644
  if (!isObject(v))
448
645
  return bad("search envelope is not an object");
449
- const results = v.results;
646
+ const results = own(v, "results");
450
647
  if (!Array.isArray(results))
451
648
  return bad("results must be an array", "results");
452
- for (let i = 0; i < results.length; i += 1) {
453
- const verdict = checkSessionSearchResult(results[i]);
649
+ const rows = ownItems(results);
650
+ for (let i = 0; i < rows.length; i += 1) {
651
+ const verdict = checkSessionSearchResult(rows[i]);
454
652
  if (verdict !== true)
455
653
  return nested(`results[${i}]`, verdict);
456
654
  }
457
655
  return true;
458
- };
459
- const checkSessionsState = (v) => {
656
+ });
657
+ const checkSessionsState = seatCheck((v) => {
460
658
  if (!isObject(v))
461
659
  return bad("sessions state is not an object");
462
- const sessions = v.sessions;
660
+ const sessions = own(v, "sessions");
463
661
  if (!Array.isArray(sessions))
464
662
  return bad("sessions must be an array", "sessions");
465
- for (let i = 0; i < sessions.length; i += 1) {
466
- const verdict = checkLocalSessionRecord(sessions[i]);
663
+ const rows = ownItems(sessions);
664
+ for (let i = 0; i < rows.length; i += 1) {
665
+ const verdict = checkLocalSessionRecord(rows[i]);
467
666
  if (verdict !== true)
468
667
  return nested(`sessions[${i}]`, verdict);
469
668
  }
470
669
  return true;
471
- };
472
- const checkFocusedSessionState = (v) => {
670
+ });
671
+ const checkFocusedSessionState = seatCheck((v) => {
473
672
  if (!isObject(v))
474
673
  return bad("focused session state is not an object");
475
- if (v.sessionId !== null && typeof v.sessionId !== "string") {
674
+ const sessionId = own(v, "sessionId");
675
+ if (sessionId !== null && typeof sessionId !== "string") {
476
676
  return bad("sessionId must be a string or null", "sessionId");
477
677
  }
478
678
  return true;
479
- };
480
- const checkSettingsState = (v) => {
679
+ });
680
+ const checkSettingsState = seatCheck((v) => {
481
681
  if (!isObject(v))
482
682
  return bad("settings state is not an object");
483
- if (v.defaultModel !== null && typeof v.defaultModel !== "string") {
683
+ const defaultModel = own(v, "defaultModel");
684
+ if (defaultModel !== null && typeof defaultModel !== "string") {
484
685
  return bad("defaultModel must be a string or null", "defaultModel");
485
686
  }
486
- if (!optionalString(v.engineVersion))
687
+ if (!optionalString(own(v, "engineVersion")))
487
688
  return bad("engineVersion must be a string when present", "engineVersion");
488
- if (!optionalString(v.dataRoot))
689
+ if (!optionalString(own(v, "dataRoot")))
489
690
  return bad("dataRoot must be a string when present", "dataRoot");
490
691
  return true;
491
- };
692
+ });
492
693
  const checkPickFolderResult = (v) => v === null || (typeof v === "string" && v.length > 0)
493
694
  ? true
494
695
  : 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);
696
+ const checkSeatCapabilitiesState = seatCheck((v) => {
697
+ if (!isObject(v) || Array.isArray(v))
698
+ return bad("seat capabilities state is not an object");
699
+ const proto = Object.getPrototypeOf(v);
700
+ if (proto !== Object.prototype && proto !== null)
701
+ return bad("seat capabilities state is not a plain object");
702
+ for (const k of Reflect.ownKeys(v)) {
703
+ const name = typeof k === "string" ? k : String(k);
704
+ if (typeof k !== "string" || !inTuple(SEAT_CAPABILITY_NAMES, k)) {
705
+ return bad(`${name} is not a registered seat capability (${SEAT_CAPABILITY_NAMES.join("|")})`, name);
512
706
  }
513
- return true;
707
+ const value = own(v, k);
708
+ if (!isAbsent(value) && typeof value !== "boolean")
709
+ return bad(`${k} must be a boolean when present`, k);
514
710
  }
515
- catch {
516
- return bad("seat capabilities state could not be read");
517
- }
518
- };
711
+ return true;
712
+ });
519
713
  export const LOCAL_SESSIONS_SPEC = {
520
714
  ns: "sema.web",
521
715
  service: "LocalSessions",
@@ -533,7 +727,7 @@ export const LOCAL_SESSIONS_SPEC = {
533
727
  getTranscript: { kind: "invoke", check: checkGetTranscriptResult },
534
728
  searchSessions: { kind: "invoke", check: checkSessionSearchEnvelope },
535
729
  uploadAttachment: { kind: "invoke", check: checkAttachmentUploadReceipt },
536
- listModels: { kind: "invoke", check: checkSeatModelCatalog },
730
+ listModels: { kind: "invoke", check: checkLiveModelCatalog },
537
731
  applyModelConfig: { kind: "invoke", check: checkApplyModelConfigResult },
538
732
  pickFolder: { kind: "invoke", check: checkPickFolderResult },
539
733
  onEvent: { kind: "event", check: checkLocalSessionEvent },
@@ -590,6 +784,7 @@ export const LOCAL_SESSION_EVENT_KEYS = [
590
784
  "hasPreClearSession",
591
785
  "requestId",
592
786
  "outcome",
787
+ "parked",
593
788
  "chrome",
594
789
  ];
595
790
  export const TOOL_PERMISSION_REQUEST_KEYS = [
@@ -635,6 +830,7 @@ export const SEND_MESSAGE_REQUEST_KEYS = [
635
830
  "retainSubagentSessions",
636
831
  "settings",
637
832
  "scenario",
833
+ "rewind",
638
834
  ];
639
835
  export const SEAT_SEND_MESSAGE_KEY_ORIGINS = {
640
836
  sessionId: { seatOnly: "座位会话句柄(渲染端持有的本地 id);引擎会话 id 由座位记录的 `engineSessionId` 承载 —— 与引擎请求体上的同名位**同名不同义**,绝不直传" },
@@ -649,6 +845,7 @@ export const SEAT_SEND_MESSAGE_KEY_ORIGINS = {
649
845
  retainSubagentSessions: { taskRequestKey: "retainSubagentSessions" },
650
846
  settings: { taskRequestKey: "settings" },
651
847
  scenario: { taskRequestKey: "scenario" },
848
+ rewind: { projectedBy: "rewindSpecForMode", taskRequestKeys: ["resumeAt", "resumeAtMode", "restoreFiles", "rewindFilesTo"] },
652
849
  };
653
850
  export const TOOL_PERMISSION_DECISION_KEYS = [
654
851
  "sessionId",
@@ -728,6 +925,7 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
728
925
  "hasPreClearSession",
729
926
  "requestId",
730
927
  "outcome",
928
+ "parked",
731
929
  "chrome",
732
930
  ],
733
931
  unchecked: [
@@ -743,10 +941,34 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
743
941
  validated: ["id", "name", "mime", "sha256", "sizeBytes"],
744
942
  unchecked: [],
745
943
  },
746
- SeatModelCatalog: {
747
- guard: "isSeatModelCatalog",
748
- check: checkSeatModelCatalog,
749
- validated: ["models", "defaultId"],
944
+ LiveModelCatalog: {
945
+ check: checkLiveModelCatalog,
946
+ validated: ["models", "default", "defaultModel"],
947
+ unchecked: [
948
+ {
949
+ key: "droppedEntries",
950
+ why: "诊断面(哪些目录条目没被引擎收下),三态读法归 droppedModelEntriesOf(含坏形 malformed);出站门为它拒掉整份目录 = 选单为一行诊断整个消失。",
951
+ },
952
+ ],
953
+ },
954
+ SendMessageRequest: {
955
+ guard: "isSendMessageRequest",
956
+ check: checkSendMessageRequest,
957
+ validated: [
958
+ "sessionId",
959
+ "text",
960
+ "model",
961
+ "userMessageUuid",
962
+ "permissionMode",
963
+ "attachmentIds",
964
+ "reasoningEffort",
965
+ "retainBackgroundProcesses",
966
+ "forwardSubagentEvents",
967
+ "retainSubagentSessions",
968
+ "settings",
969
+ "scenario",
970
+ "rewind",
971
+ ],
750
972
  unchecked: [],
751
973
  },
752
974
  ApplyModelConfigResult: {
@@ -802,12 +1024,12 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
802
1024
  },
803
1025
  SeatCapabilitiesState: {
804
1026
  check: checkSeatCapabilitiesState,
805
- validated: ["pickFolder"],
1027
+ validated: ["pickFolder", "rewind"],
806
1028
  unchecked: [],
807
1029
  },
808
- SeatModelInfo: {
809
- check: (v) => checkSeatModelInfo(v, 0),
810
- validated: ["id", "name", "provider", "contextWindow", "maxOutputTokens"],
1030
+ SeatRewindIntent: {
1031
+ check: checkSeatRewindIntent,
1032
+ validated: ["mode", "targetMessageUuid"],
811
1033
  unchecked: [],
812
1034
  },
813
1035
  SessionSearchResult: {
@@ -864,5 +1086,6 @@ const _seatContractPins = [
864
1086
  true, true, true, true, true, true, true, true,
865
1087
  true, true, true, true, true, true, true, true,
866
1088
  true, true, true, true, true,
1089
+ true, true, true, true, true, true, true, true,
867
1090
  ];
868
1091
  void _seatContractPins;