@westbayberry/dg 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +679 -694
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1894,6 +1894,7 @@ __export(auth_exports, {
|
|
|
1894
1894
|
pollAuthSession: () => pollAuthSession,
|
|
1895
1895
|
preflightAuthCheck: () => preflightAuthCheck,
|
|
1896
1896
|
readTermsAcceptedAt: () => readTermsAcceptedAt,
|
|
1897
|
+
recordScanCapReached: () => recordScanCapReached,
|
|
1897
1898
|
recordScanNoticeShown: () => recordScanNoticeShown,
|
|
1898
1899
|
saveCredentials: () => saveCredentials,
|
|
1899
1900
|
saveCredentialsFromToken: () => saveCredentialsFromToken,
|
|
@@ -2283,18 +2284,28 @@ function writeCachedAuthStatus(status) {
|
|
|
2283
2284
|
} catch {
|
|
2284
2285
|
}
|
|
2285
2286
|
}
|
|
2287
|
+
function recordScanCapReached(scansUsed, maxScans, reason) {
|
|
2288
|
+
writeCachedAuthStatus({
|
|
2289
|
+
authenticated: !!getStoredApiKey(),
|
|
2290
|
+
freeTierCapReached: true,
|
|
2291
|
+
scansUsed,
|
|
2292
|
+
scansLimit: maxScans,
|
|
2293
|
+
capReason: reason,
|
|
2294
|
+
fetchedAt: Date.now()
|
|
2295
|
+
});
|
|
2296
|
+
}
|
|
2286
2297
|
async function preflightAuthCheck(apiUrl) {
|
|
2287
2298
|
if (process.env.DG_SIMULATE_FREE_CAP_REACHED === "1") {
|
|
2288
2299
|
throw new PreflightFreeCapReachedError(5, 5);
|
|
2289
2300
|
}
|
|
2301
|
+
const apiKey = getStoredApiKey();
|
|
2290
2302
|
const cached = readCachedAuthStatus();
|
|
2291
|
-
if (cached) {
|
|
2303
|
+
if (cached && cached.authenticated === !!apiKey) {
|
|
2292
2304
|
if (cached.freeTierCapReached) {
|
|
2293
2305
|
throw new PreflightFreeCapReachedError(cached.scansUsed, cached.scansLimit ?? cached.scansUsed, cached.capReason ?? "monthly_limit");
|
|
2294
2306
|
}
|
|
2295
2307
|
return cached;
|
|
2296
2308
|
}
|
|
2297
|
-
const apiKey = getStoredApiKey();
|
|
2298
2309
|
const headers = {};
|
|
2299
2310
|
if (apiKey) {
|
|
2300
2311
|
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
@@ -2324,17 +2335,17 @@ async function preflightAuthCheck(apiUrl) {
|
|
|
2324
2335
|
} catch {
|
|
2325
2336
|
}
|
|
2326
2337
|
if (body.freeTierCapReached) {
|
|
2327
|
-
const
|
|
2338
|
+
const capReason2 = body.capReason === "prefix_cap" ? "prefix_cap" : "monthly_limit";
|
|
2328
2339
|
const status2 = {
|
|
2329
2340
|
authenticated: !!apiKey,
|
|
2330
2341
|
freeTierCapReached: true,
|
|
2331
2342
|
scansUsed: body.scansUsed ?? 0,
|
|
2332
2343
|
scansLimit: body.maxScans ?? 0,
|
|
2333
|
-
capReason,
|
|
2344
|
+
capReason: capReason2,
|
|
2334
2345
|
fetchedAt: Date.now()
|
|
2335
2346
|
};
|
|
2336
2347
|
writeCachedAuthStatus(status2);
|
|
2337
|
-
throw new PreflightFreeCapReachedError(status2.scansUsed, status2.scansLimit ?? 0,
|
|
2348
|
+
throw new PreflightFreeCapReachedError(status2.scansUsed, status2.scansLimit ?? 0, capReason2);
|
|
2338
2349
|
}
|
|
2339
2350
|
}
|
|
2340
2351
|
if (!resp.ok) {
|
|
@@ -2352,18 +2363,20 @@ async function preflightAuthCheck(apiUrl) {
|
|
|
2352
2363
|
data = await resp.json();
|
|
2353
2364
|
} catch {
|
|
2354
2365
|
}
|
|
2366
|
+
const capReason = data.capReason === "prefix_cap" ? "prefix_cap" : "monthly_limit";
|
|
2355
2367
|
const status = {
|
|
2356
2368
|
authenticated: !!apiKey,
|
|
2357
2369
|
freeTierCapReached: !!data.freeTierCapReached,
|
|
2358
2370
|
scansUsed: data.scansUsed ?? 0,
|
|
2359
2371
|
scansLimit: data.scansLimit ?? null,
|
|
2372
|
+
capReason,
|
|
2360
2373
|
tier: data.tier,
|
|
2361
2374
|
name: data.name,
|
|
2362
2375
|
fetchedAt: Date.now()
|
|
2363
2376
|
};
|
|
2364
2377
|
writeCachedAuthStatus(status);
|
|
2365
2378
|
if (status.freeTierCapReached) {
|
|
2366
|
-
throw new PreflightFreeCapReachedError(status.scansUsed, status.scansLimit ?? 0);
|
|
2379
|
+
throw new PreflightFreeCapReachedError(status.scansUsed, status.scansLimit ?? 0, capReason);
|
|
2367
2380
|
}
|
|
2368
2381
|
return status;
|
|
2369
2382
|
}
|
|
@@ -2555,9 +2568,9 @@ function loadDgrc() {
|
|
|
2555
2568
|
`);
|
|
2556
2569
|
}
|
|
2557
2570
|
}
|
|
2558
|
-
if (cwdPath !== homePath && existsSync2(cwdPath)
|
|
2571
|
+
if (cwdPath !== homePath && existsSync2(cwdPath)) {
|
|
2559
2572
|
process.stderr.write(
|
|
2560
|
-
`dg: note: ./.dgrc.json is ignored (repo-controlled config is no longer honored). Use ~/.dg/.dgrc.json
|
|
2573
|
+
`dg: note: ./.dgrc.json is ignored (repo-controlled config is no longer honored). Use ~/.dg/.dgrc.json or CLI flags.
|
|
2561
2574
|
`
|
|
2562
2575
|
);
|
|
2563
2576
|
}
|
|
@@ -2655,7 +2668,7 @@ function parseConfig(argv, strictFlags = true) {
|
|
|
2655
2668
|
const apiKey = dgrc.apiKey && typeof dgrc.apiKey === "string" && (dgrc.apiKey.startsWith("dg_live_") || dgrc.apiKey.startsWith("dg_test_")) ? dgrc.apiKey : null;
|
|
2656
2669
|
const isProtectiveWrapper = command === "npm" || command === "pip";
|
|
2657
2670
|
const defaultMode = isProtectiveWrapper ? "block" : "warn";
|
|
2658
|
-
const modeRaw = values.mode ??
|
|
2671
|
+
const modeRaw = values.mode ?? dgrc.mode ?? defaultMode;
|
|
2659
2672
|
if (!["block", "warn", "off"].includes(modeRaw)) {
|
|
2660
2673
|
process.stderr.write(
|
|
2661
2674
|
`Error: Invalid mode "${modeRaw}". Must be block, warn, or off.
|
|
@@ -2683,7 +2696,7 @@ function parseConfig(argv, strictFlags = true) {
|
|
|
2683
2696
|
sarif: values.sarif || false,
|
|
2684
2697
|
scanAll: !values["changed-only"],
|
|
2685
2698
|
baseLockfile: values["base-lockfile"] ?? null,
|
|
2686
|
-
workspace: values.workspace ??
|
|
2699
|
+
workspace: values.workspace ?? null,
|
|
2687
2700
|
outputFile: values.output ?? null,
|
|
2688
2701
|
command,
|
|
2689
2702
|
debug,
|
|
@@ -2692,7 +2705,6 @@ function parseConfig(argv, strictFlags = true) {
|
|
|
2692
2705
|
quiet: (() => {
|
|
2693
2706
|
if (values["no-quiet"]) return false;
|
|
2694
2707
|
if (values.quiet) return true;
|
|
2695
|
-
if (process.env.DG_QUIET === "1") return true;
|
|
2696
2708
|
if (process.env.CI === "1" || process.env.CI === "true") return true;
|
|
2697
2709
|
return false;
|
|
2698
2710
|
})(),
|
|
@@ -2801,8 +2813,7 @@ var init_config = __esm({
|
|
|
2801
2813
|
--api-url <url> API base URL (default: https://api.westbayberry.com)
|
|
2802
2814
|
|
|
2803
2815
|
Install-wrapper flags (work on \`npm install\`, \`pip install\`, etc.):
|
|
2804
|
-
--dg-force Bypass a block (audit-visible
|
|
2805
|
-
--dg-force-reason "..." Reason recorded with the override
|
|
2816
|
+
--dg-force Bypass a block (audit-visible)
|
|
2806
2817
|
--dg-no-scripts Add \`--ignore-scripts\` to the real install
|
|
2807
2818
|
--strict Strongest protection: implies --dg-no-scripts and
|
|
2808
2819
|
refuses any partial-coverage scan
|
|
@@ -2811,16 +2822,11 @@ var init_config = __esm({
|
|
|
2811
2822
|
DG_API_KEY CI auth token (dg_live_* or dg_test_*).
|
|
2812
2823
|
Used when ~/.dg/config.json is absent.
|
|
2813
2824
|
File beats env if both are present.
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
DG_DEBUG=1 Enable debug output
|
|
2817
|
-
DG_QUIET=1 Same as passing --quiet
|
|
2818
|
-
DG_WORKSPACE Workspace subdirectory to scan
|
|
2819
|
-
DG_TELEMETRY=0 Opt out of anonymous crash reports (on by default; DO_NOT_TRACK=1 also opts out)
|
|
2820
|
-
DG_FORCE_POSTINSTALL=1 Force postinstall to run even outside a TTY
|
|
2821
|
-
(useful for re-running setup manually)
|
|
2825
|
+
DG_TELEMETRY=0 Opt out of anonymous crash reports (on by default;
|
|
2826
|
+
DO_NOT_TRACK=1 also opts out)
|
|
2822
2827
|
DG_NO_RC_EDIT=1 Postinstall installs shims but does not edit
|
|
2823
2828
|
shell rc files; you set PATH yourself
|
|
2829
|
+
NO_COLOR=1 Disable colored output
|
|
2824
2830
|
CI=1 Auto-enables --ci output mode + --quiet
|
|
2825
2831
|
|
|
2826
2832
|
Exit Codes:
|
|
@@ -2837,8 +2843,8 @@ var init_config = __esm({
|
|
|
2837
2843
|
if the verdict permits. Top-level versions are pinned to the
|
|
2838
2844
|
exact version we scanned (TOCTOU defense).
|
|
2839
2845
|
- Warn verdict in a TTY: shows findings and prompts \`Proceed? (Y/n)\`.
|
|
2840
|
-
- Block verdict: refuses install, prints the override command
|
|
2841
|
-
|
|
2846
|
+
- Block verdict: refuses install, prints the override command
|
|
2847
|
+
(re-run with \`--dg-force\` to install anyway).
|
|
2842
2848
|
- Read-only subcommands (npm view, pip show, pnpm list, etc.) skip
|
|
2843
2849
|
the wrapper entirely \u2014 fast pass-through to the real binary.
|
|
2844
2850
|
- \`dg scan\` is read-only and never blocks. It does not consume
|
|
@@ -2851,7 +2857,7 @@ var init_config = __esm({
|
|
|
2851
2857
|
bun add some-pkg
|
|
2852
2858
|
uv pip install numpy
|
|
2853
2859
|
pipx install black
|
|
2854
|
-
npm install risky-pkg --dg-force
|
|
2860
|
+
npm install risky-pkg --dg-force
|
|
2855
2861
|
dg scan --json | jq # CI-friendly
|
|
2856
2862
|
dg status # see what's protected
|
|
2857
2863
|
`.trimStart();
|
|
@@ -3993,7 +3999,6 @@ dg publish-check \u2014 scan a package about to be published
|
|
|
3993
3999
|
|
|
3994
4000
|
Usage:
|
|
3995
4001
|
dg publish-check [--ecosystem npm|pypi] [--json] [--dg-force]
|
|
3996
|
-
[--dg-force-reason <text>]
|
|
3997
4002
|
|
|
3998
4003
|
What it does:
|
|
3999
4004
|
Scans the package artifact you're about to publish for bundled secrets,
|
|
@@ -4005,7 +4010,6 @@ Flags:
|
|
|
4005
4010
|
--ecosystem <npm|pypi> Force ecosystem detection
|
|
4006
4011
|
--json JSON output to stdout
|
|
4007
4012
|
--dg-force Bypass block verdict (audited)
|
|
4008
|
-
--dg-force-reason <text> Reason string stored with override
|
|
4009
4013
|
|
|
4010
4014
|
Exit codes:
|
|
4011
4015
|
0 pass No risks detected
|
|
@@ -14026,7 +14030,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
14026
14030
|
var HostPortal = 4;
|
|
14027
14031
|
var HostComponent = 5;
|
|
14028
14032
|
var HostText = 6;
|
|
14029
|
-
var
|
|
14033
|
+
var Fragment7 = 7;
|
|
14030
14034
|
var Mode = 8;
|
|
14031
14035
|
var ContextConsumer = 9;
|
|
14032
14036
|
var ContextProvider = 10;
|
|
@@ -14166,7 +14170,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
14166
14170
|
return "DehydratedFragment";
|
|
14167
14171
|
case ForwardRef:
|
|
14168
14172
|
return getWrappedName$1(type, type.render, "ForwardRef");
|
|
14169
|
-
case
|
|
14173
|
+
case Fragment7:
|
|
14170
14174
|
return "Fragment";
|
|
14171
14175
|
case HostComponent:
|
|
14172
14176
|
return type;
|
|
@@ -17300,7 +17304,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
17300
17304
|
}
|
|
17301
17305
|
}
|
|
17302
17306
|
function updateFragment2(returnFiber, current2, fragment, lanes, key) {
|
|
17303
|
-
if (current2 === null || current2.tag !==
|
|
17307
|
+
if (current2 === null || current2.tag !== Fragment7) {
|
|
17304
17308
|
var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
|
|
17305
17309
|
created.return = returnFiber;
|
|
17306
17310
|
return created;
|
|
@@ -17703,7 +17707,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
17703
17707
|
if (child.key === key) {
|
|
17704
17708
|
var elementType = element.type;
|
|
17705
17709
|
if (elementType === REACT_FRAGMENT_TYPE) {
|
|
17706
|
-
if (child.tag ===
|
|
17710
|
+
if (child.tag === Fragment7) {
|
|
17707
17711
|
deleteRemainingChildren(returnFiber, child.sibling);
|
|
17708
17712
|
var existing = useFiber(child, element.props.children);
|
|
17709
17713
|
existing.return = returnFiber;
|
|
@@ -23194,7 +23198,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
23194
23198
|
var _resolvedProps2 = workInProgress2.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
|
|
23195
23199
|
return updateForwardRef(current2, workInProgress2, type, _resolvedProps2, renderLanes2);
|
|
23196
23200
|
}
|
|
23197
|
-
case
|
|
23201
|
+
case Fragment7:
|
|
23198
23202
|
return updateFragment(current2, workInProgress2, renderLanes2);
|
|
23199
23203
|
case Mode:
|
|
23200
23204
|
return updateMode(current2, workInProgress2, renderLanes2);
|
|
@@ -23631,7 +23635,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
23631
23635
|
case SimpleMemoComponent:
|
|
23632
23636
|
case FunctionComponent:
|
|
23633
23637
|
case ForwardRef:
|
|
23634
|
-
case
|
|
23638
|
+
case Fragment7:
|
|
23635
23639
|
case Mode:
|
|
23636
23640
|
case Profiler:
|
|
23637
23641
|
case ContextConsumer:
|
|
@@ -28399,7 +28403,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
28399
28403
|
return fiber;
|
|
28400
28404
|
}
|
|
28401
28405
|
function createFiberFromFragment(elements, mode, lanes, key) {
|
|
28402
|
-
var fiber = createFiber(
|
|
28406
|
+
var fiber = createFiber(Fragment7, elements, key, mode);
|
|
28403
28407
|
fiber.lanes = lanes;
|
|
28404
28408
|
return fiber;
|
|
28405
28409
|
}
|
|
@@ -42574,6 +42578,24 @@ var init_lockfile = __esm({
|
|
|
42574
42578
|
});
|
|
42575
42579
|
|
|
42576
42580
|
// src/commands/wrapper-shared.ts
|
|
42581
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
42582
|
+
function spawnTrimmed(bin, args, env3) {
|
|
42583
|
+
return new Promise((resolve3) => {
|
|
42584
|
+
const child = spawn2(bin, args, { stdio: ["inherit", "pipe", "pipe"], shell: false, env: { ...env3, FORCE_COLOR: "1" } });
|
|
42585
|
+
let buf = "";
|
|
42586
|
+
const onData = (c) => {
|
|
42587
|
+
buf += c.toString();
|
|
42588
|
+
};
|
|
42589
|
+
child.stdout?.on("data", onData);
|
|
42590
|
+
child.stderr?.on("data", onData);
|
|
42591
|
+
child.on("error", () => resolve3(1));
|
|
42592
|
+
child.on("close", (code) => {
|
|
42593
|
+
const lines = buf.split("\n").filter((l) => l.replace(ANSI_RE, "").trim() !== "");
|
|
42594
|
+
if (lines.length) process.stdout.write(lines.join("\n") + "\n");
|
|
42595
|
+
resolve3(code ?? 1);
|
|
42596
|
+
});
|
|
42597
|
+
});
|
|
42598
|
+
}
|
|
42577
42599
|
function injectIgnoreScripts(args, opts) {
|
|
42578
42600
|
if (!opts.isNpmFamily) return args;
|
|
42579
42601
|
if (!(opts.strict || opts.dgNoScripts)) return args;
|
|
@@ -42582,7 +42604,6 @@ function injectIgnoreScripts(args, opts) {
|
|
|
42582
42604
|
}
|
|
42583
42605
|
function stripDgFlags(args) {
|
|
42584
42606
|
let dgForce = false;
|
|
42585
|
-
let dgForceReason;
|
|
42586
42607
|
let dgNoScripts = false;
|
|
42587
42608
|
const filtered = [];
|
|
42588
42609
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -42591,15 +42612,6 @@ function stripDgFlags(args) {
|
|
|
42591
42612
|
dgForce = true;
|
|
42592
42613
|
continue;
|
|
42593
42614
|
}
|
|
42594
|
-
if (arg === "--dg-force-reason") {
|
|
42595
|
-
dgForceReason = (args[i + 1] ?? "").slice(0, 500);
|
|
42596
|
-
i++;
|
|
42597
|
-
continue;
|
|
42598
|
-
}
|
|
42599
|
-
if (arg.startsWith("--dg-force-reason=")) {
|
|
42600
|
-
dgForceReason = arg.slice("--dg-force-reason=".length).slice(0, 500);
|
|
42601
|
-
continue;
|
|
42602
|
-
}
|
|
42603
42615
|
if (arg === "--dg-no-scripts") {
|
|
42604
42616
|
dgNoScripts = true;
|
|
42605
42617
|
continue;
|
|
@@ -42619,12 +42631,13 @@ function stripDgFlags(args) {
|
|
|
42619
42631
|
if (consumed) continue;
|
|
42620
42632
|
filtered.push(arg);
|
|
42621
42633
|
}
|
|
42622
|
-
return { filtered, dgForce,
|
|
42634
|
+
return { filtered, dgForce, dgNoScripts };
|
|
42623
42635
|
}
|
|
42624
|
-
var DG_VALUE_FLAGS, DG_BOOLEAN_FLAGS;
|
|
42636
|
+
var ANSI_RE, DG_VALUE_FLAGS, DG_BOOLEAN_FLAGS;
|
|
42625
42637
|
var init_wrapper_shared = __esm({
|
|
42626
42638
|
"src/commands/wrapper-shared.ts"() {
|
|
42627
42639
|
"use strict";
|
|
42640
|
+
ANSI_RE = /\x1b\[[0-9;]*m/g;
|
|
42628
42641
|
DG_VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
42629
42642
|
"--mode",
|
|
42630
42643
|
"--api-url",
|
|
@@ -42633,6 +42646,8 @@ var init_wrapper_shared = __esm({
|
|
|
42633
42646
|
"--workspace",
|
|
42634
42647
|
"--output",
|
|
42635
42648
|
"-o",
|
|
42649
|
+
// Removed flag: still consumed (with its value) so a legacy invocation is
|
|
42650
|
+
// silently stripped rather than leaking to the real installer as a package.
|
|
42636
42651
|
"--dg-force-reason"
|
|
42637
42652
|
]);
|
|
42638
42653
|
DG_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
@@ -42650,7 +42665,7 @@ var init_wrapper_shared = __esm({
|
|
|
42650
42665
|
});
|
|
42651
42666
|
|
|
42652
42667
|
// src/commands/npm-wrapper.ts
|
|
42653
|
-
import { spawn as
|
|
42668
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
42654
42669
|
import { readFileSync as readFileSync9, existsSync as existsSync12, mkdtempSync, writeFileSync as writeFileSync8, rmSync } from "node:fs";
|
|
42655
42670
|
import { join as join7 } from "node:path";
|
|
42656
42671
|
import { tmpdir } from "node:os";
|
|
@@ -42665,7 +42680,7 @@ function shimSentinelEnv() {
|
|
|
42665
42680
|
return childInstallEnv();
|
|
42666
42681
|
}
|
|
42667
42682
|
function parseNpmArgs(args) {
|
|
42668
|
-
const { filtered, dgForce,
|
|
42683
|
+
const { filtered, dgForce, dgNoScripts } = stripDgFlags(args);
|
|
42669
42684
|
const command = filtered[0] ?? "";
|
|
42670
42685
|
const shouldScan = INSTALL_COMMANDS.has(command);
|
|
42671
42686
|
const packages = [];
|
|
@@ -42686,7 +42701,6 @@ function parseNpmArgs(args) {
|
|
|
42686
42701
|
packages,
|
|
42687
42702
|
rawArgs: filtered,
|
|
42688
42703
|
dgForce,
|
|
42689
|
-
dgForceReason,
|
|
42690
42704
|
dgNoScripts,
|
|
42691
42705
|
shouldScan
|
|
42692
42706
|
};
|
|
@@ -42742,7 +42756,7 @@ async function resolveVersion(spec) {
|
|
|
42742
42756
|
return null;
|
|
42743
42757
|
}
|
|
42744
42758
|
return new Promise((resolve3) => {
|
|
42745
|
-
const child =
|
|
42759
|
+
const child = spawn3(realNpmBinary(), ["view", spec, "version", "--json"], {
|
|
42746
42760
|
stdio: ["pipe", "pipe", "pipe"],
|
|
42747
42761
|
env: shimSentinelEnv()
|
|
42748
42762
|
});
|
|
@@ -42818,9 +42832,12 @@ async function resolvePackages(specs) {
|
|
|
42818
42832
|
return { resolved, failed };
|
|
42819
42833
|
}
|
|
42820
42834
|
function runNpm(args, opts) {
|
|
42835
|
+
if (opts?.trim) {
|
|
42836
|
+
return spawnTrimmed(realNpmBinary(), args, shimSentinelEnv());
|
|
42837
|
+
}
|
|
42821
42838
|
return new Promise((resolve3) => {
|
|
42822
42839
|
const stdio = opts?.stdoutToStderr ? ["inherit", "pipe", "inherit"] : ["inherit", "inherit", "inherit"];
|
|
42823
|
-
const child =
|
|
42840
|
+
const child = spawn3(realNpmBinary(), args, { stdio, shell: false, env: shimSentinelEnv() });
|
|
42824
42841
|
if (opts?.stdoutToStderr && child.stdout) {
|
|
42825
42842
|
child.stdout.on("data", (chunk) => {
|
|
42826
42843
|
process.stderr.write(chunk);
|
|
@@ -42840,7 +42857,7 @@ async function resolveTreeNpm(specs) {
|
|
|
42840
42857
|
try {
|
|
42841
42858
|
writeFileSync8(join7(dir, "package.json"), '{"name":"_dg_resolve","version":"1.0.0","private":true}');
|
|
42842
42859
|
const stdout = await new Promise((resolve3) => {
|
|
42843
|
-
const child =
|
|
42860
|
+
const child = spawn3(
|
|
42844
42861
|
realNpmBinary(),
|
|
42845
42862
|
[
|
|
42846
42863
|
"install",
|
|
@@ -43000,10 +43017,10 @@ var init_npm_wrapper = __esm({
|
|
|
43000
43017
|
});
|
|
43001
43018
|
|
|
43002
43019
|
// src/commands/pip-wrapper.ts
|
|
43003
|
-
import { spawn as
|
|
43020
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
43004
43021
|
import { existsSync as existsSync13 } from "node:fs";
|
|
43005
43022
|
function parsePipArgs(args) {
|
|
43006
|
-
const { filtered, dgForce,
|
|
43023
|
+
const { filtered, dgForce, dgNoScripts } = stripDgFlags(args);
|
|
43007
43024
|
const command = filtered[0] ?? "";
|
|
43008
43025
|
const shouldScan = INSTALL_COMMANDS2.has(command);
|
|
43009
43026
|
const packages = [];
|
|
@@ -43030,7 +43047,6 @@ function parsePipArgs(args) {
|
|
|
43030
43047
|
packages,
|
|
43031
43048
|
rawArgs: filtered,
|
|
43032
43049
|
dgForce,
|
|
43033
|
-
dgForceReason,
|
|
43034
43050
|
dgNoScripts,
|
|
43035
43051
|
shouldScan,
|
|
43036
43052
|
requirementsFile
|
|
@@ -43202,7 +43218,7 @@ async function detectPipBinary() {
|
|
|
43202
43218
|
try {
|
|
43203
43219
|
const parts = cmd.split(" ");
|
|
43204
43220
|
const code = await new Promise((resolve3) => {
|
|
43205
|
-
const child =
|
|
43221
|
+
const child = spawn4(parts[0], [...parts.slice(1), "--version"], {
|
|
43206
43222
|
stdio: ["pipe", "pipe", "pipe"],
|
|
43207
43223
|
timeout: 5e3,
|
|
43208
43224
|
env: shimSentinelEnv2()
|
|
@@ -43221,9 +43237,12 @@ async function detectPipBinary() {
|
|
|
43221
43237
|
async function runPip(args, opts) {
|
|
43222
43238
|
const pipCmd = await detectPipBinary();
|
|
43223
43239
|
const parts = pipCmd.split(" ");
|
|
43240
|
+
if (opts?.trim) {
|
|
43241
|
+
return spawnTrimmed(parts[0], [...parts.slice(1), ...args], shimSentinelEnv2());
|
|
43242
|
+
}
|
|
43224
43243
|
return new Promise((resolve3) => {
|
|
43225
43244
|
const stdio = opts?.stdoutToStderr ? ["inherit", "pipe", "inherit"] : ["inherit", "inherit", "inherit"];
|
|
43226
|
-
const child =
|
|
43245
|
+
const child = spawn4(parts[0], [...parts.slice(1), ...args], { stdio, shell: false, env: shimSentinelEnv2() });
|
|
43227
43246
|
if (opts?.stdoutToStderr && child.stdout) {
|
|
43228
43247
|
child.stdout.on("data", (chunk) => {
|
|
43229
43248
|
process.stderr.write(chunk);
|
|
@@ -43238,7 +43257,7 @@ async function pipVersion() {
|
|
|
43238
43257
|
const pipCmd = await detectPipBinary();
|
|
43239
43258
|
const parts = pipCmd.split(" ");
|
|
43240
43259
|
return await new Promise((resolve3) => {
|
|
43241
|
-
const child =
|
|
43260
|
+
const child = spawn4(parts[0], [...parts.slice(1), "--version"], {
|
|
43242
43261
|
stdio: ["pipe", "pipe", "pipe"],
|
|
43243
43262
|
timeout: 5e3,
|
|
43244
43263
|
env: shimSentinelEnv2()
|
|
@@ -43296,7 +43315,7 @@ async function resolveTreePip(specs) {
|
|
|
43296
43315
|
const pipCmd = await detectPipBinary();
|
|
43297
43316
|
const parts = pipCmd.split(" ");
|
|
43298
43317
|
const runDryRun = (extraFlags) => new Promise((resolve3) => {
|
|
43299
|
-
const child =
|
|
43318
|
+
const child = spawn4(
|
|
43300
43319
|
parts[0],
|
|
43301
43320
|
[
|
|
43302
43321
|
...parts.slice(1),
|
|
@@ -43388,6 +43407,153 @@ var init_pip_wrapper = __esm({
|
|
|
43388
43407
|
}
|
|
43389
43408
|
});
|
|
43390
43409
|
|
|
43410
|
+
// src/wrapper/route.ts
|
|
43411
|
+
function routeVerdict(input) {
|
|
43412
|
+
const { verdict, mode, strict, dgForce } = input;
|
|
43413
|
+
const refuseHard = mode === "block" || strict;
|
|
43414
|
+
const refuseWarn = strict;
|
|
43415
|
+
const D = (outcome, refuseExitCode, extra) => ({
|
|
43416
|
+
verdict,
|
|
43417
|
+
outcome,
|
|
43418
|
+
refuseExitCode,
|
|
43419
|
+
bypassed: false,
|
|
43420
|
+
...extra
|
|
43421
|
+
});
|
|
43422
|
+
if (verdict === "free_cap") return D("refuse", 1);
|
|
43423
|
+
if (verdict === "pass") return D("install", 0);
|
|
43424
|
+
if (dgForce && (verdict === "warn" || verdict === "block")) {
|
|
43425
|
+
return D("install", 0, { audit: "override", bypassed: true });
|
|
43426
|
+
}
|
|
43427
|
+
switch (verdict) {
|
|
43428
|
+
case "warn":
|
|
43429
|
+
if (mode === "off") return D("install", 0);
|
|
43430
|
+
if (refuseWarn) return D("refuse", 1);
|
|
43431
|
+
return D("prompt", 1);
|
|
43432
|
+
// warn/block mode → prompt; decline → 1
|
|
43433
|
+
case "block":
|
|
43434
|
+
if (mode === "off") return D("install", 0);
|
|
43435
|
+
return D("refuse", 2, { audit: "block" });
|
|
43436
|
+
case "analysis_incomplete":
|
|
43437
|
+
if (dgForce) return D("install", 0, { bypassed: true });
|
|
43438
|
+
if (refuseHard) return D("refuse", 4);
|
|
43439
|
+
return D("install", 0);
|
|
43440
|
+
// off/warn → install with a "could not verify" notice
|
|
43441
|
+
case "scan_failed":
|
|
43442
|
+
case "tree_failed":
|
|
43443
|
+
if (dgForce) return D("install", 0, { bypassed: true });
|
|
43444
|
+
if (refuseHard) return D("refuse", 2);
|
|
43445
|
+
return D("install", 0);
|
|
43446
|
+
// best-effort under off/warn
|
|
43447
|
+
case "resolve_failed":
|
|
43448
|
+
if (dgForce) return D("passthrough", 0, { bypassed: true });
|
|
43449
|
+
if (refuseHard) return D("refuse", 2);
|
|
43450
|
+
return D("passthrough", 0);
|
|
43451
|
+
// nothing resolved to scan → hand off to the installer
|
|
43452
|
+
default: {
|
|
43453
|
+
const _never = verdict;
|
|
43454
|
+
void _never;
|
|
43455
|
+
return D(refuseHard ? "refuse" : "install", refuseHard ? 4 : 0);
|
|
43456
|
+
}
|
|
43457
|
+
}
|
|
43458
|
+
}
|
|
43459
|
+
var init_route = __esm({
|
|
43460
|
+
"src/wrapper/route.ts"() {
|
|
43461
|
+
"use strict";
|
|
43462
|
+
}
|
|
43463
|
+
});
|
|
43464
|
+
|
|
43465
|
+
// src/wrapper/run.ts
|
|
43466
|
+
function verdictFromResult(result, gates = {}) {
|
|
43467
|
+
if (gates.scanFailed) return "scan_failed";
|
|
43468
|
+
if (gates.treeFailed) return "tree_failed";
|
|
43469
|
+
if (gates.resolveFailed) return "resolve_failed";
|
|
43470
|
+
const action = result?.action;
|
|
43471
|
+
if (action === "pass" || action === "warn" || action === "block") return action;
|
|
43472
|
+
return "analysis_incomplete";
|
|
43473
|
+
}
|
|
43474
|
+
function scanVerdictOf(decision) {
|
|
43475
|
+
if (decision.bypassed && (decision.verdict === "warn" || decision.verdict === "block")) {
|
|
43476
|
+
return "override";
|
|
43477
|
+
}
|
|
43478
|
+
switch (decision.verdict) {
|
|
43479
|
+
case "pass":
|
|
43480
|
+
return "pass";
|
|
43481
|
+
case "warn":
|
|
43482
|
+
return "warn";
|
|
43483
|
+
case "block":
|
|
43484
|
+
return "block";
|
|
43485
|
+
case "analysis_incomplete":
|
|
43486
|
+
return "analysis_incomplete";
|
|
43487
|
+
case "scan_failed":
|
|
43488
|
+
case "tree_failed":
|
|
43489
|
+
case "resolve_failed":
|
|
43490
|
+
return "scan_failed";
|
|
43491
|
+
default:
|
|
43492
|
+
return "skipped";
|
|
43493
|
+
}
|
|
43494
|
+
}
|
|
43495
|
+
async function executeDecision(decision, ctx, presenter) {
|
|
43496
|
+
await presenter.announce(decision, ctx);
|
|
43497
|
+
if (decision.audit) {
|
|
43498
|
+
await presenter.audit(decision.audit, ctx);
|
|
43499
|
+
}
|
|
43500
|
+
const scanVerdict = scanVerdictOf(decision);
|
|
43501
|
+
const base = (installRan, installExitCode) => ({
|
|
43502
|
+
scanVerdict,
|
|
43503
|
+
installRan,
|
|
43504
|
+
installExitCode,
|
|
43505
|
+
error: ctx.error,
|
|
43506
|
+
suppressedByAllowlist: ctx.suppressedCount > 0 ? ctx.suppressedCount : void 0
|
|
43507
|
+
});
|
|
43508
|
+
switch (decision.outcome) {
|
|
43509
|
+
case "refuse":
|
|
43510
|
+
presenter.emit(base(false, null));
|
|
43511
|
+
return decision.refuseExitCode;
|
|
43512
|
+
case "install": {
|
|
43513
|
+
const code = await presenter.runInstall(ctx.installArgs);
|
|
43514
|
+
presenter.emit(base(true, code));
|
|
43515
|
+
return code;
|
|
43516
|
+
}
|
|
43517
|
+
case "passthrough": {
|
|
43518
|
+
const code = await presenter.runInstall(ctx.passthroughArgs);
|
|
43519
|
+
presenter.emit(base(true, code));
|
|
43520
|
+
return code;
|
|
43521
|
+
}
|
|
43522
|
+
case "prompt": {
|
|
43523
|
+
const proceed = await presenter.confirmProceed(ctx);
|
|
43524
|
+
if (!proceed) {
|
|
43525
|
+
presenter.emit(base(false, null));
|
|
43526
|
+
return decision.refuseExitCode;
|
|
43527
|
+
}
|
|
43528
|
+
if (presenter.onPromptAccepted) await presenter.onPromptAccepted(ctx);
|
|
43529
|
+
const code = await presenter.runInstall(ctx.installArgs);
|
|
43530
|
+
presenter.emit(base(true, code));
|
|
43531
|
+
return code;
|
|
43532
|
+
}
|
|
43533
|
+
default: {
|
|
43534
|
+
const _never = decision.outcome;
|
|
43535
|
+
void _never;
|
|
43536
|
+
return 1;
|
|
43537
|
+
}
|
|
43538
|
+
}
|
|
43539
|
+
}
|
|
43540
|
+
var init_run = __esm({
|
|
43541
|
+
"src/wrapper/run.ts"() {
|
|
43542
|
+
"use strict";
|
|
43543
|
+
}
|
|
43544
|
+
});
|
|
43545
|
+
|
|
43546
|
+
// src/wrapper/json.ts
|
|
43547
|
+
function emitWrapperJson(config, result) {
|
|
43548
|
+
if (!config.json) return;
|
|
43549
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
43550
|
+
}
|
|
43551
|
+
var init_json = __esm({
|
|
43552
|
+
"src/wrapper/json.ts"() {
|
|
43553
|
+
"use strict";
|
|
43554
|
+
}
|
|
43555
|
+
});
|
|
43556
|
+
|
|
43391
43557
|
// src/security/artifact_integrity.ts
|
|
43392
43558
|
function normalize(h, algo) {
|
|
43393
43559
|
if (!h) return void 0;
|
|
@@ -44795,7 +44961,6 @@ async function dispatchPublishCheckAudit(opts) {
|
|
|
44795
44961
|
score: opts.score,
|
|
44796
44962
|
action: opts.decisionAction,
|
|
44797
44963
|
bypassed: opts.bypassed,
|
|
44798
|
-
bypass_reason: opts.bypassReason,
|
|
44799
44964
|
event_kind: "publish_check"
|
|
44800
44965
|
},
|
|
44801
44966
|
{ apiUrl: opts.apiUrl }
|
|
@@ -44817,7 +44982,6 @@ function recordBypassLocally(record) {
|
|
|
44817
44982
|
ecosystem: record.ecosystem,
|
|
44818
44983
|
verdict: record.verdict,
|
|
44819
44984
|
trigger: record.trigger,
|
|
44820
|
-
reason: record.reason,
|
|
44821
44985
|
packages: record.packages
|
|
44822
44986
|
};
|
|
44823
44987
|
appendFileSync3(path, JSON.stringify(full) + "\n", { mode: 384 });
|
|
@@ -44840,7 +45004,6 @@ async function dispatchInstallAudit(opts) {
|
|
|
44840
45004
|
score: p.score,
|
|
44841
45005
|
action: opts.decisionAction,
|
|
44842
45006
|
bypassed: opts.bypassed,
|
|
44843
|
-
bypass_reason: opts.bypassReason,
|
|
44844
45007
|
project_hash: opts.projectHash
|
|
44845
45008
|
},
|
|
44846
45009
|
{ apiUrl: opts.apiUrl }
|
|
@@ -44879,10 +45042,6 @@ function note(config, text) {
|
|
|
44879
45042
|
if (config.quiet) return;
|
|
44880
45043
|
process.stderr.write(text);
|
|
44881
45044
|
}
|
|
44882
|
-
function emitWrapperJson(config, result) {
|
|
44883
|
-
if (!config.json) return;
|
|
44884
|
-
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
44885
|
-
}
|
|
44886
45045
|
function wrapperPackagesFromResult(result, topLevelNames) {
|
|
44887
45046
|
return result.packages.map((p) => ({
|
|
44888
45047
|
name: p.name,
|
|
@@ -45367,11 +45526,7 @@ async function runStatic(config) {
|
|
|
45367
45526
|
printTrialBanner(result, config);
|
|
45368
45527
|
process.exit(scanExitCode(result.action, config.mode));
|
|
45369
45528
|
}
|
|
45370
|
-
function mergeProjectConfig(config, _argv) {
|
|
45371
|
-
return config;
|
|
45372
|
-
}
|
|
45373
45529
|
async function runStaticNpm(npmArgs, config) {
|
|
45374
|
-
config = mergeProjectConfig(config, process.argv.slice(2));
|
|
45375
45530
|
const parsed = parseNpmArgs(npmArgs);
|
|
45376
45531
|
if (!parsed.shouldScan) {
|
|
45377
45532
|
const code = await runNpm(parsed.rawArgs);
|
|
@@ -45623,156 +45778,106 @@ async function scanAndInstallStatic(resolved, parsed, config) {
|
|
|
45623
45778
|
);
|
|
45624
45779
|
}
|
|
45625
45780
|
}
|
|
45626
|
-
|
|
45627
|
-
|
|
45628
|
-
|
|
45629
|
-
|
|
45630
|
-
|
|
45781
|
+
const npmInstallArgs = buildInstallArgs(parsed, topLevelSpecs, tree.packages, config);
|
|
45782
|
+
const npmTopLevelNames = new Set(resolved.map((p) => p.name));
|
|
45783
|
+
const npmDecision = routeVerdict({
|
|
45784
|
+
verdict: verdictFromResult(result),
|
|
45785
|
+
mode: config.mode,
|
|
45786
|
+
strict: config.strict,
|
|
45787
|
+
dgForce: parsed.dgForce
|
|
45788
|
+
});
|
|
45789
|
+
const npmPresenter = {
|
|
45790
|
+
async announce(d) {
|
|
45791
|
+
if (d.verdict === "pass") {
|
|
45792
|
+
const topLevel2 = resolved.map((p) => `${p.name} ${p.version}`);
|
|
45793
|
+
const passLine = topLevel2.length === 1 ? ` ${import_chalk5.default.green("\u2713")} ${import_chalk5.default.bold("DG verified:")} ${topLevel2[0]} is safe` : ` ${import_chalk5.default.green("\u2713")} ${import_chalk5.default.bold("DG verified:")} ${topLevel2.length} packages safe`;
|
|
45794
|
+
const installLine = topLevel2.length === 1 ? ` ${import_chalk5.default.green("\u2713")} Installing ${topLevel2[0]}` : ` ${import_chalk5.default.green("\u2713")} Installing ${topLevel2.join(", ")}`;
|
|
45795
|
+
process.stderr.write(`${passLine}
|
|
45631
45796
|
${installLine}
|
|
45632
45797
|
`);
|
|
45633
|
-
|
|
45634
|
-
|
|
45635
|
-
|
|
45798
|
+
if (parsed.dgNoScripts || config.strict) {
|
|
45799
|
+
const why = config.strict ? "--strict" : "--dg-no-scripts";
|
|
45800
|
+
process.stderr.write(import_chalk5.default.dim(` ${why}: lifecycle scripts will be suppressed during install.
|
|
45636
45801
|
`));
|
|
45637
|
-
|
|
45638
|
-
|
|
45639
|
-
|
|
45640
|
-
|
|
45641
|
-
|
|
45642
|
-
|
|
45643
|
-
|
|
45644
|
-
|
|
45645
|
-
|
|
45646
|
-
|
|
45647
|
-
|
|
45648
|
-
|
|
45649
|
-
|
|
45650
|
-
|
|
45651
|
-
|
|
45652
|
-
|
|
45653
|
-
|
|
45654
|
-
|
|
45655
|
-
|
|
45656
|
-
|
|
45657
|
-
|
|
45802
|
+
}
|
|
45803
|
+
printTrialBanner(result, config);
|
|
45804
|
+
process.stderr.write("\n");
|
|
45805
|
+
return;
|
|
45806
|
+
}
|
|
45807
|
+
const output = renderResultStatic(result, config);
|
|
45808
|
+
(config.json ? process.stderr : process.stdout).write(output + "\n");
|
|
45809
|
+
printTrialBanner(result, config);
|
|
45810
|
+
const topLevel = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
45811
|
+
if (d.verdict === "warn") {
|
|
45812
|
+
process.stderr.write(` ${import_chalk5.default.yellow("\u26A0")} ${import_chalk5.default.bold("DG flagged")} ${topLevel}.
|
|
45813
|
+
`);
|
|
45814
|
+
} else if (d.verdict === "block") {
|
|
45815
|
+
if (d.outcome === "install") {
|
|
45816
|
+
process.stderr.write(import_chalk5.default.yellow(import_chalk5.default.bold(" --dg-force: Bypassing block. Install at your own risk.\n\n")));
|
|
45817
|
+
} else {
|
|
45818
|
+
const blockedSpecArg = topLevelSpecs.length > 0 ? topLevelSpecs.join(" ") : topLevel.split(", ").map((s) => s.replace(/ /g, "@")).join(" ");
|
|
45819
|
+
process.stderr.write(
|
|
45820
|
+
` ${import_chalk5.default.red("\u2717")} ${import_chalk5.default.bold("DG blocked")} ${topLevel}.
|
|
45821
|
+
${import_chalk5.default.dim(`install anyway: npm install ${blockedSpecArg} --dg-force`)}
|
|
45822
|
+
|
|
45658
45823
|
`
|
|
45659
|
-
|
|
45660
|
-
|
|
45661
|
-
|
|
45662
|
-
|
|
45663
|
-
|
|
45664
|
-
|
|
45665
|
-
|
|
45666
|
-
|
|
45667
|
-
|
|
45668
|
-
|
|
45669
|
-
|
|
45670
|
-
|
|
45671
|
-
|
|
45672
|
-
|
|
45673
|
-
|
|
45674
|
-
|
|
45675
|
-
|
|
45676
|
-
|
|
45677
|
-
|
|
45678
|
-
|
|
45679
|
-
|
|
45680
|
-
|
|
45681
|
-
|
|
45682
|
-
}
|
|
45683
|
-
|
|
45684
|
-
|
|
45685
|
-
|
|
45686
|
-
|
|
45687
|
-
const { dispatchInstallAudit: dispatchInstallAudit3 } = await Promise.resolve().then(() => (init_audit_dispatcher(), audit_dispatcher_exports));
|
|
45688
|
-
await dispatchInstallAudit3({
|
|
45824
|
+
);
|
|
45825
|
+
}
|
|
45826
|
+
} else if (d.verdict === "analysis_incomplete") {
|
|
45827
|
+
if (d.outcome === "refuse") {
|
|
45828
|
+
const specArg = topLevelSpecs.length > 0 ? topLevelSpecs.join(" ") : resolved.map((p) => `${p.name}@${p.version}`).join(" ");
|
|
45829
|
+
process.stderr.write(
|
|
45830
|
+
` ${import_chalk5.default.cyan("?")} ${import_chalk5.default.bold("DG couldn't verify")} ${topLevel} \u2014 unverified, not safe.
|
|
45831
|
+
${import_chalk5.default.dim(`install anyway: npm install ${specArg} --dg-force`)}
|
|
45832
|
+
|
|
45833
|
+
`
|
|
45834
|
+
);
|
|
45835
|
+
} else {
|
|
45836
|
+
process.stderr.write(import_chalk5.default.dim(` DG could not fully verify ${topLevel}; proceeding (mode is not block).
|
|
45837
|
+
|
|
45838
|
+
`));
|
|
45839
|
+
}
|
|
45840
|
+
}
|
|
45841
|
+
},
|
|
45842
|
+
async confirmProceed() {
|
|
45843
|
+
const { promptYesNo: promptYesNo2 } = await Promise.resolve().then(() => (init_prompt(), prompt_exports));
|
|
45844
|
+
const proceed = await promptYesNo2({ defaultAnswer: "y", message: ` Proceed?` });
|
|
45845
|
+
if (!proceed) process.stderr.write(import_chalk5.default.dim(" Install cancelled by user.\n\n"));
|
|
45846
|
+
return proceed;
|
|
45847
|
+
},
|
|
45848
|
+
runInstall: (args) => runNpm(args, { stdoutToStderr: !!config.json }),
|
|
45849
|
+
async audit(kind) {
|
|
45850
|
+
const { dispatchInstallAudit: dispatchInstallAudit2 } = await Promise.resolve().then(() => (init_audit_dispatcher(), audit_dispatcher_exports));
|
|
45851
|
+
await dispatchInstallAudit2({
|
|
45689
45852
|
ecosystem: "npm",
|
|
45690
45853
|
packages: result.packages,
|
|
45691
|
-
decisionAction:
|
|
45692
|
-
bypassed:
|
|
45693
|
-
bypassReason: parsed.dgForceReason
|
|
45694
|
-
});
|
|
45695
|
-
process.stderr.write(
|
|
45696
|
-
import_chalk5.default.yellow(
|
|
45697
|
-
import_chalk5.default.bold(
|
|
45698
|
-
" --dg-force: Bypassing block. Install at your own risk.\n\n"
|
|
45699
|
-
)
|
|
45700
|
-
)
|
|
45701
|
-
);
|
|
45702
|
-
const code = await runNpm(buildInstallArgs(parsed, topLevelSpecs, tree.packages, config), { stdoutToStderr: !!config.json });
|
|
45703
|
-
emitWrapperJson(config, {
|
|
45704
|
-
ecosystem: "npm",
|
|
45705
|
-
packages: wrapperPackagesFromResult(result, new Set(resolved.map((p) => p.name))),
|
|
45706
|
-
scanVerdict: "override",
|
|
45707
|
-
installRan: true,
|
|
45708
|
-
installExitCode: code
|
|
45854
|
+
decisionAction: kind,
|
|
45855
|
+
bypassed: kind === "override"
|
|
45709
45856
|
});
|
|
45710
|
-
|
|
45711
|
-
|
|
45712
|
-
const { dispatchInstallAudit: dispatchInstallAudit2 } = await Promise.resolve().then(() => (init_audit_dispatcher(), audit_dispatcher_exports));
|
|
45713
|
-
await dispatchInstallAudit2({
|
|
45714
|
-
ecosystem: "npm",
|
|
45715
|
-
packages: result.packages,
|
|
45716
|
-
decisionAction: "block",
|
|
45717
|
-
bypassed: false
|
|
45718
|
-
});
|
|
45719
|
-
const topLevelBlocked = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
45720
|
-
const blockedSpecArg = topLevelSpecs.length > 0 ? topLevelSpecs.join(" ") : topLevelBlocked.split(", ").map((s) => s.replace(/ /g, "@")).join(" ");
|
|
45721
|
-
process.stderr.write(
|
|
45722
|
-
` ${import_chalk5.default.red("\u2717")} ${import_chalk5.default.bold("DG blocked")} ${topLevelBlocked}.
|
|
45723
|
-
Real install was NOT run. To override:
|
|
45724
|
-
` + import_chalk5.default.dim(` npm install ${blockedSpecArg} --dg-force --dg-force-reason="<reason>"
|
|
45725
|
-
|
|
45726
|
-
`)
|
|
45727
|
-
);
|
|
45728
|
-
emitWrapperJson(config, {
|
|
45729
|
-
ecosystem: "npm",
|
|
45730
|
-
packages: wrapperPackagesFromResult(result, new Set(resolved.map((p) => p.name))),
|
|
45731
|
-
scanVerdict: "block",
|
|
45732
|
-
installRan: false,
|
|
45733
|
-
installExitCode: null
|
|
45734
|
-
});
|
|
45735
|
-
process.exit(2);
|
|
45736
|
-
}
|
|
45737
|
-
if (result.action === "analysis_incomplete") {
|
|
45738
|
-
const topLevel = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
45739
|
-
const refuse = (config.mode === "block" || config.strict) && !parsed.dgForce;
|
|
45740
|
-
if (refuse) {
|
|
45741
|
-
const specArg = topLevelSpecs.length > 0 ? topLevelSpecs.join(" ") : resolved.map((p) => `${p.name}@${p.version}`).join(" ");
|
|
45742
|
-
process.stderr.write(
|
|
45743
|
-
` ${import_chalk5.default.cyan("?")} ${import_chalk5.default.bold("DG could not verify")} ${topLevel} \u2014 treating as unverified, not safe.
|
|
45744
|
-
Real install was NOT run (--mode block). To override:
|
|
45745
|
-
` + import_chalk5.default.dim(` npm install ${specArg} --dg-force --dg-force-reason="<reason>"
|
|
45746
|
-
|
|
45747
|
-
`)
|
|
45748
|
-
);
|
|
45857
|
+
},
|
|
45858
|
+
emit(record) {
|
|
45749
45859
|
emitWrapperJson(config, {
|
|
45750
45860
|
ecosystem: "npm",
|
|
45751
|
-
packages: wrapperPackagesFromResult(result,
|
|
45752
|
-
scanVerdict:
|
|
45753
|
-
installRan:
|
|
45754
|
-
installExitCode:
|
|
45861
|
+
packages: wrapperPackagesFromResult(result, npmTopLevelNames),
|
|
45862
|
+
scanVerdict: record.scanVerdict,
|
|
45863
|
+
installRan: record.installRan,
|
|
45864
|
+
installExitCode: record.installExitCode,
|
|
45865
|
+
error: record.error
|
|
45755
45866
|
});
|
|
45756
|
-
process.exit(4);
|
|
45757
45867
|
}
|
|
45758
|
-
|
|
45759
|
-
|
|
45760
|
-
|
|
45761
|
-
|
|
45762
|
-
|
|
45763
|
-
|
|
45764
|
-
|
|
45765
|
-
|
|
45766
|
-
|
|
45767
|
-
|
|
45768
|
-
|
|
45769
|
-
installExitCode: code
|
|
45770
|
-
});
|
|
45771
|
-
process.exit(code);
|
|
45772
|
-
}
|
|
45868
|
+
};
|
|
45869
|
+
const npmCtx = {
|
|
45870
|
+
ecosystem: "npm",
|
|
45871
|
+
apiKind: "npm",
|
|
45872
|
+
installArgs: npmInstallArgs,
|
|
45873
|
+
passthroughArgs: parsed.rawArgs,
|
|
45874
|
+
result,
|
|
45875
|
+
resolved,
|
|
45876
|
+
suppressedCount: 0
|
|
45877
|
+
};
|
|
45878
|
+
process.exit(await executeDecision(npmDecision, npmCtx, npmPresenter));
|
|
45773
45879
|
}
|
|
45774
45880
|
async function runStaticPip(pipArgs, config) {
|
|
45775
|
-
config = mergeProjectConfig(config, process.argv.slice(2));
|
|
45776
45881
|
const parsed = parsePipArgs(pipArgs);
|
|
45777
45882
|
if (!parsed.shouldScan) {
|
|
45778
45883
|
const code = await runPip(parsed.rawArgs, { stdoutToStderr: !!config.json });
|
|
@@ -45933,141 +46038,97 @@ async function runStaticPip(pipArgs, config) {
|
|
|
45933
46038
|
}
|
|
45934
46039
|
}
|
|
45935
46040
|
const pipTopLevelNames = new Set(resolved.map((p) => p.name));
|
|
45936
|
-
|
|
45937
|
-
|
|
45938
|
-
|
|
45939
|
-
|
|
45940
|
-
|
|
46041
|
+
const pipDecision = routeVerdict({
|
|
46042
|
+
verdict: verdictFromResult(result),
|
|
46043
|
+
mode: config.mode,
|
|
46044
|
+
strict: config.strict,
|
|
46045
|
+
dgForce: parsed.dgForce
|
|
46046
|
+
});
|
|
46047
|
+
const pipPresenter = {
|
|
46048
|
+
async announce(d) {
|
|
46049
|
+
if (d.verdict === "pass") {
|
|
46050
|
+
const topLevel2 = resolved.map((p) => `${p.name} ${p.version}`);
|
|
46051
|
+
const passLine = topLevel2.length === 1 ? ` ${import_chalk5.default.green("\u2713")} ${import_chalk5.default.bold("DG verified:")} ${topLevel2[0]} is safe` : ` ${import_chalk5.default.green("\u2713")} ${import_chalk5.default.bold("DG verified:")} ${topLevel2.length} packages safe`;
|
|
46052
|
+
const installLine = topLevel2.length === 1 ? ` ${import_chalk5.default.green("\u2713")} Installing ${topLevel2[0]}` : ` ${import_chalk5.default.green("\u2713")} Installing ${topLevel2.join(", ")}`;
|
|
46053
|
+
process.stderr.write(`${passLine}
|
|
45941
46054
|
${installLine}
|
|
45942
46055
|
`);
|
|
45943
|
-
|
|
45944
|
-
|
|
45945
|
-
|
|
45946
|
-
|
|
45947
|
-
|
|
45948
|
-
|
|
45949
|
-
|
|
45950
|
-
|
|
45951
|
-
|
|
45952
|
-
|
|
45953
|
-
|
|
45954
|
-
|
|
45955
|
-
|
|
45956
|
-
|
|
45957
|
-
|
|
45958
|
-
|
|
45959
|
-
|
|
45960
|
-
|
|
45961
|
-
|
|
45962
|
-
|
|
46056
|
+
printTrialBanner(result, config);
|
|
46057
|
+
process.stderr.write("\n");
|
|
46058
|
+
return;
|
|
46059
|
+
}
|
|
46060
|
+
const output = renderResultStatic(result, config);
|
|
46061
|
+
(config.json ? process.stderr : process.stdout).write(output + "\n");
|
|
46062
|
+
printTrialBanner(result, config);
|
|
46063
|
+
const topLevel = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
46064
|
+
if (d.verdict === "warn") {
|
|
46065
|
+
process.stderr.write(` ${import_chalk5.default.yellow("\u26A0")} ${import_chalk5.default.bold("DG flagged")} ${topLevel}.
|
|
46066
|
+
`);
|
|
46067
|
+
} else if (d.verdict === "block") {
|
|
46068
|
+
if (d.outcome === "install") {
|
|
46069
|
+
process.stderr.write(import_chalk5.default.yellow(import_chalk5.default.bold(" --dg-force: Bypassing block. Install at your own risk.\n\n")));
|
|
46070
|
+
} else {
|
|
46071
|
+
const pipBlockedSpecArg = resolved.map((p) => `${p.name}==${p.version}`).join(" ");
|
|
46072
|
+
process.stderr.write(
|
|
46073
|
+
` ${import_chalk5.default.red("\u2717")} ${import_chalk5.default.bold("DG blocked")} ${topLevel}.
|
|
46074
|
+
${import_chalk5.default.dim(`install anyway: pip install ${pipBlockedSpecArg} --dg-force`)}
|
|
46075
|
+
|
|
45963
46076
|
`
|
|
45964
|
-
|
|
45965
|
-
|
|
45966
|
-
|
|
45967
|
-
|
|
45968
|
-
|
|
45969
|
-
|
|
45970
|
-
|
|
45971
|
-
|
|
45972
|
-
|
|
45973
|
-
|
|
45974
|
-
|
|
45975
|
-
|
|
45976
|
-
|
|
45977
|
-
|
|
45978
|
-
|
|
45979
|
-
|
|
45980
|
-
|
|
45981
|
-
|
|
45982
|
-
|
|
45983
|
-
|
|
45984
|
-
|
|
45985
|
-
|
|
45986
|
-
|
|
45987
|
-
|
|
45988
|
-
|
|
45989
|
-
|
|
45990
|
-
await
|
|
46077
|
+
);
|
|
46078
|
+
}
|
|
46079
|
+
} else if (d.verdict === "analysis_incomplete") {
|
|
46080
|
+
if (d.outcome === "refuse") {
|
|
46081
|
+
const pipSpecArg = resolved.map((p) => `${p.name}==${p.version}`).join(" ");
|
|
46082
|
+
process.stderr.write(
|
|
46083
|
+
` ${import_chalk5.default.cyan("?")} ${import_chalk5.default.bold("DG couldn't verify")} ${topLevel} \u2014 unverified, not safe.
|
|
46084
|
+
${import_chalk5.default.dim(`install anyway: pip install ${pipSpecArg} --dg-force`)}
|
|
46085
|
+
|
|
46086
|
+
`
|
|
46087
|
+
);
|
|
46088
|
+
} else {
|
|
46089
|
+
process.stderr.write(import_chalk5.default.dim(` DG could not fully verify ${topLevel}; proceeding (mode is not block).
|
|
46090
|
+
|
|
46091
|
+
`));
|
|
46092
|
+
}
|
|
46093
|
+
}
|
|
46094
|
+
},
|
|
46095
|
+
async confirmProceed() {
|
|
46096
|
+
const { promptYesNo: promptYesNo2 } = await Promise.resolve().then(() => (init_prompt(), prompt_exports));
|
|
46097
|
+
const proceed = await promptYesNo2({ defaultAnswer: "y", message: " Proceed?" });
|
|
46098
|
+
if (!proceed) process.stderr.write(import_chalk5.default.dim(" Install cancelled by user.\n\n"));
|
|
46099
|
+
return proceed;
|
|
46100
|
+
},
|
|
46101
|
+
runInstall: (args) => runPip(args, { stdoutToStderr: !!config.json }),
|
|
46102
|
+
async audit(kind) {
|
|
46103
|
+
const { dispatchInstallAudit: dispatchInstallAudit2 } = await Promise.resolve().then(() => (init_audit_dispatcher(), audit_dispatcher_exports));
|
|
46104
|
+
await dispatchInstallAudit2({
|
|
45991
46105
|
ecosystem: "pypi",
|
|
45992
46106
|
packages: result.packages,
|
|
45993
|
-
decisionAction:
|
|
45994
|
-
bypassed:
|
|
45995
|
-
bypassReason: parsed.dgForceReason
|
|
46107
|
+
decisionAction: kind,
|
|
46108
|
+
bypassed: kind === "override"
|
|
45996
46109
|
});
|
|
45997
|
-
|
|
45998
|
-
|
|
45999
|
-
);
|
|
46000
|
-
const code = await runPip(pipInstallArgs, { stdoutToStderr: !!config.json });
|
|
46001
|
-
emitWrapperJson(config, {
|
|
46002
|
-
ecosystem: "pypi",
|
|
46003
|
-
packages: wrapperPackagesFromResult(result, pipTopLevelNames),
|
|
46004
|
-
scanVerdict: "override",
|
|
46005
|
-
installRan: true,
|
|
46006
|
-
installExitCode: code
|
|
46007
|
-
});
|
|
46008
|
-
process.exit(code);
|
|
46009
|
-
}
|
|
46010
|
-
const { dispatchInstallAudit: dispatchInstallAudit2 } = await Promise.resolve().then(() => (init_audit_dispatcher(), audit_dispatcher_exports));
|
|
46011
|
-
await dispatchInstallAudit2({
|
|
46012
|
-
ecosystem: "pypi",
|
|
46013
|
-
packages: result.packages,
|
|
46014
|
-
decisionAction: "block",
|
|
46015
|
-
bypassed: false
|
|
46016
|
-
});
|
|
46017
|
-
const pipTopLevelBlocked = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
46018
|
-
const pipBlockedSpecArg = resolved.map((p) => `${p.name}==${p.version}`).join(" ");
|
|
46019
|
-
process.stderr.write(
|
|
46020
|
-
` ${import_chalk5.default.red("\u2717")} ${import_chalk5.default.bold("DG blocked")} ${pipTopLevelBlocked}.
|
|
46021
|
-
Real install was NOT run. To override:
|
|
46022
|
-
` + import_chalk5.default.dim(` pip install ${pipBlockedSpecArg} --dg-force --dg-force-reason="<reason>"
|
|
46023
|
-
|
|
46024
|
-
`)
|
|
46025
|
-
);
|
|
46026
|
-
emitWrapperJson(config, {
|
|
46027
|
-
ecosystem: "pypi",
|
|
46028
|
-
packages: wrapperPackagesFromResult(result, pipTopLevelNames),
|
|
46029
|
-
scanVerdict: "block",
|
|
46030
|
-
installRan: false,
|
|
46031
|
-
installExitCode: null
|
|
46032
|
-
});
|
|
46033
|
-
process.exit(2);
|
|
46034
|
-
}
|
|
46035
|
-
if (result.action === "analysis_incomplete") {
|
|
46036
|
-
const pipTopLevel = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
46037
|
-
const refuse = (config.mode === "block" || config.strict) && !parsed.dgForce;
|
|
46038
|
-
if (refuse) {
|
|
46039
|
-
const pipSpecArg = resolved.map((p) => `${p.name}==${p.version}`).join(" ");
|
|
46040
|
-
process.stderr.write(
|
|
46041
|
-
` ${import_chalk5.default.cyan("?")} ${import_chalk5.default.bold("DG could not verify")} ${pipTopLevel} \u2014 treating as unverified, not safe.
|
|
46042
|
-
Real install was NOT run (--mode block). To override:
|
|
46043
|
-
` + import_chalk5.default.dim(` pip install ${pipSpecArg} --dg-force --dg-force-reason="<reason>"
|
|
46044
|
-
|
|
46045
|
-
`)
|
|
46046
|
-
);
|
|
46110
|
+
},
|
|
46111
|
+
emit(record) {
|
|
46047
46112
|
emitWrapperJson(config, {
|
|
46048
46113
|
ecosystem: "pypi",
|
|
46049
46114
|
packages: wrapperPackagesFromResult(result, pipTopLevelNames),
|
|
46050
|
-
scanVerdict:
|
|
46051
|
-
installRan:
|
|
46052
|
-
installExitCode:
|
|
46115
|
+
scanVerdict: record.scanVerdict,
|
|
46116
|
+
installRan: record.installRan,
|
|
46117
|
+
installExitCode: record.installExitCode,
|
|
46118
|
+
error: record.error
|
|
46053
46119
|
});
|
|
46054
|
-
process.exit(4);
|
|
46055
46120
|
}
|
|
46056
|
-
|
|
46057
|
-
|
|
46058
|
-
|
|
46059
|
-
|
|
46060
|
-
|
|
46061
|
-
|
|
46062
|
-
|
|
46063
|
-
|
|
46064
|
-
|
|
46065
|
-
|
|
46066
|
-
|
|
46067
|
-
installExitCode: code
|
|
46068
|
-
});
|
|
46069
|
-
process.exit(code);
|
|
46070
|
-
}
|
|
46121
|
+
};
|
|
46122
|
+
const pipCtx = {
|
|
46123
|
+
ecosystem: "pypi",
|
|
46124
|
+
apiKind: "pypi",
|
|
46125
|
+
installArgs: pipInstallArgs,
|
|
46126
|
+
passthroughArgs: parsed.rawArgs,
|
|
46127
|
+
result,
|
|
46128
|
+
resolved,
|
|
46129
|
+
suppressedCount: 0
|
|
46130
|
+
};
|
|
46131
|
+
process.exit(await executeDecision(pipDecision, pipCtx, pipPresenter));
|
|
46071
46132
|
}
|
|
46072
46133
|
async function runStaticLogin() {
|
|
46073
46134
|
const {
|
|
@@ -46181,6 +46242,9 @@ var init_static_output = __esm({
|
|
|
46181
46242
|
init_npm_wrapper();
|
|
46182
46243
|
init_pip_wrapper();
|
|
46183
46244
|
init_wrapper_shared();
|
|
46245
|
+
init_route();
|
|
46246
|
+
init_run();
|
|
46247
|
+
init_json();
|
|
46184
46248
|
init_artifact_integrity();
|
|
46185
46249
|
init_sanitize();
|
|
46186
46250
|
init_format_helpers();
|
|
@@ -48680,7 +48744,7 @@ __export(publish_check_exports, {
|
|
|
48680
48744
|
scanPayload: () => scanPayload,
|
|
48681
48745
|
summarize: () => summarize
|
|
48682
48746
|
});
|
|
48683
|
-
import { spawn as
|
|
48747
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
48684
48748
|
import { readFileSync as readFileSync13, existsSync as existsSync19, readdirSync as readdirSync3 } from "node:fs";
|
|
48685
48749
|
import { join as join12, basename as basename2 } from "node:path";
|
|
48686
48750
|
import { createGunzip } from "node:zlib";
|
|
@@ -48692,7 +48756,7 @@ function sanitizeSnippet(s, max = 40) {
|
|
|
48692
48756
|
}
|
|
48693
48757
|
async function npmPackDryRun(cwd2 = process.cwd()) {
|
|
48694
48758
|
return new Promise((resolve3) => {
|
|
48695
|
-
const child =
|
|
48759
|
+
const child = spawn5("npm", ["pack", "--dry-run", "--json"], {
|
|
48696
48760
|
cwd: cwd2,
|
|
48697
48761
|
stdio: ["ignore", "pipe", "pipe"]
|
|
48698
48762
|
});
|
|
@@ -50847,6 +50911,11 @@ async function runNpmScan(packages, skippedCount, config, dispatch) {
|
|
|
50847
50911
|
dispatch({ type: "SCAN_COMPLETE", result, durationMs: Date.now() - startMs, skippedCount });
|
|
50848
50912
|
} catch (error) {
|
|
50849
50913
|
if (error instanceof FreeCapReachedError) {
|
|
50914
|
+
try {
|
|
50915
|
+
const { recordScanCapReached: recordScanCapReached2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
50916
|
+
recordScanCapReached2(error.scansUsed, error.maxScans, error.reason);
|
|
50917
|
+
} catch {
|
|
50918
|
+
}
|
|
50850
50919
|
dispatch({ type: "FREE_CAP_REACHED", scansUsed: error.scansUsed, maxScans: error.maxScans, capReason: error.reason });
|
|
50851
50920
|
return;
|
|
50852
50921
|
}
|
|
@@ -50926,6 +50995,11 @@ async function scanProjects(projects, config, dispatch) {
|
|
|
50926
50995
|
dispatch({ type: "SCAN_COMPLETE", result: merged, durationMs: merged.durationMs, skippedCount: 0, discoveredTotal });
|
|
50927
50996
|
} catch (error) {
|
|
50928
50997
|
if (error instanceof FreeCapReachedError) {
|
|
50998
|
+
try {
|
|
50999
|
+
const { recordScanCapReached: recordScanCapReached2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
51000
|
+
recordScanCapReached2(error.scansUsed, error.maxScans, error.reason);
|
|
51001
|
+
} catch {
|
|
51002
|
+
}
|
|
50929
51003
|
dispatch({ type: "FREE_CAP_REACHED", scansUsed: error.scansUsed, maxScans: error.maxScans, capReason: error.reason });
|
|
50930
51004
|
return;
|
|
50931
51005
|
}
|
|
@@ -51726,22 +51800,18 @@ var init_readonly = __esm({
|
|
|
51726
51800
|
// src/ui/hooks/useWrapperBase.ts
|
|
51727
51801
|
function reducer4(_state, action) {
|
|
51728
51802
|
switch (action.type) {
|
|
51729
|
-
case "PASSTHROUGH":
|
|
51730
|
-
return { phase: "passthrough" };
|
|
51731
51803
|
case "RESOLVING":
|
|
51732
51804
|
return { phase: "resolving", count: action.count };
|
|
51733
51805
|
case "SCANNING":
|
|
51734
51806
|
return { phase: "scanning", count: action.count };
|
|
51735
|
-
case "PASS":
|
|
51736
|
-
return { phase: "pass", count: action.count, result: action.result };
|
|
51737
51807
|
case "WARN":
|
|
51738
|
-
return { phase: "warn", result: action.result
|
|
51739
|
-
case "
|
|
51740
|
-
return { phase: "
|
|
51741
|
-
case "
|
|
51742
|
-
return { phase: "
|
|
51808
|
+
return { phase: "warn", result: action.result };
|
|
51809
|
+
case "REFUSED":
|
|
51810
|
+
return { phase: "refused", result: action.result, verdict: action.verdict, cmd: action.cmd, exitCode: action.exitCode };
|
|
51811
|
+
case "DECLINED":
|
|
51812
|
+
return { phase: "declined", line: action.line, exitCode: action.exitCode };
|
|
51743
51813
|
case "INSTALLING":
|
|
51744
|
-
return { phase: "installing" };
|
|
51814
|
+
return { phase: "installing", line: action.line };
|
|
51745
51815
|
case "DONE":
|
|
51746
51816
|
return { phase: "done", exitCode: action.exitCode };
|
|
51747
51817
|
case "ERROR":
|
|
@@ -51750,12 +51820,17 @@ function reducer4(_state, action) {
|
|
|
51750
51820
|
return { phase: "free_cap_reached" };
|
|
51751
51821
|
}
|
|
51752
51822
|
}
|
|
51753
|
-
function useInstallWrapper(rawArgs, config, opts,
|
|
51823
|
+
function useInstallWrapper(rawArgs, config, opts, handoff) {
|
|
51754
51824
|
const [state, dispatch] = (0, import_react37.useReducer)(reducer4, { phase: "resolving", count: 0 });
|
|
51755
51825
|
const started = (0, import_react37.useRef)(false);
|
|
51756
51826
|
const parsedRef = (0, import_react37.useRef)(opts.parseArgs(rawArgs));
|
|
51757
51827
|
const pendingInstall = (0, import_react37.useRef)(null);
|
|
51758
51828
|
const rejectRef = (0, import_react37.useRef)(null);
|
|
51829
|
+
const ho = handoff ?? { install: null };
|
|
51830
|
+
const requestInstall = (args, line) => {
|
|
51831
|
+
ho.install = { run: opts.runInstall, args };
|
|
51832
|
+
dispatch({ type: "INSTALLING", line });
|
|
51833
|
+
};
|
|
51759
51834
|
const confirmInstall = () => {
|
|
51760
51835
|
if (pendingInstall.current) {
|
|
51761
51836
|
pendingInstall.current();
|
|
@@ -51778,18 +51853,14 @@ function useInstallWrapper(rawArgs, config, opts, exit) {
|
|
|
51778
51853
|
(async () => {
|
|
51779
51854
|
try {
|
|
51780
51855
|
if (!parsed.shouldScan) {
|
|
51781
|
-
|
|
51782
|
-
const code = await opts.runInstall(parsed.rawArgs);
|
|
51783
|
-
dispatch({ type: "DONE", exitCode: code });
|
|
51856
|
+
requestInstall(parsed.rawArgs, null);
|
|
51784
51857
|
return;
|
|
51785
51858
|
}
|
|
51786
51859
|
let specs;
|
|
51787
51860
|
if (parsed.packages.length === 0) {
|
|
51788
51861
|
specs = opts.inferSpecsFromContext(parsed);
|
|
51789
51862
|
if (specs.length === 0) {
|
|
51790
|
-
|
|
51791
|
-
const code = await opts.runInstall(parsed.rawArgs);
|
|
51792
|
-
dispatch({ type: "DONE", exitCode: code });
|
|
51863
|
+
requestInstall(parsed.rawArgs, null);
|
|
51793
51864
|
return;
|
|
51794
51865
|
}
|
|
51795
51866
|
} else {
|
|
@@ -51798,9 +51869,7 @@ function useInstallWrapper(rawArgs, config, opts, exit) {
|
|
|
51798
51869
|
dispatch({ type: "RESOLVING", count: specs.length });
|
|
51799
51870
|
const { resolved } = await opts.resolvePackages(specs);
|
|
51800
51871
|
if (resolved.length === 0) {
|
|
51801
|
-
|
|
51802
|
-
const code = await opts.runInstall(parsed.rawArgs);
|
|
51803
|
-
dispatch({ type: "DONE", exitCode: code });
|
|
51872
|
+
requestInstall(parsed.rawArgs, null);
|
|
51804
51873
|
return;
|
|
51805
51874
|
}
|
|
51806
51875
|
const isRequirementsInstall = opts.ecosystem === "pypi" && (parsed.rawArgs.includes("-r") || parsed.rawArgs.includes("--requirement"));
|
|
@@ -51810,7 +51879,6 @@ function useInstallWrapper(rawArgs, config, opts, exit) {
|
|
|
51810
51879
|
message: `A -r requirements install cannot be pinned to the exact scanned versions; refusing in ${config.strict ? "--strict" : "--mode block"} (resolve\u2192install mismatch risk). Use --mode warn or --dg-force to bypass.`,
|
|
51811
51880
|
proceed: false
|
|
51812
51881
|
});
|
|
51813
|
-
dispatch({ type: "DONE", exitCode: 2 });
|
|
51814
51882
|
return;
|
|
51815
51883
|
}
|
|
51816
51884
|
const pinnedArgs = isRequirementsInstall ? parsed.rawArgs : opts.ecosystem === "npm" ? pinTopLevelArgs(parsed.rawArgs, parsed.packages, resolved) : pinPipArgs(parsed.rawArgs, parsed.packages, resolved);
|
|
@@ -51830,114 +51898,61 @@ function useInstallWrapper(rawArgs, config, opts, exit) {
|
|
|
51830
51898
|
message: `Could not enumerate the dependency tree (${tree.errorMessage ?? "dry-run produced no tree"}); transitive deps would install unscanned. Install aborted in ${config.strict ? "--strict" : "--mode block"}. Use --dg-force to bypass.`,
|
|
51831
51899
|
proceed: false
|
|
51832
51900
|
});
|
|
51833
|
-
dispatch({ type: "DONE", exitCode: 2 });
|
|
51834
51901
|
return;
|
|
51835
51902
|
}
|
|
51836
51903
|
}
|
|
51837
51904
|
dispatch({ type: "SCANNING", count: scanSet.length });
|
|
51838
51905
|
const result = await opts.callAnalyze(scanSet, config);
|
|
51839
|
-
|
|
51840
|
-
|
|
51841
|
-
|
|
51842
|
-
|
|
51843
|
-
|
|
51844
|
-
|
|
51845
|
-
|
|
51906
|
+
const decision = routeVerdict({
|
|
51907
|
+
verdict: verdictFromResult(result),
|
|
51908
|
+
mode: config.mode,
|
|
51909
|
+
strict: config.strict,
|
|
51910
|
+
dgForce: parsed.dgForce
|
|
51911
|
+
});
|
|
51912
|
+
if (decision.outcome === "refuse") {
|
|
51913
|
+
const cmd = `${opts.ecosystem === "npm" ? "npm" : "pip"} ${parsed.rawArgs.join(" ")} --dg-force`;
|
|
51914
|
+
const v = decision.verdict === "analysis_incomplete" ? "incomplete" : decision.verdict === "block" ? "block" : "warn";
|
|
51915
|
+
dispatch({ type: "REFUSED", result, verdict: v, cmd, exitCode: decision.refuseExitCode });
|
|
51846
51916
|
return;
|
|
51847
51917
|
}
|
|
51848
|
-
|
|
51849
|
-
|
|
51850
|
-
|
|
51851
|
-
|
|
51852
|
-
|
|
51853
|
-
|
|
51854
|
-
|
|
51855
|
-
reason: parsed.dgForceReason,
|
|
51856
|
-
packages: result.packages.map((p) => ({ name: p.name, version: p.version, score: p.score }))
|
|
51857
|
-
});
|
|
51858
|
-
dispatch({ type: "WARN", result, dgForce: true });
|
|
51859
|
-
dispatch({ type: "INSTALLING" });
|
|
51860
|
-
const code = await opts.runInstall(installArgs);
|
|
51861
|
-
dispatch({ type: "DONE", exitCode: code });
|
|
51862
|
-
return;
|
|
51863
|
-
}
|
|
51864
|
-
dispatch({ type: "WARN", result, dgForce: false });
|
|
51865
|
-
const shouldProceed = await new Promise((resolve3) => {
|
|
51866
|
-
pendingInstall.current = () => resolve3(true);
|
|
51867
|
-
rejectRef.current = () => resolve3(false);
|
|
51918
|
+
const recordBypass = async (trigger) => {
|
|
51919
|
+
const { recordBypassLocally: recordBypassLocally2 } = await Promise.resolve().then(() => (init_audit_dispatcher(), audit_dispatcher_exports));
|
|
51920
|
+
recordBypassLocally2({
|
|
51921
|
+
ecosystem: opts.ecosystem,
|
|
51922
|
+
verdict: decision.verdict === "block" ? "block" : "warn",
|
|
51923
|
+
trigger,
|
|
51924
|
+
packages: result.packages.map((p) => ({ name: p.name, version: p.version, score: p.score }))
|
|
51868
51925
|
});
|
|
51869
|
-
|
|
51870
|
-
|
|
51871
|
-
|
|
51872
|
-
|
|
51873
|
-
|
|
51874
|
-
|
|
51875
|
-
|
|
51876
|
-
})
|
|
51877
|
-
|
|
51878
|
-
|
|
51879
|
-
|
|
51880
|
-
|
|
51881
|
-
|
|
51882
|
-
|
|
51883
|
-
|
|
51884
|
-
|
|
51885
|
-
if (result.action === "block") {
|
|
51886
|
-
if (parsed.dgForce) {
|
|
51887
|
-
const { recordBypassLocally: recordBypassLocally2 } = await Promise.resolve().then(() => (init_audit_dispatcher(), audit_dispatcher_exports));
|
|
51888
|
-
recordBypassLocally2({
|
|
51889
|
-
ecosystem: opts.ecosystem,
|
|
51890
|
-
verdict: "block",
|
|
51891
|
-
trigger: "dg-force",
|
|
51892
|
-
reason: parsed.dgForceReason,
|
|
51893
|
-
packages: result.packages.map((p) => ({ name: p.name, version: p.version, score: p.score }))
|
|
51894
|
-
});
|
|
51895
|
-
dispatch({ type: "BLOCKED", result, dgForce: true });
|
|
51896
|
-
dispatch({ type: "INSTALLING" });
|
|
51897
|
-
const code = await opts.runInstall(installArgs);
|
|
51898
|
-
dispatch({ type: "DONE", exitCode: code });
|
|
51899
|
-
return;
|
|
51900
|
-
}
|
|
51901
|
-
dispatch({ type: "BLOCKED", result, dgForce: false });
|
|
51902
|
-
const shouldProceed = await new Promise((resolve3) => {
|
|
51926
|
+
};
|
|
51927
|
+
const chalk18 = (await Promise.resolve().then(() => __toESM(require_source(), 1))).default;
|
|
51928
|
+
const top = result.packages.length === 1 ? result.packages[0] : null;
|
|
51929
|
+
const name = top ? `${top.name}@${top.version}` : `${result.packages.length} packages`;
|
|
51930
|
+
const pinnedLine = (() => {
|
|
51931
|
+
if (decision.bypassed) {
|
|
51932
|
+
const sig = decision.verdict === "block" ? chalk18.red("\u2718") : chalk18.yellow("\u26A0");
|
|
51933
|
+
return ` ${sig} ${name} ${chalk18.dim(`(${decision.verdict}) \u2014 --dg-force override, installing`)}`;
|
|
51934
|
+
}
|
|
51935
|
+
if (decision.verdict === "analysis_incomplete") return ` ${chalk18.cyan("?")} ${name} ${chalk18.dim("\u2014 could not verify; proceeding")}`;
|
|
51936
|
+
if (decision.verdict === "pass") return ` ${chalk18.green("\u2713")} ${name} ${chalk18.dim("\u2014 clean")}`;
|
|
51937
|
+
return null;
|
|
51938
|
+
})();
|
|
51939
|
+
if (decision.outcome === "prompt") {
|
|
51940
|
+
dispatch({ type: "WARN", result });
|
|
51941
|
+
const accepted = await new Promise((resolve3) => {
|
|
51903
51942
|
pendingInstall.current = () => resolve3(true);
|
|
51904
51943
|
rejectRef.current = () => resolve3(false);
|
|
51905
51944
|
});
|
|
51906
|
-
if (
|
|
51907
|
-
|
|
51908
|
-
recordBypassLocally2({
|
|
51909
|
-
ecosystem: opts.ecosystem,
|
|
51910
|
-
verdict: "block",
|
|
51911
|
-
trigger: "interactive-confirm",
|
|
51912
|
-
packages: result.packages.map((p) => ({ name: p.name, version: p.version, score: p.score }))
|
|
51913
|
-
});
|
|
51914
|
-
dispatch({ type: "INSTALLING" });
|
|
51915
|
-
const code = await opts.runInstall(installArgs);
|
|
51916
|
-
dispatch({ type: "DONE", exitCode: code });
|
|
51917
|
-
} else {
|
|
51918
|
-
dispatch({ type: "DONE", exitCode: 2 });
|
|
51919
|
-
}
|
|
51920
|
-
return;
|
|
51921
|
-
}
|
|
51922
|
-
{
|
|
51923
|
-
const refuseHard = config.mode === "block" || config.strict;
|
|
51924
|
-
const baseMsg = "DG could not fully analyze the install set (analysis incomplete).";
|
|
51925
|
-
if (refuseHard && !parsed.dgForce) {
|
|
51926
|
-
dispatch({
|
|
51927
|
-
type: "INCOMPLETE",
|
|
51928
|
-
result,
|
|
51929
|
-
proceed: false,
|
|
51930
|
-
message: `${baseMsg} Refusing install in ${config.strict ? "--strict" : "--mode block"} \u2014 unverified is not safe. Use --mode warn or --dg-force to bypass.`
|
|
51931
|
-
});
|
|
51932
|
-
dispatch({ type: "DONE", exitCode: 4 });
|
|
51945
|
+
if (!accepted) {
|
|
51946
|
+
dispatch({ type: "DECLINED", line: ` ${chalk18.yellow("\u2717")} ${name} ${chalk18.dim("\u2014 not installed")}`, exitCode: decision.refuseExitCode });
|
|
51933
51947
|
return;
|
|
51934
51948
|
}
|
|
51935
|
-
|
|
51936
|
-
|
|
51937
|
-
const code = await opts.runInstall(installArgs);
|
|
51938
|
-
dispatch({ type: "DONE", exitCode: code });
|
|
51949
|
+
await recordBypass("interactive-confirm");
|
|
51950
|
+
requestInstall(installArgs, null);
|
|
51939
51951
|
return;
|
|
51940
51952
|
}
|
|
51953
|
+
if (decision.bypassed) await recordBypass("dg-force");
|
|
51954
|
+
requestInstall(decision.outcome === "passthrough" ? parsed.rawArgs : installArgs, pinnedLine);
|
|
51955
|
+
return;
|
|
51941
51956
|
} catch (error) {
|
|
51942
51957
|
if (error instanceof FreeCapReachedError) {
|
|
51943
51958
|
dispatch({ type: "FREE_CAP_REACHED" });
|
|
@@ -51950,27 +51965,17 @@ function useInstallWrapper(rawArgs, config, opts, exit) {
|
|
|
51950
51965
|
message: `Scan failed (${message}) and --mode is block. Install aborted. Use --dg-force to bypass.`,
|
|
51951
51966
|
proceed: false
|
|
51952
51967
|
});
|
|
51953
|
-
dispatch({ type: "DONE", exitCode: 2 });
|
|
51954
51968
|
return;
|
|
51955
51969
|
}
|
|
51956
|
-
|
|
51957
|
-
|
|
51958
|
-
const code = await opts.runInstall(installArgs);
|
|
51959
|
-
dispatch({ type: "DONE", exitCode: code });
|
|
51970
|
+
const chalk18 = (await Promise.resolve().then(() => __toESM(require_source(), 1))).default;
|
|
51971
|
+
requestInstall(installArgs, ` ${chalk18.yellow("\u26A0")} ${chalk18.dim(`scan failed (${message}); proceeding`)}`);
|
|
51960
51972
|
}
|
|
51961
51973
|
})();
|
|
51962
51974
|
}, [rawArgs, config]);
|
|
51963
51975
|
return { state, confirmInstall, rejectInstall };
|
|
51964
51976
|
}
|
|
51965
|
-
function
|
|
51966
|
-
|
|
51967
|
-
const p = result.packages[0];
|
|
51968
|
-
return chalk18.green("\u2713 ") + `${p.name}@${p.version}` + chalk18.dim(" \u2014 clean. Installing.");
|
|
51969
|
-
}
|
|
51970
|
-
return chalk18.green("\u2713 ") + `${result.packages.length} packages` + chalk18.dim(" \u2014 all clean. Installing.");
|
|
51971
|
-
}
|
|
51972
|
-
function useWrapper(args, config, ecosystem, exit) {
|
|
51973
|
-
return useInstallWrapper(args, config, ecosystem === "npm" ? NPM_OPTIONS : PIP_OPTIONS, exit);
|
|
51977
|
+
function useWrapper(args, config, ecosystem, handoff) {
|
|
51978
|
+
return useInstallWrapper(args, config, ecosystem === "npm" ? NPM_OPTIONS : PIP_OPTIONS, handoff);
|
|
51974
51979
|
}
|
|
51975
51980
|
var import_react37, NPM_OPTIONS, PIP_OPTIONS;
|
|
51976
51981
|
var init_useWrapperBase = __esm({
|
|
@@ -51979,6 +51984,8 @@ var init_useWrapperBase = __esm({
|
|
|
51979
51984
|
import_react37 = __toESM(require_react(), 1);
|
|
51980
51985
|
init_client();
|
|
51981
51986
|
init_wrapper_shared();
|
|
51987
|
+
init_route();
|
|
51988
|
+
init_run();
|
|
51982
51989
|
init_npm_wrapper();
|
|
51983
51990
|
init_pip_wrapper();
|
|
51984
51991
|
NPM_OPTIONS = {
|
|
@@ -51986,7 +51993,7 @@ var init_useWrapperBase = __esm({
|
|
|
51986
51993
|
resolvePackages,
|
|
51987
51994
|
resolveTree: resolveTreeNpm,
|
|
51988
51995
|
callAnalyze: callAnalyzeAPI,
|
|
51989
|
-
runInstall: runNpm,
|
|
51996
|
+
runInstall: (args) => runNpm(args, { trim: true }),
|
|
51990
51997
|
inferSpecsFromContext: () => readBareInstallPackages(process.cwd()),
|
|
51991
51998
|
ecosystem: "npm"
|
|
51992
51999
|
};
|
|
@@ -51995,7 +52002,7 @@ var init_useWrapperBase = __esm({
|
|
|
51995
52002
|
resolvePackages: resolvePackages2,
|
|
51996
52003
|
resolveTree: resolveTreePip,
|
|
51997
52004
|
callAnalyze: callPyPIAnalyzeAPI,
|
|
51998
|
-
runInstall: runPip,
|
|
52005
|
+
runInstall: (args) => runPip(args, { trim: true }),
|
|
51999
52006
|
inferSpecsFromContext: (parsed) => {
|
|
52000
52007
|
const file = parsed.requirementsFile;
|
|
52001
52008
|
return file ? parseRequirementsFile(file) : [];
|
|
@@ -52177,6 +52184,7 @@ var init_ConfirmPrompt = __esm({
|
|
|
52177
52184
|
onReject();
|
|
52178
52185
|
}
|
|
52179
52186
|
});
|
|
52187
|
+
if (!message) return null;
|
|
52180
52188
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
52181
52189
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Text, { children: [
|
|
52182
52190
|
import_chalk17.default.red.bold("\u26A0"),
|
|
@@ -52232,7 +52240,8 @@ var init_WrapperVerdictLine = __esm({
|
|
|
52232
52240
|
WrapperVerdictLine = ({
|
|
52233
52241
|
result,
|
|
52234
52242
|
verdict,
|
|
52235
|
-
dgForce
|
|
52243
|
+
dgForce,
|
|
52244
|
+
refusal
|
|
52236
52245
|
}) => {
|
|
52237
52246
|
const total = result.packages.length;
|
|
52238
52247
|
const counts = countSummary(result);
|
|
@@ -52258,12 +52267,13 @@ var init_WrapperVerdictLine = __esm({
|
|
|
52258
52267
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { dimColor: true, children: " \u2014 all clean. Installing." })
|
|
52259
52268
|
] });
|
|
52260
52269
|
}
|
|
52261
|
-
const sigil = verdict === "block" ? "\u2718" : "\u26A0";
|
|
52262
|
-
const color = verdict === "block" ? "red" : "yellow";
|
|
52270
|
+
const sigil = verdict === "block" ? "\u2718" : verdict === "incomplete" ? "?" : "\u26A0";
|
|
52271
|
+
const color = verdict === "block" ? "red" : verdict === "incomplete" ? "cyan" : "yellow";
|
|
52263
52272
|
const prompt = verdict === "block" ? "install anyway?" : "install?";
|
|
52264
52273
|
if (total === 1) {
|
|
52265
52274
|
const p = topPackage(result);
|
|
52266
52275
|
const score = p ? p.score : result.score;
|
|
52276
|
+
const meta = verdict === "incomplete" ? `(could not verify)${reasonTag(p)}` : `(${verdict}, score ${score})${reasonTag(p)}`;
|
|
52267
52277
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Box_default, { flexDirection: "row", children: [
|
|
52268
52278
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { color, children: [
|
|
52269
52279
|
sigil,
|
|
@@ -52274,18 +52284,23 @@ var init_WrapperVerdictLine = __esm({
|
|
|
52274
52284
|
"@",
|
|
52275
52285
|
p?.version
|
|
52276
52286
|
] }),
|
|
52277
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { dimColor: true, children: [
|
|
52278
|
-
"
|
|
52279
|
-
|
|
52280
|
-
|
|
52281
|
-
|
|
52282
|
-
|
|
52283
|
-
|
|
52284
|
-
|
|
52285
|
-
|
|
52286
|
-
|
|
52287
|
-
|
|
52288
|
-
|
|
52287
|
+
refusal ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { dimColor: true, children: [
|
|
52288
|
+
" ",
|
|
52289
|
+
meta
|
|
52290
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
52291
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { dimColor: true, children: [
|
|
52292
|
+
" ",
|
|
52293
|
+
meta,
|
|
52294
|
+
" \u2014 "
|
|
52295
|
+
] }),
|
|
52296
|
+
dgForce ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { color, bold: true, children: "--dg-force: bypassing. Installing." }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { bold: true, children: [
|
|
52297
|
+
prompt,
|
|
52298
|
+
" [",
|
|
52299
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { color: "green", children: "y" }),
|
|
52300
|
+
"/",
|
|
52301
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { color: "red", children: "N" }),
|
|
52302
|
+
"]"
|
|
52303
|
+
] })
|
|
52289
52304
|
] })
|
|
52290
52305
|
] });
|
|
52291
52306
|
}
|
|
@@ -52303,14 +52318,23 @@ var init_WrapperVerdictLine = __esm({
|
|
|
52303
52318
|
total,
|
|
52304
52319
|
" packages"
|
|
52305
52320
|
] }),
|
|
52306
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { dimColor: true, children: [
|
|
52321
|
+
refusal ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { dimColor: true, children: [
|
|
52307
52322
|
": ",
|
|
52308
|
-
parts.join(", ")
|
|
52309
|
-
|
|
52310
|
-
|
|
52311
|
-
|
|
52312
|
-
|
|
52313
|
-
|
|
52323
|
+
parts.join(", ")
|
|
52324
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
52325
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { dimColor: true, children: [
|
|
52326
|
+
": ",
|
|
52327
|
+
parts.join(", "),
|
|
52328
|
+
" \u2014 "
|
|
52329
|
+
] }),
|
|
52330
|
+
dgForce ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { color, bold: true, children: "--dg-force: bypassing. Installing." }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Text, { bold: true, children: [
|
|
52331
|
+
prompt,
|
|
52332
|
+
" [",
|
|
52333
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { color: "green", children: "y" }),
|
|
52334
|
+
"/",
|
|
52335
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { color: "red", children: "N" }),
|
|
52336
|
+
"] [d] details"
|
|
52337
|
+
] })
|
|
52314
52338
|
] })
|
|
52315
52339
|
] });
|
|
52316
52340
|
};
|
|
@@ -52348,21 +52372,30 @@ var init_WrapperApp = __esm({
|
|
|
52348
52372
|
installing: "Installing with pip..."
|
|
52349
52373
|
}
|
|
52350
52374
|
};
|
|
52351
|
-
WrapperApp = ({ args, config, ecosystem }) => {
|
|
52375
|
+
WrapperApp = ({ args, config, ecosystem, handoff }) => {
|
|
52352
52376
|
const { exit } = use_app_default();
|
|
52353
|
-
const { state, confirmInstall, rejectInstall } = useWrapper(args, config, ecosystem,
|
|
52377
|
+
const { state, confirmInstall, rejectInstall } = useWrapper(args, config, ecosystem, handoff);
|
|
52354
52378
|
const [showDetails, setShowDetails] = (0, import_react38.useState)(false);
|
|
52355
52379
|
use_input_default((input) => {
|
|
52356
|
-
if (input === "d" &&
|
|
52380
|
+
if (input === "d" && state.phase === "warn") {
|
|
52357
52381
|
setShowDetails((v) => !v);
|
|
52358
52382
|
}
|
|
52359
52383
|
});
|
|
52360
52384
|
(0, import_react38.useEffect)(() => {
|
|
52361
|
-
if (state.phase === "done") {
|
|
52385
|
+
if (state.phase === "done" || state.phase === "refused" || state.phase === "declined") {
|
|
52362
52386
|
process.exitCode = state.exitCode;
|
|
52363
52387
|
const timer = setTimeout(() => exit(), 0);
|
|
52364
52388
|
return () => clearTimeout(timer);
|
|
52365
52389
|
}
|
|
52390
|
+
if (state.phase === "installing") {
|
|
52391
|
+
const timer = setTimeout(() => exit(), 0);
|
|
52392
|
+
return () => clearTimeout(timer);
|
|
52393
|
+
}
|
|
52394
|
+
if (state.phase === "error") {
|
|
52395
|
+
process.exitCode = 2;
|
|
52396
|
+
const timer = setTimeout(() => exit(), 0);
|
|
52397
|
+
return () => clearTimeout(timer);
|
|
52398
|
+
}
|
|
52366
52399
|
if (state.phase === "free_cap_reached") {
|
|
52367
52400
|
process.exitCode = 1;
|
|
52368
52401
|
const timer = setTimeout(() => exit(), 0);
|
|
@@ -52377,43 +52410,30 @@ var init_WrapperApp = __esm({
|
|
|
52377
52410
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Spinner2, { label: labels.resolving(state.count, state.count !== 1 ? "s" : "") });
|
|
52378
52411
|
case "scanning":
|
|
52379
52412
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Spinner2, { label: labels.scanning(state.count, state.count !== 1 ? "s" : "") });
|
|
52380
|
-
case "pass":
|
|
52381
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(WrapperVerdictLine, { result: state.result, verdict: "pass" });
|
|
52382
52413
|
case "warn":
|
|
52383
52414
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
52384
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(WrapperVerdictLine, { result: state.result, verdict: "warn"
|
|
52415
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(WrapperVerdictLine, { result: state.result, verdict: "warn" }),
|
|
52385
52416
|
showDetails && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ResultsView, { result: state.result, config, durationMs: state.result.durationMs }) }),
|
|
52386
|
-
|
|
52417
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ConfirmPrompt, { message: "", onConfirm: handleConfirm, onReject: handleReject })
|
|
52387
52418
|
] });
|
|
52388
|
-
case "
|
|
52419
|
+
case "refused":
|
|
52389
52420
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
52390
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(WrapperVerdictLine, { result: state.result, verdict:
|
|
52391
|
-
|
|
52392
|
-
|
|
52421
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(WrapperVerdictLine, { result: state.result, verdict: state.verdict, refusal: true }),
|
|
52422
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Text, { dimColor: true, children: [
|
|
52423
|
+
" install anyway: ",
|
|
52424
|
+
state.cmd
|
|
52425
|
+
] })
|
|
52393
52426
|
] });
|
|
52394
|
-
case "
|
|
52395
|
-
|
|
52396
|
-
|
|
52397
|
-
|
|
52398
|
-
" Proceeding with install."
|
|
52399
|
-
] });
|
|
52400
|
-
}
|
|
52401
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ErrorView, { error: new Error(state.message) });
|
|
52427
|
+
case "declined":
|
|
52428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { children: state.line });
|
|
52429
|
+
// The verdict line is Ink's final frame; it stays on screen after unmount and
|
|
52430
|
+
// the installer's (trimmed) output is printed under it by bin.ts.
|
|
52402
52431
|
case "installing":
|
|
52403
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
52432
|
+
return state.line ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { children: state.line }) : null;
|
|
52404
52433
|
case "done":
|
|
52405
52434
|
return null;
|
|
52406
52435
|
case "error":
|
|
52407
|
-
if (state.proceed) {
|
|
52408
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Text, { color: "yellow", children: [
|
|
52409
|
-
"Warning: Scan failed (",
|
|
52410
|
-
state.message,
|
|
52411
|
-
"). Proceeding with install."
|
|
52412
|
-
] });
|
|
52413
|
-
}
|
|
52414
52436
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ErrorView, { error: new Error(state.message) });
|
|
52415
|
-
case "passthrough":
|
|
52416
|
-
return null;
|
|
52417
52437
|
case "free_cap_reached": {
|
|
52418
52438
|
let hasKey = false;
|
|
52419
52439
|
try {
|
|
@@ -52449,9 +52469,9 @@ __export(conda_wrapper_exports, {
|
|
|
52449
52469
|
adapter: () => adapter,
|
|
52450
52470
|
runStaticConda: () => runStaticConda
|
|
52451
52471
|
});
|
|
52452
|
-
import { spawn as
|
|
52472
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
52453
52473
|
function parseCondaArgs(args) {
|
|
52454
|
-
const { filtered, dgForce,
|
|
52474
|
+
const { filtered, dgForce, dgNoScripts } = stripDgFlags(args);
|
|
52455
52475
|
const command = filtered[0] ?? "";
|
|
52456
52476
|
const shouldScan = INSTALL_COMMANDS3.has(command);
|
|
52457
52477
|
const packages = [];
|
|
@@ -52470,7 +52490,6 @@ function parseCondaArgs(args) {
|
|
|
52470
52490
|
packages,
|
|
52471
52491
|
rawArgs: filtered,
|
|
52472
52492
|
dgForce,
|
|
52473
|
-
dgForceReason,
|
|
52474
52493
|
dgNoScripts,
|
|
52475
52494
|
shouldScan
|
|
52476
52495
|
};
|
|
@@ -52504,7 +52523,7 @@ async function runStaticConda(args, ecosystem, config) {
|
|
|
52504
52523
|
return 127;
|
|
52505
52524
|
}
|
|
52506
52525
|
return await new Promise((resolve3) => {
|
|
52507
|
-
const child =
|
|
52526
|
+
const child = spawn6(real, parsed.rawArgs, { stdio: "inherit", env: childInstallEnv() });
|
|
52508
52527
|
child.on("close", (code) => resolve3(code ?? 1));
|
|
52509
52528
|
child.on("error", () => resolve3(1));
|
|
52510
52529
|
});
|
|
@@ -52551,7 +52570,7 @@ function pnpmFlagTakesValue(flag) {
|
|
|
52551
52570
|
return valueFlagPrefixes.includes(flag);
|
|
52552
52571
|
}
|
|
52553
52572
|
function parsePnpmArgs(args) {
|
|
52554
|
-
const { filtered, dgForce,
|
|
52573
|
+
const { filtered, dgForce, dgNoScripts } = stripDgFlags(args);
|
|
52555
52574
|
const command = filtered[0] ?? "";
|
|
52556
52575
|
const shouldScan = INSTALL_COMMANDS4.has(command);
|
|
52557
52576
|
const packages = [];
|
|
@@ -52570,7 +52589,6 @@ function parsePnpmArgs(args) {
|
|
|
52570
52589
|
packages,
|
|
52571
52590
|
rawArgs: filtered,
|
|
52572
52591
|
dgForce,
|
|
52573
|
-
dgForceReason,
|
|
52574
52592
|
dgNoScripts,
|
|
52575
52593
|
shouldScan
|
|
52576
52594
|
};
|
|
@@ -52649,7 +52667,7 @@ function yarnFlagTakesValue(flag) {
|
|
|
52649
52667
|
return valueFlagPrefixes.includes(flag);
|
|
52650
52668
|
}
|
|
52651
52669
|
function parseYarnArgs(args) {
|
|
52652
|
-
const { filtered, dgForce,
|
|
52670
|
+
const { filtered, dgForce, dgNoScripts } = stripDgFlags(args);
|
|
52653
52671
|
const command = filtered[0] ?? "";
|
|
52654
52672
|
const shouldScan = INSTALL_COMMANDS5.has(command);
|
|
52655
52673
|
const packages = [];
|
|
@@ -52668,7 +52686,6 @@ function parseYarnArgs(args) {
|
|
|
52668
52686
|
packages,
|
|
52669
52687
|
rawArgs: filtered,
|
|
52670
52688
|
dgForce,
|
|
52671
|
-
dgForceReason,
|
|
52672
52689
|
dgNoScripts,
|
|
52673
52690
|
shouldScan
|
|
52674
52691
|
};
|
|
@@ -52748,7 +52765,7 @@ function bunFlagTakesValue(flag) {
|
|
|
52748
52765
|
return valueFlagPrefixes.includes(flag);
|
|
52749
52766
|
}
|
|
52750
52767
|
function parseBunArgs(args) {
|
|
52751
|
-
const { filtered, dgForce,
|
|
52768
|
+
const { filtered, dgForce, dgNoScripts } = stripDgFlags(args);
|
|
52752
52769
|
const command = filtered[0] ?? "";
|
|
52753
52770
|
const shouldScan = INSTALL_COMMANDS6.has(command);
|
|
52754
52771
|
const packages = [];
|
|
@@ -52767,7 +52784,6 @@ function parseBunArgs(args) {
|
|
|
52767
52784
|
packages,
|
|
52768
52785
|
rawArgs: filtered,
|
|
52769
52786
|
dgForce,
|
|
52770
|
-
dgForceReason,
|
|
52771
52787
|
dgNoScripts,
|
|
52772
52788
|
shouldScan
|
|
52773
52789
|
};
|
|
@@ -52854,7 +52870,7 @@ function uvFlagTakesValue(flag) {
|
|
|
52854
52870
|
return valueFlagPrefixes.includes(flag);
|
|
52855
52871
|
}
|
|
52856
52872
|
function parseUvArgs(args) {
|
|
52857
|
-
const { filtered, dgForce,
|
|
52873
|
+
const { filtered, dgForce, dgNoScripts } = stripDgFlags(args);
|
|
52858
52874
|
const first = filtered[0] ?? "";
|
|
52859
52875
|
let command = "";
|
|
52860
52876
|
let argStart = 1;
|
|
@@ -52903,7 +52919,6 @@ function parseUvArgs(args) {
|
|
|
52903
52919
|
packages,
|
|
52904
52920
|
rawArgs: filtered,
|
|
52905
52921
|
dgForce,
|
|
52906
|
-
dgForceReason,
|
|
52907
52922
|
dgNoScripts,
|
|
52908
52923
|
shouldScan
|
|
52909
52924
|
};
|
|
@@ -52915,7 +52930,6 @@ async function resolveTopLevel5(parsed) {
|
|
|
52915
52930
|
if (at <= 0) return s;
|
|
52916
52931
|
return `${s.slice(0, at)}==${s.slice(at + 1)}`;
|
|
52917
52932
|
});
|
|
52918
|
-
void parsePipSpec;
|
|
52919
52933
|
return await resolvePackages2(normalized);
|
|
52920
52934
|
}
|
|
52921
52935
|
async function resolveTransitive4(parsed) {
|
|
@@ -52966,7 +52980,7 @@ function pipxFlagTakesValue(flag) {
|
|
|
52966
52980
|
return valueFlagPrefixes.includes(flag);
|
|
52967
52981
|
}
|
|
52968
52982
|
function parsePipxArgs(args) {
|
|
52969
|
-
const { filtered, dgForce,
|
|
52983
|
+
const { filtered, dgForce, dgNoScripts } = stripDgFlags(args);
|
|
52970
52984
|
const command = filtered[0] ?? "";
|
|
52971
52985
|
const shouldScan = INSTALL_COMMANDS7.has(command) && command !== "upgrade-all";
|
|
52972
52986
|
const packages = [];
|
|
@@ -52989,7 +53003,6 @@ function parsePipxArgs(args) {
|
|
|
52989
53003
|
packages,
|
|
52990
53004
|
rawArgs: filtered,
|
|
52991
53005
|
dgForce,
|
|
52992
|
-
dgForceReason,
|
|
52993
53006
|
dgNoScripts,
|
|
52994
53007
|
shouldScan
|
|
52995
53008
|
};
|
|
@@ -53043,11 +53056,7 @@ var wrapper_factory_exports = {};
|
|
|
53043
53056
|
__export(wrapper_factory_exports, {
|
|
53044
53057
|
runEcosystemWrapper: () => runEcosystemWrapper
|
|
53045
53058
|
});
|
|
53046
|
-
import { spawn as
|
|
53047
|
-
function emitJson(config, result) {
|
|
53048
|
-
if (!config.json) return;
|
|
53049
|
-
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
53050
|
-
}
|
|
53059
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
53051
53060
|
function shimSentinelEnv3() {
|
|
53052
53061
|
return childInstallEnv();
|
|
53053
53062
|
}
|
|
@@ -53059,7 +53068,7 @@ async function spawnRealBinary(adapter7, args) {
|
|
|
53059
53068
|
return 127;
|
|
53060
53069
|
}
|
|
53061
53070
|
return await new Promise((resolve3) => {
|
|
53062
|
-
const child =
|
|
53071
|
+
const child = spawn7(real, args, { stdio: "inherit", env: shimSentinelEnv3() });
|
|
53063
53072
|
child.on("close", (code) => resolve3(code ?? 1));
|
|
53064
53073
|
child.on("error", () => resolve3(1));
|
|
53065
53074
|
});
|
|
@@ -53110,7 +53119,7 @@ async function runEcosystemWrapper(adapter7, args, config) {
|
|
|
53110
53119
|
`)
|
|
53111
53120
|
);
|
|
53112
53121
|
}
|
|
53113
|
-
|
|
53122
|
+
emitWrapperJson(config, {
|
|
53114
53123
|
ecosystem: adapter7.ecosystem,
|
|
53115
53124
|
packages: [],
|
|
53116
53125
|
scanVerdict: "scan_failed",
|
|
@@ -53167,7 +53176,7 @@ async function runEcosystemWrapper(adapter7, args, config) {
|
|
|
53167
53176
|
`)
|
|
53168
53177
|
);
|
|
53169
53178
|
}
|
|
53170
|
-
|
|
53179
|
+
emitWrapperJson(config, {
|
|
53171
53180
|
ecosystem: adapter7.ecosystem,
|
|
53172
53181
|
packages: [],
|
|
53173
53182
|
scanVerdict: "scan_failed",
|
|
@@ -53198,7 +53207,7 @@ async function runEcosystemWrapper(adapter7, args, config) {
|
|
|
53198
53207
|
|
|
53199
53208
|
`)
|
|
53200
53209
|
);
|
|
53201
|
-
|
|
53210
|
+
emitWrapperJson(config, {
|
|
53202
53211
|
ecosystem: adapter7.ecosystem,
|
|
53203
53212
|
packages: [],
|
|
53204
53213
|
scanVerdict: "scan_failed",
|
|
@@ -53215,7 +53224,7 @@ async function runEcosystemWrapper(adapter7, args, config) {
|
|
|
53215
53224
|
|
|
53216
53225
|
`)
|
|
53217
53226
|
);
|
|
53218
|
-
|
|
53227
|
+
emitWrapperJson(config, {
|
|
53219
53228
|
ecosystem: adapter7.ecosystem,
|
|
53220
53229
|
packages: [],
|
|
53221
53230
|
scanVerdict: "scan_failed",
|
|
@@ -53231,184 +53240,152 @@ async function runEcosystemWrapper(adapter7, args, config) {
|
|
|
53231
53240
|
`)
|
|
53232
53241
|
);
|
|
53233
53242
|
}
|
|
53234
|
-
const
|
|
53235
|
-
|
|
53243
|
+
const code = await spawnRealBinary(adapter7, installArgs);
|
|
53244
|
+
emitWrapperJson(config, {
|
|
53236
53245
|
ecosystem: adapter7.ecosystem,
|
|
53237
53246
|
packages: [],
|
|
53238
53247
|
scanVerdict: "scan_failed",
|
|
53239
53248
|
installRan: true,
|
|
53240
|
-
installExitCode:
|
|
53249
|
+
installExitCode: code,
|
|
53241
53250
|
error: { code: "scan_failed", message: err.message }
|
|
53242
53251
|
});
|
|
53243
|
-
return
|
|
53252
|
+
return code;
|
|
53244
53253
|
}
|
|
53245
53254
|
const allowlist = loadAllowlist(process.cwd());
|
|
53246
53255
|
const { result: filteredResult, suppressedCount } = applyAllowlist(allowlist, result, adapter7.apiKind);
|
|
53247
53256
|
result = filteredResult;
|
|
53248
53257
|
const topLevelNames = new Set(resolved.map((p) => p.name));
|
|
53249
|
-
|
|
53250
|
-
|
|
53251
|
-
|
|
53252
|
-
|
|
53253
|
-
|
|
53254
|
-
|
|
53258
|
+
const verdict = verdictFromResult(result);
|
|
53259
|
+
const decision = routeVerdict({
|
|
53260
|
+
verdict,
|
|
53261
|
+
mode: config.mode,
|
|
53262
|
+
strict: config.strict,
|
|
53263
|
+
dgForce: parsed.dgForce
|
|
53264
|
+
});
|
|
53265
|
+
const ctx = {
|
|
53266
|
+
ecosystem: adapter7.ecosystem,
|
|
53267
|
+
apiKind: adapter7.apiKind,
|
|
53268
|
+
installArgs,
|
|
53269
|
+
passthroughArgs: parsed.rawArgs,
|
|
53270
|
+
result,
|
|
53271
|
+
resolved,
|
|
53272
|
+
suppressedCount,
|
|
53273
|
+
error: verdict === "analysis_incomplete" && decision.outcome === "refuse" ? { code: "analysis_incomplete", message: "scanner could not fully analyze the install set" } : void 0
|
|
53274
|
+
};
|
|
53275
|
+
const presenter = {
|
|
53276
|
+
announce(d) {
|
|
53277
|
+
switch (d.verdict) {
|
|
53278
|
+
case "pass": {
|
|
53279
|
+
if (config.json || config.quiet) return;
|
|
53280
|
+
const topLevel = resolved.map((p) => `${p.name} ${p.version}`);
|
|
53281
|
+
const passLine = topLevel.length === 1 ? ` ${import_chalk19.default.green("\u2713")} ${import_chalk19.default.bold("DG verified:")} ${topLevel[0]} is safe` : ` ${import_chalk19.default.green("\u2713")} ${import_chalk19.default.bold("DG verified:")} ${topLevel.length} packages safe`;
|
|
53282
|
+
const installLine = topLevel.length === 1 ? ` ${import_chalk19.default.green("\u2713")} Installing ${topLevel[0]}` : ` ${import_chalk19.default.green("\u2713")} Installing ${topLevel.join(", ")}`;
|
|
53283
|
+
process.stderr.write(`${passLine}
|
|
53255
53284
|
${installLine}
|
|
53256
53285
|
`);
|
|
53257
|
-
|
|
53258
|
-
|
|
53286
|
+
if (suppressedCount > 0) {
|
|
53287
|
+
process.stderr.write(import_chalk19.default.dim(` (${suppressedCount} finding${suppressedCount === 1 ? "" : "s"} suppressed by .dg-allowlist.json)
|
|
53259
53288
|
`));
|
|
53260
|
-
|
|
53261
|
-
|
|
53262
|
-
|
|
53263
|
-
|
|
53264
|
-
|
|
53265
|
-
|
|
53266
|
-
|
|
53267
|
-
|
|
53268
|
-
installRan: true,
|
|
53269
|
-
installExitCode: code2,
|
|
53270
|
-
suppressedByAllowlist: suppressedCount > 0 ? suppressedCount : void 0
|
|
53271
|
-
});
|
|
53272
|
-
return code2;
|
|
53273
|
-
}
|
|
53274
|
-
if (result.action === "warn") {
|
|
53275
|
-
if (!config.json && !config.quiet) {
|
|
53276
|
-
const topLevelList = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
53277
|
-
process.stderr.write(` ${import_chalk19.default.yellow("\u26A0")} ${import_chalk19.default.bold("DG flagged")} ${topLevelList}.
|
|
53289
|
+
}
|
|
53290
|
+
process.stderr.write("\n");
|
|
53291
|
+
return;
|
|
53292
|
+
}
|
|
53293
|
+
case "warn": {
|
|
53294
|
+
if (config.json || config.quiet) return;
|
|
53295
|
+
const topLevelList = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
53296
|
+
process.stderr.write(` ${import_chalk19.default.yellow("\u26A0")} ${import_chalk19.default.bold("DG flagged")} ${topLevelList}.
|
|
53278
53297
|
`);
|
|
53279
|
-
|
|
53280
|
-
|
|
53281
|
-
|
|
53282
|
-
|
|
53283
|
-
|
|
53298
|
+
const flaggedPkgs = result.packages.filter((p) => derivePackageActionPublic(p) === "warn");
|
|
53299
|
+
for (const p of flaggedPkgs.slice(0, 5)) {
|
|
53300
|
+
if (p.findings && p.findings.length > 0) {
|
|
53301
|
+
for (const f of p.findings.slice(0, 3)) {
|
|
53302
|
+
process.stderr.write(import_chalk19.default.dim(` \u2022 ${f.title ?? "finding"}
|
|
53303
|
+
`));
|
|
53304
|
+
}
|
|
53305
|
+
}
|
|
53306
|
+
}
|
|
53307
|
+
if (suppressedCount > 0) {
|
|
53308
|
+
process.stderr.write(import_chalk19.default.dim(` (${suppressedCount} additional finding${suppressedCount === 1 ? "" : "s"} suppressed by .dg-allowlist.json)
|
|
53284
53309
|
`));
|
|
53285
53310
|
}
|
|
53311
|
+
return;
|
|
53286
53312
|
}
|
|
53287
|
-
|
|
53288
|
-
|
|
53289
|
-
|
|
53313
|
+
case "block": {
|
|
53314
|
+
if (d.outcome === "install") {
|
|
53315
|
+
if (!config.json && !config.quiet) {
|
|
53316
|
+
process.stderr.write(import_chalk19.default.yellow.bold(` --dg-force: bypassing block. Install at your own risk.
|
|
53317
|
+
|
|
53290
53318
|
`));
|
|
53319
|
+
}
|
|
53320
|
+
} else if (!config.json) {
|
|
53321
|
+
const blockedList = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
53322
|
+
process.stderr.write(
|
|
53323
|
+
` ${import_chalk19.default.red("\u2717")} ${import_chalk19.default.bold("DG blocked")} ${blockedList}.
|
|
53324
|
+
${import_chalk19.default.dim(`install anyway: ${adapter7.realBinaryName} ${parsed.rawArgs.join(" ")} --dg-force`)}
|
|
53325
|
+
|
|
53326
|
+
`
|
|
53327
|
+
);
|
|
53328
|
+
}
|
|
53329
|
+
return;
|
|
53330
|
+
}
|
|
53331
|
+
case "analysis_incomplete": {
|
|
53332
|
+
const list = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
53333
|
+
if (d.outcome === "refuse") {
|
|
53334
|
+
if (!config.json) {
|
|
53335
|
+
process.stderr.write(
|
|
53336
|
+
` ${import_chalk19.default.cyan("?")} ${import_chalk19.default.bold("DG couldn't verify")} ${list} \u2014 unverified, not safe.
|
|
53337
|
+
${import_chalk19.default.dim(`install anyway: ${adapter7.realBinaryName} ${parsed.rawArgs.join(" ")} --dg-force`)}
|
|
53338
|
+
|
|
53339
|
+
`
|
|
53340
|
+
);
|
|
53341
|
+
}
|
|
53342
|
+
} else if (!config.json && !config.quiet) {
|
|
53343
|
+
process.stderr.write(
|
|
53344
|
+
import_chalk19.default.yellow(` \u26A0 DG could not fully verify ${list} (analysis incomplete). Proceeding with install (mode=${config.mode}).
|
|
53345
|
+
`)
|
|
53346
|
+
);
|
|
53347
|
+
}
|
|
53348
|
+
return;
|
|
53349
|
+
}
|
|
53350
|
+
default:
|
|
53351
|
+
return;
|
|
53352
|
+
}
|
|
53353
|
+
},
|
|
53354
|
+
async confirmProceed() {
|
|
53355
|
+
if (!(process.stderr.isTTY && !process.env.CI && !config.json)) {
|
|
53356
|
+
if (!config.json && !config.quiet) process.stderr.write(import_chalk19.default.dim(" Proceeding (non-interactive).\n"));
|
|
53357
|
+
return true;
|
|
53291
53358
|
}
|
|
53292
|
-
}
|
|
53293
|
-
if (process.stderr.isTTY && !process.env.CI && !config.json) {
|
|
53294
53359
|
const { promptYesNo: promptYesNo2 } = await Promise.resolve().then(() => (init_prompt(), prompt_exports));
|
|
53295
53360
|
const proceed = await promptYesNo2({ defaultAnswer: "y", message: " Proceed?" });
|
|
53296
|
-
if (!proceed)
|
|
53297
|
-
|
|
53298
|
-
|
|
53299
|
-
|
|
53300
|
-
|
|
53301
|
-
scanVerdict: "warn",
|
|
53302
|
-
installRan: false,
|
|
53303
|
-
installExitCode: null
|
|
53304
|
-
});
|
|
53305
|
-
return 1;
|
|
53306
|
-
}
|
|
53307
|
-
} else if (!config.json && !config.quiet) {
|
|
53308
|
-
process.stderr.write(import_chalk19.default.dim(" Proceeding (non-interactive).\n"));
|
|
53309
|
-
}
|
|
53310
|
-
const code2 = await spawnRealBinary(adapter7, installArgs);
|
|
53311
|
-
emitJson(config, {
|
|
53312
|
-
ecosystem: adapter7.ecosystem,
|
|
53313
|
-
packages: packagesFromResult(result, topLevelNames),
|
|
53314
|
-
scanVerdict: "warn",
|
|
53315
|
-
installRan: true,
|
|
53316
|
-
installExitCode: code2,
|
|
53317
|
-
suppressedByAllowlist: suppressedCount > 0 ? suppressedCount : void 0
|
|
53318
|
-
});
|
|
53319
|
-
return code2;
|
|
53320
|
-
}
|
|
53321
|
-
if (result.action === "block") {
|
|
53322
|
-
if (parsed.dgForce) {
|
|
53361
|
+
if (!proceed) process.stderr.write(import_chalk19.default.dim(" Install cancelled by user.\n\n"));
|
|
53362
|
+
return proceed;
|
|
53363
|
+
},
|
|
53364
|
+
runInstall: (args2) => spawnRealBinary(adapter7, args2),
|
|
53365
|
+
async audit(kind) {
|
|
53323
53366
|
try {
|
|
53324
53367
|
await dispatchInstallAudit({
|
|
53325
53368
|
ecosystem: adapter7.apiKind,
|
|
53326
53369
|
packages: result.packages,
|
|
53327
|
-
decisionAction:
|
|
53328
|
-
bypassed:
|
|
53329
|
-
bypassReason: parsed.dgForceReason
|
|
53370
|
+
decisionAction: kind,
|
|
53371
|
+
bypassed: kind === "override"
|
|
53330
53372
|
});
|
|
53331
53373
|
} catch {
|
|
53332
53374
|
}
|
|
53333
|
-
|
|
53334
|
-
|
|
53335
|
-
|
|
53336
|
-
`));
|
|
53337
|
-
}
|
|
53338
|
-
const code2 = await spawnRealBinary(adapter7, installArgs);
|
|
53339
|
-
emitJson(config, {
|
|
53375
|
+
},
|
|
53376
|
+
emit(record) {
|
|
53377
|
+
emitWrapperJson(config, {
|
|
53340
53378
|
ecosystem: adapter7.ecosystem,
|
|
53341
53379
|
packages: packagesFromResult(result, topLevelNames),
|
|
53342
|
-
scanVerdict:
|
|
53343
|
-
installRan:
|
|
53344
|
-
installExitCode:
|
|
53380
|
+
scanVerdict: record.scanVerdict,
|
|
53381
|
+
installRan: record.installRan,
|
|
53382
|
+
installExitCode: record.installExitCode,
|
|
53383
|
+
error: record.error,
|
|
53384
|
+
suppressedByAllowlist: record.suppressedByAllowlist
|
|
53345
53385
|
});
|
|
53346
|
-
return code2;
|
|
53347
|
-
}
|
|
53348
|
-
try {
|
|
53349
|
-
await dispatchInstallAudit({
|
|
53350
|
-
ecosystem: adapter7.apiKind,
|
|
53351
|
-
packages: result.packages,
|
|
53352
|
-
decisionAction: "block",
|
|
53353
|
-
bypassed: false
|
|
53354
|
-
});
|
|
53355
|
-
} catch {
|
|
53356
|
-
}
|
|
53357
|
-
const blockedList = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
53358
|
-
if (!config.json) {
|
|
53359
|
-
process.stderr.write(
|
|
53360
|
-
` ${import_chalk19.default.red("\u2717")} ${import_chalk19.default.bold("DG blocked")} ${blockedList}.
|
|
53361
|
-
Real install was NOT run. To override:
|
|
53362
|
-
` + import_chalk19.default.dim(` ${adapter7.realBinaryName} ${parsed.rawArgs.join(" ")} --dg-force --dg-force-reason="<reason>"
|
|
53363
|
-
|
|
53364
|
-
`)
|
|
53365
|
-
);
|
|
53366
|
-
}
|
|
53367
|
-
emitJson(config, {
|
|
53368
|
-
ecosystem: adapter7.ecosystem,
|
|
53369
|
-
packages: packagesFromResult(result, topLevelNames),
|
|
53370
|
-
scanVerdict: "block",
|
|
53371
|
-
installRan: false,
|
|
53372
|
-
installExitCode: null
|
|
53373
|
-
});
|
|
53374
|
-
return 2;
|
|
53375
|
-
}
|
|
53376
|
-
const refuseHard = config.mode === "block" || config.strict;
|
|
53377
|
-
const unverifiedList = resolved.map((p) => `${p.name} ${p.version}`).join(", ");
|
|
53378
|
-
if (refuseHard && !parsed.dgForce) {
|
|
53379
|
-
if (!config.json) {
|
|
53380
|
-
process.stderr.write(
|
|
53381
|
-
` ${import_chalk19.default.red("\u2717")} ${import_chalk19.default.bold("DG could not verify")} ${unverifiedList} \u2014 analysis incomplete.
|
|
53382
|
-
` + import_chalk19.default.dim(` --mode ${config.strict ? "strict" : "block"} \u21D2 refusing install (unverified is not safe). Use --mode warn or --dg-force to bypass.
|
|
53383
|
-
|
|
53384
|
-
`)
|
|
53385
|
-
);
|
|
53386
53386
|
}
|
|
53387
|
-
|
|
53388
|
-
|
|
53389
|
-
packages: packagesFromResult(result, topLevelNames),
|
|
53390
|
-
scanVerdict: "analysis_incomplete",
|
|
53391
|
-
installRan: false,
|
|
53392
|
-
installExitCode: null,
|
|
53393
|
-
error: { code: "analysis_incomplete", message: "scanner could not fully analyze the install set" }
|
|
53394
|
-
});
|
|
53395
|
-
return 4;
|
|
53396
|
-
}
|
|
53397
|
-
if (!config.json && !config.quiet) {
|
|
53398
|
-
process.stderr.write(
|
|
53399
|
-
import_chalk19.default.yellow(` \u26A0 DG could not fully verify ${unverifiedList} (analysis incomplete). Proceeding with install (mode=${config.mode}).
|
|
53400
|
-
`)
|
|
53401
|
-
);
|
|
53402
|
-
}
|
|
53403
|
-
const code = await spawnRealBinary(adapter7, installArgs);
|
|
53404
|
-
emitJson(config, {
|
|
53405
|
-
ecosystem: adapter7.ecosystem,
|
|
53406
|
-
packages: packagesFromResult(result, topLevelNames),
|
|
53407
|
-
scanVerdict: "analysis_incomplete",
|
|
53408
|
-
installRan: true,
|
|
53409
|
-
installExitCode: code
|
|
53410
|
-
});
|
|
53411
|
-
return code;
|
|
53387
|
+
};
|
|
53388
|
+
return await executeDecision(decision, ctx, presenter);
|
|
53412
53389
|
}
|
|
53413
53390
|
var import_chalk19;
|
|
53414
53391
|
var init_wrapper_factory = __esm({
|
|
@@ -53423,6 +53400,9 @@ var init_wrapper_factory = __esm({
|
|
|
53423
53400
|
init_wrapper_shared();
|
|
53424
53401
|
init_npm_wrapper();
|
|
53425
53402
|
init_pip_wrapper();
|
|
53403
|
+
init_route();
|
|
53404
|
+
init_run();
|
|
53405
|
+
init_json();
|
|
53426
53406
|
}
|
|
53427
53407
|
});
|
|
53428
53408
|
|
|
@@ -53675,8 +53655,6 @@ async function main() {
|
|
|
53675
53655
|
}
|
|
53676
53656
|
if (result.action === "block") {
|
|
53677
53657
|
try {
|
|
53678
|
-
const reasonIdx = args.indexOf("--dg-force-reason");
|
|
53679
|
-
const bypassReason = reasonIdx >= 0 ? args[reasonIdx + 1] : void 0;
|
|
53680
53658
|
const { dispatchPublishCheckAudit: dispatchPublishCheckAudit2 } = await Promise.resolve().then(() => (init_audit_dispatcher(), audit_dispatcher_exports));
|
|
53681
53659
|
const at = result.artifact.lastIndexOf("@");
|
|
53682
53660
|
const pkgName = at > 0 ? result.artifact.slice(0, at) : result.artifact;
|
|
@@ -53687,8 +53665,7 @@ async function main() {
|
|
|
53687
53665
|
packageVersion: pkgVersion,
|
|
53688
53666
|
score: result.score,
|
|
53689
53667
|
decisionAction: force ? "override" : "block",
|
|
53690
|
-
bypassed: !!force
|
|
53691
|
-
bypassReason
|
|
53668
|
+
bypassed: !!force
|
|
53692
53669
|
});
|
|
53693
53670
|
} catch {
|
|
53694
53671
|
}
|
|
@@ -53860,6 +53837,12 @@ async function main() {
|
|
|
53860
53837
|
return;
|
|
53861
53838
|
}
|
|
53862
53839
|
}
|
|
53840
|
+
async function runHandoff(handoff) {
|
|
53841
|
+
if (!handoff.install) {
|
|
53842
|
+
return typeof process.exitCode === "number" ? process.exitCode : 0;
|
|
53843
|
+
}
|
|
53844
|
+
return handoff.install.run(handoff.install.args);
|
|
53845
|
+
}
|
|
53863
53846
|
async function handleWrapInternal(argv) {
|
|
53864
53847
|
let ecosystem = argv[0];
|
|
53865
53848
|
if (!ecosystem) {
|
|
@@ -53896,9 +53879,9 @@ async function handleWrapInternal(argv) {
|
|
|
53896
53879
|
const { isReadonlySubcommand: isReadonlySubcommand2 } = await Promise.resolve().then(() => (init_readonly(), readonly_exports));
|
|
53897
53880
|
const ecoTyped = ecosystem;
|
|
53898
53881
|
const spawnReal = async (real, args) => {
|
|
53899
|
-
const { spawn:
|
|
53882
|
+
const { spawn: spawn8 } = await import("node:child_process");
|
|
53900
53883
|
const { childInstallEnv: childInstallEnv2 } = await Promise.resolve().then(() => (init_install(), install_exports));
|
|
53901
|
-
const child =
|
|
53884
|
+
const child = spawn8(real, args, { stdio: "inherit", env: childInstallEnv2() });
|
|
53902
53885
|
return await new Promise((resolve3) => {
|
|
53903
53886
|
child.on("close", (code) => resolve3(code ?? 1));
|
|
53904
53887
|
child.on("error", () => resolve3(1));
|
|
@@ -53925,11 +53908,12 @@ async function handleWrapInternal(argv) {
|
|
|
53925
53908
|
const { render: render2 } = await init_build2().then(() => build_exports);
|
|
53926
53909
|
const React22 = await Promise.resolve().then(() => __toESM(require_react(), 1));
|
|
53927
53910
|
const { WrapperApp: WrapperApp2 } = await init_WrapperApp().then(() => WrapperApp_exports);
|
|
53911
|
+
const handoff = { install: null };
|
|
53928
53912
|
const { waitUntilExit } = render2(
|
|
53929
|
-
React22.createElement(WrapperApp2, { config, args: wrapperArgs, ecosystem: "npm" })
|
|
53913
|
+
React22.createElement(WrapperApp2, { config, args: wrapperArgs, ecosystem: "npm", handoff })
|
|
53930
53914
|
);
|
|
53931
53915
|
await waitUntilExit();
|
|
53932
|
-
return
|
|
53916
|
+
return runHandoff(handoff);
|
|
53933
53917
|
}
|
|
53934
53918
|
if (ecosystem === "pip" || ecosystem === "pip3") {
|
|
53935
53919
|
if (config.json || !process.stdout.isTTY) {
|
|
@@ -53940,11 +53924,12 @@ async function handleWrapInternal(argv) {
|
|
|
53940
53924
|
const { render: render2 } = await init_build2().then(() => build_exports);
|
|
53941
53925
|
const React22 = await Promise.resolve().then(() => __toESM(require_react(), 1));
|
|
53942
53926
|
const { WrapperApp: WrapperApp2 } = await init_WrapperApp().then(() => WrapperApp_exports);
|
|
53927
|
+
const handoff = { install: null };
|
|
53943
53928
|
const { waitUntilExit } = render2(
|
|
53944
|
-
React22.createElement(WrapperApp2, { config, args: wrapperArgs, ecosystem: "pypi" })
|
|
53929
|
+
React22.createElement(WrapperApp2, { config, args: wrapperArgs, ecosystem: "pypi", handoff })
|
|
53945
53930
|
);
|
|
53946
53931
|
await waitUntilExit();
|
|
53947
|
-
return
|
|
53932
|
+
return runHandoff(handoff);
|
|
53948
53933
|
}
|
|
53949
53934
|
if (ecosystem === "conda" || ecosystem === "mamba") {
|
|
53950
53935
|
const { runStaticConda: runStaticConda2 } = await Promise.resolve().then(() => (init_conda_wrapper(), conda_wrapper_exports));
|