gog-safe 0.1.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 +148 -0
- package/dist/audit.d.ts +10 -0
- package/dist/audit.js +9 -0
- package/dist/audit.js.map +1 -0
- package/dist/command-control.d.ts +12 -0
- package/dist/command-control.js +49 -0
- package/dist/command-control.js.map +1 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.js +15 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +121 -0
- package/dist/index.js.map +1 -0
- package/dist/matching.d.ts +11 -0
- package/dist/matching.js +118 -0
- package/dist/matching.js.map +1 -0
- package/dist/policy.d.ts +4 -0
- package/dist/policy.js +310 -0
- package/dist/policy.js.map +1 -0
- package/dist/process.d.ts +13 -0
- package/dist/process.js +113 -0
- package/dist/process.js.map +1 -0
- package/dist/run.d.ts +8 -0
- package/dist/run.js +282 -0
- package/dist/run.js.map +1 -0
- package/dist/types.d.ts +88 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validators.d.ts +7 -0
- package/dist/validators.js +92 -0
- package/dist/validators.js.map +1 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# gog-safe
|
|
2
|
+
|
|
3
|
+
`gog-safe` is a policy-enforced wrapper around `gog`.
|
|
4
|
+
It blocks disallowed Gmail/Sheets operations, enforces JSON/non-interactive execution, and can run command-specific post-validation.
|
|
5
|
+
|
|
6
|
+
## Safety model
|
|
7
|
+
|
|
8
|
+
- `gog-safe` always returns a unified JSON response for `run`.
|
|
9
|
+
- Validator failures (timeout, non-JSON output, non-zero exit, contract violation) are fail-closed: `safety.action="block"`, `ok=false`.
|
|
10
|
+
- Audit log write failure is fail-open by default (`logging.require_audit_success=false`), and adds `audit_log_write_failed`.
|
|
11
|
+
- If `logging.require_audit_success=true`, audit failure is fail-closed.
|
|
12
|
+
- Final safety status must be read from `safety.action` and `ok`.
|
|
13
|
+
- `allowed` means only allow/deny command decision and does not include validator result.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install
|
|
19
|
+
npm run build
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## CLI
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
gog-safe run --policy ./policy.yml -- sheets get --range A1:B2
|
|
26
|
+
gog-safe validate-policy --policy ./policy.yml
|
|
27
|
+
gog-safe print-effective-policy --policy ./policy.yml
|
|
28
|
+
gog-safe version
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Config files and precedence
|
|
32
|
+
|
|
33
|
+
`gog-safe` merges files in this order:
|
|
34
|
+
|
|
35
|
+
1. `policy.yml` (required)
|
|
36
|
+
2. `~/.gog-safe/config.json` (optional)
|
|
37
|
+
3. First `.gog-safe/config.json` found while walking from current directory to parent directories (optional)
|
|
38
|
+
|
|
39
|
+
Home config is loaded before project config. Project config wins where override applies.
|
|
40
|
+
|
|
41
|
+
## Merge rules
|
|
42
|
+
|
|
43
|
+
- `commands.allow`: override priority (`project > home > policy`)
|
|
44
|
+
- `commands.deny`: union (`policy ∪ home ∪ project`)
|
|
45
|
+
- `validation.rules`: concatenation (`policy + home + project`)
|
|
46
|
+
- `validation.validators`: key merge (`project > home > policy`)
|
|
47
|
+
- `gog`, `execution`, `logging`: key override (`project > home > policy`)
|
|
48
|
+
|
|
49
|
+
## Run behavior
|
|
50
|
+
|
|
51
|
+
`run` enforces flags:
|
|
52
|
+
|
|
53
|
+
- `--json` (when `execution.enforce_json=true`)
|
|
54
|
+
- `--no-input` (when `execution.enforce_no_input=true`)
|
|
55
|
+
- `--account=<gog.account>`
|
|
56
|
+
- `--client=<gog.client>` only when `gog.client` is non-empty
|
|
57
|
+
|
|
58
|
+
User-provided `--json`, `--no-input`, `--account`, `--client` are rejected (including `--k=v` style).
|
|
59
|
+
|
|
60
|
+
`validation.rules.match` is evaluated against the original user argv (before forced flags).
|
|
61
|
+
|
|
62
|
+
v1 intentionally does not validate command option semantics.
|
|
63
|
+
|
|
64
|
+
## Validator contract (`external_command`)
|
|
65
|
+
|
|
66
|
+
stdin JSON:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"command": "gog sheets get --range A1:B2",
|
|
71
|
+
"argv": ["sheets", "get", "--range", "A1:B2"],
|
|
72
|
+
"output": {"...": "..."},
|
|
73
|
+
"policy_version": 1
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
stdout JSON:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"decision": "allow",
|
|
82
|
+
"reason": "safe"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Rules:
|
|
87
|
+
|
|
88
|
+
- timeout / non-JSON / non-zero exit / invalid `decision` or missing `reason` => `block`
|
|
89
|
+
- multiple validators are OR-block
|
|
90
|
+
- when multiple rules match, validators are merged by rule order, deduplicated, and executed in first-seen order
|
|
91
|
+
|
|
92
|
+
## Output schema (`run`)
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"ok": true,
|
|
97
|
+
"allowed": true,
|
|
98
|
+
"command": "gog sheets get",
|
|
99
|
+
"safety": {
|
|
100
|
+
"action": "allow",
|
|
101
|
+
"reasons": []
|
|
102
|
+
},
|
|
103
|
+
"data": {},
|
|
104
|
+
"meta": {
|
|
105
|
+
"policy_version": 1
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Exit codes (`run`)
|
|
111
|
+
|
|
112
|
+
- `0`: final allow (`ok=true`)
|
|
113
|
+
- `2`: policy/validator block (including fail-closed validator or audit when configured)
|
|
114
|
+
- `3`: runtime/system error (gog spawn/timeout/non-zero, invalid gog JSON, internal errors)
|
|
115
|
+
|
|
116
|
+
## Operations examples
|
|
117
|
+
|
|
118
|
+
Project-level deny override:
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"commands": {
|
|
123
|
+
"deny": ["gmail labels *"]
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Project-level allow override:
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"commands": {
|
|
133
|
+
"allow": ["sheets get"]
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Add validator only for `sheets get`:
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"validation": {
|
|
143
|
+
"rules": [
|
|
144
|
+
{ "match": "sheets get", "validators": ["llm-guard"] }
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
package/dist/audit.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface AuditRecord {
|
|
2
|
+
timestamp: string;
|
|
3
|
+
command: string;
|
|
4
|
+
allowed: boolean;
|
|
5
|
+
ok: boolean;
|
|
6
|
+
action: "allow" | "block";
|
|
7
|
+
reasons: string[];
|
|
8
|
+
metadata?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export declare function appendAuditLog(auditFile: string, record: AuditRecord): Promise<void>;
|
package/dist/audit.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { appendFile, mkdir } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export async function appendAuditLog(auditFile, record) {
|
|
4
|
+
const resolved = path.resolve(process.cwd(), auditFile);
|
|
5
|
+
const dir = path.dirname(resolved);
|
|
6
|
+
await mkdir(dir, { recursive: true });
|
|
7
|
+
await appendFile(resolved, `${JSON.stringify(record)}\n`, "utf8");
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,IAAI,MAAM,WAAW,CAAC;AAY7B,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAiB,EAAE,MAAmB;IACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,UAAU,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface CommandDecision {
|
|
2
|
+
allowed: boolean;
|
|
3
|
+
reasons: string[];
|
|
4
|
+
}
|
|
5
|
+
export declare function decideCommandAllowance(positionals: string[], allowPatterns: string[], denyPatterns: string[]): CommandDecision;
|
|
6
|
+
export declare function findForbiddenOverride(argv: string[]): string | undefined;
|
|
7
|
+
export declare function buildForcedArgs(argv: string[], options: {
|
|
8
|
+
enforceJson: boolean;
|
|
9
|
+
enforceNoInput: boolean;
|
|
10
|
+
account: string;
|
|
11
|
+
client: string;
|
|
12
|
+
}): string[];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { matchCommandPattern } from "./matching.js";
|
|
2
|
+
export function decideCommandAllowance(positionals, allowPatterns, denyPatterns) {
|
|
3
|
+
for (const denyPattern of denyPatterns) {
|
|
4
|
+
if (matchCommandPattern(denyPattern, positionals)) {
|
|
5
|
+
return {
|
|
6
|
+
allowed: false,
|
|
7
|
+
reasons: [`command_denied:${denyPattern}`],
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
for (const allowPattern of allowPatterns) {
|
|
12
|
+
if (matchCommandPattern(allowPattern, positionals)) {
|
|
13
|
+
return {
|
|
14
|
+
allowed: true,
|
|
15
|
+
reasons: [`command_allowed:${allowPattern}`],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
allowed: false,
|
|
21
|
+
reasons: ["command_not_allowed"],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const FORBIDDEN_OVERRIDE_OPTIONS = ["--json", "--no-input", "--account", "--client"];
|
|
25
|
+
export function findForbiddenOverride(argv) {
|
|
26
|
+
for (const token of argv) {
|
|
27
|
+
for (const forbidden of FORBIDDEN_OVERRIDE_OPTIONS) {
|
|
28
|
+
if (token === forbidden || token.startsWith(`${forbidden}=`)) {
|
|
29
|
+
return forbidden;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
export function buildForcedArgs(argv, options) {
|
|
36
|
+
const forced = [...argv];
|
|
37
|
+
if (options.enforceJson) {
|
|
38
|
+
forced.push("--json");
|
|
39
|
+
}
|
|
40
|
+
if (options.enforceNoInput) {
|
|
41
|
+
forced.push("--no-input");
|
|
42
|
+
}
|
|
43
|
+
forced.push(`--account=${options.account}`);
|
|
44
|
+
if (options.client.trim().length > 0) {
|
|
45
|
+
forced.push(`--client=${options.client}`);
|
|
46
|
+
}
|
|
47
|
+
return forced;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=command-control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-control.js","sourceRoot":"","sources":["../src/command-control.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAOpD,MAAM,UAAU,sBAAsB,CACpC,WAAqB,EACrB,aAAuB,EACvB,YAAsB;IAEtB,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,IAAI,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;YAClD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,CAAC,kBAAkB,WAAW,EAAE,CAAC;aAC3C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;QACzC,IAAI,mBAAmB,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE,CAAC;YACnD,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC,mBAAmB,YAAY,EAAE,CAAC;aAC7C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,CAAC,qBAAqB,CAAC;KACjC,CAAC;AACJ,CAAC;AAED,MAAM,0BAA0B,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;AAErF,MAAM,UAAU,qBAAqB,CAAC,IAAc;IAClD,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,KAAK,MAAM,SAAS,IAAI,0BAA0B,EAAE,CAAC;YACnD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,SAAS,GAAG,CAAC,EAAE,CAAC;gBAC7D,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,IAAc,EACd,OAKC;IAED,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IAEzB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,aAAa,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAE5C,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/errors.d.ts
ADDED
package/dist/errors.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export class UserInputError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = "UserInputError";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export class PolicyValidationError extends Error {
|
|
8
|
+
issues;
|
|
9
|
+
constructor(issues) {
|
|
10
|
+
super(`Policy validation failed (${issues.length} issue(s))`);
|
|
11
|
+
this.name = "PolicyValidationError";
|
|
12
|
+
this.issues = issues;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IACrC,MAAM,CAAW;IAE1B,YAAY,MAAgB;QAC1B,KAAK,CAAC,6BAA6B,MAAM,CAAC,MAAM,YAAY,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { PolicyValidationError, UserInputError } from "./errors.js";
|
|
6
|
+
import { loadEffectivePolicy } from "./policy.js";
|
|
7
|
+
import { executeRun } from "./run.js";
|
|
8
|
+
function usage() {
|
|
9
|
+
return [
|
|
10
|
+
"Usage:",
|
|
11
|
+
" gog-safe run --policy <path> -- <gog args...>",
|
|
12
|
+
" gog-safe validate-policy --policy <path>",
|
|
13
|
+
" gog-safe print-effective-policy --policy <path>",
|
|
14
|
+
" gog-safe version",
|
|
15
|
+
].join("\n");
|
|
16
|
+
}
|
|
17
|
+
function parsePolicyOption(argv) {
|
|
18
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
19
|
+
if (argv[i] === "--policy") {
|
|
20
|
+
const value = argv[i + 1];
|
|
21
|
+
if (!value || value.startsWith("--")) {
|
|
22
|
+
throw new UserInputError("--policy requires a value");
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
if (argv[i].startsWith("--policy=")) {
|
|
27
|
+
const value = argv[i].slice("--policy=".length);
|
|
28
|
+
if (!value) {
|
|
29
|
+
throw new UserInputError("--policy requires a value");
|
|
30
|
+
}
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
throw new UserInputError("--policy is required");
|
|
35
|
+
}
|
|
36
|
+
function parseRunArgs(argv) {
|
|
37
|
+
const separator = argv.indexOf("--");
|
|
38
|
+
const beforeSeparator = separator >= 0 ? argv.slice(0, separator) : argv;
|
|
39
|
+
const gogArgs = separator >= 0 ? argv.slice(separator + 1) : [];
|
|
40
|
+
const policyPath = parsePolicyOption(beforeSeparator);
|
|
41
|
+
if (gogArgs.length === 0) {
|
|
42
|
+
throw new UserInputError("run requires gog args after '--'");
|
|
43
|
+
}
|
|
44
|
+
return { policyPath, gogArgs };
|
|
45
|
+
}
|
|
46
|
+
async function readPackageVersion() {
|
|
47
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
48
|
+
const currentDir = path.dirname(currentFile);
|
|
49
|
+
const packagePath = path.resolve(currentDir, "..", "package.json");
|
|
50
|
+
const text = await readFile(packagePath, "utf8");
|
|
51
|
+
const pkg = JSON.parse(text);
|
|
52
|
+
return pkg.version ?? "0.0.0";
|
|
53
|
+
}
|
|
54
|
+
function printPolicyError(error) {
|
|
55
|
+
for (const issue of error.issues) {
|
|
56
|
+
console.error(`- ${issue}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function main() {
|
|
60
|
+
const argv = process.argv.slice(2);
|
|
61
|
+
const command = argv[0];
|
|
62
|
+
if (!command) {
|
|
63
|
+
console.error(usage());
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
if (command === "version") {
|
|
68
|
+
console.log(await readPackageVersion());
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
if (command === "validate-policy") {
|
|
72
|
+
const policyPath = parsePolicyOption(argv.slice(1));
|
|
73
|
+
await loadEffectivePolicy(policyPath);
|
|
74
|
+
console.log("policy is valid");
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
if (command === "print-effective-policy") {
|
|
78
|
+
const policyPath = parsePolicyOption(argv.slice(1));
|
|
79
|
+
const loaded = await loadEffectivePolicy(policyPath);
|
|
80
|
+
console.log(JSON.stringify(loaded.effective, null, 2));
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
if (command === "run") {
|
|
84
|
+
const { policyPath, gogArgs } = parseRunArgs(argv.slice(1));
|
|
85
|
+
const result = await executeRun(policyPath, gogArgs);
|
|
86
|
+
console.log(JSON.stringify(result.output));
|
|
87
|
+
for (const warning of result.stderrWarnings) {
|
|
88
|
+
if (warning.trim().length > 0) {
|
|
89
|
+
console.error(warning);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return result.exitCode;
|
|
93
|
+
}
|
|
94
|
+
console.error(`unknown command: ${command}`);
|
|
95
|
+
console.error(usage());
|
|
96
|
+
return 1;
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if (error instanceof PolicyValidationError) {
|
|
100
|
+
printPolicyError(error);
|
|
101
|
+
return 1;
|
|
102
|
+
}
|
|
103
|
+
if (error instanceof UserInputError) {
|
|
104
|
+
console.error(error.message);
|
|
105
|
+
console.error(usage());
|
|
106
|
+
return 1;
|
|
107
|
+
}
|
|
108
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
109
|
+
console.error(message);
|
|
110
|
+
return 1;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
main()
|
|
114
|
+
.then((code) => {
|
|
115
|
+
process.exitCode = code;
|
|
116
|
+
})
|
|
117
|
+
.catch((error) => {
|
|
118
|
+
console.error(error instanceof Error ? error.stack : String(error));
|
|
119
|
+
process.exitCode = 1;
|
|
120
|
+
});
|
|
121
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ArgvAnalysis, ValidationRule } from "./types.js";
|
|
2
|
+
export declare function tokenizePattern(pattern: string): string[];
|
|
3
|
+
export declare function validateCommandPattern(pattern: string): string[];
|
|
4
|
+
export declare function parseArgv(argv: string[]): ArgvAnalysis;
|
|
5
|
+
export declare function matchCommandPattern(pattern: string, positionals: string[]): boolean;
|
|
6
|
+
export declare function parseRuleMatch(match: string): {
|
|
7
|
+
positionals: string[];
|
|
8
|
+
requiredOptions: string[];
|
|
9
|
+
};
|
|
10
|
+
export declare function doesRuleMatch(rule: ValidationRule, analyzed: ArgvAnalysis): boolean;
|
|
11
|
+
export declare function resolveValidatorsForCommand(rules: ValidationRule[], analyzed: ArgvAnalysis): string[];
|
package/dist/matching.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
export function tokenizePattern(pattern) {
|
|
2
|
+
return pattern
|
|
3
|
+
.trim()
|
|
4
|
+
.split(/\s+/)
|
|
5
|
+
.filter((token) => token.length > 0);
|
|
6
|
+
}
|
|
7
|
+
export function validateCommandPattern(pattern) {
|
|
8
|
+
const issues = [];
|
|
9
|
+
const tokens = tokenizePattern(pattern);
|
|
10
|
+
if (tokens.length === 0) {
|
|
11
|
+
issues.push("pattern must not be empty");
|
|
12
|
+
return issues;
|
|
13
|
+
}
|
|
14
|
+
let starIndex = -1;
|
|
15
|
+
tokens.forEach((token, index) => {
|
|
16
|
+
if (token.includes("*") && token !== "*") {
|
|
17
|
+
issues.push(`invalid wildcard token: ${token}`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (token === "*") {
|
|
21
|
+
if (starIndex >= 0) {
|
|
22
|
+
issues.push("wildcard '*' must appear at most once");
|
|
23
|
+
}
|
|
24
|
+
starIndex = index;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
if (starIndex >= 0 && starIndex !== tokens.length - 1) {
|
|
28
|
+
issues.push("wildcard '*' must appear only at the end");
|
|
29
|
+
}
|
|
30
|
+
return issues;
|
|
31
|
+
}
|
|
32
|
+
export function parseArgv(argv) {
|
|
33
|
+
const positionals = [];
|
|
34
|
+
const options = new Set();
|
|
35
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
36
|
+
const token = argv[i];
|
|
37
|
+
if (!token.startsWith("--")) {
|
|
38
|
+
positionals.push(token);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const eqIndex = token.indexOf("=");
|
|
42
|
+
if (eqIndex > 0) {
|
|
43
|
+
options.add(token.slice(0, eqIndex));
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
options.add(token);
|
|
47
|
+
const next = argv[i + 1];
|
|
48
|
+
// v1 minimal parser:
|
|
49
|
+
// `--k v` is treated as option presence and `v` is not positional.
|
|
50
|
+
// Keep consuming unless the next token is another long option.
|
|
51
|
+
if (next && !next.startsWith("--")) {
|
|
52
|
+
i += 1;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return { positionals, options };
|
|
56
|
+
}
|
|
57
|
+
export function matchCommandPattern(pattern, positionals) {
|
|
58
|
+
const tokens = tokenizePattern(pattern);
|
|
59
|
+
if (tokens.length === 0) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
const hasWildcard = tokens[tokens.length - 1] === "*";
|
|
63
|
+
const base = hasWildcard ? tokens.slice(0, -1) : tokens;
|
|
64
|
+
if (hasWildcard) {
|
|
65
|
+
if (positionals.length < base.length) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return base.every((token, index) => token === positionals[index]);
|
|
69
|
+
}
|
|
70
|
+
if (base.length !== positionals.length) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
return base.every((token, index) => token === positionals[index]);
|
|
74
|
+
}
|
|
75
|
+
export function parseRuleMatch(match) {
|
|
76
|
+
const tokens = tokenizePattern(match);
|
|
77
|
+
const positionals = [];
|
|
78
|
+
const requiredOptions = [];
|
|
79
|
+
for (const token of tokens) {
|
|
80
|
+
if (!token.startsWith("--")) {
|
|
81
|
+
positionals.push(token);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const eqIndex = token.indexOf("=");
|
|
85
|
+
requiredOptions.push(eqIndex > 0 ? token.slice(0, eqIndex) : token);
|
|
86
|
+
}
|
|
87
|
+
return { positionals, requiredOptions };
|
|
88
|
+
}
|
|
89
|
+
export function doesRuleMatch(rule, analyzed) {
|
|
90
|
+
const parsed = parseRuleMatch(rule.match);
|
|
91
|
+
if (parsed.positionals.length !== analyzed.positionals.length) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
for (let i = 0; i < parsed.positionals.length; i += 1) {
|
|
95
|
+
if (parsed.positionals[i] !== analyzed.positionals[i]) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return parsed.requiredOptions.every((option) => analyzed.options.has(option));
|
|
100
|
+
}
|
|
101
|
+
export function resolveValidatorsForCommand(rules, analyzed) {
|
|
102
|
+
const merged = [];
|
|
103
|
+
const seen = new Set();
|
|
104
|
+
for (const rule of rules) {
|
|
105
|
+
if (!doesRuleMatch(rule, analyzed)) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
for (const validatorName of rule.validators) {
|
|
109
|
+
if (seen.has(validatorName)) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
seen.add(validatorName);
|
|
113
|
+
merged.push(validatorName);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return merged;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=matching.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matching.js","sourceRoot":"","sources":["../src/matching.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,OAAO,OAAO;SACX,IAAI,EAAE;SACN,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAExC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;IACnB,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC9B,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,2BAA2B,KAAK,EAAE,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QACD,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAClB,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;gBACnB,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;YACvD,CAAC;YACD,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,SAAS,IAAI,CAAC,IAAI,SAAS,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtD,MAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACxB,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YACrC,SAAS;QACX,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEnB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,qBAAqB;QACrB,mEAAmE;QACnE,+DAA+D;QAC/D,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,CAAC,IAAI,CAAC,CAAC;QACT,CAAC;IACH,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAe,EAAE,WAAqB;IACxE,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;IACtD,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAExD,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACrC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM,EAAE,CAAC;QACvC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa;IAI1C,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,eAAe,GAAa,EAAE,CAAC;IAErC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACxB,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,eAAe,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAoB,EAAE,QAAsB;IACxE,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAE1C,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,KAAK,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QAC9D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,KAAuB,EACvB,QAAsB;IAEtB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;YACnC,SAAS;QACX,CAAC;QAED,KAAK,MAAM,aAAa,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5C,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC5B,SAAS;YACX,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/policy.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EffectivePolicy, LoadedConfigSet, PartialConfig } from "./types.js";
|
|
2
|
+
export declare function buildEffectivePolicy(policyConfig: PartialConfig, homeConfig?: PartialConfig, projectConfig?: PartialConfig): EffectivePolicy;
|
|
3
|
+
export declare function validateEffectivePolicy(policy: EffectivePolicy): string[];
|
|
4
|
+
export declare function loadEffectivePolicy(policyPath: string, cwd?: string): Promise<LoadedConfigSet>;
|