@sema-agent/client-core 0.95.0 → 0.97.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 (233) hide show
  1. package/CHANGELOG.md +269 -0
  2. package/README.md +61 -31
  3. package/dist/adapt/arms.js +7 -1
  4. package/dist/adapt/toolCards.d.ts +1 -0
  5. package/dist/adapt/toolCards.js +16 -3
  6. package/dist/adapt/wireShapes.js +2 -16
  7. package/dist/adapter/activeRunSelfHeal.d.ts +4 -2
  8. package/dist/adapter/activeRunSelfHeal.js +32 -6
  9. package/dist/adapter/downstream/eventToSdkMessage.js +11 -3
  10. package/dist/adapter/downstream/terminalToSdkResult.js +14 -11
  11. package/dist/adapter/runStream.js +30 -47
  12. package/dist/agentSession/backgroundView.js +2 -15
  13. package/dist/agentSession/engineAgentRegistryRead.js +5 -4
  14. package/dist/agentSession/engineSessionBackgroundStop.js +22 -15
  15. package/dist/agentsWireCaps.d.ts +1 -1
  16. package/dist/agentsWireCaps.js +29 -12
  17. package/dist/approvalDecidedByCapability.d.ts +2 -0
  18. package/dist/approvalDecidedByCapability.js +0 -1
  19. package/dist/approvalsStreamLiveCapability.d.ts +2 -0
  20. package/dist/approvalsStreamLiveCapability.js +3 -2
  21. package/dist/attachmentSeatCapability.d.ts +2 -0
  22. package/dist/attachmentSeatCapability.js +0 -1
  23. package/dist/callerCwdCapability.d.ts +2 -4
  24. package/dist/callerCwdCapability.js +0 -7
  25. package/dist/centerWiringCapability.d.ts +2 -4
  26. package/dist/centerWiringCapability.js +4 -9
  27. package/dist/classifierVerdictWire.js +4 -16
  28. package/dist/clientSlice.js +1 -1
  29. package/dist/cloudConfigWireCaps.d.ts +4 -4
  30. package/dist/cloudConfigWireCaps.js +241 -85
  31. package/dist/coreValuePorts.d.ts +11 -7
  32. package/dist/coreValuePorts.js +5 -8
  33. package/dist/credentialProvenance.d.ts +28 -0
  34. package/dist/credentialProvenance.js +76 -0
  35. package/dist/decideFailureNote.js +3 -1
  36. package/dist/decideReceipt.js +7 -10
  37. package/dist/declared/supportFloorDeclared.js +3 -3
  38. package/dist/deviceExecutorManagementCapability.d.ts +2 -0
  39. package/dist/deviceExecutorManagementCapability.js +3 -2
  40. package/dist/displayUntrusted.d.ts +10 -3
  41. package/dist/displayUntrusted.js +371 -60
  42. package/dist/engineCapReader.d.ts +8 -2
  43. package/dist/engineCapReader.js +15 -7
  44. package/dist/engineCapsCache.d.ts +17 -3
  45. package/dist/engineCapsCache.js +268 -43
  46. package/dist/engineDirectory.d.ts +79 -0
  47. package/dist/engineDirectory.js +186 -0
  48. package/dist/engineErrorCodes.d.ts +17 -1
  49. package/dist/engineErrorCodes.js +46 -16
  50. package/dist/engineNoticeCodes.d.ts +17 -0
  51. package/dist/engineNoticeCodes.js +54 -1
  52. package/dist/executionLaneCapability.d.ts +2 -0
  53. package/dist/executionLaneCapability.js +3 -2
  54. package/dist/fileHistoryCaptureCapability.d.ts +16 -0
  55. package/dist/fileHistoryCaptureCapability.js +98 -2
  56. package/dist/fileHistoryLegNotice.js +4 -0
  57. package/dist/fleet/bgSubagentRow.d.ts +15 -0
  58. package/dist/fleet/bgSubagentRow.js +67 -0
  59. package/dist/fleet/fleetLedger.d.ts +1 -0
  60. package/dist/fleet/fleetLedger.js +164 -126
  61. package/dist/fleet/fleetProjection.d.ts +1 -0
  62. package/dist/fleet/fleetProjection.js +10 -3
  63. package/dist/fleetTaskDesc.js +4 -17
  64. package/dist/gateOutcome.d.ts +12 -1
  65. package/dist/gateOutcome.js +56 -1
  66. package/dist/gateVocabulary.d.ts +2 -2
  67. package/dist/gateVocabulary.js +4 -3
  68. package/dist/generated/engineAskFaceTables.js +1 -1
  69. package/dist/generated/engineFactTables.d.ts +5 -3
  70. package/dist/generated/engineFactTables.js +17 -4
  71. package/dist/generated/engineNoticeTables.js +12 -3
  72. package/dist/generated/sdkFactTables.d.ts +2 -0
  73. package/dist/generated/sdkFactTables.js +7 -0
  74. package/dist/generated/settingsSchemaFns.d.ts +3 -0
  75. package/dist/generated/settingsSchemaFns.js +53 -0
  76. package/dist/generated/toolNameTables.d.ts +1 -1
  77. package/dist/generated/toolNameTables.js +1 -42
  78. package/dist/hitl/approvalDecisionNoteAudit.js +2 -2
  79. package/dist/hitl/approvalEndingCause.d.ts +2 -0
  80. package/dist/hitl/approvalEndingCause.js +26 -21
  81. package/dist/hitl/approvalHolds.d.ts +16 -1
  82. package/dist/hitl/approvalHolds.js +52 -12
  83. package/dist/hitl/askGateWire.js +1 -0
  84. package/dist/hitl/askParkRowRouting.js +1 -1
  85. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  86. package/dist/hitl/automaticAnswerVerdict.js +13 -10
  87. package/dist/hitl/decisionConflict.js +4 -5
  88. package/dist/hitl/decisionRefusal.d.ts +8 -0
  89. package/dist/hitl/decisionRefusal.js +55 -14
  90. package/dist/hitl/frameRouter.d.ts +3 -1
  91. package/dist/hitl/frameRouter.js +58 -39
  92. package/dist/hitl/gateLedger.d.ts +0 -5
  93. package/dist/hitl/gateLedger.js +0 -21
  94. package/dist/hitl/hitlBridge.d.ts +6 -2
  95. package/dist/hitl/hitlBridge.js +46 -11
  96. package/dist/hitl/localAllowRule.d.ts +1 -0
  97. package/dist/hitl/localAllowRule.js +2 -2
  98. package/dist/hitl/noAllowCause.d.ts +2 -1
  99. package/dist/hitl/noAllowCause.js +3 -2
  100. package/dist/hitl/parkResolver.d.ts +1 -0
  101. package/dist/hitl/parkResolver.js +14 -56
  102. package/dist/hitl/parkRowBirthWait.d.ts +1 -0
  103. package/dist/hitl/parkRowBirthWait.js +2 -2
  104. package/dist/hitl/planReviewWire.d.ts +1 -0
  105. package/dist/hitl/planReviewWire.js +98 -20
  106. package/dist/hitl/replayedApproval.d.ts +3 -3
  107. package/dist/hitl/replayedApproval.js +21 -16
  108. package/dist/hitl/sessionPolicyDeliverable.d.ts +0 -1
  109. package/dist/hitl/sessionPolicyDeliverable.js +17 -17
  110. package/dist/hitl/sessionPolicyWire.d.ts +2 -0
  111. package/dist/hitl/sessionPolicyWire.js +15 -3
  112. package/dist/hitl/standingRows.d.ts +19 -0
  113. package/dist/hitl/standingRows.js +148 -0
  114. package/dist/hitl/suspendedReopen.js +2 -1
  115. package/dist/hitl/toolApprovalWire.d.ts +22 -10
  116. package/dist/hitl/toolApprovalWire.js +286 -47
  117. package/dist/hookMatcherVerdict.d.ts +1 -9
  118. package/dist/hookMatcherVerdict.js +21 -61
  119. package/dist/hooksWireCaps.js +2 -2
  120. package/dist/hostCallbackGuard.d.ts +1 -0
  121. package/dist/hostCallbackGuard.js +6 -0
  122. package/dist/index.d.ts +26 -12
  123. package/dist/index.js +20 -10
  124. package/dist/liveModelCatalog.d.ts +13 -0
  125. package/dist/liveModelCatalog.js +56 -0
  126. package/dist/mcpProbeCapability.d.ts +2 -4
  127. package/dist/mcpProbeCapability.js +3 -8
  128. package/dist/mcpWireCaps.d.ts +1 -0
  129. package/dist/mcpWireCaps.js +4 -1
  130. package/dist/memoryComplianceCapability.d.ts +2 -4
  131. package/dist/memoryComplianceCapability.js +3 -8
  132. package/dist/memoryOriginCapability.d.ts +2 -4
  133. package/dist/memoryOriginCapability.js +3 -8
  134. package/dist/memorySpecWire.js +2 -2
  135. package/dist/modelIdentityResolvability.d.ts +2 -2
  136. package/dist/modelIdentityResolvability.js +14 -5
  137. package/dist/noticePresentation.d.ts +68 -0
  138. package/dist/noticePresentation.js +247 -0
  139. package/dist/outputStyleSeatCapability.d.ts +2 -1
  140. package/dist/outputStyleSeatCapability.js +0 -4
  141. package/dist/ownKey.d.ts +2 -0
  142. package/dist/ownKey.js +18 -0
  143. package/dist/peerFrames.js +13 -9
  144. package/dist/peerLaneCapability.d.ts +2 -0
  145. package/dist/peerLaneCapability.js +3 -2
  146. package/dist/permissionModesCapability.d.ts +2 -4
  147. package/dist/permissionModesCapability.js +0 -7
  148. package/dist/permissionRuleIssue.js +0 -3
  149. package/dist/permissionRulesWriteCapability.d.ts +2 -0
  150. package/dist/permissionRulesWriteCapability.js +3 -2
  151. package/dist/permissionsAllowGrantCapability.d.ts +2 -0
  152. package/dist/permissionsAllowGrantCapability.js +4 -2
  153. package/dist/permissionsDeclaration.d.ts +2 -0
  154. package/dist/permissionsDeclaration.js +72 -59
  155. package/dist/printPermissionOutcome.d.ts +12 -0
  156. package/dist/printPermissionOutcome.js +50 -0
  157. package/dist/printToolResultFrame.d.ts +1 -0
  158. package/dist/printToolResultFrame.js +5 -9
  159. package/dist/promptBlockedCopy.d.ts +5 -0
  160. package/dist/promptBlockedCopy.js +35 -0
  161. package/dist/protocolSegment.d.ts +9 -6
  162. package/dist/protocolSegment.js +31 -21
  163. package/dist/providerRejection.d.ts +4 -0
  164. package/dist/providerRejection.js +75 -14
  165. package/dist/replayBody.d.ts +12 -0
  166. package/dist/replayBody.js +25 -0
  167. package/dist/request/taskRequest.d.ts +1 -4
  168. package/dist/request/taskRequest.js +74 -19
  169. package/dist/resumeRefusalCopy.js +9 -25
  170. package/dist/retryStatus.d.ts +9 -1
  171. package/dist/retryStatus.js +9 -2
  172. package/dist/rewindArchiveCapability.d.ts +3 -13
  173. package/dist/rewindArchiveCapability.js +12 -58
  174. package/dist/rewindArchiveReading.d.ts +17 -0
  175. package/dist/rewindArchiveReading.js +55 -0
  176. package/dist/ruleCompileVerdict.d.ts +9 -1
  177. package/dist/ruleCompileVerdict.js +29 -4
  178. package/dist/runTerminal.d.ts +48 -5
  179. package/dist/runTerminal.js +215 -12
  180. package/dist/sandboxWire.js +13 -0
  181. package/dist/sdkWireTransit.d.ts +2 -1
  182. package/dist/sdkWireTransit.js +1 -0
  183. package/dist/sealedKeyCapability.d.ts +2 -4
  184. package/dist/sealedKeyCapability.js +0 -7
  185. package/dist/seam.js +4 -2
  186. package/dist/seatContract.d.ts +76 -11
  187. package/dist/seatContract.js +222 -27
  188. package/dist/sessionPolicyCapability.d.ts +2 -0
  189. package/dist/sessionPolicyCapability.js +3 -2
  190. package/dist/sessionReadRedactionCapability.d.ts +2 -4
  191. package/dist/sessionReadRedactionCapability.js +0 -7
  192. package/dist/sessionSyncFileHistory.d.ts +4 -0
  193. package/dist/sessionSyncFileHistory.js +66 -0
  194. package/dist/sessionSyncFileHistoryCapability.d.ts +2 -1
  195. package/dist/sessionSyncFileHistoryCapability.js +3 -5
  196. package/dist/skillToolListsCapability.d.ts +2 -1
  197. package/dist/skillToolListsCapability.js +3 -5
  198. package/dist/sqlEngineCapability.d.ts +2 -0
  199. package/dist/sqlEngineCapability.js +4 -3
  200. package/dist/steerPriorityCapability.d.ts +2 -1
  201. package/dist/steerPriorityCapability.js +3 -5
  202. package/dist/storePostureCapability.d.ts +2 -4
  203. package/dist/storePostureCapability.js +4 -9
  204. package/dist/subagent/engineSubagentSteer.js +7 -5
  205. package/dist/subagentContentStore.js +4 -15
  206. package/dist/supportFloor.d.ts +1 -0
  207. package/dist/supportFloor.js +13 -9
  208. package/dist/systemReminderTag.d.ts +1 -0
  209. package/dist/systemReminderTag.js +8 -0
  210. package/dist/toolHistoryBadTurn.js +3 -2
  211. package/dist/toolHistoryMismatch.d.ts +0 -3
  212. package/dist/toolHistoryMismatch.js +3 -7
  213. package/dist/toolResult.d.ts +12 -1
  214. package/dist/toolResult.js +55 -1
  215. package/dist/toolResultContent.d.ts +2 -0
  216. package/dist/toolResultContent.js +63 -0
  217. package/dist/usageAnalytics.js +40 -16
  218. package/dist/userInvokedSkillsCapability.d.ts +2 -1
  219. package/dist/userInvokedSkillsCapability.js +3 -5
  220. package/dist/webSearchBackendCapability.d.ts +2 -0
  221. package/dist/webSearchBackendCapability.js +3 -2
  222. package/dist/wireErrorTriage.d.ts +2 -0
  223. package/dist/wireErrorTriage.js +91 -38
  224. package/dist/wireFailureShape.d.ts +20 -3
  225. package/dist/wireFailureShape.js +128 -72
  226. package/dist/workflowsJournalCapability.d.ts +2 -0
  227. package/dist/workflowsJournalCapability.js +3 -2
  228. package/dist/writeProtectionCapability.d.ts +2 -0
  229. package/dist/writeProtectionCapability.js +3 -2
  230. package/docs/INTEGRATION-CLIENTS.md +1784 -20
  231. package/package.json +5 -5
  232. package/dist/engineRefusedToolName.d.ts +0 -1
  233. package/dist/engineRefusedToolName.js +0 -8
@@ -1,6 +1,6 @@
1
1
  import type { ReasoningEffort } from "./effortWire.js";
2
2
  import type { PermissionMode } from "./permissionWireCaps.js";
3
- import type { LaneProof } from "./seam.js";
3
+ import type { ChromeArmKind, LaneProof } from "./seam.js";
4
4
  import type { QuestionAnswer } from "./liveQuestionStore.js";
5
5
  import type { ToolApprovalDelegation } from "./hitl/toolApprovalWire.js";
6
6
  import type { ApprovalMandateWord } from "./gateVocabulary.js";
@@ -40,6 +40,7 @@ export interface LocalSessionRecord {
40
40
  text: string;
41
41
  }>;
42
42
  parked?: boolean;
43
+ pinned?: boolean;
43
44
  }
44
45
  export declare const TOOL_PERMISSION_REQUEST_ID_DOMAINS: readonly ["live:", "durable:", "question:", "elicit:", "plan:"];
45
46
  export type ToolPermissionRequestIdDomain = (typeof TOOL_PERMISSION_REQUEST_ID_DOMAINS)[number];
@@ -67,12 +68,13 @@ export interface ToolPermissionRequest {
67
68
  ruleOffersAbsence?: string;
68
69
  askClass?: string;
69
70
  classes?: readonly string[];
71
+ sessionRow?: true;
70
72
  }
71
73
  declare const SEAT_EVENT_TYPE_TUPLE: readonly ["start", "close", "session_updated", "message", "stream_event", "chrome_event", "error", "tool_permission_resolved"];
72
74
  export type SeatEventType = (typeof SEAT_EVENT_TYPE_TUPLE)[number];
73
75
  export declare const SEAT_EVENT_TYPES: readonly SeatEventType[];
74
- declare const CHROME_EVENT_KIND_TUPLE: readonly ["panel_task", "notification_terminal", "prompt_suggestions", "subagent_lifecycle"];
75
- export type ChromeEventKind = (typeof CHROME_EVENT_KIND_TUPLE)[number];
76
+ declare const CHROME_EVENT_KIND_TUPLE: readonly ["panel_task", "notification_terminal", "prompt_suggestions", "subagent_lifecycle", "text_segment_end", "thinking_segment_end"];
77
+ export type ChromeEventKind = Extract<ChromeArmKind, (typeof CHROME_EVENT_KIND_TUPLE)[number]>;
76
78
  export declare const CHROME_EVENT_KINDS: readonly ChromeEventKind[];
77
79
  export interface SeatChromeEnvelopeBase {
78
80
  kind: ChromeEventKind;
@@ -103,11 +105,13 @@ export interface LocalSessionEvent {
103
105
  chrome?: SeatChromeEnvelope;
104
106
  }
105
107
  export declare const HITL_RESOLUTION_OUTCOMES: readonly string[];
106
- export declare const SEAT_CAPABILITY_NAMES: readonly ["pickFolder", "rewind"];
108
+ export declare const SEAT_CAPABILITY_NAMES: readonly ["pickFolder", "rewind", "recents", "patchSession"];
107
109
  export type SeatCapabilityName = (typeof SEAT_CAPABILITY_NAMES)[number];
108
110
  export interface SeatCapabilitiesState {
109
111
  pickFolder?: boolean;
110
112
  rewind?: boolean;
113
+ recents?: boolean;
114
+ patchSession?: boolean;
111
115
  }
112
116
  export type SeatCapabilityReading = {
113
117
  readonly kind: "reported";
@@ -120,6 +124,28 @@ export type SeatCapabilityReading = {
120
124
  export declare function seatCapability(state: unknown, name: SeatCapabilityName): SeatCapabilityReading;
121
125
  export declare function watchSeatCapability(store: EipcStoreClient<SeatCapabilitiesState> | undefined, name: SeatCapabilityName, onReading: (reading: SeatCapabilityReading) => void): () => void;
122
126
  export declare function seatCapabilityUnavailableDetail(name: SeatCapabilityName, reading: SeatCapabilityReading): string | undefined;
127
+ export interface RecentFolderSession {
128
+ readonly cwd?: string;
129
+ readonly lastActivityAt?: string;
130
+ readonly createdAt?: string;
131
+ }
132
+ export interface RecentFoldersInput {
133
+ readonly sessions?: readonly RecentFolderSession[] | null | undefined;
134
+ readonly registered?: readonly RecentFolderRow[] | null | undefined;
135
+ }
136
+ export declare function recentFoldersOf(input: RecentFoldersInput): string[] | null;
137
+ export type RecentFoldersHostReading = "listed" | "skipped" | "unreadable";
138
+ export interface RecentFoldersReading {
139
+ readonly folders: string[] | null;
140
+ readonly host: RecentFoldersHostReading;
141
+ readonly unreadableRows: number;
142
+ }
143
+ export interface ReadRecentFoldersInput {
144
+ readonly capability: SeatCapabilityReading;
145
+ readonly list: () => Promise<RecentFoldersResult>;
146
+ readonly sessions?: readonly RecentFolderSession[] | null | undefined;
147
+ }
148
+ export declare function readRecentFolders(input: ReadRecentFoldersInput): Promise<RecentFoldersReading>;
123
149
  export interface StartSessionOptions {
124
150
  model?: string;
125
151
  title?: string;
@@ -183,6 +209,12 @@ export declare const ATTACHMENT_UPLOAD_REQUEST_KEYS: readonly ["name", "mimeType
183
209
  export interface SessionScopedRequest {
184
210
  sessionId: string;
185
211
  }
212
+ export interface SessionRowPatchRequest {
213
+ sessionId: string;
214
+ title?: string | null;
215
+ pinned?: boolean;
216
+ }
217
+ export declare const SESSION_ROW_PATCH_REQUEST_KEYS: readonly ["sessionId", "title", "pinned"];
186
218
  export interface AttachmentUploadReceipt {
187
219
  id: string;
188
220
  name: string;
@@ -209,7 +241,6 @@ export interface EipcStoreClient<T> {
209
241
  onStateChange(cb: (state: T) => void): () => void;
210
242
  }
211
243
  export interface SettingsState {
212
- defaultModel: string | null;
213
244
  engineVersion?: string;
214
245
  dataRoot?: string;
215
246
  }
@@ -244,6 +275,13 @@ export interface SessionsState {
244
275
  export interface FocusedSessionState {
245
276
  sessionId: string | null;
246
277
  }
278
+ export interface RecentFolderRow {
279
+ path: string;
280
+ lastUsedAt?: string;
281
+ }
282
+ export interface RecentFoldersResult {
283
+ folders: RecentFolderRow[];
284
+ }
247
285
  export interface LocalSessionsApi {
248
286
  start(opts?: StartSessionOptions): Promise<LocalSessionRecord>;
249
287
  sendMessage(req: SendMessageRequest): Promise<SendMessageAck>;
@@ -261,6 +299,9 @@ export interface LocalSessionsApi {
261
299
  listModels(): Promise<LiveModelCatalog>;
262
300
  applyModelConfig(req: ApplyModelConfigRequest): Promise<ApplyModelConfigResult>;
263
301
  pickFolder(): Promise<string | null>;
302
+ listRecentFolders(): Promise<RecentFoldersResult>;
303
+ noteRecentFolder(path: string): Promise<OkAck>;
304
+ patchSession(req: SessionRowPatchRequest): Promise<LocalSessionRecord>;
264
305
  onEvent(cb: (ev: LocalSessionEvent) => void): () => void;
265
306
  onToolPermissionRequest(cb: (req: ToolPermissionRequest) => void): () => void;
266
307
  sessionsStateStore: EipcStoreClient<SessionsState>;
@@ -294,14 +335,16 @@ export interface ApplyModelConfigResult {
294
335
  }
295
336
  export declare function checkSendMessageRequest(v: unknown): SeatValidation;
296
337
  export declare function isSendMessageRequest(v: unknown): v is SendMessageRequest;
338
+ export declare const checkSessionRowPatchRequest: (v: unknown) => SeatValidation;
339
+ export declare function isSessionRowPatchRequest(v: unknown): v is SessionRowPatchRequest;
297
340
  export declare function isSendMessageAck(v: unknown): v is SendMessageAck;
298
341
  export declare const LOCAL_SESSIONS_SPEC: EipcServiceSpec;
299
- export declare const SEAT_METHOD_NAMES: readonly ["start", "sendMessage", "interrupt", "stop", "respondToToolPermission", "cancelQueuedMessage", "reorderQueuedMessage", "promoteQueuedMessage", "setFocusedSession", "setModel", "getTranscript", "searchSessions", "uploadAttachment", "listModels", "applyModelConfig", "pickFolder", "onEvent", "onToolPermissionRequest"];
342
+ export declare const SEAT_METHOD_NAMES: readonly ["start", "sendMessage", "interrupt", "stop", "respondToToolPermission", "cancelQueuedMessage", "reorderQueuedMessage", "promoteQueuedMessage", "setFocusedSession", "setModel", "getTranscript", "searchSessions", "uploadAttachment", "listModels", "applyModelConfig", "pickFolder", "listRecentFolders", "noteRecentFolder", "patchSession", "onEvent", "onToolPermissionRequest"];
300
343
  export declare const SEAT_STORE_PROPS: readonly ["sessionsStateStore", "focusedSessionStateStore", "settingsStateStore", "seatCapabilitiesStateStore"];
301
344
  export declare const SEAT_EVENT_METHOD_NAMES: readonly ["onEvent", "onToolPermissionRequest"];
302
345
  export declare const LOCAL_SESSION_EVENT_KEYS: readonly ["type", "sessionId", "message", "messages", "error", "errorCategory", "code", "request", "data", "sources", "permissionMode", "session", "userMessageUuid", "hasPreClearSession", "requestId", "outcome", "parked", "chrome"];
303
- export declare const TOOL_PERMISSION_REQUEST_KEYS: readonly ["requestId", "sessionId", "toolName", "toolCallId", "input", "message", "toctouBinding", "createdAtMs", "governanceForced", "delegation", "mandated", "mandate", "origin", "ruleOffersAbsence", "askClass", "classes"];
304
- export declare const LOCAL_SESSION_RECORD_KEYS: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked"];
346
+ export declare const TOOL_PERMISSION_REQUEST_KEYS: readonly ["requestId", "sessionId", "toolName", "toolCallId", "input", "message", "toctouBinding", "createdAtMs", "governanceForced", "delegation", "mandated", "mandate", "origin", "ruleOffersAbsence", "askClass", "classes", "sessionRow"];
347
+ export declare const LOCAL_SESSION_RECORD_KEYS: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned"];
305
348
  export declare const SEND_MESSAGE_REQUEST_KEYS: readonly ["sessionId", "text", "model", "userMessageUuid", "permissionMode", "attachmentIds", "reasoningEffort", "retainBackgroundProcesses", "forwardSubagentEvents", "retainSubagentSessions", "settings", "scenario", "rewind"];
306
349
  export declare const SEAT_SEND_MESSAGE_KEY_ORIGINS: {
307
350
  readonly sessionId: {
@@ -351,7 +394,7 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
351
394
  readonly LocalSessionRecord: {
352
395
  readonly guard: "isLocalSessionRecord";
353
396
  readonly check: (v: unknown) => SeatValidation;
354
- readonly validated: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked"];
397
+ readonly validated: readonly ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned"];
355
398
  readonly unchecked: readonly [];
356
399
  };
357
400
  readonly ToolPermissionRequest: {
@@ -382,6 +425,9 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
382
425
  }, {
383
426
  readonly key: "classes";
384
427
  readonly why: "与 askClass 同一对(CC-284),同在同缺、同一只成对窄读(非空、每员非空串、无重复、首员等于 askClass;开集、原样顺序);座位门不设第二判官,理由同 askClass。";
428
+ }, {
429
+ readonly key: "sessionRow";
430
+ readonly why: "放宽方向的展示位(CC-699),判官在过境口 toolPermissionRequestAskBits(card, requestId):卡上「本会话放行」判官 standingRowsOf 的会话行同一前提 ∧ 本请求 requestId 的域带得走(live: / durable:),严格 true 才上座、永不铸 false;座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。消费端 `=== true` 才渲「本会话放行」,其余(缺席 / 坏形)一律不渲 —— 缺席是闭合失败,不是「没说就照渲」。不经过境口自铸座位请求的宿主拿不到这一位,座位卡就不给那一档。";
385
431
  }, {
386
432
  readonly key: "ruleOffersAbsence";
387
433
  readonly why: "喂强制判据口 approvalIsMandated 的位(CC-203;寄存行那条腿的强制只以缺席词 mandated 表达),按开集读(非空串原文字节、词表不校);权威窄读在卡口与过境口,座位门不设第二判官,理由同 mandated。坏形读成缺席 ⇒ 这一路不判强制(放宽方向:寄存行上的强制就丢了;另两路 mandated / mandate 照判);表外串只是不等于 mandated。不经过境口自铸座位请求的宿主要自己按同一把窄读。";
@@ -408,6 +454,9 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
408
454
  readonly unchecked: readonly [{
409
455
  readonly key: "droppedEntries";
410
456
  readonly why: "诊断面(哪些目录条目没被引擎收下),三态读法归 droppedModelEntriesOf(含坏形 malformed);出站门为它拒掉整份目录 = 选单为一行诊断整个消失。";
457
+ }, {
458
+ readonly key: "candidateRejected";
459
+ readonly why: "诊断面(0.97.0 CC-715;当前配置是候选被整拒后回落的那一份),三态读法归 modelCandidateRejectedOf(含坏形 unreadable);出站门为它拒掉整份目录 = 选单为一行诊断整个消失。";
411
460
  }];
412
461
  };
413
462
  readonly SendMessageRequest: {
@@ -416,6 +465,12 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
416
465
  readonly validated: readonly ["sessionId", "text", "model", "userMessageUuid", "permissionMode", "attachmentIds", "reasoningEffort", "retainBackgroundProcesses", "forwardSubagentEvents", "retainSubagentSessions", "settings", "scenario", "rewind"];
417
466
  readonly unchecked: readonly [];
418
467
  };
468
+ readonly SessionRowPatchRequest: {
469
+ readonly guard: "isSessionRowPatchRequest";
470
+ readonly check: (v: unknown) => SeatValidation;
471
+ readonly validated: readonly ["sessionId", "title", "pinned"];
472
+ readonly unchecked: readonly [];
473
+ };
419
474
  readonly ApplyModelConfigResult: {
420
475
  readonly check: (v: unknown) => SeatValidation;
421
476
  readonly validated: readonly ["ok", "requiresRestart", "reason"];
@@ -464,12 +519,22 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
464
519
  };
465
520
  readonly SettingsState: {
466
521
  readonly check: (v: unknown) => SeatValidation;
467
- readonly validated: readonly ["defaultModel", "engineVersion", "dataRoot"];
522
+ readonly validated: readonly ["engineVersion", "dataRoot"];
468
523
  readonly unchecked: readonly [];
469
524
  };
470
525
  readonly SeatCapabilitiesState: {
471
526
  readonly check: (v: unknown) => SeatValidation;
472
- readonly validated: readonly ["pickFolder", "rewind"];
527
+ readonly validated: readonly ["pickFolder", "rewind", "recents", "patchSession"];
528
+ readonly unchecked: readonly [];
529
+ };
530
+ readonly RecentFoldersResult: {
531
+ readonly check: (v: unknown) => SeatValidation;
532
+ readonly validated: readonly ["folders"];
533
+ readonly unchecked: readonly [];
534
+ };
535
+ readonly RecentFolderRow: {
536
+ readonly check: (v: unknown) => SeatValidation;
537
+ readonly validated: readonly ["path", "lastUsedAt"];
473
538
  readonly unchecked: readonly [];
474
539
  };
475
540
  readonly SeatRewindIntent: {
@@ -1,7 +1,7 @@
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 { ownDataField, ownDataRefusalKeyOf, ownSendableField } from "./ownKey.js";
4
+ import { guardedRead, ownDataField, ownDataRefusalKeyOf, ownSendableField, readOwnDataValue } from "./ownKey.js";
5
5
  const bad = (reason, field) => field === undefined ? { reason } : { reason, field };
6
6
  const nested = (prefix, verdict) => {
7
7
  const path = verdict.field === undefined
@@ -13,8 +13,15 @@ const nested = (prefix, verdict) => {
13
13
  return bad(reason, path);
14
14
  };
15
15
  const isObject = (v) => typeof v === "object" && v !== null;
16
+ const isPlainRecord = (v) => {
17
+ if (!isObject(v) || Array.isArray(v))
18
+ return false;
19
+ const proto = Object.getPrototypeOf(v);
20
+ return proto === Object.prototype || proto === null;
21
+ };
16
22
  const isAbsent = (v) => typeof v === "undefined";
17
23
  const optionalString = (v) => isAbsent(v) || typeof v === "string";
24
+ const isFolderPath = (v) => typeof v === "string" && v.length > 0;
18
25
  const inTuple = (tuple, v) => tuple.includes(v);
19
26
  const own = (o, k) => ownSendableField(o, k);
20
27
  const ownItems = (a) => {
@@ -26,6 +33,16 @@ const ownItems = (a) => {
26
33
  out.push(own(a, String(i)));
27
34
  return out;
28
35
  };
36
+ const sendableKeysOf = (v) => {
37
+ const keys = [];
38
+ for (const k of Reflect.ownKeys(v)) {
39
+ if (typeof k !== "string")
40
+ continue;
41
+ own(v, k);
42
+ keys.push(k);
43
+ }
44
+ return keys;
45
+ };
29
46
  const firstAccessorPath = (root) => {
30
47
  const seen = new Set();
31
48
  const stack = [[root, ""]];
@@ -112,14 +129,16 @@ const SEAT_EVENT_TYPE_TUPLE = [
112
129
  "error",
113
130
  "tool_permission_resolved",
114
131
  ];
115
- export const SEAT_EVENT_TYPES = SEAT_EVENT_TYPE_TUPLE;
132
+ export const SEAT_EVENT_TYPES = Object.freeze(SEAT_EVENT_TYPE_TUPLE);
116
133
  const CHROME_EVENT_KIND_TUPLE = [
117
134
  "panel_task",
118
135
  "notification_terminal",
119
136
  "prompt_suggestions",
120
137
  "subagent_lifecycle",
138
+ "text_segment_end",
139
+ "thinking_segment_end",
121
140
  ];
122
- export const CHROME_EVENT_KINDS = CHROME_EVENT_KIND_TUPLE;
141
+ export const CHROME_EVENT_KINDS = Object.freeze(CHROME_EVENT_KIND_TUPLE);
123
142
  const LANE_PROOF_LANE_TUPLE = ["main", "subagent", "workflow"];
124
143
  export const SEAT_CHROME_ENVELOPE_KEYS = ["kind", "laneProof"];
125
144
  export const HITL_RESOLUTION_OUTCOMES = [
@@ -132,7 +151,7 @@ export const HITL_RESOLUTION_OUTCOMES = [
132
151
  "decline",
133
152
  "cancel",
134
153
  ];
135
- export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind"]);
154
+ export const SEAT_CAPABILITY_NAMES = Object.freeze(["pickFolder", "rewind", "recents", "patchSession"]);
136
155
  const notReported = () => Object.freeze({ kind: "not_reported" });
137
156
  const malformedReading = () => Object.freeze({ kind: "malformed" });
138
157
  const reported = (available) => Object.freeze({ kind: "reported", available });
@@ -206,6 +225,7 @@ export function watchSeatCapability(store, name, onReading) {
206
225
  const SEAT_CAPABILITY_PHRASES = Object.freeze({
207
226
  pickFolder: Object.freeze({ action: "Opening a folder", ability: "show a folder picker", support: "folder picker support" }),
208
227
  rewind: Object.freeze({ action: "Rewinding to an earlier message", ability: "rewind this session", support: "rewind support" }),
228
+ 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" }),
209
229
  });
210
230
  export function seatCapabilityUnavailableDetail(name, reading) {
211
231
  const phrase = Object.hasOwn(SEAT_CAPABILITY_PHRASES, name)
@@ -228,6 +248,96 @@ export function seatCapabilityUnavailableDetail(name, reading) {
228
248
  return `${phrase.action} isn't available: this app hasn't reported ${phrase.support}.`;
229
249
  return `${phrase.action} isn't available: this app's support report couldn't be read.`;
230
250
  }
251
+ const NO_TIME = Number.NEGATIVE_INFINITY;
252
+ const stampMs = (v) => {
253
+ if (typeof v !== "string")
254
+ return NO_TIME;
255
+ const t = Date.parse(v);
256
+ return Number.isFinite(t) ? t : NO_TIME;
257
+ };
258
+ const softField = (o, key) => typeof o === "object" && o !== null ? guardedRead(() => readOwnDataValue(o, key)) : undefined;
259
+ const softItems = (a) => {
260
+ const isArray = guardedRead(() => Array.isArray(a));
261
+ if (isArray !== true)
262
+ return undefined;
263
+ const n = softField(a, "length");
264
+ if (typeof n !== "number" || !Number.isSafeInteger(n) || n < 0)
265
+ return undefined;
266
+ const out = [];
267
+ for (let i = 0; i < n; i += 1)
268
+ out.push(softField(a, String(i)));
269
+ return out;
270
+ };
271
+ export function recentFoldersOf(input) {
272
+ const sessions = softItems(softField(input, "sessions"));
273
+ const registered = softItems(softField(input, "registered"));
274
+ if (sessions === undefined && registered === undefined)
275
+ return null;
276
+ const byPath = new Map();
277
+ let order = 0;
278
+ const place = (path, at) => {
279
+ const cur = byPath.get(path);
280
+ order += 1;
281
+ if (cur === undefined)
282
+ byPath.set(path, { at, order });
283
+ else if (at > cur.at)
284
+ cur.at = at;
285
+ };
286
+ for (const row of registered ?? []) {
287
+ const path = softField(row, "path");
288
+ if (isFolderPath(path))
289
+ place(path, stampMs(softField(row, "lastUsedAt")));
290
+ }
291
+ for (const rec of sessions ?? []) {
292
+ const cwd = softField(rec, "cwd");
293
+ if (!isFolderPath(cwd))
294
+ continue;
295
+ const active = stampMs(softField(rec, "lastActivityAt"));
296
+ place(cwd, active !== NO_TIME ? active : stampMs(softField(rec, "createdAt")));
297
+ }
298
+ return [...byPath.entries()]
299
+ .sort(([, x], [, y]) => (x.at === y.at ? x.order - y.order : x.at > y.at ? -1 : 1))
300
+ .map(([path]) => path);
301
+ }
302
+ export async function readRecentFolders(input) {
303
+ const capability = guardedRead(() => input.capability);
304
+ const list = guardedRead(() => input.list);
305
+ const sessions = guardedRead(() => input.sessions);
306
+ let registered;
307
+ let host = "skipped";
308
+ let unreadableRows = 0;
309
+ if (capability !== undefined && seatCapabilityUnavailableDetail("recents", capability) === undefined) {
310
+ try {
311
+ const items = softItems(softField(await list(), "folders"));
312
+ if (items === undefined) {
313
+ host = "unreadable";
314
+ }
315
+ else {
316
+ const rows = [];
317
+ for (const item of items) {
318
+ const path = softField(item, "path");
319
+ if (!isFolderPath(path)) {
320
+ unreadableRows += 1;
321
+ continue;
322
+ }
323
+ const lastUsedAt = softField(item, "lastUsedAt");
324
+ rows.push(typeof lastUsedAt === "string" ? { path, lastUsedAt } : { path });
325
+ }
326
+ if (items.length > 0 && rows.length === 0) {
327
+ host = "unreadable";
328
+ }
329
+ else {
330
+ registered = rows;
331
+ host = "listed";
332
+ }
333
+ }
334
+ }
335
+ catch {
336
+ host = "unreadable";
337
+ }
338
+ }
339
+ return Object.freeze({ folders: recentFoldersOf({ sessions, registered }), host, unreadableRows });
340
+ }
231
341
  export const PERMISSION_MODE_INTENTS = [...PERMISSION_MODE_WORDS];
232
342
  export const ATTACHMENT_IDS_PER_TASK_CAP = 16;
233
343
  export const SEAT_REASONING_EFFORTS = [...REASONING_EFFORT_WORDS];
@@ -241,6 +351,7 @@ export const SEAT_TURN_SETTINGS_ORIGINS = Object.freeze({
241
351
  });
242
352
  export const SEAT_REWIND_INTENT_KEYS = ["mode", "targetMessageUuid"];
243
353
  export const ATTACHMENT_UPLOAD_REQUEST_KEYS = ["name", "mimeType", "bytes"];
354
+ export const SESSION_ROW_PATCH_REQUEST_KEYS = Object.freeze(["sessionId", "title", "pinned"]);
244
355
  export const SESSION_SEARCH_RESULT_KEYS = ["sessionId", "title", "matches"];
245
356
  export const GET_TRANSCRIPT_RESULT_KEYS = ["sessionId", "messages"];
246
357
  const checkLocalSessionRecord = seatCheck((s) => {
@@ -255,7 +366,7 @@ const checkLocalSessionRecord = seatCheck((s) => {
255
366
  if (!optionalString(own(s, "title")))
256
367
  return bad("title must be a string when present", "title");
257
368
  const cwd = own(s, "cwd");
258
- if (!isAbsent(cwd) && (typeof cwd !== "string" || cwd.length === 0)) {
369
+ if (!isAbsent(cwd) && !isFolderPath(cwd)) {
259
370
  return bad("cwd must be a non-empty path string when present (absent = no folder chosen)", "cwd");
260
371
  }
261
372
  if (typeof own(s, "isRunning") !== "boolean")
@@ -274,6 +385,10 @@ const checkLocalSessionRecord = seatCheck((s) => {
274
385
  if (!isAbsent(parked) && typeof parked !== "boolean") {
275
386
  return bad("parked must be a boolean when present", "parked");
276
387
  }
388
+ const pinned = own(s, "pinned");
389
+ if (!isAbsent(pinned) && typeof pinned !== "boolean") {
390
+ return bad("pinned must be a boolean when present (absent = not pinned or unknown)", "pinned");
391
+ }
277
392
  return true;
278
393
  });
279
394
  export function isLocalSessionRecord(s) {
@@ -487,9 +602,9 @@ const checkLiveModelCatalog = seatCheck((v) => {
487
602
  return true;
488
603
  });
489
604
  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)) {
605
+ if (!isPlainRecord(v))
606
+ return bad("rewind must be a plain object {mode, targetMessageUuid}");
607
+ for (const k of sendableKeysOf(v)) {
493
608
  if (!inTuple(SEAT_REWIND_INTENT_KEYS, k))
494
609
  return bad(`unknown key (closed shape: ${SEAT_REWIND_INTENT_KEYS.join(", ")})`, k);
495
610
  }
@@ -503,9 +618,9 @@ const checkSeatRewindIntent = seatCheck((v) => {
503
618
  return true;
504
619
  });
505
620
  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)) {
621
+ if (!isPlainRecord(v))
622
+ return bad("settings must be a plain object");
623
+ for (const k of sendableKeysOf(v)) {
509
624
  if (!inTuple(SEAT_TURN_SETTINGS_KEYS, k)) {
510
625
  const host = Object.hasOwn(SEAT_TURN_SETTINGS_ORIGINS, k);
511
626
  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);
@@ -519,9 +634,9 @@ const checkSeatTurnSettings = seatCheck((v) => {
519
634
  const checkRetainSubagentSessions = seatCheck((v) => {
520
635
  if (typeof v === "boolean")
521
636
  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)) {
637
+ if (!isPlainRecord(v))
638
+ return bad("retainSubagentSessions must be a boolean or a plain object {ttlMs?, max?}");
639
+ for (const k of sendableKeysOf(v)) {
525
640
  if (k !== "ttlMs" && k !== "max")
526
641
  return bad("unknown key (closed shape: ttlMs, max)", k);
527
642
  const n = own(v, k);
@@ -532,13 +647,13 @@ const checkRetainSubagentSessions = seatCheck((v) => {
532
647
  });
533
648
  export function checkSendMessageRequest(v) {
534
649
  try {
535
- if (!isObject(v) || Array.isArray(v))
536
- return bad("sendMessage request is not an object");
650
+ if (!isPlainRecord(v))
651
+ return bad("sendMessage request is not a plain object");
537
652
  const at = firstAccessorPath(v);
538
653
  if (at !== undefined)
539
654
  return bad(NOT_PLAIN_DATA, at);
540
- const body = {};
541
- for (const k of Object.keys(v)) {
655
+ const body = Object.create(null);
656
+ for (const k of sendableKeysOf(v)) {
542
657
  if (!inTuple(SEND_MESSAGE_REQUEST_KEYS, k))
543
658
  return bad(`unknown key (closed shape: ${SEND_MESSAGE_REQUEST_KEYS.join(", ")})`, k);
544
659
  body[k] = own(v, k);
@@ -597,6 +712,30 @@ export function checkSendMessageRequest(v) {
597
712
  export function isSendMessageRequest(v) {
598
713
  return checkSendMessageRequest(v) === true;
599
714
  }
715
+ export const checkSessionRowPatchRequest = seatCheck((v) => {
716
+ if (!isPlainRecord(v))
717
+ return bad("patchSession request is not a plain object");
718
+ const body = Object.create(null);
719
+ for (const k of sendableKeysOf(v)) {
720
+ if (!inTuple(SESSION_ROW_PATCH_REQUEST_KEYS, k))
721
+ return bad(`unknown key (closed shape: ${SESSION_ROW_PATCH_REQUEST_KEYS.join(", ")})`, k);
722
+ body[k] = own(v, k);
723
+ }
724
+ if (typeof body.sessionId !== "string" || body.sessionId.length === 0)
725
+ return bad("sessionId must be a non-empty string", "sessionId");
726
+ const { title, pinned } = body;
727
+ if (!isAbsent(title) && title !== null && (typeof title !== "string" || title.length === 0)) {
728
+ return bad('title must be a non-empty string, or null to clear it back to the automatic title (an empty string is not a way to clear)', "title");
729
+ }
730
+ if (!isAbsent(pinned) && typeof pinned !== "boolean")
731
+ return bad("pinned must be a boolean when present", "pinned");
732
+ if (isAbsent(title) && isAbsent(pinned))
733
+ return bad("nothing to change: carry at least one of title / pinned");
734
+ return true;
735
+ });
736
+ export function isSessionRowPatchRequest(v) {
737
+ return checkSessionRowPatchRequest(v) === true;
738
+ }
600
739
  const checkSendMessageAck = seatCheck((v) => {
601
740
  if (!isObject(v))
602
741
  return bad("sendMessage ack is not an object");
@@ -678,11 +817,10 @@ const checkFocusedSessionState = seatCheck((v) => {
678
817
  return true;
679
818
  });
680
819
  const checkSettingsState = seatCheck((v) => {
681
- if (!isObject(v))
682
- return bad("settings state is not an object");
683
- const defaultModel = own(v, "defaultModel");
684
- if (defaultModel !== null && typeof defaultModel !== "string") {
685
- return bad("defaultModel must be a string or null", "defaultModel");
820
+ if (!isPlainRecord(v))
821
+ return bad("settings state is not a plain object");
822
+ if (Object.hasOwn(v, "defaultModel")) {
823
+ return bad("defaultModel is not carried in settings state: read the deployment default model from the model catalog (liveDefaultModelOf over the listModels() result)", "defaultModel");
686
824
  }
687
825
  if (!optionalString(own(v, "engineVersion")))
688
826
  return bad("engineVersion must be a string when present", "engineVersion");
@@ -690,9 +828,32 @@ const checkSettingsState = seatCheck((v) => {
690
828
  return bad("dataRoot must be a string when present", "dataRoot");
691
829
  return true;
692
830
  });
693
- const checkPickFolderResult = (v) => v === null || (typeof v === "string" && v.length > 0)
831
+ const checkPickFolderResult = (v) => v === null || isFolderPath(v)
694
832
  ? true
695
833
  : bad("pickFolder result must be null (cancelled) or a non-empty path string");
834
+ const checkRecentFolderRow = seatCheck((v) => {
835
+ if (!isPlainRecord(v))
836
+ return bad("recent folder row is not a plain object");
837
+ if (!isFolderPath(own(v, "path")))
838
+ return bad("path must be a non-empty path string", "path");
839
+ if (!optionalString(own(v, "lastUsedAt")))
840
+ return bad("lastUsedAt must be a string when present", "lastUsedAt");
841
+ return true;
842
+ });
843
+ const checkRecentFoldersResult = seatCheck((v) => {
844
+ if (!isPlainRecord(v))
845
+ return bad("recent folders result is not a plain object");
846
+ const folders = own(v, "folders");
847
+ if (!Array.isArray(folders))
848
+ return bad("folders must be an array", "folders");
849
+ const rows = ownItems(folders);
850
+ for (let i = 0; i < rows.length; i += 1) {
851
+ const verdict = checkRecentFolderRow(rows[i]);
852
+ if (verdict !== true)
853
+ return nested(`folders[${i}]`, verdict);
854
+ }
855
+ return true;
856
+ });
696
857
  const checkSeatCapabilitiesState = seatCheck((v) => {
697
858
  if (!isObject(v) || Array.isArray(v))
698
859
  return bad("seat capabilities state is not an object");
@@ -730,6 +891,8 @@ export const LOCAL_SESSIONS_SPEC = {
730
891
  listModels: { kind: "invoke", check: checkLiveModelCatalog },
731
892
  applyModelConfig: { kind: "invoke", check: checkApplyModelConfigResult },
732
893
  pickFolder: { kind: "invoke", check: checkPickFolderResult },
894
+ listRecentFolders: { kind: "invoke", check: checkRecentFoldersResult },
895
+ noteRecentFolder: { kind: "invoke", check: checkOkAck }, patchSession: { kind: "invoke", check: checkLocalSessionRecord },
733
896
  onEvent: { kind: "event", check: checkLocalSessionEvent },
734
897
  onToolPermissionRequest: { kind: "event", check: checkToolPermissionRequest },
735
898
  },
@@ -757,6 +920,8 @@ export const SEAT_METHOD_NAMES = [
757
920
  "listModels",
758
921
  "applyModelConfig",
759
922
  "pickFolder",
923
+ "listRecentFolders",
924
+ "noteRecentFolder", "patchSession",
760
925
  "onEvent",
761
926
  "onToolPermissionRequest",
762
927
  ];
@@ -804,6 +969,7 @@ export const TOOL_PERMISSION_REQUEST_KEYS = [
804
969
  "ruleOffersAbsence",
805
970
  "askClass",
806
971
  "classes",
972
+ "sessionRow",
807
973
  ];
808
974
  export const LOCAL_SESSION_RECORD_KEYS = [
809
975
  "sessionId",
@@ -816,6 +982,7 @@ export const LOCAL_SESSION_RECORD_KEYS = [
816
982
  "lastActivityAt",
817
983
  "queuedMessages",
818
984
  "parked",
985
+ "pinned",
819
986
  ];
820
987
  export const SEND_MESSAGE_REQUEST_KEYS = [
821
988
  "sessionId",
@@ -860,7 +1027,7 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
860
1027
  LocalSessionRecord: {
861
1028
  guard: "isLocalSessionRecord",
862
1029
  check: checkLocalSessionRecord,
863
- validated: ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked"],
1030
+ validated: ["sessionId", "engineSessionId", "model", "title", "cwd", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked", "pinned"],
864
1031
  unchecked: [],
865
1032
  },
866
1033
  ToolPermissionRequest: {
@@ -900,6 +1067,10 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
900
1067
  key: "classes",
901
1068
  why: "与 askClass 同一对(CC-284),同在同缺、同一只成对窄读(非空、每员非空串、无重复、首员等于 askClass;开集、原样顺序);座位门不设第二判官,理由同 askClass。",
902
1069
  },
1070
+ {
1071
+ key: "sessionRow",
1072
+ why: "放宽方向的展示位(CC-699),判官在过境口 toolPermissionRequestAskBits(card, requestId):卡上「本会话放行」判官 standingRowsOf 的会话行同一前提 ∧ 本请求 requestId 的域带得走(live: / durable:),严格 true 才上座、永不铸 false;座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。消费端 `=== true` 才渲「本会话放行」,其余(缺席 / 坏形)一律不渲 —— 缺席是闭合失败,不是「没说就照渲」。不经过境口自铸座位请求的宿主拿不到这一位,座位卡就不给那一档。",
1073
+ },
903
1074
  {
904
1075
  key: "ruleOffersAbsence",
905
1076
  why: "喂强制判据口 approvalIsMandated 的位(CC-203;寄存行那条腿的强制只以缺席词 mandated 表达),按开集读(非空串原文字节、词表不校);权威窄读在卡口与过境口,座位门不设第二判官,理由同 mandated。坏形读成缺席 ⇒ 这一路不判强制(放宽方向:寄存行上的强制就丢了;另两路 mandated / mandate 照判);表外串只是不等于 mandated。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
@@ -949,6 +1120,10 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
949
1120
  key: "droppedEntries",
950
1121
  why: "诊断面(哪些目录条目没被引擎收下),三态读法归 droppedModelEntriesOf(含坏形 malformed);出站门为它拒掉整份目录 = 选单为一行诊断整个消失。",
951
1122
  },
1123
+ {
1124
+ key: "candidateRejected",
1125
+ why: "诊断面(0.97.0 CC-715;当前配置是候选被整拒后回落的那一份),三态读法归 modelCandidateRejectedOf(含坏形 unreadable);出站门为它拒掉整份目录 = 选单为一行诊断整个消失。",
1126
+ },
952
1127
  ],
953
1128
  },
954
1129
  SendMessageRequest: {
@@ -971,6 +1146,12 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
971
1146
  ],
972
1147
  unchecked: [],
973
1148
  },
1149
+ SessionRowPatchRequest: {
1150
+ guard: "isSessionRowPatchRequest",
1151
+ check: checkSessionRowPatchRequest,
1152
+ validated: ["sessionId", "title", "pinned"],
1153
+ unchecked: [],
1154
+ },
974
1155
  ApplyModelConfigResult: {
975
1156
  check: checkApplyModelConfigResult,
976
1157
  validated: ["ok", "requiresRestart", "reason"],
@@ -1019,12 +1200,22 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
1019
1200
  },
1020
1201
  SettingsState: {
1021
1202
  check: checkSettingsState,
1022
- validated: ["defaultModel", "engineVersion", "dataRoot"],
1203
+ validated: ["engineVersion", "dataRoot"],
1023
1204
  unchecked: [],
1024
1205
  },
1025
1206
  SeatCapabilitiesState: {
1026
1207
  check: checkSeatCapabilitiesState,
1027
- validated: ["pickFolder", "rewind"],
1208
+ validated: ["pickFolder", "rewind", "recents", "patchSession"],
1209
+ unchecked: [],
1210
+ },
1211
+ RecentFoldersResult: {
1212
+ check: checkRecentFoldersResult,
1213
+ validated: ["folders"],
1214
+ unchecked: [],
1215
+ },
1216
+ RecentFolderRow: {
1217
+ check: checkRecentFolderRow,
1218
+ validated: ["path", "lastUsedAt"],
1028
1219
  unchecked: [],
1029
1220
  },
1030
1221
  SeatRewindIntent: {
@@ -1087,5 +1278,9 @@ const _seatContractPins = [
1087
1278
  true, true, true, true, true, true, true, true,
1088
1279
  true, true, true, true, true,
1089
1280
  true, true, true, true, true, true, true, true,
1281
+ true, true,
1282
+ true, true,
1283
+ true, true, true, true,
1284
+ true, true, true, true, true, true,
1090
1285
  ];
1091
1286
  void _seatContractPins;
@@ -1,5 +1,7 @@
1
1
  export type SessionPolicyReading = {
2
2
  kind: 'unobserved';
3
+ } | {
4
+ kind: 'unreadable';
3
5
  } | {
4
6
  kind: 'not_reported';
5
7
  } | {