@aliou/pi-guardrails 0.7.1 → 0.7.2
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/hooks/permission-gate.ts +91 -60
- package/package.json +2 -2
package/hooks/permission-gate.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
wrapTextWithAnsi,
|
|
11
11
|
} from "@mariozechner/pi-tui";
|
|
12
12
|
import type { DangerousPattern, ResolvedConfig } from "../config";
|
|
13
|
+
import { configLoader } from "../config";
|
|
13
14
|
import { emitBlocked, emitDangerous } from "../utils/events";
|
|
14
15
|
import {
|
|
15
16
|
type CompiledPattern,
|
|
@@ -221,70 +222,100 @@ export function setupPermissionGateHook(
|
|
|
221
222
|
return { block: true, reason };
|
|
222
223
|
}
|
|
223
224
|
|
|
224
|
-
|
|
225
|
-
const container = new Container();
|
|
226
|
-
const redBorder = (s: string) => theme.fg("error", s);
|
|
225
|
+
type ConfirmResult = "allow" | "allow-session" | "deny";
|
|
227
226
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
new
|
|
231
|
-
|
|
232
|
-
1,
|
|
233
|
-
0,
|
|
234
|
-
),
|
|
235
|
-
);
|
|
236
|
-
container.addChild(new Spacer(1));
|
|
237
|
-
container.addChild(
|
|
238
|
-
new Text(
|
|
239
|
-
theme.fg("warning", `This command contains ${description}:`),
|
|
240
|
-
1,
|
|
241
|
-
0,
|
|
242
|
-
),
|
|
243
|
-
);
|
|
244
|
-
container.addChild(new Spacer(1));
|
|
245
|
-
container.addChild(
|
|
246
|
-
new DynamicBorder((s: string) => theme.fg("muted", s)),
|
|
247
|
-
);
|
|
248
|
-
const commandText = new Text("", 1, 0);
|
|
249
|
-
container.addChild(commandText);
|
|
250
|
-
container.addChild(
|
|
251
|
-
new DynamicBorder((s: string) => theme.fg("muted", s)),
|
|
252
|
-
);
|
|
253
|
-
container.addChild(new Spacer(1));
|
|
254
|
-
container.addChild(
|
|
255
|
-
new Text(theme.fg("text", "Allow execution?"), 1, 0),
|
|
256
|
-
);
|
|
257
|
-
container.addChild(new Spacer(1));
|
|
258
|
-
container.addChild(
|
|
259
|
-
new Text(theme.fg("dim", "y/enter: allow • n/esc: deny"), 1, 0),
|
|
260
|
-
);
|
|
261
|
-
container.addChild(new DynamicBorder(redBorder));
|
|
227
|
+
const result = await ctx.ui.custom<ConfirmResult>(
|
|
228
|
+
(_tui, theme, _kb, done) => {
|
|
229
|
+
const container = new Container();
|
|
230
|
+
const redBorder = (s: string) => theme.fg("error", s);
|
|
262
231
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
theme.fg("
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
232
|
+
container.addChild(new DynamicBorder(redBorder));
|
|
233
|
+
container.addChild(
|
|
234
|
+
new Text(
|
|
235
|
+
theme.fg("error", theme.bold("Dangerous Command Detected")),
|
|
236
|
+
1,
|
|
237
|
+
0,
|
|
238
|
+
),
|
|
239
|
+
);
|
|
240
|
+
container.addChild(new Spacer(1));
|
|
241
|
+
container.addChild(
|
|
242
|
+
new Text(
|
|
243
|
+
theme.fg("warning", `This command contains ${description}:`),
|
|
244
|
+
1,
|
|
245
|
+
0,
|
|
246
|
+
),
|
|
247
|
+
);
|
|
248
|
+
container.addChild(new Spacer(1));
|
|
249
|
+
container.addChild(
|
|
250
|
+
new DynamicBorder((s: string) => theme.fg("muted", s)),
|
|
251
|
+
);
|
|
252
|
+
const commandText = new Text("", 1, 0);
|
|
253
|
+
container.addChild(commandText);
|
|
254
|
+
container.addChild(
|
|
255
|
+
new DynamicBorder((s: string) => theme.fg("muted", s)),
|
|
256
|
+
);
|
|
257
|
+
container.addChild(new Spacer(1));
|
|
258
|
+
container.addChild(
|
|
259
|
+
new Text(theme.fg("text", "Allow execution?"), 1, 0),
|
|
260
|
+
);
|
|
261
|
+
container.addChild(new Spacer(1));
|
|
262
|
+
container.addChild(
|
|
263
|
+
new Text(
|
|
264
|
+
theme.fg(
|
|
265
|
+
"dim",
|
|
266
|
+
"y/enter: allow • a: allow for session • n/esc: deny",
|
|
267
|
+
),
|
|
268
|
+
1,
|
|
269
|
+
0,
|
|
270
|
+
),
|
|
271
|
+
);
|
|
272
|
+
container.addChild(new DynamicBorder(redBorder));
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
render: (width: number) => {
|
|
276
|
+
const wrappedCommand = wrapTextWithAnsi(
|
|
277
|
+
theme.fg("text", command),
|
|
278
|
+
width - 4,
|
|
279
|
+
).join("\n");
|
|
280
|
+
commandText.setText(wrappedCommand);
|
|
281
|
+
return container.render(width);
|
|
282
|
+
},
|
|
283
|
+
invalidate: () => container.invalidate(),
|
|
284
|
+
handleInput: (data: string) => {
|
|
285
|
+
if (matchesKey(data, Key.enter) || data === "y" || data === "Y") {
|
|
286
|
+
done("allow");
|
|
287
|
+
} else if (data === "a" || data === "A") {
|
|
288
|
+
done("allow-session");
|
|
289
|
+
} else if (
|
|
290
|
+
matchesKey(data, Key.escape) ||
|
|
291
|
+
data === "n" ||
|
|
292
|
+
data === "N"
|
|
293
|
+
) {
|
|
294
|
+
done("deny");
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
};
|
|
298
|
+
},
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
if (result === "allow-session") {
|
|
302
|
+
// Save command as allowed in memory scope (session-only).
|
|
303
|
+
// Spread the resolved allowed patterns and append the new one.
|
|
304
|
+
const resolved = configLoader.getConfig();
|
|
305
|
+
await configLoader.save("memory", {
|
|
306
|
+
permissionGate: {
|
|
307
|
+
allowedPatterns: [
|
|
308
|
+
...resolved.permissionGate.allowedPatterns,
|
|
309
|
+
{ pattern: command },
|
|
310
|
+
],
|
|
283
311
|
},
|
|
284
|
-
};
|
|
285
|
-
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// Update the local cache so it takes effect immediately
|
|
315
|
+
allowedPatterns.push(...compileCommandPatterns([{ pattern: command }]));
|
|
316
|
+
}
|
|
286
317
|
|
|
287
|
-
if (
|
|
318
|
+
if (result === "deny") {
|
|
288
319
|
emitBlocked(pi, {
|
|
289
320
|
feature: "permissionGate",
|
|
290
321
|
toolName: "bash",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aliou/pi-guardrails",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"keywords": [
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@aliou/sh": "^0.1.0",
|
|
36
|
-
"@aliou/pi-utils-settings": "^0.
|
|
36
|
+
"@aliou/pi-utils-settings": "^0.3.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@mariozechner/pi-coding-agent": ">=0.51.0"
|