@aliou/pi-guardrails 0.12.1 → 0.13.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/README.md +8 -6
- package/extensions/path-access/index.ts +12 -0
- package/extensions/permission-gate/index.ts +12 -0
- package/package.json +7 -5
- package/src/shared/events.ts +28 -0
- package/extensions/guardrails/rules.test.ts +0 -107
- package/extensions/guardrails/targets.test.ts +0 -44
- package/extensions/path-access/grants.test.ts +0 -47
- package/extensions/path-access/rules.test.ts +0 -46
- package/extensions/path-access/targets.test.ts +0 -40
- package/extensions/permission-gate/rules.test.ts +0 -132
- package/src/core/check.test.ts +0 -169
- package/src/core/commands/dangerous.test.ts +0 -468
- package/src/core/paths/access.test.ts +0 -150
- package/src/core/paths/path.test.ts +0 -293
- package/src/core/shell/command-args.test.ts +0 -142
- package/src/shared/matching.test.ts +0 -86
- package/src/shared/paths/bash-paths.test.ts +0 -171
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { homedir } from "node:os";
|
|
2
|
-
import { describe, expect, it } from "vitest";
|
|
3
|
-
import { extractBashPathCandidates } from "./bash-paths";
|
|
4
|
-
|
|
5
|
-
const CWD = "/work/project";
|
|
6
|
-
const HOME = homedir();
|
|
7
|
-
|
|
8
|
-
describe("extractBashPathCandidates", () => {
|
|
9
|
-
it("does not extract go package wildcard patterns as paths", async () => {
|
|
10
|
-
const result = await extractBashPathCandidates("go test ./...", CWD);
|
|
11
|
-
|
|
12
|
-
expect(result).toEqual([]);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("extracts go run .go file operands", async () => {
|
|
16
|
-
const result = await extractBashPathCandidates("go run main.go", CWD);
|
|
17
|
-
|
|
18
|
-
expect(result).toEqual(["/work/project/main.go"]);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it("handles go -C global flag", async () => {
|
|
22
|
-
const result = await extractBashPathCandidates(
|
|
23
|
-
"go -C /tmp test ./...",
|
|
24
|
-
CWD,
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
expect(result).toEqual([]);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe("when a command has regular expression arguments", () => {
|
|
31
|
-
it("ignores sed expressions and extracts file operands", async () => {
|
|
32
|
-
const result = await extractBashPathCandidates(
|
|
33
|
-
"sed 's/abc/{2,3}/g' ./file",
|
|
34
|
-
CWD,
|
|
35
|
-
);
|
|
36
|
-
expect(result).toEqual(["/work/project/file"]);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it("ignores grep patterns and extracts file operands", async () => {
|
|
40
|
-
const result = await extractBashPathCandidates(
|
|
41
|
-
"grep '/api/v1' ./src",
|
|
42
|
-
CWD,
|
|
43
|
-
);
|
|
44
|
-
expect(result).toEqual(["/work/project/src"]);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("ignores ripgrep patterns and extracts search roots", async () => {
|
|
48
|
-
const result = await extractBashPathCandidates("rg '/api/v1' ./src", CWD);
|
|
49
|
-
expect(result).toEqual(["/work/project/src"]);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("ignores jq filters and extracts file operands", async () => {
|
|
53
|
-
const result = await extractBashPathCandidates(
|
|
54
|
-
"jq '.path | test(\"^/tmp/\")' ./data.json",
|
|
55
|
-
CWD,
|
|
56
|
-
);
|
|
57
|
-
expect(result).toEqual(["/work/project/data.json"]);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it("ignores interpreter inline code", async () => {
|
|
61
|
-
const result = await extractBashPathCandidates(
|
|
62
|
-
"python3 -c 'open(\"/etc/passwd\").read()'",
|
|
63
|
-
CWD,
|
|
64
|
-
);
|
|
65
|
-
expect(result).toEqual([]);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
// Regression: github issue #32 — awk regex patterns should not be
|
|
70
|
-
// treated as file paths.
|
|
71
|
-
it("does not extract awk regex patterns as paths", async () => {
|
|
72
|
-
const result = await extractBashPathCandidates(
|
|
73
|
-
"awk '/aaa/{flag=1} flag{print}' test.txt",
|
|
74
|
-
CWD,
|
|
75
|
-
);
|
|
76
|
-
// The awk program should NOT be treated as a path
|
|
77
|
-
expect(result).toEqual([]);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
describe("when command has path arguments", () => {
|
|
81
|
-
it("extracts a single absolute path", async () => {
|
|
82
|
-
expect(await extractBashPathCandidates("cat /etc/hosts", CWD)).toEqual([
|
|
83
|
-
"/etc/hosts",
|
|
84
|
-
]);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("extracts multiple absolute paths", async () => {
|
|
88
|
-
expect(await extractBashPathCandidates("cp /a /b", CWD)).toEqual([
|
|
89
|
-
"/a",
|
|
90
|
-
"/b",
|
|
91
|
-
]);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it("resolves a relative path with ./ against cwd", async () => {
|
|
95
|
-
expect(await extractBashPathCandidates("cat ./foo/bar", CWD)).toEqual([
|
|
96
|
-
"/work/project/foo/bar",
|
|
97
|
-
]);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it("expands ~ to home", async () => {
|
|
101
|
-
expect(await extractBashPathCandidates("cat ~/file", CWD)).toEqual([
|
|
102
|
-
`${HOME}/file`,
|
|
103
|
-
]);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it("detects Windows-style paths", async () => {
|
|
107
|
-
const result = await extractBashPathCandidates("type C:\\foo\\bar", CWD);
|
|
108
|
-
|
|
109
|
-
expect(result).toHaveLength(1);
|
|
110
|
-
expect(result[0]).toContain("C:\\foo\\bar");
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
describe("when command has flags and redirects", () => {
|
|
115
|
-
it("ignores flag arguments", async () => {
|
|
116
|
-
expect(await extractBashPathCandidates("ls -la /tmp", CWD)).toEqual([
|
|
117
|
-
"/tmp",
|
|
118
|
-
]);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it("extracts redirect targets", async () => {
|
|
122
|
-
expect(
|
|
123
|
-
await extractBashPathCandidates("echo foo > /tmp/out", CWD),
|
|
124
|
-
).toEqual(["/tmp/out"]);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it("extracts paths from multiple commands and redirects", async () => {
|
|
128
|
-
expect(
|
|
129
|
-
await extractBashPathCandidates(
|
|
130
|
-
"cat ./input && grep needle /tmp/log > ./out",
|
|
131
|
-
CWD,
|
|
132
|
-
),
|
|
133
|
-
).toEqual(["/work/project/input", "/tmp/log", "/work/project/out"]);
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
describe("when command has no path-like tokens", () => {
|
|
138
|
-
it("returns an empty array for bare filenames (no separators)", async () => {
|
|
139
|
-
expect(await extractBashPathCandidates("cat README.md", CWD)).toEqual([]);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it("returns an empty array for commands with no file arguments", async () => {
|
|
143
|
-
expect(await extractBashPathCandidates("echo hello", CWD)).toEqual([]);
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
describe("when command uses quoting", () => {
|
|
148
|
-
it("handles quoted paths with spaces", async () => {
|
|
149
|
-
expect(
|
|
150
|
-
await extractBashPathCandidates('cat "/tmp/hello world"', CWD),
|
|
151
|
-
).toEqual(["/tmp/hello world"]);
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
describe("when command has duplicate paths", () => {
|
|
156
|
-
it("deduplicates results", async () => {
|
|
157
|
-
expect(await extractBashPathCandidates("cat /a /a", CWD)).toEqual(["/a"]);
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
describe("when command is malformed", () => {
|
|
162
|
-
it("falls back to regex tokenization on parse failure", async () => {
|
|
163
|
-
// Unbalanced quote triggers parse error; regex fallback still finds paths
|
|
164
|
-
const result = await extractBashPathCandidates(
|
|
165
|
-
"cat /tmp/foo 'unterminated",
|
|
166
|
-
CWD,
|
|
167
|
-
);
|
|
168
|
-
expect(result).toContain("/tmp/foo");
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
});
|