@westbayberry/dg 1.1.3 → 1.1.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.
Files changed (2) hide show
  1. package/dist/index.mjs +303 -629
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1801,70 +1801,50 @@ __export(paths_exports, {
1801
1801
  dgCachePath: () => dgCachePath,
1802
1802
  dgConfigDir: () => dgConfigDir,
1803
1803
  dgConfigPath: () => dgConfigPath,
1804
- dgMigrationBreadcrumb: () => dgMigrationBreadcrumb,
1805
- dgMigrationLock: () => dgMigrationLock,
1806
1804
  dgPaths: () => dgPaths,
1807
1805
  dgReadme: () => dgReadme,
1808
1806
  dgRoot: () => dgRoot,
1809
1807
  dgStateDir: () => dgStateDir,
1810
- dgStatePath: () => dgStatePath,
1811
- legacyPaths: () => legacyPaths
1808
+ dgStatePath: () => dgStatePath
1812
1809
  });
1813
1810
  import { homedir } from "node:os";
1814
- import { join as join2, isAbsolute } from "node:path";
1811
+ import { join, isAbsolute } from "node:path";
1815
1812
  function safeAbsolute(p, fallback) {
1816
1813
  if (!p || typeof p !== "string") return fallback;
1817
1814
  if (!isAbsolute(p)) return fallback;
1818
1815
  return p;
1819
1816
  }
1820
1817
  function dgRoot() {
1821
- return join2(homedir(), `.${ROOT_DIR_NAME}`);
1818
+ return join(homedir(), `.${ROOT_DIR_NAME}`);
1822
1819
  }
1823
1820
  function dgConfigDir() {
1824
1821
  const xdg = safeAbsolute(process.env.XDG_CONFIG_HOME, "");
1825
- if (xdg) return join2(xdg, ROOT_DIR_NAME);
1822
+ if (xdg) return join(xdg, ROOT_DIR_NAME);
1826
1823
  return dgRoot();
1827
1824
  }
1828
1825
  function dgCacheDir() {
1829
1826
  const explicit = safeAbsolute(process.env.DG_CACHE_DIR, "");
1830
1827
  if (explicit) return explicit;
1831
1828
  const xdg = safeAbsolute(process.env.XDG_CACHE_HOME, "");
1832
- if (xdg) return join2(xdg, ROOT_DIR_NAME);
1833
- return join2(dgRoot(), "cache");
1829
+ if (xdg) return join(xdg, ROOT_DIR_NAME);
1830
+ return join(dgRoot(), "cache");
1834
1831
  }
1835
1832
  function dgStateDir() {
1836
1833
  const xdg = safeAbsolute(process.env.XDG_STATE_HOME, "");
1837
- if (xdg) return join2(xdg, ROOT_DIR_NAME);
1838
- return join2(dgRoot(), "state");
1834
+ if (xdg) return join(xdg, ROOT_DIR_NAME);
1835
+ return join(dgRoot(), "state");
1839
1836
  }
1840
1837
  function dgConfigPath() {
1841
- return join2(dgConfigDir(), "config.json");
1838
+ return join(dgConfigDir(), "config.json");
1842
1839
  }
1843
1840
  function dgCachePath(name) {
1844
- return join2(dgCacheDir(), name);
1841
+ return join(dgCacheDir(), name);
1845
1842
  }
1846
1843
  function dgStatePath(name) {
1847
- return join2(dgStateDir(), name);
1848
- }
1849
- function dgMigrationBreadcrumb() {
1850
- return join2(dgRoot(), ".migrated-from-v1");
1851
- }
1852
- function dgMigrationLock() {
1853
- return join2(dgRoot(), ".migration.lock");
1844
+ return join(dgStateDir(), name);
1854
1845
  }
1855
1846
  function dgReadme() {
1856
- return join2(dgRoot(), "README.txt");
1857
- }
1858
- function legacyPaths() {
1859
- const home = homedir();
1860
- const depGuardianDir = join2(home, ".dependency-guardian");
1861
- return {
1862
- dgrc: join2(home, ".dgrc.json"),
1863
- cacheDir: depGuardianDir,
1864
- updateCheck: join2(home, ".dg-update-check.json"),
1865
- aliasesShOld: join2(depGuardianDir, "aliases.sh"),
1866
- depGuardianDir
1867
- };
1847
+ return join(dgRoot(), "README.txt");
1868
1848
  }
1869
1849
  function dgPaths() {
1870
1850
  return {
@@ -1876,9 +1856,7 @@ function dgPaths() {
1876
1856
  updateCheck: dgCachePath("update-check.json"),
1877
1857
  aliasesSh: dgStatePath("aliases.sh"),
1878
1858
  hooksRegistry: dgStatePath("hooks-installed.json"),
1879
- readme: dgReadme(),
1880
- migrationBreadcrumb: dgMigrationBreadcrumb(),
1881
- migrationLock: dgMigrationLock()
1859
+ readme: dgReadme()
1882
1860
  };
1883
1861
  }
1884
1862
  var ROOT_DIR_NAME;
@@ -2519,7 +2497,7 @@ __export(config_exports, {
2519
2497
  });
2520
2498
  import { parseArgs } from "node:util";
2521
2499
  import { readFileSync as readFileSync2, existsSync as existsSync2 } from "node:fs";
2522
- import { join as join3, dirname as dirname2 } from "node:path";
2500
+ import { join as join2, dirname as dirname2 } from "node:path";
2523
2501
  import { fileURLToPath } from "node:url";
2524
2502
  function levenshtein(a, b) {
2525
2503
  if (a === b) return 0;
@@ -2560,28 +2538,24 @@ function warnUnknownDgrcKeys(parsed, source) {
2560
2538
  }
2561
2539
  }
2562
2540
  function loadDgrc() {
2563
- const cwdPath = join3(process.cwd(), ".dgrc.json");
2541
+ const cwdPath = join2(process.cwd(), ".dgrc.json");
2564
2542
  const homePath = dgConfigPath();
2565
- const legacyHomePath = legacyPaths().dgrc;
2566
2543
  let config = {};
2567
- const sources = [homePath, legacyHomePath].filter((p, i, arr) => arr.indexOf(p) === i);
2568
- for (const src of sources) {
2569
- if (!existsSync2(src)) continue;
2544
+ if (existsSync2(homePath)) {
2570
2545
  try {
2571
- const data = JSON.parse(readFileSync2(src, "utf-8"));
2572
- warnUnknownDgrcKeys(data, src);
2546
+ const data = JSON.parse(readFileSync2(homePath, "utf-8"));
2547
+ warnUnknownDgrcKeys(data, homePath);
2573
2548
  const filtered = {};
2574
2549
  for (const k of KNOWN_DGRC_KEYS) {
2575
2550
  if (k in data) filtered[k] = data[k];
2576
2551
  }
2577
2552
  config = filtered;
2578
- break;
2579
2553
  } catch {
2580
- process.stderr.write(`Warning: Failed to parse ${src}, ignoring.
2554
+ process.stderr.write(`Warning: Failed to parse ${homePath}, ignoring.
2581
2555
  `);
2582
2556
  }
2583
2557
  }
2584
- if (cwdPath !== homePath && cwdPath !== legacyHomePath && existsSync2(cwdPath) && process.env.DG_QUIET !== "1") {
2558
+ if (cwdPath !== homePath && existsSync2(cwdPath) && process.env.DG_QUIET !== "1") {
2585
2559
  process.stderr.write(
2586
2560
  `dg: note: ./.dgrc.json is ignored (repo-controlled config is no longer honored). Use ~/.dg/.dgrc.json, env vars (DG_MODE, DG_API_URL), or CLI flags.
2587
2561
  `
@@ -2619,7 +2593,7 @@ function getVersion() {
2619
2593
  try {
2620
2594
  const thisDir = dirname2(fileURLToPath(import.meta.url));
2621
2595
  const pkg = JSON.parse(
2622
- readFileSync2(join3(thisDir, "..", "package.json"), "utf-8")
2596
+ readFileSync2(join2(thisDir, "..", "package.json"), "utf-8")
2623
2597
  );
2624
2598
  return pkg.version ?? "1.0.0";
2625
2599
  } catch {
@@ -3067,8 +3041,8 @@ var init_terminal_state = __esm({
3067
3041
  });
3068
3042
 
3069
3043
  // src/shims/safe-fs.ts
3070
- import { existsSync as existsSync5, lstatSync as lstatSync3, mkdirSync as mkdirSync4, renameSync, statSync as statSync2, unlinkSync as unlinkSync4, writeFileSync as writeFileSync4 } from "node:fs";
3071
- import { dirname as dirname5, sep } from "node:path";
3044
+ import { existsSync as existsSync4, lstatSync as lstatSync3, mkdirSync as mkdirSync3, renameSync, statSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3 } from "node:fs";
3045
+ import { dirname as dirname4, sep } from "node:path";
3072
3046
  import { homedir as homedir2 } from "node:os";
3073
3047
  function ensureUnderHome(target) {
3074
3048
  const home = homedir2();
@@ -3097,28 +3071,28 @@ function safeMkdirRecursive(target, mode = 493) {
3097
3071
  for (const segment of rel) {
3098
3072
  cur = cur + sep + segment;
3099
3073
  lstatNoSymlink(cur);
3100
- if (!existsSync5(cur)) {
3101
- mkdirSync4(cur, { mode });
3074
+ if (!existsSync4(cur)) {
3075
+ mkdirSync3(cur, { mode });
3102
3076
  }
3103
3077
  }
3104
3078
  }
3105
3079
  function safeWriteFile(target, content, mode = 420) {
3106
3080
  ensureUnderHome(target);
3107
- lstatNoSymlink(dirname5(target));
3081
+ lstatNoSymlink(dirname4(target));
3108
3082
  lstatNoSymlink(target);
3109
- writeFileSync4(target, content, { mode });
3083
+ writeFileSync3(target, content, { mode });
3110
3084
  }
3111
3085
  function atomicWriteFile(target, content, mode = 420) {
3112
3086
  ensureUnderHome(target);
3113
- lstatNoSymlink(dirname5(target));
3087
+ lstatNoSymlink(dirname4(target));
3114
3088
  lstatNoSymlink(target);
3115
3089
  const tmp = `${target}.tmp.${process.pid}.${Date.now()}`;
3116
- writeFileSync4(tmp, content, { mode });
3090
+ writeFileSync3(tmp, content, { mode });
3117
3091
  renameSync(tmp, target);
3118
3092
  }
3119
3093
  function isExecutable(path2) {
3120
3094
  try {
3121
- const st = statSync2(path2);
3095
+ const st = statSync(path2);
3122
3096
  return st.isFile() && (st.mode & 73) !== 0;
3123
3097
  } catch {
3124
3098
  return false;
@@ -3132,7 +3106,7 @@ function safeUnlink(target) {
3132
3106
  if (e instanceof UnsafePathError) throw e;
3133
3107
  }
3134
3108
  try {
3135
- unlinkSync4(target);
3109
+ unlinkSync3(target);
3136
3110
  } catch (e) {
3137
3111
  const code = e.code;
3138
3112
  if (code !== "ENOENT") throw e;
@@ -3261,10 +3235,10 @@ exit /b 127
3261
3235
 
3262
3236
  // src/shims/rc-syntax.ts
3263
3237
  import { homedir as homedir3 } from "node:os";
3264
- import { join as join4 } from "node:path";
3265
- import { existsSync as existsSync6, readFileSync as readFileSync5, lstatSync as lstatSync4, appendFileSync, writeFileSync as writeFileSync5 } from "node:fs";
3238
+ import { join as join3 } from "node:path";
3239
+ import { existsSync as existsSync5, readFileSync as readFileSync4, lstatSync as lstatSync4, appendFileSync, writeFileSync as writeFileSync4 } from "node:fs";
3266
3240
  function expandHome(path2) {
3267
- if (path2.startsWith("~/")) return join4(homedir3(), path2.slice(2));
3241
+ if (path2.startsWith("~/")) return join3(homedir3(), path2.slice(2));
3268
3242
  return path2;
3269
3243
  }
3270
3244
  function detectShellKind(envShell) {
@@ -3278,13 +3252,13 @@ function rcCandidates(kind) {
3278
3252
  const home = homedir3();
3279
3253
  switch (kind) {
3280
3254
  case "zsh":
3281
- return [join4(home, ".zshrc")];
3255
+ return [join3(home, ".zshrc")];
3282
3256
  case "bash":
3283
- return [join4(home, ".bashrc"), join4(home, ".bash_profile")];
3257
+ return [join3(home, ".bashrc"), join3(home, ".bash_profile")];
3284
3258
  case "fish":
3285
- return [join4(home, ".config", "fish", "config.fish")];
3259
+ return [join3(home, ".config", "fish", "config.fish")];
3286
3260
  case "sh":
3287
- return [join4(home, ".profile")];
3261
+ return [join3(home, ".profile")];
3288
3262
  }
3289
3263
  }
3290
3264
  function pathSnippet(kind) {
@@ -3307,12 +3281,12 @@ function appendSentinelBlock(rcPath, snippet) {
3307
3281
  return { status: "failed", path: resolved, reason: e.message };
3308
3282
  }
3309
3283
  }
3310
- if (existsSync6(resolved)) {
3284
+ if (existsSync5(resolved)) {
3311
3285
  const st = lstatSync4(resolved);
3312
3286
  if (!st.isFile()) {
3313
3287
  return { status: "failed", path: resolved, reason: "rc path is not a regular file" };
3314
3288
  }
3315
- const existing = readFileSync5(resolved, "utf-8");
3289
+ const existing = readFileSync4(resolved, "utf-8");
3316
3290
  if (existing.includes(RC_SENTINEL_OPEN)) {
3317
3291
  return { status: "already-present", path: resolved };
3318
3292
  }
@@ -3323,10 +3297,10 @@ ${snippet}
3323
3297
  ${RC_SENTINEL_CLOSE}
3324
3298
  `;
3325
3299
  try {
3326
- if (existsSync6(resolved)) {
3300
+ if (existsSync5(resolved)) {
3327
3301
  appendFileSync(resolved, block, { encoding: "utf-8" });
3328
3302
  } else {
3329
- writeFileSync5(resolved, block, { encoding: "utf-8", mode: 420 });
3303
+ writeFileSync4(resolved, block, { encoding: "utf-8", mode: 420 });
3330
3304
  }
3331
3305
  return { status: "appended", path: resolved };
3332
3306
  } catch (e) {
@@ -3340,7 +3314,7 @@ function stripSentinelBlock(rcPath) {
3340
3314
  } catch (e) {
3341
3315
  return { status: "failed", path: resolved, reason: e.message };
3342
3316
  }
3343
- if (!existsSync6(resolved)) {
3317
+ if (!existsSync5(resolved)) {
3344
3318
  return { status: "already-present", path: resolved };
3345
3319
  }
3346
3320
  try {
@@ -3350,7 +3324,7 @@ function stripSentinelBlock(rcPath) {
3350
3324
  return { status: "failed", path: resolved, reason: e.message };
3351
3325
  }
3352
3326
  }
3353
- const original = readFileSync5(resolved, "utf-8");
3327
+ const original = readFileSync4(resolved, "utf-8");
3354
3328
  if (!original.includes(RC_SENTINEL_OPEN)) {
3355
3329
  return { status: "already-present", path: resolved };
3356
3330
  }
@@ -3377,7 +3351,7 @@ function stripSentinelBlock(rcPath) {
3377
3351
  if (original.endsWith("\n") && !result.endsWith("\n")) result += "\n";
3378
3352
  if (!original.endsWith("\n") && result.endsWith("\n")) result = result.slice(0, -1);
3379
3353
  try {
3380
- writeFileSync5(resolved, result, { encoding: "utf-8" });
3354
+ writeFileSync4(resolved, result, { encoding: "utf-8" });
3381
3355
  return { status: "appended", path: resolved };
3382
3356
  } catch (e) {
3383
3357
  return { status: "failed", path: resolved, reason: e.message };
@@ -3401,11 +3375,11 @@ __export(resolve_exports, {
3401
3375
  resolveRealBinary: () => resolveRealBinary,
3402
3376
  walkPathExcludingShimDir: () => walkPathExcludingShimDir
3403
3377
  });
3404
- import { existsSync as existsSync7, readFileSync as readFileSync6 } from "node:fs";
3405
- import { join as join5, delimiter, sep as sep2 } from "node:path";
3378
+ import { existsSync as existsSync6, readFileSync as readFileSync5 } from "node:fs";
3379
+ import { join as join4, delimiter, sep as sep2 } from "node:path";
3406
3380
  import { homedir as homedir4 } from "node:os";
3407
3381
  function shimDir() {
3408
- return join5(homedir4(), ".dg", "shims");
3382
+ return join4(homedir4(), ".dg", "shims");
3409
3383
  }
3410
3384
  function walkPathExcludingShimDir(name, extraExtensions = []) {
3411
3385
  const raw = process.env.PATH ?? "/usr/bin:/bin";
@@ -3415,7 +3389,7 @@ function walkPathExcludingShimDir(name, extraExtensions = []) {
3415
3389
  for (const dir of parts) {
3416
3390
  if (dir === shims || dir.startsWith(shims + sep2)) continue;
3417
3391
  for (const ext of ["", ...exts]) {
3418
- const candidate = join5(dir, name + ext);
3392
+ const candidate = join4(dir, name + ext);
3419
3393
  if (isExecutable(candidate)) return candidate;
3420
3394
  }
3421
3395
  }
@@ -3430,7 +3404,7 @@ function platformExtensions() {
3430
3404
  }
3431
3405
  function readCache2() {
3432
3406
  try {
3433
- const raw = readFileSync6(CACHE_PATH(), "utf-8");
3407
+ const raw = readFileSync5(CACHE_PATH(), "utf-8");
3434
3408
  const parsed = JSON.parse(raw);
3435
3409
  if (typeof parsed === "object" && parsed !== null) {
3436
3410
  return parsed;
@@ -3452,7 +3426,7 @@ function resolveRealBinary(ecosystem) {
3452
3426
  }
3453
3427
  const cache3 = readCache2();
3454
3428
  const cached = cache3[ecosystem];
3455
- if (cached && existsSync7(cached) && isExecutable(cached)) {
3429
+ if (cached && existsSync6(cached) && isExecutable(cached)) {
3456
3430
  return cached;
3457
3431
  }
3458
3432
  const resolved = walkPath(ecosystem, exts);
@@ -3499,13 +3473,13 @@ __export(install_exports, {
3499
3473
  uninstallShims: () => uninstallShims
3500
3474
  });
3501
3475
  import { homedir as homedir5 } from "node:os";
3502
- import { join as join6, dirname as dirname6 } from "node:path";
3476
+ import { join as join5, dirname as dirname5 } from "node:path";
3503
3477
  import { fileURLToPath as fileURLToPath2 } from "node:url";
3504
- import { chmodSync as chmodSync4, chownSync, existsSync as existsSync8, readdirSync, readFileSync as readFileSync7, statSync as statSync3, appendFileSync as appendFileSync2, writeFileSync as writeFileSync6 } from "node:fs";
3478
+ import { chmodSync as chmodSync3, chownSync, existsSync as existsSync7, readdirSync, readFileSync as readFileSync6, statSync as statSync2, appendFileSync as appendFileSync2, writeFileSync as writeFileSync5 } from "node:fs";
3505
3479
  import { spawnSync } from "node:child_process";
3506
3480
  import { randomBytes } from "node:crypto";
3507
3481
  function dgShimDir() {
3508
- return join6(homedir5(), ".dg", "shims");
3482
+ return join5(homedir5(), ".dg", "shims");
3509
3483
  }
3510
3484
  function noncePath() {
3511
3485
  return dgStatePath("shim-nonce");
@@ -3517,12 +3491,12 @@ function bypassLogPath() {
3517
3491
  return dgStatePath("bypass.log");
3518
3492
  }
3519
3493
  function dgEntryStatePath(targetHome) {
3520
- return join6(targetHome, ".dg", "state", "dg-entry");
3494
+ return join5(targetHome, ".dg", "state", "dg-entry");
3521
3495
  }
3522
3496
  function currentDgEntry() {
3523
3497
  try {
3524
- const entry = join6(dirname6(fileURLToPath2(import.meta.url)), "index.mjs");
3525
- if (existsSync8(entry)) return entry;
3498
+ const entry = join5(dirname5(fileURLToPath2(import.meta.url)), "index.mjs");
3499
+ if (existsSync7(entry)) return entry;
3526
3500
  } catch {
3527
3501
  }
3528
3502
  try {
@@ -3538,18 +3512,18 @@ function ensureDgEntryRecorded(targetHome = homedir5()) {
3538
3512
  const path2 = dgEntryStatePath(targetHome);
3539
3513
  let existing = null;
3540
3514
  try {
3541
- existing = readFileSync7(path2, "utf-8").trim();
3515
+ existing = readFileSync6(path2, "utf-8").trim();
3542
3516
  } catch {
3543
3517
  }
3544
3518
  if (existing === entry) return;
3545
- safeMkdirRecursive(dirname6(path2), 493);
3519
+ safeMkdirRecursive(dirname5(path2), 493);
3546
3520
  safeWriteFile(path2, entry + "\n", 420);
3547
3521
  } catch {
3548
3522
  }
3549
3523
  }
3550
3524
  function readNonce() {
3551
3525
  try {
3552
- const raw = readFileSync7(noncePath(), "utf-8").trim();
3526
+ const raw = readFileSync6(noncePath(), "utf-8").trim();
3553
3527
  return raw.length > 0 ? raw : null;
3554
3528
  } catch {
3555
3529
  return null;
@@ -3591,13 +3565,13 @@ function persistWindowsPath(shimsDir, outcomes) {
3591
3565
  }
3592
3566
  function updatePowerShellProfile(targetHome, shimsDir, outcomes) {
3593
3567
  if (process.platform !== "win32") return;
3594
- const profilePath = join6(targetHome, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
3595
- if (!existsSync8(profilePath)) {
3568
+ const profilePath = join5(targetHome, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
3569
+ if (!existsSync7(profilePath)) {
3596
3570
  outcomes.push({ status: "already-present", path: profilePath });
3597
3571
  return;
3598
3572
  }
3599
3573
  try {
3600
- const existing = readFileSync7(profilePath, "utf-8");
3574
+ const existing = readFileSync6(profilePath, "utf-8");
3601
3575
  if (existing.includes(">>> dg-managed >>>")) {
3602
3576
  outcomes.push({ status: "already-present", path: profilePath });
3603
3577
  return;
@@ -3616,12 +3590,12 @@ $env:Path = "${shimsDir};$env:Path"
3616
3590
  function chownTreeIfNeeded(root, uid, gid) {
3617
3591
  if (uid === void 0 || gid === void 0) return;
3618
3592
  if (process.platform === "win32") return;
3619
- if (!existsSync8(root)) return;
3593
+ if (!existsSync7(root)) return;
3620
3594
  chownIfNeeded(root, uid, gid);
3621
3595
  try {
3622
3596
  for (const entry of readdirSync(root)) {
3623
- const child = join6(root, entry);
3624
- const st = statSync3(child);
3597
+ const child = join5(root, entry);
3598
+ const st = statSync2(child);
3625
3599
  if (st.isDirectory()) {
3626
3600
  chownTreeIfNeeded(child, uid, gid);
3627
3601
  } else {
@@ -3634,18 +3608,18 @@ function chownTreeIfNeeded(root, uid, gid) {
3634
3608
  function installShims(opts = {}) {
3635
3609
  const targetHome = opts.targetHome ?? homedir5();
3636
3610
  const platform3 = opts.platform ?? (process.platform === "win32" ? "windows" : "unix");
3637
- const dgRoot2 = join6(targetHome, ".dg");
3638
- const shimsDir = join6(targetHome, ".dg", "shims");
3639
- const stateDir = join6(targetHome, ".dg", "state");
3611
+ const dgRoot2 = join5(targetHome, ".dg");
3612
+ const shimsDir = join5(targetHome, ".dg", "shims");
3613
+ const stateDir = join5(targetHome, ".dg", "state");
3640
3614
  safeMkdirRecursive(dgRoot2, 493);
3641
3615
  safeMkdirRecursive(stateDir, 493);
3642
3616
  safeMkdirRecursive(shimsDir, 493);
3643
3617
  const nonce = randomBytes(16).toString("hex");
3644
- const noncePathResolved = join6(stateDir, "shim-nonce");
3618
+ const noncePathResolved = join5(stateDir, "shim-nonce");
3645
3619
  safeWriteFile(noncePathResolved, nonce, 384);
3646
3620
  chownIfNeeded(noncePathResolved, opts.targetUid, opts.targetGid);
3647
3621
  const dgEntry = currentDgEntry();
3648
- const dgEntryPathResolved = join6(stateDir, "dg-entry");
3622
+ const dgEntryPathResolved = join5(stateDir, "dg-entry");
3649
3623
  if (dgEntry) {
3650
3624
  safeWriteFile(dgEntryPathResolved, dgEntry + "\n", 420);
3651
3625
  chownIfNeeded(dgEntryPathResolved, opts.targetUid, opts.targetGid);
@@ -3653,10 +3627,10 @@ function installShims(opts = {}) {
3653
3627
  const shimsCreated = [];
3654
3628
  for (const eco of ECOSYSTEMS) {
3655
3629
  const filename = shimFilename(eco, platform3);
3656
- const fullPath = join6(shimsDir, filename);
3630
+ const fullPath = join5(shimsDir, filename);
3657
3631
  const body = renderShim({ ecosystem: eco, platform: platform3 });
3658
3632
  safeWriteFile(fullPath, body, platform3 === "windows" ? 420 : 493);
3659
- if (platform3 !== "windows") chmodSync4(fullPath, 493);
3633
+ if (platform3 !== "windows") chmodSync3(fullPath, 493);
3660
3634
  chownIfNeeded(fullPath, opts.targetUid, opts.targetGid);
3661
3635
  shimsCreated.push(filename);
3662
3636
  }
@@ -3668,7 +3642,7 @@ function installShims(opts = {}) {
3668
3642
  resolvedRealBinaries[eco] = resolveRealBinary(eco);
3669
3643
  }
3670
3644
  const cachePathResolved = realBinaryCachePath();
3671
- if (existsSync8(cachePathResolved)) {
3645
+ if (existsSync7(cachePathResolved)) {
3672
3646
  chownIfNeeded(cachePathResolved, opts.targetUid, opts.targetGid);
3673
3647
  }
3674
3648
  const rcOutcomes = [];
@@ -3703,7 +3677,7 @@ function installShims(opts = {}) {
3703
3677
  nodeVersion: process.version,
3704
3678
  dgVersion: process.env.DG_CLI_VERSION ?? "unknown"
3705
3679
  };
3706
- const receiptResolved = join6(stateDir, "install-receipt.json");
3680
+ const receiptResolved = join5(stateDir, "install-receipt.json");
3707
3681
  safeWriteFile(receiptResolved, JSON.stringify(receipt, null, 2), 420);
3708
3682
  chownIfNeeded(receiptResolved, opts.targetUid, opts.targetGid);
3709
3683
  chownTreeIfNeeded(dgRoot2, opts.targetUid, opts.targetGid);
@@ -3719,31 +3693,31 @@ function installShims(opts = {}) {
3719
3693
  function uninstallShims(opts = {}) {
3720
3694
  const targetHome = opts.targetHome ?? homedir5();
3721
3695
  const platform3 = opts.platform ?? (process.platform === "win32" ? "windows" : "unix");
3722
- const shimsDir = join6(targetHome, ".dg", "shims");
3723
- const stateDir = join6(targetHome, ".dg", "state");
3696
+ const shimsDir = join5(targetHome, ".dg", "shims");
3697
+ const stateDir = join5(targetHome, ".dg", "state");
3724
3698
  const shimsRemoved = [];
3725
- if (existsSync8(shimsDir)) {
3699
+ if (existsSync7(shimsDir)) {
3726
3700
  for (const eco of ECOSYSTEMS) {
3727
3701
  const filename = shimFilename(eco, platform3);
3728
- const fullPath = join6(shimsDir, filename);
3729
- if (existsSync8(fullPath)) {
3702
+ const fullPath = join5(shimsDir, filename);
3703
+ if (existsSync7(fullPath)) {
3730
3704
  safeUnlink(fullPath);
3731
3705
  shimsRemoved.push(filename);
3732
3706
  }
3733
3707
  }
3734
3708
  }
3735
3709
  const stateFiles = [
3736
- join6(stateDir, "shim-nonce"),
3737
- join6(stateDir, "dg-entry"),
3738
- join6(stateDir, "install-receipt.json"),
3739
- join6(stateDir, "real-binaries.json"),
3740
- join6(stateDir, "bypass.log"),
3741
- join6(stateDir, "wiring-hint-shown"),
3742
- join6(stateDir, "first-run-shown")
3710
+ join5(stateDir, "shim-nonce"),
3711
+ join5(stateDir, "dg-entry"),
3712
+ join5(stateDir, "install-receipt.json"),
3713
+ join5(stateDir, "real-binaries.json"),
3714
+ join5(stateDir, "bypass.log"),
3715
+ join5(stateDir, "wiring-hint-shown"),
3716
+ join5(stateDir, "first-run-shown")
3743
3717
  ];
3744
3718
  const stateFilesRemoved = [];
3745
3719
  for (const f of stateFiles) {
3746
- if (existsSync8(f)) {
3720
+ if (existsSync7(f)) {
3747
3721
  safeUnlink(f);
3748
3722
  stateFilesRemoved.push(f);
3749
3723
  }
@@ -3763,7 +3737,7 @@ function uninstallShims(opts = {}) {
3763
3737
  }
3764
3738
  function revertWindowsPath(targetHome, outcomes) {
3765
3739
  if (process.platform !== "win32") return;
3766
- const shimsDir = join6(targetHome, ".dg", "shims");
3740
+ const shimsDir = join5(targetHome, ".dg", "shims");
3767
3741
  const currentPath = process.env.PATH ?? "";
3768
3742
  if (!currentPath.toLowerCase().includes(shimsDir.toLowerCase())) {
3769
3743
  outcomes.push({ status: "already-present", path: "user PATH (HKCU\\Environment)" });
@@ -3787,19 +3761,19 @@ function revertWindowsPath(targetHome, outcomes) {
3787
3761
  }
3788
3762
  function revertPowerShellProfile(targetHome, outcomes) {
3789
3763
  if (process.platform !== "win32") return;
3790
- const profilePath = join6(targetHome, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
3791
- if (!existsSync8(profilePath)) {
3764
+ const profilePath = join5(targetHome, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
3765
+ if (!existsSync7(profilePath)) {
3792
3766
  outcomes.push({ status: "already-present", path: profilePath });
3793
3767
  return;
3794
3768
  }
3795
3769
  try {
3796
- const existing = readFileSync7(profilePath, "utf-8");
3770
+ const existing = readFileSync6(profilePath, "utf-8");
3797
3771
  if (!existing.includes(">>> dg-managed >>>")) {
3798
3772
  outcomes.push({ status: "already-present", path: profilePath });
3799
3773
  return;
3800
3774
  }
3801
3775
  const stripped = existing.replace(/\n?# >>> dg-managed >>>[\s\S]*?# <<< dg-managed <<<\n?/g, "");
3802
- writeFileSync6(profilePath, stripped, "utf-8");
3776
+ writeFileSync5(profilePath, stripped, "utf-8");
3803
3777
  outcomes.push({ status: "appended", path: profilePath });
3804
3778
  } catch (e) {
3805
3779
  outcomes.push({ status: "failed", path: profilePath, reason: e.message });
@@ -4020,8 +3994,8 @@ var first_run_exports = {};
4020
3994
  __export(first_run_exports, {
4021
3995
  maybeShowWelcomePanel: () => maybeShowWelcomePanel
4022
3996
  });
4023
- import { existsSync as existsSync9, writeFileSync as writeFileSync7, mkdirSync as mkdirSync5 } from "node:fs";
4024
- import { dirname as dirname7 } from "node:path";
3997
+ import { existsSync as existsSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync4 } from "node:fs";
3998
+ import { dirname as dirname6 } from "node:path";
4025
3999
  function welcomeShownPath() {
4026
4000
  return dgStatePath("first-run-shown");
4027
4001
  }
@@ -4031,8 +4005,8 @@ function installReceiptPath2() {
4031
4005
  async function maybeShowWelcomePanel(opts) {
4032
4006
  if (SKIP_LIST.has(opts.rawCommand)) return;
4033
4007
  if (!opts.isInteractive) return;
4034
- if (existsSync9(welcomeShownPath())) return;
4035
- if (!existsSync9(installReceiptPath2())) return;
4008
+ if (existsSync8(welcomeShownPath())) return;
4009
+ if (!existsSync8(installReceiptPath2())) return;
4036
4010
  try {
4037
4011
  const chalk18 = (await Promise.resolve().then(() => __toESM(require_source(), 1))).default;
4038
4012
  const lines = [
@@ -4049,8 +4023,8 @@ async function maybeShowWelcomePanel(opts) {
4049
4023
  ];
4050
4024
  process.stderr.write(lines.join("\n"));
4051
4025
  try {
4052
- mkdirSync5(dirname7(welcomeShownPath()), { recursive: true });
4053
- writeFileSync7(welcomeShownPath(), (/* @__PURE__ */ new Date()).toISOString(), { encoding: "utf-8", mode: 420 });
4026
+ mkdirSync4(dirname6(welcomeShownPath()), { recursive: true });
4027
+ writeFileSync6(welcomeShownPath(), (/* @__PURE__ */ new Date()).toISOString(), { encoding: "utf-8", mode: 420 });
4054
4028
  } catch {
4055
4029
  }
4056
4030
  } catch {
@@ -39227,13 +39201,13 @@ var celebrate_exports = {};
39227
39201
  __export(celebrate_exports, {
39228
39202
  celebrateFirstLoginIfNew: () => celebrateFirstLoginIfNew
39229
39203
  });
39230
- import { existsSync as existsSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync6 } from "node:fs";
39231
- import { dirname as dirname8 } from "node:path";
39204
+ import { existsSync as existsSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync5 } from "node:fs";
39205
+ import { dirname as dirname7 } from "node:path";
39232
39206
  function celebratedMarker() {
39233
39207
  return dgStatePath("login-celebrated");
39234
39208
  }
39235
39209
  function shouldCelebrate() {
39236
- if (existsSync11(celebratedMarker())) return false;
39210
+ if (existsSync10(celebratedMarker())) return false;
39237
39211
  if (process.env.CI === "1" || process.env.CI === "true") return false;
39238
39212
  if (process.env.DG_NO_CELEBRATE === "1") return false;
39239
39213
  if (!process.stderr.isTTY) return false;
@@ -39241,8 +39215,8 @@ function shouldCelebrate() {
39241
39215
  }
39242
39216
  function writeCelebratedMarker() {
39243
39217
  try {
39244
- mkdirSync6(dirname8(celebratedMarker()), { recursive: true });
39245
- writeFileSync8(celebratedMarker(), (/* @__PURE__ */ new Date()).toISOString(), { encoding: "utf-8", mode: 420 });
39218
+ mkdirSync5(dirname7(celebratedMarker()), { recursive: true });
39219
+ writeFileSync7(celebratedMarker(), (/* @__PURE__ */ new Date()).toISOString(), { encoding: "utf-8", mode: 420 });
39246
39220
  } catch {
39247
39221
  }
39248
39222
  }
@@ -41487,7 +41461,7 @@ function mergeResponses(results) {
41487
41461
  const anyBlock = results.some((r) => r.action === "block");
41488
41462
  const anyWarn = results.some((r) => r.action === "warn");
41489
41463
  const anyIncomplete = results.some((r) => r.action === "analysis_incomplete") || allPackages.some((p) => Array.isArray(p.findings) && p.findings.some((f) => f.id === "analysis_incomplete"));
41490
- const action = maxScore >= 70 || anyBlock ? "block" : maxScore >= 60 || anyWarn ? "warn" : anyIncomplete ? "analysis_incomplete" : "pass";
41464
+ const action = anyBlock ? "block" : anyWarn ? "warn" : anyIncomplete ? "analysis_incomplete" : "pass";
41491
41465
  const safeVersions = {};
41492
41466
  for (const r of results) {
41493
41467
  Object.assign(safeVersions, r.safeVersions);
@@ -42290,25 +42264,25 @@ var init_parse_package_json = __esm({
42290
42264
  });
42291
42265
 
42292
42266
  // src/lockfile/index.ts
42293
- import { readFileSync as readFileSync9, existsSync as existsSync12, statSync as statSync4 } from "node:fs";
42294
- import { join as join7 } from "node:path";
42267
+ import { readFileSync as readFileSync8, existsSync as existsSync11, statSync as statSync3 } from "node:fs";
42268
+ import { join as join6 } from "node:path";
42295
42269
  function readFileSafe(path2) {
42296
- const size = statSync4(path2).size;
42270
+ const size = statSync3(path2).size;
42297
42271
  if (size > MAX_LOCKFILE_BYTES) {
42298
42272
  throw new Error(`Lockfile too large (${(size / 1024 / 1024).toFixed(0)} MB, max 50 MB): ${path2}`);
42299
42273
  }
42300
- return readFileSync9(path2, "utf-8");
42274
+ return readFileSync8(path2, "utf-8");
42301
42275
  }
42302
42276
  function discoverChanges(cwd2, config) {
42303
42277
  if (config.workspace) {
42304
- cwd2 = join7(cwd2, config.workspace);
42278
+ cwd2 = join6(cwd2, config.workspace);
42305
42279
  }
42306
42280
  const lockfileInfo = findLockfile(cwd2);
42307
42281
  const pythonDepFiles = ["requirements.txt", "Pipfile.lock", "poetry.lock", "uv.lock"];
42308
42282
  let pythonPackages = [];
42309
42283
  const pythonSkipped = [];
42310
42284
  for (const pyFile of pythonDepFiles) {
42311
- if (existsSync12(join7(cwd2, pyFile))) {
42285
+ if (existsSync11(join6(cwd2, pyFile))) {
42312
42286
  const pyPkgs = parsePythonDepFile(cwd2, pyFile);
42313
42287
  for (const p of pyPkgs) {
42314
42288
  if (p.version === "latest") {
@@ -42342,7 +42316,7 @@ function discoverChanges(cwd2, config) {
42342
42316
  const headParsed = parseLockfileByType(headContent, lockfileInfo.type);
42343
42317
  const directDeps = getDirectDeps(cwd2);
42344
42318
  if (config.baseLockfile) {
42345
- if (!existsSync12(config.baseLockfile)) {
42319
+ if (!existsSync11(config.baseLockfile)) {
42346
42320
  throw new Error(`Base lockfile not found: ${config.baseLockfile}`);
42347
42321
  }
42348
42322
  const baseContent = readFileSafe(config.baseLockfile);
@@ -42367,8 +42341,8 @@ function discoverChanges(cwd2, config) {
42367
42341
  skipped: [...diff2.skipped, ...pythonSkipped]
42368
42342
  };
42369
42343
  }
42370
- const pkgJsonPath = join7(cwd2, "package.json");
42371
- if (existsSync12(pkgJsonPath)) {
42344
+ const pkgJsonPath = join6(cwd2, "package.json");
42345
+ if (existsSync11(pkgJsonPath)) {
42372
42346
  const headPkgJson = readFileSafe(pkgJsonPath);
42373
42347
  const basePkgJson = getGitBaseFile(cwd2, "package.json");
42374
42348
  if (basePkgJson !== null) {
@@ -42418,8 +42392,8 @@ function findLockfile(cwd2) {
42418
42392
  ["pnpm-lock.yaml", "pnpm"]
42419
42393
  ];
42420
42394
  for (const [name, type] of candidates) {
42421
- const p = join7(cwd2, name);
42422
- if (existsSync12(p)) return { path: p, type };
42395
+ const p = join6(cwd2, name);
42396
+ if (existsSync11(p)) return { path: p, type };
42423
42397
  }
42424
42398
  return null;
42425
42399
  }
@@ -42435,7 +42409,7 @@ function parseLockfileByType(content, type) {
42435
42409
  }
42436
42410
  function getDirectDeps(cwd2) {
42437
42411
  try {
42438
- const content = readFileSafe(join7(cwd2, "package.json"));
42412
+ const content = readFileSafe(join6(cwd2, "package.json"));
42439
42413
  const pkg = JSON.parse(content);
42440
42414
  return /* @__PURE__ */ new Set([
42441
42415
  ...Object.keys(pkg.dependencies ?? {}),
@@ -42496,7 +42470,7 @@ function toPackageInput(change) {
42496
42470
  };
42497
42471
  }
42498
42472
  function parsePythonDepFile(projectDir, depFile) {
42499
- const content = readFileSafe(join7(projectDir, depFile));
42473
+ const content = readFileSafe(join6(projectDir, depFile));
42500
42474
  if (depFile === "Pipfile.lock") {
42501
42475
  try {
42502
42476
  const parsed = JSON.parse(content);
@@ -42634,8 +42608,8 @@ var init_wrapper_shared = __esm({
42634
42608
 
42635
42609
  // src/commands/npm-wrapper.ts
42636
42610
  import { spawn as spawn2 } from "node:child_process";
42637
- import { readFileSync as readFileSync10, existsSync as existsSync13, mkdtempSync, writeFileSync as writeFileSync9, rmSync as rmSync2 } from "node:fs";
42638
- import { join as join8 } from "node:path";
42611
+ import { readFileSync as readFileSync9, existsSync as existsSync12, mkdtempSync, writeFileSync as writeFileSync8, rmSync } from "node:fs";
42612
+ import { join as join7 } from "node:path";
42639
42613
  import { tmpdir } from "node:os";
42640
42614
  function realNpmBinary() {
42641
42615
  const real = resolveRealBinary("npm");
@@ -42821,9 +42795,9 @@ async function resolveTreeNpm(specs) {
42821
42795
  if (safe.length === 0) {
42822
42796
  return { packages: [], ok: false, errorMessage: "all specs were flag-shaped (refused)" };
42823
42797
  }
42824
- const dir = mkdtempSync(join8(tmpdir(), "dg-resolve-"));
42798
+ const dir = mkdtempSync(join7(tmpdir(), "dg-resolve-"));
42825
42799
  try {
42826
- writeFileSync9(join8(dir, "package.json"), '{"name":"_dg_resolve","version":"1.0.0","private":true}');
42800
+ writeFileSync8(join7(dir, "package.json"), '{"name":"_dg_resolve","version":"1.0.0","private":true}');
42827
42801
  const stdout = await new Promise((resolve3) => {
42828
42802
  const child = spawn2(
42829
42803
  realNpmBinary(),
@@ -42882,7 +42856,7 @@ async function resolveTreeNpm(specs) {
42882
42856
  return { packages: [], ok: false, errorMessage: e.message };
42883
42857
  } finally {
42884
42858
  try {
42885
- rmSync2(dir, { recursive: true, force: true });
42859
+ rmSync(dir, { recursive: true, force: true });
42886
42860
  } catch {
42887
42861
  }
42888
42862
  }
@@ -42903,10 +42877,10 @@ function pinTopLevelArgs(rawArgs, userSpecs, tree) {
42903
42877
  });
42904
42878
  }
42905
42879
  function readLockfilePins(cwd2) {
42906
- const lockPath = join8(cwd2, "package-lock.json");
42907
- if (!existsSync13(lockPath)) return null;
42880
+ const lockPath = join7(cwd2, "package-lock.json");
42881
+ if (!existsSync12(lockPath)) return null;
42908
42882
  try {
42909
- const lock = JSON.parse(readFileSync10(lockPath, "utf-8"));
42883
+ const lock = JSON.parse(readFileSync9(lockPath, "utf-8"));
42910
42884
  const pins = /* @__PURE__ */ new Map();
42911
42885
  const root = lock.packages?.[""] ?? {};
42912
42886
  const directDeps = /* @__PURE__ */ new Set([
@@ -42933,10 +42907,10 @@ function readBareInstallPackages(cwd2) {
42933
42907
  return readBareInstallPackagesTyped(cwd2).map((s) => s.spec);
42934
42908
  }
42935
42909
  function readBareInstallPackagesTyped(cwd2) {
42936
- const pkgPath = join8(cwd2, "package.json");
42937
- if (!existsSync13(pkgPath)) return [];
42910
+ const pkgPath = join7(cwd2, "package.json");
42911
+ if (!existsSync12(pkgPath)) return [];
42938
42912
  try {
42939
- const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
42913
+ const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
42940
42914
  const lockPins = readLockfilePins(cwd2) ?? /* @__PURE__ */ new Map();
42941
42915
  const out = [];
42942
42916
  const addOne = (name, range) => {
@@ -42986,7 +42960,7 @@ var init_npm_wrapper = __esm({
42986
42960
 
42987
42961
  // src/commands/pip-wrapper.ts
42988
42962
  import { spawn as spawn3 } from "node:child_process";
42989
- import { existsSync as existsSync14 } from "node:fs";
42963
+ import { existsSync as existsSync13 } from "node:fs";
42990
42964
  function parsePipArgs(args) {
42991
42965
  const { filtered, dgForce, dgForceReason, dgNoScripts } = stripDgFlags(args);
42992
42966
  const command = filtered[0] ?? "";
@@ -43046,7 +43020,7 @@ function parseRequirementsFile(filePath) {
43046
43020
  return parseRequirementsFileInternal(filePath, /* @__PURE__ */ new Set());
43047
43021
  }
43048
43022
  function parseRequirementsFileInternal(filePath, visited) {
43049
- if (!existsSync14(filePath)) return [];
43023
+ if (!existsSync13(filePath)) return [];
43050
43024
  let absPath;
43051
43025
  try {
43052
43026
  absPath = __require("node:path").resolve(filePath);
@@ -43550,8 +43524,8 @@ var FileSavePrompt_exports = {};
43550
43524
  __export(FileSavePrompt_exports, {
43551
43525
  FileSavePrompt: () => FileSavePrompt
43552
43526
  });
43553
- import { existsSync as existsSync15, readdirSync as readdirSync2, writeFileSync as writeFileSync10 } from "node:fs";
43554
- import { dirname as dirname9, join as join9 } from "node:path";
43527
+ import { existsSync as existsSync14, readdirSync as readdirSync2, writeFileSync as writeFileSync9 } from "node:fs";
43528
+ import { dirname as dirname8, join as join8 } from "node:path";
43555
43529
  function listDirectory(dir) {
43556
43530
  try {
43557
43531
  const raw = readdirSync2(dir, { withFileTypes: true });
@@ -43559,7 +43533,7 @@ function listDirectory(dir) {
43559
43533
  if (a.isDirectory !== b.isDirectory) return a.isDirectory ? -1 : 1;
43560
43534
  return a.name.localeCompare(b.name);
43561
43535
  });
43562
- if (dirname9(dir) !== dir) {
43536
+ if (dirname8(dir) !== dir) {
43563
43537
  entries.unshift({ name: "..", isDirectory: true });
43564
43538
  }
43565
43539
  return entries;
@@ -43654,13 +43628,13 @@ var init_FileSavePrompt = __esm({
43654
43628
  if (state.focus === "filename") {
43655
43629
  if (key.return) {
43656
43630
  const fullName = ensureJsonExtension(state.filename);
43657
- const fullPath = join9(state.directory, fullName);
43658
- if (!state.confirmOverwrite && existsSync15(fullPath)) {
43631
+ const fullPath = join8(state.directory, fullName);
43632
+ if (!state.confirmOverwrite && existsSync14(fullPath)) {
43659
43633
  dispatch({ type: "CONFIRM_OVERWRITE" });
43660
43634
  return;
43661
43635
  }
43662
43636
  try {
43663
- writeFileSync10(fullPath, json + "\n");
43637
+ writeFileSync9(fullPath, json + "\n");
43664
43638
  } catch (err) {
43665
43639
  const msg = err instanceof Error ? err.message : String(err);
43666
43640
  dispatch({ type: "SET_ERROR", error: `Write failed: ${msg}` });
@@ -43914,7 +43888,7 @@ __export(walker_exports, {
43914
43888
  discoverProjectsAsync: () => discoverProjectsAsync
43915
43889
  });
43916
43890
  import { readdir, lstat } from "node:fs/promises";
43917
- import { join as join10, relative } from "node:path";
43891
+ import { join as join9, relative } from "node:path";
43918
43892
  async function discoverProjectsAsync(root, opts = {}) {
43919
43893
  const queue = [{ dir: root, depth: 0 }];
43920
43894
  const projects = [];
@@ -43967,7 +43941,7 @@ async function scanDir(dir, depth, _root) {
43967
43941
  for (const lockfile of NPM_LOCKFILES) {
43968
43942
  const e = byName.get(lockfile);
43969
43943
  if (e && e.isFile() && !e.isSymbolicLink()) {
43970
- const lockPath = join10(dir, lockfile);
43944
+ const lockPath = join9(dir, lockfile);
43971
43945
  if (await isSafeRegularFile(lockPath)) {
43972
43946
  lockfileHits.push({ dir, lockPath, depFile: lockfile, isNpm: true });
43973
43947
  }
@@ -43977,7 +43951,7 @@ async function scanDir(dir, depth, _root) {
43977
43951
  for (const depFile of PYTHON_DEPFILES) {
43978
43952
  const e = byName.get(depFile);
43979
43953
  if (e && e.isFile() && !e.isSymbolicLink()) {
43980
- const lockPath = join10(dir, depFile);
43954
+ const lockPath = join9(dir, depFile);
43981
43955
  if (await isSafeRegularFile(lockPath)) {
43982
43956
  lockfileHits.push({ dir, lockPath, depFile, isNpm: false });
43983
43957
  }
@@ -43988,7 +43962,7 @@ async function scanDir(dir, depth, _root) {
43988
43962
  for (const e of entries) {
43989
43963
  if (!e.isDirectory() || e.isSymbolicLink()) continue;
43990
43964
  if (SKIP_DIRS.has(e.name) || e.name.startsWith(".")) continue;
43991
- subdirs.push({ dir: join10(dir, e.name), depth: depth + 1 });
43965
+ subdirs.push({ dir: join9(dir, e.name), depth: depth + 1 });
43992
43966
  }
43993
43967
  }
43994
43968
  return { subdirs, lockfileHits };
@@ -44080,8 +44054,10 @@ async function scanProjectAtPath(cwd2, config, onProgress) {
44080
44054
  };
44081
44055
  }
44082
44056
  const maxScore = allPackages.length > 0 ? Math.max(0, ...allPackages.map((p) => p.score)) : 0;
44057
+ const anyBlock = responses.some((r) => r.action === "block") || allPackages.some((p) => p.action === "block");
44058
+ const anyWarn = responses.some((r) => r.action === "warn") || allPackages.some((p) => p.action === "warn");
44083
44059
  const anyIncomplete = responses.some((r) => r.action === "analysis_incomplete") || allPackages.some((p) => Array.isArray(p.findings) && p.findings.some((f) => f?.id === "analysis_incomplete"));
44084
- const action = maxScore >= 70 ? "block" : maxScore >= 60 ? "warn" : anyIncomplete ? "analysis_incomplete" : "pass";
44060
+ const action = anyBlock ? "block" : anyWarn ? "warn" : anyIncomplete ? "analysis_incomplete" : "pass";
44085
44061
  const safeVersions = {};
44086
44062
  for (const r of responses) Object.assign(safeVersions, r.safeVersions);
44087
44063
  const totalDuration = elapsedMs();
@@ -44207,8 +44183,10 @@ async function scanConsolidated(projectPaths, config, onProgress) {
44207
44183
  };
44208
44184
  }
44209
44185
  const maxScore = allPackages.length > 0 ? Math.max(0, ...allPackages.map((p) => p.score)) : 0;
44186
+ const anyBlock = responses.some((r) => r.action === "block") || allPackages.some((p) => p.action === "block");
44187
+ const anyWarn = responses.some((r) => r.action === "warn") || allPackages.some((p) => p.action === "warn");
44210
44188
  const anyIncomplete = responses.some((r) => r.action === "analysis_incomplete") || allPackages.some((p) => Array.isArray(p.findings) && p.findings.some((f) => f?.id === "analysis_incomplete"));
44211
- const action = maxScore >= 70 ? "block" : maxScore >= 60 ? "warn" : anyIncomplete ? "analysis_incomplete" : "pass";
44189
+ const action = anyBlock ? "block" : anyWarn ? "warn" : anyIncomplete ? "analysis_incomplete" : "pass";
44212
44190
  const safeVersions = {};
44213
44191
  for (const r of responses) Object.assign(safeVersions, r.safeVersions);
44214
44192
  const totalDuration = elapsedMs();
@@ -44275,8 +44253,8 @@ __export(allowlist_exports, {
44275
44253
  loadAllowlist: () => loadAllowlist,
44276
44254
  validateAllowlist: () => validateAllowlist
44277
44255
  });
44278
- import { existsSync as existsSync16, readFileSync as readFileSync11 } from "node:fs";
44279
- import { join as join11, dirname as dirname10 } from "node:path";
44256
+ import { existsSync as existsSync15, readFileSync as readFileSync10 } from "node:fs";
44257
+ import { join as join10, dirname as dirname9 } from "node:path";
44280
44258
  function isExpired(expires) {
44281
44259
  if (!expires) return false;
44282
44260
  const date = new Date(expires);
@@ -44286,9 +44264,9 @@ function isExpired(expires) {
44286
44264
  function findAllowlistFile(startDir) {
44287
44265
  let dir = startDir;
44288
44266
  for (let i = 0; i < 32; i++) {
44289
- const candidate = join11(dir, ALLOWLIST_FILENAME);
44290
- if (existsSync16(candidate)) return candidate;
44291
- const parent = dirname10(dir);
44267
+ const candidate = join10(dir, ALLOWLIST_FILENAME);
44268
+ if (existsSync15(candidate)) return candidate;
44269
+ const parent = dirname9(dir);
44292
44270
  if (parent === dir) return null;
44293
44271
  dir = parent;
44294
44272
  }
@@ -44397,7 +44375,7 @@ function loadAllowlist(cwd2) {
44397
44375
  if (!path2) return null;
44398
44376
  let raw;
44399
44377
  try {
44400
- raw = JSON.parse(readFileSync11(path2, "utf-8"));
44378
+ raw = JSON.parse(readFileSync10(path2, "utf-8"));
44401
44379
  } catch (e) {
44402
44380
  process.stderr.write(
44403
44381
  `dg: .dg-allowlist.json at ${path2} is not valid JSON (${e.message}). Ignoring.
@@ -44428,18 +44406,8 @@ function packageMatches(entry, pkg, apiKind) {
44428
44406
  if (entry.version && entry.version !== pkg.version) return false;
44429
44407
  return true;
44430
44408
  }
44431
- function derivePackageActionFromFindings(pkg) {
44432
- const findings = pkg.findings ?? [];
44433
- if (findings.length === 0) return "pass";
44434
- const maxSev = findings.reduce((m, f) => Math.max(m, f.severity ?? 0), 0);
44435
- if (maxSev >= 4) return "block";
44436
- if (maxSev >= 2) return "warn";
44437
- return "pass";
44438
- }
44439
44409
  function derivePackageAction(pkg) {
44440
- if (pkg.action === "block" || pkg.action === "warn" || pkg.action === "pass") return pkg.action;
44441
- if (pkg.score >= 70) return "block";
44442
- if (pkg.score >= 60) return "warn";
44410
+ if (pkg.action === "block" || pkg.action === "warn") return pkg.action;
44443
44411
  return "pass";
44444
44412
  }
44445
44413
  function overallAction(packages) {
@@ -44501,7 +44469,8 @@ function applyAllowlist(allowlist, result, apiKind) {
44501
44469
  const globallySupressed = findings.filter((f) => activeGlobalRules[findingRuleId(f)] !== void 0);
44502
44470
  suppressedCount += globallySupressed.length;
44503
44471
  findings = findings.filter((f) => activeGlobalRules[findingRuleId(f)] === void 0);
44504
- const action = findings.length !== originalCount ? derivePackageActionFromFindings({ ...pkg, findings }) : pkg.action ?? derivePackageAction(pkg);
44472
+ const fullyAllowlisted = originalCount > 0 && findings.length === 0;
44473
+ const action = fullyAllowlisted ? "pass" : pkg.action ?? "pass";
44505
44474
  return { ...pkg, findings, action };
44506
44475
  });
44507
44476
  const newAction = overallAction(filteredPackages);
@@ -44686,8 +44655,8 @@ __export(audit_dispatcher_exports, {
44686
44655
  recordBypassLocally: () => recordBypassLocally,
44687
44656
  shouldFireAudit: () => shouldFireAudit
44688
44657
  });
44689
- import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync7, existsSync as existsSync17 } from "node:fs";
44690
- import { dirname as dirname11 } from "node:path";
44658
+ import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync6, existsSync as existsSync16 } from "node:fs";
44659
+ import { dirname as dirname10 } from "node:path";
44691
44660
  function _setPolicyFetcherForTests(fn) {
44692
44661
  _policyOverride = fn;
44693
44662
  }
@@ -44736,8 +44705,8 @@ function bypassLogPath2() {
44736
44705
  function recordBypassLocally(record) {
44737
44706
  try {
44738
44707
  const path2 = bypassLogPath2();
44739
- const dir = dirname11(path2);
44740
- if (!existsSync17(dir)) mkdirSync7(dir, { recursive: true, mode: 448 });
44708
+ const dir = dirname10(path2);
44709
+ if (!existsSync16(dir)) mkdirSync6(dir, { recursive: true, mode: 448 });
44741
44710
  const full = {
44742
44711
  ts: (/* @__PURE__ */ new Date()).toISOString(),
44743
44712
  cwd: record.cwd ?? process.cwd(),
@@ -44800,8 +44769,8 @@ __export(static_output_exports, {
44800
44769
  runStaticPip: () => runStaticPip,
44801
44770
  scanExitCode: () => scanExitCode
44802
44771
  });
44803
- import { writeFileSync as writeFileSync11, readFileSync as readFileSync12, existsSync as existsSync18, mkdirSync as mkdirSync8, lstatSync as lstatSync5 } from "node:fs";
44804
- import { resolve as resolvePath, dirname as dirname12 } from "node:path";
44772
+ import { writeFileSync as writeFileSync10, readFileSync as readFileSync11, existsSync as existsSync17, mkdirSync as mkdirSync7, lstatSync as lstatSync5 } from "node:fs";
44773
+ import { resolve as resolvePath, dirname as dirname11 } from "node:path";
44805
44774
  function note(config, text) {
44806
44775
  if (config.quiet) return;
44807
44776
  process.stderr.write(text);
@@ -44821,12 +44790,12 @@ function wrapperPackagesFromResult(result, topLevelNames) {
44821
44790
  }
44822
44791
  function loadPackageLockJson(cwd2 = process.cwd()) {
44823
44792
  const path2 = resolvePath(cwd2, "package-lock.json");
44824
- if (!existsSync18(path2)) return null;
44793
+ if (!existsSync17(path2)) return null;
44825
44794
  try {
44826
44795
  const st = lstatSync5(path2);
44827
44796
  if (!st.isFile()) return null;
44828
44797
  if (st.size > MAX_PACKAGE_LOCK_BYTES) return null;
44829
- return JSON.parse(readFileSync12(path2, "utf8"));
44798
+ return JSON.parse(readFileSync11(path2, "utf8"));
44830
44799
  } catch {
44831
44800
  return null;
44832
44801
  }
@@ -44834,7 +44803,7 @@ function loadPackageLockJson(cwd2 = process.cwd()) {
44834
44803
  function writeJsonFile(filepath, json) {
44835
44804
  const resolved = resolvePath(filepath);
44836
44805
  try {
44837
- writeFileSync11(resolved, json + "\n");
44806
+ writeFileSync10(resolved, json + "\n");
44838
44807
  process.stderr.write(import_chalk5.default.green(` \u2713 Saved to ${resolved}
44839
44808
 
44840
44809
  `));
@@ -44919,11 +44888,11 @@ function printTrialBanner(result, config) {
44919
44888
  if (process.env.CI === "1" || process.env.CI === "true") return;
44920
44889
  try {
44921
44890
  const stampPath = dgStatePath("trial-banner");
44922
- const lastMs = existsSync18(stampPath) ? Number(readFileSync12(stampPath, "utf-8").trim()) || 0 : 0;
44891
+ const lastMs = existsSync17(stampPath) ? Number(readFileSync11(stampPath, "utf-8").trim()) || 0 : 0;
44923
44892
  const now = Date.now();
44924
44893
  if (now - lastMs < NUDGE_INTERVAL_MS) return;
44925
- mkdirSync8(dirname12(stampPath), { recursive: true, mode: 448 });
44926
- writeFileSync11(stampPath, String(now) + "\n", { mode: 384 });
44894
+ mkdirSync7(dirname11(stampPath), { recursive: true, mode: 448 });
44895
+ writeFileSync10(stampPath, String(now) + "\n", { mode: 384 });
44927
44896
  } catch {
44928
44897
  return;
44929
44898
  }
@@ -44980,15 +44949,13 @@ function actionBadge(pkg) {
44980
44949
  if (a === "warn") return { label: "Warn", color: import_chalk5.default.yellow };
44981
44950
  if (a === "pass") return { label: "Pass", color: import_chalk5.default.green };
44982
44951
  if (a === "analysis_incomplete") return { label: "Unknown", color: import_chalk5.default.cyan };
44983
- if (pkg.score >= 70) return { label: "Block", color: import_chalk5.default.red };
44984
- if (pkg.score >= 60) return { label: "Warn", color: import_chalk5.default.yellow };
44985
44952
  return { label: "Pass", color: import_chalk5.default.green };
44986
44953
  }
44987
44954
  function isBlocked(p) {
44988
- return p.action === "block" || p.action === void 0 && p.score >= 70;
44955
+ return p.action === "block";
44989
44956
  }
44990
44957
  function isWarned(p) {
44991
- return p.action === "warn" || p.action === void 0 && p.score >= 60 && p.score < 70;
44958
+ return p.action === "warn";
44992
44959
  }
44993
44960
  function renderResultClean(result, _config) {
44994
44961
  const lines = [];
@@ -45254,8 +45221,8 @@ async function runStatic(config) {
45254
45221
  const sarif = emitSarif2(result, {});
45255
45222
  const outputPath = config.outputFile;
45256
45223
  if (outputPath) {
45257
- const { writeFileSync: writeFileSync16 } = await import("node:fs");
45258
- writeFileSync16(outputPath, sarif);
45224
+ const { writeFileSync: writeFileSync15 } = await import("node:fs");
45225
+ writeFileSync15(outputPath, sarif);
45259
45226
  process.stderr.write(import_chalk5.default.green(` \u2713 Wrote SARIF to ${outputPath}
45260
45227
  `));
45261
45228
  } else {
@@ -46016,13 +45983,13 @@ __export(status_exports, {
46016
45983
  collectStatusSnapshot: () => collectStatusSnapshot,
46017
45984
  handleStatusCommand: () => handleStatusCommand
46018
45985
  });
46019
- import { existsSync as existsSync19, readFileSync as readFileSync13 } from "node:fs";
46020
- import { join as join12 } from "node:path";
45986
+ import { existsSync as existsSync18, readFileSync as readFileSync12 } from "node:fs";
45987
+ import { join as join11 } from "node:path";
46021
45988
  import { homedir as homedir6 } from "node:os";
46022
45989
  function readPythonReceipt() {
46023
45990
  try {
46024
- const { readFileSync: readFileSync18 } = __require("node:fs");
46025
- const receipt = JSON.parse(readFileSync18(dgStatePath("python-hook-receipt.json"), "utf-8"));
45991
+ const { readFileSync: readFileSync17 } = __require("node:fs");
45992
+ const receipt = JSON.parse(readFileSync17(dgStatePath("python-hook-receipt.json"), "utf-8"));
46026
45993
  const rows = receipt?.results ?? [];
46027
45994
  return rows.map((r) => ({ pythonVersion: r.pythonVersion, status: r.status, reason: r.reason }));
46028
45995
  } catch {
@@ -46065,12 +46032,12 @@ async function collectStatusSnapshot(cliVersion2) {
46065
46032
  authPart.reachable = false;
46066
46033
  }
46067
46034
  }
46068
- const shimDir2 = join12(homedir6(), ".dg", "shims");
46035
+ const shimDir2 = join11(homedir6(), ".dg", "shims");
46069
46036
  const shimRows = ECOSYSTEMS.map((eco) => {
46070
46037
  const filename = process.platform === "win32" ? `${eco}.cmd` : eco;
46071
46038
  return {
46072
46039
  ecosystem: eco,
46073
- shimPresent: existsSync19(join12(shimDir2, filename))
46040
+ shimPresent: existsSync18(join11(shimDir2, filename))
46074
46041
  };
46075
46042
  });
46076
46043
  const engineResolvable = isEngineResolvable();
@@ -46078,11 +46045,11 @@ async function collectStatusSnapshot(cliVersion2) {
46078
46045
  const cwd2 = process.cwd();
46079
46046
  const hookPart = { installed: false };
46080
46047
  try {
46081
- const { existsSync: ex, readFileSync: readFileSync18 } = await import("node:fs");
46082
- const candidates = [join12(cwd2, ".husky", "pre-commit"), join12(cwd2, ".git", "hooks", "pre-commit")];
46048
+ const { existsSync: ex, readFileSync: readFileSync17 } = await import("node:fs");
46049
+ const candidates = [join11(cwd2, ".husky", "pre-commit"), join11(cwd2, ".git", "hooks", "pre-commit")];
46083
46050
  for (const p of candidates) {
46084
46051
  if (ex(p)) {
46085
- const content = readFileSync18(p, "utf-8");
46052
+ const content = readFileSync17(p, "utf-8");
46086
46053
  if (content.includes("dependency-guardian")) {
46087
46054
  hookPart.installed = true;
46088
46055
  break;
@@ -46113,8 +46080,8 @@ async function collectStatusSnapshot(cliVersion2) {
46113
46080
  }
46114
46081
  function isEngineResolvable() {
46115
46082
  try {
46116
- const recorded = readFileSync13(join12(homedir6(), ".dg", "state", "dg-entry"), "utf-8").trim();
46117
- if (recorded && existsSync19(recorded)) return true;
46083
+ const recorded = readFileSync12(join11(homedir6(), ".dg", "state", "dg-entry"), "utf-8").trim();
46084
+ if (recorded && existsSync18(recorded)) return true;
46118
46085
  } catch {
46119
46086
  }
46120
46087
  try {
@@ -46591,16 +46558,15 @@ var InteractiveResultsView_exports = {};
46591
46558
  __export(InteractiveResultsView_exports, {
46592
46559
  InteractiveResultsView: () => InteractiveResultsView
46593
46560
  });
46594
- import { writeFileSync as writeFileSync12 } from "node:fs";
46561
+ import { writeFileSync as writeFileSync11 } from "node:fs";
46595
46562
  import { resolve as resolvePath2 } from "node:path";
46596
46563
  function groupPackages2(packages) {
46597
46564
  return groupPackages(packages, "fingerprint");
46598
46565
  }
46599
- function actionBadge2(score) {
46600
- if (score >= 70)
46601
- return { label: "Block", color: import_chalk9.default.red };
46602
- if (score >= 60)
46603
- return { label: "Warn", color: import_chalk9.default.yellow };
46566
+ function actionBadge2(action) {
46567
+ if (action === "block") return { label: "Block", color: import_chalk9.default.red };
46568
+ if (action === "warn") return { label: "Warn", color: import_chalk9.default.yellow };
46569
+ if (action === "analysis_incomplete") return { label: "Unknown", color: import_chalk9.default.cyan };
46604
46570
  return { label: "Pass", color: import_chalk9.default.green };
46605
46571
  }
46606
46572
  function findingsSummaryHeight(group) {
@@ -46859,8 +46825,8 @@ var init_InteractiveResultsView = __esm({
46859
46825
  setExportMenu({ scope: defaultScope, format: "json", activeRow: "scope" });
46860
46826
  };
46861
46827
  const buildExportPayload = (scope, currentLicenseIdx) => {
46862
- const blocked = result.packages.filter((p) => p.score >= 70);
46863
- const warned = result.packages.filter((p) => p.score >= 60 && p.score < 70);
46828
+ const blocked = result.packages.filter((p) => p.action === "block");
46829
+ const warned = result.packages.filter((p) => p.action === "warn");
46864
46830
  const cleanPkgs = result.packages.filter((p) => p.score === 0);
46865
46831
  const passWithScore = result.packages.filter((p) => p.score > 0 && p.score < 60);
46866
46832
  const summary = {
@@ -46907,7 +46873,7 @@ var init_InteractiveResultsView = __esm({
46907
46873
  name: p.name,
46908
46874
  version: p.version,
46909
46875
  score: p.score,
46910
- action: p.score >= 70 ? "block" : "warn",
46876
+ action: p.action,
46911
46877
  findings: p.findings.map((f) => ({
46912
46878
  severity: f.severity,
46913
46879
  category: f.category ?? null,
@@ -47098,7 +47064,7 @@ var init_InteractiveResultsView = __esm({
47098
47064
  const scopeTag = scope === "current-license" && currentLicenseIdx !== null ? `${(licenseGroups[currentLicenseIdx]?.spdx ?? "license").replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 32)}` : scope;
47099
47065
  const filename = `dg-scan-${ts}-${scopeTag}.${ext}`;
47100
47066
  const path2 = resolvePath2(process.cwd(), filename);
47101
- writeFileSync12(path2, body, "utf-8");
47067
+ writeFileSync11(path2, body, "utf-8");
47102
47068
  showExportMsg(`\u2713 Exported to ${filename}`);
47103
47069
  } catch (e) {
47104
47070
  showExportMsg(`Export failed: ${e.message}`);
@@ -47883,7 +47849,7 @@ var init_InteractiveResultsView = __esm({
47883
47849
  setDetailPane(null);
47884
47850
  } else {
47885
47851
  const dpRep = dpGroup.packages[0];
47886
- const { color: dpColor } = actionBadge2(dpRep.score);
47852
+ const { color: dpColor } = actionBadge2(dpRep.action);
47887
47853
  const dpScroll = detailPane.scroll;
47888
47854
  const dpAbove = dpScroll;
47889
47855
  const dpBelow = Math.max(0, detailLines.length - dpScroll - detailContentRows);
@@ -48016,7 +47982,7 @@ var init_InteractiveResultsView = __esm({
48016
47982
  const isCursor = globalIdx === clampedCursor;
48017
47983
  const level = getLevel(globalIdx);
48018
47984
  const rep = group.packages[0];
48019
- const { label, color } = actionBadge2(rep.score);
47985
+ const { label, color } = actionBadge2(rep.action);
48020
47986
  const names = groupNames(group);
48021
47987
  const scoreStr = String(rep.score);
48022
47988
  const lcInfo = rep.license;
@@ -48502,8 +48468,8 @@ __export(publish_check_exports, {
48502
48468
  summarize: () => summarize
48503
48469
  });
48504
48470
  import { spawn as spawn4 } from "node:child_process";
48505
- import { readFileSync as readFileSync14, existsSync as existsSync20, readdirSync as readdirSync3 } from "node:fs";
48506
- import { join as join13, basename as basename2 } from "node:path";
48471
+ import { readFileSync as readFileSync13, existsSync as existsSync19, readdirSync as readdirSync3 } from "node:fs";
48472
+ import { join as join12, basename as basename2 } from "node:path";
48507
48473
  import { createGunzip } from "node:zlib";
48508
48474
  import { createReadStream } from "node:fs";
48509
48475
  function sanitizeSnippet(s, max = 40) {
@@ -48550,7 +48516,7 @@ async function npmPackDryRun(cwd2 = process.cwd()) {
48550
48516
  }));
48551
48517
  let packageJson;
48552
48518
  try {
48553
- const raw = readFileSync14(join13(cwd2, "package.json"), "utf-8");
48519
+ const raw = readFileSync13(join12(cwd2, "package.json"), "utf-8");
48554
48520
  packageJson = JSON.parse(raw);
48555
48521
  } catch {
48556
48522
  }
@@ -48562,9 +48528,9 @@ async function npmPackDryRun(cwd2 = process.cwd()) {
48562
48528
  });
48563
48529
  }
48564
48530
  function findPypiArtifacts(cwd2 = process.cwd()) {
48565
- const dist = join13(cwd2, "dist");
48566
- if (!existsSync20(dist)) return [];
48567
- return readdirSync3(dist).filter((f) => f.endsWith(".tar.gz") || f.endsWith(".whl")).map((f) => join13(dist, f));
48531
+ const dist = join12(cwd2, "dist");
48532
+ if (!existsSync19(dist)) return [];
48533
+ return readdirSync3(dist).filter((f) => f.endsWith(".tar.gz") || f.endsWith(".whl")).map((f) => join12(dist, f));
48568
48534
  }
48569
48535
  function scanPayload(files) {
48570
48536
  const findings = [];
@@ -48638,7 +48604,7 @@ async function runNpmPublishCheck(cwd2 = process.cwd()) {
48638
48604
  const payload = pack.files.map((f) => ({
48639
48605
  path: f.path,
48640
48606
  size: f.size,
48641
- read: () => readFileSync14(join13(cwd2, f.path))
48607
+ read: () => readFileSync13(join12(cwd2, f.path))
48642
48608
  }));
48643
48609
  const findings = scanPayload(payload);
48644
48610
  const scripts = pack.packageJson?.scripts ?? {};
@@ -48886,8 +48852,8 @@ var init_publish_check = __esm({
48886
48852
  });
48887
48853
 
48888
48854
  // src/state/hooks_registry.ts
48889
- import { existsSync as existsSync21, mkdirSync as mkdirSync9, readFileSync as readFileSync15, writeFileSync as writeFileSync13, chmodSync as chmodSync5 } from "node:fs";
48890
- import { dirname as dirname13, isAbsolute as isAbsolute2, normalize as normalize2 } from "node:path";
48855
+ import { existsSync as existsSync20, mkdirSync as mkdirSync8, readFileSync as readFileSync14, writeFileSync as writeFileSync12, chmodSync as chmodSync4 } from "node:fs";
48856
+ import { dirname as dirname12, isAbsolute as isAbsolute2, normalize as normalize2 } from "node:path";
48891
48857
  import { homedir as homedir7 } from "node:os";
48892
48858
  function registryPath() {
48893
48859
  return dgStatePath("hooks-installed.json");
@@ -48929,10 +48895,10 @@ function validateEntry(raw) {
48929
48895
  }
48930
48896
  function readRegistry() {
48931
48897
  const path2 = registryPath();
48932
- if (!existsSync21(path2)) return [];
48898
+ if (!existsSync20(path2)) return [];
48933
48899
  let raw;
48934
48900
  try {
48935
- raw = readFileSync15(path2, "utf-8");
48901
+ raw = readFileSync14(path2, "utf-8");
48936
48902
  } catch {
48937
48903
  return [];
48938
48904
  }
@@ -48954,12 +48920,12 @@ function readRegistry() {
48954
48920
  }
48955
48921
  function writeRegistry(entries) {
48956
48922
  const path2 = registryPath();
48957
- const parent = dirname13(path2);
48958
- if (!existsSync21(parent)) mkdirSync9(parent, { recursive: true, mode: 448 });
48923
+ const parent = dirname12(path2);
48924
+ if (!existsSync20(parent)) mkdirSync8(parent, { recursive: true, mode: 448 });
48959
48925
  const payload = { version: 1, entries };
48960
- writeFileSync13(path2, JSON.stringify(payload, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
48926
+ writeFileSync12(path2, JSON.stringify(payload, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
48961
48927
  try {
48962
- chmodSync5(path2, 384);
48928
+ chmodSync4(path2, 384);
48963
48929
  } catch {
48964
48930
  }
48965
48931
  }
@@ -49005,20 +48971,20 @@ __export(hook_exports, {
49005
48971
  });
49006
48972
  import { createHash } from "node:crypto";
49007
48973
  import {
49008
- existsSync as existsSync22,
48974
+ existsSync as existsSync21,
49009
48975
  lstatSync as lstatSync6,
49010
- readFileSync as readFileSync16,
49011
- writeFileSync as writeFileSync14,
49012
- mkdirSync as mkdirSync10,
49013
- chmodSync as chmodSync6,
49014
- unlinkSync as unlinkSync5
48976
+ readFileSync as readFileSync15,
48977
+ writeFileSync as writeFileSync13,
48978
+ mkdirSync as mkdirSync9,
48979
+ chmodSync as chmodSync5,
48980
+ unlinkSync as unlinkSync4
49015
48981
  } from "node:fs";
49016
- import { join as join14, dirname as dirname14, resolve as resolvePath3, isAbsolute as isAbsolute3 } from "node:path";
48982
+ import { join as join13, dirname as dirname13, resolve as resolvePath3, isAbsolute as isAbsolute3 } from "node:path";
49017
48983
  function hashRepoPath(repoPath) {
49018
48984
  return createHash("sha256").update(repoPath).digest("hex");
49019
48985
  }
49020
48986
  function assertSafeWriteTarget(target) {
49021
- const parent = dirname14(target);
48987
+ const parent = dirname13(target);
49022
48988
  try {
49023
48989
  const parentStat = lstatSync6(parent);
49024
48990
  if (parentStat.isSymbolicLink()) {
@@ -49046,7 +49012,7 @@ function assertSafeWriteTarget(target) {
49046
49012
  }
49047
49013
  function safeWriteFileSync(target, content) {
49048
49014
  assertSafeWriteTarget(target);
49049
- writeFileSync14(target, content);
49015
+ writeFileSync13(target, content);
49050
49016
  }
49051
49017
  function findHooksDir() {
49052
49018
  try {
@@ -49064,13 +49030,13 @@ function findRepoRoot() {
49064
49030
  }
49065
49031
  function detectHookFramework(repoRoot) {
49066
49032
  const root = repoRoot ?? findRepoRoot();
49067
- const huskyHook = join14(root, ".husky", "pre-commit");
49068
- const lefthookConfig = join14(root, "lefthook.yml");
49069
- const lefthookConfigYaml = join14(root, "lefthook.yaml");
49033
+ const huskyHook = join13(root, ".husky", "pre-commit");
49034
+ const lefthookConfig = join13(root, "lefthook.yml");
49035
+ const lefthookConfigYaml = join13(root, "lefthook.yaml");
49070
49036
  const hooksDir = findHooksDir();
49071
- const bareHook = join14(hooksDir, "pre-commit");
49072
- if (existsSync22(huskyHook)) {
49073
- const content = readFileSync16(huskyHook, "utf-8");
49037
+ const bareHook = join13(hooksDir, "pre-commit");
49038
+ if (existsSync21(huskyHook)) {
49039
+ const content = readFileSync15(huskyHook, "utf-8");
49074
49040
  return {
49075
49041
  framework: "husky",
49076
49042
  targetFile: huskyHook,
@@ -49078,8 +49044,8 @@ function detectHookFramework(repoRoot) {
49078
49044
  };
49079
49045
  }
49080
49046
  for (const cfg of [lefthookConfig, lefthookConfigYaml]) {
49081
- if (existsSync22(cfg)) {
49082
- const content = readFileSync16(cfg, "utf-8");
49047
+ if (existsSync21(cfg)) {
49048
+ const content = readFileSync15(cfg, "utf-8");
49083
49049
  const installed2 = /^\s+dependency-guardian\s*:/m.test(content);
49084
49050
  return {
49085
49051
  framework: "lefthook",
@@ -49089,8 +49055,8 @@ function detectHookFramework(repoRoot) {
49089
49055
  }
49090
49056
  }
49091
49057
  let installed = false;
49092
- if (existsSync22(bareHook)) {
49093
- installed = readFileSync16(bareHook, "utf-8").includes(HOOK_MARKER);
49058
+ if (existsSync21(bareHook)) {
49059
+ installed = readFileSync15(bareHook, "utf-8").includes(HOOK_MARKER);
49094
49060
  }
49095
49061
  return {
49096
49062
  framework: "bare",
@@ -49099,12 +49065,12 @@ function detectHookFramework(repoRoot) {
49099
49065
  };
49100
49066
  }
49101
49067
  function verifyHookInstalled(info) {
49102
- if (!existsSync22(info.targetFile)) {
49068
+ if (!existsSync21(info.targetFile)) {
49103
49069
  return { ok: false, reason: `hook file missing: ${info.targetFile}` };
49104
49070
  }
49105
49071
  let content;
49106
49072
  try {
49107
- content = readFileSync16(info.targetFile, "utf-8");
49073
+ content = readFileSync15(info.targetFile, "utf-8");
49108
49074
  } catch (e) {
49109
49075
  return { ok: false, reason: `cannot read ${info.targetFile}: ${e.message}` };
49110
49076
  }
@@ -49142,7 +49108,7 @@ ${HUSKY_SNIPPET}`;
49142
49108
 
49143
49109
  ${LEFTHOOK_ENTRY}`;
49144
49110
  case "bare":
49145
- if (existsSync22(info.targetFile)) {
49111
+ if (existsSync21(info.targetFile)) {
49146
49112
  return `Will append to existing hook at ${info.targetFile}:
49147
49113
  ${HOOK_SECTION}`;
49148
49114
  }
@@ -49151,21 +49117,21 @@ ${HOOK_SCRIPT}`;
49151
49117
  }
49152
49118
  }
49153
49119
  function installHuskyHook(targetFile) {
49154
- const existing = readFileSync16(targetFile, "utf-8");
49120
+ const existing = readFileSync15(targetFile, "utf-8");
49155
49121
  if (existing.includes(HOOK_MARKER)) {
49156
49122
  process.stderr.write(" Hook already installed in Husky.\n");
49157
49123
  return;
49158
49124
  }
49159
49125
  safeWriteFileSync(targetFile, existing.trimEnd() + "\n" + HUSKY_SNIPPET);
49160
49126
  try {
49161
- chmodSync6(targetFile, 493);
49127
+ chmodSync5(targetFile, 493);
49162
49128
  } catch {
49163
49129
  }
49164
49130
  process.stderr.write(` Appended Dependency Guardian to ${targetFile}
49165
49131
  `);
49166
49132
  }
49167
49133
  function installLefthookHook(targetFile) {
49168
- const existing = readFileSync16(targetFile, "utf-8");
49134
+ const existing = readFileSync15(targetFile, "utf-8");
49169
49135
  if (/^\s+dependency-guardian\s*:/m.test(existing)) {
49170
49136
  process.stderr.write(" Hook already installed in lefthook.\n");
49171
49137
  return;
@@ -49197,16 +49163,16 @@ function installLefthookHook(targetFile) {
49197
49163
  `);
49198
49164
  }
49199
49165
  function installBareHook(targetFile) {
49200
- const hooksDir = dirname14(targetFile);
49201
- mkdirSync10(hooksDir, { recursive: true });
49202
- if (existsSync22(targetFile)) {
49203
- const existing = readFileSync16(targetFile, "utf-8");
49166
+ const hooksDir = dirname13(targetFile);
49167
+ mkdirSync9(hooksDir, { recursive: true });
49168
+ if (existsSync21(targetFile)) {
49169
+ const existing = readFileSync15(targetFile, "utf-8");
49204
49170
  if (existing.includes(HOOK_MARKER)) {
49205
49171
  process.stderr.write(" Hook already installed.\n");
49206
49172
  return;
49207
49173
  }
49208
49174
  safeWriteFileSync(targetFile, existing.trimEnd() + "\n" + HOOK_SECTION);
49209
- chmodSync6(targetFile, 493);
49175
+ chmodSync5(targetFile, 493);
49210
49176
  process.stderr.write(
49211
49177
  ` Appended Dependency Guardian hook to existing ${targetFile}
49212
49178
  `
@@ -49214,7 +49180,7 @@ function installBareHook(targetFile) {
49214
49180
  return;
49215
49181
  }
49216
49182
  safeWriteFileSync(targetFile, HOOK_SCRIPT);
49217
- chmodSync6(targetFile, 493);
49183
+ chmodSync5(targetFile, 493);
49218
49184
  process.stderr.write(` Installed git pre-commit hook at ${targetFile}
49219
49185
  `);
49220
49186
  }
@@ -49257,10 +49223,10 @@ async function installHook() {
49257
49223
  }
49258
49224
  }
49259
49225
  function stripDgFromHookFile(hookPath, framework, repoPath) {
49260
- if (!existsSync22(hookPath)) {
49226
+ if (!existsSync21(hookPath)) {
49261
49227
  return { status: "not-found", hookPath, repoPath };
49262
49228
  }
49263
- const content = readFileSync16(hookPath, "utf-8");
49229
+ const content = readFileSync15(hookPath, "utf-8");
49264
49230
  if (framework === "lefthook") {
49265
49231
  if (!/^\s+dependency-guardian\s*:/m.test(content)) {
49266
49232
  return { status: "not-found", hookPath, repoPath };
@@ -49277,7 +49243,7 @@ function stripDgFromHookFile(hookPath, framework, repoPath) {
49277
49243
  return { status: "not-found", hookPath, repoPath };
49278
49244
  }
49279
49245
  if (framework === "bare" && content.trimStart().startsWith("#!/bin/sh\n" + HOOK_MARKER)) {
49280
- unlinkSync5(hookPath);
49246
+ unlinkSync4(hookPath);
49281
49247
  removeEntry(repoPath, hookPath);
49282
49248
  return { status: "removed", hookPath, repoPath };
49283
49249
  }
@@ -49290,7 +49256,7 @@ function stripDgFromHookFile(hookPath, framework, repoPath) {
49290
49256
  const after = content.slice(endIdx + MARKER_END.length).trimStart();
49291
49257
  const remaining = (before + (after ? "\n" + after : "")).trimEnd() + "\n";
49292
49258
  if (remaining.trim() === "" || remaining.trim() === "#!/bin/sh") {
49293
- unlinkSync5(hookPath);
49259
+ unlinkSync4(hookPath);
49294
49260
  } else {
49295
49261
  safeWriteFileSync(hookPath, remaining);
49296
49262
  }
@@ -49300,10 +49266,10 @@ function stripDgFromHookFile(hookPath, framework, repoPath) {
49300
49266
  function uninstallHookFromRepo(repoRootOverride) {
49301
49267
  const root = repoRootOverride ?? findRepoRoot();
49302
49268
  const hooksDir = findHooksDir();
49303
- const hookPath = join14(hooksDir, "pre-commit");
49304
- const huskyPath = join14(root, ".husky", "pre-commit");
49305
- if (existsSync22(huskyPath)) {
49306
- const content2 = readFileSync16(huskyPath, "utf-8");
49269
+ const hookPath = join13(hooksDir, "pre-commit");
49270
+ const huskyPath = join13(root, ".husky", "pre-commit");
49271
+ if (existsSync21(huskyPath)) {
49272
+ const content2 = readFileSync15(huskyPath, "utf-8");
49307
49273
  if (content2.includes(HOOK_MARKER)) {
49308
49274
  const startIdx2 = content2.indexOf(MARKER_START);
49309
49275
  const endIdx2 = content2.indexOf(MARKER_END);
@@ -49317,9 +49283,9 @@ function uninstallHookFromRepo(repoRootOverride) {
49317
49283
  }
49318
49284
  }
49319
49285
  }
49320
- for (const cfg of [join14(root, "lefthook.yml"), join14(root, "lefthook.yaml")]) {
49321
- if (!existsSync22(cfg)) continue;
49322
- const content2 = readFileSync16(cfg, "utf-8");
49286
+ for (const cfg of [join13(root, "lefthook.yml"), join13(root, "lefthook.yaml")]) {
49287
+ if (!existsSync21(cfg)) continue;
49288
+ const content2 = readFileSync15(cfg, "utf-8");
49323
49289
  if (/^\s+dependency-guardian\s*:/m.test(content2)) {
49324
49290
  const stripped = content2.replace(
49325
49291
  /^\s+dependency-guardian\s*:\s*\n(?:\s{6,}.*\n)+/gm,
@@ -49330,15 +49296,15 @@ function uninstallHookFromRepo(repoRootOverride) {
49330
49296
  return { status: "removed", hookPath: cfg, repoPath: root };
49331
49297
  }
49332
49298
  }
49333
- if (!existsSync22(hookPath)) {
49299
+ if (!existsSync21(hookPath)) {
49334
49300
  return { status: "not-found", hookPath, repoPath: root };
49335
49301
  }
49336
- const content = readFileSync16(hookPath, "utf-8");
49302
+ const content = readFileSync15(hookPath, "utf-8");
49337
49303
  if (!content.includes(HOOK_MARKER)) {
49338
49304
  return { status: "not-found", hookPath, repoPath: root };
49339
49305
  }
49340
49306
  if (content.trimStart().startsWith("#!/bin/sh\n" + HOOK_MARKER)) {
49341
- unlinkSync5(hookPath);
49307
+ unlinkSync4(hookPath);
49342
49308
  removeEntry(root, hookPath);
49343
49309
  return { status: "removed", hookPath, repoPath: root };
49344
49310
  }
@@ -49352,7 +49318,7 @@ function uninstallHookFromRepo(repoRootOverride) {
49352
49318
  removeEntry(root, hookPath);
49353
49319
  return { status: "removed", hookPath, repoPath: root };
49354
49320
  }
49355
- unlinkSync5(hookPath);
49321
+ unlinkSync4(hookPath);
49356
49322
  removeEntry(root, hookPath);
49357
49323
  return { status: "removed", hookPath, repoPath: root };
49358
49324
  }
@@ -49506,7 +49472,7 @@ __export(update_exports, {
49506
49472
  runUpdate: () => runUpdate
49507
49473
  });
49508
49474
  import { spawnSync as spawnSync2 } from "node:child_process";
49509
- import { accessSync, constants as constants2, realpathSync, unlinkSync as unlinkSync6 } from "node:fs";
49475
+ import { accessSync, constants as constants2, realpathSync, unlinkSync as unlinkSync5 } from "node:fs";
49510
49476
  import { sep as sep3 } from "node:path";
49511
49477
  function parseUpdateArgs(args) {
49512
49478
  return {
@@ -49617,7 +49583,7 @@ function printUpgradeCommand(latest, kind) {
49617
49583
  }
49618
49584
  function invalidateUpdateCache() {
49619
49585
  try {
49620
- unlinkSync6(dgCachePath("update-check.json"));
49586
+ unlinkSync5(dgCachePath("update-check.json"));
49621
49587
  } catch {
49622
49588
  }
49623
49589
  }
@@ -49767,8 +49733,8 @@ var init_update = __esm({
49767
49733
  });
49768
49734
 
49769
49735
  // src/python-hook/install.ts
49770
- import { existsSync as existsSync23, readFileSync as readFileSync17, unlinkSync as unlinkSync7, readdirSync as readdirSync4, statSync as statSync5 } from "node:fs";
49771
- import { dirname as dirname15, join as join15, resolve } from "node:path";
49736
+ import { existsSync as existsSync22, readFileSync as readFileSync16, unlinkSync as unlinkSync6, readdirSync as readdirSync4, statSync as statSync4 } from "node:fs";
49737
+ import { dirname as dirname14, join as join14, resolve } from "node:path";
49772
49738
  import { spawnSync as spawnSync3 } from "node:child_process";
49773
49739
  import { homedir as homedir8 } from "node:os";
49774
49740
  function probeUserSite(pythonName) {
@@ -49792,8 +49758,8 @@ function uninstallPythonHooks(_opts = {}) {
49792
49758
  const removed = [];
49793
49759
  let receipt = null;
49794
49760
  try {
49795
- if (existsSync23(receiptPath)) {
49796
- receipt = JSON.parse(readFileSync17(receiptPath, "utf-8"));
49761
+ if (existsSync22(receiptPath)) {
49762
+ receipt = JSON.parse(readFileSync16(receiptPath, "utf-8"));
49797
49763
  }
49798
49764
  } catch {
49799
49765
  receipt = null;
@@ -49811,9 +49777,9 @@ function uninstallPythonHooks(_opts = {}) {
49811
49777
  }
49812
49778
  for (const site of sites) {
49813
49779
  for (const filename of ["dg_pip_hook.py", "dg_pip_hook.pth"]) {
49814
- const full = join15(site, filename);
49780
+ const full = join14(site, filename);
49815
49781
  try {
49816
- if (existsSync23(full)) {
49782
+ if (existsSync22(full)) {
49817
49783
  safeUnlink(full);
49818
49784
  removed.push(full);
49819
49785
  }
@@ -49821,13 +49787,13 @@ function uninstallPythonHooks(_opts = {}) {
49821
49787
  }
49822
49788
  }
49823
49789
  try {
49824
- const pyCache = join15(site, "__pycache__");
49825
- if (existsSync23(pyCache) && statSync5(pyCache).isDirectory()) {
49790
+ const pyCache = join14(site, "__pycache__");
49791
+ if (existsSync22(pyCache) && statSync4(pyCache).isDirectory()) {
49826
49792
  for (const f of readdirSync4(pyCache)) {
49827
49793
  if (f.startsWith("dg_pip_hook.")) {
49828
49794
  try {
49829
- safeUnlink(join15(pyCache, f));
49830
- removed.push(join15(pyCache, f));
49795
+ safeUnlink(join14(pyCache, f));
49796
+ removed.push(join14(pyCache, f));
49831
49797
  } catch {
49832
49798
  }
49833
49799
  }
@@ -49837,8 +49803,8 @@ function uninstallPythonHooks(_opts = {}) {
49837
49803
  }
49838
49804
  }
49839
49805
  try {
49840
- if (existsSync23(receiptPath)) {
49841
- unlinkSync7(receiptPath);
49806
+ if (existsSync22(receiptPath)) {
49807
+ unlinkSync6(receiptPath);
49842
49808
  }
49843
49809
  } catch {
49844
49810
  }
@@ -49869,7 +49835,7 @@ __export(uninstall_exports, {
49869
49835
  parseUninstallArgs: () => parseUninstallArgs,
49870
49836
  runUninstall: () => runUninstall
49871
49837
  });
49872
- import { existsSync as existsSync24, rmSync as rmSync3, unlinkSync as unlinkSync8, statSync as statSync6 } from "node:fs";
49838
+ import { existsSync as existsSync23, rmSync as rmSync2, unlinkSync as unlinkSync7 } from "node:fs";
49873
49839
  function parseUninstallArgs(args) {
49874
49840
  return {
49875
49841
  assumeYes: args.includes("--yes") || args.includes("-y"),
@@ -49880,21 +49846,18 @@ function parseUninstallArgs(args) {
49880
49846
  }
49881
49847
  function safeExists(p) {
49882
49848
  try {
49883
- return existsSync24(p);
49849
+ return existsSync23(p);
49884
49850
  } catch {
49885
49851
  return false;
49886
49852
  }
49887
49853
  }
49888
49854
  function buildPlan(opts) {
49889
49855
  const p = dgPaths();
49890
- const legacy = legacyPaths();
49891
49856
  const plan = {
49892
49857
  configFiles: [],
49893
49858
  cacheDir: null,
49894
49859
  stateDir: null,
49895
49860
  rootDir: null,
49896
- legacyFiles: [],
49897
- legacyDirs: [],
49898
49861
  hooks: [],
49899
49862
  rcCleanup: false
49900
49863
  };
@@ -49903,10 +49866,6 @@ function buildPlan(opts) {
49903
49866
  if (safeExists(p.cacheDir)) plan.cacheDir = p.cacheDir;
49904
49867
  if (safeExists(p.stateDir)) plan.stateDir = p.stateDir;
49905
49868
  if (safeExists(p.root)) plan.rootDir = p.root;
49906
- for (const f of [legacy.dgrc, legacy.updateCheck]) {
49907
- if (safeExists(f)) plan.legacyFiles.push(f);
49908
- }
49909
- if (safeExists(legacy.cacheDir)) plan.legacyDirs.push(legacy.cacheDir);
49910
49869
  if (!opts.keepHooks) {
49911
49870
  plan.hooks = listEntries();
49912
49871
  }
@@ -49930,10 +49889,6 @@ function printPlan(plan, opts) {
49930
49889
  process.stderr.write(` ${plan.rootDir}/ (entire tree)
49931
49890
  `);
49932
49891
  }
49933
- for (const f of plan.legacyFiles) process.stderr.write(` ${f} (legacy)
49934
- `);
49935
- for (const d of plan.legacyDirs) process.stderr.write(` ${d}/ (legacy)
49936
- `);
49937
49892
  if (plan.hooks.length > 0) {
49938
49893
  process.stderr.write(` pre-commit hooks in ${plan.hooks.length} repo(s):
49939
49894
  `);
@@ -49996,7 +49951,7 @@ async function revokeApiKey(apiKey) {
49996
49951
  }
49997
49952
  function rmFile(path2) {
49998
49953
  try {
49999
- unlinkSync8(path2);
49954
+ unlinkSync7(path2);
50000
49955
  return { ok: true };
50001
49956
  } catch (e) {
50002
49957
  const code = e.code;
@@ -50006,20 +49961,12 @@ function rmFile(path2) {
50006
49961
  }
50007
49962
  function rmTree(path2) {
50008
49963
  try {
50009
- rmSync3(path2, { recursive: true, force: true });
49964
+ rmSync2(path2, { recursive: true, force: true });
50010
49965
  return { ok: true };
50011
49966
  } catch (e) {
50012
49967
  return { ok: false, reason: e.message };
50013
49968
  }
50014
49969
  }
50015
- function isWritableTarget(path2) {
50016
- try {
50017
- const st = statSync6(path2);
50018
- return st.isDirectory() || st.isFile();
50019
- } catch {
50020
- return false;
50021
- }
50022
- }
50023
49970
  async function runUninstall(args) {
50024
49971
  if (args.includes("--help") || args.includes("-h")) {
50025
49972
  process.stdout.write(USAGE5);
@@ -50065,7 +50012,7 @@ async function runUninstall(args) {
50065
50012
  }
50066
50013
  if (!opts.keepHooks && !opts.soft) {
50067
50014
  for (const h of plan.hooks) {
50068
- if (!existsSync24(h.repoPath)) {
50015
+ if (!existsSync23(h.repoPath)) {
50069
50016
  process.stderr.write(import_chalk11.default.dim(` \xB7 ${h.repoPath} no longer exists \u2014 skipping registered hook
50070
50017
  `));
50071
50018
  continue;
@@ -50131,22 +50078,6 @@ async function runUninstall(args) {
50131
50078
  `);
50132
50079
  }
50133
50080
  } else {
50134
- for (const f of plan.legacyFiles) {
50135
- if (!isWritableTarget(f)) continue;
50136
- const r = rmFile(f);
50137
- if (r.ok) process.stderr.write(import_chalk11.default.green(" \u2713 ") + `Removed ${f}
50138
- `);
50139
- else process.stderr.write(import_chalk11.default.red(" \u2718 ") + `${f}: ${r.reason}
50140
- `);
50141
- }
50142
- for (const d of plan.legacyDirs) {
50143
- if (!isWritableTarget(d)) continue;
50144
- const r = rmTree(d);
50145
- if (r.ok) process.stderr.write(import_chalk11.default.green(" \u2713 ") + `Removed ${d}
50146
- `);
50147
- else process.stderr.write(import_chalk11.default.red(" \u2718 ") + `${d}: ${r.reason}
50148
- `);
50149
- }
50150
50081
  if (plan.rootDir) {
50151
50082
  const r = rmTree(plan.rootDir);
50152
50083
  if (r.ok) process.stderr.write(import_chalk11.default.green(" \u2713 ") + `Removed ${plan.rootDir}
@@ -50196,9 +50127,6 @@ var init_uninstall = __esm({
50196
50127
 
50197
50128
  Removes:
50198
50129
  ~/.dg/ (config + cache + state + hooks registry)
50199
- ~/.dgrc.json (legacy, if still present)
50200
- ~/.dg/ (legacy, if still present)
50201
- ~/.dg-update-check.json (legacy, if still present)
50202
50130
  every per-repo pre-commit hook installed via 'dg hook install'
50203
50131
  the dg sentinel block in your shell rc files
50204
50132
 
@@ -50215,7 +50143,7 @@ var verify_exports = {};
50215
50143
  __export(verify_exports, {
50216
50144
  handleVerifyCommand: () => handleVerifyCommand
50217
50145
  });
50218
- import { writeFileSync as writeFileSync15 } from "node:fs";
50146
+ import { writeFileSync as writeFileSync14 } from "node:fs";
50219
50147
  function detectEcosystem(spec) {
50220
50148
  if (/[<>=!~]=?|~=/.test(spec)) return "pypi";
50221
50149
  if (spec.startsWith("@")) return "npm";
@@ -50330,7 +50258,7 @@ async function callApi(packages, ecosystem, config) {
50330
50258
  }
50331
50259
  function writeOutput(content, outputPath) {
50332
50260
  if (outputPath) {
50333
- writeFileSync15(outputPath, content);
50261
+ writeFileSync14(outputPath, content);
50334
50262
  process.stderr.write(import_chalk12.default.green(` \u2713 Wrote ${content.length} bytes to ${outputPath}
50335
50263
  `));
50336
50264
  } else {
@@ -50749,7 +50677,6 @@ async function scanProjects(projects, config, dispatch) {
50749
50677
  dispatch({ type: "DISCOVERY_EMPTY", message: "No packages to scan." });
50750
50678
  return;
50751
50679
  }
50752
- const startMs = Date.now();
50753
50680
  const results = [];
50754
50681
  let completed = 0;
50755
50682
  if (npmPackages.length > 0) {
@@ -50776,18 +50703,7 @@ async function scanProjects(projects, config, dispatch) {
50776
50703
  });
50777
50704
  results.push(pypiResult);
50778
50705
  }
50779
- const allPackages = results.flatMap((r) => r.packages);
50780
- const maxScore = Math.max(0, ...allPackages.map((p) => p.score));
50781
- const action = maxScore >= 70 ? "block" : maxScore >= 60 ? "warn" : "pass";
50782
- const safeVersions = {};
50783
- for (const r of results) Object.assign(safeVersions, r.safeVersions);
50784
- const merged = {
50785
- score: maxScore,
50786
- action,
50787
- packages: allPackages,
50788
- safeVersions,
50789
- durationMs: Date.now() - startMs
50790
- };
50706
+ const merged = mergeResponses(results);
50791
50707
  dispatch({ type: "SCAN_COMPLETE", result: merged, durationMs: merged.durationMs, skippedCount: 0, discoveredTotal });
50792
50708
  } catch (error) {
50793
50709
  if (error instanceof FreeCapReachedError) {
@@ -51333,8 +51249,8 @@ __export(ink_controls_exports, {
51333
51249
  setInkClear: () => setInkClear,
51334
51250
  setInkInstance: () => setInkInstance
51335
51251
  });
51336
- import { resolve as resolve2, dirname as dirname16 } from "node:path";
51337
- import { existsSync as existsSync25 } from "node:fs";
51252
+ import { resolve as resolve2, dirname as dirname15 } from "node:path";
51253
+ import { existsSync as existsSync24 } from "node:fs";
51338
51254
  function locateInkInstancesPath() {
51339
51255
  let cur;
51340
51256
  try {
@@ -51344,13 +51260,13 @@ function locateInkInstancesPath() {
51344
51260
  }
51345
51261
  while (cur && cur !== "/" && cur !== ".") {
51346
51262
  const candidate = resolve2(cur, "node_modules", "ink", "build", "instances.js");
51347
- if (existsSync25(candidate)) return candidate;
51348
- const parent = dirname16(cur);
51263
+ if (existsSync24(candidate)) return candidate;
51264
+ const parent = dirname15(cur);
51349
51265
  if (parent === cur) break;
51350
51266
  cur = parent;
51351
51267
  }
51352
51268
  const cwdCandidate = resolve2(process.cwd(), "node_modules", "ink", "build", "instances.js");
51353
- if (existsSync25(cwdCandidate)) return cwdCandidate;
51269
+ if (existsSync24(cwdCandidate)) return cwdCandidate;
51354
51270
  return null;
51355
51271
  }
51356
51272
  async function initInkInstances() {
@@ -51842,9 +51758,10 @@ function severityColor(sev) {
51842
51758
  if (sev >= 2) return import_chalk16.default.dim;
51843
51759
  return import_chalk16.default.dim;
51844
51760
  }
51845
- function actionBadge3(score) {
51846
- if (score >= 70) return { label: "BLOCK", color: import_chalk16.default.red };
51847
- if (score >= 60) return { label: "WARN", color: import_chalk16.default.yellow };
51761
+ function actionBadge3(action) {
51762
+ if (action === "block") return { label: "BLOCK", color: import_chalk16.default.red };
51763
+ if (action === "warn") return { label: "WARN", color: import_chalk16.default.yellow };
51764
+ if (action === "analysis_incomplete") return { label: "UNKNOWN", color: import_chalk16.default.cyan };
51848
51765
  return { label: "PASS", color: import_chalk16.default.green };
51849
51766
  }
51850
51767
  var import_chalk16, import_jsx_runtime15, SEVERITY_LABELS2, EVIDENCE_LIMIT2, ResultsView;
@@ -51896,7 +51813,7 @@ var init_ResultsView = __esm({
51896
51813
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { dimColor: true, children: "\u2500".repeat(60) }),
51897
51814
  groups.map((group) => {
51898
51815
  const rep = group.packages[0];
51899
- const { label, color } = actionBadge3(rep.score);
51816
+ const { label, color } = actionBadge3(rep.action);
51900
51817
  const names = group.packages.length === 1 ? rep.name : group.packages.length <= 3 ? group.packages.map((p) => p.name).join(", ") : `${group.packages[0].name} + ${group.packages.length - 1} similar`;
51901
51818
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Text, { children: [
51902
51819
  " ",
@@ -52028,8 +51945,8 @@ function countSummary(result) {
52028
51945
  let warn = 0;
52029
51946
  let clean = 0;
52030
51947
  for (const p of result.packages) {
52031
- if (p.score >= 70) block++;
52032
- else if (p.score >= 60) warn++;
51948
+ if (p.action === "block") block++;
51949
+ else if (p.action === "warn") warn++;
52033
51950
  else clean++;
52034
51951
  }
52035
51952
  return { block, warn, clean };
@@ -53158,253 +53075,10 @@ function closestCommand(input, commands) {
53158
53075
  return bestDist <= 3 ? best : null;
53159
53076
  }
53160
53077
 
53161
- // src/migrate.ts
53162
- init_paths();
53163
- import {
53164
- existsSync as existsSync4,
53165
- mkdirSync as mkdirSync3,
53166
- readFileSync as readFileSync4,
53167
- writeFileSync as writeFileSync3,
53168
- copyFileSync,
53169
- unlinkSync as unlinkSync3,
53170
- rmSync,
53171
- chmodSync as chmodSync3,
53172
- statSync,
53173
- openSync as openSync2,
53174
- closeSync as closeSync2,
53175
- constants as fsConstants2
53176
- } from "node:fs";
53177
- import { dirname as dirname4 } from "node:path";
53178
- var README = `dependency-guardian \u2014 local state for the dg CLI.
53179
-
53180
- config.json your account + preferences (mode 0600)
53181
- cache/update-check.json latest-version probe (24h TTL)
53182
- state/aliases.sh optional shell aliases (npm/pip wrappers)
53183
- state/auth-status.json 60s cache of /v1/auth/status
53184
- state/trial-banner throttle stamp for the trial nudge
53185
- state/bypass-log.jsonl append-only log of install-wrapper bypasses
53186
- state/hooks-installed.json registry of git hooks dg installed
53187
-
53188
- To remove everything dg has written to your machine, run:
53189
- dg uninstall
53190
-
53191
- This directory is created and managed by the dg CLI. Safe to delete.
53192
- `;
53193
- function ensureDir(path2, mode) {
53194
- if (!existsSync4(path2)) {
53195
- mkdirSync3(path2, { recursive: true, mode });
53196
- }
53197
- try {
53198
- chmodSync3(path2, mode);
53199
- } catch {
53200
- }
53201
- }
53202
- function moveFile(from, to, mode) {
53203
- const parent = dirname4(to);
53204
- ensureDir(parent, 448);
53205
- copyFileSync(from, to);
53206
- try {
53207
- chmodSync3(to, mode);
53208
- } catch {
53209
- }
53210
- if (statSync(to).size !== statSync(from).size) {
53211
- throw new Error(`size mismatch after copy: ${from} -> ${to}`);
53212
- }
53213
- unlinkSync3(from);
53214
- }
53215
- function isPidAlive(pid) {
53216
- if (!Number.isInteger(pid) || pid <= 0) return false;
53217
- try {
53218
- process.kill(pid, 0);
53219
- return true;
53220
- } catch (e) {
53221
- const code = e.code;
53222
- return code === "EPERM";
53223
- }
53224
- }
53225
- var LOCK_STALE_MS = 6e4;
53226
- function acquireLock(lockPath) {
53227
- ensureDir(dirname4(lockPath), 448);
53228
- if (existsSync4(lockPath)) {
53229
- let stale = false;
53230
- try {
53231
- const raw = readFileSync4(lockPath, "utf-8").trim();
53232
- const data = JSON.parse(raw);
53233
- const age = Date.now() - (data.at ?? 0);
53234
- const dead = !isPidAlive(data.pid ?? 0);
53235
- stale = dead || age > LOCK_STALE_MS;
53236
- } catch {
53237
- stale = true;
53238
- }
53239
- if (!stale) return "held";
53240
- try {
53241
- unlinkSync3(lockPath);
53242
- } catch {
53243
- }
53244
- }
53245
- let fd;
53246
- try {
53247
- fd = openSync2(lockPath, fsConstants2.O_CREAT | fsConstants2.O_EXCL | fsConstants2.O_WRONLY, 384);
53248
- } catch {
53249
- return "stale-held";
53250
- }
53251
- try {
53252
- writeFileSync3(lockPath, JSON.stringify({ pid: process.pid, at: Date.now() }) + "\n");
53253
- } catch {
53254
- }
53255
- return { fd, lockPath };
53256
- }
53257
- function releaseLock(state) {
53258
- if (state.fd !== null) {
53259
- try {
53260
- closeSync2(state.fd);
53261
- } catch {
53262
- }
53263
- }
53264
- try {
53265
- unlinkSync3(state.lockPath);
53266
- } catch {
53267
- }
53268
- }
53269
- function rollback(moves) {
53270
- for (const m of moves) {
53271
- try {
53272
- if (existsSync4(m.to) && !existsSync4(m.from)) {
53273
- copyFileSync(m.to, m.from);
53274
- unlinkSync3(m.to);
53275
- }
53276
- } catch {
53277
- }
53278
- }
53279
- }
53280
- function detectLegacy() {
53281
- const legacy = legacyPaths();
53282
- return existsSync4(legacy.dgrc) || existsSync4(legacy.updateCheck) || existsSync4(legacy.aliasesShOld) || existsSync4(legacy.depGuardianDir);
53283
- }
53284
- function validateLegacyConfig(path2) {
53285
- let raw;
53286
- try {
53287
- const st = statSync(path2);
53288
- if (!st.isFile()) return { ok: false, reason: "not a regular file" };
53289
- if (st.size > 1e6) return { ok: false, reason: `file too large (${st.size} bytes)` };
53290
- raw = readFileSync4(path2, "utf-8");
53291
- } catch (e) {
53292
- return { ok: false, reason: e.message };
53293
- }
53294
- let parsed;
53295
- try {
53296
- const stripped = raw.charCodeAt(0) === 65279 ? raw.slice(1) : raw;
53297
- parsed = JSON.parse(stripped);
53298
- } catch (e) {
53299
- return { ok: false, reason: `invalid JSON: ${e.message}` };
53300
- }
53301
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
53302
- return { ok: false, reason: "config root is not an object" };
53303
- }
53304
- return { ok: true, data: parsed };
53305
- }
53306
- function runMigrationIfNeeded() {
53307
- const p = dgPaths();
53308
- if (existsSync4(p.migrationBreadcrumb)) {
53309
- return { status: "no-op" };
53310
- }
53311
- if (!detectLegacy()) {
53312
- return { status: "no-op" };
53313
- }
53314
- ensureDir(p.root, 448);
53315
- const lock = acquireLock(p.migrationLock);
53316
- if (lock === "held" || lock === "stale-held") {
53317
- return { status: "skipped", reason: "another dg process is migrating" };
53318
- }
53319
- const legacy = legacyPaths();
53320
- const moves = [];
53321
- let movedCount = 0;
53322
- try {
53323
- if (existsSync4(legacy.dgrc)) {
53324
- const validation = validateLegacyConfig(legacy.dgrc);
53325
- if (!validation.ok) {
53326
- releaseLock(lock);
53327
- return {
53328
- status: "failed",
53329
- reason: `~/.dgrc.json could not be read (${validation.reason}). Fix or remove the file and re-run dg.`
53330
- };
53331
- }
53332
- ensureDir(p.configDir, 448);
53333
- writeFileSync3(p.config, JSON.stringify(validation.data, null, 2) + "\n", { mode: 384 });
53334
- try {
53335
- chmodSync3(p.config, 384);
53336
- } catch {
53337
- }
53338
- try {
53339
- unlinkSync3(legacy.dgrc);
53340
- } catch {
53341
- }
53342
- moves.push({ from: legacy.dgrc, to: p.config });
53343
- movedCount++;
53344
- }
53345
- ensureDir(p.cacheDir, 448);
53346
- if (existsSync4(legacy.updateCheck)) {
53347
- moveFile(legacy.updateCheck, p.updateCheck, 384);
53348
- moves.push({ from: legacy.updateCheck, to: p.updateCheck });
53349
- movedCount++;
53350
- }
53351
- ensureDir(p.stateDir, 448);
53352
- if (existsSync4(legacy.aliasesShOld)) {
53353
- moveFile(legacy.aliasesShOld, p.aliasesSh, 420);
53354
- moves.push({ from: legacy.aliasesShOld, to: p.aliasesSh });
53355
- movedCount++;
53356
- }
53357
- if (existsSync4(legacy.depGuardianDir) && legacy.depGuardianDir !== p.root) {
53358
- const candidates = [
53359
- { from: join(legacy.depGuardianDir, "config.json"), to: p.config, mode: 384 },
53360
- { from: join(legacy.depGuardianDir, "cache", "update-check.json"), to: p.updateCheck, mode: 384 },
53361
- { from: join(legacy.depGuardianDir, "state", "aliases.sh"), to: p.aliasesSh, mode: 420 },
53362
- { from: join(legacy.depGuardianDir, "state", "hooks-installed.json"), to: p.hooksRegistry, mode: 384 },
53363
- { from: join(legacy.depGuardianDir, "aliases.sh"), to: p.aliasesSh, mode: 420 }
53364
- ];
53365
- for (const c of candidates) {
53366
- if (existsSync4(c.from) && !existsSync4(c.to)) {
53367
- moveFile(c.from, c.to, c.mode);
53368
- moves.push({ from: c.from, to: c.to });
53369
- movedCount++;
53370
- }
53371
- }
53372
- try {
53373
- rmSync(legacy.depGuardianDir, { recursive: true, force: true });
53374
- } catch {
53375
- }
53376
- }
53377
- try {
53378
- if (existsSync4(legacy.cacheDir) && legacy.cacheDir !== p.root) {
53379
- rmSync(legacy.cacheDir, { recursive: true, force: true });
53380
- }
53381
- } catch {
53382
- }
53383
- try {
53384
- writeFileSync3(p.readme, README, { mode: 420 });
53385
- } catch {
53386
- }
53387
- writeFileSync3(p.migrationBreadcrumb, (/* @__PURE__ */ new Date()).toISOString() + "\n", { mode: 384 });
53388
- releaseLock(lock);
53389
- if (process.stderr.isTTY) {
53390
- process.stderr.write(
53391
- `dg: reorganized local state into ${p.root} (one-time, ${movedCount} file${movedCount === 1 ? "" : "s"}; see README inside).
53392
- `
53393
- );
53394
- }
53395
- return { status: "migrated", movedCount };
53396
- } catch (e) {
53397
- rollback(moves);
53398
- releaseLock(lock);
53399
- return { status: "failed", reason: e.message };
53400
- }
53401
- }
53402
-
53403
53078
  // src/bin.ts
53404
53079
  init_terminal_state();
53405
53080
  var CLI_VERSION = getVersion();
53406
53081
  initTelemetry(CLI_VERSION);
53407
- runMigrationIfNeeded();
53408
53082
  function setProcessTitle(title) {
53409
53083
  try {
53410
53084
  process.title = title;
@@ -53436,15 +53110,15 @@ async function maybeShowWiringHint(rawCommand) {
53436
53110
  const SKIP = /* @__PURE__ */ new Set(["uninstall", "__wrap", "version", "--version", "-v", "help", "--help", "-h"]);
53437
53111
  if (SKIP.has(rawCommand)) return;
53438
53112
  try {
53439
- const { existsSync: existsSync26 } = await import("node:fs");
53440
- const { join: join16 } = await import("node:path");
53113
+ const { existsSync: existsSync25 } = await import("node:fs");
53114
+ const { join: join15 } = await import("node:path");
53441
53115
  const { homedir: homedir9 } = await import("node:os");
53442
53116
  const { dgStatePath: dgStatePath2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
53443
- const receiptPath = join16(homedir9(), ".dg", "state", "install-receipt.json");
53444
- const shimPath = join16(homedir9(), ".dg", "shims", "npm");
53117
+ const receiptPath = join15(homedir9(), ".dg", "state", "install-receipt.json");
53118
+ const shimPath = join15(homedir9(), ".dg", "shims", "npm");
53445
53119
  const hintMarker = dgStatePath2("wiring-hint-shown");
53446
- if (existsSync26(receiptPath) || existsSync26(shimPath)) return;
53447
- if (existsSync26(hintMarker)) return;
53120
+ if (existsSync25(receiptPath) || existsSync25(shimPath)) return;
53121
+ if (existsSync25(hintMarker)) return;
53448
53122
  const chalk18 = (await Promise.resolve().then(() => __toESM(require_source(), 1))).default;
53449
53123
  process.stderr.write(
53450
53124
  `
@@ -53454,10 +53128,10 @@ async function maybeShowWiringHint(rawCommand) {
53454
53128
  `
53455
53129
  );
53456
53130
  try {
53457
- const { writeFileSync: writeFileSync16, mkdirSync: mkdirSync11 } = await import("node:fs");
53458
- const { dirname: dirname17 } = await import("node:path");
53459
- mkdirSync11(dirname17(hintMarker), { recursive: true });
53460
- writeFileSync16(hintMarker, (/* @__PURE__ */ new Date()).toISOString());
53131
+ const { writeFileSync: writeFileSync15, mkdirSync: mkdirSync10 } = await import("node:fs");
53132
+ const { dirname: dirname16 } = await import("node:path");
53133
+ mkdirSync10(dirname16(hintMarker), { recursive: true });
53134
+ writeFileSync15(hintMarker, (/* @__PURE__ */ new Date()).toISOString());
53461
53135
  } catch {
53462
53136
  }
53463
53137
  } catch {
@@ -53591,11 +53265,11 @@ async function main() {
53591
53265
  if (v === "npm" || v === "pypi") ecosystem = v;
53592
53266
  }
53593
53267
  const { runNpmPublishCheck: runNpmPublishCheck2, runPypiPublishCheck: runPypiPublishCheck2, renderPublishCheckResult: renderPublishCheckResult2 } = await Promise.resolve().then(() => (init_publish_check(), publish_check_exports));
53594
- const { existsSync: existsSync26 } = await import("node:fs");
53595
- const { join: join16 } = await import("node:path");
53268
+ const { existsSync: existsSync25 } = await import("node:fs");
53269
+ const { join: join15 } = await import("node:path");
53596
53270
  if (ecosystem === "auto") {
53597
- if (existsSync26(join16(process.cwd(), "package.json"))) ecosystem = "npm";
53598
- else if (existsSync26(join16(process.cwd(), "pyproject.toml")) || existsSync26(join16(process.cwd(), "setup.py"))) ecosystem = "pypi";
53271
+ if (existsSync25(join15(process.cwd(), "package.json"))) ecosystem = "npm";
53272
+ else if (existsSync25(join15(process.cwd(), "pyproject.toml")) || existsSync25(join15(process.cwd(), "setup.py"))) ecosystem = "pypi";
53599
53273
  else {
53600
53274
  process.stderr.write("\n publish-check: no package.json, pyproject.toml, or setup.py in current directory.\n Pass --ecosystem npm|pypi explicitly if your project layout differs.\n\n");
53601
53275
  process.exit(3);