claude-nomad 0.38.0 → 0.39.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 +31 -0
- package/dist/nomad.mjs +252 -244
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.39.0](https://github.com/funkadelic/claude-nomad/compare/v0.38.1...v0.39.0) (2026-06-02)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
* **doctor:** group version checks into Nomad + Dependency sections ([#228](https://github.com/funkadelic/claude-nomad/issues/228)) ([08e8bf7](https://github.com/funkadelic/claude-nomad/commit/08e8bf79a730f1e7f025a1c2ad9dd406f586b05e))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
* **how-it-works:** render repo-layout trees with FileTree ([#229](https://github.com/funkadelic/claude-nomad/issues/229)) ([b52de15](https://github.com/funkadelic/claude-nomad/commit/b52de152416ac5dabb650a1970b53a3b45262396))
|
|
14
|
+
|
|
15
|
+
## [0.38.1](https://github.com/funkadelic/claude-nomad/compare/v0.38.0...v0.38.1) (2026-06-02)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
* **docs:** base-qualify internal links so they resolve under /claude-nomad ([#222](https://github.com/funkadelic/claude-nomad/issues/222)) ([8cff369](https://github.com/funkadelic/claude-nomad/commit/8cff3691687d07eb4c0f54f9f7fdbf680342c2e4))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
* adopt fallow analyzer config ([#227](https://github.com/funkadelic/claude-nomad/issues/227)) ([ebf7ca0](https://github.com/funkadelic/claude-nomad/commit/ebf7ca0aa05510fa9edde5f408e951b7bfec05ab))
|
|
26
|
+
* break import cycles and trim unused exports ([#225](https://github.com/funkadelic/claude-nomad/issues/225)) ([1808539](https://github.com/funkadelic/claude-nomad/commit/180853964c1d09153b3c9e1272255e2a753bd6d3))
|
|
27
|
+
* **tests:** don't cancel in-progress push:main coverage runs ([#226](https://github.com/funkadelic/claude-nomad/issues/226)) ([3164283](https://github.com/funkadelic/claude-nomad/commit/31642839a5be85e3e9a966411bf5b839226616e8))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Documentation
|
|
31
|
+
|
|
32
|
+
* document ALWAYS_NEVER_SYNC credential hard-block in docs-site ([#224](https://github.com/funkadelic/claude-nomad/issues/224)) ([8904a4a](https://github.com/funkadelic/claude-nomad/commit/8904a4a8685f555e399dd394b825018e2055d373))
|
|
33
|
+
|
|
3
34
|
## [0.38.0](https://github.com/funkadelic/claude-nomad/compare/v0.37.0...v0.38.0) (2026-06-02)
|
|
4
35
|
|
|
5
36
|
|
package/dist/nomad.mjs
CHANGED
|
@@ -32,6 +32,39 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
32
32
|
mod
|
|
33
33
|
));
|
|
34
34
|
|
|
35
|
+
// src/config.never-sync.ts
|
|
36
|
+
var NEVER_SYNC;
|
|
37
|
+
var init_config_never_sync = __esm({
|
|
38
|
+
"src/config.never-sync.ts"() {
|
|
39
|
+
"use strict";
|
|
40
|
+
NEVER_SYNC = /* @__PURE__ */ new Set([
|
|
41
|
+
".claude.json",
|
|
42
|
+
".credentials.json",
|
|
43
|
+
"history.jsonl",
|
|
44
|
+
"settings.local.json",
|
|
45
|
+
"stats-cache.json",
|
|
46
|
+
"todos",
|
|
47
|
+
"shell-snapshots",
|
|
48
|
+
"debug",
|
|
49
|
+
"file-history",
|
|
50
|
+
"plans",
|
|
51
|
+
"session-env",
|
|
52
|
+
"statsig",
|
|
53
|
+
"telemetry",
|
|
54
|
+
"ide",
|
|
55
|
+
// Host-local caches and runtime state (sharedDirs guard also rejects these).
|
|
56
|
+
"cache",
|
|
57
|
+
"backups",
|
|
58
|
+
"paste-cache",
|
|
59
|
+
"daemon",
|
|
60
|
+
"jobs",
|
|
61
|
+
"tasks",
|
|
62
|
+
"security",
|
|
63
|
+
"sessions"
|
|
64
|
+
]);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
35
68
|
// node_modules/picocolors/picocolors.js
|
|
36
69
|
var require_picocolors = __commonJS({
|
|
37
70
|
"node_modules/picocolors/picocolors.js"(exports, module) {
|
|
@@ -189,7 +222,7 @@ var SAFE_LOGICAL, SAFE_SEGMENT, RESERVED_SHARED;
|
|
|
189
222
|
var init_config_sharedDirs_guard = __esm({
|
|
190
223
|
"src/config.sharedDirs.guard.ts"() {
|
|
191
224
|
"use strict";
|
|
192
|
-
|
|
225
|
+
init_config_never_sync();
|
|
193
226
|
init_utils();
|
|
194
227
|
SAFE_LOGICAL = /^[A-Za-z0-9._-]+$/;
|
|
195
228
|
SAFE_SEGMENT = /^[A-Za-z0-9._-]+$/;
|
|
@@ -341,12 +374,13 @@ function allSharedLinks(map) {
|
|
|
341
374
|
}
|
|
342
375
|
return [...SHARED_LINKS, ...extras];
|
|
343
376
|
}
|
|
344
|
-
var HOME, CLAUDE_HOME, BACKUP_BASE, REPO_HOME, SETTINGS_SCHEMA_URL, NPM_REGISTRY_LATEST_URL, GITLEAKS_PINNED_VERSION, HOST, SHARED_LINKS, SUPPORTED_EXTRAS, ALWAYS_NEVER_SYNC,
|
|
377
|
+
var HOME, CLAUDE_HOME, BACKUP_BASE, REPO_HOME, SETTINGS_SCHEMA_URL, NPM_REGISTRY_LATEST_URL, GITLEAKS_PINNED_VERSION, HOST, SHARED_LINKS, SUPPORTED_EXTRAS, ALWAYS_NEVER_SYNC, PUSH_ALLOWED_STATIC;
|
|
345
378
|
var init_config = __esm({
|
|
346
379
|
"src/config.ts"() {
|
|
347
380
|
"use strict";
|
|
348
381
|
init_config_sharedDirs_guard();
|
|
349
382
|
init_utils();
|
|
383
|
+
init_config_never_sync();
|
|
350
384
|
init_settings_keys();
|
|
351
385
|
HOME = homedir();
|
|
352
386
|
CLAUDE_HOME = resolve(HOME, ".claude");
|
|
@@ -373,31 +407,6 @@ var init_config = __esm({
|
|
|
373
407
|
"history.jsonl",
|
|
374
408
|
"stats-cache.json"
|
|
375
409
|
]);
|
|
376
|
-
NEVER_SYNC = /* @__PURE__ */ new Set([
|
|
377
|
-
".claude.json",
|
|
378
|
-
".credentials.json",
|
|
379
|
-
"history.jsonl",
|
|
380
|
-
"settings.local.json",
|
|
381
|
-
"stats-cache.json",
|
|
382
|
-
"todos",
|
|
383
|
-
"shell-snapshots",
|
|
384
|
-
"debug",
|
|
385
|
-
"file-history",
|
|
386
|
-
"plans",
|
|
387
|
-
"session-env",
|
|
388
|
-
"statsig",
|
|
389
|
-
"telemetry",
|
|
390
|
-
"ide",
|
|
391
|
-
// Host-local caches and runtime state (sharedDirs guard also rejects these).
|
|
392
|
-
"cache",
|
|
393
|
-
"backups",
|
|
394
|
-
"paste-cache",
|
|
395
|
-
"daemon",
|
|
396
|
-
"jobs",
|
|
397
|
-
"tasks",
|
|
398
|
-
"security",
|
|
399
|
-
"sessions"
|
|
400
|
-
]);
|
|
401
410
|
PUSH_ALLOWED_STATIC = [
|
|
402
411
|
"shared/CLAUDE.md",
|
|
403
412
|
"shared/my-statusline.cjs",
|
|
@@ -541,10 +550,9 @@ var init_utils_fs = __esm({
|
|
|
541
550
|
}
|
|
542
551
|
});
|
|
543
552
|
|
|
544
|
-
// src/push-gitleaks.
|
|
545
|
-
import {
|
|
546
|
-
import {
|
|
547
|
-
import { homedir as homedir2 } from "node:os";
|
|
553
|
+
// src/push-gitleaks.config.ts
|
|
554
|
+
import { existsSync as existsSync9, mkdtempSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
555
|
+
import { tmpdir } from "node:os";
|
|
548
556
|
import { join as join10 } from "node:path";
|
|
549
557
|
import { fileURLToPath } from "node:url";
|
|
550
558
|
function resolveTomlPath() {
|
|
@@ -553,110 +561,21 @@ function resolveTomlPath() {
|
|
|
553
561
|
const bundled = fileURLToPath(new URL("../.gitleaks.toml", import.meta.url));
|
|
554
562
|
return existsSync9(bundled) ? bundled : null;
|
|
555
563
|
}
|
|
556
|
-
function readGitleaksReport(reportPath) {
|
|
557
|
-
try {
|
|
558
|
-
const raw = readFileSync3(reportPath, "utf8");
|
|
559
|
-
const parsed = JSON.parse(raw);
|
|
560
|
-
if (!Array.isArray(parsed)) return null;
|
|
561
|
-
return parsed;
|
|
562
|
-
} catch {
|
|
563
|
-
return null;
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
function scanStagedTree(repoDir, forwardStreams = false) {
|
|
567
|
-
const cacheDir = join10(homedir2(), ".cache", "claude-nomad");
|
|
568
|
-
mkdirSync2(cacheDir, { recursive: true });
|
|
569
|
-
const reportPath = join10(cacheDir, `gitleaks-${nowTimestamp()}-${process.pid}.json`);
|
|
570
|
-
const { path: toml, tempPath } = resolveTomlConfig();
|
|
571
|
-
const args = [
|
|
572
|
-
"protect",
|
|
573
|
-
"--staged",
|
|
574
|
-
"--redact",
|
|
575
|
-
"-v",
|
|
576
|
-
"--report-format=json",
|
|
577
|
-
`--report-path=${reportPath}`
|
|
578
|
-
];
|
|
579
|
-
if (toml !== null) args.push("--config", toml);
|
|
580
|
-
const opts = { cwd: repoDir, stdio: ["ignore", "pipe", "pipe"] };
|
|
581
|
-
try {
|
|
582
|
-
execFileSync2("git", ["init", "-q"], opts);
|
|
583
|
-
execFileSync2("git", ["add", "-A"], opts);
|
|
584
|
-
execFileSync2("gitleaks", args, opts);
|
|
585
|
-
return [];
|
|
586
|
-
} catch (err) {
|
|
587
|
-
const e = err;
|
|
588
|
-
if (e.code === "ENOENT") throw err;
|
|
589
|
-
const report = readGitleaksReport(reportPath);
|
|
590
|
-
if (forwardStreams && report === null) {
|
|
591
|
-
if (e.stderr) process.stderr.write(e.stderr);
|
|
592
|
-
if (e.stdout) process.stdout.write(e.stdout);
|
|
593
|
-
}
|
|
594
|
-
return report;
|
|
595
|
-
} finally {
|
|
596
|
-
if (tempPath !== null) rmSync3(tempPath, { recursive: true, force: true });
|
|
597
|
-
rmSync3(reportPath, { force: true });
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
function scanFile(filePath, forwardStreams = false) {
|
|
601
|
-
const cacheDir = join10(homedir2(), ".cache", "claude-nomad");
|
|
602
|
-
mkdirSync2(cacheDir, { recursive: true });
|
|
603
|
-
const reportPath = join10(cacheDir, `gitleaks-file-${nowTimestamp()}-${process.pid}.json`);
|
|
604
|
-
const { path: toml, tempPath } = resolveTomlConfig();
|
|
605
|
-
const args = [
|
|
606
|
-
"detect",
|
|
607
|
-
"--no-git",
|
|
608
|
-
"--source",
|
|
609
|
-
filePath,
|
|
610
|
-
"--report-format=json",
|
|
611
|
-
`--report-path=${reportPath}`
|
|
612
|
-
];
|
|
613
|
-
if (toml !== null) args.push("--config", toml);
|
|
614
|
-
const opts = { stdio: ["ignore", "pipe", "pipe"] };
|
|
615
|
-
try {
|
|
616
|
-
execFileSync2("gitleaks", args, opts);
|
|
617
|
-
return [];
|
|
618
|
-
} catch (err) {
|
|
619
|
-
const e = err;
|
|
620
|
-
if (e.code === "ENOENT") return null;
|
|
621
|
-
const report = readGitleaksReport(reportPath);
|
|
622
|
-
if (forwardStreams && report === null) {
|
|
623
|
-
if (e.stderr) process.stderr.write(e.stderr);
|
|
624
|
-
if (e.stdout) process.stdout.write(e.stdout);
|
|
625
|
-
}
|
|
626
|
-
return report;
|
|
627
|
-
} finally {
|
|
628
|
-
if (tempPath !== null) rmSync3(tempPath, { recursive: true, force: true });
|
|
629
|
-
rmSync3(reportPath, { force: true });
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
var init_push_gitleaks_scan = __esm({
|
|
633
|
-
"src/push-gitleaks.scan.ts"() {
|
|
634
|
-
"use strict";
|
|
635
|
-
init_config();
|
|
636
|
-
init_push_gitleaks_config();
|
|
637
|
-
init_utils_fs();
|
|
638
|
-
}
|
|
639
|
-
});
|
|
640
|
-
|
|
641
|
-
// src/push-gitleaks.config.ts
|
|
642
|
-
import { existsSync as existsSync10, mkdtempSync, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
643
|
-
import { tmpdir } from "node:os";
|
|
644
|
-
import { join as join11 } from "node:path";
|
|
645
564
|
function buildOverlayTempConfig(overlayBody, bundled) {
|
|
646
565
|
const tempBody = `[extend]
|
|
647
566
|
path = ${JSON.stringify(bundled)}
|
|
648
567
|
|
|
649
568
|
${overlayBody}`;
|
|
650
|
-
const tempPath = mkdtempSync(
|
|
651
|
-
const configPath =
|
|
569
|
+
const tempPath = mkdtempSync(join10(tmpdir(), "nomad-gitleaks-cfg-"));
|
|
570
|
+
const configPath = join10(tempPath, "config.toml");
|
|
652
571
|
writeFileSync2(configPath, tempBody, { mode: 384, flag: "wx" });
|
|
653
572
|
return { configPath, tempPath };
|
|
654
573
|
}
|
|
655
574
|
function resolveTomlConfig() {
|
|
656
|
-
const overlayPath =
|
|
657
|
-
const repoToml =
|
|
575
|
+
const overlayPath = join10(REPO_HOME, ".gitleaks.overlay.toml");
|
|
576
|
+
const repoToml = join10(REPO_HOME, ".gitleaks.toml");
|
|
658
577
|
const bundled = resolveTomlPath();
|
|
659
|
-
if (!
|
|
578
|
+
if (!existsSync9(overlayPath)) {
|
|
660
579
|
return { path: bundled, tempPath: null };
|
|
661
580
|
}
|
|
662
581
|
if (bundled === repoToml) {
|
|
@@ -669,7 +588,7 @@ function resolveTomlConfig() {
|
|
|
669
588
|
return { path: null, tempPath: null };
|
|
670
589
|
}
|
|
671
590
|
try {
|
|
672
|
-
const overlayBody =
|
|
591
|
+
const overlayBody = readFileSync3(overlayPath, "utf8");
|
|
673
592
|
if (OVERLAY_EXTEND_RE.test(overlayBody)) {
|
|
674
593
|
throw new NomadFatal(
|
|
675
594
|
".gitleaks.overlay.toml must not contain an [extend] block; it is generated automatically. Remove the [extend] section and retry."
|
|
@@ -690,17 +609,16 @@ var init_push_gitleaks_config = __esm({
|
|
|
690
609
|
"src/push-gitleaks.config.ts"() {
|
|
691
610
|
"use strict";
|
|
692
611
|
init_config();
|
|
693
|
-
init_push_gitleaks_scan();
|
|
694
612
|
init_utils();
|
|
695
613
|
OVERLAY_EXTEND_RE = /^\s*(?:\[\s*extend\s*\]|extend\s*[.=])/m;
|
|
696
614
|
}
|
|
697
615
|
});
|
|
698
616
|
|
|
699
617
|
// src/push-checks.ts
|
|
700
|
-
import { execFileSync as
|
|
701
|
-
import { readdirSync as readdirSync3, rmSync as
|
|
702
|
-
import { homedir as
|
|
703
|
-
import { join as
|
|
618
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
619
|
+
import { readdirSync as readdirSync3, rmSync as rmSync3 } from "node:fs";
|
|
620
|
+
import { homedir as homedir2, platform } from "node:os";
|
|
621
|
+
import { join as join11 } from "node:path";
|
|
704
622
|
function gitleaksInstallHint() {
|
|
705
623
|
const head = "gitleaks not on PATH (required for nomad push). Install:";
|
|
706
624
|
const plat = platform();
|
|
@@ -720,7 +638,7 @@ function gitleaksInstallHint() {
|
|
|
720
638
|
" chmod +x ~/.local/bin/gitleaks",
|
|
721
639
|
" ~/.local/bin/gitleaks version # verify"
|
|
722
640
|
];
|
|
723
|
-
const localBin = `${
|
|
641
|
+
const localBin = `${homedir2()}/.local/bin`;
|
|
724
642
|
const paths = (process.env.PATH ?? "").split(":");
|
|
725
643
|
if (!paths.includes(localBin)) {
|
|
726
644
|
lines.push(
|
|
@@ -743,7 +661,7 @@ function findGitlinks(dir) {
|
|
|
743
661
|
return;
|
|
744
662
|
}
|
|
745
663
|
for (const e of entries) {
|
|
746
|
-
const p =
|
|
664
|
+
const p = join11(current, e.name);
|
|
747
665
|
if (e.name === ".git") {
|
|
748
666
|
hits.push(p);
|
|
749
667
|
continue;
|
|
@@ -759,18 +677,18 @@ function probeGitleaks() {
|
|
|
759
677
|
const args = ["version"];
|
|
760
678
|
if (toml !== null) args.push("--config", toml);
|
|
761
679
|
try {
|
|
762
|
-
return
|
|
680
|
+
return execFileSync2("gitleaks", args, { stdio: ["ignore", "pipe", "pipe"] }).toString().trim();
|
|
763
681
|
} catch (err) {
|
|
764
682
|
const e = err;
|
|
765
683
|
if (e.code === "ENOENT") throw new NomadFatal(gitleaksInstallHint());
|
|
766
684
|
throw new NomadFatal(`gitleaks --version failed: ${e.message}`);
|
|
767
685
|
} finally {
|
|
768
|
-
if (tempPath !== null)
|
|
686
|
+
if (tempPath !== null) rmSync3(tempPath, { recursive: true, force: true });
|
|
769
687
|
}
|
|
770
688
|
}
|
|
771
689
|
function rebaseBeforePush() {
|
|
772
690
|
try {
|
|
773
|
-
|
|
691
|
+
execFileSync2("git", ["pull", "--rebase", "--autostash"], {
|
|
774
692
|
cwd: REPO_HOME,
|
|
775
693
|
stdio: ["ignore", "pipe", "pipe"]
|
|
776
694
|
});
|
|
@@ -791,6 +709,95 @@ var init_push_checks = __esm({
|
|
|
791
709
|
}
|
|
792
710
|
});
|
|
793
711
|
|
|
712
|
+
// src/push-gitleaks.scan.ts
|
|
713
|
+
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
714
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync4, rmSync as rmSync4 } from "node:fs";
|
|
715
|
+
import { homedir as homedir3 } from "node:os";
|
|
716
|
+
import { join as join15 } from "node:path";
|
|
717
|
+
function readGitleaksReport(reportPath) {
|
|
718
|
+
try {
|
|
719
|
+
const raw = readFileSync4(reportPath, "utf8");
|
|
720
|
+
const parsed = JSON.parse(raw);
|
|
721
|
+
if (!Array.isArray(parsed)) return null;
|
|
722
|
+
return parsed;
|
|
723
|
+
} catch {
|
|
724
|
+
return null;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
function scanStagedTree(repoDir, forwardStreams = false) {
|
|
728
|
+
const cacheDir = join15(homedir3(), ".cache", "claude-nomad");
|
|
729
|
+
mkdirSync2(cacheDir, { recursive: true });
|
|
730
|
+
const reportPath = join15(cacheDir, `gitleaks-${nowTimestamp()}-${process.pid}.json`);
|
|
731
|
+
const { path: toml, tempPath } = resolveTomlConfig();
|
|
732
|
+
const args = [
|
|
733
|
+
"protect",
|
|
734
|
+
"--staged",
|
|
735
|
+
"--redact",
|
|
736
|
+
"-v",
|
|
737
|
+
"--report-format=json",
|
|
738
|
+
`--report-path=${reportPath}`
|
|
739
|
+
];
|
|
740
|
+
if (toml !== null) args.push("--config", toml);
|
|
741
|
+
const opts = { cwd: repoDir, stdio: ["ignore", "pipe", "pipe"] };
|
|
742
|
+
try {
|
|
743
|
+
execFileSync5("git", ["init", "-q"], opts);
|
|
744
|
+
execFileSync5("git", ["add", "-A"], opts);
|
|
745
|
+
execFileSync5("gitleaks", args, opts);
|
|
746
|
+
return [];
|
|
747
|
+
} catch (err) {
|
|
748
|
+
const e = err;
|
|
749
|
+
if (e.code === "ENOENT") throw err;
|
|
750
|
+
const report = readGitleaksReport(reportPath);
|
|
751
|
+
if (forwardStreams && report === null) {
|
|
752
|
+
if (e.stderr) process.stderr.write(e.stderr);
|
|
753
|
+
if (e.stdout) process.stdout.write(e.stdout);
|
|
754
|
+
}
|
|
755
|
+
return report;
|
|
756
|
+
} finally {
|
|
757
|
+
if (tempPath !== null) rmSync4(tempPath, { recursive: true, force: true });
|
|
758
|
+
rmSync4(reportPath, { force: true });
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
function scanFile(filePath, forwardStreams = false) {
|
|
762
|
+
const cacheDir = join15(homedir3(), ".cache", "claude-nomad");
|
|
763
|
+
mkdirSync2(cacheDir, { recursive: true });
|
|
764
|
+
const reportPath = join15(cacheDir, `gitleaks-file-${nowTimestamp()}-${process.pid}.json`);
|
|
765
|
+
const { path: toml, tempPath } = resolveTomlConfig();
|
|
766
|
+
const args = [
|
|
767
|
+
"detect",
|
|
768
|
+
"--no-git",
|
|
769
|
+
"--source",
|
|
770
|
+
filePath,
|
|
771
|
+
"--report-format=json",
|
|
772
|
+
`--report-path=${reportPath}`
|
|
773
|
+
];
|
|
774
|
+
if (toml !== null) args.push("--config", toml);
|
|
775
|
+
const opts = { stdio: ["ignore", "pipe", "pipe"] };
|
|
776
|
+
try {
|
|
777
|
+
execFileSync5("gitleaks", args, opts);
|
|
778
|
+
return [];
|
|
779
|
+
} catch (err) {
|
|
780
|
+
const e = err;
|
|
781
|
+
if (e.code === "ENOENT") return null;
|
|
782
|
+
const report = readGitleaksReport(reportPath);
|
|
783
|
+
if (forwardStreams && report === null) {
|
|
784
|
+
if (e.stderr) process.stderr.write(e.stderr);
|
|
785
|
+
if (e.stdout) process.stdout.write(e.stdout);
|
|
786
|
+
}
|
|
787
|
+
return report;
|
|
788
|
+
} finally {
|
|
789
|
+
if (tempPath !== null) rmSync4(tempPath, { recursive: true, force: true });
|
|
790
|
+
rmSync4(reportPath, { force: true });
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
var init_push_gitleaks_scan = __esm({
|
|
794
|
+
"src/push-gitleaks.scan.ts"() {
|
|
795
|
+
"use strict";
|
|
796
|
+
init_push_gitleaks_config();
|
|
797
|
+
init_utils_fs();
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
|
|
794
801
|
// src/push-gitleaks.ts
|
|
795
802
|
function findingIdentityKey(f) {
|
|
796
803
|
const fp = f.Fingerprint;
|
|
@@ -870,7 +877,6 @@ var init_push_gitleaks = __esm({
|
|
|
870
877
|
init_push_checks();
|
|
871
878
|
init_push_gitleaks_scan();
|
|
872
879
|
init_utils();
|
|
873
|
-
init_push_gitleaks_scan();
|
|
874
880
|
SESSION_PATH = /^shared\/projects\/[^/]+\/([^/]+)\.jsonl$/;
|
|
875
881
|
SUBAGENT_SESSION_PATH = /^shared\/projects\/[^/]+\/([^/]+)\/.*\.jsonl$/;
|
|
876
882
|
LEGACY_FATAL = "gitleaks detected secrets; review staged changes with git diff --cached and unstage offending files before retry";
|
|
@@ -1204,7 +1210,7 @@ function cmdClean(opts, backupBase = BACKUP_BASE) {
|
|
|
1204
1210
|
}
|
|
1205
1211
|
|
|
1206
1212
|
// src/commands.doctor.ts
|
|
1207
|
-
import { existsSync as
|
|
1213
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
1208
1214
|
import { join as join22 } from "node:path";
|
|
1209
1215
|
|
|
1210
1216
|
// src/commands.doctor.checks.repo.ts
|
|
@@ -1535,14 +1541,14 @@ function reportNeverSync(section2) {
|
|
|
1535
1541
|
// src/commands.doctor.checks.repository.ts
|
|
1536
1542
|
init_color();
|
|
1537
1543
|
init_config();
|
|
1538
|
-
import { execFileSync as
|
|
1539
|
-
import { existsSync as
|
|
1540
|
-
import { join as
|
|
1544
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
1545
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
1546
|
+
import { join as join12, relative as relative2 } from "node:path";
|
|
1541
1547
|
init_push_checks();
|
|
1542
1548
|
init_utils();
|
|
1543
1549
|
function reportGitleaksProbe(section2) {
|
|
1544
1550
|
try {
|
|
1545
|
-
const v =
|
|
1551
|
+
const v = execFileSync3("gitleaks", ["version"], { stdio: ["ignore", "pipe", "pipe"] }).toString().trim();
|
|
1546
1552
|
addItem(section2, `${green(okGlyph)} gitleaks: ${dim(v)}`);
|
|
1547
1553
|
return true;
|
|
1548
1554
|
} catch (err) {
|
|
@@ -1556,8 +1562,8 @@ function reportGitleaksProbe(section2) {
|
|
|
1556
1562
|
}
|
|
1557
1563
|
}
|
|
1558
1564
|
function reportGitlinks(section2) {
|
|
1559
|
-
const sharedDir =
|
|
1560
|
-
if (
|
|
1565
|
+
const sharedDir = join12(REPO_HOME, "shared");
|
|
1566
|
+
if (existsSync10(sharedDir)) {
|
|
1561
1567
|
const gitlinks = findGitlinks(sharedDir);
|
|
1562
1568
|
for (const p of gitlinks) {
|
|
1563
1569
|
const rel = relative2(REPO_HOME, p);
|
|
@@ -1575,7 +1581,7 @@ function reportGitlinks(section2) {
|
|
|
1575
1581
|
}
|
|
1576
1582
|
function reportRemote(section2) {
|
|
1577
1583
|
try {
|
|
1578
|
-
const url =
|
|
1584
|
+
const url = execFileSync3("git", ["remote", "get-url", "origin"], {
|
|
1579
1585
|
cwd: REPO_HOME,
|
|
1580
1586
|
stdio: ["ignore", "pipe", "pipe"]
|
|
1581
1587
|
}).toString().trim();
|
|
@@ -1599,8 +1605,8 @@ function reportRebaseClean(section2) {
|
|
|
1599
1605
|
|
|
1600
1606
|
// src/commands.doctor.checks.backups.ts
|
|
1601
1607
|
init_color();
|
|
1602
|
-
import { existsSync as
|
|
1603
|
-
import { join as
|
|
1608
|
+
import { existsSync as existsSync11, lstatSync as lstatSync5, readdirSync as readdirSync4 } from "node:fs";
|
|
1609
|
+
import { join as join13 } from "node:path";
|
|
1604
1610
|
init_config();
|
|
1605
1611
|
var TS_SHAPE2 = /^\d{8}-\d{6}(-\d+)?$/;
|
|
1606
1612
|
function safeReaddir(dir) {
|
|
@@ -1616,7 +1622,7 @@ var BYTES_PER_MB = 1024 * 1024;
|
|
|
1616
1622
|
function dirSizeBytes(dir) {
|
|
1617
1623
|
let bytes = 0;
|
|
1618
1624
|
for (const entry of safeReaddir(dir)) {
|
|
1619
|
-
const full =
|
|
1625
|
+
const full = join13(dir, entry);
|
|
1620
1626
|
const st = lstatSync5(full, { throwIfNoEntry: false });
|
|
1621
1627
|
if (!st) continue;
|
|
1622
1628
|
if (st.isSymbolicLink()) continue;
|
|
@@ -1627,11 +1633,11 @@ function dirSizeBytes(dir) {
|
|
|
1627
1633
|
}
|
|
1628
1634
|
function totalSizeMb(backupBase, dirs) {
|
|
1629
1635
|
let bytes = 0;
|
|
1630
|
-
for (const name of dirs) bytes += dirSizeBytes(
|
|
1636
|
+
for (const name of dirs) bytes += dirSizeBytes(join13(backupBase, name));
|
|
1631
1637
|
return bytes / BYTES_PER_MB;
|
|
1632
1638
|
}
|
|
1633
1639
|
function reportBackupsCheck(section2, backupBase = BACKUP_BASE) {
|
|
1634
|
-
if (!
|
|
1640
|
+
if (!existsSync11(backupBase)) return;
|
|
1635
1641
|
const dirs = safeReaddir(backupBase).filter((n) => TS_SHAPE2.test(n));
|
|
1636
1642
|
const count = dirs.length;
|
|
1637
1643
|
const sizeMb = totalSizeMb(backupBase, dirs);
|
|
@@ -1645,14 +1651,14 @@ function reportBackupsCheck(section2, backupBase = BACKUP_BASE) {
|
|
|
1645
1651
|
|
|
1646
1652
|
// src/commands.doctor.check-schema.ts
|
|
1647
1653
|
init_color();
|
|
1648
|
-
import { existsSync as
|
|
1649
|
-
import { join as
|
|
1654
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
1655
|
+
import { join as join14 } from "node:path";
|
|
1650
1656
|
init_config();
|
|
1651
1657
|
|
|
1652
1658
|
// src/http-fetch.ts
|
|
1653
|
-
import { execFileSync as
|
|
1659
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
1654
1660
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
1655
|
-
function fetchUrl(url, run =
|
|
1661
|
+
function fetchUrl(url, run = execFileSync4) {
|
|
1656
1662
|
try {
|
|
1657
1663
|
return run("curl", ["-fsSL", "-m", "3", url], {
|
|
1658
1664
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -1683,8 +1689,8 @@ function fetchSchemaKeys() {
|
|
|
1683
1689
|
}
|
|
1684
1690
|
}
|
|
1685
1691
|
function reportCheckSchema(section2) {
|
|
1686
|
-
const settingsPath =
|
|
1687
|
-
if (!
|
|
1692
|
+
const settingsPath = join14(CLAUDE_HOME, "settings.json");
|
|
1693
|
+
if (!existsSync12(settingsPath)) {
|
|
1688
1694
|
addItem(section2, `${dim(infoGlyph)} no ~/.claude/settings.json to check`);
|
|
1689
1695
|
return;
|
|
1690
1696
|
}
|
|
@@ -1714,7 +1720,7 @@ function reportCheckSchema(section2) {
|
|
|
1714
1720
|
init_color();
|
|
1715
1721
|
import { randomBytes } from "node:crypto";
|
|
1716
1722
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
1717
|
-
import { existsSync as
|
|
1723
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync4, readdirSync as readdirSync6, rmSync as rmSync6 } from "node:fs";
|
|
1718
1724
|
import { homedir as homedir4 } from "node:os";
|
|
1719
1725
|
import { join as join18 } from "node:path";
|
|
1720
1726
|
|
|
@@ -1817,7 +1823,7 @@ init_config();
|
|
|
1817
1823
|
init_utils();
|
|
1818
1824
|
init_utils_fs();
|
|
1819
1825
|
init_utils_json();
|
|
1820
|
-
import { cpSync as cpSync3, existsSync as
|
|
1826
|
+
import { cpSync as cpSync3, existsSync as existsSync13, mkdirSync as mkdirSync3, readdirSync as readdirSync5, rmSync as rmSync5, statSync as statSync4 } from "node:fs";
|
|
1821
1827
|
import { join as join17, relative as relative3, sep } from "node:path";
|
|
1822
1828
|
function copyDir(src, dst) {
|
|
1823
1829
|
rmSync5(dst, { recursive: true, force: true });
|
|
@@ -1846,7 +1852,7 @@ function remapPull(ts, opts = {}) {
|
|
|
1846
1852
|
const wouldPull = [];
|
|
1847
1853
|
const mapPath = join17(REPO_HOME, "path-map.json");
|
|
1848
1854
|
const repoProjects = join17(REPO_HOME, "shared", "projects");
|
|
1849
|
-
if (!
|
|
1855
|
+
if (!existsSync13(mapPath) || !existsSync13(repoProjects)) {
|
|
1850
1856
|
log("no path-map or repo projects dir; skipping session remap");
|
|
1851
1857
|
return { unmapped: 0, pulled, wouldPull };
|
|
1852
1858
|
}
|
|
@@ -1861,7 +1867,7 @@ function remapPull(ts, opts = {}) {
|
|
|
1861
1867
|
continue;
|
|
1862
1868
|
}
|
|
1863
1869
|
const src = join17(repoProjects, logical);
|
|
1864
|
-
if (!
|
|
1870
|
+
if (!existsSync13(src)) continue;
|
|
1865
1871
|
const dst = join17(localProjects, encodePath(localPath));
|
|
1866
1872
|
if (dryRun) {
|
|
1867
1873
|
wouldPull.push(logical);
|
|
@@ -1904,7 +1910,7 @@ function remapPush(ts, opts = {}) {
|
|
|
1904
1910
|
const pushed = [];
|
|
1905
1911
|
const wouldPush = [];
|
|
1906
1912
|
const mapPath = join17(REPO_HOME, "path-map.json");
|
|
1907
|
-
if (!
|
|
1913
|
+
if (!existsSync13(mapPath)) {
|
|
1908
1914
|
log("no path-map.json; skipping session export");
|
|
1909
1915
|
return { unmapped: 0, collisions: 0, pushed, wouldPush };
|
|
1910
1916
|
}
|
|
@@ -1912,7 +1918,7 @@ function remapPush(ts, opts = {}) {
|
|
|
1912
1918
|
const localProjects = join17(CLAUDE_HOME, "projects");
|
|
1913
1919
|
const repoProjects = join17(REPO_HOME, "shared", "projects");
|
|
1914
1920
|
const reverse = buildReverseMap(map);
|
|
1915
|
-
if (!
|
|
1921
|
+
if (!existsSync13(localProjects)) return { unmapped, collisions: 0, pushed, wouldPush };
|
|
1916
1922
|
if (!dryRun) mkdirSync3(repoProjects, { recursive: true });
|
|
1917
1923
|
for (const dir of readdirSync5(localProjects)) {
|
|
1918
1924
|
const logical = reverse.get(dir);
|
|
@@ -1939,7 +1945,7 @@ function buildScanTree(tmpRoot) {
|
|
|
1939
1945
|
const logicalToEncoded = /* @__PURE__ */ new Map();
|
|
1940
1946
|
let staged = 0;
|
|
1941
1947
|
const mapPath = join18(REPO_HOME, "path-map.json");
|
|
1942
|
-
if (!
|
|
1948
|
+
if (!existsSync14(mapPath)) return { logicalToEncoded, staged, malformed: false };
|
|
1943
1949
|
let map;
|
|
1944
1950
|
try {
|
|
1945
1951
|
map = readJson(mapPath);
|
|
@@ -1957,7 +1963,7 @@ function buildScanTree(tmpRoot) {
|
|
|
1957
1963
|
reverse.set(encodePath(p), logical);
|
|
1958
1964
|
}
|
|
1959
1965
|
const localProjects = join18(CLAUDE_HOME, "projects");
|
|
1960
|
-
if (!
|
|
1966
|
+
if (!existsSync14(localProjects)) return { logicalToEncoded, staged, malformed: false };
|
|
1961
1967
|
for (const dir of readdirSync6(localProjects)) {
|
|
1962
1968
|
const logical = reverse.get(dir);
|
|
1963
1969
|
if (!logical) continue;
|
|
@@ -2017,7 +2023,7 @@ function reportCheckShared(section2, gitleaksReady) {
|
|
|
2017
2023
|
|
|
2018
2024
|
// src/commands.doctor.checks.hooks.scope.ts
|
|
2019
2025
|
init_color();
|
|
2020
|
-
import { existsSync as
|
|
2026
|
+
import { existsSync as existsSync15, readFileSync as readFileSync5, readdirSync as readdirSync7, realpathSync } from "node:fs";
|
|
2021
2027
|
import { dirname as dirname2, extname, join as join19 } from "node:path";
|
|
2022
2028
|
init_config();
|
|
2023
2029
|
function typeFromPackageJson(pkgPath) {
|
|
@@ -2041,7 +2047,7 @@ function effectiveType(hookPath) {
|
|
|
2041
2047
|
let dir = dirname2(real);
|
|
2042
2048
|
for (; ; ) {
|
|
2043
2049
|
const pkg = join19(dir, "package.json");
|
|
2044
|
-
if (
|
|
2050
|
+
if (existsSync15(pkg)) return typeFromPackageJson(pkg);
|
|
2045
2051
|
const parent = dirname2(dir);
|
|
2046
2052
|
if (parent === dir) return "cjs";
|
|
2047
2053
|
dir = parent;
|
|
@@ -2084,7 +2090,7 @@ function safeRead(path) {
|
|
|
2084
2090
|
}
|
|
2085
2091
|
function reportHookScopeCheck(section2) {
|
|
2086
2092
|
const hooksDir = join19(CLAUDE_HOME, "hooks");
|
|
2087
|
-
if (!
|
|
2093
|
+
if (!existsSync15(hooksDir)) {
|
|
2088
2094
|
addItem(section2, `${dim(infoGlyph)} no ~/.claude/hooks; skipping module-scope check`);
|
|
2089
2095
|
return;
|
|
2090
2096
|
}
|
|
@@ -2111,7 +2117,7 @@ function reportHookScopeCheck(section2) {
|
|
|
2111
2117
|
|
|
2112
2118
|
// src/commands.doctor.checks.hooks.ts
|
|
2113
2119
|
init_color();
|
|
2114
|
-
import { existsSync as
|
|
2120
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
2115
2121
|
import { join as join20 } from "node:path";
|
|
2116
2122
|
init_config();
|
|
2117
2123
|
function expandHome(token) {
|
|
@@ -2150,7 +2156,7 @@ function checkEventGroups(section2, event, groups) {
|
|
|
2150
2156
|
for (const group of groups) {
|
|
2151
2157
|
for (const cmd of commandsFromGroup(group)) {
|
|
2152
2158
|
for (const resolved of claudePathsIn(cmd)) {
|
|
2153
|
-
if (
|
|
2159
|
+
if (existsSync16(resolved)) continue;
|
|
2154
2160
|
addItem(section2, `${red(failGlyph)} hooks/${event}: command target missing: ${resolved}`);
|
|
2155
2161
|
process.exitCode = 1;
|
|
2156
2162
|
anyFail = true;
|
|
@@ -2161,7 +2167,7 @@ function checkEventGroups(section2, event, groups) {
|
|
|
2161
2167
|
}
|
|
2162
2168
|
function reportHooksTargetCheck(section2) {
|
|
2163
2169
|
const settingsPath = join20(CLAUDE_HOME, "settings.json");
|
|
2164
|
-
if (!
|
|
2170
|
+
if (!existsSync16(settingsPath)) {
|
|
2165
2171
|
addItem(section2, `${dim(infoGlyph)} no ~/.claude/settings.json; skipping hook target check`);
|
|
2166
2172
|
return;
|
|
2167
2173
|
}
|
|
@@ -2291,7 +2297,7 @@ function reportNodeEngineCheck(section2) {
|
|
|
2291
2297
|
// src/commands.doctor.gitleaks-version.ts
|
|
2292
2298
|
init_color();
|
|
2293
2299
|
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
2294
|
-
import { existsSync as
|
|
2300
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
2295
2301
|
import { join as join21 } from "node:path";
|
|
2296
2302
|
init_config();
|
|
2297
2303
|
var SEMVER_MAJOR_MINOR = /^(\d+)\.(\d+)\.\d+$/;
|
|
@@ -2313,7 +2319,7 @@ function readGitleaksVersion(run, tomlExists) {
|
|
|
2313
2319
|
return null;
|
|
2314
2320
|
}
|
|
2315
2321
|
}
|
|
2316
|
-
function reportGitleaksVersionCheck(section2, run = execFileSync7, tomlExists =
|
|
2322
|
+
function reportGitleaksVersionCheck(section2, run = execFileSync7, tomlExists = existsSync17) {
|
|
2317
2323
|
const raw = readGitleaksVersion(run, tomlExists);
|
|
2318
2324
|
if (raw === null) return;
|
|
2319
2325
|
const local = majorMinorOf(raw);
|
|
@@ -2336,7 +2342,7 @@ init_color();
|
|
|
2336
2342
|
import { execFileSync as execFileSync8 } from "node:child_process";
|
|
2337
2343
|
var VERSION_TOKEN = /(\d{1,9}\.\d{1,9}\.\d{1,9})/;
|
|
2338
2344
|
var PROBE_TIMEOUT_MS = 3e3;
|
|
2339
|
-
var
|
|
2345
|
+
var FETCHER_BASE = "HTTP fetcher";
|
|
2340
2346
|
function parseFirstVersion(line) {
|
|
2341
2347
|
const m = VERSION_TOKEN.exec(line);
|
|
2342
2348
|
return m ? m[1] : null;
|
|
@@ -2360,13 +2366,13 @@ function reportFetcherRow(section2, run) {
|
|
|
2360
2366
|
const curl = probeOptionalDep("curl", run);
|
|
2361
2367
|
const wget = probeOptionalDep("wget", run);
|
|
2362
2368
|
if (curl.status === "present") {
|
|
2363
|
-
addItem(section2, `${green(okGlyph)} ${
|
|
2369
|
+
addItem(section2, `${green(okGlyph)} ${FETCHER_BASE}: curl ${curl.version ?? "(present)"}`);
|
|
2364
2370
|
} else if (wget.status === "present") {
|
|
2365
|
-
addItem(section2, `${green(okGlyph)} ${
|
|
2371
|
+
addItem(section2, `${green(okGlyph)} ${FETCHER_BASE}: wget ${wget.version ?? "(present)"}`);
|
|
2366
2372
|
} else {
|
|
2367
2373
|
addItem(
|
|
2368
2374
|
section2,
|
|
2369
|
-
`${yellow(warnGlyph)} ${
|
|
2375
|
+
`${yellow(warnGlyph)} ${FETCHER_BASE} (curl or wget): not installed (optional; needed for release-version staleness check + nomad doctor --check-schema)`
|
|
2370
2376
|
);
|
|
2371
2377
|
}
|
|
2372
2378
|
}
|
|
@@ -2487,7 +2493,7 @@ function cmdDoctor(opts = {}) {
|
|
|
2487
2493
|
reportRepoState(host);
|
|
2488
2494
|
const links = section("Shared links");
|
|
2489
2495
|
const mapPath = join22(REPO_HOME, "path-map.json");
|
|
2490
|
-
const rawMap =
|
|
2496
|
+
const rawMap = existsSync18(mapPath) ? readJsonSafe(mapPath, mapPath, links) : null;
|
|
2491
2497
|
const map = rawMap ?? { projects: {} };
|
|
2492
2498
|
reportSharedLinks(links, map);
|
|
2493
2499
|
const hooksScan = section("Hook targets");
|
|
@@ -2507,18 +2513,20 @@ function cmdDoctor(opts = {}) {
|
|
|
2507
2513
|
reportRemote(repository);
|
|
2508
2514
|
reportRebaseClean(repository);
|
|
2509
2515
|
reportActionsDrift(repository);
|
|
2510
|
-
const
|
|
2511
|
-
reportVersionCheck(
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
+
const nomadVersion = section("Nomad Version");
|
|
2517
|
+
reportVersionCheck(nomadVersion);
|
|
2518
|
+
reportBackupsCheck(nomadVersion);
|
|
2519
|
+
const depVersions = section("Dependency Versions");
|
|
2520
|
+
reportNodeEngineCheck(depVersions);
|
|
2521
|
+
reportGitleaksVersionCheck(depVersions);
|
|
2522
|
+
reportOptionalDeps(depVersions);
|
|
2516
2523
|
const sharedScan = section("Shared scan");
|
|
2517
2524
|
if (opts.checkShared === true) reportCheckShared(sharedScan, gitleaksReady);
|
|
2518
2525
|
const schemaScan = section("Schema scan");
|
|
2519
2526
|
if (opts.checkSchema === true) reportCheckSchema(schemaScan);
|
|
2520
2527
|
renderDoctor([
|
|
2521
|
-
|
|
2528
|
+
nomadVersion,
|
|
2529
|
+
depVersions,
|
|
2522
2530
|
host,
|
|
2523
2531
|
links,
|
|
2524
2532
|
hooksScan,
|
|
@@ -2534,7 +2542,7 @@ function cmdDoctor(opts = {}) {
|
|
|
2534
2542
|
// src/commands.drop-session.ts
|
|
2535
2543
|
init_config();
|
|
2536
2544
|
import { execFileSync as execFileSync12 } from "node:child_process";
|
|
2537
|
-
import { existsSync as
|
|
2545
|
+
import { existsSync as existsSync20, readdirSync as readdirSync8, statSync as statSync5 } from "node:fs";
|
|
2538
2546
|
import { join as join25, relative as relative4 } from "node:path";
|
|
2539
2547
|
|
|
2540
2548
|
// src/commands.drop-session.git.ts
|
|
@@ -2578,7 +2586,7 @@ function isInIndex(rel) {
|
|
|
2578
2586
|
init_config();
|
|
2579
2587
|
init_utils();
|
|
2580
2588
|
init_utils_json();
|
|
2581
|
-
import { existsSync as
|
|
2589
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
2582
2590
|
import { join as join23 } from "node:path";
|
|
2583
2591
|
var SHARED_PROJECT_LOGICAL = /^shared\/projects\/([^/]+)\//;
|
|
2584
2592
|
function reportScrubHint(id, matches) {
|
|
@@ -2596,7 +2604,7 @@ function reportScrubHint(id, matches) {
|
|
|
2596
2604
|
function resolveLiveTranscript(id, matches) {
|
|
2597
2605
|
try {
|
|
2598
2606
|
const mapPath = join23(REPO_HOME, "path-map.json");
|
|
2599
|
-
if (!
|
|
2607
|
+
if (!existsSync19(mapPath)) return null;
|
|
2600
2608
|
const projects = readJson(mapPath).projects;
|
|
2601
2609
|
for (const rel of matches) {
|
|
2602
2610
|
const logical = SHARED_PROJECT_LOGICAL.exec(rel)?.[1];
|
|
@@ -2604,7 +2612,7 @@ function resolveLiveTranscript(id, matches) {
|
|
|
2604
2612
|
const abs = projects[logical]?.[HOST];
|
|
2605
2613
|
if (abs === void 0) continue;
|
|
2606
2614
|
const live = join23(CLAUDE_HOME, "projects", encodePath(abs), `${id}.jsonl`);
|
|
2607
|
-
if (
|
|
2615
|
+
if (existsSync19(live)) return live;
|
|
2608
2616
|
}
|
|
2609
2617
|
return null;
|
|
2610
2618
|
} catch {
|
|
@@ -2730,12 +2738,12 @@ function cmdDropSession(id) {
|
|
|
2730
2738
|
fail(`invalid session id: ${id}`);
|
|
2731
2739
|
process.exit(1);
|
|
2732
2740
|
}
|
|
2733
|
-
if (!
|
|
2741
|
+
if (!existsSync20(REPO_HOME)) die(`repo not cloned at ${REPO_HOME}`);
|
|
2734
2742
|
const handle = acquireLock("drop-session");
|
|
2735
2743
|
if (handle === null) process.exit(0);
|
|
2736
2744
|
try {
|
|
2737
2745
|
const repoProjects = join25(REPO_HOME, "shared", "projects");
|
|
2738
|
-
if (!
|
|
2746
|
+
if (!existsSync20(repoProjects)) {
|
|
2739
2747
|
throw new NomadFatal(`no staged session matches ${id}`);
|
|
2740
2748
|
}
|
|
2741
2749
|
const matches = collectMatches(repoProjects, id);
|
|
@@ -2758,11 +2766,11 @@ function collectMatches(repoProjects, id) {
|
|
|
2758
2766
|
const matches = [];
|
|
2759
2767
|
for (const logical of readdirSync8(repoProjects)) {
|
|
2760
2768
|
const candidate = join25(repoProjects, logical, `${id}.jsonl`);
|
|
2761
|
-
if (
|
|
2769
|
+
if (existsSync20(candidate)) {
|
|
2762
2770
|
matches.push(relative4(REPO_HOME, candidate));
|
|
2763
2771
|
}
|
|
2764
2772
|
const dir = join25(repoProjects, logical, id);
|
|
2765
|
-
if (
|
|
2773
|
+
if (existsSync20(dir) && statSync5(dir).isDirectory()) {
|
|
2766
2774
|
const dirRel = relative4(REPO_HOME, dir);
|
|
2767
2775
|
const staged = expandStagedDir(dirRel);
|
|
2768
2776
|
if (staged.length > 0) matches.push(...staged);
|
|
@@ -2798,15 +2806,15 @@ function unstageOne(rel) {
|
|
|
2798
2806
|
|
|
2799
2807
|
// src/commands.redact.ts
|
|
2800
2808
|
init_config();
|
|
2801
|
-
import { existsSync as
|
|
2809
|
+
import { existsSync as existsSync22, statSync as statSync7 } from "node:fs";
|
|
2802
2810
|
import { dirname as dirname4, join as join27 } from "node:path";
|
|
2803
2811
|
|
|
2804
2812
|
// src/commands.redact.subtree.ts
|
|
2805
|
-
import { existsSync as
|
|
2813
|
+
import { existsSync as existsSync21, lstatSync as lstatSync6, readFileSync as readFileSync9, readdirSync as readdirSync9, statSync as statSync6, writeFileSync as writeFileSync4 } from "node:fs";
|
|
2806
2814
|
import { join as join26 } from "node:path";
|
|
2807
2815
|
init_utils_fs();
|
|
2808
2816
|
function collectFiles(dir, out) {
|
|
2809
|
-
if (!
|
|
2817
|
+
if (!existsSync21(dir)) return;
|
|
2810
2818
|
const st = lstatSync6(dir);
|
|
2811
2819
|
if (!st.isDirectory()) return;
|
|
2812
2820
|
for (const entry of readdirSync9(dir)) {
|
|
@@ -2861,13 +2869,13 @@ init_utils();
|
|
|
2861
2869
|
function resolveLiveTranscript2(id) {
|
|
2862
2870
|
try {
|
|
2863
2871
|
const mapPath = join27(REPO_HOME, "path-map.json");
|
|
2864
|
-
if (!
|
|
2872
|
+
if (!existsSync22(mapPath)) return null;
|
|
2865
2873
|
const projects = readJson(mapPath).projects;
|
|
2866
2874
|
for (const hostMap of Object.values(projects)) {
|
|
2867
2875
|
const abs = hostMap[HOST];
|
|
2868
2876
|
if (abs === void 0) continue;
|
|
2869
2877
|
const live = join27(CLAUDE_HOME, "projects", encodePath(abs), `${id}.jsonl`);
|
|
2870
|
-
if (
|
|
2878
|
+
if (existsSync22(live)) return live;
|
|
2871
2879
|
}
|
|
2872
2880
|
return null;
|
|
2873
2881
|
} catch {
|
|
@@ -2885,12 +2893,12 @@ function cmdRedact(opts, nowMs = Date.now, scan = scanFile) {
|
|
|
2885
2893
|
fail(`invalid session id: ${id}`);
|
|
2886
2894
|
process.exit(1);
|
|
2887
2895
|
}
|
|
2888
|
-
if (!
|
|
2896
|
+
if (!existsSync22(REPO_HOME)) die(`repo not cloned at ${REPO_HOME}`);
|
|
2889
2897
|
const handle = acquireLock("redact");
|
|
2890
2898
|
if (handle === null) process.exit(0);
|
|
2891
2899
|
try {
|
|
2892
2900
|
const localPath = resolveLiveTranscript2(id);
|
|
2893
|
-
if (localPath === null || !
|
|
2901
|
+
if (localPath === null || !existsSync22(localPath)) {
|
|
2894
2902
|
fail(`could not resolve local transcript for session ${id} on this host`);
|
|
2895
2903
|
process.exitCode = 1;
|
|
2896
2904
|
return;
|
|
@@ -2948,7 +2956,7 @@ ${lines}`);
|
|
|
2948
2956
|
}
|
|
2949
2957
|
|
|
2950
2958
|
// src/commands.pull.ts
|
|
2951
|
-
import { existsSync as
|
|
2959
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync7 } from "node:fs";
|
|
2952
2960
|
import { join as join33 } from "node:path";
|
|
2953
2961
|
|
|
2954
2962
|
// src/commands.push.sections.ts
|
|
@@ -3045,7 +3053,7 @@ init_config();
|
|
|
3045
3053
|
|
|
3046
3054
|
// src/extras-sync.ts
|
|
3047
3055
|
init_config();
|
|
3048
|
-
import { existsSync as
|
|
3056
|
+
import { existsSync as existsSync25 } from "node:fs";
|
|
3049
3057
|
import { join as join30 } from "node:path";
|
|
3050
3058
|
|
|
3051
3059
|
// src/extras-sync.diff.ts
|
|
@@ -3073,7 +3081,7 @@ function listDivergingFiles(a, b) {
|
|
|
3073
3081
|
|
|
3074
3082
|
// src/extras-sync.core.ts
|
|
3075
3083
|
init_config();
|
|
3076
|
-
import { cpSync as cpSync4, existsSync as
|
|
3084
|
+
import { cpSync as cpSync4, existsSync as existsSync23, rmSync as rmSync7 } from "node:fs";
|
|
3077
3085
|
import { join as join28 } from "node:path";
|
|
3078
3086
|
|
|
3079
3087
|
// src/extras-sync.guards.ts
|
|
@@ -3099,7 +3107,7 @@ init_utils_json();
|
|
|
3099
3107
|
function loadValidatedExtras(opts) {
|
|
3100
3108
|
const mapPath = join28(REPO_HOME, "path-map.json");
|
|
3101
3109
|
const repoExtras = join28(REPO_HOME, "shared", "extras");
|
|
3102
|
-
if (!
|
|
3110
|
+
if (!existsSync23(mapPath) || opts.requireRepoExtras === true && !existsSync23(repoExtras)) {
|
|
3103
3111
|
if (opts.missingMsg !== void 0) log(opts.missingMsg);
|
|
3104
3112
|
return null;
|
|
3105
3113
|
}
|
|
@@ -3141,7 +3149,7 @@ init_utils_json();
|
|
|
3141
3149
|
|
|
3142
3150
|
// src/extras-sync.remap.ts
|
|
3143
3151
|
init_config();
|
|
3144
|
-
import { existsSync as
|
|
3152
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync6 } from "node:fs";
|
|
3145
3153
|
import { join as join29 } from "node:path";
|
|
3146
3154
|
init_utils_fs();
|
|
3147
3155
|
function runExtrasOp(v, dryRun, paths, backup) {
|
|
@@ -3150,7 +3158,7 @@ function runExtrasOp(v, dryRun, paths, backup) {
|
|
|
3150
3158
|
const would = [];
|
|
3151
3159
|
for (const t of eachExtrasTarget(v, counts)) {
|
|
3152
3160
|
const { src, dst } = paths(t);
|
|
3153
|
-
if (!
|
|
3161
|
+
if (!existsSync24(src)) continue;
|
|
3154
3162
|
const item = `${t.logical}/${t.dirname}`;
|
|
3155
3163
|
if (dryRun) {
|
|
3156
3164
|
would.push(item);
|
|
@@ -3210,7 +3218,7 @@ function divergenceCheckExtras(ts) {
|
|
|
3210
3218
|
for (const { logical, localRoot, dirname: dirname6 } of eachExtrasTarget(v, counts)) {
|
|
3211
3219
|
const local = join30(localRoot, dirname6);
|
|
3212
3220
|
const repo = join30(REPO_HOME, "shared", "extras", logical, dirname6);
|
|
3213
|
-
if (!
|
|
3221
|
+
if (!existsSync25(local) || !existsSync25(repo)) continue;
|
|
3214
3222
|
const diff = listDivergingFiles(local, repo);
|
|
3215
3223
|
if (diff.length === 0) continue;
|
|
3216
3224
|
const projectBackupRoot = join30(backupRoot, encodePath(localRoot));
|
|
@@ -3226,7 +3234,7 @@ init_config();
|
|
|
3226
3234
|
init_utils();
|
|
3227
3235
|
init_utils_fs();
|
|
3228
3236
|
init_utils_json();
|
|
3229
|
-
import { existsSync as
|
|
3237
|
+
import { existsSync as existsSync26, lstatSync as lstatSync7, rmSync as rmSync8 } from "node:fs";
|
|
3230
3238
|
import { join as join31 } from "node:path";
|
|
3231
3239
|
function applySharedLinks(ts, map, opts = {}) {
|
|
3232
3240
|
const dryRun = opts.dryRun === true;
|
|
@@ -3234,9 +3242,9 @@ function applySharedLinks(ts, map, opts = {}) {
|
|
|
3234
3242
|
for (const name of linkNames) {
|
|
3235
3243
|
const linkPath = join31(CLAUDE_HOME, name);
|
|
3236
3244
|
const target = join31(REPO_HOME, "shared", name);
|
|
3237
|
-
if (!
|
|
3245
|
+
if (!existsSync26(linkPath)) continue;
|
|
3238
3246
|
if (lstatSync7(linkPath).isSymbolicLink()) continue;
|
|
3239
|
-
if (!
|
|
3247
|
+
if (!existsSync26(target)) continue;
|
|
3240
3248
|
if (dryRun) {
|
|
3241
3249
|
log(`would auto-move non-symlink: ${linkPath} -> backup/${ts}/${name}`);
|
|
3242
3250
|
continue;
|
|
@@ -3246,7 +3254,7 @@ function applySharedLinks(ts, map, opts = {}) {
|
|
|
3246
3254
|
}
|
|
3247
3255
|
for (const name of linkNames) {
|
|
3248
3256
|
const target = join31(REPO_HOME, "shared", name);
|
|
3249
|
-
if (!
|
|
3257
|
+
if (!existsSync26(target)) continue;
|
|
3250
3258
|
if (dryRun) {
|
|
3251
3259
|
log(`would create symlink: ${join31(CLAUDE_HOME, name)} -> ${target}`);
|
|
3252
3260
|
continue;
|
|
@@ -3258,15 +3266,15 @@ function regenerateSettings(ts, opts = {}) {
|
|
|
3258
3266
|
const dryRun = opts.dryRun === true;
|
|
3259
3267
|
const basePath = join31(REPO_HOME, "shared", "settings.base.json");
|
|
3260
3268
|
const hostPath = join31(REPO_HOME, "hosts", `${HOST}.json`);
|
|
3261
|
-
if (!
|
|
3269
|
+
if (!existsSync26(basePath)) {
|
|
3262
3270
|
die("repo not initialized; run 'nomad init' to scaffold");
|
|
3263
3271
|
}
|
|
3264
3272
|
const base = readJson(basePath);
|
|
3265
|
-
const hasOverrides =
|
|
3273
|
+
const hasOverrides = existsSync26(hostPath);
|
|
3266
3274
|
const overrides = hasOverrides ? readJson(hostPath) : {};
|
|
3267
3275
|
const merged = deepMerge(base, overrides);
|
|
3268
3276
|
const settingsPath = join31(CLAUDE_HOME, "settings.json");
|
|
3269
|
-
if (!hasOverrides &&
|
|
3277
|
+
if (!hasOverrides && existsSync26(settingsPath)) {
|
|
3270
3278
|
try {
|
|
3271
3279
|
const existing = readJson(settingsPath);
|
|
3272
3280
|
const baseKeys = new Set(Object.keys(base));
|
|
@@ -3292,7 +3300,7 @@ function regenerateSettings(ts, opts = {}) {
|
|
|
3292
3300
|
|
|
3293
3301
|
// src/preview.ts
|
|
3294
3302
|
init_config();
|
|
3295
|
-
import { existsSync as
|
|
3303
|
+
import { existsSync as existsSync27 } from "node:fs";
|
|
3296
3304
|
import { join as join32 } from "node:path";
|
|
3297
3305
|
|
|
3298
3306
|
// node_modules/diff/libesm/diff/base.js
|
|
@@ -3579,7 +3587,7 @@ function diffJsonStrings(currentJsonText, newJsonText) {
|
|
|
3579
3587
|
return lines.join("\n");
|
|
3580
3588
|
}
|
|
3581
3589
|
function readJsonOrNull(path) {
|
|
3582
|
-
if (!
|
|
3590
|
+
if (!existsSync27(path)) return null;
|
|
3583
3591
|
try {
|
|
3584
3592
|
return readJson(path);
|
|
3585
3593
|
} catch {
|
|
@@ -3593,12 +3601,12 @@ function previewSettings(basePath, hostPath, settingsPath) {
|
|
|
3593
3601
|
return;
|
|
3594
3602
|
}
|
|
3595
3603
|
const hostOverrides = readJsonOrNull(hostPath);
|
|
3596
|
-
if (hostOverrides === null &&
|
|
3604
|
+
if (hostOverrides === null && existsSync27(hostPath)) {
|
|
3597
3605
|
log(`settings.json: malformed hosts/${HOST}.json; ignoring overrides`);
|
|
3598
3606
|
}
|
|
3599
3607
|
const merged = deepMerge(base, hostOverrides ?? {});
|
|
3600
3608
|
const current = readJsonOrNull(settingsPath);
|
|
3601
|
-
if (current === null &&
|
|
3609
|
+
if (current === null && existsSync27(settingsPath)) {
|
|
3602
3610
|
log("settings.json: malformed; skipping diff");
|
|
3603
3611
|
return;
|
|
3604
3612
|
}
|
|
@@ -3648,8 +3656,8 @@ function applyWetPull(ts, map) {
|
|
|
3648
3656
|
}
|
|
3649
3657
|
function cmdPull(opts = {}) {
|
|
3650
3658
|
const dryRun = opts.dryRun === true;
|
|
3651
|
-
if (!
|
|
3652
|
-
if (!
|
|
3659
|
+
if (!existsSync28(REPO_HOME)) die(`repo not cloned at ${REPO_HOME}`);
|
|
3660
|
+
if (!existsSync28(join33(REPO_HOME, "shared", "settings.base.json"))) {
|
|
3653
3661
|
die("repo not initialized; run 'nomad init' to scaffold");
|
|
3654
3662
|
}
|
|
3655
3663
|
const handle = acquireLock("pull");
|
|
@@ -3669,7 +3677,7 @@ function cmdPull(opts = {}) {
|
|
|
3669
3677
|
);
|
|
3670
3678
|
gitOrFatal(["pull", "--rebase", "--autostash"], "git pull --rebase", REPO_HOME);
|
|
3671
3679
|
const mapPath = join33(REPO_HOME, "path-map.json");
|
|
3672
|
-
const map =
|
|
3680
|
+
const map = existsSync28(mapPath) ? readPathMap(mapPath) : { projects: {} };
|
|
3673
3681
|
divergenceCheckExtras(ts);
|
|
3674
3682
|
if (dryRun) {
|
|
3675
3683
|
const previewResult = computePreview(ts, map);
|
|
@@ -3692,7 +3700,7 @@ function cmdPull(opts = {}) {
|
|
|
3692
3700
|
|
|
3693
3701
|
// src/commands.push.ts
|
|
3694
3702
|
init_config();
|
|
3695
|
-
import { existsSync as
|
|
3703
|
+
import { existsSync as existsSync31 } from "node:fs";
|
|
3696
3704
|
import { join as join38, relative as relative5 } from "node:path";
|
|
3697
3705
|
|
|
3698
3706
|
// src/commands.push.allowlist.ts
|
|
@@ -3773,7 +3781,7 @@ import { createInterface } from "node:readline/promises";
|
|
|
3773
3781
|
// src/commands.push.recovery.redact.ts
|
|
3774
3782
|
init_config();
|
|
3775
3783
|
init_config_sharedDirs_guard();
|
|
3776
|
-
import { cpSync as cpSync5, existsSync as
|
|
3784
|
+
import { cpSync as cpSync5, existsSync as existsSync29, mkdirSync as mkdirSync8, statSync as statSync8 } from "node:fs";
|
|
3777
3785
|
import { dirname as dirname5, join as join34, sep as sep2 } from "node:path";
|
|
3778
3786
|
init_push_gitleaks_scan();
|
|
3779
3787
|
init_utils_json();
|
|
@@ -3863,7 +3871,7 @@ function applyRedact(f, ts, map, nowMs, scan = scanFile) {
|
|
|
3863
3871
|
}
|
|
3864
3872
|
mkdirSync8(stagedProjectDir, { recursive: true });
|
|
3865
3873
|
cpSync5(localPath, join34(stagedProjectDir, `${sid}.jsonl`), { force: true });
|
|
3866
|
-
if (
|
|
3874
|
+
if (existsSync29(sessionDir)) {
|
|
3867
3875
|
cpSync5(sessionDir, join34(stagedProjectDir, sid), { force: true, recursive: true });
|
|
3868
3876
|
}
|
|
3869
3877
|
return true;
|
|
@@ -4084,7 +4092,7 @@ init_color();
|
|
|
4084
4092
|
init_config();
|
|
4085
4093
|
init_config_sharedDirs_guard();
|
|
4086
4094
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
4087
|
-
import { copyFileSync, existsSync as
|
|
4095
|
+
import { copyFileSync, existsSync as existsSync30, mkdirSync as mkdirSync9, readdirSync as readdirSync10, rmSync as rmSync11 } from "node:fs";
|
|
4088
4096
|
import { homedir as homedir5 } from "node:os";
|
|
4089
4097
|
import { join as join37 } from "node:path";
|
|
4090
4098
|
init_push_leak_verdict();
|
|
@@ -4102,7 +4110,7 @@ function stageSessions(tmpRoot, map) {
|
|
|
4102
4110
|
reverse.set(encodePath(p), logical);
|
|
4103
4111
|
}
|
|
4104
4112
|
const localProjects = join37(CLAUDE_HOME, "projects");
|
|
4105
|
-
if (!
|
|
4113
|
+
if (!existsSync30(localProjects)) return 0;
|
|
4106
4114
|
let staged = 0;
|
|
4107
4115
|
for (const dir of readdirSync10(localProjects)) {
|
|
4108
4116
|
const logical = reverse.get(dir);
|
|
@@ -4124,7 +4132,7 @@ function stageExtras(tmpRoot, map) {
|
|
|
4124
4132
|
for (const dirname6 of dirnames) {
|
|
4125
4133
|
if (!whitelist.includes(dirname6)) continue;
|
|
4126
4134
|
const src = join37(localRoot, dirname6);
|
|
4127
|
-
if (!
|
|
4135
|
+
if (!existsSync30(src)) continue;
|
|
4128
4136
|
const dst = join37(tmpRoot, "shared", "extras", logical, dirname6);
|
|
4129
4137
|
copyExtras(src, dst);
|
|
4130
4138
|
staged++;
|
|
@@ -4144,7 +4152,7 @@ function previewPushLeaks(map) {
|
|
|
4144
4152
|
return { leak: false, verdictRow: NOTHING_TO_SCAN_ROW, recovery: null, findings: [] };
|
|
4145
4153
|
}
|
|
4146
4154
|
const ignoreFile = join37(REPO_HOME, ".gitleaksignore");
|
|
4147
|
-
if (
|
|
4155
|
+
if (existsSync30(ignoreFile)) {
|
|
4148
4156
|
copyFileSync(ignoreFile, join37(tmpRoot, ".gitleaksignore"));
|
|
4149
4157
|
}
|
|
4150
4158
|
let findings;
|
|
@@ -4219,7 +4227,7 @@ async function cmdPush(opts = {}) {
|
|
|
4219
4227
|
const allowAll = opts.allowAll === true;
|
|
4220
4228
|
const allowRule = opts.allowRule;
|
|
4221
4229
|
guardResolutionModeConflicts(dryRun, redactAll, allowAll, allowRule);
|
|
4222
|
-
if (!
|
|
4230
|
+
if (!existsSync31(REPO_HOME)) die(`repo not cloned at ${REPO_HOME}`);
|
|
4223
4231
|
const handle = acquireLock("push");
|
|
4224
4232
|
if (handle === null) process.exit(0);
|
|
4225
4233
|
try {
|
|
@@ -4238,7 +4246,7 @@ async function cmdPush(opts = {}) {
|
|
|
4238
4246
|
return;
|
|
4239
4247
|
}
|
|
4240
4248
|
const mapPath = join38(REPO_HOME, "path-map.json");
|
|
4241
|
-
if (!
|
|
4249
|
+
if (!existsSync31(mapPath)) {
|
|
4242
4250
|
if (dryRun) return runDryRunPreview(st, null);
|
|
4243
4251
|
die("path-map.json missing, cannot enforce push allow-list");
|
|
4244
4252
|
}
|
|
@@ -4278,17 +4286,17 @@ init_config();
|
|
|
4278
4286
|
|
|
4279
4287
|
// src/diff.ts
|
|
4280
4288
|
init_config();
|
|
4281
|
-
import { existsSync as
|
|
4289
|
+
import { existsSync as existsSync32 } from "node:fs";
|
|
4282
4290
|
import { join as join39 } from "node:path";
|
|
4283
4291
|
init_utils();
|
|
4284
4292
|
init_utils_fs();
|
|
4285
4293
|
init_utils_json();
|
|
4286
4294
|
function cmdDiff() {
|
|
4287
4295
|
try {
|
|
4288
|
-
if (!
|
|
4296
|
+
if (!existsSync32(REPO_HOME)) die(`repo not cloned at ${REPO_HOME}`);
|
|
4289
4297
|
const ts = freshBackupTs(BACKUP_BASE);
|
|
4290
4298
|
const mapPath = join39(REPO_HOME, "path-map.json");
|
|
4291
|
-
const map =
|
|
4299
|
+
const map = existsSync32(mapPath) ? readPathMap(mapPath) : { projects: {} };
|
|
4292
4300
|
const result = computePreview(ts, map);
|
|
4293
4301
|
emitSummary("diff", result.unmapped);
|
|
4294
4302
|
} catch (err) {
|
|
@@ -4303,7 +4311,7 @@ function cmdDiff() {
|
|
|
4303
4311
|
|
|
4304
4312
|
// src/init.ts
|
|
4305
4313
|
init_config();
|
|
4306
|
-
import { existsSync as
|
|
4314
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync10, writeFileSync as writeFileSync6 } from "node:fs";
|
|
4307
4315
|
import { join as join41 } from "node:path";
|
|
4308
4316
|
|
|
4309
4317
|
// src/init.gh-onboard.ts
|
|
@@ -4385,16 +4393,16 @@ init_config();
|
|
|
4385
4393
|
init_utils();
|
|
4386
4394
|
init_utils_fs();
|
|
4387
4395
|
init_utils_json();
|
|
4388
|
-
import { copyFileSync as copyFileSync2, cpSync as cpSync6, existsSync as
|
|
4396
|
+
import { copyFileSync as copyFileSync2, cpSync as cpSync6, existsSync as existsSync33, rmSync as rmSync12, statSync as statSync9 } from "node:fs";
|
|
4389
4397
|
import { join as join40 } from "node:path";
|
|
4390
4398
|
function snapshotIntoShared(map) {
|
|
4391
4399
|
for (const name of allSharedLinks(map)) {
|
|
4392
4400
|
const src = join40(CLAUDE_HOME, name);
|
|
4393
|
-
if (!
|
|
4401
|
+
if (!existsSync33(src)) continue;
|
|
4394
4402
|
const dst = join40(REPO_HOME, "shared", name);
|
|
4395
4403
|
if (statSync9(src).isDirectory()) {
|
|
4396
4404
|
const gk = join40(dst, ".gitkeep");
|
|
4397
|
-
if (
|
|
4405
|
+
if (existsSync33(gk)) rmSync12(gk);
|
|
4398
4406
|
cpSync6(src, dst, { recursive: true, force: false, errorOnExist: true });
|
|
4399
4407
|
} else {
|
|
4400
4408
|
copyFileSync2(src, dst);
|
|
@@ -4402,7 +4410,7 @@ function snapshotIntoShared(map) {
|
|
|
4402
4410
|
log(`snapshotted shared/${name} from ${src}`);
|
|
4403
4411
|
}
|
|
4404
4412
|
const userSettings = join40(CLAUDE_HOME, "settings.json");
|
|
4405
|
-
if (
|
|
4413
|
+
if (existsSync33(userSettings)) {
|
|
4406
4414
|
let parsed;
|
|
4407
4415
|
try {
|
|
4408
4416
|
parsed = readJson(userSettings);
|
|
@@ -4429,7 +4437,7 @@ function preflightConflict(repoHome) {
|
|
|
4429
4437
|
join41(repoHome, "shared")
|
|
4430
4438
|
];
|
|
4431
4439
|
for (const c of candidates) {
|
|
4432
|
-
if (
|
|
4440
|
+
if (existsSync34(c)) return c;
|
|
4433
4441
|
}
|
|
4434
4442
|
return null;
|
|
4435
4443
|
}
|
|
@@ -4448,7 +4456,7 @@ function cmdInit(opts = {}) {
|
|
|
4448
4456
|
mkdirSync10(join41(REPO_HOME, "shared", name), { recursive: true });
|
|
4449
4457
|
}
|
|
4450
4458
|
const userClaudeMd = join41(CLAUDE_HOME, "CLAUDE.md");
|
|
4451
|
-
if (!snapshot || !
|
|
4459
|
+
if (!snapshot || !existsSync34(userClaudeMd)) {
|
|
4452
4460
|
writeFileSync6(join41(REPO_HOME, "shared", "CLAUDE.md"), SHARED_CLAUDE_MD);
|
|
4453
4461
|
log("created shared/CLAUDE.md");
|
|
4454
4462
|
}
|
|
@@ -4722,7 +4730,7 @@ function parsePushArgs(argv) {
|
|
|
4722
4730
|
// package.json
|
|
4723
4731
|
var package_default = {
|
|
4724
4732
|
name: "claude-nomad",
|
|
4725
|
-
version: "0.
|
|
4733
|
+
version: "0.39.0",
|
|
4726
4734
|
type: "module",
|
|
4727
4735
|
description: "Sync Claude Code config (~/.claude/) across machines via a private Git repo, with path remapping and per-host settings overrides.",
|
|
4728
4736
|
keywords: [
|
|
@@ -4912,7 +4920,7 @@ var DEFAULT_HELP = [
|
|
|
4912
4920
|
init_config();
|
|
4913
4921
|
init_utils();
|
|
4914
4922
|
init_utils_json();
|
|
4915
|
-
import { existsSync as
|
|
4923
|
+
import { existsSync as existsSync35, readFileSync as readFileSync11, readdirSync as readdirSync11 } from "node:fs";
|
|
4916
4924
|
import { join as join42 } from "node:path";
|
|
4917
4925
|
function resumeCmd(sessionId) {
|
|
4918
4926
|
if (!/^[A-Za-z0-9_-]+$/.test(sessionId) || sessionId.length > 128) {
|
|
@@ -4920,7 +4928,7 @@ function resumeCmd(sessionId) {
|
|
|
4920
4928
|
process.exit(1);
|
|
4921
4929
|
}
|
|
4922
4930
|
const projectsRoot = join42(CLAUDE_HOME, "projects");
|
|
4923
|
-
if (!
|
|
4931
|
+
if (!existsSync35(projectsRoot)) {
|
|
4924
4932
|
fail(`${projectsRoot} does not exist`);
|
|
4925
4933
|
process.exit(1);
|
|
4926
4934
|
}
|
|
@@ -4935,7 +4943,7 @@ function resumeCmd(sessionId) {
|
|
|
4935
4943
|
process.exit(1);
|
|
4936
4944
|
}
|
|
4937
4945
|
const mapPath = join42(REPO_HOME, "path-map.json");
|
|
4938
|
-
if (!
|
|
4946
|
+
if (!existsSync35(mapPath)) {
|
|
4939
4947
|
fail("path-map.json missing");
|
|
4940
4948
|
process.exit(1);
|
|
4941
4949
|
}
|
|
@@ -4959,7 +4967,7 @@ function resumeCmd(sessionId) {
|
|
|
4959
4967
|
function findTranscriptPath(projectsRoot, sessionId) {
|
|
4960
4968
|
for (const dir of readdirSync11(projectsRoot)) {
|
|
4961
4969
|
const candidate = join42(projectsRoot, dir, `${sessionId}.jsonl`);
|
|
4962
|
-
if (
|
|
4970
|
+
if (existsSync35(candidate)) return candidate;
|
|
4963
4971
|
}
|
|
4964
4972
|
return null;
|
|
4965
4973
|
}
|
package/package.json
CHANGED