@sema-agent/client-core 0.99.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 (374) hide show
  1. package/CHANGELOG.md +572 -0
  2. package/README.md +174 -114
  3. package/dist/adapt/arms.js +109 -50
  4. package/dist/adapt/panelTasks.d.ts +2 -1
  5. package/dist/adapt/panelTasks.js +32 -9
  6. package/dist/adapt/textStream.d.ts +1 -1
  7. package/dist/adapt/textStream.js +58 -32
  8. package/dist/adapt/toolCards.js +9 -8
  9. package/dist/adapt.js +7 -1
  10. package/dist/adapter/activeRunSelfHeal.d.ts +31 -2
  11. package/dist/adapter/activeRunSelfHeal.js +162 -13
  12. package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
  13. package/dist/adapter/downstream/eventToSdkMessage.js +157 -20
  14. package/dist/adapter/downstream/terminalToSdkResult.d.ts +60 -1
  15. package/dist/adapter/downstream/terminalToSdkResult.js +219 -39
  16. package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
  17. package/dist/adapter/downstream/wiringManifestView.js +1 -0
  18. package/dist/adapter/runStream.d.ts +4 -4
  19. package/dist/adapter/runStream.js +184 -42
  20. package/dist/adapter/types.d.ts +2 -0
  21. package/dist/agentsWireCaps.d.ts +9 -7
  22. package/dist/agentsWireCaps.js +101 -17
  23. package/dist/approvalDecidedByCapability.js +2 -2
  24. package/dist/approvalFrameFamilies.d.ts +33 -0
  25. package/dist/approvalFrameFamilies.js +120 -0
  26. package/dist/approvalsStreamLiveCapability.js +2 -2
  27. package/dist/attachmentsWireCaps.js +41 -13
  28. package/dist/callerCwdCapability.js +2 -2
  29. package/dist/centerWiringCapability.js +2 -2
  30. package/dist/clockReading.d.ts +2 -0
  31. package/dist/clockReading.js +4 -0
  32. package/dist/cloudConfigWireCaps.d.ts +28 -5
  33. package/dist/cloudConfigWireCaps.js +334 -103
  34. package/dist/compactionStatus.d.ts +34 -0
  35. package/dist/compactionStatus.js +196 -0
  36. package/dist/coreValuePorts.d.ts +12 -2
  37. package/dist/coreValuePorts.js +9 -0
  38. package/dist/decideFailureNote.js +8 -6
  39. package/dist/decideReceipt.js +2 -2
  40. package/dist/deviceExecutorManagementCapability.js +2 -2
  41. package/dist/deviceFlowPolling.js +1 -1
  42. package/dist/disableSkillsWire.d.ts +1 -1
  43. package/dist/disableSkillsWire.js +4 -3
  44. package/dist/displayUntrusted.d.ts +1 -0
  45. package/dist/displayUntrusted.js +215 -13
  46. package/dist/engineAgentPanelStore.d.ts +7 -4
  47. package/dist/engineCapReader.js +1 -1
  48. package/dist/engineConfigDrift.js +1 -1
  49. package/dist/engineErrorCodes.d.ts +23 -6
  50. package/dist/engineErrorCodes.js +36 -11
  51. package/dist/engineGenerationConvergence.d.ts +39 -0
  52. package/dist/engineGenerationConvergence.js +95 -0
  53. package/dist/engineGenerationPort.d.ts +61 -0
  54. package/dist/engineGenerationPort.js +144 -0
  55. package/dist/engineHealthFacts.d.ts +23 -0
  56. package/dist/engineHealthFacts.js +92 -0
  57. package/dist/engineIdentity.d.ts +4 -0
  58. package/dist/engineIdentity.js +11 -0
  59. package/dist/engineNoticeCodes.d.ts +2 -5
  60. package/dist/engineRowRef.js +4 -0
  61. package/dist/engineSessionMessages.js +2 -2
  62. package/dist/engineToolDirectory.d.ts +3 -0
  63. package/dist/engineToolDirectory.js +6 -4
  64. package/dist/engineWireFor.d.ts +99 -0
  65. package/dist/engineWireFor.js +248 -6
  66. package/dist/engineWireTarget.d.ts +1 -0
  67. package/dist/engineWireTarget.js +8 -0
  68. package/dist/env/uiLanguage.js +1 -1
  69. package/dist/errorSupplementRoles.d.ts +3 -0
  70. package/dist/errorSupplementRoles.js +37 -0
  71. package/dist/eventLeg.d.ts +1 -7
  72. package/dist/eventLeg.js +7 -8
  73. package/dist/executionLaneCapability.js +2 -2
  74. package/dist/fileHistoryCaptureCapability.d.ts +0 -3
  75. package/dist/fileHistoryCaptureCapability.js +3 -7
  76. package/dist/finalVerifyWire.d.ts +6 -3
  77. package/dist/finalVerifyWire.js +6 -23
  78. package/dist/flagInput.d.ts +4 -0
  79. package/dist/flagInput.js +24 -0
  80. package/dist/fleet/fleetLedger.js +5 -2
  81. package/dist/fleet/fleetProjection.d.ts +1 -0
  82. package/dist/fleet/fleetProjection.js +15 -2
  83. package/dist/gateVocabulary.js +3 -0
  84. package/dist/generated/engineFactTables.d.ts +7 -2
  85. package/dist/generated/engineFactTables.js +79 -0
  86. package/dist/generated/engineNoticeTables.js +15 -0
  87. package/dist/generated/settingsSchemaActiveTiers.d.ts +1 -0
  88. package/dist/generated/settingsSchemaActiveTiers.js +14 -0
  89. package/dist/generated/settingsSchemaCallerTextEcho.d.ts +1 -0
  90. package/dist/generated/settingsSchemaCallerTextEcho.js +8 -0
  91. package/dist/generated/settingsSchemaControlAndBidi.d.ts +1 -0
  92. package/dist/generated/settingsSchemaControlAndBidi.js +8 -0
  93. package/dist/generated/settingsSchemaDefaultModel.d.ts +11 -0
  94. package/dist/generated/settingsSchemaDefaultModel.js +25 -0
  95. package/dist/generated/settingsSchemaFns.d.ts +66 -0
  96. package/dist/generated/settingsSchemaFns.js +38 -0
  97. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
  98. package/dist/generated/settingsSchemaMcpRequestEntry.js +156 -0
  99. package/dist/generated/settingsSchemaSafetyMergeSpec.d.ts +1 -0
  100. package/dist/generated/settingsSchemaSafetyMergeSpec.js +95 -0
  101. package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -0
  102. package/dist/generated/settingsSchemaSettingsSources.js +58 -0
  103. package/dist/generated/settingsSchemaTables.d.ts +3 -0
  104. package/dist/generated/settingsSchemaTables.js +18 -0
  105. package/dist/generated/settingsSchemaTypes.d.ts +28 -0
  106. package/dist/generated/settingsSchemaUrlPattern.d.ts +1 -0
  107. package/dist/generated/settingsSchemaUrlPattern.js +183 -0
  108. package/dist/headlessPermissionModeWire.d.ts +18 -2
  109. package/dist/headlessPermissionModeWire.js +30 -19
  110. package/dist/hitl/allowRuleShadow.js +9 -7
  111. package/dist/hitl/approvalCardReading.d.ts +3 -0
  112. package/dist/hitl/approvalCardReading.js +17 -0
  113. package/dist/hitl/approvalCardReasons.js +2 -2
  114. package/dist/hitl/approvalCompleteParked.js +1 -1
  115. package/dist/hitl/approvalDelivery.d.ts +87 -0
  116. package/dist/hitl/approvalDelivery.js +193 -0
  117. package/dist/hitl/approvalHolds.d.ts +14 -0
  118. package/dist/hitl/approvalHolds.js +41 -0
  119. package/dist/hitl/approvalResolution.d.ts +11 -0
  120. package/dist/hitl/approvalResolution.js +50 -11
  121. package/dist/hitl/askClassPair.d.ts +8 -2
  122. package/dist/hitl/askClassPair.js +31 -4
  123. package/dist/hitl/askParkAutoReopenBlock.d.ts +30 -0
  124. package/dist/hitl/askParkAutoReopenBlock.js +117 -0
  125. package/dist/hitl/askParkRowRouting.js +4 -1
  126. package/dist/hitl/attributionLadder.d.ts +62 -0
  127. package/dist/hitl/attributionLadder.js +138 -0
  128. package/dist/hitl/automaticAnswerVerdict.d.ts +6 -1
  129. package/dist/hitl/automaticAnswerVerdict.js +46 -11
  130. package/dist/hitl/crashConverged.js +2 -2
  131. package/dist/hitl/decisionConflict.d.ts +6 -2
  132. package/dist/hitl/decisionConflict.js +24 -9
  133. package/dist/hitl/decisionLedger.d.ts +55 -0
  134. package/dist/hitl/decisionLedger.js +156 -0
  135. package/dist/hitl/decisionRefusal.d.ts +21 -10
  136. package/dist/hitl/decisionRefusal.js +100 -55
  137. package/dist/hitl/decisionSend.d.ts +116 -0
  138. package/dist/hitl/decisionSend.js +563 -0
  139. package/dist/hitl/frameRouter.d.ts +1 -0
  140. package/dist/hitl/frameRouter.js +9 -2
  141. package/dist/hitl/hitlBridge.d.ts +18 -6
  142. package/dist/hitl/hitlBridge.js +59 -43
  143. package/dist/hitl/livePendingAsk.js +4 -3
  144. package/dist/hitl/noAllowCause.js +1 -1
  145. package/dist/hitl/parkResolver.js +3 -2
  146. package/dist/hitl/persistedRulesWire.js +1 -0
  147. package/dist/hitl/planReviewWire.d.ts +4 -0
  148. package/dist/hitl/planReviewWire.js +104 -106
  149. package/dist/hitl/resumeRunningCard.d.ts +3 -2
  150. package/dist/hitl/resumeRunningCard.js +17 -11
  151. package/dist/hitl/sessionPolicyDeliverable.d.ts +5 -2
  152. package/dist/hitl/sessionPolicyDeliverable.js +65 -35
  153. package/dist/hitl/sessionPolicyWire.d.ts +13 -3
  154. package/dist/hitl/sessionPolicyWire.js +81 -16
  155. package/dist/hitl/standingRows.js +1 -1
  156. package/dist/hitl/toolApprovalWire.d.ts +9 -10
  157. package/dist/hitl/toolApprovalWire.js +103 -151
  158. package/dist/hookMatcherVerdict.d.ts +2 -0
  159. package/dist/hookMatcherVerdict.js +12 -0
  160. package/dist/hooksCompactTransition.d.ts +19 -0
  161. package/dist/hooksCompactTransition.js +41 -0
  162. package/dist/hooksWireCaps.d.ts +1 -1
  163. package/dist/hooksWireCaps.js +202 -203
  164. package/dist/host.d.ts +1 -14
  165. package/dist/host.js +0 -8
  166. package/dist/hostCallbackGuard.d.ts +1 -0
  167. package/dist/hostCallbackGuard.js +1 -1
  168. package/dist/hostSettingsSource.d.ts +172 -0
  169. package/dist/hostSettingsSource.js +675 -0
  170. package/dist/hostTurnSettings.d.ts +114 -19
  171. package/dist/hostTurnSettings.js +966 -68
  172. package/dist/httpHookPolicy.d.ts +37 -0
  173. package/dist/httpHookPolicy.js +176 -0
  174. package/dist/humanTurn.d.ts +4 -2
  175. package/dist/humanTurn.js +40 -10
  176. package/dist/humanTurnRead.js +4 -3
  177. package/dist/humanTurnSentences.d.ts +10 -0
  178. package/dist/humanTurnSentences.js +74 -0
  179. package/dist/i18n/messages.en.d.ts +313 -0
  180. package/dist/i18n/messages.en.js +326 -13
  181. package/dist/i18n/messages.zh.js +341 -13
  182. package/dist/i18n/translate.js +3 -3
  183. package/dist/index.d.ts +85 -15
  184. package/dist/index.js +53 -12
  185. package/dist/inheritEnvCapability.d.ts +4 -1
  186. package/dist/inheritEnvCapability.js +38 -17
  187. package/dist/inheritEnvWire.d.ts +2 -1
  188. package/dist/inheritEnvWire.js +11 -5
  189. package/dist/injectionLaneNotice.d.ts +5 -0
  190. package/dist/injectionLaneNotice.js +46 -0
  191. package/dist/interactiveToolsWire.d.ts +4 -2
  192. package/dist/interactiveToolsWire.js +5 -5
  193. package/dist/jsonFaithful.d.ts +20 -0
  194. package/dist/jsonFaithful.js +152 -0
  195. package/dist/limitsWire.d.ts +7 -2
  196. package/dist/limitsWire.js +19 -13
  197. package/dist/liveInitToolFace.d.ts +6 -1
  198. package/dist/liveInitToolFace.js +5 -3
  199. package/dist/liveModelCatalog.d.ts +22 -0
  200. package/dist/liveModelCatalog.js +132 -18
  201. package/dist/mcpPanel.js +3 -1
  202. package/dist/mcpProbeCapability.js +2 -2
  203. package/dist/mcpReconnect.js +2 -2
  204. package/dist/mcpStatusSupersetKeys.d.ts +24 -0
  205. package/dist/mcpStatusSupersetKeys.js +45 -0
  206. package/dist/mcpToolToggles.d.ts +6 -0
  207. package/dist/mcpToolToggles.js +47 -0
  208. package/dist/mcpWireCaps.d.ts +48 -4
  209. package/dist/mcpWireCaps.js +338 -99
  210. package/dist/mcpWireTransport.d.ts +4 -0
  211. package/dist/mcpWireTransport.js +18 -0
  212. package/dist/memoryComplianceCapability.js +2 -2
  213. package/dist/memoryOriginCapability.js +2 -2
  214. package/dist/model/catalogDefault.d.ts +24 -0
  215. package/dist/model/catalogDefault.js +4 -0
  216. package/dist/model/liveCatalogShape.js +5 -4
  217. package/dist/model/modelsPolicy.js +4 -3
  218. package/dist/model/onboardJudgement.d.ts +1 -0
  219. package/dist/model/onboardJudgement.js +1 -1
  220. package/dist/model/subagentModelWord.js +2 -2
  221. package/dist/modelCapabilityProbe.d.ts +2 -1
  222. package/dist/modelCapabilityProbe.js +16 -15
  223. package/dist/modelIdentityResolvability.d.ts +12 -1
  224. package/dist/modelIdentityResolvability.js +69 -28
  225. package/dist/modsKernelIdentity.d.ts +10 -0
  226. package/dist/modsKernelIdentity.js +103 -0
  227. package/dist/modsKernelTransit.d.ts +8 -0
  228. package/dist/modsKernelTransit.js +6 -0
  229. package/dist/notifications.d.ts +30 -12
  230. package/dist/notifications.js +241 -53
  231. package/dist/outputStyleSeatCapability.js +2 -2
  232. package/dist/ownKey.d.ts +37 -0
  233. package/dist/ownKey.js +238 -2
  234. package/dist/panelReduce.d.ts +5 -0
  235. package/dist/panelReduce.js +45 -13
  236. package/dist/panelStateHolder.d.ts +1 -0
  237. package/dist/panelStateHolder.js +10 -1
  238. package/dist/peerFrames.d.ts +1 -1
  239. package/dist/peerFrames.js +6 -2
  240. package/dist/peerLaneCapability.js +2 -2
  241. package/dist/permissionModesCapability.js +4 -4
  242. package/dist/permissionRuleIssue.d.ts +2 -1
  243. package/dist/permissionRuleIssue.js +24 -21
  244. package/dist/permissionRulesWriteCapability.js +2 -2
  245. package/dist/permissionsAllowGrantCapability.js +2 -2
  246. package/dist/permissionsDeclaration.d.ts +43 -4
  247. package/dist/permissionsDeclaration.js +102 -35
  248. package/dist/pluginHooksWire.d.ts +20 -4
  249. package/dist/pluginHooksWire.js +101 -60
  250. package/dist/prepareRefusal.d.ts +9 -0
  251. package/dist/prepareRefusal.js +90 -0
  252. package/dist/printInitToolFace.js +2 -2
  253. package/dist/printModelStatus.js +1 -1
  254. package/dist/projectMemory.d.ts +32 -0
  255. package/dist/projectMemory.js +70 -0
  256. package/dist/promptBlockedCopy.d.ts +2 -1
  257. package/dist/promptBlockedCopy.js +2 -1
  258. package/dist/promptDelivery.d.ts +23 -3
  259. package/dist/promptDelivery.js +169 -30
  260. package/dist/providerRejection.d.ts +19 -1
  261. package/dist/providerRejection.js +75 -4
  262. package/dist/queuedDelivery.d.ts +48 -0
  263. package/dist/queuedDelivery.js +233 -0
  264. package/dist/reattachWindow.d.ts +94 -0
  265. package/dist/reattachWindow.js +127 -0
  266. package/dist/request/printNotification.d.ts +1 -1
  267. package/dist/request/printNotification.js +5 -1
  268. package/dist/request/submissionIdentity.d.ts +37 -0
  269. package/dist/request/submissionIdentity.js +65 -0
  270. package/dist/request/taskRequest.d.ts +22 -14
  271. package/dist/request/taskRequest.js +312 -202
  272. package/dist/resultFrameKeys.d.ts +1 -0
  273. package/dist/resultFrameKeys.js +4 -1
  274. package/dist/resumeRefusalCopy.d.ts +3 -1
  275. package/dist/resumeRefusalCopy.js +22 -4
  276. package/dist/retryStatus.d.ts +26 -0
  277. package/dist/retryStatus.js +133 -28
  278. package/dist/rewindArchiveCapability.js +2 -2
  279. package/dist/rewindEngineAction.d.ts +2 -0
  280. package/dist/rewindEngineAction.js +23 -1
  281. package/dist/rowKind.d.ts +36 -0
  282. package/dist/rowKind.js +97 -0
  283. package/dist/ruleCompileVerdict.d.ts +18 -0
  284. package/dist/ruleCompileVerdict.js +67 -2
  285. package/dist/ruleReadings.d.ts +58 -0
  286. package/dist/ruleReadings.js +132 -0
  287. package/dist/ruleRefusalSentence.d.ts +8 -0
  288. package/dist/ruleRefusalSentence.js +64 -0
  289. package/dist/runCancelContext.d.ts +0 -1
  290. package/dist/runCancelContext.js +1 -2
  291. package/dist/runTerminal.d.ts +5 -0
  292. package/dist/runTerminal.js +52 -17
  293. package/dist/sandboxWire.d.ts +3 -2
  294. package/dist/sandboxWire.js +59 -27
  295. package/dist/scenarioRefusal.d.ts +2 -1
  296. package/dist/scenarioRefusal.js +6 -6
  297. package/dist/scenarioSkills.d.ts +20 -0
  298. package/dist/scenarioSkills.js +72 -0
  299. package/dist/scenarioWire.d.ts +5 -2
  300. package/dist/scenarioWire.js +9 -9
  301. package/dist/sealedKeyCapability.js +2 -2
  302. package/dist/seam.d.ts +26 -9
  303. package/dist/seam.js +44 -4
  304. package/dist/seatContract.d.ts +62 -9
  305. package/dist/seatContract.js +70 -25
  306. package/dist/selfOrchestrationDenial.js +1 -1
  307. package/dist/sessionPolicyCapability.js +2 -2
  308. package/dist/sessionRulesChildrenReadLive.d.ts +6 -0
  309. package/dist/sessionRulesChildrenReadLive.js +5 -0
  310. package/dist/sessionRulesNamespaceFormsCapability.d.ts +12 -0
  311. package/dist/sessionRulesNamespaceFormsCapability.js +29 -0
  312. package/dist/sessionSyncFileHistoryCapability.js +2 -2
  313. package/dist/settingsCredentialKeyPaths.d.ts +8 -0
  314. package/dist/settingsCredentialKeyPaths.js +274 -0
  315. package/dist/settingsHooksSalvage.d.ts +1 -0
  316. package/dist/settingsHooksSalvage.js +7 -1
  317. package/dist/settingsLayerAdmission.d.ts +4 -0
  318. package/dist/settingsLayerAdmission.js +16 -0
  319. package/dist/skillToolListsCapability.js +6 -5
  320. package/dist/skillsWireCaps.d.ts +14 -3
  321. package/dist/skillsWireCaps.js +48 -18
  322. package/dist/slashCommandGate.d.ts +24 -0
  323. package/dist/slashCommandGate.js +74 -0
  324. package/dist/slashCommandTable.d.ts +14 -0
  325. package/dist/slashCommandTable.js +99 -0
  326. package/dist/sqlEngineCapability.js +2 -2
  327. package/dist/steerPriorityCapability.js +2 -2
  328. package/dist/storePostureCapability.js +2 -2
  329. package/dist/subagent/agentStateDetail.js +1 -1
  330. package/dist/subagent/engineDelegatedPrompt.d.ts +9 -0
  331. package/dist/subagent/engineDelegatedPrompt.js +38 -7
  332. package/dist/subagent/engineRowStopGate.js +2 -2
  333. package/dist/subagent/engineSubagentResume.js +3 -3
  334. package/dist/subagent/engineTaskHandleWire.d.ts +1 -0
  335. package/dist/subagent/engineTaskHandleWire.js +10 -0
  336. package/dist/subagentContentStore.d.ts +1 -0
  337. package/dist/subagentContentStore.js +135 -27
  338. package/dist/submitFailure.d.ts +8 -0
  339. package/dist/submitFailure.js +17 -0
  340. package/dist/supportFloor.d.ts +1 -0
  341. package/dist/supportFloor.js +7 -0
  342. package/dist/terminationIntent.d.ts +55 -0
  343. package/dist/terminationIntent.js +352 -0
  344. package/dist/toolHistoryMismatch.d.ts +8 -0
  345. package/dist/toolHistoryMismatch.js +37 -6
  346. package/dist/toolResult.d.ts +13 -3
  347. package/dist/toolResult.js +158 -9
  348. package/dist/toolResultContent.d.ts +13 -0
  349. package/dist/toolResultContent.js +82 -7
  350. package/dist/toolRoster.d.ts +18 -0
  351. package/dist/toolRoster.js +64 -0
  352. package/dist/toolsFlagNames.d.ts +8 -0
  353. package/dist/toolsFlagNames.js +110 -0
  354. package/dist/turnFailurePresentation.js +41 -96
  355. package/dist/usageLimitAutoResume.d.ts +74 -0
  356. package/dist/usageLimitAutoResume.js +227 -0
  357. package/dist/userAttachmentEnvelope.js +1 -1
  358. package/dist/userAttachmentSeat.js +5 -5
  359. package/dist/userInvokedSkillsCapability.js +2 -2
  360. package/dist/webSearchBackendCapability.js +2 -2
  361. package/dist/wireErrorTriage.js +99 -50
  362. package/dist/wireFailureShape.d.ts +25 -1
  363. package/dist/wireFailureShape.js +92 -5
  364. package/dist/wireRefusalCopy.d.ts +75 -18
  365. package/dist/wireRefusalCopy.js +532 -148
  366. package/dist/wiringFleetDoctor.d.ts +3 -0
  367. package/dist/wiringFleetDoctor.js +21 -0
  368. package/dist/workflow.d.ts +2 -1
  369. package/dist/workflow.js +38 -1
  370. package/dist/workflowClient.d.ts +2 -7
  371. package/dist/workflowsJournalCapability.js +2 -2
  372. package/dist/writeProtectionCapability.js +2 -2
  373. package/docs/INTEGRATION-CLIENTS.md +1013 -190
  374. package/package.json +15 -4
@@ -8,6 +8,8 @@ import { CORE_PROTOCOL_PREFIXES } from './generated/toolNameTables.js';
8
8
  import { rosterMountedNames } from './rosterMountedNames.js';
9
9
  import { capForDisplay } from './fleetTaskDesc.js';
10
10
  import { deniedEntryToolName } from './engineToolDirectory.js';
11
+ import { hasCoreValuePort, mcpNamespace, mintNamespacePrefix } from './coreValuePorts.js';
12
+ import { msg, renderMessage } from './i18n/translate.js';
11
13
  import { assemblyRefusal, withAssemblyRefusal } from './wireFailureShape.js';
12
14
  export const MAX_TASK_AGENTS = 32;
13
15
  export const TASK_AGENT_WIRE_FIELDS = [
@@ -28,6 +30,7 @@ export const TASK_AGENT_WIRE_FIELDS = [
28
30
  'observerMessage',
29
31
  ];
30
32
  export const AGENT_MEMORY_WORDS = frozenSet(['user', 'project', 'local']);
33
+ export const REFUSED_PROJECT_SERVER_CAUSES = Object.freeze(['rejected', 'not_approved', 'disabled', 'policy_blocked', 'plugin_only', 'malformed_config']);
31
34
  const SOURCE_RANK = {
32
35
  policySettings: 0,
33
36
  flagSettings: 1,
@@ -113,8 +116,58 @@ function toolListShapeRefusal(agent, key, v) {
113
116
  return withAssemblyRefusal(new TypeError(`projectAgentsForWire: agent "${capForDisplay(agent, 80)}" has ${key} written as ${listShapeWord(v)}, but it must be an array of tool-name strings — ` +
114
117
  'refusing to assemble the agents list (a list dropped silently would give the agent every tool, or remove a deny rule). Fix the definition.'), 'input_malformed');
115
118
  }
119
+ const REFUSED_SERVER_PHRASE_KEYS = Object.freeze({
120
+ rejected: ['config.agentsWire.refusedServer.cause.rejected', 'config.agentsWire.refusedServer.way.rejected'],
121
+ not_approved: ['config.agentsWire.refusedServer.cause.notApproved', 'config.agentsWire.refusedServer.way.notApproved'],
122
+ disabled: ['config.agentsWire.refusedServer.cause.disabled', 'config.agentsWire.refusedServer.way.disabled'],
123
+ policy_blocked: ['config.agentsWire.refusedServer.cause.policyBlocked', 'config.agentsWire.refusedServer.way.policyBlocked'],
124
+ plugin_only: ['config.agentsWire.refusedServer.cause.pluginOnly', 'config.agentsWire.refusedServer.way.pluginOnly'],
125
+ malformed_config: ['config.agentsWire.refusedServer.cause.malformedConfig', 'config.agentsWire.refusedServer.way.malformedConfig'],
126
+ });
127
+ const REFUSED_SERVER_UNKNOWN_PHRASE = ['config.agentsWire.refusedServer.cause.unknown', 'config.agentsWire.refusedServer.way.unknown'];
128
+ const REFUSED_SERVER_NAME_MAX = 80;
129
+ function refusedServerIndexOf(list) {
130
+ try {
131
+ if (!Array.isArray(list) || list.length === 0)
132
+ return [];
133
+ if (!hasCoreValuePort('protocolOf') || !hasCoreValuePort('mintNamespacePrefix'))
134
+ return [];
135
+ const ns = mcpNamespace();
136
+ if (ns === undefined)
137
+ return [];
138
+ const out = [];
139
+ const seen = new Set();
140
+ for (const row of list) {
141
+ try {
142
+ if (row === null || typeof row !== 'object')
143
+ continue;
144
+ const name = row.name;
145
+ const cause = row.cause;
146
+ if (typeof name !== 'string' || name === '' || seen.has(name))
147
+ continue;
148
+ const prefix = mintNamespacePrefix(ns, name);
149
+ if (typeof prefix !== 'string' || prefix.length === 0)
150
+ continue;
151
+ seen.add(name);
152
+ const known = typeof cause === 'string' && Object.hasOwn(REFUSED_SERVER_PHRASE_KEYS, cause) ? REFUSED_SERVER_PHRASE_KEYS[cause] : undefined;
153
+ out.push({ name, prefix, phrase: known ?? REFUSED_SERVER_UNKNOWN_PHRASE });
154
+ }
155
+ catch {
156
+ continue;
157
+ }
158
+ }
159
+ return out;
160
+ }
161
+ catch {
162
+ return [];
163
+ }
164
+ }
165
+ function entryNamesServer(entry, prefix) {
166
+ return entry.startsWith(prefix) || entry === prefix.slice(0, -2);
167
+ }
116
168
  export function projectAgentsForWire(defs, deps) {
117
169
  const warnings = [];
170
+ const refusedServers = refusedServerIndexOf(deps.refusedProjectServers);
118
171
  const customs = defs
119
172
  .filter(d => d.source !== 'built-in')
120
173
  .slice()
@@ -171,9 +224,8 @@ export function projectAgentsForWire(defs, deps) {
171
224
  whoMemo = `agent "${name}"${typeof source === 'string' && source.length > 0 ? ` (${capForDisplay(source, 120)})` : ''}`;
172
225
  return whoMemo;
173
226
  };
174
- const rosterInHand = typeof rosterMountedNames(deps.toolRoster) === 'object';
175
227
  const flaws = agentToolListFlaws([item], deps.toolRoster).map((f) => {
176
- if (!rosterInHand || f.list !== 'disallowedTools' || f.kind !== 'retired' || f.currentName === undefined || f.toolName !== undefined)
228
+ if (f.list !== 'disallowedTools' || f.kind !== 'retired' || f.currentName === undefined || f.toolName !== undefined)
177
229
  return f;
178
230
  const to = f.currentName;
179
231
  if (item.denyTools !== undefined)
@@ -191,7 +243,30 @@ export function projectAgentsForWire(defs, deps) {
191
243
  for (const f of flaws) {
192
244
  if (f.list !== 'tools')
193
245
  continue;
194
- warnings.push(`agents wire: ${who}: its tools entry ${toolListFlawPhrase(f)} — sent as written; tool names are matched exactly, so this entry gives the agent nothing unless this run has a tool with exactly that name. Fix the entry in the agent definition.`);
246
+ warnings.push(renderMessage(msg('config.agentsWire.toolEntry.sentence', { who, phrase: toolListFlawPhrase(f) })));
247
+ }
248
+ }
249
+ if (refusedServers.length > 0 && item.allowTools !== undefined) {
250
+ const told = new Set();
251
+ const mounted = rosterMountedNames(deps.toolRoster);
252
+ const mountedNames = typeof mounted === 'object' ? mounted : undefined;
253
+ for (const entry of item.allowTools) {
254
+ if (mountedNames?.has(entry) === true)
255
+ continue;
256
+ const hit = refusedServers.find((r) => entryNamesServer(entry, r.prefix));
257
+ if (hit === undefined)
258
+ continue;
259
+ const sentence = renderMessage(msg('config.agentsWire.refusedServer.sentence', {
260
+ who: whoOf(),
261
+ entry: JSON.stringify(entry),
262
+ server: JSON.stringify(capForDisplay(hit.name, REFUSED_SERVER_NAME_MAX)),
263
+ cause: msg(hit.phrase[0]),
264
+ way: msg(hit.phrase[1]),
265
+ }));
266
+ if (told.has(sentence))
267
+ continue;
268
+ told.add(sentence);
269
+ warnings.push(sentence);
195
270
  }
196
271
  }
197
272
  if (def.memory !== undefined) {
@@ -300,6 +375,12 @@ let preparedKey = null;
300
375
  let preparedCapsGen = null;
301
376
  let preparedPromise = null;
302
377
  let payload;
378
+ function setPayload(agents, warnings) {
379
+ payload = { agents, warnings: Object.freeze([...warnings]) };
380
+ }
381
+ function clearPayload() {
382
+ payload = undefined;
383
+ }
303
384
  let currentGeneration = null;
304
385
  function concludeGeneration(generation, outcome) {
305
386
  if (generation !== null && preparedPromise === generation && currentGeneration !== null)
@@ -335,7 +416,7 @@ function watchCapsVerdict(baseUrl) {
335
416
  void engineCapsSettled(baseUrl).then(() => {
336
417
  if (preparedKey !== baseUrl || capsVerdictAt(baseUrl) !== false)
337
418
  return;
338
- payload = undefined;
419
+ clearPayload();
339
420
  concludeGeneration(preparedPromise, 'ok');
340
421
  currentGeneration?.settle();
341
422
  });
@@ -345,12 +426,10 @@ function applyProjectionIfCurrent(generation, projected) {
345
426
  return false;
346
427
  const accepted = capsVerdictAt(preparedKey) !== false;
347
428
  if (accepted) {
348
- for (const w of projected.warnings)
349
- warnOnce(w);
350
- payload = projected.agents;
429
+ setPayload(projected.agents, projected.warnings);
351
430
  }
352
431
  else {
353
- payload = undefined;
432
+ clearPayload();
354
433
  }
355
434
  concludeGeneration(generation, 'ok');
356
435
  currentGeneration?.settle();
@@ -361,7 +440,7 @@ async function runPrepare(cfg, projector, generation) {
361
440
  const [, projected] = await Promise.all([capsSettledAt(cfg.baseUrl), projector()]);
362
441
  if (capsVerdictAt(cfg.baseUrl) === false) {
363
442
  if (preparedKey === cfg.baseUrl) {
364
- payload = undefined;
443
+ clearPayload();
365
444
  concludeGeneration(generation, 'ok');
366
445
  if (projected.agents) {
367
446
  warnOnce(`agents wire: this engine does not support per-task custom agents (capabilities.taskAgents is not true: the engine does not report it, or this deployment turns it off, for example a multi-tenant one; this client cannot tell which) — ${projected.agents.length} custom agent definition(s) will NOT be sent`);
@@ -371,13 +450,14 @@ async function runPrepare(cfg, projector, generation) {
371
450
  }
372
451
  if (!applyProjectionIfCurrent(generation, projected))
373
452
  return;
374
- if (payload && hostEnv().SEMA_DEBUG) {
375
- console.error(`[sema] agents wire: ${payload.length} custom agent(s) → TaskRequest.agents (${payload.map(a => a.name).join(', ')})`);
453
+ const sent = payload?.agents;
454
+ if (sent && hostEnv().SEMA_DEBUG) {
455
+ console.error(`[sema] agents wire: ${sent.length} custom agent(s) → TaskRequest.agents (${sent.map(a => a.name).join(', ')})`);
376
456
  }
377
457
  }
378
458
  catch (e) {
379
459
  if (preparedPromise === generation)
380
- payload = undefined;
460
+ clearPayload();
381
461
  concludeGeneration(generation, 'failed');
382
462
  if (hostEnv().SEMA_DEBUG) {
383
463
  console.error('[sema] agents wire prepare failed (the readiness gate refuses this turn):', e);
@@ -412,7 +492,7 @@ export function invalidateTaskAgentsWire() {
412
492
  const projector = activeProjector;
413
493
  if (!preparedPromise || !projector)
414
494
  return Promise.resolve();
415
- payload = undefined;
495
+ clearPayload();
416
496
  return startGeneration(generation => runReproject(projector, generation));
417
497
  }
418
498
  async function runReproject(projector, generation) {
@@ -443,7 +523,7 @@ export async function awaitTaskAgentsWire(timeoutMs = 4000) {
443
523
  return taskAgentsReady();
444
524
  const projector = activeProjector;
445
525
  if (currentGeneration?.outcome === 'failed' && projector !== null) {
446
- payload = undefined;
526
+ clearPayload();
447
527
  void startGeneration(generation => runReproject(projector, generation));
448
528
  }
449
529
  let timeoutHandle;
@@ -502,10 +582,14 @@ function kickTaskAgentsRefresh() {
502
582
  export function taskAgentsField() {
503
583
  const base = preparedKey;
504
584
  if (capsVerdictAt(base) === false) {
505
- payload = undefined;
585
+ clearPayload();
506
586
  return {};
507
587
  }
508
- const current = payload;
588
+ const held = payload;
589
+ const current = held?.agents;
590
+ if (held !== undefined)
591
+ for (const w of held.warnings)
592
+ warnOnce(w);
509
593
  kickTaskAgentsRefresh();
510
594
  return current ? { agents: current } : {};
511
595
  }
@@ -515,6 +599,6 @@ export function _resetAgentsWireForTest() {
515
599
  preparedCapsGen = null;
516
600
  preparedPromise = null;
517
601
  currentGeneration = null;
518
- payload = undefined;
602
+ clearPayload();
519
603
  emittedWarnings.clear();
520
604
  }
@@ -1,4 +1,4 @@
1
- import { engineWireTarget } from './engineWireTarget.js';
1
+ import { engineWireTargetBaseUrl } from './engineWireTarget.js';
2
2
  import { createEngineCapReader } from './engineCapReader.js';
3
3
  import { ownDataField, readOwnDataValue } from './ownKey.js';
4
4
  export function projectApprovalDecidedByCapability(caps) {
@@ -18,7 +18,7 @@ const reader = createEngineCapReader({
18
18
  name: 'approvalDecidedBy',
19
19
  project: projectApprovalDecidedByCapability,
20
20
  });
21
- export function observedApprovalDecidedBy(baseUrl = engineWireTarget()?.baseUrl) {
21
+ export function observedApprovalDecidedBy(baseUrl = engineWireTargetBaseUrl()) {
22
22
  return reader.observed(baseUrl);
23
23
  }
24
24
  export function approvalDecidedByAdmitted(reading) {
@@ -0,0 +1,33 @@
1
+ export type ApprovalFrameFamiliesReading = {
2
+ readonly kind: 'confirmed';
3
+ readonly families: readonly string[];
4
+ } | {
5
+ readonly kind: 'absent';
6
+ } | {
7
+ readonly kind: 'declined';
8
+ } | {
9
+ readonly kind: 'unreadable';
10
+ } | {
11
+ readonly kind: 'unobserved';
12
+ };
13
+ export declare function observedApprovalFrameFamilies(baseUrl?: string | undefined): ApprovalFrameFamiliesReading;
14
+ export type ApprovalFrameFamiliesWithheldCause = 'capability_absent' | 'capability_declined' | 'capability_unreadable' | 'reading_absent';
15
+ export interface ApprovalFrameFamiliesWithheld {
16
+ readonly cause: ApprovalFrameFamiliesWithheldCause;
17
+ }
18
+ export interface ApprovalFrameFamiliesDeclaration {
19
+ readonly field: {
20
+ readonly approvalFrameFamilies?: readonly string[];
21
+ };
22
+ readonly withheld?: ApprovalFrameFamiliesWithheld;
23
+ }
24
+ export declare function approvalFrameFamiliesDeclaration(reading: ApprovalFrameFamiliesReading): ApprovalFrameFamiliesDeclaration;
25
+ export declare function frameFamiliesJudgementOf(reading: ApprovalFrameFamiliesReading): FrameFamiliesJudgement;
26
+ export type FrameFamiliesJudgement = {
27
+ readonly ok: true;
28
+ readonly families: readonly string[];
29
+ } | {
30
+ readonly ok: false;
31
+ readonly cause: ApprovalFrameFamiliesWithheldCause;
32
+ };
33
+ export declare function intersectRenderedFamilies(presented: readonly string[], rendered: readonly string[]): readonly string[];
@@ -0,0 +1,120 @@
1
+ import { engineCapNestedValue, engineCapValue } from './engineCapsCache.js';
2
+ import { engineWireTargetBaseUrl } from './engineWireTarget.js';
3
+ import { appendOwnElement, guardedRead, readOwnDataValue } from './ownKey.js';
4
+ const PRESENTED_FAMILIES_KEY = 'approvalFrameFamilies';
5
+ const ACCEPTANCE_GROUP_KEY = 'taskSettings';
6
+ const ACCEPTANCE_KEY = 'approvalFrameFamilies';
7
+ const SERVER_FRAME_FAMILY_WORDS = Object.freeze(['tool_approval', 'approval_request']);
8
+ const RENDERED_FRAME_FAMILY_WORDS = Object.freeze(['tool_approval', 'approval_request']);
9
+ const MAX_PRESENTED_ENTRIES = 16;
10
+ const READ_ABSENT = Object.freeze({ kind: 'absent' });
11
+ const READ_DECLINED = Object.freeze({ kind: 'declined' });
12
+ const READ_UNREADABLE = Object.freeze({ kind: 'unreadable' });
13
+ const READ_UNOBSERVED = Object.freeze({ kind: 'unobserved' });
14
+ function presentedFamiliesOf(raw) {
15
+ try {
16
+ if (!Array.isArray(raw)) {
17
+ if (typeof raw === 'object' && raw !== null)
18
+ Object.getPrototypeOf(raw);
19
+ return 'declined';
20
+ }
21
+ const lenDesc = Object.getOwnPropertyDescriptor(raw, 'length');
22
+ const len = lenDesc !== undefined && Object.hasOwn(lenDesc, 'value') ? lenDesc.value : undefined;
23
+ if (typeof len !== 'number' || !Number.isInteger(len) || len < 0)
24
+ return 'unreadable';
25
+ if (len > MAX_PRESENTED_ENTRIES)
26
+ return 'declined';
27
+ const out = [];
28
+ for (let i = 0; i < len; i++) {
29
+ const d = Object.getOwnPropertyDescriptor(raw, String(i));
30
+ if (d === undefined)
31
+ return 'declined';
32
+ if (!Object.hasOwn(d, 'value'))
33
+ return 'unreadable';
34
+ const w = d.value;
35
+ if (typeof w !== 'string' || !SERVER_FRAME_FAMILY_WORDS.includes(w))
36
+ return 'declined';
37
+ if (!out.includes(w))
38
+ appendOwnElement(out, w);
39
+ }
40
+ return Object.freeze(out);
41
+ }
42
+ catch {
43
+ return 'unreadable';
44
+ }
45
+ }
46
+ export function observedApprovalFrameFamilies(baseUrl) {
47
+ try {
48
+ const picked = baseUrl === undefined ? engineWireTargetBaseUrl() : baseUrl;
49
+ const base = typeof picked === 'string' ? picked : undefined;
50
+ const accepted = engineCapNestedValue(base, ACCEPTANCE_GROUP_KEY, ACCEPTANCE_KEY);
51
+ switch (accepted.kind) {
52
+ case 'unobserved':
53
+ return READ_UNOBSERVED;
54
+ case 'not_reported':
55
+ return READ_ABSENT;
56
+ case 'unreadable':
57
+ return READ_UNREADABLE;
58
+ case 'null':
59
+ return READ_DECLINED;
60
+ case 'value':
61
+ if (accepted.value !== true)
62
+ return READ_DECLINED;
63
+ break;
64
+ }
65
+ const presented = engineCapValue(base, PRESENTED_FAMILIES_KEY);
66
+ switch (presented.kind) {
67
+ case 'unobserved':
68
+ return READ_UNOBSERVED;
69
+ case 'not_reported':
70
+ return READ_ABSENT;
71
+ case 'unreadable':
72
+ return READ_UNREADABLE;
73
+ case 'null':
74
+ return READ_DECLINED;
75
+ case 'value': {
76
+ const families = presentedFamiliesOf(presented.value);
77
+ if (families === 'declined')
78
+ return READ_DECLINED;
79
+ if (families === 'unreadable')
80
+ return READ_UNREADABLE;
81
+ return Object.freeze({ kind: 'confirmed', families });
82
+ }
83
+ }
84
+ }
85
+ catch {
86
+ return READ_UNOBSERVED;
87
+ }
88
+ }
89
+ const NO_FIELD = Object.freeze(Object.create(null));
90
+ function withheldOf(cause) {
91
+ return Object.freeze({ field: NO_FIELD, withheld: Object.freeze({ cause }) });
92
+ }
93
+ export function approvalFrameFamiliesDeclaration(reading) {
94
+ const j = judgeReading(reading);
95
+ return j.ok ? Object.freeze({ field: Object.freeze({ approvalFrameFamilies: j.families }) }) : withheldOf(j.cause);
96
+ }
97
+ export function frameFamiliesJudgementOf(reading) {
98
+ return judgeReading(reading);
99
+ }
100
+ function judgeReading(reading) {
101
+ const kind = guardedRead(() => (typeof reading === 'object' && reading !== null ? readOwnDataValue(reading, 'kind') : undefined));
102
+ if (kind === 'absent')
103
+ return { ok: false, cause: 'capability_absent' };
104
+ if (kind === 'declined')
105
+ return { ok: false, cause: 'capability_declined' };
106
+ if (kind !== 'confirmed')
107
+ return { ok: false, cause: 'capability_unreadable' };
108
+ const raw = guardedRead(() => readOwnDataValue(reading, 'families'));
109
+ const presented = presentedFamiliesOf(raw);
110
+ if (presented === 'declined' || presented === 'unreadable')
111
+ return { ok: false, cause: 'capability_unreadable' };
112
+ return { ok: true, families: intersectRenderedFamilies(presented, RENDERED_FRAME_FAMILY_WORDS) };
113
+ }
114
+ export function intersectRenderedFamilies(presented, rendered) {
115
+ const out = [];
116
+ for (const w of presented)
117
+ if (rendered.includes(w) && !out.includes(w))
118
+ appendOwnElement(out, w);
119
+ return Object.freeze(out);
120
+ }
@@ -1,4 +1,4 @@
1
- import { engineWireTarget } from './engineWireTarget.js';
1
+ import { engineWireTargetBaseUrl } from './engineWireTarget.js';
2
2
  import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
3
3
  import { ownDataField } from './ownKey.js';
4
4
  export function projectApprovalsStreamLiveCapability(caps) {
@@ -22,7 +22,7 @@ const reader = createEngineCapReader({
22
22
  name: 'approvalsStreamLive',
23
23
  project: projectApprovalsStreamLiveCapability,
24
24
  });
25
- export function observedApprovalsStreamLive(baseUrl = engineWireTarget()?.baseUrl) {
25
+ export function observedApprovalsStreamLive(baseUrl = engineWireTargetBaseUrl()) {
26
26
  return reader.observed(baseUrl);
27
27
  }
28
28
  export function livePendingNeedsReconcile(reading) {
@@ -1,6 +1,8 @@
1
1
  import { hostEnv } from './hostEnv.js';
2
2
  import { envFlagOff } from './envFlag.js';
3
3
  import { retiredAttachmentsKeyOf } from './taskRequestWords.js';
4
+ import { looksLikeKnownSecret, REDACTION_MARKER_PREFIX } from './displayUntrusted.js';
5
+ import { msg, renderMessage } from './i18n/translate.js';
4
6
  export const ATTACHMENTS_ENV = 'SEMA_ATTACHMENTS';
5
7
  export const ATTACHMENTS_SPEC_KEYS = Object.freeze([
6
8
  'todoReminder',
@@ -57,20 +59,38 @@ function refuse(token, why) {
57
59
  function deny(kind, token, why, index, key) {
58
60
  return { ok: false, refusal: { kind, token, why, entry: index + 1, key } };
59
61
  }
60
- function judgeAttachmentsEnv(raw) {
62
+ const CREDENTIAL_TOKEN_PLACEHOLDER = `${REDACTION_MARKER_PREFIX}:secret\u00bb`;
63
+ function credentialShapedWord(original) {
64
+ if (original === undefined || original.length === 0)
65
+ return false;
66
+ try {
67
+ const bare = original.replace(/^[+-]+/, '');
68
+ const eq = bare.indexOf('=');
69
+ return looksLikeKnownSecret(original) || looksLikeKnownSecret(bare) || (eq >= 0 && looksLikeKnownSecret(bare.slice(eq + 1)));
70
+ }
71
+ catch {
72
+ return false;
73
+ }
74
+ }
75
+ function judgeAttachmentsEnv(raw, original = raw) {
61
76
  if (envFlagOff(raw))
62
77
  return { ok: true, spec: allDefaultOnOff() };
63
78
  const tokens = raw.split(',').map(t => t.trim()).filter(t => t.length > 0);
79
+ const originals = original.split(',').map(t => t.trim()).filter(t => t.length > 0);
80
+ const denyAt = (kind, token, why, index, key) => deny(kind, credentialShapedWord(originals[index]) ? CREDENTIAL_TOKEN_PLACEHOLDER : token, why, index, key);
64
81
  for (const [i, token] of tokens.entries()) {
65
82
  const named = retiredAttachmentsKeyOf(token);
66
83
  if (named !== undefined)
67
- return { ok: false, refusal: { kind: 'retired_key', token, why: named.why, entry: i + 1, key: named.key, retired: named } };
84
+ return { ok: false, refusal: { kind: 'retired_key', token: credentialShapedWord(originals[i]) ? CREDENTIAL_TOKEN_PLACEHOLDER : token, why: named.why, entry: i + 1, key: named.key, retired: named } };
68
85
  }
69
86
  if (tokens.length === 0)
70
87
  return { ok: true, spec: productDefaultAttachments() };
71
88
  if (tokens.length === 1 && (tokens[0] === 'full' || tokens[0] === 'all'))
72
89
  return { ok: true, spec: allLiteralTrue() };
73
90
  if (tokens.length === 1 && !isKnownToken(tokens[0])) {
91
+ if (credentialShapedWord(originals[0])) {
92
+ return deny('credential_shaped_word', CREDENTIAL_TOKEN_PLACEHOLDER, 'the value looks like a credential, not an attachments list', 0, undefined);
93
+ }
74
94
  return { ok: true, spec: productDefaultAttachments() };
75
95
  }
76
96
  const spec = {};
@@ -86,9 +106,9 @@ function judgeAttachmentsEnv(raw) {
86
106
  if (token.startsWith('-')) {
87
107
  const key = canonicalKey(token.slice(1));
88
108
  if (key === undefined)
89
- return deny('unknown_key', token, 'unknown attachments key', i, undefined);
109
+ return denyAt('unknown_key', token, 'unknown attachments key', i, undefined);
90
110
  if (!isDefaultOnKey(key)) {
91
- return deny('minus_on_literal_true_key', token, `"${key}" belongs to the literal-true family whose OFF is "delete the key", not "send false" ` +
111
+ return denyAt('minus_on_literal_true_key', token, `"${key}" belongs to the literal-true family whose OFF is "delete the key", not "send false" ` +
92
112
  '(core wire contract, board [479] ask-2) — simply do not turn it on. ' +
93
113
  `Only the core DEFAULT-ON keys (${ATTACHMENTS_DEFAULT_ON_KEYS.join(' / ')}) accept an explicit false`, i, key);
94
114
  }
@@ -98,34 +118,39 @@ function judgeAttachmentsEnv(raw) {
98
118
  const [lhs, rhs] = splitAssign(token);
99
119
  if (rhs !== undefined) {
100
120
  if (canonicalKey(lhs) !== 'todoReminderMode')
101
- return deny('value_form_on_other_key', token, 'only `todoReminderMode` takes a `key=value` form', i, canonicalKey(lhs));
121
+ return denyAt('value_form_on_other_key', token, 'only `todoReminderMode` takes a `key=value` form', i, canonicalKey(lhs));
102
122
  const mode = TODO_REMINDER_MODES.find(v => v === rhs);
103
123
  if (mode === undefined)
104
- return deny('todo_mode_bad_value', token, `todoReminderMode must be one of ${TODO_REMINDER_MODES.join('|')}`, i, 'todoReminderMode');
124
+ return denyAt('todo_mode_bad_value', token, `todoReminderMode must be one of ${TODO_REMINDER_MODES.join('|')}`, i, 'todoReminderMode');
105
125
  spec.todoReminderMode = mode;
106
126
  continue;
107
127
  }
108
128
  const key = canonicalKey(lhs.startsWith('+') ? lhs.slice(1) : lhs);
109
129
  if (key === undefined)
110
- return deny('unknown_key', token, 'unknown attachments key', i, undefined);
130
+ return denyAt('unknown_key', token, 'unknown attachments key', i, undefined);
111
131
  if (isDefaultOnOnlyKey(key)) {
112
- return deny('plus_on_default_on_key', token, `"${key}" is core DEFAULT-ON — turning it "on" is a no-op that would send a redundant true; ` + `use "-${key}" to turn it OFF`, i, key);
132
+ return denyAt('plus_on_default_on_key', token, `"${key}" is core DEFAULT-ON — turning it "on" is a no-op that would send a redundant true; ` + `use "-${key}" to turn it OFF`, i, key);
113
133
  }
114
134
  if (key === 'todoReminderMode')
115
- return deny('todo_mode_needs_value', token, 'todoReminderMode needs a value: `todoReminderMode=baseline|off`', i, key);
135
+ return denyAt('todo_mode_needs_value', token, 'todoReminderMode needs a value: `todoReminderMode=baseline|off`', i, key);
116
136
  spec[key] = true;
117
137
  }
118
138
  return { ok: true, spec };
119
139
  }
120
- function envRawOf(env) {
121
- return (env[ATTACHMENTS_ENV] ?? '').trim().toLowerCase();
140
+ function envTextOf(env) {
141
+ const original = (env[ATTACHMENTS_ENV] ?? '').trim();
142
+ return { lower: original.toLowerCase(), original };
122
143
  }
123
144
  export function attachmentsForRequest(env = hostEnv()) {
124
- const judged = judgeAttachmentsEnv(envRawOf(env));
145
+ const text = envTextOf(env);
146
+ const judged = judgeAttachmentsEnv(text.lower, text.original);
125
147
  if (!judged.ok)
126
148
  return refuse(judged.refusal.token, judged.refusal.why);
127
149
  return judged.spec;
128
150
  }
151
+ function headWithCatalogLine(head, catalogLine) {
152
+ return `${head} ${catalogLine} ${attachmentsWayOut()}`;
153
+ }
129
154
  function attachmentsWayOut() {
130
155
  const on = OPT_IN_KEYS.join(', ');
131
156
  const off = ATTACHMENTS_DEFAULT_ON_KEYS.join(', ');
@@ -141,6 +166,8 @@ function attachmentsRefusalSentence(r) {
141
166
  return `${head} names "${key}", a key that no longer exists — ${r.retired?.because ?? 'it was retired'}, and a request carrying that key is refused by the server. Remove that entry${r.retired === undefined ? '' : `; ${r.retired.remedy}`}. ${attachmentsWayOut()}`;
142
167
  case 'unknown_key':
143
168
  return `${head} is not an attachment this version knows. ${attachmentsWayOut()}`;
169
+ case 'credential_shaped_word':
170
+ return headWithCatalogLine(head, renderMessage(msg('config.attachments.refusal.credentialShapedWord')));
144
171
  case 'minus_on_literal_true_key':
145
172
  return key === 'todoReminderMode'
146
173
  ? `${head} puts a minus on todoReminderMode, which is a setting with a value rather than something to turn off — write todoReminderMode=${TODO_REMINDER_MODES.join(' or todoReminderMode=')}, or leave it out of the list. A minus only works on ${ATTACHMENTS_DEFAULT_ON_KEYS.join(', ')}, which are on by default. ${attachmentsWayOut()}`
@@ -160,7 +187,8 @@ function attachmentsUnreadableSentence() {
160
187
  }
161
188
  export function attachmentsSubmitVerdict(env = hostEnv()) {
162
189
  try {
163
- const judged = judgeAttachmentsEnv(envRawOf(env));
190
+ const text = envTextOf(env);
191
+ const judged = judgeAttachmentsEnv(text.lower, text.original);
164
192
  if (judged.ok)
165
193
  return { ok: true, attachments: judged.spec };
166
194
  return { ok: false, sentence: attachmentsRefusalSentence(judged.refusal), refusedKey: judged.refusal.key };
@@ -1,4 +1,4 @@
1
- import { engineWireTarget } from './engineWireTarget.js';
1
+ import { engineWireTargetBaseUrl } from './engineWireTarget.js';
2
2
  import { createEngineCapReader } from './engineCapReader.js';
3
3
  import { ownDataField, readOwnDataValue } from './ownKey.js';
4
4
  export function projectCallerCwdCapability(caps) {
@@ -18,7 +18,7 @@ const reader = createEngineCapReader({
18
18
  name: 'callerCwd',
19
19
  project: projectCallerCwdCapability,
20
20
  });
21
- export function observedCallerCwd(baseUrl = engineWireTarget()?.baseUrl) {
21
+ export function observedCallerCwd(baseUrl = engineWireTargetBaseUrl()) {
22
22
  return reader.observed(baseUrl);
23
23
  }
24
24
  export function callerCwdAdmitted(reading) {
@@ -1,5 +1,5 @@
1
1
  import { capForDisplay } from './fleetTaskDesc.js';
2
- import { engineWireTarget } from './engineWireTarget.js';
2
+ import { engineWireTargetBaseUrl } from './engineWireTarget.js';
3
3
  import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
4
4
  import { ownDataField } from './ownKey.js';
5
5
  const nonEmpty = (v) => typeof v === 'string' && v !== '';
@@ -95,7 +95,7 @@ const reader = createEngineCapReader({
95
95
  name: 'centerWiring',
96
96
  project: projectCenterWiringForCache,
97
97
  });
98
- export function observedCenterWiring(baseUrl = engineWireTarget()?.baseUrl) {
98
+ export function observedCenterWiring(baseUrl = engineWireTargetBaseUrl()) {
99
99
  return reader.observed(baseUrl);
100
100
  }
101
101
  function guarded(reading) {
@@ -0,0 +1,2 @@
1
+ export declare const MAX_CLOCK_READING_MS = 8640000000000000;
2
+ export declare function usableClockMs(t: {} | null | undefined): number | null;
@@ -0,0 +1,4 @@
1
+ export const MAX_CLOCK_READING_MS = 8.64e15;
2
+ export function usableClockMs(t) {
3
+ return typeof t === 'number' && Number.isFinite(t) && Math.abs(t) <= MAX_CLOCK_READING_MS ? t : null;
4
+ }
@@ -1,21 +1,39 @@
1
1
  import type { SkillSpec } from '@sema-agent/sdk';
2
2
  import type { McpServerSpec } from './mcpWireCaps.js';
3
3
  import type { EnvLike } from './hostEnv.js';
4
+ import type { SkillToolListsReading } from './skillToolListsCapability.js';
5
+ import type { McpEntryKeyIssue } from './generated/settingsSchemaTypes.js';
4
6
  export type { McpServerSpec };
5
7
  type Rec = Record<string, unknown>;
6
8
  export type { EnvLike };
7
- export type CloudMcpDropReason = 'disabled' | 'missing-field' | 'unknown-transport' | 'capped' | 'principal-and-assertion-header' | 'tool-axes-invalid' | 'elicitation-invalid';
9
+ export type CloudMcpDropReason = 'disabled' | 'missing-field' | 'unknown-transport' | 'principal-and-assertion-header' | 'tool-axes-invalid' | 'tool-faces-invalid' | 'elicitation-invalid' | 'allow-tools-invalid' | 'entry-unreadable' | 'name-unusable' | 'transport-invalid';
8
10
  export interface CloudMcpDroppedServer {
9
11
  name?: string;
10
12
  reason: CloudMcpDropReason;
13
+ path?: string;
14
+ problem?: string;
15
+ }
16
+ export interface CloudMcpDegradedServer {
17
+ name: string;
18
+ lost: readonly McpEntryKeyIssue[];
11
19
  }
12
20
  export interface CloudMcpProjection {
13
21
  specs: McpServerSpec[];
14
22
  missingEnv: string[];
15
23
  droppedServers: CloudMcpDroppedServer[];
24
+ degradedServers: CloudMcpDegradedServer[];
16
25
  }
17
26
  export declare function cloudMcpToSpecs(servers: unknown, env: EnvLike): CloudMcpProjection;
18
- export declare function cloudSkillsToSpecs(manifestSkills: unknown, resolveBody: (contentHash: string) => string | null): SkillSpec[];
27
+ export interface CloudSkillsOptions {
28
+ readonly skillToolLists?: SkillToolListsReading;
29
+ }
30
+ export type CloudSkillDropReason = 'tool-list-invalid';
31
+ export interface CloudSkillDropped {
32
+ readonly name: string;
33
+ readonly reason: CloudSkillDropReason;
34
+ readonly path: string;
35
+ }
36
+ export declare function cloudSkillsToSpecs(manifestSkills: unknown, resolveBody: (contentHash: string) => string | null, opts?: CloudSkillsOptions): SkillSpec[];
19
37
  export interface CloudModelRefIssue {
20
38
  readonly key: 'models' | 'roles' | 'atMention' | 'tierGroups' | 'activeTierGroup';
21
39
  readonly at?: string;
@@ -110,7 +128,9 @@ export interface CloudProjection {
110
128
  missingEnv: string[];
111
129
  scope: string;
112
130
  skillsMissingBody: string[];
131
+ droppedSkills: CloudSkillDropped[];
113
132
  droppedMcpServers: CloudMcpDroppedServer[];
133
+ degradedMcpServers: CloudMcpDegradedServer[];
114
134
  droppedModels: CloudDroppedModel[];
115
135
  execution: CloudExecutionProjection;
116
136
  effectiveWarnings: CloudEffectiveWarningsReading;
@@ -118,11 +138,14 @@ export interface CloudProjection {
118
138
  runtimeCaps: CloudRuntimeCapsReading;
119
139
  modelRefIssues: CloudModelRefIssue[];
120
140
  }
121
- export declare function projectEffectiveBody(body: unknown, skillBodies: Record<string, string>, env: EnvLike, rostersValue?: unknown, opts?: CloudModelsDocOptions): CloudProjection;
141
+ export declare function projectEffectiveBody(body: unknown, skillBodies: Record<string, string>, env: EnvLike, rostersValue?: unknown, opts?: CloudModelsDocOptions, skills?: CloudSkillsOptions): CloudProjection;
122
142
  export interface CloudEffectiveNotice {
123
143
  readonly level: 'warn' | 'info';
124
144
  readonly text: string;
125
145
  }
126
- export declare function cloudEffectiveNotices(p: Pick<CloudProjection, 'effectiveWarnings' | 'budget' | 'runtimeCaps' | 'modelRefIssues' | 'droppedMcpServers'> & {
146
+ export interface CloudEffectiveNoticesOptionalInput {
127
147
  readonly mcp?: readonly McpServerSpec[];
128
- }): CloudEffectiveNotice[];
148
+ readonly degradedMcpServers?: readonly CloudMcpDegradedServer[];
149
+ readonly droppedSkills?: readonly CloudSkillDropped[];
150
+ }
151
+ export declare function cloudEffectiveNotices(p: Pick<CloudProjection, 'effectiveWarnings' | 'budget' | 'runtimeCaps' | 'modelRefIssues' | 'droppedMcpServers'> & CloudEffectiveNoticesOptionalInput): CloudEffectiveNotice[];