@westbayberry/dg 1.1.3 → 1.1.5

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 +366 -644
  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);
@@ -44547,7 +44516,29 @@ function findingFingerprint(pkg, f) {
44547
44516
  function buildSarif(response, opts = {}) {
44548
44517
  const ruleMap = /* @__PURE__ */ new Map();
44549
44518
  const results = [];
44519
+ const INCOMPLETE_RULE = "dg.analysis_incomplete";
44550
44520
  for (const pkg of response.packages) {
44521
+ if (pkg.action === "analysis_incomplete") {
44522
+ if (!ruleMap.has(INCOMPLETE_RULE)) {
44523
+ ruleMap.set(INCOMPLETE_RULE, {
44524
+ id: INCOMPLETE_RULE,
44525
+ name: INCOMPLETE_RULE,
44526
+ shortDescription: { text: "Package could not be fully analyzed \u2014 treat as unverified" },
44527
+ defaultConfiguration: { level: "warning" }
44528
+ });
44529
+ }
44530
+ results.push({
44531
+ ruleId: INCOMPLETE_RULE,
44532
+ level: "warning",
44533
+ message: { text: `${pkg.name} ${pkg.version}: analysis incomplete \u2014 the scanner could not fully evaluate this package. Treat as unverified, not safe.` },
44534
+ locations: [{
44535
+ physicalLocation: {
44536
+ artifactLocation: { uri: opts.lockfileUri ?? `dg:${pkg.name}@${pkg.version}` }
44537
+ }
44538
+ }],
44539
+ partialFingerprints: { dg_finding: `${pkg.name}@${pkg.version}#${INCOMPLETE_RULE}`.slice(0, 240) }
44540
+ });
44541
+ }
44551
44542
  const findings = pkg.findings ?? [];
44552
44543
  for (const f of findings) {
44553
44544
  const id = findingId(f);
@@ -44686,8 +44677,8 @@ __export(audit_dispatcher_exports, {
44686
44677
  recordBypassLocally: () => recordBypassLocally,
44687
44678
  shouldFireAudit: () => shouldFireAudit
44688
44679
  });
44689
- import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync7, existsSync as existsSync17 } from "node:fs";
44690
- import { dirname as dirname11 } from "node:path";
44680
+ import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync6, existsSync as existsSync16 } from "node:fs";
44681
+ import { dirname as dirname10 } from "node:path";
44691
44682
  function _setPolicyFetcherForTests(fn) {
44692
44683
  _policyOverride = fn;
44693
44684
  }
@@ -44736,8 +44727,8 @@ function bypassLogPath2() {
44736
44727
  function recordBypassLocally(record) {
44737
44728
  try {
44738
44729
  const path2 = bypassLogPath2();
44739
- const dir = dirname11(path2);
44740
- if (!existsSync17(dir)) mkdirSync7(dir, { recursive: true, mode: 448 });
44730
+ const dir = dirname10(path2);
44731
+ if (!existsSync16(dir)) mkdirSync6(dir, { recursive: true, mode: 448 });
44741
44732
  const full = {
44742
44733
  ts: (/* @__PURE__ */ new Date()).toISOString(),
44743
44734
  cwd: record.cwd ?? process.cwd(),
@@ -44800,8 +44791,8 @@ __export(static_output_exports, {
44800
44791
  runStaticPip: () => runStaticPip,
44801
44792
  scanExitCode: () => scanExitCode
44802
44793
  });
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";
44794
+ import { writeFileSync as writeFileSync10, readFileSync as readFileSync11, existsSync as existsSync17, mkdirSync as mkdirSync7, lstatSync as lstatSync5 } from "node:fs";
44795
+ import { resolve as resolvePath, dirname as dirname11 } from "node:path";
44805
44796
  function note(config, text) {
44806
44797
  if (config.quiet) return;
44807
44798
  process.stderr.write(text);
@@ -44821,12 +44812,12 @@ function wrapperPackagesFromResult(result, topLevelNames) {
44821
44812
  }
44822
44813
  function loadPackageLockJson(cwd2 = process.cwd()) {
44823
44814
  const path2 = resolvePath(cwd2, "package-lock.json");
44824
- if (!existsSync18(path2)) return null;
44815
+ if (!existsSync17(path2)) return null;
44825
44816
  try {
44826
44817
  const st = lstatSync5(path2);
44827
44818
  if (!st.isFile()) return null;
44828
44819
  if (st.size > MAX_PACKAGE_LOCK_BYTES) return null;
44829
- return JSON.parse(readFileSync12(path2, "utf8"));
44820
+ return JSON.parse(readFileSync11(path2, "utf8"));
44830
44821
  } catch {
44831
44822
  return null;
44832
44823
  }
@@ -44834,7 +44825,7 @@ function loadPackageLockJson(cwd2 = process.cwd()) {
44834
44825
  function writeJsonFile(filepath, json) {
44835
44826
  const resolved = resolvePath(filepath);
44836
44827
  try {
44837
- writeFileSync11(resolved, json + "\n");
44828
+ writeFileSync10(resolved, json + "\n");
44838
44829
  process.stderr.write(import_chalk5.default.green(` \u2713 Saved to ${resolved}
44839
44830
 
44840
44831
  `));
@@ -44919,11 +44910,11 @@ function printTrialBanner(result, config) {
44919
44910
  if (process.env.CI === "1" || process.env.CI === "true") return;
44920
44911
  try {
44921
44912
  const stampPath = dgStatePath("trial-banner");
44922
- const lastMs = existsSync18(stampPath) ? Number(readFileSync12(stampPath, "utf-8").trim()) || 0 : 0;
44913
+ const lastMs = existsSync17(stampPath) ? Number(readFileSync11(stampPath, "utf-8").trim()) || 0 : 0;
44923
44914
  const now = Date.now();
44924
44915
  if (now - lastMs < NUDGE_INTERVAL_MS) return;
44925
- mkdirSync8(dirname12(stampPath), { recursive: true, mode: 448 });
44926
- writeFileSync11(stampPath, String(now) + "\n", { mode: 384 });
44916
+ mkdirSync7(dirname11(stampPath), { recursive: true, mode: 448 });
44917
+ writeFileSync10(stampPath, String(now) + "\n", { mode: 384 });
44927
44918
  } catch {
44928
44919
  return;
44929
44920
  }
@@ -44972,6 +44963,7 @@ function handleFreeCapReached2(error, jsonMode = false) {
44972
44963
  function actionColor(action) {
44973
44964
  if (action === "block") return import_chalk5.default.red;
44974
44965
  if (action === "warn") return import_chalk5.default.yellow;
44966
+ if (action === "analysis_incomplete") return import_chalk5.default.cyan;
44975
44967
  return import_chalk5.default.green;
44976
44968
  }
44977
44969
  function actionBadge(pkg) {
@@ -44980,15 +44972,16 @@ function actionBadge(pkg) {
44980
44972
  if (a === "warn") return { label: "Warn", color: import_chalk5.default.yellow };
44981
44973
  if (a === "pass") return { label: "Pass", color: import_chalk5.default.green };
44982
44974
  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
44975
  return { label: "Pass", color: import_chalk5.default.green };
44986
44976
  }
44987
44977
  function isBlocked(p) {
44988
- return p.action === "block" || p.action === void 0 && p.score >= 70;
44978
+ return p.action === "block";
44989
44979
  }
44990
44980
  function isWarned(p) {
44991
- return p.action === "warn" || p.action === void 0 && p.score >= 60 && p.score < 70;
44981
+ return p.action === "warn";
44982
+ }
44983
+ function isIncomplete(p) {
44984
+ return p.action === "analysis_incomplete";
44992
44985
  }
44993
44986
  function renderResultClean(result, _config) {
44994
44987
  const lines = [];
@@ -45001,7 +44994,8 @@ function renderResultClean(result, _config) {
45001
44994
  }
45002
44995
  const blocked = result.packages.filter(isBlocked);
45003
44996
  const warned = result.packages.filter(isWarned);
45004
- if (result.action === "pass" && blocked.length === 0 && warned.length === 0) {
44997
+ const incomplete = result.packages.filter(isIncomplete);
44998
+ if (result.action === "pass" && blocked.length === 0 && warned.length === 0 && incomplete.length === 0) {
45005
44999
  lines.push("");
45006
45000
  lines.push(` ${import_chalk5.default.green("\u2713")} ${import_chalk5.default.bold("Dependency Guardian")} checked ${total} package${total !== 1 ? "s" : ""}. ${import_chalk5.default.green("No risky behavior found.")}`);
45007
45001
  if (result.durationMs) {
@@ -45010,11 +45004,18 @@ function renderResultClean(result, _config) {
45010
45004
  lines.push("");
45011
45005
  return lines.join("\n");
45012
45006
  }
45013
- const headerColor = result.action === "block" ? import_chalk5.default.red : import_chalk5.default.yellow;
45014
- const headerLabel = result.action === "block" ? "BLOCK" : "WARN";
45007
+ const headerLabel = result.action === "block" ? "BLOCK" : result.action === "warn" ? "WARN" : result.action === "analysis_incomplete" ? "UNKNOWN" : "PASS";
45008
+ const headerColor = actionColor(result.action);
45009
+ const cleanCount = total - blocked.length - warned.length - incomplete.length;
45010
+ const countParts = [
45011
+ `${blocked.length} block`,
45012
+ `${warned.length} warn`,
45013
+ ...incomplete.length > 0 ? [`${incomplete.length} unknown`] : [],
45014
+ `${cleanCount} clean`
45015
+ ];
45015
45016
  lines.push("");
45016
45017
  lines.push(` ${headerColor(import_chalk5.default.bold(headerLabel))} ${import_chalk5.default.bold("Dependency Guardian")} ${import_chalk5.default.dim(`(score ${result.score})`)}`);
45017
- lines.push(` ${import_chalk5.default.dim(`${total} package${total !== 1 ? "s" : ""} scanned \xB7 ${blocked.length} block \xB7 ${warned.length} warn \xB7 ${total - blocked.length - warned.length} clean`)}`);
45018
+ lines.push(` ${import_chalk5.default.dim(`${total} package${total !== 1 ? "s" : ""} scanned \xB7 ${countParts.join(" \xB7 ")}`)}`);
45018
45019
  lines.push("");
45019
45020
  const showFirst = (pkgs, color, label) => {
45020
45021
  if (pkgs.length === 0) return;
@@ -45030,10 +45031,13 @@ function renderResultClean(result, _config) {
45030
45031
  };
45031
45032
  showFirst(blocked, import_chalk5.default.red, "Blocked");
45032
45033
  showFirst(warned, import_chalk5.default.yellow, "Warnings");
45034
+ showFirst(incomplete, import_chalk5.default.cyan, "Could not analyze");
45033
45035
  if (result.action === "block") {
45034
45036
  lines.push(` ${import_chalk5.default.dim("Next step:")} review the findings above, then either pin a safe version or use ${import_chalk5.default.bold("--dg-force")} to bypass.`);
45035
45037
  } else if (result.action === "warn") {
45036
45038
  lines.push(` ${import_chalk5.default.dim("Next step:")} review the warnings; install proceeds unless you set ${import_chalk5.default.bold("--mode block")}.`);
45039
+ } else if (result.action === "analysis_incomplete") {
45040
+ lines.push(` ${import_chalk5.default.dim("Next step:")} one or more packages could not be fully analyzed \u2014 treat as unverified, not safe. Re-run to retry.`);
45037
45041
  }
45038
45042
  lines.push("");
45039
45043
  return lines.join("\n");
@@ -45052,13 +45056,21 @@ function renderResultDetails(result, _config) {
45052
45056
  lines.push("");
45053
45057
  const blocked = result.packages.filter(isBlocked);
45054
45058
  const warned = result.packages.filter(isWarned);
45055
- const passWithScore = result.packages.filter((p) => p.score > 0 && p.score < 60);
45056
- const clean = result.packages.filter((p) => p.score === 0);
45059
+ const incomplete = result.packages.filter(isIncomplete);
45060
+ const rest = result.packages.filter((p) => !isBlocked(p) && !isWarned(p) && !isIncomplete(p));
45061
+ const passWithScore = rest.filter((p) => p.score > 0 && p.score < 60);
45062
+ const clean = rest.filter((p) => p.score === 0);
45057
45063
  const total = result.packages.length;
45058
45064
  const needsAttention = blocked.length + warned.length;
45059
- if (needsAttention > 0) {
45065
+ if (needsAttention > 0 || incomplete.length > 0) {
45066
+ const segs = [
45067
+ import_chalk5.default.red(`${blocked.length} block`),
45068
+ import_chalk5.default.yellow(`${warned.length} warn`),
45069
+ ...incomplete.length > 0 ? [import_chalk5.default.cyan(`${incomplete.length} unknown`)] : [],
45070
+ import_chalk5.default.green(`${clean.length + passWithScore.length} pass`)
45071
+ ];
45060
45072
  lines.push(
45061
- ` ${total} package${total !== 1 ? "s" : ""} scanned ${import_chalk5.default.dim("\u2502")} ${import_chalk5.default.red(`${blocked.length} block`)} ${import_chalk5.default.dim("\u2502")} ${import_chalk5.default.yellow(`${warned.length} warn`)} ${import_chalk5.default.dim("\u2502")} ${import_chalk5.default.green(`${clean.length + passWithScore.length} pass`)}`
45073
+ ` ${total} package${total !== 1 ? "s" : ""} scanned ${import_chalk5.default.dim("\u2502")} ${segs.join(` ${import_chalk5.default.dim("\u2502")} `)}`
45062
45074
  );
45063
45075
  } else {
45064
45076
  lines.push(
@@ -45071,8 +45083,8 @@ function renderResultDetails(result, _config) {
45071
45083
  lines.push("");
45072
45084
  return lines.join("\n");
45073
45085
  }
45074
- if (needsAttention > 0) {
45075
- const groups = groupPackages([...blocked, ...warned]);
45086
+ if (needsAttention > 0 || incomplete.length > 0) {
45087
+ const groups = groupPackages([...blocked, ...warned, ...incomplete]);
45076
45088
  lines.push(` ${import_chalk5.default.bold("Needs Attention")}`);
45077
45089
  lines.push(` ${import_chalk5.default.dim("\u2500".repeat(60))}`);
45078
45090
  for (const group of groups) {
@@ -45254,8 +45266,8 @@ async function runStatic(config) {
45254
45266
  const sarif = emitSarif2(result, {});
45255
45267
  const outputPath = config.outputFile;
45256
45268
  if (outputPath) {
45257
- const { writeFileSync: writeFileSync16 } = await import("node:fs");
45258
- writeFileSync16(outputPath, sarif);
45269
+ const { writeFileSync: writeFileSync15 } = await import("node:fs");
45270
+ writeFileSync15(outputPath, sarif);
45259
45271
  process.stderr.write(import_chalk5.default.green(` \u2713 Wrote SARIF to ${outputPath}
45260
45272
  `));
45261
45273
  } else {
@@ -46016,13 +46028,13 @@ __export(status_exports, {
46016
46028
  collectStatusSnapshot: () => collectStatusSnapshot,
46017
46029
  handleStatusCommand: () => handleStatusCommand
46018
46030
  });
46019
- import { existsSync as existsSync19, readFileSync as readFileSync13 } from "node:fs";
46020
- import { join as join12 } from "node:path";
46031
+ import { existsSync as existsSync18, readFileSync as readFileSync12 } from "node:fs";
46032
+ import { join as join11 } from "node:path";
46021
46033
  import { homedir as homedir6 } from "node:os";
46022
46034
  function readPythonReceipt() {
46023
46035
  try {
46024
- const { readFileSync: readFileSync18 } = __require("node:fs");
46025
- const receipt = JSON.parse(readFileSync18(dgStatePath("python-hook-receipt.json"), "utf-8"));
46036
+ const { readFileSync: readFileSync17 } = __require("node:fs");
46037
+ const receipt = JSON.parse(readFileSync17(dgStatePath("python-hook-receipt.json"), "utf-8"));
46026
46038
  const rows = receipt?.results ?? [];
46027
46039
  return rows.map((r) => ({ pythonVersion: r.pythonVersion, status: r.status, reason: r.reason }));
46028
46040
  } catch {
@@ -46065,12 +46077,12 @@ async function collectStatusSnapshot(cliVersion2) {
46065
46077
  authPart.reachable = false;
46066
46078
  }
46067
46079
  }
46068
- const shimDir2 = join12(homedir6(), ".dg", "shims");
46080
+ const shimDir2 = join11(homedir6(), ".dg", "shims");
46069
46081
  const shimRows = ECOSYSTEMS.map((eco) => {
46070
46082
  const filename = process.platform === "win32" ? `${eco}.cmd` : eco;
46071
46083
  return {
46072
46084
  ecosystem: eco,
46073
- shimPresent: existsSync19(join12(shimDir2, filename))
46085
+ shimPresent: existsSync18(join11(shimDir2, filename))
46074
46086
  };
46075
46087
  });
46076
46088
  const engineResolvable = isEngineResolvable();
@@ -46078,11 +46090,11 @@ async function collectStatusSnapshot(cliVersion2) {
46078
46090
  const cwd2 = process.cwd();
46079
46091
  const hookPart = { installed: false };
46080
46092
  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")];
46093
+ const { existsSync: ex, readFileSync: readFileSync17 } = await import("node:fs");
46094
+ const candidates = [join11(cwd2, ".husky", "pre-commit"), join11(cwd2, ".git", "hooks", "pre-commit")];
46083
46095
  for (const p of candidates) {
46084
46096
  if (ex(p)) {
46085
- const content = readFileSync18(p, "utf-8");
46097
+ const content = readFileSync17(p, "utf-8");
46086
46098
  if (content.includes("dependency-guardian")) {
46087
46099
  hookPart.installed = true;
46088
46100
  break;
@@ -46113,8 +46125,8 @@ async function collectStatusSnapshot(cliVersion2) {
46113
46125
  }
46114
46126
  function isEngineResolvable() {
46115
46127
  try {
46116
- const recorded = readFileSync13(join12(homedir6(), ".dg", "state", "dg-entry"), "utf-8").trim();
46117
- if (recorded && existsSync19(recorded)) return true;
46128
+ const recorded = readFileSync12(join11(homedir6(), ".dg", "state", "dg-entry"), "utf-8").trim();
46129
+ if (recorded && existsSync18(recorded)) return true;
46118
46130
  } catch {
46119
46131
  }
46120
46132
  try {
@@ -46591,16 +46603,15 @@ var InteractiveResultsView_exports = {};
46591
46603
  __export(InteractiveResultsView_exports, {
46592
46604
  InteractiveResultsView: () => InteractiveResultsView
46593
46605
  });
46594
- import { writeFileSync as writeFileSync12 } from "node:fs";
46606
+ import { writeFileSync as writeFileSync11 } from "node:fs";
46595
46607
  import { resolve as resolvePath2 } from "node:path";
46596
46608
  function groupPackages2(packages) {
46597
46609
  return groupPackages(packages, "fingerprint");
46598
46610
  }
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 };
46611
+ function actionBadge2(action) {
46612
+ if (action === "block") return { label: "Block", color: import_chalk9.default.red };
46613
+ if (action === "warn") return { label: "Warn", color: import_chalk9.default.yellow };
46614
+ if (action === "analysis_incomplete") return { label: "Unknown", color: import_chalk9.default.cyan };
46604
46615
  return { label: "Pass", color: import_chalk9.default.green };
46605
46616
  }
46606
46617
  function findingsSummaryHeight(group) {
@@ -46797,11 +46808,11 @@ var init_InteractiveResultsView = __esm({
46797
46808
  const scanUsage = usageDisplay ? usageDisplay.text : result.freeScansRemaining !== void 0 ? `${result.freeScansRemaining.toLocaleString()} packages left` : scanUsageProp;
46798
46809
  const usageNearLimit = usageDisplay?.nearLimit ?? false;
46799
46810
  const flagged = (0, import_react30.useMemo)(
46800
- () => result.packages.filter((p) => p.score > 0),
46811
+ () => result.packages.filter((p) => p.score > 0 || p.action === "analysis_incomplete"),
46801
46812
  [result.packages]
46802
46813
  );
46803
46814
  const clean = (0, import_react30.useMemo)(
46804
- () => result.packages.filter((p) => p.score === 0),
46815
+ () => result.packages.filter((p) => p.score === 0 && p.action !== "analysis_incomplete"),
46805
46816
  [result.packages]
46806
46817
  );
46807
46818
  const total = result.packages.length;
@@ -46859,8 +46870,8 @@ var init_InteractiveResultsView = __esm({
46859
46870
  setExportMenu({ scope: defaultScope, format: "json", activeRow: "scope" });
46860
46871
  };
46861
46872
  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);
46873
+ const blocked = result.packages.filter((p) => p.action === "block");
46874
+ const warned = result.packages.filter((p) => p.action === "warn");
46864
46875
  const cleanPkgs = result.packages.filter((p) => p.score === 0);
46865
46876
  const passWithScore = result.packages.filter((p) => p.score > 0 && p.score < 60);
46866
46877
  const summary = {
@@ -46907,7 +46918,7 @@ var init_InteractiveResultsView = __esm({
46907
46918
  name: p.name,
46908
46919
  version: p.version,
46909
46920
  score: p.score,
46910
- action: p.score >= 70 ? "block" : "warn",
46921
+ action: p.action,
46911
46922
  findings: p.findings.map((f) => ({
46912
46923
  severity: f.severity,
46913
46924
  category: f.category ?? null,
@@ -47098,7 +47109,7 @@ var init_InteractiveResultsView = __esm({
47098
47109
  const scopeTag = scope === "current-license" && currentLicenseIdx !== null ? `${(licenseGroups[currentLicenseIdx]?.spdx ?? "license").replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 32)}` : scope;
47099
47110
  const filename = `dg-scan-${ts}-${scopeTag}.${ext}`;
47100
47111
  const path2 = resolvePath2(process.cwd(), filename);
47101
- writeFileSync12(path2, body, "utf-8");
47112
+ writeFileSync11(path2, body, "utf-8");
47102
47113
  showExportMsg(`\u2713 Exported to ${filename}`);
47103
47114
  } catch (e) {
47104
47115
  showExportMsg(`Export failed: ${e.message}`);
@@ -47883,7 +47894,7 @@ var init_InteractiveResultsView = __esm({
47883
47894
  setDetailPane(null);
47884
47895
  } else {
47885
47896
  const dpRep = dpGroup.packages[0];
47886
- const { color: dpColor } = actionBadge2(dpRep.score);
47897
+ const { color: dpColor } = actionBadge2(dpRep.action);
47887
47898
  const dpScroll = detailPane.scroll;
47888
47899
  const dpAbove = dpScroll;
47889
47900
  const dpBelow = Math.max(0, detailLines.length - dpScroll - detailContentRows);
@@ -48016,7 +48027,7 @@ var init_InteractiveResultsView = __esm({
48016
48027
  const isCursor = globalIdx === clampedCursor;
48017
48028
  const level = getLevel(globalIdx);
48018
48029
  const rep = group.packages[0];
48019
- const { label, color } = actionBadge2(rep.score);
48030
+ const { label, color } = actionBadge2(rep.action);
48020
48031
  const names = groupNames(group);
48021
48032
  const scoreStr = String(rep.score);
48022
48033
  const lcInfo = rep.license;
@@ -48502,8 +48513,8 @@ __export(publish_check_exports, {
48502
48513
  summarize: () => summarize
48503
48514
  });
48504
48515
  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";
48516
+ import { readFileSync as readFileSync13, existsSync as existsSync19, readdirSync as readdirSync3 } from "node:fs";
48517
+ import { join as join12, basename as basename2 } from "node:path";
48507
48518
  import { createGunzip } from "node:zlib";
48508
48519
  import { createReadStream } from "node:fs";
48509
48520
  function sanitizeSnippet(s, max = 40) {
@@ -48550,7 +48561,7 @@ async function npmPackDryRun(cwd2 = process.cwd()) {
48550
48561
  }));
48551
48562
  let packageJson;
48552
48563
  try {
48553
- const raw = readFileSync14(join13(cwd2, "package.json"), "utf-8");
48564
+ const raw = readFileSync13(join12(cwd2, "package.json"), "utf-8");
48554
48565
  packageJson = JSON.parse(raw);
48555
48566
  } catch {
48556
48567
  }
@@ -48562,9 +48573,9 @@ async function npmPackDryRun(cwd2 = process.cwd()) {
48562
48573
  });
48563
48574
  }
48564
48575
  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));
48576
+ const dist = join12(cwd2, "dist");
48577
+ if (!existsSync19(dist)) return [];
48578
+ return readdirSync3(dist).filter((f) => f.endsWith(".tar.gz") || f.endsWith(".whl")).map((f) => join12(dist, f));
48568
48579
  }
48569
48580
  function scanPayload(files) {
48570
48581
  const findings = [];
@@ -48638,7 +48649,7 @@ async function runNpmPublishCheck(cwd2 = process.cwd()) {
48638
48649
  const payload = pack.files.map((f) => ({
48639
48650
  path: f.path,
48640
48651
  size: f.size,
48641
- read: () => readFileSync14(join13(cwd2, f.path))
48652
+ read: () => readFileSync13(join12(cwd2, f.path))
48642
48653
  }));
48643
48654
  const findings = scanPayload(payload);
48644
48655
  const scripts = pack.packageJson?.scripts ?? {};
@@ -48886,8 +48897,8 @@ var init_publish_check = __esm({
48886
48897
  });
48887
48898
 
48888
48899
  // 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";
48900
+ import { existsSync as existsSync20, mkdirSync as mkdirSync8, readFileSync as readFileSync14, writeFileSync as writeFileSync12, chmodSync as chmodSync4 } from "node:fs";
48901
+ import { dirname as dirname12, isAbsolute as isAbsolute2, normalize as normalize2 } from "node:path";
48891
48902
  import { homedir as homedir7 } from "node:os";
48892
48903
  function registryPath() {
48893
48904
  return dgStatePath("hooks-installed.json");
@@ -48929,10 +48940,10 @@ function validateEntry(raw) {
48929
48940
  }
48930
48941
  function readRegistry() {
48931
48942
  const path2 = registryPath();
48932
- if (!existsSync21(path2)) return [];
48943
+ if (!existsSync20(path2)) return [];
48933
48944
  let raw;
48934
48945
  try {
48935
- raw = readFileSync15(path2, "utf-8");
48946
+ raw = readFileSync14(path2, "utf-8");
48936
48947
  } catch {
48937
48948
  return [];
48938
48949
  }
@@ -48954,12 +48965,12 @@ function readRegistry() {
48954
48965
  }
48955
48966
  function writeRegistry(entries) {
48956
48967
  const path2 = registryPath();
48957
- const parent = dirname13(path2);
48958
- if (!existsSync21(parent)) mkdirSync9(parent, { recursive: true, mode: 448 });
48968
+ const parent = dirname12(path2);
48969
+ if (!existsSync20(parent)) mkdirSync8(parent, { recursive: true, mode: 448 });
48959
48970
  const payload = { version: 1, entries };
48960
- writeFileSync13(path2, JSON.stringify(payload, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
48971
+ writeFileSync12(path2, JSON.stringify(payload, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
48961
48972
  try {
48962
- chmodSync5(path2, 384);
48973
+ chmodSync4(path2, 384);
48963
48974
  } catch {
48964
48975
  }
48965
48976
  }
@@ -49005,20 +49016,20 @@ __export(hook_exports, {
49005
49016
  });
49006
49017
  import { createHash } from "node:crypto";
49007
49018
  import {
49008
- existsSync as existsSync22,
49019
+ existsSync as existsSync21,
49009
49020
  lstatSync as lstatSync6,
49010
- readFileSync as readFileSync16,
49011
- writeFileSync as writeFileSync14,
49012
- mkdirSync as mkdirSync10,
49013
- chmodSync as chmodSync6,
49014
- unlinkSync as unlinkSync5
49021
+ readFileSync as readFileSync15,
49022
+ writeFileSync as writeFileSync13,
49023
+ mkdirSync as mkdirSync9,
49024
+ chmodSync as chmodSync5,
49025
+ unlinkSync as unlinkSync4
49015
49026
  } from "node:fs";
49016
- import { join as join14, dirname as dirname14, resolve as resolvePath3, isAbsolute as isAbsolute3 } from "node:path";
49027
+ import { join as join13, dirname as dirname13, resolve as resolvePath3, isAbsolute as isAbsolute3 } from "node:path";
49017
49028
  function hashRepoPath(repoPath) {
49018
49029
  return createHash("sha256").update(repoPath).digest("hex");
49019
49030
  }
49020
49031
  function assertSafeWriteTarget(target) {
49021
- const parent = dirname14(target);
49032
+ const parent = dirname13(target);
49022
49033
  try {
49023
49034
  const parentStat = lstatSync6(parent);
49024
49035
  if (parentStat.isSymbolicLink()) {
@@ -49046,7 +49057,7 @@ function assertSafeWriteTarget(target) {
49046
49057
  }
49047
49058
  function safeWriteFileSync(target, content) {
49048
49059
  assertSafeWriteTarget(target);
49049
- writeFileSync14(target, content);
49060
+ writeFileSync13(target, content);
49050
49061
  }
49051
49062
  function findHooksDir() {
49052
49063
  try {
@@ -49064,13 +49075,13 @@ function findRepoRoot() {
49064
49075
  }
49065
49076
  function detectHookFramework(repoRoot) {
49066
49077
  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");
49078
+ const huskyHook = join13(root, ".husky", "pre-commit");
49079
+ const lefthookConfig = join13(root, "lefthook.yml");
49080
+ const lefthookConfigYaml = join13(root, "lefthook.yaml");
49070
49081
  const hooksDir = findHooksDir();
49071
- const bareHook = join14(hooksDir, "pre-commit");
49072
- if (existsSync22(huskyHook)) {
49073
- const content = readFileSync16(huskyHook, "utf-8");
49082
+ const bareHook = join13(hooksDir, "pre-commit");
49083
+ if (existsSync21(huskyHook)) {
49084
+ const content = readFileSync15(huskyHook, "utf-8");
49074
49085
  return {
49075
49086
  framework: "husky",
49076
49087
  targetFile: huskyHook,
@@ -49078,8 +49089,8 @@ function detectHookFramework(repoRoot) {
49078
49089
  };
49079
49090
  }
49080
49091
  for (const cfg of [lefthookConfig, lefthookConfigYaml]) {
49081
- if (existsSync22(cfg)) {
49082
- const content = readFileSync16(cfg, "utf-8");
49092
+ if (existsSync21(cfg)) {
49093
+ const content = readFileSync15(cfg, "utf-8");
49083
49094
  const installed2 = /^\s+dependency-guardian\s*:/m.test(content);
49084
49095
  return {
49085
49096
  framework: "lefthook",
@@ -49089,8 +49100,8 @@ function detectHookFramework(repoRoot) {
49089
49100
  }
49090
49101
  }
49091
49102
  let installed = false;
49092
- if (existsSync22(bareHook)) {
49093
- installed = readFileSync16(bareHook, "utf-8").includes(HOOK_MARKER);
49103
+ if (existsSync21(bareHook)) {
49104
+ installed = readFileSync15(bareHook, "utf-8").includes(HOOK_MARKER);
49094
49105
  }
49095
49106
  return {
49096
49107
  framework: "bare",
@@ -49099,12 +49110,12 @@ function detectHookFramework(repoRoot) {
49099
49110
  };
49100
49111
  }
49101
49112
  function verifyHookInstalled(info) {
49102
- if (!existsSync22(info.targetFile)) {
49113
+ if (!existsSync21(info.targetFile)) {
49103
49114
  return { ok: false, reason: `hook file missing: ${info.targetFile}` };
49104
49115
  }
49105
49116
  let content;
49106
49117
  try {
49107
- content = readFileSync16(info.targetFile, "utf-8");
49118
+ content = readFileSync15(info.targetFile, "utf-8");
49108
49119
  } catch (e) {
49109
49120
  return { ok: false, reason: `cannot read ${info.targetFile}: ${e.message}` };
49110
49121
  }
@@ -49142,7 +49153,7 @@ ${HUSKY_SNIPPET}`;
49142
49153
 
49143
49154
  ${LEFTHOOK_ENTRY}`;
49144
49155
  case "bare":
49145
- if (existsSync22(info.targetFile)) {
49156
+ if (existsSync21(info.targetFile)) {
49146
49157
  return `Will append to existing hook at ${info.targetFile}:
49147
49158
  ${HOOK_SECTION}`;
49148
49159
  }
@@ -49151,21 +49162,21 @@ ${HOOK_SCRIPT}`;
49151
49162
  }
49152
49163
  }
49153
49164
  function installHuskyHook(targetFile) {
49154
- const existing = readFileSync16(targetFile, "utf-8");
49165
+ const existing = readFileSync15(targetFile, "utf-8");
49155
49166
  if (existing.includes(HOOK_MARKER)) {
49156
49167
  process.stderr.write(" Hook already installed in Husky.\n");
49157
49168
  return;
49158
49169
  }
49159
49170
  safeWriteFileSync(targetFile, existing.trimEnd() + "\n" + HUSKY_SNIPPET);
49160
49171
  try {
49161
- chmodSync6(targetFile, 493);
49172
+ chmodSync5(targetFile, 493);
49162
49173
  } catch {
49163
49174
  }
49164
49175
  process.stderr.write(` Appended Dependency Guardian to ${targetFile}
49165
49176
  `);
49166
49177
  }
49167
49178
  function installLefthookHook(targetFile) {
49168
- const existing = readFileSync16(targetFile, "utf-8");
49179
+ const existing = readFileSync15(targetFile, "utf-8");
49169
49180
  if (/^\s+dependency-guardian\s*:/m.test(existing)) {
49170
49181
  process.stderr.write(" Hook already installed in lefthook.\n");
49171
49182
  return;
@@ -49197,16 +49208,16 @@ function installLefthookHook(targetFile) {
49197
49208
  `);
49198
49209
  }
49199
49210
  function installBareHook(targetFile) {
49200
- const hooksDir = dirname14(targetFile);
49201
- mkdirSync10(hooksDir, { recursive: true });
49202
- if (existsSync22(targetFile)) {
49203
- const existing = readFileSync16(targetFile, "utf-8");
49211
+ const hooksDir = dirname13(targetFile);
49212
+ mkdirSync9(hooksDir, { recursive: true });
49213
+ if (existsSync21(targetFile)) {
49214
+ const existing = readFileSync15(targetFile, "utf-8");
49204
49215
  if (existing.includes(HOOK_MARKER)) {
49205
49216
  process.stderr.write(" Hook already installed.\n");
49206
49217
  return;
49207
49218
  }
49208
49219
  safeWriteFileSync(targetFile, existing.trimEnd() + "\n" + HOOK_SECTION);
49209
- chmodSync6(targetFile, 493);
49220
+ chmodSync5(targetFile, 493);
49210
49221
  process.stderr.write(
49211
49222
  ` Appended Dependency Guardian hook to existing ${targetFile}
49212
49223
  `
@@ -49214,7 +49225,7 @@ function installBareHook(targetFile) {
49214
49225
  return;
49215
49226
  }
49216
49227
  safeWriteFileSync(targetFile, HOOK_SCRIPT);
49217
- chmodSync6(targetFile, 493);
49228
+ chmodSync5(targetFile, 493);
49218
49229
  process.stderr.write(` Installed git pre-commit hook at ${targetFile}
49219
49230
  `);
49220
49231
  }
@@ -49257,10 +49268,10 @@ async function installHook() {
49257
49268
  }
49258
49269
  }
49259
49270
  function stripDgFromHookFile(hookPath, framework, repoPath) {
49260
- if (!existsSync22(hookPath)) {
49271
+ if (!existsSync21(hookPath)) {
49261
49272
  return { status: "not-found", hookPath, repoPath };
49262
49273
  }
49263
- const content = readFileSync16(hookPath, "utf-8");
49274
+ const content = readFileSync15(hookPath, "utf-8");
49264
49275
  if (framework === "lefthook") {
49265
49276
  if (!/^\s+dependency-guardian\s*:/m.test(content)) {
49266
49277
  return { status: "not-found", hookPath, repoPath };
@@ -49277,7 +49288,7 @@ function stripDgFromHookFile(hookPath, framework, repoPath) {
49277
49288
  return { status: "not-found", hookPath, repoPath };
49278
49289
  }
49279
49290
  if (framework === "bare" && content.trimStart().startsWith("#!/bin/sh\n" + HOOK_MARKER)) {
49280
- unlinkSync5(hookPath);
49291
+ unlinkSync4(hookPath);
49281
49292
  removeEntry(repoPath, hookPath);
49282
49293
  return { status: "removed", hookPath, repoPath };
49283
49294
  }
@@ -49290,7 +49301,7 @@ function stripDgFromHookFile(hookPath, framework, repoPath) {
49290
49301
  const after = content.slice(endIdx + MARKER_END.length).trimStart();
49291
49302
  const remaining = (before + (after ? "\n" + after : "")).trimEnd() + "\n";
49292
49303
  if (remaining.trim() === "" || remaining.trim() === "#!/bin/sh") {
49293
- unlinkSync5(hookPath);
49304
+ unlinkSync4(hookPath);
49294
49305
  } else {
49295
49306
  safeWriteFileSync(hookPath, remaining);
49296
49307
  }
@@ -49300,10 +49311,10 @@ function stripDgFromHookFile(hookPath, framework, repoPath) {
49300
49311
  function uninstallHookFromRepo(repoRootOverride) {
49301
49312
  const root = repoRootOverride ?? findRepoRoot();
49302
49313
  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");
49314
+ const hookPath = join13(hooksDir, "pre-commit");
49315
+ const huskyPath = join13(root, ".husky", "pre-commit");
49316
+ if (existsSync21(huskyPath)) {
49317
+ const content2 = readFileSync15(huskyPath, "utf-8");
49307
49318
  if (content2.includes(HOOK_MARKER)) {
49308
49319
  const startIdx2 = content2.indexOf(MARKER_START);
49309
49320
  const endIdx2 = content2.indexOf(MARKER_END);
@@ -49317,9 +49328,9 @@ function uninstallHookFromRepo(repoRootOverride) {
49317
49328
  }
49318
49329
  }
49319
49330
  }
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");
49331
+ for (const cfg of [join13(root, "lefthook.yml"), join13(root, "lefthook.yaml")]) {
49332
+ if (!existsSync21(cfg)) continue;
49333
+ const content2 = readFileSync15(cfg, "utf-8");
49323
49334
  if (/^\s+dependency-guardian\s*:/m.test(content2)) {
49324
49335
  const stripped = content2.replace(
49325
49336
  /^\s+dependency-guardian\s*:\s*\n(?:\s{6,}.*\n)+/gm,
@@ -49330,15 +49341,15 @@ function uninstallHookFromRepo(repoRootOverride) {
49330
49341
  return { status: "removed", hookPath: cfg, repoPath: root };
49331
49342
  }
49332
49343
  }
49333
- if (!existsSync22(hookPath)) {
49344
+ if (!existsSync21(hookPath)) {
49334
49345
  return { status: "not-found", hookPath, repoPath: root };
49335
49346
  }
49336
- const content = readFileSync16(hookPath, "utf-8");
49347
+ const content = readFileSync15(hookPath, "utf-8");
49337
49348
  if (!content.includes(HOOK_MARKER)) {
49338
49349
  return { status: "not-found", hookPath, repoPath: root };
49339
49350
  }
49340
49351
  if (content.trimStart().startsWith("#!/bin/sh\n" + HOOK_MARKER)) {
49341
- unlinkSync5(hookPath);
49352
+ unlinkSync4(hookPath);
49342
49353
  removeEntry(root, hookPath);
49343
49354
  return { status: "removed", hookPath, repoPath: root };
49344
49355
  }
@@ -49352,7 +49363,7 @@ function uninstallHookFromRepo(repoRootOverride) {
49352
49363
  removeEntry(root, hookPath);
49353
49364
  return { status: "removed", hookPath, repoPath: root };
49354
49365
  }
49355
- unlinkSync5(hookPath);
49366
+ unlinkSync4(hookPath);
49356
49367
  removeEntry(root, hookPath);
49357
49368
  return { status: "removed", hookPath, repoPath: root };
49358
49369
  }
@@ -49506,7 +49517,7 @@ __export(update_exports, {
49506
49517
  runUpdate: () => runUpdate
49507
49518
  });
49508
49519
  import { spawnSync as spawnSync2 } from "node:child_process";
49509
- import { accessSync, constants as constants2, realpathSync, unlinkSync as unlinkSync6 } from "node:fs";
49520
+ import { accessSync, constants as constants2, realpathSync, unlinkSync as unlinkSync5 } from "node:fs";
49510
49521
  import { sep as sep3 } from "node:path";
49511
49522
  function parseUpdateArgs(args) {
49512
49523
  return {
@@ -49617,7 +49628,7 @@ function printUpgradeCommand(latest, kind) {
49617
49628
  }
49618
49629
  function invalidateUpdateCache() {
49619
49630
  try {
49620
- unlinkSync6(dgCachePath("update-check.json"));
49631
+ unlinkSync5(dgCachePath("update-check.json"));
49621
49632
  } catch {
49622
49633
  }
49623
49634
  }
@@ -49767,8 +49778,8 @@ var init_update = __esm({
49767
49778
  });
49768
49779
 
49769
49780
  // 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";
49781
+ import { existsSync as existsSync22, readFileSync as readFileSync16, unlinkSync as unlinkSync6, readdirSync as readdirSync4, statSync as statSync4 } from "node:fs";
49782
+ import { dirname as dirname14, join as join14, resolve } from "node:path";
49772
49783
  import { spawnSync as spawnSync3 } from "node:child_process";
49773
49784
  import { homedir as homedir8 } from "node:os";
49774
49785
  function probeUserSite(pythonName) {
@@ -49792,8 +49803,8 @@ function uninstallPythonHooks(_opts = {}) {
49792
49803
  const removed = [];
49793
49804
  let receipt = null;
49794
49805
  try {
49795
- if (existsSync23(receiptPath)) {
49796
- receipt = JSON.parse(readFileSync17(receiptPath, "utf-8"));
49806
+ if (existsSync22(receiptPath)) {
49807
+ receipt = JSON.parse(readFileSync16(receiptPath, "utf-8"));
49797
49808
  }
49798
49809
  } catch {
49799
49810
  receipt = null;
@@ -49811,9 +49822,9 @@ function uninstallPythonHooks(_opts = {}) {
49811
49822
  }
49812
49823
  for (const site of sites) {
49813
49824
  for (const filename of ["dg_pip_hook.py", "dg_pip_hook.pth"]) {
49814
- const full = join15(site, filename);
49825
+ const full = join14(site, filename);
49815
49826
  try {
49816
- if (existsSync23(full)) {
49827
+ if (existsSync22(full)) {
49817
49828
  safeUnlink(full);
49818
49829
  removed.push(full);
49819
49830
  }
@@ -49821,13 +49832,13 @@ function uninstallPythonHooks(_opts = {}) {
49821
49832
  }
49822
49833
  }
49823
49834
  try {
49824
- const pyCache = join15(site, "__pycache__");
49825
- if (existsSync23(pyCache) && statSync5(pyCache).isDirectory()) {
49835
+ const pyCache = join14(site, "__pycache__");
49836
+ if (existsSync22(pyCache) && statSync4(pyCache).isDirectory()) {
49826
49837
  for (const f of readdirSync4(pyCache)) {
49827
49838
  if (f.startsWith("dg_pip_hook.")) {
49828
49839
  try {
49829
- safeUnlink(join15(pyCache, f));
49830
- removed.push(join15(pyCache, f));
49840
+ safeUnlink(join14(pyCache, f));
49841
+ removed.push(join14(pyCache, f));
49831
49842
  } catch {
49832
49843
  }
49833
49844
  }
@@ -49837,8 +49848,8 @@ function uninstallPythonHooks(_opts = {}) {
49837
49848
  }
49838
49849
  }
49839
49850
  try {
49840
- if (existsSync23(receiptPath)) {
49841
- unlinkSync7(receiptPath);
49851
+ if (existsSync22(receiptPath)) {
49852
+ unlinkSync6(receiptPath);
49842
49853
  }
49843
49854
  } catch {
49844
49855
  }
@@ -49869,7 +49880,7 @@ __export(uninstall_exports, {
49869
49880
  parseUninstallArgs: () => parseUninstallArgs,
49870
49881
  runUninstall: () => runUninstall
49871
49882
  });
49872
- import { existsSync as existsSync24, rmSync as rmSync3, unlinkSync as unlinkSync8, statSync as statSync6 } from "node:fs";
49883
+ import { existsSync as existsSync23, rmSync as rmSync2, unlinkSync as unlinkSync7 } from "node:fs";
49873
49884
  function parseUninstallArgs(args) {
49874
49885
  return {
49875
49886
  assumeYes: args.includes("--yes") || args.includes("-y"),
@@ -49880,21 +49891,18 @@ function parseUninstallArgs(args) {
49880
49891
  }
49881
49892
  function safeExists(p) {
49882
49893
  try {
49883
- return existsSync24(p);
49894
+ return existsSync23(p);
49884
49895
  } catch {
49885
49896
  return false;
49886
49897
  }
49887
49898
  }
49888
49899
  function buildPlan(opts) {
49889
49900
  const p = dgPaths();
49890
- const legacy = legacyPaths();
49891
49901
  const plan = {
49892
49902
  configFiles: [],
49893
49903
  cacheDir: null,
49894
49904
  stateDir: null,
49895
49905
  rootDir: null,
49896
- legacyFiles: [],
49897
- legacyDirs: [],
49898
49906
  hooks: [],
49899
49907
  rcCleanup: false
49900
49908
  };
@@ -49903,10 +49911,6 @@ function buildPlan(opts) {
49903
49911
  if (safeExists(p.cacheDir)) plan.cacheDir = p.cacheDir;
49904
49912
  if (safeExists(p.stateDir)) plan.stateDir = p.stateDir;
49905
49913
  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
49914
  if (!opts.keepHooks) {
49911
49915
  plan.hooks = listEntries();
49912
49916
  }
@@ -49930,10 +49934,6 @@ function printPlan(plan, opts) {
49930
49934
  process.stderr.write(` ${plan.rootDir}/ (entire tree)
49931
49935
  `);
49932
49936
  }
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
49937
  if (plan.hooks.length > 0) {
49938
49938
  process.stderr.write(` pre-commit hooks in ${plan.hooks.length} repo(s):
49939
49939
  `);
@@ -49996,7 +49996,7 @@ async function revokeApiKey(apiKey) {
49996
49996
  }
49997
49997
  function rmFile(path2) {
49998
49998
  try {
49999
- unlinkSync8(path2);
49999
+ unlinkSync7(path2);
50000
50000
  return { ok: true };
50001
50001
  } catch (e) {
50002
50002
  const code = e.code;
@@ -50006,20 +50006,12 @@ function rmFile(path2) {
50006
50006
  }
50007
50007
  function rmTree(path2) {
50008
50008
  try {
50009
- rmSync3(path2, { recursive: true, force: true });
50009
+ rmSync2(path2, { recursive: true, force: true });
50010
50010
  return { ok: true };
50011
50011
  } catch (e) {
50012
50012
  return { ok: false, reason: e.message };
50013
50013
  }
50014
50014
  }
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
50015
  async function runUninstall(args) {
50024
50016
  if (args.includes("--help") || args.includes("-h")) {
50025
50017
  process.stdout.write(USAGE5);
@@ -50065,7 +50057,7 @@ async function runUninstall(args) {
50065
50057
  }
50066
50058
  if (!opts.keepHooks && !opts.soft) {
50067
50059
  for (const h of plan.hooks) {
50068
- if (!existsSync24(h.repoPath)) {
50060
+ if (!existsSync23(h.repoPath)) {
50069
50061
  process.stderr.write(import_chalk11.default.dim(` \xB7 ${h.repoPath} no longer exists \u2014 skipping registered hook
50070
50062
  `));
50071
50063
  continue;
@@ -50131,22 +50123,6 @@ async function runUninstall(args) {
50131
50123
  `);
50132
50124
  }
50133
50125
  } 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
50126
  if (plan.rootDir) {
50151
50127
  const r = rmTree(plan.rootDir);
50152
50128
  if (r.ok) process.stderr.write(import_chalk11.default.green(" \u2713 ") + `Removed ${plan.rootDir}
@@ -50196,9 +50172,6 @@ var init_uninstall = __esm({
50196
50172
 
50197
50173
  Removes:
50198
50174
  ~/.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
50175
  every per-repo pre-commit hook installed via 'dg hook install'
50203
50176
  the dg sentinel block in your shell rc files
50204
50177
 
@@ -50215,7 +50188,7 @@ var verify_exports = {};
50215
50188
  __export(verify_exports, {
50216
50189
  handleVerifyCommand: () => handleVerifyCommand
50217
50190
  });
50218
- import { writeFileSync as writeFileSync15 } from "node:fs";
50191
+ import { writeFileSync as writeFileSync14 } from "node:fs";
50219
50192
  function detectEcosystem(spec) {
50220
50193
  if (/[<>=!~]=?|~=/.test(spec)) return "pypi";
50221
50194
  if (spec.startsWith("@")) return "npm";
@@ -50330,7 +50303,7 @@ async function callApi(packages, ecosystem, config) {
50330
50303
  }
50331
50304
  function writeOutput(content, outputPath) {
50332
50305
  if (outputPath) {
50333
- writeFileSync15(outputPath, content);
50306
+ writeFileSync14(outputPath, content);
50334
50307
  process.stderr.write(import_chalk12.default.green(` \u2713 Wrote ${content.length} bytes to ${outputPath}
50335
50308
  `));
50336
50309
  } else {
@@ -50749,7 +50722,6 @@ async function scanProjects(projects, config, dispatch) {
50749
50722
  dispatch({ type: "DISCOVERY_EMPTY", message: "No packages to scan." });
50750
50723
  return;
50751
50724
  }
50752
- const startMs = Date.now();
50753
50725
  const results = [];
50754
50726
  let completed = 0;
50755
50727
  if (npmPackages.length > 0) {
@@ -50776,18 +50748,7 @@ async function scanProjects(projects, config, dispatch) {
50776
50748
  });
50777
50749
  results.push(pypiResult);
50778
50750
  }
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
- };
50751
+ const merged = mergeResponses(results);
50791
50752
  dispatch({ type: "SCAN_COMPLETE", result: merged, durationMs: merged.durationMs, skippedCount: 0, discoveredTotal });
50792
50753
  } catch (error) {
50793
50754
  if (error instanceof FreeCapReachedError) {
@@ -51333,8 +51294,8 @@ __export(ink_controls_exports, {
51333
51294
  setInkClear: () => setInkClear,
51334
51295
  setInkInstance: () => setInkInstance
51335
51296
  });
51336
- import { resolve as resolve2, dirname as dirname16 } from "node:path";
51337
- import { existsSync as existsSync25 } from "node:fs";
51297
+ import { resolve as resolve2, dirname as dirname15 } from "node:path";
51298
+ import { existsSync as existsSync24 } from "node:fs";
51338
51299
  function locateInkInstancesPath() {
51339
51300
  let cur;
51340
51301
  try {
@@ -51344,13 +51305,13 @@ function locateInkInstancesPath() {
51344
51305
  }
51345
51306
  while (cur && cur !== "/" && cur !== ".") {
51346
51307
  const candidate = resolve2(cur, "node_modules", "ink", "build", "instances.js");
51347
- if (existsSync25(candidate)) return candidate;
51348
- const parent = dirname16(cur);
51308
+ if (existsSync24(candidate)) return candidate;
51309
+ const parent = dirname15(cur);
51349
51310
  if (parent === cur) break;
51350
51311
  cur = parent;
51351
51312
  }
51352
51313
  const cwdCandidate = resolve2(process.cwd(), "node_modules", "ink", "build", "instances.js");
51353
- if (existsSync25(cwdCandidate)) return cwdCandidate;
51314
+ if (existsSync24(cwdCandidate)) return cwdCandidate;
51354
51315
  return null;
51355
51316
  }
51356
51317
  async function initInkInstances() {
@@ -51842,9 +51803,10 @@ function severityColor(sev) {
51842
51803
  if (sev >= 2) return import_chalk16.default.dim;
51843
51804
  return import_chalk16.default.dim;
51844
51805
  }
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 };
51806
+ function actionBadge3(action) {
51807
+ if (action === "block") return { label: "BLOCK", color: import_chalk16.default.red };
51808
+ if (action === "warn") return { label: "WARN", color: import_chalk16.default.yellow };
51809
+ if (action === "analysis_incomplete") return { label: "UNKNOWN", color: import_chalk16.default.cyan };
51848
51810
  return { label: "PASS", color: import_chalk16.default.green };
51849
51811
  }
51850
51812
  var import_chalk16, import_jsx_runtime15, SEVERITY_LABELS2, EVIDENCE_LIMIT2, ResultsView;
@@ -51870,8 +51832,8 @@ var init_ResultsView = __esm({
51870
51832
  config: _config,
51871
51833
  durationMs
51872
51834
  }) => {
51873
- const flagged = result.packages.filter((p) => p.score > 0);
51874
- const clean = result.packages.filter((p) => p.score === 0);
51835
+ const flagged = result.packages.filter((p) => p.score > 0 || p.action === "analysis_incomplete");
51836
+ const clean = result.packages.filter((p) => p.score === 0 && p.action !== "analysis_incomplete");
51875
51837
  const total = result.packages.length;
51876
51838
  const groups = groupPackages(flagged);
51877
51839
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, children: [
@@ -51896,7 +51858,7 @@ var init_ResultsView = __esm({
51896
51858
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { dimColor: true, children: "\u2500".repeat(60) }),
51897
51859
  groups.map((group) => {
51898
51860
  const rep = group.packages[0];
51899
- const { label, color } = actionBadge3(rep.score);
51861
+ const { label, color } = actionBadge3(rep.action);
51900
51862
  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
51863
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Text, { children: [
51902
51864
  " ",
@@ -52026,13 +51988,15 @@ function reasonTag(pkg) {
52026
51988
  function countSummary(result) {
52027
51989
  let block = 0;
52028
51990
  let warn = 0;
51991
+ let unknown = 0;
52029
51992
  let clean = 0;
52030
51993
  for (const p of result.packages) {
52031
- if (p.score >= 70) block++;
52032
- else if (p.score >= 60) warn++;
51994
+ if (p.action === "block") block++;
51995
+ else if (p.action === "warn") warn++;
51996
+ else if (p.action === "analysis_incomplete") unknown++;
52033
51997
  else clean++;
52034
51998
  }
52035
- return { block, warn, clean };
51999
+ return { block, warn, unknown, clean };
52036
52000
  }
52037
52001
  var import_jsx_runtime17, WrapperVerdictLine;
52038
52002
  var init_WrapperVerdictLine = __esm({
@@ -52103,6 +52067,7 @@ var init_WrapperVerdictLine = __esm({
52103
52067
  const parts = [];
52104
52068
  if (counts.block > 0) parts.push(`${counts.block} block`);
52105
52069
  if (counts.warn > 0) parts.push(`${counts.warn} warn`);
52070
+ if (counts.unknown > 0) parts.push(`${counts.unknown} unknown`);
52106
52071
  if (counts.clean > 0) parts.push(`${counts.clean} clean`);
52107
52072
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Box_default, { flexDirection: "row", children: [
52108
52073
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { color, children: [
@@ -53158,253 +53123,10 @@ function closestCommand(input, commands) {
53158
53123
  return bestDist <= 3 ? best : null;
53159
53124
  }
53160
53125
 
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
53126
  // src/bin.ts
53404
53127
  init_terminal_state();
53405
53128
  var CLI_VERSION = getVersion();
53406
53129
  initTelemetry(CLI_VERSION);
53407
- runMigrationIfNeeded();
53408
53130
  function setProcessTitle(title) {
53409
53131
  try {
53410
53132
  process.title = title;
@@ -53436,15 +53158,15 @@ async function maybeShowWiringHint(rawCommand) {
53436
53158
  const SKIP = /* @__PURE__ */ new Set(["uninstall", "__wrap", "version", "--version", "-v", "help", "--help", "-h"]);
53437
53159
  if (SKIP.has(rawCommand)) return;
53438
53160
  try {
53439
- const { existsSync: existsSync26 } = await import("node:fs");
53440
- const { join: join16 } = await import("node:path");
53161
+ const { existsSync: existsSync25 } = await import("node:fs");
53162
+ const { join: join15 } = await import("node:path");
53441
53163
  const { homedir: homedir9 } = await import("node:os");
53442
53164
  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");
53165
+ const receiptPath = join15(homedir9(), ".dg", "state", "install-receipt.json");
53166
+ const shimPath = join15(homedir9(), ".dg", "shims", "npm");
53445
53167
  const hintMarker = dgStatePath2("wiring-hint-shown");
53446
- if (existsSync26(receiptPath) || existsSync26(shimPath)) return;
53447
- if (existsSync26(hintMarker)) return;
53168
+ if (existsSync25(receiptPath) || existsSync25(shimPath)) return;
53169
+ if (existsSync25(hintMarker)) return;
53448
53170
  const chalk18 = (await Promise.resolve().then(() => __toESM(require_source(), 1))).default;
53449
53171
  process.stderr.write(
53450
53172
  `
@@ -53454,10 +53176,10 @@ async function maybeShowWiringHint(rawCommand) {
53454
53176
  `
53455
53177
  );
53456
53178
  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());
53179
+ const { writeFileSync: writeFileSync15, mkdirSync: mkdirSync10 } = await import("node:fs");
53180
+ const { dirname: dirname16 } = await import("node:path");
53181
+ mkdirSync10(dirname16(hintMarker), { recursive: true });
53182
+ writeFileSync15(hintMarker, (/* @__PURE__ */ new Date()).toISOString());
53461
53183
  } catch {
53462
53184
  }
53463
53185
  } catch {
@@ -53591,11 +53313,11 @@ async function main() {
53591
53313
  if (v === "npm" || v === "pypi") ecosystem = v;
53592
53314
  }
53593
53315
  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");
53316
+ const { existsSync: existsSync25 } = await import("node:fs");
53317
+ const { join: join15 } = await import("node:path");
53596
53318
  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";
53319
+ if (existsSync25(join15(process.cwd(), "package.json"))) ecosystem = "npm";
53320
+ else if (existsSync25(join15(process.cwd(), "pyproject.toml")) || existsSync25(join15(process.cwd(), "setup.py"))) ecosystem = "pypi";
53599
53321
  else {
53600
53322
  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
53323
  process.exit(3);