@stratusagent/permissions 0.14.2 → 0.14.4

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/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":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stratusagent/permissions",
3
- "version": "0.14.2",
3
+ "version": "0.14.4",
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.13 <23 || >=23.4"
18
+ "node": ">=22.16 <23 || >=24"
18
19
  },
19
20
  "dependencies": {
20
- "@stratusagent/core": "0.14.2"
21
+ "@stratusagent/core": "0.14.4"
21
22
  },
22
23
  "devDependencies": {
23
24
  "@types/node": "^24.6.0",
24
25
  "typescript": "^5.9.3"
25
26
  },
26
- "license": "MIT",
27
+ "license": "Apache-2.0",
27
28
  "repository": {
28
29
  "type": "git",
29
30
  "url": "git+https://github.com/stratuslabs/agent.git",