@westbayberry/dg 1.0.51 → 1.0.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.mjs +626 -538
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -19192,9 +19192,9 @@ function handleContentBlockStart(event, state) {
19192
19192
  function handleContentBlockDelta(event, state, recordOutputs) {
19193
19193
  if (event.type !== "content_block_delta" || !event.delta) return;
19194
19194
  if (typeof event.index === "number" && "partial_json" in event.delta && typeof event.delta.partial_json === "string") {
19195
- const active = state.activeToolBlocks[event.index];
19196
- if (active) {
19197
- active.inputJsonParts.push(event.delta.partial_json);
19195
+ const active2 = state.activeToolBlocks[event.index];
19196
+ if (active2) {
19197
+ active2.inputJsonParts.push(event.delta.partial_json);
19198
19198
  }
19199
19199
  }
19200
19200
  if (recordOutputs && typeof event.delta.text === "string") {
@@ -19203,9 +19203,9 @@ function handleContentBlockDelta(event, state, recordOutputs) {
19203
19203
  }
19204
19204
  function handleContentBlockStop(event, state) {
19205
19205
  if (event.type !== "content_block_stop" || typeof event.index !== "number") return;
19206
- const active = state.activeToolBlocks[event.index];
19207
- if (!active) return;
19208
- const raw = active.inputJsonParts.join("");
19206
+ const active2 = state.activeToolBlocks[event.index];
19207
+ if (!active2) return;
19208
+ const raw = active2.inputJsonParts.join("");
19209
19209
  let parsedInput;
19210
19210
  try {
19211
19211
  parsedInput = raw ? JSON.parse(raw) : {};
@@ -19214,8 +19214,8 @@ function handleContentBlockStop(event, state) {
19214
19214
  }
19215
19215
  state.toolCalls.push({
19216
19216
  type: "tool_use",
19217
- id: active.id,
19218
- name: active.name,
19217
+ id: active2.id,
19218
+ name: active2.name,
19219
19219
  input: parsedInput
19220
19220
  });
19221
19221
  delete state.activeToolBlocks[event.index];
@@ -48378,6 +48378,34 @@ var init_update_check = __esm({
48378
48378
  }
48379
48379
  });
48380
48380
 
48381
+ // src/alt-screen.ts
48382
+ var alt_screen_exports = {};
48383
+ __export(alt_screen_exports, {
48384
+ altScreenActive: () => altScreenActive,
48385
+ enterAltScreen: () => enterAltScreen,
48386
+ leaveAltScreen: () => leaveAltScreen
48387
+ });
48388
+ function enterAltScreen() {
48389
+ if (!process.stdout.isTTY || active) return;
48390
+ process.stdout.write("\x1B[?1049h\x1B[2J\x1B[H");
48391
+ active = true;
48392
+ }
48393
+ function leaveAltScreen() {
48394
+ if (!active) return;
48395
+ process.stdout.write("\x1B[?1049l\x1B[?25h");
48396
+ active = false;
48397
+ }
48398
+ function altScreenActive() {
48399
+ return active;
48400
+ }
48401
+ var active;
48402
+ var init_alt_screen = __esm({
48403
+ "src/alt-screen.ts"() {
48404
+ "use strict";
48405
+ active = false;
48406
+ }
48407
+ });
48408
+
48381
48409
  // node_modules/react/cjs/react.production.min.js
48382
48410
  var require_react_production_min = __commonJS({
48383
48411
  "node_modules/react/cjs/react.production.min.js"(exports) {
@@ -49718,7 +49746,7 @@ var require_react_development = __commonJS({
49718
49746
  var dispatcher = resolveDispatcher();
49719
49747
  return dispatcher.useReducer(reducer7, initialArg, init3);
49720
49748
  }
49721
- function useRef9(initialValue) {
49749
+ function useRef10(initialValue) {
49722
49750
  var dispatcher = resolveDispatcher();
49723
49751
  return dispatcher.useRef(initialValue);
49724
49752
  }
@@ -50512,7 +50540,7 @@ var require_react_development = __commonJS({
50512
50540
  exports.useLayoutEffect = useLayoutEffect2;
50513
50541
  exports.useMemo = useMemo5;
50514
50542
  exports.useReducer = useReducer8;
50515
- exports.useRef = useRef9;
50543
+ exports.useRef = useRef10;
50516
50544
  exports.useState = useState11;
50517
50545
  exports.useSyncExternalStore = useSyncExternalStore;
50518
50546
  exports.useTransition = useTransition;
@@ -83514,6 +83542,7 @@ async function callAnalyzeAPI(packages, config3, onProgress) {
83514
83542
  const results = [];
83515
83543
  let completed = 0;
83516
83544
  const tTotal = Date.now();
83545
+ if (onProgress) onProgress(0, packages.length, []);
83517
83546
  for (let i = 0; i < batches.length; i++) {
83518
83547
  const batch = batches[i];
83519
83548
  const tBatch = Date.now();
@@ -83775,7 +83804,7 @@ var init_api3 = __esm({
83775
83804
  });
83776
83805
 
83777
83806
  // src/scan-core.ts
83778
- async function scanProjectAtPath(cwd2, config3) {
83807
+ async function scanProjectAtPath(cwd2, config3, onProgress) {
83779
83808
  const startNs = process.hrtime.bigint();
83780
83809
  const elapsedMs = () => Number((process.hrtime.bigint() - startNs) / 1000000n);
83781
83810
  try {
@@ -83799,13 +83828,26 @@ async function scanProjectAtPath(cwd2, config3) {
83799
83828
  };
83800
83829
  }
83801
83830
  const responses = [];
83831
+ let cumulativeDone = 0;
83802
83832
  if (npmPackages.length > 0) {
83803
- const npmResp = await callAnalyzeAPI(npmPackages, config3);
83833
+ const npmOnProgress = onProgress ? (done, _total, currentBatch) => {
83834
+ onProgress({
83835
+ done: cumulativeDone + done,
83836
+ total: totalDiscovered,
83837
+ current: currentBatch ?? []
83838
+ });
83839
+ } : void 0;
83840
+ const npmResp = await callAnalyzeAPI(npmPackages, config3, npmOnProgress);
83804
83841
  responses.push(npmResp);
83842
+ cumulativeDone += npmPackages.length;
83805
83843
  }
83806
83844
  if (pyPackages.length > 0) {
83807
- const pyResp = await callPyPIAnalyzeAPI(pyPackages, config3);
83845
+ const pyOnProgress = onProgress ? (done, _total) => {
83846
+ onProgress({ done: cumulativeDone + done, total: totalDiscovered, current: [] });
83847
+ } : void 0;
83848
+ const pyResp = await callPyPIAnalyzeAPI(pyPackages, config3, pyOnProgress);
83808
83849
  responses.push(pyResp);
83850
+ cumulativeDone += pyPackages.length;
83809
83851
  }
83810
83852
  const allPackages = responses.flatMap((r) => r.packages);
83811
83853
  const maxScore = allPackages.length > 0 ? Math.max(0, ...allPackages.map((p) => p.score)) : 0;
@@ -83882,10 +83924,15 @@ function initialState(dryRun, firstRun) {
83882
83924
  hookError: null,
83883
83925
  scanRan: false,
83884
83926
  scanResult: null,
83927
+ scanProgress: null,
83885
83928
  skipped: /* @__PURE__ */ new Set()
83886
83929
  };
83887
83930
  }
83888
83931
  function reducer(state, action) {
83932
+ if (process.env.DG_DEBUG_WIZARD && action.type !== "scan_progress") {
83933
+ process.stderr.write(`[wizard] action=${action.type} phase=${state.phase}
83934
+ `);
83935
+ }
83889
83936
  switch (action.type) {
83890
83937
  // ── First-run guided tour transitions ──────────────────────────────────
83891
83938
  case "welcome_yes":
@@ -83982,12 +84029,15 @@ function reducer(state, action) {
83982
84029
  skipped
83983
84030
  };
83984
84031
  }
84032
+ case "scan_progress":
84033
+ return { ...state, scanProgress: action.progress };
83985
84034
  case "scan_done":
83986
84035
  return {
83987
84036
  ...state,
83988
84037
  phase: state.firstRun ? "result_first_scan" : "show_app_link",
83989
84038
  scanRan: true,
83990
- scanResult: action.outcome
84039
+ scanResult: action.outcome,
84040
+ scanProgress: null
83991
84041
  };
83992
84042
  case "app_link_acked":
83993
84043
  return { ...state, phase: "done" };
@@ -84101,7 +84151,13 @@ function useInit(opts = {}) {
84101
84151
  const projects = state.projects.length > 0 ? state.projects : [{ path: opts.cwd ?? process.cwd() }];
84102
84152
  const allOutcomes = [];
84103
84153
  for (const proj of projects) {
84104
- const outcome = await scanFn(proj.path, config3);
84154
+ if (process.env.DG_DEBUG_WIZARD) process.stderr.write(`[wizard] scanning ${proj.path}
84155
+ `);
84156
+ const outcome = await scanFn(proj.path, config3, (p) => {
84157
+ dispatch({ type: "scan_progress", progress: p });
84158
+ });
84159
+ if (process.env.DG_DEBUG_WIZARD) process.stderr.write(`[wizard] scan done ${proj.path} status=${outcome.status}
84160
+ `);
84105
84161
  allOutcomes.push(outcome);
84106
84162
  }
84107
84163
  const allPackages = allOutcomes.flatMap(
@@ -86834,13 +86890,93 @@ var init_Spinner = __esm({
86834
86890
  }
86835
86891
  });
86836
86892
 
86893
+ // src/ui/components/ProgressBar.tsx
86894
+ function estimateScanSeconds(packageCount) {
86895
+ return Math.ceil(Math.max(5, packageCount * 0.35 - 10));
86896
+ }
86897
+ function formatTime(seconds) {
86898
+ if (seconds < 60) return `${seconds}s`;
86899
+ const m = Math.floor(seconds / 60);
86900
+ const s = seconds % 60;
86901
+ return s > 0 ? `${m}m ${s}s` : `${m}m`;
86902
+ }
86903
+ var import_react25, import_chalk4, import_jsx_runtime2, ProgressBar;
86904
+ var init_ProgressBar = __esm({
86905
+ async "src/ui/components/ProgressBar.tsx"() {
86906
+ "use strict";
86907
+ import_react25 = __toESM(require_react());
86908
+ await init_build2();
86909
+ await init_build3();
86910
+ import_chalk4 = __toESM(require_source());
86911
+ await init_useTerminalSize();
86912
+ import_jsx_runtime2 = __toESM(require_jsx_runtime());
86913
+ ProgressBar = ({
86914
+ value,
86915
+ total,
86916
+ label
86917
+ }) => {
86918
+ const startRef = (0, import_react25.useRef)(Date.now());
86919
+ const [elapsed, setElapsed] = (0, import_react25.useState)(0);
86920
+ (0, import_react25.useEffect)(() => {
86921
+ const timer = setInterval(() => {
86922
+ setElapsed(Math.floor((Date.now() - startRef.current) / 1e3));
86923
+ }, 1e3);
86924
+ return () => clearInterval(timer);
86925
+ }, []);
86926
+ const { cols: termWidth } = useTerminalSize();
86927
+ const percent = total > 0 ? Math.round(value / total * 100) : 0;
86928
+ const estimate = estimateScanSeconds(total);
86929
+ const timeInfo = `${formatTime(elapsed)} / ~${formatTime(estimate)}`;
86930
+ const counter = `${value}/${total} ${percent}%`;
86931
+ const barWidth = Math.max(10, termWidth - counter.length - 8);
86932
+ const fraction = total > 0 ? Math.min(1, value / total) : 0;
86933
+ const filled = Math.round(fraction * barWidth);
86934
+ const empty = barWidth - filled;
86935
+ const filledBar = "\u2501".repeat(filled);
86936
+ const emptyBar = "\u2501".repeat(empty);
86937
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, children: [
86938
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
86939
+ import_chalk4.default.cyan("\u25C6"),
86940
+ " ",
86941
+ import_chalk4.default.bold("Dependency Guardian")
86942
+ ] }),
86943
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { children: "" }),
86944
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { children: [
86945
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(build_default, { type: "dots" }) }),
86946
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
86947
+ " Scanning ",
86948
+ total,
86949
+ " packages... "
86950
+ ] }),
86951
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: timeInfo })
86952
+ ] }),
86953
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { children: [
86954
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { children: " " }),
86955
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "green", children: filledBar }),
86956
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: emptyBar }),
86957
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
86958
+ " ",
86959
+ counter
86960
+ ] })
86961
+ ] }),
86962
+ label && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { dimColor: true, children: [
86963
+ " ",
86964
+ import_chalk4.default.dim("\u203A"),
86965
+ " ",
86966
+ label
86967
+ ] }) })
86968
+ ] });
86969
+ };
86970
+ }
86971
+ });
86972
+
86837
86973
  // src/ui/components/Mascot.tsx
86838
- var import_jsx_runtime2, FACES, Mascot;
86974
+ var import_jsx_runtime3, FACES, Mascot;
86839
86975
  var init_Mascot = __esm({
86840
86976
  async "src/ui/components/Mascot.tsx"() {
86841
86977
  "use strict";
86842
86978
  await init_build2();
86843
- import_jsx_runtime2 = __toESM(require_jsx_runtime());
86979
+ import_jsx_runtime3 = __toESM(require_jsx_runtime());
86844
86980
  FACES = {
86845
86981
  idle: { left: "o", right: "o", mouth: "^" },
86846
86982
  alert: { left: "O", right: "O", mouth: "^" },
@@ -86864,7 +87000,7 @@ var init_Mascot = __esm({
86864
87000
  " ( ( ) ( ) )",
86865
87001
  "(__(__)___(__)__)"
86866
87002
  ];
86867
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box_default, { flexDirection: "column", children: lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color, children: line }, i)) });
87003
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { flexDirection: "column", children: lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color, children: line }, i)) });
86868
87004
  };
86869
87005
  }
86870
87006
  });
@@ -86933,13 +87069,13 @@ var init_wizard_demo_data = __esm({
86933
87069
  });
86934
87070
 
86935
87071
  // src/ui/components/ScanResultCard.tsx
86936
- var import_jsx_runtime3, ScanResultCard;
87072
+ var import_jsx_runtime4, ScanResultCard;
86937
87073
  var init_ScanResultCard = __esm({
86938
87074
  async "src/ui/components/ScanResultCard.tsx"() {
86939
87075
  "use strict";
86940
87076
  await init_build2();
86941
87077
  init_wizard_demo_data();
86942
- import_jsx_runtime3 = __toESM(require_jsx_runtime());
87078
+ import_jsx_runtime4 = __toESM(require_jsx_runtime());
86943
87079
  ScanResultCard = ({ outcome }) => {
86944
87080
  let verdict;
86945
87081
  let verdictColor;
@@ -86979,63 +87115,63 @@ var init_ScanResultCard = __esm({
86979
87115
  extraNote = `Scan didn't finish: ${o.message ?? "unknown error"}`;
86980
87116
  }
86981
87117
  }
86982
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { flexDirection: "column", children: verdict !== "EMPTY" && packages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
86983
- packages.length === 1 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
86984
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { bold: true, children: packages[0].name }),
86985
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { dimColor: true, children: [
87118
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { flexDirection: "column", children: verdict !== "EMPTY" && packages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
87119
+ packages.length === 1 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { children: [
87120
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { bold: true, children: packages[0].name }),
87121
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { dimColor: true, children: [
86986
87122
  "@",
86987
87123
  packages[0].version
86988
87124
  ] })
86989
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { dimColor: true, children: [
87125
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { dimColor: true, children: [
86990
87126
  packages.length,
86991
87127
  " packages"
86992
87128
  ] }),
86993
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: " " }),
86994
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
86995
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: verdictColor, bold: true, children: verdict }),
86996
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { dimColor: true, children: " \xB7 " }),
86997
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { bold: true, children: [
87129
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { children: " " }),
87130
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { children: [
87131
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: verdictColor, bold: true, children: verdict }),
87132
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { dimColor: true, children: " \xB7 " }),
87133
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { bold: true, children: [
86998
87134
  score,
86999
87135
  "/100"
87000
87136
  ] })
87001
87137
  ] }),
87002
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: " " }),
87003
- packages.length === 1 ? packages[0].findings.slice(0, 3).map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { dimColor: true, children: [
87138
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { children: " " }),
87139
+ packages.length === 1 ? packages[0].findings.slice(0, 3).map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { dimColor: true, children: [
87004
87140
  " \u2022 ",
87005
87141
  friendlyCategory(f.category),
87006
87142
  f.title ? ` \u2014 ${f.title}` : ""
87007
- ] }, `f-${i}`)) : packages.slice(0, 3).map((pkg) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { dimColor: true, children: [
87143
+ ] }, `f-${i}`)) : packages.slice(0, 3).map((pkg) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { dimColor: true, children: [
87008
87144
  " \u2022 ",
87009
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { bold: true, children: pkg.name }),
87145
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { bold: true, children: pkg.name }),
87010
87146
  " ",
87011
87147
  pkg.score,
87012
87148
  "/100"
87013
87149
  ] }, pkg.name)),
87014
- packages.length > 3 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { dimColor: true, children: " + " + (packages.length - 3) + " more" }) : null
87015
- ] }) : verdict !== "EMPTY" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
87016
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: verdictColor, bold: true, children: verdict }),
87017
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { dimColor: true, children: " \xB7 " }),
87018
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { bold: true, children: [
87150
+ packages.length > 3 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { dimColor: true, children: " + " + (packages.length - 3) + " more" }) : null
87151
+ ] }) : verdict !== "EMPTY" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { children: [
87152
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: verdictColor, bold: true, children: verdict }),
87153
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { dimColor: true, children: " \xB7 " }),
87154
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { bold: true, children: [
87019
87155
  score,
87020
87156
  "/100"
87021
87157
  ] })
87022
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { dimColor: true, children: extraNote }) });
87158
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { dimColor: true, children: extraNote }) });
87023
87159
  };
87024
87160
  }
87025
87161
  });
87026
87162
 
87027
87163
  // src/ui/components/DemoScanAnimation.tsx
87028
- var import_react25, import_jsx_runtime4, DemoScanAnimation;
87164
+ var import_react26, import_jsx_runtime5, DemoScanAnimation;
87029
87165
  var init_DemoScanAnimation = __esm({
87030
87166
  async "src/ui/components/DemoScanAnimation.tsx"() {
87031
87167
  "use strict";
87032
- import_react25 = __toESM(require_react());
87168
+ import_react26 = __toESM(require_react());
87033
87169
  await init_Spinner();
87034
87170
  init_wizard_demo_data();
87035
- import_jsx_runtime4 = __toESM(require_jsx_runtime());
87171
+ import_jsx_runtime5 = __toESM(require_jsx_runtime());
87036
87172
  DemoScanAnimation = ({ onComplete }) => {
87037
- const [labelIdx, setLabelIdx] = (0, import_react25.useState)(0);
87038
- (0, import_react25.useEffect)(() => {
87173
+ const [labelIdx, setLabelIdx] = (0, import_react26.useState)(0);
87174
+ (0, import_react26.useEffect)(() => {
87039
87175
  const tickMs = Math.floor(DEMO_SCAN_TOTAL_MS / DEMO_SCAN_LABELS.length);
87040
87176
  const interval = setInterval(() => {
87041
87177
  setLabelIdx((i) => {
@@ -87049,7 +87185,7 @@ var init_DemoScanAnimation = __esm({
87049
87185
  }, tickMs);
87050
87186
  return () => clearInterval(interval);
87051
87187
  }, [onComplete]);
87052
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Spinner2, { label: DEMO_SCAN_LABELS[labelIdx] });
87188
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Spinner2, { label: DEMO_SCAN_LABELS[labelIdx] });
87053
87189
  };
87054
87190
  }
87055
87191
  });
@@ -87082,16 +87218,16 @@ function phaseToStep(phase) {
87082
87218
  return 0;
87083
87219
  }
87084
87220
  }
87085
- var import_jsx_runtime5, TOTAL_STEPS, ProgressDots;
87221
+ var import_jsx_runtime6, TOTAL_STEPS, ProgressDots;
87086
87222
  var init_ProgressDots = __esm({
87087
87223
  async "src/ui/components/ProgressDots.tsx"() {
87088
87224
  "use strict";
87089
87225
  await init_build2();
87090
- import_jsx_runtime5 = __toESM(require_jsx_runtime());
87226
+ import_jsx_runtime6 = __toESM(require_jsx_runtime());
87091
87227
  TOTAL_STEPS = 6;
87092
- ProgressDots = ({ current }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: Array.from({ length: TOTAL_STEPS }).map((_, i) => {
87228
+ ProgressDots = ({ current }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: Array.from({ length: TOTAL_STEPS }).map((_, i) => {
87093
87229
  const filled = i < current;
87094
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: filled ? "green" : void 0, dimColor: !filled, children: filled ? "\u25CF " : "\u25CB " }, i);
87230
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: filled ? "green" : void 0, dimColor: !filled, children: filled ? "\u25CF " : "\u25CB " }, i);
87095
87231
  }) });
87096
87232
  }
87097
87233
  });
@@ -87105,22 +87241,23 @@ import { basename as basename3 } from "node:path";
87105
87241
  function defaultYesNoCursor(phase) {
87106
87242
  return phase === "confirm_wrap" ? 1 : 0;
87107
87243
  }
87108
- var import_react26, import_jsx_runtime6, YES_NO_PHASES, InitApp;
87244
+ var import_react27, import_jsx_runtime7, YES_NO_PHASES, InitApp;
87109
87245
  var init_InitApp = __esm({
87110
87246
  async "src/ui/InitApp.tsx"() {
87111
87247
  "use strict";
87112
- import_react26 = __toESM(require_react());
87248
+ import_react27 = __toESM(require_react());
87113
87249
  await init_build2();
87114
87250
  init_useInit();
87115
87251
  await init_useTerminalSize();
87116
87252
  await init_Spinner();
87253
+ await init_ProgressBar();
87117
87254
  await init_Mascot();
87118
87255
  await init_ScanResultCard();
87119
87256
  await init_DemoScanAnimation();
87120
87257
  await init_ProgressDots();
87121
87258
  init_wizard_demo_data();
87122
87259
  init_sanitize();
87123
- import_jsx_runtime6 = __toESM(require_jsx_runtime());
87260
+ import_jsx_runtime7 = __toESM(require_jsx_runtime());
87124
87261
  YES_NO_PHASES = /* @__PURE__ */ new Set([
87125
87262
  "greet",
87126
87263
  "confirm_hook",
@@ -87137,21 +87274,29 @@ var init_InitApp = __esm({
87137
87274
  const { state, canGoBack: canGoBack2, runDetect, runInstallHook, runVerifyHook, runScan, dispatch } = useInit({ dryRun, firstRun });
87138
87275
  const { exit } = use_app_default();
87139
87276
  useTerminalSize();
87140
- const [yesNoCursor, setYesNoCursor] = (0, import_react26.useState)(defaultYesNoCursor(state.phase));
87141
- (0, import_react26.useEffect)(() => {
87277
+ const [yesNoCursor, setYesNoCursor] = (0, import_react27.useState)(defaultYesNoCursor(state.phase));
87278
+ const prevPhaseRef = (0, import_react27.useRef)(state.phase);
87279
+ const [, forceTick] = (0, import_react27.useState)(0);
87280
+ (0, import_react27.useEffect)(() => {
87281
+ if (prevPhaseRef.current === "run_scan" && state.phase === "result_first_scan") {
87282
+ Promise.resolve().then(() => forceTick((n) => n + 1));
87283
+ }
87284
+ prevPhaseRef.current = state.phase;
87285
+ }, [state.phase]);
87286
+ (0, import_react27.useEffect)(() => {
87142
87287
  if (YES_NO_PHASES.has(state.phase)) {
87143
87288
  setYesNoCursor(defaultYesNoCursor(state.phase));
87144
87289
  }
87145
87290
  }, [state.phase]);
87146
- (0, import_react26.useEffect)(() => {
87291
+ (0, import_react27.useEffect)(() => {
87147
87292
  if (state.phase === "detect") {
87148
87293
  runDetect();
87149
87294
  }
87150
87295
  }, [state.phase, runDetect]);
87151
- (0, import_react26.useEffect)(() => {
87296
+ (0, import_react27.useEffect)(() => {
87152
87297
  if (state.scanRan && onScanRan) onScanRan();
87153
87298
  }, [state.scanRan, onScanRan]);
87154
- (0, import_react26.useEffect)(() => {
87299
+ (0, import_react27.useEffect)(() => {
87155
87300
  if (state.phase === "install_hook") {
87156
87301
  runInstallHook();
87157
87302
  }
@@ -87301,22 +87446,22 @@ var init_InitApp = __esm({
87301
87446
  return;
87302
87447
  }
87303
87448
  });
87304
- const yesNoRow = (yesLabel = "Yes", noLabel = "No") => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { children: [
87305
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { inverse: yesNoCursor === 0, bold: yesNoCursor === 0, color: "green", children: ` ${yesLabel} ` }),
87306
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87307
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { inverse: yesNoCursor === 1, bold: yesNoCursor === 1, color: "red", children: ` ${noLabel} ` })
87449
+ const yesNoRow = (yesLabel = "Yes", noLabel = "No") => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { children: [
87450
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { inverse: yesNoCursor === 0, bold: yesNoCursor === 0, color: "green", children: ` ${yesLabel} ` }),
87451
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87452
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { inverse: yesNoCursor === 1, bold: yesNoCursor === 1, color: "red", children: ` ${noLabel} ` })
87308
87453
  ] });
87309
- const okButton = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { inverse: true, bold: true, color: "green", children: ` OK ` }) });
87454
+ const okButton = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { inverse: true, bold: true, color: "green", children: ` OK ` }) });
87310
87455
  const isYesNo = YES_NO_PHASES.has(state.phase);
87311
- const stepHint = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { dimColor: true, children: [
87456
+ const stepHint = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
87312
87457
  isYesNo ? "\u2190 \u2192 choose \xB7 Enter confirm \xB7 " : "",
87313
87458
  canGoBack2 ? "[b] back \xB7 " : "",
87314
87459
  "[s] skip \xB7 [q] quit"
87315
87460
  ] }) });
87316
87461
  const currentStep = phaseToStep(state.phase);
87317
- const Scene = (props) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "row", paddingTop: 1, children: [
87318
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { flexDirection: "column", marginRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Mascot, { mood: props.mood, color: props.color }) }),
87319
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
87462
+ const Scene = (props) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "row", paddingTop: 1, children: [
87463
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { flexDirection: "column", marginRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Mascot, { mood: props.mood, color: props.color }) }),
87464
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
87320
87465
  Box_default,
87321
87466
  {
87322
87467
  flexDirection: "column",
@@ -87326,8 +87471,8 @@ var init_InitApp = __esm({
87326
87471
  paddingY: 0,
87327
87472
  flexGrow: 1,
87328
87473
  children: [
87329
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProgressDots, { current: currentStep }),
87330
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87474
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProgressDots, { current: currentStep }),
87475
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87331
87476
  props.children
87332
87477
  ]
87333
87478
  }
@@ -87349,60 +87494,60 @@ var init_InitApp = __esm({
87349
87494
  })();
87350
87495
  switch (state.phase) {
87351
87496
  case "greet":
87352
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Scene, { mood: "happy", color: "green", children: [
87353
- returning ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87497
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Scene, { mood: "happy", color: "green", children: [
87498
+ returning ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87354
87499
  "Hey, welcome back \u{1F44B} I'm ",
87355
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "green", children: "Dependency Guardian" }),
87500
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "green", children: "Dependency Guardian" }),
87356
87501
  "."
87357
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87502
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87358
87503
  "Hey \u{1F44B} I'm ",
87359
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "green", children: "Dependency Guardian" }),
87504
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "green", children: "Dependency Guardian" }),
87360
87505
  "."
87361
87506
  ] }),
87362
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87363
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "I watch the code that gets added to your project" }),
87364
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "so bad stuff doesn't sneak in." }),
87365
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87366
- returning ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "Want a refresher? Takes about a minute." }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
87367
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "Looks like it's your first time here." }),
87368
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "Want me to show you around? Takes about a minute." })
87507
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87508
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "I watch the code that gets added to your project" }),
87509
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "so bad stuff doesn't sneak in." }),
87510
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87511
+ returning ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Want a refresher? Takes about a minute." }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
87512
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Looks like it's your first time here." }),
87513
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Want me to show you around? Takes about a minute." })
87369
87514
  ] }),
87370
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87515
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87371
87516
  yesNoRow("Yes", "I know what I'm doing"),
87372
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: "\u2190 \u2192 choose \xB7 Enter confirm \xB7 [q] quit anytime" }) })
87517
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: "\u2190 \u2192 choose \xB7 Enter confirm \xB7 [q] quit anytime" }) })
87373
87518
  ] });
87374
87519
  case "value_prop":
87375
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Scene, { mood: "worried", color: "yellow", children: [
87376
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87520
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Scene, { mood: "worried", color: "yellow", children: [
87521
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87377
87522
  "In ",
87378
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "2025-2026" }),
87523
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "2025-2026" }),
87379
87524
  ", over ",
87380
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "50,000" }),
87525
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "50,000" }),
87381
87526
  " packages on"
87382
87527
  ] }),
87383
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87384
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "npm" }),
87528
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87529
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "npm" }),
87385
87530
  " and ",
87386
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "PyPI" }),
87531
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "PyPI" }),
87387
87532
  " have been caught doing bad"
87388
87533
  ] }),
87389
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "things \u2014 stealing passwords, mining crypto," }),
87390
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "installing backdoors." }),
87391
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87392
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: "I scan both today, with 20+ more languages planned." }),
87393
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87394
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "Want to see me catch one in the act?" }),
87395
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87534
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "things \u2014 stealing passwords, mining crypto," }),
87535
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "installing backdoors." }),
87536
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87537
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: "I scan both today, with 20+ more languages planned." }),
87538
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87539
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Want to see me catch one in the act?" }),
87540
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87396
87541
  okButton,
87397
87542
  stepHint
87398
87543
  ] });
87399
87544
  case "demo_scanning":
87400
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Scene, { mood: "scanning", color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DemoScanAnimation, { onComplete: () => dispatch({ type: "demo_complete" }) }) });
87545
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Scene, { mood: "scanning", color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DemoScanAnimation, { onComplete: () => dispatch({ type: "demo_complete" }) }) });
87401
87546
  case "demo_result":
87402
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Scene, { mood: "alarmed", color: "red", children: [
87403
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "red", children: "Got one." }),
87404
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87405
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
87547
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Scene, { mood: "alarmed", color: "red", children: [
87548
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "red", children: "Got one." }),
87549
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87550
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
87406
87551
  ScanResultCard,
87407
87552
  {
87408
87553
  outcome: {
@@ -87413,200 +87558,205 @@ var init_InitApp = __esm({
87413
87558
  }
87414
87559
  }
87415
87560
  ),
87416
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87417
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "yellow", bold: true, children: "This one's fake. The next one won't be." }),
87418
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87561
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87562
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "yellow", bold: true, children: "This one's fake. The next one won't be." }),
87563
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87419
87564
  okButton,
87420
87565
  stepHint
87421
87566
  ] });
87422
87567
  case "scenario":
87423
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Scene, { mood: "explaining", color: "cyan", children: [
87424
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87568
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Scene, { mood: "explaining", color: "cyan", children: [
87569
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87425
87570
  "Here's the situation in ",
87426
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: projectName }),
87571
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: projectName }),
87427
87572
  "."
87428
87573
  ] }),
87429
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87430
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: 'npm packages can ship "install scripts" \u2014 code that' }),
87431
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87574
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87575
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: 'npm packages can ship "install scripts" \u2014 code that' }),
87576
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87432
87577
  "runs the moment you ",
87433
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "npm install" }),
87578
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "npm install" }),
87434
87579
  " them."
87435
87580
  ] }),
87436
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87437
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87581
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87582
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87438
87583
  "To catch that, use ",
87439
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: "dg npm install" }),
87584
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: "dg npm install" }),
87440
87585
  " or"
87441
87586
  ] }),
87442
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87443
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: "dg pip install" }),
87587
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87588
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: "dg pip install" }),
87444
87589
  " instead of the normal command."
87445
87590
  ] }),
87446
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "I scan the package first, before any code runs" }),
87447
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "on your machine." }),
87448
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87449
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "I can also add a safety net to git so nothing" }),
87450
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "slips through at commit time." }),
87451
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87591
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "I scan the package first, before any code runs" }),
87592
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "on your machine." }),
87593
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87594
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "I can also add a safety net to git so nothing" }),
87595
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "slips through at commit time." }),
87596
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87452
87597
  okButton,
87453
87598
  stepHint
87454
87599
  ] });
87455
87600
  case "detect":
87456
87601
  if (!state.firstRun) {
87457
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
87458
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "green", children: "Dependency Guardian" }),
87459
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: "Looking around..." })
87602
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
87603
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "green", children: "Dependency Guardian" }),
87604
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: "Looking around..." })
87460
87605
  ] });
87461
87606
  }
87462
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Scene, { mood: "scanning", color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Spinner2, { label: "Looking around..." }) });
87607
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Scene, { mood: "scanning", color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Spinner2, { label: "Looking around..." }) });
87463
87608
  case "confirm_hook":
87464
- if (!state.hookInfo) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "..." });
87609
+ if (!state.hookInfo) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "..." });
87465
87610
  if (state.hookInfo.alreadyInstalled) {
87466
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Scene, { mood: "happy", color: "green", children: [
87467
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "green", children: "Looks like you already did this step." }),
87468
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87469
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "The pre-commit hook is already installed in" }),
87470
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87471
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: hookTargetFile }),
87611
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Scene, { mood: "happy", color: "green", children: [
87612
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "green", children: "Looks like you already did this step." }),
87613
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87614
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "The pre-commit hook is already installed in" }),
87615
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87616
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: hookTargetFile }),
87472
87617
  "."
87473
87618
  ] }),
87474
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87475
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "Every commit that adds a package gets scanned." }),
87476
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87619
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87620
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Every commit that adds a package gets scanned." }),
87621
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87477
87622
  okButton,
87478
87623
  stepHint
87479
87624
  ] });
87480
87625
  }
87481
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Scene, { mood: "curious", color: "green", children: [
87482
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "Git can run a safety check before each commit." }),
87483
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "I'd add my scan to that check \u2014 one line of code." }),
87484
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87485
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "After that, every commit that adds a package" }),
87486
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "gets scanned first. If I find malware, the" }),
87487
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "commit stops before your code ships anywhere." }),
87488
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87489
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "Want me to set it up?" }),
87490
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87626
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Scene, { mood: "curious", color: "green", children: [
87627
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Git can run a safety check before each commit." }),
87628
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "I'd add my scan to that check \u2014 one line of code." }),
87629
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87630
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "After that, every commit that adds a package" }),
87631
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "gets scanned first. If I find malware, the" }),
87632
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "commit stops before your code ships anywhere." }),
87633
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87634
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Want me to set it up?" }),
87635
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87491
87636
  yesNoRow("Yes", "No"),
87492
87637
  stepHint
87493
87638
  ] });
87494
87639
  case "install_hook":
87495
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Scene, { mood: "scanning", color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Spinner2, { label: "Adding the hook..." }) });
87640
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Scene, { mood: "scanning", color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Spinner2, { label: "Adding the hook..." }) });
87496
87641
  case "verify_hook":
87497
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Scene, { mood: "scanning", color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Spinner2, { label: "Testing it..." }) });
87642
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Scene, { mood: "scanning", color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Spinner2, { label: "Testing it..." }) });
87498
87643
  case "confirm_wrap":
87499
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Scene, { mood: state.hookError ? "alert" : "happy", color: state.hookError ? "yellow" : "green", children: [
87500
- state.hookVerifyMs !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { color: "green", children: [
87644
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Scene, { mood: state.hookError ? "alert" : "happy", color: state.hookError ? "yellow" : "green", children: [
87645
+ state.hookVerifyMs !== null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "green", children: [
87501
87646
  "\u2713 Hook works. ",
87502
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { bold: true, children: [
87647
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { bold: true, children: [
87503
87648
  state.hookVerifyMs,
87504
87649
  "ms"
87505
87650
  ] }),
87506
87651
  "."
87507
87652
  ] }) : null,
87508
- state.hookError ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { color: "yellow", children: [
87653
+ state.hookError ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
87509
87654
  "\u26A0 ",
87510
87655
  state.hookError
87511
87656
  ] }) : null,
87512
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87513
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { dimColor: true, children: [
87657
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87658
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
87514
87659
  "I can also catch packages at ",
87515
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "npm install" }),
87660
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "npm install" }),
87516
87661
  " time, before"
87517
87662
  ] }),
87518
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: "they hit your package.json. Adds one line to your shell config." }),
87519
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87520
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "Want it?" }),
87521
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87663
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: "they hit your package.json. Adds one line to your shell config." }),
87664
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87665
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Want it?" }),
87666
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87522
87667
  yesNoRow(),
87523
87668
  stepHint
87524
87669
  ] });
87525
87670
  case "confirm_scan":
87526
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Scene, { mood: "happy", color: "green", children: [
87527
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87671
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Scene, { mood: "happy", color: "green", children: [
87672
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87528
87673
  "Can I scan ",
87529
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: projectName }),
87674
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: projectName }),
87530
87675
  " now?"
87531
87676
  ] }),
87532
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87533
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "I'll check what's already installed and show" }),
87534
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "you what I see." }),
87535
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87677
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87678
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "I'll check what's already installed and show" }),
87679
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "you what I see." }),
87680
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87536
87681
  yesNoRow("Scan", "Skip"),
87537
87682
  stepHint
87538
87683
  ] });
87539
- case "run_scan":
87540
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Scene, { mood: "scanning", color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Spinner2, { label: "Looking..." }) });
87684
+ case "run_scan": {
87685
+ const p = state.scanProgress;
87686
+ if (p && p.total > 0) {
87687
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProgressBar, { value: p.done, total: p.total });
87688
+ }
87689
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Scene, { mood: "scanning", color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Spinner2, { label: "Scanning..." }) });
87690
+ }
87541
87691
  case "result_first_scan": {
87542
87692
  const r = state.scanResult;
87543
87693
  const okScan = r?.status === "ok" && r.result;
87544
87694
  const empty = r?.status === "no_packages";
87545
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Scene, { mood: resultMood, color: resultMood === "alarmed" ? "red" : resultMood === "alert" ? "yellow" : "green", children: [
87546
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "Done." }),
87547
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87548
- okScan ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87695
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Scene, { mood: resultMood, color: resultMood === "alarmed" ? "red" : resultMood === "alert" ? "yellow" : "green", children: [
87696
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "Done." }),
87697
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87698
+ okScan ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87549
87699
  "I scanned ",
87550
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: projectName }),
87700
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: projectName }),
87551
87701
  "."
87552
- ] }) : empty ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87702
+ ] }) : empty ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87553
87703
  "I didn't find any packages to scan in ",
87554
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: projectName }),
87704
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: projectName }),
87555
87705
  "."
87556
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87706
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87557
87707
  "I tried to scan ",
87558
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: projectName }),
87708
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: projectName }),
87559
87709
  " but ran into a snag."
87560
87710
  ] }),
87561
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87562
- state.scanResult ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ScanResultCard, { outcome: { kind: "real", outcome: state.scanResult } }) : null,
87563
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87564
- okScan && resultMood === "happy" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "green", children: "You're already in good shape." }) : null,
87565
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87711
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87712
+ state.scanResult ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ScanResultCard, { outcome: { kind: "real", outcome: state.scanResult } }) : null,
87713
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87714
+ okScan && resultMood === "happy" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "green", children: "You're already in good shape." }) : null,
87715
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87566
87716
  okButton,
87567
87717
  stepHint
87568
87718
  ] });
87569
87719
  }
87570
87720
  case "what_happens_next":
87571
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Scene, { mood: "explaining", color: "cyan", children: [
87572
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "What happens from here." }),
87573
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87574
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "You commit normally. If I find nothing, you" }),
87575
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "won't even see me \u2014 the commit just goes through." }),
87576
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87577
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "If I find something bad, you'll see a card like" }),
87578
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "the demo I showed you. Read it. If it's a real" }),
87579
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "threat, investigate." }),
87580
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87581
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87721
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Scene, { mood: "explaining", color: "cyan", children: [
87722
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "What happens from here." }),
87723
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87724
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "You commit normally. If I find nothing, you" }),
87725
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "won't even see me \u2014 the commit just goes through." }),
87726
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87727
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "If I find something bad, you'll see a card like" }),
87728
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "the demo I showed you. Read it. If it's a real" }),
87729
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "threat, investigate." }),
87730
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87731
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87582
87732
  "If it's a false alarm, just add ",
87583
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: "--no-verify" }),
87733
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: "--no-verify" }),
87584
87734
  ":"
87585
87735
  ] }),
87586
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87736
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87587
87737
  " ",
87588
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: 'git commit -m "your message" --no-verify' })
87738
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: 'git commit -m "your message" --no-verify' })
87589
87739
  ] }),
87590
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87591
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "I won't be offended." }),
87592
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87740
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87741
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "I won't be offended." }),
87742
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87593
87743
  okButton,
87594
87744
  stepHint
87595
87745
  ] });
87596
87746
  case "pitch_app":
87597
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Scene, { mood: "idle", color: "green", children: [
87598
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: "One last thing." }),
87599
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87600
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "I'm watching your laptop. For your team," }),
87601
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "there's a GitHub App that watches every pull" }),
87602
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "request the same way. Optional \u2014 install it" }),
87603
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "whenever:" }),
87604
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87605
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87747
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Scene, { mood: "idle", color: "green", children: [
87748
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: "One last thing." }),
87749
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87750
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "I'm watching your laptop. For your team," }),
87751
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "there's a GitHub App that watches every pull" }),
87752
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "request the same way. Optional \u2014 install it" }),
87753
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "whenever:" }),
87754
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87755
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87606
87756
  " ",
87607
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: "https://github.com/apps/dependency-guardian" })
87757
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: "https://github.com/apps/dependency-guardian" })
87608
87758
  ] }),
87609
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87759
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87610
87760
  okButton,
87611
87761
  stepHint
87612
87762
  ] });
@@ -87619,7 +87769,7 @@ var init_InitApp = __esm({
87619
87769
  const verdict = r.action === "block" ? "BLOCKED" : r.action === "warn" ? "WARNING" : "PASSED";
87620
87770
  const color = r.action === "block" ? "red" : r.action === "warn" ? "yellow" : "green";
87621
87771
  scanLine.push(
87622
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { color, children: [
87772
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color, children: [
87623
87773
  "\u2713 Scanned ",
87624
87774
  scan.result.scannedCount,
87625
87775
  " package",
@@ -87634,136 +87784,136 @@ var init_InitApp = __esm({
87634
87784
  ] }, "scan-summary")
87635
87785
  );
87636
87786
  } else if (scan.status === "no_packages") {
87637
- scanLine.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { dimColor: true, children: [
87787
+ scanLine.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
87638
87788
  "\u2713 Scan ran \u2014 nothing to check yet (",
87639
87789
  scan.result?.durationMs ?? 0,
87640
87790
  "ms)"
87641
87791
  ] }, "scan-empty"));
87642
87792
  } else if (scan.status === "trial_exhausted") {
87643
- scanLine.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "yellow", children: "\u26A0 Free trial scans used up \u2014 `dg login` to continue" }, "scan-trial"));
87793
+ scanLine.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "yellow", children: "\u26A0 Free trial scans used up \u2014 `dg login` to continue" }, "scan-trial"));
87644
87794
  } else if (scan.status === "error") {
87645
- scanLine.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { color: "yellow", children: [
87795
+ scanLine.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
87646
87796
  "\u26A0 Scan didn't finish: ",
87647
87797
  scan.message
87648
87798
  ] }, "scan-err"));
87649
87799
  }
87650
- scanLine.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }, "sp"));
87800
+ scanLine.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }, "sp"));
87651
87801
  }
87652
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
87653
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "green", children: "Server-side coverage (optional)" }),
87654
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87802
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
87803
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "green", children: "Server-side coverage (optional)" }),
87804
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87655
87805
  scanLine,
87656
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: "The CLI protects you on this laptop. Install the GitHub App" }),
87657
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: "too for server-side scanning on every PR." }),
87658
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87659
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "cyan", children: "https://github.com/apps/dependency-guardian/installations/new" }),
87660
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87661
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: "Press Enter to continue." }),
87806
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: "The CLI protects you on this laptop. Install the GitHub App" }),
87807
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: "too for server-side scanning on every PR." }),
87808
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87809
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "cyan", children: "https://github.com/apps/dependency-guardian/installations/new" }),
87810
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87811
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: "Press Enter to continue." }),
87662
87812
  stepHint
87663
87813
  ] });
87664
87814
  }
87665
87815
  case "done": {
87666
87816
  const lines = [];
87667
87817
  if (state.firstRun && state.skipped.has("scenario") && state.engaged) {
87668
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Scene, { mood: "wink", color: "cyan", children: [
87669
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "No worries." }),
87670
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87671
- returning ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87818
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Scene, { mood: "wink", color: "cyan", children: [
87819
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "No worries." }),
87820
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87821
+ returning ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87672
87822
  "Catch you later. ",
87673
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: "dg kitty" }),
87823
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: "dg kitty" }),
87674
87824
  " any time."
87675
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
87676
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: "Running your command now. If you change your" }),
87677
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87825
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
87826
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Running your command now. If you change your" }),
87827
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87678
87828
  "mind later, ",
87679
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: "dg kitty" }),
87829
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: "dg kitty" }),
87680
87830
  " brings me back."
87681
87831
  ] })
87682
87832
  ] }),
87683
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }),
87833
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
87684
87834
  okButton
87685
87835
  ] });
87686
87836
  }
87687
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "green", children: "You're set." }, "header"));
87688
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }, "sp1"));
87837
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "green", children: "You're set." }, "header"));
87838
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }, "sp1"));
87689
87839
  if (state.hookInstalled && !state.skipped.has("install_hook")) {
87690
87840
  lines.push(
87691
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87841
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87692
87842
  " ",
87693
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "green", children: "\u2713" }),
87843
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "green", children: "\u2713" }),
87694
87844
  " I'm running on every commit"
87695
87845
  ] }, "hook")
87696
87846
  );
87697
87847
  } else {
87698
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: " \u25CB Hook (skipped)" }, "hook"));
87848
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " \u25CB Hook (skipped)" }, "hook"));
87699
87849
  }
87700
87850
  if (state.scanRan && state.scanResult) {
87701
87851
  const scan = state.scanResult;
87702
87852
  if (scan.status === "ok" && scan.result) {
87703
87853
  const r = scan.result.result;
87704
- const tail = r.action === "block" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "red", bold: true, children: "found something to block" }) : r.action === "warn" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "yellow", bold: true, children: "flagged a few things" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "green", children: "all clean" });
87854
+ const tail = r.action === "block" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "red", bold: true, children: "found something to block" }) : r.action === "warn" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "yellow", bold: true, children: "flagged a few things" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "green", children: "all clean" });
87705
87855
  lines.push(
87706
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87856
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87707
87857
  " ",
87708
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "green", children: "\u2713" }),
87858
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "green", children: "\u2713" }),
87709
87859
  " Scanned ",
87710
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, children: scan.result.scannedCount }),
87860
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, children: scan.result.scannedCount }),
87711
87861
  " packages \u2014 ",
87712
87862
  tail
87713
87863
  ] }, "scan")
87714
87864
  );
87715
87865
  } else if (scan.status === "no_packages") {
87716
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: " \u25CB Nothing to scan yet" }, "scan"));
87866
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " \u25CB Nothing to scan yet" }, "scan"));
87717
87867
  } else {
87718
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { color: "yellow", children: [
87868
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
87719
87869
  " \u26A0 ",
87720
87870
  scan.message ?? "scan didn't finish"
87721
87871
  ] }, "scan"));
87722
87872
  }
87723
87873
  } else if (state.skipped.has("run_scan")) {
87724
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { dimColor: true, children: " \u25CB First scan (skipped)" }, "scan"));
87874
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: " \u25CB First scan (skipped)" }, "scan"));
87725
87875
  }
87726
87876
  lines.push(
87727
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87877
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87728
87878
  " ",
87729
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "green", children: "\u2713" }),
87879
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "green", children: "\u2713" }),
87730
87880
  " You know how to bypass me if I'm wrong"
87731
87881
  ] }, "bypass")
87732
87882
  );
87733
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }, "sp2"));
87734
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87883
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }, "sp2"));
87884
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87735
87885
  "Forget anything? ",
87736
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: "dg kitty" }),
87886
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: "dg kitty" }),
87737
87887
  " brings me back."
87738
87888
  ] }, "kitty"));
87739
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87889
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87740
87890
  "Full command list: ",
87741
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: "dg help" })
87891
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: "dg help" })
87742
87892
  ] }, "help"));
87743
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
87893
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
87744
87894
  "Curious about more? ",
87745
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "cyan", children: "https://westbayberry.com/docs" })
87895
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "cyan", children: "https://westbayberry.com/docs" })
87746
87896
  ] }, "docs"));
87747
87897
  if (state.hookError) {
87748
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }, "sp3"));
87749
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { color: "yellow", children: [
87898
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }, "sp3"));
87899
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
87750
87900
  "Note: ",
87751
87901
  state.hookError
87752
87902
  ] }, "err"));
87753
87903
  }
87754
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }, "sp4"));
87755
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { bold: true, color: "green", children: "Build fast, don't get hacked." }, "signoff"));
87904
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }, "sp4"));
87905
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { bold: true, color: "green", children: "Build fast, don't get hacked." }, "signoff"));
87756
87906
  if (state.dryRun) {
87757
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "yellow", children: "(dry run \u2014 no files were modified)" }, "dry"));
87907
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "yellow", children: "(dry run \u2014 no files were modified)" }, "dry"));
87758
87908
  }
87759
- lines.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }, "sp5"));
87909
+ lines.push(/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }, "sp5"));
87760
87910
  lines.push(
87761
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { inverse: true, bold: true, color: "green", children: ` OK ` }) }, "ok-btn")
87911
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { inverse: true, bold: true, color: "green", children: ` OK ` }) }, "ok-btn")
87762
87912
  );
87763
87913
  if (!state.firstRun) {
87764
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { flexDirection: "column", paddingLeft: 1, children: lines });
87914
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { flexDirection: "column", paddingLeft: 1, children: lines });
87765
87915
  }
87766
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Scene, { mood: state.hookError ? "worried" : "proud", color: state.hookError ? "yellow" : "green", children: lines });
87916
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Scene, { mood: state.hookError ? "worried" : "proud", color: state.hookError ? "yellow" : "green", children: lines });
87767
87917
  }
87768
87918
  }
87769
87919
  };
@@ -87786,19 +87936,25 @@ async function maybeOfferFirstRunWizard(opts) {
87786
87936
  const { render: render2 } = await init_build2().then(() => build_exports);
87787
87937
  const React21 = await Promise.resolve().then(() => __toESM(require_react()));
87788
87938
  const { InitApp: InitApp2 } = await init_InitApp().then(() => InitApp_exports);
87789
- const { waitUntilExit } = render2(
87790
- React21.createElement(InitApp2, {
87791
- firstRun: true,
87792
- onReachedDone: () => {
87793
- reachedDone = true;
87794
- },
87795
- onScanRan: () => {
87796
- scanRanInWizard = true;
87797
- }
87798
- })
87799
- );
87800
- mounted = true;
87801
- await waitUntilExit();
87939
+ const { enterAltScreen: enterAltScreen2, leaveAltScreen: leaveAltScreen2 } = await Promise.resolve().then(() => (init_alt_screen(), alt_screen_exports));
87940
+ enterAltScreen2();
87941
+ try {
87942
+ const { waitUntilExit } = render2(
87943
+ React21.createElement(InitApp2, {
87944
+ firstRun: true,
87945
+ onReachedDone: () => {
87946
+ reachedDone = true;
87947
+ },
87948
+ onScanRan: () => {
87949
+ scanRanInWizard = true;
87950
+ }
87951
+ })
87952
+ );
87953
+ mounted = true;
87954
+ await waitUntilExit();
87955
+ } finally {
87956
+ leaveAltScreen2();
87957
+ }
87802
87958
  } catch {
87803
87959
  return;
87804
87960
  }
@@ -87850,11 +88006,11 @@ function reducer2(state, action) {
87850
88006
  }
87851
88007
  }
87852
88008
  function useLogin() {
87853
- const [state, dispatch] = (0, import_react27.useReducer)(reducer2, { phase: "creating" });
87854
- const started = (0, import_react27.useRef)(false);
87855
- const sessionRef = (0, import_react27.useRef)(null);
87856
- const cancelledRef = (0, import_react27.useRef)(false);
87857
- (0, import_react27.useEffect)(() => {
88009
+ const [state, dispatch] = (0, import_react28.useReducer)(reducer2, { phase: "creating" });
88010
+ const started = (0, import_react28.useRef)(false);
88011
+ const sessionRef = (0, import_react28.useRef)(null);
88012
+ const cancelledRef = (0, import_react28.useRef)(false);
88013
+ (0, import_react28.useEffect)(() => {
87858
88014
  if (started.current) return;
87859
88015
  started.current = true;
87860
88016
  (async () => {
@@ -87898,7 +88054,7 @@ function useLogin() {
87898
88054
  cancelledRef.current = true;
87899
88055
  };
87900
88056
  }, []);
87901
- const openAndPoll = (0, import_react27.useCallback)(() => {
88057
+ const openAndPoll = (0, import_react28.useCallback)(() => {
87902
88058
  const session = sessionRef.current;
87903
88059
  if (!session) return;
87904
88060
  dispatch({ type: "BROWSER_OPENED" });
@@ -87934,11 +88090,11 @@ function useLogin() {
87934
88090
  }, []);
87935
88091
  return { state, openAndPoll };
87936
88092
  }
87937
- var import_react27, POLL_INTERVAL_MS, MAX_POLL_ATTEMPTS;
88093
+ var import_react28, POLL_INTERVAL_MS, MAX_POLL_ATTEMPTS;
87938
88094
  var init_useLogin = __esm({
87939
88095
  "src/ui/hooks/useLogin.ts"() {
87940
88096
  "use strict";
87941
- import_react27 = __toESM(require_react());
88097
+ import_react28 = __toESM(require_react());
87942
88098
  init_auth();
87943
88099
  POLL_INTERVAL_MS = 2e3;
87944
88100
  MAX_POLL_ATTEMPTS = 150;
@@ -87950,19 +88106,19 @@ var LoginApp_exports = {};
87950
88106
  __export(LoginApp_exports, {
87951
88107
  LoginApp: () => LoginApp
87952
88108
  });
87953
- var import_react28, import_jsx_runtime7, LoginApp;
88109
+ var import_react29, import_jsx_runtime8, LoginApp;
87954
88110
  var init_LoginApp = __esm({
87955
88111
  async "src/ui/LoginApp.tsx"() {
87956
88112
  "use strict";
87957
- import_react28 = __toESM(require_react());
88113
+ import_react29 = __toESM(require_react());
87958
88114
  await init_build2();
87959
88115
  init_useLogin();
87960
88116
  await init_Spinner();
87961
- import_jsx_runtime7 = __toESM(require_jsx_runtime());
88117
+ import_jsx_runtime8 = __toESM(require_jsx_runtime());
87962
88118
  LoginApp = () => {
87963
88119
  const { state, openAndPoll } = useLogin();
87964
88120
  const { exit } = use_app_default();
87965
- (0, import_react28.useEffect)(() => {
88121
+ (0, import_react29.useEffect)(() => {
87966
88122
  if (state.phase === "success") {
87967
88123
  process.exitCode = 0;
87968
88124
  const timer = setTimeout(() => exit(), 0);
@@ -87986,60 +88142,60 @@ var init_LoginApp = __esm({
87986
88142
  });
87987
88143
  switch (state.phase) {
87988
88144
  case "creating":
87989
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Spinner2, { label: "Creating login session..." });
88145
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Spinner2, { label: "Creating login session..." });
87990
88146
  case "already_logged_in":
87991
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
87992
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "yellow", children: "Already authenticated." }),
87993
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
88147
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88148
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "yellow", children: "Already authenticated." }),
88149
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { dimColor: true, children: [
87994
88150
  "Run ",
87995
88151
  "`dg logout`",
87996
88152
  " first to re-authenticate."
87997
88153
  ] })
87998
88154
  ] });
87999
88155
  case "ready":
88000
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88001
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
88002
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Authenticate your account at:" }),
88003
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "cyan", children: state.verifyUrl }),
88004
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
88005
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: "Press ENTER to open in the browser..." })
88156
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88157
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: " " }),
88158
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: "Authenticate your account at:" }),
88159
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "cyan", children: state.verifyUrl }),
88160
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: " " }),
88161
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { dimColor: true, children: "Press ENTER to open in the browser..." })
88006
88162
  ] });
88007
88163
  case "waiting":
88008
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88009
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
88010
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Authenticate your account at:" }),
88011
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "cyan", children: state.verifyUrl }),
88012
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
88013
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Spinner2, { label: "Waiting for authorization..." })
88164
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88165
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: " " }),
88166
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: "Authenticate your account at:" }),
88167
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "cyan", children: state.verifyUrl }),
88168
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: " " }),
88169
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Spinner2, { label: "Waiting for authorization..." })
88014
88170
  ] });
88015
88171
  case "success":
88016
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88017
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
88018
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "green", bold: true, children: [
88172
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88173
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: " " }),
88174
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { color: "green", bold: true, children: [
88019
88175
  "Logged in as ",
88020
88176
  state.email
88021
88177
  ] }),
88022
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: "Credentials saved." }),
88023
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
88024
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { children: [
88178
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { dimColor: true, children: "Credentials saved." }),
88179
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: " " }),
88180
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { children: [
88025
88181
  "Run ",
88026
88182
  "`dg scan`",
88027
88183
  " to scan your dependencies."
88028
88184
  ] })
88029
88185
  ] });
88030
88186
  case "expired":
88031
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88032
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "yellow", children: "Session expired." }),
88033
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
88187
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88188
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "yellow", children: "Session expired." }),
88189
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { dimColor: true, children: [
88034
88190
  "Run ",
88035
88191
  "`dg login`",
88036
88192
  " to try again."
88037
88193
  ] })
88038
88194
  ] });
88039
88195
  case "error":
88040
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88041
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "red", bold: true, children: "Error: " }),
88042
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "red", children: state.message })
88196
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88197
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "red", bold: true, children: "Error: " }),
88198
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: "red", children: state.message })
88043
88199
  ] });
88044
88200
  }
88045
88201
  };
@@ -88302,14 +88458,14 @@ function reducer3(state, action) {
88302
88458
  return { ...state, error: action.error };
88303
88459
  }
88304
88460
  }
88305
- var import_react29, import_chalk4, import_jsx_runtime8, VISIBLE_ROWS, FileSavePrompt;
88461
+ var import_react30, import_chalk5, import_jsx_runtime9, VISIBLE_ROWS, FileSavePrompt;
88306
88462
  var init_FileSavePrompt = __esm({
88307
88463
  async "src/ui/components/FileSavePrompt.tsx"() {
88308
88464
  "use strict";
88309
- import_react29 = __toESM(require_react());
88465
+ import_react30 = __toESM(require_react());
88310
88466
  await init_build2();
88311
- import_chalk4 = __toESM(require_source());
88312
- import_jsx_runtime8 = __toESM(require_jsx_runtime());
88467
+ import_chalk5 = __toESM(require_source());
88468
+ import_jsx_runtime9 = __toESM(require_jsx_runtime());
88313
88469
  VISIBLE_ROWS = 15;
88314
88470
  FileSavePrompt = ({
88315
88471
  defaultName,
@@ -88321,8 +88477,8 @@ var init_FileSavePrompt = __esm({
88321
88477
  onSaved,
88322
88478
  onCancel
88323
88479
  }) => {
88324
- const initialEntries = (0, import_react29.useMemo)(() => listDirectory(initialDir), [initialDir]);
88325
- const [state, dispatch] = (0, import_react29.useReducer)(reducer3, {
88480
+ const initialEntries = (0, import_react30.useMemo)(() => listDirectory(initialDir), [initialDir]);
88481
+ const [state, dispatch] = (0, import_react30.useReducer)(reducer3, {
88326
88482
  filename: defaultName,
88327
88483
  cursorPos: defaultName.length,
88328
88484
  directory: initialDir,
@@ -88334,7 +88490,7 @@ var init_FileSavePrompt = __esm({
88334
88490
  confirmOverwrite: false,
88335
88491
  error: null
88336
88492
  });
88337
- const filteredEntries = (0, import_react29.useMemo)(() => {
88493
+ const filteredEntries = (0, import_react30.useMemo)(() => {
88338
88494
  const dirs = state.entries.filter((e) => e.isDirectory);
88339
88495
  if (!state.filterText) return dirs;
88340
88496
  const q = state.filterText.toLowerCase();
@@ -88427,86 +88583,86 @@ var init_FileSavePrompt = __esm({
88427
88583
  dispatch({ type: "FILTER", text: state.filterText + input });
88428
88584
  }
88429
88585
  });
88430
- const actionColor2 = scanAction === "block" ? import_chalk4.default.red : scanAction === "warn" ? import_chalk4.default.yellow : import_chalk4.default.green;
88431
- const filenameDisplay = state.filename.slice(0, state.cursorPos) + (state.focus === "filename" ? import_chalk4.default.inverse(state.filename[state.cursorPos] || " ") : "") + state.filename.slice(state.cursorPos + 1);
88586
+ const actionColor2 = scanAction === "block" ? import_chalk5.default.red : scanAction === "warn" ? import_chalk5.default.yellow : import_chalk5.default.green;
88587
+ const filenameDisplay = state.filename.slice(0, state.cursorPos) + (state.focus === "filename" ? import_chalk5.default.inverse(state.filename[state.cursorPos] || " ") : "") + state.filename.slice(state.cursorPos + 1);
88432
88588
  const shortDir = state.directory.replace(process.env.HOME || "", "~");
88433
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88434
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { children: [
88435
- import_chalk4.default.cyan("\u25C6"),
88589
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
88590
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
88591
+ import_chalk5.default.cyan("\u25C6"),
88436
88592
  " ",
88437
- import_chalk4.default.bold("Save Scan Results")
88593
+ import_chalk5.default.bold("Save Scan Results")
88438
88594
  ] }),
88439
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { children: [
88595
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
88440
88596
  "Score: ",
88441
- import_chalk4.default.bold(String(score)),
88597
+ import_chalk5.default.bold(String(score)),
88442
88598
  " ",
88443
88599
  actionColor2(scanAction.toUpperCase()),
88444
88600
  " ",
88445
- import_chalk4.default.dim("\u2502"),
88601
+ import_chalk5.default.dim("\u2502"),
88446
88602
  " ",
88447
88603
  packageCount,
88448
88604
  " packages scanned"
88449
88605
  ] }),
88450
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: "" }),
88451
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { children: [
88452
- state.focus === "filename" ? import_chalk4.default.cyan("\u258C") : " ",
88453
- import_chalk4.default.bold("File:"),
88606
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: "" }),
88607
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
88608
+ state.focus === "filename" ? import_chalk5.default.cyan("\u258C") : " ",
88609
+ import_chalk5.default.bold("File:"),
88454
88610
  " ",
88455
88611
  filenameDisplay,
88456
- import_chalk4.default.dim(".json")
88612
+ import_chalk5.default.dim(".json")
88457
88613
  ] }),
88458
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: import_chalk4.default.dim(` \u2500\u2500\u2500 ${shortDir} \u2500\u2500\u2500 [${state.browserCursor + 1}/${filteredEntries.length}]`) }),
88614
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: import_chalk5.default.dim(` \u2500\u2500\u2500 ${shortDir} \u2500\u2500\u2500 [${state.browserCursor + 1}/${filteredEntries.length}]`) }),
88459
88615
  visibleEntries.map((entry, i) => {
88460
88616
  const realIdx = state.browserViewport + i;
88461
88617
  const isCursor = state.focus === "browser" && realIdx === state.browserCursor;
88462
- const prefix = isCursor ? import_chalk4.default.cyan("\u258C") : " ";
88618
+ const prefix = isCursor ? import_chalk5.default.cyan("\u258C") : " ";
88463
88619
  const icon = entry.isDirectory ? "\u{1F4C1} " : " ";
88464
- const name = entry.isDirectory ? import_chalk4.default.bold(entry.name + "/") : entry.name;
88465
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { children: [
88620
+ const name = entry.isDirectory ? import_chalk5.default.bold(entry.name + "/") : entry.name;
88621
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
88466
88622
  prefix,
88467
88623
  icon,
88468
88624
  name
88469
88625
  ] }, `${entry.name}-${i}`);
88470
88626
  }),
88471
- filteredEntries.length > VISIBLE_ROWS && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { dimColor: true, children: [
88627
+ filteredEntries.length > VISIBLE_ROWS && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { dimColor: true, children: [
88472
88628
  " ",
88473
- import_chalk4.default.dim(`\u2191\u2193 ${filteredEntries.length - VISIBLE_ROWS} more`)
88629
+ import_chalk5.default.dim(`\u2191\u2193 ${filteredEntries.length - VISIBLE_ROWS} more`)
88474
88630
  ] }),
88475
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: "" }),
88476
- state.filterText && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { dimColor: true, children: [
88631
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: "" }),
88632
+ state.filterText && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { dimColor: true, children: [
88477
88633
  ' filter: "',
88478
88634
  state.filterText,
88479
88635
  '" (',
88480
88636
  filteredEntries.length,
88481
88637
  " matches)"
88482
88638
  ] }),
88483
- state.confirmOverwrite && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { color: "yellow", children: [
88639
+ state.confirmOverwrite && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: "yellow", children: [
88484
88640
  " ",
88485
- import_chalk4.default.yellow("\u26A0"),
88641
+ import_chalk5.default.yellow("\u26A0"),
88486
88642
  " ",
88487
88643
  ensureJsonExtension(state.filename),
88488
88644
  " exists ",
88489
- import_chalk4.default.dim("\u2014"),
88645
+ import_chalk5.default.dim("\u2014"),
88490
88646
  " Enter again to overwrite"
88491
88647
  ] }),
88492
- state.error && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { color: "red", children: [
88648
+ state.error && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: "red", children: [
88493
88649
  " ",
88494
- import_chalk4.default.red("\u2717"),
88650
+ import_chalk5.default.red("\u2717"),
88495
88651
  " ",
88496
88652
  state.error
88497
88653
  ] }),
88498
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { children: [
88499
- import_chalk4.default.bold.hex("#FFD700")("\u23CE"),
88654
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
88655
+ import_chalk5.default.bold.hex("#FFD700")("\u23CE"),
88500
88656
  " ",
88501
- import_chalk4.default.bold.hex("#FFD700")("save"),
88657
+ import_chalk5.default.bold.hex("#FFD700")("save"),
88502
88658
  " ",
88503
- import_chalk4.default.bold.cyan("\u2191\u2193"),
88659
+ import_chalk5.default.bold.cyan("\u2191\u2193"),
88504
88660
  " ",
88505
- import_chalk4.default.dim("browse"),
88661
+ import_chalk5.default.dim("browse"),
88506
88662
  " ",
88507
- import_chalk4.default.bold.cyan("esc"),
88663
+ import_chalk5.default.bold.cyan("esc"),
88508
88664
  " ",
88509
- import_chalk4.default.dim("cancel")
88665
+ import_chalk5.default.dim("cancel")
88510
88666
  ] })
88511
88667
  ] });
88512
88668
  };
@@ -88528,12 +88684,12 @@ function writeJsonFile(filepath, json) {
88528
88684
  const resolved = resolvePath(filepath);
88529
88685
  try {
88530
88686
  writeFileSync5(resolved, json + "\n");
88531
- process.stderr.write(import_chalk5.default.green(` \u2713 Saved to ${resolved}
88687
+ process.stderr.write(import_chalk6.default.green(` \u2713 Saved to ${resolved}
88532
88688
 
88533
88689
  `));
88534
88690
  } catch (err) {
88535
88691
  const msg = err instanceof Error ? err.message : String(err);
88536
- process.stderr.write(import_chalk5.default.red(` Error saving file: ${msg}
88692
+ process.stderr.write(import_chalk6.default.red(` Error saving file: ${msg}
88537
88693
 
88538
88694
  `));
88539
88695
  }
@@ -88565,14 +88721,14 @@ async function handleJsonOutput(result, config3) {
88565
88721
  json,
88566
88722
  onSaved: (filepath) => {
88567
88723
  inkInstance.unmount();
88568
- process.stderr.write(import_chalk5.default.green(` \u2713 Saved to ${filepath}
88724
+ process.stderr.write(import_chalk6.default.green(` \u2713 Saved to ${filepath}
88569
88725
 
88570
88726
  `));
88571
88727
  resolve2();
88572
88728
  },
88573
88729
  onCancel: () => {
88574
88730
  inkInstance.unmount();
88575
- process.stderr.write(import_chalk5.default.dim(" Cancelled.\n\n"));
88731
+ process.stderr.write(import_chalk6.default.dim(" Cancelled.\n\n"));
88576
88732
  resolve2();
88577
88733
  }
88578
88734
  })
@@ -88583,7 +88739,7 @@ async function handleJsonOutput(result, config3) {
88583
88739
  function printTrialBanner(result) {
88584
88740
  if (result.trialScansRemaining === void 0) return;
88585
88741
  process.stderr.write(
88586
- import_chalk5.default.dim(` Free tier \xB7 Run \`dg login\` for higher scan limits.
88742
+ import_chalk6.default.dim(` Free tier \xB7 Run \`dg login\` for higher scan limits.
88587
88743
  `)
88588
88744
  );
88589
88745
  }
@@ -88605,13 +88761,13 @@ function handleTrialExhausted2(error2, jsonMode = false) {
88605
88761
  }, null, 2) + "\n");
88606
88762
  } else {
88607
88763
  if (hasKey) {
88608
- process.stderr.write(import_chalk5.default.yellow(`
88764
+ process.stderr.write(import_chalk6.default.yellow(`
88609
88765
  ${message}
88610
88766
 
88611
88767
  `));
88612
88768
  } else {
88613
88769
  process.stderr.write(
88614
- import_chalk5.default.yellow("\n Monthly scan limit reached (1,000 scans/month on free tier).\n") + import_chalk5.default.white(" Run `dg login` for higher limits, or upgrade at westbayberry.com/pricing\n\n")
88770
+ import_chalk6.default.yellow("\n Monthly scan limit reached (1,000 scans/month on free tier).\n") + import_chalk6.default.white(" Run `dg login` for higher limits, or upgrade at westbayberry.com/pricing\n\n")
88615
88771
  );
88616
88772
  }
88617
88773
  }
@@ -88621,9 +88777,9 @@ function handleTrialExhausted2(error2, jsonMode = false) {
88621
88777
  return false;
88622
88778
  }
88623
88779
  function actionColor(action) {
88624
- if (action === "block") return import_chalk5.default.red;
88625
- if (action === "warn") return import_chalk5.default.yellow;
88626
- return import_chalk5.default.green;
88780
+ if (action === "block") return import_chalk6.default.red;
88781
+ if (action === "warn") return import_chalk6.default.yellow;
88782
+ return import_chalk6.default.green;
88627
88783
  }
88628
88784
  function pad(s, len) {
88629
88785
  return s + " ".repeat(Math.max(0, len - s.length));
@@ -88643,18 +88799,18 @@ function groupPackages(packages) {
88643
88799
  return [...map.values()].map((pkgs) => ({ packages: pkgs, key: pkgs[0].name })).sort((a, b) => b.packages[0].score - a.packages[0].score);
88644
88800
  }
88645
88801
  function actionBadge(score) {
88646
- if (score >= 70) return { label: "Block", color: import_chalk5.default.red };
88647
- if (score >= 60) return { label: "Warn", color: import_chalk5.default.yellow };
88648
- return { label: "Pass", color: import_chalk5.default.green };
88802
+ if (score >= 70) return { label: "Block", color: import_chalk6.default.red };
88803
+ if (score >= 60) return { label: "Warn", color: import_chalk6.default.yellow };
88804
+ return { label: "Pass", color: import_chalk6.default.green };
88649
88805
  }
88650
88806
  function renderResultStatic(result, _config) {
88651
88807
  const lines = [];
88652
88808
  const actionStr = result.action.toUpperCase();
88653
88809
  const colorAction = actionColor(result.action);
88654
88810
  lines.push("");
88655
- lines.push(` ${import_chalk5.default.bold("Dependency Guardian")}`);
88811
+ lines.push(` ${import_chalk6.default.bold("Dependency Guardian")}`);
88656
88812
  lines.push(
88657
- ` Score: ${import_chalk5.default.bold(String(result.score))}${" ".repeat(
88813
+ ` Score: ${import_chalk6.default.bold(String(result.score))}${" ".repeat(
88658
88814
  Math.max(1, 50 - String(result.score).length)
88659
88815
  )}${colorAction(actionStr)}`
88660
88816
  );
@@ -88664,11 +88820,11 @@ function renderResultStatic(result, _config) {
88664
88820
  const total = result.packages.length;
88665
88821
  if (flagged.length > 0) {
88666
88822
  lines.push(
88667
- ` ${total} package${total !== 1 ? "s" : ""} scanned ${import_chalk5.default.dim("\u2502")} ${import_chalk5.default.yellow(`${flagged.length} flagged`)} \u2502 ${import_chalk5.default.green(`${clean.length} clean`)}`
88823
+ ` ${total} package${total !== 1 ? "s" : ""} scanned ${import_chalk6.default.dim("\u2502")} ${import_chalk6.default.yellow(`${flagged.length} flagged`)} \u2502 ${import_chalk6.default.green(`${clean.length} clean`)}`
88668
88824
  );
88669
88825
  } else {
88670
88826
  lines.push(
88671
- ` ${total} package${total !== 1 ? "s" : ""} scanned ${import_chalk5.default.dim("\u2502")} ${import_chalk5.default.green("all clean")}`
88827
+ ` ${total} package${total !== 1 ? "s" : ""} scanned ${import_chalk6.default.dim("\u2502")} ${import_chalk6.default.green("all clean")}`
88672
88828
  );
88673
88829
  }
88674
88830
  const licensedPkgs = result.packages.filter((p) => p.license);
@@ -88677,7 +88833,7 @@ function renderResultStatic(result, _config) {
88677
88833
  );
88678
88834
  if (licenseIssues.length > 0) {
88679
88835
  lines.push(
88680
- ` ${import_chalk5.default.dim("Licenses:")} ${import_chalk5.default.yellow(`${licenseIssues.length} need review`)} \u2502 ${import_chalk5.default.green(`${licensedPkgs.length - licenseIssues.length} permissive`)}`
88836
+ ` ${import_chalk6.default.dim("Licenses:")} ${import_chalk6.default.yellow(`${licenseIssues.length} need review`)} \u2502 ${import_chalk6.default.green(`${licensedPkgs.length - licenseIssues.length} permissive`)}`
88681
88837
  );
88682
88838
  }
88683
88839
  lines.push("");
@@ -88688,30 +88844,30 @@ function renderResultStatic(result, _config) {
88688
88844
  }
88689
88845
  const groups = groupPackages(flagged);
88690
88846
  if (flagged.length > 0) {
88691
- lines.push(` ${import_chalk5.default.bold("Flagged Packages")}`);
88692
- lines.push(` ${import_chalk5.default.dim("\u2500".repeat(60))}`);
88847
+ lines.push(` ${import_chalk6.default.bold("Flagged Packages")}`);
88848
+ lines.push(` ${import_chalk6.default.dim("\u2500".repeat(60))}`);
88693
88849
  for (const group of groups) {
88694
88850
  const rep = group.packages[0];
88695
88851
  const { label, color } = actionBadge(rep.score);
88696
88852
  const names = group.packages.length === 1 ? rep.name : group.packages.length <= 3 ? group.packages.map((p) => p.name).join(", ") : `${group.packages[0].name} + ${group.packages.length - 1} similar`;
88697
88853
  const lcInfo = rep.license;
88698
88854
  const lcStr = lcInfo ? truncate2(lcInfo.spdx ?? lcInfo.raw ?? "", 14) : "";
88699
- const lcColor = !lcInfo ? import_chalk5.default.dim : lcInfo.riskCategory === "permissive" ? import_chalk5.default.green : lcInfo.riskCategory === "no-license" || lcInfo.riskCategory === "unlicensed" || lcInfo.riskCategory === "network-copyleft" ? import_chalk5.default.red : import_chalk5.default.yellow;
88855
+ const lcColor = !lcInfo ? import_chalk6.default.dim : lcInfo.riskCategory === "permissive" ? import_chalk6.default.green : lcInfo.riskCategory === "no-license" || lcInfo.riskCategory === "unlicensed" || lcInfo.riskCategory === "network-copyleft" ? import_chalk6.default.red : import_chalk6.default.yellow;
88700
88856
  lines.push(
88701
- ` ${color(pad(label, 7))}${import_chalk5.default.bold(pad(truncate2(names, 36), 38))}${lcColor(pad(lcStr, 16))}${import_chalk5.default.dim(`score ${rep.score}`)}`
88857
+ ` ${color(pad(label, 7))}${import_chalk6.default.bold(pad(truncate2(names, 36), 38))}${lcColor(pad(lcStr, 16))}${import_chalk6.default.dim(`score ${rep.score}`)}`
88702
88858
  );
88703
88859
  }
88704
88860
  lines.push("");
88705
88861
  }
88706
88862
  if (clean.length > 0) {
88707
88863
  lines.push(
88708
- ` ${import_chalk5.default.green("\u2713")} ${import_chalk5.default.dim(`${clean.length} package${clean.length !== 1 ? "s" : ""} passed with score 0`)}`
88864
+ ` ${import_chalk6.default.green("\u2713")} ${import_chalk6.default.dim(`${clean.length} package${clean.length !== 1 ? "s" : ""} passed with score 0`)}`
88709
88865
  );
88710
88866
  lines.push("");
88711
88867
  }
88712
88868
  if (result.durationMs) {
88713
88869
  lines.push(
88714
- ` ${import_chalk5.default.dim(`Completed in ${(result.durationMs / 1e3).toFixed(1)}s`)}`
88870
+ ` ${import_chalk6.default.dim(`Completed in ${(result.durationMs / 1e3).toFixed(1)}s`)}`
88715
88871
  );
88716
88872
  lines.push("");
88717
88873
  }
@@ -88720,12 +88876,12 @@ function renderResultStatic(result, _config) {
88720
88876
  async function runStatic(config3) {
88721
88877
  const dbg = (msg) => {
88722
88878
  if (config3.debug)
88723
- process.stderr.write(import_chalk5.default.dim(` [debug] ${msg}
88879
+ process.stderr.write(import_chalk6.default.dim(` [debug] ${msg}
88724
88880
  `));
88725
88881
  };
88726
88882
  if (config3.mode === "off") {
88727
88883
  process.stderr.write(
88728
- import_chalk5.default.dim(" Dependency Guardian: mode is off \u2014 skipping.\n")
88884
+ import_chalk6.default.dim(" Dependency Guardian: mode is off \u2014 skipping.\n")
88729
88885
  );
88730
88886
  process.exit(0);
88731
88887
  }
@@ -88733,7 +88889,7 @@ async function runStatic(config3) {
88733
88889
  `mode=${config3.mode} max=${config3.maxPackages}`
88734
88890
  );
88735
88891
  dbg(`api=${config3.apiUrl}`);
88736
- process.stderr.write(import_chalk5.default.dim(" Discovering package changes...\n"));
88892
+ process.stderr.write(import_chalk6.default.dim(" Discovering package changes...\n"));
88737
88893
  let discovery = discoverChanges(process.cwd(), config3);
88738
88894
  dbg(`discovery method: ${discovery.method}`);
88739
88895
  if (discovery.pythonPackages.length > 0) {
@@ -88743,17 +88899,17 @@ async function runStatic(config3) {
88743
88899
  const { discoverProjects: discoverProjects2 } = await Promise.resolve().then(() => (init_discover(), discover_exports));
88744
88900
  const subProjects = discoverProjects2(process.cwd());
88745
88901
  if (subProjects.length === 0) {
88746
- process.stderr.write(import_chalk5.default.dim(" No package changes detected.\n"));
88902
+ process.stderr.write(import_chalk6.default.dim(" No package changes detected.\n"));
88747
88903
  process.exit(0);
88748
88904
  }
88749
88905
  const totalPkgs = subProjects.reduce((s, p) => s + p.packageCount, 0);
88750
88906
  process.stderr.write(
88751
- import_chalk5.default.dim(` Found ${subProjects.length} projects (${totalPkgs} packages total):
88907
+ import_chalk6.default.dim(` Found ${subProjects.length} projects (${totalPkgs} packages total):
88752
88908
  `)
88753
88909
  );
88754
88910
  for (const proj of subProjects) {
88755
88911
  process.stderr.write(
88756
- import_chalk5.default.dim(` ${proj.ecosystem} ${proj.relativePath} (${proj.packageCount})
88912
+ import_chalk6.default.dim(` ${proj.ecosystem} ${proj.relativePath} (${proj.packageCount})
88757
88913
  `)
88758
88914
  );
88759
88915
  }
@@ -88783,7 +88939,7 @@ async function runStatic(config3) {
88783
88939
  }
88784
88940
  }
88785
88941
  if (allNpmPkgs.length === 0 && allPyPkgs.length === 0) {
88786
- process.stderr.write(import_chalk5.default.dim(" No package changes detected across projects.\n"));
88942
+ process.stderr.write(import_chalk6.default.dim(" No package changes detected across projects.\n"));
88787
88943
  process.exit(0);
88788
88944
  }
88789
88945
  discovery = {
@@ -88796,14 +88952,14 @@ async function runStatic(config3) {
88796
88952
  const packages = discovery.packages;
88797
88953
  const totalToScan = packages.length + discovery.pythonPackages.length;
88798
88954
  process.stderr.write(
88799
- import_chalk5.default.dim(
88955
+ import_chalk6.default.dim(
88800
88956
  ` Scanning ${totalToScan} package${totalToScan !== 1 ? "s" : ""}${discovery.pythonPackages.length > 0 ? ` (${packages.length} npm + ${discovery.pythonPackages.length} Python)` : ""} (${discovery.method})...
88801
88957
  `
88802
88958
  )
88803
88959
  );
88804
88960
  if (discovery.skipped.length > 0 && config3.maxPackages < 1e4) {
88805
88961
  process.stderr.write(
88806
- import_chalk5.default.dim(
88962
+ import_chalk6.default.dim(
88807
88963
  ` Note: ${discovery.skipped.length} package(s) not scanned (--max-packages=${config3.maxPackages})
88808
88964
  `
88809
88965
  )
@@ -88817,7 +88973,7 @@ async function runStatic(config3) {
88817
88973
  const startMs = Date.now();
88818
88974
  if (packages.length > 0) {
88819
88975
  result = await callAnalyzeAPI(packages, config3, (done, total) => {
88820
- process.stderr.write(import_chalk5.default.dim(` Analyzed ${done}/${total}...
88976
+ process.stderr.write(import_chalk6.default.dim(` Analyzed ${done}/${total}...
88821
88977
  `));
88822
88978
  });
88823
88979
  } else {
@@ -88825,7 +88981,7 @@ async function runStatic(config3) {
88825
88981
  }
88826
88982
  if (discovery.pythonPackages.length > 0) {
88827
88983
  process.stderr.write(
88828
- import_chalk5.default.dim(` Scanning ${discovery.pythonPackages.length} Python package${discovery.pythonPackages.length !== 1 ? "s" : ""}...
88984
+ import_chalk6.default.dim(` Scanning ${discovery.pythonPackages.length} Python package${discovery.pythonPackages.length !== 1 ? "s" : ""}...
88829
88985
  `)
88830
88986
  );
88831
88987
  const pyResult = await callPyPIAnalyzeAPI(discovery.pythonPackages, config3);
@@ -88872,7 +89028,7 @@ async function runStaticNpm(npmArgs, config3) {
88872
89028
  const bareSpecs = readBareInstallPackages(process.cwd());
88873
89029
  if (bareSpecs.length === 0) {
88874
89030
  process.stderr.write(
88875
- import_chalk5.default.dim(
89031
+ import_chalk6.default.dim(
88876
89032
  " Dependency Guardian: no packages to scan, passing through to npm.\n"
88877
89033
  )
88878
89034
  );
@@ -88880,7 +89036,7 @@ async function runStaticNpm(npmArgs, config3) {
88880
89036
  process.exit(code);
88881
89037
  }
88882
89038
  process.stderr.write(
88883
- import_chalk5.default.dim(
89039
+ import_chalk6.default.dim(
88884
89040
  ` Resolving ${bareSpecs.length} package${bareSpecs.length !== 1 ? "s" : ""} from package.json...
88885
89041
  `
88886
89042
  )
@@ -88888,7 +89044,7 @@ async function runStaticNpm(npmArgs, config3) {
88888
89044
  const { resolved: resolved2, failed: failed2 } = await resolvePackages(bareSpecs);
88889
89045
  if (failed2.length > 0 && config3.debug) {
88890
89046
  process.stderr.write(
88891
- import_chalk5.default.dim(
89047
+ import_chalk6.default.dim(
88892
89048
  ` [debug] Could not resolve: ${failed2.slice(0, 5).join(", ")}${failed2.length > 5 ? ` (+${failed2.length - 5} more)` : ""}
88893
89049
  `
88894
89050
  )
@@ -88897,7 +89053,7 @@ async function runStaticNpm(npmArgs, config3) {
88897
89053
  return scanAndInstallStatic(resolved2, parsed, config3);
88898
89054
  }
88899
89055
  process.stderr.write(
88900
- import_chalk5.default.dim(
89056
+ import_chalk6.default.dim(
88901
89057
  ` Resolving ${parsed.packages.length} package${parsed.packages.length !== 1 ? "s" : ""}...
88902
89058
  `
88903
89059
  )
@@ -88905,7 +89061,7 @@ async function runStaticNpm(npmArgs, config3) {
88905
89061
  const { resolved, failed } = await resolvePackages(parsed.packages);
88906
89062
  if (failed.length > 0) {
88907
89063
  process.stderr.write(
88908
- import_chalk5.default.yellow(
89064
+ import_chalk6.default.yellow(
88909
89065
  ` Warning: Could not resolve versions for: ${failed.join(", ")}
88910
89066
  `
88911
89067
  )
@@ -88913,7 +89069,7 @@ async function runStaticNpm(npmArgs, config3) {
88913
89069
  }
88914
89070
  if (resolved.length === 0) {
88915
89071
  process.stderr.write(
88916
- import_chalk5.default.dim(" No packages to scan. Passing through to npm.\n")
89072
+ import_chalk6.default.dim(" No packages to scan. Passing through to npm.\n")
88917
89073
  );
88918
89074
  const code = await runNpm(parsed.rawArgs);
88919
89075
  process.exit(code);
@@ -88922,7 +89078,7 @@ async function runStaticNpm(npmArgs, config3) {
88922
89078
  }
88923
89079
  async function scanAndInstallStatic(resolved, parsed, config3) {
88924
89080
  process.stderr.write(
88925
- import_chalk5.default.dim(
89081
+ import_chalk6.default.dim(
88926
89082
  ` Scanning ${resolved.length} package${resolved.length !== 1 ? "s" : ""}...
88927
89083
  `
88928
89084
  )
@@ -88934,7 +89090,7 @@ async function scanAndInstallStatic(resolved, parsed, config3) {
88934
89090
  const elapsed = Date.now() - startMs;
88935
89091
  if (config3.debug) {
88936
89092
  process.stderr.write(
88937
- import_chalk5.default.dim(
89093
+ import_chalk6.default.dim(
88938
89094
  ` [debug] API responded in ${elapsed}ms, action=${result.action}, score=${result.score}
88939
89095
  `
88940
89096
  )
@@ -88944,7 +89100,7 @@ async function scanAndInstallStatic(resolved, parsed, config3) {
88944
89100
  if (handleTrialExhausted2(error2, config3.json)) return;
88945
89101
  const msg = error2 instanceof Error ? error2.message : String(error2);
88946
89102
  process.stderr.write(
88947
- import_chalk5.default.yellow(
89103
+ import_chalk6.default.yellow(
88948
89104
  ` Warning: Scan failed (${msg}). Proceeding with install.
88949
89105
  `
88950
89106
  )
@@ -88955,8 +89111,8 @@ async function scanAndInstallStatic(resolved, parsed, config3) {
88955
89111
  }
88956
89112
  if (result.action === "pass") {
88957
89113
  process.stderr.write(
88958
- import_chalk5.default.green(
88959
- ` ${import_chalk5.default.bold("\u2713")} ${resolved.length} package${resolved.length !== 1 ? "s" : ""} scanned \u2014 all clear
89114
+ import_chalk6.default.green(
89115
+ ` ${import_chalk6.default.bold("\u2713")} ${resolved.length} package${resolved.length !== 1 ? "s" : ""} scanned \u2014 all clear
88960
89116
  `
88961
89117
  )
88962
89118
  );
@@ -88970,7 +89126,7 @@ async function scanAndInstallStatic(resolved, parsed, config3) {
88970
89126
  printTrialBanner(result);
88971
89127
  if (result.action === "warn") {
88972
89128
  process.stderr.write(
88973
- import_chalk5.default.yellow(" Warnings detected. Proceeding with install.\n\n")
89129
+ import_chalk6.default.yellow(" Warnings detected. Proceeding with install.\n\n")
88974
89130
  );
88975
89131
  const code = await runNpm(parsed.rawArgs);
88976
89132
  process.exit(code);
@@ -88978,8 +89134,8 @@ async function scanAndInstallStatic(resolved, parsed, config3) {
88978
89134
  if (result.action === "block") {
88979
89135
  if (parsed.dgForce) {
88980
89136
  process.stderr.write(
88981
- import_chalk5.default.yellow(
88982
- import_chalk5.default.bold(
89137
+ import_chalk6.default.yellow(
89138
+ import_chalk6.default.bold(
88983
89139
  " --dg-force: Bypassing block. Install at your own risk.\n\n"
88984
89140
  )
88985
89141
  )
@@ -88988,10 +89144,10 @@ async function scanAndInstallStatic(resolved, parsed, config3) {
88988
89144
  process.exit(code);
88989
89145
  }
88990
89146
  process.stderr.write(
88991
- import_chalk5.default.red(import_chalk5.default.bold(" BLOCKED: ")) + import_chalk5.default.red("High-risk packages detected. Install aborted.\n")
89147
+ import_chalk6.default.red(import_chalk6.default.bold(" BLOCKED: ")) + import_chalk6.default.red("High-risk packages detected. Install aborted.\n")
88992
89148
  );
88993
89149
  process.stderr.write(
88994
- import_chalk5.default.dim(" Use --dg-force to bypass this check.\n\n")
89150
+ import_chalk6.default.dim(" Use --dg-force to bypass this check.\n\n")
88995
89151
  );
88996
89152
  process.exit(2);
88997
89153
  }
@@ -89008,13 +89164,13 @@ async function runStaticPip(pipArgs, config3) {
89008
89164
  }
89009
89165
  if (specs.length === 0) {
89010
89166
  process.stderr.write(
89011
- import_chalk5.default.dim(" Dependency Guardian: no packages to scan, passing through to pip.\n")
89167
+ import_chalk6.default.dim(" Dependency Guardian: no packages to scan, passing through to pip.\n")
89012
89168
  );
89013
89169
  const code = await runPip(parsed.rawArgs);
89014
89170
  process.exit(code);
89015
89171
  }
89016
89172
  process.stderr.write(
89017
- import_chalk5.default.dim(
89173
+ import_chalk6.default.dim(
89018
89174
  ` Resolving ${specs.length} package${specs.length !== 1 ? "s" : ""} from PyPI...
89019
89175
  `
89020
89176
  )
@@ -89022,19 +89178,19 @@ async function runStaticPip(pipArgs, config3) {
89022
89178
  const { resolved, failed } = await resolvePackages2(specs);
89023
89179
  if (failed.length > 0) {
89024
89180
  process.stderr.write(
89025
- import_chalk5.default.yellow(` Warning: Could not resolve versions for: ${failed.join(", ")}
89181
+ import_chalk6.default.yellow(` Warning: Could not resolve versions for: ${failed.join(", ")}
89026
89182
  `)
89027
89183
  );
89028
89184
  }
89029
89185
  if (resolved.length === 0) {
89030
89186
  process.stderr.write(
89031
- import_chalk5.default.dim(" No packages to scan. Passing through to pip.\n")
89187
+ import_chalk6.default.dim(" No packages to scan. Passing through to pip.\n")
89032
89188
  );
89033
89189
  const code = await runPip(parsed.rawArgs);
89034
89190
  process.exit(code);
89035
89191
  }
89036
89192
  process.stderr.write(
89037
- import_chalk5.default.dim(
89193
+ import_chalk6.default.dim(
89038
89194
  ` Scanning ${resolved.length} Python package${resolved.length !== 1 ? "s" : ""}...
89039
89195
  `
89040
89196
  )
@@ -89046,7 +89202,7 @@ async function runStaticPip(pipArgs, config3) {
89046
89202
  if (handleTrialExhausted2(error2, config3.json)) return;
89047
89203
  const msg = error2 instanceof Error ? error2.message : String(error2);
89048
89204
  process.stderr.write(
89049
- import_chalk5.default.yellow(` Warning: Scan failed (${msg}). Proceeding with install.
89205
+ import_chalk6.default.yellow(` Warning: Scan failed (${msg}). Proceeding with install.
89050
89206
  `)
89051
89207
  );
89052
89208
  const code = await runPip(parsed.rawArgs);
@@ -89055,8 +89211,8 @@ async function runStaticPip(pipArgs, config3) {
89055
89211
  }
89056
89212
  if (result.action === "pass") {
89057
89213
  process.stderr.write(
89058
- import_chalk5.default.green(
89059
- ` ${import_chalk5.default.bold("\u2713")} ${resolved.length} package${resolved.length !== 1 ? "s" : ""} scanned \u2014 all clear
89214
+ import_chalk6.default.green(
89215
+ ` ${import_chalk6.default.bold("\u2713")} ${resolved.length} package${resolved.length !== 1 ? "s" : ""} scanned \u2014 all clear
89060
89216
  `
89061
89217
  )
89062
89218
  );
@@ -89070,7 +89226,7 @@ async function runStaticPip(pipArgs, config3) {
89070
89226
  printTrialBanner(result);
89071
89227
  if (result.action === "warn") {
89072
89228
  process.stderr.write(
89073
- import_chalk5.default.yellow(" Warnings detected. Proceeding with install.\n\n")
89229
+ import_chalk6.default.yellow(" Warnings detected. Proceeding with install.\n\n")
89074
89230
  );
89075
89231
  const code = await runPip(parsed.rawArgs);
89076
89232
  process.exit(code);
@@ -89078,16 +89234,16 @@ async function runStaticPip(pipArgs, config3) {
89078
89234
  if (result.action === "block") {
89079
89235
  if (parsed.dgForce) {
89080
89236
  process.stderr.write(
89081
- import_chalk5.default.yellow(import_chalk5.default.bold(" --dg-force: Bypassing block. Install at your own risk.\n\n"))
89237
+ import_chalk6.default.yellow(import_chalk6.default.bold(" --dg-force: Bypassing block. Install at your own risk.\n\n"))
89082
89238
  );
89083
89239
  const code = await runPip(parsed.rawArgs);
89084
89240
  process.exit(code);
89085
89241
  }
89086
89242
  process.stderr.write(
89087
- import_chalk5.default.red(import_chalk5.default.bold(" BLOCKED: ")) + import_chalk5.default.red("High-risk packages detected. Install aborted.\n")
89243
+ import_chalk6.default.red(import_chalk6.default.bold(" BLOCKED: ")) + import_chalk6.default.red("High-risk packages detected. Install aborted.\n")
89088
89244
  );
89089
89245
  process.stderr.write(
89090
- import_chalk5.default.dim(" Use --dg-force to bypass this check.\n\n")
89246
+ import_chalk6.default.dim(" Use --dg-force to bypass this check.\n\n")
89091
89247
  );
89092
89248
  process.exit(2);
89093
89249
  }
@@ -89110,22 +89266,22 @@ async function runStaticLogin() {
89110
89266
  });
89111
89267
  if (resp.ok) {
89112
89268
  process.stderr.write(
89113
- import_chalk5.default.yellow(" Already authenticated.\n") + import_chalk5.default.dim(" Run `dg logout` first to re-authenticate.\n")
89269
+ import_chalk6.default.yellow(" Already authenticated.\n") + import_chalk6.default.dim(" Run `dg logout` first to re-authenticate.\n")
89114
89270
  );
89115
89271
  return;
89116
89272
  }
89117
89273
  } catch {
89118
89274
  }
89119
- process.stderr.write(import_chalk5.default.dim(" Stored key is invalid. Starting fresh login...\n"));
89275
+ process.stderr.write(import_chalk6.default.dim(" Stored key is invalid. Starting fresh login...\n"));
89120
89276
  saveCredentials2("");
89121
89277
  }
89122
- process.stderr.write(import_chalk5.default.dim(" Creating login session...\n"));
89278
+ process.stderr.write(import_chalk6.default.dim(" Creating login session...\n"));
89123
89279
  let session;
89124
89280
  try {
89125
89281
  session = await createAuthSession2();
89126
89282
  } catch (err) {
89127
89283
  process.stderr.write(
89128
- import_chalk5.default.red(` Error: ${err instanceof Error ? err.message : String(err)}
89284
+ import_chalk6.default.red(` Error: ${err instanceof Error ? err.message : String(err)}
89129
89285
  `)
89130
89286
  );
89131
89287
  process.exit(1);
@@ -89133,10 +89289,10 @@ async function runStaticLogin() {
89133
89289
  process.stderr.write(`
89134
89290
  Authenticate your account at:
89135
89291
  `);
89136
- process.stderr.write(` ${import_chalk5.default.cyan(session.verifyUrl)}
89292
+ process.stderr.write(` ${import_chalk6.default.cyan(session.verifyUrl)}
89137
89293
 
89138
89294
  `);
89139
- process.stderr.write(import_chalk5.default.dim(" Press ENTER to open in the browser...\n"));
89295
+ process.stderr.write(import_chalk6.default.dim(" Press ENTER to open in the browser...\n"));
89140
89296
  await new Promise((resolve2) => {
89141
89297
  const onData = () => {
89142
89298
  process.stdin.removeListener("data", onData);
@@ -89151,7 +89307,7 @@ async function runStaticLogin() {
89151
89307
  openBrowser2(session.verifyUrl);
89152
89308
  } catch {
89153
89309
  }
89154
- process.stderr.write(import_chalk5.default.dim(" Waiting for authorization...\n"));
89310
+ process.stderr.write(import_chalk6.default.dim(" Waiting for authorization...\n"));
89155
89311
  const POLL_INTERVAL = 2e3;
89156
89312
  const MAX_ATTEMPTS = 150;
89157
89313
  for (let i = 0; i < MAX_ATTEMPTS; i++) {
@@ -89161,15 +89317,15 @@ async function runStaticLogin() {
89161
89317
  if (result.status === "complete" && result.apiKey) {
89162
89318
  saveCredentials2(result.apiKey);
89163
89319
  process.stderr.write(
89164
- import_chalk5.default.green(`
89320
+ import_chalk6.default.green(`
89165
89321
  Logged in as ${result.email ?? "unknown"}
89166
- `) + import_chalk5.default.dim(" Credentials saved.\n\n")
89322
+ `) + import_chalk6.default.dim(" Credentials saved.\n\n")
89167
89323
  );
89168
89324
  return;
89169
89325
  }
89170
89326
  if (result.status === "expired") {
89171
89327
  process.stderr.write(
89172
- import_chalk5.default.yellow("\n Session expired. Run `dg login` to try again.\n")
89328
+ import_chalk6.default.yellow("\n Session expired. Run `dg login` to try again.\n")
89173
89329
  );
89174
89330
  process.exit(1);
89175
89331
  }
@@ -89177,15 +89333,15 @@ async function runStaticLogin() {
89177
89333
  }
89178
89334
  }
89179
89335
  process.stderr.write(
89180
- import_chalk5.default.yellow("\n Timed out waiting for authorization.\n")
89336
+ import_chalk6.default.yellow("\n Timed out waiting for authorization.\n")
89181
89337
  );
89182
89338
  process.exit(1);
89183
89339
  }
89184
- var import_chalk5;
89340
+ var import_chalk6;
89185
89341
  var init_static_output = __esm({
89186
89342
  "src/static-output.ts"() {
89187
89343
  "use strict";
89188
- import_chalk5 = __toESM(require_source());
89344
+ import_chalk6 = __toESM(require_source());
89189
89345
  init_api3();
89190
89346
  init_auth();
89191
89347
  init_lockfile();
@@ -89256,10 +89412,10 @@ function reducer4(_state, action) {
89256
89412
  }
89257
89413
  }
89258
89414
  function useScan(config3) {
89259
- const [state, dispatch] = (0, import_react30.useReducer)(reducer4, { phase: "discovering" });
89260
- const started = (0, import_react30.useRef)(false);
89261
- const [multiProjects, setMultiProjects] = (0, import_react30.useState)(null);
89262
- (0, import_react30.useEffect)(() => {
89415
+ const [state, dispatch] = (0, import_react31.useReducer)(reducer4, { phase: "discovering" });
89416
+ const started = (0, import_react31.useRef)(false);
89417
+ const [multiProjects, setMultiProjects] = (0, import_react31.useState)(null);
89418
+ (0, import_react31.useEffect)(() => {
89263
89419
  if (started.current) return;
89264
89420
  started.current = true;
89265
89421
  const projects = discoverProjects(process.cwd());
@@ -89286,11 +89442,11 @@ function useScan(config3) {
89286
89442
  scanProjects(projects, config3, dispatch);
89287
89443
  }
89288
89444
  }, [config3]);
89289
- const scanSelectedProjects = (0, import_react30.useCallback)((projects) => {
89445
+ const scanSelectedProjects = (0, import_react31.useCallback)((projects) => {
89290
89446
  dispatch({ type: "DISCOVERY_COMPLETE", packages: [], skippedCount: 0 });
89291
89447
  scanProjects(projects, config3, dispatch);
89292
89448
  }, [config3]);
89293
- const restartSelection = (0, import_react30.useCallback)(() => {
89449
+ const restartSelection = (0, import_react31.useCallback)(() => {
89294
89450
  if (!multiProjects) return;
89295
89451
  dispatch({ type: "RESTART_SELECTION", projects: multiProjects });
89296
89452
  }, [multiProjects]);
@@ -89410,11 +89566,11 @@ async function scanProjects(projects, config3, dispatch) {
89410
89566
  dispatch({ type: "ERROR", error: err });
89411
89567
  }
89412
89568
  }
89413
- var import_react30;
89569
+ var import_react31;
89414
89570
  var init_useScan = __esm({
89415
89571
  "src/ui/hooks/useScan.ts"() {
89416
89572
  "use strict";
89417
- import_react30 = __toESM(require_react());
89573
+ import_react31 = __toESM(require_react());
89418
89574
  init_lockfile();
89419
89575
  init_api3();
89420
89576
  init_discover();
@@ -89423,85 +89579,6 @@ var init_useScan = __esm({
89423
89579
  }
89424
89580
  });
89425
89581
 
89426
- // src/ui/components/ProgressBar.tsx
89427
- function estimateScanSeconds(packageCount) {
89428
- return Math.ceil(Math.max(5, packageCount * 0.35 - 10));
89429
- }
89430
- function formatTime(seconds) {
89431
- if (seconds < 60) return `${seconds}s`;
89432
- const m = Math.floor(seconds / 60);
89433
- const s = seconds % 60;
89434
- return s > 0 ? `${m}m ${s}s` : `${m}m`;
89435
- }
89436
- var import_react31, import_chalk6, import_jsx_runtime9, ProgressBar;
89437
- var init_ProgressBar = __esm({
89438
- async "src/ui/components/ProgressBar.tsx"() {
89439
- "use strict";
89440
- import_react31 = __toESM(require_react());
89441
- await init_build2();
89442
- await init_build3();
89443
- import_chalk6 = __toESM(require_source());
89444
- import_jsx_runtime9 = __toESM(require_jsx_runtime());
89445
- ProgressBar = ({
89446
- value,
89447
- total,
89448
- label
89449
- }) => {
89450
- const startRef = (0, import_react31.useRef)(Date.now());
89451
- const [elapsed, setElapsed] = (0, import_react31.useState)(0);
89452
- (0, import_react31.useEffect)(() => {
89453
- const timer = setInterval(() => {
89454
- setElapsed(Math.floor((Date.now() - startRef.current) / 1e3));
89455
- }, 1e3);
89456
- return () => clearInterval(timer);
89457
- }, []);
89458
- const termWidth = process.stdout.columns || 80;
89459
- const percent = total > 0 ? Math.round(value / total * 100) : 0;
89460
- const estimate = estimateScanSeconds(total);
89461
- const timeInfo = `${formatTime(elapsed)} / ~${formatTime(estimate)}`;
89462
- const counter = `${value}/${total} ${percent}%`;
89463
- const barWidth = Math.max(10, termWidth - counter.length - 8);
89464
- const fraction = total > 0 ? Math.min(1, value / total) : 0;
89465
- const filled = Math.round(fraction * barWidth);
89466
- const empty = barWidth - filled;
89467
- const filledBar = "\u2501".repeat(filled);
89468
- const emptyBar = "\u2501".repeat(empty);
89469
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, children: [
89470
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
89471
- import_chalk6.default.cyan("\u25C6"),
89472
- " ",
89473
- import_chalk6.default.bold("Dependency Guardian")
89474
- ] }),
89475
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: "" }),
89476
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { children: [
89477
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "cyan", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(build_default, { type: "dots" }) }),
89478
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
89479
- " Scanning ",
89480
- total,
89481
- " packages... "
89482
- ] }),
89483
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { dimColor: true, children: timeInfo })
89484
- ] }),
89485
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { children: [
89486
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { children: " " }),
89487
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: "green", children: filledBar }),
89488
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { dimColor: true, children: emptyBar }),
89489
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
89490
- " ",
89491
- counter
89492
- ] })
89493
- ] }),
89494
- label && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { dimColor: true, children: [
89495
- " ",
89496
- import_chalk6.default.dim("\u203A"),
89497
- " ",
89498
- label
89499
- ] }) })
89500
- ] });
89501
- };
89502
- }
89503
- });
89504
-
89505
89582
  // src/ui/components/ScoreHeader.tsx
89506
89583
  function scoreColor(score, action) {
89507
89584
  const colorFn = action === "block" ? import_chalk7.default.red.bold : action === "warn" ? import_chalk7.default.yellow.bold : import_chalk7.default.green.bold;
@@ -89693,7 +89770,7 @@ var init_ScoreHeader = __esm({
89693
89770
  });
89694
89771
 
89695
89772
  // src/ui/hooks/useExpandAnimation.ts
89696
- function useExpandAnimation(targetHeight, active, durationMs = 180) {
89773
+ function useExpandAnimation(targetHeight, active2, durationMs = 180) {
89697
89774
  const [visibleLines, setVisibleLines] = (0, import_react32.useState)(0);
89698
89775
  const timerRef = (0, import_react32.useRef)(null);
89699
89776
  (0, import_react32.useEffect)(() => {
@@ -89701,7 +89778,7 @@ function useExpandAnimation(targetHeight, active, durationMs = 180) {
89701
89778
  clearInterval(timerRef.current);
89702
89779
  timerRef.current = null;
89703
89780
  }
89704
- if (!active || targetHeight <= 0) {
89781
+ if (!active2 || targetHeight <= 0) {
89705
89782
  setVisibleLines(0);
89706
89783
  return;
89707
89784
  }
@@ -89724,10 +89801,10 @@ function useExpandAnimation(targetHeight, active, durationMs = 180) {
89724
89801
  timerRef.current = null;
89725
89802
  }
89726
89803
  };
89727
- }, [active, targetHeight, durationMs]);
89804
+ }, [active2, targetHeight, durationMs]);
89728
89805
  return {
89729
- visibleLines: active ? visibleLines : 0,
89730
- isAnimating: active && visibleLines > 0 && visibleLines < targetHeight
89806
+ visibleLines: active2 ? visibleLines : 0,
89807
+ isAnimating: active2 && visibleLines > 0 && visibleLines < targetHeight
89731
89808
  };
89732
89809
  }
89733
89810
  var import_react32;
@@ -90840,7 +90917,7 @@ var init_App2 = __esm({
90840
90917
  (0, import_react35.useEffect)(() => {
90841
90918
  prevPhaseRef.current = state.phase;
90842
90919
  }, [state.phase]);
90843
- const leaveAltScreen = (0, import_react35.useCallback)(() => {
90920
+ const leaveAltScreen2 = (0, import_react35.useCallback)(() => {
90844
90921
  if (altScreenActiveRef.current && process.stdout.isTTY) {
90845
90922
  process.stdout.write("\x1B[?1049l");
90846
90923
  altScreenActiveRef.current = false;
@@ -90858,15 +90935,15 @@ var init_App2 = __esm({
90858
90935
  process.exitCode = 0;
90859
90936
  }
90860
90937
  }
90861
- leaveAltScreen();
90938
+ leaveAltScreen2();
90862
90939
  exit();
90863
- }, [state, config3, exit, leaveAltScreen]);
90940
+ }, [state, config3, exit, leaveAltScreen2]);
90864
90941
  const exitWithMessage = (0, import_react35.useCallback)((message, exitCode) => {
90865
90942
  process.exitCode = exitCode;
90866
- leaveAltScreen();
90943
+ leaveAltScreen2();
90867
90944
  process.stderr.write(message);
90868
90945
  return setTimeout(() => exit(), 0);
90869
- }, [exit, leaveAltScreen]);
90946
+ }, [exit, leaveAltScreen2]);
90870
90947
  (0, import_react35.useEffect)(() => {
90871
90948
  if (state.phase === "empty") {
90872
90949
  const timer = exitWithMessage(`${state.message}
@@ -90894,7 +90971,7 @@ var init_App2 = __esm({
90894
90971
  if (state.phase === "discovering" || state.phase === "scanning") {
90895
90972
  if (input === "q" || key.escape) {
90896
90973
  process.exitCode = 0;
90897
- leaveAltScreen();
90974
+ leaveAltScreen2();
90898
90975
  exit();
90899
90976
  }
90900
90977
  }
@@ -90911,7 +90988,7 @@ var init_App2 = __esm({
90911
90988
  onConfirm: scanSelectedProjects,
90912
90989
  onCancel: () => {
90913
90990
  process.exitCode = 0;
90914
- leaveAltScreen();
90991
+ leaveAltScreen2();
90915
90992
  exit();
90916
90993
  },
90917
90994
  userStatus
@@ -91817,6 +91894,7 @@ init_telemetry();
91817
91894
  init_config();
91818
91895
  init_npm_wrapper();
91819
91896
  init_update_check();
91897
+ init_alt_screen();
91820
91898
  var CLI_VERSION = getVersion();
91821
91899
  initTelemetry(CLI_VERSION);
91822
91900
  function closestCommand(input, commands) {
@@ -91837,9 +91915,14 @@ function closestCommand(input, commands) {
91837
91915
  return bestDist <= 3 ? best : null;
91838
91916
  }
91839
91917
  process.on("SIGINT", () => {
91918
+ leaveAltScreen();
91840
91919
  process.stderr.write("\n");
91841
91920
  process.exit(130);
91842
91921
  });
91922
+ process.on("SIGTERM", () => {
91923
+ leaveAltScreen();
91924
+ process.exit(143);
91925
+ });
91843
91926
  var isInteractive = process.stdout.isTTY === true && !process.env.CI && !process.env.NO_COLOR;
91844
91927
  async function main() {
91845
91928
  const rawCommand = process.argv[2];
@@ -91871,10 +91954,15 @@ async function main() {
91871
91954
  const { render: render3 } = await init_build2().then(() => build_exports);
91872
91955
  const React22 = await Promise.resolve().then(() => __toESM(require_react()));
91873
91956
  const { InitApp: InitApp2 } = await init_InitApp().then(() => InitApp_exports);
91874
- const { waitUntilExit } = render3(
91875
- React22.createElement(InitApp2, { firstRun: true, returning: true })
91876
- );
91877
- await waitUntilExit();
91957
+ enterAltScreen();
91958
+ try {
91959
+ const { waitUntilExit } = render3(
91960
+ React22.createElement(InitApp2, { firstRun: true, returning: true })
91961
+ );
91962
+ await waitUntilExit();
91963
+ } finally {
91964
+ leaveAltScreen();
91965
+ }
91878
91966
  try {
91879
91967
  const { markFirstRunComplete: markFirstRunComplete2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
91880
91968
  markFirstRunComplete2();