@getcodesentinel/codesentinel 1.19.0 → 1.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3702,6 +3702,7 @@ var ANSI2 = {
3702
3702
  cyan: "\x1B[36m",
3703
3703
  green: "\x1B[32m"
3704
3704
  };
3705
+ var PROMPT_PADDING = " ";
3705
3706
  var renderMenu = (currentVersion, actions, selectedIndex) => {
3706
3707
  const optionLabels = actions.map((action, index) => `${index + 1}. ${action.label}`);
3707
3708
  const labelWidth = optionLabels.reduce((max, label) => Math.max(max, label.length), 0);
@@ -3732,6 +3733,46 @@ var hideCursor2 = () => {
3732
3733
  var showCursor2 = () => {
3733
3734
  stderr2.write("\x1B[?25h");
3734
3735
  };
3736
+ var pipeWithPadding = (stream, target, padding) => {
3737
+ if (stream === null) {
3738
+ return;
3739
+ }
3740
+ stream.setEncoding("utf8");
3741
+ let buffer = "";
3742
+ let needsPrefix = true;
3743
+ const writeChunk = (chunk) => {
3744
+ let start = 0;
3745
+ while (start < chunk.length) {
3746
+ if (needsPrefix) {
3747
+ target.write(padding);
3748
+ needsPrefix = false;
3749
+ }
3750
+ const newlineIndex = chunk.indexOf("\n", start);
3751
+ if (newlineIndex === -1) {
3752
+ target.write(chunk.slice(start));
3753
+ return;
3754
+ }
3755
+ target.write(chunk.slice(start, newlineIndex + 1));
3756
+ needsPrefix = true;
3757
+ start = newlineIndex + 1;
3758
+ }
3759
+ };
3760
+ stream.on("data", (chunk) => {
3761
+ buffer += chunk;
3762
+ const lastNewlineIndex = buffer.lastIndexOf("\n");
3763
+ if (lastNewlineIndex === -1) {
3764
+ return;
3765
+ }
3766
+ writeChunk(buffer.slice(0, lastNewlineIndex + 1));
3767
+ buffer = buffer.slice(lastNewlineIndex + 1);
3768
+ });
3769
+ stream.on("end", () => {
3770
+ if (buffer.length > 0) {
3771
+ writeChunk(buffer);
3772
+ buffer = "";
3773
+ }
3774
+ });
3775
+ };
3735
3776
  var promptSelection = async (currentVersion, actions) => {
3736
3777
  if (!stdin2.isTTY || !stderr2.isTTY || typeof stdin2.setRawMode !== "function") {
3737
3778
  return "exit";
@@ -3788,46 +3829,99 @@ var createPrompt = () => createPromisesInterface({
3788
3829
  output: stderr2
3789
3830
  });
3790
3831
  var promptText = async (prompt, label, defaultValue) => {
3791
- const suffix = defaultValue === void 0 ? "" : ` [${defaultValue}]`;
3792
- const answer = await prompt.question(
3793
- `${label}${suffix}: `
3794
- );
3832
+ const suffix = defaultValue === void 0 || defaultValue.length === 0 ? "" : ` [${defaultValue}]`;
3833
+ let answer;
3834
+ try {
3835
+ answer = await prompt.question(
3836
+ `${PROMPT_PADDING}${label}${suffix}: `
3837
+ );
3838
+ } catch (error) {
3839
+ if (error instanceof Error && "code" in error && error.code === "ABORT_ERR") {
3840
+ stderr2.write("\n");
3841
+ return null;
3842
+ }
3843
+ throw error;
3844
+ }
3795
3845
  const trimmed = answer.trim();
3796
3846
  return trimmed.length > 0 ? trimmed : defaultValue ?? "";
3797
3847
  };
3848
+ var renderDependencyRiskPrompt = (errorMessage) => {
3849
+ clearTerminal();
3850
+ stderr2.write(`${PROMPT_PADDING}${ANSI2.bold}Scan dependency risk${ANSI2.reset}
3851
+ `);
3852
+ if (errorMessage !== void 0) {
3853
+ stderr2.write(`
3854
+ ${PROMPT_PADDING}${errorMessage}
3855
+ `);
3856
+ }
3857
+ stderr2.write("\n");
3858
+ };
3798
3859
  var buildDependencyRiskArgs = async () => {
3799
3860
  const prompt = createPrompt();
3800
3861
  try {
3801
- const dependency = await promptText(prompt, "Dependency spec", "");
3802
- if (dependency.length === 0) {
3803
- stderr2.write("A dependency spec is required.\n");
3804
- return null;
3862
+ let errorMessage;
3863
+ while (true) {
3864
+ renderDependencyRiskPrompt(errorMessage);
3865
+ const dependency = await promptText(prompt, "Package name");
3866
+ if (dependency === null) {
3867
+ return { kind: "cancel" };
3868
+ }
3869
+ if (dependency.length === 0) {
3870
+ errorMessage = "A package name is required.";
3871
+ continue;
3872
+ }
3873
+ return {
3874
+ kind: "run",
3875
+ args: ["dependency-risk", dependency]
3876
+ };
3805
3877
  }
3806
- return ["dependency-risk", dependency];
3807
3878
  } finally {
3808
3879
  prompt.close();
3809
3880
  }
3810
3881
  };
3811
3882
  var waitForReturnToMenu = async () => {
3812
- const prompt = createPromisesInterface({
3813
- input: stdin2,
3814
- output: stderr2
3815
- });
3816
- try {
3817
- await prompt.question("Press enter to return to the menu...");
3818
- } finally {
3819
- prompt.close();
3883
+ if (!stdin2.isTTY || !stderr2.isTTY || typeof stdin2.setRawMode !== "function") {
3884
+ return;
3820
3885
  }
3886
+ stderr2.write(`
3887
+ ${PROMPT_PADDING}Press enter to return to the menu...`);
3888
+ await new Promise((resolve6) => {
3889
+ emitKeypressEvents2(stdin2);
3890
+ const previousRawMode = stdin2.isRaw;
3891
+ const cleanup = () => {
3892
+ stdin2.off("keypress", onKeypress);
3893
+ stdin2.pause();
3894
+ stdin2.setRawMode(previousRawMode);
3895
+ showCursor2();
3896
+ stderr2.write("\n");
3897
+ resolve6();
3898
+ };
3899
+ const onKeypress = (_str, key) => {
3900
+ if (key.ctrl === true && key.name === "c") {
3901
+ cleanup();
3902
+ return;
3903
+ }
3904
+ if (key.name === "return" || key.name === "enter") {
3905
+ cleanup();
3906
+ }
3907
+ };
3908
+ hideCursor2();
3909
+ stdin2.on("keypress", onKeypress);
3910
+ stdin2.setRawMode(true);
3911
+ stdin2.resume();
3912
+ });
3821
3913
  };
3822
3914
  var runCliCommand = async (scriptPath2, args) => {
3823
3915
  return await new Promise((resolve6, reject) => {
3824
3916
  const child = spawn2(process.execPath, [...process.execArgv, scriptPath2, ...args], {
3825
- stdio: "inherit",
3917
+ stdio: ["inherit", "pipe", "pipe"],
3826
3918
  env: {
3827
3919
  ...process.env,
3828
3920
  CODESENTINEL_NO_UPDATE_NOTIFIER: "1"
3829
3921
  }
3830
3922
  });
3923
+ pipeWithPadding(child.stdout, stdout, PROMPT_PADDING);
3924
+ pipeWithPadding(child.stderr, stderr2, PROMPT_PADDING);
3831
3925
  child.on("error", (error) => {
3832
3926
  reject(error);
3833
3927
  });
@@ -3838,34 +3932,35 @@ var runCliCommand = async (scriptPath2, args) => {
3838
3932
  };
3839
3933
  var runInteractiveCliMenu = async (input) => {
3840
3934
  if (!stdin2.isTTY || !stderr2.isTTY || !stdout.isTTY) {
3841
- stderr2.write("Interactive menu requires a TTY.\n");
3935
+ stderr2.write(`${PROMPT_PADDING}Interactive menu requires a TTY.
3936
+ `);
3842
3937
  return 1;
3843
3938
  }
3844
3939
  const actions = [
3845
3940
  {
3846
3941
  label: "Run overview",
3847
3942
  description: "combined analyze + explain + report",
3848
- commandBuilder: () => ["run"]
3943
+ commandBuilder: () => ({ kind: "run", args: ["run"] })
3849
3944
  },
3850
3945
  {
3851
3946
  label: "Analyze repository",
3852
3947
  description: "structural and health scoring summary",
3853
- commandBuilder: () => ["analyze"]
3948
+ commandBuilder: () => ({ kind: "run", args: ["analyze"] })
3854
3949
  },
3855
3950
  {
3856
3951
  label: "Explain hotspots",
3857
3952
  description: "top findings in markdown by default",
3858
- commandBuilder: () => ["explain", "--format", "md"]
3953
+ commandBuilder: () => ({ kind: "run", args: ["explain", "--format", "md"] })
3859
3954
  },
3860
3955
  {
3861
3956
  label: "Generate report",
3862
3957
  description: "create a full report for a repository",
3863
- commandBuilder: () => ["report", "--format", "md"]
3958
+ commandBuilder: () => ({ kind: "run", args: ["report", "--format", "md"] })
3864
3959
  },
3865
3960
  {
3866
3961
  label: "Run policy check",
3867
3962
  description: "execute governance gates",
3868
- commandBuilder: () => ["check"]
3963
+ commandBuilder: () => ({ kind: "run", args: ["check"] })
3869
3964
  },
3870
3965
  {
3871
3966
  label: "Scan dependency risk",
@@ -3881,18 +3976,18 @@ var runInteractiveCliMenu = async (input) => {
3881
3976
  }
3882
3977
  const selectedAction = actions[selectedIndex];
3883
3978
  if (selectedAction === void 0) {
3884
- stderr2.write("\n");
3979
+ stderr2.write(`
3980
+ ${PROMPT_PADDING}`);
3885
3981
  return 1;
3886
3982
  }
3887
- const args = await selectedAction.commandBuilder();
3888
- if (args === null) {
3889
- await waitForReturnToMenu();
3983
+ const actionResult = await selectedAction.commandBuilder();
3984
+ if (actionResult.kind === "cancel") {
3890
3985
  continue;
3891
3986
  }
3892
- const exitCode = await runCliCommand(input.scriptPath, args);
3987
+ const exitCode = await runCliCommand(input.scriptPath, actionResult.args);
3893
3988
  if (exitCode !== 0) {
3894
3989
  stderr2.write(`
3895
- Command exited with code ${exitCode}.
3990
+ ${PROMPT_PADDING}Command exited with code ${exitCode}.
3896
3991
  `);
3897
3992
  } else {
3898
3993
  stderr2.write("\n");