wayfind 2.0.78 → 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
|
@@ -2908,12 +2908,21 @@ function ensureStateWritePermissions() {
|
|
|
2908
2908
|
if (!HOME) return [];
|
|
2909
2909
|
const settingsPath = path.join(HOME, '.claude', 'settings.json');
|
|
2910
2910
|
|
|
2911
|
+
// Each path is listed twice: once as absolute (for tools that resolve paths)
|
|
2912
|
+
// and once as the literal form Claude Code may pass (tilde or relative).
|
|
2913
|
+
// Permission matching is against the literal file_path argument, not the
|
|
2914
|
+
// resolved path, so both forms are needed.
|
|
2911
2915
|
const required = [
|
|
2912
2916
|
`Write(${HOME}/.claude/memory/**)`,
|
|
2917
|
+
`Write(~/.claude/memory/**)`,
|
|
2913
2918
|
`Write(${HOME}/.claude/global-state.md)`,
|
|
2919
|
+
`Write(~/.claude/global-state.md)`,
|
|
2914
2920
|
`Write(${HOME}/.claude/state.md)`,
|
|
2921
|
+
`Write(~/.claude/state.md)`,
|
|
2915
2922
|
`Write(${HOME}/**/.claude/team-state.md)`,
|
|
2923
|
+
`Write(.claude/team-state.md)`,
|
|
2916
2924
|
`Write(${HOME}/**/.claude/personal-state.md)`,
|
|
2925
|
+
`Write(.claude/personal-state.md)`,
|
|
2917
2926
|
];
|
|
2918
2927
|
|
|
2919
2928
|
let settings = {};
|
|
@@ -2933,6 +2942,40 @@ function ensureStateWritePermissions() {
|
|
|
2933
2942
|
return added;
|
|
2934
2943
|
}
|
|
2935
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
|
+
|
|
2936
2979
|
/**
|
|
2937
2980
|
* Re-sync hooks and commands from the installed Wayfind package to ~/.claude/.
|
|
2938
2981
|
* Copies hook scripts and slash-command files, overwriting stale copies.
|
|
@@ -3017,6 +3060,15 @@ function runUpdate() {
|
|
|
3017
3060
|
for (const p of addedPerms) console.log(` ✓ Allowlisted: ${p}`);
|
|
3018
3061
|
console.log(' (Prevents plan-mode prompts on journal and state-file writes)');
|
|
3019
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
|
+
}
|
|
3020
3072
|
}
|
|
3021
3073
|
|
|
3022
3074
|
// ── Migrate to plugin ───────────────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -146,25 +146,69 @@ 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
|
-
|
|
153
|
+
### Part A: Write allowlist
|
|
154
|
+
|
|
155
|
+
Ensure the following entries are present in `permissions.allow`. Add any that are missing — do NOT remove existing entries.
|
|
156
|
+
|
|
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.
|
|
154
158
|
|
|
155
159
|
```
|
|
156
160
|
Write(<HOME>/.claude/memory/**)
|
|
161
|
+
Write(~/.claude/memory/**)
|
|
157
162
|
Write(<HOME>/.claude/global-state.md)
|
|
163
|
+
Write(~/.claude/global-state.md)
|
|
158
164
|
Write(<HOME>/.claude/state.md)
|
|
165
|
+
Write(~/.claude/state.md)
|
|
159
166
|
Write(<HOME>/**/.claude/team-state.md)
|
|
167
|
+
Write(.claude/team-state.md)
|
|
160
168
|
Write(<HOME>/**/.claude/personal-state.md)
|
|
169
|
+
Write(.claude/personal-state.md)
|
|
161
170
|
```
|
|
162
171
|
|
|
163
172
|
Where `<HOME>` is the user's actual home directory (e.g. `/home/greg` or `/Users/greg`).
|
|
164
173
|
|
|
165
|
-
|
|
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.
|
|
166
210
|
|
|
167
|
-
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).
|
|
168
212
|
|
|
169
213
|
## Step 5: Register State Files in Global Index
|
|
170
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
|