@gethelio/proxy 0.3.0 → 0.5.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.
- package/dist/cli.js +1967 -239
- package/dist/dashboard-assets/assets/index-DZKoV0Vx.css +1 -0
- package/dist/dashboard-assets/assets/{index-CAgnN6wV.js → index-DgywE2WQ.js} +30 -30
- package/dist/dashboard-assets/index.html +2 -2
- package/dist/index.d.ts +440 -11
- package/dist/index.js +1932 -237
- package/package.json +1 -1
- package/dist/dashboard-assets/assets/index-DG3h7Cvn.css +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,12 @@ declare const policiesSchema: z.ZodObject<{
|
|
|
36
36
|
regex: z.ZodOptional<z.ZodString>;
|
|
37
37
|
}, z.core.$strict>>>;
|
|
38
38
|
environment: z.ZodOptional<z.ZodString>;
|
|
39
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
40
|
+
eq: z.ZodOptional<z.ZodString>;
|
|
41
|
+
neq: z.ZodOptional<z.ZodString>;
|
|
42
|
+
contains: z.ZodOptional<z.ZodString>;
|
|
43
|
+
regex: z.ZodOptional<z.ZodString>;
|
|
44
|
+
}, z.core.$strict>]>>>;
|
|
39
45
|
}, z.core.$strict>;
|
|
40
46
|
action: z.ZodEnum<{
|
|
41
47
|
allow: "allow";
|
|
@@ -63,6 +69,7 @@ declare const policiesSchema: z.ZodObject<{
|
|
|
63
69
|
tool: "tool";
|
|
64
70
|
agent: "agent";
|
|
65
71
|
session: "session";
|
|
72
|
+
sender_id: "sender_id";
|
|
66
73
|
}>>;
|
|
67
74
|
max_spend: z.ZodOptional<z.ZodObject<{
|
|
68
75
|
field: z.ZodString;
|
|
@@ -73,6 +80,7 @@ declare const policiesSchema: z.ZodObject<{
|
|
|
73
80
|
tool: "tool";
|
|
74
81
|
agent: "agent";
|
|
75
82
|
session: "session";
|
|
83
|
+
sender_id: "sender_id";
|
|
76
84
|
}>>;
|
|
77
85
|
}, z.core.$strict>>;
|
|
78
86
|
}, z.core.$strict>>;
|
|
@@ -81,6 +89,38 @@ declare const policiesSchema: z.ZodObject<{
|
|
|
81
89
|
suggestion: z.ZodOptional<z.ZodString>;
|
|
82
90
|
}, z.core.$strict>>;
|
|
83
91
|
}, z.core.$strict>>>;
|
|
92
|
+
install: z.ZodOptional<z.ZodObject<{
|
|
93
|
+
default: z.ZodDefault<z.ZodEnum<{
|
|
94
|
+
allow: "allow";
|
|
95
|
+
deny: "deny";
|
|
96
|
+
}>>;
|
|
97
|
+
rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
98
|
+
name: z.ZodOptional<z.ZodString>;
|
|
99
|
+
match: z.ZodObject<{
|
|
100
|
+
name: z.ZodOptional<z.ZodString>;
|
|
101
|
+
source: z.ZodOptional<z.ZodString>;
|
|
102
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
103
|
+
eq: z.ZodOptional<z.ZodString>;
|
|
104
|
+
neq: z.ZodOptional<z.ZodString>;
|
|
105
|
+
contains: z.ZodOptional<z.ZodString>;
|
|
106
|
+
regex: z.ZodOptional<z.ZodString>;
|
|
107
|
+
}, z.core.$strict>]>>>;
|
|
108
|
+
}, z.core.$strict>;
|
|
109
|
+
action: z.ZodEnum<{
|
|
110
|
+
allow: "allow";
|
|
111
|
+
deny_install: "deny_install";
|
|
112
|
+
}>;
|
|
113
|
+
feedback: z.ZodOptional<z.ZodObject<{
|
|
114
|
+
message: z.ZodString;
|
|
115
|
+
suggestion: z.ZodOptional<z.ZodString>;
|
|
116
|
+
}, z.core.$strict>>;
|
|
117
|
+
}, z.core.$strict>>>;
|
|
118
|
+
}, z.core.$strict>>;
|
|
119
|
+
on_tool_drift: z.ZodOptional<z.ZodEnum<{
|
|
120
|
+
require_approval: "require_approval";
|
|
121
|
+
log: "log";
|
|
122
|
+
block: "block";
|
|
123
|
+
}>>;
|
|
84
124
|
hot_reload: z.ZodOptional<z.ZodBoolean>;
|
|
85
125
|
}, z.core.$strict>;
|
|
86
126
|
declare const approvalChannelSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
@@ -159,6 +199,12 @@ declare const helioConfigSchema: z.ZodObject<{
|
|
|
159
199
|
regex: z.ZodOptional<z.ZodString>;
|
|
160
200
|
}, z.core.$strict>>>;
|
|
161
201
|
environment: z.ZodOptional<z.ZodString>;
|
|
202
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
203
|
+
eq: z.ZodOptional<z.ZodString>;
|
|
204
|
+
neq: z.ZodOptional<z.ZodString>;
|
|
205
|
+
contains: z.ZodOptional<z.ZodString>;
|
|
206
|
+
regex: z.ZodOptional<z.ZodString>;
|
|
207
|
+
}, z.core.$strict>]>>>;
|
|
162
208
|
}, z.core.$strict>;
|
|
163
209
|
action: z.ZodEnum<{
|
|
164
210
|
allow: "allow";
|
|
@@ -186,6 +232,7 @@ declare const helioConfigSchema: z.ZodObject<{
|
|
|
186
232
|
tool: "tool";
|
|
187
233
|
agent: "agent";
|
|
188
234
|
session: "session";
|
|
235
|
+
sender_id: "sender_id";
|
|
189
236
|
}>>;
|
|
190
237
|
max_spend: z.ZodOptional<z.ZodObject<{
|
|
191
238
|
field: z.ZodString;
|
|
@@ -196,6 +243,7 @@ declare const helioConfigSchema: z.ZodObject<{
|
|
|
196
243
|
tool: "tool";
|
|
197
244
|
agent: "agent";
|
|
198
245
|
session: "session";
|
|
246
|
+
sender_id: "sender_id";
|
|
199
247
|
}>>;
|
|
200
248
|
}, z.core.$strict>>;
|
|
201
249
|
}, z.core.$strict>>;
|
|
@@ -204,6 +252,38 @@ declare const helioConfigSchema: z.ZodObject<{
|
|
|
204
252
|
suggestion: z.ZodOptional<z.ZodString>;
|
|
205
253
|
}, z.core.$strict>>;
|
|
206
254
|
}, z.core.$strict>>>;
|
|
255
|
+
install: z.ZodOptional<z.ZodObject<{
|
|
256
|
+
default: z.ZodDefault<z.ZodEnum<{
|
|
257
|
+
allow: "allow";
|
|
258
|
+
deny: "deny";
|
|
259
|
+
}>>;
|
|
260
|
+
rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
261
|
+
name: z.ZodOptional<z.ZodString>;
|
|
262
|
+
match: z.ZodObject<{
|
|
263
|
+
name: z.ZodOptional<z.ZodString>;
|
|
264
|
+
source: z.ZodOptional<z.ZodString>;
|
|
265
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
266
|
+
eq: z.ZodOptional<z.ZodString>;
|
|
267
|
+
neq: z.ZodOptional<z.ZodString>;
|
|
268
|
+
contains: z.ZodOptional<z.ZodString>;
|
|
269
|
+
regex: z.ZodOptional<z.ZodString>;
|
|
270
|
+
}, z.core.$strict>]>>>;
|
|
271
|
+
}, z.core.$strict>;
|
|
272
|
+
action: z.ZodEnum<{
|
|
273
|
+
allow: "allow";
|
|
274
|
+
deny_install: "deny_install";
|
|
275
|
+
}>;
|
|
276
|
+
feedback: z.ZodOptional<z.ZodObject<{
|
|
277
|
+
message: z.ZodString;
|
|
278
|
+
suggestion: z.ZodOptional<z.ZodString>;
|
|
279
|
+
}, z.core.$strict>>;
|
|
280
|
+
}, z.core.$strict>>>;
|
|
281
|
+
}, z.core.$strict>>;
|
|
282
|
+
on_tool_drift: z.ZodOptional<z.ZodEnum<{
|
|
283
|
+
require_approval: "require_approval";
|
|
284
|
+
log: "log";
|
|
285
|
+
block: "block";
|
|
286
|
+
}>>;
|
|
207
287
|
hot_reload: z.ZodOptional<z.ZodBoolean>;
|
|
208
288
|
}, z.core.$strict>>;
|
|
209
289
|
approval: z.ZodPrefault<z.ZodObject<{
|
|
@@ -240,6 +320,7 @@ declare const helioConfigSchema: z.ZodObject<{
|
|
|
240
320
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
241
321
|
port: z.ZodDefault<z.ZodNumber>;
|
|
242
322
|
host: z.ZodDefault<z.ZodString>;
|
|
323
|
+
evaluation_ttl: z.ZodDefault<z.ZodString>;
|
|
243
324
|
}, z.core.$strip>>;
|
|
244
325
|
}, z.core.$strip>;
|
|
245
326
|
/** Fully validated and defaulted Helio configuration. */
|
|
@@ -303,6 +384,22 @@ interface InputCondition {
|
|
|
303
384
|
/** Pre-compiled RegExp when operator is 'regex'. */
|
|
304
385
|
readonly regex?: RegExp;
|
|
305
386
|
}
|
|
387
|
+
/**
|
|
388
|
+
* A single flattened metadata condition (issue #13 — `match.metadata.*`).
|
|
389
|
+
*
|
|
390
|
+
* Mirrors InputCondition but matches a flat top-level key of the adapter-supplied
|
|
391
|
+
* context object (no JSONPath traversal), and is restricted to the string-friendly
|
|
392
|
+
* operator subset — metadata values (channel_id, sender_id, …) are strings, so the
|
|
393
|
+
* numeric comparators are deliberately excluded.
|
|
394
|
+
*/
|
|
395
|
+
interface MetadataCondition {
|
|
396
|
+
/** The metadata key to read (e.g. "channel_id", "sender_id", or virtual "agent_id"). */
|
|
397
|
+
readonly key: string;
|
|
398
|
+
readonly operator: 'eq' | 'neq' | 'contains' | 'regex';
|
|
399
|
+
readonly value: unknown;
|
|
400
|
+
/** Pre-compiled RegExp when operator is 'regex'. */
|
|
401
|
+
readonly regex?: RegExp;
|
|
402
|
+
}
|
|
306
403
|
/** Compiled match block for a policy rule. */
|
|
307
404
|
interface CompiledMatch {
|
|
308
405
|
readonly tool?: ToolMatcher;
|
|
@@ -310,6 +407,8 @@ interface CompiledMatch {
|
|
|
310
407
|
/** Flattened list of input conditions (one entry per path+operator pair). */
|
|
311
408
|
readonly input?: readonly InputCondition[];
|
|
312
409
|
readonly environment?: string;
|
|
410
|
+
/** Flattened list of metadata conditions (one entry per key+operator pair). */
|
|
411
|
+
readonly metadata?: readonly MetadataCondition[];
|
|
313
412
|
}
|
|
314
413
|
/** Compiled approval configuration with durations as milliseconds. */
|
|
315
414
|
interface CompiledApproval {
|
|
@@ -324,13 +423,13 @@ interface CompiledSpendLimit {
|
|
|
324
423
|
readonly limit: number;
|
|
325
424
|
readonly currency: string;
|
|
326
425
|
readonly windowMs: number;
|
|
327
|
-
readonly key?: 'tool' | 'agent' | 'session';
|
|
426
|
+
readonly key?: 'tool' | 'agent' | 'session' | 'sender_id';
|
|
328
427
|
}
|
|
329
428
|
/** Compiled rate/spend limit configuration. */
|
|
330
429
|
interface CompiledLimits {
|
|
331
430
|
readonly maxCalls?: number;
|
|
332
431
|
readonly windowMs?: number;
|
|
333
|
-
readonly key?: 'tool' | 'agent' | 'session';
|
|
432
|
+
readonly key?: 'tool' | 'agent' | 'session' | 'sender_id';
|
|
334
433
|
readonly maxSpend?: CompiledSpendLimit;
|
|
335
434
|
}
|
|
336
435
|
/** Policy action types. */
|
|
@@ -361,12 +460,44 @@ interface CompiledPolicyRule {
|
|
|
361
460
|
readonly suggestion?: string;
|
|
362
461
|
};
|
|
363
462
|
}
|
|
463
|
+
/** Compiled match block for an install-time rule (issue #13). */
|
|
464
|
+
interface CompiledInstallMatch {
|
|
465
|
+
/** Glob matcher on the package name. */
|
|
466
|
+
readonly name?: ToolMatcher;
|
|
467
|
+
/** Exact ecosystem/source match (npm | pip | …). */
|
|
468
|
+
readonly source?: string;
|
|
469
|
+
/** Flattened metadata conditions (sender/channel-gated installs). */
|
|
470
|
+
readonly metadata?: readonly MetadataCondition[];
|
|
471
|
+
}
|
|
472
|
+
/** A compiled install-time rule. */
|
|
473
|
+
interface CompiledInstallRule {
|
|
474
|
+
readonly index: number;
|
|
475
|
+
readonly name?: string;
|
|
476
|
+
readonly match: CompiledInstallMatch;
|
|
477
|
+
readonly action: 'deny_install' | 'allow';
|
|
478
|
+
readonly feedback?: {
|
|
479
|
+
readonly message: string;
|
|
480
|
+
readonly suggestion?: string;
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
/** Compiled install-time policy (issue #13). */
|
|
484
|
+
interface CompiledInstallPolicy {
|
|
485
|
+
readonly defaultAction: 'allow' | 'deny';
|
|
486
|
+
readonly rules: readonly CompiledInstallRule[];
|
|
487
|
+
}
|
|
364
488
|
/** Top-level compiled policy — what the engine consumes. */
|
|
365
489
|
interface CompiledPolicy {
|
|
366
490
|
readonly defaultAction: 'allow' | 'deny';
|
|
367
491
|
readonly flagDestructive?: 'log' | 'require_approval';
|
|
368
492
|
readonly dryRun?: boolean;
|
|
493
|
+
/**
|
|
494
|
+
* Response to tool definition drift (issue #25). Undefined means "block"
|
|
495
|
+
* at the use site — conservative by default.
|
|
496
|
+
*/
|
|
497
|
+
readonly onToolDrift?: 'block' | 'require_approval' | 'log';
|
|
369
498
|
readonly rules: readonly CompiledPolicyRule[];
|
|
499
|
+
/** Install-time policy (issue #13 — deny_install). Undefined ⇒ observational. */
|
|
500
|
+
readonly install?: CompiledInstallPolicy;
|
|
370
501
|
}
|
|
371
502
|
/** A non-fatal warning produced during policy compilation. */
|
|
372
503
|
interface PolicyParseWarning {
|
|
@@ -406,6 +537,13 @@ interface MatchContext {
|
|
|
406
537
|
readonly toolArguments?: Readonly<Record<string, unknown>>;
|
|
407
538
|
/** The configured environment label (e.g. "production", "staging"). */
|
|
408
539
|
readonly environment?: string;
|
|
540
|
+
/**
|
|
541
|
+
* Adapter-supplied context for `match.metadata.*` (issue #13). Present only on
|
|
542
|
+
* the sideband (host-enforced) path; always absent on the MCP path, so metadata
|
|
543
|
+
* rules are inert there by construction. The virtual `agent_id` key (from the
|
|
544
|
+
* request column) is merged in by the decision pipeline, not stored here twice.
|
|
545
|
+
*/
|
|
546
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
409
547
|
}
|
|
410
548
|
|
|
411
549
|
/** A JSON-RPC 2.0 request object. */
|
|
@@ -722,6 +860,27 @@ interface AuditRecord {
|
|
|
722
860
|
readonly flagged_destructive: boolean;
|
|
723
861
|
/** Whether this record was produced in dry-run mode. */
|
|
724
862
|
readonly dry_run: boolean;
|
|
863
|
+
/**
|
|
864
|
+
* Record category discriminator (issues #12/#16). `'tool_call'` is the
|
|
865
|
+
* default for governed tool calls; `'drift_event'` for tool-definition drift
|
|
866
|
+
* records; `'install_scan'` for sideband install evaluations; and
|
|
867
|
+
* `'evaluation_expired'` for sideband evaluations whose `/audit` never
|
|
868
|
+
* arrived (the bypass/tamper signal — block_reason stays null so they do not
|
|
869
|
+
* count as enforcement blocks).
|
|
870
|
+
*/
|
|
871
|
+
readonly record_kind: 'tool_call' | 'drift_event' | 'install_scan' | 'evaluation_expired';
|
|
872
|
+
/**
|
|
873
|
+
* Enforcement origin: `'mcp'` for the proxy path, or an adapter-supplied
|
|
874
|
+
* origin string (e.g. `'openclaw'`) for sideband-governed calls. Surfaces
|
|
875
|
+
* the enforcement-grade ladder (structural vs host-enforced) per record.
|
|
876
|
+
*/
|
|
877
|
+
readonly origin: string;
|
|
878
|
+
/**
|
|
879
|
+
* Adapter-supplied context object (reserved keys: `channel_id`, `sender_id`,
|
|
880
|
+
* `sender_name`, `conversation_id`). Null for MCP-origin records. Backs
|
|
881
|
+
* `match.metadata.*` (#13) and the dashboard metadata columns (#16).
|
|
882
|
+
*/
|
|
883
|
+
readonly metadata: Record<string, unknown> | null;
|
|
725
884
|
/** ISO 8601 timestamp of when the record was persisted. */
|
|
726
885
|
readonly created_at: string;
|
|
727
886
|
}
|
|
@@ -747,6 +906,14 @@ interface AuditQueryFilters {
|
|
|
747
906
|
readonly flagged_destructive?: boolean;
|
|
748
907
|
/** Include only dry-run records (true) or non-dry-run records (false). */
|
|
749
908
|
readonly dry_run?: boolean;
|
|
909
|
+
/** Filter by record kind (tool_call / drift_event / install_scan / evaluation_expired). */
|
|
910
|
+
readonly record_kind?: string;
|
|
911
|
+
/** Filter by enforcement origin (e.g. 'mcp', 'openclaw'). */
|
|
912
|
+
readonly origin?: string;
|
|
913
|
+
/** Filter by metadata.channel_id (adapter-supplied; JSON-extracted, substring match). */
|
|
914
|
+
readonly channel_id?: string;
|
|
915
|
+
/** Filter by metadata.sender_id (adapter-supplied; JSON-extracted, substring match). */
|
|
916
|
+
readonly sender_id?: string;
|
|
750
917
|
/** Include only records where upstream HTTP status is >= this value. */
|
|
751
918
|
readonly upstream_status_min?: number;
|
|
752
919
|
/** Include only records where upstream HTTP status is <= this value. */
|
|
@@ -917,7 +1084,7 @@ declare class AuditWriter {
|
|
|
917
1084
|
* is scheduled. This keeps request-path latency bounded even under bursty
|
|
918
1085
|
* write load.
|
|
919
1086
|
*/
|
|
920
|
-
push(record: Omit<AuditRecord, 'id' | 'created_at'
|
|
1087
|
+
push(record: Omit<AuditRecord, 'id' | 'created_at'>, id?: string): void;
|
|
921
1088
|
/**
|
|
922
1089
|
* Push a record and schedule a high-priority async flush.
|
|
923
1090
|
*
|
|
@@ -926,7 +1093,7 @@ declare class AuditWriter {
|
|
|
926
1093
|
* A fatal-process crash still invokes the crash-drain hook, which calls
|
|
927
1094
|
* `flush()` synchronously before exit.
|
|
928
1095
|
*/
|
|
929
|
-
pushImmediate(record: Omit<AuditRecord, 'id' | 'created_at'
|
|
1096
|
+
pushImmediate(record: Omit<AuditRecord, 'id' | 'created_at'>, id?: string): void;
|
|
930
1097
|
/**
|
|
931
1098
|
* Schedule a flush on the next tick, coalescing multiple calls into one.
|
|
932
1099
|
*/
|
|
@@ -1110,7 +1277,14 @@ declare class EvidenceStore {
|
|
|
1110
1277
|
}
|
|
1111
1278
|
|
|
1112
1279
|
/** Possible states of an approval ticket. */
|
|
1113
|
-
type ApprovalStatus = 'pending' | 'approved' | 'denied' | 'timeout' | 'break_glass' | 'client_disconnected' | 'shutdown_cancelled'
|
|
1280
|
+
type ApprovalStatus = 'pending' | 'approved' | 'denied' | 'timeout' | 'break_glass' | 'client_disconnected' | 'shutdown_cancelled'
|
|
1281
|
+
/**
|
|
1282
|
+
* The approver's native UI cancelled the request (e.g. an OpenClaw
|
|
1283
|
+
* `/approve` dialog dismissed without a decision). Distinct from
|
|
1284
|
+
* `client_disconnected`, which the router reserves for the requesting agent
|
|
1285
|
+
* aborting the held MCP request. Sideband (native) approvals only. (#12.)
|
|
1286
|
+
*/
|
|
1287
|
+
| 'cancelled';
|
|
1114
1288
|
/** A failed attempt to deliver an approval notification. */
|
|
1115
1289
|
interface ApprovalNotificationFailure {
|
|
1116
1290
|
readonly channel: string;
|
|
@@ -1233,7 +1407,7 @@ declare class ApprovalQueue {
|
|
|
1233
1407
|
* @returns `true` if the ticket was resolved, `false` if not found or
|
|
1234
1408
|
* already resolved (no double-resolution).
|
|
1235
1409
|
*/
|
|
1236
|
-
resolve(id: string, status: 'approved' | 'denied' | 'timeout' | 'break_glass' | 'client_disconnected' | 'shutdown_cancelled', resolvedBy?: string, options?: {
|
|
1410
|
+
resolve(id: string, status: 'approved' | 'denied' | 'timeout' | 'break_glass' | 'client_disconnected' | 'shutdown_cancelled' | 'cancelled', resolvedBy?: string, options?: {
|
|
1237
1411
|
denial_reason?: string;
|
|
1238
1412
|
break_glass_reason?: string;
|
|
1239
1413
|
}): boolean;
|
|
@@ -1276,6 +1450,19 @@ interface ApprovalSubmitParams {
|
|
|
1276
1450
|
readonly matched_rule: CompiledPolicyRule | undefined;
|
|
1277
1451
|
readonly session_id: string | null;
|
|
1278
1452
|
}
|
|
1453
|
+
/** Resolution statuses a native (sideband) ticket can be moved to. */
|
|
1454
|
+
type NativeResolution = 'approved' | 'denied' | 'timeout' | 'cancelled';
|
|
1455
|
+
/** Parameters for creating a native (adapter-owned) approval ticket. */
|
|
1456
|
+
interface NativeTicketParams {
|
|
1457
|
+
readonly tool_name: string;
|
|
1458
|
+
readonly tool_input: Record<string, unknown>;
|
|
1459
|
+
readonly matched_rule: CompiledPolicyRule | undefined;
|
|
1460
|
+
readonly session_id: string | null;
|
|
1461
|
+
/** Adapter origin (e.g. "openclaw"); stored as channel_name `native:<origin>`. */
|
|
1462
|
+
readonly origin: string;
|
|
1463
|
+
/** Ticket timeout in ms (rule timeout, else the router default). */
|
|
1464
|
+
readonly timeout_ms?: number;
|
|
1465
|
+
}
|
|
1279
1466
|
declare class ApprovalRouter {
|
|
1280
1467
|
private readonly defaultTimeoutMs;
|
|
1281
1468
|
readonly defaultOnTimeout: 'allow' | 'deny';
|
|
@@ -1296,6 +1483,36 @@ declare class ApprovalRouter {
|
|
|
1296
1483
|
* is held open.
|
|
1297
1484
|
*/
|
|
1298
1485
|
submit(params: ApprovalSubmitParams, abortSignal?: AbortSignal): Promise<ApprovalOutcome>;
|
|
1486
|
+
/**
|
|
1487
|
+
* Create a native (adapter-owned) approval ticket without holding a Promise.
|
|
1488
|
+
*
|
|
1489
|
+
* Used by the sideband governance path (issue #12, D10): when `/evaluate`
|
|
1490
|
+
* yields `require_approval`, the adapter runs the approval in its own UI
|
|
1491
|
+
* (e.g. OpenClaw's Telegram dialog), so Helio must NOT block, start
|
|
1492
|
+
* timeout/escalation timers, or notify a channel — doing so would
|
|
1493
|
+
* double-notify. We still create the queue ticket and fire `onSubmit` so the
|
|
1494
|
+
* dashboard's `approval_requested` SSE event flows and the ticket is visible.
|
|
1495
|
+
*
|
|
1496
|
+
* The ticket's `channel_name` is `native:<origin>`, which marks it as
|
|
1497
|
+
* adapter-owned: the dashboard approve/deny endpoints refuse it (it can only
|
|
1498
|
+
* be resolved through the adapter), and {@link resolveNativeTicket} is the
|
|
1499
|
+
* resolution path.
|
|
1500
|
+
*/
|
|
1501
|
+
createNativeTicket(params: NativeTicketParams): ApprovalTicket;
|
|
1502
|
+
/**
|
|
1503
|
+
* Resolve a native ticket created by {@link createNativeTicket}.
|
|
1504
|
+
*
|
|
1505
|
+
* Resolves the queue ticket and fires `onResolve` (→ `approval_resolved`
|
|
1506
|
+
* SSE), with no held Promise to settle. Refuses tickets that have a pending
|
|
1507
|
+
* router Promise (those are MCP-path tickets; resolving them here would leave
|
|
1508
|
+
* the held request hanging) and tickets that are not `native:`-prefixed.
|
|
1509
|
+
*
|
|
1510
|
+
* @returns `true` if resolved, `false` if not found, already resolved, not a
|
|
1511
|
+
* native ticket, or router-managed.
|
|
1512
|
+
*/
|
|
1513
|
+
resolveNativeTicket(ticketId: string, status: NativeResolution, resolvedBy?: string, options?: {
|
|
1514
|
+
denial_reason?: string;
|
|
1515
|
+
}): boolean;
|
|
1299
1516
|
/**
|
|
1300
1517
|
* Approve a pending ticket. Resolves the held Promise so the governed
|
|
1301
1518
|
* forwarder can forward the request upstream.
|
|
@@ -1320,6 +1537,8 @@ declare class ApprovalRouter {
|
|
|
1320
1537
|
* already resolved.
|
|
1321
1538
|
*/
|
|
1322
1539
|
breakGlass(ticketId: string, resolvedBy: string, reason: string): boolean;
|
|
1540
|
+
/** Look up a ticket by id (delegates to the queue). */
|
|
1541
|
+
getTicket(ticketId: string): ApprovalTicket | undefined;
|
|
1323
1542
|
/** Clean up all pending timers and resolve all pending promises. */
|
|
1324
1543
|
close(): void;
|
|
1325
1544
|
private finalizePending;
|
|
@@ -1390,6 +1609,21 @@ declare class RateLimiter {
|
|
|
1390
1609
|
* - At/over limit: does NOT record (blocked calls don't consume a slot)
|
|
1391
1610
|
*/
|
|
1392
1611
|
check(params: RateLimitCheckParams): RateLimitResult;
|
|
1612
|
+
/**
|
|
1613
|
+
* Unconditionally record a call against the rate limit.
|
|
1614
|
+
*
|
|
1615
|
+
* Unlike check(), this always appends the timestamp — even when the bucket
|
|
1616
|
+
* is already at/over the limit — because the call it represents has already
|
|
1617
|
+
* executed. The sideband splits decision from execution: /evaluate peeks
|
|
1618
|
+
* (non-destructive), and /audit calls record() once the external call ran,
|
|
1619
|
+
* so refusing to record at the limit (as check() does) would let real calls
|
|
1620
|
+
* escape accounting and under-count subsequent peeks. (issue #12, D3.)
|
|
1621
|
+
*
|
|
1622
|
+
* Warnings fire only while the post-append count stays within the limit —
|
|
1623
|
+
* exact parity with check(), which never warns on its over-limit path — so a
|
|
1624
|
+
* burst of over-limit audits cannot flood the dashboard's limit_warning feed.
|
|
1625
|
+
*/
|
|
1626
|
+
record(params: RateLimitCheckParams): RateLimitResult;
|
|
1393
1627
|
/**
|
|
1394
1628
|
* Check the rate limit without recording the call (non-destructive).
|
|
1395
1629
|
*
|
|
@@ -1499,6 +1733,20 @@ declare class SpendLimiter {
|
|
|
1499
1733
|
* - Would exceed: does NOT record (rejected spends don't consume budget)
|
|
1500
1734
|
*/
|
|
1501
1735
|
check(params: SpendLimitCheckParams): SpendLimitResult;
|
|
1736
|
+
/**
|
|
1737
|
+
* Unconditionally record a spend against the limit.
|
|
1738
|
+
*
|
|
1739
|
+
* Unlike check(), this always appends the amount — even when it pushes the
|
|
1740
|
+
* window past the limit — because the spend it represents has already been
|
|
1741
|
+
* incurred. The sideband peeks at /evaluate and commits here at /audit once
|
|
1742
|
+
* the external call ran (issue #12, D3).
|
|
1743
|
+
*
|
|
1744
|
+
* Throws on a negative or non-finite amount: such amounts are rejected at
|
|
1745
|
+
* /evaluate, so one reaching record() is a logic bug we surface loudly rather
|
|
1746
|
+
* than silently corrupt the sliding-window sum. Warnings fire only while the
|
|
1747
|
+
* post-append spend stays within the limit (parity with check()).
|
|
1748
|
+
*/
|
|
1749
|
+
record(params: SpendLimitCheckParams): SpendLimitResult;
|
|
1502
1750
|
/**
|
|
1503
1751
|
* Check the spend limit without recording the spend (non-destructive).
|
|
1504
1752
|
*
|
|
@@ -1587,6 +1835,7 @@ declare class GovernedForwarder implements McpForwarder {
|
|
|
1587
1835
|
private readonly spendLimiter;
|
|
1588
1836
|
private readonly annotationCache;
|
|
1589
1837
|
private agentKeyWarned;
|
|
1838
|
+
private senderKeyWarned;
|
|
1590
1839
|
constructor(inner: McpForwarder, policy: CompiledPolicy, options?: GovernedForwarderOptions);
|
|
1591
1840
|
/**
|
|
1592
1841
|
* Swap the compiled policy atomically and reconcile limit bucket state
|
|
@@ -1617,6 +1866,15 @@ declare class GovernedForwarder implements McpForwarder {
|
|
|
1617
1866
|
*/
|
|
1618
1867
|
primeAnnotationCache(): Promise<AnnotationCachePrimeResult>;
|
|
1619
1868
|
forward(request: McpRequest): Promise<ForwardResult>;
|
|
1869
|
+
/**
|
|
1870
|
+
* Apply a tools/list response to the definition cache and surface any
|
|
1871
|
+
* drift: console warning + immediate audit record per event. Single entry
|
|
1872
|
+
* point for both runtime tools/list responses and startup priming, so the
|
|
1873
|
+
* cache is updated exactly once per response.
|
|
1874
|
+
*/
|
|
1875
|
+
private applyToolDefinitionUpdate;
|
|
1876
|
+
/** Write an immediate audit record for a drift event (not a tool call). */
|
|
1877
|
+
private writeDriftAuditRecord;
|
|
1620
1878
|
private handleToolsCall;
|
|
1621
1879
|
private handleApproval;
|
|
1622
1880
|
private handleRateLimit;
|
|
@@ -1631,6 +1889,7 @@ declare class GovernedForwarder implements McpForwarder {
|
|
|
1631
1889
|
/** Determine if the request was actually forwarded to the upstream MCP server. */
|
|
1632
1890
|
private wasForwardedUpstream;
|
|
1633
1891
|
private writeAuditRecord;
|
|
1892
|
+
private makeDriftBlockResult;
|
|
1634
1893
|
private makeDenyResult;
|
|
1635
1894
|
private makePolicyMisconfiguredResult;
|
|
1636
1895
|
private makeUnsupportedResult;
|
|
@@ -1640,15 +1899,169 @@ declare class GovernedForwarder implements McpForwarder {
|
|
|
1640
1899
|
private makeClientDisconnectedBlockResult;
|
|
1641
1900
|
}
|
|
1642
1901
|
|
|
1902
|
+
/** The outcome vocabulary adapters branch on — never internal rule actions. */
|
|
1903
|
+
type WireDecision = 'allow' | 'deny' | 'require_approval' | 'rate_limited' | 'spend_limited' | 'dry_run';
|
|
1904
|
+
/** Tool definition carried by /evaluate (optional; enables the drift guard). */
|
|
1905
|
+
interface WireToolDefinition {
|
|
1906
|
+
readonly name: string;
|
|
1907
|
+
readonly description?: string;
|
|
1908
|
+
readonly input_schema?: unknown;
|
|
1909
|
+
readonly output_schema?: unknown;
|
|
1910
|
+
readonly title?: string;
|
|
1911
|
+
readonly annotations?: Record<string, unknown>;
|
|
1912
|
+
}
|
|
1913
|
+
interface EvaluateInput {
|
|
1914
|
+
readonly origin: string;
|
|
1915
|
+
readonly adapter_version?: string;
|
|
1916
|
+
readonly agent_id: string | null;
|
|
1917
|
+
readonly session_id: string | null;
|
|
1918
|
+
readonly tool: WireToolDefinition;
|
|
1919
|
+
readonly arguments: Record<string, unknown> | undefined;
|
|
1920
|
+
readonly metadata: Record<string, unknown> | null;
|
|
1921
|
+
}
|
|
1922
|
+
interface InstallScanInput {
|
|
1923
|
+
readonly origin: string;
|
|
1924
|
+
readonly agent_id: string | null;
|
|
1925
|
+
readonly session_id: string | null;
|
|
1926
|
+
readonly package: {
|
|
1927
|
+
readonly name: string;
|
|
1928
|
+
readonly version?: string;
|
|
1929
|
+
readonly source?: string;
|
|
1930
|
+
readonly spec?: string;
|
|
1931
|
+
readonly url?: string;
|
|
1932
|
+
};
|
|
1933
|
+
readonly metadata: Record<string, unknown> | null;
|
|
1934
|
+
}
|
|
1935
|
+
interface AuditInput {
|
|
1936
|
+
readonly evaluation_id: string;
|
|
1937
|
+
readonly status: 'success' | 'error' | 'not_executed';
|
|
1938
|
+
readonly error?: string;
|
|
1939
|
+
readonly duration_ms?: number;
|
|
1940
|
+
readonly result?: unknown;
|
|
1941
|
+
readonly actual_amount?: number;
|
|
1942
|
+
}
|
|
1943
|
+
interface ResolveApprovalInput {
|
|
1944
|
+
readonly resolution: 'approved' | 'denied' | 'timeout' | 'cancelled';
|
|
1945
|
+
readonly resolved_by?: string;
|
|
1946
|
+
readonly reason?: string;
|
|
1947
|
+
readonly scope?: 'once' | 'always';
|
|
1948
|
+
}
|
|
1949
|
+
/** A service result: HTTP status + JSON body, adapted verbatim by the route. */
|
|
1950
|
+
interface ServiceResult {
|
|
1951
|
+
readonly status: number;
|
|
1952
|
+
readonly body: Record<string, unknown>;
|
|
1953
|
+
}
|
|
1954
|
+
interface GovernanceServiceOptions {
|
|
1955
|
+
readonly policy: CompiledPolicy;
|
|
1956
|
+
readonly environment?: string;
|
|
1957
|
+
readonly evidenceStore?: EvidenceStore;
|
|
1958
|
+
readonly approvalRouter?: ApprovalRouter;
|
|
1959
|
+
readonly rateLimiter?: RateLimiter;
|
|
1960
|
+
readonly spendLimiter?: SpendLimiter;
|
|
1961
|
+
readonly auditWriter?: AuditWriter;
|
|
1962
|
+
/** Default approval timeout (ms) when a rule sets none. */
|
|
1963
|
+
readonly approvalTimeoutMs?: number;
|
|
1964
|
+
/** Pending-evaluation TTL (ms). Default 10 minutes. */
|
|
1965
|
+
readonly ttlMs?: number;
|
|
1966
|
+
/** Clock for testable time. Defaults to Date.now. */
|
|
1967
|
+
readonly now?: () => number;
|
|
1968
|
+
/** Sweep interval (ms). 0 disables the periodic GC backstop. Default 30s. */
|
|
1969
|
+
readonly sweepIntervalMs?: number;
|
|
1970
|
+
/** Max pending evaluations (count). Default 10,000. Overridable for tests. */
|
|
1971
|
+
readonly maxPending?: number;
|
|
1972
|
+
/** Max pending-evaluation footprint (serialized bytes). Default 64 MiB. */
|
|
1973
|
+
readonly maxPendingBytes?: number;
|
|
1974
|
+
/** Max distinct sender_id limit keys (issue #13). Default 50,000. Overridable for tests. */
|
|
1975
|
+
readonly maxSenderKeys?: number;
|
|
1976
|
+
}
|
|
1977
|
+
declare class GovernanceService {
|
|
1978
|
+
private policy;
|
|
1979
|
+
private readonly environment;
|
|
1980
|
+
private readonly evidenceStore;
|
|
1981
|
+
private readonly approvalRouter;
|
|
1982
|
+
private readonly rateLimiter;
|
|
1983
|
+
private readonly spendLimiter;
|
|
1984
|
+
private readonly auditWriter;
|
|
1985
|
+
private readonly approvalTimeoutMs;
|
|
1986
|
+
private readonly ttlMs;
|
|
1987
|
+
private readonly now;
|
|
1988
|
+
private readonly maxPending;
|
|
1989
|
+
private readonly maxPendingBytes;
|
|
1990
|
+
private readonly maxSenderKeys;
|
|
1991
|
+
/** Distinct sender_id limit keys with live state (reservation registry, issue #13). */
|
|
1992
|
+
private readonly senderKeys;
|
|
1993
|
+
private readonly pending;
|
|
1994
|
+
private readonly tombstones;
|
|
1995
|
+
private readonly caches;
|
|
1996
|
+
/** Native approval ticket id → its pending evaluation id, for on-access
|
|
1997
|
+
* deadline enforcement on the resolve path. */
|
|
1998
|
+
private readonly ticketToEvaluation;
|
|
1999
|
+
private pendingBytes;
|
|
2000
|
+
private sweepTimer;
|
|
2001
|
+
private closed;
|
|
2002
|
+
constructor(options: GovernanceServiceOptions);
|
|
2003
|
+
/** Swap the compiled policy on hot-reload (mirrors GovernedForwarder). */
|
|
2004
|
+
updatePolicy(policy: CompiledPolicy): void;
|
|
2005
|
+
evaluate(req: EvaluateInput): ServiceResult;
|
|
2006
|
+
audit(req: AuditInput, payloadHash: string): ServiceResult;
|
|
2007
|
+
installScan(req: InstallScanInput): ServiceResult;
|
|
2008
|
+
/** First-match-wins evaluation of the compiled install policy (issue #13). */
|
|
2009
|
+
private evaluateInstall;
|
|
2010
|
+
resolveApproval(ticketId: string, req: ResolveApprovalInput): ServiceResult;
|
|
2011
|
+
sweep(): void;
|
|
2012
|
+
/**
|
|
2013
|
+
* Reserve a cardinality slot for a sender-keyed limit (issue #13).
|
|
2014
|
+
*
|
|
2015
|
+
* Only `sender:*` keys are gated — tool/session families are bounded by upstream
|
|
2016
|
+
* cardinality, and the MCP path never reaches here, so structural traffic cannot
|
|
2017
|
+
* be starved. A key already backed by live state (registry or a live limiter
|
|
2018
|
+
* bucket) costs no new slot. At capacity we lazily prune dead keys before failing
|
|
2019
|
+
* closed, so an emptied bucket frees its slot without waiting for the sweep.
|
|
2020
|
+
*/
|
|
2021
|
+
private reserveSenderKey;
|
|
2022
|
+
/** Drop registry keys with no pending evaluation AND no live limiter bucket. */
|
|
2023
|
+
private pruneSenderKeys;
|
|
2024
|
+
/**
|
|
2025
|
+
* Whether either limiter still holds a live bucket for `key`. Uses the public
|
|
2026
|
+
* `getKeyState()` — never the limiters' private maps — and its lazy eviction of
|
|
2027
|
+
* an emptied bucket IS the prune-on-touch mechanism.
|
|
2028
|
+
*/
|
|
2029
|
+
private hasLiveBucket;
|
|
2030
|
+
close(): void;
|
|
2031
|
+
/** Apply crossed deadlines to one pending entry. Returns its post-state. */
|
|
2032
|
+
private enforceDeadlines;
|
|
2033
|
+
private cacheFor;
|
|
2034
|
+
private discardPending;
|
|
2035
|
+
private getTicketStatus;
|
|
2036
|
+
private planRate;
|
|
2037
|
+
private planSpend;
|
|
2038
|
+
/** Commit a limit plan at /audit time and return the evidence_chain block. */
|
|
2039
|
+
private commitLimit;
|
|
2040
|
+
private writeAudit;
|
|
2041
|
+
private assertApprovalRouter;
|
|
2042
|
+
}
|
|
2043
|
+
|
|
1643
2044
|
/** Options for constructing the SDK sideband Hono app. */
|
|
1644
2045
|
interface SidebandAppOptions {
|
|
1645
2046
|
/**
|
|
1646
|
-
* Bearer token
|
|
1647
|
-
*
|
|
1648
|
-
*
|
|
1649
|
-
* explicitly disabled the per-boot token via env.
|
|
2047
|
+
* Bearer token for the evidence/context/session routes (the SDK scope).
|
|
2048
|
+
* When omitted or empty, those routes run open — useful for local
|
|
2049
|
+
* development when the operator has disabled the per-boot token via env.
|
|
1650
2050
|
*/
|
|
1651
2051
|
readonly token?: string;
|
|
2052
|
+
/**
|
|
2053
|
+
* Bearer token for the governance routes (the adapter scope, issue #12/F6).
|
|
2054
|
+
* Distinct from `token` so an SDK client cannot drive policy decisions and
|
|
2055
|
+
* an adapter cannot write evidence it was not granted. When omitted, the
|
|
2056
|
+
* governance routes run open (and only mount if `governance` is provided).
|
|
2057
|
+
*/
|
|
2058
|
+
readonly adapterToken?: string;
|
|
2059
|
+
/**
|
|
2060
|
+
* The governance service backing `/evaluate`, `/audit`, `/install-scan`, and
|
|
2061
|
+
* `/approval/:id/resolve`. When omitted, those routes return 503
|
|
2062
|
+
* `governance_unavailable` (evidence-only deployments, and existing tests).
|
|
2063
|
+
*/
|
|
2064
|
+
readonly governance?: GovernanceService;
|
|
1652
2065
|
}
|
|
1653
2066
|
/**
|
|
1654
2067
|
* Create a Hono app for the SDK sideband API.
|
|
@@ -1673,6 +2086,20 @@ interface SidebandAppOptions {
|
|
|
1673
2086
|
*/
|
|
1674
2087
|
declare function createSidebandApp(store: EvidenceStore, options?: SidebandAppOptions): Hono;
|
|
1675
2088
|
|
|
2089
|
+
/**
|
|
2090
|
+
* Error thrown when the GovernanceService is wired in a way that could fail
|
|
2091
|
+
* open — for example, an approval-capable policy with no ApprovalRouter to
|
|
2092
|
+
* route `require_approval` decisions through (issue #12). Surfaced at
|
|
2093
|
+
* construction and on hot-reload so a misconfiguration crashes loudly rather
|
|
2094
|
+
* than silently degrading an approval into an unenforced allow.
|
|
2095
|
+
*
|
|
2096
|
+
* Direct embedders of GovernanceService can catch this distinctly; the bundled
|
|
2097
|
+
* CLI always provides a router, so it never fires in the shipped path.
|
|
2098
|
+
*/
|
|
2099
|
+
declare class GovernanceConfigError extends Error {
|
|
2100
|
+
constructor(message: string);
|
|
2101
|
+
}
|
|
2102
|
+
|
|
1676
2103
|
/** @internal Exported for testing only. */
|
|
1677
2104
|
declare class QueueChannel implements ApprovalChannel {
|
|
1678
2105
|
readonly type = "dashboard";
|
|
@@ -1809,6 +2236,8 @@ interface ActionEvent {
|
|
|
1809
2236
|
readonly dry_run: boolean;
|
|
1810
2237
|
readonly matched_rule: string | null;
|
|
1811
2238
|
readonly matched_rule_index: number | null;
|
|
2239
|
+
readonly record_kind: AuditRecord['record_kind'];
|
|
2240
|
+
readonly origin: string;
|
|
1812
2241
|
}
|
|
1813
2242
|
/** Payload for an approval_requested event. */
|
|
1814
2243
|
interface ApprovalRequestedEvent {
|
|
@@ -1903,4 +2332,4 @@ interface DashboardAppOptions {
|
|
|
1903
2332
|
*/
|
|
1904
2333
|
declare function createDashboardApp(deps: DashboardAppDeps, options?: DashboardAppOptions): Hono;
|
|
1905
2334
|
|
|
1906
|
-
export { type ApprovalAppOptions, type ApprovalChannel, type ApprovalOutcome, ApprovalQueue, type ApprovalQueueOptions, ApprovalRouter, type ApprovalRouterOptions, type ApprovalStatus, type ApprovalTicket, type AuditAggregateStats, type AuditListResult, type AuditPaginationOptions, type AuditQueryFilters, type AuditRecord, AuditStore, type AuditStoreOptions, type AuditTimeBucket, AuditWriter, type AuditWriterOptions, type CompilePoliciesResult, type CompiledPolicy, type CompiledPolicyRule, ConfigError, type CreateAppOptions, type DashboardAppDeps, type DashboardAppOptions, DashboardEventBus, type DashboardEventType, type DashboardEvents, type EvidenceEntry, EvidenceStore, type EvidenceStoreOptions, GovernedForwarder, type GovernedForwarderOptions, type HelioConfig, type MatchContext, type PolicyDecision, PolicyParseError, QueueChannel, type RateLimitCheckParams, type RateLimitKeyState, type RateLimitResult, RateLimiter, type RateLimiterOptions, type ServerHandle, type SessionState, type SlackActionAppOptions, SlackChannel, type SlackChannelOptions, type SpendLimitCheckParams, type SpendLimitKeyState, type SpendLimitResult, SpendLimiter, type SpendLimiterOptions, SseUpstreamForwarder, type SseUpstreamForwarderOptions, StdioForwarder, type StdioForwarderOptions, StreamableHttpForwarder, type StreamableHttpForwarderOptions, UpstreamForwarder, type UpstreamForwarderOptions, VERSION, WebhookChannel, type WebhookChannelOptions, compilePolicies, createApp, createApprovalApp, createChannels, createDashboardApp, createSidebandApp, createSlackActionApp, evaluatePolicy, loadConfig, matchRule, startServer, startSidebandServer };
|
|
2335
|
+
export { type ApprovalAppOptions, type ApprovalChannel, type ApprovalOutcome, ApprovalQueue, type ApprovalQueueOptions, ApprovalRouter, type ApprovalRouterOptions, type ApprovalStatus, type ApprovalTicket, type AuditAggregateStats, type AuditInput, type AuditListResult, type AuditPaginationOptions, type AuditQueryFilters, type AuditRecord, AuditStore, type AuditStoreOptions, type AuditTimeBucket, AuditWriter, type AuditWriterOptions, type CompilePoliciesResult, type CompiledPolicy, type CompiledPolicyRule, ConfigError, type CreateAppOptions, type DashboardAppDeps, type DashboardAppOptions, DashboardEventBus, type DashboardEventType, type DashboardEvents, type EvaluateInput, type EvidenceEntry, EvidenceStore, type EvidenceStoreOptions, GovernanceConfigError, GovernanceService, type GovernanceServiceOptions, GovernedForwarder, type GovernedForwarderOptions, type HelioConfig, type InstallScanInput, type MatchContext, type PolicyDecision, PolicyParseError, QueueChannel, type RateLimitCheckParams, type RateLimitKeyState, type RateLimitResult, RateLimiter, type RateLimiterOptions, type ResolveApprovalInput, type ServerHandle, type SessionState, type SlackActionAppOptions, SlackChannel, type SlackChannelOptions, type SpendLimitCheckParams, type SpendLimitKeyState, type SpendLimitResult, SpendLimiter, type SpendLimiterOptions, SseUpstreamForwarder, type SseUpstreamForwarderOptions, StdioForwarder, type StdioForwarderOptions, StreamableHttpForwarder, type StreamableHttpForwarderOptions, UpstreamForwarder, type UpstreamForwarderOptions, VERSION, WebhookChannel, type WebhookChannelOptions, type WireDecision, compilePolicies, createApp, createApprovalApp, createChannels, createDashboardApp, createSidebandApp, createSlackActionApp, evaluatePolicy, loadConfig, matchRule, startServer, startSidebandServer };
|