@sema-agent/client-core 0.88.0 → 0.89.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.
@@ -1,8 +1,8 @@
1
- import { engineCapNestedTrue, engineCapState } from './engineCapsCache.js';
1
+ import { engineCapNestedTrue, engineCapState, engineCapValue } from './engineCapsCache.js';
2
2
  import { displayUntrusted } from './displayUntrusted.js';
3
3
  import { collapseLabel } from './fleetTaskDesc.js';
4
4
  import { hostLog, hostSettings } from './host.js';
5
- import { decidePluginHooks, dedupeSettingsHookGroups, filterSettingsHookGroups, occupancyOf, settingsHookDropText, } from './pluginHooksWire.js';
5
+ import { createSettingsHookJudge, decidePluginHooks, dedupeSettingsHookGroups, filterSettingsHookGroups, occupancyOf, settingsHookDropText, } from './pluginHooksWire.js';
6
6
  import { MAX_HOOK_NOTICE_TEXT_CHARS } from './notifications.js';
7
7
  import { goalStopHookMatcher, __resetGoalStopHookForTests } from './goalStopHook.js';
8
8
  export { GOAL_STOP_HOOK_WIRE_ENV, CC_STOP_SEMANTICS_MIN_SERVER, ccStopSemanticsFromVersion, engineCcStopSemantics, isGoalStopHookWireArmed, setWireSessionStopHook, getWireSessionStopHook, getWireSessionStopHookCcSemantics, buildGoalStopHookPrompt, } from './goalStopHook.js';
@@ -121,7 +121,7 @@ function readPluginHooks(settings, warnIfAbsent) {
121
121
  }
122
122
  return { state: 'absent' };
123
123
  }
124
- const NO_PLAN_ENGINE = { ownedByThisShell: null, pluginHooksCapable: null };
124
+ const NO_PLAN_ENGINE = { ownedByThisShell: null, pluginHooksCapable: null, hooksCapable: null };
125
125
  export function hooksForWire(opts = {}) {
126
126
  const given = opts?.plan;
127
127
  if (isHooksWirePlan(given))
@@ -131,7 +131,7 @@ export function hooksForWire(opts = {}) {
131
131
  }
132
132
  if (isHooksWirePlan(opts))
133
133
  return opts.wire;
134
- return buildHooksWirePlan(NO_PLAN_ENGINE, new Set(), false).wire;
134
+ return buildHooksWirePlan(NO_PLAN_ENGINE, () => false, false, true).wire;
135
135
  }
136
136
  function isHooksWirePlan(v) {
137
137
  try {
@@ -139,14 +139,17 @@ function isHooksWirePlan(v) {
139
139
  return false;
140
140
  const o = v;
141
141
  for (const k of PLAN_KEYS)
142
- if (!Object.hasOwn(o, k))
142
+ if (!Object.hasOwn(o, k) && k !== 'settingsVerdicts' && k !== 'settingsExcluded')
143
143
  return false;
144
144
  const reader = o.pluginReader;
145
145
  const engineFacts = o.engine;
146
146
  const wire = o.wire;
147
+ const arrayOrAbsent = (k) => !Object.hasOwn(o, k) || Array.isArray(o[k]);
147
148
  return (Array.isArray(o.verdicts) &&
148
149
  Array.isArray(o.excluded) &&
149
150
  Array.isArray(o.settingsDropped) &&
151
+ arrayOrAbsent('settingsVerdicts') &&
152
+ arrayOrAbsent('settingsExcluded') &&
150
153
  (reader === 'present' || reader === 'absent' || reader === 'failed') &&
151
154
  typeof engineFacts === 'object' &&
152
155
  engineFacts !== null &&
@@ -157,7 +160,7 @@ function isHooksWirePlan(v) {
157
160
  return false;
158
161
  }
159
162
  }
160
- const PLAN_KEYS = ['engine', 'pluginReader', 'verdicts', 'excluded', 'settingsDropped', 'wire'];
163
+ const PLAN_KEYS = ['engine', 'pluginReader', 'verdicts', 'excluded', 'settingsDropped', 'settingsVerdicts', 'settingsExcluded', 'wire'];
161
164
  const _planKeysPin = [true, true];
162
165
  void _planKeysPin;
163
166
  export function hooksWirePlan(opts = {}) {
@@ -168,6 +171,7 @@ export function hooksWirePlan(opts = {}) {
168
171
  pluginHooksCapable: engineCapState(o.baseUrl, 'taskSettings') === 'unprobed'
169
172
  ? null
170
173
  : engineCapNestedTrue(o.baseUrl, 'taskSettings', 'pluginHooks'),
174
+ hooksCapable: taskHooksCapability(o.baseUrl),
171
175
  };
172
176
  const shellEvents = new Set();
173
177
  if (Array.isArray(o.shellHookEvents)) {
@@ -175,12 +179,72 @@ export function hooksWirePlan(opts = {}) {
175
179
  if (typeof e === 'string')
176
180
  shellEvents.add(e);
177
181
  }
178
- return buildHooksWirePlan(engine, shellEvents, true);
182
+ const typesByEvent = shellHookTypesOf(o);
183
+ const shellRuns = (event, type) => {
184
+ if (!shellEvents.has(event))
185
+ return false;
186
+ const types = typesByEvent?.get(event);
187
+ return types === undefined || (typeof type === 'string' && types.has(type));
188
+ };
189
+ const settingsShellRuns = typesByEvent !== undefined ? shellRuns : (event, type) => type !== 'prompt' && type !== 'agent' && shellRuns(event, type);
190
+ return buildHooksWirePlan(engine, shellRuns, true, promptAuthoredByUserOf(o), settingsShellRuns);
191
+ }
192
+ function taskHooksCapability(baseUrl) {
193
+ const v = engineCapValue(baseUrl, 'taskSettings');
194
+ if (v.kind !== 'value')
195
+ return null;
196
+ if (v.value === false)
197
+ return false;
198
+ if (typeof v.value !== 'object' || v.value === null || Array.isArray(v.value))
199
+ return null;
200
+ const hooks = v.value.hooks;
201
+ return hooks === true ? true : hooks === false ? false : null;
202
+ }
203
+ function shellHookTypesOf(o) {
204
+ let raw;
205
+ try {
206
+ raw = o.shellHookTypesByEvent;
207
+ if (raw === undefined)
208
+ return undefined;
209
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw))
210
+ throw new TypeError('not a plain object');
211
+ const out = new Map();
212
+ for (const key of Object.keys(raw)) {
213
+ const types = raw[key];
214
+ if (!Array.isArray(types) || !types.every((t) => typeof t === 'string'))
215
+ throw new TypeError(`value for one event is not an array of strings`);
216
+ out.set(key, new Set(types));
217
+ }
218
+ return out;
219
+ }
220
+ catch (err) {
221
+ hostLog('debug', `hooksWirePlan: shellHookTypesByEvent is malformed — treated as absent (command and http hooks count as running on every reported event; prompt and agent hooks from settings stay with the engine): ${String(err)}`);
222
+ return undefined;
223
+ }
224
+ }
225
+ function promptAuthoredByUserOf(o) {
226
+ let v;
227
+ try {
228
+ v = o.promptAuthoredByUser;
229
+ }
230
+ catch (err) {
231
+ hostLog('debug', `hooksWirePlan: promptAuthoredByUser threw while being read — treated as written by the user: ${String(err)}`);
232
+ return true;
233
+ }
234
+ if (v === false)
235
+ return false;
236
+ if (v !== undefined && v !== true) {
237
+ hostLog('debug', 'hooksWirePlan: promptAuthoredByUser is not a boolean — treated as written by the user');
238
+ }
239
+ return true;
179
240
  }
180
- function buildHooksWirePlan(engine, shellEvents, withPlugins) {
241
+ function buildHooksWirePlan(engine, shellRuns, withPlugins, promptAuthoredByUser, settingsShellRuns = shellRuns) {
181
242
  const settingsDropped = [];
243
+ const settingsVerdicts = [];
244
+ const settingsExcluded = [];
245
+ const judge = withPlugins ? createSettingsHookJudge(engine, settingsShellRuns, promptAuthoredByUser) : undefined;
182
246
  let settingsStripped = 0;
183
- const planOf = (pluginReader, wire, verdicts = [], excluded = []) => ({ engine, pluginReader, verdicts, excluded, settingsDropped, wire });
247
+ const planOf = (pluginReader, wire, verdicts = [], excluded = []) => ({ engine, pluginReader, verdicts, excluded, settingsDropped, settingsVerdicts, settingsExcluded, wire });
184
248
  const closedPlan = (settings, reason) => {
185
249
  if (!withPlugins)
186
250
  return planOf('absent', undefined);
@@ -193,7 +257,8 @@ function buildHooksWirePlan(engine, shellEvents, withPlugins) {
193
257
  exclusion: reason,
194
258
  managedOnly: false,
195
259
  engine,
196
- shellHookEvents: shellEvents,
260
+ shellRuns,
261
+ promptAuthoredByUser,
197
262
  occupied: new Map(),
198
263
  }));
199
264
  if (d === undefined)
@@ -265,8 +330,10 @@ function buildHooksWirePlan(engine, shellEvents, withPlugins) {
265
330
  for (const [event, groups] of Object.entries(hooks)) {
266
331
  if (!Array.isArray(groups) || groups.length === 0)
267
332
  continue;
268
- const kept = filterSettingsHookGroups(source, event, groups, engine.pluginHooksCapable === true, shellEvents.has(event), !withPlugins);
333
+ const kept = filterSettingsHookGroups(source, event, groups, engine.pluginHooksCapable === true, (type) => shellRuns(event, type), !withPlugins, judge);
269
334
  settingsDropped.push(...kept.drops);
335
+ settingsVerdicts.push(...kept.verdicts);
336
+ settingsExcluded.push(...kept.excluded);
270
337
  settingsStripped += kept.stripped;
271
338
  if (kept.groups.length === 0)
272
339
  continue;
@@ -334,7 +401,8 @@ function buildHooksWirePlan(engine, shellEvents, withPlugins) {
334
401
  exclusion: startup ? 'startup_mode' : undefined,
335
402
  managedOnly: managedOnlyPlugins,
336
403
  engine,
337
- shellHookEvents: shellEvents,
404
+ shellRuns,
405
+ promptAuthoredByUser,
338
406
  occupied,
339
407
  });
340
408
  });
package/dist/index.d.ts CHANGED
@@ -40,6 +40,7 @@ export * from './deviceExecutorManagementCapability.js';
40
40
  export * from './mcpReconnect.js';
41
41
  export * from './leaderConflict.js';
42
42
  export * from './runTerminal.js';
43
+ export { providerRejectionResend, type ProviderRejectionResend } from './providerRejection.js';
43
44
  export * from './runCancelContext.js';
44
45
  export * from './argvFlagValue.js';
45
46
  export * from './readFacePosture.js';
@@ -66,7 +67,7 @@ export type { DisplayUntrustedOptions, DisplayMark, DisplayMarkSpan, DisplayUntr
66
67
  export type * from './types/engineState.js';
67
68
  export * from './hostEnv.js';
68
69
  export * from './unrefTimer.js';
69
- export * from './controlRouter.js';
70
+ export { ControlRouter, ControlSafetyError, errCodes, type ControlClientLike, type ControlRouterOptions, type ControlSafetyCode, type ErrCodes, type QueuedCommand, type QueuePriority, type RunsResourceLike, } from './controlRouter.js';
70
71
  export * from './sseIdleTriage.js';
71
72
  export * from './engineWireSdk.js';
72
73
  export * from './classifierVerdictWire.js';
@@ -111,6 +112,8 @@ export * from './adapter/downstream/terminalToSdkResult.js';
111
112
  export * from './adapter/runStream.js';
112
113
  export * from './adapter/activeRunSelfHeal.js';
113
114
  export * from './request/taskRequest.js';
115
+ export { disableSkillsDeclaration } from './disableSkillsWire.js';
116
+ export type { DisableSkillsDeclaration } from './disableSkillsWire.js';
114
117
  export * from './clientSlice.js';
115
118
  export * from './host.js';
116
119
  export { DEFAULT_SESSION_KEY } from './sessionSlot.js';
@@ -159,7 +162,7 @@ export * from './detachWire.js';
159
162
  export * from './workflowMonitor.js';
160
163
  export * from './workflowClient.js';
161
164
  export * from './hooksWireCaps.js';
162
- export { ENGINE_FIRED_HOOK_EVENTS, PLUGIN_HOOK_DISPOSITIONS, PLUGIN_HOOK_REASONS, PLUGIN_HOOK_EXCLUSION_REASONS, SETTINGS_HOOK_DROP_REASONS, isEngineFiredHookEvent, pluginHookVerdictOf, pluginHookReasonText, settingsHookDropText, pluginHookExecutorLabel, hooksNotRunNotice, type EngineFiredHookEvent, type PluginHookDisposition, type PluginHookReason, type PluginHookExclusionReason, type SettingsHookDropReason, type HookSettingsSource, type PluginHookKey, type PluginHookVerdict, type PluginHookExclusion, type SettingsHookDrop, type HooksWireEngineFacts, type PluginHookReaderState, type HooksWirePlan, type HooksWirePlanOptions, } from './pluginHooksWire.js';
165
+ export { ENGINE_FIRED_HOOK_EVENTS, PLUGIN_HOOK_DISPOSITIONS, PLUGIN_HOOK_REASONS, PLUGIN_HOOK_EXCLUSION_REASONS, SETTINGS_HOOK_DROP_REASONS, isEngineFiredHookEvent, pluginHookVerdictOf, pluginHookReasonText, settingsHookDropText, pluginHookExecutorLabel, hooksNotRunNotice, settingsHooksKeptLocally, type EngineFiredHookEvent, type PluginHookDisposition, type PluginHookReason, type PluginHookExclusionReason, type SettingsHookDropReason, type HookSettingsSource, type PluginHookKey, type PluginHookVerdict, type PluginHookExclusion, type SettingsHookDrop, type SettingsHookVerdict, type SettingsHookExclusion, type HooksWireEngineFacts, type PluginHookReaderState, type HooksWirePlan, type HooksWirePlanOptions, } from './pluginHooksWire.js';
163
166
  export * from './liveInitToolFace.js';
164
167
  export * from './printInitToolFace.js';
165
168
  export * from './model/providerPresets.js';
@@ -197,7 +200,7 @@ export * from './request/printNotification.js';
197
200
  export * from './seatContract.js';
198
201
  export * from './agentSession/contract.js';
199
202
  export * from './agentSession/backgroundView.js';
200
- export { READ_CREDENTIAL_NOT_ACCEPTED_NOTICE } from './readCredentialRefusal.js';
203
+ export { READ_CREDENTIAL_NOT_ACCEPTED_NOTICE, isReadCredentialRefusal } from './readCredentialRefusal.js';
201
204
  export { readEngineAgentRegistry, isEngineAgentRegistryListingSuperseded } from './agentSession/engineAgentRegistryRead.js';
202
205
  export type { EngineAgentRegistryClient } from './agentSession/engineAgentRegistryRead.js';
203
206
  export { stopEngineSessionBackground, engineSessionBackgroundReceiptReadingOf, ENGINE_SESSION_BACKGROUND_RECEIPT_STATES, } from './agentSession/engineSessionBackgroundStop.js';
package/dist/index.js CHANGED
@@ -35,6 +35,7 @@ export * from './deviceExecutorManagementCapability.js';
35
35
  export * from './mcpReconnect.js';
36
36
  export * from './leaderConflict.js';
37
37
  export * from './runTerminal.js';
38
+ export { providerRejectionResend } from './providerRejection.js';
38
39
  export * from './runCancelContext.js';
39
40
  export * from './argvFlagValue.js';
40
41
  export * from './readFacePosture.js';
@@ -59,7 +60,7 @@ export * from './fleetTaskDesc.js';
59
60
  export { displayUntrusted, displayUntrustedMarks } from './displayUntrusted.js';
60
61
  export * from './hostEnv.js';
61
62
  export * from './unrefTimer.js';
62
- export * from './controlRouter.js';
63
+ export { ControlRouter, ControlSafetyError, errCodes, } from './controlRouter.js';
63
64
  export * from './sseIdleTriage.js';
64
65
  export * from './engineWireSdk.js';
65
66
  export * from './classifierVerdictWire.js';
@@ -102,6 +103,7 @@ export * from './adapter/downstream/terminalToSdkResult.js';
102
103
  export * from './adapter/runStream.js';
103
104
  export * from './adapter/activeRunSelfHeal.js';
104
105
  export * from './request/taskRequest.js';
106
+ export { disableSkillsDeclaration } from './disableSkillsWire.js';
105
107
  export * from './clientSlice.js';
106
108
  export * from './host.js';
107
109
  export { DEFAULT_SESSION_KEY } from './sessionSlot.js';
@@ -145,7 +147,7 @@ export * from './detachWire.js';
145
147
  export * from './workflowMonitor.js';
146
148
  export * from './workflowClient.js';
147
149
  export * from './hooksWireCaps.js';
148
- export { ENGINE_FIRED_HOOK_EVENTS, PLUGIN_HOOK_DISPOSITIONS, PLUGIN_HOOK_REASONS, PLUGIN_HOOK_EXCLUSION_REASONS, SETTINGS_HOOK_DROP_REASONS, isEngineFiredHookEvent, pluginHookVerdictOf, pluginHookReasonText, settingsHookDropText, pluginHookExecutorLabel, hooksNotRunNotice, } from './pluginHooksWire.js';
150
+ export { ENGINE_FIRED_HOOK_EVENTS, PLUGIN_HOOK_DISPOSITIONS, PLUGIN_HOOK_REASONS, PLUGIN_HOOK_EXCLUSION_REASONS, SETTINGS_HOOK_DROP_REASONS, isEngineFiredHookEvent, pluginHookVerdictOf, pluginHookReasonText, settingsHookDropText, pluginHookExecutorLabel, hooksNotRunNotice, settingsHooksKeptLocally, } from './pluginHooksWire.js';
149
151
  export * from './liveInitToolFace.js';
150
152
  export * from './printInitToolFace.js';
151
153
  export * from './model/providerPresets.js';
@@ -181,7 +183,7 @@ export * from './request/printNotification.js';
181
183
  export * from './seatContract.js';
182
184
  export * from './agentSession/contract.js';
183
185
  export * from './agentSession/backgroundView.js';
184
- export { READ_CREDENTIAL_NOT_ACCEPTED_NOTICE } from './readCredentialRefusal.js';
186
+ export { READ_CREDENTIAL_NOT_ACCEPTED_NOTICE, isReadCredentialRefusal } from './readCredentialRefusal.js';
185
187
  export { readEngineAgentRegistry, isEngineAgentRegistryListingSuperseded } from './agentSession/engineAgentRegistryRead.js';
186
188
  export { stopEngineSessionBackground, engineSessionBackgroundReceiptReadingOf, ENGINE_SESSION_BACKGROUND_RECEIPT_STATES, } from './agentSession/engineSessionBackgroundStop.js';
187
189
  export { eraseSessionMemory, sessionMemoryEraseOutcome, SESSION_MEMORY_ERASE_REFUSAL_REASONS, SESSION_MEMORY_ERASE_UNCONFIRMED_WHYS, SESSION_MEMORY_ERASE_RETRIES, } from './sessionMemoryErase.js';
@@ -4,9 +4,9 @@ export declare const ENGINE_FIRED_HOOK_EVENTS: readonly ["PreToolUse", "PostTool
4
4
  export type EngineFiredHookEvent = (typeof ENGINE_FIRED_HOOK_EVENTS)[number];
5
5
  export declare const PLUGIN_HOOK_DISPOSITIONS: readonly ["engine", "shell", "not_run"];
6
6
  export type PluginHookDisposition = (typeof PLUGIN_HOOK_DISPOSITIONS)[number];
7
- export declare const PLUGIN_HOOK_REASONS: readonly ["projected", "shell_event", "no_executor", "engine_not_local", "engine_locality_unknown", "engine_capability_absent", "engine_capability_unknown", "not_command", "sensitive_options", "engine_limit", "shell_form_user_config", "user_config_unset", "malformed_entry"];
7
+ export declare const PLUGIN_HOOK_REASONS: readonly ["projected", "shell_event", "no_executor", "engine_not_local", "engine_locality_unknown", "engine_capability_absent", "engine_capability_unknown", "not_command", "sensitive_options", "engine_limit", "shell_form_user_config", "user_config_unset", "malformed_entry", "engine_hooks_off", "engine_hooks_unknown", "engine_type_skipped", "engine_llm_limit", "engine_unconfirmed", "engine_elsewhere"];
8
8
  export type PluginHookReason = (typeof PLUGIN_HOOK_REASONS)[number];
9
- export declare const PLUGIN_HOOK_EXCLUSION_REASONS: readonly ["workspace_untrusted", "governance_unreadable", "policy_disable_all", "startup_mode", "managed_plugins_only"];
9
+ export declare const PLUGIN_HOOK_EXCLUSION_REASONS: readonly ["workspace_untrusted", "governance_unreadable", "policy_disable_all", "startup_mode", "managed_plugins_only", "prompt_not_user_authored"];
10
10
  export type PluginHookExclusionReason = (typeof PLUGIN_HOOK_EXCLUSION_REASONS)[number];
11
11
  export declare const SETTINGS_HOOK_DROP_REASONS: readonly ["exec_form_unsupported", "mcp_tool_unsupported"];
12
12
  export type SettingsHookDropReason = (typeof SETTINGS_HOOK_DROP_REASONS)[number];
@@ -33,9 +33,25 @@ export interface SettingsHookDrop {
33
33
  readonly reason: SettingsHookDropReason;
34
34
  readonly notRun: boolean;
35
35
  }
36
+ export interface SettingsHookVerdict {
37
+ readonly source: HookSettingsSource;
38
+ readonly event: string;
39
+ readonly groupIndex: number;
40
+ readonly hookIndex: number;
41
+ readonly disposition: PluginHookDisposition;
42
+ readonly reason: PluginHookReason;
43
+ }
44
+ export interface SettingsHookExclusion {
45
+ readonly source: HookSettingsSource;
46
+ readonly event: string;
47
+ readonly groupIndex: number;
48
+ readonly hookIndex: number;
49
+ readonly reason: PluginHookExclusionReason;
50
+ }
36
51
  export interface HooksWireEngineFacts {
37
52
  readonly ownedByThisShell: boolean | null;
38
53
  readonly pluginHooksCapable: boolean | null;
54
+ readonly hooksCapable: boolean | null;
39
55
  }
40
56
  export type PluginHookReaderState = 'present' | 'absent' | 'failed';
41
57
  export interface HooksWirePlan {
@@ -44,19 +60,34 @@ export interface HooksWirePlan {
44
60
  readonly verdicts: readonly PluginHookVerdict[];
45
61
  readonly excluded: readonly PluginHookExclusion[];
46
62
  readonly settingsDropped: readonly SettingsHookDrop[];
63
+ readonly settingsVerdicts: readonly SettingsHookVerdict[];
64
+ readonly settingsExcluded: readonly SettingsHookExclusion[];
47
65
  readonly wire: WireHooksConfig | undefined;
48
66
  }
49
67
  export interface HooksWirePlanOptions {
50
68
  readonly baseUrl?: string;
51
69
  readonly engineOwnedByThisShell?: boolean;
52
70
  readonly shellHookEvents?: readonly string[];
71
+ readonly shellHookTypesByEvent?: Readonly<Record<string, readonly string[]>>;
72
+ readonly promptAuthoredByUser?: boolean;
53
73
  }
54
74
  export declare const ENGINE_HOOK_LIMITS: {
55
75
  readonly maxGroupsPerEvent: 16;
56
76
  readonly maxEntriesPerEvent: 32;
57
77
  readonly maxCommandChars: 8192;
78
+ readonly maxLlmEntriesPerEvent: 4;
79
+ };
80
+ export type ShellRunsHook = (event: string, type: string | undefined) => boolean;
81
+ type HookExecutor = {
82
+ readonly kind: 'excluded';
83
+ readonly reason: 'prompt_not_user_authored';
84
+ } | {
85
+ readonly kind: 'judged';
86
+ readonly disposition: PluginHookDisposition;
87
+ readonly reason: PluginHookReason;
58
88
  };
59
89
  type WireHookGroup = NonNullable<WireHooksConfig[string]>[number];
90
+ type WireHookEntry = WireHookGroup['hooks'][number];
60
91
  export declare function isEngineFiredHookEvent(event: string): boolean;
61
92
  export interface EventOccupancy {
62
93
  readonly groups: number;
@@ -68,7 +99,8 @@ export interface PluginHookDecisionInput {
68
99
  readonly exclusion: PluginHookExclusionReason | undefined;
69
100
  readonly managedOnly: boolean;
70
101
  readonly engine: HooksWireEngineFacts;
71
- readonly shellHookEvents: ReadonlySet<string>;
102
+ readonly shellRuns: ShellRunsHook;
103
+ readonly promptAuthoredByUser: boolean;
72
104
  readonly occupied: ReadonlyMap<string, EventOccupancy>;
73
105
  }
74
106
  export interface PluginHookDecision {
@@ -78,12 +110,16 @@ export interface PluginHookDecision {
78
110
  readonly unreadable: number;
79
111
  }
80
112
  export declare function decidePluginHooks(input: PluginHookDecisionInput): PluginHookDecision;
81
- export declare function filterSettingsHookGroups(source: HookSettingsSource, event: string, groups: readonly WireHookGroup[], execFormCapable: boolean, hostFires: boolean, failLoudMcpTool: boolean): SettingsHookFilterResult;
113
+ export declare function filterSettingsHookGroups(source: HookSettingsSource, event: string, groups: readonly WireHookGroup[], execFormCapable: boolean, shellRunsType: (type: string | undefined) => boolean, failLoudMcpTool: boolean, judge?: SettingsHookJudge): SettingsHookFilterResult;
82
114
  export interface SettingsHookFilterResult {
83
115
  readonly groups: WireHookGroup[];
84
116
  readonly drops: SettingsHookDrop[];
85
117
  readonly stripped: number;
118
+ readonly verdicts: SettingsHookVerdict[];
119
+ readonly excluded: SettingsHookExclusion[];
86
120
  }
121
+ export type SettingsHookJudge = (event: string, group: WireHookGroup, entry: WireHookEntry) => HookExecutor;
122
+ export declare function createSettingsHookJudge(engine: HooksWireEngineFacts, shellRuns: ShellRunsHook, promptAuthoredByUser: boolean): SettingsHookJudge;
87
123
  export interface SourcedSettingsHookGroup {
88
124
  readonly source: HookSettingsSource;
89
125
  readonly group: WireHookGroup;
@@ -94,6 +130,12 @@ export interface SettingsHookDedupResult {
94
130
  readonly removed: number;
95
131
  }
96
132
  export declare function pluginHookVerdictOf(plan: HooksWirePlan, pluginId: string, event: string, groupIndex: number, hookIndex: number): PluginHookVerdict | undefined;
133
+ export declare function settingsHooksKeptLocally<T>(plan: HooksWirePlan, event: string, group: {
134
+ readonly matcher?: string;
135
+ readonly hooks: readonly T[];
136
+ }, opts?: {
137
+ readonly engineCompaction?: 'performed' | 'not_performed';
138
+ }): readonly T[];
97
139
  export declare function pluginHookReasonText(reason: PluginHookReason): string;
98
140
  export declare function settingsHookDropText(reason: SettingsHookDropReason): string;
99
141
  export declare function pluginHookExecutorLabel(v: PluginHookVerdict): string;