Files
gnome-jarvis/vendor/agent-harness/agent/perm-rules.js
T
2026-09-11 13:41:22 -04:00

60 lines
1.8 KiB
JavaScript

/**
* Persistent allow/deny patterns. No Bare imports.
*
* A rule is { tool, pattern, decision: 'allow'|'deny' }.
* Shell patterns match the leading tokens of the command (e.g. "git status").
* Path patterns match args.path / args.file, prefix or exact.
*/
function patternFromArgs(tool, args) {
args = args || {};
if (tool === 'run_terminal_cmd') {
return String(args.command || '')
.trim()
.split(/\s+/)
.slice(0, 2)
.join(' ');
}
if (args.path) return String(args.path);
if (args.file) return String(args.file);
if (args.url) return String(args.url);
if (args.name) return String(args.name);
return '*';
}
function globish(value, pattern) {
const v = String(value || '');
const p = String(pattern || '');
if (!p || p === '*') return true;
if (v === p) return true;
if (v.indexOf(p) === 0) return true;
if (p.endsWith('*') && v.indexOf(p.slice(0, -1)) === 0) return true;
return false;
}
function matchRule(rule, tool, args) {
if (!rule || rule.tool !== tool) return false;
const pat = patternFromArgs(tool, args);
return globish(pat, rule.pattern);
}
function resolve(rules, tool, args) {
const list = Array.isArray(rules) ? rules : [];
for (let i = list.length - 1; i >= 0; i--) {
if (matchRule(list[i], tool, args)) return list[i].decision === 'deny' ? 'deny' : 'allow';
}
return null;
}
function addRule(rules, tool, args, decision) {
const next = Array.isArray(rules) ? rules.slice() : [];
const pattern = patternFromArgs(tool, args);
const rec = { tool: String(tool), pattern: pattern || '*', decision: decision === 'deny' ? 'deny' : 'allow' };
const idx = next.findIndex((r) => r.tool === rec.tool && r.pattern === rec.pattern);
if (idx >= 0) next[idx] = rec;
else next.push(rec);
return next;
}
module.exports = { patternFromArgs, globish, matchRule, resolve, addRule };