@vapi-network/cli 0.2.0 → 0.2.2

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/brand.d.ts CHANGED
@@ -1,13 +1,35 @@
1
- export declare const MARK_STEP_MS = 70;
1
+ /** Terminal cells are about twice as tall as wide; 21x9 keeps the 743x659 aspect. */
2
+ export declare const MARK_COLUMNS = 21;
3
+ export declare const MARK_ROWS = 9;
2
4
  export declare const WORDMARK = "vAPI Network";
3
- /** `ink` renders in the terminal's default foreground, like the black mark on paper. */
5
+ export declare const WELCOME = "Welcome to the vAPI Network";
6
+ export declare const TAGLINE: readonly ["The trusted network where agents", "and humans do business.", "", "Search APIs, pay per call, keep", "receipts. More coming soon."];
7
+ /** Design-token colours; `ink` renders in the terminal's own foreground colour. */
4
8
  export declare const MARK_PALETTE: {
5
- readonly orange: "#FF6A1A";
6
- readonly pink: "#FF3D8B";
7
- readonly lime: "#B8F32D";
8
- readonly cyan: "#22D3EE";
9
- readonly blue: "#0052FF";
10
- readonly purple: "#8B5CF6";
9
+ readonly orange: {
10
+ readonly hex: "#ff7300";
11
+ readonly ansi16: 33;
12
+ };
13
+ readonly pink: {
14
+ readonly hex: "#ff337c";
15
+ readonly ansi16: 95;
16
+ };
17
+ readonly lime: {
18
+ readonly hex: "#c3ff3d";
19
+ readonly ansi16: 92;
20
+ };
21
+ readonly cyan: {
22
+ readonly hex: "#97efff";
23
+ readonly ansi16: 96;
24
+ };
25
+ readonly blue: {
26
+ readonly hex: "#0041eb";
27
+ readonly ansi16: 34;
28
+ };
29
+ readonly purple: {
30
+ readonly hex: "#8a37fb";
31
+ readonly ansi16: 35;
32
+ };
11
33
  readonly ink: null;
12
34
  };
13
35
  export type MarkColorName = keyof typeof MARK_PALETTE;
@@ -16,37 +38,37 @@ export type MarkBlock = {
16
38
  x: number;
17
39
  width: number;
18
40
  color: MarkColorName;
19
- /** Reveal step; blocks that share a delay appear in the same frame. */
20
- delay: number;
21
41
  };
22
42
  export declare const MARK_BLOCKS: readonly MarkBlock[];
23
- export type MarkRenderOptions = {
24
- /** Emit 24-bit ANSI colour. Defaults to false so output stays pipe-safe. */
25
- color?: boolean;
26
- };
27
- export type BannerOptions = MarkRenderOptions & {
28
- version: string;
29
- };
30
- export type AnimateBannerOptions = BannerOptions & {
31
- write(chunk: string): void;
32
- stepMs?: number;
33
- sleep?(milliseconds: number): Promise<void>;
34
- };
35
- export type AnimationEnvironment = {
43
+ /** 0 = no colour, 1 = 16 colours, 2 = 256 colours, 3 = truecolour (the supports-color scale). */
44
+ export type ColorLevel = 0 | 1 | 2 | 3;
45
+ export type TerminalEnvironment = {
36
46
  isTty?: boolean;
37
- json?: boolean;
38
47
  env?: NodeJS.ProcessEnv;
39
48
  };
40
- /** Colour is off whenever `NO_COLOR` is set or stdout is not a terminal. */
41
- export declare function markColorEnabled(environment?: AnimationEnvironment): boolean;
42
- /** Animate only in an interactive, colour-capable, human-facing terminal. */
43
- export declare function shouldAnimateMark(environment?: AnimationEnvironment): boolean;
49
+ export type BannerOptions = {
50
+ version: string;
51
+ /** Defaults to 0 so output stays pipe-safe. */
52
+ colorLevel?: ColorLevel;
53
+ /** Terminal width; below the framed width the banner falls back to plain text. */
54
+ columns?: number;
55
+ };
56
+ /**
57
+ * Colour capability the way chalk's supports-color decides it: NO_COLOR and
58
+ * a redirected stdout disable colour, FORCE_COLOR overrides, and otherwise
59
+ * the terminal's own advertisement (COLORTERM, TERM, TERM_PROGRAM) picks
60
+ * the level. Apple Terminal advertises 256 colours, not truecolour.
61
+ */
62
+ export declare function detectColorLevel(environment?: TerminalEnvironment): ColorLevel;
63
+ /** The complete mark: `MARK_ROWS` lines of exactly `MARK_COLUMNS` visible cells. */
64
+ export declare function renderMark(colorLevel?: ColorLevel): string;
65
+ /** Width in columns of the framed banner. */
66
+ export declare function bannerWidth(): number;
44
67
  /**
45
- * Every reveal step of the mark, oldest first. Pure: the last frame is the
46
- * complete mark and each frame is exactly `MARK_ROWS` lines.
68
+ * The welcome banner: the mark on the left, the welcome text on the right,
69
+ * inside a rounded frame. When the terminal is narrower than the frame, the
70
+ * text alone is printed so nothing wraps.
47
71
  */
48
- export declare function renderMarkFrames(options?: MarkRenderOptions): string[];
49
- /** The complete mark with the wordmark and version beneath it. */
50
72
  export declare function renderBanner(options: BannerOptions): string;
51
- /** Reveal the mark in place, then print the wordmark and version. */
52
- export declare function animateBanner(options: AnimateBannerOptions): Promise<void>;
73
+ /** Nearest xterm 256-colour index, the same cube mapping chalk's ansi-styles uses. */
74
+ export declare function rgbToAnsi256(red: number, green: number, blue: number): number;
package/dist/cli.d.ts CHANGED
@@ -2,11 +2,6 @@ export declare const HELP = "vAPI Network\n\nUsage:\n vapi init [--networks <ba
2
2
  export type CliIo = {
3
3
  stdout(message: string): void;
4
4
  stderr(message: string): void;
5
- /**
6
- * Raw stdout sink for cursor control. Only an interactive terminal supplies
7
- * one; without it every banner falls back to a single static frame.
8
- */
9
- write?(chunk: string): void;
10
5
  };
11
6
  export type CliDependencies = {
12
7
  fetchImpl?: typeof fetch;
package/dist/cli.js CHANGED
@@ -46673,7 +46673,7 @@ function csvCell(value) {
46673
46673
  import { mkdir as mkdir6, writeFile as writeFile4 } from "node:fs/promises";
46674
46674
  import { arch, platform, release } from "node:os";
46675
46675
  import { join as join2 } from "node:path";
46676
- var VAPI_CLIENT_VERSION = "0.2.0";
46676
+ var VAPI_CLIENT_VERSION = "0.2.2";
46677
46677
  async function createSupportReport(options) {
46678
46678
  const message = options.message.trim();
46679
46679
  if (!message) throw new Error("Support report message must not be empty.");
@@ -48805,96 +48805,124 @@ function asRecord(value) {
48805
48805
 
48806
48806
  // src/brand.ts
48807
48807
  var MARK_SOURCE_WIDTH = 743;
48808
- var MARK_COLUMNS = 34;
48809
- var MARK_ROWS = 3;
48808
+ var MARK_SOURCE_HEIGHT = 659;
48809
+ var MARK_SOURCE_ROW_HEIGHT = 217;
48810
+ var MARK_COLUMNS = 21;
48811
+ var MARK_ROWS = 9;
48810
48812
  var BLOCK = "\u2588";
48811
- var MARK_STEP_MS = 70;
48812
48813
  var WORDMARK = "vAPI Network";
48813
- var RESET = "\x1B[0m";
48814
- var DEFAULT_FOREGROUND = "\x1B[39m";
48815
- var HIDE_CURSOR = "\x1B[?25l";
48816
- var SHOW_CURSOR = "\x1B[?25h";
48814
+ var WELCOME = "Welcome to the vAPI Network";
48815
+ var TAGLINE = [
48816
+ "The trusted network where agents",
48817
+ "and humans do business.",
48818
+ "",
48819
+ "Search APIs, pay per call, keep",
48820
+ "receipts. More coming soon."
48821
+ ];
48822
+ var ESC = String.fromCharCode(27);
48823
+ var RESET = `${ESC}[0m`;
48824
+ var BOLD = `${ESC}[1m`;
48825
+ var DIM = `${ESC}[2m`;
48826
+ var DEFAULT_FOREGROUND = `${ESC}[39m`;
48817
48827
  var MARK_PALETTE = {
48818
- orange: "#FF6A1A",
48819
- pink: "#FF3D8B",
48820
- lime: "#B8F32D",
48821
- cyan: "#22D3EE",
48822
- blue: "#0052FF",
48823
- purple: "#8B5CF6",
48828
+ orange: { hex: "#ff7300", ansi16: 33 },
48829
+ pink: { hex: "#ff337c", ansi16: 95 },
48830
+ lime: { hex: "#c3ff3d", ansi16: 92 },
48831
+ cyan: { hex: "#97efff", ansi16: 96 },
48832
+ blue: { hex: "#0041eb", ansi16: 34 },
48833
+ purple: { hex: "#8a37fb", ansi16: 35 },
48824
48834
  ink: null
48825
48835
  };
48826
48836
  var MARK_BLOCKS = [
48827
- { row: 0, x: 2, width: 90, color: "orange", delay: 0 },
48828
- { row: 0, x: 94, width: 35, color: "pink", delay: 1 },
48829
- { row: 0, x: 131, width: 16, color: "lime", delay: 2 },
48830
- { row: 0, x: 522, width: 219, color: "ink", delay: 1 },
48831
- { row: 1, x: 124, width: 50, color: "cyan", delay: 3 },
48832
- { row: 1, x: 176, width: 24, color: "blue", delay: 4 },
48833
- { row: 1, x: 202, width: 17, color: "purple", delay: 5 },
48834
- { row: 1, x: 402, width: 219, color: "blue", delay: 4 },
48835
- { row: 2, x: 282, width: 219, color: "ink", delay: 7 }
48837
+ { row: 0, x: 2, width: 90, color: "orange" },
48838
+ { row: 0, x: 94, width: 35, color: "pink" },
48839
+ { row: 0, x: 131, width: 16, color: "lime" },
48840
+ { row: 0, x: 522, width: 219, color: "ink" },
48841
+ { row: 1, x: 124, width: 50, color: "cyan" },
48842
+ { row: 1, x: 176, width: 24, color: "blue" },
48843
+ { row: 1, x: 202, width: 17, color: "purple" },
48844
+ { row: 1, x: 402, width: 219, color: "blue" },
48845
+ { row: 2, x: 282, width: 219, color: "ink" }
48836
48846
  ];
48837
- function markColorEnabled(environment = {}) {
48847
+ function detectColorLevel(environment = {}) {
48838
48848
  const env = environment.env ?? process.env;
48839
48849
  const isTty = environment.isTty ?? Boolean(process.stdout.isTTY);
48840
- return isTty && !env.NO_COLOR;
48841
- }
48842
- function shouldAnimateMark(environment = {}) {
48843
- const env = environment.env ?? process.env;
48844
- if (environment.json) return false;
48845
- if (env.NO_COLOR || env.CI) return false;
48846
- return markColorEnabled(environment);
48847
- }
48848
- function renderMarkFrames(options = {}) {
48849
- const steps = [...new Set(MARK_BLOCKS.map((block) => block.delay))].sort(
48850
- (left, right) => left - right
48851
- );
48852
- return steps.map(
48853
- (step) => renderFrame(
48854
- MARK_BLOCKS.filter((block) => block.delay <= step),
48855
- options.color === true
48856
- )
48857
- );
48858
- }
48859
- function renderBanner(options) {
48860
- const frames = renderMarkFrames(options);
48861
- return [frames[frames.length - 1], WORDMARK, `v${options.version}`].join("\n");
48862
- }
48863
- async function animateBanner(options) {
48864
- const frames = renderMarkFrames({ color: options.color !== false });
48865
- const sleep = options.sleep ?? defaultSleep;
48866
- const stepMs = options.stepMs ?? MARK_STEP_MS;
48867
- options.write(HIDE_CURSOR);
48868
- try {
48869
- for (const [index2, frame] of frames.entries()) {
48870
- if (index2 > 0) options.write(`\x1B[${MARK_ROWS}A`);
48871
- options.write(
48872
- frame.split("\n").map((line) => `\r\x1B[2K${line}
48873
- `).join("")
48874
- );
48875
- if (index2 < frames.length - 1) await sleep(stepMs);
48876
- }
48877
- } finally {
48878
- options.write(SHOW_CURSOR);
48850
+ if (env.NO_COLOR) return 0;
48851
+ const forced = env.FORCE_COLOR;
48852
+ if (forced !== void 0) {
48853
+ if (forced === "0" || forced === "false") return 0;
48854
+ if (forced === "2") return 2;
48855
+ if (forced === "3") return 3;
48856
+ return 1;
48879
48857
  }
48880
- options.write(`${WORDMARK}
48881
- `);
48882
- options.write(`v${options.version}
48883
- `);
48884
- }
48885
- function renderFrame(blocks, color) {
48858
+ if (!isTty) return 0;
48859
+ const term = env.TERM ?? "";
48860
+ const program = env.TERM_PROGRAM ?? "";
48861
+ if (term === "dumb") return 0;
48862
+ if (/^(truecolor|24bit)$/i.test(env.COLORTERM ?? "")) return 3;
48863
+ if (/kitty|wezterm|ghostty|alacritty/i.test(term)) return 3;
48864
+ if (/^(iTerm\.app|vscode|Hyper|WezTerm|ghostty)$/i.test(program)) return 3;
48865
+ if (/-256(?:color)?$/i.test(term) || program === "Apple_Terminal") return 2;
48866
+ return 1;
48867
+ }
48868
+ function renderMark(colorLevel = 0) {
48886
48869
  const rows = [];
48887
48870
  for (let row = 0; row < MARK_ROWS; row += 1) {
48871
+ const sourceY = row * MARK_SOURCE_HEIGHT / MARK_ROWS;
48872
+ const band = Math.min(2, Math.floor(sourceY / MARK_SOURCE_ROW_HEIGHT));
48888
48873
  rows.push(
48889
48874
  renderRow(
48890
- blocks.filter((block) => block.row === row),
48891
- color
48875
+ MARK_BLOCKS.filter((block) => block.row === band),
48876
+ colorLevel
48892
48877
  )
48893
48878
  );
48894
48879
  }
48895
48880
  return rows.join("\n");
48896
48881
  }
48897
- function renderRow(blocks, color) {
48882
+ function bannerWidth() {
48883
+ return frameInnerWidth() + 2;
48884
+ }
48885
+ function renderBanner(options) {
48886
+ const colorLevel = options.colorLevel ?? 0;
48887
+ const columns = options.columns ?? Number.POSITIVE_INFINITY;
48888
+ const text = bannerText(options.version, colorLevel);
48889
+ if (columns < bannerWidth()) {
48890
+ return text.map((line) => line.styled).join("\n");
48891
+ }
48892
+ const inner = frameInnerWidth();
48893
+ const markLines = renderMark(colorLevel).split("\n");
48894
+ const lines = [];
48895
+ lines.push(`\u256D${"\u2500".repeat(inner)}\u256E`);
48896
+ lines.push(`\u2502${" ".repeat(inner)}\u2502`);
48897
+ for (let row = 0; row < MARK_ROWS; row += 1) {
48898
+ const entry = text[row];
48899
+ const value = entry?.value ?? "";
48900
+ const styled = entry?.styled ?? "";
48901
+ const pad4 = " ".repeat(TEXT_WIDTH - value.length);
48902
+ lines.push(`\u2502 ${markLines[row]}${" ".repeat(GAP)}${styled}${pad4} \u2502`);
48903
+ }
48904
+ lines.push(`\u2502${" ".repeat(inner)}\u2502`);
48905
+ lines.push(`\u2570${"\u2500".repeat(inner)}\u256F`);
48906
+ return lines.join("\n");
48907
+ }
48908
+ var GAP = 3;
48909
+ var TEXT_WIDTH = Math.max(WELCOME.length, ...TAGLINE.map((line) => line.length));
48910
+ function frameInnerWidth() {
48911
+ return 2 + MARK_COLUMNS + GAP + TEXT_WIDTH + 2;
48912
+ }
48913
+ function bannerText(version5, colorLevel) {
48914
+ const style = (value, code) => colorLevel > 0 && value ? `${code}${value}${RESET}` : value;
48915
+ const rows = [
48916
+ { value: WELCOME, styled: style(WELCOME, BOLD) },
48917
+ { value: "", styled: "" },
48918
+ ...TAGLINE.map((line) => ({ value: line, styled: line })),
48919
+ { value: "", styled: "" },
48920
+ { value: `${WORDMARK} v${version5}`, styled: style(`${WORDMARK} v${version5}`, DIM) }
48921
+ ];
48922
+ if (rows.length > MARK_ROWS) throw new Error("banner text is taller than the mark");
48923
+ return rows;
48924
+ }
48925
+ function renderRow(blocks, colorLevel) {
48898
48926
  const ordered = [...blocks].sort((left, right) => left.x - right.x);
48899
48927
  let column = 0;
48900
48928
  let line = "";
@@ -48905,11 +48933,11 @@ function renderRow(blocks, color) {
48905
48933
  column = start;
48906
48934
  }
48907
48935
  const width = scaleWidth(block.width);
48908
- const glyphs = BLOCK.repeat(width);
48909
- line += color ? `${ansiPrefix(block.color)}${glyphs}${RESET}` : glyphs;
48936
+ const cells = BLOCK.repeat(width);
48937
+ line += colorLevel > 0 ? `${foreground(block.color, colorLevel)}${cells}${RESET}` : cells;
48910
48938
  column += width;
48911
48939
  }
48912
- return line;
48940
+ return line + " ".repeat(Math.max(0, MARK_COLUMNS - column));
48913
48941
  }
48914
48942
  function scaleColumn(x) {
48915
48943
  return Math.round(x * MARK_COLUMNS / MARK_SOURCE_WIDTH);
@@ -48917,20 +48945,28 @@ function scaleColumn(x) {
48917
48945
  function scaleWidth(width) {
48918
48946
  return Math.max(1, Math.round(width * MARK_COLUMNS / MARK_SOURCE_WIDTH));
48919
48947
  }
48920
- function ansiPrefix(color) {
48921
- const hex3 = MARK_PALETTE[color];
48922
- if (hex3 === null) return DEFAULT_FOREGROUND;
48923
- const value = Number.parseInt(hex3.slice(1), 16);
48924
- return `\x1B[38;2;${value >> 16 & 255};${value >> 8 & 255};${value & 255}m`;
48948
+ function foreground(color, colorLevel) {
48949
+ const entry = MARK_PALETTE[color];
48950
+ if (entry === null) return DEFAULT_FOREGROUND;
48951
+ const value = Number.parseInt(entry.hex.slice(1), 16);
48952
+ const red = value >> 16 & 255;
48953
+ const green = value >> 8 & 255;
48954
+ const blue = value & 255;
48955
+ if (colorLevel === 3) return `${ESC}[38;2;${red};${green};${blue}m`;
48956
+ if (colorLevel === 2) return `${ESC}[38;5;${rgbToAnsi256(red, green, blue)}m`;
48957
+ return `${ESC}[${entry.ansi16}m`;
48925
48958
  }
48926
- function defaultSleep(milliseconds) {
48927
- return new Promise((resolve) => {
48928
- setTimeout(resolve, milliseconds);
48929
- });
48959
+ function rgbToAnsi256(red, green, blue) {
48960
+ if (red === green && green === blue) {
48961
+ if (red < 8) return 16;
48962
+ if (red > 248) return 231;
48963
+ return Math.round((red - 8) / 247 * 24) + 232;
48964
+ }
48965
+ return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
48930
48966
  }
48931
48967
 
48932
48968
  // src/version.ts
48933
- var CLI_VERSION = "0.2.0";
48969
+ var CLI_VERSION = "0.2.2";
48934
48970
 
48935
48971
  // src/cli.ts
48936
48972
  var HELP_HEADING = "vAPI Network";
@@ -48959,8 +48995,7 @@ var processIo = {
48959
48995
  stdout: (message) => process.stdout.write(`${message}
48960
48996
  `),
48961
48997
  stderr: (message) => process.stderr.write(`${message}
48962
- `),
48963
- write: (chunk) => process.stdout.write(chunk)
48998
+ `)
48964
48999
  };
48965
49000
  var UsageError = class extends Error {
48966
49001
  };
@@ -48979,7 +49014,7 @@ async function runCli(argv = process.argv.slice(2), io = processIo, dependencies
48979
49014
  if (command === void 0 || command === "help" || command === "--help" || command === "-h") {
48980
49015
  requireNoArguments(args.slice(command === void 0 ? 0 : 1), command ?? "help");
48981
49016
  if (command === void 0 && !json2) {
48982
- io.stdout(staticBanner());
49017
+ showBanner(io);
48983
49018
  io.stdout(HELP.slice(HELP_HEADING.length + 2));
48984
49019
  return 0;
48985
49020
  }
@@ -49050,7 +49085,7 @@ async function initCommand(argv, json2, io, dependencies) {
49050
49085
  });
49051
49086
  const networks = parseInitNetworks(parsed.one("--networks") ?? "base");
49052
49087
  const enableSolana = networks.includes("solana");
49053
- if (!json2) await showBanner(io);
49088
+ if (!json2) showBanner(io);
49054
49089
  const paths = getVapiPaths();
49055
49090
  let migrated = [];
49056
49091
  if (!process.env.VAPI_HOME?.trim()) {
@@ -49412,16 +49447,14 @@ function formatNextStep(label, value, note) {
49412
49447
  const step = `${label.padEnd(10)}${value}`;
49413
49448
  return note === void 0 ? step : `${step.padEnd(52)} ${note}`;
49414
49449
  }
49415
- async function showBanner(io) {
49416
- const write = io.write;
49417
- if (write === void 0 || !shouldAnimateMark()) {
49418
- io.stdout(staticBanner());
49419
- return;
49420
- }
49421
- await animateBanner({ version: CLI_VERSION, write });
49422
- }
49423
- function staticBanner() {
49424
- return renderBanner({ version: CLI_VERSION, color: markColorEnabled() });
49450
+ function showBanner(io) {
49451
+ io.stdout(
49452
+ renderBanner({
49453
+ version: CLI_VERSION,
49454
+ colorLevel: detectColorLevel(),
49455
+ columns: process.stdout.columns
49456
+ })
49457
+ );
49425
49458
  }
49426
49459
  function formatAccounts(accounts) {
49427
49460
  if (accounts.length === 0) return "No configured network accounts.";