@sema-agent/client-core 0.98.0 → 0.100.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 (236) hide show
  1. package/CHANGELOG.md +376 -0
  2. package/README.md +61 -35
  3. package/dist/adapt/arms.js +120 -55
  4. package/dist/adapt/panelTasks.d.ts +3 -2
  5. package/dist/adapt/panelTasks.js +34 -11
  6. package/dist/adapt/textStream.d.ts +1 -1
  7. package/dist/adapt/textStream.js +51 -28
  8. package/dist/adapter/activeRunSelfHeal.d.ts +11 -3
  9. package/dist/adapter/activeRunSelfHeal.js +210 -294
  10. package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
  11. package/dist/adapter/downstream/eventToSdkMessage.js +176 -12
  12. package/dist/adapter/downstream/terminalToSdkResult.js +10 -0
  13. package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
  14. package/dist/adapter/downstream/wiringManifestView.js +1 -0
  15. package/dist/adapter/runStream.js +82 -40
  16. package/dist/adapter/types.d.ts +2 -0
  17. package/dist/adapter/types.js +2 -1
  18. package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
  19. package/dist/agentsWireCaps.d.ts +7 -3
  20. package/dist/agentsWireCaps.js +133 -39
  21. package/dist/cloudConfigWireCaps.d.ts +10 -1
  22. package/dist/cloudConfigWireCaps.js +181 -65
  23. package/dist/compactionStatus.d.ts +34 -0
  24. package/dist/compactionStatus.js +196 -0
  25. package/dist/controlRouter.d.ts +4 -2
  26. package/dist/controlRouter.js +39 -51
  27. package/dist/coreValuePorts.d.ts +26 -1
  28. package/dist/coreValuePorts.js +10 -0
  29. package/dist/corruptSessionCopy.d.ts +2 -1
  30. package/dist/corruptSessionCopy.js +3 -3
  31. package/dist/decideFailureNote.js +3 -3
  32. package/dist/declared/supportFloorDeclared.js +1 -1
  33. package/dist/detachWire.js +3 -2
  34. package/dist/devicesFace.d.ts +34 -0
  35. package/dist/devicesFace.js +90 -0
  36. package/dist/displayUntrusted.d.ts +1 -0
  37. package/dist/displayUntrusted.js +153 -5
  38. package/dist/engineAgentPanelStore.d.ts +14 -4
  39. package/dist/engineAgentPanelStore.js +14 -0
  40. package/dist/engineCapReader.d.ts +2 -1
  41. package/dist/engineCapReader.js +7 -5
  42. package/dist/engineCapsCache.d.ts +8 -0
  43. package/dist/engineCapsCache.js +59 -6
  44. package/dist/engineCapsChange.d.ts +2 -0
  45. package/dist/engineCapsChange.js +9 -0
  46. package/dist/engineErrorCodes.d.ts +11 -2
  47. package/dist/engineErrorCodes.js +11 -12
  48. package/dist/engineRowRef.js +4 -0
  49. package/dist/engineSessionMessages.d.ts +1 -0
  50. package/dist/engineSessionMessages.js +7 -1
  51. package/dist/engineTargetSeat.d.ts +27 -0
  52. package/dist/engineTargetSeat.js +199 -0
  53. package/dist/engineToolDirectory.d.ts +3 -0
  54. package/dist/engineToolDirectory.js +4 -2
  55. package/dist/engineWireFor.js +3 -8
  56. package/dist/env/uiLanguage.d.ts +2 -1
  57. package/dist/env/uiLanguage.js +3 -2
  58. package/dist/eventLeg.d.ts +7 -5
  59. package/dist/eventLeg.js +68 -49
  60. package/dist/fileHistoryCaptureCapability.d.ts +2 -4
  61. package/dist/fileHistoryCaptureCapability.js +12 -22
  62. package/dist/fileHistoryLegNotice.d.ts +2 -1
  63. package/dist/fileHistoryLegNotice.js +3 -3
  64. package/dist/frameBinding.d.ts +3 -0
  65. package/dist/frameBinding.js +12 -0
  66. package/dist/gateOutcome.js +16 -2
  67. package/dist/gateVocabulary.d.ts +8 -7
  68. package/dist/gateVocabulary.js +71 -73
  69. package/dist/generated/engineFactTables.d.ts +18 -1
  70. package/dist/generated/engineFactTables.js +56 -0
  71. package/dist/generated/engineNoticeTables.js +12 -3
  72. package/dist/generated/settingsSchemaFns.d.ts +18 -0
  73. package/dist/generated/settingsSchemaFns.js +70 -0
  74. package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
  75. package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
  76. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
  77. package/dist/generated/settingsSchemaMcpRequestEntry.js +162 -0
  78. package/dist/generated/settingsSchemaTables.d.ts +2 -0
  79. package/dist/generated/settingsSchemaTables.js +9 -0
  80. package/dist/generated/settingsSchemaTypes.d.ts +133 -0
  81. package/dist/generated/settingsSchemaTypes.js +1 -0
  82. package/dist/hitl/allowRuleShadow.d.ts +2 -1
  83. package/dist/hitl/allowRuleShadow.js +18 -15
  84. package/dist/hitl/approvalCardReasons.d.ts +3 -2
  85. package/dist/hitl/approvalCardReasons.js +29 -30
  86. package/dist/hitl/approvalHolds.d.ts +17 -0
  87. package/dist/hitl/approvalHolds.js +114 -29
  88. package/dist/hitl/askClassPair.d.ts +2 -2
  89. package/dist/hitl/askClassPair.js +16 -0
  90. package/dist/hitl/askGateWire.js +2 -1
  91. package/dist/hitl/askSettlementLine.d.ts +14 -4
  92. package/dist/hitl/askSettlementLine.js +67 -47
  93. package/dist/hitl/attributionLadder.d.ts +23 -0
  94. package/dist/hitl/attributionLadder.js +67 -0
  95. package/dist/hitl/automaticAnswerVerdict.d.ts +2 -1
  96. package/dist/hitl/automaticAnswerVerdict.js +8 -8
  97. package/dist/hitl/crashConvergedNotice.d.ts +5 -4
  98. package/dist/hitl/crashConvergedNotice.js +28 -41
  99. package/dist/hitl/decisionLedger.d.ts +55 -0
  100. package/dist/hitl/decisionLedger.js +156 -0
  101. package/dist/hitl/decisionRefusal.d.ts +1 -0
  102. package/dist/hitl/decisionRefusal.js +1 -1
  103. package/dist/hitl/decisionSend.d.ts +113 -0
  104. package/dist/hitl/decisionSend.js +579 -0
  105. package/dist/hitl/frameRouter.js +7 -8
  106. package/dist/hitl/hitlBridge.d.ts +1 -0
  107. package/dist/hitl/hitlBridge.js +21 -9
  108. package/dist/hitl/persistedRulesWire.d.ts +6 -5
  109. package/dist/hitl/persistedRulesWire.js +55 -73
  110. package/dist/hitl/planReviewWire.d.ts +5 -0
  111. package/dist/hitl/planReviewWire.js +53 -76
  112. package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
  113. package/dist/hitl/sessionPolicyDeliverable.js +49 -9
  114. package/dist/hitl/sessionPolicyWire.d.ts +2 -1
  115. package/dist/hitl/sessionPolicyWire.js +23 -24
  116. package/dist/hitl/suspendedReopen.d.ts +2 -1
  117. package/dist/hitl/suspendedReopen.js +7 -10
  118. package/dist/hitl/toolApprovalWire.d.ts +17 -5
  119. package/dist/hitl/toolApprovalWire.js +120 -147
  120. package/dist/hooksWireCaps.js +145 -56
  121. package/dist/host.d.ts +21 -0
  122. package/dist/hostTurnSettings.d.ts +110 -0
  123. package/dist/hostTurnSettings.js +692 -0
  124. package/dist/humanTurn.d.ts +15 -1
  125. package/dist/humanTurn.js +100 -12
  126. package/dist/humanTurnRead.d.ts +2 -0
  127. package/dist/humanTurnRead.js +22 -1
  128. package/dist/i18n/messages.en.d.ts +713 -0
  129. package/dist/i18n/messages.en.js +713 -0
  130. package/dist/i18n/messages.zh.js +854 -1
  131. package/dist/index.d.ts +45 -13
  132. package/dist/index.js +27 -9
  133. package/dist/inheritEnvCapability.d.ts +4 -2
  134. package/dist/inheritEnvCapability.js +12 -5
  135. package/dist/inheritEnvWire.d.ts +3 -2
  136. package/dist/inheritEnvWire.js +14 -16
  137. package/dist/injectionLaneNotice.d.ts +5 -0
  138. package/dist/injectionLaneNotice.js +46 -0
  139. package/dist/interactiveHalt.js +17 -6
  140. package/dist/liveModelCatalog.d.ts +2 -1
  141. package/dist/liveModelCatalog.js +14 -8
  142. package/dist/mcpPanel.d.ts +10 -1
  143. package/dist/mcpPanel.js +42 -13
  144. package/dist/mcpProbeCapability.d.ts +2 -1
  145. package/dist/mcpProbeCapability.js +7 -11
  146. package/dist/mcpProbeWire.d.ts +3 -1
  147. package/dist/mcpProbeWire.js +5 -0
  148. package/dist/mcpReconnect.js +2 -2
  149. package/dist/mcpToolToggles.d.ts +6 -0
  150. package/dist/mcpToolToggles.js +46 -0
  151. package/dist/mcpWireCaps.d.ts +43 -3
  152. package/dist/mcpWireCaps.js +194 -59
  153. package/dist/mcpWireTransport.d.ts +4 -0
  154. package/dist/mcpWireTransport.js +18 -0
  155. package/dist/memoryEntriesWire.js +5 -10
  156. package/dist/model/onboardJudgement.d.ts +93 -0
  157. package/dist/model/onboardJudgement.js +415 -0
  158. package/dist/model/tierVocabulary.d.ts +2 -0
  159. package/dist/model/tierVocabulary.js +17 -5
  160. package/dist/modelCapabilityProbe.d.ts +65 -0
  161. package/dist/modelCapabilityProbe.js +601 -0
  162. package/dist/modelIdentityResolvability.d.ts +5 -0
  163. package/dist/modelIdentityResolvability.js +49 -22
  164. package/dist/ownKey.d.ts +33 -0
  165. package/dist/ownKey.js +109 -0
  166. package/dist/panelReduce.d.ts +11 -1
  167. package/dist/panelReduce.js +95 -16
  168. package/dist/panelStateHolder.d.ts +1 -0
  169. package/dist/panelStateHolder.js +10 -1
  170. package/dist/permissionRuleIssue.d.ts +2 -1
  171. package/dist/permissionRuleIssue.js +23 -20
  172. package/dist/permissionRulesWriteCapability.d.ts +2 -1
  173. package/dist/permissionRulesWriteCapability.js +8 -6
  174. package/dist/pluginHooksWire.d.ts +46 -3
  175. package/dist/pluginHooksWire.js +220 -12
  176. package/dist/prepareRefusal.d.ts +8 -0
  177. package/dist/prepareRefusal.js +72 -0
  178. package/dist/printModelStatus.d.ts +63 -0
  179. package/dist/printModelStatus.js +155 -0
  180. package/dist/request/taskRequest.d.ts +16 -10
  181. package/dist/request/taskRequest.js +195 -58
  182. package/dist/resumeRefusalCopy.d.ts +14 -9
  183. package/dist/resumeRefusalCopy.js +89 -144
  184. package/dist/retryStatus.d.ts +55 -0
  185. package/dist/retryStatus.js +155 -19
  186. package/dist/ruleRefusalSentence.d.ts +4 -0
  187. package/dist/ruleRefusalSentence.js +58 -0
  188. package/dist/sandboxWire.d.ts +2 -1
  189. package/dist/sandboxWire.js +55 -21
  190. package/dist/scenarioRefusal.d.ts +10 -0
  191. package/dist/scenarioRefusal.js +111 -0
  192. package/dist/seam.d.ts +48 -9
  193. package/dist/seam.js +54 -5
  194. package/dist/seatContract.d.ts +272 -14
  195. package/dist/seatContract.js +711 -23
  196. package/dist/selfOrchestrationDenial.js +7 -19
  197. package/dist/sessionIdSegment.d.ts +6 -0
  198. package/dist/sessionIdSegment.js +24 -0
  199. package/dist/sessionMemoryStatus.js +6 -11
  200. package/dist/sessionPolicyCapability.d.ts +2 -1
  201. package/dist/sessionPolicyCapability.js +8 -6
  202. package/dist/settingsCredentialKeyPaths.d.ts +8 -0
  203. package/dist/settingsCredentialKeyPaths.js +219 -0
  204. package/dist/settingsHooksSalvage.d.ts +44 -0
  205. package/dist/settingsHooksSalvage.js +211 -0
  206. package/dist/skillToolListsCapability.d.ts +2 -1
  207. package/dist/skillToolListsCapability.js +8 -6
  208. package/dist/skillsWireCaps.d.ts +0 -3
  209. package/dist/skillsWireCaps.js +1 -2
  210. package/dist/sseIdleTriage.js +3 -2
  211. package/dist/subagent/engineSubagentResume.js +15 -9
  212. package/dist/subagentContentStore.d.ts +4 -0
  213. package/dist/subagentContentStore.js +157 -27
  214. package/dist/toolHistoryMismatch.js +3 -2
  215. package/dist/toolRoster.d.ts +3 -2
  216. package/dist/toolRoster.js +21 -20
  217. package/dist/toolsFlagNames.d.ts +8 -0
  218. package/dist/toolsFlagNames.js +110 -0
  219. package/dist/turnFailurePresentation.d.ts +12 -1
  220. package/dist/turnFailurePresentation.js +220 -15
  221. package/dist/usageAnalytics.js +6 -11
  222. package/dist/userAttachmentEnvelope.d.ts +1 -0
  223. package/dist/userAttachmentEnvelope.js +37 -7
  224. package/dist/userAttachmentSeat.d.ts +21 -0
  225. package/dist/userAttachmentSeat.js +75 -0
  226. package/dist/userInvokedSkillsCapability.d.ts +11 -1
  227. package/dist/userInvokedSkillsCapability.js +31 -7
  228. package/dist/wireErrorTriage.d.ts +7 -0
  229. package/dist/wireErrorTriage.js +23 -1
  230. package/dist/wireFailureShape.js +2 -1
  231. package/dist/wireRefusalCopy.d.ts +62 -16
  232. package/dist/wireRefusalCopy.js +307 -148
  233. package/dist/workflowsJournalCapability.d.ts +2 -1
  234. package/dist/workflowsJournalCapability.js +8 -6
  235. package/docs/INTEGRATION-CLIENTS.md +951 -42
  236. package/package.json +5 -5
@@ -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,110 @@
1
+ import type { TaskRequest } from '@sema-agent/sdk';
2
+ import type { WireHooksConfig } from './finalVerifyWire.js';
3
+ import type { memoryOffDeclared as MemoryOffDeclared } from './request/taskRequest.js';
4
+ import type { EnvLike } from './hostEnv.js';
5
+ import type { SettingsDocument } from './host.js';
6
+ import { type HookSettingsSource, type HooksWirePlan } from './pluginHooksWire.js';
7
+ import { type WebSearchApiKeyFor } from './webSearchWireCaps.js';
8
+ import { type FileHistoryCaptureReading } from './fileHistoryCaptureCapability.js';
9
+ export declare const HOST_SUPPLIED_KEYS: readonly ["settings.hooks", "settings.resolved", "settings.webSearch", "settings.outputStyle", "memory", "fileHistory"];
10
+ export type HostSuppliedKey = (typeof HOST_SUPPLIED_KEYS)[number];
11
+ export declare const HOST_SETTING_CAUSES: readonly ["carried", "entries_dropped", "source_rejected", "projection_failed", "source_unreadable", "empty", "no_source", "host_port_missing", "value_malformed"];
12
+ export type HostSettingCause = (typeof HOST_SETTING_CAUSES)[number];
13
+ export declare const HOST_SETTING_DISPOSITIONS: readonly ["carry", "carry_partial", "withhold_notice", "refuse_turn", "unwired", "nothing_to_carry"];
14
+ export type HostSettingDisposition = (typeof HOST_SETTING_DISPOSITIONS)[number];
15
+ export type HostSettingPlane = 'turn' | 'session' | 'diagnostic';
16
+ export type HostSettingNoticeId = 'HS-UNWIRED' | 'HS-MANAGED-REJECTED' | 'HS-PROJECTION' | 'HS-SOURCE-UNREADABLE' | 'HS-WEBSEARCH-MALFORMED' | 'HS-SWITCH-MALFORMED' | 'HS-FILEHISTORY-UNJUDGED';
17
+ export interface HostSettingRow {
18
+ readonly key: HostSuppliedKey;
19
+ readonly cause: HostSettingCause;
20
+ readonly disposition: HostSettingDisposition;
21
+ readonly layers?: readonly HookSettingsSource[];
22
+ }
23
+ export interface HostSettingNotice {
24
+ readonly id: HostSettingNoticeId;
25
+ readonly plane: HostSettingPlane;
26
+ readonly text: string;
27
+ }
28
+ export type HostTurnVerdict = {
29
+ readonly kind: 'send';
30
+ } | {
31
+ readonly kind: 'refuse';
32
+ readonly notice: HostSettingNotice;
33
+ };
34
+ export interface HostTurnSettingsSources {
35
+ readonly hooks: {
36
+ readonly plan: HooksWirePlan;
37
+ } | 'none';
38
+ readonly resolved: {
39
+ readonly snapshot: SettingsDocument;
40
+ } | 'none';
41
+ readonly webSearch: HostWebSearchSource | 'none';
42
+ readonly outputStyle: {
43
+ readonly name: string;
44
+ } | 'none';
45
+ readonly memory: HostMemorySource | 'none';
46
+ readonly fileHistory: {
47
+ readonly reading: FileHistoryCaptureReading;
48
+ readonly captureOff: boolean;
49
+ } | 'none';
50
+ }
51
+ export interface HostWebSearchSource {
52
+ readonly section?: SettingsDocument;
53
+ readonly env: EnvLike;
54
+ readonly apiKeyFor?: WebSearchApiKeyFor;
55
+ }
56
+ export interface HostMemorySource {
57
+ readonly flag?: string;
58
+ readonly settingsMemory?: SettingsDocument;
59
+ }
60
+ export interface HostTurnSettingsInput {
61
+ readonly sources: HostTurnSettingsSources;
62
+ }
63
+ export interface HostSettingsCarried {
64
+ readonly hooks?: WireHooksConfig;
65
+ readonly resolved?: SettingsDocument;
66
+ readonly webSearch?: SettingsDocument;
67
+ readonly outputStyle?: string;
68
+ readonly memory?: TaskRequest['memory'];
69
+ readonly fileHistory?: TaskRequest['fileHistory'];
70
+ }
71
+ declare const hostTurnSettingsBrand: unique symbol;
72
+ export interface HostTurnSettings {
73
+ readonly [hostTurnSettingsBrand]: true;
74
+ readonly verdict: HostTurnVerdict;
75
+ readonly rows: readonly HostSettingRow[];
76
+ readonly notices: readonly HostSettingNotice[];
77
+ readonly hooks: HooksWirePlan | undefined;
78
+ readonly carried: HostSettingsCarried;
79
+ }
80
+ export interface HostTurnSettingsJudges {
81
+ readonly materialize: HostResolvedMaterializer;
82
+ readonly memoryOffDeclared: typeof MemoryOffDeclared;
83
+ }
84
+ export declare function rethrowHostResolvedDeferred(product: HostTurnSettings): void;
85
+ export type HostResolvedMaterializer = (snapshot: SettingsDocument) => SettingsDocument;
86
+ export declare function buildHostTurnSettings(input: HostTurnSettingsInput, judges: HostTurnSettingsJudges): HostTurnSettings;
87
+ export declare function hostSettingsSelfCheck(product: HostTurnSettings): readonly HostSuppliedKey[];
88
+ export declare const hostProjectionNotice: () => HostSettingNotice;
89
+ export declare class HostSettingsRefused extends Error {
90
+ readonly notice: HostSettingNotice;
91
+ constructor(n: HostSettingNotice);
92
+ }
93
+ export declare function hostTurnSettingsOf(v: unknown, depth?: 'shape' | 'full'): HostTurnSettings | undefined;
94
+ export interface HostHooksIntersection {
95
+ readonly hooks: WireHooksConfig | undefined;
96
+ readonly dropped: number;
97
+ readonly judged: boolean;
98
+ }
99
+ export declare function intersectHostHooks(sent: WireHooksConfig, now: WireHooksConfig | undefined): HostHooksIntersection;
100
+ export interface HostIntakeSnapshot {
101
+ readonly carried: HostSettingsCarried;
102
+ readonly refuses: boolean;
103
+ readonly dispositions: Readonly<Record<HostSuppliedKey, HostSettingDisposition>>;
104
+ readonly refusingKeys: readonly HostSuppliedKey[];
105
+ readonly turnNotices: readonly HostSettingNotice[] | undefined;
106
+ readonly notice: HostSettingNotice | undefined;
107
+ }
108
+ export declare function hostIntakeSnapshotOf(product: HostTurnSettings, onResolved?: (resolved: HostSettingsCarried['resolved']) => void): HostIntakeSnapshot | undefined;
109
+ export declare const UNWIRED_HOST_TURN_SETTINGS: HostTurnSettings;
110
+ export {};