@sema-agent/client-core 0.93.1 → 0.95.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (321) hide show
  1. package/CHANGELOG.md +554 -0
  2. package/README.md +89 -55
  3. package/dist/adapt/arms.js +13 -11
  4. package/dist/adapt/panelTasks.js +4 -10
  5. package/dist/adapt/toolCards.js +2 -2
  6. package/dist/adapt/wireShapes.js +3 -8
  7. package/dist/adapter/activeRunSelfHeal.d.ts +8 -3
  8. package/dist/adapter/activeRunSelfHeal.js +20 -12
  9. package/dist/adapter/downstream/eventToSdkMessage.js +24 -17
  10. package/dist/adapter/downstream/terminalToSdkResult.js +13 -6
  11. package/dist/adapter/runStream.js +2 -1
  12. package/dist/adapter/types.d.ts +7 -0
  13. package/dist/adapter/types.js +15 -0
  14. package/dist/agentSession/backgroundView.js +5 -1
  15. package/dist/agentSession/engineAgentRegistryRead.js +2 -1
  16. package/dist/agentSession/engineSessionBackgroundStop.js +5 -3
  17. package/dist/agentsWireCaps.d.ts +17 -0
  18. package/dist/agentsWireCaps.js +111 -1
  19. package/dist/approvalDecidedByCapability.d.ts +0 -1
  20. package/dist/approvalDecidedByCapability.js +2 -7
  21. package/dist/approvalReachWire.d.ts +18 -0
  22. package/dist/approvalReachWire.js +58 -0
  23. package/dist/approvalsStreamLiveCapability.d.ts +0 -1
  24. package/dist/approvalsStreamLiveCapability.js +15 -14
  25. package/dist/atMostOnce.d.ts +8 -0
  26. package/dist/atMostOnce.js +36 -0
  27. package/dist/attachmentSeatCapability.d.ts +0 -1
  28. package/dist/attachmentSeatCapability.js +0 -3
  29. package/dist/attachmentsWireCaps.js +11 -6
  30. package/dist/bashExitReading.d.ts +10 -0
  31. package/dist/bashExitReading.js +12 -0
  32. package/dist/callerCwdCapability.d.ts +15 -0
  33. package/dist/callerCwdCapability.js +42 -0
  34. package/dist/centerWiringCapability.d.ts +1 -3
  35. package/dist/centerWiringCapability.js +18 -21
  36. package/dist/classifierStatus.js +4 -4
  37. package/dist/cloudConfigWireCaps.js +43 -21
  38. package/dist/compensations.js +1 -1
  39. package/dist/controlRouter.js +3 -10
  40. package/dist/coreValuePorts.d.ts +64 -1
  41. package/dist/coreValuePorts.js +30 -0
  42. package/dist/cycleOrder.d.ts +15 -0
  43. package/dist/cycleOrder.js +45 -0
  44. package/dist/decideFailureNote.js +4 -1
  45. package/dist/decideReceipt.d.ts +2 -1
  46. package/dist/decideReceipt.js +41 -13
  47. package/dist/declared/supportFloorDeclared.d.ts +1 -0
  48. package/dist/declared/supportFloorDeclared.js +5 -0
  49. package/dist/detachWire.d.ts +1 -4
  50. package/dist/detachWire.js +1 -1
  51. package/dist/deviceExecutorManagementCapability.d.ts +0 -1
  52. package/dist/deviceExecutorManagementCapability.js +36 -40
  53. package/dist/deviceFlowPolling.d.ts +5 -0
  54. package/dist/deviceFlowPolling.js +28 -0
  55. package/dist/deviceRebind.d.ts +88 -0
  56. package/dist/deviceRebind.js +242 -0
  57. package/dist/displayUntrusted.d.ts +1 -0
  58. package/dist/displayUntrusted.js +963 -30
  59. package/dist/engineAgentAbsence.d.ts +2 -2
  60. package/dist/engineAgentPanelStore.d.ts +8 -18
  61. package/dist/engineAgentPanelStore.js +19 -537
  62. package/dist/engineCapReader.d.ts +6 -6
  63. package/dist/engineCapReader.js +30 -43
  64. package/dist/engineCapsCache.d.ts +7 -2
  65. package/dist/engineCapsCache.js +64 -26
  66. package/dist/engineCredentialRequirement.d.ts +9 -0
  67. package/dist/engineCredentialRequirement.js +23 -0
  68. package/dist/engineEnvSourcing.d.ts +53 -0
  69. package/dist/engineEnvSourcing.js +81 -0
  70. package/dist/engineErrorCodes.d.ts +19 -4
  71. package/dist/engineErrorCodes.js +39 -21
  72. package/dist/engineIdentity.js +2 -0
  73. package/dist/engineNoticeCodes.d.ts +22 -2
  74. package/dist/engineNoticeCodes.js +73 -6
  75. package/dist/engineRefusedToolName.d.ts +1 -0
  76. package/dist/engineRefusedToolName.js +8 -0
  77. package/dist/engineWireSdk.js +2 -2
  78. package/dist/executionLaneCapability.d.ts +2 -3
  79. package/dist/executionLaneCapability.js +28 -28
  80. package/dist/fileHistoryCaptureCapability.d.ts +0 -1
  81. package/dist/fileHistoryCaptureCapability.js +13 -12
  82. package/dist/fileHistoryLegNotice.d.ts +14 -2
  83. package/dist/fileHistoryLegNotice.js +101 -15
  84. package/dist/fleet/fleetLedger.d.ts +2 -0
  85. package/dist/fleet/fleetLedger.js +74 -52
  86. package/dist/fleet/fleetProjection.d.ts +0 -3
  87. package/dist/fleet/fleetProjection.js +9 -16
  88. package/dist/fleetAgentPanelProjection.d.ts +4 -17
  89. package/dist/fleetAgentPanelProjection.js +7 -197
  90. package/dist/fleetAgentRowLike.d.ts +16 -0
  91. package/dist/fleetAgentRowLike.js +1 -0
  92. package/dist/gateOutcome.d.ts +2 -1
  93. package/dist/gateOutcome.js +33 -18
  94. package/dist/gateVocabulary.js +1 -1
  95. package/dist/generated/engineAskFaceTables.d.ts +3 -0
  96. package/dist/generated/engineAskFaceTables.js +12 -0
  97. package/dist/generated/engineFactTables.d.ts +4 -2
  98. package/dist/generated/engineFactTables.js +13 -0
  99. package/dist/generated/engineNoticeTables.d.ts +5 -0
  100. package/dist/generated/engineNoticeTables.js +7 -0
  101. package/dist/generated/sdkFactTables.d.ts +5 -0
  102. package/dist/generated/sdkFactTables.js +34 -0
  103. package/dist/generated/settingsSchemaFns.d.ts +10 -0
  104. package/dist/generated/settingsSchemaFns.js +22 -0
  105. package/dist/generated/settingsSchemaTables.d.ts +3 -0
  106. package/dist/generated/settingsSchemaTables.js +3 -0
  107. package/dist/headlessPermissionModeWire.d.ts +2 -2
  108. package/dist/headlessPermissionModeWire.js +11 -21
  109. package/dist/headlessReconnectWire.js +49 -20
  110. package/dist/hitl/allowRuleShadow.d.ts +1 -1
  111. package/dist/hitl/allowRuleShadow.js +49 -8
  112. package/dist/hitl/approvalCompleteParked.d.ts +1 -0
  113. package/dist/hitl/approvalCompleteParked.js +14 -0
  114. package/dist/hitl/approvalEndingCause.d.ts +5 -0
  115. package/dist/hitl/approvalEndingCause.js +61 -0
  116. package/dist/hitl/approvalHolds.d.ts +46 -0
  117. package/dist/hitl/approvalHolds.js +140 -0
  118. package/dist/hitl/approvalOutcomeNote.js +2 -1
  119. package/dist/hitl/approvalResolution.js +9 -1
  120. package/dist/hitl/approvalsFeed.js +23 -6
  121. package/dist/hitl/askGateWire.d.ts +2 -1
  122. package/dist/hitl/askGateWire.js +29 -1
  123. package/dist/hitl/automaticAnswerVerdict.d.ts +8 -2
  124. package/dist/hitl/automaticAnswerVerdict.js +71 -23
  125. package/dist/hitl/crashConverged.js +2 -0
  126. package/dist/hitl/decisionConflict.d.ts +3 -0
  127. package/dist/hitl/decisionConflict.js +43 -0
  128. package/dist/hitl/decisionRefusal.d.ts +23 -0
  129. package/dist/hitl/decisionRefusal.js +88 -0
  130. package/dist/hitl/frameRouter.d.ts +10 -0
  131. package/dist/hitl/frameRouter.js +71 -32
  132. package/dist/hitl/gateLedger.d.ts +8 -0
  133. package/dist/hitl/gateLedger.js +38 -0
  134. package/dist/hitl/hitlBridge.d.ts +14 -3
  135. package/dist/hitl/hitlBridge.js +75 -62
  136. package/dist/hitl/hitlHostSurface.d.ts +3 -0
  137. package/dist/hitl/hitlHostSurface.js +17 -15
  138. package/dist/hitl/livePendingAsk.d.ts +16 -6
  139. package/dist/hitl/livePendingAsk.js +36 -4
  140. package/dist/hitl/localAllowRule.js +2 -1
  141. package/dist/hitl/noAllowCause.d.ts +9 -0
  142. package/dist/hitl/noAllowCause.js +26 -0
  143. package/dist/hitl/parkExpiryJudgements.d.ts +19 -0
  144. package/dist/hitl/parkExpiryJudgements.js +46 -0
  145. package/dist/hitl/parkResolver.d.ts +3 -7
  146. package/dist/hitl/parkResolver.js +55 -28
  147. package/dist/hitl/parkRowBirthWait.js +2 -1
  148. package/dist/hitl/persistedRulesWire.d.ts +6 -1
  149. package/dist/hitl/persistedRulesWire.js +16 -4
  150. package/dist/hitl/planReviewWire.d.ts +2 -3
  151. package/dist/hitl/planReviewWire.js +86 -39
  152. package/dist/hitl/replayedApproval.d.ts +8 -0
  153. package/dist/hitl/replayedApproval.js +125 -10
  154. package/dist/hitl/resumeRunningCard.d.ts +2 -0
  155. package/dist/hitl/resumeRunningCard.js +15 -4
  156. package/dist/hitl/sessionPolicyDeliverable.d.ts +1 -1
  157. package/dist/hitl/sessionPolicyDeliverable.js +3 -8
  158. package/dist/hitl/sessionPolicyWire.js +1 -1
  159. package/dist/hitl/toolApprovalWire.d.ts +50 -5
  160. package/dist/hitl/toolApprovalWire.js +368 -56
  161. package/dist/hooksWireCaps.js +38 -6
  162. package/dist/host.d.ts +5 -0
  163. package/dist/host.js +3 -1
  164. package/dist/hostCallbackGuard.d.ts +1 -0
  165. package/dist/hostCallbackGuard.js +25 -0
  166. package/dist/humanTurnRead.d.ts +15 -1
  167. package/dist/humanTurnRead.js +28 -2
  168. package/dist/index.d.ts +45 -14
  169. package/dist/index.js +33 -12
  170. package/dist/interactiveInterrupt.d.ts +8 -0
  171. package/dist/interactiveInterrupt.js +54 -0
  172. package/dist/limitsWire.d.ts +5 -1
  173. package/dist/limitsWire.js +51 -13
  174. package/dist/liveModelCatalog.d.ts +109 -0
  175. package/dist/liveModelCatalog.js +344 -18
  176. package/dist/mcpEngineLeg.d.ts +25 -0
  177. package/dist/mcpEngineLeg.js +71 -15
  178. package/dist/mcpPanel.js +2 -1
  179. package/dist/mcpProbeCapability.d.ts +0 -1
  180. package/dist/mcpProbeCapability.js +13 -12
  181. package/dist/mcpReconnect.d.ts +1 -3
  182. package/dist/mcpReconnect.js +20 -10
  183. package/dist/memoryComplianceCapability.d.ts +0 -1
  184. package/dist/memoryComplianceCapability.js +14 -13
  185. package/dist/memoryOriginCapability.d.ts +0 -1
  186. package/dist/memoryOriginCapability.js +14 -13
  187. package/dist/memoryVerbsWire.d.ts +1 -1
  188. package/dist/memoryVerbsWire.js +4 -0
  189. package/dist/model/liveCatalogShape.d.ts +14 -0
  190. package/dist/model/liveCatalogShape.js +71 -0
  191. package/dist/model/modelSupplyRules.d.ts +1 -0
  192. package/dist/model/modelSupplyRules.js +30 -9
  193. package/dist/model/modelsPolicy.d.ts +21 -0
  194. package/dist/model/modelsPolicy.js +90 -0
  195. package/dist/modelIdentityResolvability.d.ts +4 -2
  196. package/dist/modelIdentityResolvability.js +25 -5
  197. package/dist/modelSwitchFallback.d.ts +69 -0
  198. package/dist/modelSwitchFallback.js +206 -0
  199. package/dist/notifications.js +12 -11
  200. package/dist/outputStyleSeatCapability.d.ts +15 -0
  201. package/dist/outputStyleSeatCapability.js +42 -0
  202. package/dist/ownKey.d.ts +7 -0
  203. package/dist/ownKey.js +58 -0
  204. package/dist/panelReduce.d.ts +114 -0
  205. package/dist/panelReduce.js +1135 -0
  206. package/dist/panelStateHolder.d.ts +17 -0
  207. package/dist/panelStateHolder.js +201 -0
  208. package/dist/peerLaneCapability.d.ts +0 -1
  209. package/dist/peerLaneCapability.js +15 -14
  210. package/dist/permissionModesCapability.d.ts +0 -1
  211. package/dist/permissionModesCapability.js +5 -10
  212. package/dist/permissionRuleIssue.js +1 -1
  213. package/dist/permissionRulesWriteCapability.d.ts +0 -1
  214. package/dist/permissionRulesWriteCapability.js +15 -14
  215. package/dist/permissionsAllowGrantCapability.d.ts +2 -1
  216. package/dist/permissionsAllowGrantCapability.js +35 -19
  217. package/dist/permissionsDeclaration.d.ts +16 -1
  218. package/dist/permissionsDeclaration.js +142 -15
  219. package/dist/printToolResultFrame.js +2 -10
  220. package/dist/promptDelivery.js +0 -8
  221. package/dist/protocolSegment.d.ts +1 -0
  222. package/dist/protocolSegment.js +13 -1
  223. package/dist/request/taskRequest.d.ts +11 -3
  224. package/dist/request/taskRequest.js +13 -1
  225. package/dist/resultFrameKeys.d.ts +4 -0
  226. package/dist/resultFrameKeys.js +13 -0
  227. package/dist/resumeRefusalCopy.d.ts +18 -1
  228. package/dist/resumeRefusalCopy.js +132 -31
  229. package/dist/retryStatus.js +6 -4
  230. package/dist/rewindArchiveCapability.d.ts +2 -1
  231. package/dist/rewindArchiveCapability.js +28 -15
  232. package/dist/rewindEngineAction.d.ts +21 -0
  233. package/dist/rewindEngineAction.js +36 -0
  234. package/dist/rewindWireCaps.d.ts +2 -1
  235. package/dist/rewindWireCaps.js +1 -0
  236. package/dist/{hitl/rosterMountedNames.d.ts → rosterMountedNames.d.ts} +1 -1
  237. package/dist/runCancelContext.js +2 -1
  238. package/dist/runTerminal.d.ts +0 -11
  239. package/dist/runTerminal.js +4 -27
  240. package/dist/sdkRegistryTransit.d.ts +2 -1
  241. package/dist/sdkRegistryTransit.js +1 -0
  242. package/dist/sealedKeyCapability.d.ts +0 -1
  243. package/dist/sealedKeyCapability.js +19 -20
  244. package/dist/seatContract.d.ts +85 -28
  245. package/dist/seatContract.js +512 -148
  246. package/dist/sessionIdSegment.d.ts +1 -0
  247. package/dist/sessionIdSegment.js +11 -0
  248. package/dist/sessionMemoryErase.d.ts +1 -1
  249. package/dist/sessionMemoryErase.js +6 -1
  250. package/dist/sessionMemoryStatus.js +3 -2
  251. package/dist/sessionPolicyCapability.d.ts +0 -1
  252. package/dist/sessionPolicyCapability.js +14 -13
  253. package/dist/sessionReadRedactionCapability.d.ts +15 -0
  254. package/dist/sessionReadRedactionCapability.js +42 -0
  255. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -1
  256. package/dist/sessionSyncFileHistoryCapability.js +13 -12
  257. package/dist/skillToolListsCapability.d.ts +0 -1
  258. package/dist/skillToolListsCapability.js +13 -12
  259. package/dist/skillsWireCaps.d.ts +4 -0
  260. package/dist/skillsWireCaps.js +66 -1
  261. package/dist/sqlEngineCapability.d.ts +0 -1
  262. package/dist/sqlEngineCapability.js +21 -21
  263. package/dist/steerPriorityCapability.d.ts +0 -1
  264. package/dist/steerPriorityCapability.js +18 -19
  265. package/dist/storePostureCapability.d.ts +1 -1
  266. package/dist/storePostureCapability.js +16 -16
  267. package/dist/streamDrainingLegs.d.ts +6 -0
  268. package/dist/streamDrainingLegs.js +23 -0
  269. package/dist/subagent/agentStateDetail.d.ts +1 -0
  270. package/dist/subagent/agentStateDetail.js +41 -0
  271. package/dist/subagent/engineCompactWire.d.ts +15 -0
  272. package/dist/subagent/engineCompactWire.js +82 -45
  273. package/dist/subagent/engineDelegatedPrompt.js +10 -6
  274. package/dist/subagent/engineSubagentOutput.d.ts +0 -1
  275. package/dist/subagent/engineSubagentOutput.js +5 -20
  276. package/dist/subagent/engineSubagentTail.d.ts +0 -1
  277. package/dist/subagent/engineSubagentTail.js +7 -32
  278. package/dist/subagentContentStore.js +3 -3
  279. package/dist/supportFloor.js +2 -5
  280. package/dist/taskRequestWords.d.ts +2 -4
  281. package/dist/taskRequestWords.js +3 -2
  282. package/dist/terminalStatuses.d.ts +30 -0
  283. package/dist/terminalStatuses.js +67 -0
  284. package/dist/toolResult.d.ts +5 -0
  285. package/dist/toolResult.js +88 -36
  286. package/dist/types/engineState.d.ts +2 -1
  287. package/dist/usageAnalytics.d.ts +146 -0
  288. package/dist/usageAnalytics.js +311 -0
  289. package/dist/userAttachmentEnvelope.d.ts +22 -1
  290. package/dist/userAttachmentEnvelope.js +90 -2
  291. package/dist/userInvokedSkillsCapability.d.ts +0 -1
  292. package/dist/userInvokedSkillsCapability.js +13 -12
  293. package/dist/webSearchBackendCapability.d.ts +0 -1
  294. package/dist/webSearchBackendCapability.js +20 -19
  295. package/dist/webSearchWireCaps.js +3 -11
  296. package/dist/wireErrorTriage.d.ts +11 -0
  297. package/dist/wireErrorTriage.js +35 -0
  298. package/dist/wireFailureShape.d.ts +10 -0
  299. package/dist/wireFailureShape.js +72 -5
  300. package/dist/wireRefusalCopy.d.ts +6 -1
  301. package/dist/wireRefusalCopy.js +23 -25
  302. package/dist/wiringInstructionsAttribution.d.ts +10 -0
  303. package/dist/wiringInstructionsAttribution.js +67 -0
  304. package/dist/workflowClient.js +19 -2
  305. package/dist/workflowsJournalCapability.d.ts +0 -1
  306. package/dist/workflowsJournalCapability.js +13 -12
  307. package/dist/writeProtectionCapability.d.ts +0 -1
  308. package/dist/writeProtectionCapability.js +26 -26
  309. package/docs/INTEGRATION-CLIENTS.md +1733 -52
  310. package/package.json +5 -5
  311. package/dist/askSurvivesStandingAnswer.d.ts +0 -13
  312. package/dist/askSurvivesStandingAnswer.js +0 -53
  313. package/dist/engineCapsGenerationGuard.d.ts +0 -4
  314. package/dist/engineCapsGenerationGuard.js +0 -19
  315. package/dist/hitl/askSurvivesPosture.d.ts +0 -20
  316. package/dist/hitl/askSurvivesPosture.js +0 -48
  317. package/dist/panelRunningHistory.d.ts +0 -22
  318. package/dist/panelRunningHistory.js +0 -82
  319. package/dist/registryConflict.d.ts +0 -3
  320. package/dist/registryConflict.js +0 -44
  321. /package/dist/{hitl/rosterMountedNames.js → rosterMountedNames.js} +0 -0
@@ -1,6 +1,7 @@
1
1
  import { ccToolDenialKindForSettledBy, isCcToolDenialKind, isGateDeniedByWord } from './gateVocabulary.js';
2
2
  import { GATE_PARKED_ERROR_CODE } from './engineErrorCodes.js';
3
3
  import { CORE_MODE_RELEASE_REASONS, CORE_SETTLEMENT_KINDS } from './generated/engineFactTables.js';
4
+ import { readAskOrigin } from './ownKey.js';
4
5
  function str(v) {
5
6
  return typeof v === 'string' && v.length > 0 ? v : undefined;
6
7
  }
@@ -32,7 +33,8 @@ function readSettlement(v) {
32
33
  const who = readWho(s.who);
33
34
  if (kind === undefined || who === undefined)
34
35
  return undefined;
35
- const when = typeof s.when === 'number' && Number.isFinite(s.when) ? s.when : undefined;
36
+ const whenRaw = s.when;
37
+ const when = typeof whenRaw === 'number' && Number.isFinite(whenRaw) ? whenRaw : undefined;
36
38
  const note = str(s.note);
37
39
  return {
38
40
  kind,
@@ -62,7 +64,7 @@ function readModeRelease(raw) {
62
64
  const classes = nonEmptyStringList(r.classes);
63
65
  if (mode === undefined || askClass === undefined || classes === undefined)
64
66
  return undefined;
65
- const origin = str(r.origin);
67
+ const origin = readAskOrigin(r);
66
68
  const mandate = str(r.mandate);
67
69
  const reason = str(r.reason);
68
70
  return {
@@ -94,7 +96,7 @@ function readClassifierRound(raw) {
94
96
  }
95
97
  return view;
96
98
  }
97
- export function gateOutcomeOf(frame) {
99
+ function readGateRecord(frame) {
98
100
  if (typeof frame !== 'object' || frame === null || Array.isArray(frame))
99
101
  return undefined;
100
102
  const g = frame.gate;
@@ -107,7 +109,9 @@ export function gateOutcomeOf(frame) {
107
109
  const dr = d;
108
110
  const dk = str(dr.kind);
109
111
  let disposition;
110
- const classifier = readClassifierRound(dr.classifier);
112
+ let causePresent = false;
113
+ const classifierRaw = dr.classifier;
114
+ const classifier = readClassifierRound(classifierRaw);
111
115
  if (dk === 'allowed') {
112
116
  const released = readModeRelease(dr.released);
113
117
  disposition = {
@@ -120,7 +124,9 @@ export function gateOutcomeOf(frame) {
120
124
  const deniedBy = str(dr.deniedBy);
121
125
  if (deniedBy === undefined)
122
126
  return undefined;
123
- const cause = str(dr.cause);
127
+ const causeRaw = dr.cause;
128
+ causePresent = causeRaw !== undefined;
129
+ const cause = str(causeRaw);
124
130
  const mode = str(dr.mode);
125
131
  const askClass = str(dr.askClass);
126
132
  const classes = nonEmptyStringList(dr.classes);
@@ -137,14 +143,23 @@ export function gateOutcomeOf(frame) {
137
143
  else {
138
144
  return undefined;
139
145
  }
140
- const settlement = readSettlement(raw.settlement);
141
- const origin = str(raw.origin);
146
+ const settlementRaw = raw.settlement;
147
+ const settlement = readSettlement(settlementRaw);
148
+ const origin = readAskOrigin(raw);
142
149
  return {
143
- disposition,
144
- ...(settlement !== undefined ? { settlement } : {}),
145
- ...(origin !== undefined ? { origin } : {}),
150
+ view: {
151
+ disposition,
152
+ ...(settlement !== undefined ? { settlement } : {}),
153
+ ...(origin !== undefined ? { origin } : {}),
154
+ },
155
+ settlementPresent: settlementRaw !== undefined,
156
+ causePresent,
157
+ classifierPresent: classifierRaw !== undefined,
146
158
  };
147
159
  }
160
+ export function gateOutcomeOf(frame) {
161
+ return readGateRecord(frame)?.view;
162
+ }
148
163
  export function isGateParkedToolEnd(frame) {
149
164
  if (typeof frame !== 'object' || frame === null || Array.isArray(frame))
150
165
  return false;
@@ -171,6 +186,9 @@ export function isDenialLimitAutoDeniedGate(g) {
171
186
  export function isParkSlaExpiredGate(g) {
172
187
  return g?.settlement?.kind === 'park_sla_expired';
173
188
  }
189
+ export function isApproverUnavailableGate(g) {
190
+ return isDeniedGate(g) && g?.settlement?.kind === 'approver_unavailable';
191
+ }
174
192
  export function isHumanSettledGate(g) {
175
193
  const k = g?.settlement?.kind;
176
194
  return k === 'human_allowed' || k === 'human_refused';
@@ -186,21 +204,19 @@ export function ccToolDenialKindForToolEnd(frame) {
186
204
  return stamped;
187
205
  if (frame._sema_denial_unclassified === true)
188
206
  return undefined;
189
- const outcome = gateOutcomeOf(frame);
207
+ const record = readGateRecord(frame);
208
+ const outcome = record?.view;
190
209
  const kind = outcome?.settlement?.kind;
191
210
  if (kind === 'human_refused')
192
211
  return ccToolDenialKindForSettledBy('human');
193
212
  if (kind === 'policy_refused')
194
213
  return ccToolDenialKindForSettledBy('policy');
195
- const rawGate = frame.gate;
196
- const settlementAbsent = typeof rawGate === 'object' && rawGate !== null && rawGate.settlement === undefined;
197
- if (outcome !== undefined && settlementAbsent && outcome.disposition.kind === 'denied') {
214
+ if (record !== undefined && outcome !== undefined && !record.settlementPresent && outcome.disposition.kind === 'denied') {
198
215
  const by = outcome.disposition.deniedBy;
199
216
  if (by === 'ask_resolution' || !isGateDeniedByWord(by))
200
217
  return undefined;
201
218
  if (DENIED_BY_MAY_CARRY_CAUSE.has(by)) {
202
- const rawDisposition = rawKeyOf(rawGate, 'disposition');
203
- if (rawKeyOf(rawDisposition, 'cause') !== undefined) {
219
+ if (record.causePresent) {
204
220
  const cause = outcome.disposition.cause;
205
221
  if (cause === 'unavailable')
206
222
  return 'automode-unavailable';
@@ -210,14 +226,13 @@ export function ccToolDenialKindForToolEnd(frame) {
210
226
  }
211
227
  if (by === 'classifier')
212
228
  return 'automode-blocked';
213
- if (rawKeyOf(rawDisposition, 'classifier') !== undefined)
229
+ if (record.classifierPresent)
214
230
  return undefined;
215
231
  }
216
232
  return ccToolDenialKindForSettledBy('policy');
217
233
  }
218
234
  return undefined;
219
235
  }
220
- const rawKeyOf = (holder, key) => typeof holder === 'object' && holder !== null ? holder[key] : undefined;
221
236
  const DENIED_BY_MAY_CARRY_CAUSE = new Set(['classifier', 'policy']);
222
237
  const _gateOutcomeShapePin = (w) => w;
223
238
  void _gateOutcomeShapePin;
@@ -69,7 +69,7 @@ export function askOriginDetail(origin) {
69
69
  return `this call asks; its origin ${word} is a word newer than this client, so answer it as usual`;
70
70
  }
71
71
  export function mandatedApprovalDetail() {
72
- return 'no saved allow rule and no remembered answer can retire this question; each call is settled on its own — by you here, by a hook, or by an automatic check the deployment runs — and an answer covers only that call';
72
+ return 'no saved allow rule and no remembered answer can retire this question; each call is settled on its own — by you here or by an automatic check the deployment runs — and an answer covers only that call';
73
73
  }
74
74
  const _mandateWordsPin = true;
75
75
  void _mandateWordsPin;
@@ -0,0 +1,3 @@
1
+ export declare const CORE_ASK_FACES: readonly ["shell", "other"];
2
+ export declare const CORE_SHELL_FACE_TOOL_NAMES: readonly string[];
3
+ export declare const CORE_RELEASABLE_ASK_CLASSES_BY_FACE: Readonly<Record<(typeof CORE_ASK_FACES)[number], readonly string[]>>;
@@ -0,0 +1,12 @@
1
+ export const CORE_ASK_FACES = Object.freeze([
2
+ "shell",
3
+ "other",
4
+ ]);
5
+ export const CORE_SHELL_FACE_TOOL_NAMES = Object.freeze([
6
+ "Bash",
7
+ "Monitor",
8
+ ]);
9
+ export const CORE_RELEASABLE_ASK_CLASSES_BY_FACE = Object.freeze({
10
+ "shell": Object.freeze(["transcript_write", "rule_unreadable", "write_protection_unresolved", "probe", "write_protection", "tool_marks_mcp", "tool_marks_a2a", "artifact_shared_read", "mode", "unstated", "ordinary"]),
11
+ "other": Object.freeze(["transcript_write", "rule_unreadable", "probe", "write_protection", "tool_marks_mcp", "tool_marks_a2a", "artifact_shared_read", "mode", "unstated", "ordinary"]),
12
+ });
@@ -8,7 +8,7 @@ export declare const CORE_DENIED_BY_VALUES: readonly ["policy", "hook", "org", "
8
8
  export declare const CORE_PERMISSION_MODE_FOLD_REASONS: readonly string[];
9
9
  export declare const CORE_ENGINE_CARD_TYPES: readonly string[];
10
10
  export declare const CORE_TOOL_DECLARATION_CODES: readonly string[];
11
- export declare const CORE_MODE_RELEASE_REASONS: readonly ["rule_unreadable"];
11
+ export declare const CORE_MODE_RELEASE_REASONS: readonly ["rule_unreadable", "write_protection_unresolved"];
12
12
  export declare const CORE_HOOK_TOOL_ALIASES: Readonly<Record<string, string>>;
13
13
  export declare const CORE_ASK_EVIDENCE_ABSENCE_VALUES: readonly ["not_wired", "not_adjudicated", "unavailable", "no_match", "not_reported"];
14
14
  export declare const CORE_SYSTEM_INJECTION_PRIORITIES: readonly ["now", "next", "later"];
@@ -21,7 +21,7 @@ export interface CoreModeArbitrationRow {
21
21
  readonly ruleMayClear: boolean;
22
22
  readonly hookAskFloor: boolean;
23
23
  }
24
- export declare const CORE_MODE_ARBITRATION: Readonly<Record<"content_question" | "hook" | "ancestor" | "unverifiable_delete" | "transcript_write" | "org_rule" | "governance_unavailable" | "rule_unreadable" | "ask_rule" | "denial_limit_fallback" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "write_protection_unresolved" | "probe" | "write_protection" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "mode" | "unstated" | "ordinary", CoreModeArbitrationRow>>;
24
+ export declare const CORE_MODE_ARBITRATION: Readonly<Record<"content_question" | "hook" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "transcript_write" | "org_rule" | "governance_unavailable" | "rule_unreadable" | "ask_rule" | "denial_limit_fallback" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "write_protection_unresolved" | "probe" | "write_protection" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "mode" | "unstated" | "ordinary", CoreModeArbitrationRow>>;
25
25
  export declare const CORE_SKILL_GRANT_ORIGINS: readonly ["model", "user", "inherited"];
26
26
  export declare const CORE_ALLOW_ENTRY_INERT_REASONS: readonly ["wildcard_all", "namespace_wildcard", "path_pattern", "domain", "content_unsupported", "grammar", "tool_name", "near_miss"];
27
27
  export declare const CORE_ALLOW_RULE_MEMBERS: readonly ["hook", "deployment", "persisted", "skill", "request"];
@@ -38,3 +38,5 @@ export declare const CORE_RULE_BEHAVIORS: readonly ["deny", "ask", "allow"];
38
38
  export declare const CORE_MCP_IMAGE_MAX_BASE64: number;
39
39
  export declare const CORE_MAX_PENDING_STEER_CHARS: number;
40
40
  export declare const CORE_PROMPT_BLOCK_CAUSES: readonly ["block", "crashed", "timeout", "cancelled"];
41
+ export declare const CORE_PERMISSION_MODES: readonly ["default", "acceptEdits", "plan", "auto", "bypassPermissions", "dontAsk"];
42
+ export declare const CORE_APPROVAL_REACH: readonly ["none"];
@@ -113,6 +113,7 @@ export const CORE_TOOL_DECLARATION_CODES = Object.freeze([
113
113
  ]);
114
114
  export const CORE_MODE_RELEASE_REASONS = Object.freeze([
115
115
  "rule_unreadable",
116
+ "write_protection_unresolved",
116
117
  ]);
117
118
  export const CORE_HOOK_TOOL_ALIASES = Object.freeze(Object.assign(Object.create(null), Object.fromEntries([
118
119
  ["ListPeers", "ListAgents"],
@@ -144,6 +145,7 @@ export const CORE_MODE_ARBITRATION = Object.freeze({
144
145
  "content_question": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
145
146
  "hook": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
146
147
  "ancestor": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
148
+ "dangerous_delete": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
147
149
  "unverifiable_delete": Object.freeze({ bypassImmune: true, classifierEligible: true, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
148
150
  "transcript_write": Object.freeze({ bypassImmune: false, classifierEligible: true, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
149
151
  "org_rule": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
@@ -255,3 +257,14 @@ export const CORE_PROMPT_BLOCK_CAUSES = Object.freeze([
255
257
  "timeout",
256
258
  "cancelled",
257
259
  ]);
260
+ export const CORE_PERMISSION_MODES = Object.freeze([
261
+ "default",
262
+ "acceptEdits",
263
+ "plan",
264
+ "auto",
265
+ "bypassPermissions",
266
+ "dontAsk",
267
+ ]);
268
+ export const CORE_APPROVAL_REACH = Object.freeze([
269
+ "none",
270
+ ]);
@@ -4,3 +4,8 @@ export declare const CORE_MCP_INJECTION_DROP_REASONS: readonly string[];
4
4
  export declare const CORE_NOTICE_MINTER: Readonly<Record<string, 'engine' | 'server'>>;
5
5
  export declare const CORE_USER_INPUT_UNDRAINED_CAUSES: readonly ["leg_end", "crashed"];
6
6
  export declare const CORE_TOOL_TURN_INCOMPLETE_CAUSES: readonly ["truncated", "unnamed", "bad_frame", "missing_result_synthesized"];
7
+ export interface CoreUserInputUndrainedFamily {
8
+ readonly code: string;
9
+ readonly countKey: string;
10
+ }
11
+ export declare const CORE_USER_INPUT_UNDRAINED_FAMILIES: Readonly<Record<"steer" | "followUp", CoreUserInputUndrainedFamily>>;
@@ -28,6 +28,7 @@ export const CORE_ENGINE_NOTICE_CODES = Object.freeze([
28
28
  "permission.ask_released_by_mode",
29
29
  "permission.read_deny_unapplied",
30
30
  "permission.rule_store_unavailable",
31
+ "permission.rule_row_dropped",
31
32
  "permission.allowed_tool_not_granted",
32
33
  "peer.inbound_disposition",
33
34
  "peer.held_settled",
@@ -116,6 +117,7 @@ export const CORE_NOTICE_AUDIENCE = Object.freeze({
116
117
  "permission.ask_released_by_mode": "user",
117
118
  "permission.read_deny_unapplied": "user",
118
119
  "permission.rule_store_unavailable": "user",
120
+ "permission.rule_row_dropped": "user",
119
121
  "permission.allowed_tool_not_granted": "user",
120
122
  "peer.inbound_disposition": "user",
121
123
  "peer.held_settled": "user",
@@ -210,6 +212,7 @@ export const CORE_NOTICE_MINTER = Object.freeze({
210
212
  "permission.ask_released_by_mode": "engine",
211
213
  "permission.read_deny_unapplied": "engine",
212
214
  "permission.rule_store_unavailable": "engine",
215
+ "permission.rule_row_dropped": "engine",
213
216
  "permission.allowed_tool_not_granted": "engine",
214
217
  "peer.inbound_disposition": "engine",
215
218
  "peer.held_settled": "engine",
@@ -278,3 +281,7 @@ export const CORE_TOOL_TURN_INCOMPLETE_CAUSES = Object.freeze([
278
281
  "bad_frame",
279
282
  "missing_result_synthesized",
280
283
  ]);
284
+ export const CORE_USER_INPUT_UNDRAINED_FAMILIES = Object.freeze({
285
+ "steer": Object.freeze({ code: "task.user_steer_undrained", countKey: "steer" }),
286
+ "followUp": Object.freeze({ code: "task.user_followup_undrained", countKey: "followUp" }),
287
+ });
@@ -0,0 +1,5 @@
1
+ export declare const SDK_ABORT_CAUSES: readonly ["client_disconnected", "ask_park_grace_exhausted", "cancel_verb"];
2
+ export declare const SDK_STATUS_DERIVED_COARSE_CODES: readonly ["request.rejected", "auth.unauthorized", "auth.forbidden", "not_found.resource", "request.payload_too_large", "request.unprocessable", "limit.rate_exceeded", "capability.unavailable", "internal.error"];
3
+ export declare const SDK_DENY_REASON_ROUTING_FAILURE: "routing_failure_fail_closed";
4
+ export declare const SDK_ASK_ROW_ENDING_CAUSES: readonly ["routing_failure_fail_closed", "run_cancelled", "run_exited", "batch_aborted", "batch_sibling_withdrawn", "batch_bound_elsewhere", "adhoc_leg_no_durable_domain", "orphan_ttl_exceeded", "crashed_before_park", "shutdown_before_park"];
5
+ export declare const SDK_RUN_DEATH_VERDICT_CODES: readonly ["run.stalled", "run.orphaned", "approval.expired"];
@@ -0,0 +1,34 @@
1
+ export const SDK_ABORT_CAUSES = Object.freeze([
2
+ "client_disconnected",
3
+ "ask_park_grace_exhausted",
4
+ "cancel_verb",
5
+ ]);
6
+ export const SDK_STATUS_DERIVED_COARSE_CODES = Object.freeze([
7
+ "request.rejected",
8
+ "auth.unauthorized",
9
+ "auth.forbidden",
10
+ "not_found.resource",
11
+ "request.payload_too_large",
12
+ "request.unprocessable",
13
+ "limit.rate_exceeded",
14
+ "capability.unavailable",
15
+ "internal.error",
16
+ ]);
17
+ export const SDK_DENY_REASON_ROUTING_FAILURE = "routing_failure_fail_closed";
18
+ export const SDK_ASK_ROW_ENDING_CAUSES = Object.freeze([
19
+ "routing_failure_fail_closed",
20
+ "run_cancelled",
21
+ "run_exited",
22
+ "batch_aborted",
23
+ "batch_sibling_withdrawn",
24
+ "batch_bound_elsewhere",
25
+ "adhoc_leg_no_durable_domain",
26
+ "orphan_ttl_exceeded",
27
+ "crashed_before_park",
28
+ "shutdown_before_park",
29
+ ]);
30
+ export const SDK_RUN_DEATH_VERDICT_CODES = Object.freeze([
31
+ "run.stalled",
32
+ "run.orphaned",
33
+ "approval.expired",
34
+ ]);
@@ -0,0 +1,10 @@
1
+ export declare const SETTINGS_AT_MENTION_MODES: readonly ["all", "none", "only"];
2
+ export type SettingsAtMention = {
3
+ readonly mode: Exclude<(typeof SETTINGS_AT_MENTION_MODES)[number], 'only'>;
4
+ } | {
5
+ readonly mode: 'only';
6
+ readonly models: readonly string[];
7
+ };
8
+ export declare const SETTINGS_IS_LOOPBACK_AUTH_HOST: (host: string) => boolean;
9
+ export declare const SETTINGS_IS_HIERARCHICAL_URL: (raw: string) => boolean;
10
+ export declare const SETTINGS_NARROW_AT_MENTION: (atMention: SettingsAtMention, available: ReadonlySet<string>) => SettingsAtMention;
@@ -0,0 +1,22 @@
1
+ export const SETTINGS_AT_MENTION_MODES = Object.freeze([
2
+ "all",
3
+ "none",
4
+ "only",
5
+ ]);
6
+ export const SETTINGS_IS_LOOPBACK_AUTH_HOST = function isLoopbackAuthHost(host) {
7
+ return host === "127.0.0.1" || host === "localhost" || host === "::1" || host === "[::1]" || host === "::ffff:127.0.0.1";
8
+ };
9
+ export const SETTINGS_IS_HIERARCHICAL_URL = function isHierarchicalUrl(raw) {
10
+ if (!URL.canParse(raw))
11
+ return false;
12
+ const u = new URL(raw);
13
+ return u.href.startsWith(`${u.protocol}//`);
14
+ };
15
+ export const SETTINGS_NARROW_AT_MENTION = function narrowAtMention(atMention, available) {
16
+ if (atMention.mode !== "only")
17
+ return atMention;
18
+ const kept = atMention.models.filter((n) => available.has(n));
19
+ if (kept.length === atMention.models.length)
20
+ return atMention;
21
+ return kept.length > 0 ? { mode: "only", models: kept } : { mode: "none" };
22
+ };
@@ -1,5 +1,8 @@
1
1
  export declare const SETTINGS_ENGINE_OWNED_HOOK_EVENTS: readonly ["PreToolUse", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "PreCompact", "PostCompact", "Stop", "StopFailure", "UserPromptSubmit"];
2
2
  export declare const SETTINGS_SECRET_LITERAL_RE: RegExp;
3
+ export declare const SETTINGS_PRIVATE_KEY_PEM_HEADER: RegExp;
4
+ export declare const SETTINGS_DEVICE_CODE_TTL_SECONDS = 900;
5
+ export declare const SETTINGS_DEVICE_POLL_INTERVAL_SECONDS = 5;
3
6
  export declare const SETTINGS_TIER_GROUP_NAME_RE: RegExp;
4
7
  export declare const SETTINGS_BUDGET_NUMBER_KEYS: readonly ["maxBudgetUsd", "tpmLimit", "rpmLimit", "maxParallelRequests", "maxRunCostUsd", "maxIterations"];
5
8
  export declare const SETTINGS_BUDGET_STRING_KEYS: readonly ["mode", "budgetDuration", "enforcement"];
@@ -10,6 +10,9 @@ export const SETTINGS_ENGINE_OWNED_HOOK_EVENTS = Object.freeze([
10
10
  "UserPromptSubmit",
11
11
  ]);
12
12
  export const SETTINGS_SECRET_LITERAL_RE = Object.freeze(/^(sk-|gh[opus]_|github_pat_|xox[baprse]-|xapp-|bearer\s|basic\s|eyJ[A-Za-z0-9_-]{10,}\.|AKIA[0-9A-Z]{12,}|AIza[0-9A-Za-z_-]{20,}|-----BEGIN[A-Z0-9 ]*PRIVATE KEY)/i);
13
+ export const SETTINGS_PRIVATE_KEY_PEM_HEADER = Object.freeze(/-----BEGIN[A-Z0-9 ]*PRIVATE KEY/i);
14
+ export const SETTINGS_DEVICE_CODE_TTL_SECONDS = 900;
15
+ export const SETTINGS_DEVICE_POLL_INTERVAL_SECONDS = 5;
13
16
  export const SETTINGS_TIER_GROUP_NAME_RE = Object.freeze(/^[a-z0-9][a-z0-9._-]*$/i);
14
17
  export const SETTINGS_BUDGET_NUMBER_KEYS = Object.freeze([
15
18
  "maxBudgetUsd",
@@ -3,10 +3,10 @@ import { type PermissionModesReading } from './permissionModesCapability.js';
3
3
  import { type EnvLike } from './hostEnv.js';
4
4
  export declare const HEADLESS_PERMISSION_MODE_ENV = "SEMA_HEADLESS_PERMISSION_MODE";
5
5
  export declare const HEADLESS_PERMISSION_WIRE_MODES: readonly PermissionMode[];
6
- export declare function normalizeShellPermissionModeForWire(mode: string | undefined, permissionModes?: PermissionModesReading): string | undefined;
6
+ export declare function normalizeShellPermissionModeForWire(mode: string | undefined): string | undefined;
7
7
  export type HeadlessPermissionResolution = {
8
8
  fields: PermissionModeField;
9
- source: 'flag' | 'env' | 'default' | 'absent';
9
+ source: 'flag' | 'env' | 'default';
10
10
  warning?: string;
11
11
  };
12
12
  export declare function permissionModeFromArgv(argv: readonly string[]): string | undefined;
@@ -6,15 +6,10 @@ import { PERMISSION_MODE_WORDS } from './taskRequestWords.js';
6
6
  import { readOwnDataValue } from './ownKey.js';
7
7
  export const HEADLESS_PERMISSION_MODE_ENV = 'SEMA_HEADLESS_PERMISSION_MODE';
8
8
  export const HEADLESS_PERMISSION_WIRE_MODES = [...PERMISSION_MODE_WORDS];
9
- const SHELL_INTERNAL_MODE_TO_WIRE = new Map([
10
- ['manual', 'default'],
11
- ['dontAsk', 'default'],
12
- ]);
13
- export function normalizeShellPermissionModeForWire(mode, permissionModes) {
9
+ const SHELL_INTERNAL_MODE_TO_WIRE = new Map([['manual', 'default']]);
10
+ export function normalizeShellPermissionModeForWire(mode) {
14
11
  if (mode === undefined)
15
12
  return undefined;
16
- if (mode === 'dontAsk' && permissionModeAdmitted(permissionModes, mode))
17
- return mode;
18
13
  return SHELL_INTERNAL_MODE_TO_WIRE.get(mode) ?? mode;
19
14
  }
20
15
  export function permissionModeFromArgv(argv) {
@@ -35,8 +30,9 @@ export function resolveHeadlessPermissionMode(argv, env = hostEnv(), permissionM
35
30
  const flagMode = permissionModeFromArgv(argv);
36
31
  if (flagMode !== undefined) {
37
32
  const snap = flagMode === 'dontAsk' ? dontAskSnapshot(permissionModes) : undefined;
38
- const normalized = normalizeShellPermissionModeForWire(flagMode, snap);
39
- return { fields: permissionModeField(normalized, { stampDefault: true, permissionModes: snap }), source: 'flag' };
33
+ const normalized = normalizeShellPermissionModeForWire(flagMode);
34
+ const projected = permissionModeField(normalized, { stampDefault: true, permissionModes: snap });
35
+ return { fields: projected.permissionMode !== undefined ? projected : permissionModeField('default', { stampDefault: true }), source: 'flag' };
40
36
  }
41
37
  const raw = env[HEADLESS_PERMISSION_MODE_ENV]?.trim();
42
38
  if (raw === undefined || raw === '') {
@@ -44,21 +40,15 @@ export function resolveHeadlessPermissionMode(argv, env = hostEnv(), permissionM
44
40
  }
45
41
  if (HEADLESS_PERMISSION_WIRE_MODES.includes(raw)) {
46
42
  const snap = raw === 'dontAsk' ? dontAskSnapshot(permissionModes) : undefined;
47
- if (raw === 'dontAsk' && snap === undefined) {
48
- const downgraded = {
49
- fields: permissionModeField('default', { stampDefault: true }),
50
- source: 'env',
51
- };
52
- if (!warnedInvalidEnv) {
53
- warnedInvalidEnv = true;
54
- downgraded.warning = `sema: ${HEADLESS_PERMISSION_MODE_ENV}="dontAsk" is only sent once this client knows the engine accepts that mode, and ${dontAskWithheldClause(permissionModes)} — this run uses "default"`;
55
- }
56
- return downgraded;
57
- }
58
- return {
43
+ const resolution = {
59
44
  fields: permissionModeField(raw, { stampDefault: true, permissionModes: snap }),
60
45
  source: 'env',
61
46
  };
47
+ if (raw === 'dontAsk' && resolution.fields.permissionMode !== 'dontAsk' && !warnedInvalidEnv) {
48
+ warnedInvalidEnv = true;
49
+ resolution.warning = `sema: ${HEADLESS_PERMISSION_MODE_ENV}="dontAsk" is only sent once this client knows the engine accepts that mode, and ${dontAskWithheldClause(permissionModes)} — this run uses "default"`;
50
+ }
51
+ return resolution;
62
52
  }
63
53
  const resolution = {
64
54
  fields: permissionModeField('default', { stampDefault: true }),
@@ -1,23 +1,18 @@
1
1
  import { isSseIdleError, probeEngineAlive } from './sseIdleTriage.js';
2
2
  import { hostEnv } from './hostEnv.js';
3
+ import { isSdkRunFrameSynthesizable } from './terminalStatuses.js';
4
+ import { createStreamDrainingLegs } from './streamDrainingLegs.js';
5
+ import { abortableSleep } from './abortableSleep.js';
3
6
  export const HEADLESS_RECONNECT_MAX = 2;
4
7
  function debugLog(msg) {
5
8
  if (hostEnv().SEMA_DEBUG) {
6
9
  console.error(`[sema] headless reconnect: ${msg}`);
7
10
  }
8
11
  }
9
- const RUN_ROW_TERMINAL_STATUSES = new Set([
10
- 'completed',
11
- 'failed',
12
- 'timeout',
13
- 'blocked',
14
- 'suspended',
15
- 'needs_review',
16
- ]);
17
12
  export function terminalEventFromRunRow(row) {
18
13
  if (!row || typeof row.status !== 'string')
19
14
  return null;
20
- if (RUN_ROW_TERMINAL_STATUSES.has(row.status)) {
15
+ if (isSdkRunFrameSynthesizable(row.status)) {
21
16
  if (row.result && typeof row.result === 'object') {
22
17
  return { type: 'done', result: row.result };
23
18
  }
@@ -49,6 +44,15 @@ export async function* withHeadlessR1Reconnect(live, deps) {
49
44
  let lastSeenSeq;
50
45
  const probe = deps.probeAlive ?? probeEngineAlive;
51
46
  let isRecoverableTear;
47
+ const drains = createStreamDrainingLegs();
48
+ let drainReopenAfterMs;
49
+ const terminalFromRunRow = async (taskId) => {
50
+ const row = await deps.getRun(taskId).catch(() => null);
51
+ const terminal = terminalEventFromRunRow(row);
52
+ if (terminal)
53
+ debugLog(`run row terminal (${String(row?.status)}) — synthesizing the terminal frame (R1b)`);
54
+ return terminal;
55
+ };
52
56
  for (;;) {
53
57
  if (deps.signal?.aborted)
54
58
  throw originalTearErr;
@@ -59,25 +63,37 @@ export async function* withHeadlessR1Reconnect(live, deps) {
59
63
  const taskId = deps.getTaskId();
60
64
  if (!taskId)
61
65
  throw originalTearErr;
62
- if (attempts >= HEADLESS_RECONNECT_MAX) {
63
- debugLog(`budget exhausted (${attempts}/${HEADLESS_RECONNECT_MAX}) — falling to the honest death path`);
64
- throw originalTearErr;
66
+ if (drainReopenAfterMs !== undefined) {
67
+ const waitMs = drainReopenAfterMs;
68
+ drainReopenAfterMs = undefined;
69
+ await abortableSleep(waitMs, deps.signal ?? new AbortController().signal);
70
+ if (deps.signal?.aborted)
71
+ throw originalTearErr;
72
+ debugLog(`engine draining — reopening runs.events(${taskId}${lastSeenSeq !== undefined ? `, Last-Event-ID ${lastSeenSeq}` : ''}) after ${waitMs}ms (not counted against the reconnect budget)`);
73
+ }
74
+ else {
75
+ if (attempts >= HEADLESS_RECONNECT_MAX) {
76
+ debugLog(`budget exhausted (${attempts}/${HEADLESS_RECONNECT_MAX}) — falling to the honest death path`);
77
+ throw originalTearErr;
78
+ }
79
+ attempts++;
80
+ if (!(await probe(deps.baseUrl)))
81
+ throw originalTearErr;
82
+ debugLog(`attempt ${attempts}/${HEADLESS_RECONNECT_MAX} — switching to runs.events(${taskId}${lastSeenSeq !== undefined ? `, Last-Event-ID ${lastSeenSeq}` : ''})`);
65
83
  }
66
- attempts++;
67
- if (!(await probe(deps.baseUrl)))
68
- throw originalTearErr;
69
- debugLog(`attempt ${attempts}/${HEADLESS_RECONNECT_MAX} — switching to runs.events(${taskId}${lastSeenSeq !== undefined ? `, Last-Event-ID ${lastSeenSeq}` : ''})`);
70
84
  try {
71
85
  const cont = deps.openEvents(taskId, lastSeenSeq !== undefined ? String(lastSeenSeq) : undefined);
72
86
  for await (const ev of cont) {
73
87
  if (deps.signal?.aborted)
74
88
  return;
89
+ if (drains.see(ev))
90
+ continue;
75
91
  const rec = ev;
76
92
  const t = rec?.type;
77
93
  if (t === undefined)
78
94
  continue;
79
95
  if (t === 'error') {
80
- debugLog(`runs.events lane frame type=error code=${String(rec?.errorCode ?? rec?.code ?? '')} — SDK resumes with Last-Event-ID internally`);
96
+ debugLog(`runs.events lane frame type=error code=${String(rec?.errorCode ?? rec?.code ?? '')} — not forwarded (the cap frame is resumed inside the SDK)`);
81
97
  continue;
82
98
  }
83
99
  const seq = typeof rec?.id === 'string' && /^\d+$/.test(rec.id) ? Number(rec.id) : undefined;
@@ -94,16 +110,29 @@ export async function* withHeadlessR1Reconnect(live, deps) {
94
110
  }
95
111
  if (deps.signal?.aborted)
96
112
  return;
113
+ const drained = drains.legEnded('returned');
114
+ if (drained !== undefined) {
115
+ if ('reconnectAfterMs' in drained) {
116
+ drainReopenAfterMs = drained.reconnectAfterMs;
117
+ continue;
118
+ }
119
+ debugLog(`runs.events kept ending on drain end frames (${drained.giveUp}) — checking the run row`);
120
+ const terminal = await terminalFromRunRow(taskId);
121
+ if (terminal) {
122
+ yield terminal;
123
+ return;
124
+ }
125
+ continue;
126
+ }
97
127
  debugLog('runs.events continuation ended without a terminal frame');
98
128
  }
99
129
  catch (contErr) {
130
+ drains.legEnded('threw');
100
131
  debugLog(`runs.events continuation failed: ${contErr instanceof Error ? contErr.message : String(contErr)}`);
101
132
  if (deps.signal?.aborted)
102
133
  throw originalTearErr;
103
- const row = await deps.getRun(taskId).catch(() => null);
104
- const terminal = terminalEventFromRunRow(row);
134
+ const terminal = await terminalFromRunRow(taskId);
105
135
  if (terminal) {
106
- debugLog(`run row terminal (${String(row?.status)}) — synthesizing the terminal frame (R1b)`);
107
136
  yield terminal;
108
137
  return;
109
138
  }
@@ -18,4 +18,4 @@ export interface ApprovalAllowRuleShadow {
18
18
  export declare function readAllowRuleShadowFromWire(carrier: object | null | undefined, leg: 'frame' | 'row'): ApprovalAllowRuleShadow | undefined;
19
19
  export declare function readApprovalAllowRuleShadow(card: object | null | undefined): ApprovalAllowRuleShadow | undefined;
20
20
  export declare function approvalAllowRuleShadowed(card: object | null | undefined): boolean;
21
- export declare function legacyShadowedRuleTextOf(r: ApprovalAllowRuleShadow | undefined): string | undefined;
21
+ export declare function allowRuleShadowSentence(card: object | null | undefined): string | undefined;
@@ -1,4 +1,5 @@
1
1
  import { CORE_ALLOW_RULE_MEMBERS } from '../generated/engineFactTables.js';
2
+ import { quoteUntrustedForSentence } from '../displayUntrusted.js';
2
3
  const KNOWN_MEMBERS = new Set(CORE_ALLOW_RULE_MEMBERS);
3
4
  function freezeMember(m) {
4
5
  return Object.freeze({ ...m });
@@ -154,14 +155,54 @@ export function readApprovalAllowRuleShadow(card) {
154
155
  export function approvalAllowRuleShadowed(card) {
155
156
  return readApprovalAllowRuleShadow(card) !== undefined;
156
157
  }
157
- export function legacyShadowedRuleTextOf(r) {
158
- if (r === undefined)
158
+ const ENTRY_MAX = 4096;
159
+ const MEMBER_MAX = 64;
160
+ const ENTRIES_SHOWN = 5;
161
+ const UNREADABLE_LINE = 'An allow rule matched this call but cannot clear it; which rule could not be read, so this one is confirmed individually.';
162
+ function legacySingleEntry(shadow) {
163
+ if (shadow.unreadable === true || shadow.members.length !== 1)
159
164
  return undefined;
160
- for (const m of r.members) {
161
- if (m.member !== 'persisted' || m.entries === undefined)
162
- continue;
163
- const first = m.entries[0];
164
- return typeof first === 'string' && first.trim() !== '' ? first : undefined;
165
+ const m = shadow.members[0];
166
+ if (m.member !== 'persisted' || m.malformed === true || m.omitted !== undefined)
167
+ return undefined;
168
+ if (m.entries === undefined || m.entries.length !== 1)
169
+ return undefined;
170
+ return quoteUntrustedForSentence(m.entries[0], ENTRY_MAX);
171
+ }
172
+ function memberPhrase(m) {
173
+ const memberWord = m.member === undefined ? undefined : KNOWN_MEMBERS.has(m.member) ? m.member : quoteUntrustedForSentence(m.member, MEMBER_MAX);
174
+ const word = memberWord ?? 'an unrecognised source';
175
+ const entries = m.entries ?? [];
176
+ if (m.malformed === true && entries.length === 0)
177
+ return `${word} (could not be read)`;
178
+ const listed = entries
179
+ .map((e) => quoteUntrustedForSentence(e, ENTRY_MAX))
180
+ .filter((e) => e !== undefined)
181
+ .slice(0, ENTRIES_SHOWN);
182
+ const notListed = entries.length - listed.length + (m.omitted ?? 0);
183
+ const parts = [];
184
+ if (listed.length > 0)
185
+ parts.push(listed.join(', '));
186
+ if (notListed > 0)
187
+ parts.push(listed.length > 0 ? `and ${String(notListed)} more not listed` : `${String(notListed)} not listed`);
188
+ if (m.malformed === true)
189
+ parts.push('part of it could not be read');
190
+ return parts.length > 0 ? `${word}: ${parts.join('; ')}` : word;
191
+ }
192
+ export function allowRuleShadowSentence(card) {
193
+ const shadow = readApprovalAllowRuleShadow(card);
194
+ if (shadow === undefined)
195
+ return undefined;
196
+ try {
197
+ if (shadow.unreadable === true || shadow.members.length === 0)
198
+ return UNREADABLE_LINE;
199
+ const legacy = legacySingleEntry(shadow);
200
+ if (legacy !== undefined) {
201
+ return `Your saved permission rule ${legacy} still exists — it just cannot clear this particular call, so this one is confirmed individually.`;
202
+ }
203
+ return `Allow rules matched this call but cannot clear it, so this one is confirmed individually — ${shadow.members.map(memberPhrase).join(' · ')}.`;
204
+ }
205
+ catch {
206
+ return UNREADABLE_LINE;
165
207
  }
166
- return undefined;
167
208
  }
@@ -0,0 +1 @@
1
+ export declare function approvalCompleteParked(frame: unknown): boolean;