@westbayberry/dg 1.0.60 → 1.0.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +1982 -727
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -6477,7 +6477,7 @@ var require_has_flag = __commonJS({
|
|
|
6477
6477
|
var require_supports_color = __commonJS({
|
|
6478
6478
|
"node_modules/supports-color/index.js"(exports, module2) {
|
|
6479
6479
|
"use strict";
|
|
6480
|
-
var
|
|
6480
|
+
var os5 = __require("os");
|
|
6481
6481
|
var tty2 = __require("tty");
|
|
6482
6482
|
var hasFlag2 = require_has_flag();
|
|
6483
6483
|
var { env: env3 } = process;
|
|
@@ -6525,7 +6525,7 @@ var require_supports_color = __commonJS({
|
|
|
6525
6525
|
return min;
|
|
6526
6526
|
}
|
|
6527
6527
|
if (process.platform === "win32") {
|
|
6528
|
-
const osRelease =
|
|
6528
|
+
const osRelease = os5.release().split(".");
|
|
6529
6529
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
6530
6530
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
6531
6531
|
}
|
|
@@ -6827,7 +6827,7 @@ var require_require_in_the_middle = __commonJS({
|
|
|
6827
6827
|
} else {
|
|
6828
6828
|
throw new Error("'require-in-the-middle' requires Node.js >=v9.3.0 or >=v8.10.0");
|
|
6829
6829
|
}
|
|
6830
|
-
var
|
|
6830
|
+
var normalize4 = /([/\\]index)?(\.js)?$/;
|
|
6831
6831
|
var ExportsCache = class {
|
|
6832
6832
|
constructor() {
|
|
6833
6833
|
this._localCache = /* @__PURE__ */ new Map();
|
|
@@ -7024,7 +7024,7 @@ var require_require_in_the_middle = __commonJS({
|
|
|
7024
7024
|
};
|
|
7025
7025
|
function resolveModuleName(stat) {
|
|
7026
7026
|
const normalizedPath = path3.sep !== "/" ? stat.path.split(path3.sep).join("/") : stat.path;
|
|
7027
|
-
return path3.posix.join(stat.name, normalizedPath).replace(
|
|
7027
|
+
return path3.posix.join(stat.name, normalizedPath).replace(normalize4, "");
|
|
7028
7028
|
}
|
|
7029
7029
|
}
|
|
7030
7030
|
});
|
|
@@ -23527,7 +23527,7 @@ var require_ProcessDetector = __commonJS({
|
|
|
23527
23527
|
exports.processDetector = void 0;
|
|
23528
23528
|
var api_1 = (init_esm(), __toCommonJS(esm_exports));
|
|
23529
23529
|
var semconv_1 = require_semconv3();
|
|
23530
|
-
var
|
|
23530
|
+
var os5 = __require("os");
|
|
23531
23531
|
var ProcessDetector = class {
|
|
23532
23532
|
detect(_config) {
|
|
23533
23533
|
const attributes = {
|
|
@@ -23547,7 +23547,7 @@ var require_ProcessDetector = __commonJS({
|
|
|
23547
23547
|
attributes[semconv_1.ATTR_PROCESS_COMMAND] = process.argv[1];
|
|
23548
23548
|
}
|
|
23549
23549
|
try {
|
|
23550
|
-
const userInfo =
|
|
23550
|
+
const userInfo = os5.userInfo();
|
|
23551
23551
|
attributes[semconv_1.ATTR_PROCESS_OWNER] = userInfo.username;
|
|
23552
23552
|
} catch (e) {
|
|
23553
23553
|
api_1.diag.debug(`error obtaining process owner: ${e}`);
|
|
@@ -26807,7 +26807,7 @@ var init_childProcess = __esm({
|
|
|
26807
26807
|
import { execFile } from "node:child_process";
|
|
26808
26808
|
import { readFile, readdir } from "node:fs";
|
|
26809
26809
|
import * as os from "node:os";
|
|
26810
|
-
import { join as
|
|
26810
|
+
import { join as join3 } from "node:path";
|
|
26811
26811
|
import { promisify } from "node:util";
|
|
26812
26812
|
function _updateContext(contexts) {
|
|
26813
26813
|
if (contexts.app?.app_memory) {
|
|
@@ -26935,7 +26935,7 @@ async function getLinuxInfo() {
|
|
|
26935
26935
|
if (!distroFile) {
|
|
26936
26936
|
return linuxInfo;
|
|
26937
26937
|
}
|
|
26938
|
-
const distroPath =
|
|
26938
|
+
const distroPath = join3("/etc", distroFile.name);
|
|
26939
26939
|
const contents = (await readFileAsync(distroPath, { encoding: "utf-8" })).toLowerCase();
|
|
26940
26940
|
const { distros } = distroFile;
|
|
26941
26941
|
linuxInfo.name = distros.find((d) => contents.indexOf(getLinuxDistroId(d)) >= 0) || distros[0];
|
|
@@ -27847,7 +27847,7 @@ var init_detection = __esm({
|
|
|
27847
27847
|
|
|
27848
27848
|
// node_modules/@sentry/node-core/build/esm/integrations/modules.js
|
|
27849
27849
|
import { existsSync, readFileSync } from "node:fs";
|
|
27850
|
-
import { dirname as dirname2, join as
|
|
27850
|
+
import { dirname as dirname2, join as join4 } from "node:path";
|
|
27851
27851
|
function getRequireCachePaths() {
|
|
27852
27852
|
try {
|
|
27853
27853
|
return __require.cache ? Object.keys(__require.cache) : [];
|
|
@@ -27878,7 +27878,7 @@ function collectRequireModules() {
|
|
|
27878
27878
|
if (mainPaths.indexOf(dir) < 0) {
|
|
27879
27879
|
return updir();
|
|
27880
27880
|
}
|
|
27881
|
-
const pkgfile =
|
|
27881
|
+
const pkgfile = join4(orig, "package.json");
|
|
27882
27882
|
seen.add(orig);
|
|
27883
27883
|
if (!existsSync(pkgfile)) {
|
|
27884
27884
|
return updir();
|
|
@@ -27901,7 +27901,7 @@ function _getModules() {
|
|
|
27901
27901
|
}
|
|
27902
27902
|
function getPackageJson() {
|
|
27903
27903
|
try {
|
|
27904
|
-
const filePath =
|
|
27904
|
+
const filePath = join4(process.cwd(), "package.json");
|
|
27905
27905
|
const packageJson = JSON.parse(readFileSync(filePath, "utf8"));
|
|
27906
27906
|
return packageJson;
|
|
27907
27907
|
} catch {
|
|
@@ -46158,16 +46158,8 @@ function initTelemetry(version) {
|
|
|
46158
46158
|
dsn: CLI_DSN,
|
|
46159
46159
|
release: `dg-cli@${version}`,
|
|
46160
46160
|
environment: process.env.CI ? "ci" : "local",
|
|
46161
|
-
// TODO: reduce sample rate when CLI usage exceeds ~10k DAU
|
|
46162
46161
|
sampleRate: 1,
|
|
46163
46162
|
sendDefaultPii: false,
|
|
46164
|
-
// Sentry's default Node integrations patch `fs`, which collides
|
|
46165
|
-
// with node-sqlite3-wasm's NODEFS layer — every Database open
|
|
46166
|
-
// returned "unable to open database file" and the local scan
|
|
46167
|
-
// cache stayed empty (0 rows even after thousands of scans).
|
|
46168
|
-
// Opt out of the default integrations entirely; we keep crash +
|
|
46169
|
-
// unhandled-rejection reporting via the two explicit integrations
|
|
46170
|
-
// below, which don't touch fs.
|
|
46171
46163
|
defaultIntegrations: false,
|
|
46172
46164
|
integrations: [
|
|
46173
46165
|
onUncaughtExceptionIntegration({ exitEvenIfOtherHandlersAreRegistered: false }),
|
|
@@ -46244,6 +46236,92 @@ var init_telemetry = __esm({
|
|
|
46244
46236
|
}
|
|
46245
46237
|
});
|
|
46246
46238
|
|
|
46239
|
+
// src/paths.ts
|
|
46240
|
+
import { homedir } from "node:os";
|
|
46241
|
+
import { join as join5, isAbsolute as isAbsolute2 } from "node:path";
|
|
46242
|
+
function safeAbsolute(p, fallback) {
|
|
46243
|
+
if (!p || typeof p !== "string") return fallback;
|
|
46244
|
+
if (!isAbsolute2(p)) return fallback;
|
|
46245
|
+
return p;
|
|
46246
|
+
}
|
|
46247
|
+
function dgRoot() {
|
|
46248
|
+
return join5(homedir(), `.${ROOT_DIR_NAME}`);
|
|
46249
|
+
}
|
|
46250
|
+
function dgConfigDir() {
|
|
46251
|
+
const xdg = safeAbsolute(process.env.XDG_CONFIG_HOME, "");
|
|
46252
|
+
if (xdg) return join5(xdg, ROOT_DIR_NAME);
|
|
46253
|
+
return dgRoot();
|
|
46254
|
+
}
|
|
46255
|
+
function dgCacheDir() {
|
|
46256
|
+
const explicit = safeAbsolute(process.env.DG_CACHE_DIR, "");
|
|
46257
|
+
if (explicit) return explicit;
|
|
46258
|
+
const xdg = safeAbsolute(process.env.XDG_CACHE_HOME, "");
|
|
46259
|
+
if (xdg) return join5(xdg, ROOT_DIR_NAME);
|
|
46260
|
+
return join5(dgRoot(), "cache");
|
|
46261
|
+
}
|
|
46262
|
+
function dgStateDir() {
|
|
46263
|
+
const xdg = safeAbsolute(process.env.XDG_STATE_HOME, "");
|
|
46264
|
+
if (xdg) return join5(xdg, ROOT_DIR_NAME);
|
|
46265
|
+
return join5(dgRoot(), "state");
|
|
46266
|
+
}
|
|
46267
|
+
function dgConfigPath() {
|
|
46268
|
+
return join5(dgConfigDir(), "config.json");
|
|
46269
|
+
}
|
|
46270
|
+
function dgCachePath(name) {
|
|
46271
|
+
return join5(dgCacheDir(), name);
|
|
46272
|
+
}
|
|
46273
|
+
function dgStatePath(name) {
|
|
46274
|
+
return join5(dgStateDir(), name);
|
|
46275
|
+
}
|
|
46276
|
+
function dgMigrationBreadcrumb() {
|
|
46277
|
+
return join5(dgRoot(), ".migrated-from-v1");
|
|
46278
|
+
}
|
|
46279
|
+
function dgMigrationLock() {
|
|
46280
|
+
return join5(dgRoot(), ".migration.lock");
|
|
46281
|
+
}
|
|
46282
|
+
function dgReadme() {
|
|
46283
|
+
return join5(dgRoot(), "README.txt");
|
|
46284
|
+
}
|
|
46285
|
+
function legacyPaths() {
|
|
46286
|
+
const home = homedir();
|
|
46287
|
+
const depGuardianDir = join5(home, ".dependency-guardian");
|
|
46288
|
+
return {
|
|
46289
|
+
dgrc: join5(home, ".dgrc.json"),
|
|
46290
|
+
cacheDir: depGuardianDir,
|
|
46291
|
+
cacheSqlite: join5(home, ".dg", "cache.sqlite"),
|
|
46292
|
+
routingHint: join5(home, ".dg", "scan-routing-hint.json"),
|
|
46293
|
+
updateCheck: join5(home, ".dg-update-check.json"),
|
|
46294
|
+
trialBannerOld: join5(depGuardianDir, "last-trial-banner"),
|
|
46295
|
+
aliasesShOld: join5(depGuardianDir, "aliases.sh"),
|
|
46296
|
+
depGuardianDir
|
|
46297
|
+
};
|
|
46298
|
+
}
|
|
46299
|
+
function dgPaths() {
|
|
46300
|
+
return {
|
|
46301
|
+
root: dgRoot(),
|
|
46302
|
+
configDir: dgConfigDir(),
|
|
46303
|
+
cacheDir: dgCacheDir(),
|
|
46304
|
+
stateDir: dgStateDir(),
|
|
46305
|
+
config: dgConfigPath(),
|
|
46306
|
+
cacheSqlite: dgCachePath("scans.sqlite"),
|
|
46307
|
+
updateCheck: dgCachePath("update-check.json"),
|
|
46308
|
+
routingHint: dgCachePath("routing-hint.json"),
|
|
46309
|
+
trialBanner: dgStatePath("trial-banner"),
|
|
46310
|
+
aliasesSh: dgStatePath("aliases.sh"),
|
|
46311
|
+
hooksRegistry: dgStatePath("hooks-installed.json"),
|
|
46312
|
+
readme: dgReadme(),
|
|
46313
|
+
migrationBreadcrumb: dgMigrationBreadcrumb(),
|
|
46314
|
+
migrationLock: dgMigrationLock()
|
|
46315
|
+
};
|
|
46316
|
+
}
|
|
46317
|
+
var ROOT_DIR_NAME;
|
|
46318
|
+
var init_paths = __esm({
|
|
46319
|
+
"src/paths.ts"() {
|
|
46320
|
+
"use strict";
|
|
46321
|
+
ROOT_DIR_NAME = "dg";
|
|
46322
|
+
}
|
|
46323
|
+
});
|
|
46324
|
+
|
|
46247
46325
|
// src/auth/auth.ts
|
|
46248
46326
|
var auth_exports = {};
|
|
46249
46327
|
__export(auth_exports, {
|
|
@@ -46274,9 +46352,8 @@ __export(auth_exports, {
|
|
|
46274
46352
|
scrubAuthToken: () => scrubAuthToken,
|
|
46275
46353
|
setProtectConfig: () => setProtectConfig
|
|
46276
46354
|
});
|
|
46277
|
-
import { readFileSync as readFileSync2, writeFileSync, unlinkSync, existsSync as existsSync2, chmodSync, lstatSync, openSync, fchmodSync, closeSync, constants as fsConstants } from "node:fs";
|
|
46278
|
-
import {
|
|
46279
|
-
import { homedir } from "node:os";
|
|
46355
|
+
import { readFileSync as readFileSync2, writeFileSync, unlinkSync, existsSync as existsSync2, mkdirSync, chmodSync, lstatSync, openSync, fchmodSync, closeSync, constants as fsConstants } from "node:fs";
|
|
46356
|
+
import { dirname as dirname3 } from "node:path";
|
|
46280
46357
|
import { spawn } from "node:child_process";
|
|
46281
46358
|
import { randomUUID } from "node:crypto";
|
|
46282
46359
|
function authBase() {
|
|
@@ -46354,7 +46431,13 @@ async function pollAuthSession(sessionId) {
|
|
|
46354
46431
|
};
|
|
46355
46432
|
}
|
|
46356
46433
|
function configPath() {
|
|
46357
|
-
return
|
|
46434
|
+
return dgConfigPath();
|
|
46435
|
+
}
|
|
46436
|
+
function ensureConfigDir() {
|
|
46437
|
+
const dir = dgConfigDir();
|
|
46438
|
+
if (!existsSync2(dir)) {
|
|
46439
|
+
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
46440
|
+
}
|
|
46358
46441
|
}
|
|
46359
46442
|
function ensureConfigPerms(path3) {
|
|
46360
46443
|
let st;
|
|
@@ -46416,7 +46499,19 @@ function readConfig() {
|
|
|
46416
46499
|
}
|
|
46417
46500
|
}
|
|
46418
46501
|
function writeDgrc(payload) {
|
|
46502
|
+
ensureConfigDir();
|
|
46419
46503
|
const p = configPath();
|
|
46504
|
+
const parent = dirname3(p);
|
|
46505
|
+
if (parent !== p) {
|
|
46506
|
+
try {
|
|
46507
|
+
const st = lstatSync(parent);
|
|
46508
|
+
if (st && typeof st.isSymbolicLink === "function" && st.isSymbolicLink()) {
|
|
46509
|
+
throw new Error(`refusing to write ${p}: parent ${parent} is a symlink`);
|
|
46510
|
+
}
|
|
46511
|
+
} catch (e) {
|
|
46512
|
+
if (e instanceof Error && e.message.startsWith("refusing")) throw e;
|
|
46513
|
+
}
|
|
46514
|
+
}
|
|
46420
46515
|
writeFileSync(p, JSON.stringify(payload, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
46421
46516
|
try {
|
|
46422
46517
|
chmodSync(p, 384);
|
|
@@ -46666,12 +46761,12 @@ function openBrowser(url) {
|
|
|
46666
46761
|
} catch {
|
|
46667
46762
|
}
|
|
46668
46763
|
}
|
|
46669
|
-
var DEFAULT_WEB_BASE,
|
|
46764
|
+
var DEFAULT_WEB_BASE, MAX_QUEUED_EVENTS;
|
|
46670
46765
|
var init_auth = __esm({
|
|
46671
46766
|
"src/auth/auth.ts"() {
|
|
46672
46767
|
"use strict";
|
|
46768
|
+
init_paths();
|
|
46673
46769
|
DEFAULT_WEB_BASE = "https://westbayberry.com";
|
|
46674
|
-
CONFIG_FILE = ".dgrc.json";
|
|
46675
46770
|
MAX_QUEUED_EVENTS = 50;
|
|
46676
46771
|
}
|
|
46677
46772
|
});
|
|
@@ -46687,9 +46782,8 @@ __export(config_exports, {
|
|
|
46687
46782
|
});
|
|
46688
46783
|
import { parseArgs } from "node:util";
|
|
46689
46784
|
import { readFileSync as readFileSync3, existsSync as existsSync3 } from "node:fs";
|
|
46690
|
-
import { join as
|
|
46785
|
+
import { join as join6, dirname as dirname4 } from "node:path";
|
|
46691
46786
|
import { fileURLToPath } from "node:url";
|
|
46692
|
-
import { homedir as homedir2 } from "node:os";
|
|
46693
46787
|
function levenshtein(a, b) {
|
|
46694
46788
|
if (a === b) return 0;
|
|
46695
46789
|
if (a.length === 0) return b.length;
|
|
@@ -46729,24 +46823,28 @@ function warnUnknownDgrcKeys(parsed, source) {
|
|
|
46729
46823
|
}
|
|
46730
46824
|
}
|
|
46731
46825
|
function loadDgrc() {
|
|
46732
|
-
const cwdPath =
|
|
46733
|
-
const homePath =
|
|
46826
|
+
const cwdPath = join6(process.cwd(), ".dgrc.json");
|
|
46827
|
+
const homePath = dgConfigPath();
|
|
46828
|
+
const legacyHomePath = legacyPaths().dgrc;
|
|
46734
46829
|
let config3 = {};
|
|
46735
|
-
|
|
46830
|
+
const sources = [homePath, legacyHomePath].filter((p, i, arr) => arr.indexOf(p) === i);
|
|
46831
|
+
for (const src of sources) {
|
|
46832
|
+
if (!existsSync3(src)) continue;
|
|
46736
46833
|
try {
|
|
46737
|
-
const
|
|
46738
|
-
warnUnknownDgrcKeys(
|
|
46739
|
-
const
|
|
46834
|
+
const data = JSON.parse(readFileSync3(src, "utf-8"));
|
|
46835
|
+
warnUnknownDgrcKeys(data, src);
|
|
46836
|
+
const filtered = {};
|
|
46740
46837
|
for (const k of KNOWN_DGRC_KEYS) {
|
|
46741
|
-
if (k in
|
|
46838
|
+
if (k in data) filtered[k] = data[k];
|
|
46742
46839
|
}
|
|
46743
|
-
config3 =
|
|
46840
|
+
config3 = filtered;
|
|
46841
|
+
break;
|
|
46744
46842
|
} catch {
|
|
46745
|
-
process.stderr.write(`Warning: Failed to parse ${
|
|
46843
|
+
process.stderr.write(`Warning: Failed to parse ${src}, ignoring.
|
|
46746
46844
|
`);
|
|
46747
46845
|
}
|
|
46748
46846
|
}
|
|
46749
|
-
if (existsSync3(cwdPath) && cwdPath !== homePath) {
|
|
46847
|
+
if (existsSync3(cwdPath) && cwdPath !== homePath && cwdPath !== legacyHomePath) {
|
|
46750
46848
|
try {
|
|
46751
46849
|
const cwd2 = JSON.parse(readFileSync3(cwdPath, "utf-8"));
|
|
46752
46850
|
warnUnknownDgrcKeys(cwd2, cwdPath);
|
|
@@ -46774,10 +46872,7 @@ function validateApiUrl(url) {
|
|
|
46774
46872
|
);
|
|
46775
46873
|
process.exit(1);
|
|
46776
46874
|
}
|
|
46777
|
-
const isLocal = host === "localhost" ||
|
|
46778
|
-
// which would wrongly accept `192.1680.0.1` or `100.1.2.3` (public).
|
|
46779
|
-
/^(127\.|10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.|100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\.)/.test(host) || // IPv6: loopback and unique local (fc00::/7 → fc** or fd**)
|
|
46780
|
-
host === "::1" || /^f[cd][0-9a-f]{2}:/i.test(host);
|
|
46875
|
+
const isLocal = host === "localhost" || /^(127\.|10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.|100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\.)/.test(host) || host === "::1" || /^f[cd][0-9a-f]{2}:/i.test(host);
|
|
46781
46876
|
if (parsed.protocol !== "https:" && !isLocal) {
|
|
46782
46877
|
process.stderr.write(`Error: API URL must use HTTPS (got ${parsed.protocol}). Use localhost for local testing.
|
|
46783
46878
|
`);
|
|
@@ -46792,9 +46887,9 @@ function validateApiUrl(url) {
|
|
|
46792
46887
|
}
|
|
46793
46888
|
function getVersion() {
|
|
46794
46889
|
try {
|
|
46795
|
-
const thisDir =
|
|
46890
|
+
const thisDir = dirname4(fileURLToPath(import.meta.url));
|
|
46796
46891
|
const pkg = JSON.parse(
|
|
46797
|
-
readFileSync3(
|
|
46892
|
+
readFileSync3(join6(thisDir, "..", "package.json"), "utf-8")
|
|
46798
46893
|
);
|
|
46799
46894
|
return pkg.version ?? "1.0.0";
|
|
46800
46895
|
} catch {
|
|
@@ -46825,7 +46920,6 @@ function parseConfig(argv, strictFlags = true) {
|
|
|
46825
46920
|
strict: { type: "boolean", default: false },
|
|
46826
46921
|
help: { type: "boolean", default: false },
|
|
46827
46922
|
version: { type: "boolean", default: false },
|
|
46828
|
-
// Recognized but handled server-side via policy dashboard
|
|
46829
46923
|
"no-config": { type: "boolean", default: false },
|
|
46830
46924
|
allowlist: { type: "string" },
|
|
46831
46925
|
"block-threshold": { type: "string" },
|
|
@@ -46905,6 +46999,7 @@ var init_config = __esm({
|
|
|
46905
46999
|
"src/config.ts"() {
|
|
46906
47000
|
"use strict";
|
|
46907
47001
|
init_auth();
|
|
47002
|
+
init_paths();
|
|
46908
47003
|
KNOWN_DGRC_KEYS = ["apiKey", "apiUrl", "mode", "maxPackages"];
|
|
46909
47004
|
INTERNAL_DGRC_KEYS = [
|
|
46910
47005
|
"deviceId",
|
|
@@ -46918,26 +47013,27 @@ var init_config = __esm({
|
|
|
46918
47013
|
USAGE = `
|
|
46919
47014
|
Dependency Guardian \u2014 Supply chain security scanner
|
|
46920
47015
|
|
|
46921
|
-
Get protected
|
|
46922
|
-
dg
|
|
46923
|
-
dg
|
|
47016
|
+
Get protected:
|
|
47017
|
+
dg init Set up this project (hook + protect + first scan)
|
|
47018
|
+
dg login Free account, higher scan limits
|
|
47019
|
+
dg protect Auto-scan on \`npm install\` / \`pip install\`
|
|
46924
47020
|
|
|
46925
47021
|
Common commands:
|
|
46926
47022
|
dg scan Audit this project's dependencies (read-only)
|
|
46927
47023
|
dg status Show your coverage at a glance
|
|
46928
|
-
dg protect Enable opt-in protection (stored in ~/.dgrc.json)
|
|
46929
|
-
dg protect off Disable protection
|
|
46930
47024
|
dg npm install <pkg> One-shot: scan + install a package
|
|
46931
47025
|
dg pip install <pkg> Same, for pip
|
|
46932
47026
|
dg hook install Block risky lockfile changes at commit time
|
|
46933
47027
|
dg login / dg logout Manage authentication
|
|
46934
47028
|
dg update Check for and install the latest dg version
|
|
47029
|
+
dg uninstall Remove everything dg has written locally
|
|
46935
47030
|
|
|
46936
47031
|
Common flags:
|
|
46937
47032
|
--json Machine-readable output (CI/scripts)
|
|
46938
47033
|
--quiet Suppress login + update nudges
|
|
46939
47034
|
--output, -o <file> Save scan result to a file (requires \`dg login\`)
|
|
46940
47035
|
|
|
47036
|
+
Local state lives in ~/.dg/.
|
|
46941
47037
|
Need more? Advanced flags + env vars: \`dg --help-all\`.
|
|
46942
47038
|
`.trimStart();
|
|
46943
47039
|
USAGE_ALL = `
|
|
@@ -46949,22 +47045,24 @@ var init_config = __esm({
|
|
|
46949
47045
|
dg pip install <pkg> [pip-flags]
|
|
46950
47046
|
|
|
46951
47047
|
Commands:
|
|
47048
|
+
init Fast per-project setup (hook + protect + first scan)
|
|
46952
47049
|
scan Read-only audit: scans the project's lockfiles + reports
|
|
46953
47050
|
npm Protective install wrapper for npm (default mode: BLOCK)
|
|
46954
47051
|
pip Protective install wrapper for pip (default mode: BLOCK)
|
|
46955
|
-
protect Enable opt-in low-friction protection (
|
|
46956
|
-
~/.
|
|
46957
|
-
by sourcing it)
|
|
47052
|
+
protect Enable opt-in low-friction protection (config under
|
|
47053
|
+
~/.dg/ + per-user shell-alias snippet
|
|
47054
|
+
\u2014 opt in by sourcing it)
|
|
46958
47055
|
protect off Disable protection in the current project
|
|
46959
47056
|
hook install Install git pre-commit hook to scan lockfile changes
|
|
46960
47057
|
hook uninstall Remove the pre-commit hook
|
|
46961
47058
|
login Authenticate with your WestBayBerry account
|
|
46962
47059
|
logout Remove saved credentials
|
|
46963
|
-
|
|
47060
|
+
uninstall Remove every file dg has written locally (config, cache,
|
|
47061
|
+
hooks across repos, shell-rc lines)
|
|
46964
47062
|
status Show coverage overview (auth, protect, hook, npm/pip, update)
|
|
46965
47063
|
update Check for and install the latest version
|
|
46966
47064
|
wrap Show instructions to alias npm to dg (manual)
|
|
46967
|
-
kitty Re-run the
|
|
47065
|
+
kitty Re-run the first-time intro tour
|
|
46968
47066
|
help Show short help (\`dg --help-all\` for this view)
|
|
46969
47067
|
version Show version number
|
|
46970
47068
|
|
|
@@ -47051,7 +47149,7 @@ __export(npm_wrapper_exports, {
|
|
|
47051
47149
|
});
|
|
47052
47150
|
import { spawn as spawn2 } from "node:child_process";
|
|
47053
47151
|
import { readFileSync as readFileSync4, existsSync as existsSync4, mkdtempSync, writeFileSync as writeFileSync2, rmSync } from "node:fs";
|
|
47054
|
-
import { join as
|
|
47152
|
+
import { join as join7 } from "node:path";
|
|
47055
47153
|
import { tmpdir } from "node:os";
|
|
47056
47154
|
function parseNpmArgs(args) {
|
|
47057
47155
|
let dgForce = false;
|
|
@@ -47260,9 +47358,9 @@ async function resolveTreeNpm(specs) {
|
|
|
47260
47358
|
if (safe.length === 0) {
|
|
47261
47359
|
return { packages: [], ok: false, errorMessage: "all specs were flag-shaped (refused)" };
|
|
47262
47360
|
}
|
|
47263
|
-
const dir = mkdtempSync(
|
|
47361
|
+
const dir = mkdtempSync(join7(tmpdir(), "dg-resolve-"));
|
|
47264
47362
|
try {
|
|
47265
|
-
writeFileSync2(
|
|
47363
|
+
writeFileSync2(join7(dir, "package.json"), '{"name":"_dg_resolve","version":"1.0.0","private":true}');
|
|
47266
47364
|
const stdout = await new Promise((resolve3) => {
|
|
47267
47365
|
const child = spawn2(
|
|
47268
47366
|
"npm",
|
|
@@ -47342,7 +47440,7 @@ function pinTopLevelArgs(rawArgs, userSpecs, tree) {
|
|
|
47342
47440
|
});
|
|
47343
47441
|
}
|
|
47344
47442
|
function readLockfilePins(cwd2) {
|
|
47345
|
-
const lockPath =
|
|
47443
|
+
const lockPath = join7(cwd2, "package-lock.json");
|
|
47346
47444
|
if (!existsSync4(lockPath)) return null;
|
|
47347
47445
|
try {
|
|
47348
47446
|
const lock = JSON.parse(readFileSync4(lockPath, "utf-8"));
|
|
@@ -47372,7 +47470,7 @@ function readBareInstallPackages(cwd2) {
|
|
|
47372
47470
|
return readBareInstallPackagesTyped(cwd2).map((s) => s.spec);
|
|
47373
47471
|
}
|
|
47374
47472
|
function readBareInstallPackagesTyped(cwd2) {
|
|
47375
|
-
const pkgPath =
|
|
47473
|
+
const pkgPath = join7(cwd2, "package.json");
|
|
47376
47474
|
if (!existsSync4(pkgPath)) return [];
|
|
47377
47475
|
try {
|
|
47378
47476
|
const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
|
|
@@ -48645,14 +48743,14 @@ var require_templates = __commonJS({
|
|
|
48645
48743
|
}
|
|
48646
48744
|
return results;
|
|
48647
48745
|
}
|
|
48648
|
-
function buildStyle(
|
|
48746
|
+
function buildStyle(chalk17, styles8) {
|
|
48649
48747
|
const enabled = {};
|
|
48650
48748
|
for (const layer of styles8) {
|
|
48651
48749
|
for (const style of layer.styles) {
|
|
48652
48750
|
enabled[style[0]] = layer.inverse ? null : style.slice(1);
|
|
48653
48751
|
}
|
|
48654
48752
|
}
|
|
48655
|
-
let current =
|
|
48753
|
+
let current = chalk17;
|
|
48656
48754
|
for (const [styleName, styles9] of Object.entries(enabled)) {
|
|
48657
48755
|
if (!Array.isArray(styles9)) {
|
|
48658
48756
|
continue;
|
|
@@ -48664,7 +48762,7 @@ var require_templates = __commonJS({
|
|
|
48664
48762
|
}
|
|
48665
48763
|
return current;
|
|
48666
48764
|
}
|
|
48667
|
-
module2.exports = (
|
|
48765
|
+
module2.exports = (chalk17, temporary) => {
|
|
48668
48766
|
const styles8 = [];
|
|
48669
48767
|
const chunks = [];
|
|
48670
48768
|
let chunk = [];
|
|
@@ -48674,13 +48772,13 @@ var require_templates = __commonJS({
|
|
|
48674
48772
|
} else if (style) {
|
|
48675
48773
|
const string = chunk.join("");
|
|
48676
48774
|
chunk = [];
|
|
48677
|
-
chunks.push(styles8.length === 0 ? string : buildStyle(
|
|
48775
|
+
chunks.push(styles8.length === 0 ? string : buildStyle(chalk17, styles8)(string));
|
|
48678
48776
|
styles8.push({ inverse, styles: parseStyle(style) });
|
|
48679
48777
|
} else if (close2) {
|
|
48680
48778
|
if (styles8.length === 0) {
|
|
48681
48779
|
throw new Error("Found extraneous } in Chalk template literal");
|
|
48682
48780
|
}
|
|
48683
|
-
chunks.push(buildStyle(
|
|
48781
|
+
chunks.push(buildStyle(chalk17, styles8)(chunk.join("")));
|
|
48684
48782
|
chunk = [];
|
|
48685
48783
|
styles8.pop();
|
|
48686
48784
|
} else {
|
|
@@ -48728,16 +48826,16 @@ var require_source = __commonJS({
|
|
|
48728
48826
|
}
|
|
48729
48827
|
};
|
|
48730
48828
|
var chalkFactory2 = (options) => {
|
|
48731
|
-
const
|
|
48732
|
-
applyOptions2(
|
|
48733
|
-
|
|
48734
|
-
Object.setPrototypeOf(
|
|
48735
|
-
Object.setPrototypeOf(
|
|
48736
|
-
|
|
48829
|
+
const chalk18 = {};
|
|
48830
|
+
applyOptions2(chalk18, options);
|
|
48831
|
+
chalk18.template = (...arguments_) => chalkTag(chalk18.template, ...arguments_);
|
|
48832
|
+
Object.setPrototypeOf(chalk18, Chalk.prototype);
|
|
48833
|
+
Object.setPrototypeOf(chalk18.template, chalk18);
|
|
48834
|
+
chalk18.template.constructor = () => {
|
|
48737
48835
|
throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
|
|
48738
48836
|
};
|
|
48739
|
-
|
|
48740
|
-
return
|
|
48837
|
+
chalk18.template.Instance = ChalkClass;
|
|
48838
|
+
return chalk18.template;
|
|
48741
48839
|
};
|
|
48742
48840
|
function Chalk(options) {
|
|
48743
48841
|
return chalkFactory2(options);
|
|
@@ -48848,7 +48946,7 @@ var require_source = __commonJS({
|
|
|
48848
48946
|
return openAll + string + closeAll;
|
|
48849
48947
|
};
|
|
48850
48948
|
var template;
|
|
48851
|
-
var chalkTag = (
|
|
48949
|
+
var chalkTag = (chalk18, ...strings) => {
|
|
48852
48950
|
const [firstString] = strings;
|
|
48853
48951
|
if (!isArray(firstString) || !isArray(firstString.raw)) {
|
|
48854
48952
|
return strings.join(" ");
|
|
@@ -48864,25 +48962,27 @@ var require_source = __commonJS({
|
|
|
48864
48962
|
if (template === void 0) {
|
|
48865
48963
|
template = require_templates();
|
|
48866
48964
|
}
|
|
48867
|
-
return template(
|
|
48965
|
+
return template(chalk18, parts.join(""));
|
|
48868
48966
|
};
|
|
48869
48967
|
Object.defineProperties(Chalk.prototype, styles8);
|
|
48870
|
-
var
|
|
48871
|
-
|
|
48872
|
-
|
|
48873
|
-
|
|
48874
|
-
module2.exports =
|
|
48968
|
+
var chalk17 = Chalk();
|
|
48969
|
+
chalk17.supportsColor = stdoutColor2;
|
|
48970
|
+
chalk17.stderr = Chalk({ level: stderrColor2 ? stderrColor2.level : 0 });
|
|
48971
|
+
chalk17.stderr.supportsColor = stderrColor2;
|
|
48972
|
+
module2.exports = chalk17;
|
|
48875
48973
|
}
|
|
48876
48974
|
});
|
|
48877
48975
|
|
|
48878
48976
|
// src/update-check.ts
|
|
48879
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "node:fs";
|
|
48880
|
-
import {
|
|
48881
|
-
import { join as join7 } from "node:path";
|
|
48977
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "node:fs";
|
|
48978
|
+
import { dirname as dirname5 } from "node:path";
|
|
48882
48979
|
import { execFileSync } from "node:child_process";
|
|
48980
|
+
function cacheFile() {
|
|
48981
|
+
return dgCachePath("update-check.json");
|
|
48982
|
+
}
|
|
48883
48983
|
function readCache() {
|
|
48884
48984
|
try {
|
|
48885
|
-
const raw = readFileSync5(
|
|
48985
|
+
const raw = readFileSync5(cacheFile(), "utf-8");
|
|
48886
48986
|
const data = JSON.parse(raw);
|
|
48887
48987
|
if (typeof data.latest === "string" && typeof data.checkedAt === "number") {
|
|
48888
48988
|
return data;
|
|
@@ -48893,7 +48993,10 @@ function readCache() {
|
|
|
48893
48993
|
}
|
|
48894
48994
|
function writeCache(entry) {
|
|
48895
48995
|
try {
|
|
48896
|
-
|
|
48996
|
+
const path3 = cacheFile();
|
|
48997
|
+
const parent = dirname5(path3);
|
|
48998
|
+
if (!existsSync5(parent)) mkdirSync2(parent, { recursive: true, mode: 448 });
|
|
48999
|
+
writeFileSync3(path3, JSON.stringify(entry), "utf-8");
|
|
48897
49000
|
} catch {
|
|
48898
49001
|
}
|
|
48899
49002
|
}
|
|
@@ -48954,45 +49057,45 @@ async function checkForUpdate(currentVersion) {
|
|
|
48954
49057
|
return null;
|
|
48955
49058
|
}
|
|
48956
49059
|
async function runUpdate(currentVersion) {
|
|
48957
|
-
const
|
|
48958
|
-
process.stderr.write(
|
|
49060
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
49061
|
+
process.stderr.write(chalk17.dim(" Checking for updates...\n"));
|
|
48959
49062
|
const latest = await fetchLatestVersion();
|
|
48960
49063
|
if (!latest) {
|
|
48961
|
-
process.stderr.write(
|
|
49064
|
+
process.stderr.write(chalk17.red(" Could not reach npm registry.\n"));
|
|
48962
49065
|
process.exit(1);
|
|
48963
49066
|
}
|
|
48964
49067
|
if (!isNewer(latest, currentVersion)) {
|
|
48965
49068
|
process.stderr.write(
|
|
48966
|
-
|
|
49069
|
+
chalk17.green(` Already on latest version (${currentVersion}).
|
|
48967
49070
|
`)
|
|
48968
49071
|
);
|
|
48969
49072
|
return;
|
|
48970
49073
|
}
|
|
48971
|
-
process.stderr.write(
|
|
49074
|
+
process.stderr.write(chalk17.dim(` Installing ${PKG_NAME}@${latest}...
|
|
48972
49075
|
`));
|
|
48973
49076
|
try {
|
|
48974
49077
|
execFileSync("npm", ["install", "-g", `${PKG_NAME}@${latest}`], { stdio: "inherit" });
|
|
48975
49078
|
writeCache({ latest, checkedAt: Date.now() });
|
|
48976
49079
|
process.stderr.write(
|
|
48977
|
-
|
|
49080
|
+
chalk17.green(`
|
|
48978
49081
|
Updated ${currentVersion} \u2192 ${latest}
|
|
48979
49082
|
`)
|
|
48980
49083
|
);
|
|
48981
49084
|
} catch {
|
|
48982
49085
|
process.stderr.write(
|
|
48983
|
-
|
|
49086
|
+
chalk17.red(`
|
|
48984
49087
|
Update failed. Try manually: npm i -g ${PKG_NAME}@${latest}
|
|
48985
49088
|
`)
|
|
48986
49089
|
);
|
|
48987
49090
|
process.exit(1);
|
|
48988
49091
|
}
|
|
48989
49092
|
}
|
|
48990
|
-
var PKG_NAME,
|
|
49093
|
+
var PKG_NAME, CHECK_INTERVAL_MS;
|
|
48991
49094
|
var init_update_check = __esm({
|
|
48992
49095
|
"src/update-check.ts"() {
|
|
48993
49096
|
"use strict";
|
|
49097
|
+
init_paths();
|
|
48994
49098
|
PKG_NAME = "@westbayberry/dg";
|
|
48995
|
-
CACHE_FILE = join7(homedir3(), ".dg-update-check.json");
|
|
48996
49099
|
CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
48997
49100
|
}
|
|
48998
49101
|
});
|
|
@@ -49961,12 +50064,12 @@ var require_react_development = __commonJS({
|
|
|
49961
50064
|
var SEPARATOR = ".";
|
|
49962
50065
|
var SUBSEPARATOR = ":";
|
|
49963
50066
|
function escape2(key) {
|
|
49964
|
-
var
|
|
50067
|
+
var escapeRegex2 = /[=:]/g;
|
|
49965
50068
|
var escaperLookup = {
|
|
49966
50069
|
"=": "=0",
|
|
49967
50070
|
":": "=2"
|
|
49968
50071
|
};
|
|
49969
|
-
var escapedString = key.replace(
|
|
50072
|
+
var escapedString = key.replace(escapeRegex2, function(match) {
|
|
49970
50073
|
return escaperLookup[match];
|
|
49971
50074
|
});
|
|
49972
50075
|
return "$" + escapedString;
|
|
@@ -79989,10 +80092,10 @@ var init_source = __esm({
|
|
|
79989
80092
|
object.level = options.level === void 0 ? colorLevel : options.level;
|
|
79990
80093
|
};
|
|
79991
80094
|
chalkFactory = (options) => {
|
|
79992
|
-
const
|
|
79993
|
-
applyOptions(
|
|
79994
|
-
Object.setPrototypeOf(
|
|
79995
|
-
return
|
|
80095
|
+
const chalk17 = (...strings) => strings.join(" ");
|
|
80096
|
+
applyOptions(chalk17, options);
|
|
80097
|
+
Object.setPrototypeOf(chalk17, createChalk.prototype);
|
|
80098
|
+
return chalk17;
|
|
79996
80099
|
};
|
|
79997
80100
|
Object.setPrototypeOf(createChalk.prototype, Function.prototype);
|
|
79998
80101
|
for (const [styleName, style] of Object.entries(ansi_styles_default3)) {
|
|
@@ -83078,22 +83181,18 @@ var init_skip_list = __esm({
|
|
|
83078
83181
|
"src/discover/skip-list.ts"() {
|
|
83079
83182
|
"use strict";
|
|
83080
83183
|
SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
83081
|
-
// Package caches
|
|
83082
83184
|
"node_modules",
|
|
83083
83185
|
".venv",
|
|
83084
83186
|
"venv",
|
|
83085
83187
|
"__pycache__",
|
|
83086
83188
|
"vendor",
|
|
83087
83189
|
"bower_components",
|
|
83088
|
-
// VCS + tooling
|
|
83089
83190
|
".git",
|
|
83090
83191
|
".tox",
|
|
83091
83192
|
".eggs",
|
|
83092
|
-
// Build outputs
|
|
83093
83193
|
"dist",
|
|
83094
83194
|
"build",
|
|
83095
83195
|
"target",
|
|
83096
|
-
// target: Rust + Java
|
|
83097
83196
|
".next",
|
|
83098
83197
|
".nuxt",
|
|
83099
83198
|
".turbo",
|
|
@@ -83102,24 +83201,17 @@ var init_skip_list = __esm({
|
|
|
83102
83201
|
".parcel-cache",
|
|
83103
83202
|
".gradle",
|
|
83104
83203
|
".terraform",
|
|
83105
|
-
// Test caches
|
|
83106
83204
|
"coverage",
|
|
83107
83205
|
".cache",
|
|
83108
83206
|
".pytest_cache",
|
|
83109
83207
|
".mypy_cache",
|
|
83110
|
-
// Project-local: validation outputs, fixture sandboxes, archives,
|
|
83111
|
-
// and temp scratch (no project lives inside a tmp dir; corpus dumps
|
|
83112
|
-
// for validation runs frequently land in tmp subtrees with 100k+
|
|
83113
|
-
// entries that lock the walker on their readdir).
|
|
83114
83208
|
"validation-results",
|
|
83115
83209
|
"test-fixtures",
|
|
83116
83210
|
"fixtures",
|
|
83117
83211
|
"archive",
|
|
83118
83212
|
"tmp",
|
|
83119
83213
|
"temp",
|
|
83120
|
-
// Vendored Ansible collections (WBB monorepo specific; harmless on others)
|
|
83121
83214
|
"ansible_collections",
|
|
83122
|
-
// IDE / editor
|
|
83123
83215
|
".idea",
|
|
83124
83216
|
".vscode"
|
|
83125
83217
|
]);
|
|
@@ -83220,7 +83312,7 @@ async function discoverProjectsAsync(root, opts = {}) {
|
|
|
83220
83312
|
const nonEmpty = projects.filter((p) => p.packageCount > 0);
|
|
83221
83313
|
return nonEmpty.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
83222
83314
|
}
|
|
83223
|
-
function discoverProjects(
|
|
83315
|
+
function discoverProjects(_root) {
|
|
83224
83316
|
throw new Error(
|
|
83225
83317
|
"discoverProjects (sync) is no longer implemented. Use `await discoverProjectsAsync(root)` instead. See dependency-guardian/cli/src/discover/walker.ts."
|
|
83226
83318
|
);
|
|
@@ -83283,27 +83375,137 @@ var init_walker = __esm({
|
|
|
83283
83375
|
}
|
|
83284
83376
|
});
|
|
83285
83377
|
|
|
83378
|
+
// src/state/hooks_registry.ts
|
|
83379
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync5, chmodSync as chmodSync3 } from "node:fs";
|
|
83380
|
+
import { dirname as dirname7, isAbsolute as isAbsolute3, normalize as normalize2 } from "node:path";
|
|
83381
|
+
import { homedir as homedir2 } from "node:os";
|
|
83382
|
+
function registryPath() {
|
|
83383
|
+
return dgStatePath("hooks-installed.json");
|
|
83384
|
+
}
|
|
83385
|
+
function isSafeAbsolute(p) {
|
|
83386
|
+
if (typeof p !== "string" || p.length === 0) return false;
|
|
83387
|
+
if (!isAbsolute3(p)) return false;
|
|
83388
|
+
if (p.includes("\0")) return false;
|
|
83389
|
+
if (p.split("/").some((seg) => seg === "..")) return false;
|
|
83390
|
+
if (normalize2(p) !== p) return false;
|
|
83391
|
+
return true;
|
|
83392
|
+
}
|
|
83393
|
+
function isWithinHomeOrTmp(p) {
|
|
83394
|
+
const home = homedir2();
|
|
83395
|
+
if (p === home || p.startsWith(home + "/")) return true;
|
|
83396
|
+
const rawTmp = process.env.TMPDIR || "/tmp";
|
|
83397
|
+
const tmpdir2 = rawTmp.endsWith("/") ? rawTmp.slice(0, -1) : rawTmp;
|
|
83398
|
+
if (p === tmpdir2 || p.startsWith(tmpdir2 + "/")) return true;
|
|
83399
|
+
if (p === "/tmp" || p.startsWith("/tmp/")) return true;
|
|
83400
|
+
if (p === "/private/tmp" || p.startsWith("/private/tmp/")) return true;
|
|
83401
|
+
if (p.startsWith("/private/var/")) return true;
|
|
83402
|
+
return false;
|
|
83403
|
+
}
|
|
83404
|
+
function validateEntry(raw) {
|
|
83405
|
+
if (!raw || typeof raw !== "object") return null;
|
|
83406
|
+
const o = raw;
|
|
83407
|
+
if (!isSafeAbsolute(o.repoPath)) return null;
|
|
83408
|
+
if (!isSafeAbsolute(o.hookPath)) return null;
|
|
83409
|
+
if (!isWithinHomeOrTmp(o.repoPath)) return null;
|
|
83410
|
+
if (!isWithinHomeOrTmp(o.hookPath)) return null;
|
|
83411
|
+
if (o.framework !== "husky" && o.framework !== "lefthook" && o.framework !== "bare") return null;
|
|
83412
|
+
if (typeof o.installedAt !== "string" || o.installedAt.length === 0) return null;
|
|
83413
|
+
return {
|
|
83414
|
+
repoPath: o.repoPath,
|
|
83415
|
+
framework: o.framework,
|
|
83416
|
+
hookPath: o.hookPath,
|
|
83417
|
+
installedAt: o.installedAt
|
|
83418
|
+
};
|
|
83419
|
+
}
|
|
83420
|
+
function readRegistry() {
|
|
83421
|
+
const path3 = registryPath();
|
|
83422
|
+
if (!existsSync8(path3)) return [];
|
|
83423
|
+
let raw;
|
|
83424
|
+
try {
|
|
83425
|
+
raw = readFileSync8(path3, "utf-8");
|
|
83426
|
+
} catch {
|
|
83427
|
+
return [];
|
|
83428
|
+
}
|
|
83429
|
+
let parsed;
|
|
83430
|
+
try {
|
|
83431
|
+
parsed = JSON.parse(raw);
|
|
83432
|
+
} catch {
|
|
83433
|
+
return [];
|
|
83434
|
+
}
|
|
83435
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return [];
|
|
83436
|
+
const file = parsed;
|
|
83437
|
+
if (file.version !== 1 || !Array.isArray(file.entries)) return [];
|
|
83438
|
+
const out = [];
|
|
83439
|
+
for (const e of file.entries) {
|
|
83440
|
+
const v = validateEntry(e);
|
|
83441
|
+
if (v) out.push(v);
|
|
83442
|
+
}
|
|
83443
|
+
return out;
|
|
83444
|
+
}
|
|
83445
|
+
function writeRegistry(entries) {
|
|
83446
|
+
const path3 = registryPath();
|
|
83447
|
+
const parent = dirname7(path3);
|
|
83448
|
+
if (!existsSync8(parent)) mkdirSync4(parent, { recursive: true, mode: 448 });
|
|
83449
|
+
const payload = { version: 1, entries };
|
|
83450
|
+
writeFileSync5(path3, JSON.stringify(payload, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
83451
|
+
try {
|
|
83452
|
+
chmodSync3(path3, 384);
|
|
83453
|
+
} catch {
|
|
83454
|
+
}
|
|
83455
|
+
}
|
|
83456
|
+
function sameEntry(a, b) {
|
|
83457
|
+
return a.repoPath === b.repoPath && a.hookPath === b.hookPath;
|
|
83458
|
+
}
|
|
83459
|
+
function addEntry(entry) {
|
|
83460
|
+
if (!isSafeAbsolute(entry.repoPath) || !isWithinHomeOrTmp(entry.repoPath)) return;
|
|
83461
|
+
if (!isSafeAbsolute(entry.hookPath) || !isWithinHomeOrTmp(entry.hookPath)) return;
|
|
83462
|
+
const next = { ...entry, installedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
83463
|
+
const existing = readRegistry();
|
|
83464
|
+
const filtered = existing.filter((e) => !sameEntry(e, next));
|
|
83465
|
+
filtered.push(next);
|
|
83466
|
+
writeRegistry(filtered);
|
|
83467
|
+
}
|
|
83468
|
+
function removeEntry(repoPath, hookPath) {
|
|
83469
|
+
const existing = readRegistry();
|
|
83470
|
+
const filtered = existing.filter((e) => !(e.repoPath === repoPath && e.hookPath === hookPath));
|
|
83471
|
+
if (filtered.length === existing.length) return false;
|
|
83472
|
+
writeRegistry(filtered);
|
|
83473
|
+
return true;
|
|
83474
|
+
}
|
|
83475
|
+
function listEntries() {
|
|
83476
|
+
return readRegistry();
|
|
83477
|
+
}
|
|
83478
|
+
var init_hooks_registry = __esm({
|
|
83479
|
+
"src/state/hooks_registry.ts"() {
|
|
83480
|
+
"use strict";
|
|
83481
|
+
init_paths();
|
|
83482
|
+
}
|
|
83483
|
+
});
|
|
83484
|
+
|
|
83286
83485
|
// src/commands/hook.ts
|
|
83287
83486
|
var hook_exports = {};
|
|
83288
83487
|
__export(hook_exports, {
|
|
83289
83488
|
detectHookFramework: () => detectHookFramework,
|
|
83290
83489
|
handleHookCommand: () => handleHookCommand,
|
|
83291
83490
|
installHookForFramework: () => installHookForFramework,
|
|
83292
|
-
previewHookInstall: () => previewHookInstall
|
|
83491
|
+
previewHookInstall: () => previewHookInstall,
|
|
83492
|
+
stripDgFromHookFile: () => stripDgFromHookFile,
|
|
83493
|
+
uninstallHookFromRepo: () => uninstallHookFromRepo,
|
|
83494
|
+
verifyHookInstalled: () => verifyHookInstalled
|
|
83293
83495
|
});
|
|
83294
83496
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
83295
83497
|
import {
|
|
83296
|
-
existsSync as
|
|
83498
|
+
existsSync as existsSync9,
|
|
83297
83499
|
lstatSync as lstatSync2,
|
|
83298
|
-
readFileSync as
|
|
83299
|
-
writeFileSync as
|
|
83300
|
-
mkdirSync,
|
|
83301
|
-
chmodSync as
|
|
83302
|
-
unlinkSync as
|
|
83500
|
+
readFileSync as readFileSync9,
|
|
83501
|
+
writeFileSync as writeFileSync6,
|
|
83502
|
+
mkdirSync as mkdirSync5,
|
|
83503
|
+
chmodSync as chmodSync4,
|
|
83504
|
+
unlinkSync as unlinkSync3
|
|
83303
83505
|
} from "node:fs";
|
|
83304
|
-
import { join as join9, dirname as
|
|
83506
|
+
import { join as join9, dirname as dirname8, resolve as resolvePath, isAbsolute as isAbsolute4 } from "node:path";
|
|
83305
83507
|
function assertSafeWriteTarget(target) {
|
|
83306
|
-
const parent =
|
|
83508
|
+
const parent = dirname8(target);
|
|
83307
83509
|
try {
|
|
83308
83510
|
const parentStat = lstatSync2(parent);
|
|
83309
83511
|
if (parentStat.isSymbolicLink()) {
|
|
@@ -83331,7 +83533,7 @@ function assertSafeWriteTarget(target) {
|
|
|
83331
83533
|
}
|
|
83332
83534
|
function safeWriteFileSync(target, content) {
|
|
83333
83535
|
assertSafeWriteTarget(target);
|
|
83334
|
-
|
|
83536
|
+
writeFileSync6(target, content);
|
|
83335
83537
|
}
|
|
83336
83538
|
function findHooksDir() {
|
|
83337
83539
|
try {
|
|
@@ -83360,8 +83562,8 @@ function detectHookFramework(repoRoot) {
|
|
|
83360
83562
|
const lefthookConfigYaml = join9(root, "lefthook.yaml");
|
|
83361
83563
|
const hooksDir = findHooksDir();
|
|
83362
83564
|
const bareHook = join9(hooksDir, "pre-commit");
|
|
83363
|
-
if (
|
|
83364
|
-
const content =
|
|
83565
|
+
if (existsSync9(huskyHook)) {
|
|
83566
|
+
const content = readFileSync9(huskyHook, "utf-8");
|
|
83365
83567
|
return {
|
|
83366
83568
|
framework: "husky",
|
|
83367
83569
|
targetFile: huskyHook,
|
|
@@ -83369,8 +83571,8 @@ function detectHookFramework(repoRoot) {
|
|
|
83369
83571
|
};
|
|
83370
83572
|
}
|
|
83371
83573
|
for (const cfg of [lefthookConfig, lefthookConfigYaml]) {
|
|
83372
|
-
if (
|
|
83373
|
-
const content =
|
|
83574
|
+
if (existsSync9(cfg)) {
|
|
83575
|
+
const content = readFileSync9(cfg, "utf-8");
|
|
83374
83576
|
const installed2 = /^\s+dependency-guardian\s*:/m.test(content);
|
|
83375
83577
|
return {
|
|
83376
83578
|
framework: "lefthook",
|
|
@@ -83380,8 +83582,8 @@ function detectHookFramework(repoRoot) {
|
|
|
83380
83582
|
}
|
|
83381
83583
|
}
|
|
83382
83584
|
let installed = false;
|
|
83383
|
-
if (
|
|
83384
|
-
installed =
|
|
83585
|
+
if (existsSync9(bareHook)) {
|
|
83586
|
+
installed = readFileSync9(bareHook, "utf-8").includes(HOOK_MARKER);
|
|
83385
83587
|
}
|
|
83386
83588
|
return {
|
|
83387
83589
|
framework: "bare",
|
|
@@ -83389,6 +83591,37 @@ function detectHookFramework(repoRoot) {
|
|
|
83389
83591
|
alreadyInstalled: installed
|
|
83390
83592
|
};
|
|
83391
83593
|
}
|
|
83594
|
+
function verifyHookInstalled(info) {
|
|
83595
|
+
if (!existsSync9(info.targetFile)) {
|
|
83596
|
+
return { ok: false, reason: `hook file missing: ${info.targetFile}` };
|
|
83597
|
+
}
|
|
83598
|
+
let content;
|
|
83599
|
+
try {
|
|
83600
|
+
content = readFileSync9(info.targetFile, "utf-8");
|
|
83601
|
+
} catch (e) {
|
|
83602
|
+
return { ok: false, reason: `cannot read ${info.targetFile}: ${e.message}` };
|
|
83603
|
+
}
|
|
83604
|
+
if (info.framework === "lefthook") {
|
|
83605
|
+
if (!/^\s+dependency-guardian\s*:/m.test(content)) {
|
|
83606
|
+
return { ok: false, reason: `lefthook entry missing in ${info.targetFile}` };
|
|
83607
|
+
}
|
|
83608
|
+
return { ok: true };
|
|
83609
|
+
}
|
|
83610
|
+
if (!content.includes(HOOK_MARKER)) {
|
|
83611
|
+
return { ok: false, reason: `hook marker missing in ${info.targetFile}` };
|
|
83612
|
+
}
|
|
83613
|
+
if (info.framework === "bare" || info.framework === "husky") {
|
|
83614
|
+
try {
|
|
83615
|
+
const mode = lstatSync2(info.targetFile).mode & 511;
|
|
83616
|
+
if ((mode & 73) === 0) {
|
|
83617
|
+
return { ok: false, reason: `hook is not executable (mode ${mode.toString(8)})` };
|
|
83618
|
+
}
|
|
83619
|
+
} catch (e) {
|
|
83620
|
+
return { ok: false, reason: `cannot stat ${info.targetFile}: ${e.message}` };
|
|
83621
|
+
}
|
|
83622
|
+
}
|
|
83623
|
+
return { ok: true };
|
|
83624
|
+
}
|
|
83392
83625
|
function previewHookInstall(info) {
|
|
83393
83626
|
if (info.alreadyInstalled) {
|
|
83394
83627
|
return `(already installed in ${info.targetFile} \u2014 no changes needed)`;
|
|
@@ -83402,7 +83635,7 @@ ${HUSKY_SNIPPET}`;
|
|
|
83402
83635
|
|
|
83403
83636
|
${LEFTHOOK_ENTRY}`;
|
|
83404
83637
|
case "bare":
|
|
83405
|
-
if (
|
|
83638
|
+
if (existsSync9(info.targetFile)) {
|
|
83406
83639
|
return `Will append to existing hook at ${info.targetFile}:
|
|
83407
83640
|
${HOOK_SECTION}`;
|
|
83408
83641
|
}
|
|
@@ -83411,21 +83644,21 @@ ${HOOK_SCRIPT}`;
|
|
|
83411
83644
|
}
|
|
83412
83645
|
}
|
|
83413
83646
|
function installHuskyHook(targetFile) {
|
|
83414
|
-
const existing =
|
|
83647
|
+
const existing = readFileSync9(targetFile, "utf-8");
|
|
83415
83648
|
if (existing.includes(HOOK_MARKER)) {
|
|
83416
83649
|
process.stderr.write(" Hook already installed in Husky.\n");
|
|
83417
83650
|
return;
|
|
83418
83651
|
}
|
|
83419
83652
|
safeWriteFileSync(targetFile, existing.trimEnd() + "\n" + HUSKY_SNIPPET);
|
|
83420
83653
|
try {
|
|
83421
|
-
|
|
83654
|
+
chmodSync4(targetFile, 493);
|
|
83422
83655
|
} catch {
|
|
83423
83656
|
}
|
|
83424
83657
|
process.stderr.write(` Appended Dependency Guardian to ${targetFile}
|
|
83425
83658
|
`);
|
|
83426
83659
|
}
|
|
83427
83660
|
function installLefthookHook(targetFile) {
|
|
83428
|
-
const existing =
|
|
83661
|
+
const existing = readFileSync9(targetFile, "utf-8");
|
|
83429
83662
|
if (/^\s+dependency-guardian\s*:/m.test(existing)) {
|
|
83430
83663
|
process.stderr.write(" Hook already installed in lefthook.\n");
|
|
83431
83664
|
return;
|
|
@@ -83457,16 +83690,16 @@ function installLefthookHook(targetFile) {
|
|
|
83457
83690
|
`);
|
|
83458
83691
|
}
|
|
83459
83692
|
function installBareHook(targetFile) {
|
|
83460
|
-
const hooksDir =
|
|
83461
|
-
|
|
83462
|
-
if (
|
|
83463
|
-
const existing =
|
|
83693
|
+
const hooksDir = dirname8(targetFile);
|
|
83694
|
+
mkdirSync5(hooksDir, { recursive: true });
|
|
83695
|
+
if (existsSync9(targetFile)) {
|
|
83696
|
+
const existing = readFileSync9(targetFile, "utf-8");
|
|
83464
83697
|
if (existing.includes(HOOK_MARKER)) {
|
|
83465
83698
|
process.stderr.write(" Hook already installed.\n");
|
|
83466
83699
|
return;
|
|
83467
83700
|
}
|
|
83468
83701
|
safeWriteFileSync(targetFile, existing.trimEnd() + "\n" + HOOK_SECTION);
|
|
83469
|
-
|
|
83702
|
+
chmodSync4(targetFile, 493);
|
|
83470
83703
|
process.stderr.write(
|
|
83471
83704
|
` Appended Dependency Guardian hook to existing ${targetFile}
|
|
83472
83705
|
`
|
|
@@ -83474,7 +83707,7 @@ function installBareHook(targetFile) {
|
|
|
83474
83707
|
return;
|
|
83475
83708
|
}
|
|
83476
83709
|
safeWriteFileSync(targetFile, HOOK_SCRIPT);
|
|
83477
|
-
|
|
83710
|
+
chmodSync4(targetFile, 493);
|
|
83478
83711
|
process.stderr.write(` Installed git pre-commit hook at ${targetFile}
|
|
83479
83712
|
`);
|
|
83480
83713
|
}
|
|
@@ -83494,71 +83727,107 @@ function installHookForFramework(info) {
|
|
|
83494
83727
|
async function installHook() {
|
|
83495
83728
|
const info = detectHookFramework();
|
|
83496
83729
|
installHookForFramework(info);
|
|
83730
|
+
try {
|
|
83731
|
+
const repoPath = findRepoRoot();
|
|
83732
|
+
const hookPath = isAbsolute4(info.targetFile) ? info.targetFile : resolvePath(repoPath, info.targetFile);
|
|
83733
|
+
addEntry({
|
|
83734
|
+
repoPath,
|
|
83735
|
+
framework: info.framework,
|
|
83736
|
+
hookPath
|
|
83737
|
+
});
|
|
83738
|
+
} catch {
|
|
83739
|
+
}
|
|
83497
83740
|
try {
|
|
83498
83741
|
const { pingSetupEvent: pingSetupEvent2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
83499
83742
|
await pingSetupEvent2("hook_installed");
|
|
83500
83743
|
} catch {
|
|
83501
83744
|
}
|
|
83502
83745
|
}
|
|
83503
|
-
|
|
83746
|
+
function stripDgFromHookFile(hookPath, framework, repoPath) {
|
|
83747
|
+
if (!existsSync9(hookPath)) {
|
|
83748
|
+
return { status: "not-found", hookPath, repoPath };
|
|
83749
|
+
}
|
|
83750
|
+
const content = readFileSync9(hookPath, "utf-8");
|
|
83751
|
+
if (framework === "lefthook") {
|
|
83752
|
+
if (!/^\s+dependency-guardian\s*:/m.test(content)) {
|
|
83753
|
+
return { status: "not-found", hookPath, repoPath };
|
|
83754
|
+
}
|
|
83755
|
+
const stripped = content.replace(
|
|
83756
|
+
/^\s+dependency-guardian\s*:\s*\n(?:\s{6,}.*\n)+/gm,
|
|
83757
|
+
""
|
|
83758
|
+
);
|
|
83759
|
+
safeWriteFileSync(hookPath, stripped);
|
|
83760
|
+
removeEntry(repoPath, hookPath);
|
|
83761
|
+
return { status: "removed", hookPath, repoPath };
|
|
83762
|
+
}
|
|
83763
|
+
if (!content.includes(HOOK_MARKER)) {
|
|
83764
|
+
return { status: "not-found", hookPath, repoPath };
|
|
83765
|
+
}
|
|
83766
|
+
if (framework === "bare" && content.trimStart().startsWith("#!/bin/sh\n" + HOOK_MARKER)) {
|
|
83767
|
+
unlinkSync3(hookPath);
|
|
83768
|
+
removeEntry(repoPath, hookPath);
|
|
83769
|
+
return { status: "removed", hookPath, repoPath };
|
|
83770
|
+
}
|
|
83771
|
+
const startIdx = content.indexOf(MARKER_START);
|
|
83772
|
+
const endIdx = content.indexOf(MARKER_END);
|
|
83773
|
+
if (startIdx === -1 || endIdx === -1) {
|
|
83774
|
+
return { status: "not-found", hookPath, repoPath };
|
|
83775
|
+
}
|
|
83776
|
+
const before = content.slice(0, startIdx).trimEnd();
|
|
83777
|
+
const after = content.slice(endIdx + MARKER_END.length).trimStart();
|
|
83778
|
+
const remaining = (before + (after ? "\n" + after : "")).trimEnd() + "\n";
|
|
83779
|
+
if (remaining.trim() === "" || remaining.trim() === "#!/bin/sh") {
|
|
83780
|
+
unlinkSync3(hookPath);
|
|
83781
|
+
} else {
|
|
83782
|
+
safeWriteFileSync(hookPath, remaining);
|
|
83783
|
+
}
|
|
83784
|
+
removeEntry(repoPath, hookPath);
|
|
83785
|
+
return { status: "removed", hookPath, repoPath };
|
|
83786
|
+
}
|
|
83787
|
+
function uninstallHookFromRepo(repoRootOverride) {
|
|
83788
|
+
const root = repoRootOverride ?? findRepoRoot();
|
|
83504
83789
|
const hooksDir = findHooksDir();
|
|
83505
83790
|
const hookPath = join9(hooksDir, "pre-commit");
|
|
83506
|
-
|
|
83507
|
-
|
|
83508
|
-
const
|
|
83509
|
-
if (
|
|
83510
|
-
const
|
|
83511
|
-
|
|
83512
|
-
|
|
83513
|
-
const
|
|
83514
|
-
|
|
83515
|
-
|
|
83516
|
-
|
|
83517
|
-
|
|
83518
|
-
|
|
83519
|
-
|
|
83520
|
-
|
|
83521
|
-
|
|
83522
|
-
|
|
83523
|
-
|
|
83524
|
-
|
|
83525
|
-
|
|
83526
|
-
|
|
83527
|
-
|
|
83528
|
-
|
|
83529
|
-
|
|
83530
|
-
|
|
83531
|
-
|
|
83532
|
-
|
|
83533
|
-
""
|
|
83534
|
-
);
|
|
83535
|
-
safeWriteFileSync(cfg, stripped);
|
|
83536
|
-
process.stderr.write(
|
|
83537
|
-
` Removed Dependency Guardian section from ${cfg}
|
|
83538
|
-
`
|
|
83539
|
-
);
|
|
83540
|
-
return;
|
|
83541
|
-
}
|
|
83542
|
-
}
|
|
83791
|
+
const huskyPath = join9(root, ".husky", "pre-commit");
|
|
83792
|
+
if (existsSync9(huskyPath)) {
|
|
83793
|
+
const content2 = readFileSync9(huskyPath, "utf-8");
|
|
83794
|
+
if (content2.includes(HOOK_MARKER)) {
|
|
83795
|
+
const startIdx2 = content2.indexOf(MARKER_START);
|
|
83796
|
+
const endIdx2 = content2.indexOf(MARKER_END);
|
|
83797
|
+
if (startIdx2 !== -1 && endIdx2 !== -1) {
|
|
83798
|
+
const before = content2.slice(0, startIdx2).trimEnd();
|
|
83799
|
+
const after = content2.slice(endIdx2 + MARKER_END.length).trimStart();
|
|
83800
|
+
const remaining = (before + (after ? "\n" + after : "")).trimEnd() + "\n";
|
|
83801
|
+
safeWriteFileSync(huskyPath, remaining);
|
|
83802
|
+
removeEntry(root, huskyPath);
|
|
83803
|
+
return { status: "removed", hookPath: huskyPath, repoPath: root };
|
|
83804
|
+
}
|
|
83805
|
+
}
|
|
83806
|
+
}
|
|
83807
|
+
for (const cfg of [join9(root, "lefthook.yml"), join9(root, "lefthook.yaml")]) {
|
|
83808
|
+
if (!existsSync9(cfg)) continue;
|
|
83809
|
+
const content2 = readFileSync9(cfg, "utf-8");
|
|
83810
|
+
if (/^\s+dependency-guardian\s*:/m.test(content2)) {
|
|
83811
|
+
const stripped = content2.replace(
|
|
83812
|
+
/^\s+dependency-guardian\s*:\s*\n(?:\s{6,}.*\n)+/gm,
|
|
83813
|
+
""
|
|
83814
|
+
);
|
|
83815
|
+
safeWriteFileSync(cfg, stripped);
|
|
83816
|
+
removeEntry(root, cfg);
|
|
83817
|
+
return { status: "removed", hookPath: cfg, repoPath: root };
|
|
83543
83818
|
}
|
|
83544
|
-
} catch {
|
|
83545
83819
|
}
|
|
83546
|
-
if (!
|
|
83547
|
-
|
|
83548
|
-
return;
|
|
83820
|
+
if (!existsSync9(hookPath)) {
|
|
83821
|
+
return { status: "not-found", hookPath, repoPath: root };
|
|
83549
83822
|
}
|
|
83550
|
-
const content =
|
|
83823
|
+
const content = readFileSync9(hookPath, "utf-8");
|
|
83551
83824
|
if (!content.includes(HOOK_MARKER)) {
|
|
83552
|
-
|
|
83553
|
-
" No Dependency Guardian hook found in pre-commit.\n"
|
|
83554
|
-
);
|
|
83555
|
-
return;
|
|
83825
|
+
return { status: "not-found", hookPath, repoPath: root };
|
|
83556
83826
|
}
|
|
83557
83827
|
if (content.trimStart().startsWith("#!/bin/sh\n" + HOOK_MARKER)) {
|
|
83558
|
-
|
|
83559
|
-
|
|
83560
|
-
|
|
83561
|
-
return;
|
|
83828
|
+
unlinkSync3(hookPath);
|
|
83829
|
+
removeEntry(root, hookPath);
|
|
83830
|
+
return { status: "removed", hookPath, repoPath: root };
|
|
83562
83831
|
}
|
|
83563
83832
|
const startIdx = content.indexOf(MARKER_START);
|
|
83564
83833
|
const endIdx = content.indexOf(MARKER_END);
|
|
@@ -83567,19 +83836,32 @@ async function uninstallHook() {
|
|
|
83567
83836
|
const after = content.slice(endIdx + MARKER_END.length).trimStart();
|
|
83568
83837
|
const remaining = (before + (after ? "\n" + after : "")).trimEnd() + "\n";
|
|
83569
83838
|
safeWriteFileSync(hookPath, remaining);
|
|
83570
|
-
|
|
83571
|
-
|
|
83572
|
-
|
|
83573
|
-
|
|
83839
|
+
removeEntry(root, hookPath);
|
|
83840
|
+
return { status: "removed", hookPath, repoPath: root };
|
|
83841
|
+
}
|
|
83842
|
+
unlinkSync3(hookPath);
|
|
83843
|
+
removeEntry(root, hookPath);
|
|
83844
|
+
return { status: "removed", hookPath, repoPath: root };
|
|
83845
|
+
}
|
|
83846
|
+
async function uninstallHook() {
|
|
83847
|
+
let result;
|
|
83848
|
+
try {
|
|
83849
|
+
result = uninstallHookFromRepo();
|
|
83850
|
+
} catch (e) {
|
|
83851
|
+
process.stderr.write(` Error: ${e.message}
|
|
83852
|
+
`);
|
|
83574
83853
|
return;
|
|
83575
83854
|
}
|
|
83576
|
-
|
|
83577
|
-
|
|
83855
|
+
if (result.status === "removed") {
|
|
83856
|
+
process.stderr.write(` Removed Dependency Guardian section from ${result.hookPath}
|
|
83578
83857
|
`);
|
|
83579
|
-
|
|
83580
|
-
|
|
83581
|
-
|
|
83582
|
-
|
|
83858
|
+
try {
|
|
83859
|
+
const { pingSetupEvent: pingSetupEvent2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
83860
|
+
await pingSetupEvent2("hook_uninstalled");
|
|
83861
|
+
} catch {
|
|
83862
|
+
}
|
|
83863
|
+
} else {
|
|
83864
|
+
process.stderr.write(" No Dependency Guardian hook found in this repo.\n");
|
|
83583
83865
|
}
|
|
83584
83866
|
}
|
|
83585
83867
|
async function handleHookCommand(args) {
|
|
@@ -83593,11 +83875,6 @@ async function handleHookCommand(args) {
|
|
|
83593
83875
|
await installHook();
|
|
83594
83876
|
} else if (subcommand === "uninstall") {
|
|
83595
83877
|
await uninstallHook();
|
|
83596
|
-
try {
|
|
83597
|
-
const { pingSetupEvent: pingSetupEvent2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
83598
|
-
await pingSetupEvent2("hook_uninstalled");
|
|
83599
|
-
} catch {
|
|
83600
|
-
}
|
|
83601
83878
|
} else {
|
|
83602
83879
|
process.stderr.write(` Unknown hook command: ${subcommand}
|
|
83603
83880
|
`);
|
|
@@ -83615,6 +83892,7 @@ var HOOK_MARKER, MARKER_START, MARKER_END, LEFTHOOK_MARKER, HOOK_SCRIPT, HOOK_SE
|
|
|
83615
83892
|
var init_hook = __esm({
|
|
83616
83893
|
"src/commands/hook.ts"() {
|
|
83617
83894
|
"use strict";
|
|
83895
|
+
init_hooks_registry();
|
|
83618
83896
|
HOOK_MARKER = "# dependency-guardian-hook";
|
|
83619
83897
|
MARKER_START = "# dependency-guardian-hook-start";
|
|
83620
83898
|
MARKER_END = "# dependency-guardian-hook-end";
|
|
@@ -83983,14 +84261,14 @@ var init_parse_package_json = __esm({
|
|
|
83983
84261
|
|
|
83984
84262
|
// src/lockfile/index.ts
|
|
83985
84263
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
83986
|
-
import { readFileSync as
|
|
84264
|
+
import { readFileSync as readFileSync10, existsSync as existsSync10, statSync as statSync2 } from "node:fs";
|
|
83987
84265
|
import { join as join10 } from "node:path";
|
|
83988
84266
|
function readFileSafe(path3) {
|
|
83989
|
-
const size =
|
|
84267
|
+
const size = statSync2(path3).size;
|
|
83990
84268
|
if (size > MAX_LOCKFILE_BYTES) {
|
|
83991
84269
|
throw new Error(`Lockfile too large (${(size / 1024 / 1024).toFixed(0)} MB, max 50 MB): ${path3}`);
|
|
83992
84270
|
}
|
|
83993
|
-
return
|
|
84271
|
+
return readFileSync10(path3, "utf-8");
|
|
83994
84272
|
}
|
|
83995
84273
|
function discoverChanges(cwd2, config3) {
|
|
83996
84274
|
if (config3.workspace) {
|
|
@@ -84000,7 +84278,7 @@ function discoverChanges(cwd2, config3) {
|
|
|
84000
84278
|
const pythonDepFiles = ["requirements.txt", "Pipfile.lock", "poetry.lock"];
|
|
84001
84279
|
let pythonPackages = [];
|
|
84002
84280
|
for (const pyFile of pythonDepFiles) {
|
|
84003
|
-
if (
|
|
84281
|
+
if (existsSync10(join10(cwd2, pyFile))) {
|
|
84004
84282
|
const pyPkgs = parsePythonDepFile(cwd2, pyFile);
|
|
84005
84283
|
for (const p of pyPkgs) {
|
|
84006
84284
|
if (p.version === "latest") continue;
|
|
@@ -84026,7 +84304,7 @@ function discoverChanges(cwd2, config3) {
|
|
|
84026
84304
|
const headParsed = parseLockfileByType(headContent, lockfileInfo.type);
|
|
84027
84305
|
const directDeps = getDirectDeps(cwd2);
|
|
84028
84306
|
if (config3.baseLockfile) {
|
|
84029
|
-
if (!
|
|
84307
|
+
if (!existsSync10(config3.baseLockfile)) {
|
|
84030
84308
|
throw new Error(`Base lockfile not found: ${config3.baseLockfile}`);
|
|
84031
84309
|
}
|
|
84032
84310
|
const baseContent = readFileSafe(config3.baseLockfile);
|
|
@@ -84052,7 +84330,7 @@ function discoverChanges(cwd2, config3) {
|
|
|
84052
84330
|
};
|
|
84053
84331
|
}
|
|
84054
84332
|
const pkgJsonPath = join10(cwd2, "package.json");
|
|
84055
|
-
if (
|
|
84333
|
+
if (existsSync10(pkgJsonPath)) {
|
|
84056
84334
|
const headPkgJson = readFileSafe(pkgJsonPath);
|
|
84057
84335
|
const basePkgJson = getGitBaseFile(cwd2, "package.json");
|
|
84058
84336
|
if (basePkgJson !== null) {
|
|
@@ -84096,7 +84374,7 @@ function findLockfile(cwd2) {
|
|
|
84096
84374
|
];
|
|
84097
84375
|
for (const [name, type] of candidates) {
|
|
84098
84376
|
const p = join10(cwd2, name);
|
|
84099
|
-
if (
|
|
84377
|
+
if (existsSync10(p)) return { path: p, type };
|
|
84100
84378
|
}
|
|
84101
84379
|
return null;
|
|
84102
84380
|
}
|
|
@@ -84300,16 +84578,20 @@ var init_sanitize = __esm({
|
|
|
84300
84578
|
// src/cache/local_cache.ts
|
|
84301
84579
|
import * as path2 from "node:path";
|
|
84302
84580
|
import * as fs2 from "node:fs";
|
|
84303
|
-
import * as os5 from "node:os";
|
|
84304
84581
|
import { createRequire } from "node:module";
|
|
84305
84582
|
function defaultDbPath() {
|
|
84306
|
-
|
|
84307
|
-
return path2.join(baseDir, "cache.sqlite");
|
|
84583
|
+
return dgCachePath("scans.sqlite");
|
|
84308
84584
|
}
|
|
84309
84585
|
function tryLoadDriver() {
|
|
84310
84586
|
try {
|
|
84311
84587
|
const mod = moduleRequire("node-sqlite3-wasm");
|
|
84312
84588
|
const Ctor = mod.Database;
|
|
84589
|
+
if (typeof Ctor !== "function") {
|
|
84590
|
+
if (process.env.DG_PERF) {
|
|
84591
|
+
console.warn(`[CLI-CACHE] node-sqlite3-wasm did not export Database (got ${typeof Ctor})`);
|
|
84592
|
+
}
|
|
84593
|
+
return null;
|
|
84594
|
+
}
|
|
84313
84595
|
return (p) => new Ctor(p);
|
|
84314
84596
|
} catch (err) {
|
|
84315
84597
|
if (process.env.DG_PERF) {
|
|
@@ -84326,6 +84608,7 @@ var moduleRequire, DEFAULT_MAX_ROWS, DEFAULT_TTL_SECONDS, LocalScanCache, _share
|
|
|
84326
84608
|
var init_local_cache = __esm({
|
|
84327
84609
|
"src/cache/local_cache.ts"() {
|
|
84328
84610
|
"use strict";
|
|
84611
|
+
init_paths();
|
|
84329
84612
|
moduleRequire = createRequire(import.meta.url);
|
|
84330
84613
|
DEFAULT_MAX_ROWS = 1e5;
|
|
84331
84614
|
DEFAULT_TTL_SECONDS = 24 * 60 * 60;
|
|
@@ -84353,6 +84636,15 @@ var init_local_cache = __esm({
|
|
|
84353
84636
|
this.db.exec("PRAGMA busy_timeout = 5000");
|
|
84354
84637
|
this.initSchema();
|
|
84355
84638
|
this.vacuumExpired();
|
|
84639
|
+
if (!fs2.existsSync(dbPath)) {
|
|
84640
|
+
if (process.env.DG_PERF) {
|
|
84641
|
+
console.warn(`[CLI-CACHE] cache file ${dbPath} did not materialize after init \u2014 disabling`);
|
|
84642
|
+
}
|
|
84643
|
+
this.disabled = true;
|
|
84644
|
+
this.db = null;
|
|
84645
|
+
return;
|
|
84646
|
+
}
|
|
84647
|
+
this.mergeLegacyIfPresent();
|
|
84356
84648
|
} catch (err) {
|
|
84357
84649
|
this.disabled = true;
|
|
84358
84650
|
if (process.env.DG_PERF) {
|
|
@@ -84361,6 +84653,61 @@ var init_local_cache = __esm({
|
|
|
84361
84653
|
this.db = null;
|
|
84362
84654
|
}
|
|
84363
84655
|
}
|
|
84656
|
+
mergeLegacyIfPresent() {
|
|
84657
|
+
if (!this.db || !this.insertStmt) return;
|
|
84658
|
+
const legacy = legacyPaths().cacheSqlite;
|
|
84659
|
+
if (!fs2.existsSync(legacy)) return;
|
|
84660
|
+
const driver = tryLoadDriver();
|
|
84661
|
+
if (!driver) return;
|
|
84662
|
+
let legacyDb = null;
|
|
84663
|
+
try {
|
|
84664
|
+
legacyDb = driver(legacy);
|
|
84665
|
+
const rows = legacyDb.all(
|
|
84666
|
+
"SELECT name, version, score, payload, fetched_at, expires_at FROM scan_cache_v2 WHERE expires_at > ?",
|
|
84667
|
+
[Date.now()]
|
|
84668
|
+
);
|
|
84669
|
+
if (rows.length === 0) {
|
|
84670
|
+
try {
|
|
84671
|
+
legacyDb.close();
|
|
84672
|
+
} catch {
|
|
84673
|
+
}
|
|
84674
|
+
try {
|
|
84675
|
+
fs2.unlinkSync(legacy);
|
|
84676
|
+
} catch {
|
|
84677
|
+
}
|
|
84678
|
+
return;
|
|
84679
|
+
}
|
|
84680
|
+
const stmt = this.insertStmt;
|
|
84681
|
+
this.db.exec("BEGIN");
|
|
84682
|
+
for (const r of rows) {
|
|
84683
|
+
stmt.run([r.name, r.version, r.score, r.payload, r.fetched_at, r.expires_at]);
|
|
84684
|
+
}
|
|
84685
|
+
this.db.exec("COMMIT");
|
|
84686
|
+
if (process.env.DG_PERF) {
|
|
84687
|
+
console.warn(`[CLI-CACHE] merged ${rows.length} rows from legacy ${legacy}`);
|
|
84688
|
+
}
|
|
84689
|
+
try {
|
|
84690
|
+
legacyDb.close();
|
|
84691
|
+
} catch {
|
|
84692
|
+
}
|
|
84693
|
+
try {
|
|
84694
|
+
fs2.unlinkSync(legacy);
|
|
84695
|
+
} catch {
|
|
84696
|
+
}
|
|
84697
|
+
} catch (err) {
|
|
84698
|
+
try {
|
|
84699
|
+
legacyDb?.close();
|
|
84700
|
+
} catch {
|
|
84701
|
+
}
|
|
84702
|
+
try {
|
|
84703
|
+
this.db.exec("ROLLBACK");
|
|
84704
|
+
} catch {
|
|
84705
|
+
}
|
|
84706
|
+
if (process.env.DG_PERF) {
|
|
84707
|
+
console.warn(`[CLI-CACHE] legacy cache merge failed: ${err instanceof Error ? err.message : err}`);
|
|
84708
|
+
}
|
|
84709
|
+
}
|
|
84710
|
+
}
|
|
84364
84711
|
initSchema() {
|
|
84365
84712
|
if (!this.db) return;
|
|
84366
84713
|
this.db.exec(`
|
|
@@ -84387,21 +84734,9 @@ var init_local_cache = __esm({
|
|
|
84387
84734
|
expires_at = excluded.expires_at
|
|
84388
84735
|
`);
|
|
84389
84736
|
}
|
|
84390
|
-
/**
|
|
84391
|
-
* Collision-free key for the in-memory Map returned by `lookup()`. Uses
|
|
84392
|
-
* a NUL separator (illegal in npm + PyPI package names — JS strings
|
|
84393
|
-
* handle NUL fine; the v1 `${name}@${version}` form was string-collidable
|
|
84394
|
-
* when names contained "@"). Callers must use this same helper to look
|
|
84395
|
-
* entries up — never reconstruct by hand.
|
|
84396
|
-
*/
|
|
84397
84737
|
static cacheKey(name, version) {
|
|
84398
84738
|
return `${name}\0${version}`;
|
|
84399
84739
|
}
|
|
84400
|
-
/**
|
|
84401
|
-
* Batch lookup. Returns a Map keyed by the v2 key (`name\0version`). Expired
|
|
84402
|
-
* rows are excluded by the WHERE clause; the caller can treat absence as
|
|
84403
|
-
* "go ask the server."
|
|
84404
|
-
*/
|
|
84405
84740
|
lookup(packages) {
|
|
84406
84741
|
const out = /* @__PURE__ */ new Map();
|
|
84407
84742
|
if (this.disabled || !this.db || packages.length === 0) return out;
|
|
@@ -84442,11 +84777,6 @@ var init_local_cache = __esm({
|
|
|
84442
84777
|
}
|
|
84443
84778
|
return out;
|
|
84444
84779
|
}
|
|
84445
|
-
/**
|
|
84446
|
-
* Persist fresh scan results. Uses a single transaction so all rows commit
|
|
84447
|
-
* together (fast + crash-safe). Inserts past maxRows trigger LRU eviction
|
|
84448
|
-
* on the oldest fetched_at.
|
|
84449
|
-
*/
|
|
84450
84780
|
insert(rows) {
|
|
84451
84781
|
if (this.disabled || !this.db || !this.insertStmt || rows.length === 0) return;
|
|
84452
84782
|
const now = Date.now();
|
|
@@ -84534,6 +84864,7 @@ __export(client_exports, {
|
|
|
84534
84864
|
ANON_BATCH_SIZE: () => ANON_BATCH_SIZE,
|
|
84535
84865
|
APIError: () => APIError,
|
|
84536
84866
|
BATCH_SIZE: () => BATCH_SIZE,
|
|
84867
|
+
BatchPoolPartialError: () => BatchPoolPartialError,
|
|
84537
84868
|
ClientOutdatedError: () => ClientOutdatedError,
|
|
84538
84869
|
TrialExhaustedError: () => TrialExhaustedError,
|
|
84539
84870
|
callAnalyzeAPI: () => callAnalyzeAPI,
|
|
@@ -84611,23 +84942,32 @@ async function callAnalyzeAPI(packages, config3, onProgress) {
|
|
|
84611
84942
|
batches.push(uncached.slice(i, i + batchSize));
|
|
84612
84943
|
}
|
|
84613
84944
|
const tTotal = Date.now();
|
|
84614
|
-
|
|
84615
|
-
|
|
84616
|
-
|
|
84617
|
-
|
|
84618
|
-
|
|
84619
|
-
|
|
84620
|
-
|
|
84621
|
-
|
|
84622
|
-
|
|
84623
|
-
|
|
84624
|
-
|
|
84625
|
-
|
|
84626
|
-
|
|
84627
|
-
|
|
84628
|
-
|
|
84945
|
+
let results;
|
|
84946
|
+
try {
|
|
84947
|
+
results = await runBatchPool(
|
|
84948
|
+
batches,
|
|
84949
|
+
(batch, onRateLimit, onPackageProgress) => callBatchWithRetry(batch, config3, onRateLimit, onPackageProgress),
|
|
84950
|
+
{
|
|
84951
|
+
onBatchDone: (_batchIndex, batch, completed) => {
|
|
84952
|
+
if (adjustedOnProgress) {
|
|
84953
|
+
adjustedOnProgress(completed, uncached.length, batch.map((p) => p.name));
|
|
84954
|
+
}
|
|
84955
|
+
},
|
|
84956
|
+
onPackageProgress: (completed, latestName) => {
|
|
84957
|
+
if (adjustedOnProgress) {
|
|
84958
|
+
adjustedOnProgress(completed, uncached.length, latestName ? [latestName] : []);
|
|
84959
|
+
}
|
|
84960
|
+
},
|
|
84961
|
+
totalBatches: batches.length
|
|
84962
|
+
}
|
|
84963
|
+
);
|
|
84964
|
+
} catch (e) {
|
|
84965
|
+
if (e instanceof BatchPoolPartialError && e.partialResults.length > 0) {
|
|
84966
|
+
const partial = mergeResponses(e.partialResults);
|
|
84967
|
+
persistServerResponse(cache3, partial);
|
|
84629
84968
|
}
|
|
84630
|
-
|
|
84969
|
+
throw e instanceof BatchPoolPartialError ? e.cause : e;
|
|
84970
|
+
}
|
|
84631
84971
|
if (process.env.DG_PERF) console.error(`[CLI-PERF] total: ${uncached.length} uncached packages \u2192 ${Date.now() - tTotal}ms`);
|
|
84632
84972
|
serverResponse = mergeResponses(results);
|
|
84633
84973
|
}
|
|
@@ -84772,8 +85112,8 @@ async function runBatchPool(batches, fn, opts) {
|
|
|
84772
85112
|
if (catchup > 0) completedPackages += catchup;
|
|
84773
85113
|
if (opts.onBatchDone) opts.onBatchDone(i, batch, completedPackages);
|
|
84774
85114
|
} catch (e) {
|
|
84775
|
-
firstError = e;
|
|
84776
|
-
|
|
85115
|
+
if (firstError === null) firstError = e;
|
|
85116
|
+
return;
|
|
84777
85117
|
}
|
|
84778
85118
|
}
|
|
84779
85119
|
}
|
|
@@ -84781,7 +85121,10 @@ async function runBatchPool(batches, fn, opts) {
|
|
|
84781
85121
|
const workers = [];
|
|
84782
85122
|
for (let s = 0; s < workerCount; s++) workers.push(worker(s));
|
|
84783
85123
|
await Promise.allSettled(workers);
|
|
84784
|
-
if (firstError !== null)
|
|
85124
|
+
if (firstError !== null) {
|
|
85125
|
+
const partials = results.filter((r) => r !== void 0);
|
|
85126
|
+
throw new BatchPoolPartialError(firstError, partials);
|
|
85127
|
+
}
|
|
84785
85128
|
return results;
|
|
84786
85129
|
}
|
|
84787
85130
|
async function callBatchWithRetry(packages, config3, onRateLimit, onPackageProgress) {
|
|
@@ -84835,7 +85178,6 @@ function mergeResponses(results) {
|
|
|
84835
85178
|
action,
|
|
84836
85179
|
packages: allPackages,
|
|
84837
85180
|
safeVersions,
|
|
84838
|
-
// Sum, not max — batches run sequentially, total wall-clock is the sum
|
|
84839
85181
|
durationMs: results.reduce((s, r) => s + (r.durationMs || 0), 0)
|
|
84840
85182
|
};
|
|
84841
85183
|
}
|
|
@@ -84987,26 +85329,52 @@ async function readNdjsonAnalyzeResponse(response, onPackageProgress) {
|
|
|
84987
85329
|
async function callPyPIAnalyzeAPI(packages, config3, onProgress) {
|
|
84988
85330
|
const batchSize = config3.apiKey ? BATCH_SIZE : ANON_BATCH_SIZE;
|
|
84989
85331
|
_currentScanId = randomUUID2();
|
|
84990
|
-
|
|
84991
|
-
|
|
85332
|
+
const cache3 = getSharedLocalCache();
|
|
85333
|
+
const tLocalLookup = Date.now();
|
|
85334
|
+
const localHits = cache3.lookup(packages.map((p) => ({ name: p.name, version: p.version })));
|
|
85335
|
+
if (process.env.DG_PERF && !cache3.isDisabled) {
|
|
85336
|
+
console.error(`[CLI-PERF] pypi local cache: ${localHits.size}/${packages.length} hits \u2192 ${Date.now() - tLocalLookup}ms`);
|
|
84992
85337
|
}
|
|
84993
|
-
const
|
|
84994
|
-
|
|
84995
|
-
|
|
85338
|
+
const uncached = packages.filter((p) => !localHits.has(LocalScanCache.cacheKey(p.name, p.version)));
|
|
85339
|
+
if (uncached.length === 0) {
|
|
85340
|
+
if (onProgress) onProgress(packages.length, packages.length);
|
|
85341
|
+
return localHitsToResponse(packages, localHits);
|
|
84996
85342
|
}
|
|
84997
|
-
|
|
84998
|
-
|
|
84999
|
-
|
|
85000
|
-
(
|
|
85001
|
-
|
|
85002
|
-
|
|
85003
|
-
|
|
85004
|
-
|
|
85005
|
-
totalBatches: batches.length
|
|
85343
|
+
let serverResponse;
|
|
85344
|
+
if (uncached.length <= batchSize) {
|
|
85345
|
+
serverResponse = await callPyPIBatch(uncached, config3);
|
|
85346
|
+
if (onProgress) onProgress(localHits.size + uncached.length, packages.length);
|
|
85347
|
+
} else {
|
|
85348
|
+
const batches = [];
|
|
85349
|
+
for (let i = 0; i < uncached.length; i += batchSize) {
|
|
85350
|
+
batches.push(uncached.slice(i, i + batchSize));
|
|
85006
85351
|
}
|
|
85007
|
-
|
|
85008
|
-
|
|
85009
|
-
|
|
85352
|
+
const tTotal = Date.now();
|
|
85353
|
+
let results;
|
|
85354
|
+
try {
|
|
85355
|
+
results = await runBatchPool(
|
|
85356
|
+
batches,
|
|
85357
|
+
(batch) => callPyPIBatch(batch, config3),
|
|
85358
|
+
{
|
|
85359
|
+
onBatchDone: (_i, _batch, completed) => {
|
|
85360
|
+
if (onProgress) onProgress(localHits.size + completed, packages.length);
|
|
85361
|
+
},
|
|
85362
|
+
totalBatches: batches.length
|
|
85363
|
+
}
|
|
85364
|
+
);
|
|
85365
|
+
} catch (e) {
|
|
85366
|
+
if (e instanceof BatchPoolPartialError && e.partialResults.length > 0) {
|
|
85367
|
+
const partial = mergeResponses(e.partialResults);
|
|
85368
|
+
persistServerResponse(cache3, partial);
|
|
85369
|
+
}
|
|
85370
|
+
throw e instanceof BatchPoolPartialError ? e.cause : e;
|
|
85371
|
+
}
|
|
85372
|
+
if (process.env.DG_PERF) console.error(`[CLI-PERF] pypi total: ${uncached.length} uncached \u2192 ${Date.now() - tTotal}ms`);
|
|
85373
|
+
serverResponse = mergeResponses(results);
|
|
85374
|
+
}
|
|
85375
|
+
persistServerResponse(cache3, serverResponse);
|
|
85376
|
+
if (localHits.size === 0) return serverResponse;
|
|
85377
|
+
return mergeLocalHitsWithServer(packages, localHits, serverResponse);
|
|
85010
85378
|
}
|
|
85011
85379
|
async function callPyPIBatch(packages, config3) {
|
|
85012
85380
|
const url = `${config3.apiUrl}/v1/pypi/analyze`;
|
|
@@ -85069,7 +85437,7 @@ async function callPyPIBatch(packages, config3) {
|
|
|
85069
85437
|
checkVersionFloor(raw);
|
|
85070
85438
|
return sanitizeResponse(raw);
|
|
85071
85439
|
}
|
|
85072
|
-
var APIError, TrialExhaustedError, ClientOutdatedError, BATCH_SIZE, ANON_BATCH_SIZE, MAX_RETRIES, RETRY_DELAY_MS, DEFAULT_BATCH_CONCURRENCY, _currentScanId;
|
|
85440
|
+
var APIError, TrialExhaustedError, ClientOutdatedError, BATCH_SIZE, ANON_BATCH_SIZE, MAX_RETRIES, RETRY_DELAY_MS, DEFAULT_BATCH_CONCURRENCY, _currentScanId, BatchPoolPartialError;
|
|
85073
85441
|
var init_client3 = __esm({
|
|
85074
85442
|
"src/api/client.ts"() {
|
|
85075
85443
|
"use strict";
|
|
@@ -85110,6 +85478,14 @@ var init_client3 = __esm({
|
|
|
85110
85478
|
RETRY_DELAY_MS = 5e3;
|
|
85111
85479
|
DEFAULT_BATCH_CONCURRENCY = 4;
|
|
85112
85480
|
_currentScanId = "";
|
|
85481
|
+
BatchPoolPartialError = class extends Error {
|
|
85482
|
+
constructor(cause, partialResults) {
|
|
85483
|
+
super(cause instanceof Error ? cause.message : String(cause));
|
|
85484
|
+
this.cause = cause;
|
|
85485
|
+
this.partialResults = partialResults;
|
|
85486
|
+
this.name = "BatchPoolPartialError";
|
|
85487
|
+
}
|
|
85488
|
+
};
|
|
85113
85489
|
}
|
|
85114
85490
|
});
|
|
85115
85491
|
|
|
@@ -85246,11 +85622,11 @@ __export(protect_exports, {
|
|
|
85246
85622
|
stripAliasSourceFromRc: () => stripAliasSourceFromRc,
|
|
85247
85623
|
suggestedShellRc: () => suggestedShellRc
|
|
85248
85624
|
});
|
|
85249
|
-
import { existsSync as
|
|
85250
|
-
import { join as
|
|
85251
|
-
import { homedir as
|
|
85625
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11, writeFileSync as writeFileSync7, unlinkSync as unlinkSync5, mkdirSync as mkdirSync7, lstatSync as lstatSync3, appendFileSync } from "node:fs";
|
|
85626
|
+
import { join as join11, dirname as dirname10 } from "node:path";
|
|
85627
|
+
import { homedir as homedir3 } from "node:os";
|
|
85252
85628
|
function aliasFile() {
|
|
85253
|
-
return
|
|
85629
|
+
return dgStatePath("aliases.sh");
|
|
85254
85630
|
}
|
|
85255
85631
|
function safeIsRegularFile(path3) {
|
|
85256
85632
|
try {
|
|
@@ -85261,7 +85637,7 @@ function safeIsRegularFile(path3) {
|
|
|
85261
85637
|
}
|
|
85262
85638
|
}
|
|
85263
85639
|
function safeWriteFileSync2(target, content, mode = 420) {
|
|
85264
|
-
const parent =
|
|
85640
|
+
const parent = dirname10(target);
|
|
85265
85641
|
try {
|
|
85266
85642
|
const parentStat = lstatSync3(parent);
|
|
85267
85643
|
if (parentStat.isSymbolicLink()) {
|
|
@@ -85278,34 +85654,23 @@ function safeWriteFileSync2(target, content, mode = 420) {
|
|
|
85278
85654
|
} catch (e) {
|
|
85279
85655
|
if (e instanceof Error && e.message.startsWith("refusing")) throw e;
|
|
85280
85656
|
}
|
|
85281
|
-
|
|
85657
|
+
writeFileSync7(target, content, { encoding: "utf-8", mode });
|
|
85282
85658
|
}
|
|
85283
|
-
function readProtectConfig(
|
|
85284
|
-
|
|
85285
|
-
if (stored) return stored;
|
|
85286
|
-
const legacyPath = join12(cwd2, LEGACY_PROJECT_FILE);
|
|
85287
|
-
if (safeIsRegularFile(legacyPath)) {
|
|
85288
|
-
try {
|
|
85289
|
-
const data = JSON.parse(readFileSync9(legacyPath, "utf-8"));
|
|
85290
|
-
if (typeof data === "object" && data !== null) {
|
|
85291
|
-
const cfg = data;
|
|
85292
|
-
setProtectConfig(cfg);
|
|
85293
|
-
return cfg;
|
|
85294
|
-
}
|
|
85295
|
-
} catch {
|
|
85296
|
-
}
|
|
85297
|
-
}
|
|
85298
|
-
return null;
|
|
85659
|
+
function readProtectConfig(_cwd) {
|
|
85660
|
+
return getProtectConfig() ?? null;
|
|
85299
85661
|
}
|
|
85300
85662
|
function writeProtectConfig(_cwd, cfg) {
|
|
85301
85663
|
setProtectConfig(cfg);
|
|
85302
85664
|
}
|
|
85303
85665
|
function writeAliasSnippet() {
|
|
85304
|
-
const dir =
|
|
85305
|
-
|
|
85666
|
+
const dir = dirname10(aliasFile());
|
|
85667
|
+
mkdirSync7(dir, { recursive: true, mode: 448 });
|
|
85306
85668
|
safeWriteFileSync2(aliasFile(), ALIAS_SNIPPET);
|
|
85307
85669
|
return aliasFile();
|
|
85308
85670
|
}
|
|
85671
|
+
function legacyAliasPath() {
|
|
85672
|
+
return legacyPaths().aliasesShOld;
|
|
85673
|
+
}
|
|
85309
85674
|
function suggestedShellRc() {
|
|
85310
85675
|
const shell = (process.env.SHELL ?? "").toLowerCase();
|
|
85311
85676
|
if (shell.includes("zsh")) return { rc: "~/.zshrc", shellName: "zsh" };
|
|
@@ -85314,19 +85679,19 @@ function suggestedShellRc() {
|
|
|
85314
85679
|
return { rc: "~/.zshrc", shellName: "your shell rc" };
|
|
85315
85680
|
}
|
|
85316
85681
|
function expandHome(path3) {
|
|
85317
|
-
if (path3.startsWith("~/")) return
|
|
85318
|
-
if (path3 === "~") return
|
|
85682
|
+
if (path3.startsWith("~/")) return join11(homedir3(), path3.slice(2));
|
|
85683
|
+
if (path3 === "~") return homedir3();
|
|
85319
85684
|
return path3;
|
|
85320
85685
|
}
|
|
85321
85686
|
function appendAliasSourceToRc(rcPathRaw, sourceLine) {
|
|
85322
85687
|
const rcPath = expandHome(rcPathRaw);
|
|
85323
|
-
const home =
|
|
85688
|
+
const home = homedir3();
|
|
85324
85689
|
if (!rcPath.startsWith(home + "/") && rcPath !== home) {
|
|
85325
85690
|
return { status: "failed", rcPath, reason: "rc path is outside the home directory" };
|
|
85326
85691
|
}
|
|
85327
85692
|
try {
|
|
85328
|
-
const parent =
|
|
85329
|
-
if (
|
|
85693
|
+
const parent = dirname10(rcPath);
|
|
85694
|
+
if (existsSync12(parent)) {
|
|
85330
85695
|
const parentStat = lstatSync3(parent);
|
|
85331
85696
|
if (parentStat.isSymbolicLink()) {
|
|
85332
85697
|
return { status: "failed", rcPath, reason: "parent directory is a symlink" };
|
|
@@ -85335,7 +85700,7 @@ function appendAliasSourceToRc(rcPathRaw, sourceLine) {
|
|
|
85335
85700
|
} catch (e) {
|
|
85336
85701
|
return { status: "failed", rcPath, reason: e.message };
|
|
85337
85702
|
}
|
|
85338
|
-
if (
|
|
85703
|
+
if (existsSync12(rcPath)) {
|
|
85339
85704
|
let st;
|
|
85340
85705
|
try {
|
|
85341
85706
|
st = lstatSync3(rcPath);
|
|
@@ -85349,8 +85714,8 @@ function appendAliasSourceToRc(rcPathRaw, sourceLine) {
|
|
|
85349
85714
|
return { status: "failed", rcPath, reason: "rc path is not a regular file" };
|
|
85350
85715
|
}
|
|
85351
85716
|
try {
|
|
85352
|
-
const existing =
|
|
85353
|
-
if (existing.includes(aliasFile()) || existing.includes(
|
|
85717
|
+
const existing = readFileSync11(rcPath, "utf-8");
|
|
85718
|
+
if (existing.includes(RC_SENTINEL_OPEN) || existing.includes(aliasFile()) || existing.includes(legacyAliasPath()) || existing.includes(sourceLine.trim())) {
|
|
85354
85719
|
return { status: "already-present", rcPath };
|
|
85355
85720
|
}
|
|
85356
85721
|
} catch (e) {
|
|
@@ -85359,8 +85724,9 @@ function appendAliasSourceToRc(rcPathRaw, sourceLine) {
|
|
|
85359
85724
|
}
|
|
85360
85725
|
try {
|
|
85361
85726
|
const block = `
|
|
85362
|
-
|
|
85727
|
+
${RC_SENTINEL_OPEN}
|
|
85363
85728
|
${sourceLine}
|
|
85729
|
+
${RC_SENTINEL_CLOSE}
|
|
85364
85730
|
`;
|
|
85365
85731
|
appendFileSync(rcPath, block, { encoding: "utf-8" });
|
|
85366
85732
|
return { status: "appended", rcPath };
|
|
@@ -85393,12 +85759,14 @@ function aliasSnippetExists() {
|
|
|
85393
85759
|
}
|
|
85394
85760
|
function aliasSnippetSourced() {
|
|
85395
85761
|
const candidates = [".zshrc", ".bashrc", ".bash_profile", ".profile"];
|
|
85762
|
+
const aliasFilePath = aliasFile();
|
|
85763
|
+
const legacyAlias = legacyAliasPath();
|
|
85396
85764
|
for (const rc of candidates) {
|
|
85397
|
-
const path3 =
|
|
85765
|
+
const path3 = join11(homedir3(), rc);
|
|
85398
85766
|
if (!safeIsRegularFile(path3)) continue;
|
|
85399
85767
|
try {
|
|
85400
|
-
const content =
|
|
85401
|
-
if (content.includes(
|
|
85768
|
+
const content = readFileSync11(path3, "utf-8");
|
|
85769
|
+
if (content.includes(RC_SENTINEL_OPEN) || content.includes(aliasFilePath) || content.includes(legacyAlias) || content.includes(".dependency-guardian/aliases.sh")) {
|
|
85402
85770
|
return { sourced: true, rcFile: path3 };
|
|
85403
85771
|
}
|
|
85404
85772
|
} catch {
|
|
@@ -85409,33 +85777,51 @@ function aliasSnippetSourced() {
|
|
|
85409
85777
|
function stripAliasSourceFromRc() {
|
|
85410
85778
|
const candidates = [".zshrc", ".bashrc", ".bash_profile", ".profile"];
|
|
85411
85779
|
const modified = [];
|
|
85780
|
+
const manualReviewNeeded = [];
|
|
85412
85781
|
const aliasFilePath = aliasFile();
|
|
85782
|
+
const legacyAlias = legacyAliasPath();
|
|
85413
85783
|
for (const rc of candidates) {
|
|
85414
|
-
const path3 =
|
|
85784
|
+
const path3 = join11(homedir3(), rc);
|
|
85415
85785
|
if (!safeIsRegularFile(path3)) continue;
|
|
85416
85786
|
let content;
|
|
85417
85787
|
try {
|
|
85418
|
-
content =
|
|
85788
|
+
content = readFileSync11(path3, "utf-8");
|
|
85419
85789
|
} catch {
|
|
85420
85790
|
continue;
|
|
85421
85791
|
}
|
|
85422
|
-
|
|
85792
|
+
const hasOpen = content.includes(RC_SENTINEL_OPEN);
|
|
85793
|
+
const hasClose = content.includes(RC_SENTINEL_CLOSE);
|
|
85794
|
+
const hasPath = content.includes(aliasFilePath) || content.includes(legacyAlias) || content.includes(".dependency-guardian/aliases.sh");
|
|
85795
|
+
if (!hasOpen && !hasPath) continue;
|
|
85796
|
+
if (hasOpen && !hasClose) {
|
|
85797
|
+
manualReviewNeeded.push(path3);
|
|
85423
85798
|
continue;
|
|
85424
85799
|
}
|
|
85425
|
-
|
|
85426
|
-
|
|
85427
|
-
|
|
85428
|
-
|
|
85429
|
-
|
|
85430
|
-
|
|
85431
|
-
|
|
85432
|
-
|
|
85800
|
+
let next = content;
|
|
85801
|
+
if (hasOpen && hasClose) {
|
|
85802
|
+
const pattern = new RegExp(
|
|
85803
|
+
`\\n?${escapeRegex(RC_SENTINEL_OPEN)}[\\s\\S]*?${escapeRegex(RC_SENTINEL_CLOSE)}\\n?`,
|
|
85804
|
+
"g"
|
|
85805
|
+
);
|
|
85806
|
+
next = next.replace(pattern, "\n");
|
|
85807
|
+
}
|
|
85808
|
+
if (hasPath) {
|
|
85809
|
+
const lines = next.split("\n");
|
|
85810
|
+
const out = [];
|
|
85811
|
+
for (let i = 0; i < lines.length; i++) {
|
|
85812
|
+
const line = lines[i];
|
|
85813
|
+
const isSourceLine = line.includes(aliasFilePath) || line.includes(legacyAlias) || line.includes(".dependency-guardian/aliases.sh");
|
|
85814
|
+
if (isSourceLine && (line.trimStart().startsWith("source ") || line.trimStart().startsWith(". "))) {
|
|
85815
|
+
if (out.length > 0 && out[out.length - 1].trim().startsWith("# Added by dg kitty")) {
|
|
85816
|
+
out.pop();
|
|
85817
|
+
}
|
|
85818
|
+
continue;
|
|
85433
85819
|
}
|
|
85434
|
-
|
|
85820
|
+
out.push(line);
|
|
85435
85821
|
}
|
|
85436
|
-
out.
|
|
85822
|
+
next = out.join("\n");
|
|
85437
85823
|
}
|
|
85438
|
-
|
|
85824
|
+
next = next.replace(/\n{3,}/g, "\n\n");
|
|
85439
85825
|
if (next === content) continue;
|
|
85440
85826
|
try {
|
|
85441
85827
|
safeWriteFileSync2(path3, next, 420);
|
|
@@ -85443,7 +85829,10 @@ function stripAliasSourceFromRc() {
|
|
|
85443
85829
|
} catch {
|
|
85444
85830
|
}
|
|
85445
85831
|
}
|
|
85446
|
-
return modified;
|
|
85832
|
+
return { modified, manualReviewNeeded };
|
|
85833
|
+
}
|
|
85834
|
+
function escapeRegex(s) {
|
|
85835
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
85447
85836
|
}
|
|
85448
85837
|
async function runProtectInit(cwd2, opts = {}) {
|
|
85449
85838
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -85471,7 +85860,7 @@ async function runProtectInit(cwd2, opts = {}) {
|
|
|
85471
85860
|
}
|
|
85472
85861
|
process.stderr.write("\n");
|
|
85473
85862
|
process.stderr.write(import_chalk4.default.green(" \u2713 ") + import_chalk4.default.bold("Dependency Guardian protection: ENABLED") + "\n");
|
|
85474
|
-
process.stderr.write(import_chalk4.default.dim(" Stored
|
|
85863
|
+
process.stderr.write(import_chalk4.default.dim(" Stored under ~/.dg/.\n"));
|
|
85475
85864
|
process.stderr.write(import_chalk4.default.dim(` Mode: ${cfg.mode}${cfg.strict ? " \xB7 strict" : ""}
|
|
85476
85865
|
`));
|
|
85477
85866
|
process.stderr.write("\n");
|
|
@@ -85505,7 +85894,7 @@ async function runProtectOff(cwd2, opts = {}) {
|
|
|
85505
85894
|
if (getProtectConfig()) {
|
|
85506
85895
|
try {
|
|
85507
85896
|
clearProtectConfig();
|
|
85508
|
-
process.stderr.write(import_chalk4.default.green(" \u2713 ") + "Cleared protect config
|
|
85897
|
+
process.stderr.write(import_chalk4.default.green(" \u2713 ") + "Cleared protect config\n");
|
|
85509
85898
|
removed += 1;
|
|
85510
85899
|
try {
|
|
85511
85900
|
const { pingSetupEvent: pingSetupEvent2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
@@ -85519,21 +85908,10 @@ async function runProtectOff(cwd2, opts = {}) {
|
|
|
85519
85908
|
} else {
|
|
85520
85909
|
process.stderr.write(import_chalk4.default.dim(" Protect config already cleared.\n"));
|
|
85521
85910
|
}
|
|
85522
|
-
|
|
85523
|
-
if (safeIsRegularFile(legacyPath)) {
|
|
85524
|
-
try {
|
|
85525
|
-
unlinkSync3(legacyPath);
|
|
85526
|
-
process.stderr.write(import_chalk4.default.green(" \u2713 ") + `Removed legacy ${legacyPath}
|
|
85527
|
-
`);
|
|
85528
|
-
removed += 1;
|
|
85529
|
-
} catch (e) {
|
|
85530
|
-
process.stderr.write(import_chalk4.default.red(` Could not remove ${legacyPath}: ${e.message}
|
|
85531
|
-
`));
|
|
85532
|
-
}
|
|
85533
|
-
}
|
|
85911
|
+
void cwd2;
|
|
85534
85912
|
if (opts.removeShell && aliasSnippetExists()) {
|
|
85535
85913
|
try {
|
|
85536
|
-
|
|
85914
|
+
unlinkSync5(aliasFile());
|
|
85537
85915
|
process.stderr.write(import_chalk4.default.green(" \u2713 ") + `Removed ${aliasFile()}
|
|
85538
85916
|
`);
|
|
85539
85917
|
removed += 1;
|
|
@@ -85541,12 +85919,18 @@ async function runProtectOff(cwd2, opts = {}) {
|
|
|
85541
85919
|
process.stderr.write(import_chalk4.default.red(` Could not remove ${aliasFile()}: ${e.message}
|
|
85542
85920
|
`));
|
|
85543
85921
|
}
|
|
85544
|
-
const
|
|
85545
|
-
for (const p of
|
|
85922
|
+
const stripResult = stripAliasSourceFromRc();
|
|
85923
|
+
for (const p of stripResult.modified) {
|
|
85546
85924
|
process.stderr.write(import_chalk4.default.green(" \u2713 ") + `Removed source line from ${p}
|
|
85547
85925
|
`);
|
|
85548
85926
|
removed += 1;
|
|
85549
85927
|
}
|
|
85928
|
+
for (const p of stripResult.manualReviewNeeded) {
|
|
85929
|
+
process.stderr.write(
|
|
85930
|
+
import_chalk4.default.yellow(" \u26A0 ") + `Could not safely strip ${p}: opening sentinel without matching close. Remove the dg block by hand.
|
|
85931
|
+
`
|
|
85932
|
+
);
|
|
85933
|
+
}
|
|
85550
85934
|
} else if (aliasSnippetExists()) {
|
|
85551
85935
|
process.stderr.write(
|
|
85552
85936
|
import_chalk4.default.dim(` Shell snippet at ${aliasFile()} kept (other projects may use it).
|
|
@@ -85604,13 +85988,15 @@ function runInit(flags, cwd2) {
|
|
|
85604
85988
|
}
|
|
85605
85989
|
return runProtectInit(cwd2, opts);
|
|
85606
85990
|
}
|
|
85607
|
-
var import_chalk4,
|
|
85991
|
+
var import_chalk4, RC_SENTINEL_OPEN, RC_SENTINEL_CLOSE, DEFAULT_CONFIG, ALIAS_SNIPPET, USAGE3;
|
|
85608
85992
|
var init_protect = __esm({
|
|
85609
85993
|
"src/commands/protect.ts"() {
|
|
85610
85994
|
"use strict";
|
|
85611
85995
|
import_chalk4 = __toESM(require_source());
|
|
85612
85996
|
init_auth();
|
|
85613
|
-
|
|
85997
|
+
init_paths();
|
|
85998
|
+
RC_SENTINEL_OPEN = "# >>> dependency-guardian (managed) >>>";
|
|
85999
|
+
RC_SENTINEL_CLOSE = "# <<< dependency-guardian (managed) <<<";
|
|
85614
86000
|
DEFAULT_CONFIG = {
|
|
85615
86001
|
version: 1,
|
|
85616
86002
|
enabled: true,
|
|
@@ -85619,7 +86005,7 @@ var init_protect = __esm({
|
|
|
85619
86005
|
};
|
|
85620
86006
|
ALIAS_SNIPPET = `# Dependency Guardian \u2014 opt-in shell aliases
|
|
85621
86007
|
# Source this from your shell rc to route npm/pip through dg:
|
|
85622
|
-
# echo 'source ~/.
|
|
86008
|
+
# echo 'source ~/.dg/aliases.sh' >> ~/.zshrc # or ~/.bashrc
|
|
85623
86009
|
# To turn it off, remove that line.
|
|
85624
86010
|
|
|
85625
86011
|
# Only alias if a real dg binary is on PATH.
|
|
@@ -85646,7 +86032,7 @@ unset __dg_bin
|
|
|
85646
86032
|
|
|
85647
86033
|
Usage:
|
|
85648
86034
|
dg protect Enable protection (same as \`dg protect init\`)
|
|
85649
|
-
dg protect off Disable protection
|
|
86035
|
+
dg protect off Disable protection
|
|
85650
86036
|
|
|
85651
86037
|
Flags (for init):
|
|
85652
86038
|
--no-shell Skip generating the shell-alias snippet
|
|
@@ -85654,10 +86040,10 @@ unset __dg_bin
|
|
|
85654
86040
|
--strict Refuse partial-coverage scans + suppress scripts
|
|
85655
86041
|
|
|
85656
86042
|
What \`dg protect\` does:
|
|
85657
|
-
1.
|
|
85658
|
-
2. Generates
|
|
85659
|
-
\`~/.
|
|
85660
|
-
shell rc. We do NOT touch your rc ourselves.
|
|
86043
|
+
1. Stores protection settings under ~/.dg/.
|
|
86044
|
+
2. Generates a shell-alias snippet at
|
|
86045
|
+
\`~/.dg/state/aliases.sh\` that you can \`source\`
|
|
86046
|
+
from your shell rc. We do NOT touch your rc ourselves.
|
|
85661
86047
|
3. Tells you exactly what line to add (and how to undo it).
|
|
85662
86048
|
|
|
85663
86049
|
After protection is on, \`npm install\` and \`pip install\` route through
|
|
@@ -85665,7 +86051,7 @@ unset __dg_bin
|
|
|
85665
86051
|
|
|
85666
86052
|
To see current coverage status, run \`dg status\`.
|
|
85667
86053
|
To disable, run \`dg protect off\`. (Pass --remove-shell to also delete
|
|
85668
|
-
the
|
|
86054
|
+
the alias snippet and strip the source line from your shell rc.)
|
|
85669
86055
|
|
|
85670
86056
|
Why this is opt-in:
|
|
85671
86057
|
DG never silently hijacks global npm/pip. Every change is explicit
|
|
@@ -85675,8 +86061,8 @@ unset __dg_bin
|
|
|
85675
86061
|
});
|
|
85676
86062
|
|
|
85677
86063
|
// src/ui/hooks/useInit.ts
|
|
85678
|
-
import { statSync as
|
|
85679
|
-
import { join as
|
|
86064
|
+
import { statSync as statSync3 } from "node:fs";
|
|
86065
|
+
import { join as join12 } from "node:path";
|
|
85680
86066
|
function initialState(dryRun, firstRun) {
|
|
85681
86067
|
return {
|
|
85682
86068
|
phase: firstRun ? "greet" : "detect",
|
|
@@ -85707,7 +86093,7 @@ function initialState(dryRun, firstRun) {
|
|
|
85707
86093
|
function detectCwdIsProject(cwd2) {
|
|
85708
86094
|
for (const marker of PROJECT_MARKERS) {
|
|
85709
86095
|
try {
|
|
85710
|
-
const stat =
|
|
86096
|
+
const stat = statSync3(join12(cwd2, marker));
|
|
85711
86097
|
if (stat.isFile()) return true;
|
|
85712
86098
|
} catch {
|
|
85713
86099
|
}
|
|
@@ -85720,7 +86106,6 @@ function reducer(state, action) {
|
|
|
85720
86106
|
`);
|
|
85721
86107
|
}
|
|
85722
86108
|
switch (action.type) {
|
|
85723
|
-
// ── First-run guided tour transitions ──────────────────────────────────
|
|
85724
86109
|
case "welcome_yes":
|
|
85725
86110
|
return { ...state, phase: "value_prop", engaged: true };
|
|
85726
86111
|
case "welcome_no": {
|
|
@@ -85800,6 +86185,9 @@ function reducer(state, action) {
|
|
|
85800
86185
|
if (!state.protectInfo) {
|
|
85801
86186
|
return { ...state, phase: "pitch_app" };
|
|
85802
86187
|
}
|
|
86188
|
+
if (state.protectInfo.alreadySourced) {
|
|
86189
|
+
return { ...state, phase: "pitch_app" };
|
|
86190
|
+
}
|
|
85803
86191
|
return { ...state, phase: "optional_protection" };
|
|
85804
86192
|
case "optional_protection_yes":
|
|
85805
86193
|
return { ...state, phase: "optional_protection_result" };
|
|
@@ -85814,7 +86202,6 @@ function reducer(state, action) {
|
|
|
85814
86202
|
return { ...state, phase: "pitch_app" };
|
|
85815
86203
|
case "pitch_acked":
|
|
85816
86204
|
return { ...state, phase: "done" };
|
|
85817
|
-
// ── Existing Phase 1b transitions (unchanged) ──────────────────────────
|
|
85818
86205
|
case "detected":
|
|
85819
86206
|
return {
|
|
85820
86207
|
...state,
|
|
@@ -85902,9 +86289,7 @@ function goBack(state) {
|
|
|
85902
86289
|
value_prop: "greet",
|
|
85903
86290
|
demo_result: "value_prop",
|
|
85904
86291
|
confirm_wrap: "verify_hook",
|
|
85905
|
-
// legacy only
|
|
85906
86292
|
show_app_link: "confirm_scan"
|
|
85907
|
-
// legacy only
|
|
85908
86293
|
};
|
|
85909
86294
|
if (state.phase === "confirm_hook") {
|
|
85910
86295
|
return { ...state, phase: state.firstRun ? "scenario" : "detect" };
|
|
@@ -85959,7 +86344,7 @@ function useInit(opts = {}) {
|
|
|
85959
86344
|
dispatch({
|
|
85960
86345
|
type: "hook_installed",
|
|
85961
86346
|
protectInfo: {
|
|
85962
|
-
rcLine: "source ~/.
|
|
86347
|
+
rcLine: "source ~/.dg/state/aliases.sh",
|
|
85963
86348
|
rcFile: "~/.zshrc",
|
|
85964
86349
|
shellName: "zsh",
|
|
85965
86350
|
alreadySourced: false
|
|
@@ -85973,8 +86358,15 @@ function useInit(opts = {}) {
|
|
|
85973
86358
|
let protectInfo;
|
|
85974
86359
|
try {
|
|
85975
86360
|
const { rcLine, rcFile, shellName, alreadySourced } = setupProtectQuietly(cwd2);
|
|
86361
|
+
let sourced = alreadySourced;
|
|
86362
|
+
if (!alreadySourced) {
|
|
86363
|
+
const out = appendAliasSourceToRc(rcFile, rcLine);
|
|
86364
|
+
if (out.status === "appended" || out.status === "already-present") {
|
|
86365
|
+
sourced = true;
|
|
86366
|
+
}
|
|
86367
|
+
}
|
|
85976
86368
|
void Promise.resolve().then(() => (init_auth(), auth_exports)).then((m) => m.enqueueSetupEvent("protect_enabled"));
|
|
85977
|
-
protectInfo = { rcLine, rcFile, shellName, alreadySourced };
|
|
86369
|
+
protectInfo = { rcLine, rcFile, shellName, alreadySourced: sourced };
|
|
85978
86370
|
} catch {
|
|
85979
86371
|
}
|
|
85980
86372
|
dispatch({ type: "hook_installed", protectInfo });
|
|
@@ -85990,26 +86382,25 @@ function useInit(opts = {}) {
|
|
|
85990
86382
|
dispatch({ type: "hook_verified", durationMs: 0 });
|
|
85991
86383
|
return;
|
|
85992
86384
|
}
|
|
86385
|
+
if (!state.hookInfo) {
|
|
86386
|
+
dispatch({ type: "hook_verify_failed", error: "hook framework not detected" });
|
|
86387
|
+
return;
|
|
86388
|
+
}
|
|
86389
|
+
const t0 = Date.now();
|
|
85993
86390
|
try {
|
|
85994
|
-
const
|
|
85995
|
-
|
|
85996
|
-
|
|
85997
|
-
if (outcome.status === "error" && outcome.error) {
|
|
85998
|
-
dispatch({
|
|
85999
|
-
type: "hook_verify_failed",
|
|
86000
|
-
error: outcome.message ?? outcome.error.message
|
|
86001
|
-
});
|
|
86391
|
+
const result = verifyHookInstalled(state.hookInfo);
|
|
86392
|
+
if (!result.ok) {
|
|
86393
|
+
dispatch({ type: "hook_verify_failed", error: result.reason ?? "verification failed" });
|
|
86002
86394
|
return;
|
|
86003
86395
|
}
|
|
86004
|
-
|
|
86005
|
-
dispatch({ type: "hook_verified", durationMs: ms });
|
|
86396
|
+
dispatch({ type: "hook_verified", durationMs: Date.now() - t0 });
|
|
86006
86397
|
} catch (e) {
|
|
86007
86398
|
dispatch({
|
|
86008
86399
|
type: "hook_verify_failed",
|
|
86009
86400
|
error: e instanceof Error ? e.message : String(e)
|
|
86010
86401
|
});
|
|
86011
86402
|
}
|
|
86012
|
-
}, [state.dryRun,
|
|
86403
|
+
}, [state.dryRun, state.hookInfo]);
|
|
86013
86404
|
const runScan = (0, import_react22.useCallback)(async () => {
|
|
86014
86405
|
if (state.dryRun) {
|
|
86015
86406
|
dispatch({
|
|
@@ -86031,11 +86422,23 @@ function useInit(opts = {}) {
|
|
|
86031
86422
|
const config3 = parseConfig([process.argv[0] ?? "node", "init", "--scan-all"], false);
|
|
86032
86423
|
const projects = state.projects.length > 0 ? state.projects : [{ path: opts.cwd ?? process.cwd() }];
|
|
86033
86424
|
const allOutcomes = [];
|
|
86034
|
-
|
|
86425
|
+
const perProject = /* @__PURE__ */ new Map();
|
|
86426
|
+
const aggregate = (current) => {
|
|
86427
|
+
let done = 0;
|
|
86428
|
+
let total = 0;
|
|
86429
|
+
for (const v of perProject.values()) {
|
|
86430
|
+
done += v.done;
|
|
86431
|
+
total += v.total;
|
|
86432
|
+
}
|
|
86433
|
+
return { done, total, current };
|
|
86434
|
+
};
|
|
86435
|
+
for (let i = 0; i < projects.length; i++) {
|
|
86436
|
+
const proj = projects[i];
|
|
86035
86437
|
if (process.env.DG_DEBUG_WIZARD) process.stderr.write(`[wizard] scanning ${proj.path}
|
|
86036
86438
|
`);
|
|
86037
86439
|
const outcome = await scanFn(proj.path, config3, (p) => {
|
|
86038
|
-
|
|
86440
|
+
perProject.set(i, { done: p.done, total: p.total });
|
|
86441
|
+
dispatch({ type: "scan_progress", progress: aggregate(p.current) });
|
|
86039
86442
|
});
|
|
86040
86443
|
if (process.env.DG_DEBUG_WIZARD) process.stderr.write(`[wizard] scan done ${proj.path} status=${outcome.status}
|
|
86041
86444
|
`);
|
|
@@ -86286,8 +86689,8 @@ __export(ink_controls_exports, {
|
|
|
86286
86689
|
setInkClear: () => setInkClear,
|
|
86287
86690
|
setInkInstance: () => setInkInstance
|
|
86288
86691
|
});
|
|
86289
|
-
import { resolve as resolve2, dirname as
|
|
86290
|
-
import { existsSync as
|
|
86692
|
+
import { resolve as resolve2, dirname as dirname11 } from "node:path";
|
|
86693
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
86291
86694
|
function locateInkInstancesPath() {
|
|
86292
86695
|
let cur;
|
|
86293
86696
|
try {
|
|
@@ -86297,13 +86700,13 @@ function locateInkInstancesPath() {
|
|
|
86297
86700
|
}
|
|
86298
86701
|
while (cur && cur !== "/" && cur !== ".") {
|
|
86299
86702
|
const candidate = resolve2(cur, "node_modules", "ink", "build", "instances.js");
|
|
86300
|
-
if (
|
|
86301
|
-
const parent =
|
|
86703
|
+
if (existsSync13(candidate)) return candidate;
|
|
86704
|
+
const parent = dirname11(cur);
|
|
86302
86705
|
if (parent === cur) break;
|
|
86303
86706
|
cur = parent;
|
|
86304
86707
|
}
|
|
86305
86708
|
const cwdCandidate = resolve2(process.cwd(), "node_modules", "ink", "build", "instances.js");
|
|
86306
|
-
if (
|
|
86709
|
+
if (existsSync13(cwdCandidate)) return cwdCandidate;
|
|
86307
86710
|
return null;
|
|
86308
86711
|
}
|
|
86309
86712
|
async function initInkInstances() {
|
|
@@ -89122,7 +89525,16 @@ var init_demo_data = __esm({
|
|
|
89122
89525
|
"Postinstall Curl Pipe": "Downloads code and runs it",
|
|
89123
89526
|
"Suspicious Network": "Talks to suspicious servers",
|
|
89124
89527
|
"Typosquatting": "Pretending to be a popular package",
|
|
89125
|
-
"Sandbox Escape": "Tries to break out of safety checks"
|
|
89528
|
+
"Sandbox Escape": "Tries to break out of safety checks",
|
|
89529
|
+
"cross-signal-correlation": "Multiple detector signals correlated",
|
|
89530
|
+
"lifecycle-risk": "Install-time script risk",
|
|
89531
|
+
"runtime-behavior": "Suspicious runtime behavior",
|
|
89532
|
+
"data-exfiltration": "Sends data off-machine",
|
|
89533
|
+
"code-quality": "Obfuscated or low-quality code",
|
|
89534
|
+
"supply-chain-metadata": "Suspicious package metadata",
|
|
89535
|
+
"filesystem-risk": "Reads sensitive paths",
|
|
89536
|
+
"behavioral-anomaly": "Unusual behavior shape",
|
|
89537
|
+
"license-compliance": "License risk"
|
|
89126
89538
|
};
|
|
89127
89539
|
}
|
|
89128
89540
|
});
|
|
@@ -89204,15 +89616,17 @@ var init_ScanResultCard = __esm({
|
|
|
89204
89616
|
packages.length === 1 ? packages[0].findings.slice(0, 3).map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { dimColor: true, children: [
|
|
89205
89617
|
" \u2022 ",
|
|
89206
89618
|
friendlyCategory(f.category),
|
|
89207
|
-
f.title ? ` \u2014 ${f.title}` : ""
|
|
89208
|
-
] }, `f-${i}`)) : packages.slice(0, 3).map((pkg) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { dimColor: true, children: [
|
|
89619
|
+
f.title && f.title !== f.category ? ` \u2014 ${f.title}` : ""
|
|
89620
|
+
] }, `f-${i}`)) : [...packages].sort((a, b) => b.score - a.score).slice(0, 3).map((pkg) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { dimColor: true, children: [
|
|
89209
89621
|
" \u2022 ",
|
|
89210
89622
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { bold: true, children: pkg.name }),
|
|
89211
89623
|
" ",
|
|
89212
89624
|
pkg.score,
|
|
89213
|
-
"/100"
|
|
89625
|
+
"/100",
|
|
89626
|
+
pkg.findings && pkg.findings[0] ? ` \xB7 ${friendlyCategory(pkg.findings[0].category)}` : ""
|
|
89214
89627
|
] }, pkg.name)),
|
|
89215
|
-
packages.length > 3 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { dimColor: true, children: " + " + (packages.length - 3) + " more" }) : null
|
|
89628
|
+
packages.length > 3 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { dimColor: true, children: " + " + (packages.length - 3) + " more" }) : null,
|
|
89629
|
+
packages.length >= 1 && packages.some((p) => p.findings && p.findings.length > 0 && !p.findings[0].title) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { dimColor: true, children: " Sign in with `dg login` for full finding details." }) : null
|
|
89216
89630
|
] }) : verdict !== "EMPTY" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
|
|
89217
89631
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: verdictColor, bold: true, children: verdict }),
|
|
89218
89632
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { dimColor: true, children: " \xB7 " }),
|
|
@@ -89432,7 +89846,7 @@ var init_InitApp = __esm({
|
|
|
89432
89846
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Spinner2, { label: "Creating login session..." });
|
|
89433
89847
|
case "ready":
|
|
89434
89848
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
89435
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "Sign in to Dependency Guardian" }),
|
|
89849
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "Sign in to WestBayBerry Dependency Guardian" }),
|
|
89436
89850
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
|
|
89437
89851
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "Authenticate your account at:" }),
|
|
89438
89852
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "cyan", children: state.verifyUrl }),
|
|
@@ -89441,7 +89855,7 @@ var init_InitApp = __esm({
|
|
|
89441
89855
|
] });
|
|
89442
89856
|
case "waiting":
|
|
89443
89857
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
89444
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "Sign in to Dependency Guardian" }),
|
|
89858
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "Sign in to WestBayBerry Dependency Guardian" }),
|
|
89445
89859
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
|
|
89446
89860
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: state.verifyUrl }),
|
|
89447
89861
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
|
|
@@ -89453,7 +89867,7 @@ var init_InitApp = __esm({
|
|
|
89453
89867
|
"\u2713 Signed in as ",
|
|
89454
89868
|
state.email
|
|
89455
89869
|
] }),
|
|
89456
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: "Credentials saved to ~/.
|
|
89870
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: "Credentials saved to ~/.dg/config.json" })
|
|
89457
89871
|
] });
|
|
89458
89872
|
case "already_logged_in":
|
|
89459
89873
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
@@ -90123,7 +90537,7 @@ var init_InitApp = __esm({
|
|
|
90123
90537
|
] }, "p1a"),
|
|
90124
90538
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
|
|
90125
90539
|
installCmd,
|
|
90126
|
-
" them. That's where most attacks
|
|
90540
|
+
" them. That's where most attacks happen."
|
|
90127
90541
|
] }, "p1b"),
|
|
90128
90542
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }, "sp2"),
|
|
90129
90543
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FlowDiagram, {}, "diagram"),
|
|
@@ -90251,7 +90665,7 @@ var init_InitApp = __esm({
|
|
|
90251
90665
|
mood: "scanning",
|
|
90252
90666
|
color: "cyan",
|
|
90253
90667
|
scrollable: false,
|
|
90254
|
-
body: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Spinner2, { label: "
|
|
90668
|
+
body: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Spinner2, { label: "Verifying the hook..." })
|
|
90255
90669
|
}
|
|
90256
90670
|
);
|
|
90257
90671
|
case "confirm_wrap": {
|
|
@@ -90472,7 +90886,7 @@ var init_InitApp = __esm({
|
|
|
90472
90886
|
);
|
|
90473
90887
|
case "optional_protection": {
|
|
90474
90888
|
const p = state.protectInfo;
|
|
90475
|
-
const rcLine = p?.rcLine ?? "source ~/.
|
|
90889
|
+
const rcLine = p?.rcLine ?? "source ~/.dg/state/aliases.sh";
|
|
90476
90890
|
const rcFile = p?.rcFile ?? "~/.zshrc";
|
|
90477
90891
|
const shellLabel = p?.shellName && p.shellName !== "your shell rc" ? p.shellName : null;
|
|
90478
90892
|
const stackBoth = state.stackNpm && state.stackPypi;
|
|
@@ -90611,7 +91025,7 @@ var init_InitApp = __esm({
|
|
|
90611
91025
|
);
|
|
90612
91026
|
}
|
|
90613
91027
|
if (r.kind === "failed") {
|
|
90614
|
-
const rcLine = state.protectInfo?.rcLine ?? "source ~/.
|
|
91028
|
+
const rcLine = state.protectInfo?.rcLine ?? "source ~/.dg/state/aliases.sh";
|
|
90615
91029
|
const rcFile = state.protectInfo?.rcFile ?? "~/.zshrc";
|
|
90616
91030
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
90617
91031
|
Scene,
|
|
@@ -90946,7 +91360,14 @@ var init_first_run = __esm({
|
|
|
90946
91360
|
"status",
|
|
90947
91361
|
"protect",
|
|
90948
91362
|
"login",
|
|
90949
|
-
"cleanup"
|
|
91363
|
+
"cleanup",
|
|
91364
|
+
"uninstall",
|
|
91365
|
+
"init",
|
|
91366
|
+
"scan",
|
|
91367
|
+
"npm",
|
|
91368
|
+
"pip",
|
|
91369
|
+
"wrap",
|
|
91370
|
+
"publish-check"
|
|
90950
91371
|
]);
|
|
90951
91372
|
}
|
|
90952
91373
|
});
|
|
@@ -91148,7 +91569,7 @@ __export(pip_wrapper_exports, {
|
|
|
91148
91569
|
runPip: () => runPip
|
|
91149
91570
|
});
|
|
91150
91571
|
import { spawn as spawn3 } from "node:child_process";
|
|
91151
|
-
import { existsSync as
|
|
91572
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
91152
91573
|
function parsePipArgs(args) {
|
|
91153
91574
|
let dgForce = false;
|
|
91154
91575
|
let dgForceReason;
|
|
@@ -91247,7 +91668,7 @@ function parseRequirementsFile(filePath) {
|
|
|
91247
91668
|
return parseRequirementsFileInternal(filePath, /* @__PURE__ */ new Set());
|
|
91248
91669
|
}
|
|
91249
91670
|
function parseRequirementsFileInternal(filePath, visited) {
|
|
91250
|
-
if (!
|
|
91671
|
+
if (!existsSync14(filePath)) return [];
|
|
91251
91672
|
let absPath;
|
|
91252
91673
|
try {
|
|
91253
91674
|
absPath = __require("node:path").resolve(filePath);
|
|
@@ -91565,7 +91986,7 @@ var init_pip_wrapper = __esm({
|
|
|
91565
91986
|
});
|
|
91566
91987
|
|
|
91567
91988
|
// src/security/artifact_integrity.ts
|
|
91568
|
-
function
|
|
91989
|
+
function normalize3(h, algo) {
|
|
91569
91990
|
if (!h) return void 0;
|
|
91570
91991
|
const trimmed = h.trim();
|
|
91571
91992
|
const re2 = algo === "sha512" ? SHA512_HEX : SHA256_HEX;
|
|
@@ -91582,8 +92003,8 @@ function compareArtifactHashes(pairs) {
|
|
|
91582
92003
|
};
|
|
91583
92004
|
for (const p of pairs) {
|
|
91584
92005
|
const key = `${p.name}@${p.version}`;
|
|
91585
|
-
const api =
|
|
91586
|
-
const local =
|
|
92006
|
+
const api = normalize3(p.apiHash, p.algorithm);
|
|
92007
|
+
const local = normalize3(p.localHash, p.algorithm);
|
|
91587
92008
|
const apiRaw = (p.apiHash ?? "").toString();
|
|
91588
92009
|
const localRaw = (p.localHash ?? "").toString();
|
|
91589
92010
|
const apiPresent = apiRaw.length > 0;
|
|
@@ -91709,8 +92130,8 @@ var FileSavePrompt_exports = {};
|
|
|
91709
92130
|
__export(FileSavePrompt_exports, {
|
|
91710
92131
|
FileSavePrompt: () => FileSavePrompt
|
|
91711
92132
|
});
|
|
91712
|
-
import { existsSync as
|
|
91713
|
-
import { dirname as
|
|
92133
|
+
import { existsSync as existsSync15, readdirSync, writeFileSync as writeFileSync8 } from "node:fs";
|
|
92134
|
+
import { dirname as dirname12, join as join13 } from "node:path";
|
|
91714
92135
|
function listDirectory(dir) {
|
|
91715
92136
|
try {
|
|
91716
92137
|
const raw = readdirSync(dir, { withFileTypes: true });
|
|
@@ -91718,7 +92139,7 @@ function listDirectory(dir) {
|
|
|
91718
92139
|
if (a.isDirectory !== b.isDirectory) return a.isDirectory ? -1 : 1;
|
|
91719
92140
|
return a.name.localeCompare(b.name);
|
|
91720
92141
|
});
|
|
91721
|
-
if (
|
|
92142
|
+
if (dirname12(dir) !== dir) {
|
|
91722
92143
|
entries.unshift({ name: "..", isDirectory: true });
|
|
91723
92144
|
}
|
|
91724
92145
|
return entries;
|
|
@@ -91810,13 +92231,13 @@ var init_FileSavePrompt = __esm({
|
|
|
91810
92231
|
if (state.focus === "filename") {
|
|
91811
92232
|
if (key.return) {
|
|
91812
92233
|
const fullName = ensureJsonExtension(state.filename);
|
|
91813
|
-
const fullPath =
|
|
91814
|
-
if (!state.confirmOverwrite &&
|
|
92234
|
+
const fullPath = join13(state.directory, fullName);
|
|
92235
|
+
if (!state.confirmOverwrite && existsSync15(fullPath)) {
|
|
91815
92236
|
dispatch({ type: "CONFIRM_OVERWRITE" });
|
|
91816
92237
|
return;
|
|
91817
92238
|
}
|
|
91818
92239
|
try {
|
|
91819
|
-
|
|
92240
|
+
writeFileSync8(fullPath, json + "\n");
|
|
91820
92241
|
} catch (err) {
|
|
91821
92242
|
const msg = err instanceof Error ? err.message : String(err);
|
|
91822
92243
|
dispatch({ type: "SET_ERROR", error: `Write failed: ${msg}` });
|
|
@@ -92068,25 +92489,24 @@ __export(static_output_exports, {
|
|
|
92068
92489
|
runStaticNpm: () => runStaticNpm,
|
|
92069
92490
|
runStaticPip: () => runStaticPip
|
|
92070
92491
|
});
|
|
92071
|
-
import { writeFileSync as
|
|
92072
|
-
import { resolve as
|
|
92073
|
-
import { homedir as homedir6 } from "node:os";
|
|
92492
|
+
import { writeFileSync as writeFileSync9, readFileSync as readFileSync12, existsSync as existsSync16, mkdirSync as mkdirSync8, lstatSync as lstatSync4 } from "node:fs";
|
|
92493
|
+
import { resolve as resolvePath2, dirname as dirname13 } from "node:path";
|
|
92074
92494
|
function loadPackageLockJson(cwd2 = process.cwd()) {
|
|
92075
|
-
const path3 =
|
|
92076
|
-
if (!
|
|
92495
|
+
const path3 = resolvePath2(cwd2, "package-lock.json");
|
|
92496
|
+
if (!existsSync16(path3)) return null;
|
|
92077
92497
|
try {
|
|
92078
92498
|
const st = lstatSync4(path3);
|
|
92079
92499
|
if (!st.isFile()) return null;
|
|
92080
92500
|
if (st.size > MAX_PACKAGE_LOCK_BYTES) return null;
|
|
92081
|
-
return JSON.parse(
|
|
92501
|
+
return JSON.parse(readFileSync12(path3, "utf8"));
|
|
92082
92502
|
} catch {
|
|
92083
92503
|
return null;
|
|
92084
92504
|
}
|
|
92085
92505
|
}
|
|
92086
92506
|
function writeJsonFile(filepath, json) {
|
|
92087
|
-
const resolved =
|
|
92507
|
+
const resolved = resolvePath2(filepath);
|
|
92088
92508
|
try {
|
|
92089
|
-
|
|
92509
|
+
writeFileSync9(resolved, json + "\n");
|
|
92090
92510
|
process.stderr.write(import_chalk8.default.green(` \u2713 Saved to ${resolved}
|
|
92091
92511
|
|
|
92092
92512
|
`));
|
|
@@ -92156,12 +92576,12 @@ function printTrialBanner(result, config3) {
|
|
|
92156
92576
|
if (config3?.json || config3?.ci || config3?.quiet) return;
|
|
92157
92577
|
if (process.env.CI === "1" || process.env.CI === "true") return;
|
|
92158
92578
|
try {
|
|
92159
|
-
const stampPath =
|
|
92160
|
-
const lastMs =
|
|
92579
|
+
const stampPath = dgStatePath("trial-banner");
|
|
92580
|
+
const lastMs = existsSync16(stampPath) ? Number(readFileSync12(stampPath, "utf-8").trim()) || 0 : 0;
|
|
92161
92581
|
const now = Date.now();
|
|
92162
92582
|
if (now - lastMs < NUDGE_INTERVAL_MS) return;
|
|
92163
|
-
|
|
92164
|
-
|
|
92583
|
+
mkdirSync8(dirname13(stampPath), { recursive: true, mode: 448 });
|
|
92584
|
+
writeFileSync9(stampPath, String(now) + "\n");
|
|
92165
92585
|
} catch {
|
|
92166
92586
|
return;
|
|
92167
92587
|
}
|
|
@@ -93100,6 +93520,7 @@ var init_static_output = __esm({
|
|
|
93100
93520
|
"src/formatters/static-output.ts"() {
|
|
93101
93521
|
"use strict";
|
|
93102
93522
|
import_chalk8 = __toESM(require_source());
|
|
93523
|
+
init_paths();
|
|
93103
93524
|
init_client3();
|
|
93104
93525
|
init_auth();
|
|
93105
93526
|
init_lockfile();
|
|
@@ -93117,13 +93538,13 @@ __export(status_exports, {
|
|
|
93117
93538
|
handleStatusCommand: () => handleStatusCommand
|
|
93118
93539
|
});
|
|
93119
93540
|
async function handleStatusCommand(cliVersion) {
|
|
93120
|
-
const
|
|
93541
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
93121
93542
|
const apiKey = getStoredApiKey();
|
|
93122
93543
|
process.stderr.write("\n");
|
|
93123
|
-
process.stderr.write(
|
|
93544
|
+
process.stderr.write(chalk17.bold(" Dependency Guardian \u2014 coverage status\n\n"));
|
|
93124
93545
|
if (!apiKey) {
|
|
93125
93546
|
process.stderr.write(
|
|
93126
|
-
` ${
|
|
93547
|
+
` ${chalk17.yellow("\xB7")} ${chalk17.bold("Auth")} ` + chalk17.dim("anonymous \u2014 `dg login` (free) for saved scan history, dashboard, and finding titles\n")
|
|
93127
93548
|
);
|
|
93128
93549
|
} else {
|
|
93129
93550
|
let tierLine = "signed in";
|
|
@@ -93149,29 +93570,29 @@ async function handleStatusCommand(cliVersion) {
|
|
|
93149
93570
|
} catch {
|
|
93150
93571
|
tierLine = "signed in (could not reach API)";
|
|
93151
93572
|
}
|
|
93152
|
-
process.stderr.write(` ${
|
|
93573
|
+
process.stderr.write(` ${chalk17.green("\u2713")} ${chalk17.bold("Auth")} ` + chalk17.dim(tierLine + "\n"));
|
|
93153
93574
|
}
|
|
93154
93575
|
const cwd2 = process.cwd();
|
|
93155
93576
|
const protect = readProtectConfig(cwd2);
|
|
93156
93577
|
if (protect && protect.enabled) {
|
|
93157
93578
|
process.stderr.write(
|
|
93158
|
-
` ${
|
|
93579
|
+
` ${chalk17.green("\u2713")} ${chalk17.bold("Protect")} ` + chalk17.dim(`enabled in this project (mode=${protect.mode}${protect.strict ? ", strict" : ""})
|
|
93159
93580
|
`)
|
|
93160
93581
|
);
|
|
93161
93582
|
} else {
|
|
93162
93583
|
process.stderr.write(
|
|
93163
|
-
` ${
|
|
93584
|
+
` ${chalk17.yellow("\xB7")} ${chalk17.bold("Protect")} ` + chalk17.dim("not enabled in this project \u2014 run `dg protect init` for opt-in protection\n")
|
|
93164
93585
|
);
|
|
93165
93586
|
}
|
|
93166
93587
|
let hookLine = "no pre-commit hook \u2014 `dg hook install` to gate commits";
|
|
93167
93588
|
let hookOk = false;
|
|
93168
93589
|
try {
|
|
93169
|
-
const { existsSync:
|
|
93170
|
-
const { join:
|
|
93171
|
-
const candidates = [
|
|
93590
|
+
const { existsSync: existsSync21, readFileSync: readFileSync14 } = await import("node:fs");
|
|
93591
|
+
const { join: join16 } = await import("node:path");
|
|
93592
|
+
const candidates = [join16(cwd2, ".husky", "pre-commit"), join16(cwd2, ".git", "hooks", "pre-commit")];
|
|
93172
93593
|
for (const path3 of candidates) {
|
|
93173
|
-
if (
|
|
93174
|
-
const content =
|
|
93594
|
+
if (existsSync21(path3)) {
|
|
93595
|
+
const content = readFileSync14(path3, "utf-8");
|
|
93175
93596
|
if (content.includes("dependency-guardian")) {
|
|
93176
93597
|
hookLine = `installed in ${path3}`;
|
|
93177
93598
|
hookOk = true;
|
|
@@ -93182,7 +93603,7 @@ async function handleStatusCommand(cliVersion) {
|
|
|
93182
93603
|
} catch {
|
|
93183
93604
|
}
|
|
93184
93605
|
process.stderr.write(
|
|
93185
|
-
` ${hookOk ?
|
|
93606
|
+
` ${hookOk ? chalk17.green("\u2713") : chalk17.yellow("\xB7")} ${chalk17.bold("Hook")} ` + chalk17.dim(hookLine + "\n")
|
|
93186
93607
|
);
|
|
93187
93608
|
try {
|
|
93188
93609
|
const banner = await checkForUpdate(cliVersion).catch(() => null);
|
|
@@ -93190,20 +93611,20 @@ async function handleStatusCommand(cliVersion) {
|
|
|
93190
93611
|
const m = banner.match(/(\d+\.\d+\.\d+)\s+→\s+(\d+\.\d+\.\d+)/);
|
|
93191
93612
|
const latest = m ? m[2] : "newer";
|
|
93192
93613
|
process.stderr.write(
|
|
93193
|
-
` ${
|
|
93614
|
+
` ${chalk17.yellow("!")} ${chalk17.bold("Update")} ` + chalk17.dim(`available \u2014 ${cliVersion} \u2192 ${latest} (run \`dg update\`)
|
|
93194
93615
|
`)
|
|
93195
93616
|
);
|
|
93196
93617
|
} else {
|
|
93197
|
-
process.stderr.write(` ${
|
|
93618
|
+
process.stderr.write(` ${chalk17.green("\u2713")} ${chalk17.bold("Update")} ` + chalk17.dim(`on latest (${cliVersion})
|
|
93198
93619
|
`));
|
|
93199
93620
|
}
|
|
93200
93621
|
} catch {
|
|
93201
93622
|
}
|
|
93202
93623
|
try {
|
|
93203
|
-
const { execFileSync:
|
|
93624
|
+
const { execFileSync: execFileSync5 } = await import("node:child_process");
|
|
93204
93625
|
const npmV = (() => {
|
|
93205
93626
|
try {
|
|
93206
|
-
return
|
|
93627
|
+
return execFileSync5("npm", ["--version"], { encoding: "utf-8", timeout: 5e3 }).trim();
|
|
93207
93628
|
} catch {
|
|
93208
93629
|
return null;
|
|
93209
93630
|
}
|
|
@@ -93212,21 +93633,21 @@ async function handleStatusCommand(cliVersion) {
|
|
|
93212
93633
|
const pipV = await pipVersion2();
|
|
93213
93634
|
const pipProbe = pipV ? await pipSupportsDryRunReport2() : null;
|
|
93214
93635
|
const npmLine = npmV ? `npm ${npmV} (transitive scan supported)` : "npm not found on PATH";
|
|
93215
|
-
const npmGlyph = npmV ?
|
|
93216
|
-
process.stderr.write(` ${npmGlyph} ${
|
|
93636
|
+
const npmGlyph = npmV ? chalk17.green("\u2713") : chalk17.yellow("\xB7");
|
|
93637
|
+
process.stderr.write(` ${npmGlyph} ${chalk17.bold("npm")} ` + chalk17.dim(npmLine + "\n"));
|
|
93217
93638
|
let pipLine;
|
|
93218
93639
|
let pipGlyph;
|
|
93219
93640
|
if (!pipV) {
|
|
93220
93641
|
pipLine = "pip not found on PATH (Python projects won't scan)";
|
|
93221
|
-
pipGlyph =
|
|
93642
|
+
pipGlyph = chalk17.yellow("\xB7");
|
|
93222
93643
|
} else if (pipProbe?.ok) {
|
|
93223
93644
|
pipLine = `pip ${pipV} (transitive scan supported)`;
|
|
93224
|
-
pipGlyph =
|
|
93645
|
+
pipGlyph = chalk17.green("\u2713");
|
|
93225
93646
|
} else {
|
|
93226
93647
|
pipLine = `pip ${pipV} \u2014 transitive scan unavailable (${pipProbe?.reason ?? "old pip"}; \`pip install -U pip\`)`;
|
|
93227
|
-
pipGlyph =
|
|
93648
|
+
pipGlyph = chalk17.yellow("!");
|
|
93228
93649
|
}
|
|
93229
|
-
process.stderr.write(` ${pipGlyph} ${
|
|
93650
|
+
process.stderr.write(` ${pipGlyph} ${chalk17.bold("pip")} ` + chalk17.dim(pipLine + "\n"));
|
|
93230
93651
|
} catch {
|
|
93231
93652
|
}
|
|
93232
93653
|
process.stderr.write("\n");
|
|
@@ -93252,8 +93673,8 @@ __export(publish_check_exports, {
|
|
|
93252
93673
|
summarize: () => summarize
|
|
93253
93674
|
});
|
|
93254
93675
|
import { spawn as spawn4 } from "node:child_process";
|
|
93255
|
-
import { readFileSync as
|
|
93256
|
-
import { join as
|
|
93676
|
+
import { readFileSync as readFileSync13, existsSync as existsSync17, readdirSync as readdirSync2 } from "node:fs";
|
|
93677
|
+
import { join as join14, basename as basename4 } from "node:path";
|
|
93257
93678
|
import { createGunzip } from "node:zlib";
|
|
93258
93679
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
93259
93680
|
function sanitizeSnippet(s, max = 40) {
|
|
@@ -93300,7 +93721,7 @@ async function npmPackDryRun(cwd2 = process.cwd()) {
|
|
|
93300
93721
|
}));
|
|
93301
93722
|
let packageJson;
|
|
93302
93723
|
try {
|
|
93303
|
-
const raw =
|
|
93724
|
+
const raw = readFileSync13(join14(cwd2, "package.json"), "utf-8");
|
|
93304
93725
|
packageJson = JSON.parse(raw);
|
|
93305
93726
|
} catch {
|
|
93306
93727
|
}
|
|
@@ -93312,9 +93733,9 @@ async function npmPackDryRun(cwd2 = process.cwd()) {
|
|
|
93312
93733
|
});
|
|
93313
93734
|
}
|
|
93314
93735
|
function findPypiArtifacts(cwd2 = process.cwd()) {
|
|
93315
|
-
const dist =
|
|
93316
|
-
if (!
|
|
93317
|
-
return readdirSync2(dist).filter((f) => f.endsWith(".tar.gz") || f.endsWith(".whl")).map((f) =>
|
|
93736
|
+
const dist = join14(cwd2, "dist");
|
|
93737
|
+
if (!existsSync17(dist)) return [];
|
|
93738
|
+
return readdirSync2(dist).filter((f) => f.endsWith(".tar.gz") || f.endsWith(".whl")).map((f) => join14(dist, f));
|
|
93318
93739
|
}
|
|
93319
93740
|
function scanPayload(files) {
|
|
93320
93741
|
const findings = [];
|
|
@@ -93388,7 +93809,7 @@ async function runNpmPublishCheck(cwd2 = process.cwd()) {
|
|
|
93388
93809
|
const payload = pack.files.map((f) => ({
|
|
93389
93810
|
path: f.path,
|
|
93390
93811
|
size: f.size,
|
|
93391
|
-
read: () =>
|
|
93812
|
+
read: () => readFileSync13(join14(cwd2, f.path))
|
|
93392
93813
|
}));
|
|
93393
93814
|
const findings = scanPayload(payload);
|
|
93394
93815
|
const scripts = pack.packageJson?.scripts ?? {};
|
|
@@ -93609,11 +94030,6 @@ var init_publish_check = __esm({
|
|
|
93609
94030
|
recommendation: "Revoke the token at github.com/settings/tokens and remove the file from the payload."
|
|
93610
94031
|
},
|
|
93611
94032
|
{
|
|
93612
|
-
// Slack tokens come in several real shapes:
|
|
93613
|
-
// xoxb-{teamId}-{botId}-{secret} (legacy 3-seg)
|
|
93614
|
-
// xoxa-2-{teamId}-{userId}-{secret} (4-seg)
|
|
93615
|
-
// xoxp-{N}-{N}-{N}-{hex} (4-seg user)
|
|
93616
|
-
// Accept ≥2 numeric segments + an alphanumeric tail of length ≥10.
|
|
93617
94033
|
re: /xox[abp]-[0-9]+-[0-9]+(-[0-9]+)?-[A-Za-z0-9]{10,}/,
|
|
93618
94034
|
category: "bundled-secret",
|
|
93619
94035
|
severity: 5,
|
|
@@ -93646,9 +94062,7 @@ __export(cleanup_exports, {
|
|
|
93646
94062
|
handleCleanupCommand: () => handleCleanupCommand,
|
|
93647
94063
|
runCleanup: () => runCleanup
|
|
93648
94064
|
});
|
|
93649
|
-
import { existsSync as
|
|
93650
|
-
import { join as join17 } from "node:path";
|
|
93651
|
-
import { homedir as homedir7 } from "node:os";
|
|
94065
|
+
import { existsSync as existsSync18, unlinkSync as unlinkSync6 } from "node:fs";
|
|
93652
94066
|
async function confirm(prompt) {
|
|
93653
94067
|
process.stderr.write(prompt);
|
|
93654
94068
|
return new Promise((resolve3) => {
|
|
@@ -93679,16 +94093,19 @@ async function revokeKey(apiKey) {
|
|
|
93679
94093
|
}
|
|
93680
94094
|
}
|
|
93681
94095
|
async function runCleanup(opts = {}) {
|
|
94096
|
+
const configPath2 = dgConfigPath();
|
|
94097
|
+
const legacyDgrc = legacyPaths().dgrc;
|
|
93682
94098
|
process.stderr.write(import_chalk9.default.bold("\n Dependency Guardian cleanup\n\n"));
|
|
94099
|
+
process.stderr.write(import_chalk9.default.dim(" Note: `dg cleanup` is deprecated. Use `dg uninstall` for a full removal\n"));
|
|
94100
|
+
process.stderr.write(import_chalk9.default.dim(" that also strips per-repo git hooks and shell-rc lines.\n\n"));
|
|
93683
94101
|
process.stderr.write(" This will:\n");
|
|
93684
94102
|
process.stderr.write(" 1. Revoke this device's API key on the server\n");
|
|
93685
|
-
process.stderr.write(` 2. Remove ${
|
|
94103
|
+
process.stderr.write(` 2. Remove ${configPath2}
|
|
93686
94104
|
`);
|
|
93687
|
-
process.stderr.write(" 3. Remove the shell-alias snippet
|
|
93688
|
-
process.stderr.write(" 4. Remove any legacy .dgprotect.json in the current directory\n\n");
|
|
94105
|
+
process.stderr.write(" 3. Remove the shell-alias snippet\n\n");
|
|
93689
94106
|
process.stderr.write(import_chalk9.default.dim(" Git pre-commit hooks in your projects are NOT removed.\n"));
|
|
93690
|
-
process.stderr.write(import_chalk9.default.dim(" Run `dg
|
|
93691
|
-
process.stderr.write(import_chalk9.default.dim("
|
|
94107
|
+
process.stderr.write(import_chalk9.default.dim(" Run `dg uninstall` to remove every dg artifact, or `dg hook uninstall`\n"));
|
|
94108
|
+
process.stderr.write(import_chalk9.default.dim(" per repo to remove just the pre-commit hooks.\n\n"));
|
|
93692
94109
|
if (!opts.assumeYes) {
|
|
93693
94110
|
if (!process.stdin.isTTY) {
|
|
93694
94111
|
process.stderr.write(import_chalk9.default.yellow(" Non-interactive shell \u2014 pass --yes to confirm without prompting.\n\n"));
|
|
@@ -93712,18 +94129,17 @@ async function runCleanup(opts = {}) {
|
|
|
93712
94129
|
} else {
|
|
93713
94130
|
process.stderr.write(import_chalk9.default.dim(" \xB7 No saved API key found\n"));
|
|
93714
94131
|
}
|
|
93715
|
-
|
|
93716
|
-
|
|
93717
|
-
|
|
93718
|
-
|
|
94132
|
+
for (const p of [configPath2, legacyDgrc]) {
|
|
94133
|
+
if (existsSync18(p)) {
|
|
94134
|
+
try {
|
|
94135
|
+
unlinkSync6(p);
|
|
94136
|
+
process.stderr.write(import_chalk9.default.green(" \u2713 ") + `Removed ${p}
|
|
93719
94137
|
`);
|
|
93720
|
-
|
|
93721
|
-
|
|
94138
|
+
} catch (e) {
|
|
94139
|
+
process.stderr.write(import_chalk9.default.red(" \u2718 ") + `Couldn't remove ${p}: ${e.message}
|
|
93722
94140
|
`);
|
|
94141
|
+
}
|
|
93723
94142
|
}
|
|
93724
|
-
} else {
|
|
93725
|
-
process.stderr.write(import_chalk9.default.dim(` \xB7 ${DGRC_PATH} already absent
|
|
93726
|
-
`));
|
|
93727
94143
|
}
|
|
93728
94144
|
process.stderr.write("\n");
|
|
93729
94145
|
await runProtectOff(process.cwd(), { removeShell: true });
|
|
@@ -93735,7 +94151,7 @@ async function handleCleanupCommand(args) {
|
|
|
93735
94151
|
const assumeYes = args.includes("--yes") || args.includes("-y");
|
|
93736
94152
|
return runCleanup({ assumeYes });
|
|
93737
94153
|
}
|
|
93738
|
-
var import_chalk9
|
|
94154
|
+
var import_chalk9;
|
|
93739
94155
|
var init_cleanup = __esm({
|
|
93740
94156
|
"src/commands/cleanup.ts"() {
|
|
93741
94157
|
"use strict";
|
|
@@ -93743,7 +94159,572 @@ var init_cleanup = __esm({
|
|
|
93743
94159
|
init_protect();
|
|
93744
94160
|
init_auth();
|
|
93745
94161
|
init_config();
|
|
93746
|
-
|
|
94162
|
+
init_paths();
|
|
94163
|
+
}
|
|
94164
|
+
});
|
|
94165
|
+
|
|
94166
|
+
// src/commands/uninstall.ts
|
|
94167
|
+
var uninstall_exports = {};
|
|
94168
|
+
__export(uninstall_exports, {
|
|
94169
|
+
handleUninstallCommand: () => handleUninstallCommand,
|
|
94170
|
+
parseUninstallArgs: () => parseUninstallArgs,
|
|
94171
|
+
runUninstall: () => runUninstall
|
|
94172
|
+
});
|
|
94173
|
+
import { existsSync as existsSync19, rmSync as rmSync3, unlinkSync as unlinkSync7, statSync as statSync5 } from "node:fs";
|
|
94174
|
+
function parseUninstallArgs(args) {
|
|
94175
|
+
return {
|
|
94176
|
+
assumeYes: args.includes("--yes") || args.includes("-y"),
|
|
94177
|
+
dryRun: args.includes("--dry-run"),
|
|
94178
|
+
soft: args.includes("--soft"),
|
|
94179
|
+
keepHooks: args.includes("--keep-hooks")
|
|
94180
|
+
};
|
|
94181
|
+
}
|
|
94182
|
+
function safeExists(p) {
|
|
94183
|
+
try {
|
|
94184
|
+
return existsSync19(p);
|
|
94185
|
+
} catch {
|
|
94186
|
+
return false;
|
|
94187
|
+
}
|
|
94188
|
+
}
|
|
94189
|
+
function buildPlan(opts) {
|
|
94190
|
+
const p = dgPaths();
|
|
94191
|
+
const legacy = legacyPaths();
|
|
94192
|
+
const plan = {
|
|
94193
|
+
configFiles: [],
|
|
94194
|
+
cacheDir: null,
|
|
94195
|
+
stateDir: null,
|
|
94196
|
+
rootDir: null,
|
|
94197
|
+
legacyFiles: [],
|
|
94198
|
+
legacyDirs: [],
|
|
94199
|
+
hooks: [],
|
|
94200
|
+
rcCleanup: false
|
|
94201
|
+
};
|
|
94202
|
+
if (safeExists(p.config)) plan.configFiles.push(p.config);
|
|
94203
|
+
if (!opts.soft) {
|
|
94204
|
+
if (safeExists(p.cacheDir)) plan.cacheDir = p.cacheDir;
|
|
94205
|
+
if (safeExists(p.stateDir)) plan.stateDir = p.stateDir;
|
|
94206
|
+
if (safeExists(p.root)) plan.rootDir = p.root;
|
|
94207
|
+
for (const f of [legacy.dgrc, legacy.updateCheck]) {
|
|
94208
|
+
if (safeExists(f)) plan.legacyFiles.push(f);
|
|
94209
|
+
}
|
|
94210
|
+
if (safeExists(legacy.cacheDir)) plan.legacyDirs.push(legacy.cacheDir);
|
|
94211
|
+
if (!opts.keepHooks) {
|
|
94212
|
+
plan.hooks = listEntries();
|
|
94213
|
+
}
|
|
94214
|
+
plan.rcCleanup = true;
|
|
94215
|
+
}
|
|
94216
|
+
return plan;
|
|
94217
|
+
}
|
|
94218
|
+
function printPlan(plan, opts) {
|
|
94219
|
+
process.stderr.write(import_chalk10.default.bold("\n Dependency Guardian uninstall\n\n"));
|
|
94220
|
+
if (opts.soft) {
|
|
94221
|
+
process.stderr.write(import_chalk10.default.dim(" Soft mode: removing config + api key only.\n\n"));
|
|
94222
|
+
} else if (opts.dryRun) {
|
|
94223
|
+
process.stderr.write(import_chalk10.default.yellow(" Dry run \u2014 no files will be touched.\n\n"));
|
|
94224
|
+
}
|
|
94225
|
+
process.stderr.write(" Will remove:\n");
|
|
94226
|
+
if (plan.configFiles.length > 0) {
|
|
94227
|
+
for (const f of plan.configFiles) process.stderr.write(` ${f}
|
|
94228
|
+
`);
|
|
94229
|
+
}
|
|
94230
|
+
if (plan.rootDir && !opts.soft) {
|
|
94231
|
+
process.stderr.write(` ${plan.rootDir}/ (entire tree)
|
|
94232
|
+
`);
|
|
94233
|
+
}
|
|
94234
|
+
for (const f of plan.legacyFiles) process.stderr.write(` ${f} (legacy)
|
|
94235
|
+
`);
|
|
94236
|
+
for (const d of plan.legacyDirs) process.stderr.write(` ${d}/ (legacy)
|
|
94237
|
+
`);
|
|
94238
|
+
if (plan.hooks.length > 0) {
|
|
94239
|
+
process.stderr.write(` pre-commit hooks in ${plan.hooks.length} repo(s):
|
|
94240
|
+
`);
|
|
94241
|
+
for (const h of plan.hooks) {
|
|
94242
|
+
process.stderr.write(import_chalk10.default.dim(` - ${h.repoPath} (${h.framework})
|
|
94243
|
+
`));
|
|
94244
|
+
}
|
|
94245
|
+
} else if (!opts.keepHooks && !opts.soft) {
|
|
94246
|
+
process.stderr.write(import_chalk10.default.dim(` pre-commit hooks: none registered
|
|
94247
|
+
`));
|
|
94248
|
+
}
|
|
94249
|
+
if (plan.rcCleanup) {
|
|
94250
|
+
process.stderr.write(` sentinel block in your shell rc files (~/.zshrc, ~/.bashrc, ~/.bash_profile, ~/.profile)
|
|
94251
|
+
`);
|
|
94252
|
+
}
|
|
94253
|
+
process.stderr.write(" Will also:\n");
|
|
94254
|
+
process.stderr.write(" revoke this device's API key on the server (best-effort, 5s timeout)\n\n");
|
|
94255
|
+
if (!opts.soft) {
|
|
94256
|
+
process.stderr.write(import_chalk10.default.dim(
|
|
94257
|
+
" Note: this does NOT run `npm uninstall -g @westbayberry/dg`.\n After confirming, run that separately to remove the binary itself.\n\n"
|
|
94258
|
+
));
|
|
94259
|
+
}
|
|
94260
|
+
}
|
|
94261
|
+
async function confirm2(prompt) {
|
|
94262
|
+
if (!process.stdin.isTTY) return false;
|
|
94263
|
+
process.stderr.write(prompt);
|
|
94264
|
+
return new Promise((resolve3) => {
|
|
94265
|
+
let buf = "";
|
|
94266
|
+
const onData = (chunk) => {
|
|
94267
|
+
buf += chunk.toString("utf8");
|
|
94268
|
+
const idx = buf.indexOf("\n");
|
|
94269
|
+
if (idx < 0) return;
|
|
94270
|
+
process.stdin.off("data", onData);
|
|
94271
|
+
const ans = buf.slice(0, idx).trim().toLowerCase();
|
|
94272
|
+
resolve3(ans === "y" || ans === "yes");
|
|
94273
|
+
};
|
|
94274
|
+
process.stdin.on("data", onData);
|
|
94275
|
+
});
|
|
94276
|
+
}
|
|
94277
|
+
async function revokeApiKey(apiKey) {
|
|
94278
|
+
try {
|
|
94279
|
+
const config3 = parseConfig(["node", "dg", "uninstall"], false);
|
|
94280
|
+
const ctrl = new AbortController();
|
|
94281
|
+
const timer = setTimeout(() => ctrl.abort(), REVOKE_TIMEOUT_MS);
|
|
94282
|
+
let resp;
|
|
94283
|
+
try {
|
|
94284
|
+
resp = await fetch(`${config3.apiUrl}/v1/auth/revoke`, {
|
|
94285
|
+
method: "POST",
|
|
94286
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
94287
|
+
signal: ctrl.signal
|
|
94288
|
+
});
|
|
94289
|
+
} finally {
|
|
94290
|
+
clearTimeout(timer);
|
|
94291
|
+
}
|
|
94292
|
+
if (resp.ok || resp.status === 401) return { ok: true };
|
|
94293
|
+
return { ok: false, reason: `HTTP ${resp.status}` };
|
|
94294
|
+
} catch (e) {
|
|
94295
|
+
return { ok: false, reason: e.message };
|
|
94296
|
+
}
|
|
94297
|
+
}
|
|
94298
|
+
function rmFile(path3) {
|
|
94299
|
+
try {
|
|
94300
|
+
unlinkSync7(path3);
|
|
94301
|
+
return { ok: true };
|
|
94302
|
+
} catch (e) {
|
|
94303
|
+
const code = e.code;
|
|
94304
|
+
if (code === "ENOENT") return { ok: true };
|
|
94305
|
+
return { ok: false, reason: e.message };
|
|
94306
|
+
}
|
|
94307
|
+
}
|
|
94308
|
+
function rmTree(path3) {
|
|
94309
|
+
try {
|
|
94310
|
+
rmSync3(path3, { recursive: true, force: true });
|
|
94311
|
+
return { ok: true };
|
|
94312
|
+
} catch (e) {
|
|
94313
|
+
return { ok: false, reason: e.message };
|
|
94314
|
+
}
|
|
94315
|
+
}
|
|
94316
|
+
function isWritableTarget(path3) {
|
|
94317
|
+
try {
|
|
94318
|
+
const st = statSync5(path3);
|
|
94319
|
+
return st.isDirectory() || st.isFile();
|
|
94320
|
+
} catch {
|
|
94321
|
+
return false;
|
|
94322
|
+
}
|
|
94323
|
+
}
|
|
94324
|
+
async function runUninstall(args) {
|
|
94325
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
94326
|
+
process.stdout.write(USAGE4);
|
|
94327
|
+
return 0;
|
|
94328
|
+
}
|
|
94329
|
+
const opts = parseUninstallArgs(args);
|
|
94330
|
+
const plan = buildPlan(opts);
|
|
94331
|
+
printPlan(plan, opts);
|
|
94332
|
+
if (opts.dryRun) {
|
|
94333
|
+
process.stderr.write(import_chalk10.default.dim(" Dry run: nothing was changed.\n\n"));
|
|
94334
|
+
return 0;
|
|
94335
|
+
}
|
|
94336
|
+
if (!opts.assumeYes) {
|
|
94337
|
+
if (!process.stdin.isTTY) {
|
|
94338
|
+
process.stderr.write(import_chalk10.default.yellow(" Non-interactive shell \u2014 pass --yes to proceed.\n\n"));
|
|
94339
|
+
return 1;
|
|
94340
|
+
}
|
|
94341
|
+
const ok = await confirm2(" Proceed? [y/N] ");
|
|
94342
|
+
if (!ok) {
|
|
94343
|
+
process.stderr.write(import_chalk10.default.dim("\n Cancelled. Nothing changed.\n\n"));
|
|
94344
|
+
return 0;
|
|
94345
|
+
}
|
|
94346
|
+
process.stderr.write("\n");
|
|
94347
|
+
}
|
|
94348
|
+
const apiKey = getStoredApiKey();
|
|
94349
|
+
if (apiKey) {
|
|
94350
|
+
const r = await revokeApiKey(apiKey);
|
|
94351
|
+
if (r.ok) {
|
|
94352
|
+
process.stderr.write(import_chalk10.default.green(" \u2713 ") + "Revoked API key server-side\n");
|
|
94353
|
+
} else {
|
|
94354
|
+
process.stderr.write(
|
|
94355
|
+
import_chalk10.default.yellow(" \u26A0 ") + `Could not revoke API key (${r.reason ?? "unknown"}); local removal continues
|
|
94356
|
+
`
|
|
94357
|
+
);
|
|
94358
|
+
}
|
|
94359
|
+
} else {
|
|
94360
|
+
process.stderr.write(import_chalk10.default.dim(" \xB7 No stored API key\n"));
|
|
94361
|
+
}
|
|
94362
|
+
if (!opts.keepHooks && !opts.soft) {
|
|
94363
|
+
for (const h of plan.hooks) {
|
|
94364
|
+
if (!existsSync19(h.repoPath)) {
|
|
94365
|
+
process.stderr.write(import_chalk10.default.dim(` \xB7 ${h.repoPath} no longer exists \u2014 skipping registered hook
|
|
94366
|
+
`));
|
|
94367
|
+
continue;
|
|
94368
|
+
}
|
|
94369
|
+
try {
|
|
94370
|
+
const r = stripDgFromHookFile(h.hookPath, h.framework, h.repoPath);
|
|
94371
|
+
if (r.status === "removed") {
|
|
94372
|
+
process.stderr.write(import_chalk10.default.green(" \u2713 ") + `Removed hook ${h.hookPath}
|
|
94373
|
+
`);
|
|
94374
|
+
} else {
|
|
94375
|
+
process.stderr.write(import_chalk10.default.dim(` \xB7 No dg hook found at ${h.hookPath}
|
|
94376
|
+
`));
|
|
94377
|
+
}
|
|
94378
|
+
} catch (e) {
|
|
94379
|
+
process.stderr.write(
|
|
94380
|
+
import_chalk10.default.yellow(" \u26A0 ") + `Could not remove hook ${h.hookPath}: ${e.message}
|
|
94381
|
+
`
|
|
94382
|
+
);
|
|
94383
|
+
}
|
|
94384
|
+
}
|
|
94385
|
+
}
|
|
94386
|
+
if (plan.rcCleanup) {
|
|
94387
|
+
try {
|
|
94388
|
+
const r = stripAliasSourceFromRc();
|
|
94389
|
+
for (const f of r.modified) {
|
|
94390
|
+
process.stderr.write(import_chalk10.default.green(" \u2713 ") + `Stripped sentinel block from ${f}
|
|
94391
|
+
`);
|
|
94392
|
+
}
|
|
94393
|
+
for (const f of r.manualReviewNeeded) {
|
|
94394
|
+
process.stderr.write(
|
|
94395
|
+
import_chalk10.default.yellow(" \u26A0 ") + `${f} has an open sentinel but no close \u2014 leaving it; remove the block by hand
|
|
94396
|
+
`
|
|
94397
|
+
);
|
|
94398
|
+
}
|
|
94399
|
+
} catch (e) {
|
|
94400
|
+
process.stderr.write(import_chalk10.default.yellow(` \u26A0 Shell-rc cleanup failed: ${e.message}
|
|
94401
|
+
`));
|
|
94402
|
+
}
|
|
94403
|
+
}
|
|
94404
|
+
if (opts.soft) {
|
|
94405
|
+
for (const f of plan.configFiles) {
|
|
94406
|
+
const r = rmFile(f);
|
|
94407
|
+
if (r.ok) process.stderr.write(import_chalk10.default.green(" \u2713 ") + `Removed ${f}
|
|
94408
|
+
`);
|
|
94409
|
+
else process.stderr.write(import_chalk10.default.red(" \u2718 ") + `${f}: ${r.reason}
|
|
94410
|
+
`);
|
|
94411
|
+
}
|
|
94412
|
+
} else {
|
|
94413
|
+
for (const f of plan.legacyFiles) {
|
|
94414
|
+
if (!isWritableTarget(f)) continue;
|
|
94415
|
+
const r = rmFile(f);
|
|
94416
|
+
if (r.ok) process.stderr.write(import_chalk10.default.green(" \u2713 ") + `Removed ${f}
|
|
94417
|
+
`);
|
|
94418
|
+
else process.stderr.write(import_chalk10.default.red(" \u2718 ") + `${f}: ${r.reason}
|
|
94419
|
+
`);
|
|
94420
|
+
}
|
|
94421
|
+
for (const d of plan.legacyDirs) {
|
|
94422
|
+
if (!isWritableTarget(d)) continue;
|
|
94423
|
+
const r = rmTree(d);
|
|
94424
|
+
if (r.ok) process.stderr.write(import_chalk10.default.green(" \u2713 ") + `Removed ${d}
|
|
94425
|
+
`);
|
|
94426
|
+
else process.stderr.write(import_chalk10.default.red(" \u2718 ") + `${d}: ${r.reason}
|
|
94427
|
+
`);
|
|
94428
|
+
}
|
|
94429
|
+
if (plan.rootDir) {
|
|
94430
|
+
const r = rmTree(plan.rootDir);
|
|
94431
|
+
if (r.ok) process.stderr.write(import_chalk10.default.green(" \u2713 ") + `Removed ${plan.rootDir}
|
|
94432
|
+
`);
|
|
94433
|
+
else process.stderr.write(import_chalk10.default.red(" \u2718 ") + `${plan.rootDir}: ${r.reason}
|
|
94434
|
+
`);
|
|
94435
|
+
}
|
|
94436
|
+
}
|
|
94437
|
+
process.stderr.write("\n");
|
|
94438
|
+
if (opts.soft) {
|
|
94439
|
+
process.stderr.write(import_chalk10.default.bold(" Soft cleanup complete.\n"));
|
|
94440
|
+
} else {
|
|
94441
|
+
process.stderr.write(import_chalk10.default.bold.green(" Uninstall complete.\n\n"));
|
|
94442
|
+
process.stderr.write(" To remove the binary itself, run:\n");
|
|
94443
|
+
process.stderr.write(import_chalk10.default.cyan(" npm uninstall -g @westbayberry/dg\n\n"));
|
|
94444
|
+
}
|
|
94445
|
+
return 0;
|
|
94446
|
+
}
|
|
94447
|
+
function handleUninstallCommand(args) {
|
|
94448
|
+
return runUninstall(args);
|
|
94449
|
+
}
|
|
94450
|
+
var import_chalk10, REVOKE_TIMEOUT_MS, USAGE4;
|
|
94451
|
+
var init_uninstall = __esm({
|
|
94452
|
+
"src/commands/uninstall.ts"() {
|
|
94453
|
+
"use strict";
|
|
94454
|
+
import_chalk10 = __toESM(require_source());
|
|
94455
|
+
init_paths();
|
|
94456
|
+
init_hooks_registry();
|
|
94457
|
+
init_hook();
|
|
94458
|
+
init_protect();
|
|
94459
|
+
init_auth();
|
|
94460
|
+
init_config();
|
|
94461
|
+
REVOKE_TIMEOUT_MS = 5e3;
|
|
94462
|
+
USAGE4 = `
|
|
94463
|
+
dg uninstall \u2014 remove every file dg has written locally
|
|
94464
|
+
|
|
94465
|
+
Usage:
|
|
94466
|
+
dg uninstall [flags]
|
|
94467
|
+
|
|
94468
|
+
Flags:
|
|
94469
|
+
--yes, -y Skip the confirmation prompt
|
|
94470
|
+
--dry-run Show what would be removed; make no changes
|
|
94471
|
+
--soft Only revoke API key + remove the config file
|
|
94472
|
+
(leaves cache, hooks, and rc-source-line in place)
|
|
94473
|
+
--keep-hooks Leave per-repo pre-commit hooks installed
|
|
94474
|
+
|
|
94475
|
+
Removes:
|
|
94476
|
+
~/.dg/ (config + cache + state + hooks registry)
|
|
94477
|
+
~/.dgrc.json (legacy, if still present)
|
|
94478
|
+
~/.dg/ (legacy, if still present)
|
|
94479
|
+
~/.dg-update-check.json (legacy, if still present)
|
|
94480
|
+
every per-repo pre-commit hook installed via 'dg hook install'
|
|
94481
|
+
the dg sentinel block in your shell rc files
|
|
94482
|
+
|
|
94483
|
+
Also revokes this device's API key server-side (5s timeout; offline is OK,
|
|
94484
|
+
local cleanup proceeds either way).
|
|
94485
|
+
|
|
94486
|
+
Does NOT run 'npm uninstall -g @westbayberry/dg' \u2014 run that separately.
|
|
94487
|
+
`.trimStart();
|
|
94488
|
+
}
|
|
94489
|
+
});
|
|
94490
|
+
|
|
94491
|
+
// src/commands/init.ts
|
|
94492
|
+
var init_exports3 = {};
|
|
94493
|
+
__export(init_exports3, {
|
|
94494
|
+
handleInitCommand: () => handleInitCommand,
|
|
94495
|
+
parseInitArgs: () => parseInitArgs,
|
|
94496
|
+
runInit: () => runInit2
|
|
94497
|
+
});
|
|
94498
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
94499
|
+
import { join as join15 } from "node:path";
|
|
94500
|
+
import * as readline2 from "node:readline";
|
|
94501
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
94502
|
+
function parseInitArgs(args) {
|
|
94503
|
+
const opts = {
|
|
94504
|
+
assumeYes: false,
|
|
94505
|
+
installHook: true,
|
|
94506
|
+
enableProtect: true,
|
|
94507
|
+
appendRc: false,
|
|
94508
|
+
runScan: true
|
|
94509
|
+
};
|
|
94510
|
+
for (const a of args) {
|
|
94511
|
+
if (a === "--yes" || a === "-y") opts.assumeYes = true;
|
|
94512
|
+
else if (a === "--no-hook") opts.installHook = false;
|
|
94513
|
+
else if (a === "--no-protect") opts.enableProtect = false;
|
|
94514
|
+
else if (a === "--no-scan") opts.runScan = false;
|
|
94515
|
+
else if (a === "--append-rc") opts.appendRc = true;
|
|
94516
|
+
}
|
|
94517
|
+
return opts;
|
|
94518
|
+
}
|
|
94519
|
+
async function confirm3(prompt, defaultYes, assumeYes) {
|
|
94520
|
+
if (assumeYes) {
|
|
94521
|
+
process.stderr.write(prompt + (defaultYes ? "yes" : "no") + " (--yes)\n");
|
|
94522
|
+
return defaultYes;
|
|
94523
|
+
}
|
|
94524
|
+
if (!process.stdin.isTTY) {
|
|
94525
|
+
process.stderr.write(prompt + (defaultYes ? "yes" : "no") + " (non-interactive default)\n");
|
|
94526
|
+
return defaultYes;
|
|
94527
|
+
}
|
|
94528
|
+
process.stderr.write(prompt);
|
|
94529
|
+
return new Promise((resolve3) => {
|
|
94530
|
+
const rl = readline2.createInterface({ input: process.stdin });
|
|
94531
|
+
rl.once("line", (line) => {
|
|
94532
|
+
rl.close();
|
|
94533
|
+
const ans = line.trim().toLowerCase();
|
|
94534
|
+
if (ans === "") resolve3(defaultYes);
|
|
94535
|
+
else if (ans === "y" || ans === "yes") resolve3(true);
|
|
94536
|
+
else resolve3(false);
|
|
94537
|
+
});
|
|
94538
|
+
});
|
|
94539
|
+
}
|
|
94540
|
+
function detectEcosystem(cwd2) {
|
|
94541
|
+
const npm = existsSync20(join15(cwd2, "package.json")) || existsSync20(join15(cwd2, "package-lock.json")) || existsSync20(join15(cwd2, "pnpm-lock.yaml")) || existsSync20(join15(cwd2, "yarn.lock"));
|
|
94542
|
+
const pypi = existsSync20(join15(cwd2, "pyproject.toml")) || existsSync20(join15(cwd2, "setup.py")) || existsSync20(join15(cwd2, "requirements.txt")) || existsSync20(join15(cwd2, "Pipfile")) || existsSync20(join15(cwd2, "poetry.lock"));
|
|
94543
|
+
return { npm, pypi };
|
|
94544
|
+
}
|
|
94545
|
+
function findRepoRootOrNull(cwd2) {
|
|
94546
|
+
try {
|
|
94547
|
+
return execFileSync4("git", ["-C", cwd2, "rev-parse", "--show-toplevel"], {
|
|
94548
|
+
encoding: "utf-8",
|
|
94549
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
94550
|
+
}).trim();
|
|
94551
|
+
} catch {
|
|
94552
|
+
return null;
|
|
94553
|
+
}
|
|
94554
|
+
}
|
|
94555
|
+
async function runInit2(args) {
|
|
94556
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
94557
|
+
process.stdout.write(USAGE5);
|
|
94558
|
+
return 0;
|
|
94559
|
+
}
|
|
94560
|
+
const opts = parseInitArgs(args);
|
|
94561
|
+
const cwd2 = process.cwd();
|
|
94562
|
+
if (getFirstRunCompletedAt() === null) {
|
|
94563
|
+
process.stderr.write(
|
|
94564
|
+
import_chalk11.default.yellow(" This looks like your first time using dg.\n") + import_chalk11.default.dim(" Run ") + import_chalk11.default.cyan("dg kitty") + import_chalk11.default.dim(" first for the guided intro,\n") + import_chalk11.default.dim(" then come back to ") + import_chalk11.default.cyan("dg init") + import_chalk11.default.dim(" to set up this project.\n\n")
|
|
94565
|
+
);
|
|
94566
|
+
return 1;
|
|
94567
|
+
}
|
|
94568
|
+
process.stderr.write(import_chalk11.default.bold("\n Setting up Dependency Guardian for this project.\n\n"));
|
|
94569
|
+
const eco = detectEcosystem(cwd2);
|
|
94570
|
+
if (!eco.npm && !eco.pypi) {
|
|
94571
|
+
process.stderr.write(
|
|
94572
|
+
import_chalk11.default.yellow(" No lockfile or manifest found in this directory.\n") + import_chalk11.default.dim(" Expected one of: package.json, pnpm-lock.yaml, yarn.lock,\n") + import_chalk11.default.dim(" pyproject.toml, requirements.txt, Pipfile.\n") + import_chalk11.default.dim(" cd into your project root and re-run dg init.\n\n")
|
|
94573
|
+
);
|
|
94574
|
+
return 1;
|
|
94575
|
+
}
|
|
94576
|
+
const stacks = [];
|
|
94577
|
+
if (eco.npm) stacks.push("npm");
|
|
94578
|
+
if (eco.pypi) stacks.push("pypi");
|
|
94579
|
+
process.stderr.write(import_chalk11.default.green(" \u2713 ") + `Detected: ${stacks.join(" + ")}
|
|
94580
|
+
|
|
94581
|
+
`);
|
|
94582
|
+
if (opts.installHook) {
|
|
94583
|
+
const repoRoot = findRepoRootOrNull(cwd2);
|
|
94584
|
+
if (repoRoot === null) {
|
|
94585
|
+
process.stderr.write(import_chalk11.default.dim(" \xB7 Not a git repo \u2014 skipping pre-commit hook.\n"));
|
|
94586
|
+
} else {
|
|
94587
|
+
let info;
|
|
94588
|
+
try {
|
|
94589
|
+
info = detectHookFramework(repoRoot);
|
|
94590
|
+
} catch (e) {
|
|
94591
|
+
process.stderr.write(import_chalk11.default.yellow(` \u26A0 Hook detection failed: ${e.message}
|
|
94592
|
+
`));
|
|
94593
|
+
info = { framework: "bare", targetFile: join15(repoRoot, ".git", "hooks", "pre-commit"), alreadyInstalled: false };
|
|
94594
|
+
}
|
|
94595
|
+
if (info.alreadyInstalled) {
|
|
94596
|
+
process.stderr.write(import_chalk11.default.dim(` \xB7 Pre-commit hook already installed at ${info.targetFile}.
|
|
94597
|
+
`));
|
|
94598
|
+
} else {
|
|
94599
|
+
const prompt = ` Install git pre-commit hook? (${info.framework} \u2192 ${info.targetFile})
|
|
94600
|
+
Blocks commits that add high-risk lockfile changes. [Y/n] `;
|
|
94601
|
+
const yes = await confirm3(prompt, true, opts.assumeYes);
|
|
94602
|
+
if (yes) {
|
|
94603
|
+
try {
|
|
94604
|
+
installHookForFramework(info);
|
|
94605
|
+
addEntry({
|
|
94606
|
+
repoPath: repoRoot,
|
|
94607
|
+
framework: info.framework,
|
|
94608
|
+
hookPath: info.targetFile
|
|
94609
|
+
});
|
|
94610
|
+
} catch (e) {
|
|
94611
|
+
process.stderr.write(import_chalk11.default.red(` \u2718 Hook install failed: ${e.message}
|
|
94612
|
+
`));
|
|
94613
|
+
}
|
|
94614
|
+
} else {
|
|
94615
|
+
process.stderr.write(import_chalk11.default.dim(" \xB7 Skipped hook install.\n"));
|
|
94616
|
+
}
|
|
94617
|
+
}
|
|
94618
|
+
process.stderr.write("\n");
|
|
94619
|
+
}
|
|
94620
|
+
}
|
|
94621
|
+
if (opts.enableProtect) {
|
|
94622
|
+
const prompt = " Enable 'dg protect' so 'npm install' / 'pip install' route\n through dg automatically? [Y/n] ";
|
|
94623
|
+
const yes = await confirm3(prompt, true, opts.assumeYes);
|
|
94624
|
+
if (yes) {
|
|
94625
|
+
try {
|
|
94626
|
+
await runProtectInit(cwd2, { noShell: true });
|
|
94627
|
+
const { rc } = suggestedShellRc();
|
|
94628
|
+
const rcLine = `source ${dgStatePath("aliases.sh")}`;
|
|
94629
|
+
if (opts.appendRc) {
|
|
94630
|
+
const out = appendAliasSourceToRc(rc, rcLine);
|
|
94631
|
+
if (out.status === "appended") {
|
|
94632
|
+
process.stderr.write(import_chalk11.default.green(" \u2713 ") + `Added source line to ${out.rcPath}
|
|
94633
|
+
`);
|
|
94634
|
+
} else if (out.status === "already-present") {
|
|
94635
|
+
process.stderr.write(import_chalk11.default.dim(` \xB7 Source line already present in ${out.rcPath}
|
|
94636
|
+
`));
|
|
94637
|
+
} else {
|
|
94638
|
+
process.stderr.write(
|
|
94639
|
+
import_chalk11.default.yellow(" \u26A0 ") + `Could not append to ${out.rcPath}: ${out.reason}. Add this line by hand:
|
|
94640
|
+
` + import_chalk11.default.cyan(` ${rcLine}
|
|
94641
|
+
`)
|
|
94642
|
+
);
|
|
94643
|
+
}
|
|
94644
|
+
} else {
|
|
94645
|
+
process.stderr.write(
|
|
94646
|
+
import_chalk11.default.dim(` Add this line to ${rc} to activate the wrapper:
|
|
94647
|
+
`) + import_chalk11.default.cyan(` ${rcLine}
|
|
94648
|
+
`) + import_chalk11.default.dim(` (re-run with --append-rc to have dg add it for you)
|
|
94649
|
+
`)
|
|
94650
|
+
);
|
|
94651
|
+
}
|
|
94652
|
+
} catch (e) {
|
|
94653
|
+
process.stderr.write(import_chalk11.default.red(` \u2718 Protect setup failed: ${e.message}
|
|
94654
|
+
`));
|
|
94655
|
+
}
|
|
94656
|
+
} else {
|
|
94657
|
+
process.stderr.write(import_chalk11.default.dim(" \xB7 Skipped protect setup.\n"));
|
|
94658
|
+
}
|
|
94659
|
+
process.stderr.write("\n");
|
|
94660
|
+
}
|
|
94661
|
+
if (opts.runScan) {
|
|
94662
|
+
const prompt = ` Run an initial scan now? [Y/n] `;
|
|
94663
|
+
const yes = await confirm3(prompt, true, opts.assumeYes);
|
|
94664
|
+
if (yes) {
|
|
94665
|
+
process.stderr.write(import_chalk11.default.dim(" Running 'dg scan'...\n\n"));
|
|
94666
|
+
try {
|
|
94667
|
+
const { runStatic: runStatic2 } = await Promise.resolve().then(() => (init_static_output(), static_output_exports));
|
|
94668
|
+
const { parseConfig: parseConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
94669
|
+
const cfg = parseConfig2(["node", "dg", "scan"], false);
|
|
94670
|
+
await runStatic2(cfg);
|
|
94671
|
+
} catch (e) {
|
|
94672
|
+
process.stderr.write(import_chalk11.default.yellow(` \u26A0 Initial scan failed: ${e.message}
|
|
94673
|
+
`));
|
|
94674
|
+
process.stderr.write(import_chalk11.default.dim(` Run 'dg scan' manually when ready.
|
|
94675
|
+
`));
|
|
94676
|
+
}
|
|
94677
|
+
} else {
|
|
94678
|
+
process.stderr.write(import_chalk11.default.dim(" \xB7 Skipped initial scan.\n"));
|
|
94679
|
+
}
|
|
94680
|
+
process.stderr.write("\n");
|
|
94681
|
+
}
|
|
94682
|
+
process.stderr.write(import_chalk11.default.bold.green(" \u2713 Setup complete.\n"));
|
|
94683
|
+
process.stderr.write(import_chalk11.default.dim(" Run 'dg status' anytime to check this project's coverage.\n"));
|
|
94684
|
+
if (!isLoggedIn()) {
|
|
94685
|
+
process.stderr.write(import_chalk11.default.dim(" Run 'dg login' for a free account + higher scan limits.\n"));
|
|
94686
|
+
}
|
|
94687
|
+
process.stderr.write("\n");
|
|
94688
|
+
return 0;
|
|
94689
|
+
}
|
|
94690
|
+
function handleInitCommand(args) {
|
|
94691
|
+
return runInit2(args);
|
|
94692
|
+
}
|
|
94693
|
+
var import_chalk11, USAGE5;
|
|
94694
|
+
var init_init = __esm({
|
|
94695
|
+
"src/commands/init.ts"() {
|
|
94696
|
+
"use strict";
|
|
94697
|
+
import_chalk11 = __toESM(require_source());
|
|
94698
|
+
init_auth();
|
|
94699
|
+
init_hook();
|
|
94700
|
+
init_hooks_registry();
|
|
94701
|
+
init_protect();
|
|
94702
|
+
init_paths();
|
|
94703
|
+
USAGE5 = `
|
|
94704
|
+
dg init \u2014 fast per-project setup
|
|
94705
|
+
|
|
94706
|
+
Usage:
|
|
94707
|
+
dg init [flags]
|
|
94708
|
+
|
|
94709
|
+
Flags:
|
|
94710
|
+
--yes, -y Accept all default answers without prompting (CI-safe)
|
|
94711
|
+
--no-hook Skip git pre-commit hook installation
|
|
94712
|
+
--no-protect Skip enabling 'dg protect' (npm/pip wrapper)
|
|
94713
|
+
--no-scan Skip the initial scan
|
|
94714
|
+
--append-rc Auto-append the alias source-line to your shell rc
|
|
94715
|
+
(default: print the line for you to paste)
|
|
94716
|
+
|
|
94717
|
+
What it does (each step asks first):
|
|
94718
|
+
1. Detect ecosystem (npm / pypi) in this directory
|
|
94719
|
+
2. Install a git pre-commit hook that blocks risky lockfile changes
|
|
94720
|
+
3. Enable 'dg protect' so 'npm install' and 'pip install' route
|
|
94721
|
+
through dg
|
|
94722
|
+
4. Run a first scan of your current dependencies
|
|
94723
|
+
|
|
94724
|
+
This is the per-project equivalent of 'dg kitty' \u2014 the one-time intro
|
|
94725
|
+
wizard that auto-runs on your very first dg invocation. Re-run
|
|
94726
|
+
'dg kitty' if you want the full tour again.
|
|
94727
|
+
`.trimStart();
|
|
93747
94728
|
}
|
|
93748
94729
|
});
|
|
93749
94730
|
|
|
@@ -94003,14 +94984,14 @@ function formatRate(ratePerSec) {
|
|
|
94003
94984
|
if (ratePerSec >= 1) return `${Math.round(ratePerSec)} pkg/s`;
|
|
94004
94985
|
return `${ratePerSec.toFixed(1)} pkg/s`;
|
|
94005
94986
|
}
|
|
94006
|
-
var import_react32,
|
|
94987
|
+
var import_react32, import_chalk12, import_jsx_runtime9, ProgressBar;
|
|
94007
94988
|
var init_ProgressBar = __esm({
|
|
94008
94989
|
async "src/ui/components/ProgressBar.tsx"() {
|
|
94009
94990
|
"use strict";
|
|
94010
94991
|
import_react32 = __toESM(require_react());
|
|
94011
94992
|
await init_build2();
|
|
94012
94993
|
await init_build3();
|
|
94013
|
-
|
|
94994
|
+
import_chalk12 = __toESM(require_source());
|
|
94014
94995
|
await init_useTerminalSize();
|
|
94015
94996
|
import_jsx_runtime9 = __toESM(require_jsx_runtime());
|
|
94016
94997
|
ProgressBar = ({
|
|
@@ -94051,7 +95032,7 @@ var init_ProgressBar = __esm({
|
|
|
94051
95032
|
const filledBar = "\u2501".repeat(filled);
|
|
94052
95033
|
const emptyBar = "\u2501".repeat(empty);
|
|
94053
95034
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, children: [
|
|
94054
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children:
|
|
95035
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: import_chalk12.default.bold("Dependency Guardian") }),
|
|
94055
95036
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: "" }),
|
|
94056
95037
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { children: [
|
|
94057
95038
|
done ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "green", children: "\u2713" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(build_default, { type: "dots" }) }),
|
|
@@ -94080,7 +95061,7 @@ var init_ProgressBar = __esm({
|
|
|
94080
95061
|
] }),
|
|
94081
95062
|
label && !compact && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { dimColor: true, children: [
|
|
94082
95063
|
" ",
|
|
94083
|
-
|
|
95064
|
+
import_chalk12.default.dim("\u203A"),
|
|
94084
95065
|
" ",
|
|
94085
95066
|
label
|
|
94086
95067
|
] }) })
|
|
@@ -94091,7 +95072,7 @@ var init_ProgressBar = __esm({
|
|
|
94091
95072
|
|
|
94092
95073
|
// src/ui/components/ScoreHeader.tsx
|
|
94093
95074
|
function scoreColor(score, action) {
|
|
94094
|
-
const colorFn = action === "block" ?
|
|
95075
|
+
const colorFn = action === "block" ? import_chalk13.default.red.bold : action === "warn" ? import_chalk13.default.yellow.bold : action === "analysis_incomplete" ? import_chalk13.default.cyan.bold : import_chalk13.default.green.bold;
|
|
94095
95076
|
return colorFn(String(score));
|
|
94096
95077
|
}
|
|
94097
95078
|
function plot(grid, x, y, type) {
|
|
@@ -94123,10 +95104,10 @@ function fillCircle(grid, cx, cy, r, type) {
|
|
|
94123
95104
|
}
|
|
94124
95105
|
function renderLogo(action) {
|
|
94125
95106
|
const colors = {
|
|
94126
|
-
1:
|
|
94127
|
-
2:
|
|
94128
|
-
3: (s) =>
|
|
94129
|
-
4: action === "block" ?
|
|
95107
|
+
1: import_chalk13.default.dim,
|
|
95108
|
+
2: import_chalk13.default.white,
|
|
95109
|
+
3: (s) => import_chalk13.default.bold.white(s),
|
|
95110
|
+
4: action === "block" ? import_chalk13.default.red : action === "warn" ? import_chalk13.default.yellow : action === "analysis_incomplete" ? import_chalk13.default.cyan : import_chalk13.default.green
|
|
94130
95111
|
};
|
|
94131
95112
|
const result = [];
|
|
94132
95113
|
const { chars, types, cols } = LOGO_DATA;
|
|
@@ -94135,18 +95116,18 @@ function renderLogo(action) {
|
|
|
94135
95116
|
for (let j = 0; j < cols; j++) {
|
|
94136
95117
|
const ch = chars[i + j];
|
|
94137
95118
|
const t = types[i + j];
|
|
94138
|
-
row += t > 0 ? (colors[t] ??
|
|
95119
|
+
row += t > 0 ? (colors[t] ?? import_chalk13.default.dim)(ch) : ch;
|
|
94139
95120
|
}
|
|
94140
95121
|
result.push(row);
|
|
94141
95122
|
}
|
|
94142
95123
|
return result;
|
|
94143
95124
|
}
|
|
94144
|
-
var
|
|
95125
|
+
var import_chalk13, import_jsx_runtime10, LOGO_DATA, ScoreHeader;
|
|
94145
95126
|
var init_ScoreHeader = __esm({
|
|
94146
95127
|
async "src/ui/components/ScoreHeader.tsx"() {
|
|
94147
95128
|
"use strict";
|
|
94148
95129
|
await init_build2();
|
|
94149
|
-
|
|
95130
|
+
import_chalk13 = __toESM(require_source());
|
|
94150
95131
|
import_jsx_runtime10 = __toESM(require_jsx_runtime());
|
|
94151
95132
|
LOGO_DATA = (() => {
|
|
94152
95133
|
const W = 22, H = 28;
|
|
@@ -94211,28 +95192,28 @@ var init_ScoreHeader = __esm({
|
|
|
94211
95192
|
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Box_default, { flexDirection: "row", children: [
|
|
94212
95193
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, children: [
|
|
94213
95194
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { bold: true, children: [
|
|
94214
|
-
|
|
95195
|
+
import_chalk13.default.cyan("\u25C6"),
|
|
94215
95196
|
" Dependency Guardian ",
|
|
94216
|
-
userStatus ?
|
|
95197
|
+
userStatus ? import_chalk13.default.dim(userStatus) : ""
|
|
94217
95198
|
] }),
|
|
94218
95199
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { children: " " }),
|
|
94219
95200
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { children: [
|
|
94220
|
-
|
|
95201
|
+
import_chalk13.default.dim("Score"),
|
|
94221
95202
|
" ",
|
|
94222
95203
|
scoreColor(score, action)
|
|
94223
95204
|
] }),
|
|
94224
95205
|
total !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
94225
95206
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { children: " " }),
|
|
94226
95207
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { children: [
|
|
94227
|
-
|
|
95208
|
+
import_chalk13.default.dim(`${total} package${total !== 1 ? "s" : ""} scanned`),
|
|
94228
95209
|
flagged !== void 0 && flagged > 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
94229
95210
|
" ",
|
|
94230
|
-
|
|
95211
|
+
import_chalk13.default.yellow(`${flagged} flagged`),
|
|
94231
95212
|
" ",
|
|
94232
|
-
|
|
95213
|
+
import_chalk13.default.green(`${clean ?? 0} clean`)
|
|
94233
95214
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
94234
95215
|
" ",
|
|
94235
|
-
|
|
95216
|
+
import_chalk13.default.green("all clean")
|
|
94236
95217
|
] })
|
|
94237
95218
|
] }),
|
|
94238
95219
|
scanUsage && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { dimColor: true, children: scanUsage })
|
|
@@ -94293,8 +95274,8 @@ var init_useExpandAnimation = __esm({
|
|
|
94293
95274
|
});
|
|
94294
95275
|
|
|
94295
95276
|
// src/ui/components/InteractiveResultsView.tsx
|
|
94296
|
-
import { writeFileSync as
|
|
94297
|
-
import { resolve as
|
|
95277
|
+
import { writeFileSync as writeFileSync10 } from "node:fs";
|
|
95278
|
+
import { resolve as resolvePath3 } from "node:path";
|
|
94298
95279
|
function groupPackages2(packages) {
|
|
94299
95280
|
const map = /* @__PURE__ */ new Map();
|
|
94300
95281
|
for (const pkg of packages) {
|
|
@@ -94307,10 +95288,10 @@ function groupPackages2(packages) {
|
|
|
94307
95288
|
}
|
|
94308
95289
|
function actionBadge2(score) {
|
|
94309
95290
|
if (score >= 70)
|
|
94310
|
-
return { label: "Block", color:
|
|
95291
|
+
return { label: "Block", color: import_chalk14.default.red };
|
|
94311
95292
|
if (score >= 60)
|
|
94312
|
-
return { label: "Warn", color:
|
|
94313
|
-
return { label: "Pass", color:
|
|
95293
|
+
return { label: "Warn", color: import_chalk14.default.yellow };
|
|
95294
|
+
return { label: "Pass", color: import_chalk14.default.green };
|
|
94314
95295
|
}
|
|
94315
95296
|
function truncate3(s, max) {
|
|
94316
95297
|
return s.length <= max ? s : s.slice(0, max - 1) + "\u2026";
|
|
@@ -94407,7 +95388,7 @@ function buildDetailLines(group, safeVersion, maxWidth) {
|
|
|
94407
95388
|
connector,
|
|
94408
95389
|
" ",
|
|
94409
95390
|
sevColor(pad2(sevLabel, 8)),
|
|
94410
|
-
|
|
95391
|
+
import_chalk14.default.dim(f.category ?? "")
|
|
94411
95392
|
] }, `finding-${i}`)
|
|
94412
95393
|
);
|
|
94413
95394
|
}
|
|
@@ -94415,7 +95396,7 @@ function buildDetailLines(group, safeVersion, maxWidth) {
|
|
|
94415
95396
|
} else if (rep.score > 0) {
|
|
94416
95397
|
lines.push(
|
|
94417
95398
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { color: "yellow", children: [
|
|
94418
|
-
|
|
95399
|
+
import_chalk14.default.yellow("\u2192"),
|
|
94419
95400
|
" Upgrade to Pro to see risk categories"
|
|
94420
95401
|
] }, "upgrade")
|
|
94421
95402
|
);
|
|
@@ -94424,15 +95405,15 @@ function buildDetailLines(group, safeVersion, maxWidth) {
|
|
|
94424
95405
|
if (rep.recommendation) {
|
|
94425
95406
|
lines.push(
|
|
94426
95407
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
94427
|
-
|
|
95408
|
+
import_chalk14.default.dim("Recommendation:"),
|
|
94428
95409
|
" ",
|
|
94429
|
-
|
|
95410
|
+
import_chalk14.default.cyan(truncate3(rep.recommendation, maxWidth - 18))
|
|
94430
95411
|
] }, "recommendation")
|
|
94431
95412
|
);
|
|
94432
95413
|
}
|
|
94433
95414
|
if (safeVersion) {
|
|
94434
95415
|
lines.push(
|
|
94435
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children:
|
|
95416
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: import_chalk14.default.green(`Safe version: ${rep.name}@${safeVersion}`) }, "safe")
|
|
94436
95417
|
);
|
|
94437
95418
|
}
|
|
94438
95419
|
return lines;
|
|
@@ -94452,24 +95433,24 @@ function licenseLine(rep) {
|
|
|
94452
95433
|
if (!lc) return null;
|
|
94453
95434
|
const spdx = lc.spdx ?? lc.raw ?? "";
|
|
94454
95435
|
const desc = LICENSE_DESCRIPTIONS[lc.riskCategory] ?? "";
|
|
94455
|
-
const lcColor = lc.riskCategory === "permissive" ?
|
|
95436
|
+
const lcColor = lc.riskCategory === "permissive" ? import_chalk14.default.green : lc.riskCategory === "no-license" || lc.riskCategory === "unlicensed" || lc.riskCategory === "network-copyleft" ? import_chalk14.default.red : import_chalk14.default.yellow;
|
|
94456
95437
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
94457
95438
|
T.branch,
|
|
94458
95439
|
" ",
|
|
94459
95440
|
lcColor(spdx),
|
|
94460
95441
|
" ",
|
|
94461
|
-
|
|
95442
|
+
import_chalk14.default.dim("\u2014"),
|
|
94462
95443
|
" ",
|
|
94463
|
-
|
|
95444
|
+
import_chalk14.default.dim(desc)
|
|
94464
95445
|
] }, "license-info");
|
|
94465
95446
|
}
|
|
94466
|
-
var import_react34,
|
|
95447
|
+
var import_react34, import_chalk14, import_jsx_runtime11, SEVERITY_LABELS, SEVERITY_COLORS, EVIDENCE_LIMIT, FIXED_CHROME, DETAIL_PANE_CHROME, InteractiveResultsView, T, LICENSE_DESCRIPTIONS, FindingsSummary;
|
|
94467
95448
|
var init_InteractiveResultsView = __esm({
|
|
94468
95449
|
async "src/ui/components/InteractiveResultsView.tsx"() {
|
|
94469
95450
|
"use strict";
|
|
94470
95451
|
import_react34 = __toESM(require_react());
|
|
94471
95452
|
await init_build2();
|
|
94472
|
-
|
|
95453
|
+
import_chalk14 = __toESM(require_source());
|
|
94473
95454
|
init_auth();
|
|
94474
95455
|
await init_ScoreHeader();
|
|
94475
95456
|
init_useExpandAnimation();
|
|
@@ -94484,11 +95465,11 @@ var init_InteractiveResultsView = __esm({
|
|
|
94484
95465
|
1: "INFO"
|
|
94485
95466
|
};
|
|
94486
95467
|
SEVERITY_COLORS = {
|
|
94487
|
-
5: (s) =>
|
|
94488
|
-
4: (s) =>
|
|
94489
|
-
3: (s) =>
|
|
94490
|
-
2: (s) =>
|
|
94491
|
-
1: (s) =>
|
|
95468
|
+
5: (s) => import_chalk14.default.red.bold(s),
|
|
95469
|
+
4: (s) => import_chalk14.default.red(s),
|
|
95470
|
+
3: (s) => import_chalk14.default.yellow(s),
|
|
95471
|
+
2: (s) => import_chalk14.default.cyan(s),
|
|
95472
|
+
1: (s) => import_chalk14.default.gray(s)
|
|
94492
95473
|
};
|
|
94493
95474
|
EVIDENCE_LIMIT = 2;
|
|
94494
95475
|
FIXED_CHROME = 21;
|
|
@@ -94805,8 +95786,8 @@ var init_InteractiveResultsView = __esm({
|
|
|
94805
95786
|
const { body, ext } = formatExport(payload, scope, format);
|
|
94806
95787
|
const scopeTag = scope === "current-license" && currentLicenseIdx !== null ? `${(licenseGroups[currentLicenseIdx]?.spdx ?? "license").replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 32)}` : scope;
|
|
94807
95788
|
const filename = `dg-scan-${ts}-${scopeTag}.${ext}`;
|
|
94808
|
-
const path3 =
|
|
94809
|
-
|
|
95789
|
+
const path3 = resolvePath3(process.cwd(), filename);
|
|
95790
|
+
writeFileSync10(path3, body, "utf-8");
|
|
94810
95791
|
showExportMsg(`\u2713 Exported to ${filename}`);
|
|
94811
95792
|
} catch (e) {
|
|
94812
95793
|
showExportMsg(`Export failed: ${e.message}`);
|
|
@@ -95178,13 +96159,13 @@ var init_InteractiveResultsView = __esm({
|
|
|
95178
96159
|
];
|
|
95179
96160
|
const renderRow = (title, rows, current, isActive) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", marginBottom: 1, children: [
|
|
95180
96161
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95181
|
-
isActive ?
|
|
95182
|
-
isActive ?
|
|
96162
|
+
isActive ? import_chalk14.default.cyan("\u258C ") : " ",
|
|
96163
|
+
isActive ? import_chalk14.default.bold(title) : import_chalk14.default.dim(title)
|
|
95183
96164
|
] }),
|
|
95184
96165
|
rows.map((r) => {
|
|
95185
96166
|
const selected = r.value === current;
|
|
95186
|
-
const bullet = selected ? isActive ?
|
|
95187
|
-
const text = selected ?
|
|
96167
|
+
const bullet = selected ? isActive ? import_chalk14.default.cyan("\u25CF") : import_chalk14.default.green("\u25CF") : import_chalk14.default.dim("\u25CB");
|
|
96168
|
+
const text = selected ? import_chalk14.default.bold(r.label) : r.label;
|
|
95188
96169
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { children: [
|
|
95189
96170
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { width: 5, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95190
96171
|
" ",
|
|
@@ -95210,32 +96191,32 @@ var init_InteractiveResultsView = __esm({
|
|
|
95210
96191
|
),
|
|
95211
96192
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingLeft: 2, paddingRight: 2, width: "100%", children: [
|
|
95212
96193
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { bold: true, children: [
|
|
95213
|
-
|
|
96194
|
+
import_chalk14.default.cyan("\u25C6"),
|
|
95214
96195
|
" Export ",
|
|
95215
|
-
|
|
96196
|
+
import_chalk14.default.dim("(pick what to export and which format)")
|
|
95216
96197
|
] }),
|
|
95217
96198
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }),
|
|
95218
96199
|
renderRow("What", SCOPES_RENDER, exportMenu.scope, exportMenu.activeRow === "scope"),
|
|
95219
96200
|
renderRow("Format", FORMATS_RENDER, exportMenu.format, exportMenu.activeRow === "format")
|
|
95220
96201
|
] }),
|
|
95221
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children:
|
|
96202
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: import_chalk14.default.dim("\u2500".repeat(Math.max(20, termCols - 4))) }),
|
|
95222
96203
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95223
96204
|
" ",
|
|
95224
|
-
|
|
96205
|
+
import_chalk14.default.bold.cyan("\u2191\u2193"),
|
|
95225
96206
|
" ",
|
|
95226
|
-
|
|
96207
|
+
import_chalk14.default.dim("scroll"),
|
|
95227
96208
|
" ",
|
|
95228
|
-
|
|
96209
|
+
import_chalk14.default.bold.cyan("\u2190\u2192/Tab"),
|
|
95229
96210
|
" ",
|
|
95230
|
-
|
|
96211
|
+
import_chalk14.default.dim("switch row"),
|
|
95231
96212
|
" ",
|
|
95232
|
-
|
|
96213
|
+
import_chalk14.default.bold.cyan("\u23CE"),
|
|
95233
96214
|
" ",
|
|
95234
|
-
|
|
96215
|
+
import_chalk14.default.dim("export"),
|
|
95235
96216
|
" ",
|
|
95236
|
-
|
|
96217
|
+
import_chalk14.default.bold.cyan("Esc"),
|
|
95237
96218
|
" ",
|
|
95238
|
-
|
|
96219
|
+
import_chalk14.default.dim("cancel")
|
|
95239
96220
|
] })
|
|
95240
96221
|
] });
|
|
95241
96222
|
}
|
|
@@ -95265,97 +96246,97 @@ var init_InteractiveResultsView = __esm({
|
|
|
95265
96246
|
width: "100%",
|
|
95266
96247
|
children: [
|
|
95267
96248
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { bold: true, children: [
|
|
95268
|
-
|
|
96249
|
+
import_chalk14.default.cyan("\u25C6"),
|
|
95269
96250
|
" Keyboard Shortcuts"
|
|
95270
96251
|
] }),
|
|
95271
96252
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }),
|
|
95272
96253
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, children: " Navigation" }),
|
|
95273
96254
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95274
96255
|
" ",
|
|
95275
|
-
|
|
96256
|
+
import_chalk14.default.cyan("\u2191 k"),
|
|
95276
96257
|
" ",
|
|
95277
|
-
|
|
96258
|
+
import_chalk14.default.dim("Move up")
|
|
95278
96259
|
] }),
|
|
95279
96260
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95280
96261
|
" ",
|
|
95281
|
-
|
|
96262
|
+
import_chalk14.default.cyan("\u2193 j"),
|
|
95282
96263
|
" ",
|
|
95283
|
-
|
|
96264
|
+
import_chalk14.default.dim("Move down")
|
|
95284
96265
|
] }),
|
|
95285
96266
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95286
96267
|
" ",
|
|
95287
|
-
|
|
96268
|
+
import_chalk14.default.cyan("g"),
|
|
95288
96269
|
" ",
|
|
95289
|
-
|
|
96270
|
+
import_chalk14.default.dim("Jump to top")
|
|
95290
96271
|
] }),
|
|
95291
96272
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95292
96273
|
" ",
|
|
95293
|
-
|
|
96274
|
+
import_chalk14.default.cyan("G"),
|
|
95294
96275
|
" ",
|
|
95295
|
-
|
|
96276
|
+
import_chalk14.default.dim("Jump to bottom")
|
|
95296
96277
|
] }),
|
|
95297
96278
|
!isDetail && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95298
96279
|
" ",
|
|
95299
|
-
|
|
96280
|
+
import_chalk14.default.cyan("PgUp"),
|
|
95300
96281
|
" ",
|
|
95301
|
-
|
|
96282
|
+
import_chalk14.default.dim("Page up")
|
|
95302
96283
|
] }),
|
|
95303
96284
|
!isDetail && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95304
96285
|
" ",
|
|
95305
|
-
|
|
96286
|
+
import_chalk14.default.cyan("PgDn"),
|
|
95306
96287
|
" ",
|
|
95307
|
-
|
|
96288
|
+
import_chalk14.default.dim("Page down")
|
|
95308
96289
|
] }),
|
|
95309
96290
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }),
|
|
95310
96291
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, children: " Actions" }),
|
|
95311
96292
|
!isDetail && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95312
96293
|
" ",
|
|
95313
|
-
|
|
96294
|
+
import_chalk14.default.cyan("\u23CE"),
|
|
95314
96295
|
" ",
|
|
95315
|
-
|
|
96296
|
+
import_chalk14.default.dim("Expand findings")
|
|
95316
96297
|
] }),
|
|
95317
96298
|
isDetail && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95318
96299
|
" ",
|
|
95319
|
-
|
|
96300
|
+
import_chalk14.default.cyan("Esc"),
|
|
95320
96301
|
" ",
|
|
95321
|
-
|
|
96302
|
+
import_chalk14.default.dim("Back to list")
|
|
95322
96303
|
] }),
|
|
95323
96304
|
!isDetail && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95324
96305
|
" ",
|
|
95325
|
-
|
|
96306
|
+
import_chalk14.default.cyan("/"),
|
|
95326
96307
|
" ",
|
|
95327
|
-
|
|
96308
|
+
import_chalk14.default.dim("Search packages")
|
|
95328
96309
|
] }),
|
|
95329
96310
|
!isDetail && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95330
96311
|
" ",
|
|
95331
|
-
|
|
96312
|
+
import_chalk14.default.cyan("l"),
|
|
95332
96313
|
" ",
|
|
95333
|
-
|
|
96314
|
+
import_chalk14.default.dim("License breakdown (browse + drill-in)")
|
|
95334
96315
|
] }),
|
|
95335
96316
|
!isDetail && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95336
96317
|
" ",
|
|
95337
|
-
|
|
96318
|
+
import_chalk14.default.cyan("e"),
|
|
95338
96319
|
" ",
|
|
95339
|
-
|
|
96320
|
+
import_chalk14.default.dim("Export menu \u2014 pick scope (all / summary / packages / licenses / findings) and format (JSON / CSV / Markdown / text)")
|
|
95340
96321
|
] }),
|
|
95341
96322
|
!isDetail && onBack && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95342
96323
|
" ",
|
|
95343
|
-
|
|
96324
|
+
import_chalk14.default.cyan("b"),
|
|
95344
96325
|
" ",
|
|
95345
|
-
|
|
96326
|
+
import_chalk14.default.dim("Back to project selector")
|
|
95346
96327
|
] }),
|
|
95347
96328
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95348
96329
|
" ",
|
|
95349
|
-
|
|
96330
|
+
import_chalk14.default.cyan("q"),
|
|
95350
96331
|
" ",
|
|
95351
|
-
|
|
96332
|
+
import_chalk14.default.dim("Quit")
|
|
95352
96333
|
] }),
|
|
95353
96334
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }),
|
|
95354
96335
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
95355
96336
|
" Press ",
|
|
95356
|
-
|
|
96337
|
+
import_chalk14.default.bold.cyan("?"),
|
|
95357
96338
|
" or ",
|
|
95358
|
-
|
|
96339
|
+
import_chalk14.default.bold.cyan("Esc"),
|
|
95359
96340
|
" to close"
|
|
95360
96341
|
] })
|
|
95361
96342
|
]
|
|
@@ -95365,11 +96346,11 @@ var init_InteractiveResultsView = __esm({
|
|
|
95365
96346
|
}
|
|
95366
96347
|
if (showLicenses) {
|
|
95367
96348
|
const lcColor = (risk) => {
|
|
95368
|
-
if (risk === "permissive") return
|
|
95369
|
-
if (risk === "weak-copyleft") return
|
|
95370
|
-
if (risk === "strong-copyleft") return
|
|
95371
|
-
if (risk === "no-license" || risk === "network-copyleft" || risk === "unlicensed") return
|
|
95372
|
-
return
|
|
96349
|
+
if (risk === "permissive") return import_chalk14.default.green;
|
|
96350
|
+
if (risk === "weak-copyleft") return import_chalk14.default.yellow;
|
|
96351
|
+
if (risk === "strong-copyleft") return import_chalk14.default.yellow.bold;
|
|
96352
|
+
if (risk === "no-license" || risk === "network-copyleft" || risk === "unlicensed") return import_chalk14.default.red;
|
|
96353
|
+
return import_chalk14.default.dim;
|
|
95373
96354
|
};
|
|
95374
96355
|
const totalCount = result.packages.length;
|
|
95375
96356
|
const maxCount = licenseGroups[0]?.count ?? 1;
|
|
@@ -95401,7 +96382,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
95401
96382
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingLeft: 2, paddingRight: 2, width: "100%", children: [
|
|
95402
96383
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { children: [
|
|
95403
96384
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { bold: true, children: [
|
|
95404
|
-
|
|
96385
|
+
import_chalk14.default.cyan("\u25C6"),
|
|
95405
96386
|
" ",
|
|
95406
96387
|
color(g.spdx)
|
|
95407
96388
|
] }),
|
|
@@ -95417,16 +96398,16 @@ var init_InteractiveResultsView = __esm({
|
|
|
95417
96398
|
] }),
|
|
95418
96399
|
licenseSearchMode || q ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95419
96400
|
" ",
|
|
95420
|
-
|
|
96401
|
+
import_chalk14.default.bold.cyan("/"),
|
|
95421
96402
|
" ",
|
|
95422
|
-
q ||
|
|
95423
|
-
licenseSearchMode ?
|
|
96403
|
+
q || import_chalk14.default.dim("(type to filter; Esc clears, Enter confirms)"),
|
|
96404
|
+
licenseSearchMode ? import_chalk14.default.cyan("\u2588") : ""
|
|
95424
96405
|
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }),
|
|
95425
96406
|
_above > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: ` \u2191 ${_above} more above` }),
|
|
95426
96407
|
_slice.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: ` (no packages match "${q}")` }),
|
|
95427
96408
|
_slice.map((p) => {
|
|
95428
96409
|
const score = p.score;
|
|
95429
|
-
const scoreColor2 = score >= 70 ?
|
|
96410
|
+
const scoreColor2 = score >= 70 ? import_chalk14.default.red : score >= 60 ? import_chalk14.default.yellow : score === 0 ? import_chalk14.default.dim : import_chalk14.default.green;
|
|
95430
96411
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { children: [
|
|
95431
96412
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { width: Math.max(28, Math.floor(termCols * 0.45)), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: p.name }) }),
|
|
95432
96413
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { width: 16, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: p.version }) }),
|
|
@@ -95435,35 +96416,35 @@ var init_InteractiveResultsView = __esm({
|
|
|
95435
96416
|
}),
|
|
95436
96417
|
_below > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: ` \u2193 ${_below} more below` })
|
|
95437
96418
|
] }),
|
|
95438
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children:
|
|
96419
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: import_chalk14.default.dim("\u2500".repeat(Math.max(20, termCols - 4))) }),
|
|
95439
96420
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95440
96421
|
" ",
|
|
95441
|
-
|
|
96422
|
+
import_chalk14.default.bold.cyan("\u2191\u2193"),
|
|
95442
96423
|
" ",
|
|
95443
|
-
|
|
96424
|
+
import_chalk14.default.dim("scroll"),
|
|
95444
96425
|
" ",
|
|
95445
|
-
|
|
96426
|
+
import_chalk14.default.bold.cyan("/"),
|
|
95446
96427
|
" ",
|
|
95447
|
-
|
|
96428
|
+
import_chalk14.default.dim("search"),
|
|
95448
96429
|
" ",
|
|
95449
|
-
|
|
96430
|
+
import_chalk14.default.bold.cyan("e"),
|
|
95450
96431
|
" ",
|
|
95451
|
-
|
|
96432
|
+
import_chalk14.default.dim("export"),
|
|
95452
96433
|
" ",
|
|
95453
|
-
|
|
96434
|
+
import_chalk14.default.bold.cyan("Esc"),
|
|
95454
96435
|
" ",
|
|
95455
|
-
|
|
96436
|
+
import_chalk14.default.dim("back"),
|
|
95456
96437
|
" ",
|
|
95457
|
-
|
|
96438
|
+
import_chalk14.default.bold.cyan("l"),
|
|
95458
96439
|
" ",
|
|
95459
|
-
|
|
96440
|
+
import_chalk14.default.dim("close"),
|
|
95460
96441
|
" ",
|
|
95461
|
-
|
|
96442
|
+
import_chalk14.default.bold.cyan("q"),
|
|
95462
96443
|
" ",
|
|
95463
|
-
|
|
96444
|
+
import_chalk14.default.dim("quit"),
|
|
95464
96445
|
exportMsg && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
95465
96446
|
" ",
|
|
95466
|
-
|
|
96447
|
+
import_chalk14.default.green(exportMsg)
|
|
95467
96448
|
] })
|
|
95468
96449
|
] })
|
|
95469
96450
|
] });
|
|
@@ -95509,9 +96490,9 @@ var init_InteractiveResultsView = __esm({
|
|
|
95509
96490
|
width: "100%",
|
|
95510
96491
|
children: [
|
|
95511
96492
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { bold: true, children: [
|
|
95512
|
-
|
|
96493
|
+
import_chalk14.default.cyan("\u25C6"),
|
|
95513
96494
|
" Licenses ",
|
|
95514
|
-
|
|
96495
|
+
import_chalk14.default.dim(`(${licenseGroups.length} unique across ${totalCount} packages)`)
|
|
95515
96496
|
] }),
|
|
95516
96497
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: "" }),
|
|
95517
96498
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { children: [
|
|
@@ -95531,10 +96512,10 @@ var init_InteractiveResultsView = __esm({
|
|
|
95531
96512
|
const spdxText = truncate3(g.spdx, spdxCol - 1);
|
|
95532
96513
|
const riskText = g.risk === "unknown" ? "\u2014" : g.risk;
|
|
95533
96514
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { children: [
|
|
95534
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { width: 2, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: isSelected ?
|
|
95535
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { width: spdxCol, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: isSelected ?
|
|
96515
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { width: 2, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: isSelected ? import_chalk14.default.cyan("\u258C") : " " }) }),
|
|
96516
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { width: spdxCol, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: isSelected ? import_chalk14.default.bold(color(spdxText)) : color(spdxText) }) }),
|
|
95536
96517
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { width: riskCol, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: riskText }) }),
|
|
95537
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { width: countCol, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children:
|
|
96518
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { width: countCol, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: import_chalk14.default.bold(String(g.count)) }) }),
|
|
95538
96519
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { width: barCol, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: color(bar) }) })
|
|
95539
96520
|
] }, `${g.risk}::${g.spdx}::${absIdx}`);
|
|
95540
96521
|
}),
|
|
@@ -95542,31 +96523,31 @@ var init_InteractiveResultsView = __esm({
|
|
|
95542
96523
|
]
|
|
95543
96524
|
}
|
|
95544
96525
|
),
|
|
95545
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children:
|
|
96526
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: import_chalk14.default.dim("\u2500".repeat(Math.max(20, termCols - 4))) }),
|
|
95546
96527
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95547
96528
|
" ",
|
|
95548
|
-
|
|
96529
|
+
import_chalk14.default.bold.cyan("\u2191\u2193"),
|
|
95549
96530
|
" ",
|
|
95550
|
-
|
|
96531
|
+
import_chalk14.default.dim("navigate"),
|
|
95551
96532
|
" ",
|
|
95552
|
-
|
|
96533
|
+
import_chalk14.default.bold.cyan("\u23CE"),
|
|
95553
96534
|
" ",
|
|
95554
|
-
|
|
96535
|
+
import_chalk14.default.dim("view packages"),
|
|
95555
96536
|
" ",
|
|
95556
|
-
|
|
96537
|
+
import_chalk14.default.bold.cyan("e"),
|
|
95557
96538
|
" ",
|
|
95558
|
-
|
|
96539
|
+
import_chalk14.default.dim("export"),
|
|
95559
96540
|
" ",
|
|
95560
|
-
|
|
96541
|
+
import_chalk14.default.bold.cyan("l/Esc"),
|
|
95561
96542
|
" ",
|
|
95562
|
-
|
|
96543
|
+
import_chalk14.default.dim("close"),
|
|
95563
96544
|
" ",
|
|
95564
|
-
|
|
96545
|
+
import_chalk14.default.bold.cyan("q"),
|
|
95565
96546
|
" ",
|
|
95566
|
-
|
|
96547
|
+
import_chalk14.default.dim("quit"),
|
|
95567
96548
|
exportMsg && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
95568
96549
|
" ",
|
|
95569
|
-
|
|
96550
|
+
import_chalk14.default.green(exportMsg)
|
|
95570
96551
|
] })
|
|
95571
96552
|
] })
|
|
95572
96553
|
] });
|
|
@@ -95608,19 +96589,19 @@ var init_InteractiveResultsView = __esm({
|
|
|
95608
96589
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { justifyContent: "space-between", children: [
|
|
95609
96590
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { bold: true, children: [
|
|
95610
96591
|
groupNames(dpGroup),
|
|
95611
|
-
dpRep.license ?
|
|
96592
|
+
dpRep.license ? import_chalk14.default.dim(" \xB7 ") + (dpRep.license.riskCategory === "permissive" ? import_chalk14.default.green(dpRep.license.spdx ?? dpRep.license.raw ?? "") : dpRep.license.riskCategory === "no-license" || dpRep.license.riskCategory === "network-copyleft" ? import_chalk14.default.red(dpRep.license.spdx ?? dpRep.license.raw ?? "No license") : import_chalk14.default.yellow(dpRep.license.spdx ?? dpRep.license.raw ?? "")) : ""
|
|
95612
96593
|
] }),
|
|
95613
96594
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: dpColor(`score ${dpRep.score}`) })
|
|
95614
96595
|
] }),
|
|
95615
96596
|
dpAbove > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
95616
|
-
|
|
96597
|
+
import_chalk14.default.cyan(" \u2191"),
|
|
95617
96598
|
" ",
|
|
95618
96599
|
dpAbove,
|
|
95619
96600
|
" more above"
|
|
95620
96601
|
] }),
|
|
95621
96602
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { flexDirection: "column", marginLeft: 2, children: dpVisible }),
|
|
95622
96603
|
dpBelow > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
95623
|
-
|
|
96604
|
+
import_chalk14.default.cyan(" \u2193"),
|
|
95624
96605
|
" ",
|
|
95625
96606
|
dpBelow,
|
|
95626
96607
|
" more below"
|
|
@@ -95639,13 +96620,13 @@ var init_InteractiveResultsView = __esm({
|
|
|
95639
96620
|
width: "100%",
|
|
95640
96621
|
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { justifyContent: "space-between", children: [
|
|
95641
96622
|
clean.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95642
|
-
|
|
96623
|
+
import_chalk14.default.green("\u2713"),
|
|
95643
96624
|
" ",
|
|
95644
|
-
|
|
96625
|
+
import_chalk14.default.green.bold(String(clean.length)),
|
|
95645
96626
|
" ",
|
|
95646
|
-
|
|
96627
|
+
import_chalk14.default.dim(`package${clean.length !== 1 ? "s" : ""} passed with score 0`),
|
|
95647
96628
|
" ",
|
|
95648
|
-
|
|
96629
|
+
import_chalk14.default.dim(`\xB7 ${(durationMs / 1e3).toFixed(1)}s`)
|
|
95649
96630
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
95650
96631
|
(durationMs / 1e3).toFixed(1),
|
|
95651
96632
|
"s"
|
|
@@ -95654,20 +96635,20 @@ var init_InteractiveResultsView = __esm({
|
|
|
95654
96635
|
] })
|
|
95655
96636
|
}
|
|
95656
96637
|
),
|
|
95657
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children:
|
|
96638
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: import_chalk14.default.dim("\u2500".repeat(Math.max(20, termCols - 4))) }),
|
|
95658
96639
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95659
96640
|
" ",
|
|
95660
|
-
|
|
96641
|
+
import_chalk14.default.bold.cyan("\u2191\u2193"),
|
|
95661
96642
|
" ",
|
|
95662
|
-
|
|
96643
|
+
import_chalk14.default.dim("scroll"),
|
|
95663
96644
|
" ",
|
|
95664
|
-
|
|
96645
|
+
import_chalk14.default.bold.cyan("Esc"),
|
|
95665
96646
|
" ",
|
|
95666
|
-
|
|
96647
|
+
import_chalk14.default.dim("back"),
|
|
95667
96648
|
" ",
|
|
95668
|
-
|
|
96649
|
+
import_chalk14.default.bold.cyan("q"),
|
|
95669
96650
|
" ",
|
|
95670
|
-
|
|
96651
|
+
import_chalk14.default.dim("quit")
|
|
95671
96652
|
] })
|
|
95672
96653
|
] });
|
|
95673
96654
|
}
|
|
@@ -95700,7 +96681,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
95700
96681
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: searchQuery ? `${groups.length} of ${allGroupCount}` : `${clampedCursor + 1}/${groups.length}` })
|
|
95701
96682
|
] }),
|
|
95702
96683
|
aboveCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
95703
|
-
|
|
96684
|
+
import_chalk14.default.cyan(" \u2191"),
|
|
95704
96685
|
" ",
|
|
95705
96686
|
aboveCount,
|
|
95706
96687
|
" more above"
|
|
@@ -95715,22 +96696,22 @@ var init_InteractiveResultsView = __esm({
|
|
|
95715
96696
|
const scoreStr = String(rep.score);
|
|
95716
96697
|
const lcInfo = rep.license;
|
|
95717
96698
|
const lcStr = lcInfo ? truncate3(lcInfo.spdx ?? lcInfo.raw ?? "", lcCol - 2) : "";
|
|
95718
|
-
const lcColor = !lcInfo ?
|
|
96699
|
+
const lcColor = !lcInfo ? import_chalk14.default.dim : lcInfo.riskCategory === "permissive" ? import_chalk14.default.green : lcInfo.riskCategory === "no-license" || lcInfo.riskCategory === "unlicensed" || lcInfo.riskCategory === "network-copyleft" ? import_chalk14.default.red : import_chalk14.default.yellow;
|
|
95719
96700
|
const arrow = level === "summary" ? "\u25BE" : "\u25B8";
|
|
95720
96701
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
95721
96702
|
isCursor ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { backgroundColor: "#1a1a2e", children: [
|
|
95722
|
-
|
|
96703
|
+
import_chalk14.default.cyan("\u258C"),
|
|
95723
96704
|
" ",
|
|
95724
|
-
|
|
96705
|
+
import_chalk14.default.cyan(arrow),
|
|
95725
96706
|
" ",
|
|
95726
96707
|
` `,
|
|
95727
96708
|
color(pad2(label, 6)),
|
|
95728
|
-
|
|
96709
|
+
import_chalk14.default.bold(pad2(truncate3(names, nameCol - 2), nameCol)),
|
|
95729
96710
|
lcColor(pad2(lcStr, lcCol)),
|
|
95730
96711
|
color(scoreStr.padStart(3)),
|
|
95731
96712
|
" "
|
|
95732
96713
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95733
|
-
` ${
|
|
96714
|
+
` ${import_chalk14.default.dim(arrow)} `,
|
|
95734
96715
|
color(pad2(label, 6)),
|
|
95735
96716
|
pad2(truncate3(names, nameCol - 2), nameCol),
|
|
95736
96717
|
lcColor(pad2(lcStr, lcCol)),
|
|
@@ -95747,7 +96728,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
95747
96728
|
] }, group.key);
|
|
95748
96729
|
}),
|
|
95749
96730
|
belowCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
95750
|
-
|
|
96731
|
+
import_chalk14.default.cyan(" \u2193"),
|
|
95751
96732
|
" ",
|
|
95752
96733
|
belowCount,
|
|
95753
96734
|
" more below"
|
|
@@ -95774,13 +96755,13 @@ var init_InteractiveResultsView = __esm({
|
|
|
95774
96755
|
] }),
|
|
95775
96756
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { justifyContent: "space-between", children: [
|
|
95776
96757
|
clean.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95777
|
-
|
|
96758
|
+
import_chalk14.default.green("\u2713"),
|
|
95778
96759
|
" ",
|
|
95779
|
-
|
|
96760
|
+
import_chalk14.default.green.bold(String(clean.length)),
|
|
95780
96761
|
" ",
|
|
95781
|
-
|
|
96762
|
+
import_chalk14.default.dim(`package${clean.length !== 1 ? "s" : ""} passed with score 0`),
|
|
95782
96763
|
" ",
|
|
95783
|
-
|
|
96764
|
+
import_chalk14.default.dim(`\xB7 ${(durationMs / 1e3).toFixed(1)}s`)
|
|
95784
96765
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
95785
96766
|
(durationMs / 1e3).toFixed(1),
|
|
95786
96767
|
"s"
|
|
@@ -95790,66 +96771,66 @@ var init_InteractiveResultsView = __esm({
|
|
|
95790
96771
|
]
|
|
95791
96772
|
}
|
|
95792
96773
|
),
|
|
95793
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children:
|
|
96774
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: import_chalk14.default.dim("\u2500".repeat(Math.max(20, termCols - 4))) }),
|
|
95794
96775
|
searchMode ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95795
96776
|
" ",
|
|
95796
|
-
|
|
96777
|
+
import_chalk14.default.bold.cyan("/"),
|
|
95797
96778
|
" ",
|
|
95798
96779
|
searchQuery,
|
|
95799
|
-
|
|
96780
|
+
import_chalk14.default.cyan("\u2588"),
|
|
95800
96781
|
" ",
|
|
95801
|
-
|
|
96782
|
+
import_chalk14.default.dim("Esc clear")
|
|
95802
96783
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
95803
96784
|
" ",
|
|
95804
96785
|
groups.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
95805
|
-
|
|
96786
|
+
import_chalk14.default.bold.cyan("\u2191\u2193"),
|
|
95806
96787
|
" ",
|
|
95807
|
-
|
|
96788
|
+
import_chalk14.default.dim("navigate"),
|
|
95808
96789
|
" ",
|
|
95809
|
-
|
|
96790
|
+
import_chalk14.default.bold.cyan("\u23CE"),
|
|
95810
96791
|
" ",
|
|
95811
|
-
|
|
96792
|
+
import_chalk14.default.dim("expand"),
|
|
95812
96793
|
" ",
|
|
95813
|
-
|
|
96794
|
+
import_chalk14.default.bold.cyan("/"),
|
|
95814
96795
|
" ",
|
|
95815
|
-
|
|
96796
|
+
import_chalk14.default.dim("search"),
|
|
95816
96797
|
" ",
|
|
95817
|
-
|
|
96798
|
+
import_chalk14.default.bold.cyan("l"),
|
|
95818
96799
|
" ",
|
|
95819
|
-
|
|
96800
|
+
import_chalk14.default.dim("licenses"),
|
|
95820
96801
|
" ",
|
|
95821
|
-
|
|
96802
|
+
import_chalk14.default.bold.cyan("e"),
|
|
95822
96803
|
" ",
|
|
95823
|
-
|
|
96804
|
+
import_chalk14.default.dim("export"),
|
|
95824
96805
|
" ",
|
|
95825
96806
|
onBack && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
95826
|
-
|
|
96807
|
+
import_chalk14.default.bold.cyan("b"),
|
|
95827
96808
|
" ",
|
|
95828
|
-
|
|
96809
|
+
import_chalk14.default.dim("back"),
|
|
95829
96810
|
" "
|
|
95830
96811
|
] }),
|
|
95831
|
-
|
|
96812
|
+
import_chalk14.default.bold.cyan("q"),
|
|
95832
96813
|
" ",
|
|
95833
|
-
|
|
96814
|
+
import_chalk14.default.dim("quit"),
|
|
95834
96815
|
exportMsg && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
95835
96816
|
" ",
|
|
95836
|
-
|
|
96817
|
+
import_chalk14.default.green(exportMsg)
|
|
95837
96818
|
] })
|
|
95838
96819
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
95839
96820
|
"Press ",
|
|
95840
|
-
|
|
96821
|
+
import_chalk14.default.bold.cyan("q"),
|
|
95841
96822
|
" or ",
|
|
95842
|
-
|
|
96823
|
+
import_chalk14.default.bold.cyan("Enter"),
|
|
95843
96824
|
" ",
|
|
95844
|
-
|
|
96825
|
+
import_chalk14.default.dim("to exit")
|
|
95845
96826
|
] })
|
|
95846
96827
|
] })
|
|
95847
96828
|
] });
|
|
95848
96829
|
};
|
|
95849
96830
|
T = {
|
|
95850
|
-
branch:
|
|
95851
|
-
last:
|
|
95852
|
-
pipe:
|
|
96831
|
+
branch: import_chalk14.default.dim("\u251C\u2500\u2500"),
|
|
96832
|
+
last: import_chalk14.default.dim("\u2514\u2500\u2500"),
|
|
96833
|
+
pipe: import_chalk14.default.dim("\u2502"),
|
|
95853
96834
|
blank: " "
|
|
95854
96835
|
};
|
|
95855
96836
|
LICENSE_DESCRIPTIONS = {
|
|
@@ -95875,9 +96856,9 @@ var init_InteractiveResultsView = __esm({
|
|
|
95875
96856
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
95876
96857
|
hasAffects ? T.branch : T.last,
|
|
95877
96858
|
" ",
|
|
95878
|
-
|
|
96859
|
+
import_chalk14.default.yellow("\u2192"),
|
|
95879
96860
|
" ",
|
|
95880
|
-
|
|
96861
|
+
import_chalk14.default.yellow("Upgrade to Pro"),
|
|
95881
96862
|
" for finding details"
|
|
95882
96863
|
] }, "upgrade")
|
|
95883
96864
|
);
|
|
@@ -95895,7 +96876,7 @@ var init_InteractiveResultsView = __esm({
|
|
|
95895
96876
|
" ",
|
|
95896
96877
|
sevColor(pad2(sevLabel, 5)),
|
|
95897
96878
|
" ",
|
|
95898
|
-
|
|
96879
|
+
import_chalk14.default.dim(f.category ?? ""),
|
|
95899
96880
|
title
|
|
95900
96881
|
] }, `finding-${idx}`)
|
|
95901
96882
|
);
|
|
@@ -95941,12 +96922,12 @@ function getHint(error2) {
|
|
|
95941
96922
|
return null;
|
|
95942
96923
|
}
|
|
95943
96924
|
}
|
|
95944
|
-
var
|
|
96925
|
+
var import_chalk15, import_jsx_runtime12, ErrorView;
|
|
95945
96926
|
var init_ErrorView = __esm({
|
|
95946
96927
|
async "src/ui/components/ErrorView.tsx"() {
|
|
95947
96928
|
"use strict";
|
|
95948
96929
|
await init_build2();
|
|
95949
|
-
|
|
96930
|
+
import_chalk15 = __toESM(require_source());
|
|
95950
96931
|
init_sanitize();
|
|
95951
96932
|
import_jsx_runtime12 = __toESM(require_jsx_runtime());
|
|
95952
96933
|
ErrorView = ({ error: error2 }) => {
|
|
@@ -95960,10 +96941,10 @@ var init_ErrorView = __esm({
|
|
|
95960
96941
|
paddingLeft: 1,
|
|
95961
96942
|
paddingRight: 1,
|
|
95962
96943
|
children: [
|
|
95963
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { children:
|
|
96944
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { children: import_chalk15.default.red.bold("\u2718 Error") }),
|
|
95964
96945
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { children: sanitize(error2.message) }),
|
|
95965
96946
|
hint && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { children: [
|
|
95966
|
-
|
|
96947
|
+
import_chalk15.default.yellow("\u2192"),
|
|
95967
96948
|
" ",
|
|
95968
96949
|
hint
|
|
95969
96950
|
] })
|
|
@@ -95975,13 +96956,13 @@ var init_ErrorView = __esm({
|
|
|
95975
96956
|
});
|
|
95976
96957
|
|
|
95977
96958
|
// src/ui/components/ProjectSelector.tsx
|
|
95978
|
-
var import_react35,
|
|
96959
|
+
var import_react35, import_chalk16, import_jsx_runtime13, ProjectSelector;
|
|
95979
96960
|
var init_ProjectSelector = __esm({
|
|
95980
96961
|
async "src/ui/components/ProjectSelector.tsx"() {
|
|
95981
96962
|
"use strict";
|
|
95982
96963
|
import_react35 = __toESM(require_react());
|
|
95983
96964
|
await init_build2();
|
|
95984
|
-
|
|
96965
|
+
import_chalk16 = __toESM(require_source());
|
|
95985
96966
|
init_sanitize();
|
|
95986
96967
|
import_jsx_runtime13 = __toESM(require_jsx_runtime());
|
|
95987
96968
|
ProjectSelector = ({ projects, onConfirm, onCancel, userStatus }) => {
|
|
@@ -96011,14 +96992,14 @@ var init_ProjectSelector = __esm({
|
|
|
96011
96992
|
onCancel();
|
|
96012
96993
|
}
|
|
96013
96994
|
});
|
|
96014
|
-
const ecosystemLabel = (eco) => eco === "npm" ?
|
|
96995
|
+
const ecosystemLabel = (eco) => eco === "npm" ? import_chalk16.default.magenta("npm") : import_chalk16.default.blue("pip");
|
|
96015
96996
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
|
|
96016
96997
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { children: [
|
|
96017
|
-
|
|
96998
|
+
import_chalk16.default.cyan("\u25C6"),
|
|
96018
96999
|
" ",
|
|
96019
|
-
|
|
97000
|
+
import_chalk16.default.bold("Dependency Guardian"),
|
|
96020
97001
|
" ",
|
|
96021
|
-
userStatus ?
|
|
97002
|
+
userStatus ? import_chalk16.default.dim(userStatus) : ""
|
|
96022
97003
|
] }),
|
|
96023
97004
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: "" }),
|
|
96024
97005
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { bold: true, children: [
|
|
@@ -96031,30 +97012,30 @@ var init_ProjectSelector = __esm({
|
|
|
96031
97012
|
projects.map((proj, i) => {
|
|
96032
97013
|
const isCursor = i === cursor;
|
|
96033
97014
|
const isSelected = selected.has(i);
|
|
96034
|
-
const prefix = isCursor ?
|
|
96035
|
-
const check = isSelected ?
|
|
97015
|
+
const prefix = isCursor ? import_chalk16.default.cyan("\u258C") : " ";
|
|
97016
|
+
const check = isSelected ? import_chalk16.default.green("\u25C9") : import_chalk16.default.dim("\u25CB");
|
|
96036
97017
|
const line = `${prefix}${check} ${sanitize(proj.relativePath).padEnd(40)} ${ecosystemLabel(proj.ecosystem).padEnd(5)} ${proj.packageCount} packages`;
|
|
96037
97018
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { backgroundColor: isCursor ? "#1a1a2e" : void 0, children: line }, i);
|
|
96038
97019
|
}),
|
|
96039
97020
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: "" }),
|
|
96040
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { dimColor: true, children: selected.size === 0 ?
|
|
97021
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { dimColor: true, children: selected.size === 0 ? import_chalk16.default.yellow("Select at least 1 project to scan") : `${selected.size} of ${projects.length} selected` }),
|
|
96041
97022
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: "" }),
|
|
96042
97023
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { children: [
|
|
96043
|
-
|
|
97024
|
+
import_chalk16.default.bold.cyan("space"),
|
|
96044
97025
|
" ",
|
|
96045
|
-
|
|
97026
|
+
import_chalk16.default.dim("toggle"),
|
|
96046
97027
|
" ",
|
|
96047
|
-
|
|
97028
|
+
import_chalk16.default.bold.cyan("a"),
|
|
96048
97029
|
" ",
|
|
96049
|
-
|
|
97030
|
+
import_chalk16.default.dim("all"),
|
|
96050
97031
|
" ",
|
|
96051
|
-
|
|
97032
|
+
import_chalk16.default.bold.hex("#FFD700")("\u23CE"),
|
|
96052
97033
|
" ",
|
|
96053
|
-
|
|
97034
|
+
import_chalk16.default.bold.hex("#FFD700")("scan"),
|
|
96054
97035
|
" ",
|
|
96055
|
-
|
|
97036
|
+
import_chalk16.default.bold.cyan("q"),
|
|
96056
97037
|
" ",
|
|
96057
|
-
|
|
97038
|
+
import_chalk16.default.dim("quit")
|
|
96058
97039
|
] })
|
|
96059
97040
|
] });
|
|
96060
97041
|
};
|
|
@@ -96398,9 +97379,9 @@ function useInstallWrapper(rawArgs, config3, opts, exit) {
|
|
|
96398
97379
|
const result = await opts.callAnalyze(resolved, config3);
|
|
96399
97380
|
if (result.action === "pass") {
|
|
96400
97381
|
if (exit) exit();
|
|
96401
|
-
const
|
|
97382
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
96402
97383
|
process.stderr.write(
|
|
96403
|
-
|
|
97384
|
+
chalk17.green(` \u2713 ${resolved.length} package${resolved.length !== 1 ? "s" : ""} scanned \u2014 all clear
|
|
96404
97385
|
`)
|
|
96405
97386
|
);
|
|
96406
97387
|
process.stderr.write("\n");
|
|
@@ -96411,8 +97392,8 @@ function useInstallWrapper(rawArgs, config3, opts, exit) {
|
|
|
96411
97392
|
if (result.action === "warn") {
|
|
96412
97393
|
if (exit) exit();
|
|
96413
97394
|
process.stdout.write(renderResultStatic(result, config3) + "\n");
|
|
96414
|
-
const
|
|
96415
|
-
process.stderr.write(
|
|
97395
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
97396
|
+
process.stderr.write(chalk17.yellow(" Warnings detected. Proceeding with install.\n\n"));
|
|
96416
97397
|
const code = await opts.runInstall(parsed.rawArgs);
|
|
96417
97398
|
process.exit(code);
|
|
96418
97399
|
return;
|
|
@@ -96525,16 +97506,16 @@ function groupPackages3(packages) {
|
|
|
96525
97506
|
return [...map.values()].map((pkgs) => ({ packages: pkgs, key: pkgs[0].name })).sort((a, b) => b.packages[0].score - a.packages[0].score);
|
|
96526
97507
|
}
|
|
96527
97508
|
function severityColor(sev) {
|
|
96528
|
-
if (sev >= 5) return (s) =>
|
|
96529
|
-
if (sev >= 4) return
|
|
96530
|
-
if (sev >= 3) return
|
|
96531
|
-
if (sev >= 2) return
|
|
96532
|
-
return
|
|
97509
|
+
if (sev >= 5) return (s) => import_chalk17.default.bold.red(s);
|
|
97510
|
+
if (sev >= 4) return import_chalk17.default.magenta;
|
|
97511
|
+
if (sev >= 3) return import_chalk17.default.yellow;
|
|
97512
|
+
if (sev >= 2) return import_chalk17.default.dim;
|
|
97513
|
+
return import_chalk17.default.dim;
|
|
96533
97514
|
}
|
|
96534
97515
|
function actionBadge3(score) {
|
|
96535
|
-
if (score >= 70) return { label: "BLOCK", color:
|
|
96536
|
-
if (score >= 60) return { label: "WARN", color:
|
|
96537
|
-
return { label: "PASS", color:
|
|
97516
|
+
if (score >= 70) return { label: "BLOCK", color: import_chalk17.default.red };
|
|
97517
|
+
if (score >= 60) return { label: "WARN", color: import_chalk17.default.yellow };
|
|
97518
|
+
return { label: "PASS", color: import_chalk17.default.green };
|
|
96538
97519
|
}
|
|
96539
97520
|
function truncate4(s, max) {
|
|
96540
97521
|
return s.length <= max ? s : s.slice(0, max - 1) + "\u2026";
|
|
@@ -96542,12 +97523,12 @@ function truncate4(s, max) {
|
|
|
96542
97523
|
function pad3(s, len) {
|
|
96543
97524
|
return s + " ".repeat(Math.max(0, len - s.length));
|
|
96544
97525
|
}
|
|
96545
|
-
var
|
|
97526
|
+
var import_chalk17, import_jsx_runtime17, SEVERITY_LABELS2, EVIDENCE_LIMIT2, ResultsView;
|
|
96546
97527
|
var init_ResultsView = __esm({
|
|
96547
97528
|
async "src/ui/components/ResultsView.tsx"() {
|
|
96548
97529
|
"use strict";
|
|
96549
97530
|
await init_build2();
|
|
96550
|
-
|
|
97531
|
+
import_chalk17 = __toESM(require_source());
|
|
96551
97532
|
await init_ScoreHeader();
|
|
96552
97533
|
await init_DurationLine();
|
|
96553
97534
|
import_jsx_runtime17 = __toESM(require_jsx_runtime());
|
|
@@ -96573,15 +97554,15 @@ var init_ResultsView = __esm({
|
|
|
96573
97554
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ScoreHeader, { score: result.score, action: result.action }),
|
|
96574
97555
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Newline, {}),
|
|
96575
97556
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { children: [
|
|
96576
|
-
|
|
97557
|
+
import_chalk17.default.dim(`${total} package${total !== 1 ? "s" : ""} scanned`),
|
|
96577
97558
|
flagged.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
96578
97559
|
" ",
|
|
96579
|
-
|
|
97560
|
+
import_chalk17.default.yellow(`${flagged.length} flagged`),
|
|
96580
97561
|
" ",
|
|
96581
|
-
|
|
97562
|
+
import_chalk17.default.green(`${clean.length} clean`)
|
|
96582
97563
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
96583
97564
|
" ",
|
|
96584
|
-
|
|
97565
|
+
import_chalk17.default.green("all clean")
|
|
96585
97566
|
] })
|
|
96586
97567
|
] }),
|
|
96587
97568
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Newline, {}),
|
|
@@ -96595,18 +97576,18 @@ var init_ResultsView = __esm({
|
|
|
96595
97576
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { children: [
|
|
96596
97577
|
" ",
|
|
96597
97578
|
color(pad3(label, 7)),
|
|
96598
|
-
|
|
96599
|
-
|
|
97579
|
+
import_chalk17.default.bold(pad3(truncate4(names, 50), 52)),
|
|
97580
|
+
import_chalk17.default.dim(`score ${rep.score}`)
|
|
96600
97581
|
] }, group.key);
|
|
96601
97582
|
}),
|
|
96602
97583
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Newline, {})
|
|
96603
97584
|
] }),
|
|
96604
97585
|
clean.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { children: [
|
|
96605
|
-
|
|
97586
|
+
import_chalk17.default.green("\u2713"),
|
|
96606
97587
|
" ",
|
|
96607
|
-
|
|
97588
|
+
import_chalk17.default.green.bold(String(clean.length)),
|
|
96608
97589
|
" ",
|
|
96609
|
-
|
|
97590
|
+
import_chalk17.default.dim(`package${clean.length !== 1 ? "s" : ""} passed with score 0`)
|
|
96610
97591
|
] }),
|
|
96611
97592
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Newline, {}),
|
|
96612
97593
|
groups.filter((g) => g.packages[0].score > 0).map((group) => {
|
|
@@ -96616,9 +97597,9 @@ var init_ResultsView = __esm({
|
|
|
96616
97597
|
const safeVersion = result.safeVersions[rep.name];
|
|
96617
97598
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
96618
97599
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { children: [
|
|
96619
|
-
|
|
97600
|
+
import_chalk17.default.dim("\u2500\u2500"),
|
|
96620
97601
|
" ",
|
|
96621
|
-
|
|
97602
|
+
import_chalk17.default.bold(`${names} (score: ${rep.score})`)
|
|
96622
97603
|
] }),
|
|
96623
97604
|
group.packages.length > 3 && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { dimColor: true, children: [
|
|
96624
97605
|
" Affects: ",
|
|
@@ -96640,18 +97621,18 @@ var init_ResultsView = __esm({
|
|
|
96640
97621
|
] }),
|
|
96641
97622
|
evidenceSlice.map((ev, i) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { children: [
|
|
96642
97623
|
" ",
|
|
96643
|
-
|
|
97624
|
+
import_chalk17.default.dim(truncate4(ev, 76))
|
|
96644
97625
|
] }, i)),
|
|
96645
97626
|
overflow > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { children: [
|
|
96646
97627
|
" ",
|
|
96647
|
-
|
|
97628
|
+
import_chalk17.default.dim(`... and ${overflow} more`)
|
|
96648
97629
|
] }),
|
|
96649
97630
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { children: " " })
|
|
96650
97631
|
] }, idx);
|
|
96651
97632
|
}),
|
|
96652
97633
|
safeVersion && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { children: [
|
|
96653
97634
|
" ",
|
|
96654
|
-
|
|
97635
|
+
import_chalk17.default.green(`Safe version: ${rep.name}@${safeVersion}`)
|
|
96655
97636
|
] }),
|
|
96656
97637
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Newline, {})
|
|
96657
97638
|
] }, group.key);
|
|
@@ -96664,13 +97645,13 @@ var init_ResultsView = __esm({
|
|
|
96664
97645
|
});
|
|
96665
97646
|
|
|
96666
97647
|
// src/ui/components/ConfirmPrompt.tsx
|
|
96667
|
-
var
|
|
97648
|
+
var import_chalk18, import_jsx_runtime18, ConfirmPrompt;
|
|
96668
97649
|
var init_ConfirmPrompt = __esm({
|
|
96669
97650
|
async "src/ui/components/ConfirmPrompt.tsx"() {
|
|
96670
97651
|
"use strict";
|
|
96671
97652
|
await init_build2();
|
|
96672
97653
|
await init_build2();
|
|
96673
|
-
|
|
97654
|
+
import_chalk18 = __toESM(require_source());
|
|
96674
97655
|
import_jsx_runtime18 = __toESM(require_jsx_runtime());
|
|
96675
97656
|
ConfirmPrompt = ({
|
|
96676
97657
|
message,
|
|
@@ -96686,15 +97667,15 @@ var init_ConfirmPrompt = __esm({
|
|
|
96686
97667
|
});
|
|
96687
97668
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
96688
97669
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Text, { children: [
|
|
96689
|
-
|
|
97670
|
+
import_chalk18.default.red.bold("\u26A0"),
|
|
96690
97671
|
" ",
|
|
96691
|
-
|
|
97672
|
+
import_chalk18.default.bold(message)
|
|
96692
97673
|
] }),
|
|
96693
97674
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Text, { children: [
|
|
96694
97675
|
"Install anyway? [",
|
|
96695
|
-
|
|
97676
|
+
import_chalk18.default.bold.green("y"),
|
|
96696
97677
|
"es / ",
|
|
96697
|
-
|
|
97678
|
+
import_chalk18.default.bold.red("N"),
|
|
96698
97679
|
"o]"
|
|
96699
97680
|
] })
|
|
96700
97681
|
] });
|
|
@@ -97081,10 +98062,272 @@ function closestCommand(input, commands) {
|
|
|
97081
98062
|
return bestDist <= 3 ? best : null;
|
|
97082
98063
|
}
|
|
97083
98064
|
|
|
98065
|
+
// src/migrate.ts
|
|
98066
|
+
init_paths();
|
|
98067
|
+
import {
|
|
98068
|
+
existsSync as existsSync6,
|
|
98069
|
+
mkdirSync as mkdirSync3,
|
|
98070
|
+
readFileSync as readFileSync6,
|
|
98071
|
+
writeFileSync as writeFileSync4,
|
|
98072
|
+
copyFileSync,
|
|
98073
|
+
unlinkSync as unlinkSync2,
|
|
98074
|
+
rmSync as rmSync2,
|
|
98075
|
+
chmodSync as chmodSync2,
|
|
98076
|
+
statSync,
|
|
98077
|
+
openSync as openSync2,
|
|
98078
|
+
closeSync as closeSync2,
|
|
98079
|
+
constants as fsConstants2
|
|
98080
|
+
} from "node:fs";
|
|
98081
|
+
import { dirname as dirname6 } from "node:path";
|
|
98082
|
+
var README = `dependency-guardian \u2014 local state for the dg CLI.
|
|
98083
|
+
|
|
98084
|
+
config.json your account + preferences (mode 0600)
|
|
98085
|
+
cache/scans.sqlite 24h package-scan cache
|
|
98086
|
+
cache/update-check.json latest-version probe (24h TTL)
|
|
98087
|
+
cache/routing-hint.json scan-routing hint
|
|
98088
|
+
state/aliases.sh optional shell aliases (npm/pip wrappers)
|
|
98089
|
+
state/trial-banner throttle stamp for the trial nudge
|
|
98090
|
+
state/hooks-installed.json registry of git hooks dg installed
|
|
98091
|
+
|
|
98092
|
+
To remove everything dg has written to your machine, run:
|
|
98093
|
+
dg uninstall
|
|
98094
|
+
|
|
98095
|
+
This directory is created and managed by the dg CLI. Safe to delete.
|
|
98096
|
+
`;
|
|
98097
|
+
function ensureDir(path3, mode) {
|
|
98098
|
+
if (!existsSync6(path3)) {
|
|
98099
|
+
mkdirSync3(path3, { recursive: true, mode });
|
|
98100
|
+
}
|
|
98101
|
+
try {
|
|
98102
|
+
chmodSync2(path3, mode);
|
|
98103
|
+
} catch {
|
|
98104
|
+
}
|
|
98105
|
+
}
|
|
98106
|
+
function moveFile(from, to, mode) {
|
|
98107
|
+
const parent = dirname6(to);
|
|
98108
|
+
ensureDir(parent, 448);
|
|
98109
|
+
copyFileSync(from, to);
|
|
98110
|
+
try {
|
|
98111
|
+
chmodSync2(to, mode);
|
|
98112
|
+
} catch {
|
|
98113
|
+
}
|
|
98114
|
+
if (statSync(to).size !== statSync(from).size) {
|
|
98115
|
+
throw new Error(`size mismatch after copy: ${from} -> ${to}`);
|
|
98116
|
+
}
|
|
98117
|
+
unlinkSync2(from);
|
|
98118
|
+
}
|
|
98119
|
+
function isPidAlive(pid) {
|
|
98120
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
98121
|
+
try {
|
|
98122
|
+
process.kill(pid, 0);
|
|
98123
|
+
return true;
|
|
98124
|
+
} catch (e) {
|
|
98125
|
+
const code = e.code;
|
|
98126
|
+
return code === "EPERM";
|
|
98127
|
+
}
|
|
98128
|
+
}
|
|
98129
|
+
var LOCK_STALE_MS = 6e4;
|
|
98130
|
+
function acquireLock(lockPath) {
|
|
98131
|
+
ensureDir(dirname6(lockPath), 448);
|
|
98132
|
+
if (existsSync6(lockPath)) {
|
|
98133
|
+
let stale = false;
|
|
98134
|
+
try {
|
|
98135
|
+
const raw = readFileSync6(lockPath, "utf-8").trim();
|
|
98136
|
+
const data = JSON.parse(raw);
|
|
98137
|
+
const age = Date.now() - (data.at ?? 0);
|
|
98138
|
+
const dead = !isPidAlive(data.pid ?? 0);
|
|
98139
|
+
stale = dead || age > LOCK_STALE_MS;
|
|
98140
|
+
} catch {
|
|
98141
|
+
stale = true;
|
|
98142
|
+
}
|
|
98143
|
+
if (!stale) return "held";
|
|
98144
|
+
try {
|
|
98145
|
+
unlinkSync2(lockPath);
|
|
98146
|
+
} catch {
|
|
98147
|
+
}
|
|
98148
|
+
}
|
|
98149
|
+
let fd;
|
|
98150
|
+
try {
|
|
98151
|
+
fd = openSync2(lockPath, fsConstants2.O_CREAT | fsConstants2.O_EXCL | fsConstants2.O_WRONLY, 384);
|
|
98152
|
+
} catch {
|
|
98153
|
+
return "stale-held";
|
|
98154
|
+
}
|
|
98155
|
+
try {
|
|
98156
|
+
writeFileSync4(lockPath, JSON.stringify({ pid: process.pid, at: Date.now() }) + "\n");
|
|
98157
|
+
} catch {
|
|
98158
|
+
}
|
|
98159
|
+
return { fd, lockPath };
|
|
98160
|
+
}
|
|
98161
|
+
function releaseLock(state) {
|
|
98162
|
+
if (state.fd !== null) {
|
|
98163
|
+
try {
|
|
98164
|
+
closeSync2(state.fd);
|
|
98165
|
+
} catch {
|
|
98166
|
+
}
|
|
98167
|
+
}
|
|
98168
|
+
try {
|
|
98169
|
+
unlinkSync2(state.lockPath);
|
|
98170
|
+
} catch {
|
|
98171
|
+
}
|
|
98172
|
+
}
|
|
98173
|
+
function rollback(moves) {
|
|
98174
|
+
for (const m of moves) {
|
|
98175
|
+
try {
|
|
98176
|
+
if (existsSync6(m.to) && !existsSync6(m.from)) {
|
|
98177
|
+
copyFileSync(m.to, m.from);
|
|
98178
|
+
unlinkSync2(m.to);
|
|
98179
|
+
}
|
|
98180
|
+
} catch {
|
|
98181
|
+
}
|
|
98182
|
+
}
|
|
98183
|
+
}
|
|
98184
|
+
function detectLegacy() {
|
|
98185
|
+
const legacy = legacyPaths();
|
|
98186
|
+
return existsSync6(legacy.dgrc) || existsSync6(legacy.cacheSqlite) || existsSync6(legacy.routingHint) || existsSync6(legacy.updateCheck) || existsSync6(legacy.trialBannerOld) || existsSync6(legacy.aliasesShOld) || existsSync6(legacy.depGuardianDir);
|
|
98187
|
+
}
|
|
98188
|
+
function validateLegacyConfig(path3) {
|
|
98189
|
+
let raw;
|
|
98190
|
+
try {
|
|
98191
|
+
const st = statSync(path3);
|
|
98192
|
+
if (!st.isFile()) return { ok: false, reason: "not a regular file" };
|
|
98193
|
+
if (st.size > 1e6) return { ok: false, reason: `file too large (${st.size} bytes)` };
|
|
98194
|
+
raw = readFileSync6(path3, "utf-8");
|
|
98195
|
+
} catch (e) {
|
|
98196
|
+
return { ok: false, reason: e.message };
|
|
98197
|
+
}
|
|
98198
|
+
let parsed;
|
|
98199
|
+
try {
|
|
98200
|
+
const stripped = raw.charCodeAt(0) === 65279 ? raw.slice(1) : raw;
|
|
98201
|
+
parsed = JSON.parse(stripped);
|
|
98202
|
+
} catch (e) {
|
|
98203
|
+
return { ok: false, reason: `invalid JSON: ${e.message}` };
|
|
98204
|
+
}
|
|
98205
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
98206
|
+
return { ok: false, reason: "config root is not an object" };
|
|
98207
|
+
}
|
|
98208
|
+
return { ok: true, data: parsed };
|
|
98209
|
+
}
|
|
98210
|
+
function runMigrationIfNeeded() {
|
|
98211
|
+
const p = dgPaths();
|
|
98212
|
+
if (existsSync6(p.migrationBreadcrumb)) {
|
|
98213
|
+
return { status: "no-op" };
|
|
98214
|
+
}
|
|
98215
|
+
if (!detectLegacy()) {
|
|
98216
|
+
return { status: "no-op" };
|
|
98217
|
+
}
|
|
98218
|
+
ensureDir(p.root, 448);
|
|
98219
|
+
const lock = acquireLock(p.migrationLock);
|
|
98220
|
+
if (lock === "held" || lock === "stale-held") {
|
|
98221
|
+
return { status: "skipped", reason: "another dg process is migrating" };
|
|
98222
|
+
}
|
|
98223
|
+
const legacy = legacyPaths();
|
|
98224
|
+
const moves = [];
|
|
98225
|
+
let movedCount = 0;
|
|
98226
|
+
try {
|
|
98227
|
+
if (existsSync6(legacy.dgrc)) {
|
|
98228
|
+
const validation = validateLegacyConfig(legacy.dgrc);
|
|
98229
|
+
if (!validation.ok) {
|
|
98230
|
+
releaseLock(lock);
|
|
98231
|
+
return {
|
|
98232
|
+
status: "failed",
|
|
98233
|
+
reason: `~/.dgrc.json could not be read (${validation.reason}). Fix or remove the file and re-run dg.`
|
|
98234
|
+
};
|
|
98235
|
+
}
|
|
98236
|
+
ensureDir(p.configDir, 448);
|
|
98237
|
+
writeFileSync4(p.config, JSON.stringify(validation.data, null, 2) + "\n", { mode: 384 });
|
|
98238
|
+
try {
|
|
98239
|
+
chmodSync2(p.config, 384);
|
|
98240
|
+
} catch {
|
|
98241
|
+
}
|
|
98242
|
+
try {
|
|
98243
|
+
unlinkSync2(legacy.dgrc);
|
|
98244
|
+
} catch {
|
|
98245
|
+
}
|
|
98246
|
+
moves.push({ from: legacy.dgrc, to: p.config });
|
|
98247
|
+
movedCount++;
|
|
98248
|
+
}
|
|
98249
|
+
ensureDir(p.cacheDir, 448);
|
|
98250
|
+
if (existsSync6(legacy.cacheSqlite)) {
|
|
98251
|
+
moveFile(legacy.cacheSqlite, p.cacheSqlite, 384);
|
|
98252
|
+
moves.push({ from: legacy.cacheSqlite, to: p.cacheSqlite });
|
|
98253
|
+
movedCount++;
|
|
98254
|
+
}
|
|
98255
|
+
if (existsSync6(legacy.routingHint)) {
|
|
98256
|
+
moveFile(legacy.routingHint, p.routingHint, 384);
|
|
98257
|
+
moves.push({ from: legacy.routingHint, to: p.routingHint });
|
|
98258
|
+
movedCount++;
|
|
98259
|
+
}
|
|
98260
|
+
if (existsSync6(legacy.updateCheck)) {
|
|
98261
|
+
moveFile(legacy.updateCheck, p.updateCheck, 384);
|
|
98262
|
+
moves.push({ from: legacy.updateCheck, to: p.updateCheck });
|
|
98263
|
+
movedCount++;
|
|
98264
|
+
}
|
|
98265
|
+
ensureDir(p.stateDir, 448);
|
|
98266
|
+
if (existsSync6(legacy.trialBannerOld)) {
|
|
98267
|
+
moveFile(legacy.trialBannerOld, p.trialBanner, 384);
|
|
98268
|
+
moves.push({ from: legacy.trialBannerOld, to: p.trialBanner });
|
|
98269
|
+
movedCount++;
|
|
98270
|
+
}
|
|
98271
|
+
if (existsSync6(legacy.aliasesShOld)) {
|
|
98272
|
+
moveFile(legacy.aliasesShOld, p.aliasesSh, 420);
|
|
98273
|
+
moves.push({ from: legacy.aliasesShOld, to: p.aliasesSh });
|
|
98274
|
+
movedCount++;
|
|
98275
|
+
}
|
|
98276
|
+
if (existsSync6(legacy.depGuardianDir) && legacy.depGuardianDir !== p.root) {
|
|
98277
|
+
const candidates = [
|
|
98278
|
+
{ from: join(legacy.depGuardianDir, "config.json"), to: p.config, mode: 384 },
|
|
98279
|
+
{ from: join(legacy.depGuardianDir, "cache", "scans.sqlite"), to: p.cacheSqlite, mode: 384 },
|
|
98280
|
+
{ from: join(legacy.depGuardianDir, "cache", "update-check.json"), to: p.updateCheck, mode: 384 },
|
|
98281
|
+
{ from: join(legacy.depGuardianDir, "cache", "routing-hint.json"), to: p.routingHint, mode: 384 },
|
|
98282
|
+
{ from: join(legacy.depGuardianDir, "state", "aliases.sh"), to: p.aliasesSh, mode: 420 },
|
|
98283
|
+
{ from: join(legacy.depGuardianDir, "state", "trial-banner"), to: p.trialBanner, mode: 384 },
|
|
98284
|
+
{ from: join(legacy.depGuardianDir, "state", "hooks-installed.json"), to: p.hooksRegistry, mode: 384 },
|
|
98285
|
+
{ from: join(legacy.depGuardianDir, "last-trial-banner"), to: p.trialBanner, mode: 384 },
|
|
98286
|
+
{ from: join(legacy.depGuardianDir, "aliases.sh"), to: p.aliasesSh, mode: 420 }
|
|
98287
|
+
];
|
|
98288
|
+
for (const c of candidates) {
|
|
98289
|
+
if (existsSync6(c.from) && !existsSync6(c.to)) {
|
|
98290
|
+
moveFile(c.from, c.to, c.mode);
|
|
98291
|
+
moves.push({ from: c.from, to: c.to });
|
|
98292
|
+
movedCount++;
|
|
98293
|
+
}
|
|
98294
|
+
}
|
|
98295
|
+
try {
|
|
98296
|
+
rmSync2(legacy.depGuardianDir, { recursive: true, force: true });
|
|
98297
|
+
} catch {
|
|
98298
|
+
}
|
|
98299
|
+
}
|
|
98300
|
+
try {
|
|
98301
|
+
if (existsSync6(legacy.cacheDir) && legacy.cacheDir !== p.root) {
|
|
98302
|
+
rmSync2(legacy.cacheDir, { recursive: true, force: true });
|
|
98303
|
+
}
|
|
98304
|
+
} catch {
|
|
98305
|
+
}
|
|
98306
|
+
try {
|
|
98307
|
+
writeFileSync4(p.readme, README, { mode: 420 });
|
|
98308
|
+
} catch {
|
|
98309
|
+
}
|
|
98310
|
+
writeFileSync4(p.migrationBreadcrumb, (/* @__PURE__ */ new Date()).toISOString() + "\n", { mode: 384 });
|
|
98311
|
+
releaseLock(lock);
|
|
98312
|
+
if (process.stderr.isTTY) {
|
|
98313
|
+
process.stderr.write(
|
|
98314
|
+
`dg: reorganized local state into ${p.root} (one-time, ${movedCount} file${movedCount === 1 ? "" : "s"}; see README inside).
|
|
98315
|
+
`
|
|
98316
|
+
);
|
|
98317
|
+
}
|
|
98318
|
+
return { status: "migrated", movedCount };
|
|
98319
|
+
} catch (e) {
|
|
98320
|
+
rollback(moves);
|
|
98321
|
+
releaseLock(lock);
|
|
98322
|
+
return { status: "failed", reason: e.message };
|
|
98323
|
+
}
|
|
98324
|
+
}
|
|
98325
|
+
|
|
97084
98326
|
// src/bin.ts
|
|
97085
98327
|
init_alt_screen();
|
|
97086
98328
|
var CLI_VERSION = getVersion();
|
|
97087
98329
|
initTelemetry(CLI_VERSION);
|
|
98330
|
+
runMigrationIfNeeded();
|
|
97088
98331
|
function setProcessTitle(title) {
|
|
97089
98332
|
try {
|
|
97090
98333
|
process.title = title;
|
|
@@ -97112,8 +98355,8 @@ var isInteractive = process.stdout.isTTY === true && !process.env.CI && !process
|
|
|
97112
98355
|
async function main() {
|
|
97113
98356
|
const rawCommand = process.argv[2];
|
|
97114
98357
|
if (!rawCommand || rawCommand === "help" || rawCommand === "--help" || rawCommand === "-h") {
|
|
97115
|
-
const { USAGE:
|
|
97116
|
-
process.stdout.write(
|
|
98358
|
+
const { USAGE: USAGE6 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
98359
|
+
process.stdout.write(USAGE6);
|
|
97117
98360
|
return;
|
|
97118
98361
|
}
|
|
97119
98362
|
if (rawCommand === "--help-all" || rawCommand === "help-all") {
|
|
@@ -97126,15 +98369,15 @@ async function main() {
|
|
|
97126
98369
|
`);
|
|
97127
98370
|
return;
|
|
97128
98371
|
}
|
|
97129
|
-
const KNOWN_COMMANDS = ["scan", "npm", "pip", "wrap", "login", "logout", "status", "hook", "update", "kitty", "help", "version", "protect", "publish-check", "cleanup"];
|
|
98372
|
+
const KNOWN_COMMANDS = ["init", "scan", "npm", "pip", "wrap", "login", "logout", "status", "hook", "update", "kitty", "help", "version", "protect", "publish-check", "cleanup", "uninstall"];
|
|
97130
98373
|
if (rawCommand && !rawCommand.startsWith("-") && !KNOWN_COMMANDS.includes(rawCommand)) {
|
|
97131
|
-
const
|
|
98374
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
97132
98375
|
const best = closestCommand(rawCommand, KNOWN_COMMANDS);
|
|
97133
98376
|
const hint = best ? ` Did you mean '${best}'?` : "";
|
|
97134
98377
|
process.stderr.write(`
|
|
97135
|
-
${
|
|
98378
|
+
${chalk17.bold.red("Error:")} Unknown command '${rawCommand}'.${hint}
|
|
97136
98379
|
`);
|
|
97137
|
-
process.stderr.write(
|
|
98380
|
+
process.stderr.write(chalk17.dim(` Run 'dg --help' for available commands.
|
|
97138
98381
|
|
|
97139
98382
|
`));
|
|
97140
98383
|
process.exit(1);
|
|
@@ -97170,16 +98413,16 @@ async function main() {
|
|
|
97170
98413
|
} catch {
|
|
97171
98414
|
}
|
|
97172
98415
|
} else {
|
|
97173
|
-
const
|
|
98416
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
97174
98417
|
process.stderr.write(
|
|
97175
|
-
|
|
98418
|
+
chalk17.dim(
|
|
97176
98419
|
" note: --fresh skipped marking the first-run sentinel.\n The next dg command will re-trigger the wizard.\n\n"
|
|
97177
98420
|
)
|
|
97178
98421
|
);
|
|
97179
98422
|
}
|
|
97180
98423
|
} else {
|
|
97181
|
-
const
|
|
97182
|
-
process.stderr.write(
|
|
98424
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
98425
|
+
process.stderr.write(chalk17.yellow(" dg kitty needs an interactive terminal.\n"));
|
|
97183
98426
|
}
|
|
97184
98427
|
return;
|
|
97185
98428
|
}
|
|
@@ -97227,11 +98470,11 @@ async function main() {
|
|
|
97227
98470
|
if (v === "npm" || v === "pypi") ecosystem = v;
|
|
97228
98471
|
}
|
|
97229
98472
|
const { runNpmPublishCheck: runNpmPublishCheck2, runPypiPublishCheck: runPypiPublishCheck2, renderPublishCheckResult: renderPublishCheckResult2 } = await Promise.resolve().then(() => (init_publish_check(), publish_check_exports));
|
|
97230
|
-
const { existsSync:
|
|
97231
|
-
const { join:
|
|
98473
|
+
const { existsSync: existsSync21 } = await import("node:fs");
|
|
98474
|
+
const { join: join16 } = await import("node:path");
|
|
97232
98475
|
if (ecosystem === "auto") {
|
|
97233
|
-
if (
|
|
97234
|
-
else if (
|
|
98476
|
+
if (existsSync21(join16(process.cwd(), "package.json"))) ecosystem = "npm";
|
|
98477
|
+
else if (existsSync21(join16(process.cwd(), "pyproject.toml")) || existsSync21(join16(process.cwd(), "setup.py"))) ecosystem = "pypi";
|
|
97235
98478
|
else {
|
|
97236
98479
|
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");
|
|
97237
98480
|
process.exit(3);
|
|
@@ -97242,9 +98485,9 @@ async function main() {
|
|
|
97242
98485
|
if (wantJson) {
|
|
97243
98486
|
process.stdout.write(JSON.stringify({ ok: false, error: out.errorMessage }) + "\n");
|
|
97244
98487
|
} else {
|
|
97245
|
-
const
|
|
98488
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
97246
98489
|
process.stderr.write(`
|
|
97247
|
-
${
|
|
98490
|
+
${chalk17.red("publish-check error:")} ${out.errorMessage}
|
|
97248
98491
|
|
|
97249
98492
|
`);
|
|
97250
98493
|
}
|
|
@@ -97286,8 +98529,8 @@ async function main() {
|
|
|
97286
98529
|
await handleHookCommand2(process.argv.slice(3));
|
|
97287
98530
|
const updateMsg2 = await updatePromise2;
|
|
97288
98531
|
if (updateMsg2) {
|
|
97289
|
-
const
|
|
97290
|
-
process.stderr.write(
|
|
98532
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
98533
|
+
process.stderr.write(chalk17.dim(updateMsg2));
|
|
97291
98534
|
}
|
|
97292
98535
|
return;
|
|
97293
98536
|
}
|
|
@@ -97300,9 +98543,21 @@ async function main() {
|
|
|
97300
98543
|
const code = await handleCleanupCommand2(process.argv.slice(3));
|
|
97301
98544
|
process.exit(code);
|
|
97302
98545
|
}
|
|
98546
|
+
if (rawCommand === "uninstall") {
|
|
98547
|
+
const { handleUninstallCommand: handleUninstallCommand2 } = await Promise.resolve().then(() => (init_uninstall(), uninstall_exports));
|
|
98548
|
+
const code = await handleUninstallCommand2(process.argv.slice(3));
|
|
98549
|
+
process.exit(code);
|
|
98550
|
+
}
|
|
98551
|
+
if (rawCommand === "init") {
|
|
98552
|
+
const { gateOrExit: gateOrExit2 } = await Promise.resolve().then(() => (init_terms_gate(), terms_gate_exports));
|
|
98553
|
+
await gateOrExit2();
|
|
98554
|
+
const { handleInitCommand: handleInitCommand2 } = await Promise.resolve().then(() => (init_init(), init_exports3));
|
|
98555
|
+
const code = await handleInitCommand2(process.argv.slice(3));
|
|
98556
|
+
process.exit(code);
|
|
98557
|
+
}
|
|
97303
98558
|
if (rawCommand === "logout") {
|
|
97304
98559
|
const { getStoredApiKey: getStoredApiKey2, clearCredentials: clearCredentials2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
97305
|
-
const
|
|
98560
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
97306
98561
|
const apiKey = getStoredApiKey2();
|
|
97307
98562
|
if (apiKey) {
|
|
97308
98563
|
const { parseConfig: parseConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
@@ -97317,7 +98572,7 @@ async function main() {
|
|
|
97317
98572
|
}
|
|
97318
98573
|
}
|
|
97319
98574
|
clearCredentials2();
|
|
97320
|
-
process.stderr.write(
|
|
98575
|
+
process.stderr.write(chalk17.green(" Logged out.\n"));
|
|
97321
98576
|
return;
|
|
97322
98577
|
}
|
|
97323
98578
|
const strictFlags = rawCommand !== "npm" && rawCommand !== "pip";
|
|
@@ -97341,8 +98596,8 @@ async function main() {
|
|
|
97341
98596
|
await runStatic2(config3);
|
|
97342
98597
|
} else {
|
|
97343
98598
|
if (config3.mode === "off") {
|
|
97344
|
-
const
|
|
97345
|
-
process.stderr.write(
|
|
98599
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
98600
|
+
process.stderr.write(chalk17.dim(" Dependency Guardian: mode is off \u2014 skipping.\n"));
|
|
97346
98601
|
process.exit(0);
|
|
97347
98602
|
}
|
|
97348
98603
|
const { getStoredApiKey: getStoredApiKey2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
@@ -97356,11 +98611,11 @@ async function main() {
|
|
|
97356
98611
|
signal: AbortSignal.timeout(3e3)
|
|
97357
98612
|
});
|
|
97358
98613
|
if (resp.ok) {
|
|
97359
|
-
const
|
|
98614
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
97360
98615
|
const data = await resp.json();
|
|
97361
98616
|
const name = data.name || "authenticated";
|
|
97362
98617
|
const tier = data.tier || "free";
|
|
97363
|
-
const tierColor = tier === "free" ?
|
|
98618
|
+
const tierColor = tier === "free" ? chalk17.yellow(tier) : chalk17.green(tier);
|
|
97364
98619
|
userStatus = `${name} \xB7 ${tierColor}`;
|
|
97365
98620
|
if (data.scansLimit === null || data.scansLimit === void 0) {
|
|
97366
98621
|
scanUsage = "unlimited scans";
|
|
@@ -97396,8 +98651,8 @@ async function main() {
|
|
|
97396
98651
|
}
|
|
97397
98652
|
const updateMsg2 = await updatePromise;
|
|
97398
98653
|
if (updateMsg2) {
|
|
97399
|
-
const
|
|
97400
|
-
process.stderr.write(
|
|
98654
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
98655
|
+
process.stderr.write(chalk17.dim(updateMsg2));
|
|
97401
98656
|
}
|
|
97402
98657
|
try {
|
|
97403
98658
|
const { pingSetupEvent: pingSetupEvent2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
@@ -97416,8 +98671,8 @@ async function main() {
|
|
|
97416
98671
|
}
|
|
97417
98672
|
const updateMsg2 = await updatePromise;
|
|
97418
98673
|
if (updateMsg2) {
|
|
97419
|
-
const
|
|
97420
|
-
process.stderr.write(
|
|
98674
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
98675
|
+
process.stderr.write(chalk17.dim(updateMsg2));
|
|
97421
98676
|
}
|
|
97422
98677
|
try {
|
|
97423
98678
|
const { pingSetupEvent: pingSetupEvent2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
@@ -97443,8 +98698,8 @@ async function main() {
|
|
|
97443
98698
|
}
|
|
97444
98699
|
const updateMsg = await updatePromise;
|
|
97445
98700
|
if (updateMsg) {
|
|
97446
|
-
const
|
|
97447
|
-
process.stderr.write(
|
|
98701
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
98702
|
+
process.stderr.write(chalk17.dim(updateMsg));
|
|
97448
98703
|
}
|
|
97449
98704
|
try {
|
|
97450
98705
|
const { pingSetupEvent: pingSetupEvent2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
@@ -97468,8 +98723,8 @@ main().catch(async (err) => {
|
|
|
97468
98723
|
authenticated: isAuthed
|
|
97469
98724
|
});
|
|
97470
98725
|
await flush2();
|
|
97471
|
-
const
|
|
97472
|
-
const color = err.securityRelease ?
|
|
98726
|
+
const chalk17 = (await Promise.resolve().then(() => __toESM(require_source()))).default;
|
|
98727
|
+
const color = err.securityRelease ? chalk17.bold.red : chalk17.yellow;
|
|
97473
98728
|
if (process.argv.includes("--json")) {
|
|
97474
98729
|
process.stdout.write(JSON.stringify({
|
|
97475
98730
|
error: true,
|