@sema-agent/client-core 0.100.0 → 0.101.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 (335) hide show
  1. package/CHANGELOG.md +395 -0
  2. package/README.md +164 -117
  3. package/dist/adapt/arms.js +51 -16
  4. package/dist/adapt/textStream.js +7 -4
  5. package/dist/adapt/toolCards.js +9 -8
  6. package/dist/adapt.js +7 -1
  7. package/dist/adapter/activeRunSelfHeal.d.ts +24 -2
  8. package/dist/adapter/activeRunSelfHeal.js +108 -6
  9. package/dist/adapter/downstream/eventToSdkMessage.js +33 -12
  10. package/dist/adapter/downstream/terminalToSdkResult.d.ts +60 -1
  11. package/dist/adapter/downstream/terminalToSdkResult.js +209 -39
  12. package/dist/adapter/runStream.d.ts +4 -4
  13. package/dist/adapter/runStream.js +158 -43
  14. package/dist/agentsWireCaps.d.ts +2 -7
  15. package/dist/agentsWireCaps.js +1 -2
  16. package/dist/approvalDecidedByCapability.js +2 -2
  17. package/dist/approvalFrameFamilies.d.ts +33 -0
  18. package/dist/approvalFrameFamilies.js +120 -0
  19. package/dist/approvalsStreamLiveCapability.js +2 -2
  20. package/dist/attachmentsWireCaps.js +41 -13
  21. package/dist/callerCwdCapability.js +2 -2
  22. package/dist/centerWiringCapability.js +2 -2
  23. package/dist/clockReading.d.ts +2 -0
  24. package/dist/clockReading.js +4 -0
  25. package/dist/cloudConfigWireCaps.d.ts +19 -5
  26. package/dist/cloudConfigWireCaps.js +193 -56
  27. package/dist/coreValuePorts.d.ts +12 -2
  28. package/dist/coreValuePorts.js +9 -0
  29. package/dist/decideFailureNote.js +5 -3
  30. package/dist/decideReceipt.js +2 -2
  31. package/dist/deviceExecutorManagementCapability.js +2 -2
  32. package/dist/deviceFlowPolling.js +1 -1
  33. package/dist/disableSkillsWire.d.ts +1 -1
  34. package/dist/disableSkillsWire.js +4 -3
  35. package/dist/displayUntrusted.d.ts +1 -0
  36. package/dist/displayUntrusted.js +65 -8
  37. package/dist/engineCapReader.js +1 -1
  38. package/dist/engineConfigDrift.js +1 -1
  39. package/dist/engineErrorCodes.d.ts +14 -5
  40. package/dist/engineErrorCodes.js +27 -6
  41. package/dist/engineGenerationConvergence.d.ts +39 -0
  42. package/dist/engineGenerationConvergence.js +95 -0
  43. package/dist/engineGenerationPort.d.ts +61 -0
  44. package/dist/engineGenerationPort.js +144 -0
  45. package/dist/engineHealthFacts.d.ts +23 -0
  46. package/dist/engineHealthFacts.js +92 -0
  47. package/dist/engineIdentity.d.ts +4 -0
  48. package/dist/engineIdentity.js +11 -0
  49. package/dist/engineNoticeCodes.d.ts +2 -5
  50. package/dist/engineRowRef.js +3 -0
  51. package/dist/engineSessionMessages.js +2 -2
  52. package/dist/engineToolDirectory.js +2 -2
  53. package/dist/engineWireFor.d.ts +99 -0
  54. package/dist/engineWireFor.js +248 -6
  55. package/dist/engineWireTarget.d.ts +1 -0
  56. package/dist/engineWireTarget.js +8 -0
  57. package/dist/env/uiLanguage.js +1 -1
  58. package/dist/errorSupplementRoles.d.ts +3 -0
  59. package/dist/errorSupplementRoles.js +37 -0
  60. package/dist/executionLaneCapability.js +2 -2
  61. package/dist/fileHistoryCaptureCapability.js +3 -3
  62. package/dist/finalVerifyWire.d.ts +6 -3
  63. package/dist/finalVerifyWire.js +6 -23
  64. package/dist/flagInput.d.ts +4 -0
  65. package/dist/flagInput.js +24 -0
  66. package/dist/fleet/fleetLedger.js +5 -2
  67. package/dist/fleet/fleetProjection.d.ts +1 -0
  68. package/dist/fleet/fleetProjection.js +15 -2
  69. package/dist/gateVocabulary.js +3 -0
  70. package/dist/generated/engineFactTables.d.ts +7 -3
  71. package/dist/generated/engineFactTables.js +52 -0
  72. package/dist/generated/engineNoticeTables.js +12 -0
  73. package/dist/generated/settingsSchemaActiveTiers.d.ts +1 -0
  74. package/dist/generated/settingsSchemaActiveTiers.js +14 -0
  75. package/dist/generated/settingsSchemaCallerTextEcho.d.ts +1 -0
  76. package/dist/generated/settingsSchemaCallerTextEcho.js +8 -0
  77. package/dist/generated/settingsSchemaControlAndBidi.d.ts +1 -0
  78. package/dist/generated/settingsSchemaControlAndBidi.js +8 -0
  79. package/dist/generated/settingsSchemaDefaultModel.d.ts +11 -0
  80. package/dist/generated/settingsSchemaDefaultModel.js +25 -0
  81. package/dist/generated/settingsSchemaFns.d.ts +54 -0
  82. package/dist/generated/settingsSchemaFns.js +26 -1
  83. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -1
  84. package/dist/generated/settingsSchemaMcpRequestEntry.js +1 -7
  85. package/dist/generated/settingsSchemaSafetyMergeSpec.d.ts +1 -0
  86. package/dist/generated/settingsSchemaSafetyMergeSpec.js +95 -0
  87. package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -0
  88. package/dist/generated/settingsSchemaSettingsSources.js +58 -0
  89. package/dist/generated/settingsSchemaTables.d.ts +2 -0
  90. package/dist/generated/settingsSchemaTables.js +13 -0
  91. package/dist/generated/settingsSchemaUrlPattern.d.ts +1 -0
  92. package/dist/generated/settingsSchemaUrlPattern.js +183 -0
  93. package/dist/headlessPermissionModeWire.d.ts +18 -2
  94. package/dist/headlessPermissionModeWire.js +30 -19
  95. package/dist/hitl/allowRuleShadow.js +7 -5
  96. package/dist/hitl/approvalCardReading.d.ts +3 -0
  97. package/dist/hitl/approvalCardReading.js +17 -0
  98. package/dist/hitl/approvalCompleteParked.js +1 -1
  99. package/dist/hitl/approvalDelivery.d.ts +87 -0
  100. package/dist/hitl/approvalDelivery.js +193 -0
  101. package/dist/hitl/approvalResolution.d.ts +11 -0
  102. package/dist/hitl/approvalResolution.js +50 -11
  103. package/dist/hitl/askClassPair.d.ts +6 -0
  104. package/dist/hitl/askClassPair.js +30 -3
  105. package/dist/hitl/askParkAutoReopenBlock.d.ts +30 -0
  106. package/dist/hitl/askParkAutoReopenBlock.js +117 -0
  107. package/dist/hitl/askParkRowRouting.js +4 -1
  108. package/dist/hitl/attributionLadder.d.ts +42 -3
  109. package/dist/hitl/attributionLadder.js +79 -8
  110. package/dist/hitl/automaticAnswerVerdict.d.ts +6 -1
  111. package/dist/hitl/automaticAnswerVerdict.js +46 -11
  112. package/dist/hitl/crashConverged.js +2 -2
  113. package/dist/hitl/decisionConflict.d.ts +6 -2
  114. package/dist/hitl/decisionConflict.js +24 -9
  115. package/dist/hitl/decisionRefusal.d.ts +20 -10
  116. package/dist/hitl/decisionRefusal.js +99 -54
  117. package/dist/hitl/decisionSend.d.ts +3 -0
  118. package/dist/hitl/decisionSend.js +87 -103
  119. package/dist/hitl/frameRouter.d.ts +1 -0
  120. package/dist/hitl/frameRouter.js +9 -2
  121. package/dist/hitl/hitlBridge.d.ts +18 -6
  122. package/dist/hitl/hitlBridge.js +41 -37
  123. package/dist/hitl/livePendingAsk.js +4 -3
  124. package/dist/hitl/noAllowCause.js +1 -1
  125. package/dist/hitl/parkResolver.js +3 -2
  126. package/dist/hitl/persistedRulesWire.js +1 -0
  127. package/dist/hitl/planReviewWire.d.ts +4 -0
  128. package/dist/hitl/planReviewWire.js +59 -30
  129. package/dist/hitl/resumeRunningCard.d.ts +3 -2
  130. package/dist/hitl/resumeRunningCard.js +17 -11
  131. package/dist/hitl/sessionPolicyDeliverable.d.ts +5 -2
  132. package/dist/hitl/sessionPolicyDeliverable.js +62 -29
  133. package/dist/hitl/sessionPolicyWire.d.ts +13 -3
  134. package/dist/hitl/sessionPolicyWire.js +81 -16
  135. package/dist/hitl/standingRows.js +1 -1
  136. package/dist/hitl/toolApprovalWire.d.ts +9 -10
  137. package/dist/hitl/toolApprovalWire.js +72 -54
  138. package/dist/hookMatcherVerdict.d.ts +2 -0
  139. package/dist/hookMatcherVerdict.js +12 -0
  140. package/dist/hooksCompactTransition.d.ts +19 -0
  141. package/dist/hooksCompactTransition.js +41 -0
  142. package/dist/hooksWireCaps.d.ts +1 -1
  143. package/dist/hooksWireCaps.js +202 -203
  144. package/dist/host.d.ts +1 -14
  145. package/dist/host.js +0 -8
  146. package/dist/hostCallbackGuard.d.ts +1 -0
  147. package/dist/hostCallbackGuard.js +1 -1
  148. package/dist/hostSettingsSource.d.ts +172 -0
  149. package/dist/hostSettingsSource.js +675 -0
  150. package/dist/hostTurnSettings.d.ts +73 -17
  151. package/dist/hostTurnSettings.js +594 -97
  152. package/dist/httpHookPolicy.d.ts +37 -0
  153. package/dist/httpHookPolicy.js +176 -0
  154. package/dist/humanTurn.d.ts +2 -1
  155. package/dist/humanTurn.js +37 -7
  156. package/dist/humanTurnRead.js +4 -3
  157. package/dist/humanTurnSentences.d.ts +10 -0
  158. package/dist/humanTurnSentences.js +74 -0
  159. package/dist/i18n/messages.en.d.ts +184 -2
  160. package/dist/i18n/messages.en.js +187 -5
  161. package/dist/i18n/messages.zh.js +197 -5
  162. package/dist/i18n/translate.js +3 -3
  163. package/dist/index.d.ts +69 -15
  164. package/dist/index.js +45 -13
  165. package/dist/inheritEnvCapability.d.ts +3 -1
  166. package/dist/inheritEnvCapability.js +31 -17
  167. package/dist/inheritEnvWire.d.ts +2 -1
  168. package/dist/inheritEnvWire.js +11 -5
  169. package/dist/interactiveToolsWire.d.ts +4 -2
  170. package/dist/interactiveToolsWire.js +5 -5
  171. package/dist/jsonFaithful.d.ts +20 -0
  172. package/dist/jsonFaithful.js +152 -0
  173. package/dist/limitsWire.d.ts +7 -2
  174. package/dist/limitsWire.js +19 -13
  175. package/dist/liveInitToolFace.d.ts +6 -1
  176. package/dist/liveInitToolFace.js +5 -3
  177. package/dist/liveModelCatalog.d.ts +22 -0
  178. package/dist/liveModelCatalog.js +132 -18
  179. package/dist/mcpPanel.js +1 -1
  180. package/dist/mcpProbeCapability.js +2 -2
  181. package/dist/mcpStatusSupersetKeys.d.ts +24 -0
  182. package/dist/mcpStatusSupersetKeys.js +45 -0
  183. package/dist/mcpToolToggles.js +2 -1
  184. package/dist/mcpWireCaps.d.ts +39 -1
  185. package/dist/mcpWireCaps.js +254 -50
  186. package/dist/memoryComplianceCapability.js +2 -2
  187. package/dist/memoryOriginCapability.js +2 -2
  188. package/dist/model/catalogDefault.d.ts +24 -0
  189. package/dist/model/catalogDefault.js +4 -0
  190. package/dist/model/liveCatalogShape.js +5 -4
  191. package/dist/model/modelsPolicy.js +4 -3
  192. package/dist/model/onboardJudgement.d.ts +1 -0
  193. package/dist/model/onboardJudgement.js +1 -1
  194. package/dist/model/subagentModelWord.js +2 -2
  195. package/dist/modelCapabilityProbe.js +6 -6
  196. package/dist/modelIdentityResolvability.d.ts +10 -1
  197. package/dist/modelIdentityResolvability.js +62 -39
  198. package/dist/modsKernelIdentity.d.ts +10 -0
  199. package/dist/modsKernelIdentity.js +103 -0
  200. package/dist/modsKernelTransit.d.ts +8 -0
  201. package/dist/modsKernelTransit.js +6 -0
  202. package/dist/notifications.d.ts +30 -12
  203. package/dist/notifications.js +241 -53
  204. package/dist/outputStyleSeatCapability.js +2 -2
  205. package/dist/ownKey.d.ts +11 -0
  206. package/dist/ownKey.js +164 -3
  207. package/dist/panelReduce.js +1 -1
  208. package/dist/peerFrames.d.ts +1 -1
  209. package/dist/peerFrames.js +6 -2
  210. package/dist/peerLaneCapability.js +2 -2
  211. package/dist/permissionModesCapability.js +4 -4
  212. package/dist/permissionRuleIssue.js +2 -0
  213. package/dist/permissionRulesWriteCapability.js +2 -2
  214. package/dist/permissionsAllowGrantCapability.js +2 -2
  215. package/dist/permissionsDeclaration.d.ts +43 -4
  216. package/dist/permissionsDeclaration.js +102 -35
  217. package/dist/pluginHooksWire.d.ts +20 -4
  218. package/dist/pluginHooksWire.js +92 -53
  219. package/dist/prepareRefusal.d.ts +3 -2
  220. package/dist/prepareRefusal.js +27 -9
  221. package/dist/printInitToolFace.js +2 -2
  222. package/dist/printModelStatus.js +1 -1
  223. package/dist/projectMemory.d.ts +32 -0
  224. package/dist/projectMemory.js +70 -0
  225. package/dist/promptBlockedCopy.d.ts +2 -1
  226. package/dist/promptBlockedCopy.js +2 -1
  227. package/dist/promptDelivery.d.ts +23 -3
  228. package/dist/promptDelivery.js +169 -30
  229. package/dist/providerRejection.d.ts +19 -1
  230. package/dist/providerRejection.js +75 -4
  231. package/dist/queuedDelivery.d.ts +48 -0
  232. package/dist/queuedDelivery.js +233 -0
  233. package/dist/reattachWindow.d.ts +94 -0
  234. package/dist/reattachWindow.js +127 -0
  235. package/dist/request/printNotification.d.ts +1 -1
  236. package/dist/request/printNotification.js +5 -1
  237. package/dist/request/submissionIdentity.d.ts +37 -0
  238. package/dist/request/submissionIdentity.js +65 -0
  239. package/dist/request/taskRequest.d.ts +12 -4
  240. package/dist/request/taskRequest.js +221 -152
  241. package/dist/resultFrameKeys.d.ts +1 -0
  242. package/dist/resultFrameKeys.js +4 -1
  243. package/dist/retryStatus.d.ts +8 -0
  244. package/dist/retryStatus.js +57 -9
  245. package/dist/rewindArchiveCapability.js +2 -2
  246. package/dist/rewindEngineAction.d.ts +2 -0
  247. package/dist/rewindEngineAction.js +23 -1
  248. package/dist/rowKind.d.ts +36 -0
  249. package/dist/rowKind.js +97 -0
  250. package/dist/ruleCompileVerdict.d.ts +18 -0
  251. package/dist/ruleCompileVerdict.js +67 -2
  252. package/dist/ruleReadings.d.ts +58 -0
  253. package/dist/ruleReadings.js +132 -0
  254. package/dist/ruleRefusalSentence.d.ts +4 -0
  255. package/dist/ruleRefusalSentence.js +9 -3
  256. package/dist/runCancelContext.d.ts +0 -1
  257. package/dist/runCancelContext.js +1 -2
  258. package/dist/runTerminal.d.ts +5 -0
  259. package/dist/runTerminal.js +52 -17
  260. package/dist/sandboxWire.d.ts +1 -1
  261. package/dist/sandboxWire.js +4 -6
  262. package/dist/scenarioRefusal.js +1 -1
  263. package/dist/scenarioSkills.d.ts +20 -0
  264. package/dist/scenarioSkills.js +72 -0
  265. package/dist/scenarioWire.d.ts +5 -2
  266. package/dist/scenarioWire.js +9 -9
  267. package/dist/sealedKeyCapability.js +2 -2
  268. package/dist/seam.d.ts +2 -0
  269. package/dist/seam.js +2 -2
  270. package/dist/seatContract.d.ts +46 -1
  271. package/dist/seatContract.js +49 -19
  272. package/dist/selfOrchestrationDenial.js +1 -1
  273. package/dist/sessionPolicyCapability.js +2 -2
  274. package/dist/sessionRulesChildrenReadLive.d.ts +6 -0
  275. package/dist/sessionRulesChildrenReadLive.js +5 -0
  276. package/dist/sessionRulesNamespaceFormsCapability.d.ts +12 -0
  277. package/dist/sessionRulesNamespaceFormsCapability.js +29 -0
  278. package/dist/sessionSyncFileHistoryCapability.js +2 -2
  279. package/dist/settingsCredentialKeyPaths.js +60 -5
  280. package/dist/settingsHooksSalvage.d.ts +1 -0
  281. package/dist/settingsHooksSalvage.js +7 -1
  282. package/dist/settingsLayerAdmission.d.ts +4 -0
  283. package/dist/settingsLayerAdmission.js +16 -0
  284. package/dist/skillToolListsCapability.js +6 -5
  285. package/dist/skillsWireCaps.d.ts +14 -0
  286. package/dist/skillsWireCaps.js +47 -16
  287. package/dist/slashCommandGate.d.ts +24 -0
  288. package/dist/slashCommandGate.js +74 -0
  289. package/dist/slashCommandTable.d.ts +14 -0
  290. package/dist/slashCommandTable.js +99 -0
  291. package/dist/sqlEngineCapability.js +2 -2
  292. package/dist/steerPriorityCapability.js +2 -2
  293. package/dist/storePostureCapability.js +2 -2
  294. package/dist/subagent/agentStateDetail.js +1 -1
  295. package/dist/subagent/engineDelegatedPrompt.d.ts +9 -0
  296. package/dist/subagent/engineDelegatedPrompt.js +38 -7
  297. package/dist/subagent/engineRowStopGate.js +2 -2
  298. package/dist/subagent/engineSubagentResume.js +3 -3
  299. package/dist/subagent/engineTaskHandleWire.d.ts +1 -0
  300. package/dist/subagent/engineTaskHandleWire.js +10 -0
  301. package/dist/submitFailure.d.ts +8 -0
  302. package/dist/submitFailure.js +17 -0
  303. package/dist/supportFloor.d.ts +1 -0
  304. package/dist/supportFloor.js +7 -0
  305. package/dist/terminationIntent.d.ts +55 -0
  306. package/dist/terminationIntent.js +352 -0
  307. package/dist/toolHistoryMismatch.d.ts +8 -0
  308. package/dist/toolHistoryMismatch.js +37 -6
  309. package/dist/toolResult.d.ts +13 -3
  310. package/dist/toolResult.js +158 -9
  311. package/dist/toolResultContent.d.ts +13 -0
  312. package/dist/toolResultContent.js +82 -7
  313. package/dist/toolRoster.d.ts +18 -0
  314. package/dist/toolRoster.js +64 -0
  315. package/dist/turnFailurePresentation.js +27 -90
  316. package/dist/usageLimitAutoResume.d.ts +74 -0
  317. package/dist/usageLimitAutoResume.js +227 -0
  318. package/dist/userAttachmentEnvelope.js +1 -1
  319. package/dist/userAttachmentSeat.js +5 -5
  320. package/dist/userInvokedSkillsCapability.js +2 -2
  321. package/dist/webSearchBackendCapability.js +2 -2
  322. package/dist/wireErrorTriage.js +99 -50
  323. package/dist/wireFailureShape.d.ts +25 -1
  324. package/dist/wireFailureShape.js +92 -5
  325. package/dist/wireRefusalCopy.d.ts +24 -1
  326. package/dist/wireRefusalCopy.js +253 -32
  327. package/dist/wiringFleetDoctor.d.ts +3 -0
  328. package/dist/wiringFleetDoctor.js +21 -0
  329. package/dist/workflow.d.ts +2 -1
  330. package/dist/workflow.js +38 -1
  331. package/dist/workflowClient.d.ts +2 -7
  332. package/dist/workflowsJournalCapability.js +2 -2
  333. package/dist/writeProtectionCapability.js +2 -2
  334. package/docs/INTEGRATION-CLIENTS.md +607 -181
  335. package/package.json +14 -3
@@ -2,3 +2,4 @@ export declare function resultErrorCodeOf(frame: unknown): string | undefined;
2
2
  export declare function resultSelectedModelOf(frame: unknown): string | undefined;
3
3
  export declare function resultSalvagedResultOf(frame: unknown): string | undefined;
4
4
  export declare function resultParkFailedReasonOf(frame: unknown): string | undefined;
5
+ export declare function resultErrorCodeInTextOf(frame: object | null | undefined): true | undefined;
@@ -1,4 +1,4 @@
1
- import { readFrameStringKey } from './ownKey.js';
1
+ import { readFrameStringKey, readFrameTrueMark } from './ownKey.js';
2
2
  export function resultErrorCodeOf(frame) {
3
3
  return readFrameStringKey(frame, '_sema_error_code');
4
4
  }
@@ -11,3 +11,6 @@ export function resultSalvagedResultOf(frame) {
11
11
  export function resultParkFailedReasonOf(frame) {
12
12
  return readFrameStringKey(frame, '_sema_park_failed_reason');
13
13
  }
14
+ export function resultErrorCodeInTextOf(frame) {
15
+ return readFrameTrueMark(frame, '_sema_error_code_in_text') ? true : undefined;
16
+ }
@@ -1,3 +1,4 @@
1
+ import type { UiLanguage } from './env/uiLanguage.js';
1
2
  export type RetryStatus = {
2
3
  kind: 'stalled';
3
4
  deadline: number;
@@ -134,4 +135,11 @@ export interface ApiErrorNoticeCtx {
134
135
  }
135
136
  export declare function apiErrorFactsOfRow(row: ApiErrorRowLike | null | undefined): ApiErrorRowFacts;
136
137
  export declare function apiErrorNotice(facts: ApiErrorRowFacts | null | undefined, ctx?: ApiErrorNoticeCtx): ApiErrorNotice | undefined;
138
+ export type ResultWayOutWord = NonNullable<ApiErrorNotice['recourse']>;
139
+ export interface ResultWayOut {
140
+ readonly word: ResultWayOutWord;
141
+ readonly keySource?: string;
142
+ }
143
+ export declare function resultWayOutOf(frame: object | null | undefined): ResultWayOut | undefined;
144
+ export declare function wayOutSentence(wayOut: ResultWayOut | null | undefined, lang?: UiLanguage): string | undefined;
137
145
  export {};
@@ -1,6 +1,7 @@
1
1
  import { displayUntrusted } from './displayUntrusted.js';
2
2
  import { guardedRead, readOwnDataFiniteNumber, readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
3
3
  import { msg, renderMessage } from './i18n/translate.js';
4
+ import { conditionRecourseOf, isHttpStatus, isServiceSideStatus, terminalRecourseOf } from './providerRejection.js';
4
5
  export const BRAIN_STATUS_PHASES = [
5
6
  'rate_limited',
6
7
  'retrying',
@@ -122,10 +123,10 @@ export function retryStatusFromArm(arm, nowMs) {
122
123
  }
123
124
  const WAIT_SWITCH_FRACTION = 0.5;
124
125
  const CONDITION_READINGS = Object.freeze({
125
- quota_exhausted: { clause: 'this account cannot be served by the model service until someone acts or its usage window resets', recourse: 'switch_model' },
126
- throttled: { clause: 'the model service is rate limiting requests, which clears on its own', recourse: 'switch_model' },
127
- overloaded: { clause: 'the model service is overloaded', recourse: 'switch_model' },
128
- stop_other: { clause: 'the model service refused this request', resendNote: 'resending will not change it', recourse: 'fix_request' },
126
+ quota_exhausted: { clause: 'this account cannot be served by the model service until someone acts or its usage window resets' },
127
+ throttled: { clause: 'the model service is rate limiting requests, which clears on its own' },
128
+ overloaded: { clause: 'the model service is overloaded' },
129
+ stop_other: { clause: 'the model service refused this request', resendNote: 'resending will not change it' },
129
130
  unknown: null,
130
131
  });
131
132
  function conditionReadingOf(word) {
@@ -152,7 +153,7 @@ function noticeCount(n) {
152
153
  return n !== undefined && Number.isInteger(n) && n >= 1 ? n : undefined;
153
154
  }
154
155
  function noticeHttp(n) {
155
- return n !== undefined && Number.isInteger(n) && n >= 100 && n <= 999 ? n : undefined;
156
+ return isHttpStatus(n) ? n : undefined;
156
157
  }
157
158
  function spanText(ms) {
158
159
  const total = Math.floor(ms / 1000);
@@ -216,7 +217,8 @@ export function retryStatusParts(status, ctx) {
216
217
  return sealParts({ phase: 'waiting_first_token', model, elapsedMs: elapsed, timeoutMs: ceiling, recourse: offerSwitch ? 'switch_model' : 'wait' });
217
218
  }
218
219
  const terminal = kind === 'error' && noticeValue(status, 'terminal') === true;
219
- const reading = conditionReadingOf(noticeText(status, 'providerCondition'));
220
+ const conditionWord = noticeText(status, 'providerCondition');
221
+ const reading = conditionReadingOf(conditionWord);
220
222
  const http = noticeHttp(noticeNumber(status, 'errorStatus'));
221
223
  const attempt = noticeCount(noticeNumber(status, 'attempt'));
222
224
  const maxRetries = noticeCount(noticeNumber(status, 'maxRetries'));
@@ -224,12 +226,12 @@ export function retryStatusParts(status, ctx) {
224
226
  const note = washedText(engineWords);
225
227
  const source = reading === undefined ? undefined : sourcePhraseOf(noticeText(status, 'providerConditionSource'));
226
228
  const condition = reading === undefined ? undefined : `${reading.clause.charAt(0).toUpperCase()}${reading.clause.slice(1)}`;
227
- const serviceSide = http !== undefined && (http === 429 || (http >= 500 && http <= 599));
229
+ const serviceSide = http !== undefined && isServiceSideStatus(http);
228
230
  const knownArm = armWord === 'stalled' || armWord === 'error';
229
231
  const recourse = !knownArm
230
232
  ? undefined
231
233
  : reading !== undefined
232
- ? reading.recourse
234
+ ? conditionRecourseOf(conditionWord)
233
235
  : serviceSide
234
236
  ? 'switch_model'
235
237
  : !terminal
@@ -312,6 +314,52 @@ export function apiErrorNotice(facts, ctx) {
312
314
  };
313
315
  const modelName = noticeText(ctx, 'modelName');
314
316
  const notice = retryStatusNotice(terminal, modelName !== undefined ? { modelName } : undefined);
315
- const recourse = status === 401 || status === 403 ? 'check_credentials' : notice.recourse;
317
+ const recourse = terminalRecourseOf(status, providerCondition);
316
318
  return Object.freeze(recourse === undefined ? { line: notice.line } : { line: notice.line, recourse });
317
319
  }
320
+ const RESULT_WAY_OUT_WORDS = Object.freeze(['check_credentials', 'switch_model', 'wait', 'fix_request']);
321
+ const _wayOutWordPins = [true, true];
322
+ void _wayOutWordPins;
323
+ const KEY_SOURCE_DISPLAY_MAX = 60;
324
+ const WAY_OUT_SENTENCE_KEYS = Object.freeze({
325
+ check_credentials: 'notice.wayOut.checkCredentials',
326
+ switch_model: 'notice.wayOut.switchModel',
327
+ wait: 'notice.wayOut.wait',
328
+ fix_request: 'notice.wayOut.fixRequest',
329
+ });
330
+ function isResultWayOutWord(v) {
331
+ return typeof v === 'string' && RESULT_WAY_OUT_WORDS.includes(v);
332
+ }
333
+ export function resultWayOutOf(frame) {
334
+ try {
335
+ const raw = guardedRead(() => readOwnDataValue(frame, '_sema_wayOut'));
336
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw))
337
+ return undefined;
338
+ const word = guardedRead(() => readOwnDataNonEmptyString(raw, 'word'));
339
+ if (!isResultWayOutWord(word))
340
+ return undefined;
341
+ const keySource = guardedRead(() => readOwnDataNonEmptyString(raw, 'keySource'));
342
+ return Object.freeze(keySource === undefined ? { word } : { word, keySource });
343
+ }
344
+ catch {
345
+ return undefined;
346
+ }
347
+ }
348
+ export function wayOutSentence(wayOut, lang) {
349
+ try {
350
+ if (typeof wayOut !== 'object' || wayOut === null)
351
+ return undefined;
352
+ const word = readOwnDataNonEmptyString(wayOut, 'word');
353
+ if (!isResultWayOutWord(word))
354
+ return undefined;
355
+ if (word === 'check_credentials') {
356
+ const keySource = readOwnDataNonEmptyString(wayOut, 'keySource');
357
+ if (keySource !== undefined)
358
+ return renderMessage(msg('notice.wayOut.checkCredentialsFrom', { source: displayUntrusted(keySource, { max: KEY_SOURCE_DISPLAY_MAX }) }), lang);
359
+ }
360
+ return renderMessage(msg(WAY_OUT_SENTENCE_KEYS[word]), lang);
361
+ }
362
+ catch {
363
+ return undefined;
364
+ }
365
+ }
@@ -1,8 +1,8 @@
1
- import { engineWireTarget } from './engineWireTarget.js';
1
+ import { engineWireTargetBaseUrl } from './engineWireTarget.js';
2
2
  import { rewindArchiveReadingAt, rewindConversationAvailability, } from './rewindArchiveReading.js';
3
3
  import { unreadableReadingDetail } from './engineCapReader.js';
4
4
  export { projectRewindArchiveCapability, rewindConversationAvailability } from './rewindArchiveReading.js';
5
- export function observedRewindArchive(baseUrl = engineWireTarget()?.baseUrl) {
5
+ export function observedRewindArchive(baseUrl = engineWireTargetBaseUrl()) {
6
6
  return rewindArchiveReadingAt(baseUrl);
7
7
  }
8
8
  export function rewindCodeArchiveAvailability(reading, mode) {
@@ -1,3 +1,4 @@
1
+ import type { UiLanguage } from './env/uiLanguage.js';
1
2
  import { type RewindArchiveReading } from './rewindArchiveCapability.js';
2
3
  import { type RewindMode, type SeamRewindSpec } from './rewindWireCaps.js';
3
4
  export type RewindRestoreOption = RewindMode | 'summarize' | 'summarize_up_to' | 'nevermind';
@@ -19,3 +20,4 @@ export type RewindEngineAction = {
19
20
  };
20
21
  export declare function decideRewindEngineAction(option: RewindRestoreOption, resolved: RewindTargetResolution, reading?: RewindArchiveReading): RewindEngineAction;
21
22
  export declare function previewEngineRewind(option: RewindRestoreOption, resolved: RewindTargetResolution, reading?: RewindArchiveReading): RewindEngineAction['kind'];
23
+ export declare function rewindConversationOnlyNotice(option: RewindRestoreOption, action: RewindEngineAction | null | undefined, lang?: UiLanguage, reading?: RewindArchiveReading): string | undefined;
@@ -1,4 +1,5 @@
1
- import { observedRewindArchive } from './rewindArchiveCapability.js';
1
+ import { msg, renderMessage } from './i18n/translate.js';
2
+ import { engineRewindRefusedNow, observedRewindArchive } from './rewindArchiveCapability.js';
2
3
  import { REWIND_MODES, rewindSpecForMode } from './rewindWireCaps.js';
3
4
  import { readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
4
5
  function modeOfOption(option) {
@@ -34,3 +35,24 @@ export function decideRewindEngineAction(option, resolved, reading = observedRew
34
35
  export function previewEngineRewind(option, resolved, reading = observedRewindArchive()) {
35
36
  return decideRewindEngineAction(option, resolved, reading).kind;
36
37
  }
38
+ const UNOBSERVED_READING = { kind: 'unobserved' };
39
+ export function rewindConversationOnlyNotice(option, action, lang, reading = observedRewindArchive()) {
40
+ try {
41
+ const mode = modeOfOption(option);
42
+ if (mode === undefined || rewindSpecForMode(mode, 'x', UNOBSERVED_READING).restoreFiles !== true)
43
+ return undefined;
44
+ if (typeof action !== 'object' || action === null || readOwnDataValue(action, 'kind') !== 'arm')
45
+ return undefined;
46
+ const spec = readOwnDataValue(action, 'spec');
47
+ if (typeof spec !== 'object' || spec === null)
48
+ return undefined;
49
+ if (readOwnDataValue(spec, 'restoreFiles') === true)
50
+ return undefined;
51
+ const codeOnlyMode = REWIND_MODES.find((m) => !carriesResumeAt(m));
52
+ const codeRouteDeadEnd = codeOnlyMode !== undefined && engineRewindRefusedNow(codeOnlyMode, reading);
53
+ return renderMessage(msg(codeRouteDeadEnd ? 'session.rewind.conversationOnly.noCodeRoute' : 'session.rewind.conversationOnly.withCodeRoute'), lang);
54
+ }
55
+ catch {
56
+ return undefined;
57
+ }
58
+ }
@@ -0,0 +1,36 @@
1
+ export declare const RUN_STOPPED_MESSAGE_PREFIX = "Run stopped";
2
+ export declare const RUN_BLOCKED_MESSAGE_PREFIX = "Run blocked";
3
+ export declare const PROMPT_BLOCKED_BY_HOOK_ROW_LEAD = "UserPromptSubmit operation blocked by hook";
4
+ export declare const MODEL_OUTPUT_ERROR_PREFIX = "Model output error";
5
+ export declare const OUTCOME_UNKNOWN_ROW_PREFIX = "Outcome unknown";
6
+ export declare const SESSION_BUSY_ROW_LEAD = "This session is locked by an earlier run";
7
+ export declare const SEMA_ROW_KIND_KEY = "_sema_row_kind";
8
+ export declare const SEMA_ROW_KINDS: readonly [Readonly<{
9
+ kind: "api_error";
10
+ owner: "client-core";
11
+ }>, Readonly<{
12
+ kind: "governance_stop";
13
+ owner: "client-core";
14
+ }>, Readonly<{
15
+ kind: "model_output_error";
16
+ owner: "client-core";
17
+ }>, Readonly<{
18
+ kind: "outcome_unknown";
19
+ owner: "client-core";
20
+ }>, Readonly<{
21
+ kind: "session_busy";
22
+ owner: "client-core";
23
+ }>, Readonly<{
24
+ kind: "engine_link";
25
+ owner: "client-core";
26
+ }>];
27
+ export type SemaRowKind = (typeof SEMA_ROW_KINDS)[number]['kind'];
28
+ export declare function rowKindOf(m: object | null | undefined): SemaRowKind | undefined;
29
+ export declare function rowKindOf<H extends string>(m: object | null | undefined, opts: {
30
+ readonly hostKinds: readonly H[];
31
+ }): SemaRowKind | H | undefined;
32
+ export declare function isSyntheticRow(m: object | null | undefined): boolean;
33
+ export declare function legacyRowKindOfText(text: string): SemaRowKind | undefined;
34
+ export declare function inferLegacyRowKind(m: object | null | undefined, opts?: {
35
+ readonly requireFlag?: boolean;
36
+ }): SemaRowKind | undefined;
@@ -0,0 +1,97 @@
1
+ import { guardedRead, readOwnDataValue } from './ownKey.js';
2
+ export const RUN_STOPPED_MESSAGE_PREFIX = 'Run stopped';
3
+ export const RUN_BLOCKED_MESSAGE_PREFIX = 'Run blocked';
4
+ export const PROMPT_BLOCKED_BY_HOOK_ROW_LEAD = 'UserPromptSubmit operation blocked by hook';
5
+ export const MODEL_OUTPUT_ERROR_PREFIX = 'Model output error';
6
+ export const OUTCOME_UNKNOWN_ROW_PREFIX = 'Outcome unknown';
7
+ export const SESSION_BUSY_ROW_LEAD = 'This session is locked by an earlier run';
8
+ const API_ERROR_ROW_PREFIX = 'API Error';
9
+ const LOGIN_API_ERROR_ROW_PREFIX = `Please run /login · ${API_ERROR_ROW_PREFIX}`;
10
+ export const SEMA_ROW_KIND_KEY = '_sema_row_kind';
11
+ export const SEMA_ROW_KINDS = Object.freeze([
12
+ Object.freeze({ kind: 'api_error', owner: 'client-core' }),
13
+ Object.freeze({ kind: 'governance_stop', owner: 'client-core' }),
14
+ Object.freeze({ kind: 'model_output_error', owner: 'client-core' }),
15
+ Object.freeze({ kind: 'outcome_unknown', owner: 'client-core' }),
16
+ Object.freeze({ kind: 'session_busy', owner: 'client-core' }),
17
+ Object.freeze({ kind: 'engine_link', owner: 'client-core' }),
18
+ ]);
19
+ const KIND_WORDS = new Set(SEMA_ROW_KINDS.map((e) => e.kind));
20
+ const ownData = (o, key) => guardedRead(() => readOwnDataValue(o, key));
21
+ export function rowKindOf(m, opts) {
22
+ const v = ownData(m, SEMA_ROW_KIND_KEY);
23
+ if (typeof v !== 'string' || v.length === 0)
24
+ return undefined;
25
+ if (KIND_WORDS.has(v))
26
+ return v;
27
+ const hostKinds = opts === undefined ? undefined : ownData(opts, 'hostKinds');
28
+ if (Array.isArray(hostKinds)) {
29
+ try {
30
+ if (hostKinds.includes(v))
31
+ return v;
32
+ }
33
+ catch {
34
+ return undefined;
35
+ }
36
+ }
37
+ return undefined;
38
+ }
39
+ function hasSyntheticFlag(m) {
40
+ return ownData(m, '_sema_api_error_message') === true || ownData(m, 'isApiErrorMessage') === true;
41
+ }
42
+ export function isSyntheticRow(m) {
43
+ const v = ownData(m, SEMA_ROW_KIND_KEY);
44
+ if (typeof v === 'string' && v.length > 0)
45
+ return true;
46
+ return hasSyntheticFlag(m);
47
+ }
48
+ export function legacyRowKindOfText(text) {
49
+ const t = text.trimStart();
50
+ if (t.startsWith(API_ERROR_ROW_PREFIX) || t.startsWith(LOGIN_API_ERROR_ROW_PREFIX))
51
+ return 'api_error';
52
+ if (t.startsWith(`${RUN_STOPPED_MESSAGE_PREFIX}:`) || t.startsWith(RUN_BLOCKED_MESSAGE_PREFIX) || t.startsWith(PROMPT_BLOCKED_BY_HOOK_ROW_LEAD))
53
+ return 'governance_stop';
54
+ if (t.startsWith(`${MODEL_OUTPUT_ERROR_PREFIX}:`))
55
+ return 'model_output_error';
56
+ if (t.startsWith(`${OUTCOME_UNKNOWN_ROW_PREFIX}:`))
57
+ return 'outcome_unknown';
58
+ if (t.startsWith(SESSION_BUSY_ROW_LEAD))
59
+ return 'session_busy';
60
+ return undefined;
61
+ }
62
+ function singleTextOf(m) {
63
+ if (ownData(m, 'type') !== 'assistant')
64
+ return undefined;
65
+ const envelope = ownData(m, 'message');
66
+ if (typeof envelope !== 'object' || envelope === null)
67
+ return undefined;
68
+ const content = ownData(envelope, 'content');
69
+ if (typeof content === 'string')
70
+ return content;
71
+ if (!Array.isArray(content))
72
+ return undefined;
73
+ try {
74
+ if (content.length !== 1)
75
+ return undefined;
76
+ }
77
+ catch {
78
+ return undefined;
79
+ }
80
+ const block = ownData(content, '0');
81
+ if (ownData(block, 'type') !== 'text')
82
+ return undefined;
83
+ const text = ownData(block, 'text');
84
+ return typeof text === 'string' ? text : undefined;
85
+ }
86
+ export function inferLegacyRowKind(m, opts) {
87
+ const present = rowKindOf(m);
88
+ if (present !== undefined)
89
+ return present;
90
+ if (ownData(m, SEMA_ROW_KIND_KEY) !== undefined)
91
+ return undefined;
92
+ const requireFlag = opts === undefined ? true : ownData(opts, 'requireFlag') !== false;
93
+ if (requireFlag && !hasSyntheticFlag(m))
94
+ return undefined;
95
+ const text = singleTextOf(m);
96
+ return text === undefined ? undefined : legacyRowKindOfText(text);
97
+ }
@@ -8,3 +8,21 @@ export type RuleCompileVerdict = {
8
8
  readonly kind: 'unknown';
9
9
  };
10
10
  export declare function ruleCompileVerdict(rule: string, behavior: 'deny' | 'ask'): RuleCompileVerdict;
11
+ export interface RuleCompilePathBases {
12
+ readonly cwd?: string;
13
+ readonly root?: string;
14
+ readonly home?: string;
15
+ }
16
+ export declare function ruleCompileVerdictUnder(rule: string, behavior: 'deny' | 'ask', pathBases: RuleCompilePathBases): RuleCompileVerdict;
17
+ export type DenyEntryInertReason = 'grammar' | 'content_unsupported' | 'wildcard_all' | 'namespace_wildcard';
18
+ export type DenyEntryReading = {
19
+ readonly kind: 'row';
20
+ } | {
21
+ readonly kind: 'inert';
22
+ readonly reason: DenyEntryInertReason;
23
+ } | {
24
+ readonly kind: 'unknown';
25
+ };
26
+ export declare function denyEntryReading(rule: string): DenyEntryReading;
27
+ export declare const DOMAIN_TIGHTEN_HONORED_FROM = "7.135.0";
28
+ export declare function tightenEntryNeverMatches(rule: string, serverVersion: string | undefined): boolean;
@@ -1,4 +1,6 @@
1
- import { validatePermissionRules } from './coreValuePorts.js';
1
+ import { readRuleEntry, validatePermissionRules } from './coreValuePorts.js';
2
+ import { guardedRead, readOwnDataValue } from './ownKey.js';
3
+ import { engineVersionTier } from './supportFloor.js';
2
4
  const RULE_COMPILE_ROOT = '/';
3
5
  function issueText(issue, key) {
4
6
  try {
@@ -20,9 +22,21 @@ function firstIssue(issues) {
20
22
  }
21
23
  }
22
24
  export function ruleCompileVerdict(rule, behavior) {
25
+ return compileUnder(rule, behavior, { root: RULE_COMPILE_ROOT });
26
+ }
27
+ export function ruleCompileVerdictUnder(rule, behavior, pathBases) {
28
+ const given = {};
29
+ for (const base of ['cwd', 'root', 'home']) {
30
+ const v = guardedRead(() => readOwnDataValue(pathBases, base));
31
+ if (typeof v === 'string')
32
+ given[base] = v;
33
+ }
34
+ return compileUnder(rule, behavior, given);
35
+ }
36
+ function compileUnder(rule, behavior, pathBases) {
23
37
  let issues;
24
38
  try {
25
- issues = validatePermissionRules([{ rule, behavior }], { pathBases: { root: RULE_COMPILE_ROOT } });
39
+ issues = validatePermissionRules([{ rule, behavior }], { pathBases });
26
40
  if (!Array.isArray(issues))
27
41
  return { kind: 'unknown' };
28
42
  if (issues.length === 0)
@@ -36,3 +50,54 @@ export function ruleCompileVerdict(rule, behavior) {
36
50
  const message = issueText(issue, 'message');
37
51
  return { kind: 'refused', ...(code !== undefined ? { code } : {}), ...(message !== undefined ? { message } : {}) };
38
52
  }
53
+ export function denyEntryReading(rule) {
54
+ try {
55
+ const reading = readRuleEntry(rule, 'deny');
56
+ if (typeof reading !== 'object' || reading === null)
57
+ return { kind: 'unknown' };
58
+ const kind = readOwnDataValue(reading, 'kind');
59
+ if (kind === 'row') {
60
+ const compiled = readOwnDataValue(reading, 'compiled');
61
+ return typeof compiled === 'object' && compiled !== null ? { kind: 'row' } : { kind: 'unknown' };
62
+ }
63
+ if (kind !== 'inert')
64
+ return { kind: 'unknown' };
65
+ const reason = readOwnDataValue(reading, 'reason');
66
+ if (reason === 'grammar' || reason === 'content_unsupported' || reason === 'wildcard_all' || reason === 'namespace_wildcard')
67
+ return { kind: 'inert', reason };
68
+ return { kind: 'unknown' };
69
+ }
70
+ catch {
71
+ return { kind: 'unknown' };
72
+ }
73
+ }
74
+ function readsAsDomainSpelling(rule) {
75
+ try {
76
+ const reading = readRuleEntry(rule, 'allow');
77
+ if (typeof reading !== 'object' || reading === null)
78
+ return false;
79
+ if (readOwnDataValue(reading, 'kind') !== 'row')
80
+ return false;
81
+ const compiled = readOwnDataValue(reading, 'compiled');
82
+ if (typeof compiled !== 'object' || compiled === null)
83
+ return false;
84
+ return readOwnDataValue(compiled, 'kind') === 'domain';
85
+ }
86
+ catch {
87
+ return false;
88
+ }
89
+ }
90
+ export const DOMAIN_TIGHTEN_HONORED_FROM = '7.135.0';
91
+ function targetLeavesDomainTightenInert(serverVersion) {
92
+ return engineVersionTier(serverVersion) === 'engine' && engineVersionTier(serverVersion, DOMAIN_TIGHTEN_HONORED_FROM) === 'legacy';
93
+ }
94
+ export function tightenEntryNeverMatches(rule, serverVersion) {
95
+ if (!targetLeavesDomainTightenInert(serverVersion))
96
+ return false;
97
+ const r = denyEntryReading(rule);
98
+ if (r.kind !== 'inert' || r.reason !== 'content_unsupported')
99
+ return false;
100
+ if (!readsAsDomainSpelling(rule))
101
+ return false;
102
+ return ruleCompileVerdict(rule, 'deny').kind === 'compiles';
103
+ }
@@ -0,0 +1,58 @@
1
+ import type { UiLanguage } from './env/uiLanguage.js';
2
+ import { type PermissionsDeclarationInput, type PermissionsKeptReason, type WireRuleOrigin } from './permissionsDeclaration.js';
3
+ import type { PermissionsAllowGrantReading } from './permissionsAllowGrantCapability.js';
4
+ import { type RuleCompileVerdict } from './ruleCompileVerdict.js';
5
+ import type { ToolRosterView } from './toolRoster.js';
6
+ export interface RuleReadingBases {
7
+ readonly cwd?: string;
8
+ readonly root?: string;
9
+ readonly home?: string;
10
+ }
11
+ export interface RuleReadingFacts {
12
+ readonly bases?: RuleReadingBases;
13
+ readonly roster?: ToolRosterView | null;
14
+ }
15
+ export interface RuleReadingEntryRow {
16
+ readonly kind: 'row';
17
+ readonly grammar: string;
18
+ }
19
+ export interface RuleReadingEntryInert {
20
+ readonly kind: 'inert';
21
+ readonly reason: string;
22
+ readonly verdict?: string;
23
+ readonly currentName?: string;
24
+ readonly currentNameShown?: string;
25
+ }
26
+ export interface RuleReadingEntryUnread {
27
+ readonly kind: 'unread';
28
+ }
29
+ export type RuleReadingEntry = RuleReadingEntryRow | RuleReadingEntryInert | RuleReadingEntryUnread;
30
+ export type PermissionsRuleCompileReading = RuleCompileVerdict;
31
+ export interface PermissionsRuleWireSent {
32
+ readonly sent: true;
33
+ readonly as: string;
34
+ }
35
+ export interface PermissionsRuleWireKept {
36
+ readonly sent: false;
37
+ readonly reason: PermissionsKeptReason;
38
+ readonly code?: string;
39
+ readonly message?: string;
40
+ }
41
+ export type PermissionsRuleWire = PermissionsRuleWireSent | PermissionsRuleWireKept;
42
+ export interface PermissionsRuleReading {
43
+ readonly rule: string;
44
+ readonly list: 'deny' | 'cliDeny' | 'ask' | 'allow';
45
+ readonly bucket: 'deny' | 'ask' | 'allow';
46
+ readonly origin?: WireRuleOrigin;
47
+ readonly wire: PermissionsRuleWire;
48
+ readonly entry: RuleReadingEntry;
49
+ readonly compile?: PermissionsRuleCompileReading;
50
+ }
51
+ export type RuleReadingEntryMode = 'with_roster' | 'grammar_only' | 'unavailable';
52
+ export interface PermissionsRuleReadings {
53
+ readonly rules: readonly PermissionsRuleReading[];
54
+ readonly entryMode: RuleReadingEntryMode;
55
+ }
56
+ export declare function ruleReadingsOf(input: PermissionsDeclarationInput, caps: PermissionsAllowGrantReading, facts?: RuleReadingFacts | null): PermissionsRuleReadings;
57
+ export type RuleNearMissRow = Pick<PermissionsRuleReading, 'rule' | 'wire' | 'entry'>;
58
+ export declare function ruleNearMissSentence(rows: readonly RuleNearMissRow[], lang?: UiLanguage): string | undefined;
@@ -0,0 +1,132 @@
1
+ import { displayUntrusted } from './displayUntrusted.js';
2
+ import { capForDisplay } from './fleetTaskDesc.js';
3
+ import { hasCoreValuePort, readRuleEntry } from './coreValuePorts.js';
4
+ import { msg, renderMessage } from './i18n/translate.js';
5
+ import { guardedRead, readOwnDataValue } from './ownKey.js';
6
+ import { assembledRuleRows } from './permissionsDeclaration.js';
7
+ import { ruleCompileVerdictUnder } from './ruleCompileVerdict.js';
8
+ import { rosterMountedNames } from './rosterMountedNames.js';
9
+ const unread = () => Object.freeze({ kind: 'unread' });
10
+ function text(v) {
11
+ return typeof v === 'string' && v !== '' ? v : undefined;
12
+ }
13
+ function entryOf(rule, direction, roster) {
14
+ try {
15
+ const reading = readRuleEntry(rule, direction, roster);
16
+ if (typeof reading !== 'object' || reading === null)
17
+ return unread();
18
+ const kind = readOwnDataValue(reading, 'kind');
19
+ if (kind === 'row') {
20
+ const compiled = readOwnDataValue(reading, 'compiled');
21
+ if (typeof compiled !== 'object' || compiled === null)
22
+ return unread();
23
+ const grammar = text(readOwnDataValue(compiled, 'kind'));
24
+ return grammar === undefined ? unread() : Object.freeze({ kind: 'row', grammar });
25
+ }
26
+ if (kind !== 'inert')
27
+ return unread();
28
+ const reason = text(readOwnDataValue(reading, 'reason'));
29
+ if (reason === undefined)
30
+ return unread();
31
+ const verdict = text(readOwnDataValue(reading, 'verdict'));
32
+ const currentName = text(readOwnDataValue(reading, 'currentName'));
33
+ return Object.freeze({
34
+ kind: 'inert',
35
+ reason,
36
+ ...(verdict !== undefined ? { verdict } : {}),
37
+ ...(currentName !== undefined ? { currentName, currentNameShown: displayUntrusted(currentName) } : {}),
38
+ });
39
+ }
40
+ catch {
41
+ return unread();
42
+ }
43
+ }
44
+ function factsOf(facts) {
45
+ if (typeof facts !== 'object' || facts === null)
46
+ return { bases: undefined, roster: undefined };
47
+ const bases = guardedRead(() => readOwnDataValue(facts, 'bases'));
48
+ const roster = guardedRead(() => readOwnDataValue(facts, 'roster'));
49
+ return {
50
+ bases: typeof bases === 'object' && bases !== null ? bases : undefined,
51
+ roster: (roster ?? undefined),
52
+ };
53
+ }
54
+ export function ruleReadingsOf(input, caps, facts) {
55
+ const rows = assembledRuleRows(input, caps);
56
+ const { bases, roster: rosterView } = factsOf(facts);
57
+ const readerInstalled = hasCoreValuePort('readRuleEntry');
58
+ const mounted = readerInstalled ? rosterMountedNames(rosterView) : 'absent';
59
+ const roster = typeof mounted === 'object' ? mounted : undefined;
60
+ const rules = rows.map((r) => {
61
+ const wire = r.fate.sent
62
+ ? Object.freeze({ sent: true, as: r.fate.wire })
63
+ : Object.freeze({
64
+ sent: false,
65
+ reason: r.fate.reason,
66
+ ...(r.fate.code !== undefined ? { code: r.fate.code } : {}),
67
+ ...(r.fate.message !== undefined ? { message: r.fate.message } : {}),
68
+ });
69
+ const entry = readerInstalled ? entryOf(r.rule, r.bucket === 'allow' ? 'allow' : 'deny', roster) : unread();
70
+ const compile = bases !== undefined && r.bucket !== 'allow' ? ruleCompileVerdictUnder(r.rule, r.bucket, bases) : undefined;
71
+ return Object.freeze({
72
+ rule: r.rule,
73
+ list: r.list,
74
+ bucket: r.bucket,
75
+ ...(r.origin !== undefined ? { origin: r.origin } : {}),
76
+ wire,
77
+ entry,
78
+ ...(compile !== undefined ? { compile } : {}),
79
+ });
80
+ });
81
+ const anyRead = rules.some((r) => r.entry.kind !== 'unread');
82
+ const entryMode = !readerInstalled || (rules.length > 0 && !anyRead) ? 'unavailable' : roster !== undefined ? 'with_roster' : 'grammar_only';
83
+ return Object.freeze({ rules: Object.freeze(rules), entryMode });
84
+ }
85
+ const NEAR_MISS_NAMED_MAX = 5;
86
+ const NEAR_MISS_RULE_MAX = 120;
87
+ const NEAR_MISS_NAME_MAX = 80;
88
+ export function ruleNearMissSentence(rows, lang) {
89
+ const seen = new Set();
90
+ const items = [];
91
+ try {
92
+ if (!Array.isArray(rows))
93
+ return undefined;
94
+ for (const row of rows) {
95
+ if (typeof row !== 'object' || row === null)
96
+ continue;
97
+ const rule = guardedRead(() => readOwnDataValue(row, 'rule'));
98
+ if (typeof rule !== 'string' || rule === '' || seen.has(rule))
99
+ continue;
100
+ const wire = guardedRead(() => readOwnDataValue(row, 'wire'));
101
+ if (typeof wire !== 'object' || wire === null || guardedRead(() => readOwnDataValue(wire, 'sent')) !== true)
102
+ continue;
103
+ const entry = guardedRead(() => readOwnDataValue(row, 'entry'));
104
+ if (typeof entry !== 'object' || entry === null)
105
+ continue;
106
+ if (guardedRead(() => readOwnDataValue(entry, 'kind')) !== 'inert' || guardedRead(() => readOwnDataValue(entry, 'reason')) !== 'near_miss')
107
+ continue;
108
+ const mounted = text(guardedRead(() => readOwnDataValue(entry, 'currentName')));
109
+ if (mounted === undefined)
110
+ continue;
111
+ seen.add(rule);
112
+ items.push({ rule, mounted });
113
+ }
114
+ }
115
+ catch {
116
+ return undefined;
117
+ }
118
+ if (items.length === 0)
119
+ return undefined;
120
+ const shown = items.slice(0, NEAR_MISS_NAMED_MAX);
121
+ const separator = renderMessage(msg('rules.refusal.itemSeparator'), lang);
122
+ const named = shown
123
+ .map((it) => renderMessage(msg('rules.refusal.item', {
124
+ rule: `"${capForDisplay(it.rule, NEAR_MISS_RULE_MAX)}"`,
125
+ reason: renderMessage(msg('rules.nearMiss.reason', { mounted: capForDisplay(displayUntrusted(it.mounted), NEAR_MISS_NAME_MAX) }), lang),
126
+ }), lang))
127
+ .join(separator);
128
+ const rest = items.length - shown.length;
129
+ const list = rest > 0 ? msg('rules.refusal.list.more', { shown: named, count: rest }) : named;
130
+ const listText = typeof list === 'string' ? list : renderMessage(list, lang);
131
+ return renderMessage(items.length === 1 ? msg('rules.nearMiss.sentence.one', { list: listText }) : msg('rules.nearMiss.sentence.other', { count: items.length, list: listText }), lang);
132
+ }
@@ -2,3 +2,7 @@ import type { UiLanguage } from './env/uiLanguage.js';
2
2
  import type { PermissionsKeptRule } from './permissionsDeclaration.js';
3
3
  export type RuleRefusalRow = Pick<PermissionsKeptRule, 'rule' | 'reason' | 'code' | 'message'>;
4
4
  export declare function ruleRefusalSentence(rows: readonly RuleRefusalRow[], lang?: UiLanguage): string | undefined;
5
+ export declare function ruleRefusalListText(items: readonly {
6
+ readonly rule?: string;
7
+ readonly reason: string;
8
+ }[], lang?: UiLanguage): string;