claude-permissions-manager 0.6.0 → 0.9.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 +53 -6
- package/dist/cli.js +28 -14
- package/dist/cli.js.map +1 -1
- package/dist/commands/audit.d.ts +1 -0
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +29 -2
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/completion.d.ts +0 -7
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +36 -12
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +67 -11
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +21 -6
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +11 -10
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +11 -4
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/manage.d.ts +5 -0
- package/dist/commands/manage.d.ts.map +1 -1
- package/dist/commands/manage.js +74 -15
- package/dist/commands/manage.js.map +1 -1
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +3 -2
- package/dist/commands/show.js.map +1 -1
- package/dist/core/discovery.d.ts +0 -1
- package/dist/core/discovery.d.ts.map +1 -1
- package/dist/core/discovery.js +22 -10
- package/dist/core/discovery.js.map +1 -1
- package/dist/core/merger.d.ts.map +1 -1
- package/dist/core/merger.js +67 -3
- package/dist/core/merger.js.map +1 -1
- package/dist/core/parser.d.ts.map +1 -1
- package/dist/core/parser.js +6 -2
- package/dist/core/parser.js.map +1 -1
- package/dist/core/schemas.d.ts +0 -1
- package/dist/core/schemas.d.ts.map +1 -1
- package/dist/core/schemas.js.map +1 -1
- package/dist/core/types.d.ts +3 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +2 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/writer.d.ts +6 -1
- package/dist/core/writer.d.ts.map +1 -1
- package/dist/core/writer.js +10 -3
- package/dist/core/writer.js.map +1 -1
- package/dist/tui/app.d.ts.map +1 -1
- package/dist/tui/app.js +15 -4
- package/dist/tui/app.js.map +1 -1
- package/dist/tui/components/Header.d.ts.map +1 -1
- package/dist/tui/components/Header.js +1 -1
- package/dist/tui/components/Header.js.map +1 -1
- package/dist/tui/screens/Audit.d.ts +3 -2
- package/dist/tui/screens/Audit.d.ts.map +1 -1
- package/dist/tui/screens/Audit.js +21 -20
- package/dist/tui/screens/Audit.js.map +1 -1
- package/dist/tui/screens/Diff.d.ts.map +1 -1
- package/dist/tui/screens/Diff.js +38 -14
- package/dist/tui/screens/Diff.js.map +1 -1
- package/dist/tui/screens/ProjectDetail.d.ts.map +1 -1
- package/dist/tui/screens/ProjectDetail.js +10 -3
- package/dist/tui/screens/ProjectDetail.js.map +1 -1
- package/dist/tui/screens/ProjectList.js +2 -2
- package/dist/tui/screens/ProjectList.js.map +1 -1
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +6 -0
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/paths.d.ts +0 -4
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +6 -22
- package/dist/utils/paths.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -70,12 +70,54 @@ cpm mode acceptEdits --project ~/my-project --scope project
|
|
|
70
70
|
### Flags
|
|
71
71
|
|
|
72
72
|
```
|
|
73
|
-
--root <dir>
|
|
74
|
-
--depth <n>
|
|
75
|
-
--json
|
|
76
|
-
--no-global
|
|
73
|
+
--root <dir> Override scan root (default: ~)
|
|
74
|
+
--depth <n> Max directory depth for scanning (default: 8)
|
|
75
|
+
--json Output as JSON (list, show, audit, diff, export)
|
|
76
|
+
--no-global Skip user/managed global settings (list, audit, export, ui)
|
|
77
|
+
--exit-code Exit 1 if issues found, 2 if critical issues (audit only — useful in CI)
|
|
78
|
+
--dry-run Preview what would be written without modifying files (allow, deny, ask, mode, reset --all)
|
|
79
|
+
--format <fmt> Output format: json|csv (export only, default: json)
|
|
80
|
+
--output <file> Write output to file instead of stdout (export only)
|
|
77
81
|
```
|
|
78
82
|
|
|
83
|
+
#### Exit codes
|
|
84
|
+
|
|
85
|
+
All commands exit `0` on success and `1` on error (missing `.claude` directory, invalid arguments, file I/O failure).
|
|
86
|
+
|
|
87
|
+
`cpm audit --exit-code` uses additional codes:
|
|
88
|
+
|
|
89
|
+
| Code | Meaning |
|
|
90
|
+
|------|---------|
|
|
91
|
+
| `0` | No issues found |
|
|
92
|
+
| `1` | Warnings found (high, medium, or low severity) |
|
|
93
|
+
| `2` | Critical issues found |
|
|
94
|
+
|
|
95
|
+
#### Path arguments
|
|
96
|
+
|
|
97
|
+
`cpm` does **not** expand a bare `~` — use `~/` (with trailing slash) or a full path:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
cpm show ~/my-project # ✓ works
|
|
101
|
+
cpm show ~ # ✗ won't expand to home directory
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### JSON output format
|
|
105
|
+
|
|
106
|
+
When using `--json`, allow/deny/ask rules are emitted as objects with `rule` and `scope` fields (consistent across `list`, `show`, `diff`, and `export`):
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"allow": [
|
|
111
|
+
{ "rule": "Bash(npm run *)", "scope": "project" },
|
|
112
|
+
{ "rule": "Read", "scope": "user" }
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`scope` is one of `"managed"`, `"user"`, `"project"`, or `"local"`.
|
|
118
|
+
|
|
119
|
+
`cpm diff --json` additionally wraps rule arrays into `onlyInA`, `onlyInB`, and `inBoth` sub-keys. `inBoth` entries are plain strings (the scope is the same in both projects by definition).
|
|
120
|
+
|
|
79
121
|
## Shell completion
|
|
80
122
|
|
|
81
123
|
```bash
|
|
@@ -98,12 +140,17 @@ Run `cpm` (or `cpm ui`) for the interactive terminal UI:
|
|
|
98
140
|
- `d` — diff two projects
|
|
99
141
|
- `q` — quit
|
|
100
142
|
|
|
143
|
+
In the audit screen:
|
|
144
|
+
- `↑↓` / `j`/`k` — navigate warnings
|
|
145
|
+
- `Enter` — jump to that project's detail screen (back returns to audit)
|
|
146
|
+
- `←` / `Esc` / `q` — back to list
|
|
147
|
+
|
|
101
148
|
In project detail (permissions tab):
|
|
102
149
|
- `1` / `2` / `3` — switch tabs (permissions / MCP / warnings)
|
|
103
150
|
- `j`/`k` — move cursor through rules
|
|
104
151
|
- `a` — add allow rule, `d` — add deny rule, `s` — add ask rule
|
|
105
152
|
- `x` — delete selected rule
|
|
106
|
-
- `←` / `Esc` / `q` — back
|
|
153
|
+
- `←` / `Esc` / `q` — back
|
|
107
154
|
|
|
108
155
|
## What it reads
|
|
109
156
|
|
|
@@ -126,4 +173,4 @@ Values from all scopes are merged. Deny rules at any scope win absolutely.
|
|
|
126
173
|
|
|
127
174
|
## Requirements
|
|
128
175
|
|
|
129
|
-
Node.js ≥
|
|
176
|
+
Node.js ≥ 20
|
package/dist/cli.js
CHANGED
|
@@ -4,11 +4,16 @@ import { listCommand } from "./commands/list.js";
|
|
|
4
4
|
import { showCommand } from "./commands/show.js";
|
|
5
5
|
import { auditCommand } from "./commands/audit.js";
|
|
6
6
|
import { homeDir } from "./utils/paths.js";
|
|
7
|
+
import { PermissionModeSchema } from "./core/schemas.js";
|
|
8
|
+
function parseDepth(raw, fallback = 8) {
|
|
9
|
+
const n = parseInt(raw, 10);
|
|
10
|
+
return Number.isFinite(n) && n >= 0 ? n : fallback;
|
|
11
|
+
}
|
|
7
12
|
const program = new Command();
|
|
8
13
|
program
|
|
9
14
|
.name("cpm")
|
|
10
15
|
.description("Claude Permissions Manager — discover and manage Claude Code permissions")
|
|
11
|
-
.version("0.
|
|
16
|
+
.version("0.9.0");
|
|
12
17
|
// Default action: TUI when TTY, list otherwise
|
|
13
18
|
program.action(async () => {
|
|
14
19
|
// If any non-option args were passed, they didn't match a known subcommand
|
|
@@ -19,10 +24,10 @@ program.action(async () => {
|
|
|
19
24
|
}
|
|
20
25
|
if (process.stdout.isTTY) {
|
|
21
26
|
const { uiCommand } = await import("./commands/ui.js");
|
|
22
|
-
await uiCommand({ root: homeDir() });
|
|
27
|
+
await uiCommand({ root: homeDir(), maxDepth: 8, includeGlobal: true });
|
|
23
28
|
}
|
|
24
29
|
else {
|
|
25
|
-
await listCommand({ root: homeDir() });
|
|
30
|
+
await listCommand({ root: homeDir(), maxDepth: 8, includeGlobal: true });
|
|
26
31
|
}
|
|
27
32
|
});
|
|
28
33
|
program
|
|
@@ -30,11 +35,13 @@ program
|
|
|
30
35
|
.description("Launch interactive TUI")
|
|
31
36
|
.option("--root <dir>", "Root directory to scan from", homeDir())
|
|
32
37
|
.option("--depth <n>", "Max scan depth", "8")
|
|
38
|
+
.option("--no-global", "Skip user and managed global settings")
|
|
33
39
|
.action(async (opts) => {
|
|
34
40
|
const { uiCommand } = await import("./commands/ui.js");
|
|
35
41
|
await uiCommand({
|
|
36
42
|
root: opts.root,
|
|
37
|
-
maxDepth:
|
|
43
|
+
maxDepth: parseDepth(opts.depth),
|
|
44
|
+
includeGlobal: opts.global !== false,
|
|
38
45
|
});
|
|
39
46
|
});
|
|
40
47
|
program
|
|
@@ -47,7 +54,7 @@ program
|
|
|
47
54
|
.action(async (opts) => {
|
|
48
55
|
await listCommand({
|
|
49
56
|
root: opts.root,
|
|
50
|
-
maxDepth:
|
|
57
|
+
maxDepth: parseDepth(opts.depth),
|
|
51
58
|
json: opts.json,
|
|
52
59
|
includeGlobal: opts.global !== false,
|
|
53
60
|
});
|
|
@@ -66,12 +73,14 @@ program
|
|
|
66
73
|
.option("--depth <n>", "Max scan depth", "8")
|
|
67
74
|
.option("--json", "Output as JSON")
|
|
68
75
|
.option("--no-global", "Skip user and managed global settings")
|
|
76
|
+
.option("--exit-code", "Exit with code 1 (issues found) or 2 (critical issues) for CI use")
|
|
69
77
|
.action(async (opts) => {
|
|
70
78
|
await auditCommand({
|
|
71
79
|
root: opts.root,
|
|
72
|
-
maxDepth:
|
|
80
|
+
maxDepth: parseDepth(opts.depth),
|
|
73
81
|
json: opts.json,
|
|
74
82
|
includeGlobal: opts.global !== false,
|
|
83
|
+
exitCode: opts.exitCode,
|
|
75
84
|
});
|
|
76
85
|
});
|
|
77
86
|
program
|
|
@@ -87,27 +96,30 @@ program
|
|
|
87
96
|
.description('Add a rule to the allow list (e.g. cpm allow "Bash(npm run *)")')
|
|
88
97
|
.option("--scope <scope>", "Settings scope: local|project|user (default: local)", "local")
|
|
89
98
|
.option("--project <path>", "Project path for local/project scope (default: cwd)")
|
|
99
|
+
.option("--dry-run", "Preview what would be written without modifying any files")
|
|
90
100
|
.action(async (rule, opts) => {
|
|
91
101
|
const { allowCommand } = await import("./commands/manage.js");
|
|
92
|
-
await allowCommand(rule, opts);
|
|
102
|
+
await allowCommand(rule, { ...opts, dryRun: opts.dryRun });
|
|
93
103
|
});
|
|
94
104
|
program
|
|
95
105
|
.command("deny <rule>")
|
|
96
106
|
.description('Add a rule to the deny list (e.g. cpm deny "Read(**/.env)")')
|
|
97
107
|
.option("--scope <scope>", "Settings scope: local|project|user (default: local)", "local")
|
|
98
108
|
.option("--project <path>", "Project path for local/project scope (default: cwd)")
|
|
109
|
+
.option("--dry-run", "Preview what would be written without modifying any files")
|
|
99
110
|
.action(async (rule, opts) => {
|
|
100
111
|
const { denyCommand } = await import("./commands/manage.js");
|
|
101
|
-
await denyCommand(rule, opts);
|
|
112
|
+
await denyCommand(rule, { ...opts, dryRun: opts.dryRun });
|
|
102
113
|
});
|
|
103
114
|
program
|
|
104
115
|
.command("ask <rule>")
|
|
105
116
|
.description('Add a rule to the ask list (always prompt for confirmation)')
|
|
106
117
|
.option("--scope <scope>", "Settings scope: local|project|user (default: local)", "local")
|
|
107
118
|
.option("--project <path>", "Project path for local/project scope (default: cwd)")
|
|
119
|
+
.option("--dry-run", "Preview what would be written without modifying any files")
|
|
108
120
|
.action(async (rule, opts) => {
|
|
109
121
|
const { askCommand } = await import("./commands/manage.js");
|
|
110
|
-
await askCommand(rule, opts);
|
|
122
|
+
await askCommand(rule, { ...opts, dryRun: opts.dryRun });
|
|
111
123
|
});
|
|
112
124
|
program
|
|
113
125
|
.command("reset [rule]")
|
|
@@ -115,11 +127,12 @@ program
|
|
|
115
127
|
.option("--scope <scope>", "Settings scope: local|project|user (default: local)", "local")
|
|
116
128
|
.option("--project <path>", "Project path for local/project scope (default: cwd)")
|
|
117
129
|
.option("--all", "Clear all permission rules")
|
|
118
|
-
.option("--yes", "Skip confirmation prompt")
|
|
130
|
+
.option("--yes", "Skip confirmation prompt (with --all)")
|
|
131
|
+
.option("--dry-run", "Preview what would be cleared without modifying any files (with --all)")
|
|
119
132
|
.action(async (rule, opts) => {
|
|
120
133
|
const { resetRuleCommand, resetAllCommand } = await import("./commands/manage.js");
|
|
121
134
|
if (opts.all) {
|
|
122
|
-
await resetAllCommand(opts);
|
|
135
|
+
await resetAllCommand({ ...opts, dryRun: opts.dryRun });
|
|
123
136
|
}
|
|
124
137
|
else if (rule) {
|
|
125
138
|
await resetRuleCommand(rule, opts);
|
|
@@ -131,12 +144,13 @@ program
|
|
|
131
144
|
});
|
|
132
145
|
program
|
|
133
146
|
.command("mode <mode>")
|
|
134
|
-
.description(
|
|
147
|
+
.description(`Set defaultMode: ${PermissionModeSchema.options.join("|")}`)
|
|
135
148
|
.option("--scope <scope>", "Settings scope: local|project|user (default: local)", "local")
|
|
136
149
|
.option("--project <path>", "Project path for local/project scope (default: cwd)")
|
|
150
|
+
.option("--dry-run", "Preview what would be written without modifying any files")
|
|
137
151
|
.action(async (mode, opts) => {
|
|
138
152
|
const { modeCommand } = await import("./commands/manage.js");
|
|
139
|
-
await modeCommand(mode, opts);
|
|
153
|
+
await modeCommand(mode, { ...opts, dryRun: opts.dryRun });
|
|
140
154
|
});
|
|
141
155
|
program
|
|
142
156
|
.command("export")
|
|
@@ -150,7 +164,7 @@ program
|
|
|
150
164
|
const { exportCommand } = await import("./commands/export.js");
|
|
151
165
|
await exportCommand({
|
|
152
166
|
root: opts.root,
|
|
153
|
-
maxDepth:
|
|
167
|
+
maxDepth: parseDepth(opts.depth),
|
|
154
168
|
format: opts.format,
|
|
155
169
|
output: opts.output,
|
|
156
170
|
includeGlobal: opts.global !== false,
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/audit.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,wBAAsB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,wBAAsB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiF/G"}
|
package/dist/commands/audit.js
CHANGED
|
@@ -15,13 +15,33 @@ export async function auditCommand(options) {
|
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
+
const exitWithCode = () => {
|
|
19
|
+
if (options.exitCode && allIssues.length > 0) {
|
|
20
|
+
const hasCritical = allIssues.some((i) => i.severity === "critical");
|
|
21
|
+
process.exit(hasCritical ? 2 : 1);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
18
24
|
if (options.json) {
|
|
19
|
-
console.log(JSON.stringify({
|
|
25
|
+
console.log(JSON.stringify({
|
|
26
|
+
generatedAt: result.scannedAt.toISOString(),
|
|
27
|
+
scanRoot: result.scanRoot,
|
|
28
|
+
projectCount: result.projects.length,
|
|
29
|
+
issueCount: allIssues.length,
|
|
30
|
+
issues: allIssues,
|
|
31
|
+
errors: result.errors,
|
|
32
|
+
}, null, 2));
|
|
33
|
+
exitWithCode();
|
|
20
34
|
return;
|
|
21
35
|
}
|
|
22
36
|
if (allIssues.length === 0) {
|
|
23
37
|
console.log(chalk.green(`\n✓ No issues found across ${result.projects.length} project(s).`));
|
|
24
|
-
|
|
38
|
+
if (result.errors.length > 0) {
|
|
39
|
+
console.log(chalk.red(`\n${result.errors.length} scan error(s) — some projects could not be checked:`));
|
|
40
|
+
for (const e of result.errors) {
|
|
41
|
+
console.log(chalk.red(` ${collapseHome(e.path)}: ${e.error}`));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return; // exit 0
|
|
25
45
|
}
|
|
26
46
|
const bySeverity = {
|
|
27
47
|
critical: allIssues.filter((i) => i.severity === "critical"),
|
|
@@ -42,5 +62,12 @@ export async function auditCommand(options) {
|
|
|
42
62
|
}
|
|
43
63
|
console.log("");
|
|
44
64
|
}
|
|
65
|
+
if (result.errors.length > 0) {
|
|
66
|
+
console.log(chalk.red(`${result.errors.length} scan error(s) — some projects could not be checked:`));
|
|
67
|
+
for (const e of result.errors) {
|
|
68
|
+
console.log(chalk.red(` ${collapseHome(e.path)}: ${e.error}`));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exitWithCode();
|
|
45
72
|
}
|
|
46
73
|
//# sourceMappingURL=audit.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shell completion for cpm.
|
|
3
|
-
*
|
|
4
|
-
* Usage:
|
|
5
|
-
* eval "$(cpm completion bash)" # add to ~/.bashrc
|
|
6
|
-
* eval "$(cpm completion zsh)" # add to ~/.zshrc
|
|
7
|
-
*/
|
|
8
1
|
export declare function completionCommand(shell: string): Promise<void>;
|
|
9
2
|
//# sourceMappingURL=completion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/commands/completion.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/commands/completion.ts"],"names":[],"mappings":"AAgSA,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASpE"}
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* eval "$(cpm completion bash)" # add to ~/.bashrc
|
|
6
6
|
* eval "$(cpm completion zsh)" # add to ~/.zshrc
|
|
7
7
|
*/
|
|
8
|
+
import { PermissionModeSchema } from "../core/schemas.js";
|
|
9
|
+
import { WRITABLE_SCOPES } from "../core/types.js";
|
|
8
10
|
const COMMANDS = [
|
|
9
11
|
"ui",
|
|
10
12
|
"list",
|
|
@@ -20,8 +22,8 @@ const COMMANDS = [
|
|
|
20
22
|
"init",
|
|
21
23
|
"completion",
|
|
22
24
|
];
|
|
23
|
-
const SCOPES =
|
|
24
|
-
const MODES =
|
|
25
|
+
const SCOPES = WRITABLE_SCOPES;
|
|
26
|
+
const MODES = PermissionModeSchema.options;
|
|
25
27
|
const PRESETS = ["safe", "node", "strict"];
|
|
26
28
|
const FORMATS = ["json", "csv"];
|
|
27
29
|
// Bash completion script
|
|
@@ -54,6 +56,10 @@ _cpm_completions() {
|
|
|
54
56
|
COMPREPLY=( \$(compgen -W "${presetList}" -- "\${cur}") )
|
|
55
57
|
return 0
|
|
56
58
|
;;
|
|
59
|
+
--mode)
|
|
60
|
+
COMPREPLY=( \$(compgen -W "${modeList}" -- "\${cur}") )
|
|
61
|
+
return 0
|
|
62
|
+
;;
|
|
57
63
|
--root|--project|--output)
|
|
58
64
|
COMPREPLY=( \$(compgen -d -- "\${cur}") )
|
|
59
65
|
return 0
|
|
@@ -81,14 +87,26 @@ _cpm_completions() {
|
|
|
81
87
|
mode)
|
|
82
88
|
if [[ "\${cur}" != -* ]]; then
|
|
83
89
|
COMPREPLY=( \$(compgen -W "${modeList}" -- "\${cur}") )
|
|
84
|
-
|
|
90
|
+
else
|
|
91
|
+
COMPREPLY=( \$(compgen -W "--scope --project --dry-run" -- "\${cur}") )
|
|
85
92
|
fi
|
|
93
|
+
return 0
|
|
86
94
|
;;
|
|
87
|
-
show
|
|
95
|
+
show)
|
|
88
96
|
if [[ "\${cur}" != -* ]]; then
|
|
89
97
|
COMPREPLY=( \$(compgen -d -- "\${cur}") )
|
|
90
|
-
|
|
98
|
+
else
|
|
99
|
+
COMPREPLY=( \$(compgen -W "--json" -- "\${cur}") )
|
|
91
100
|
fi
|
|
101
|
+
return 0
|
|
102
|
+
;;
|
|
103
|
+
diff)
|
|
104
|
+
if [[ "\${cur}" != -* ]]; then
|
|
105
|
+
COMPREPLY=( \$(compgen -d -- "\${cur}") )
|
|
106
|
+
else
|
|
107
|
+
COMPREPLY=( \$(compgen -W "--json" -- "\${cur}") )
|
|
108
|
+
fi
|
|
109
|
+
return 0
|
|
92
110
|
;;
|
|
93
111
|
completion)
|
|
94
112
|
COMPREPLY=( \$(compgen -W "bash zsh" -- "\${cur}") )
|
|
@@ -99,11 +117,11 @@ _cpm_completions() {
|
|
|
99
117
|
return 0
|
|
100
118
|
;;
|
|
101
119
|
ui)
|
|
102
|
-
COMPREPLY=( \$(compgen -W "--root --depth --
|
|
120
|
+
COMPREPLY=( \$(compgen -W "--root --depth --no-global" -- "\${cur}") )
|
|
103
121
|
return 0
|
|
104
122
|
;;
|
|
105
123
|
audit)
|
|
106
|
-
COMPREPLY=( \$(compgen -W "--root --depth --json --no-global" -- "\${cur}") )
|
|
124
|
+
COMPREPLY=( \$(compgen -W "--root --depth --json --no-global --exit-code" -- "\${cur}") )
|
|
107
125
|
return 0
|
|
108
126
|
;;
|
|
109
127
|
export)
|
|
@@ -111,11 +129,11 @@ _cpm_completions() {
|
|
|
111
129
|
return 0
|
|
112
130
|
;;
|
|
113
131
|
allow|deny|ask)
|
|
114
|
-
COMPREPLY=( \$(compgen -W "--scope --project" -- "\${cur}") )
|
|
132
|
+
COMPREPLY=( \$(compgen -W "--scope --project --dry-run" -- "\${cur}") )
|
|
115
133
|
return 0
|
|
116
134
|
;;
|
|
117
135
|
reset)
|
|
118
|
-
COMPREPLY=( \$(compgen -W "--scope --project --all --yes" -- "\${cur}") )
|
|
136
|
+
COMPREPLY=( \$(compgen -W "--scope --project --all --yes --dry-run" -- "\${cur}") )
|
|
119
137
|
return 0
|
|
120
138
|
;;
|
|
121
139
|
init)
|
|
@@ -182,10 +200,13 @@ ${commandDefs}
|
|
|
182
200
|
_arguments \\
|
|
183
201
|
'--scope[Settings scope]:scope:(${scopeList})' \\
|
|
184
202
|
'--project[Project path]:project:_directories' \\
|
|
203
|
+
'--dry-run[Preview without writing]' \\
|
|
185
204
|
'1:mode:(${modeList})'
|
|
186
205
|
;;
|
|
187
206
|
show)
|
|
188
|
-
_arguments
|
|
207
|
+
_arguments \\
|
|
208
|
+
'1:project:_directories' \\
|
|
209
|
+
'--json[Output as JSON]'
|
|
189
210
|
;;
|
|
190
211
|
diff)
|
|
191
212
|
_arguments \\
|
|
@@ -197,6 +218,7 @@ ${commandDefs}
|
|
|
197
218
|
_arguments \\
|
|
198
219
|
'--scope[Settings scope]:scope:(${scopeList})' \\
|
|
199
220
|
'--project[Project path]:project:_directories' \\
|
|
221
|
+
'--dry-run[Preview without writing]' \\
|
|
200
222
|
'1:rule:'
|
|
201
223
|
;;
|
|
202
224
|
reset)
|
|
@@ -205,6 +227,7 @@ ${commandDefs}
|
|
|
205
227
|
'--project[Project path]:project:_directories' \\
|
|
206
228
|
'--all[Clear all rules]' \\
|
|
207
229
|
'--yes[Skip confirmation]' \\
|
|
230
|
+
'--dry-run[Preview without writing]' \\
|
|
208
231
|
'1:rule:'
|
|
209
232
|
;;
|
|
210
233
|
init)
|
|
@@ -226,14 +249,15 @@ ${commandDefs}
|
|
|
226
249
|
_arguments \\
|
|
227
250
|
'--root[Root directory]:root:_directories' \\
|
|
228
251
|
'--depth[Max scan depth]:depth:' \\
|
|
229
|
-
'--
|
|
252
|
+
'--no-global[Skip user and managed global settings]'
|
|
230
253
|
;;
|
|
231
254
|
audit)
|
|
232
255
|
_arguments \\
|
|
233
256
|
'--root[Root directory]:root:_directories' \\
|
|
234
257
|
'--depth[Max scan depth]:depth:' \\
|
|
235
258
|
'--json[Output as JSON]' \\
|
|
236
|
-
'--no-global[Skip user and managed global settings]'
|
|
259
|
+
'--no-global[Skip user and managed global settings]' \\
|
|
260
|
+
'--exit-code[Exit 1 if issues, 2 if critical (for CI)]'
|
|
237
261
|
;;
|
|
238
262
|
export)
|
|
239
263
|
_arguments \\
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../src/commands/completion.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../src/commands/completion.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAMA,wBAAsB,WAAW,CAC/B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5B,OAAO,CAAC,IAAI,CAAC,CAqOf"}
|
package/dist/commands/diff.js
CHANGED
|
@@ -5,6 +5,9 @@ import { expandHome, collapseHome } from "../utils/paths.js";
|
|
|
5
5
|
export async function diffCommand(path1, path2, opts = {}) {
|
|
6
6
|
const root1 = resolve(expandHome(path1));
|
|
7
7
|
const root2 = resolve(expandHome(path2));
|
|
8
|
+
if (root1 === root2) {
|
|
9
|
+
console.log(chalk.yellow("Note: comparing a project with itself — paths resolve to the same directory."));
|
|
10
|
+
}
|
|
8
11
|
const [result1, result2] = await Promise.all([
|
|
9
12
|
scan({ root: root1, maxDepth: 1 }),
|
|
10
13
|
scan({ root: root2, maxDepth: 1 }),
|
|
@@ -24,20 +27,38 @@ export async function diffCommand(path1, path2, opts = {}) {
|
|
|
24
27
|
const mcpNamesA = new Set(p1.mcpServers.map((s) => s.name));
|
|
25
28
|
const mcpNamesB = new Set(p2.mcpServers.map((s) => s.name));
|
|
26
29
|
if (opts.json) {
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const
|
|
30
|
+
// Pre-compute Sets for O(1) lookup instead of O(n) per-item scan
|
|
31
|
+
const p1AllowRaws = new Set(p1.allow.map((r) => r.raw));
|
|
32
|
+
const p2AllowRaws = new Set(p2.allow.map((r) => r.raw));
|
|
33
|
+
const p1DenyRaws = new Set(p1.deny.map((r) => r.raw));
|
|
34
|
+
const p2DenyRaws = new Set(p2.deny.map((r) => r.raw));
|
|
35
|
+
const p1AskRaws = new Set(p1.ask.map((r) => r.raw));
|
|
36
|
+
const p2AskRaws = new Set(p2.ask.map((r) => r.raw));
|
|
37
|
+
const toRuleObj = (r) => ({ rule: r.raw, scope: r.scope });
|
|
38
|
+
const allowOnlyA = p1.allow.filter((r) => !p2AllowRaws.has(r.raw)).map(toRuleObj);
|
|
39
|
+
const allowOnlyB = p2.allow.filter((r) => !p1AllowRaws.has(r.raw)).map(toRuleObj);
|
|
40
|
+
const denyOnlyA = p1.deny.filter((r) => !p2DenyRaws.has(r.raw)).map(toRuleObj);
|
|
41
|
+
const denyOnlyB = p2.deny.filter((r) => !p1DenyRaws.has(r.raw)).map(toRuleObj);
|
|
42
|
+
const askOnlyA = p1.ask.filter((r) => !p2AskRaws.has(r.raw)).map(toRuleObj);
|
|
43
|
+
const askOnlyB = p2.ask.filter((r) => !p1AskRaws.has(r.raw)).map(toRuleObj);
|
|
33
44
|
const mcpOnlyA = [...mcpNamesA].filter((n) => !mcpNamesB.has(n));
|
|
34
45
|
const mcpOnlyB = [...mcpNamesB].filter((n) => !mcpNamesA.has(n));
|
|
46
|
+
const envNamesA = new Set(p1.envVarNames);
|
|
47
|
+
const envNamesB = new Set(p2.envVarNames);
|
|
48
|
+
const envOnlyA = p1.envVarNames.filter((v) => !envNamesB.has(v));
|
|
49
|
+
const envOnlyB = p2.envVarNames.filter((v) => !envNamesA.has(v));
|
|
50
|
+
const dirNamesA = new Set(p1.additionalDirs);
|
|
51
|
+
const dirNamesB = new Set(p2.additionalDirs);
|
|
52
|
+
const dirsOnlyA = p1.additionalDirs.filter((d) => !dirNamesB.has(d));
|
|
53
|
+
const dirsOnlyB = p2.additionalDirs.filter((d) => !dirNamesA.has(d));
|
|
35
54
|
const identical = p1.defaultMode === p2.defaultMode &&
|
|
36
55
|
p1.isBypassDisabled === p2.isBypassDisabled &&
|
|
37
56
|
allowOnlyA.length === 0 && allowOnlyB.length === 0 &&
|
|
38
57
|
denyOnlyA.length === 0 && denyOnlyB.length === 0 &&
|
|
39
58
|
askOnlyA.length === 0 && askOnlyB.length === 0 &&
|
|
40
|
-
mcpOnlyA.length === 0 && mcpOnlyB.length === 0
|
|
59
|
+
mcpOnlyA.length === 0 && mcpOnlyB.length === 0 &&
|
|
60
|
+
envOnlyA.length === 0 && envOnlyB.length === 0 &&
|
|
61
|
+
dirsOnlyA.length === 0 && dirsOnlyB.length === 0;
|
|
41
62
|
const output = {
|
|
42
63
|
projectA: root1,
|
|
43
64
|
projectB: root2,
|
|
@@ -47,23 +68,33 @@ export async function diffCommand(path1, path2, opts = {}) {
|
|
|
47
68
|
allow: {
|
|
48
69
|
onlyInA: allowOnlyA,
|
|
49
70
|
onlyInB: allowOnlyB,
|
|
50
|
-
inBoth: p1.allow.filter((r) =>
|
|
71
|
+
inBoth: p1.allow.filter((r) => p2AllowRaws.has(r.raw)).map((r) => r.raw),
|
|
51
72
|
},
|
|
52
73
|
deny: {
|
|
53
74
|
onlyInA: denyOnlyA,
|
|
54
75
|
onlyInB: denyOnlyB,
|
|
55
|
-
inBoth: p1.deny.filter((r) =>
|
|
76
|
+
inBoth: p1.deny.filter((r) => p2DenyRaws.has(r.raw)).map((r) => r.raw),
|
|
56
77
|
},
|
|
57
78
|
ask: {
|
|
58
79
|
onlyInA: askOnlyA,
|
|
59
80
|
onlyInB: askOnlyB,
|
|
60
|
-
inBoth: p1.ask.filter((r) =>
|
|
81
|
+
inBoth: p1.ask.filter((r) => p2AskRaws.has(r.raw)).map((r) => r.raw),
|
|
61
82
|
},
|
|
62
83
|
mcpServers: {
|
|
63
84
|
onlyInA: mcpOnlyA,
|
|
64
85
|
onlyInB: mcpOnlyB,
|
|
65
86
|
inBoth: [...mcpNamesA].filter((n) => mcpNamesB.has(n)),
|
|
66
87
|
},
|
|
88
|
+
envVarNames: {
|
|
89
|
+
onlyInA: envOnlyA,
|
|
90
|
+
onlyInB: envOnlyB,
|
|
91
|
+
inBoth: p1.envVarNames.filter((v) => envNamesB.has(v)),
|
|
92
|
+
},
|
|
93
|
+
additionalDirs: {
|
|
94
|
+
onlyInA: dirsOnlyA,
|
|
95
|
+
onlyInB: dirsOnlyB,
|
|
96
|
+
inBoth: p1.additionalDirs.filter((d) => dirNamesB.has(d)),
|
|
97
|
+
},
|
|
67
98
|
};
|
|
68
99
|
console.log(JSON.stringify(output, null, 2));
|
|
69
100
|
return;
|
|
@@ -111,6 +142,29 @@ export async function diffCommand(path1, path2, opts = {}) {
|
|
|
111
142
|
printDiff("ALLOW", p1.allow, p2.allow, "green");
|
|
112
143
|
printDiff("DENY", p1.deny, p2.deny, "red");
|
|
113
144
|
printDiff("ASK", p1.ask, p2.ask, "yellow");
|
|
145
|
+
// Helper for plain string set diffs (env vars, dirs)
|
|
146
|
+
function printStringsDiff(label, a, b) {
|
|
147
|
+
const setA = new Set(a);
|
|
148
|
+
const setB = new Set(b);
|
|
149
|
+
const all = new Set([...setA, ...setB]);
|
|
150
|
+
if (all.size === 0)
|
|
151
|
+
return;
|
|
152
|
+
console.log(chalk.bold(label));
|
|
153
|
+
for (const v of all) {
|
|
154
|
+
if (setA.has(v) && setB.has(v)) {
|
|
155
|
+
console.log(chalk.gray(` = ${v}`));
|
|
156
|
+
}
|
|
157
|
+
else if (setA.has(v)) {
|
|
158
|
+
console.log(chalk.red(` - ${v} (only in A)`));
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
console.log(chalk.green(` + ${v} (only in B)`));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
console.log("");
|
|
165
|
+
}
|
|
166
|
+
printStringsDiff("ENV VARS", p1.envVarNames, p2.envVarNames);
|
|
167
|
+
printStringsDiff("ADDITIONAL DIRS", p1.additionalDirs, p2.additionalDirs);
|
|
114
168
|
// MCP servers diff
|
|
115
169
|
const allMcp = new Set([...mcpNamesA, ...mcpNamesB]);
|
|
116
170
|
if (allMcp.size > 0) {
|
|
@@ -153,7 +207,9 @@ export async function diffCommand(path1, path2, opts = {}) {
|
|
|
153
207
|
!setsEqual(p1.allow, p2.allow) ||
|
|
154
208
|
!setsEqual(p1.deny, p2.deny) ||
|
|
155
209
|
!setsEqual(p1.ask, p2.ask) ||
|
|
156
|
-
!setsOfStringsEqual(mcpNamesA, mcpNamesB)
|
|
210
|
+
!setsOfStringsEqual(mcpNamesA, mcpNamesB) ||
|
|
211
|
+
!setsOfStringsEqual(new Set(p1.envVarNames), new Set(p2.envVarNames)) ||
|
|
212
|
+
!setsOfStringsEqual(new Set(p1.additionalDirs), new Set(p2.additionalDirs));
|
|
157
213
|
if (!hasChanges) {
|
|
158
214
|
console.log(chalk.green("✓ Projects have identical effective permissions."));
|
|
159
215
|
}
|