@sema-agent/client-core 0.98.0 → 0.99.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 (192) hide show
  1. package/CHANGELOG.md +199 -0
  2. package/README.md +35 -22
  3. package/dist/adapt/arms.js +61 -20
  4. package/dist/adapt/panelTasks.d.ts +1 -1
  5. package/dist/adapt/panelTasks.js +2 -2
  6. package/dist/adapter/activeRunSelfHeal.d.ts +4 -3
  7. package/dist/adapter/activeRunSelfHeal.js +162 -293
  8. package/dist/adapter/downstream/eventToSdkMessage.js +52 -4
  9. package/dist/adapter/runStream.js +52 -37
  10. package/dist/adapter/types.js +2 -1
  11. package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
  12. package/dist/agentsWireCaps.d.ts +0 -3
  13. package/dist/agentsWireCaps.js +33 -24
  14. package/dist/cloudConfigWireCaps.d.ts +1 -1
  15. package/dist/cloudConfigWireCaps.js +26 -4
  16. package/dist/controlRouter.d.ts +4 -2
  17. package/dist/controlRouter.js +39 -51
  18. package/dist/coreValuePorts.d.ts +26 -1
  19. package/dist/coreValuePorts.js +10 -0
  20. package/dist/corruptSessionCopy.d.ts +2 -1
  21. package/dist/corruptSessionCopy.js +3 -3
  22. package/dist/declared/supportFloorDeclared.js +1 -1
  23. package/dist/detachWire.js +3 -2
  24. package/dist/devicesFace.d.ts +34 -0
  25. package/dist/devicesFace.js +90 -0
  26. package/dist/displayUntrusted.d.ts +1 -0
  27. package/dist/displayUntrusted.js +3 -0
  28. package/dist/engineAgentPanelStore.d.ts +7 -0
  29. package/dist/engineAgentPanelStore.js +14 -0
  30. package/dist/engineCapReader.d.ts +2 -1
  31. package/dist/engineCapReader.js +7 -5
  32. package/dist/engineCapsCache.d.ts +8 -0
  33. package/dist/engineCapsCache.js +59 -6
  34. package/dist/engineCapsChange.d.ts +2 -0
  35. package/dist/engineCapsChange.js +9 -0
  36. package/dist/engineErrorCodes.d.ts +2 -1
  37. package/dist/engineErrorCodes.js +2 -7
  38. package/dist/engineRowRef.js +3 -0
  39. package/dist/engineSessionMessages.d.ts +1 -0
  40. package/dist/engineSessionMessages.js +7 -1
  41. package/dist/engineTargetSeat.d.ts +27 -0
  42. package/dist/engineTargetSeat.js +199 -0
  43. package/dist/engineWireFor.js +3 -8
  44. package/dist/env/uiLanguage.d.ts +2 -1
  45. package/dist/env/uiLanguage.js +3 -2
  46. package/dist/eventLeg.d.ts +8 -0
  47. package/dist/eventLeg.js +61 -41
  48. package/dist/fileHistoryCaptureCapability.d.ts +2 -1
  49. package/dist/fileHistoryCaptureCapability.js +12 -18
  50. package/dist/fileHistoryLegNotice.d.ts +2 -1
  51. package/dist/fileHistoryLegNotice.js +3 -3
  52. package/dist/frameBinding.d.ts +3 -0
  53. package/dist/frameBinding.js +12 -0
  54. package/dist/gateOutcome.js +16 -2
  55. package/dist/gateVocabulary.d.ts +8 -7
  56. package/dist/gateVocabulary.js +71 -73
  57. package/dist/generated/engineFactTables.d.ts +17 -1
  58. package/dist/generated/engineFactTables.js +29 -0
  59. package/dist/generated/engineNoticeTables.js +9 -3
  60. package/dist/generated/settingsSchemaFns.d.ts +6 -0
  61. package/dist/generated/settingsSchemaFns.js +57 -0
  62. package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
  63. package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
  64. package/dist/generated/settingsSchemaTables.d.ts +1 -0
  65. package/dist/generated/settingsSchemaTables.js +4 -0
  66. package/dist/generated/settingsSchemaTypes.d.ts +105 -0
  67. package/dist/generated/settingsSchemaTypes.js +1 -0
  68. package/dist/hitl/allowRuleShadow.d.ts +2 -1
  69. package/dist/hitl/allowRuleShadow.js +17 -14
  70. package/dist/hitl/approvalCardReasons.d.ts +3 -2
  71. package/dist/hitl/approvalCardReasons.js +27 -28
  72. package/dist/hitl/approvalHolds.d.ts +3 -0
  73. package/dist/hitl/approvalHolds.js +73 -29
  74. package/dist/hitl/askClassPair.d.ts +1 -1
  75. package/dist/hitl/askClassPair.js +16 -0
  76. package/dist/hitl/askGateWire.js +2 -1
  77. package/dist/hitl/askSettlementLine.d.ts +14 -4
  78. package/dist/hitl/askSettlementLine.js +67 -47
  79. package/dist/hitl/automaticAnswerVerdict.d.ts +2 -1
  80. package/dist/hitl/automaticAnswerVerdict.js +8 -8
  81. package/dist/hitl/crashConvergedNotice.d.ts +5 -4
  82. package/dist/hitl/crashConvergedNotice.js +28 -41
  83. package/dist/hitl/frameRouter.js +7 -8
  84. package/dist/hitl/hitlBridge.d.ts +1 -0
  85. package/dist/hitl/hitlBridge.js +3 -3
  86. package/dist/hitl/persistedRulesWire.d.ts +6 -5
  87. package/dist/hitl/persistedRulesWire.js +55 -73
  88. package/dist/hitl/planReviewWire.d.ts +5 -0
  89. package/dist/hitl/planReviewWire.js +8 -0
  90. package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
  91. package/dist/hitl/sessionPolicyDeliverable.js +46 -3
  92. package/dist/hitl/sessionPolicyWire.d.ts +2 -1
  93. package/dist/hitl/sessionPolicyWire.js +23 -24
  94. package/dist/hitl/suspendedReopen.d.ts +2 -1
  95. package/dist/hitl/suspendedReopen.js +7 -10
  96. package/dist/hitl/toolApprovalWire.d.ts +17 -5
  97. package/dist/hitl/toolApprovalWire.js +79 -40
  98. package/dist/hooksWireCaps.js +145 -56
  99. package/dist/host.d.ts +21 -0
  100. package/dist/hostTurnSettings.d.ts +71 -0
  101. package/dist/hostTurnSettings.js +291 -0
  102. package/dist/humanTurn.d.ts +14 -1
  103. package/dist/humanTurn.js +100 -12
  104. package/dist/humanTurnRead.d.ts +2 -0
  105. package/dist/humanTurnRead.js +22 -1
  106. package/dist/i18n/messages.en.d.ts +582 -0
  107. package/dist/i18n/messages.en.js +582 -0
  108. package/dist/i18n/messages.zh.js +718 -1
  109. package/dist/index.d.ts +29 -13
  110. package/dist/index.js +18 -9
  111. package/dist/inheritEnvCapability.d.ts +3 -2
  112. package/dist/inheritEnvCapability.js +3 -3
  113. package/dist/inheritEnvWire.d.ts +3 -2
  114. package/dist/inheritEnvWire.js +12 -14
  115. package/dist/interactiveHalt.js +17 -6
  116. package/dist/liveModelCatalog.d.ts +2 -1
  117. package/dist/liveModelCatalog.js +14 -8
  118. package/dist/mcpPanel.d.ts +10 -1
  119. package/dist/mcpPanel.js +40 -13
  120. package/dist/mcpProbeCapability.d.ts +2 -1
  121. package/dist/mcpProbeCapability.js +7 -11
  122. package/dist/mcpProbeWire.d.ts +3 -1
  123. package/dist/mcpProbeWire.js +5 -0
  124. package/dist/mcpWireCaps.d.ts +34 -0
  125. package/dist/mcpWireCaps.js +117 -17
  126. package/dist/memoryEntriesWire.js +5 -10
  127. package/dist/model/onboardJudgement.d.ts +93 -0
  128. package/dist/model/onboardJudgement.js +415 -0
  129. package/dist/model/tierVocabulary.d.ts +2 -0
  130. package/dist/model/tierVocabulary.js +17 -5
  131. package/dist/modelCapabilityProbe.d.ts +64 -0
  132. package/dist/modelCapabilityProbe.js +600 -0
  133. package/dist/modelIdentityResolvability.d.ts +3 -0
  134. package/dist/modelIdentityResolvability.js +26 -17
  135. package/dist/ownKey.d.ts +7 -0
  136. package/dist/ownKey.js +34 -0
  137. package/dist/panelReduce.d.ts +6 -1
  138. package/dist/panelReduce.js +50 -3
  139. package/dist/permissionRuleIssue.js +2 -0
  140. package/dist/permissionRulesWriteCapability.d.ts +2 -1
  141. package/dist/permissionRulesWriteCapability.js +8 -6
  142. package/dist/pluginHooksWire.d.ts +46 -3
  143. package/dist/pluginHooksWire.js +217 -11
  144. package/dist/printModelStatus.d.ts +63 -0
  145. package/dist/printModelStatus.js +155 -0
  146. package/dist/request/taskRequest.d.ts +11 -5
  147. package/dist/request/taskRequest.js +112 -16
  148. package/dist/resumeRefusalCopy.d.ts +12 -9
  149. package/dist/resumeRefusalCopy.js +70 -143
  150. package/dist/retryStatus.d.ts +37 -0
  151. package/dist/retryStatus.js +79 -0
  152. package/dist/scenarioRefusal.d.ts +9 -0
  153. package/dist/scenarioRefusal.js +111 -0
  154. package/dist/seam.d.ts +25 -1
  155. package/dist/seam.js +10 -1
  156. package/dist/seatContract.d.ts +260 -10
  157. package/dist/seatContract.js +692 -19
  158. package/dist/selfOrchestrationDenial.js +7 -19
  159. package/dist/sessionIdSegment.d.ts +6 -0
  160. package/dist/sessionIdSegment.js +24 -0
  161. package/dist/sessionMemoryStatus.js +6 -11
  162. package/dist/sessionPolicyCapability.d.ts +2 -1
  163. package/dist/sessionPolicyCapability.js +8 -6
  164. package/dist/settingsHooksSalvage.d.ts +44 -0
  165. package/dist/settingsHooksSalvage.js +211 -0
  166. package/dist/skillToolListsCapability.d.ts +2 -1
  167. package/dist/skillToolListsCapability.js +8 -6
  168. package/dist/sseIdleTriage.js +3 -2
  169. package/dist/subagent/engineSubagentResume.js +15 -9
  170. package/dist/subagentContentStore.d.ts +3 -0
  171. package/dist/subagentContentStore.js +22 -0
  172. package/dist/toolHistoryMismatch.js +3 -2
  173. package/dist/toolRoster.d.ts +3 -2
  174. package/dist/toolRoster.js +21 -20
  175. package/dist/turnFailurePresentation.d.ts +12 -1
  176. package/dist/turnFailurePresentation.js +212 -15
  177. package/dist/usageAnalytics.js +6 -11
  178. package/dist/userAttachmentEnvelope.d.ts +1 -0
  179. package/dist/userAttachmentEnvelope.js +37 -7
  180. package/dist/userAttachmentSeat.d.ts +21 -0
  181. package/dist/userAttachmentSeat.js +75 -0
  182. package/dist/userInvokedSkillsCapability.d.ts +11 -1
  183. package/dist/userInvokedSkillsCapability.js +31 -7
  184. package/dist/wireErrorTriage.d.ts +7 -0
  185. package/dist/wireErrorTriage.js +23 -1
  186. package/dist/wireFailureShape.js +2 -1
  187. package/dist/wireRefusalCopy.d.ts +13 -1
  188. package/dist/wireRefusalCopy.js +24 -28
  189. package/dist/workflowsJournalCapability.d.ts +2 -1
  190. package/dist/workflowsJournalCapability.js +8 -6
  191. package/docs/INTEGRATION-CLIENTS.md +542 -30
  192. package/package.json +5 -5
@@ -1,7 +1,10 @@
1
1
  import { PERMISSION_MODE_WORDS, REASONING_EFFORT_WORDS } from "./taskRequestWords.js";
2
2
  import { liveDefaultModelCopy, liveModelRowCopy } from "./model/liveCatalogShape.js";
3
3
  import { REWIND_MODES } from "./rewindWireCaps.js";
4
+ import { SETTINGS_MODEL_API_WORDS } from "./generated/settingsSchemaTables.js";
5
+ import { PROBE_VERDICTS } from "./modelCapabilityProbe.js";
4
6
  import { guardedRead, ownDataField, ownDataRefusalKeyOf, ownSendableField, readOwnDataValue } from "./ownKey.js";
7
+ import { MCP_LIVENESS_STATES } from "./mcpLiveness.js";
5
8
  const bad = (reason, field) => field === undefined ? { reason } : { reason, field };
6
9
  const nested = (prefix, verdict) => {
7
10
  const path = verdict.field === undefined
@@ -89,6 +92,124 @@ const seatCheckAt = (fn) => (v, field) => {
89
92
  return key !== undefined ? bad(NOT_PLAIN_DATA, `${field}.${key}`) : bad("payload could not be read", field);
90
93
  }
91
94
  };
95
+ const pathAt = (path, key) => (path === "" ? key : `${path}.${key}`);
96
+ const reqF = (rule) => ({ opt: false, rule });
97
+ const optF = (rule) => ({ opt: true, rule });
98
+ const ruleOf = (label, pred) => ({
99
+ label,
100
+ test: (v, path) => (pred(v) ? true : bad(`bad value (${label})`, path === "" ? undefined : path)),
101
+ });
102
+ function shapeVerdict(spec, v, path, disc) {
103
+ if (!isPlainRecord(v))
104
+ return bad("not object", path === "" ? undefined : path);
105
+ for (const k of sendableKeysOf(v)) {
106
+ if (k !== disc && !Object.hasOwn(spec, k))
107
+ return bad("unknown key", pathAt(path, k));
108
+ }
109
+ for (const k of Object.keys(spec)) {
110
+ const s = spec[k];
111
+ const val = own(v, k);
112
+ if (isAbsent(val)) {
113
+ if (!s.opt)
114
+ return bad("missing key", pathAt(path, k));
115
+ continue;
116
+ }
117
+ const verdict = s.rule.test(val, pathAt(path, k));
118
+ if (verdict !== true)
119
+ return verdict;
120
+ }
121
+ return true;
122
+ }
123
+ const shapeRule = (label, spec) => ({ label, test: (v, path) => shapeVerdict(spec, v, path) });
124
+ const armsRule = (label, disc, arms) => ({
125
+ label,
126
+ test: (v, path) => {
127
+ if (!isPlainRecord(v))
128
+ return bad("not object", path === "" ? undefined : path);
129
+ const d = own(v, disc);
130
+ if (typeof d !== "string" || !Object.hasOwn(arms, d))
131
+ return bad("unknown arm", pathAt(path, disc));
132
+ return shapeVerdict(arms[d], v, path, disc);
133
+ },
134
+ });
135
+ const isArraySlotKey = (k, n) => k === "length" || (/^(0|[1-9][0-9]*)$/.test(k) && Number(k) < n);
136
+ const arrayRule = (item, nonEmpty = false) => ({
137
+ label: `${item.label}[]`,
138
+ test: (v, path) => {
139
+ if (!Array.isArray(v))
140
+ return bad(`bad value (${item.label}[])`, path === "" ? undefined : path);
141
+ const n = ownDataField(v, "length");
142
+ for (const k of Reflect.ownKeys(v)) {
143
+ if (typeof k === "string" && !isArraySlotKey(k, typeof n === "number" ? n : 0))
144
+ return bad("unknown key", pathAt(path, k));
145
+ }
146
+ const rows = ownItems(v);
147
+ if (nonEmpty && rows.length === 0)
148
+ return bad(`bad value (${item.label}[])`, path === "" ? undefined : path);
149
+ for (let i = 0; i < rows.length; i += 1) {
150
+ const verdict = item.test(rows[i], `${path}[${i}]`);
151
+ if (verdict !== true)
152
+ return verdict;
153
+ }
154
+ return true;
155
+ },
156
+ });
157
+ const oneOfRule = (label, words) => ruleOf(label, (v) => typeof v === "string" && words.includes(v));
158
+ const R_STR = ruleOf("string", (v) => typeof v === "string");
159
+ const R_NONEMPTY = ruleOf("non-empty string", (v) => typeof v === "string" && v.length > 0);
160
+ const R_BOOL = ruleOf("boolean", (v) => typeof v === "boolean");
161
+ const R_TRUE = ruleOf("true", (v) => v === true);
162
+ const R_NUM = ruleOf("finite number", (v) => typeof v === "number" && Number.isFinite(v));
163
+ const R_INT0 = ruleOf("non-negative integer", (v) => typeof v === "number" && Number.isSafeInteger(v) && v >= 0);
164
+ const R_INT1 = ruleOf("positive integer", (v) => typeof v === "number" && Number.isSafeInteger(v) && v > 0);
165
+ const keyWords = (k) => k
166
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
167
+ .toLowerCase()
168
+ .split(/[^a-z0-9]+/)
169
+ .filter((w) => w.length > 0);
170
+ const SECRET_KEY_WORDS = new Set(["token", "secret", "password", "passwd", "authorization", "bearer", "sealed"]);
171
+ const SECRET_KEY_PAIRS = new Set(["api key", "device code", "access key", "private key"]);
172
+ const isSecretKeyName = (k) => {
173
+ const words = keyWords(k);
174
+ for (let i = 0; i < words.length; i += 1) {
175
+ if (SECRET_KEY_WORDS.has(words[i]))
176
+ return true;
177
+ if (i + 1 < words.length && SECRET_KEY_PAIRS.has(`${words[i]} ${words[i + 1]}`))
178
+ return true;
179
+ }
180
+ return false;
181
+ };
182
+ const firstSecretKeyPath = (root, allow) => {
183
+ const seen = new Set();
184
+ const stack = [[root, ""]];
185
+ while (stack.length > 0) {
186
+ const [v, path] = stack.pop();
187
+ if (typeof v !== "object" || v === null || seen.has(v))
188
+ continue;
189
+ seen.add(v);
190
+ const isArr = Array.isArray(v);
191
+ for (const k of Reflect.ownKeys(v)) {
192
+ if (typeof k !== "string" || (isArr && k === "length"))
193
+ continue;
194
+ const d = Reflect.getOwnPropertyDescriptor(v, k);
195
+ if (d === undefined || !Object.hasOwn(d, "value"))
196
+ continue;
197
+ const at = isArr && /^[0-9]+$/.test(k) ? `${path}[${k}]` : pathAt(path, k);
198
+ if (isSecretKeyName(k) && !allow.has(at))
199
+ return at;
200
+ stack.push([d.value, at]);
201
+ }
202
+ }
203
+ return undefined;
204
+ };
205
+ const NO_SECRET_ALLOW = new Set();
206
+ const seatShapeCheck = (rule, allow = NO_SECRET_ALLOW) => seatCheck((v) => {
207
+ const verdict = rule.test(v, "");
208
+ if (verdict !== true)
209
+ return verdict;
210
+ const secret = firstSecretKeyPath(v, allow);
211
+ return secret === undefined ? true : bad("secret key", secret);
212
+ });
92
213
  export const TOOL_PERMISSION_REQUEST_ID_DOMAINS = Object.freeze([
93
214
  "live:",
94
215
  "durable:",
@@ -127,6 +248,7 @@ const SEAT_EVENT_TYPE_TUPLE = [
127
248
  "chrome_event",
128
249
  "error",
129
250
  "tool_permission_resolved",
251
+ "subagent_content",
130
252
  ];
131
253
  export const SEAT_EVENT_TYPES = Object.freeze(SEAT_EVENT_TYPE_TUPLE);
132
254
  const CHROME_EVENT_KIND_TUPLE = [
@@ -205,7 +327,7 @@ export function readSeatStreamDelta(message) {
205
327
  return Object.freeze({ kind: "malformed" });
206
328
  }
207
329
  }
208
- export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession"]);
330
+ export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard"]);
209
331
  const notReported = () => Object.freeze({ kind: "not_reported" });
210
332
  const malformedReading = () => Object.freeze({ kind: "malformed" });
211
333
  const reported = (available) => Object.freeze({ kind: "reported", available });
@@ -277,6 +399,9 @@ const SEAT_CAPABILITY_PHRASES = Object.freeze({
277
399
  pickFolder: Object.freeze({ action: "Opening a folder", ability: "show a folder picker", support: "folder picker support" }),
278
400
  rewind: Object.freeze({ action: "Rewinding to an earlier message", ability: "rewind this session", support: "rewind support" }),
279
401
  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" }),
402
+ devices: Object.freeze({ action: "Managing devices", ability: "manage devices", support: "device support" }),
403
+ engineTarget: Object.freeze({ action: "Switching engines", ability: "switch engines", support: "engine-switching support" }),
404
+ onboard: Object.freeze({ action: "Model setup", ability: "add models", support: "model-setup support" }),
280
405
  });
281
406
  export function seatCapabilityUnavailableDetail(name, reading) {
282
407
  const phrase = Object.hasOwn(SEAT_CAPABILITY_PHRASES, name)
@@ -405,6 +530,378 @@ export const ATTACHMENT_UPLOAD_REQUEST_KEYS = ["name", "mimeType", "bytes"];
405
530
  export const SESSION_ROW_PATCH_REQUEST_KEYS = Object.freeze(["sessionId", "title", "pinned"]);
406
531
  export const SESSION_SEARCH_RESULT_KEYS = ["sessionId", "title", "matches"];
407
532
  export const GET_TRANSCRIPT_RESULT_KEYS = ["sessionId", "messages"];
533
+ const DEVICE_REFUSED_SPEC = { status: reqF(R_INT0), errorCode: optF(R_STR), message: optF(R_STR) };
534
+ const DEVICE_LANE_ABSENT_SPEC = { runStoreOnly: optF(R_TRUE) };
535
+ const DEVICE_TRANSPORT_SPEC = { detail: optF(R_STR) };
536
+ const DEVICE_UNREADABLE_SPEC = { why: reqF(R_STR) };
537
+ const DEVICE_UNCONFIRMED_SPEC = {
538
+ why: reqF(oneOfRule("unconfirmed why", ["accepted-unreadable", "transport", "server-error"])),
539
+ detail: optF(R_STR),
540
+ mayStillBeRunning: reqF(R_BOOL),
541
+ };
542
+ const DEVICE_RATE_LIMITED_SPEC = { retryAfterSec: optF(R_NUM) };
543
+ const DEVICE_ROSTER_ROW = shapeRule("device row", {
544
+ deviceId: reqF(R_NONEMPTY),
545
+ name: optF(R_STR),
546
+ status: reqF(oneOfRule("device status", ["online", "offline", "unknown"])),
547
+ lastSeenAt: optF(R_STR),
548
+ });
549
+ const DEVICE_BINDING = shapeRule("device binding", {
550
+ deviceId: reqF(R_NONEMPTY),
551
+ rev: reqF(R_INT0),
552
+ boundAt: optF(R_STR),
553
+ });
554
+ const checkDeviceListOutcome = seatShapeCheck(armsRule("listDevices outcome", "kind", {
555
+ ok: { devices: reqF(arrayRule(DEVICE_ROSTER_ROW)), dropped: reqF(R_INT0) },
556
+ unreadable: DEVICE_UNREADABLE_SPEC,
557
+ "lane-absent": DEVICE_LANE_ABSENT_SPEC,
558
+ refused: DEVICE_REFUSED_SPEC,
559
+ transport: DEVICE_TRANSPORT_SPEC,
560
+ unarmed: {},
561
+ }));
562
+ const checkDeviceSessionBindingOutcome = seatShapeCheck(armsRule("readSessionBinding outcome", "kind", {
563
+ ok: { rootSessionId: reqF(R_NONEMPTY), boundDevice: reqF(DEVICE_BINDING) },
564
+ "not-found": {},
565
+ unreadable: DEVICE_UNREADABLE_SPEC,
566
+ "lane-absent": DEVICE_LANE_ABSENT_SPEC,
567
+ refused: DEVICE_REFUSED_SPEC,
568
+ transport: DEVICE_TRANSPORT_SPEC,
569
+ unarmed: {},
570
+ }));
571
+ const checkDeviceRebindOutcome = seatShapeCheck(armsRule("rebindSession outcome", "kind", {
572
+ ok: { deviceId: reqF(R_NONEMPTY), rev: reqF(R_INT0), workspaceCarryover: optF(oneOfRule("carryover", ["none"])) },
573
+ "active-run": { activeTaskId: optF(R_STR) },
574
+ "rev-conflict": { currentRev: optF(R_INT0) },
575
+ "not-found": {},
576
+ unconfirmed: DEVICE_UNCONFIRMED_SPEC,
577
+ "lane-absent": DEVICE_LANE_ABSENT_SPEC,
578
+ refused: DEVICE_REFUSED_SPEC,
579
+ unarmed: {},
580
+ }));
581
+ const ENROLL_TOKEN_ALLOW = new Set(["token"]);
582
+ const checkDeviceEnrollTokenOutcome = seatShapeCheck(armsRule("issueEnrollToken outcome", "kind", {
583
+ ok: { token: reqF(R_NONEMPTY), expiresAt: optF(R_STR), ttlSec: optF(R_INT1) },
584
+ "rate-limited": DEVICE_RATE_LIMITED_SPEC,
585
+ unreadable: DEVICE_UNREADABLE_SPEC,
586
+ "lane-absent": DEVICE_LANE_ABSENT_SPEC,
587
+ refused: DEVICE_REFUSED_SPEC,
588
+ transport: DEVICE_TRANSPORT_SPEC,
589
+ unarmed: {},
590
+ }), ENROLL_TOKEN_ALLOW);
591
+ const checkDeviceRevokeOutcome = seatShapeCheck(armsRule("revokeDevice outcome", "kind", {
592
+ ok: { deviceId: reqF(R_NONEMPTY), revokedAt: optF(R_STR) },
593
+ "not-found": {},
594
+ unconfirmed: DEVICE_UNCONFIRMED_SPEC,
595
+ "lane-absent": DEVICE_LANE_ABSENT_SPEC,
596
+ refused: DEVICE_REFUSED_SPEC,
597
+ unarmed: {},
598
+ }));
599
+ export const checkSeatDeviceRebindRequest = seatShapeCheck(shapeRule("rebindSession request", {
600
+ sessionId: reqF(R_NONEMPTY),
601
+ toDeviceId: reqF(R_NONEMPTY),
602
+ expectedRev: reqF(R_INT0),
603
+ fromDeviceId: reqF(R_NONEMPTY),
604
+ }));
605
+ export const checkSeatDeviceRevokeRequest = seatShapeCheck(shapeRule("revokeDevice request", { deviceId: reqF(R_NONEMPTY), reason: optF(R_STR) }));
606
+ export const ENGINE_TARGET_REFUSALS = Object.freeze([
607
+ "busy",
608
+ "switching",
609
+ "not_configured",
610
+ "not_signed_in",
611
+ "probe_failed",
612
+ "org_policy",
613
+ "url_refused",
614
+ "login_failed",
615
+ "storage_unavailable",
616
+ "no_local_runtime",
617
+ "input",
618
+ ]);
619
+ export const CLOUD_LOGIN_FAILURES = Object.freeze([
620
+ "access_denied",
621
+ "expired_token",
622
+ "invalid_grant",
623
+ "cancelled",
624
+ "transport",
625
+ "refused",
626
+ "no_tokens",
627
+ "other",
628
+ ]);
629
+ const R_ISO = R_NONEMPTY;
630
+ const R_LOGIN_FAILURE = oneOfRule("login failure", CLOUD_LOGIN_FAILURES);
631
+ const R_DISPLAY_URL = ruleOf("display url", (v) => {
632
+ if (typeof v !== "string" || v.length === 0)
633
+ return false;
634
+ let u;
635
+ try {
636
+ u = new URL(v);
637
+ }
638
+ catch {
639
+ return false;
640
+ }
641
+ return (u.protocol === "https:" || u.protocol === "http:") && u.username === "" && u.password === "" && u.search === "" && u.hash === "";
642
+ });
643
+ const R_VERIFICATION_URI_COMPLETE = ruleOf("verification uri", (v) => {
644
+ if (typeof v !== "string" || v.length === 0)
645
+ return false;
646
+ let text = v;
647
+ for (let i = 0; i < 4; i += 1) {
648
+ let next;
649
+ try {
650
+ next = decodeURIComponent(text);
651
+ }
652
+ catch {
653
+ return false;
654
+ }
655
+ if (next === text)
656
+ break;
657
+ text = next;
658
+ }
659
+ return !/device[_-]?code/i.test(text);
660
+ });
661
+ const ENGINE_PROBE_READING = shapeRule("engine probe", {
662
+ ok: reqF(R_BOOL),
663
+ version: optF(R_STR),
664
+ detail: optF(R_STR),
665
+ at: reqF(R_ISO),
666
+ });
667
+ const SEAT_LOCAL_MCP_ROW = shapeRule("mcp row", {
668
+ name: reqF(R_NONEMPTY),
669
+ status: reqF(R_STR),
670
+ toolCount: optF(R_INT0),
671
+ liveness: optF(R_STR),
672
+ errorCode: optF(R_STR),
673
+ forcedAsk: optF(arrayRule(R_NONEMPTY, true)),
674
+ });
675
+ const SEAT_LOCAL_MCP_READING = armsRule("mcp reading", "status", {
676
+ listed: { servers: reqF(arrayRule(SEAT_LOCAL_MCP_ROW)), readAt: reqF(R_ISO), restartRequired: optF(R_TRUE) },
677
+ unreadable: { cause: reqF(R_NONEMPTY), detail: optF(R_STR), readAt: reqF(R_ISO), restartRequired: optF(R_TRUE) },
678
+ });
679
+ const ENGINE_TARGET_CLOUD = shapeRule("cloud", {
680
+ configured: reqF(R_BOOL),
681
+ url: optF(R_DISPLAY_URL),
682
+ label: optF(R_STR),
683
+ auth: optF(armsRule("cloud auth", "kind", {
684
+ registry: { registryUrl: reqF(R_DISPLAY_URL), principal: optF(R_STR), role: optF(R_STR), scope: optF(R_STR) },
685
+ token: {},
686
+ })),
687
+ login: optF(armsRule("cloud login", "state", {
688
+ pending: {
689
+ registryUrl: reqF(R_DISPLAY_URL),
690
+ userCode: reqF(R_NONEMPTY),
691
+ verificationUri: reqF(R_DISPLAY_URL),
692
+ verificationUriComplete: optF(R_VERIFICATION_URI_COMPLETE),
693
+ expiresAt: reqF(R_ISO),
694
+ },
695
+ failed: { failure: reqF(R_LOGIN_FAILURE), status: optF(R_INT0), at: reqF(R_ISO) },
696
+ })),
697
+ lastProbe: optF(ENGINE_PROBE_READING),
698
+ authError: optF(shapeRule("auth error", {
699
+ failure: reqF(R_LOGIN_FAILURE),
700
+ status: optF(R_INT0),
701
+ at: reqF(R_ISO),
702
+ })),
703
+ orgEngine: optF(shapeRule("org engine", { url: reqF(R_DISPLAY_URL), required: reqF(R_BOOL) })),
704
+ });
705
+ const ENGINE_TARGET_LOCAL = shapeRule("local", {
706
+ lastBootError: optF(R_STR),
707
+ mcp: optF(SEAT_LOCAL_MCP_READING),
708
+ });
709
+ const ENGINE_TARGET_STATE = shapeRule("engine target", {
710
+ mode: reqF(oneOfRule("engine mode", ["local", "cloud"])),
711
+ generation: reqF(R_INT0),
712
+ cloud: reqF(ENGINE_TARGET_CLOUD),
713
+ local: reqF(ENGINE_TARGET_LOCAL),
714
+ });
715
+ const checkEngineTargetState = seatShapeCheck(ENGINE_TARGET_STATE);
716
+ const okArmsRule = (label, okSpec, refusedSpec) => ({
717
+ label,
718
+ test: (v, path) => {
719
+ if (!isPlainRecord(v))
720
+ return bad("not object", path === "" ? undefined : path);
721
+ const ok = own(v, "ok");
722
+ if (ok === true)
723
+ return shapeVerdict(okSpec, v, path, "ok");
724
+ if (ok === false)
725
+ return shapeVerdict(refusedSpec, v, path, "ok");
726
+ return bad("unknown arm", pathAt(path, "ok"));
727
+ },
728
+ });
729
+ const ENGINE_TARGET_REFUSED_SPEC = {
730
+ refusal: reqF(oneOfRule("engineTarget refusal", ENGINE_TARGET_REFUSALS)),
731
+ failure: optF(R_LOGIN_FAILURE),
732
+ status: optF(R_INT0),
733
+ detail: optF(R_STR),
734
+ };
735
+ const checkEngineTargetResult = seatShapeCheck(okArmsRule("engineTarget result", {}, ENGINE_TARGET_REFUSED_SPEC));
736
+ const checkCancelCloudLogin = seatShapeCheck(shapeRule("cancel ack", { ok: reqF(R_BOOL) }));
737
+ const checkCloudLoginStart = seatShapeCheck(okArmsRule("startCloudLogin result", {
738
+ verificationUri: reqF(R_DISPLAY_URL),
739
+ verificationUriComplete: optF(R_VERIFICATION_URI_COMPLETE),
740
+ userCode: reqF(R_NONEMPTY),
741
+ expiresAt: reqF(R_ISO),
742
+ }, ENGINE_TARGET_REFUSED_SPEC));
743
+ const checkCloudConnectResult = seatShapeCheck(okArmsRule("connect result", {
744
+ probe: reqF(shapeRule("probe", { version: optF(R_STR) })),
745
+ }, ENGINE_TARGET_REFUSED_SPEC));
746
+ export const checkCloudLoginRequest = seatShapeCheck(shapeRule("startCloudLogin request", { registryUrl: reqF(R_DISPLAY_URL) }));
747
+ export const checkCloudEngineConnectRequest = seatShapeCheck(shapeRule("connectCloudEngine request", { url: reqF(R_DISPLAY_URL) }));
748
+ const CONFIGURE_TOKEN_ALLOW = new Set(["token"]);
749
+ export const checkCloudEngineConfigureRequest = seatShapeCheck(shapeRule("configureCloudEngine request", { url: reqF(R_DISPLAY_URL), token: reqF(R_NONEMPTY) }), CONFIGURE_TOKEN_ALLOW);
750
+ export const ONBOARD_REFUSALS = Object.freeze([
751
+ "input",
752
+ "probe_failed",
753
+ "probe_unverified",
754
+ "credential_unpaired",
755
+ "catalog_unreadable",
756
+ "write_conflict",
757
+ "write_failed",
758
+ "engine_is_remote",
759
+ "env_catalog_present",
760
+ ]);
761
+ const R_API_WORD = oneOfRule("api", SETTINGS_MODEL_API_WORDS);
762
+ const ONBOARD_PROBE_RESULT = shapeRule("probe result", {
763
+ verdict: reqF(oneOfRule("probe verdict", PROBE_VERDICTS)),
764
+ detail: reqF(R_STR),
765
+ thinking: optF(R_NONEMPTY),
766
+ });
767
+ const ENGINE_UP_SPEC = { model: reqF(ruleOf("string|null", (x) => x === null || typeof x === "string")) };
768
+ const ENGINE_NOT_UP_SPEC = { reason: reqF(R_STR) };
769
+ const ENGINE_RESTART_OUTCOME = armsRule("engine restart", "state", {
770
+ started: ENGINE_UP_SPEC,
771
+ restarted: ENGINE_UP_SPEC,
772
+ pending: ENGINE_NOT_UP_SPEC,
773
+ failed: ENGINE_NOT_UP_SPEC,
774
+ skipped: ENGINE_NOT_UP_SPEC,
775
+ });
776
+ const ONBOARD_SOURCE = armsRule("onboard source", "kind", {
777
+ preset: { providerId: reqF(R_NONEMPTY) },
778
+ custom: {},
779
+ imported: { profileId: reqF(R_NONEMPTY) },
780
+ });
781
+ const ONBOARD_ENTRY_SPEC = {
782
+ source: reqF(ONBOARD_SOURCE),
783
+ modelId: reqF(R_NONEMPTY),
784
+ baseUrl: optF(R_NONEMPTY),
785
+ api: optF(R_API_WORD),
786
+ apiKey: optF(R_NONEMPTY),
787
+ contextWindow: optF(R_INT1),
788
+ maxTokens: optF(R_INT1),
789
+ };
790
+ const ONBOARD_KEY_ALLOW = new Set(["apiKey"]);
791
+ export const checkOnboardEntryRequest = seatShapeCheck(shapeRule("probeOnboardEntry request", ONBOARD_ENTRY_SPEC), ONBOARD_KEY_ALLOW);
792
+ export const checkOnboardApplyRequest = seatShapeCheck(shapeRule("applyOnboardEntry request", {
793
+ ...ONBOARD_ENTRY_SPEC,
794
+ makeDefault: optF(R_BOOL),
795
+ acceptUnverified: optF(R_BOOL),
796
+ }), ONBOARD_KEY_ALLOW);
797
+ const checkOnboardProbeResult = seatShapeCheck(ONBOARD_PROBE_RESULT);
798
+ const checkOnboardApplyResult = seatShapeCheck(okArmsRule("applyOnboardEntry result", {
799
+ entryName: reqF(R_NONEMPTY),
800
+ modelId: reqF(R_NONEMPTY),
801
+ keyEnv: reqF(R_NONEMPTY),
802
+ updatedExisting: reqF(R_BOOL),
803
+ probe: reqF(ONBOARD_PROBE_RESULT),
804
+ otherIssues: reqF(arrayRule(shapeRule("catalog issue", {
805
+ name: reqF(R_NONEMPTY),
806
+ modelId: reqF(R_STR),
807
+ issue: reqF(R_NONEMPTY),
808
+ }))),
809
+ engine: reqF(ENGINE_RESTART_OUTCOME),
810
+ }, {
811
+ refusal: reqF(oneOfRule("onboard refusal", ONBOARD_REFUSALS)),
812
+ detail: optF(R_STR),
813
+ probe: optF(ONBOARD_PROBE_RESULT),
814
+ }));
815
+ const checkOnboardProvidersResult = seatShapeCheck(shapeRule("onboard providers", {
816
+ providers: reqF(arrayRule(shapeRule("provider row", {
817
+ id: reqF(R_NONEMPTY),
818
+ name: reqF(R_NONEMPTY),
819
+ baseUrl: reqF(R_NONEMPTY),
820
+ api: reqF(R_API_WORD),
821
+ keyAuth: reqF(R_BOOL),
822
+ authEnv: reqF(R_STR),
823
+ models: reqF(arrayRule(shapeRule("provider model", {
824
+ id: reqF(R_NONEMPTY),
825
+ contextWindow: reqF(R_INT1),
826
+ maxTokens: reqF(R_INT1),
827
+ }))),
828
+ consoleUrl: optF(R_STR),
829
+ }))),
830
+ importable: optF(arrayRule(shapeRule("importable profile", {
831
+ id: reqF(R_NONEMPTY),
832
+ name: reqF(R_STR),
833
+ baseUrl: reqF(R_NONEMPTY),
834
+ api: reqF(R_API_WORD),
835
+ hasKey: reqF(R_BOOL),
836
+ models: reqF(arrayRule(R_NONEMPTY)),
837
+ }))),
838
+ }));
839
+ const checkSessionMcpPanelFailure = seatShapeCheck(armsRule("readSessionMcpPanel failure", "kind", {
840
+ unreadable: DEVICE_UNREADABLE_SPEC,
841
+ transport: DEVICE_TRANSPORT_SPEC,
842
+ unarmed: {},
843
+ }));
844
+ function mcpPanelLivenessArms() {
845
+ const arms = {};
846
+ for (const state of MCP_LIVENESS_STATES)
847
+ arms[state] = state === "unreachable" ? { observedAt: reqF(R_NUM), errorCode: optF(R_NONEMPTY) } : { observedAt: reqF(R_NUM) };
848
+ const keysPin = [true, true];
849
+ void keysPin;
850
+ return arms;
851
+ }
852
+ const MCP_PANEL_LIVENESS_VIEW = armsRule("mcp liveness", "state", mcpPanelLivenessArms());
853
+ const MCP_PANEL_LEG_ENTRY = shapeRule("leg entry", {
854
+ name: reqF(R_NONEMPTY),
855
+ status: reqF(R_NONEMPTY),
856
+ source: optF(R_NONEMPTY),
857
+ errorCode: optF(R_NONEMPTY),
858
+ toolCount: optF(R_NUM),
859
+ delivered: optF(R_NONEMPTY),
860
+ httpStatus: optF(R_NUM),
861
+ liveness: optF(MCP_PANEL_LIVENESS_VIEW),
862
+ livenessUnreadable: optF(R_TRUE),
863
+ });
864
+ const MCP_PANEL_LAST_LEG = shapeRule("last leg", {
865
+ runId: reqF(R_NONEMPTY),
866
+ at: reqF(R_NONEMPTY),
867
+ mcp: reqF(arrayRule(MCP_PANEL_LEG_ENTRY)),
868
+ });
869
+ const MCP_PANEL_SERVER_ROW = shapeRule("panel server", {
870
+ name: reqF(R_NONEMPTY),
871
+ status: reqF(R_NONEMPTY),
872
+ serverInfo: optF(shapeRule("server info", {
873
+ name: reqF(R_STR),
874
+ version: reqF(R_STR),
875
+ })),
876
+ toolNames: optF(arrayRule(R_STR)),
877
+ error: optF(R_STR),
878
+ });
879
+ const MCP_PANEL_SCENARIO_REFUSAL = shapeRule("scenario refusal", {
880
+ errorCode: optF(R_NONEMPTY),
881
+ error: optF(R_STR),
882
+ scenario: optF(R_NONEMPTY),
883
+ source: optF(oneOfRule("refusal source", ["ruling", "deployment"])),
884
+ });
885
+ const checkSessionMcpPanelServersView = seatShapeCheck(shapeRule("servers view", {
886
+ asOf: reqF(R_NONEMPTY),
887
+ lastLegMcp: optF(MCP_PANEL_LAST_LEG),
888
+ lastLegMcpUnreadable: optF(R_TRUE),
889
+ servers: reqF(arrayRule(MCP_PANEL_SERVER_ROW)),
890
+ degraded: optF(R_TRUE),
891
+ }));
892
+ const checkSessionMcpPanelRefusalView = seatShapeCheck(shapeRule("refusal view", {
893
+ asOf: reqF(R_NONEMPTY),
894
+ lastLegMcp: optF(MCP_PANEL_LAST_LEG),
895
+ lastLegMcpUnreadable: optF(R_TRUE),
896
+ scenarioRefusal: reqF(MCP_PANEL_SCENARIO_REFUSAL),
897
+ }));
898
+ const checkSessionMcpPanelResult = seatCheck((v) => {
899
+ if (!isPlainRecord(v))
900
+ return bad("mcp panel result is not a plain object");
901
+ if (Object.hasOwn(v, "kind"))
902
+ return checkSessionMcpPanelFailure(v);
903
+ return Object.hasOwn(v, "scenarioRefusal") ? checkSessionMcpPanelRefusalView(v) : checkSessionMcpPanelServersView(v);
904
+ });
408
905
  const checkLocalSessionRecord = seatCheck((s) => {
409
906
  if (!isPlainRecord(s))
410
907
  return bad("session record is not a plain object");
@@ -505,6 +1002,91 @@ const checkLaneProof = seatCheckAt((v, field) => {
505
1002
  }
506
1003
  return true;
507
1004
  });
1005
+ const R_NEVER = ruleOf("absent", () => false);
1006
+ const RETRY_ERROR_PAYLOAD = shapeRule("retry error", {
1007
+ formatted: reqF(R_STR),
1008
+ isNetworkDown: optF(R_BOOL),
1009
+ connection: optF(shapeRule("connection", { isSSLError: optF(R_BOOL) })),
1010
+ rateLimits: optF({
1011
+ label: "rate limits",
1012
+ test: (v, path) => v === null
1013
+ ? true
1014
+ : shapeVerdict({ resetsAt: optF(R_NUM), rateLimitType: optF(R_STR) }, v, path),
1015
+ }),
1016
+ });
1017
+ const RETRY_COMMON_SPEC = {
1018
+ deadline: reqF(R_NUM),
1019
+ attempt: optF(R_NUM),
1020
+ maxRetries: optF(R_NUM),
1021
+ errClass: optF(R_STR),
1022
+ retryAtMs: optF(R_NUM),
1023
+ errorStatus: optF(R_NUM),
1024
+ providerCondition: optF(R_STR),
1025
+ providerConditionSource: optF(R_STR),
1026
+ elapsedMs: optF(R_NUM),
1027
+ timeoutMs: optF(R_NUM),
1028
+ };
1029
+ const RETRY_STATUS = armsRule("retry status", "kind", {
1030
+ stalled: { ...RETRY_COMMON_SPEC, detail: optF(R_STR) },
1031
+ error: { ...RETRY_COMMON_SPEC, terminal: optF(R_TRUE), error: reqF(RETRY_ERROR_PAYLOAD) },
1032
+ waiting: { ...RETRY_COMMON_SPEC, terminal: optF(R_NEVER), error: reqF(RETRY_ERROR_PAYLOAD) },
1033
+ });
1034
+ const ENGINE_TURN_USAGE = shapeRule("engine usage", {
1035
+ inputTokens: reqF(R_NUM),
1036
+ totalInputTokens: reqF(R_NUM),
1037
+ outputTokens: reqF(R_NUM),
1038
+ cacheReadTokens: reqF(R_NUM),
1039
+ cacheWriteTokens: reqF(R_NUM),
1040
+ costMicroUsd: reqF(R_NUM),
1041
+ });
1042
+ const SEMA_MODEL_USAGE = shapeRule("model usage", {
1043
+ inputTokens: reqF(R_NUM),
1044
+ outputTokens: reqF(R_NUM),
1045
+ cacheReadInputTokens: reqF(R_NUM),
1046
+ cacheCreationInputTokens: reqF(R_NUM),
1047
+ webSearchRequests: reqF(R_NUM),
1048
+ costUSD: reqF(R_NUM),
1049
+ contextWindow: reqF(R_NUM),
1050
+ maxOutputTokens: reqF(R_NUM),
1051
+ canonicalModel: optF(R_STR),
1052
+ provider: optF(R_STR),
1053
+ _sema_cost_absent: optF(R_TRUE),
1054
+ _sema_web_search_requests_absent: optF(R_TRUE),
1055
+ _sema_context_window_absent: optF(R_TRUE),
1056
+ _sema_max_output_tokens_absent: optF(R_TRUE),
1057
+ });
1058
+ const SEAT_CHROME_PAYLOAD_SPECS = {
1059
+ retry_status: { status: reqF({ label: "retry status", test: (v, path) => (v === null ? true : RETRY_STATUS.test(v, path)) }) },
1060
+ context_usage: {
1061
+ usedTokens: optF(R_NUM),
1062
+ windowTokens: optF(R_NUM),
1063
+ compactAtTokens: optF(R_NUM),
1064
+ sections: optF(arrayRule(shapeRule("section", { id: reqF(R_STR), tokens: reqF(R_NUM), kind: optF(R_STR) }))),
1065
+ eventId: optF(R_NONEMPTY),
1066
+ },
1067
+ last_turn_usage: {
1068
+ usage: reqF(SEMA_MODEL_USAGE),
1069
+ engineUsage: optF(ENGINE_TURN_USAGE),
1070
+ engineUsageUnknownKeys: optF(R_INT1),
1071
+ usageMissing: optF(R_TRUE),
1072
+ stopReason: optF(R_STR),
1073
+ responseModel: optF(R_NONEMPTY),
1074
+ },
1075
+ bgshell_register: {
1076
+ taskId: reqF(R_NONEMPTY),
1077
+ registration: reqF(shapeRule("registration", {
1078
+ kind: reqF(oneOfRule("registration kind", ["register"])),
1079
+ taskId: reqF(R_NONEMPTY),
1080
+ command: reqF(R_STR),
1081
+ description: optF(R_STR),
1082
+ receipt: reqF(R_STR),
1083
+ source: reqF(oneOfRule("registration source", ["bash", "monitor"])),
1084
+ })),
1085
+ },
1086
+ bgshell_settle: { taskId: reqF(R_NONEMPTY), status: reqF(R_STR), outputPath: optF(R_STR) },
1087
+ memory_saved: { id: reqF(R_NONEMPTY), notes: reqF(arrayRule(R_NONEMPTY, true)) },
1088
+ };
1089
+ const ENVELOPE_ROWS = { kind: reqF({ label: "kind", test: () => true }), laneProof: reqF({ label: "laneProof", test: () => true }) };
508
1090
  const checkSeatChromeEnvelope = seatCheckAt((v, field) => {
509
1091
  if (!isPlainRecord(v))
510
1092
  return bad("chrome must be a plain object", field);
@@ -514,7 +1096,13 @@ const checkSeatChromeEnvelope = seatCheckAt((v, field) => {
514
1096
  if (!inTuple(CHROME_EVENT_KIND_TUPLE, kind)) {
515
1097
  return bad(`chrome.kind is not a renderer-wired arm (${CHROME_EVENT_KIND_TUPLE.join("|")})`, `${field}.kind`);
516
1098
  }
517
- return checkLaneProof(own(v, "laneProof"), `${field}.laneProof`);
1099
+ const lane = checkLaneProof(own(v, "laneProof"), `${field}.laneProof`);
1100
+ if (lane !== true)
1101
+ return lane;
1102
+ if (Object.hasOwn(SEAT_CHROME_PAYLOAD_SPECS, kind)) {
1103
+ return shapeVerdict({ ...ENVELOPE_ROWS, ...SEAT_CHROME_PAYLOAD_SPECS[kind] }, v, field);
1104
+ }
1105
+ return true;
518
1106
  });
519
1107
  const checkLocalSessionEvent = seatCheck((v) => {
520
1108
  if (!isPlainRecord(v))
@@ -534,18 +1122,6 @@ const checkLocalSessionEvent = seatCheck((v) => {
534
1122
  const code = own(v, "code");
535
1123
  if (!isAbsent(code) && typeof code !== "number")
536
1124
  return bad("code must be a number when present", "code");
537
- const request = own(v, "request");
538
- if (!isAbsent(request)) {
539
- const verdict = checkToolPermissionRequest(request);
540
- if (verdict !== true)
541
- return nested("request", verdict);
542
- }
543
- const sources = own(v, "sources");
544
- if (!isAbsent(sources)) {
545
- const okSources = Array.isArray(sources) && ownItems(sources).every((t) => typeof t === "string");
546
- if (!okSources)
547
- return bad("sources must be a string[]", "sources");
548
- }
549
1125
  const session = own(v, "session");
550
1126
  if (!isAbsent(session)) {
551
1127
  const verdict = checkLocalSessionRecord(session);
@@ -573,8 +1149,43 @@ const checkLocalSessionEvent = seatCheck((v) => {
573
1149
  if (verdict !== true)
574
1150
  return nested("chrome", verdict);
575
1151
  }
1152
+ const sub = own(v, "subagentContent");
1153
+ if (type === "subagent_content") {
1154
+ if (isAbsent(sub))
1155
+ return bad("missing key", "subagentContent");
1156
+ const verdict = SUBAGENT_CONTENT_SHAPE.test(sub, "subagentContent");
1157
+ if (verdict !== true)
1158
+ return verdict;
1159
+ }
1160
+ else if (!isAbsent(sub)) {
1161
+ return bad("unexpected key", "subagentContent");
1162
+ }
576
1163
  return true;
577
1164
  });
1165
+ const SUBAGENT_CONTENT_SHAPE = shapeRule("subagent content", {
1166
+ type: reqF(oneOfRule("content type", ["text_delta", "reasoning_delta", "text", "reasoning", "tool_start", "tool_end"])),
1167
+ taskId: reqF(R_NONEMPTY),
1168
+ parentToolCallId: reqF(R_NONEMPTY),
1169
+ delta: optF(R_STR),
1170
+ text: optF(R_STR),
1171
+ eventId: optF(R_STR),
1172
+ toolCallId: optF(R_STR),
1173
+ toolName: optF(R_STR),
1174
+ args: optF({ label: "passthrough", test: () => true }),
1175
+ output: optF(R_STR),
1176
+ isError: optF(R_BOOL),
1177
+ });
1178
+ export function readSeatSubagentContent(event) {
1179
+ try {
1180
+ if (checkLocalSessionEvent(event) !== true || own(event, "type") !== "subagent_content")
1181
+ return undefined;
1182
+ const sub = own(event, "subagentContent");
1183
+ return { ...sub };
1184
+ }
1185
+ catch {
1186
+ return undefined;
1187
+ }
1188
+ }
578
1189
  export function isLocalSessionEvent(v) {
579
1190
  return checkLocalSessionEvent(v) === true;
580
1191
  }
@@ -945,6 +1556,21 @@ export const LOCAL_SESSIONS_SPEC = {
945
1556
  pickFolder: { kind: "invoke", check: checkPickFolderResult },
946
1557
  listRecentFolders: { kind: "invoke", check: checkRecentFoldersResult },
947
1558
  noteRecentFolder: { kind: "invoke", check: checkOkAck }, patchSession: { kind: "invoke", check: checkLocalSessionRecord },
1559
+ listDevices: { kind: "invoke", check: checkDeviceListOutcome },
1560
+ readSessionBinding: { kind: "invoke", check: checkDeviceSessionBindingOutcome },
1561
+ rebindSession: { kind: "invoke", check: checkDeviceRebindOutcome },
1562
+ issueEnrollToken: { kind: "invoke", check: checkDeviceEnrollTokenOutcome },
1563
+ revokeDevice: { kind: "invoke", check: checkDeviceRevokeOutcome },
1564
+ setEngineMode: { kind: "invoke", check: checkEngineTargetResult },
1565
+ startCloudLogin: { kind: "invoke", check: checkCloudLoginStart },
1566
+ cancelCloudLogin: { kind: "invoke", check: checkCancelCloudLogin },
1567
+ connectCloudEngine: { kind: "invoke", check: checkCloudConnectResult },
1568
+ configureCloudEngine: { kind: "invoke", check: checkCloudConnectResult },
1569
+ clearCloudEngine: { kind: "invoke", check: checkEngineTargetResult },
1570
+ listOnboardProviders: { kind: "invoke", check: checkOnboardProvidersResult },
1571
+ probeOnboardEntry: { kind: "invoke", check: checkOnboardProbeResult },
1572
+ applyOnboardEntry: { kind: "invoke", check: checkOnboardApplyResult },
1573
+ readSessionMcpPanel: { kind: "invoke", check: checkSessionMcpPanelResult },
948
1574
  onEvent: { kind: "event", check: checkLocalSessionEvent },
949
1575
  onToolPermissionRequest: { kind: "event", check: checkToolPermissionRequest },
950
1576
  },
@@ -953,6 +1579,7 @@ export const LOCAL_SESSIONS_SPEC = {
953
1579
  focusedSessionState: { check: checkFocusedSessionState },
954
1580
  settingsState: { check: checkSettingsState },
955
1581
  seatCapabilitiesState: { check: checkSeatCapabilitiesState },
1582
+ engineTargetState: { check: checkEngineTargetState },
956
1583
  },
957
1584
  };
958
1585
  export const SEAT_METHOD_NAMES = [
@@ -974,6 +1601,21 @@ export const SEAT_METHOD_NAMES = [
974
1601
  "pickFolder",
975
1602
  "listRecentFolders",
976
1603
  "noteRecentFolder", "patchSession",
1604
+ "listDevices",
1605
+ "readSessionBinding",
1606
+ "rebindSession",
1607
+ "issueEnrollToken",
1608
+ "revokeDevice",
1609
+ "setEngineMode",
1610
+ "startCloudLogin",
1611
+ "cancelCloudLogin",
1612
+ "connectCloudEngine",
1613
+ "configureCloudEngine",
1614
+ "clearCloudEngine",
1615
+ "listOnboardProviders",
1616
+ "probeOnboardEntry",
1617
+ "applyOnboardEntry",
1618
+ "readSessionMcpPanel",
977
1619
  "onEvent",
978
1620
  "onToolPermissionRequest",
979
1621
  ];
@@ -982,6 +1624,7 @@ export const SEAT_STORE_PROPS = [
982
1624
  "focusedSessionStateStore",
983
1625
  "settingsStateStore",
984
1626
  "seatCapabilitiesStateStore",
1627
+ "engineTargetStateStore",
985
1628
  ];
986
1629
  export const SEAT_EVENT_METHOD_NAMES = ["onEvent", "onToolPermissionRequest"];
987
1630
  export const LOCAL_SESSION_EVENT_KEYS = [
@@ -991,8 +1634,6 @@ export const LOCAL_SESSION_EVENT_KEYS = [
991
1634
  "error",
992
1635
  "errorCategory",
993
1636
  "code",
994
- "request",
995
- "sources",
996
1637
  "session",
997
1638
  "userMessageUuid",
998
1639
  "requestId",
@@ -1000,6 +1641,7 @@ export const LOCAL_SESSION_EVENT_KEYS = [
1000
1641
  "parked",
1001
1642
  "chrome",
1002
1643
  "_sema_turnFailure",
1644
+ "subagentContent",
1003
1645
  ];
1004
1646
  export const TOOL_PERMISSION_REQUEST_KEYS = [
1005
1647
  "requestId",
@@ -1135,14 +1777,13 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
1135
1777
  "error",
1136
1778
  "errorCategory",
1137
1779
  "code",
1138
- "request",
1139
- "sources",
1140
1780
  "session",
1141
1781
  "userMessageUuid",
1142
1782
  "requestId",
1143
1783
  "outcome",
1144
1784
  "parked",
1145
1785
  "chrome",
1786
+ "subagentContent",
1146
1787
  ],
1147
1788
  unchecked: [
1148
1789
  {
@@ -1254,7 +1895,7 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
1254
1895
  },
1255
1896
  SeatCapabilitiesState: {
1256
1897
  check: checkSeatCapabilitiesState,
1257
- validated: ["pickFolder", "rewind", "recents", "patchSession"],
1898
+ validated: ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard"],
1258
1899
  unchecked: [],
1259
1900
  },
1260
1901
  RecentFoldersResult: {
@@ -1287,8 +1928,39 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
1287
1928
  validated: ["kind", "laneProof"],
1288
1929
  unchecked: [],
1289
1930
  },
1931
+ SessionMcpPanelResult: {
1932
+ check: checkSessionMcpPanelResult,
1933
+ validated: ["kind", "why", "detail", "asOf", "servers", "lastLegMcp", "lastLegMcpUnreadable", "degraded", "scenarioRefusal"],
1934
+ unchecked: [],
1935
+ },
1290
1936
  };
1291
1937
  export const SEAT_VALIDATOR_COVERAGE_EXEMPT = [
1938
+ ...[
1939
+ ["DeviceListOutcome", checkDeviceListOutcome],
1940
+ ["DeviceSessionBindingOutcome", checkDeviceSessionBindingOutcome],
1941
+ ["DeviceRebindOutcome", checkDeviceRebindOutcome],
1942
+ ["DeviceEnrollTokenOutcome", checkDeviceEnrollTokenOutcome],
1943
+ ["DeviceRevokeOutcome", checkDeviceRevokeOutcome],
1944
+ ["SeatDeviceRebindRequest", checkSeatDeviceRebindRequest],
1945
+ ["SeatDeviceRevokeRequest", checkSeatDeviceRevokeRequest],
1946
+ ["EngineTargetState", checkEngineTargetState],
1947
+ ["EngineTargetResult", checkEngineTargetResult],
1948
+ ["CloudLoginStart", checkCloudLoginStart],
1949
+ ["CloudLoginCancelAck", checkCancelCloudLogin],
1950
+ ["CloudConnectResult", checkCloudConnectResult],
1951
+ ["CloudLoginRequest", checkCloudLoginRequest],
1952
+ ["CloudEngineConnectRequest", checkCloudEngineConnectRequest],
1953
+ ["CloudEngineConfigureRequest", checkCloudEngineConfigureRequest],
1954
+ ["OnboardProvidersResult", checkOnboardProvidersResult],
1955
+ ["OnboardProbeResult", checkOnboardProbeResult],
1956
+ ["OnboardApplyResult", checkOnboardApplyResult],
1957
+ ["OnboardEntryRequest", checkOnboardEntryRequest],
1958
+ ["OnboardApplyRequest", checkOnboardApplyRequest],
1959
+ ].map(([label, check]) => ({
1960
+ label,
1961
+ check,
1962
+ why: "座位闭形规则铸的判官(规格表型由对象型派生,键集与必选性编译期两向钉);逐臂逐键投毒在三只席位门(见上方注)。",
1963
+ })),
1292
1964
  {
1293
1965
  label: "PickFolderResult",
1294
1966
  check: checkPickFolderResult,
@@ -1333,5 +2005,6 @@ const _seatContractPins = [
1333
2005
  true, true, true, true, true, true,
1334
2006
  true, true,
1335
2007
  true, true, true, true,
2008
+ true, true, true,
1336
2009
  ];
1337
2010
  void _seatContractPins;