@massu/core 1.6.3 → 1.8.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 CHANGED
@@ -31,6 +31,78 @@ npx massu doctor
31
31
  npx massu validate-config
32
32
  ```
33
33
 
34
+ ### Permission Seeding
35
+
36
+ To skip the per-tool MCP permission dialog on a fresh install, `npx massu install-commands` automatically seeds the canonical glob `mcp__massu__*` into `.claude/settings.local.json`'s `permissions.allow` array. It also propagates the user-global `defaultMode` (from `~/.claude/settings.json`) into the project-local file (see "Permissions trap" below).
37
+
38
+ Three lifecycle subcommands for managing the allowlist:
39
+
40
+ ```bash
41
+ # Seed the canonical entry + propagate global defaultMode (idempotent)
42
+ npx massu permissions install
43
+
44
+ # Read-only check — exit 0 if all canonical entries present
45
+ npx massu permissions verify
46
+
47
+ # Extended diagnostic — surfaces 4 drift kinds with severity-mapped exit codes
48
+ npx massu permissions check-drift
49
+ ```
50
+
51
+ To opt out of automatic permission seeding during `install-commands` (e.g., when permissions are managed centrally by enterprise policy):
52
+
53
+ ```bash
54
+ npx massu install-commands --skip-permissions
55
+ ```
56
+
57
+ `defaultMode` validity reference (per [Claude Code docs](https://code.claude.com/docs/en/permission-modes)):
58
+
59
+ | Mode | Activatable from settings file alone | Requires launch flag |
60
+ |---|---|---|
61
+ | `default` | ✓ | — |
62
+ | `acceptEdits` | ✓ | — |
63
+ | `plan` | ✓ | — |
64
+ | `bypassPermissions` | — | `--permission-mode bypassPermissions` or `--dangerously-skip-permissions` |
65
+ | `auto` | — | `--permission-mode auto` (plus plan/admin/model preconditions) |
66
+ | `dontAsk` | — | `--permission-mode dontAsk` |
67
+
68
+ `permissions check-drift` warns when a launch-flag-required value is set in settings without the corresponding flag (these settings are silently inert without the launch flag).
69
+
70
+ ### Permissions trap (settings merge)
71
+
72
+ Empirically observed in Claude Code 2.1.x: a project-local `.claude/settings.local.json` that has a `permissions` object **without** a `defaultMode` key silently STRIPS the user-global `defaultMode` from `~/.claude/settings.json` during settings merge. The merge unit appears to be the entire `permissions` object's top-level keys, not individual keys within it — undocumented at `code.claude.com/docs/en/permissions`.
73
+
74
+ **Before** (trap state):
75
+ ```jsonc
76
+ // ~/.claude/settings.json (global)
77
+ { "permissions": { "defaultMode": "auto" } }
78
+
79
+ // .claude/settings.local.json (project)
80
+ { "permissions": { "allow": ["mcp__massu__*"] } }
81
+ // Effective defaultMode in this project: NONE (global "auto" silently stripped)
82
+ ```
83
+
84
+ **After** (correct state, what `massu permissions install` writes):
85
+ ```jsonc
86
+ // .claude/settings.local.json (project)
87
+ { "permissions": {
88
+ "allow": ["mcp__massu__*"],
89
+ "defaultMode": "auto"
90
+ } }
91
+ ```
92
+
93
+ The install writer:
94
+ 1. Reads global `~/.claude/settings.json`
95
+ 2. Reads project-local `.claude/settings.local.json`
96
+ 3. Computes merged state: `allow` = union with canonical entries; `defaultMode` = local override OR global value OR omit; `deny`/`ask` preserved from local
97
+ 4. Atomic-writes the complete merged block
98
+ 5. Post-write fail-loud assertion: re-reads disk and confirms the merge survived
99
+
100
+ To audit any project for the trap (or any other permission drift):
101
+ ```bash
102
+ npx massu permissions check-drift
103
+ # Exit 4 + stderr "drift[strips-global-defaultmode]: ..." if the trap is present
104
+ ```
105
+
34
106
  ## Documentation
35
107
 
36
108
  Full documentation at [massu.ai](https://massu.ai).