veefore 1.4.0 → 1.4.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.
Files changed (2) hide show
  1. package/dist/veefore.mjs +55 -51
  2. package/package.json +1 -1
package/dist/veefore.mjs CHANGED
@@ -586,16 +586,6 @@ var LOGO = [
586
586
  " \u2588\u2588 \u2588\u2588 \u2588\u2588",
587
587
  " \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588"
588
588
  ];
589
- var LOGO_SMALL = [
590
- "\u2580\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2588 \u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2588\u2580",
591
- " \u2580\u2584 \u2584\u2584 \u2580\u2588 \u2588\u2580 \u2584\u2584 \u2584\u2588",
592
- " \u2588\u2584 \u2588 \u2588\u2580 \u2588 \u2584\u2588",
593
- " \u2588\u2584 \u2588 \u2588\u2580 \u2588 \u2584\u2588",
594
- " \u2588 \u2580\u2588\u2584\u2580 \u2588\u2580 \u2588",
595
- " \u2588 \u2580\u2588 \u2588\u2580 \u2588",
596
- " \u2580\u2588 \u2584\u2580 \u2588\u2580",
597
- " \u2580\u2588\u2584\u2584\u2588\u2588 \u2588\u2580"
598
- ];
599
589
 
600
590
  // src/tui.ts
601
591
  function isInteractive() {
@@ -655,7 +645,7 @@ var STARS = [
655
645
  ];
656
646
  async function showWelcome(context, options = {}) {
657
647
  if (!isInteractive()) return;
658
- const lines = welcomeLines(context, options.reserve ?? 0);
648
+ const lines = welcomeLines(context);
659
649
  if ((options.animate ?? true) && process.env.VEEFORE_NO_ANIMATION === void 0) {
660
650
  for (const line of lines) {
661
651
  out(line);
@@ -665,9 +655,9 @@ async function showWelcome(context, options = {}) {
665
655
  }
666
656
  for (const line of lines) out(line);
667
657
  }
668
- function welcomeLines(context, reserve) {
658
+ function welcomeLines(context) {
669
659
  const width = Math.min(columns(), 100);
670
- const art = rows() >= LOGO.length + 6 + reserve ? LOGO : LOGO_SMALL;
660
+ const art = LOGO;
671
661
  const logoWidth = Math.max(...art.map((line) => [...line].length));
672
662
  const indent = 5;
673
663
  const gap = 6;
@@ -677,7 +667,7 @@ function welcomeLines(context, reserve) {
677
667
  );
678
668
  const sideBySide = width >= indent + logoWidth + gap + panelWidth + 2;
679
669
  const panel = renderPanel(context.facts);
680
- const showLogo = width >= indent + logoWidth + 2 && (sideBySide || rows() >= art.length + 6 + panel.length + 2 + reserve);
670
+ const showLogo = width >= indent + logoWidth + 2;
681
671
  const rule = style.grey("\xB7".repeat(Math.max(10, Math.min(width - 2, 72))));
682
672
  const lines = [];
683
673
  const add = (line = "") => void lines.push(line);
@@ -735,7 +725,7 @@ function renderPanel(facts) {
735
725
  }
736
726
  function clearScreen() {
737
727
  if (!isInteractive()) return;
738
- process.stdout.write("\x1B[H\x1B[2J");
728
+ process.stdout.write("\x1B[H\x1B[J");
739
729
  }
740
730
  var appDepth = 0;
741
731
  var restoreInstalled = false;
@@ -749,7 +739,7 @@ function enterApp() {
749
739
  if (appDepth > 0) process.stdout.write("\x1B[?25h\x1B[?1049l");
750
740
  });
751
741
  }
752
- process.stdout.write("\x1B[?1049h\x1B[H\x1B[2J");
742
+ process.stdout.write("\x1B[?1049h\x1B[?25l\x1B[H\x1B[J");
753
743
  }
754
744
  function leaveApp() {
755
745
  if (!isInteractive() || appDepth === 0) return;
@@ -757,6 +747,9 @@ function leaveApp() {
757
747
  if (appDepth > 0) return;
758
748
  process.stdout.write("\x1B[?25h\x1B[?1049l");
759
749
  }
750
+ function inApp() {
751
+ return appDepth > 0;
752
+ }
760
753
  async function onOrdinaryScreen(body) {
761
754
  const depth = appDepth;
762
755
  if (depth > 0) {
@@ -768,35 +761,19 @@ async function onOrdinaryScreen(body) {
768
761
  } finally {
769
762
  if (depth > 0) {
770
763
  appDepth = depth;
771
- process.stdout.write("\x1B[?1049h\x1B[H\x1B[2J");
764
+ process.stdout.write("\x1B[?1049h\x1B[H\x1B[J");
772
765
  }
773
766
  }
774
767
  }
775
- function compactHeader(context) {
776
- const facts = Object.fromEntries(context.facts);
777
- const parts = [
778
- brand(style.bold("Veefore")),
779
- style.grey(`v${context.version}`),
780
- ...[facts.Folder, facts["Signed in"], facts.Veefore].filter((v) => Boolean(v))
781
- ];
782
- out();
783
- out(fit(` ${parts.join(style.grey(" \xB7 "))}`, columns() - 1));
784
- out(` ${style.grey("\xB7".repeat(Math.max(10, Math.min(columns() - 2, 72))))}`);
785
- }
786
768
  async function beginScreen(source, options = {}) {
787
769
  if (!isInteractive()) return;
788
770
  clearScreen();
789
- const reserve = options.reserve ?? 0;
790
- if (options.compact || rows() < LOGO_SMALL.length + 6 + reserve) compactHeader(source());
791
- else await showWelcome(source(), { animate: options.animate ?? false, reserve });
771
+ await showWelcome(source(), { animate: options.animate ?? false });
792
772
  }
793
- function drawScreen(source, options = {}) {
773
+ function drawScreen(source) {
794
774
  if (!isInteractive()) return;
795
775
  clearScreen();
796
- const reserve = options.reserve ?? 0;
797
- const context = source();
798
- if (options.compact || rows() < LOGO_SMALL.length + 6 + reserve) compactHeader(context);
799
- else for (const line of welcomeLines(context, reserve)) out(line);
776
+ for (const line of welcomeLines(source())) out(line);
800
777
  }
801
778
  async function showOutput(lines, options) {
802
779
  if (!isInteractive()) {
@@ -987,14 +964,19 @@ async function select(question, real, settings = {}) {
987
964
  return new Promise((resolve, reject) => {
988
965
  const wasRaw = stdin.isRaw;
989
966
  const restoreCursor = () => {
990
- stdout.write("\x1B[?25h");
967
+ if (!inApp()) stdout.write("\x1B[?25h");
991
968
  };
992
969
  const stopWatching = settings.redraw ? watchFacts(repaint) : void 0;
970
+ const onResize = () => {
971
+ if (settings.redraw) repaint();
972
+ else draw();
973
+ };
993
974
  const finish = (result) => {
994
975
  stdin.off("keypress", onKey);
995
976
  stdin.setRawMode(wasRaw);
996
977
  stdin.pause();
997
978
  stopWatching?.();
979
+ process.stdout.off("resize", onResize);
998
980
  process.off("exit", restoreCursor);
999
981
  if (rendered > 0) stdout.write(`\x1B[${rendered}A\r\x1B[J`);
1000
982
  restoreCursor();
@@ -1044,6 +1026,7 @@ async function select(question, real, settings = {}) {
1044
1026
  stdin.resume();
1045
1027
  stdout.write("\x1B[?25l");
1046
1028
  stdin.on("keypress", onKey);
1029
+ process.stdout.on("resize", onResize);
1047
1030
  draw();
1048
1031
  });
1049
1032
  }
@@ -3659,6 +3642,11 @@ var EVENT_TYPES = [
3659
3642
  "user.profile_updated",
3660
3643
  "onboarding.completed",
3661
3644
  "session.revoked",
3645
+ // Sign-in is served from its own origin, so a session cannot be carried
3646
+ // across to the console by cookie; it is re-issued there from a one-time
3647
+ // code. Recorded at both ends, so the trail shows one session ending and
3648
+ // its replacement beginning rather than an unexplained gap.
3649
+ "session.handed_over",
3662
3650
  "cli.authorization_approved",
3663
3651
  "cli.authorization_denied",
3664
3652
  "cli.session_issued",
@@ -7497,7 +7485,7 @@ import { homedir as homedir2 } from "node:os";
7497
7485
  import path11 from "node:path";
7498
7486
 
7499
7487
  // src/version.ts
7500
- var CLI_VERSION = "1.4.0";
7488
+ var CLI_VERSION = "1.4.1";
7501
7489
 
7502
7490
  // src/panel.ts
7503
7491
  function welcomeSource(flags = {}) {
@@ -8164,20 +8152,36 @@ async function homeCommand(args, flags) {
8164
8152
  return await homeLoop(args, flags);
8165
8153
  } finally {
8166
8154
  leaveApp();
8155
+ printFarewell();
8167
8156
  }
8168
8157
  }
8158
+ var farewellPrinted = false;
8159
+ function printFarewell() {
8160
+ if (!isInteractive() || inApp() || farewellPrinted) return;
8161
+ const project = readProjectConfig();
8162
+ if (!project) return;
8163
+ farewellPrinted = true;
8164
+ out();
8165
+ out(
8166
+ `${brand(style.bold("Veefore"))} ${style.grey("\xB7")} ${style.bold(project.agentName)} ${style.grey(`\xB7 ${project.environmentName} \xB7 ${project.controlPlaneUrl}`)}`
8167
+ );
8168
+ out(style.grey(" veefore dev watch decisions live"));
8169
+ out(style.grey(" veefore doctor check the security posture"));
8170
+ out(style.grey(" veefore open this again"));
8171
+ out();
8172
+ }
8169
8173
  async function homeLoop(args, flags) {
8170
8174
  const source = welcomeSource(flags);
8171
8175
  let first = true;
8172
8176
  for (; ; ) {
8173
8177
  if (readProjectConfig()) return initCommand(args, flags);
8174
8178
  const body = () => {
8175
- drawScreen(source, { reserve: 11 });
8179
+ drawScreen(source);
8176
8180
  out();
8177
8181
  out(style.bold("Let's get started."));
8178
8182
  out();
8179
8183
  };
8180
- await beginScreen(source, { animate: first, reserve: 11 });
8184
+ await beginScreen(source, { animate: first });
8181
8185
  first = false;
8182
8186
  out();
8183
8187
  out(style.bold("Let's get started."));
@@ -8209,7 +8213,11 @@ async function homeLoop(args, flags) {
8209
8213
  // Setup done: "Continue", and the next pass opens the project home
8210
8214
  // with the panel filled in. Otherwise "Back to menu", to read why and
8211
8215
  // choose again.
8212
- label: () => readProjectConfig() ? "Continue" : "Back to menu"
8216
+ label: () => readProjectConfig() ? "Continue" : "Back to menu",
8217
+ // Setup asks questions and draws its own screens as it goes, so it has
8218
+ // to reach the terminal as it runs. Collecting it would hold those
8219
+ // screens back and then print them all at once.
8220
+ live: true
8213
8221
  });
8214
8222
  continue;
8215
8223
  }
@@ -8234,12 +8242,8 @@ async function initWithWelcome(args, flags) {
8234
8242
  return initCommand(args, flags);
8235
8243
  }
8236
8244
  async function runOnScreen(source, flags, run2, options = {}) {
8237
- const header = () => {
8238
- out();
8239
- compactHeader(source());
8240
- };
8245
+ const header = () => drawScreen(source);
8241
8246
  if (options.live) {
8242
- clearScreen();
8243
8247
  header();
8244
8248
  let code2 = 0;
8245
8249
  try {
@@ -8708,7 +8712,7 @@ async function selectEnvironment(api, me, workspaceId, options, flags) {
8708
8712
  }
8709
8713
  }
8710
8714
  async function stepScreen(source, decided, step, total) {
8711
- await beginScreen(source, { compact: true });
8715
+ await beginScreen(source);
8712
8716
  out();
8713
8717
  out(` ${style.bold("Set up this project")} ${style.grey(`step ${step} of ${total}`)}`);
8714
8718
  if (decided.length > 0) {
@@ -8943,13 +8947,14 @@ async function projectHome(existing, flags) {
8943
8947
  return await projectHomeLoop(existing, flags);
8944
8948
  } finally {
8945
8949
  leaveApp();
8950
+ printFarewell();
8946
8951
  }
8947
8952
  }
8948
8953
  async function projectHomeLoop(existing, flags) {
8949
8954
  const source = welcomeSource(flags);
8950
8955
  let last = 0;
8951
8956
  for (let round = 0; ; round += 1) {
8952
- await beginScreen(source, { animate: round === 0, reserve: 18 });
8957
+ await beginScreen(source, { animate: round === 0 });
8953
8958
  const state = await agentState(existing);
8954
8959
  printProjectSummary(existing, state);
8955
8960
  const choices = homeChoices(existing, state, flags);
@@ -8964,7 +8969,7 @@ async function projectHomeLoop(existing, flags) {
8964
8969
  // Repainted as soon as a sign-in, sign-out or project change is
8965
8970
  // noticed, so the panel and the status never sit stale.
8966
8971
  redraw: () => {
8967
- drawScreen(source, { reserve: 18 });
8972
+ drawScreen(source);
8968
8973
  printProjectSummary(existing, state);
8969
8974
  out();
8970
8975
  }
@@ -8976,8 +8981,7 @@ async function projectHomeLoop(existing, flags) {
8976
8981
  }
8977
8982
  if (picked.leaves) {
8978
8983
  return onOrdinaryScreen(async () => {
8979
- clearScreen();
8980
- compactHeader(source());
8984
+ drawScreen(source);
8981
8985
  try {
8982
8986
  return await picked.run();
8983
8987
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veefore",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "Veefore command line: sign in, scan an agent project, set it up and protect its tools.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://veefore.com",