claude-nomad 0.46.0 → 0.47.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/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.47.0](https://github.com/funkadelic/claude-nomad/compare/v0.46.0...v0.47.0) (2026-06-09)
4
+
5
+
6
+ ### Added
7
+
8
+ * **extras:** add .claude as a supported per-project extra ([#274](https://github.com/funkadelic/claude-nomad/issues/274)) ([41a79a3](https://github.com/funkadelic/claude-nomad/commit/41a79a3fa9963f2ade76ec4d89d880d9634bb0d2))
9
+
10
+
11
+ ### Changed
12
+
13
+ * remove orphaned shared/ folder from package ([#267](https://github.com/funkadelic/claude-nomad/issues/267)) ([93e4119](https://github.com/funkadelic/claude-nomad/commit/93e411951df4aa600e94da8d9db4298129ad1fa2))
14
+
15
+
16
+ ### Documentation
17
+
18
+ * **extras:** document .claude extra in security, features, and recovery pages ([#275](https://github.com/funkadelic/claude-nomad/issues/275)) ([232016c](https://github.com/funkadelic/claude-nomad/commit/232016c5cb14988fb3fe8dd3f1f558d49789fffb))
19
+ * **faq:** explain unmapped local projects in nomad doctor ([#273](https://github.com/funkadelic/claude-nomad/issues/273)) ([6c2e9d4](https://github.com/funkadelic/claude-nomad/commit/6c2e9d475decb8cea3e159a3047f5f9daff24785))
20
+
21
+
22
+ ### Dependencies
23
+
24
+ * bump @types/node in the dev-dependencies group ([#272](https://github.com/funkadelic/claude-nomad/issues/272)) ([951471e](https://github.com/funkadelic/claude-nomad/commit/951471e0879eee0e10756f67a9e58554dce96c52))
25
+ * bump actions/checkout from 6.0.2 to 6.0.3 ([#269](https://github.com/funkadelic/claude-nomad/issues/269)) ([21b7490](https://github.com/funkadelic/claude-nomad/commit/21b7490b273bfe22aa76216edc5de44a49b57c59))
26
+ * bump codecov/codecov-action from 6.0.1 to 7.0.0 ([#270](https://github.com/funkadelic/claude-nomad/issues/270)) ([905d468](https://github.com/funkadelic/claude-nomad/commit/905d46832e6d52c825419be39fac08d5408de39f))
27
+ * bump github/codeql-action from 4.36.0 to 4.36.2 ([#271](https://github.com/funkadelic/claude-nomad/issues/271)) ([6ff50c7](https://github.com/funkadelic/claude-nomad/commit/6ff50c76d3ddc9e0cd8247f572288b722cd588b5))
28
+
3
29
  ## [0.46.0](https://github.com/funkadelic/claude-nomad/compare/v0.45.0...v0.46.0) (2026-06-08)
4
30
 
5
31
 
package/dist/nomad.mjs CHANGED
@@ -33,7 +33,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
33
  ));
34
34
 
35
35
  // src/config.never-sync.ts
36
- var NEVER_SYNC;
36
+ var NEVER_SYNC, CLAUDE_EXTRA_NEVER_SYNC;
37
37
  var init_config_never_sync = __esm({
38
38
  "src/config.never-sync.ts"() {
39
39
  "use strict";
@@ -62,6 +62,7 @@ var init_config_never_sync = __esm({
62
62
  "security",
63
63
  "sessions"
64
64
  ]);
65
+ CLAUDE_EXTRA_NEVER_SYNC = /* @__PURE__ */ new Set([...NEVER_SYNC, "projects"]);
65
66
  }
66
67
  });
67
68
 
@@ -407,7 +408,7 @@ var init_config = __esm({
407
408
  "my-statusline.cjs",
408
409
  "hooks"
409
410
  ];
410
- SUPPORTED_EXTRAS = [".planning", "CLAUDE.md"];
411
+ SUPPORTED_EXTRAS = [".planning", "CLAUDE.md", ".claude"];
411
412
  ALWAYS_NEVER_SYNC = /* @__PURE__ */ new Set([
412
413
  ".claude.json",
413
414
  ".credentials.json",
@@ -4240,7 +4241,7 @@ function listDivergingFiles(a, b) {
4240
4241
  // src/extras-sync.core.ts
4241
4242
  init_config();
4242
4243
  import { cpSync as cpSync6, existsSync as existsSync30, rmSync as rmSync10 } from "node:fs";
4243
- import { join as join36 } from "node:path";
4244
+ import { basename, join as join36 } from "node:path";
4244
4245
 
4245
4246
  // src/extras-sync.guards.ts
4246
4247
  init_utils();
@@ -4301,6 +4302,18 @@ function copyExtras(src, dst) {
4301
4302
  rmSync10(dst, { recursive: true, force: true });
4302
4303
  cpSync6(src, dst, { recursive: true, force: true, verbatimSymlinks: true });
4303
4304
  }
4305
+ function extrasDenySet(dirname7) {
4306
+ return dirname7 === ".claude" ? CLAUDE_EXTRA_NEVER_SYNC : ALWAYS_NEVER_SYNC;
4307
+ }
4308
+ function copyExtrasFiltered(src, dst, blockSet) {
4309
+ rmSync10(dst, { recursive: true, force: true });
4310
+ cpSync6(src, dst, {
4311
+ recursive: true,
4312
+ force: true,
4313
+ verbatimSymlinks: true,
4314
+ filter: (srcEntry) => srcEntry === src || !blockSet.has(basename(srcEntry))
4315
+ });
4316
+ }
4304
4317
 
4305
4318
  // src/extras-sync.ts
4306
4319
  init_utils();
@@ -4311,7 +4324,7 @@ init_config();
4311
4324
  import { existsSync as existsSync31, mkdirSync as mkdirSync7 } from "node:fs";
4312
4325
  import { join as join37 } from "node:path";
4313
4326
  init_utils_fs();
4314
- function runExtrasOp(v, dryRun, paths, backup) {
4327
+ function runExtrasOp(v, dryRun, paths, backup, copy) {
4315
4328
  const counts = { unmapped: 0, skipped: 0 };
4316
4329
  const done = [];
4317
4330
  const would = [];
@@ -4324,7 +4337,7 @@ function runExtrasOp(v, dryRun, paths, backup) {
4324
4337
  continue;
4325
4338
  }
4326
4339
  backup(dst, t.localRoot);
4327
- copyExtras(src, dst);
4340
+ copy(src, dst, t.dirname);
4328
4341
  done.push(item2);
4329
4342
  }
4330
4343
  return { ...counts, done, would };
@@ -4343,7 +4356,10 @@ function remapExtrasPush(ts, opts = {}) {
4343
4356
  src: join37(localRoot, dirname7),
4344
4357
  dst: join37(repoExtras, logical, dirname7)
4345
4358
  }),
4346
- (dst) => backupRepoWrite(dst, ts, repo)
4359
+ (dst) => backupRepoWrite(dst, ts, repo),
4360
+ // Push filters every extra by its per-name denylist: `.claude` gets the
4361
+ // full NEVER_SYNC boundary, `.planning` keeps the narrow ALWAYS_NEVER_SYNC.
4362
+ (src, dst, dirname7) => copyExtrasFiltered(src, dst, extrasDenySet(dirname7))
4347
4363
  );
4348
4364
  return { unmapped, skipped, pushed: done, wouldPush: would };
4349
4365
  }
@@ -4364,7 +4380,13 @@ function remapExtrasPull(ts, opts = {}) {
4364
4380
  }),
4365
4381
  // Snapshot the host-side dst BEFORE copyExtras clobbers it. Anchor on
4366
4382
  // localRoot so the backup tree mirrors the project layout.
4367
- (dst, localRoot) => backupExtrasWrite(dst, ts, localRoot)
4383
+ (dst, localRoot) => backupExtrasWrite(dst, ts, localRoot),
4384
+ // Pull filters `.claude` against its NEVER_SYNC boundary so a repo poisoned
4385
+ // out-of-band cannot restore a blocked per-host file (e.g. settings.local.json)
4386
+ // onto this host. Other extras use the exact-mirror copyExtras: the repo is
4387
+ // clean once push filters, and exact mirror is the documented restore for
4388
+ // `.planning`.
4389
+ (src, dst, dirname7) => dirname7 === ".claude" ? copyExtrasFiltered(src, dst, extrasDenySet(dirname7)) : copyExtras(src, dst)
4368
4390
  );
4369
4391
  return { unmapped, skipped, pulled: done, wouldPull: would };
4370
4392
  }
@@ -5055,9 +5077,15 @@ function isAllowed(path, allowed) {
5055
5077
  }
5056
5078
  return false;
5057
5079
  }
5080
+ function blockSetFor(segments) {
5081
+ if (segments[0] !== "shared" || segments[1] !== "extras") return NEVER_SYNC;
5082
+ return segments[3] === ".claude" ? CLAUDE_EXTRA_NEVER_SYNC : ALWAYS_NEVER_SYNC;
5083
+ }
5058
5084
  function isNeverSync(path) {
5059
- const blockSet = path.startsWith("shared/extras/") ? ALWAYS_NEVER_SYNC : NEVER_SYNC;
5060
- for (const segment of path.split("/")) {
5085
+ const segments = path.split("/");
5086
+ const blockSet = blockSetFor(segments);
5087
+ const scan = segments[0] === "shared" && segments[1] === "extras" ? segments.slice(4) : segments;
5088
+ for (const segment of scan) {
5061
5089
  if (blockSet.has(segment)) return true;
5062
5090
  }
5063
5091
  return false;
@@ -5802,7 +5830,7 @@ function parsePushArgs(argv) {
5802
5830
  // package.json
5803
5831
  var package_default = {
5804
5832
  name: "claude-nomad",
5805
- version: "0.46.0",
5833
+ version: "0.47.0",
5806
5834
  type: "module",
5807
5835
  description: "Sync Claude Code config (~/.claude/) across machines via a private Git repo, with path remapping and per-host settings overrides.",
5808
5836
  keywords: [
@@ -5825,7 +5853,6 @@ var package_default = {
5825
5853
  },
5826
5854
  files: [
5827
5855
  "dist/",
5828
- "shared/.gitignore",
5829
5856
  ".gitleaks.toml",
5830
5857
  "README.md",
5831
5858
  "CHANGELOG.md",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-nomad",
3
- "version": "0.46.0",
3
+ "version": "0.47.0",
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": [
@@ -23,7 +23,6 @@
23
23
  },
24
24
  "files": [
25
25
  "dist/",
26
- "shared/.gitignore",
27
26
  ".gitleaks.toml",
28
27
  "README.md",
29
28
  "CHANGELOG.md",
package/shared/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- *.token
2
- *.key
3
- .env
4
- .env.*
5
- .claude.json
6
- settings.local.json
7
- *.pem
8
- id_rsa
9
- id_ed25519