@sema-agent/client-core 0.108.0 → 0.110.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 (179) hide show
  1. package/CHANGELOG.md +294 -0
  2. package/README.md +77 -40
  3. package/dist/adapt/arms.js +41 -13
  4. package/dist/adapt/textStream.d.ts +2 -0
  5. package/dist/adapt/textStream.js +37 -16
  6. package/dist/adapter/activeRunSelfHeal.js +1 -1
  7. package/dist/adapter/downstream/eventToSdkMessage.js +11 -5
  8. package/dist/agentSession/engineAgentRegistryRead.js +2 -0
  9. package/dist/bashExitReading.d.ts +12 -0
  10. package/dist/bashExitReading.js +44 -0
  11. package/dist/checkpointRowVerdict.d.ts +1 -1
  12. package/dist/checkpointRowVerdict.js +4 -2
  13. package/dist/compensations.js +1 -1
  14. package/dist/declared/supportFloorDeclared.js +1 -1
  15. package/dist/displayUntrusted.js +132 -14
  16. package/dist/engineAgentAbsence.d.ts +2 -0
  17. package/dist/engineAgentAbsence.js +28 -0
  18. package/dist/engineErrorCodes.d.ts +7 -0
  19. package/dist/engineErrorCodes.js +7 -0
  20. package/dist/engineHealthFacts.d.ts +26 -0
  21. package/dist/engineHealthFacts.js +63 -4
  22. package/dist/engineInlineTaskStats.d.ts +4 -3
  23. package/dist/engineInlineTaskStats.js +18 -2
  24. package/dist/engineNoticeCodes.d.ts +138 -0
  25. package/dist/engineNoticeCodes.js +662 -55
  26. package/dist/engineRepoint.d.ts +140 -0
  27. package/dist/engineRepoint.js +285 -0
  28. package/dist/engineRowRef.js +2 -0
  29. package/dist/engineSessionMessages.d.ts +2 -1
  30. package/dist/engineSessionMessages.js +5 -0
  31. package/dist/errorSupplementRoles.js +5 -1
  32. package/dist/fleet/fleetProjection.js +3 -2
  33. package/dist/fleetTaskDesc.js +3 -3
  34. package/dist/generated/engineFactTables.d.ts +3 -0
  35. package/dist/generated/engineFactTables.js +18 -0
  36. package/dist/generated/engineNoticeTables.js +3 -0
  37. package/dist/generated/sdkFactTables.d.ts +1 -0
  38. package/dist/generated/sdkFactTables.js +4 -0
  39. package/dist/hitl/approvalAskers.d.ts +6 -0
  40. package/dist/hitl/approvalAskers.js +30 -0
  41. package/dist/hitl/approvalCardReasons.js +25 -4
  42. package/dist/hitl/approvalRequestFrameReading.d.ts +21 -0
  43. package/dist/hitl/approvalRequestFrameReading.js +90 -0
  44. package/dist/hitl/approvalResolution.d.ts +8 -1
  45. package/dist/hitl/approvalResolution.js +4 -0
  46. package/dist/hitl/approvalsFeed.js +1 -1
  47. package/dist/hitl/askGateWire.js +0 -2
  48. package/dist/hitl/askParkRowRouting.js +5 -2
  49. package/dist/hitl/automaticAnswerVerdict.d.ts +5 -2
  50. package/dist/hitl/automaticAnswerVerdict.js +18 -4
  51. package/dist/hitl/decisionConflict.d.ts +2 -1
  52. package/dist/hitl/decisionConflict.js +10 -4
  53. package/dist/hitl/decisionRefusal.js +1 -0
  54. package/dist/hitl/decisionSend.d.ts +3 -0
  55. package/dist/hitl/decisionSend.js +29 -11
  56. package/dist/hitl/editedApprovalAcceptance.d.ts +25 -0
  57. package/dist/hitl/editedApprovalAcceptance.js +26 -0
  58. package/dist/hitl/frameRouter.js +13 -19
  59. package/dist/hitl/gateLedger.d.ts +0 -4
  60. package/dist/hitl/gateLedger.js +0 -19
  61. package/dist/hitl/hitlBridge.d.ts +5 -0
  62. package/dist/hitl/hitlBridge.js +13 -9
  63. package/dist/hitl/hitlHostSurface.d.ts +1 -0
  64. package/dist/hitl/hitlHostSurface.js +7 -2
  65. package/dist/hitl/hostWithdrawal.d.ts +15 -0
  66. package/dist/hitl/hostWithdrawal.js +38 -0
  67. package/dist/hitl/livePendingAsk.js +17 -16
  68. package/dist/hitl/localAllowRule.js +2 -1
  69. package/dist/hitl/noAllowCause.d.ts +1 -1
  70. package/dist/hitl/noAllowCause.js +4 -2
  71. package/dist/hitl/parkExpiryJudgements.js +26 -1
  72. package/dist/hitl/parkOwnership.d.ts +2 -0
  73. package/dist/hitl/parkOwnership.js +48 -8
  74. package/dist/hitl/parkResolver.js +32 -16
  75. package/dist/hitl/parkedUnresumable.d.ts +13 -0
  76. package/dist/hitl/parkedUnresumable.js +80 -0
  77. package/dist/hitl/permissionRuleScope.d.ts +4 -0
  78. package/dist/hitl/permissionRuleScope.js +31 -0
  79. package/dist/hitl/persistedRulesWire.d.ts +2 -0
  80. package/dist/hitl/persistedRulesWire.js +13 -12
  81. package/dist/hitl/planReviewWire.js +14 -4
  82. package/dist/hitl/sessionAllowRoute.js +5 -4
  83. package/dist/hitl/sessionPolicyWire.js +6 -4
  84. package/dist/hitl/standingRows.d.ts +2 -5
  85. package/dist/hitl/standingRows.js +30 -15
  86. package/dist/hitl/toolApprovalWire.d.ts +42 -9
  87. package/dist/hitl/toolApprovalWire.js +267 -44
  88. package/dist/hooksWireCaps.js +35 -4
  89. package/dist/hostSettingsSource.js +2 -0
  90. package/dist/hostTurnSettings.d.ts +10 -4
  91. package/dist/hostTurnSettings.js +112 -5
  92. package/dist/i18n/messages.en.d.ts +251 -0
  93. package/dist/i18n/messages.en.js +254 -2
  94. package/dist/i18n/messages.zh.js +264 -2
  95. package/dist/index.d.ts +48 -12
  96. package/dist/index.js +29 -7
  97. package/dist/inheritEnvCapability.js +2 -0
  98. package/dist/inputAuthor.d.ts +16 -0
  99. package/dist/inputAuthor.js +44 -0
  100. package/dist/interruptRefusalNote.d.ts +2 -0
  101. package/dist/interruptRefusalNote.js +17 -0
  102. package/dist/liveModelCatalog.d.ts +2 -0
  103. package/dist/liveModelCatalog.js +21 -7
  104. package/dist/liveQuestionStore.d.ts +4 -1
  105. package/dist/liveQuestionStore.js +12 -3
  106. package/dist/localEngineJudge.d.ts +75 -0
  107. package/dist/localEngineJudge.js +242 -0
  108. package/dist/localEngineOccupancy.d.ts +88 -0
  109. package/dist/localEngineOccupancy.js +269 -0
  110. package/dist/localEngineSeatReading.d.ts +29 -0
  111. package/dist/localEngineSeatReading.js +294 -0
  112. package/dist/localEngineSpawn.d.ts +113 -0
  113. package/dist/localEngineSpawn.js +486 -0
  114. package/dist/localEngineStep.d.ts +286 -0
  115. package/dist/localEngineStep.js +1086 -0
  116. package/dist/localEngineStopLadder.d.ts +29 -0
  117. package/dist/localEngineStopLadder.js +139 -0
  118. package/dist/localEngineSwapCard.d.ts +43 -0
  119. package/dist/localEngineSwapCard.js +205 -0
  120. package/dist/localEngineTiming.d.ts +8 -0
  121. package/dist/localEngineTiming.js +8 -0
  122. package/dist/mcpEngineLeg.d.ts +3 -0
  123. package/dist/mcpEngineLeg.js +38 -1
  124. package/dist/mcpPanel.js +2 -0
  125. package/dist/mcpReconnect.d.ts +9 -1
  126. package/dist/mcpReconnect.js +132 -20
  127. package/dist/mcpWireCaps.js +2 -2
  128. package/dist/memoryEntriesWire.d.ts +1 -1
  129. package/dist/memoryEntriesWire.js +5 -0
  130. package/dist/modelCapabilityProbe.js +4 -3
  131. package/dist/modsFace.d.ts +8 -1
  132. package/dist/modsFace.js +27 -0
  133. package/dist/noticePresentation.d.ts +2 -0
  134. package/dist/noticePresentation.js +79 -1
  135. package/dist/notifications.d.ts +17 -6
  136. package/dist/notifications.js +67 -19
  137. package/dist/ownKey.d.ts +5 -0
  138. package/dist/ownKey.js +8 -1
  139. package/dist/peerFrames.d.ts +40 -2
  140. package/dist/peerFrames.js +158 -3
  141. package/dist/pluginHooksWire.d.ts +2 -1
  142. package/dist/pluginHooksWire.js +56 -1
  143. package/dist/replayBody.js +10 -2
  144. package/dist/request/taskRequest.d.ts +5 -0
  145. package/dist/request/taskRequest.js +138 -21
  146. package/dist/resumeRefusalCopy.d.ts +1 -3
  147. package/dist/resumeRefusalCopy.js +2 -1
  148. package/dist/retryStatus.d.ts +2 -2
  149. package/dist/retryStatus.js +2 -0
  150. package/dist/ruleReadings.js +1 -1
  151. package/dist/seam.d.ts +24 -2
  152. package/dist/seam.js +15 -2
  153. package/dist/seatContract.d.ts +125 -10
  154. package/dist/seatContract.js +373 -7
  155. package/dist/sessionBackground.js +4 -1
  156. package/dist/sessionBackgroundHandoff.js +2 -1
  157. package/dist/sessionEngine.d.ts +2 -0
  158. package/dist/sessionEngine.js +111 -0
  159. package/dist/sessionMemoryStatus.d.ts +2 -1
  160. package/dist/sessionSyncFileHistory.d.ts +4 -0
  161. package/dist/sessionSyncFileHistory.js +28 -0
  162. package/dist/sseIdleTriage.d.ts +13 -1
  163. package/dist/sseIdleTriage.js +24 -6
  164. package/dist/subagent/engineSubagentTail.js +6 -0
  165. package/dist/subagentContentStore.d.ts +12 -0
  166. package/dist/subagentContentStore.js +72 -11
  167. package/dist/terminalStatuses.d.ts +1 -0
  168. package/dist/terminalStatuses.js +4 -1
  169. package/dist/toolResult.js +18 -5
  170. package/dist/turnFailurePresentation.js +9 -2
  171. package/dist/typePins.d.ts +11 -0
  172. package/dist/usageAnalytics.d.ts +17 -0
  173. package/dist/usageAnalytics.js +44 -2
  174. package/dist/wireFailureShape.d.ts +22 -5
  175. package/dist/wireFailureShape.js +47 -26
  176. package/dist/wireRefusalCopy.d.ts +31 -1
  177. package/dist/wireRefusalCopy.js +167 -2
  178. package/docs/INTEGRATION-CLIENTS.md +3269 -21
  179. package/package.json +5 -5
@@ -10,6 +10,7 @@ import { MCP_LIVENESS_STATES } from "./mcpLiveness.js";
10
10
  import { THINKING_LATCH_EVENTS, THINKING_LATCH_ROW_WORDS } from "./thinkingLatchWords.js";
11
11
  import { EXECUTION_PLACEMENT_ROLES } from "./executionPlacementWords.js";
12
12
  import { isSessionEngineView } from "./sessionEngine.js";
13
+ import { LOCAL_ENGINE_SWAP_CAUSES } from "./localEngineSwapCard.js";
13
14
  const bad = (reason, field) => field === undefined ? { reason } : { reason, field };
14
15
  const nested = (prefix, verdict) => {
15
16
  const path = verdict.field === undefined
@@ -184,6 +185,21 @@ const R_INT0 = ruleOf("non-negative integer", (v) => typeof v === "number" && Nu
184
185
  const R_INT1 = ruleOf("positive integer", (v) => typeof v === "number" && Number.isSafeInteger(v) && v > 0);
185
186
  const SESSION_ENGINE_KIND_WORDS = Object.freeze(["local", "cloud"]);
186
187
  const R_ENGINE_LANE = oneOfRule("engine lane", SESSION_ENGINE_KIND_WORDS);
188
+ const R_ROW_BAR = armsRule("row verdict", "kind", {
189
+ lacking: { code: reqF(R_NONEMPTY), reason: optF(R_NONEMPTY), requires: optF(arrayRule(R_NONEMPTY)), sentence: reqF(R_NONEMPTY) },
190
+ damaged: { code: reqF(R_NONEMPTY), reason: optF(R_NONEMPTY), requires: optF(arrayRule(R_NONEMPTY)), sentence: reqF(R_NONEMPTY) },
191
+ unknown: { word: reqF(R_NONEMPTY), sentence: optF(R_NONEMPTY) },
192
+ unreadable: {},
193
+ });
194
+ const PARKED_ROW_DEADLINE_WORDS = Object.freeze(["armed", "none"]);
195
+ const R_PARKED_ROW = shapeRule("parked row", {
196
+ rowVerdict: reqF(R_ROW_BAR),
197
+ rowKey: optF(R_NONEMPTY),
198
+ taskId: optF(R_NONEMPTY),
199
+ toolName: optF(R_NONEMPTY),
200
+ rowDeadline: optF(oneOfRule("deadline word", PARKED_ROW_DEADLINE_WORDS)),
201
+ });
202
+ const R_PARKED_UNRESUMABLE = arrayRule(R_PARKED_ROW, true);
187
203
  const keyWords = (k) => k
188
204
  .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
189
205
  .toLowerCase()
@@ -293,6 +309,8 @@ const CHROME_ARM_SEAT_ROUTE = {
293
309
  compaction_started: "seat",
294
310
  compaction_outcome: "seat",
295
311
  engine_notice: "seat",
312
+ subagent_alias: "seat",
313
+ session_box_notice: "seat",
296
314
  workflow_notification_enqueue: "host",
297
315
  plan_review_park: "host",
298
316
  approval_request: "host",
@@ -381,7 +399,7 @@ export function readSeatStreamDelta(message) {
381
399
  return Object.freeze({ kind: "malformed" });
382
400
  }
383
401
  }
384
- export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles", "thinkingLatch", "computerUseSwitch", "engineModeDefaultOnly", "seatActions"]);
402
+ export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles", "thinkingLatch", "computerUseSwitch", "engineModeDefaultOnly", "seatActions", "notificationLevels", "modsView"]);
385
403
  const notReported = () => Object.freeze({ kind: "not_reported" });
386
404
  const malformedReading = () => Object.freeze({ kind: "malformed" });
387
405
  const reported = (available) => Object.freeze({ kind: "reported", available });
@@ -461,6 +479,8 @@ const SEAT_CAPABILITY_PHRASES = Object.freeze({
461
479
  computerUseSwitch: Object.freeze({ action: "Computer use", ability: "be switched", support: "switch support" }),
462
480
  engineModeDefaultOnly: Object.freeze({ action: "Default-only engine switching", ability: "keep existing sessions on their engine", support: "default-only engine switching" }),
463
481
  seatActions: Object.freeze({ action: "App menu actions", ability: "send actions to this window", support: "app action support" }),
482
+ notificationLevels: Object.freeze({ action: "Choosing notification levels", ability: "keep notification levels", support: "notification-level support" }),
483
+ modsView: Object.freeze({ action: "Showing mods", ability: "show mods", support: "mods support" }),
464
484
  });
465
485
  export function seatCapabilityUnavailableDetail(name, reading) {
466
486
  const phrase = Object.hasOwn(SEAT_CAPABILITY_PHRASES, name)
@@ -583,6 +603,7 @@ export const SEAT_TURN_SETTINGS_ORIGINS = Object.freeze({
583
603
  hooks: Object.freeze({ hostSupplied: "settings.hooks" }),
584
604
  resolved: Object.freeze({ hostSupplied: "settings.resolved" }),
585
605
  outputStyle: Object.freeze({ hostSupplied: "settings.outputStyle" }),
606
+ env: Object.freeze({ hostSupplied: "settings.env" }),
586
607
  });
587
608
  export const SEAT_REWIND_INTENT_KEYS = ["mode", "targetMessageUuid"];
588
609
  export const ATTACHMENT_UPLOAD_REQUEST_KEYS = ["name", "mimeType", "bytes"];
@@ -687,6 +708,18 @@ export const CLOUD_LOGIN_FAILURES = Object.freeze([
687
708
  "no_tokens",
688
709
  "other",
689
710
  ]);
711
+ export const LOCAL_ENGINE_DOWN_REASONS = Object.freeze([
712
+ "lock-unavailable",
713
+ "spawn-failed",
714
+ "spawn-refused",
715
+ "stop-failed",
716
+ "crash-loop",
717
+ "high-water-unreadable",
718
+ "principal-unknown",
719
+ ]);
720
+ export const LOCAL_ENGINE_WAITING_REASONS = Object.freeze(["starting", "dormant", "draining", "unanswered", "peer"]);
721
+ export const ENGINE_SWAP_ANSWER_OUTCOMES = Object.freeze(["started", "stale-card", "nothing-pending"]);
722
+ export const SELF_UPGRADE_OUTCOMES = Object.freeze(["started", "unavailable"]);
690
723
  const R_ISO = R_NONEMPTY;
691
724
  const R_LOGIN_FAILURE = oneOfRule("login failure", CLOUD_LOGIN_FAILURES);
692
725
  const R_DISPLAY_URL = ruleOf("display url", (v) => {
@@ -763,10 +796,80 @@ const ENGINE_TARGET_CLOUD = shapeRule("cloud", {
763
796
  })),
764
797
  orgEngine: optF(shapeRule("org engine", { url: reqF(R_DISPLAY_URL), required: reqF(R_BOOL) })),
765
798
  });
766
- const ENGINE_TARGET_LOCAL = shapeRule("local", {
799
+ const R_FINITE_TIME = ruleOf("non-negative integer", (v) => typeof v === "number" && Number.isSafeInteger(v) && v >= 0);
800
+ const SWAP_CARD_IDENTITY = shapeRule("engine identity", {
801
+ pid: optF(R_INT1),
802
+ instanceId: optF(R_NONEMPTY),
803
+ startedAt: optF(R_FINITE_TIME),
804
+ });
805
+ const SWAP_CARD_REF_SPEC = {
806
+ pid: reqF(R_INT1),
807
+ port: reqF(ruleOf("port", (v) => typeof v === "number" && Number.isInteger(v) && v >= 1 && v <= 65535)),
808
+ identity: reqF(SWAP_CARD_IDENTITY),
809
+ version: optF(R_NONEMPTY),
810
+ };
811
+ const SWAP_CARD_PROCESS_SPEC = { pid: reqF(R_INT1), startedAt: optF(R_INT1) };
812
+ const R_SWAP_CARD_TARGET = {
813
+ label: "card target",
814
+ test: (v, path) => {
815
+ if (!isPlainRecord(v))
816
+ return bad("not object", path === "" ? undefined : path);
817
+ return shapeVerdict(isAbsent(own(v, "identity")) ? SWAP_CARD_PROCESS_SPEC : SWAP_CARD_REF_SPEC, v, path);
818
+ },
819
+ };
820
+ const SWAP_CARD = shapeRule("swap card", {
821
+ cause: reqF(oneOfRule("swap cause", LOCAL_ENGINE_SWAP_CAUSES)),
822
+ target: reqF(R_SWAP_CARD_TARGET),
823
+ running: optF(R_NONEMPTY),
824
+ own: optF(R_NONEMPTY),
825
+ others: reqF(ruleOf("others count|null", (v) => {
826
+ if (v === null)
827
+ return true;
828
+ if (!isPlainRecord(v))
829
+ return false;
830
+ return shapeVerdict({ total: reqF(R_INT0), midTurn: reqF(R_INT0) }, v, "") === true;
831
+ })),
832
+ inflight: reqF(ruleOf("count|null", (v) => v === null || (typeof v === "number" && Number.isSafeInteger(v) && v >= 0))),
833
+ bgLive: reqF(ruleOf("count|null", (v) => v === null || (typeof v === "number" && Number.isSafeInteger(v) && v >= 0))),
834
+ unknown: reqF(arrayRule(oneOfRule("card unknown", ["others", "inflight", "bg", "self"]))),
835
+ forcedWithinMs: reqF(R_INT0),
836
+ fingerprint: reqF(R_NONEMPTY),
837
+ });
838
+ const LOCAL_ENGINE_SEAT_READING = armsRule("engine lifecycle", "phase", {
839
+ waiting: { why: reqF(oneOfRule("waiting reason", LOCAL_ENGINE_WAITING_REASONS)), unverifiable: optF(R_TRUE) },
840
+ attached: {},
841
+ pending: { serving: reqF(R_BOOL), card: optF(SWAP_CARD) },
842
+ swapping: { mode: reqF(oneOfRule("swap mode", ["idle", "forced"])) },
843
+ down: { reason: reqF(oneOfRule("down reason", LOCAL_ENGINE_DOWN_REASONS)) },
844
+ behind: { running: reqF(R_NONEMPTY), own: reqF(R_NONEMPTY), upgrade: reqF(oneOfRule("upgrade entry", ["available", "unavailable"])) },
845
+ });
846
+ const R_LIFECYCLE_DERIVED = ruleOf("lifecycle-derived", () => false);
847
+ const R_LIFECYCLE_WITHDRAWN = ruleOf("lifecycle-withdrawn", () => false);
848
+ const R_UNANSWERED_ONLY = ruleOf("unanswered-only", () => false);
849
+ const ENGINE_TARGET_LOCAL_SPEC = {
767
850
  lastBootError: optF(R_STR),
768
851
  mcp: optF(SEAT_LOCAL_MCP_READING),
769
- });
852
+ lifecycle: reqF(LOCAL_ENGINE_SEAT_READING),
853
+ };
854
+ const ENGINE_TARGET_LOCAL = {
855
+ label: "local",
856
+ test: (v, path) => {
857
+ const verdict = shapeVerdict(ENGINE_TARGET_LOCAL_SPEC, v, path);
858
+ if (verdict !== true)
859
+ return verdict;
860
+ const rec = v;
861
+ const lifecycle = own(rec, "lifecycle");
862
+ const phase = own(lifecycle, "phase");
863
+ const bootError = !isAbsent(own(rec, "lastBootError"));
864
+ if (bootError !== (phase === "down"))
865
+ return R_LIFECYCLE_DERIVED.test(undefined, pathAt(path, "lastBootError"));
866
+ if (phase !== "attached" && phase !== "pending" && !isAbsent(own(rec, "mcp")))
867
+ return R_LIFECYCLE_WITHDRAWN.test(undefined, pathAt(path, "mcp"));
868
+ if (phase === "waiting" && own(lifecycle, "why") !== "unanswered" && !isAbsent(own(lifecycle, "unverifiable")))
869
+ return R_UNANSWERED_ONLY.test(undefined, pathAt(pathAt(path, "lifecycle"), "unverifiable"));
870
+ return true;
871
+ },
872
+ };
770
873
  const ENGINE_TARGET_STATE = shapeRule("engine target", {
771
874
  mode: reqF(R_ENGINE_LANE),
772
875
  generation: reqF(R_INT0),
@@ -794,6 +897,8 @@ const ENGINE_TARGET_REFUSED_SPEC = {
794
897
  detail: optF(R_STR),
795
898
  };
796
899
  const checkEngineTargetResult = seatShapeCheck(okArmsRule("engineTarget result", {}, ENGINE_TARGET_REFUSED_SPEC));
900
+ const checkEngineSwapAnswerOutcome = seatShapeCheck(oneOfRule("swap answer", ENGINE_SWAP_ANSWER_OUTCOMES));
901
+ const checkSelfUpgradeOutcome = seatShapeCheck(oneOfRule("self upgrade", SELF_UPGRADE_OUTCOMES));
797
902
  const checkCancelCloudLogin = seatShapeCheck(shapeRule("cancel ack", { ok: reqF(R_BOOL) }));
798
903
  const checkCloudLoginStart = seatShapeCheck(okArmsRule("startCloudLogin result", {
799
904
  verificationUri: reqF(R_DISPLAY_URL),
@@ -971,6 +1076,46 @@ const checkSessionMcpPanelResult = seatCheck((v) => {
971
1076
  return checkSessionMcpPanelFailure(v);
972
1077
  return Object.hasOwn(v, "scenarioRefusal") ? checkSessionMcpPanelRefusalView(v) : checkSessionMcpPanelServersView(v);
973
1078
  });
1079
+ const MOD_ROW_SKIP = shapeRule("mod skip", {
1080
+ registration: reqF(R_NONEMPTY),
1081
+ cause: reqF(R_NONEMPTY),
1082
+ reason: reqF(R_NONEMPTY),
1083
+ });
1084
+ const MOD_ROW_MOUNTED_SPEC = {
1085
+ name: reqF(R_NONEMPTY),
1086
+ seat: reqF(R_NONEMPTY),
1087
+ tier: reqF(R_NONEMPTY),
1088
+ provenance: optF(R_NONEMPTY),
1089
+ events: reqF(arrayRule(R_STR)),
1090
+ observe: optF(arrayRule(R_STR)),
1091
+ skipped: optF(arrayRule(MOD_ROW_SKIP, true)),
1092
+ };
1093
+ const MOD_ROW_REFUSED_SPEC = {
1094
+ name: reqF(R_NONEMPTY),
1095
+ seat: reqF(R_NONEMPTY),
1096
+ tier: reqF(R_NONEMPTY),
1097
+ provenance: optF(R_NONEMPTY),
1098
+ refusedBy: reqF(R_NONEMPTY),
1099
+ reason: reqF(R_NONEMPTY),
1100
+ };
1101
+ const MOD_ROW = {
1102
+ label: "mod row",
1103
+ test: (v, path) => {
1104
+ if (!isPlainRecord(v))
1105
+ return bad("not object", path);
1106
+ return Object.hasOwn(v, "refusedBy") || Object.hasOwn(v, "reason") ? shapeVerdict(MOD_ROW_REFUSED_SPEC, v, path) : shapeVerdict(MOD_ROW_MOUNTED_SPEC, v, path);
1107
+ },
1108
+ };
1109
+ const checkSessionModsFailure = seatShapeCheck(armsRule("readSessionMods failure", "kind", {
1110
+ unreadable: DEVICE_UNREADABLE_SPEC,
1111
+ unarmed: {},
1112
+ }));
1113
+ const checkSessionModsView = seatShapeCheck(shapeRule("mods view", { rows: reqF(arrayRule(MOD_ROW)) }));
1114
+ const checkSessionModsResult = seatCheck((v) => {
1115
+ if (!isPlainRecord(v))
1116
+ return bad("not object");
1117
+ return Object.hasOwn(v, "kind") ? checkSessionModsFailure(v) : checkSessionModsView(v);
1118
+ });
974
1119
  const MCP_TOOL_TOGGLE_KEY = shapeRule("toggle key", {
975
1120
  server: reqF(R_NONEMPTY),
976
1121
  tool: reqF(R_NONEMPTY),
@@ -1066,6 +1211,75 @@ export function planSetComputerUse(request, lockedByEnv) {
1066
1211
  return Object.freeze({ kind: "refused", reason: "confirmation-required" });
1067
1212
  return Object.freeze({ kind: "apply", enabled: intent.kind === "enable" });
1068
1213
  }
1214
+ export const NOTIFICATION_LEVEL_TYPES = Object.freeze(["permission", "question", "idle"]);
1215
+ export const NOTIFICATION_LEVELS = Object.freeze(["off", "badge", "banner"]);
1216
+ export const NOTIFICATION_LEVEL_REFUSAL_REASONS = Object.freeze(["invalid-request", "unsupported-level", "write-failed"]);
1217
+ const R_NOTIFICATION_LEVEL = oneOfRule("notification level", NOTIFICATION_LEVELS);
1218
+ const NOTIFICATION_SUPPORTED_ITEMS = arrayRule(R_NOTIFICATION_LEVEL, true);
1219
+ const NOTIFICATION_SUPPORTED_ORDER = "bad value (supported levels: off first, closed-set order, no repeats)";
1220
+ const R_NOTIFICATION_SUPPORTED = {
1221
+ label: "supported levels",
1222
+ test: (v, path) => {
1223
+ const verdict = NOTIFICATION_SUPPORTED_ITEMS.test(v, path);
1224
+ if (verdict !== true)
1225
+ return verdict;
1226
+ const rank = (x) => NOTIFICATION_LEVELS.indexOf(x);
1227
+ const rows = ownItems(v);
1228
+ if (rows[0] !== "off")
1229
+ return bad(NOTIFICATION_SUPPORTED_ORDER, path);
1230
+ for (let i = 1; i < rows.length; i += 1)
1231
+ if (rank(rows[i]) <= rank(rows[i - 1]))
1232
+ return bad(NOTIFICATION_SUPPORTED_ORDER, `${path}[${i}]`);
1233
+ return true;
1234
+ },
1235
+ };
1236
+ const NOTIFICATION_LEVELS_STATE_SHAPE = shapeRule("notification levels state", {
1237
+ levels: reqF(shapeRule("notification levels", {
1238
+ permission: reqF(R_NOTIFICATION_LEVEL),
1239
+ question: reqF(R_NOTIFICATION_LEVEL),
1240
+ idle: reqF(R_NOTIFICATION_LEVEL),
1241
+ })),
1242
+ supported: reqF(R_NOTIFICATION_SUPPORTED),
1243
+ });
1244
+ const NOTIFICATION_LEVELS_STATE = {
1245
+ label: NOTIFICATION_LEVELS_STATE_SHAPE.label,
1246
+ test: (v, path) => {
1247
+ const verdict = NOTIFICATION_LEVELS_STATE_SHAPE.test(v, path);
1248
+ if (verdict !== true)
1249
+ return verdict;
1250
+ const rec = v;
1251
+ const levels = own(rec, "levels");
1252
+ const supported = ownItems(own(rec, "supported"));
1253
+ for (const t of NOTIFICATION_LEVEL_TYPES)
1254
+ if (!supported.includes(own(levels, t)))
1255
+ return bad("unsupported level", pathAt(path, `levels.${t}`));
1256
+ return true;
1257
+ },
1258
+ };
1259
+ const checkNotificationLevelsState = seatShapeCheck(NOTIFICATION_LEVELS_STATE);
1260
+ const checkSetNotificationLevelResult = seatShapeCheck(okArmsRule("setNotificationLevel result", { state: reqF(NOTIFICATION_LEVELS_STATE) }, {
1261
+ reason: reqF(oneOfRule("notification level refusal", NOTIFICATION_LEVEL_REFUSAL_REASONS)),
1262
+ state: reqF(NOTIFICATION_LEVELS_STATE),
1263
+ }));
1264
+ export function planSetNotificationLevel(type, level, supported) {
1265
+ if (typeof type !== "string" || !inTuple(NOTIFICATION_LEVEL_TYPES, type) || typeof level !== "string" || !inTuple(NOTIFICATION_LEVELS, level)) {
1266
+ return Object.freeze({ kind: "refused", reason: "invalid-request" });
1267
+ }
1268
+ let delivers = false;
1269
+ try {
1270
+ const n = Array.isArray(supported) ? ownDataField(supported, "length") : undefined;
1271
+ if (typeof n === "number" && Number.isSafeInteger(n) && n <= NOTIFICATION_LEVELS.length) {
1272
+ for (let i = 0; i < n && !delivers; i += 1)
1273
+ delivers = own(supported, String(i)) === level;
1274
+ }
1275
+ }
1276
+ catch {
1277
+ delivers = false;
1278
+ }
1279
+ if (!delivers)
1280
+ return Object.freeze({ kind: "refused", reason: "unsupported-level" });
1281
+ return Object.freeze({ kind: "apply", type, level });
1282
+ }
1069
1283
  export const SEAT_ACTION_NAMES = Object.freeze(["new-project", "prefill-composer"]);
1070
1284
  const SEAT_PREFILL_TEXT_MAX = 14336;
1071
1285
  const SEAT_PREFILL_CWD_MAX = 4096;
@@ -1240,11 +1454,77 @@ const checkLocalSessionRecord = seatCheck((s) => {
1240
1454
  if (!isAbsent(lane) && (typeof lane !== "string" || lane.length === 0)) {
1241
1455
  return bad("executionLane must be a non-empty string when present (absent = no writer lane reading)", "executionLane");
1242
1456
  }
1457
+ const parkedRows = own(s, "parkedUnresumable");
1458
+ if (!isAbsent(parkedRows)) {
1459
+ const verdict = R_PARKED_UNRESUMABLE.test(parkedRows, "parkedUnresumable");
1460
+ if (verdict !== true)
1461
+ return verdict;
1462
+ if (parked === false)
1463
+ return bad("bad value (parked:false)", "parkedUnresumable");
1464
+ }
1243
1465
  return true;
1244
1466
  });
1245
1467
  export function isLocalSessionRecord(s) {
1246
1468
  return checkLocalSessionRecord(s) === true;
1247
1469
  }
1470
+ const checkParkedUnresumableSlot = seatCheck((v) => R_PARKED_UNRESUMABLE.test(v, "parkedUnresumable"));
1471
+ const parkedVerdictCopy = (rv) => {
1472
+ const kind = own(rv, "kind");
1473
+ const str = (k) => {
1474
+ const x = own(rv, k);
1475
+ return typeof x === "string" ? x : undefined;
1476
+ };
1477
+ const sentence = str("sentence");
1478
+ if (kind === "lacking" || kind === "damaged") {
1479
+ const reason = str("reason");
1480
+ const requires = own(rv, "requires");
1481
+ return Object.freeze({
1482
+ kind,
1483
+ code: str("code") ?? "",
1484
+ ...(reason !== undefined ? { reason } : {}),
1485
+ ...(Array.isArray(requires) ? { requires: Object.freeze(ownItems(requires).filter((w) => typeof w === "string")) } : {}),
1486
+ sentence: sentence ?? "",
1487
+ });
1488
+ }
1489
+ if (kind === "unknown")
1490
+ return Object.freeze({ kind, word: str("word") ?? "", ...(sentence !== undefined ? { sentence } : {}) });
1491
+ return Object.freeze({ kind: "unreadable" });
1492
+ };
1493
+ const parkedRowCopy = (item) => {
1494
+ const str = (k) => {
1495
+ const x = own(item, k);
1496
+ return typeof x === "string" ? x : undefined;
1497
+ };
1498
+ const rv = own(item, "rowVerdict");
1499
+ const rowKey = str("rowKey");
1500
+ const taskId = str("taskId");
1501
+ const toolName = str("toolName");
1502
+ const rowDeadline = str("rowDeadline");
1503
+ return Object.freeze({
1504
+ rowVerdict: parkedVerdictCopy(typeof rv === "object" && rv !== null ? rv : {}),
1505
+ ...(rowKey !== undefined ? { rowKey } : {}),
1506
+ ...(taskId !== undefined ? { taskId } : {}),
1507
+ ...(toolName !== undefined ? { toolName } : {}),
1508
+ ...(rowDeadline === "armed" || rowDeadline === "none" ? { rowDeadline } : {}),
1509
+ });
1510
+ };
1511
+ export function readSeatParkedUnresumable(record) {
1512
+ try {
1513
+ if (typeof record !== "object" || record === null)
1514
+ return undefined;
1515
+ const v = own(record, "parkedUnresumable");
1516
+ if (isAbsent(v))
1517
+ return undefined;
1518
+ if (own(record, "parked") === false)
1519
+ return undefined;
1520
+ if (checkParkedUnresumableSlot(v) !== true)
1521
+ return undefined;
1522
+ return Object.freeze(ownItems(v).map((item) => parkedRowCopy(item)));
1523
+ }
1524
+ catch {
1525
+ return undefined;
1526
+ }
1527
+ }
1248
1528
  const checkToctouBinding = seatCheck((v) => {
1249
1529
  if (!isPlainRecord(v))
1250
1530
  return bad("toctouBinding must be a plain object", "toctouBinding");
@@ -1750,7 +2030,37 @@ export function isSendMessageAck(v) {
1750
2030
  }
1751
2031
  const checkInterruptAck = seatCheck((v) => isPlainRecord(v) && typeof own(v, "interrupted") === "boolean" ? true : bad("interrupt ack needs a plain object with boolean `interrupted`", "interrupted"));
1752
2032
  const checkStopAck = seatCheck((v) => isPlainRecord(v) && typeof own(v, "stopped") === "boolean" ? true : bad("stop ack needs a plain object with boolean `stopped`", "stopped"));
1753
- const checkOkAck = seatCheck((v) => isPlainRecord(v) && typeof own(v, "ok") === "boolean" ? true : bad("ack needs a plain object with boolean `ok`", "ok"));
2033
+ const okAckVerdict = (v) => isPlainRecord(v) && typeof own(v, "ok") === "boolean" ? true : bad("ack needs a plain object with boolean `ok`", "ok");
2034
+ const checkOkAck = seatCheck(okAckVerdict);
2035
+ const TOOL_PERMISSION_SETTLED_WORDS = Object.freeze(["allow", "deny"]);
2036
+ const R_SETTLED_ELSEWHERE = shapeRule("settled elsewhere", {
2037
+ firstDecision: reqF(oneOfRule("decision word", TOOL_PERMISSION_SETTLED_WORDS)),
2038
+ contrary: reqF(R_BOOL),
2039
+ });
2040
+ const checkToolPermissionAck = seatCheck((v) => {
2041
+ const base = okAckVerdict(v);
2042
+ if (base !== true)
2043
+ return base;
2044
+ const slot = own(v, "settledElsewhere");
2045
+ return isAbsent(slot) ? true : R_SETTLED_ELSEWHERE.test(slot, "settledElsewhere");
2046
+ });
2047
+ const checkSettledElsewhereSlot = seatCheck((v) => R_SETTLED_ELSEWHERE.test(v, "settledElsewhere"));
2048
+ export function readToolPermissionSettledElsewhere(ack) {
2049
+ try {
2050
+ if (typeof ack !== "object" || ack === null)
2051
+ return undefined;
2052
+ const slot = own(ack, "settledElsewhere");
2053
+ if (isAbsent(slot))
2054
+ return undefined;
2055
+ if (checkSettledElsewhereSlot(slot) !== true)
2056
+ return undefined;
2057
+ const first = own(slot, "firstDecision");
2058
+ return Object.freeze({ firstDecision: first === "allow" ? "allow" : "deny", contrary: own(slot, "contrary") === true });
2059
+ }
2060
+ catch {
2061
+ return undefined;
2062
+ }
2063
+ }
1754
2064
  const checkBooleanAck = (v) => typeof v === "boolean" ? true : bad("expected a bare boolean result");
1755
2065
  const checkGetTranscriptResult = seatCheck((v) => {
1756
2066
  if (!isPlainRecord(v))
@@ -1873,7 +2183,7 @@ export const LOCAL_SESSIONS_SPEC = {
1873
2183
  sendMessage: { kind: "invoke", check: checkSendMessageAck },
1874
2184
  interrupt: { kind: "invoke", check: checkInterruptAck },
1875
2185
  stop: { kind: "invoke", check: checkStopAck },
1876
- respondToToolPermission: { kind: "invoke", check: checkOkAck },
2186
+ respondToToolPermission: { kind: "invoke", check: checkToolPermissionAck },
1877
2187
  cancelQueuedMessage: { kind: "invoke", check: checkBooleanAck },
1878
2188
  reorderQueuedMessage: { kind: "invoke", check: checkBooleanAck },
1879
2189
  promoteQueuedMessage: { kind: "invoke", check: checkBooleanAck },
@@ -1898,6 +2208,8 @@ export const LOCAL_SESSIONS_SPEC = {
1898
2208
  connectCloudEngine: { kind: "invoke", check: checkCloudConnectResult },
1899
2209
  configureCloudEngine: { kind: "invoke", check: checkCloudConnectResult },
1900
2210
  clearCloudEngine: { kind: "invoke", check: checkEngineTargetResult },
2211
+ answerEngineSwap: { kind: "invoke", check: checkEngineSwapAnswerOutcome },
2212
+ beginSelfUpgrade: { kind: "invoke", check: checkSelfUpgradeOutcome },
1901
2213
  listOnboardProviders: { kind: "invoke", check: checkOnboardProvidersResult },
1902
2214
  probeOnboardEntry: { kind: "invoke", check: checkOnboardProbeResult },
1903
2215
  applyOnboardEntry: { kind: "invoke", check: checkOnboardApplyResult },
@@ -1907,7 +2219,10 @@ export const LOCAL_SESSIONS_SPEC = {
1907
2219
  setThinkingLatch: { kind: "invoke", check: checkOkAck },
1908
2220
  getComputerUse: { kind: "invoke", check: checkComputerUseState },
1909
2221
  setComputerUse: { kind: "invoke", check: checkSetComputerUseResult },
2222
+ getNotificationLevels: { kind: "invoke", check: checkNotificationLevelsState },
2223
+ setNotificationLevel: { kind: "invoke", check: checkSetNotificationLevelResult },
1910
2224
  claimSeatActions: { kind: "invoke", check: checkOkAck },
2225
+ readSessionMods: { kind: "invoke", check: checkSessionModsResult },
1911
2226
  onEvent: { kind: "event", check: checkLocalSessionEvent },
1912
2227
  onToolPermissionRequest: { kind: "event", check: checkToolPermissionRequest },
1913
2228
  onSeatAction: { kind: "event", check: checkSeatAction },
@@ -1950,6 +2265,8 @@ export const SEAT_METHOD_NAMES = [
1950
2265
  "connectCloudEngine",
1951
2266
  "configureCloudEngine",
1952
2267
  "clearCloudEngine",
2268
+ "answerEngineSwap",
2269
+ "beginSelfUpgrade",
1953
2270
  "listOnboardProviders",
1954
2271
  "probeOnboardEntry",
1955
2272
  "applyOnboardEntry",
@@ -1959,7 +2276,10 @@ export const SEAT_METHOD_NAMES = [
1959
2276
  "setThinkingLatch",
1960
2277
  "getComputerUse",
1961
2278
  "setComputerUse",
2279
+ "getNotificationLevels",
2280
+ "setNotificationLevel",
1962
2281
  "claimSeatActions",
2282
+ "readSessionMods",
1963
2283
  "onEvent",
1964
2284
  "onToolPermissionRequest",
1965
2285
  "onSeatAction",
@@ -2006,6 +2326,12 @@ export const TOOL_PERMISSION_REQUEST_KEYS = [
2006
2326
  "askClass",
2007
2327
  "classes",
2008
2328
  "sessionRow",
2329
+ "probeReason",
2330
+ "probeCause",
2331
+ "feedbackCapable",
2332
+ "requestedBy",
2333
+ "frameReading",
2334
+ "inputSource",
2009
2335
  ];
2010
2336
  export const LOCAL_SESSION_RECORD_KEYS = [
2011
2337
  "sessionId",
@@ -2024,6 +2350,7 @@ export const LOCAL_SESSION_RECORD_KEYS = [
2024
2350
  "thinkingLatch",
2025
2351
  "engine",
2026
2352
  "executionLane",
2353
+ "parkedUnresumable",
2027
2354
  ];
2028
2355
  export const SEND_MESSAGE_REQUEST_KEYS = [
2029
2356
  "sessionId",
@@ -2062,13 +2389,14 @@ export const TOOL_PERMISSION_DECISION_KEYS = [
2062
2389
  "answer",
2063
2390
  "updatedInput",
2064
2391
  "remember",
2392
+ "feedback",
2065
2393
  ];
2066
2394
  export const START_SESSION_OPTION_KEYS = ["model", "title", "cwd", "excludeTools", "engine"];
2067
2395
  export const SEAT_VALIDATOR_KEY_COVERAGE = {
2068
2396
  LocalSessionRecord: {
2069
2397
  guard: "isLocalSessionRecord",
2070
2398
  check: checkLocalSessionRecord,
2071
- validated: ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned", "rowTag", "unreadable", "thinkingLatch", "engine", "executionLane"],
2399
+ validated: ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned", "rowTag", "unreadable", "thinkingLatch", "engine", "executionLane", "parkedUnresumable"],
2072
2400
  unchecked: [],
2073
2401
  },
2074
2402
  ToolPermissionRequest: {
@@ -2112,10 +2440,34 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
2112
2440
  key: "sessionRow",
2113
2441
  why: "放宽方向的展示位(CC-699),判官在过境口 toolPermissionRequestAskBits(card, requestId):卡上「本会话放行」判官 standingRowsOf 的会话行同一前提 ∧ 本请求 requestId 的域带得走(live: / durable:),严格 true 才上座、永不铸 false;座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。消费端 `=== true` 才渲「本会话放行」,其余(缺席 / 坏形)一律不渲 —— 缺席是闭合失败,不是「没说就照渲」。不经过境口自铸座位请求的宿主拿不到这一位,座位卡就不给那一档。",
2114
2442
  },
2443
+ {
2444
+ key: "feedbackCapable",
2445
+ why: "放宽方向的展示位(CC-585),判官在过境口 toolPermissionRequestAskBits(card, requestId):卡判官 answerCarriage(card) 答 model(卡带耐久待决行腿的正向事实 parkRow)∧ 本请求 requestId 的域恰是 durable:(只有 /decide 收放行反馈位),严格 true 才上座、永不铸 false;座位门不设第二判官,理由同 sessionRow(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。消费端 `=== true` 才渲「Yes + 告诉 agent 下一步」那一格输入,其余(缺席 / 坏形)一律不渲 —— 缺席是闭合失败。不经过境口自铸座位请求的宿主拿不到这一位,座位卡就不给那一格。",
2446
+ },
2115
2447
  {
2116
2448
  key: "ruleOffersAbsence",
2117
2449
  why: "喂强制判据口 approvalIsMandated 的位(CC-203;寄存行那条腿的强制只以缺席词 mandated 表达),按开集读(非空串原文字节、词表不校);权威窄读在卡口与过境口,座位门不设第二判官,理由同 mandated。坏形读成缺席 ⇒ 这一路不判强制(放宽方向:寄存行上的强制就丢了;另两路 mandated / mandate 照判);表外串只是不等于 mandated。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
2118
2450
  },
2451
+ {
2452
+ key: "probeReason",
2453
+ why: "展示位(CC-1316),权威窄读在过境口 toolPermissionRequestAskBits,与「为什么问」那一句的读口 askProbeReasonDetail 同一个读点(自有数据属性、取值器不执行;串且去两端空白后非空才在场,原文字节);座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。坏形读成缺席 ⇒ 卡上不显示这一句,不改决断;缺席不是「没有原因」。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
2454
+ },
2455
+ {
2456
+ key: "probeCause",
2457
+ why: "展示位(CC-1316),与 probeReason 同一对、同一个读点;载体层判(自有数据属性、非 null 非数组对象)才在场,同一引用原样搬运,内部成员不校(成员的窄读归 askProbeReasonDetail / probeCauseRowsOf);座位门不设第二判官,理由同 probeReason。坏形读成缺席 ⇒ 不显示因由行,不改决断。两位按键隔离:一位读不出不连坐另一位。",
2458
+ },
2459
+ {
2460
+ key: "requestedBy",
2461
+ why: "展示位(CC-1341),权威窄读在过境口 toolPermissionRequestAskBits,读点是卡口的唯一载体级读口 approvalRequestedByOf(载体顶层的自有数据属性、取值器不执行;kind 恰 extension 且 name 非空串才在场,出冻结的新铸副本);原始耐久待决行不读(上游不在行上铸这一位);座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。坏形读成缺席 ⇒ 卡上不显示发起者行,不改决断;缺席不是「模型发起」。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
2462
+ },
2463
+ {
2464
+ key: "frameReading",
2465
+ why: "展示位(CC-1345),权威窄读在过境口 toolPermissionRequestAskBits,读点是包内唯一读口 cardPayloadReadingOf(卡上 cardPayloadUnreadable 严格 true ∧ cardPayloadUnreadableWhy 是判因闭集三词之一才在场;卡面通用卡第一行按因选句同读它);座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。表外词 / 游离判因词 / 判因未知读成缺席 ⇒ 卡上回落不分因的原句,不改决断;缺席不是「帧读得出」。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
2466
+ },
2467
+ {
2468
+ key: "inputSource",
2469
+ why: "展示位(CC-1366),权威窄读在过境口 toolPermissionRequestAskBits,读点是包内唯一窄读 approvalInputSourceOf(载体顶层的自有数据属性、取值器不执行;闭集 record / stream 两词精确字节才在场);来源位本身只有一个铸点(卡入参读法的读数 → 位),过境口只抄卡上已铸的位、不拿 input 重判来源,原始帧 / 原始耐久待决行直交恒缺席;座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。表外词 / 近义词 / 非串读成缺席 ⇒ 壳按来源不明处置,不改决断;缺席不是 record。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
2470
+ },
2119
2471
  ],
2120
2472
  },
2121
2473
  LocalSessionEvent: {
@@ -2247,6 +2599,11 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
2247
2599
  validated: ["ok"],
2248
2600
  unchecked: [],
2249
2601
  },
2602
+ ToolPermissionAck: {
2603
+ check: checkToolPermissionAck,
2604
+ validated: ["ok", "settledElsewhere"],
2605
+ unchecked: [],
2606
+ },
2250
2607
  GetTranscriptResult: {
2251
2608
  check: checkGetTranscriptResult,
2252
2609
  validated: ["sessionId", "messages"],
@@ -2274,7 +2631,7 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
2274
2631
  },
2275
2632
  SeatCapabilitiesState: {
2276
2633
  check: checkSeatCapabilitiesState,
2277
- validated: ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles", "thinkingLatch", "computerUseSwitch", "engineModeDefaultOnly", "seatActions"],
2634
+ validated: ["pickFolder", "rewind", "recents", "patchSession", "devices", "engineTarget", "onboard", "mcpToolToggles", "thinkingLatch", "computerUseSwitch", "engineModeDefaultOnly", "seatActions", "notificationLevels", "modsView"],
2278
2635
  unchecked: [],
2279
2636
  },
2280
2637
  RecentFoldersResult: {
@@ -2340,7 +2697,12 @@ export const SEAT_VALIDATOR_COVERAGE_EXEMPT = [
2340
2697
  ["ComputerUseState", checkComputerUseState],
2341
2698
  ["SetComputerUseResult", checkSetComputerUseResult],
2342
2699
  ["SetComputerUseRequest", checkSetComputerUseRequest],
2700
+ ["NotificationLevelsState", checkNotificationLevelsState],
2701
+ ["SetNotificationLevelResult", checkSetNotificationLevelResult],
2343
2702
  ["SeatAction", checkSeatAction],
2703
+ ["EngineSwapAnswerOutcome", checkEngineSwapAnswerOutcome],
2704
+ ["SelfUpgradeOutcome", checkSelfUpgradeOutcome],
2705
+ ["SessionModsResult", checkSessionModsResult],
2344
2706
  ].map(([label, check]) => ({
2345
2707
  label,
2346
2708
  check,
@@ -2404,5 +2766,9 @@ const _seatContractPins = [
2404
2766
  true, true, true, true,
2405
2767
  true, true,
2406
2768
  true, true, true, true, true, true, true,
2769
+ true, true, true, true, true, true, true, true,
2770
+ true, true, true, true, true,
2771
+ true, true, true,
2772
+ true, true, true, true,
2407
2773
  ];
2408
2774
  void _seatContractPins;
@@ -6,6 +6,7 @@ import { isLoopbackWireUrl } from './engineWireSdk.js';
6
6
  import { hostEnv } from './hostEnv.js';
7
7
  import { approvalDecisionHolds } from './hitl/approvalHolds.js';
8
8
  import { readRunTerminal } from './runTerminal.js';
9
+ import { isReplayedTerminal } from './replayBody.js';
9
10
  import { appendOwnElement, ownDataField, putOwnKey, readOwnDataFiniteNumber, readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
10
11
  import { msg, renderMessage } from './i18n/translate.js';
11
12
  export function projectSessionBackgroundable(caps) {
@@ -34,6 +35,8 @@ export function readSessionBackgroundable(baseUrl = engineWireTargetBaseUrl()) {
34
35
  return Object.freeze({ kind: 'unobserved' });
35
36
  }
36
37
  }
38
+ const localEngineLanePin = true;
39
+ void localEngineLanePin;
37
40
  export const OPENING_RECORD_CAP = 256;
38
41
  const wireStates = new WeakMap();
39
42
  const isObj = (v) => (typeof v === 'object' && v !== null) || typeof v === 'function';
@@ -416,7 +419,7 @@ function observeFrame(rec, ev) {
416
419
  }
417
420
  else {
418
421
  rec.phase = 'ended-unstarted';
419
- rec.replay = type === 'done' && frameSlot(ev, 'replay') === true;
422
+ rec.replay = type === 'done' && isReplayedTerminal(ev);
420
423
  }
421
424
  return;
422
425
  }
@@ -4,6 +4,7 @@ import { REATTACH_WINDOW_MS, reattachBackoffMs } from './reattachWindow.js';
4
4
  import { terminalEventFromRunRow } from './headlessReconnectWire.js';
5
5
  import { RUN_CANCELLED_CODE } from './runCancelContext.js';
6
6
  import { readRunTerminal } from './runTerminal.js';
7
+ import { isReplayedTerminal } from './replayBody.js';
7
8
  import { readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
8
9
  import { backgroundHandoffSentence, judgeHandoff, ownSlotOf, wireStateOf, } from './sessionBackground.js';
9
10
  export const BACKGROUND_HANDOFF_ABORT_REASON = 'background';
@@ -34,7 +35,7 @@ function executionSettlementOf(ev) {
34
35
  return { runEnded: true, kind: 'cancelled', status: 'failed' };
35
36
  return { runEnded: true, kind: 'failed', status: 'failed', ...(code !== undefined ? { errorCode: code } : {}) };
36
37
  }
37
- if (type !== 'done' || slot(ev, 'replay') === true)
38
+ if (type !== 'done' || isReplayedTerminal(ev))
38
39
  return undefined;
39
40
  const read = readRunTerminal(slot(ev, 'result'));
40
41
  if (read === null)
@@ -153,5 +153,7 @@ export declare function sessionEngineBindingFor(input: SessionEngineBindingInput
153
153
  export declare function isSessionEngineView(v: {} | null | undefined): boolean;
154
154
  export declare function readSessionEngine(record: SessionMapRecord | undefined): SessionEngineReading;
155
155
  export declare function commitSessionEngine(store: SessionMapStorePort, session: SessionEngineSessionRef, request: SessionEngineCommitRequest): SessionEngineCommitResult;
156
+ export type SessionEngineRepointResult = 'moved' | 'unaffected' | 'conflict' | 'unreadable' | 'store-failed' | 'request-invalid';
157
+ export declare function repointSessionEngine(store: SessionMapStorePort, from: string, to: string): SessionEngineRepointResult;
156
158
  export declare function sessionDispatchRefusedFor(refusal: SessionDispatchRefusal): SessionDispatchRefused;
157
159
  export declare function sessionDispatchTarget(reading: SessionEngineReading, ctx: SessionEngineWiring): SessionDispatchDecision;