claude-nomad 0.52.2 → 0.52.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.52.4](https://github.com/funkadelic/claude-nomad/compare/v0.52.3...v0.52.4) (2026-06-20)
4
+
5
+
6
+ ### Fixed
7
+
8
+ * **hooks-filter:** detect gsd hook entries with quoted launcher paths ([#325](https://github.com/funkadelic/claude-nomad/issues/325)) ([71d79f4](https://github.com/funkadelic/claude-nomad/commit/71d79f4a1555a3bfcf2537d02cad2f52612cc8fc))
9
+
10
+ ## [0.52.3](https://github.com/funkadelic/claude-nomad/compare/v0.52.2...v0.52.3) (2026-06-20)
11
+
12
+
13
+ ### Fixed
14
+
15
+ * **diff:** strip gsd hook entries from both sides of settings preview ([#323](https://github.com/funkadelic/claude-nomad/issues/323)) ([5d52583](https://github.com/funkadelic/claude-nomad/commit/5d52583b397b70e68ef4fde9d47af83830fe9c77))
16
+
3
17
  ## [0.52.2](https://github.com/funkadelic/claude-nomad/compare/v0.52.1...v0.52.2) (2026-06-19)
4
18
 
5
19
 
package/README.md CHANGED
@@ -40,7 +40,8 @@ survives different file paths and your secrets never ride along.
40
40
  - **Every push is secret-scanned.** Only an explicit allow-list of paths ever leaves the machine,
41
41
  credentials never sync, and gitleaks scans the exact files about to be published. The push aborts
42
42
  on any hit, with an interactive menu to redact, allow, or drop the finding.
43
- - **Preview before you trust it.** `nomad diff` shows offline what a pull would change, and
43
+ - **Preview before you trust it.** `nomad diff` shows offline what a pull would change (gsd-owned
44
+ hook churn is filtered the same as on pull, so the preview matches what a real pull writes), and
44
45
  `--dry-run` on pull and push prints the plan without writing anything.
45
46
  - **One command tells you what is wrong.** `nomad doctor` is a read-only health check: wedged sync
46
47
  repo, broken hook references, hooks that would crash on session start because of a missing
package/dist/nomad.mjs CHANGED
@@ -1277,6 +1277,16 @@ function scriptBasename(token) {
1277
1277
  const lastSlash = Math.max(token.lastIndexOf("/"), token.lastIndexOf("\\"));
1278
1278
  return lastSlash >= 0 ? token.slice(lastSlash + 1) : token;
1279
1279
  }
1280
+ function stripQuotes(token) {
1281
+ if (token.length >= 2) {
1282
+ const head = token.at(0);
1283
+ const tail = token.at(-1);
1284
+ if (head === '"' && tail === '"' || head === "'" && tail === "'") {
1285
+ return token.slice(1, -1);
1286
+ }
1287
+ }
1288
+ return token;
1289
+ }
1280
1290
  function isGsdHookEntry(command) {
1281
1291
  const tokens = command.trim().split(/\s+/);
1282
1292
  if (tokens.length === 0 || tokens[0] === "") return false;
@@ -1285,7 +1295,7 @@ function isGsdHookEntry(command) {
1285
1295
  while (i < tokens.length && envAssign.test(tokens[i])) {
1286
1296
  i++;
1287
1297
  }
1288
- const first = tokens[i] ?? "";
1298
+ const first = stripQuotes(tokens[i] ?? "");
1289
1299
  const firstBase = scriptBasename(first);
1290
1300
  const firstHasPath = first.includes("/") || first.includes("\\");
1291
1301
  if (firstHasPath && !KNOWN_LAUNCHER_BASENAMES.has(firstBase) || first.startsWith(GSD_PREFIX)) {
@@ -1293,7 +1303,7 @@ function isGsdHookEntry(command) {
1293
1303
  }
1294
1304
  for (let j = i + 1; j < tokens.length; j++) {
1295
1305
  if (tokens[j].startsWith("-")) continue;
1296
- return scriptBasename(tokens[j]).startsWith(GSD_PREFIX);
1306
+ return scriptBasename(stripQuotes(tokens[j])).startsWith(GSD_PREFIX);
1297
1307
  }
1298
1308
  return false;
1299
1309
  }
@@ -5558,14 +5568,15 @@ function previewSettings(basePath, hostPath, settingsPath) {
5558
5568
  if (hostOverrides === null && existsSync36(hostPath)) {
5559
5569
  notes.push(`malformed hosts/${HOST}.json; ignoring overrides`);
5560
5570
  }
5561
- const merged = deepMerge(base, hostOverrides ?? {});
5571
+ const merged = stripGsdHookEntries(deepMerge(base, hostOverrides ?? {}));
5562
5572
  const current = readJsonOrNull(settingsPath);
5563
5573
  if (current === null && existsSync36(settingsPath)) {
5564
5574
  return { diff: "", notes: [...notes, "malformed; skipping diff"] };
5565
5575
  }
5566
- const rawEqual = JSON.stringify(current ?? {}, null, 2) === JSON.stringify(merged, null, 2);
5576
+ const strippedCurrent = stripGsdHookEntries(current ?? {});
5577
+ const rawEqual = JSON.stringify(strippedCurrent, null, 2) === JSON.stringify(merged, null, 2);
5567
5578
  const diff = diffJsonStrings(
5568
- JSON.stringify(sortKeysDeep(current ?? {}), null, 2),
5579
+ JSON.stringify(sortKeysDeep(strippedCurrent), null, 2),
5569
5580
  JSON.stringify(sortKeysDeep(merged), null, 2)
5570
5581
  );
5571
5582
  if (diff === "" && !rawEqual) notes.push(CANONICAL_ORDER_NOTE);
@@ -6794,7 +6805,7 @@ function parsePushArgs(argv) {
6794
6805
  // package.json
6795
6806
  var package_default = {
6796
6807
  name: "claude-nomad",
6797
- version: "0.52.2",
6808
+ version: "0.52.4",
6798
6809
  type: "module",
6799
6810
  description: "Sync Claude Code config (~/.claude/) across machines via a private Git repo, with path remapping and per-host settings overrides.",
6800
6811
  keywords: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-nomad",
3
- "version": "0.52.2",
3
+ "version": "0.52.4",
4
4
  "type": "module",
5
5
  "description": "Sync Claude Code config (~/.claude/) across machines via a private Git repo, with path remapping and per-host settings overrides.",
6
6
  "keywords": [