@sema-agent/client-core 0.98.0 → 0.99.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 (192) hide show
  1. package/CHANGELOG.md +199 -0
  2. package/README.md +35 -22
  3. package/dist/adapt/arms.js +61 -20
  4. package/dist/adapt/panelTasks.d.ts +1 -1
  5. package/dist/adapt/panelTasks.js +2 -2
  6. package/dist/adapter/activeRunSelfHeal.d.ts +4 -3
  7. package/dist/adapter/activeRunSelfHeal.js +162 -293
  8. package/dist/adapter/downstream/eventToSdkMessage.js +52 -4
  9. package/dist/adapter/runStream.js +52 -37
  10. package/dist/adapter/types.js +2 -1
  11. package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
  12. package/dist/agentsWireCaps.d.ts +0 -3
  13. package/dist/agentsWireCaps.js +33 -24
  14. package/dist/cloudConfigWireCaps.d.ts +1 -1
  15. package/dist/cloudConfigWireCaps.js +26 -4
  16. package/dist/controlRouter.d.ts +4 -2
  17. package/dist/controlRouter.js +39 -51
  18. package/dist/coreValuePorts.d.ts +26 -1
  19. package/dist/coreValuePorts.js +10 -0
  20. package/dist/corruptSessionCopy.d.ts +2 -1
  21. package/dist/corruptSessionCopy.js +3 -3
  22. package/dist/declared/supportFloorDeclared.js +1 -1
  23. package/dist/detachWire.js +3 -2
  24. package/dist/devicesFace.d.ts +34 -0
  25. package/dist/devicesFace.js +90 -0
  26. package/dist/displayUntrusted.d.ts +1 -0
  27. package/dist/displayUntrusted.js +3 -0
  28. package/dist/engineAgentPanelStore.d.ts +7 -0
  29. package/dist/engineAgentPanelStore.js +14 -0
  30. package/dist/engineCapReader.d.ts +2 -1
  31. package/dist/engineCapReader.js +7 -5
  32. package/dist/engineCapsCache.d.ts +8 -0
  33. package/dist/engineCapsCache.js +59 -6
  34. package/dist/engineCapsChange.d.ts +2 -0
  35. package/dist/engineCapsChange.js +9 -0
  36. package/dist/engineErrorCodes.d.ts +2 -1
  37. package/dist/engineErrorCodes.js +2 -7
  38. package/dist/engineRowRef.js +3 -0
  39. package/dist/engineSessionMessages.d.ts +1 -0
  40. package/dist/engineSessionMessages.js +7 -1
  41. package/dist/engineTargetSeat.d.ts +27 -0
  42. package/dist/engineTargetSeat.js +199 -0
  43. package/dist/engineWireFor.js +3 -8
  44. package/dist/env/uiLanguage.d.ts +2 -1
  45. package/dist/env/uiLanguage.js +3 -2
  46. package/dist/eventLeg.d.ts +8 -0
  47. package/dist/eventLeg.js +61 -41
  48. package/dist/fileHistoryCaptureCapability.d.ts +2 -1
  49. package/dist/fileHistoryCaptureCapability.js +12 -18
  50. package/dist/fileHistoryLegNotice.d.ts +2 -1
  51. package/dist/fileHistoryLegNotice.js +3 -3
  52. package/dist/frameBinding.d.ts +3 -0
  53. package/dist/frameBinding.js +12 -0
  54. package/dist/gateOutcome.js +16 -2
  55. package/dist/gateVocabulary.d.ts +8 -7
  56. package/dist/gateVocabulary.js +71 -73
  57. package/dist/generated/engineFactTables.d.ts +17 -1
  58. package/dist/generated/engineFactTables.js +29 -0
  59. package/dist/generated/engineNoticeTables.js +9 -3
  60. package/dist/generated/settingsSchemaFns.d.ts +6 -0
  61. package/dist/generated/settingsSchemaFns.js +57 -0
  62. package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
  63. package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
  64. package/dist/generated/settingsSchemaTables.d.ts +1 -0
  65. package/dist/generated/settingsSchemaTables.js +4 -0
  66. package/dist/generated/settingsSchemaTypes.d.ts +105 -0
  67. package/dist/generated/settingsSchemaTypes.js +1 -0
  68. package/dist/hitl/allowRuleShadow.d.ts +2 -1
  69. package/dist/hitl/allowRuleShadow.js +17 -14
  70. package/dist/hitl/approvalCardReasons.d.ts +3 -2
  71. package/dist/hitl/approvalCardReasons.js +27 -28
  72. package/dist/hitl/approvalHolds.d.ts +3 -0
  73. package/dist/hitl/approvalHolds.js +73 -29
  74. package/dist/hitl/askClassPair.d.ts +1 -1
  75. package/dist/hitl/askClassPair.js +16 -0
  76. package/dist/hitl/askGateWire.js +2 -1
  77. package/dist/hitl/askSettlementLine.d.ts +14 -4
  78. package/dist/hitl/askSettlementLine.js +67 -47
  79. package/dist/hitl/automaticAnswerVerdict.d.ts +2 -1
  80. package/dist/hitl/automaticAnswerVerdict.js +8 -8
  81. package/dist/hitl/crashConvergedNotice.d.ts +5 -4
  82. package/dist/hitl/crashConvergedNotice.js +28 -41
  83. package/dist/hitl/frameRouter.js +7 -8
  84. package/dist/hitl/hitlBridge.d.ts +1 -0
  85. package/dist/hitl/hitlBridge.js +3 -3
  86. package/dist/hitl/persistedRulesWire.d.ts +6 -5
  87. package/dist/hitl/persistedRulesWire.js +55 -73
  88. package/dist/hitl/planReviewWire.d.ts +5 -0
  89. package/dist/hitl/planReviewWire.js +8 -0
  90. package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
  91. package/dist/hitl/sessionPolicyDeliverable.js +46 -3
  92. package/dist/hitl/sessionPolicyWire.d.ts +2 -1
  93. package/dist/hitl/sessionPolicyWire.js +23 -24
  94. package/dist/hitl/suspendedReopen.d.ts +2 -1
  95. package/dist/hitl/suspendedReopen.js +7 -10
  96. package/dist/hitl/toolApprovalWire.d.ts +17 -5
  97. package/dist/hitl/toolApprovalWire.js +79 -40
  98. package/dist/hooksWireCaps.js +145 -56
  99. package/dist/host.d.ts +21 -0
  100. package/dist/hostTurnSettings.d.ts +71 -0
  101. package/dist/hostTurnSettings.js +291 -0
  102. package/dist/humanTurn.d.ts +14 -1
  103. package/dist/humanTurn.js +100 -12
  104. package/dist/humanTurnRead.d.ts +2 -0
  105. package/dist/humanTurnRead.js +22 -1
  106. package/dist/i18n/messages.en.d.ts +582 -0
  107. package/dist/i18n/messages.en.js +582 -0
  108. package/dist/i18n/messages.zh.js +718 -1
  109. package/dist/index.d.ts +29 -13
  110. package/dist/index.js +18 -9
  111. package/dist/inheritEnvCapability.d.ts +3 -2
  112. package/dist/inheritEnvCapability.js +3 -3
  113. package/dist/inheritEnvWire.d.ts +3 -2
  114. package/dist/inheritEnvWire.js +12 -14
  115. package/dist/interactiveHalt.js +17 -6
  116. package/dist/liveModelCatalog.d.ts +2 -1
  117. package/dist/liveModelCatalog.js +14 -8
  118. package/dist/mcpPanel.d.ts +10 -1
  119. package/dist/mcpPanel.js +40 -13
  120. package/dist/mcpProbeCapability.d.ts +2 -1
  121. package/dist/mcpProbeCapability.js +7 -11
  122. package/dist/mcpProbeWire.d.ts +3 -1
  123. package/dist/mcpProbeWire.js +5 -0
  124. package/dist/mcpWireCaps.d.ts +34 -0
  125. package/dist/mcpWireCaps.js +117 -17
  126. package/dist/memoryEntriesWire.js +5 -10
  127. package/dist/model/onboardJudgement.d.ts +93 -0
  128. package/dist/model/onboardJudgement.js +415 -0
  129. package/dist/model/tierVocabulary.d.ts +2 -0
  130. package/dist/model/tierVocabulary.js +17 -5
  131. package/dist/modelCapabilityProbe.d.ts +64 -0
  132. package/dist/modelCapabilityProbe.js +600 -0
  133. package/dist/modelIdentityResolvability.d.ts +3 -0
  134. package/dist/modelIdentityResolvability.js +26 -17
  135. package/dist/ownKey.d.ts +7 -0
  136. package/dist/ownKey.js +34 -0
  137. package/dist/panelReduce.d.ts +6 -1
  138. package/dist/panelReduce.js +50 -3
  139. package/dist/permissionRuleIssue.js +2 -0
  140. package/dist/permissionRulesWriteCapability.d.ts +2 -1
  141. package/dist/permissionRulesWriteCapability.js +8 -6
  142. package/dist/pluginHooksWire.d.ts +46 -3
  143. package/dist/pluginHooksWire.js +217 -11
  144. package/dist/printModelStatus.d.ts +63 -0
  145. package/dist/printModelStatus.js +155 -0
  146. package/dist/request/taskRequest.d.ts +11 -5
  147. package/dist/request/taskRequest.js +112 -16
  148. package/dist/resumeRefusalCopy.d.ts +12 -9
  149. package/dist/resumeRefusalCopy.js +70 -143
  150. package/dist/retryStatus.d.ts +37 -0
  151. package/dist/retryStatus.js +79 -0
  152. package/dist/scenarioRefusal.d.ts +9 -0
  153. package/dist/scenarioRefusal.js +111 -0
  154. package/dist/seam.d.ts +25 -1
  155. package/dist/seam.js +10 -1
  156. package/dist/seatContract.d.ts +260 -10
  157. package/dist/seatContract.js +692 -19
  158. package/dist/selfOrchestrationDenial.js +7 -19
  159. package/dist/sessionIdSegment.d.ts +6 -0
  160. package/dist/sessionIdSegment.js +24 -0
  161. package/dist/sessionMemoryStatus.js +6 -11
  162. package/dist/sessionPolicyCapability.d.ts +2 -1
  163. package/dist/sessionPolicyCapability.js +8 -6
  164. package/dist/settingsHooksSalvage.d.ts +44 -0
  165. package/dist/settingsHooksSalvage.js +211 -0
  166. package/dist/skillToolListsCapability.d.ts +2 -1
  167. package/dist/skillToolListsCapability.js +8 -6
  168. package/dist/sseIdleTriage.js +3 -2
  169. package/dist/subagent/engineSubagentResume.js +15 -9
  170. package/dist/subagentContentStore.d.ts +3 -0
  171. package/dist/subagentContentStore.js +22 -0
  172. package/dist/toolHistoryMismatch.js +3 -2
  173. package/dist/toolRoster.d.ts +3 -2
  174. package/dist/toolRoster.js +21 -20
  175. package/dist/turnFailurePresentation.d.ts +12 -1
  176. package/dist/turnFailurePresentation.js +212 -15
  177. package/dist/usageAnalytics.js +6 -11
  178. package/dist/userAttachmentEnvelope.d.ts +1 -0
  179. package/dist/userAttachmentEnvelope.js +37 -7
  180. package/dist/userAttachmentSeat.d.ts +21 -0
  181. package/dist/userAttachmentSeat.js +75 -0
  182. package/dist/userInvokedSkillsCapability.d.ts +11 -1
  183. package/dist/userInvokedSkillsCapability.js +31 -7
  184. package/dist/wireErrorTriage.d.ts +7 -0
  185. package/dist/wireErrorTriage.js +23 -1
  186. package/dist/wireFailureShape.js +2 -1
  187. package/dist/wireRefusalCopy.d.ts +13 -1
  188. package/dist/wireRefusalCopy.js +24 -28
  189. package/dist/workflowsJournalCapability.d.ts +2 -1
  190. package/dist/workflowsJournalCapability.js +8 -6
  191. package/docs/INTEGRATION-CLIENTS.md +542 -30
  192. package/package.json +5 -5
@@ -11,6 +11,8 @@ import { readAllowRuleShadowFromWire, retiredAllowRuleShadowKeyPresent, RETIRED_
11
11
  import { createSessionSlot, DEFAULT_SESSION_KEY } from '../sessionSlot.js';
12
12
  import { readEngineActiveBgTasks } from '../fleet/fleetLedger.js';
13
13
  import { CORE_SKILL_TOOL_NAME } from '../generated/toolNameTables.js';
14
+ import { CORE_ALLOW_ENTRY_INERT_REASONS } from '../generated/engineFactTables.js';
15
+ import { msg, renderMessage } from '../i18n/translate.js';
14
16
  import { INTERRUPT_DENY_REASON, observeCancelByDeny, surfaceApprovalParking, surfaceRememberNotApplied, surfaceEditNotForwarded, surfaceEditRefusedOnBlindAsk, surfaceRuleArmNotSent, surfaceRuleArmRejected } from './hitlHostSurface.js';
15
17
  import { approvalCallKey, liveFrameCallKey } from './gateIdentity.js';
16
18
  import { displayUntrusted } from '../displayUntrusted.js';
@@ -967,23 +969,24 @@ function usableProbeReason(raw) {
967
969
  return typeof raw === 'string' && raw.trim() !== '' ? raw : undefined;
968
970
  }
969
971
  const PROBE_CAUSE_CODE_WORD = /^[a-z][a-z0-9_]{0,31}(?:\.[a-z][a-z0-9_]{0,31}){1,3}$/;
970
- export function askProbeReasonDetail(card) {
972
+ export function askProbeReasonDetail(card, lang) {
971
973
  const prose = usableProbeReason(ownDataValue(card, 'probeReason'));
972
974
  const shown = prose === undefined ? '' : displayUntrusted(prose);
973
- const sentence = probeCauseSentence(ownDataValue(card, 'probeCause'), shown !== '');
975
+ const sentence = probeCauseSentence(ownDataValue(card, 'probeCause'), shown !== '', lang);
974
976
  if (sentence === undefined)
975
977
  return shown === '' ? undefined : shown;
976
- return shown === '' ? sentence : `${sentence} ${shown}`;
978
+ return shown === '' ? sentence : renderMessage(msg('approval.probe.proseJoin', { sentence, prose: shown }), lang);
977
979
  }
978
- function probeCauseSentence(cause, withProse) {
980
+ function probeCauseSentence(cause, withProse, lang) {
979
981
  try {
980
982
  if (!isWireRecordCarrier(cause))
981
983
  return undefined;
982
984
  const code = ownDataValue(cause, 'code');
983
- const head = withProse
984
- ? 'An automatic check could not clear this call, so it is asking you'
985
- : 'An automatic check could not clear this call, so it is asking you; the engine did not say the specific reason';
986
- return typeof code === 'string' && PROBE_CAUSE_CODE_WORD.test(code) ? `${head} (check code: ${code}).` : `${head}.`;
985
+ const withCode = typeof code === 'string' && PROBE_CAUSE_CODE_WORD.test(code);
986
+ const key = withProse
987
+ ? withCode ? 'approval.probe.withProseCode' : 'approval.probe.withProse'
988
+ : withCode ? 'approval.probe.noProseCode' : 'approval.probe.noProse';
989
+ return renderMessage(withCode ? msg(key, { code }) : msg(key), lang);
987
990
  }
988
991
  catch {
989
992
  return undefined;
@@ -1041,6 +1044,21 @@ export function readApprovalBoundGrants(v) {
1041
1044
  return undefined;
1042
1045
  return Object.freeze({ skill, allowedTools, disallowedTools });
1043
1046
  }
1047
+ const READS_AS_NOTHING_HEAD = '<reads as nothing (';
1048
+ export function readBoundGrantEntry(entry) {
1049
+ if (typeof entry !== 'string' || entry === '')
1050
+ return undefined;
1051
+ if (!entry.startsWith('<'))
1052
+ return Object.freeze({ kind: 'rule' });
1053
+ if (entry.startsWith(READS_AS_NOTHING_HEAD)) {
1054
+ const close = entry.indexOf('): ', READS_AS_NOTHING_HEAD.length);
1055
+ const word = close > 0 ? entry.slice(READS_AS_NOTHING_HEAD.length, close) : undefined;
1056
+ if (word !== undefined && CORE_ALLOW_ENTRY_INERT_REASONS.includes(word)) {
1057
+ return Object.freeze({ kind: 'reads_as_nothing', reason: word });
1058
+ }
1059
+ }
1060
+ return Object.freeze({ kind: 'reads_as_nothing' });
1061
+ }
1044
1062
  const BOUND_GRANT_NOT_BINDABLE = 'not_bindable';
1045
1063
  const SERVER_CLASS_READ_CAP = 64;
1046
1064
  function readApprovalGrantBinding(carrier) {
@@ -1161,34 +1179,45 @@ export function readApprovalClassifierNoRuling(v) {
1161
1179
  return typeof w === 'string' && CAUSE_WORD.test(w) ? w : undefined;
1162
1180
  }
1163
1181
  const CLASSIFIER_NO_RULING_REASONS = Object.freeze({
1164
- error: 'could not run for this call (it failed)',
1165
- timeout: 'could not run for this call (it timed out)',
1166
- parse_error: 'answered for this call but gave no verdict it could use',
1182
+ error: 'approval.classifier.noRulingError',
1183
+ timeout: 'approval.classifier.noRulingTimeout',
1184
+ parse_error: 'approval.classifier.noRulingParseError',
1167
1185
  });
1168
1186
  const _noRulingPin = [true, true];
1169
1187
  void _noRulingPin;
1170
- export function classifierNoRulingDetail(word) {
1188
+ export function classifierNoRulingDetail(word, lang) {
1171
1189
  if (typeof word === 'string' && Object.hasOwn(CLASSIFIER_NO_RULING_REASONS, word)) {
1172
- return `The auto-mode classifier ${CLASSIFIER_NO_RULING_REASONS[word]}, so it is asking you instead.`;
1190
+ return renderMessage(msg(CLASSIFIER_NO_RULING_REASONS[word]), lang);
1173
1191
  }
1174
1192
  if (typeof word === 'string' && CAUSE_WORD.test(word))
1175
- return `The auto-mode classifier did not rule on this call (reason: ${word}), so it is asking you instead.`;
1176
- return 'The auto-mode classifier did not rule on this call, so it is asking you instead.';
1193
+ return renderMessage(msg('approval.classifier.noRulingOther', { reason: word }), lang);
1194
+ return renderMessage(msg('approval.classifier.noRulingBare'), lang);
1177
1195
  }
1178
- const entries = (n) => (n === 1 ? '1 tool entry' : `${String(n)} tool entries`);
1179
- export function approvalBoundGrantsDetail(grants) {
1196
+ export function approvalBoundGrantsDetail(grants, lang) {
1180
1197
  const g = readApprovalBoundGrants({ boundGrants: grants });
1181
1198
  if (g === undefined)
1182
1199
  return undefined;
1183
1200
  if (g.skill === null)
1184
- return 'This call names no loaded skill, so approving it grants nothing beyond this call.';
1185
- const a = g.allowedTools.length;
1186
- const d = g.disallowedTools.length;
1187
- if (a === 0 && d === 0)
1188
- return 'Approving this activates the skill shown on the card; it lists no tools to run without asking and none to refuse.';
1189
- const allow = `${entries(a)} it lists ${a === 1 ? 'runs' : 'run'} without asking once it is active`;
1190
- const deny = `${entries(d)} ${d === 1 ? 'is' : 'are'} refused for the rest of this run`;
1191
- return `Approving this activates the skill shown on the card: ${allow}, and ${deny}.`;
1201
+ return renderMessage(msg('approval.boundGrants.noSkill'), lang);
1202
+ const isRule = (e) => readBoundGrantEntry(e)?.kind === 'rule';
1203
+ const a = g.allowedTools.filter(isRule).length;
1204
+ const d = g.disallowedTools.filter(isRule).length;
1205
+ const allowNothing = g.allowedTools.length - a;
1206
+ const denyNothing = g.disallowedTools.length - d;
1207
+ if (denyNothing > 0) {
1208
+ return renderMessage(denyNothing === 1 ? msg('approval.boundGrants.notActivated.one') : msg('approval.boundGrants.notActivated.other', { count: String(denyNothing) }), lang);
1209
+ }
1210
+ if (a === 0 && d === 0) {
1211
+ if (allowNothing > 0)
1212
+ return renderMessage(allowNothing === 1 ? msg('approval.boundGrants.listsNoToolsWithNothing.one') : msg('approval.boundGrants.listsNoToolsWithNothing.other', { count: String(allowNothing) }), lang);
1213
+ return renderMessage(msg('approval.boundGrants.listsNoTools'), lang);
1214
+ }
1215
+ const allow = a === 1 ? msg('approval.boundGrants.allowPart.one') : msg('approval.boundGrants.allowPart.other', { count: a });
1216
+ const deny = d === 1 ? msg('approval.boundGrants.denyPart.one') : msg('approval.boundGrants.denyPart.other', { count: d });
1217
+ if (allowNothing > 0) {
1218
+ return renderMessage(allowNothing === 1 ? msg('approval.boundGrants.activatesWithNothing.one', { allow, deny }) : msg('approval.boundGrants.activatesWithNothing.other', { allow, deny, count: String(allowNothing) }), lang);
1219
+ }
1220
+ return renderMessage(msg('approval.boundGrants.activates', { allow, deny }), lang);
1192
1221
  }
1193
1222
  const CALL_LEDGER_MAX_CALLS = 256;
1194
1223
  const CALL_LEDGER_MAX_ASKS_PER_CALL = 8;
@@ -1289,7 +1318,7 @@ function noteCallOutcome(slot, r) {
1289
1318
  const fateRank = { not_sent: 0, not_accepted: 1, unconfirmed: 2 };
1290
1319
  entry.answerFate = entry.answerFate !== undefined && fateRank[entry.answerFate] > fateRank[next] ? entry.answerFate : next;
1291
1320
  }
1292
- export function approvalPriorCardsDetail(card) {
1321
+ export function approvalPriorCardsDetail(card, lang) {
1293
1322
  const prior = ownDataValue(card, 'priorCardsForCall');
1294
1323
  let isList = false;
1295
1324
  try {
@@ -1307,13 +1336,12 @@ export function approvalPriorCardsDetail(card) {
1307
1336
  for (let i = 0; i < length; i++)
1308
1337
  items.push(ownDataValue(prior, String(i)));
1309
1338
  const outcome = ownDataValue(items[length - 1], 'outcome');
1310
- const earlier = outcome === 'allowed' ? 'you already approved an earlier one' : outcome === 'denied' ? 'an earlier one was denied' : 'an earlier one was shown first';
1339
+ const earlier = msg(outcome === 'allowed' ? 'approval.priorCard.earlier.allowed' : outcome === 'denied' ? 'approval.priorCard.earlier.denied' : 'approval.priorCard.earlier.shown');
1311
1340
  const fromRule = items.some((p) => ownDataValue(p, 'origin') === 'ask_rule');
1312
1341
  const thisFromRule = ownDataValue(card, 'origin') === 'ask_rule';
1313
- if (fromRule && !thisFromRule) {
1314
- return `This is a second approval for the same call: ${earlier}, which your ask rule asked for. This one is a separate check, not from your ask rule, and needs its own answer.`;
1315
- }
1316
- return `This is a second approval for the same call: ${earlier}. This one is a separate check and needs its own answer.`;
1342
+ if (fromRule && !thisFromRule)
1343
+ return renderMessage(msg('approval.priorCard.fromRule', { earlier }), lang);
1344
+ return renderMessage(msg('approval.priorCard.plain', { earlier }), lang);
1317
1345
  }
1318
1346
  const PRIOR_ANSWER_PHRASE = Object.freeze({
1319
1347
  allow: 'Yes',
@@ -1710,10 +1738,9 @@ export async function surfaceToolApprovalFrameAndRespond(frame, respond, streamA
1710
1738
  const receivedAtMs = Date.now();
1711
1739
  const approvalId = frame.approvalId;
1712
1740
  const entry = { frame, approvalId, identity: liveCardIdentityOf(approvalId, frame, run), respond, streamArgs, signal, lane, receivedAtMs };
1713
- return enterLiveCard(entry, 0);
1741
+ return enterLiveCard(entry);
1714
1742
  }
1715
- const LIVE_ENTRY_MAX_ROUNDS = 8;
1716
- function enterLiveCard(e, round) {
1743
+ function enterLiveCard(e) {
1717
1744
  const { approvalId, signal } = e;
1718
1745
  const held = liveCardHoldOf(liveFrameCallKey(approvalId));
1719
1746
  if (held !== undefined)
@@ -1721,9 +1748,9 @@ function enterLiveCard(e, round) {
1721
1748
  const settled = settledLiveCardOutcome(approvalId);
1722
1749
  if (settled !== undefined)
1723
1750
  return Promise.resolve(settled);
1724
- const other = round < LIVE_ENTRY_MAX_ROUNDS ? approvalHoldFor(e.identity, (h) => h.lane === 'live') : undefined;
1751
+ const other = approvalHoldFor(e.identity, (h) => h.lane === 'live');
1725
1752
  if (other !== undefined)
1726
- return joinOtherLaneHolder(e, other, round);
1753
+ return joinOtherLaneHolder(e, other);
1727
1754
  return holdLiveCard(e.identity, signal, async (hold) => {
1728
1755
  const slot = {};
1729
1756
  const out = await presentToolApprovalFrameAndRespond(e.frame, approvalId, e.respond, e.streamArgs, signal, e.lane, hold, slot, e.receivedAtMs);
@@ -1731,7 +1758,7 @@ function enterLiveCard(e, round) {
1731
1758
  return out;
1732
1759
  });
1733
1760
  }
1734
- async function joinOtherLaneHolder(e, other, round) {
1761
+ async function joinOtherLaneHolder(e, other) {
1735
1762
  const wait = await awaitApprovalHolder(other, e.signal, 'respond');
1736
1763
  if (wait.kind === 'settled') {
1737
1764
  noteHolderSettledApproval(e.approvalId, wait.how, wait.outcome);
@@ -1739,7 +1766,7 @@ async function joinOtherLaneHolder(e, other, round) {
1739
1766
  }
1740
1767
  if (wait.kind === 'left')
1741
1768
  return { kind: 'not_sent', lane: 'respond', cause: 'retracted', joinedInFlight: true };
1742
- return enterLiveCard(e, round + 1);
1769
+ return enterLiveCard(e);
1743
1770
  }
1744
1771
  function liveCardIdentityOf(approvalId, frame, run) {
1745
1772
  const toolCallId = typeof frame.toolCallId === 'string' && frame.toolCallId !== '' ? frame.toolCallId : undefined;
@@ -1789,8 +1816,20 @@ export async function joinApprovalHolder(identity, signal) {
1789
1816
  return { kind: 'joined', outcome: { kind: 'not_sent', lane: 'decide', cause: 'retracted', joinedInFlight: true } };
1790
1817
  return { kind: 'free' };
1791
1818
  }
1792
- export function claimApprovalCard(identity, signal) {
1793
- return claimApprovalCardFor(readApprovalHolderIdentity(identity), signal);
1819
+ function readApprovalCardClaimSignal(v) {
1820
+ if (typeof v !== 'object' || v === null)
1821
+ return undefined;
1822
+ try {
1823
+ const d = Object.getOwnPropertyDescriptor(v, 'signal');
1824
+ const x = d !== undefined && Object.hasOwn(d, 'value') ? d.value : undefined;
1825
+ return typeof x === 'object' && x !== null ? x : undefined;
1826
+ }
1827
+ catch {
1828
+ return undefined;
1829
+ }
1830
+ }
1831
+ export function claimApprovalCard(identity, options) {
1832
+ return claimApprovalCardFor(readApprovalHolderIdentity(identity), readApprovalCardClaimSignal(options));
1794
1833
  }
1795
1834
  async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, streamArgs, signal, lane, hold, ledgerSlot, receivedAtMs) {
1796
1835
  const frameToolCallId = typeof frame.toolCallId === 'string' && frame.toolCallId !== '' ? frame.toolCallId : undefined;
@@ -1,7 +1,9 @@
1
1
  import { engineCapNestedTrue, engineCapState, engineCapValue } from './engineCapsCache.js';
2
+ import { msg, renderMessage } from './i18n/translate.js';
2
3
  import { capForDisplay, collapseLabel } from './fleetTaskDesc.js';
3
4
  import { hostLog, hostSettings } from './host.js';
4
- import { createSettingsHookJudge, decidePluginHooks, dedupeSettingsHookGroups, filterSettingsHookGroups, occupancyOf, } from './pluginHooksWire.js';
5
+ import { hooksSalvageMaskOf, salvageSettingsHooksEntries, settingsHooksSalvageNotice } from './settingsHooksSalvage.js';
6
+ import { createSettingsHookJudge, decidePluginHooks, decideSessionHooks, dedupeSettingsHookGroups, filterSettingsHookGroups, hooksWirePlanShapeOf, occupancyOf, } from './pluginHooksWire.js';
5
7
  import { MAX_HOOK_NOTICE_TEXT_CHARS } from './notifications.js';
6
8
  import { goalStopHookMatcher, __resetGoalStopHookForTests } from './goalStopHook.js';
7
9
  export { GOAL_STOP_HOOK_WIRE_ENV, isGoalStopHookWireArmed, setWireSessionStopHook, getWireSessionStopHook, } from './goalStopHook.js';
@@ -99,15 +101,38 @@ function managedPolicyUnreadable(settings) {
99
101
  return true;
100
102
  }
101
103
  }
102
- function hooksOfSource(source) {
104
+ const NO_LAYER = Object.freeze({ hooks: null, mask: undefined });
105
+ function layerOfDoc(source, doc) {
103
106
  try {
104
- const s = hostSettings()?.getSettingsForSource(source);
105
- return s?.hooks && typeof s.hooks === 'object' && !Array.isArray(s.hooks) ? s.hooks : null;
107
+ return classifyLayer(source, doc);
108
+ }
109
+ catch (err) {
110
+ hostLog('debug', `hooksWireCaps: ${source} settings could not be read by the hooks reader — treated as no hooks from this source: ${String(err)}`);
111
+ return NO_LAYER;
112
+ }
113
+ }
114
+ function classifyLayer(source, doc) {
115
+ const salvage = salvageSettingsHooksEntries(doc);
116
+ const hooks = typeof doc === 'object' && doc !== null && !Array.isArray(doc) ? doc.hooks : undefined;
117
+ const original = typeof hooks === 'object' && hooks !== null && !Array.isArray(hooks) ? hooks : null;
118
+ if (salvage.outcome === 'loaded')
119
+ return { hooks: original, mask: undefined };
120
+ const notice = settingsHooksSalvageNotice(salvage, source, doc) ?? '';
121
+ const row = Object.freeze({ source, outcome: salvage.outcome, dropped: salvage.dropped, rejections: salvage.rejections, notice });
122
+ if (salvage.outcome === 'rejected')
123
+ return { hooks: null, mask: undefined, row };
124
+ return { hooks: original, mask: hooksSalvageMaskOf(salvage.dropped), row };
125
+ }
126
+ function layerOfSource(source) {
127
+ let doc;
128
+ try {
129
+ doc = hostSettings()?.getSettingsForSource(source);
106
130
  }
107
131
  catch (err) {
108
132
  hostLog('debug', `hooksWireCaps: ${source} settings read threw — treated as no hooks from this source: ${String(err)}`);
109
- return null;
133
+ return NO_LAYER;
110
134
  }
135
+ return layerOfDoc(source, doc);
111
136
  }
112
137
  let warnedNoPluginReader = new WeakSet();
113
138
  const NO_PLUGIN_READER_WARNING = 'client-core: the installed settings port does not implement enabledPluginHooks() — ' +
@@ -143,32 +168,70 @@ function readPluginHooks(settings, warnIfAbsent) {
143
168
  }
144
169
  return { state: 'absent' };
145
170
  }
146
- function usageError(tail) {
147
- return new TypeError(`hooksForWire: pass { plan } with the plan returned by hooksWirePlan() for this turn — ${tail}`);
171
+ function readSessionHooks(settings) {
172
+ try {
173
+ const member = settings.sessionHooks;
174
+ if (member === undefined)
175
+ return { state: 'absent' };
176
+ if (typeof member !== 'function') {
177
+ hostLog('debug', 'hooksWireCaps: sessionHooks is not a method — no session hooks judged this turn');
178
+ return { state: 'failed' };
179
+ }
180
+ const r = member.call(settings);
181
+ const sources = typeof r === 'object' && r !== null ? r.sources : undefined;
182
+ if (Array.isArray(sources))
183
+ return { state: 'present', sources };
184
+ hostLog('debug', 'hooksWireCaps: sessionHooks() returned a malformed reading — no session hooks judged this turn');
185
+ return { state: 'failed' };
186
+ }
187
+ catch (err) {
188
+ hostLog('debug', `hooksWireCaps: sessionHooks() threw — no session hooks judged this turn: ${String(err)}`);
189
+ return { state: 'failed' };
190
+ }
191
+ }
192
+ function suppressedLocallyOf(o) {
193
+ let raw;
194
+ try {
195
+ raw = o.suppressedLocally;
196
+ }
197
+ catch {
198
+ hostLog('debug', 'hooksWirePlan: suppressedLocally threw while being read — treated as absent (no plugin suppressed locally)');
199
+ return undefined;
200
+ }
201
+ if (raw === undefined)
202
+ return undefined;
203
+ if (!Array.isArray(raw) || !raw.every((x) => typeof x === 'string')) {
204
+ hostLog('debug', 'hooksWirePlan: suppressedLocally is not an array of plugin ids — treated as absent (no plugin suppressed locally)');
205
+ return undefined;
206
+ }
207
+ return new Set(raw);
208
+ }
209
+ function usageError(sentence) {
210
+ return new TypeError(renderMessage(sentence));
148
211
  }
149
212
  function hostValueShape(v) {
150
213
  try {
151
214
  if (v === undefined)
152
- return 'nothing';
215
+ return msg('config.hooks.valueShape.nothing');
153
216
  if (v === null)
154
- return 'null';
217
+ return msg('config.hooks.valueShape.null');
155
218
  if (Array.isArray(v))
156
- return 'an array';
157
- return typeof v === 'object' ? 'an object' : `a ${typeof v}`;
219
+ return msg('config.hooks.valueShape.array');
220
+ return typeof v === 'object' ? msg('config.hooks.valueShape.object') : msg('config.hooks.valueShape.typeof', { type: typeof v });
158
221
  }
159
222
  catch {
160
- return 'unreadable';
223
+ return msg('config.hooks.valueShape.unreadable');
161
224
  }
162
225
  }
163
226
  export function hooksForWire(opts) {
164
227
  if (typeof opts !== 'object' || opts === null)
165
- throw usageError(`got ${hostValueShape(opts)}.`);
228
+ throw usageError(msg('config.hooks.forWire.gotShape', { shape: hostValueShape(opts) }));
166
229
  let given;
167
230
  try {
168
231
  given = opts.plan;
169
232
  }
170
233
  catch {
171
- throw usageError(`reading opts.plan threw.`);
234
+ throw usageError(msg('config.hooks.forWire.readPlanThrew'));
172
235
  }
173
236
  const shape = planShapeOf(given);
174
237
  if (shape === 'plan') {
@@ -176,46 +239,16 @@ export function hooksForWire(opts) {
176
239
  return given.wire;
177
240
  }
178
241
  catch {
179
- throw usageError(`reading the plan's wire threw.`);
242
+ throw usageError(msg('config.hooks.forWire.readWireThrew'));
180
243
  }
181
244
  }
182
245
  if (shape === 'threw')
183
- throw usageError(`opts.plan could not be read as a plan.`);
246
+ throw usageError(msg('config.hooks.forWire.planUnreadable'));
184
247
  if (given === undefined && planShapeOf(opts) === 'plan')
185
- throw usageError(`the plan itself was passed; wrap it as { plan }.`);
186
- throw usageError(`opts.plan is ${given === undefined ? 'missing' : `not such a plan (got ${hostValueShape(given)})`}.`);
248
+ throw usageError(msg('config.hooks.forWire.planPassedBare'));
249
+ throw usageError(given === undefined ? msg('config.hooks.forWire.planMissing') : msg('config.hooks.forWire.planNotPlan', { shape: hostValueShape(given) }));
187
250
  }
188
- function planShapeOf(v) {
189
- try {
190
- if (typeof v !== 'object' || v === null || Array.isArray(v))
191
- return 'not';
192
- const o = v;
193
- for (const k of PLAN_KEYS)
194
- if (!Object.hasOwn(o, k) && k !== 'settingsVerdicts' && k !== 'settingsExcluded')
195
- return 'not';
196
- const reader = o.pluginReader;
197
- const engineFacts = o.engine;
198
- const wire = o.wire;
199
- const arrayOrAbsent = (k) => !Object.hasOwn(o, k) || Array.isArray(o[k]);
200
- return Array.isArray(o.verdicts) &&
201
- Array.isArray(o.excluded) &&
202
- Array.isArray(o.settingsDropped) &&
203
- arrayOrAbsent('settingsVerdicts') &&
204
- arrayOrAbsent('settingsExcluded') &&
205
- (reader === 'present' || reader === 'absent' || reader === 'failed') &&
206
- typeof engineFacts === 'object' &&
207
- engineFacts !== null &&
208
- (wire === undefined || (typeof wire === 'object' && wire !== null && !Array.isArray(wire)))
209
- ? 'plan'
210
- : 'not';
211
- }
212
- catch {
213
- return 'threw';
214
- }
215
- }
216
- const PLAN_KEYS = ['engine', 'pluginReader', 'verdicts', 'excluded', 'settingsDropped', 'settingsVerdicts', 'settingsExcluded', 'wire'];
217
- const _planKeysPin = [true, true];
218
- void _planKeysPin;
251
+ const planShapeOf = hooksWirePlanShapeOf;
219
252
  export function hooksWirePlan(opts = {}) {
220
253
  const o = opts ?? {};
221
254
  const owned = o.engineOwnedByThisShell;
@@ -241,7 +274,7 @@ export function hooksWirePlan(opts = {}) {
241
274
  const types = typesByEvent.get(event);
242
275
  return types === undefined || (typeof type === 'string' && types.has(type));
243
276
  };
244
- return buildHooksWirePlan(engine, shellRuns, promptAuthoredByUserOf(o));
277
+ return buildHooksWirePlan(engine, shellRuns, promptAuthoredByUserOf(o), suppressedLocallyOf(o));
245
278
  }
246
279
  function taskHooksCapability(baseUrl) {
247
280
  const v = engineCapValue(baseUrl, 'taskSettings');
@@ -292,14 +325,34 @@ function promptAuthoredByUserOf(o) {
292
325
  }
293
326
  return true;
294
327
  }
295
- function buildHooksWirePlan(engine, shellRuns, promptAuthoredByUser) {
328
+ function buildHooksWirePlan(engine, shellRuns, promptAuthoredByUser, suppressedLocally) {
296
329
  const settingsDropped = [];
297
330
  const settingsVerdicts = [];
298
331
  const settingsExcluded = [];
332
+ const settingsSalvage = [];
333
+ let sessionVerdicts = [];
334
+ let sessionReader = 'absent';
335
+ let closedBy = null;
299
336
  const judge = createSettingsHookJudge(engine, shellRuns, promptAuthoredByUser);
300
337
  let settingsStripped = 0;
301
- const planOf = (pluginReader, wire, verdicts = [], excluded = []) => ({ engine, pluginReader, verdicts, excluded, settingsDropped, settingsVerdicts, settingsExcluded, wire });
338
+ const planOf = (pluginReader, wire, verdicts = [], excluded = [], moduleVerdicts = []) => ({
339
+ engine,
340
+ pluginReader,
341
+ verdicts,
342
+ excluded,
343
+ settingsDropped,
344
+ settingsVerdicts,
345
+ settingsExcluded,
346
+ settingsSalvage,
347
+ moduleVerdicts,
348
+ sessionVerdicts,
349
+ sessionReader,
350
+ closedBy,
351
+ wire,
352
+ });
302
353
  const closedPlan = (settings, reason) => {
354
+ closedBy = reason;
355
+ sessionReader = readSessionHooks(settings).state;
303
356
  const read = readPluginHooks(settings, false);
304
357
  if (read.reading === undefined)
305
358
  return planOf(read.state, undefined);
@@ -333,13 +386,28 @@ function buildHooksWirePlan(engine, shellRuns, promptAuthoredByUser) {
333
386
  if (managedPolicyUnreadable(settings))
334
387
  return closedPlan(settings, 'governance_unreadable');
335
388
  let policy = null;
389
+ let policyDoc;
336
390
  try {
337
- policy = settings.getSettingsForSource('policySettings');
391
+ policyDoc = settings.getSettingsForSource('policySettings');
392
+ policy = policyDoc;
338
393
  }
339
394
  catch (err) {
340
395
  hostLog('debug', `hooksWireCaps: policySettings read threw — fail-closed (no hooks projected to the engine): ${String(err)}`);
341
396
  return closedPlan(settings, 'governance_unreadable');
342
397
  }
398
+ let policyLayer;
399
+ try {
400
+ policyLayer = classifyLayer('policySettings', policyDoc);
401
+ }
402
+ catch (err) {
403
+ hostLog('debug', `hooksWireCaps: managed settings could not be read by the hooks reader — fail-closed (no hooks projected to the engine): ${String(err)}`);
404
+ return closedPlan(settings, 'governance_unreadable');
405
+ }
406
+ if (policyLayer.row?.outcome === 'rejected') {
407
+ settingsSalvage.push(policyLayer.row);
408
+ hostLog('debug', 'hooksWireCaps: managed settings hooks rejected by the hooks reader — fail-closed (no hooks projected to the engine)');
409
+ return closedPlan(settings, 'governance_unreadable');
410
+ }
343
411
  if (policy?.disableAllHooks === true) {
344
412
  hostLog('debug', 'hooksWireCaps: disableAllHooks (managed) — no hooks projected to the engine');
345
413
  return closedPlan(settings, 'policy_disable_all');
@@ -356,6 +424,21 @@ function buildHooksWirePlan(engine, shellRuns, promptAuthoredByUser) {
356
424
  hostLog('debug', 'hooksWireCaps: disableAllHooks (merged, non-managed) — only policySettings hooks projected to the engine');
357
425
  }
358
426
  const managedOnly = managedByPolicy || disabledByNonManaged;
427
+ {
428
+ const sr = readSessionHooks(settings);
429
+ sessionReader = sr.state;
430
+ if (sr.sources !== undefined && !managedOnly) {
431
+ const sources = sr.sources;
432
+ const ds = guardPluginTraversal(() => decideSessionHooks({ sources, engine, shellRuns, promptAuthoredByUser }));
433
+ if (ds === undefined)
434
+ sessionReader = 'failed';
435
+ else {
436
+ sessionVerdicts = ds.verdicts;
437
+ if (ds.unreadable > 0)
438
+ hostLog('debug', `hooksWireCaps: ${ds.unreadable} session hook source(s) or group(s) unreadable — skipped`);
439
+ }
440
+ }
441
+ }
359
442
  const read = readPluginHooks(settings, true);
360
443
  let oldStartupBit;
361
444
  let pluginDataThrew = false;
@@ -378,13 +461,18 @@ function buildHooksWirePlan(engine, shellRuns, promptAuthoredByUser) {
378
461
  const merged = {};
379
462
  const sourced = new Map();
380
463
  for (const source of sources) {
381
- const hooks = hooksOfSource(source);
464
+ const layer = source === 'policySettings' ? policyLayer : layerOfSource(source);
465
+ if (layer.row !== undefined)
466
+ settingsSalvage.push(layer.row);
467
+ const hooks = layer.hooks;
382
468
  if (!hooks)
383
469
  continue;
384
470
  for (const [event, groups] of Object.entries(hooks)) {
471
+ if (layer.mask !== undefined && layer.mask.eventDropped(event))
472
+ continue;
385
473
  if (!Array.isArray(groups) || groups.length === 0)
386
474
  continue;
387
- const kept = filterSettingsHookGroups(source, event, groups, engine.pluginHooksCapable === true, (type) => shellRuns(event, type), judge);
475
+ const kept = filterSettingsHookGroups(source, event, groups, engine.pluginHooksCapable === true, (type) => shellRuns(event, type), judge, layer.mask);
388
476
  settingsDropped.push(...kept.drops);
389
477
  settingsVerdicts.push(...kept.verdicts);
390
478
  settingsExcluded.push(...kept.excluded);
@@ -441,6 +529,7 @@ function buildHooksWirePlan(engine, shellRuns, promptAuthoredByUser) {
441
529
  shellRuns,
442
530
  promptAuthoredByUser,
443
531
  occupied,
532
+ ...(suppressedLocally !== undefined ? { suppressedLocally } : {}),
444
533
  });
445
534
  });
446
535
  if (d === undefined)
@@ -450,7 +539,7 @@ function buildHooksWirePlan(engine, shellRuns, promptAuthoredByUser) {
450
539
  }
451
540
  for (const [event, groups] of d.projected)
452
541
  merged[event] = [...(merged[event] ?? []), ...groups];
453
- return planOf('present', wireOf(), d.verdicts, d.excluded);
542
+ return planOf('present', wireOf(), d.verdicts, d.excluded, d.modules);
454
543
  }
455
544
  export function __resetHooksWireCapsForTests() {
456
545
  __resetGoalStopHookForTests();
package/dist/host.d.ts CHANGED
@@ -9,6 +9,7 @@ export interface SettingsPort {
9
9
  enabledPluginHooks?(): PluginHooksReading;
10
10
  hooksStartupMode?(): HooksStartupMode | undefined;
11
11
  managedPolicyReading?(): ManagedPolicyReading;
12
+ sessionHooks?(): SessionHooksReading;
12
13
  }
13
14
  export type ManagedPolicyState = 'absent' | 'in-effect' | 'unreadable';
14
15
  export interface ManagedPolicyReading {
@@ -32,6 +33,26 @@ export interface PluginHookSource {
32
33
  readonly managed: boolean;
33
34
  readonly options?: Readonly<Record<string, PluginHookOption>>;
34
35
  readonly hooks: WireHooksConfig;
36
+ readonly hooksModule?: boolean;
37
+ }
38
+ export type SessionHookOrigin = 'skill' | 'agent' | 'sdk_host';
39
+ export interface SessionHookSource {
40
+ readonly origin: SessionHookOrigin;
41
+ readonly name: string;
42
+ readonly hooks: WireHooksConfig | {
43
+ readonly [event: string]: readonly {
44
+ readonly matcher?: string;
45
+ readonly hooks: readonly (NonNullable<WireHooksConfig[string]>[number]['hooks'][number] | SessionLocalHook)[];
46
+ }[] | undefined;
47
+ };
48
+ }
49
+ export interface SessionLocalHook {
50
+ readonly type: 'callback' | 'function';
51
+ readonly callback?: (...args: never[]) => void;
52
+ readonly timeout?: number;
53
+ }
54
+ export interface SessionHooksReading {
55
+ readonly sources: readonly SessionHookSource[];
35
56
  }
36
57
  export interface PluginHooksReading {
37
58
  readonly plugins: readonly PluginHookSource[];
@@ -0,0 +1,71 @@
1
+ import type { WireHooksConfig } from './finalVerifyWire.js';
2
+ import type { SettingsDocument } from './host.js';
3
+ import { type HookSettingsSource, type HooksWirePlan } from './pluginHooksWire.js';
4
+ export declare const HOST_SUPPLIED_KEYS: readonly ["settings.hooks", "settings.resolved", "settings.webSearch", "settings.outputStyle"];
5
+ export type HostSuppliedKey = (typeof HOST_SUPPLIED_KEYS)[number];
6
+ export declare const HOST_SETTING_CAUSES: readonly ["carried", "entries_dropped", "source_rejected", "projection_failed", "source_unreadable", "empty", "no_source", "host_port_missing"];
7
+ export type HostSettingCause = (typeof HOST_SETTING_CAUSES)[number];
8
+ export declare const HOST_SETTING_DISPOSITIONS: readonly ["carry", "carry_partial", "withhold_notice", "refuse_turn", "unwired", "nothing_to_carry"];
9
+ export type HostSettingDisposition = (typeof HOST_SETTING_DISPOSITIONS)[number];
10
+ export type HostSettingPlane = 'turn' | 'session' | 'diagnostic';
11
+ export type HostSettingNoticeId = 'HS-UNWIRED' | 'HS-MANAGED-REJECTED' | 'HS-PROJECTION' | 'HS-SOURCE-UNREADABLE';
12
+ export interface HostSettingRow {
13
+ readonly key: HostSuppliedKey;
14
+ readonly cause: HostSettingCause;
15
+ readonly disposition: HostSettingDisposition;
16
+ readonly layers?: readonly HookSettingsSource[];
17
+ }
18
+ export interface HostSettingNotice {
19
+ readonly id: HostSettingNoticeId;
20
+ readonly plane: HostSettingPlane;
21
+ readonly text: string;
22
+ }
23
+ export type HostTurnVerdict = {
24
+ readonly kind: 'send';
25
+ } | {
26
+ readonly kind: 'refuse';
27
+ readonly notice: HostSettingNotice;
28
+ };
29
+ export interface HostTurnSettingsSources {
30
+ readonly hooks: {
31
+ readonly plan: HooksWirePlan;
32
+ } | 'none';
33
+ readonly resolved: {
34
+ readonly snapshot: SettingsDocument;
35
+ } | 'none';
36
+ readonly webSearch: {
37
+ readonly settings: SettingsDocument;
38
+ } | 'none';
39
+ readonly outputStyle: {
40
+ readonly name: string;
41
+ } | 'none';
42
+ }
43
+ export interface HostTurnSettingsInput {
44
+ readonly sources: HostTurnSettingsSources;
45
+ }
46
+ export interface HostSettingsCarried {
47
+ readonly hooks?: WireHooksConfig;
48
+ readonly resolved?: SettingsDocument;
49
+ readonly webSearch?: SettingsDocument;
50
+ readonly outputStyle?: string;
51
+ }
52
+ declare const hostTurnSettingsBrand: unique symbol;
53
+ export interface HostTurnSettings {
54
+ readonly [hostTurnSettingsBrand]: true;
55
+ readonly verdict: HostTurnVerdict;
56
+ readonly rows: readonly HostSettingRow[];
57
+ readonly notices: readonly HostSettingNotice[];
58
+ readonly hooks: HooksWirePlan | undefined;
59
+ readonly carried: HostSettingsCarried;
60
+ }
61
+ export declare function rethrowHostResolvedDeferred(product: HostTurnSettings): void;
62
+ export type HostResolvedMaterializer = (snapshot: SettingsDocument) => SettingsDocument;
63
+ export declare function buildHostTurnSettings(input: HostTurnSettingsInput, materialize: HostResolvedMaterializer): HostTurnSettings;
64
+ export declare function hostSettingsSelfCheck(product: HostTurnSettings): readonly HostSuppliedKey[];
65
+ export declare class HostSettingsRefused extends Error {
66
+ readonly notice: HostSettingNotice;
67
+ constructor(n: HostSettingNotice);
68
+ }
69
+ export declare function hostTurnSettingsOf(v: unknown, depth?: 'shape' | 'full'): HostTurnSettings | undefined;
70
+ export declare const UNWIRED_HOST_TURN_SETTINGS: HostTurnSettings;
71
+ export {};