@aliou/pi-guardrails 0.9.5 → 0.11.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 +51 -3
- package/docs/defaults.md +140 -0
- package/docs/examples.md +170 -0
- package/package.json +7 -3
- package/src/commands/onboarding-command.ts +76 -0
- package/src/commands/onboarding.ts +390 -0
- package/src/commands/settings-command.ts +158 -3
- package/src/config.ts +102 -3
- package/src/hooks/index.ts +4 -2
- package/src/hooks/path-access.ts +396 -0
- package/src/hooks/permission-gate/dangerous-commands.test.ts +336 -0
- package/src/hooks/permission-gate/dangerous-commands.ts +345 -0
- package/src/hooks/permission-gate/index.test.ts +332 -0
- package/src/hooks/{permission-gate.ts → permission-gate/index.ts} +275 -159
- package/src/hooks/policies.ts +20 -4
- package/src/index.ts +62 -3
- package/src/utils/bash-paths.test.ts +91 -0
- package/src/utils/bash-paths.ts +96 -0
- package/src/utils/events.ts +1 -1
- package/src/utils/migration.ts +55 -1
- package/src/utils/path-access.test.ts +154 -0
- package/src/utils/path-access.ts +62 -0
- package/src/utils/path.test.ts +177 -0
- package/src/utils/path.ts +74 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Expand a leading tilde to the current user's home directory.
|
|
6
|
+
* Preserves all other paths unchanged.
|
|
7
|
+
*/
|
|
8
|
+
export function expandHomePath(input: string): string {
|
|
9
|
+
if (input === "~") return homedir();
|
|
10
|
+
if (input.startsWith("~/") || input.startsWith("~\\"))
|
|
11
|
+
return join(homedir(), input.slice(2));
|
|
12
|
+
return input;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function resolveFromCwd(input: string, cwd: string): string {
|
|
16
|
+
return resolve(cwd, expandHomePath(input));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Lexical boundary check. Returns true if targetAbsPath equals rootAbsPath
|
|
21
|
+
* or is a descendant. Both paths must already be resolved (absolute, no ..).
|
|
22
|
+
* Does NOT resolve symlinks — this is a known limitation.
|
|
23
|
+
*/
|
|
24
|
+
export function isWithinBoundary(
|
|
25
|
+
targetAbsPath: string,
|
|
26
|
+
rootAbsPath: string,
|
|
27
|
+
): boolean {
|
|
28
|
+
const rel = relative(rootAbsPath, targetAbsPath);
|
|
29
|
+
return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Format an absolute path for display:
|
|
34
|
+
* - relative if inside cwd
|
|
35
|
+
* - ~/... if under home
|
|
36
|
+
* - absolute otherwise
|
|
37
|
+
*/
|
|
38
|
+
export function normalizeForDisplay(absPath: string, cwd: string): string {
|
|
39
|
+
const home = homedir();
|
|
40
|
+
const rel = relative(cwd, absPath);
|
|
41
|
+
if (rel === "" || (!rel.startsWith("..") && !isAbsolute(rel)))
|
|
42
|
+
return rel || ".";
|
|
43
|
+
if (
|
|
44
|
+
absPath === home ||
|
|
45
|
+
absPath.startsWith(`${home}/`) ||
|
|
46
|
+
absPath.startsWith(`${home}\\`)
|
|
47
|
+
) {
|
|
48
|
+
return `~${absPath.slice(home.length)}`;
|
|
49
|
+
}
|
|
50
|
+
return absPath;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Convert an absolute path to storage form for config persistence.
|
|
55
|
+
* Uses ~/ for home paths, absolute otherwise. Appends trailing / for directory grants.
|
|
56
|
+
*/
|
|
57
|
+
export function toStorageForm(absPath: string, isDirectory: boolean): string {
|
|
58
|
+
const home = homedir();
|
|
59
|
+
let stored: string;
|
|
60
|
+
if (
|
|
61
|
+
absPath === home ||
|
|
62
|
+
absPath.startsWith(`${home}/`) ||
|
|
63
|
+
absPath.startsWith(`${home}\\`)
|
|
64
|
+
) {
|
|
65
|
+
stored = `~${absPath.slice(home.length)}`;
|
|
66
|
+
} else {
|
|
67
|
+
stored = absPath;
|
|
68
|
+
}
|
|
69
|
+
// Normalize separators to forward slash for storage
|
|
70
|
+
stored = stored.replace(/\\/g, "/");
|
|
71
|
+
if (isDirectory && !stored.endsWith("/")) stored += "/";
|
|
72
|
+
if (!isDirectory && stored.endsWith("/")) stored = stored.slice(0, -1);
|
|
73
|
+
return stored;
|
|
74
|
+
}
|