wayfind 2.0.79 → 2.0.80
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/bin/team-context.js
CHANGED
|
@@ -2942,6 +2942,40 @@ function ensureStateWritePermissions() {
|
|
|
2942
2942
|
return added;
|
|
2943
2943
|
}
|
|
2944
2944
|
|
|
2945
|
+
/**
|
|
2946
|
+
* Ensure ~/.claude/settings.json has the PermissionRequest hook that auto-approves
|
|
2947
|
+
* Write calls to Wayfind state files. The permissions.allow list doesn't suppress
|
|
2948
|
+
* Claude Code's sensitive-file prompt for ~/.claude/ paths; a PermissionRequest hook
|
|
2949
|
+
* returning {"decision":"allow"} does.
|
|
2950
|
+
* Idempotent — no-ops if the hook command is already registered.
|
|
2951
|
+
* @returns {boolean} true if the hook was added
|
|
2952
|
+
*/
|
|
2953
|
+
function ensurePermissionRequestHook() {
|
|
2954
|
+
if (!HOME) return false;
|
|
2955
|
+
const settingsPath = path.join(HOME, '.claude', 'settings.json');
|
|
2956
|
+
const hookCommand = 'bash ~/.claude/hooks/allow-wayfind-writes.sh';
|
|
2957
|
+
|
|
2958
|
+
let settings = {};
|
|
2959
|
+
if (fs.existsSync(settingsPath)) {
|
|
2960
|
+
try { settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8')); } catch { return false; }
|
|
2961
|
+
}
|
|
2962
|
+
|
|
2963
|
+
if (!settings.hooks) settings.hooks = {};
|
|
2964
|
+
if (!Array.isArray(settings.hooks.PermissionRequest)) settings.hooks.PermissionRequest = [];
|
|
2965
|
+
|
|
2966
|
+
const alreadyRegistered = settings.hooks.PermissionRequest.some(entry =>
|
|
2967
|
+
Array.isArray(entry.hooks) && entry.hooks.some(h => h.command === hookCommand)
|
|
2968
|
+
);
|
|
2969
|
+
if (alreadyRegistered) return false;
|
|
2970
|
+
|
|
2971
|
+
settings.hooks.PermissionRequest.push({
|
|
2972
|
+
matcher: 'Write',
|
|
2973
|
+
hooks: [{ type: 'command', command: hookCommand, timeout: 5000 }],
|
|
2974
|
+
});
|
|
2975
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
2976
|
+
return true;
|
|
2977
|
+
}
|
|
2978
|
+
|
|
2945
2979
|
/**
|
|
2946
2980
|
* Re-sync hooks and commands from the installed Wayfind package to ~/.claude/.
|
|
2947
2981
|
* Copies hook scripts and slash-command files, overwriting stale copies.
|
|
@@ -3026,6 +3060,15 @@ function runUpdate() {
|
|
|
3026
3060
|
for (const p of addedPerms) console.log(` ✓ Allowlisted: ${p}`);
|
|
3027
3061
|
console.log(' (Prevents plan-mode prompts on journal and state-file writes)');
|
|
3028
3062
|
}
|
|
3063
|
+
|
|
3064
|
+
// Register PermissionRequest hook to suppress sensitive-file prompts for
|
|
3065
|
+
// ~/.claude/ paths, which the allowlist alone cannot suppress.
|
|
3066
|
+
const hookAdded = ensurePermissionRequestHook();
|
|
3067
|
+
if (hookAdded) {
|
|
3068
|
+
console.log('\n── PermissionRequest hook ──');
|
|
3069
|
+
console.log(' ✓ Registered allow-wayfind-writes.sh');
|
|
3070
|
+
console.log(' (Suppresses sensitive-file prompts for ~/.claude/ paths)');
|
|
3071
|
+
}
|
|
3029
3072
|
}
|
|
3030
3073
|
|
|
3031
3074
|
// ── Migrate to plugin ───────────────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -146,10 +146,12 @@ Read the repo's `CLAUDE.md`. If it does NOT already contain "Session State Proto
|
|
|
146
146
|
|
|
147
147
|
If `CLAUDE.md` doesn't exist, create a minimal one with the repo name as a heading and the block above.
|
|
148
148
|
|
|
149
|
-
## Step 4.5: Patch Write Permissions in ~/.claude/settings.json
|
|
149
|
+
## Step 4.5: Patch Write Permissions and PermissionRequest Hook in ~/.claude/settings.json
|
|
150
150
|
|
|
151
151
|
Read `~/.claude/settings.json` (create it as `{}` if missing).
|
|
152
152
|
|
|
153
|
+
### Part A: Write allowlist
|
|
154
|
+
|
|
153
155
|
Ensure the following entries are present in `permissions.allow`. Add any that are missing — do NOT remove existing entries.
|
|
154
156
|
|
|
155
157
|
Each path needs two forms: absolute (for tools that resolve paths before the permission check) and literal (tilde or relative, for tools that pass the path as-is). Both are required — Claude Code matches against the literal `file_path` argument, not the resolved path.
|
|
@@ -169,9 +171,44 @@ Write(.claude/personal-state.md)
|
|
|
169
171
|
|
|
170
172
|
Where `<HOME>` is the user's actual home directory (e.g. `/home/greg` or `/Users/greg`).
|
|
171
173
|
|
|
172
|
-
|
|
174
|
+
### Part B: PermissionRequest hook
|
|
175
|
+
|
|
176
|
+
Claude Code has a hardcoded sensitive-file check for `~/.claude/` paths that fires **independently** of `permissions.allow` — the allowlist alone cannot suppress it. A `PermissionRequest` hook is required.
|
|
177
|
+
|
|
178
|
+
First verify `~/.claude/hooks/allow-wayfind-writes.sh` exists. If missing, create it:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
#!/usr/bin/env bash
|
|
182
|
+
input=$(cat)
|
|
183
|
+
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
184
|
+
[ -z "$file_path" ] && exit 0
|
|
185
|
+
expanded="${file_path/#\~/$HOME}"
|
|
186
|
+
if [[ "$expanded" == "$HOME/.claude/memory/"* ]] || \
|
|
187
|
+
[[ "$expanded" == "$HOME/.claude/global-state.md" ]] || \
|
|
188
|
+
[[ "$expanded" == "$HOME/.claude/state.md" ]] || \
|
|
189
|
+
[[ "$expanded" == *"/.claude/team-state.md" ]] || \
|
|
190
|
+
[[ "$expanded" == *"/.claude/personal-state.md" ]]; then
|
|
191
|
+
echo '{"decision": "allow"}'
|
|
192
|
+
exit 0
|
|
193
|
+
fi
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Make it executable: `chmod +x ~/.claude/hooks/allow-wayfind-writes.sh`
|
|
197
|
+
|
|
198
|
+
Then ensure this entry is present in `hooks.PermissionRequest` in `~/.claude/settings.json`:
|
|
199
|
+
|
|
200
|
+
```json
|
|
201
|
+
{
|
|
202
|
+
"matcher": "Write",
|
|
203
|
+
"hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/allow-wayfind-writes.sh", "timeout": 5000 }]
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Add it if missing — do NOT remove existing entries in the array.
|
|
208
|
+
|
|
209
|
+
**Why:** Without Part A, plan-mode users get prompted on every journal write. Without Part B, even bypass-mode users see "sensitive file" prompts for `~/.claude/` paths — which the allowlist cannot suppress.
|
|
173
210
|
|
|
174
|
-
Report: "Write permissions patched — N entries added" (or "already present" if nothing changed).
|
|
211
|
+
Report: "Write permissions patched — N entries added; PermissionRequest hook registered" (or "already present" for each if nothing changed).
|
|
175
212
|
|
|
176
213
|
## Step 5: Register State Files in Global Index
|
|
177
214
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Auto-approve Write permission requests for known-safe Wayfind state files.
|
|
3
|
+
# Runs as a PermissionRequest hook so it fires before Claude Code's sensitive-file
|
|
4
|
+
# prompt — the allowlist in settings.json doesn't suppress that prompt.
|
|
5
|
+
#
|
|
6
|
+
# Returns {"decision": "allow"} for matched paths, exits 0 with no output otherwise
|
|
7
|
+
# (Claude Code falls through to its normal permission handling).
|
|
8
|
+
|
|
9
|
+
input=$(cat)
|
|
10
|
+
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
11
|
+
|
|
12
|
+
[ -z "$file_path" ] && exit 0
|
|
13
|
+
|
|
14
|
+
# Expand leading tilde to $HOME
|
|
15
|
+
expanded="${file_path/#\~/$HOME}"
|
|
16
|
+
|
|
17
|
+
if [[ "$expanded" == "$HOME/.claude/memory/"* ]] || \
|
|
18
|
+
[[ "$expanded" == "$HOME/.claude/global-state.md" ]] || \
|
|
19
|
+
[[ "$expanded" == "$HOME/.claude/state.md" ]] || \
|
|
20
|
+
[[ "$expanded" == *"/.claude/team-state.md" ]] || \
|
|
21
|
+
[[ "$expanded" == *"/.claude/personal-state.md" ]]; then
|
|
22
|
+
echo '{"decision": "allow"}'
|
|
23
|
+
exit 0
|
|
24
|
+
fi
|