@sema-agent/client-core 0.82.7 → 0.83.1
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.
- package/CHANGELOG.md +97 -0
- package/README.md +15 -7
- package/dist/adapt/arms.d.ts +3 -2
- package/dist/adapt/arms.js +17 -11
- package/dist/adapt/ids.js +12 -8
- package/dist/adapt/textStream.d.ts +3 -2
- package/dist/adapt/toolCards.d.ts +2 -3
- package/dist/adapt/toolCards.js +1 -1
- package/dist/adapt.d.ts +1 -1
- package/dist/adapt.js +13 -6
- package/dist/adapter/activeRunSelfHeal.js +34 -17
- package/dist/adapter/downstream/eventToSdkMessage.js +1 -1
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -4
- package/dist/adapter/downstream/terminalToSdkResult.js +46 -8
- package/dist/adapter/runStream.js +25 -8
- package/dist/clientSlice.d.ts +0 -5
- package/dist/displayUntrusted.d.ts +24 -0
- package/dist/displayUntrusted.js +1437 -0
- package/dist/engineNoticeCodes.js +4 -0
- package/dist/fleet/fleetRowAgentType.d.ts +0 -1
- package/dist/fleet/fleetRowAgentType.js +0 -3
- package/dist/fleetTaskDesc.js +3 -3
- package/dist/gateVocabulary.js +1 -1
- package/dist/hitl/approvalDecisionNoteAudit.js +4 -2
- package/dist/hitl/approvalResolution.js +2 -0
- package/dist/hitl/frameRouter.d.ts +3 -2
- package/dist/hitl/sessionPolicyDeliverable.d.ts +14 -0
- package/dist/hitl/sessionPolicyDeliverable.js +80 -0
- package/dist/hitl/toolApprovalWire.d.ts +1 -0
- package/dist/hitl/toolApprovalWire.js +56 -10
- package/dist/hooksWireCaps.d.ts +6 -1
- package/dist/hooksWireCaps.js +220 -13
- package/dist/host.d.ts +25 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/liveInitToolFace.d.ts +4 -2
- package/dist/liveInitToolFace.js +2 -2
- package/dist/model/catalogLoader.d.ts +1 -6
- package/dist/panelRunningHistory.d.ts +3 -2
- package/dist/peerFrames.d.ts +0 -1
- package/dist/peerFrames.js +2 -1
- package/dist/pluginHooksWire.d.ts +92 -0
- package/dist/pluginHooksWire.js +429 -0
- package/dist/printInitToolFace.js +1 -1
- package/dist/request/printNotification.js +26 -26
- package/dist/seam.d.ts +8 -2
- package/dist/seam.js +18 -7
- package/dist/subagent/engineSubagentResume.js +2 -1
- package/dist/systemReminderTag.d.ts +0 -1
- package/dist/systemReminderTag.js +0 -3
- package/dist/toolResult.js +1 -0
- package/dist/uuidV5.d.ts +3 -0
- package/dist/uuidV5.js +178 -0
- package/dist/webSearchWireCaps.d.ts +0 -3
- package/dist/webSearchWireCaps.js +21 -51
- package/dist/wireFailureShape.d.ts +2 -1
- package/docs/INTEGRATION-CLIENTS.md +794 -13
- package/package.json +2 -2
package/dist/hooksWireCaps.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import { engineCapNestedTrue } from './engineCapsCache.js';
|
|
1
|
+
import { engineCapNestedTrue, engineCapState } from './engineCapsCache.js';
|
|
2
|
+
import { displayUntrusted } from './displayUntrusted.js';
|
|
2
3
|
import { collapseLabel } from './fleetTaskDesc.js';
|
|
3
4
|
import { hostLog, hostSettings } from './host.js';
|
|
5
|
+
import { decidePluginHooks, filterSettingsHookGroups, occupancyOf, settingsHookDropText, } from './pluginHooksWire.js';
|
|
4
6
|
import { MAX_HOOK_NOTICE_TEXT_CHARS } from './notifications.js';
|
|
5
7
|
import { goalStopHookMatcher, __resetGoalStopHookForTests } from './goalStopHook.js';
|
|
6
8
|
export { GOAL_STOP_HOOK_WIRE_ENV, CC_STOP_SEMANTICS_MIN_SERVER, ccStopSemanticsFromVersion, engineCcStopSemantics, isGoalStopHookWireArmed, setWireSessionStopHook, getWireSessionStopHook, getWireSessionStopHookCcSemantics, buildGoalStopHookPrompt, } from './goalStopHook.js';
|
|
7
9
|
const EDITABLE_HOOK_SOURCES = ['userSettings', 'projectSettings', 'localSettings'];
|
|
10
|
+
const ALL_HOOK_SOURCES = ['policySettings', ...EDITABLE_HOOK_SOURCES];
|
|
11
|
+
const _hookSourceListsPin = [true, true];
|
|
12
|
+
void _hookSourceListsPin;
|
|
8
13
|
function hooksLockedToPluginOnly(policyValue) {
|
|
9
14
|
if (policyValue === true)
|
|
10
15
|
return true;
|
|
@@ -12,6 +17,26 @@ function hooksLockedToPluginOnly(policyValue) {
|
|
|
12
17
|
return policyValue.includes('hooks');
|
|
13
18
|
return false;
|
|
14
19
|
}
|
|
20
|
+
let warnedNoMergedReader = new WeakSet();
|
|
21
|
+
const NO_MERGED_READER_WARNING = 'client-core: the installed settings port does not implement mergedDisableAllHooks() — ' +
|
|
22
|
+
'a disableAllHooks set in user, project, local or flag settings is not applied to hooks sent to the engine ' +
|
|
23
|
+
'(only a managed-settings disableAllHooks is). Implement SettingsPort.mergedDisableAllHooks() to return ' +
|
|
24
|
+
'the effective merged value.';
|
|
25
|
+
function nonManagedDisableAllHooks(settings) {
|
|
26
|
+
try {
|
|
27
|
+
if (typeof settings.mergedDisableAllHooks === 'function')
|
|
28
|
+
return settings.mergedDisableAllHooks() === true;
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
hostLog('debug', `hooksWireCaps: merged disableAllHooks read threw — fail-closed (only policySettings hooks projected to the engine): ${String(err)}`);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
if (!warnedNoMergedReader.has(settings)) {
|
|
35
|
+
warnedNoMergedReader.add(settings);
|
|
36
|
+
hostLog('warn', NO_MERGED_READER_WARNING);
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
15
40
|
function hooksOfSource(source) {
|
|
16
41
|
try {
|
|
17
42
|
const s = hostSettings()?.getSettingsForSource(source);
|
|
@@ -22,19 +47,137 @@ function hooksOfSource(source) {
|
|
|
22
47
|
return null;
|
|
23
48
|
}
|
|
24
49
|
}
|
|
25
|
-
|
|
50
|
+
let warnedNoPluginReader = new WeakSet();
|
|
51
|
+
const NO_PLUGIN_READER_WARNING = 'client-core: the installed settings port does not implement enabledPluginHooks() — ' +
|
|
52
|
+
'plugin hooks are not sent to the engine and are not reported as not running. ' +
|
|
53
|
+
'Implement SettingsPort.enabledPluginHooks() to list the enabled plugins and their hooks.';
|
|
54
|
+
let warnedNoPlanDrops = new WeakMap();
|
|
55
|
+
function noPlanDropWarning(event, reason) {
|
|
56
|
+
return (`client-core: ${displayUntrusted(event, { credentialUrls: false, credentialWords: false })} hooks from settings are not sent to the engine (${reason}), so they do not run there — ` +
|
|
57
|
+
`${settingsHookDropText(reason)}. Build the request with hooksForWire({ plan }) from hooksWirePlan() and show ` +
|
|
58
|
+
'hooksNotRunNotice(plan) to tell the user which hooks will not run.');
|
|
59
|
+
}
|
|
60
|
+
function guardPluginTraversal(run) {
|
|
61
|
+
try {
|
|
62
|
+
return run();
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
hostLog('debug', `hooksWireCaps: plugin hook data threw while being read — no plugin hooks projected this turn: ${String(err)}`);
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function readPluginHooks(settings, warnIfAbsent) {
|
|
70
|
+
try {
|
|
71
|
+
if (typeof settings.enabledPluginHooks === 'function') {
|
|
72
|
+
const r = settings.enabledPluginHooks();
|
|
73
|
+
if (typeof r === 'object' && r !== null && Array.isArray(r.plugins)) {
|
|
74
|
+
return { state: 'present', reading: r };
|
|
75
|
+
}
|
|
76
|
+
hostLog('debug', 'hooksWireCaps: enabledPluginHooks() returned a malformed reading — no plugin hooks projected this turn');
|
|
77
|
+
return { state: 'failed' };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
hostLog('debug', `hooksWireCaps: enabledPluginHooks() threw — no plugin hooks projected this turn: ${String(err)}`);
|
|
82
|
+
return { state: 'failed' };
|
|
83
|
+
}
|
|
84
|
+
if (warnIfAbsent && !warnedNoPluginReader.has(settings)) {
|
|
85
|
+
warnedNoPluginReader.add(settings);
|
|
86
|
+
hostLog('warn', NO_PLUGIN_READER_WARNING);
|
|
87
|
+
}
|
|
88
|
+
return { state: 'absent' };
|
|
89
|
+
}
|
|
90
|
+
const NO_PLAN_ENGINE = { ownedByThisShell: null, pluginHooksCapable: null };
|
|
91
|
+
export function hooksForWire(opts = {}) {
|
|
92
|
+
const given = opts?.plan;
|
|
93
|
+
if (isHooksWirePlan(given))
|
|
94
|
+
return given.wire;
|
|
95
|
+
if (given !== undefined && given !== null) {
|
|
96
|
+
hostLog('debug', 'hooksForWire: opts.plan is not a plan from hooksWirePlan() — treated as absent (settings hooks only)');
|
|
97
|
+
}
|
|
98
|
+
if (isHooksWirePlan(opts))
|
|
99
|
+
return opts.wire;
|
|
100
|
+
return buildHooksWirePlan(NO_PLAN_ENGINE, new Set(), false).wire;
|
|
101
|
+
}
|
|
102
|
+
function isHooksWirePlan(v) {
|
|
103
|
+
try {
|
|
104
|
+
if (typeof v !== 'object' || v === null || Array.isArray(v))
|
|
105
|
+
return false;
|
|
106
|
+
const o = v;
|
|
107
|
+
for (const k of PLAN_KEYS)
|
|
108
|
+
if (!Object.hasOwn(o, k))
|
|
109
|
+
return false;
|
|
110
|
+
const reader = o.pluginReader;
|
|
111
|
+
const engineFacts = o.engine;
|
|
112
|
+
const wire = o.wire;
|
|
113
|
+
return (Array.isArray(o.verdicts) &&
|
|
114
|
+
Array.isArray(o.excluded) &&
|
|
115
|
+
Array.isArray(o.settingsDropped) &&
|
|
116
|
+
(reader === 'present' || reader === 'absent' || reader === 'failed') &&
|
|
117
|
+
typeof engineFacts === 'object' &&
|
|
118
|
+
engineFacts !== null &&
|
|
119
|
+
(wire === undefined || (typeof wire === 'object' && wire !== null && !Array.isArray(wire))));
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
hostLog('debug', `hooksForWire: a value offered as a plan threw while being read — treated as not a plan: ${String(err)}`);
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const PLAN_KEYS = ['engine', 'pluginReader', 'verdicts', 'excluded', 'settingsDropped', 'wire'];
|
|
127
|
+
const _planKeysPin = [true, true];
|
|
128
|
+
void _planKeysPin;
|
|
129
|
+
export function hooksWirePlan(opts = {}) {
|
|
130
|
+
const o = opts ?? {};
|
|
131
|
+
const owned = o.engineOwnedByThisShell;
|
|
132
|
+
const engine = {
|
|
133
|
+
ownedByThisShell: owned === true ? true : owned === false ? false : null,
|
|
134
|
+
pluginHooksCapable: engineCapState(o.baseUrl, 'taskSettings') === 'unprobed'
|
|
135
|
+
? null
|
|
136
|
+
: engineCapNestedTrue(o.baseUrl, 'taskSettings', 'pluginHooks'),
|
|
137
|
+
};
|
|
138
|
+
const shellEvents = new Set();
|
|
139
|
+
if (Array.isArray(o.shellHookEvents)) {
|
|
140
|
+
for (const e of o.shellHookEvents)
|
|
141
|
+
if (typeof e === 'string')
|
|
142
|
+
shellEvents.add(e);
|
|
143
|
+
}
|
|
144
|
+
return buildHooksWirePlan(engine, shellEvents, true);
|
|
145
|
+
}
|
|
146
|
+
function buildHooksWirePlan(engine, shellEvents, withPlugins) {
|
|
147
|
+
const settingsDropped = [];
|
|
148
|
+
let settingsStripped = 0;
|
|
149
|
+
const planOf = (pluginReader, wire, verdicts = [], excluded = []) => ({ engine, pluginReader, verdicts, excluded, settingsDropped, wire });
|
|
150
|
+
const closedPlan = (settings, reason) => {
|
|
151
|
+
if (!withPlugins)
|
|
152
|
+
return planOf('absent', undefined);
|
|
153
|
+
const read = readPluginHooks(settings, false);
|
|
154
|
+
if (read.reading === undefined)
|
|
155
|
+
return planOf(read.state, undefined);
|
|
156
|
+
const reading = read.reading;
|
|
157
|
+
const d = guardPluginTraversal(() => decidePluginHooks({
|
|
158
|
+
plugins: reading.plugins,
|
|
159
|
+
exclusion: reason,
|
|
160
|
+
managedOnly: false,
|
|
161
|
+
engine,
|
|
162
|
+
shellHookEvents: shellEvents,
|
|
163
|
+
occupied: new Map(),
|
|
164
|
+
}));
|
|
165
|
+
if (d === undefined)
|
|
166
|
+
return planOf('failed', undefined);
|
|
167
|
+
return planOf(read.state, undefined, d.verdicts, d.excluded);
|
|
168
|
+
};
|
|
26
169
|
const settings = hostSettings();
|
|
27
170
|
if (settings === undefined)
|
|
28
|
-
return undefined;
|
|
171
|
+
return planOf('absent', undefined);
|
|
29
172
|
try {
|
|
30
173
|
if (settings.shouldSkipHookDueToTrust()) {
|
|
31
174
|
hostLog('debug', 'hooksWireCaps: workspace not trusted — no hooks projected to the engine');
|
|
32
|
-
return
|
|
175
|
+
return closedPlan(settings, 'workspace_untrusted');
|
|
33
176
|
}
|
|
34
177
|
}
|
|
35
178
|
catch (err) {
|
|
36
179
|
hostLog('debug', `hooksWireCaps: workspace trust check threw — fail-closed (no hooks projected to the engine): ${String(err)}`);
|
|
37
|
-
return
|
|
180
|
+
return closedPlan(settings, 'governance_unreadable');
|
|
38
181
|
}
|
|
39
182
|
let policy = null;
|
|
40
183
|
try {
|
|
@@ -42,20 +185,25 @@ export function hooksForWire() {
|
|
|
42
185
|
}
|
|
43
186
|
catch (err) {
|
|
44
187
|
hostLog('debug', `hooksWireCaps: policySettings read threw — fail-closed (no hooks projected to the engine): ${String(err)}`);
|
|
45
|
-
return
|
|
188
|
+
return closedPlan(settings, 'governance_unreadable');
|
|
46
189
|
}
|
|
47
190
|
if (policy?.disableAllHooks === true) {
|
|
48
191
|
hostLog('debug', 'hooksWireCaps: disableAllHooks (managed) — no hooks projected to the engine');
|
|
49
|
-
return
|
|
192
|
+
return closedPlan(settings, 'policy_disable_all');
|
|
50
193
|
}
|
|
51
194
|
const pluginOnlyHooks = hooksLockedToPluginOnly(policy?.strictPluginOnlyCustomization);
|
|
52
195
|
if (pluginOnlyHooks) {
|
|
53
196
|
hostLog('debug', 'hooksWireCaps: strictPluginOnlyCustomization locks the hooks surface (managed) — only policySettings hooks projected to the engine');
|
|
54
197
|
}
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
198
|
+
const managedByPolicy = policy?.allowManagedHooksOnly === true || pluginOnlyHooks;
|
|
199
|
+
let mergedMemo;
|
|
200
|
+
const mergedDisable = () => (mergedMemo ??= nonManagedDisableAllHooks(settings));
|
|
201
|
+
const disabledByNonManaged = !managedByPolicy && mergedDisable();
|
|
202
|
+
if (disabledByNonManaged) {
|
|
203
|
+
hostLog('debug', 'hooksWireCaps: disableAllHooks (merged, non-managed) — only policySettings hooks projected to the engine');
|
|
204
|
+
}
|
|
205
|
+
const managedOnly = managedByPolicy || disabledByNonManaged;
|
|
206
|
+
const sources = managedOnly ? ['policySettings'] : ALL_HOOK_SOURCES;
|
|
59
207
|
const merged = {};
|
|
60
208
|
for (const source of sources) {
|
|
61
209
|
const hooks = hooksOfSource(source);
|
|
@@ -64,17 +212,76 @@ export function hooksForWire() {
|
|
|
64
212
|
for (const [event, groups] of Object.entries(hooks)) {
|
|
65
213
|
if (!Array.isArray(groups) || groups.length === 0)
|
|
66
214
|
continue;
|
|
67
|
-
|
|
215
|
+
const kept = filterSettingsHookGroups(source, event, groups, engine.pluginHooksCapable === true, shellEvents.has(event), !withPlugins);
|
|
216
|
+
settingsDropped.push(...kept.drops);
|
|
217
|
+
settingsStripped += kept.stripped;
|
|
218
|
+
if (kept.groups.length === 0)
|
|
219
|
+
continue;
|
|
220
|
+
merged[event] = [...(merged[event] ?? []), ...kept.groups];
|
|
68
221
|
}
|
|
69
222
|
}
|
|
70
223
|
const goalMatcher = goalStopHookMatcher(managedOnly);
|
|
71
224
|
if (goalMatcher !== null) {
|
|
72
225
|
merged['Stop'] = [...(merged['Stop'] ?? []), goalMatcher];
|
|
73
226
|
}
|
|
74
|
-
|
|
227
|
+
if (settingsDropped.length > 0) {
|
|
228
|
+
hostLog('debug', `hooksWireCaps: ${settingsDropped.length} settings hook entr${settingsDropped.length === 1 ? 'y' : 'ies'} not sent to the engine ` +
|
|
229
|
+
`(${[...new Set(settingsDropped.map((d) => d.reason))].join(', ')}) — see hooksWirePlan().settingsDropped`);
|
|
230
|
+
}
|
|
231
|
+
if (settingsStripped > 0) {
|
|
232
|
+
hostLog('debug', `hooksWireCaps: ${settingsStripped} settings hook entr${settingsStripped === 1 ? 'y' : 'ies'} carried a plugin key — ` +
|
|
233
|
+
'stripped before sending (plugin context is only minted for entries from the plugin reader)');
|
|
234
|
+
}
|
|
235
|
+
const wireOf = () => (Object.keys(merged).length > 0 ? merged : undefined);
|
|
236
|
+
if (!withPlugins) {
|
|
237
|
+
let seen = warnedNoPlanDrops.get(settings);
|
|
238
|
+
for (const d of settingsDropped) {
|
|
239
|
+
if (!d.notRun)
|
|
240
|
+
continue;
|
|
241
|
+
const key = `${d.event}\u0000${d.reason}`;
|
|
242
|
+
if (seen?.has(key) === true)
|
|
243
|
+
continue;
|
|
244
|
+
if (seen === undefined) {
|
|
245
|
+
seen = new Set();
|
|
246
|
+
warnedNoPlanDrops.set(settings, seen);
|
|
247
|
+
}
|
|
248
|
+
seen.add(key);
|
|
249
|
+
hostLog('warn', noPlanDropWarning(d.event, d.reason));
|
|
250
|
+
}
|
|
251
|
+
return planOf('absent', wireOf());
|
|
252
|
+
}
|
|
253
|
+
const read = readPluginHooks(settings, true);
|
|
254
|
+
if (read.reading === undefined)
|
|
255
|
+
return planOf(read.state, wireOf());
|
|
256
|
+
const reading = read.reading;
|
|
257
|
+
const occupied = occupancyOf(merged);
|
|
258
|
+
const d = guardPluginTraversal(() => {
|
|
259
|
+
const plugins = reading.plugins;
|
|
260
|
+
const startupMode = reading.suppressedByStartupMode === true;
|
|
261
|
+
const managedOnlyPlugins = !startupMode && plugins.length > 0 && (policy?.allowManagedHooksOnly === true || mergedDisable());
|
|
262
|
+
return decidePluginHooks({
|
|
263
|
+
plugins,
|
|
264
|
+
exclusion: startupMode ? 'startup_mode' : undefined,
|
|
265
|
+
managedOnly: managedOnlyPlugins,
|
|
266
|
+
engine,
|
|
267
|
+
shellHookEvents: shellEvents,
|
|
268
|
+
occupied,
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
if (d === undefined)
|
|
272
|
+
return planOf('failed', wireOf());
|
|
273
|
+
if (d.unreadable > 0) {
|
|
274
|
+
hostLog('debug', `hooksWireCaps: ${d.unreadable} plugin hook source(s) or group(s) unreadable — skipped`);
|
|
275
|
+
}
|
|
276
|
+
for (const [event, groups] of d.projected)
|
|
277
|
+
merged[event] = [...(merged[event] ?? []), ...groups];
|
|
278
|
+
return planOf('present', wireOf(), d.verdicts, d.excluded);
|
|
75
279
|
}
|
|
76
280
|
export function __resetHooksWireCapsForTests() {
|
|
77
281
|
__resetGoalStopHookForTests();
|
|
282
|
+
warnedNoMergedReader = new WeakSet();
|
|
283
|
+
warnedNoPluginReader = new WeakSet();
|
|
284
|
+
warnedNoPlanDrops = new WeakMap();
|
|
78
285
|
}
|
|
79
286
|
export function fleetHookFailureNoticeCapable(baseUrl) {
|
|
80
287
|
return engineCapNestedTrue(baseUrl, 'fleet', 'hookFailureNotice');
|
package/dist/host.d.ts
CHANGED
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
import type { AdapterLogLevel, TimerHandle } from './seam.js';
|
|
2
|
+
import type { WireHooksConfig } from './finalVerifyWire.js';
|
|
2
3
|
import { type NotificationQueuePort } from './notifications.js';
|
|
3
4
|
export type SettingsDocument = Record<string, unknown>;
|
|
4
5
|
export interface SettingsPort {
|
|
5
6
|
getSettingsForSource(source: string): SettingsDocument | null;
|
|
6
7
|
shouldSkipHookDueToTrust(hook?: unknown): boolean;
|
|
8
|
+
mergedDisableAllHooks?(): boolean | undefined;
|
|
9
|
+
enabledPluginHooks?(): PluginHooksReading;
|
|
10
|
+
}
|
|
11
|
+
export type PluginHookOptionValue = string | number | boolean;
|
|
12
|
+
export interface PluginHookSensitiveOption {
|
|
13
|
+
readonly sensitive: true;
|
|
14
|
+
}
|
|
15
|
+
export interface PluginHookPlainOption {
|
|
16
|
+
readonly sensitive: false;
|
|
17
|
+
readonly value?: PluginHookOptionValue;
|
|
18
|
+
}
|
|
19
|
+
export type PluginHookOption = PluginHookSensitiveOption | PluginHookPlainOption;
|
|
20
|
+
export interface PluginHookSource {
|
|
21
|
+
readonly id: string;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly root: string;
|
|
24
|
+
readonly dataDir: string;
|
|
25
|
+
readonly managed: boolean;
|
|
26
|
+
readonly options?: Readonly<Record<string, PluginHookOption>>;
|
|
27
|
+
readonly hooks: WireHooksConfig;
|
|
28
|
+
}
|
|
29
|
+
export interface PluginHooksReading {
|
|
30
|
+
readonly plugins: readonly PluginHookSource[];
|
|
31
|
+
readonly suppressedByStartupMode?: boolean;
|
|
7
32
|
}
|
|
8
33
|
export interface FsPort {
|
|
9
34
|
getScratchpadDir(): string | undefined;
|
package/dist/index.d.ts
CHANGED
|
@@ -56,6 +56,8 @@ export * from './modelCapabilityProbe.js';
|
|
|
56
56
|
export * from './classifierStatus.js';
|
|
57
57
|
export * from './engineToolLabelStore.js';
|
|
58
58
|
export * from './fleetTaskDesc.js';
|
|
59
|
+
export { displayUntrusted } from './displayUntrusted.js';
|
|
60
|
+
export type { DisplayUntrustedOptions, DisplayMark } from './displayUntrusted.js';
|
|
59
61
|
export type * from './types/engineState.js';
|
|
60
62
|
export * from './hostEnv.js';
|
|
61
63
|
export * from './unrefTimer.js';
|
|
@@ -135,6 +137,7 @@ export * from './detachWire.js';
|
|
|
135
137
|
export * from './workflowMonitor.js';
|
|
136
138
|
export * from './workflowClient.js';
|
|
137
139
|
export * from './hooksWireCaps.js';
|
|
140
|
+
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';
|
|
138
141
|
export * from './liveInitToolFace.js';
|
|
139
142
|
export * from './printInitToolFace.js';
|
|
140
143
|
export * from './model/providerPresets.js';
|
|
@@ -160,6 +163,7 @@ export * from './hitl/resumeRunningCard.js';
|
|
|
160
163
|
export * from './hitl/persistedRulesWire.js';
|
|
161
164
|
export * from './hitl/localAllowRule.js';
|
|
162
165
|
export * from './hitl/sessionPolicyWire.js';
|
|
166
|
+
export * from './hitl/sessionPolicyDeliverable.js';
|
|
163
167
|
export * from './hitl/approvalsFeed.js';
|
|
164
168
|
export * from './hitl/livePendingAsk.js';
|
|
165
169
|
export * from './hitl/crashConverged.js';
|
package/dist/index.js
CHANGED
|
@@ -56,6 +56,7 @@ export * from './modelCapabilityProbe.js';
|
|
|
56
56
|
export * from './classifierStatus.js';
|
|
57
57
|
export * from './engineToolLabelStore.js';
|
|
58
58
|
export * from './fleetTaskDesc.js';
|
|
59
|
+
export { displayUntrusted } from './displayUntrusted.js';
|
|
59
60
|
export * from './hostEnv.js';
|
|
60
61
|
export * from './unrefTimer.js';
|
|
61
62
|
export * from './controlRouter.js';
|
|
@@ -133,6 +134,7 @@ export * from './detachWire.js';
|
|
|
133
134
|
export * from './workflowMonitor.js';
|
|
134
135
|
export * from './workflowClient.js';
|
|
135
136
|
export * from './hooksWireCaps.js';
|
|
137
|
+
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';
|
|
136
138
|
export * from './liveInitToolFace.js';
|
|
137
139
|
export * from './printInitToolFace.js';
|
|
138
140
|
export * from './model/providerPresets.js';
|
|
@@ -158,6 +160,7 @@ export * from './hitl/resumeRunningCard.js';
|
|
|
158
160
|
export * from './hitl/persistedRulesWire.js';
|
|
159
161
|
export * from './hitl/localAllowRule.js';
|
|
160
162
|
export * from './hitl/sessionPolicyWire.js';
|
|
163
|
+
export * from './hitl/sessionPolicyDeliverable.js';
|
|
161
164
|
export * from './hitl/approvalsFeed.js';
|
|
162
165
|
export * from './hitl/livePendingAsk.js';
|
|
163
166
|
export * from './hitl/crashConverged.js';
|
|
@@ -15,7 +15,9 @@ export declare function probeScenarioTools(baseUrl: string, scenario: string, op
|
|
|
15
15
|
tools: string[];
|
|
16
16
|
toolset?: string;
|
|
17
17
|
} | null>;
|
|
18
|
-
export
|
|
18
|
+
export interface LiveInitToolFaceOptions {
|
|
19
19
|
fetchImpl?: typeof fetch;
|
|
20
20
|
timeoutMs?: number;
|
|
21
|
-
|
|
21
|
+
webSearchStamped?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare function resolveLiveInitToolFace(argv: readonly string[], env: EnvLike, opts?: LiveInitToolFaceOptions): Promise<LiveInitToolFace | null>;
|
package/dist/liveInitToolFace.js
CHANGED
|
@@ -2,7 +2,7 @@ import { makeEngineWireClient, resolveWireAuth } from './engineWireSdk.js';
|
|
|
2
2
|
import { hostLog } from './host.js';
|
|
3
3
|
import { scenarioForPrint } from './scenarioWire.js';
|
|
4
4
|
import { resolveHeadlessInteractiveTools } from './interactiveToolsWire.js';
|
|
5
|
-
import {
|
|
5
|
+
import { webSearchVerdictFromEnv } from './webSearchWireCaps.js';
|
|
6
6
|
export const ENGINE_HANDS_BAND = [
|
|
7
7
|
'Bash',
|
|
8
8
|
'Read',
|
|
@@ -105,7 +105,7 @@ export async function resolveLiveInitToolFace(argv, env, opts) {
|
|
|
105
105
|
}
|
|
106
106
|
let webSearch = false;
|
|
107
107
|
try {
|
|
108
|
-
webSearch =
|
|
108
|
+
webSearch = typeof opts?.webSearchStamped === 'boolean' ? opts.webSearchStamped : webSearchVerdictFromEnv(env).kind === 'honored';
|
|
109
109
|
}
|
|
110
110
|
catch {
|
|
111
111
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type EnvLike } from '../hostEnv.js';
|
|
2
|
-
import { type ModelCatalogResult
|
|
2
|
+
import { type ModelCatalogResult } from './catalog.js';
|
|
3
3
|
import type { ProviderPreset } from './providerPresets.js';
|
|
4
4
|
export declare const DEFAULT_CATALOG_SOURCES: readonly string[];
|
|
5
5
|
export declare const CATALOG_DEFAULT_HOSTS: readonly string[];
|
|
@@ -12,11 +12,6 @@ export interface CatalogSourceAttempt {
|
|
|
12
12
|
shaChecked?: boolean;
|
|
13
13
|
detail?: string;
|
|
14
14
|
}
|
|
15
|
-
export interface CatalogCacheEnvelope {
|
|
16
|
-
fetchedAt?: number;
|
|
17
|
-
sourceUrl: string;
|
|
18
|
-
catalog: OnlineCatalogDoc;
|
|
19
|
-
}
|
|
20
15
|
export interface CatalogCachePort {
|
|
21
16
|
read(path: string): string | null | Promise<string | null>;
|
|
22
17
|
writeAtomic(path: string, text: string): void | Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare function notePanelRowRunning(taskId: string): void;
|
|
2
2
|
export declare function retirePanelRowRunning(taskId: string): void;
|
|
3
|
-
|
|
3
|
+
interface PanelRowEndedIdentity {
|
|
4
4
|
cycleSeq?: number;
|
|
5
5
|
startedAt?: number;
|
|
6
6
|
}
|
|
@@ -11,7 +11,7 @@ export declare function holdNewbornTerminalRow(taskId: string, ev: object): void
|
|
|
11
11
|
export declare function peekHeldNewbornTerminalRow<T extends object>(taskId: string): T | undefined;
|
|
12
12
|
export declare function takeHeldNewbornTerminalRow<T extends object>(taskId: string): T | undefined;
|
|
13
13
|
export declare function dropHeldNewbornTerminalRow(taskId: string): void;
|
|
14
|
-
|
|
14
|
+
interface HeldNewbornTerminalRef {
|
|
15
15
|
readonly taskId: string;
|
|
16
16
|
readonly transcriptId?: string;
|
|
17
17
|
readonly parentToolCallId?: string;
|
|
@@ -19,3 +19,4 @@ export interface HeldNewbornTerminalRef {
|
|
|
19
19
|
export declare function heldNewbornTerminalRefs(): HeldNewbornTerminalRef[];
|
|
20
20
|
export declare function __resetPanelRunningHistoryForTests(): void;
|
|
21
21
|
export declare function __panelRunningHistorySize(): number;
|
|
22
|
+
export {};
|
package/dist/peerFrames.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export declare const AGENT_MESSAGE_TAG = "agent-message";
|
|
2
2
|
export declare const CROSS_SESSION_MESSAGE_TAG = "cross-session-message";
|
|
3
3
|
export declare const PEER_FRAME_LANES: readonly ["agent_message", "cross_session_message", "cross_session_notice"];
|
|
4
|
-
export type PeerFrameLane = (typeof PEER_FRAME_LANES)[number];
|
|
5
4
|
export declare const CROSS_SESSION_NOTICE_KINDS: readonly ["delivery_notice", "idle_notice"];
|
|
6
5
|
export type CrossSessionNoticeKind = (typeof CROSS_SESSION_NOTICE_KINDS)[number];
|
|
7
6
|
export declare const PEER_MODE_CLASSES: readonly ["bypass", "prompting"];
|
package/dist/peerFrames.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { applyDisplayFace, LEGACY_NAME_FACE } from './displayUntrusted.js';
|
|
1
2
|
const WIRE_KEY_FROM = 'from';
|
|
2
3
|
const WIRE_KEY_BODY = 'body';
|
|
3
4
|
const WIRE_KEY_KIND = 'kind';
|
|
@@ -124,7 +125,7 @@ function neutralizeAuthorityTags(text) {
|
|
|
124
125
|
function cleanName(v) {
|
|
125
126
|
if (typeof v !== 'string')
|
|
126
127
|
return undefined;
|
|
127
|
-
const t = v
|
|
128
|
+
const t = applyDisplayFace(v, LEGACY_NAME_FACE);
|
|
128
129
|
return t.length > 0 ? t : undefined;
|
|
129
130
|
}
|
|
130
131
|
function escapeEnvelopeTag(tag, text) {
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { WireHooksConfig } from './finalVerifyWire.js';
|
|
2
|
+
import type { PluginHookSource } from './host.js';
|
|
3
|
+
export declare const ENGINE_FIRED_HOOK_EVENTS: readonly ["PreToolUse", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "PreCompact", "PostCompact", "Stop", "StopFailure", "UserPromptSubmit"];
|
|
4
|
+
export type EngineFiredHookEvent = (typeof ENGINE_FIRED_HOOK_EVENTS)[number];
|
|
5
|
+
export declare const PLUGIN_HOOK_DISPOSITIONS: readonly ["engine", "shell", "not_run"];
|
|
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"];
|
|
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"];
|
|
10
|
+
export type PluginHookExclusionReason = (typeof PLUGIN_HOOK_EXCLUSION_REASONS)[number];
|
|
11
|
+
export declare const SETTINGS_HOOK_DROP_REASONS: readonly ["exec_form_unsupported", "mcp_tool_unsupported"];
|
|
12
|
+
export type SettingsHookDropReason = (typeof SETTINGS_HOOK_DROP_REASONS)[number];
|
|
13
|
+
export type HookSettingsSource = 'policySettings' | 'userSettings' | 'projectSettings' | 'localSettings';
|
|
14
|
+
export interface PluginHookKey {
|
|
15
|
+
readonly pluginId: string;
|
|
16
|
+
readonly pluginName: string;
|
|
17
|
+
readonly event: string;
|
|
18
|
+
readonly groupIndex: number;
|
|
19
|
+
readonly hookIndex: number;
|
|
20
|
+
}
|
|
21
|
+
export interface PluginHookVerdict extends PluginHookKey {
|
|
22
|
+
readonly disposition: PluginHookDisposition;
|
|
23
|
+
readonly reason: PluginHookReason;
|
|
24
|
+
}
|
|
25
|
+
export interface PluginHookExclusion extends PluginHookKey {
|
|
26
|
+
readonly reason: PluginHookExclusionReason;
|
|
27
|
+
}
|
|
28
|
+
export interface SettingsHookDrop {
|
|
29
|
+
readonly source: HookSettingsSource;
|
|
30
|
+
readonly event: string;
|
|
31
|
+
readonly groupIndex: number;
|
|
32
|
+
readonly hookIndex: number;
|
|
33
|
+
readonly reason: SettingsHookDropReason;
|
|
34
|
+
readonly notRun: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface HooksWireEngineFacts {
|
|
37
|
+
readonly ownedByThisShell: boolean | null;
|
|
38
|
+
readonly pluginHooksCapable: boolean | null;
|
|
39
|
+
}
|
|
40
|
+
export type PluginHookReaderState = 'present' | 'absent' | 'failed';
|
|
41
|
+
export interface HooksWirePlan {
|
|
42
|
+
readonly engine: HooksWireEngineFacts;
|
|
43
|
+
readonly pluginReader: PluginHookReaderState;
|
|
44
|
+
readonly verdicts: readonly PluginHookVerdict[];
|
|
45
|
+
readonly excluded: readonly PluginHookExclusion[];
|
|
46
|
+
readonly settingsDropped: readonly SettingsHookDrop[];
|
|
47
|
+
readonly wire: WireHooksConfig | undefined;
|
|
48
|
+
}
|
|
49
|
+
export interface HooksWirePlanOptions {
|
|
50
|
+
readonly baseUrl?: string;
|
|
51
|
+
readonly engineOwnedByThisShell?: boolean;
|
|
52
|
+
readonly shellHookEvents?: readonly string[];
|
|
53
|
+
}
|
|
54
|
+
export declare const ENGINE_HOOK_LIMITS: {
|
|
55
|
+
readonly maxGroupsPerEvent: 16;
|
|
56
|
+
readonly maxEntriesPerEvent: 32;
|
|
57
|
+
readonly maxCommandChars: 8192;
|
|
58
|
+
};
|
|
59
|
+
type WireHookGroup = NonNullable<WireHooksConfig[string]>[number];
|
|
60
|
+
export declare function isEngineFiredHookEvent(event: string): boolean;
|
|
61
|
+
export interface EventOccupancy {
|
|
62
|
+
readonly groups: number;
|
|
63
|
+
readonly entries: number;
|
|
64
|
+
}
|
|
65
|
+
export declare function occupancyOf(wire: WireHooksConfig): Map<string, EventOccupancy>;
|
|
66
|
+
export interface PluginHookDecisionInput {
|
|
67
|
+
readonly plugins: readonly PluginHookSource[];
|
|
68
|
+
readonly exclusion: PluginHookExclusionReason | undefined;
|
|
69
|
+
readonly managedOnly: boolean;
|
|
70
|
+
readonly engine: HooksWireEngineFacts;
|
|
71
|
+
readonly shellHookEvents: ReadonlySet<string>;
|
|
72
|
+
readonly occupied: ReadonlyMap<string, EventOccupancy>;
|
|
73
|
+
}
|
|
74
|
+
export interface PluginHookDecision {
|
|
75
|
+
readonly verdicts: readonly PluginHookVerdict[];
|
|
76
|
+
readonly excluded: readonly PluginHookExclusion[];
|
|
77
|
+
readonly projected: ReadonlyMap<string, readonly WireHookGroup[]>;
|
|
78
|
+
readonly unreadable: number;
|
|
79
|
+
}
|
|
80
|
+
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;
|
|
82
|
+
export interface SettingsHookFilterResult {
|
|
83
|
+
readonly groups: WireHookGroup[];
|
|
84
|
+
readonly drops: SettingsHookDrop[];
|
|
85
|
+
readonly stripped: number;
|
|
86
|
+
}
|
|
87
|
+
export declare function pluginHookVerdictOf(plan: HooksWirePlan, pluginId: string, event: string, groupIndex: number, hookIndex: number): PluginHookVerdict | undefined;
|
|
88
|
+
export declare function pluginHookReasonText(reason: PluginHookReason): string;
|
|
89
|
+
export declare function settingsHookDropText(reason: SettingsHookDropReason): string;
|
|
90
|
+
export declare function pluginHookExecutorLabel(v: PluginHookVerdict): string;
|
|
91
|
+
export declare function hooksNotRunNotice(plan: HooksWirePlan): readonly string[];
|
|
92
|
+
export {};
|