@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
@@ -1,11 +1,14 @@
1
- import { MCP_CAPS, mcpAssertionHeaderNotSentNotice, mcpElicitationVerdict, mcpToolAxesVerdict, readMcpHttpIdentityHeaders } from './mcpWireCaps.js';
2
- import { toCappedSpec } from './skillsWireCaps.js';
1
+ import { mcpAllowToolsVerdict, mcpAssertionHeaderNotSentNotice, mcpElicitationVerdict, mcpToolAxesVerdict, mcpToolFacesVerdict, readMcpHttpIdentityHeaders } from './mcpWireCaps.js';
2
+ import { skillToolListsVerdict, toCappedSpec } from './skillsWireCaps.js';
3
+ import { SETTINGS_DESCRIBE_BAD_WIRE_NAME, SETTINGS_IS_USABLE_WIRE_NAME, SETTINGS_READ_REQUEST_MCP_TRANSPORT } from './generated/settingsSchemaFns.js';
4
+ import { snapshotArgs, wireTransportOf } from './mcpWireTransport.js';
3
5
  import { msg, renderMessage } from './i18n/translate.js';
4
6
  import { TIER_ORDER } from './model/tierVocabulary.js';
5
7
  import { SETTINGS_NARROW_AT_MENTION } from './generated/settingsSchemaFns.js';
6
8
  import { modelsPolicyOf } from './model/modelsPolicy.js';
7
9
  import { normalizeEngineBaseUrl } from './engineUrl.js';
8
10
  import { guardedRead, readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
11
+ import { capForDisplay } from './fleetTaskDesc.js';
9
12
  import { SETTINGS_BUDGET_NUMBER_KEYS, SETTINGS_BUDGET_PER_MODEL_NUMBER_KEYS, SETTINGS_BUDGET_STRING_KEYS, SETTINGS_TIER_GROUP_NAME_RE, } from './generated/settingsSchemaTables.js';
10
13
  const asRec = (v) => (typeof v === 'object' && v !== null && !Array.isArray(v) ? v : undefined);
11
14
  const asArr = (v) => (Array.isArray(v) ? v : []);
@@ -14,115 +17,203 @@ export function cloudMcpToSpecs(servers, env) {
14
17
  const specs = [];
15
18
  const missingEnv = [];
16
19
  const droppedServers = [];
17
- const drop = (name, reason) => {
18
- droppedServers.push({ ...(name ? { name } : {}), reason });
20
+ const degradedServers = [];
21
+ const recordDrop = (name, reason, path, problem) => {
22
+ droppedServers.push({ ...(name ? { name } : {}), reason, ...(path !== undefined ? { path } : {}), ...(problem !== undefined ? { problem } : {}) });
19
23
  };
20
24
  for (const raw of asArr(servers)) {
21
- const s = asRec(raw);
22
- const name = s ? asStr(s.name) : undefined;
23
- if (specs.length >= MCP_CAPS.items) {
24
- drop(name, 'capped');
25
+ let s;
26
+ try {
27
+ s = asRec(raw);
28
+ }
29
+ catch {
30
+ recordDrop(undefined, 'entry-unreadable');
31
+ continue;
32
+ }
33
+ let name;
34
+ try {
35
+ name = s ? asStr(s.name) : undefined;
36
+ }
37
+ catch {
38
+ recordDrop(undefined, 'entry-unreadable');
25
39
  continue;
26
40
  }
27
- if (!s || s.enabled === false) {
28
- drop(name, s?.enabled === false ? 'disabled' : 'missing-field');
41
+ if (!s) {
42
+ recordDrop(name, 'missing-field');
43
+ continue;
44
+ }
45
+ let enabled;
46
+ try {
47
+ enabled = s.enabled;
48
+ }
49
+ catch {
50
+ recordDrop(name, 'entry-unreadable');
51
+ continue;
52
+ }
53
+ if (enabled === false) {
54
+ recordDrop(name, 'disabled');
55
+ continue;
56
+ }
57
+ let t;
58
+ try {
59
+ t = asRec(s.transport);
60
+ }
61
+ catch {
62
+ recordDrop(name, 'entry-unreadable');
29
63
  continue;
30
64
  }
31
- const t = asRec(s.transport);
32
65
  if (!name || !t) {
33
- drop(name, 'missing-field');
66
+ recordDrop(name, 'missing-field');
34
67
  continue;
35
68
  }
36
- let transport = null;
37
- if (t.kind === 'stdio') {
38
- const command = asStr(t.command);
39
- if (!command) {
40
- drop(name, 'missing-field');
41
- continue;
42
- }
43
- const envOut = {};
44
- for (const [target, ref] of Object.entries(asRec(t.envRefs) ?? {})) {
69
+ if (!SETTINGS_IS_USABLE_WIRE_NAME(name)) {
70
+ recordDrop(name, 'name-unusable');
71
+ continue;
72
+ }
73
+ let candidate;
74
+ let requiredRaw;
75
+ const missingHere = [];
76
+ const resolveRefs = (refs) => {
77
+ const out = [];
78
+ for (const [target, ref] of Object.entries(asRec(refs) ?? {})) {
45
79
  const refName = asStr(ref);
46
80
  if (!refName)
47
81
  continue;
48
82
  const v = env[refName];
49
83
  if (v === undefined || v === '')
50
- missingEnv.push(refName);
84
+ missingHere.push(refName);
51
85
  else
52
- envOut[target] = v;
86
+ out.push([target, v]);
53
87
  }
54
- const args = asArr(t.args).filter((a) => typeof a === 'string');
55
- transport = {
56
- kind: 'stdio',
57
- command,
58
- ...(args.length > 0 ? { args } : {}),
59
- ...(Object.keys(envOut).length > 0 ? { env: envOut } : {}),
60
- };
61
- }
62
- else if (t.kind === 'http') {
63
- const url = asStr(t.url);
64
- if (!url) {
65
- drop(name, 'missing-field');
66
- continue;
67
- }
68
- const identity = readMcpHttpIdentityHeaders(t);
69
- if (identity.kind === 'both_set') {
70
- drop(name, 'principal-and-assertion-header');
71
- continue;
88
+ return out;
89
+ };
90
+ const dropHard = (issue, raw) => {
91
+ const missing = (issue.path === 'transport.command' || issue.path === 'transport.url') && asStr(raw) === undefined;
92
+ if (missing)
93
+ recordDrop(name, 'missing-field');
94
+ else
95
+ recordDrop(name, 'transport-invalid', issue.path);
96
+ };
97
+ try {
98
+ if (t.kind === 'stdio') {
99
+ const command = t.command;
100
+ requiredRaw = command;
101
+ const head = SETTINGS_READ_REQUEST_MCP_TRANSPORT({ kind: 'stdio', command });
102
+ if (!head.ok) {
103
+ dropHard(head.issue, command);
104
+ continue;
105
+ }
106
+ const envEntries = resolveRefs(t.envRefs);
107
+ candidate = { kind: 'stdio', command, args: snapshotArgs(t.args), env: envEntries.length > 0 ? Object.fromEntries(envEntries) : undefined };
72
108
  }
73
- const headers = {};
74
- for (const [headerName, ref] of Object.entries(asRec(t.headerRefs) ?? {})) {
75
- const refName = asStr(ref);
76
- if (!refName)
109
+ else if (t.kind === 'http') {
110
+ const url = t.url;
111
+ requiredRaw = url;
112
+ const head = SETTINGS_READ_REQUEST_MCP_TRANSPORT({ kind: 'http', url });
113
+ if (!head.ok) {
114
+ dropHard(head.issue, url);
77
115
  continue;
78
- const v = env[refName];
79
- if (v === undefined || v === '')
80
- missingEnv.push(refName);
81
- else
82
- headers[headerName] = v;
116
+ }
117
+ const principalHeader = t.principalHeader;
118
+ const assertionHeader = t.assertionHeader;
119
+ if (readMcpHttpIdentityHeaders({ principalHeader, assertionHeader }).kind === 'both_set') {
120
+ recordDrop(name, 'principal-and-assertion-header');
121
+ continue;
122
+ }
123
+ const headerEntries = resolveRefs(t.headerRefs);
124
+ candidate = { kind: 'http', url, headers: headerEntries.length > 0 ? Object.fromEntries(headerEntries) : undefined, principalHeader, assertionHeader };
125
+ }
126
+ else {
127
+ recordDrop(name, 'unknown-transport');
128
+ continue;
83
129
  }
84
- transport = {
85
- kind: 'http',
86
- url,
87
- ...(Object.keys(headers).length > 0 ? { headers } : {}),
88
- ...(identity.principalHeader !== undefined ? { principalHeader: identity.principalHeader } : {}),
89
- ...(identity.assertionHeader !== undefined ? { assertionHeader: identity.assertionHeader } : {}),
90
- };
91
130
  }
92
- else {
93
- drop(name, 'unknown-transport');
131
+ catch {
132
+ recordDrop(name, 'transport-invalid', 'transport');
133
+ continue;
134
+ }
135
+ let read;
136
+ try {
137
+ read = SETTINGS_READ_REQUEST_MCP_TRANSPORT(candidate);
138
+ }
139
+ catch {
140
+ recordDrop(name, 'transport-invalid', 'transport');
141
+ continue;
142
+ }
143
+ if (!read.ok) {
144
+ dropHard(read.issue, requiredRaw);
145
+ continue;
146
+ }
147
+ const transport = wireTransportOf(read.transport);
148
+ let axesDeclared;
149
+ let elicitationDeclared;
150
+ let allowDeclared;
151
+ try {
152
+ axesDeclared = s.toolAxes;
153
+ elicitationDeclared = s.elicitation;
154
+ allowDeclared = s.allowTools;
155
+ }
156
+ catch {
157
+ recordDrop(name, 'entry-unreadable');
94
158
  continue;
95
159
  }
96
- const axesDeclared = s.toolAxes;
97
160
  const axesVerdict = mcpToolAxesVerdict(axesDeclared);
98
161
  if (axesVerdict.kind === 'bad') {
99
- drop(name, 'tool-axes-invalid');
162
+ recordDrop(name, 'tool-axes-invalid');
100
163
  continue;
101
164
  }
102
165
  const axesShipped = axesVerdict.kind === 'ok' ? axesVerdict.toolAxes : axesDeclared;
103
- const elVerdict = mcpElicitationVerdict(s.elicitation);
166
+ let facesDeclared;
167
+ let facesUnreadable = false;
168
+ try {
169
+ facesDeclared = s.toolFaces;
170
+ }
171
+ catch {
172
+ facesUnreadable = true;
173
+ }
174
+ const facesVerdict = facesUnreadable
175
+ ? Object.freeze({ kind: 'bad', problem: renderMessage(msg('config.mcp.toolFacesUnreadable')) })
176
+ : mcpToolFacesVerdict(facesDeclared);
177
+ if (facesVerdict.kind === 'bad') {
178
+ recordDrop(name, 'tool-faces-invalid', undefined, facesVerdict.problem);
179
+ continue;
180
+ }
181
+ const facesShipped = facesVerdict.kind === 'ok' ? facesVerdict.toolFaces : facesDeclared;
182
+ const elVerdict = mcpElicitationVerdict(elicitationDeclared);
104
183
  if (elVerdict.kind === 'bad') {
105
- drop(name, 'elicitation-invalid');
184
+ recordDrop(name, 'elicitation-invalid');
185
+ continue;
186
+ }
187
+ const allowVerdict = mcpAllowToolsVerdict(() => allowDeclared, `config.mcp.servers.${capForDisplay(name, DEGRADED_NAME_SHOWN)}.`);
188
+ if (allowVerdict.kind === 'bad') {
189
+ recordDrop(name, 'allow-tools-invalid', allowVerdict.path, allowVerdict.problem);
106
190
  continue;
107
191
  }
108
- const allowToolsWritten = Array.isArray(s.allowTools);
109
- const allowTools = asArr(s.allowTools).filter((a) => typeof a === 'string');
192
+ missingEnv.push(...missingHere);
193
+ if (read.lost.length > 0)
194
+ degradedServers.push({ name, lost: Object.freeze([...read.lost]) });
110
195
  specs.push({
111
196
  name,
112
197
  transport,
113
- ...(allowToolsWritten ? { allowTools } : {}),
198
+ ...(allowVerdict.allowTools !== undefined ? { allowTools: allowVerdict.allowTools } : {}),
114
199
  ...(elVerdict.elicitation !== undefined ? { elicitation: elVerdict.elicitation } : {}),
115
- ...(s.toolFaces !== undefined ? { toolFaces: s.toolFaces } : {}),
200
+ ...(facesShipped !== undefined ? { toolFaces: facesShipped } : {}),
116
201
  ...(axesShipped !== undefined ? { toolAxes: axesShipped } : {}),
117
202
  });
118
203
  }
119
- return { specs, missingEnv: [...new Set(missingEnv)], droppedServers };
204
+ return { specs, missingEnv: [...new Set(missingEnv)], droppedServers, degradedServers };
205
+ }
206
+ export function cloudSkillsToSpecs(manifestSkills, resolveBody, opts) {
207
+ return projectCloudSkills(manifestSkills, resolveBody, opts).specs;
120
208
  }
121
- export function cloudSkillsToSpecs(manifestSkills, resolveBody) {
209
+ function projectCloudSkills(manifestSkills, resolveBody, opts) {
122
210
  const specs = [];
211
+ const dropped = [];
123
212
  const seen = new Set();
124
- for (const raw of asArr(manifestSkills)) {
125
- const s = asRec(raw);
213
+ const reading = opts?.skillToolLists;
214
+ const entries = asArr(manifestSkills);
215
+ for (let i = 0; i < entries.length; i++) {
216
+ const s = asRec(entries[i]);
126
217
  if (!s || s.enabled === false)
127
218
  continue;
128
219
  const name = asStr(s.name);
@@ -136,9 +227,14 @@ export function cloudSkillsToSpecs(manifestSkills, resolveBody) {
136
227
  if (!spec || seen.has(spec.name))
137
228
  continue;
138
229
  seen.add(spec.name);
139
- specs.push(spec);
230
+ const verdict = skillToolListsVerdict(s, reading);
231
+ if (verdict.kind === 'bad') {
232
+ dropped.push({ name: spec.name, reason: 'tool-list-invalid', path: `skills[${i}].${verdict.key}${verdict.index !== undefined ? `[${verdict.index}]` : ''}` });
233
+ continue;
234
+ }
235
+ specs.push({ ...spec, ...verdict.lists });
140
236
  }
141
- return specs;
237
+ return { specs, dropped };
142
238
  }
143
239
  const REGISTRY_ENTRY_ANNOTATION_KEYS = ['origin', 'overridesTeam'];
144
240
  function withoutRegistryAnnotations(e) {
@@ -222,7 +318,7 @@ function modelsDocOf(models, opts) {
222
318
  const acceptedFlags = accept ? stripped.map(acceptedName) : undefined;
223
319
  const names = acceptedFlags ? new Set(stripped.filter((_, i) => acceptedFlags[i]).map((e) => e.name)) : allNames;
224
320
  const issues = [...copyFailures];
225
- const drop = (i) => {
321
+ const recordDrop = (i) => {
226
322
  issues.push({ ...i, outcome: 'dropped' });
227
323
  };
228
324
  const refOf = (v) => (typeof v === 'string' && v !== '' ? { target: v } : {});
@@ -243,13 +339,13 @@ function modelsDocOf(models, opts) {
243
339
  const doc = { models: written };
244
340
  const policy = modelsPolicyOf(m);
245
341
  if (policy.unreadable) {
246
- drop({ key: 'roles', at: 'default', reason: 'unreadable' });
247
- drop({ key: 'atMention', at: 'models', reason: 'unreadable' });
342
+ recordDrop({ key: 'roles', at: 'default', reason: 'unreadable' });
343
+ recordDrop({ key: 'atMention', at: 'models', reason: 'unreadable' });
248
344
  }
249
345
  const rolesRead = guarded(() => ({ value: m.roles }));
250
346
  const roleEntries = rolesRead === undefined ? undefined : guarded(() => Object.entries(asRec(rolesRead.value) ?? {}));
251
347
  if (roleEntries === undefined)
252
- drop({ key: 'roles', at: 'models', reason: 'unreadable' });
348
+ recordDrop({ key: 'roles', at: 'models', reason: 'unreadable' });
253
349
  const keptRoles = {};
254
350
  for (const [role, t] of roleEntries ?? []) {
255
351
  const first = guarded(() => {
@@ -258,20 +354,20 @@ function modelsDocOf(models, opts) {
258
354
  return { tr: r, has, model: has ? r.model : undefined };
259
355
  });
260
356
  if (first === undefined) {
261
- drop({ key: 'roles', at: role, reason: 'unreadable' });
357
+ recordDrop({ key: 'roles', at: role, reason: 'unreadable' });
262
358
  continue;
263
359
  }
264
360
  const { tr, has, model } = first;
265
361
  if (typeof model === 'string') {
266
362
  const verdict = modelRefVerdict(model);
267
363
  if (verdict !== 'accepted') {
268
- drop({ key: 'roles', at: role, ...refOf(model), reason: verdict });
364
+ recordDrop({ key: 'roles', at: role, ...refOf(model), reason: verdict });
269
365
  continue;
270
366
  }
271
367
  }
272
368
  const copy = writtenCopyOf(t, tr !== undefined && has ? { key: 'model', value: model } : undefined);
273
369
  if (copy === undefined) {
274
- drop({ key: 'roles', at: role, ...refOf(model), reason: 'unreadable' });
370
+ recordDrop({ key: 'roles', at: role, ...refOf(model), reason: 'unreadable' });
275
371
  continue;
276
372
  }
277
373
  setOwn(keptRoles, role, copy.value);
@@ -286,14 +382,14 @@ function modelsDocOf(models, opts) {
286
382
  doc.roles = rolesOut;
287
383
  const am = policy.atMention;
288
384
  if (am?.kind === 'unreadable') {
289
- drop({ key: 'atMention', at: 'atMention', reason: 'unreadable' });
385
+ recordDrop({ key: 'atMention', at: 'atMention', reason: 'unreadable' });
290
386
  }
291
387
  else if (am !== undefined) {
292
388
  const v = am.value;
293
389
  if (v.mode === 'only') {
294
390
  for (const n of v.models)
295
391
  if (!names.has(n))
296
- drop({ key: 'atMention', target: n, reason: reasonOf(n) });
392
+ recordDrop({ key: 'atMention', target: n, reason: reasonOf(n) });
297
393
  const narrowed = SETTINGS_NARROW_AT_MENTION(v, names);
298
394
  if (narrowed.mode === 'only') {
299
395
  doc.atMention = { mode: 'only', models: [...narrowed.models] };
@@ -301,7 +397,7 @@ function modelsDocOf(models, opts) {
301
397
  else {
302
398
  doc.atMention = { mode: narrowed.mode };
303
399
  if (narrowed.mode === 'none' && !catalogKept)
304
- drop({ key: 'atMention', at: 'atMention', reason: 'dangling' });
400
+ recordDrop({ key: 'atMention', at: 'atMention', reason: 'dangling' });
305
401
  }
306
402
  }
307
403
  else if (v.mode === 'none') {
@@ -315,11 +411,11 @@ function modelsDocOf(models, opts) {
315
411
  const tgValue = typeof tg === 'object' ? tg.value : undefined;
316
412
  const rawGroupNames = new Set((Array.isArray(tgValue) ? tgValue : []).map((g) => asStr(asRec(g)?.name)).filter((n) => !!n));
317
413
  if (tg === 'unreadable') {
318
- drop({ key: 'tierGroups', at: 'models', reason: 'unreadable' });
414
+ recordDrop({ key: 'tierGroups', at: 'models', reason: 'unreadable' });
319
415
  }
320
416
  else if (tg !== 'absent') {
321
417
  if (!Array.isArray(tgValue)) {
322
- drop({ key: 'tierGroups', reason: 'unreadable' });
418
+ recordDrop({ key: 'tierGroups', reason: 'unreadable' });
323
419
  }
324
420
  else {
325
421
  const groups = [];
@@ -328,11 +424,11 @@ function modelsDocOf(models, opts) {
328
424
  const g = asRec(raw);
329
425
  const name = g ? asStr(g.name) : undefined;
330
426
  if (!g || !name || !TIER_GROUP_NAME.test(name)) {
331
- drop({ key: 'tierGroups', ...(name ? { at: name } : {}), reason: 'unreadable' });
427
+ recordDrop({ key: 'tierGroups', ...(name ? { at: name } : {}), reason: 'unreadable' });
332
428
  continue;
333
429
  }
334
430
  if (groupNames.has(name)) {
335
- drop({ key: 'tierGroups', at: name, reason: 'duplicate' });
431
+ recordDrop({ key: 'tierGroups', at: name, reason: 'duplicate' });
336
432
  continue;
337
433
  }
338
434
  groupNames.add(name);
@@ -340,15 +436,15 @@ function modelsDocOf(models, opts) {
340
436
  if (Object.hasOwn(g, 'tiers')) {
341
437
  const t = asRec(g.tiers);
342
438
  if (!t)
343
- drop({ key: 'tierGroups', at: `${name}.tiers`, reason: 'unreadable' });
439
+ recordDrop({ key: 'tierGroups', at: `${name}.tiers`, reason: 'unreadable' });
344
440
  else {
345
441
  for (const [tier, model] of Object.entries(t)) {
346
442
  if (!TIER_WORDS.includes(tier))
347
- drop({ key: 'tierGroups', at: `${name}.${tier}`, ...refOf(model), reason: 'unsupported' });
443
+ recordDrop({ key: 'tierGroups', at: `${name}.${tier}`, ...refOf(model), reason: 'unsupported' });
348
444
  else if (typeof model === 'string' && names.has(model))
349
445
  setOwn(tiers, tier, model);
350
446
  else
351
- drop({ key: 'tierGroups', at: `${name}.${tier}`, ...refOf(model), reason: reasonOf(model) });
447
+ recordDrop({ key: 'tierGroups', at: `${name}.${tier}`, ...refOf(model), reason: reasonOf(model) });
352
448
  }
353
449
  }
354
450
  }
@@ -358,14 +454,14 @@ function modelsDocOf(models, opts) {
358
454
  }
359
455
  }
360
456
  if (atg === 'unreadable') {
361
- drop({ key: 'activeTierGroup', at: 'models', reason: 'unreadable' });
457
+ recordDrop({ key: 'activeTierGroup', at: 'models', reason: 'unreadable' });
362
458
  }
363
459
  else if (atg !== 'absent') {
364
460
  const a = atg.value;
365
461
  if (typeof a === 'string' && groupNames?.has(a))
366
462
  doc.activeTierGroup = a;
367
463
  else
368
- drop({ key: 'activeTierGroup', ...refOf(a), reason: typeof a === 'string' && a !== '' ? (rawGroupNames.has(a) ? 'rejected' : 'dangling') : 'unreadable' });
464
+ recordDrop({ key: 'activeTierGroup', ...refOf(a), reason: typeof a === 'string' && a !== '' ? (rawGroupNames.has(a) ? 'rejected' : 'dangling') : 'unreadable' });
369
465
  }
370
466
  }
371
467
  return { doc, issues, entriesRead: copied };
@@ -562,14 +658,14 @@ function runtimeCapsOf(b, mode) {
562
658
  }
563
659
  return { kind: 'configured', caps, uninterpretedKeys: uninterpreted };
564
660
  }
565
- export function projectEffectiveBody(body, skillBodies, env, rostersValue, opts) {
661
+ export function projectEffectiveBody(body, skillBodies, env, rostersValue, opts, skills) {
566
662
  const b = asRec(body) ?? {};
567
663
  const config = asRec(b.config) ?? {};
568
664
  const mcpDomain = asRec(config.mcp);
569
665
  const skillsDomain = asRec(config.skills);
570
- const { specs: mcp, missingEnv: mcpMissing, droppedServers: droppedMcpServers } = cloudMcpToSpecs(mcpDomain?.servers, env);
666
+ const { specs: mcp, missingEnv: mcpMissing, droppedServers: droppedMcpServers, degradedServers: degradedMcpServers } = cloudMcpToSpecs(mcpDomain?.servers, env);
571
667
  const manifest = asArr(skillsDomain?.skills);
572
- const skills = cloudSkillsToSpecs(manifest, (hash) => skillBodies[hash] ?? null);
668
+ const { specs: skillSpecs, dropped: droppedSkills } = projectCloudSkills(manifest, (hash) => skillBodies[hash] ?? null, skills);
573
669
  const skillsMissingBody = manifest
574
670
  .map((raw) => {
575
671
  const s = asRec(raw);
@@ -584,14 +680,16 @@ export function projectEffectiveBody(body, skillBodies, env, rostersValue, opts)
584
680
  const view = viewModeOf(b);
585
681
  return {
586
682
  mcp,
587
- skills,
683
+ skills: skillSpecs,
588
684
  modelsDoc,
589
685
  modelNames: cloudModelNames(modelsDoc),
590
686
  rosterNames: cloudRosterNames(rostersValue),
591
687
  missingEnv: [...new Set([...mcpMissing, ...cloudModelMissingKeyEnv(modelsDoc, env)])],
592
688
  scope: asStr(b.scope) ?? 'global',
593
689
  skillsMissingBody,
690
+ droppedSkills,
594
691
  droppedMcpServers,
692
+ degradedMcpServers,
595
693
  droppedModels: entriesRead === undefined ? [] : cloudModelsDropped({ models: entriesRead }),
596
694
  execution: cloudExecutionToPolicy(config.execution),
597
695
  effectiveWarnings: effectiveWarningsOf(b),
@@ -672,13 +770,29 @@ const MCP_DROP_SENTENCES = {
672
770
  level: 'warn',
673
771
  text: (who) => renderMessage(msg('config.mcp.cloudToolAxesInvalid', { who })),
674
772
  },
773
+ 'tool-faces-invalid': {
774
+ level: 'warn',
775
+ text: (who) => renderMessage(msg('config.mcp.cloudToolFacesInvalid', { who })),
776
+ },
675
777
  'elicitation-invalid': {
676
778
  level: 'warn',
677
779
  text: (who) => renderMessage(msg('config.mcp.cloudElicitationInvalid', { who })),
678
780
  },
679
- capped: {
781
+ 'allow-tools-invalid': {
782
+ level: 'warn',
783
+ text: (who) => renderMessage(msg('config.mcp.cloudAllowToolsInvalid', { who })),
784
+ },
785
+ 'entry-unreadable': {
786
+ level: 'warn',
787
+ text: (who) => renderMessage(msg('config.mcp.cloudEntryUnreadable', { who })),
788
+ },
789
+ 'name-unusable': {
680
790
  level: 'warn',
681
- text: (who) => `cloud config: MCP server entries left out because more than ${MCP_CAPS.items} were served to you and this client passes at most ${MCP_CAPS.items} to the engine: ${who}`,
791
+ text: (who) => renderMessage(msg('config.mcp.cloudNameUnusable', { who })),
792
+ },
793
+ 'transport-invalid': {
794
+ level: 'warn',
795
+ text: (who) => renderMessage(msg('config.mcp.cloudTransportInvalid', { who })),
682
796
  },
683
797
  disabled: {
684
798
  level: 'info',
@@ -688,9 +802,9 @@ const MCP_DROP_SENTENCES = {
688
802
  const MCP_DROP_UNRECOGNISED = (who) => `cloud config: MCP server entries left out for a reason this client does not recognise: ${who}`;
689
803
  const MCP_DROP_LIST_UNREADABLE = 'cloud config: the list of MCP server entries left out could not be read by this client — servers missing from the local tool list may have been left out without notice';
690
804
  const MCP_DROP_NAMES_SHOWN = 5;
691
- function mcpDropWho(names, unnamed) {
692
- const distinct = [...new Set(names)];
693
- const parts = distinct.slice(0, MCP_DROP_NAMES_SHOWN).map((n) => `"${n}"`);
805
+ function mcpDropWho(labels, unnamed) {
806
+ const distinct = [...new Set(labels)];
807
+ const parts = distinct.slice(0, MCP_DROP_NAMES_SHOWN);
694
808
  if (distinct.length > MCP_DROP_NAMES_SHOWN)
695
809
  parts.push(`+${distinct.length - MCP_DROP_NAMES_SHOWN} more`);
696
810
  if (unnamed > 0)
@@ -728,6 +842,8 @@ function droppedMcpNotices(carrier) {
728
842
  catch {
729
843
  return listUnreadable;
730
844
  }
845
+ if (typeof count !== 'number' || !Number.isSafeInteger(count) || count < 0)
846
+ return listUnreadable;
731
847
  const known = new Map();
732
848
  const unrecognised = { names: [], unnamed: 0 };
733
849
  for (let i = 0; i < count; i++) {
@@ -738,6 +854,15 @@ function droppedMcpNotices(carrier) {
738
854
  return typeof raw === 'string' && Object.hasOwn(MCP_DROP_SENTENCES, raw) ? raw : undefined;
739
855
  });
740
856
  const name = guarded(() => readOwnDataNonEmptyString(rowObj, 'name'));
857
+ const path = reason === 'transport-invalid' || reason === 'allow-tools-invalid' ? guarded(() => readOwnDataNonEmptyString(rowObj, 'path')) : undefined;
858
+ const pathLabel = path !== undefined && (reason === 'allow-tools-invalid' ? /^allowTools(\[\d{1,9}\])?$/ : /^transport(\.[A-Za-z]{1,32})?$/).test(path) ? ` (${path})` : '';
859
+ const label = name === undefined
860
+ ? undefined
861
+ : reason === 'name-unusable'
862
+ ? SETTINGS_DESCRIBE_BAD_WIRE_NAME(name)
863
+ : reason === 'transport-invalid' || reason === 'allow-tools-invalid' || reason === 'entry-unreadable'
864
+ ? `"${capForDisplay(name, DEGRADED_NAME_SHOWN)}"${pathLabel}`
865
+ : `"${name}"${pathLabel}`;
741
866
  let bucket = unrecognised;
742
867
  if (reason !== undefined) {
743
868
  let b = known.get(reason);
@@ -745,10 +870,10 @@ function droppedMcpNotices(carrier) {
745
870
  known.set(reason, (b = { names: [], unnamed: 0 }));
746
871
  bucket = b;
747
872
  }
748
- if (name === undefined)
873
+ if (label === undefined)
749
874
  bucket.unnamed++;
750
875
  else
751
- bucket.names.push(name);
876
+ bucket.names.push(label);
752
877
  }
753
878
  const out = [];
754
879
  for (const reason of Object.keys(MCP_DROP_SENTENCES)) {
@@ -761,6 +886,110 @@ function droppedMcpNotices(carrier) {
761
886
  }
762
887
  return out;
763
888
  }
889
+ const DEGRADED_LOST_SHOWN = 80;
890
+ const DEGRADED_NAME_SHOWN = 128;
891
+ const LOST_PATH_SHAPE = /^transport(\.[A-Za-z_][A-Za-z0-9_]{0,31}){1,2}$/;
892
+ function degradedLostLabels(rowObj) {
893
+ const lost = readOwnDataValue(rowObj, 'lost');
894
+ const out = [];
895
+ if (!Array.isArray(lost))
896
+ return out;
897
+ const n = guarded(() => lost.length) ?? 0;
898
+ for (let i = 0; i < n; i++) {
899
+ const one = guarded(() => readOwnDataValue(lost, String(i)));
900
+ const issue = typeof one === 'object' && one !== null ? one : undefined;
901
+ const path = guarded(() => readOwnDataNonEmptyString(issue, 'path'));
902
+ if (path === undefined || !LOST_PATH_SHAPE.test(path))
903
+ continue;
904
+ const member = guarded(() => readOwnDataNonEmptyString(issue, 'member'));
905
+ out.push(member !== undefined && !path.endsWith(`.${member}`) ? `${path} (member "${capForDisplay(member, DEGRADED_LOST_SHOWN)}")` : path);
906
+ }
907
+ return [...new Set(out)];
908
+ }
909
+ function degradedMcpNotices(carrier) {
910
+ const unreadable = [{ level: 'warn', text: renderMessage(msg('config.mcp.cloudTransportDegradedUnreadable')) }];
911
+ let desc;
912
+ try {
913
+ desc = Object.getOwnPropertyDescriptor(carrier, 'degradedMcpServers');
914
+ }
915
+ catch {
916
+ return unreadable;
917
+ }
918
+ if (desc === undefined)
919
+ return [];
920
+ if (!Object.hasOwn(desc, 'value'))
921
+ return unreadable;
922
+ const rows = desc.value;
923
+ let count = 0;
924
+ try {
925
+ if (!Array.isArray(rows))
926
+ return unreadable;
927
+ count = rows.length;
928
+ }
929
+ catch {
930
+ return unreadable;
931
+ }
932
+ if (typeof count !== 'number' || !Number.isSafeInteger(count) || count < 0)
933
+ return unreadable;
934
+ const labels = [];
935
+ let unnamed = 0;
936
+ for (let i = 0; i < count; i++) {
937
+ const row = guarded(() => readOwnDataValue(rows, String(i)));
938
+ const rowObj = typeof row === 'object' && row !== null ? row : undefined;
939
+ const name = guarded(() => readOwnDataNonEmptyString(rowObj, 'name'));
940
+ if (name === undefined) {
941
+ unnamed++;
942
+ continue;
943
+ }
944
+ const paths = guarded(() => degradedLostLabels(rowObj)) ?? [];
945
+ labels.push(`"${capForDisplay(name, DEGRADED_NAME_SHOWN)}"${paths.length > 0 ? ` (${paths.join(', ')})` : ''}`);
946
+ }
947
+ if (labels.length + unnamed === 0)
948
+ return [];
949
+ return [{ level: 'warn', text: renderMessage(msg('config.mcp.cloudTransportDegraded', { who: mcpDropWho(labels, unnamed) })) }];
950
+ }
951
+ function droppedSkillNotices(carrier) {
952
+ const unreadable = [{ level: 'warn', text: renderMessage(msg('config.skills.cloudDroppedUnreadable')) }];
953
+ let desc;
954
+ try {
955
+ desc = Object.getOwnPropertyDescriptor(carrier, 'droppedSkills');
956
+ }
957
+ catch {
958
+ return unreadable;
959
+ }
960
+ if (desc === undefined)
961
+ return [];
962
+ if (!Object.hasOwn(desc, 'value'))
963
+ return unreadable;
964
+ const rows = desc.value;
965
+ let count = 0;
966
+ try {
967
+ if (!Array.isArray(rows))
968
+ return unreadable;
969
+ count = rows.length;
970
+ }
971
+ catch {
972
+ return unreadable;
973
+ }
974
+ if (typeof count !== 'number' || !Number.isSafeInteger(count) || count < 0)
975
+ return unreadable;
976
+ const labels = [];
977
+ let unnamed = 0;
978
+ for (let i = 0; i < count; i++) {
979
+ const row = guarded(() => readOwnDataValue(rows, String(i)));
980
+ const rowObj = typeof row === 'object' && row !== null ? row : undefined;
981
+ const name = guarded(() => readOwnDataNonEmptyString(rowObj, 'name'));
982
+ if (name === undefined) {
983
+ unnamed++;
984
+ continue;
985
+ }
986
+ const path = guarded(() => readOwnDataNonEmptyString(rowObj, 'path'));
987
+ labels.push(`"${capForDisplay(name, DEGRADED_NAME_SHOWN)}"${path !== undefined && /^skills\[\d{1,10}\]\.(?:allowedTools|disallowedTools)(?:\[\d{1,10}\])?$/.test(path) ? ` (${path})` : ''}`);
988
+ }
989
+ if (labels.length + unnamed === 0)
990
+ return [];
991
+ return [{ level: 'warn', text: renderMessage(msg('config.skills.cloudToolListInvalid', { who: mcpDropWho(labels, unnamed) })) }];
992
+ }
764
993
  function budgetNotice(r) {
765
994
  switch (r.kind) {
766
995
  case 'configured': {
@@ -829,6 +1058,8 @@ export function cloudEffectiveNotices(p) {
829
1058
  });
830
1059
  }
831
1060
  out.push(...droppedMcpNotices(p));
1061
+ out.push(...degradedMcpNotices(p));
1062
+ out.push(...droppedSkillNotices(p));
832
1063
  const assertionLine = mcpAssertionHeaderNotSentNotice(guarded(() => readOwnDataValue(p, 'mcp')) ?? []);
833
1064
  if (assertionLine !== undefined)
834
1065
  out.push({ level: 'warn', text: `cloud config: ${assertionLine}` });