@stratusagent/permissions 0.14.1 → 0.14.3
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/LICENSE +202 -21
- package/NOTICE +5 -0
- package/dist/index.d.ts +37 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +298 -29
- package/dist/index.js.map +1 -1
- package/dist/review.d.ts +148 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/review.js +511 -0
- package/dist/review.js.map +1 -0
- package/package.json +6 -5
package/dist/review.js
ADDED
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
import { analyzeCommand, commandScopeFromPrefix, matchesScope, } from "./commands.js";
|
|
2
|
+
import { analyzeCompound } from "./compound.js";
|
|
3
|
+
import { normalizeTrustedDomain, originScopeFor, trustedDomainOf } from "./origins.js";
|
|
4
|
+
const VERDICTS = ['allow', 'ask', 'block'];
|
|
5
|
+
const RULE_KEYS = new Set(['tool', 'command', 'origin', 'destination', 'verdict']);
|
|
6
|
+
const MATCHERS = ['command', 'origin', 'destination'];
|
|
7
|
+
/** `mcp.stripe.refund`, or `mcp.stripe.*`. A bare `*` would be a posture, not a rule. */
|
|
8
|
+
const TOOL_PATTERN = /^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)*(?:\.\*)?$/;
|
|
9
|
+
/**
|
|
10
|
+
* The words of a rule that asks or blocks: the base command and the
|
|
11
|
+
* subcommands after it. Looser than an allow scope on purpose, since a
|
|
12
|
+
* rule that refuses `git push` must also refuse `git push --force`.
|
|
13
|
+
*/
|
|
14
|
+
const commandWords = (raw) => {
|
|
15
|
+
if (/['"]/.test(raw)) {
|
|
16
|
+
return { reason: 'it contains quotes; write the command as plain words' };
|
|
17
|
+
}
|
|
18
|
+
const analysis = analyzeCommand(raw.trim());
|
|
19
|
+
if (analysis.pipeline) {
|
|
20
|
+
return { reason: 'it is a pipeline; write one command' };
|
|
21
|
+
}
|
|
22
|
+
if (analysis.disqualifiedBy || analysis.base === undefined) {
|
|
23
|
+
return { reason: analysis.disqualifiedBy ?? 'it could not be read as a command' };
|
|
24
|
+
}
|
|
25
|
+
const args = analysis.tokens.slice(1);
|
|
26
|
+
if (args.some((token) => token.startsWith('-'))) {
|
|
27
|
+
return { reason: 'it names a flag; write the command and its subcommands only' };
|
|
28
|
+
}
|
|
29
|
+
return { scope: { command: analysis.base, ...(args.length > 0 ? { args } : {}) } };
|
|
30
|
+
};
|
|
31
|
+
/** The domain an `https://*.<domain>` origin names, or undefined for any other spelling. */
|
|
32
|
+
const wildcardDomain = (origin) => {
|
|
33
|
+
const match = /^https:\/\/\*\.([^/:]+)$/i.exec(origin.trim());
|
|
34
|
+
return match ? normalizeTrustedDomain(match[1]) : undefined;
|
|
35
|
+
};
|
|
36
|
+
const DESTINATION_PATTERN = /^[a-z][a-z0-9-]*:\S+$/;
|
|
37
|
+
/**
|
|
38
|
+
* Reads one rule from config, or says why it can't. Refused rather than
|
|
39
|
+
* dropped, like the rest of `approvals`: a rule an operator wrote and the
|
|
40
|
+
* daemon skipped would leave them believing a block is in place.
|
|
41
|
+
*/
|
|
42
|
+
export const parseReviewRule = (raw) => {
|
|
43
|
+
if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
|
|
44
|
+
return { reason: 'expected an object like { "tool": "shell.run", "command": "git push", "verdict": "allow" }' };
|
|
45
|
+
}
|
|
46
|
+
const source = raw;
|
|
47
|
+
const unknownKey = Object.keys(source).find((key) => !RULE_KEYS.has(key));
|
|
48
|
+
if (unknownKey !== undefined) {
|
|
49
|
+
return { reason: `unknown key "${unknownKey}"; a rule has tool, verdict and at most one of command, origin or destination` };
|
|
50
|
+
}
|
|
51
|
+
if (typeof source.tool !== 'string' || source.tool.length === 0) {
|
|
52
|
+
return { reason: 'it needs a tool: an exact name, or a prefix ending in .* (mcp.stripe.*)' };
|
|
53
|
+
}
|
|
54
|
+
if (!TOOL_PATTERN.test(source.tool)) {
|
|
55
|
+
return { reason: `tool "${source.tool}" is neither an exact name nor a prefix ending in .*` };
|
|
56
|
+
}
|
|
57
|
+
if (typeof source.verdict !== 'string' || !VERDICTS.includes(source.verdict)) {
|
|
58
|
+
return { reason: 'it needs a verdict: allow, ask or block' };
|
|
59
|
+
}
|
|
60
|
+
const verdict = source.verdict;
|
|
61
|
+
const named = MATCHERS.filter((key) => source[key] !== undefined);
|
|
62
|
+
if (named.length > 1) {
|
|
63
|
+
return { reason: `it names ${named.join(' and ')}; a rule takes at most one of command, origin or destination` };
|
|
64
|
+
}
|
|
65
|
+
const rule = { tool: source.tool, verdict };
|
|
66
|
+
const matcher = named[0];
|
|
67
|
+
if (matcher === undefined) {
|
|
68
|
+
return { rule };
|
|
69
|
+
}
|
|
70
|
+
const value = source[matcher];
|
|
71
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
72
|
+
return { reason: `${matcher} must be a non-empty string` };
|
|
73
|
+
}
|
|
74
|
+
if (matcher === 'command') {
|
|
75
|
+
const scope = verdict === 'allow' ? commandScopeFromPrefix(value) : commandWords(value);
|
|
76
|
+
if ('reason' in scope) {
|
|
77
|
+
return { reason: `command "${value}": ${scope.reason}` };
|
|
78
|
+
}
|
|
79
|
+
return { rule: { ...rule, command: value.trim() } };
|
|
80
|
+
}
|
|
81
|
+
if (matcher === 'origin') {
|
|
82
|
+
// A `*` anywhere but a leading `https://*.` is a typo, not a pattern,
|
|
83
|
+
// even where the URL parser would take it as part of a host name.
|
|
84
|
+
const exact = value.includes('*') ? undefined : originScopeFor(value.trim());
|
|
85
|
+
if (wildcardDomain(value) === undefined && (exact === undefined || exact.origin !== value.trim().replace(/\/$/, ''))) {
|
|
86
|
+
return { reason: `origin "${value}" is not an origin like https://app.example.com or https://*.example.com` };
|
|
87
|
+
}
|
|
88
|
+
return { rule: { ...rule, origin: value.trim().replace(/\/$/, '') } };
|
|
89
|
+
}
|
|
90
|
+
if (!DESTINATION_PATTERN.test(value.trim())) {
|
|
91
|
+
return { reason: `destination "${value}" is not a destination like slack:C0123 or slack:*` };
|
|
92
|
+
}
|
|
93
|
+
return { rule: { ...rule, destination: value.trim() } };
|
|
94
|
+
};
|
|
95
|
+
const toolMatches = (pattern, toolName) => pattern.endsWith('.*') ? toolName.startsWith(pattern.slice(0, -1)) : pattern === toolName;
|
|
96
|
+
const commandRuleMatches = (rule, command) => {
|
|
97
|
+
if (rule.verdict === 'allow') {
|
|
98
|
+
// All of it, through the same engine as an approved scope, and no
|
|
99
|
+
// redirection: a line that also writes somewhere is more than the rule
|
|
100
|
+
// says yes to.
|
|
101
|
+
const parsed = commandScopeFromPrefix(rule.command);
|
|
102
|
+
if ('reason' in parsed) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
const compound = analyzeCompound(command);
|
|
106
|
+
if (compound.disqualifiedBy) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
const stages = compound.pipelines.flat();
|
|
110
|
+
return stages.length > 0
|
|
111
|
+
&& stages.every((stage) => stage.redirects.length === 0 && matchesScope(stage.analysis, parsed.scope));
|
|
112
|
+
}
|
|
113
|
+
// Any of it, for a rule that asks or blocks, and the words anywhere in
|
|
114
|
+
// the line as a backstop for one this reader can't split (`bash -c "…"`).
|
|
115
|
+
const words = commandWords(rule.command);
|
|
116
|
+
if ('reason' in words) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
const args = words.scope.args ?? [];
|
|
120
|
+
if (stagesOf(command).some((stage) => stageMatchesRule(stage, words.scope.command, args))) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
// Other words of the same command may sit between the program and each
|
|
124
|
+
// of the rule's words (`git -C repo push`, `git --no-pager push`), never
|
|
125
|
+
// a separator that starts another command.
|
|
126
|
+
const sequence = [words.scope.command, ...(words.scope.args ?? [])]
|
|
127
|
+
.map((word) => word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
|
|
128
|
+
.join('(?:\\s+[^\\s;&|()]+)*?\\s+');
|
|
129
|
+
// A program called by its path (`/usr/bin/git push`) is one the reader
|
|
130
|
+
// above refuses, so the backstop takes a path in front of the name.
|
|
131
|
+
return new RegExp(`(?:^|[\\s;&|("'\`])(?:[^\\s;&|()"'\`<>]*/)?${sequence}(?=$|[\\s;&|)"'\`])`).test(command);
|
|
132
|
+
};
|
|
133
|
+
const originRuleMatches = (pattern, origin) => {
|
|
134
|
+
const domain = wildcardDomain(pattern);
|
|
135
|
+
if (domain !== undefined) {
|
|
136
|
+
return trustedDomainOf(origin, [domain]) !== undefined;
|
|
137
|
+
}
|
|
138
|
+
return originScopeFor(pattern)?.origin === origin;
|
|
139
|
+
};
|
|
140
|
+
const destinationRuleMatches = (pattern, destination) => pattern.endsWith(':*')
|
|
141
|
+
? destination.startsWith(pattern.slice(0, -1)) && destination.length > pattern.length - 1
|
|
142
|
+
: pattern === destination;
|
|
143
|
+
/**
|
|
144
|
+
* The first rule that matches this call, or undefined. A rule naming a
|
|
145
|
+
* matcher matches only a call that names that thing: a `command` rule
|
|
146
|
+
* never matches a tool that runs no command.
|
|
147
|
+
*/
|
|
148
|
+
export const matchReviewRule = (rules, call) => rules.find((rule) => {
|
|
149
|
+
if (!toolMatches(rule.tool, call.toolName)) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
if (rule.command !== undefined) {
|
|
153
|
+
return call.command !== undefined && commandRuleMatches(rule, call.command);
|
|
154
|
+
}
|
|
155
|
+
if (rule.origin !== undefined) {
|
|
156
|
+
return call.origin !== undefined && originRuleMatches(rule.origin, call.origin);
|
|
157
|
+
}
|
|
158
|
+
if (rule.destination !== undefined) {
|
|
159
|
+
return call.destination !== undefined && destinationRuleMatches(rule.destination, call.destination);
|
|
160
|
+
}
|
|
161
|
+
return true;
|
|
162
|
+
});
|
|
163
|
+
/** How a rule reads in a reason: its tool and matcher, never the call's input. */
|
|
164
|
+
export const describeReviewRule = (rule) => `${rule.tool}${rule.command !== undefined ? ` command "${rule.command}"` : ''}${rule.origin !== undefined ? ` origin ${rule.origin}` : ''}${rule.destination !== undefined ? ` destination ${rule.destination}` : ''}: ${rule.verdict}`;
|
|
165
|
+
/**
|
|
166
|
+
* The whole address or host, with nothing of a longer name on either side:
|
|
167
|
+
* `169.254.169.254.example.com` is somebody else's site.
|
|
168
|
+
*/
|
|
169
|
+
const METADATA_ADDRESSES = /(?<![A-Za-z0-9.-])(?:169\.254\.169\.254|metadata\.google\.internal)\.?(?![A-Za-z0-9.-])|(?<![0-9A-Fa-f:])fd00:ec2::254(?![0-9A-Fa-f:])/i;
|
|
170
|
+
/** Token shapes long enough to be a credential rather than a mention of its prefix. */
|
|
171
|
+
const TOKEN_SHAPES = [
|
|
172
|
+
/\bxox[abposr]-[0-9A-Za-z-]{10,}/,
|
|
173
|
+
/\bxapp-[0-9A-Za-z-]{10,}/,
|
|
174
|
+
/\bghp_[0-9A-Za-z]{20,}/,
|
|
175
|
+
/\bgithub_pat_[0-9A-Za-z_]{20,}/,
|
|
176
|
+
/\bsk-ant-[0-9A-Za-z_-]{10,}/,
|
|
177
|
+
/\bAKIA[0-9A-Z]{16}\b/,
|
|
178
|
+
];
|
|
179
|
+
/** A stored value shorter than this is too likely to occur by chance to block on. */
|
|
180
|
+
const MIN_SECRET_LENGTH = 8;
|
|
181
|
+
/** Programs that reach the network, for a shell command that sends outside. */
|
|
182
|
+
const NETWORK_CLIENTS = new Set([
|
|
183
|
+
'curl', 'wget', 'nc', 'ncat', 'netcat', 'socat', 'telnet', 'ssh', 'scp', 'sftp', 'rsync', 'ftp',
|
|
184
|
+
'http', 'https', 'xh', 'aria2c', 'gh',
|
|
185
|
+
]);
|
|
186
|
+
/** What a download may be piped into and run. */
|
|
187
|
+
const INTERPRETERS = new Set([
|
|
188
|
+
'sh', 'bash', 'zsh', 'dash', 'ksh', 'fish', 'python', 'python3', 'perl', 'ruby', 'node', 'bun', 'deno',
|
|
189
|
+
]);
|
|
190
|
+
const DOWNLOADERS = new Set(['curl', 'wget']);
|
|
191
|
+
/**
|
|
192
|
+
* Programs that run another program named among their arguments
|
|
193
|
+
* (`sudo -u root sh`, `env -i bash`, `xargs sh`). Only their names: any
|
|
194
|
+
* later word naming an interpreter or a downloader counts, so an option no
|
|
195
|
+
* list could keep up with (`sudo -R / sh`) can't hide one.
|
|
196
|
+
*/
|
|
197
|
+
const WRAPPER_NAMES = new Set([
|
|
198
|
+
'sudo', 'doas', 'su', 'runuser', 'env', 'command', 'builtin', 'exec', 'nohup', 'nice', 'ionice', 'time',
|
|
199
|
+
'timeout', 'stdbuf', 'setsid', 'xargs', 'chroot', 'taskset', 'unbuffer', 'busybox', 'parallel',
|
|
200
|
+
]);
|
|
201
|
+
const ASSIGNMENT = /^[A-Za-z_][A-Za-z0-9_]*=/;
|
|
202
|
+
const strings = (value, out = []) => {
|
|
203
|
+
if (typeof value === 'string') {
|
|
204
|
+
out.push(value);
|
|
205
|
+
}
|
|
206
|
+
else if (Array.isArray(value)) {
|
|
207
|
+
for (const item of value) {
|
|
208
|
+
strings(item, out);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else if (value !== null && typeof value === 'object') {
|
|
212
|
+
for (const item of Object.values(value)) {
|
|
213
|
+
strings(item, out);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return out;
|
|
217
|
+
};
|
|
218
|
+
const baseName = (word) => word.split('/').pop() ?? word;
|
|
219
|
+
/**
|
|
220
|
+
* Whether one stage of a pipeline runs one of `programs`: as its program
|
|
221
|
+
* (past leading assignments, by name or path), or anywhere after a wrapper.
|
|
222
|
+
*/
|
|
223
|
+
const stageRuns = (words, programs) => {
|
|
224
|
+
const start = words.findIndex((word) => !ASSIGNMENT.test(word));
|
|
225
|
+
if (start < 0) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
const program = baseName(words[start]);
|
|
229
|
+
return programs.has(program)
|
|
230
|
+
|| (WRAPPER_NAMES.has(program) && words.slice(start + 1).some((word) => programs.has(baseName(word))));
|
|
231
|
+
};
|
|
232
|
+
const sendsOutside = (call) => {
|
|
233
|
+
if (call.toolName === 'message.send' || call.toolName === 'web.fetch'
|
|
234
|
+
|| call.toolName.startsWith('browser.') || call.toolName.startsWith('mcp.')) {
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
if (call.command === undefined) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
// Any word that names a client, not only the program a wrapper runs: a
|
|
241
|
+
// wrapper option no table lists (`sudo -R / curl`), a client fed by
|
|
242
|
+
// another stage (`| xargs curl`) or called by a quoted path can't hide
|
|
243
|
+
// one. Coarse on purpose, since this only decides whether a token in the
|
|
244
|
+
// call is being sent out.
|
|
245
|
+
return stagesOf(call.command).some((stage) => stage.some((word) => NETWORK_CLIENTS.has(baseName(word))));
|
|
246
|
+
};
|
|
247
|
+
/**
|
|
248
|
+
* A shell line split roughly: pipelines of stages of words, with quotes
|
|
249
|
+
* kept together and removed and separators counted only outside quotes.
|
|
250
|
+
* No expansions. For a line the analyzer refuses, and for a word that holds
|
|
251
|
+
* a command itself.
|
|
252
|
+
*/
|
|
253
|
+
const roughPipelines = (text) => {
|
|
254
|
+
const pipelines = [];
|
|
255
|
+
let stages = [];
|
|
256
|
+
let words = [];
|
|
257
|
+
let word = '';
|
|
258
|
+
let started = false;
|
|
259
|
+
// `'`, `"`, or `$'` for ANSI-C quoting, whose backslash escapes decode.
|
|
260
|
+
let quote;
|
|
261
|
+
const endWord = () => {
|
|
262
|
+
if (started) {
|
|
263
|
+
words.push(word);
|
|
264
|
+
}
|
|
265
|
+
word = '';
|
|
266
|
+
started = false;
|
|
267
|
+
};
|
|
268
|
+
const endStage = () => {
|
|
269
|
+
endWord();
|
|
270
|
+
if (words.length > 0) {
|
|
271
|
+
stages.push(words);
|
|
272
|
+
}
|
|
273
|
+
words = [];
|
|
274
|
+
};
|
|
275
|
+
const endPipeline = () => {
|
|
276
|
+
endStage();
|
|
277
|
+
if (stages.length > 0) {
|
|
278
|
+
pipelines.push(stages);
|
|
279
|
+
}
|
|
280
|
+
stages = [];
|
|
281
|
+
};
|
|
282
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
283
|
+
const char = text[index];
|
|
284
|
+
if (quote !== undefined) {
|
|
285
|
+
if (char === (quote === "$'" ? "'" : quote)) {
|
|
286
|
+
quote = undefined;
|
|
287
|
+
}
|
|
288
|
+
else if (char === '\\' && quote === "$'" && index + 1 < text.length) {
|
|
289
|
+
const escape = /^(?:x([0-9A-Fa-f]{1,2})|u([0-9A-Fa-f]{1,4})|U([0-9A-Fa-f]{1,8})|([0-7]{1,3})|(.))/s.exec(text.slice(index + 1));
|
|
290
|
+
const [whole = '', hex, u4, u8, octal, other] = escape ?? [];
|
|
291
|
+
const code = hex ?? u4 ?? u8;
|
|
292
|
+
word += code !== undefined
|
|
293
|
+
? String.fromCodePoint(Number.parseInt(code, 16) % 0x110000)
|
|
294
|
+
: octal !== undefined
|
|
295
|
+
? String.fromCharCode(Number.parseInt(octal, 8))
|
|
296
|
+
: { n: '\n', t: '\t', r: '\r', a: '\u0007', b: '\b', e: '\u001b', E: '\u001b', f: '\f', v: '\v' }[other ?? ''] ?? other ?? '';
|
|
297
|
+
index += whole.length;
|
|
298
|
+
}
|
|
299
|
+
else if (char === '\\' && quote === '"' && index + 1 < text.length) {
|
|
300
|
+
index += 1;
|
|
301
|
+
word += text[index];
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
word += char;
|
|
305
|
+
}
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
if (char === '"' || char === "'") {
|
|
309
|
+
quote = char;
|
|
310
|
+
started = true;
|
|
311
|
+
}
|
|
312
|
+
else if (char === '$' && (text[index + 1] === "'" || text[index + 1] === '"')) {
|
|
313
|
+
// `$'…'` (ANSI-C) and `$"…"` (locale) quoting: the shell drops the `$`.
|
|
314
|
+
index += 1;
|
|
315
|
+
quote = text[index] === "'" ? "$'" : '"';
|
|
316
|
+
started = true;
|
|
317
|
+
}
|
|
318
|
+
else if (char === '\\' && index + 1 < text.length) {
|
|
319
|
+
index += 1;
|
|
320
|
+
word += text[index];
|
|
321
|
+
started = true;
|
|
322
|
+
}
|
|
323
|
+
else if (char === '\n' || char === ';') {
|
|
324
|
+
endPipeline();
|
|
325
|
+
}
|
|
326
|
+
else if (/\s/.test(char)) {
|
|
327
|
+
endWord();
|
|
328
|
+
}
|
|
329
|
+
else if (char === '&') {
|
|
330
|
+
if (text[index + 1] === '&') {
|
|
331
|
+
index += 1;
|
|
332
|
+
}
|
|
333
|
+
endPipeline();
|
|
334
|
+
}
|
|
335
|
+
else if (char === '|') {
|
|
336
|
+
if (text[index + 1] === '|') {
|
|
337
|
+
index += 1;
|
|
338
|
+
endPipeline();
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
if (text[index + 1] === '&') {
|
|
342
|
+
index += 1;
|
|
343
|
+
}
|
|
344
|
+
endStage();
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
else if ('()`<>'.includes(char)) {
|
|
348
|
+
endWord();
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
word += char;
|
|
352
|
+
started = true;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
endPipeline();
|
|
356
|
+
return pipelines;
|
|
357
|
+
};
|
|
358
|
+
/**
|
|
359
|
+
* Each pipeline as its stages' words: the analyzer's when it reads the
|
|
360
|
+
* line, a rough split when it refuses it (a program called by its path is
|
|
361
|
+
* one), plus, one level down, the pipelines of any word that holds a
|
|
362
|
+
* command itself (`bash -c "git push"`). Coarse on purpose: these only
|
|
363
|
+
* decide whether a rule that asks or blocks applies.
|
|
364
|
+
*/
|
|
365
|
+
const pipelinesOf = (command) => {
|
|
366
|
+
const compound = analyzeCompound(command);
|
|
367
|
+
// The analyzer reads `$'git'` as the word `$git`; the shell runs `git`.
|
|
368
|
+
const top = compound.disqualifiedBy || /\$['"]/.test(command)
|
|
369
|
+
? roughPipelines(command)
|
|
370
|
+
: compound.pipelines.map((pipeline) => pipeline.map((stage) => [...stage.analysis.tokens]));
|
|
371
|
+
const nested = top.flat(2).filter((word) => /[\s;&|]/.test(word)).flatMap((word) => roughPipelines(word));
|
|
372
|
+
return [...top, ...nested];
|
|
373
|
+
};
|
|
374
|
+
const stagesOf = (command) => pipelinesOf(command).flat();
|
|
375
|
+
/** Whether `needle` appears in `words` in order, other words allowed between. */
|
|
376
|
+
const inOrder = (needle, words) => {
|
|
377
|
+
let found = 0;
|
|
378
|
+
for (const word of words) {
|
|
379
|
+
if (found < needle.length && word === needle[found]) {
|
|
380
|
+
found += 1;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return found === needle.length;
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* Whether a stage runs a rule's program (by name or path, as its program
|
|
387
|
+
* or after a wrapper) with the rule's words after it, in order: `git -C
|
|
388
|
+
* repo push` is a `git push`.
|
|
389
|
+
*/
|
|
390
|
+
const stageMatchesRule = (stage, program, args) => {
|
|
391
|
+
const start = stage.findIndex((word) => !ASSIGNMENT.test(word));
|
|
392
|
+
if (start < 0) {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
const first = baseName(stage[start]);
|
|
396
|
+
const at = first === program
|
|
397
|
+
? [start]
|
|
398
|
+
: WRAPPER_NAMES.has(first)
|
|
399
|
+
? stage.flatMap((word, index) => (index > start && baseName(word) === program ? [index] : []))
|
|
400
|
+
: [];
|
|
401
|
+
return at.some((index) => inOrder(args, stage.slice(index + 1)));
|
|
402
|
+
};
|
|
403
|
+
/**
|
|
404
|
+
* Whether a stage runs one of `programs` itself, or in a command one of its
|
|
405
|
+
* words holds (`sh -c "curl …" | sh` downloads in its first stage).
|
|
406
|
+
*/
|
|
407
|
+
const stageRunsDeep = (words, programs) => stageRuns(words, programs)
|
|
408
|
+
|| words.some((word) => /[\s;&|]/.test(word) && roughPipelines(word).flat().some((inner) => stageRuns(inner, programs)));
|
|
409
|
+
const pipesDownloadIntoInterpreter = (command) => pipelinesOf(command).some((pipeline) => {
|
|
410
|
+
const first = pipeline.findIndex((words) => stageRunsDeep(words, DOWNLOADERS));
|
|
411
|
+
return first >= 0 && pipeline.slice(first + 1).some((words) => stageRunsDeep(words, INTERPRETERS));
|
|
412
|
+
});
|
|
413
|
+
/**
|
|
414
|
+
* The built-in rules, in order: a cloud metadata address blocks, a token
|
|
415
|
+
* or stored credential in a call that sends outside blocks, and a
|
|
416
|
+
* download piped into an interpreter asks. `secrets` are the stored
|
|
417
|
+
* credential values the agent can use; one is matched exactly.
|
|
418
|
+
*/
|
|
419
|
+
export const builtInReviewRule = (call, secrets) => {
|
|
420
|
+
const values = strings(call.input);
|
|
421
|
+
if (values.some((value) => METADATA_ADDRESSES.test(value))) {
|
|
422
|
+
return {
|
|
423
|
+
rule: 'metadata-address',
|
|
424
|
+
verdict: 'block',
|
|
425
|
+
reason: `${call.toolName} names a cloud metadata address, which the built-in review rules block`,
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
if (sendsOutside(call)) {
|
|
429
|
+
const known = secrets.filter((secret) => secret.length >= MIN_SECRET_LENGTH);
|
|
430
|
+
if (values.some((value) => TOKEN_SHAPES.some((shape) => shape.test(value)) || known.some((secret) => value.includes(secret)))) {
|
|
431
|
+
return {
|
|
432
|
+
rule: 'sends-secret',
|
|
433
|
+
verdict: 'block',
|
|
434
|
+
reason: `${call.toolName} would send what looks like a credential or token outside, which the built-in review rules block`,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
if (call.command !== undefined && pipesDownloadIntoInterpreter(call.command)) {
|
|
439
|
+
return {
|
|
440
|
+
rule: 'pipe-to-shell',
|
|
441
|
+
verdict: 'ask',
|
|
442
|
+
reason: `${call.toolName} pipes a download into an interpreter, which the built-in review rules ask a person about`,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
return undefined;
|
|
446
|
+
};
|
|
447
|
+
/**
|
|
448
|
+
* The fixed codes a reviewer's answer is reported under. The reviewer's own
|
|
449
|
+
* line can echo the call's input, so the log and the event carry one of
|
|
450
|
+
* these instead, and the line goes only to the agent and the approver, who
|
|
451
|
+
* are shown the call anyway.
|
|
452
|
+
*/
|
|
453
|
+
export const REVIEW_CODES = [
|
|
454
|
+
'asked-for',
|
|
455
|
+
'not-asked-for',
|
|
456
|
+
'follows-outside-content',
|
|
457
|
+
'sends-secret',
|
|
458
|
+
'new-destination',
|
|
459
|
+
'unclear',
|
|
460
|
+
'review-failed',
|
|
461
|
+
];
|
|
462
|
+
/**
|
|
463
|
+
* A review that couldn't run, with the kind a person reads in the log
|
|
464
|
+
* (`provider-error`, `budget`, `unparseable`, `unknown-model`). Anything
|
|
465
|
+
* else a reviewer throws is reported as `error`. Either way the call is
|
|
466
|
+
* asked about, never allowed.
|
|
467
|
+
*/
|
|
468
|
+
export class ReviewFailure extends Error {
|
|
469
|
+
kind;
|
|
470
|
+
constructor(kind, message) {
|
|
471
|
+
super(message ?? `the review couldn't run: ${kind}`);
|
|
472
|
+
this.name = 'ReviewFailure';
|
|
473
|
+
this.kind = kind;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
const REVIEW_REASON_LIMIT = 300;
|
|
477
|
+
/**
|
|
478
|
+
* The reviewer's answer if it has the right shape, with an unknown code
|
|
479
|
+
* read as `unclear` and the reason cut to one bounded line; undefined when
|
|
480
|
+
* the verdict or the reason is missing, which counts as a failed review.
|
|
481
|
+
*/
|
|
482
|
+
export const readReviewAnswer = (raw) => {
|
|
483
|
+
if (typeof raw !== 'object' || raw === null) {
|
|
484
|
+
return undefined;
|
|
485
|
+
}
|
|
486
|
+
const source = raw;
|
|
487
|
+
if (typeof source.verdict !== 'string' || !VERDICTS.includes(source.verdict)) {
|
|
488
|
+
return undefined;
|
|
489
|
+
}
|
|
490
|
+
if (typeof source.reason !== 'string' || source.reason.trim().length === 0) {
|
|
491
|
+
return undefined;
|
|
492
|
+
}
|
|
493
|
+
// The first line, with every control and bidi character made a space: the
|
|
494
|
+
// reason is shown at a terminal prompt and may echo the call's own text.
|
|
495
|
+
const line = source.reason.trim().split(/\r?\n/)[0]
|
|
496
|
+
.replace(/[\u0000-\u001f\u007f-\u009f\u2028\u2029\u202a-\u202e\u2066-\u2069]/g, ' ')
|
|
497
|
+
.replace(/\s+/g, ' ')
|
|
498
|
+
.trim();
|
|
499
|
+
if (line.length === 0) {
|
|
500
|
+
return undefined;
|
|
501
|
+
}
|
|
502
|
+
const code = typeof source.code === 'string' && REVIEW_CODES.includes(source.code) && source.code !== 'review-failed'
|
|
503
|
+
? source.code
|
|
504
|
+
: 'unclear';
|
|
505
|
+
return {
|
|
506
|
+
verdict: source.verdict,
|
|
507
|
+
code,
|
|
508
|
+
reason: line.length > REVIEW_REASON_LIMIT ? `${line.slice(0, REVIEW_REASON_LIMIT)}…` : line,
|
|
509
|
+
};
|
|
510
|
+
};
|
|
511
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../src/review.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,YAAY,GAEb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAoBvF,MAAM,QAAQ,GAAsB,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAC9D,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;AACnF,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,aAAa,CAAU,CAAC;AAE/D,yFAAyF;AACzF,MAAM,YAAY,GAAG,gDAAgD,CAAC;AAEtE;;;;GAIG;AACH,MAAM,YAAY,GAAG,CAAC,GAAW,EAAgD,EAAE;IACjF,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,MAAM,EAAE,sDAAsD,EAAE,CAAC;IAC5E,CAAC;IACD,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5C,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACtB,OAAO,EAAE,MAAM,EAAE,qCAAqC,EAAE,CAAC;IAC3D,CAAC;IACD,IAAI,QAAQ,CAAC,cAAc,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3D,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,cAAc,IAAI,mCAAmC,EAAE,CAAC;IACpF,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACtC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAChD,OAAO,EAAE,MAAM,EAAE,6DAA6D,EAAE,CAAC;IACnF,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;AACrF,CAAC,CAAC;AAEF,4FAA4F;AAC5F,MAAM,cAAc,GAAG,CAAC,MAAc,EAAsB,EAAE;IAC5D,MAAM,KAAK,GAAG,2BAA2B,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9D,OAAO,KAAK,CAAC,CAAC,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACxE,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AAEpD;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAY,EAA6C,EAAE;IACzF,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,OAAO,EAAE,MAAM,EAAE,4FAA4F,EAAE,CAAC;IAClH,CAAC;IACD,MAAM,MAAM,GAAG,GAA8B,CAAC;IAC9C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1E,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,EAAE,MAAM,EAAE,gBAAgB,UAAU,+EAA+E,EAAE,CAAC;IAC/H,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChE,OAAO,EAAE,MAAM,EAAE,yEAAyE,EAAE,CAAC;IAC/F,CAAC;IACD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,MAAM,EAAE,SAAS,MAAM,CAAC,IAAI,sDAAsD,EAAE,CAAC;IAChG,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7E,OAAO,EAAE,MAAM,EAAE,yCAAyC,EAAE,CAAC;IAC/D,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAA0B,CAAC;IAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC;IAClE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,MAAM,EAAE,YAAY,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,8DAA8D,EAAE,CAAC;IACnH,CAAC;IACD,MAAM,IAAI,GAAe,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;IACxD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,6BAA6B,EAAE,CAAC;IAC7D,CAAC;IACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACxF,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;YACtB,OAAO,EAAE,MAAM,EAAE,YAAY,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QAC3D,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;IACtD,CAAC;IACD,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,sEAAsE;QACtE,kEAAkE;QAClE,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7E,IAAI,cAAc,CAAC,KAAK,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;YACrH,OAAO,EAAE,MAAM,EAAE,WAAW,KAAK,0EAA0E,EAAE,CAAC;QAChH,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;IACxE,CAAC;IACD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAC5C,OAAO,EAAE,MAAM,EAAE,gBAAgB,KAAK,oDAAoD,EAAE,CAAC;IAC/F,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;AAC1D,CAAC,CAAC;AAUF,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,QAAgB,EAAW,EAAE,CACjE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC;AAE5F,MAAM,kBAAkB,GAAG,CAAC,IAAgB,EAAE,OAAe,EAAW,EAAE;IACxE,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QAC7B,kEAAkE;QAClE,uEAAuE;QACvE,eAAe;QACf,MAAM,MAAM,GAAG,sBAAsB,CAAC,IAAI,CAAC,OAAiB,CAAC,CAAC;QAC9D,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,QAAQ,CAAC,cAAc,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QACzC,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC;eACnB,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3G,CAAC;IACD,uEAAuE;IACvE,0EAA0E;IAC1E,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,OAAiB,CAAC,CAAC;IACnD,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;IACpC,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC1F,OAAO,IAAI,CAAC;IACd,CAAC;IACD,uEAAuE;IACvE,yEAAyE;IACzE,2CAA2C;IAC3C,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;SAChE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;SAC1D,IAAI,CAAC,4BAA4B,CAAC,CAAC;IACtC,uEAAuE;IACvE,oEAAoE;IACpE,OAAO,IAAI,MAAM,CAAC,8CAA8C,QAAQ,qBAAqB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC/G,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,OAAe,EAAE,MAAc,EAAW,EAAE;IACrE,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,eAAe,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,SAAS,CAAC;IACzD,CAAC;IACD,OAAO,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;AACpD,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAW,EAAE,CAC/E,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IACpB,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC;IACzF,CAAC,CAAC,OAAO,KAAK,WAAW,CAAC;AAE9B;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAA4B,EAAE,IAAkB,EAA0B,EAAE,CAC1G,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;IAClB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9E,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,sBAAsB,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACtG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC,CAAC;AAEL,kFAAkF;AAClF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAgB,EAAU,EAAE,CAC7D,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;AAY1O;;;GAGG;AACH,MAAM,kBAAkB,GAAG,yIAAyI,CAAC;AAErK,uFAAuF;AACvF,MAAM,YAAY,GAAsB;IACtC,iCAAiC;IACjC,0BAA0B;IAC1B,wBAAwB;IACxB,gCAAgC;IAChC,6BAA6B;IAC7B,sBAAsB;CACvB,CAAC;AAEF,qFAAqF;AACrF,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAE5B,+EAA+E;AAC/E,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK;IAC/F,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI;CACtC,CAAC,CAAC;AAEH,iDAAiD;AACjD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CACvG,CAAC,CAAC;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAC9C;;;;;GAKG;AACH,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IACvG,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU;CAC/F,CAAC,CAAC;AACH,MAAM,UAAU,GAAG,0BAA0B,CAAC;AAE9C,MAAM,OAAO,GAAG,CAAC,KAA4B,EAAE,MAAgB,EAAE,EAAY,EAAE;IAC7E,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;SAAM,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACxC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC;AAEzE;;;GAGG;AACH,MAAM,SAAS,GAAG,CAAC,KAAwB,EAAE,QAA6B,EAAW,EAAE;IACrF,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAW,CAAC,CAAC;IACjD,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;WACvB,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3G,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,IAA4C,EAAW,EAAE;IAC7E,IAAI,IAAI,CAAC,QAAQ,KAAK,cAAc,IAAI,IAAI,CAAC,QAAQ,KAAK,WAAW;WAChE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,uEAAuE;IACvE,oEAAoE;IACpE,uEAAuE;IACvE,yEAAyE;IACzE,0BAA0B;IAC1B,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3G,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,cAAc,GAAG,CAAC,IAAY,EAAgB,EAAE;IACpD,MAAM,SAAS,GAAiB,EAAE,CAAC;IACnC,IAAI,MAAM,GAAe,EAAE,CAAC;IAC5B,IAAI,KAAK,GAAa,EAAE,CAAC;IACzB,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,wEAAwE;IACxE,IAAI,KAAyB,CAAC;IAC9B,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QACD,IAAI,GAAG,EAAE,CAAC;QACV,OAAO,GAAG,KAAK,CAAC;IAClB,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,GAAS,EAAE;QAC1B,OAAO,EAAE,CAAC;QACV,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,KAAK,GAAG,EAAE,CAAC;IACb,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,GAAS,EAAE;QAC7B,QAAQ,EAAE,CAAC;QACX,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;QACD,MAAM,GAAG,EAAE,CAAC;IACd,CAAC,CAAC;IACF,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAW,CAAC;QACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5C,KAAK,GAAG,SAAS,CAAC;YACpB,CAAC;iBAAM,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBACtE,MAAM,MAAM,GAAG,oFAAoF,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;gBAChI,MAAM,CAAC,KAAK,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,EAAE,CAAC;gBAC7D,MAAM,IAAI,GAAG,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC;gBAC7B,IAAI,IAAI,IAAI,KAAK,SAAS;oBACxB,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC;oBAC5D,CAAC,CAAC,KAAK,KAAK,SAAS;wBACnB,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;wBAChD,CAAC,CAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAA6B,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC9J,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC;YACxB,CAAC;iBAAM,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBACrE,KAAK,IAAI,CAAC,CAAC;gBACX,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,IAAI,IAAI,IAAI,CAAC;YACf,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACjC,KAAK,GAAG,IAAI,CAAC;YACb,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YAChF,wEAAwE;YACxE,KAAK,IAAI,CAAC,CAAC;YACX,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;YACzC,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACpD,KAAK,IAAI,CAAC,CAAC;YACX,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACzC,WAAW,EAAE,CAAC;QAChB,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,OAAO,EAAE,CAAC;QACZ,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACxB,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBAC5B,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;YACD,WAAW,EAAE,CAAC;QAChB,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACxB,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBAC5B,KAAK,IAAI,CAAC,CAAC;gBACX,WAAW,EAAE,CAAC;YAChB,CAAC;iBAAM,CAAC;gBACN,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBAC5B,KAAK,IAAI,CAAC,CAAC;gBACb,CAAC;gBACD,QAAQ,EAAE,CAAC;YACb,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,CAAC;QACZ,CAAC;aAAM,CAAC;YACN,IAAI,IAAI,IAAI,CAAC;YACb,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IACD,WAAW,EAAE,CAAC;IACd,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,WAAW,GAAG,CAAC,OAAe,EAAgB,EAAE;IACpD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAC1C,wEAAwE;IACxE,MAAM,GAAG,GAAG,QAAQ,CAAC,cAAc,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;QAC3D,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC;QACzB,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9F,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1G,OAAO,CAAC,GAAG,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,OAAe,EAAc,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;AAE9E,iFAAiF;AACjF,MAAM,OAAO,GAAG,CAAC,MAAyB,EAAE,KAAwB,EAAW,EAAE;IAC/E,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,IAAI,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACpD,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC;AACjC,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,CAAC,KAAwB,EAAE,OAAe,EAAE,IAAuB,EAAW,EAAE;IACvG,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAW,CAAC,CAAC;IAC/C,MAAM,EAAE,GAAG,KAAK,KAAK,OAAO;QAC1B,CAAC,CAAC,CAAC,KAAK,CAAC;QACT,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;YACxB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9F,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,aAAa,GAAG,CAAC,KAAwB,EAAE,QAA6B,EAAW,EAAE,CACzF,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC;OACvB,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;AAE3H,MAAM,4BAA4B,GAAG,CAAC,OAAe,EAAW,EAAE,CAChE,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;IACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;IAC/E,OAAO,KAAK,IAAI,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;AACrG,CAAC,CAAC,CAAC;AAEL;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,IAA8D,EAC9D,OAA0B,EACI,EAAE;IAChC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAC3D,OAAO;YACL,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,OAAO;YAChB,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,wEAAwE;SACjG,CAAC;IACJ,CAAC;IACD,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,iBAAiB,CAAC,CAAC;QAC7E,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9H,OAAO;gBACL,IAAI,EAAE,cAAc;gBACpB,OAAO,EAAE,OAAO;gBAChB,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,kGAAkG;aAC3H,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,4BAA4B,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7E,OAAO;YACL,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,2FAA2F;SACpH,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,WAAW;IACX,eAAe;IACf,yBAAyB;IACzB,cAAc;IACd,iBAAiB;IACjB,SAAS;IACT,eAAe;CACP,CAAC;AA8CX;;;;;GAKG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAAgB;QACxC,KAAK,CAAC,OAAO,IAAI,4BAA4B,IAAI,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAeD,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAY,EAA4B,EAAE;IACzE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,GAA8B,CAAC;IAC9C,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7E,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3E,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,0EAA0E;IAC1E,yEAAyE;IACzE,MAAM,IAAI,GAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAY;SAC5D,OAAO,CAAC,qEAAqE,EAAE,GAAG,CAAC;SACnF,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IACV,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAK,YAAkC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe;QAC1I,CAAC,CAAC,MAAM,CAAC,IAAkB;QAC3B,CAAC,CAAC,SAAS,CAAC;IACd,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAA0B;QAC1C,IAAI;QACJ,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;KAC5F,CAAC;AACJ,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stratusagent/permissions",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -11,19 +11,20 @@
|
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
|
-
"dist"
|
|
14
|
+
"dist",
|
|
15
|
+
"NOTICE"
|
|
15
16
|
],
|
|
16
17
|
"engines": {
|
|
17
|
-
"node": ">=22.
|
|
18
|
+
"node": ">=22.16 <23 || >=24"
|
|
18
19
|
},
|
|
19
20
|
"dependencies": {
|
|
20
|
-
"@stratusagent/core": "0.14.
|
|
21
|
+
"@stratusagent/core": "0.14.3"
|
|
21
22
|
},
|
|
22
23
|
"devDependencies": {
|
|
23
24
|
"@types/node": "^24.6.0",
|
|
24
25
|
"typescript": "^5.9.3"
|
|
25
26
|
},
|
|
26
|
-
"license": "
|
|
27
|
+
"license": "Apache-2.0",
|
|
27
28
|
"repository": {
|
|
28
29
|
"type": "git",
|
|
29
30
|
"url": "git+https://github.com/stratuslabs/agent.git",
|