@lazyingart/agintiflow 0.17.4 → 0.17.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.17.4",
3
+ "version": "0.17.6",
4
4
  "type": "module",
5
5
  "description": "AgInTiFlow is a resumable Playwright website-control agent with OpenAI-compatible tool calling.",
6
6
  "license": "Apache-2.0",
@@ -4,7 +4,7 @@ import fs from "node:fs/promises";
4
4
  import os from "node:os";
5
5
  import path from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
- import { buildPromptLayout, classifyEscapeAction, formatWorkspaceChange, stripMarkdown } from "../src/interactive-cli.js";
7
+ import { buildLaunchHeaderLines, buildPromptLayout, classifyEscapeAction, formatWorkspaceChange, stripMarkdown } from "../src/interactive-cli.js";
8
8
 
9
9
  const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
10
10
  const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "agintiflow-cli-chat-"));
@@ -100,6 +100,10 @@ try {
100
100
  ) {
101
101
  throw new Error("workspace patch event formatter did not preserve red/green diff content");
102
102
  }
103
+ const launchHeader = buildLaunchHeaderLines({ width: 120, packageVersion: "0.0.0", animated: false }).join("\n");
104
+ if (!launchHeader.includes("█████") || !launchHeader.includes("v0.0.0") || launchHeader.split("\n").length < 9) {
105
+ throw new Error("large launch header did not render a centered multi-line title");
106
+ }
103
107
 
104
108
  const promptLayout = buildPromptLayout(`${"x".repeat(180)}\nsecond line`, 95, 80, 24);
105
109
  const promptText = promptLayout.renderedRows
@@ -205,6 +209,7 @@ try {
205
209
  "markdown-table-no-duplicate",
206
210
  "patch-diff-render",
207
211
  "workspace-patch-event-render",
212
+ "large-launch-header",
208
213
  "prompt-layout",
209
214
  "user-prompt-label",
210
215
  "escape-policy",
@@ -107,7 +107,7 @@ function boxedLine(content, width) {
107
107
  function secretInputDisplay({ value, selectedPreview, placeholder }) {
108
108
  if (value) return color(`${"•".repeat(Math.min(value.length, 24))} (${value.length} chars)`, ansi.inputBg);
109
109
  if (selectedPreview) return `${color(` ${selectedPreview} `, ansi.selected, ansi.bold)} ${color("selected", ansi.yellow)}`;
110
- return color(placeholder || "paste key here", ansi.dim);
110
+ return color(String(placeholder || "").padEnd(30, " "), ansi.inputBg);
111
111
  }
112
112
 
113
113
  function renderSecretBox({ title, helpText, statusText, currentPreview, value, selected, actionText }) {
@@ -119,7 +119,7 @@ function renderSecretBox({ title, helpText, statusText, currentPreview, value, s
119
119
  boxedLine(color(compactLine(title, inner), ansi.bold, ansi.cyan), width),
120
120
  helpText ? boxedLine(`${color("key", ansi.muted)} ${compactLine(helpText, inner - 6)}`, width) : "",
121
121
  statusText ? boxedLine(`${color("status", ansi.muted)} ${compactLine(statusText, inner - 8)}`, width) : "",
122
- boxedLine(`${color("input", ansi.muted)} ${secretInputDisplay({ value, selectedPreview, placeholder: "hidden input" })}`, width),
122
+ boxedLine(`${color("input", ansi.muted)} ${secretInputDisplay({ value, selectedPreview })}`, width),
123
123
  boxedLine(color(compactLine(actionText, inner), ansi.dim), width),
124
124
  `${color("╰", ansi.border)}${color("─", ansi.border).repeat(width - 2)}${color("╯", ansi.border)}`,
125
125
  ].filter(Boolean);
@@ -33,6 +33,15 @@ const ansi = {
33
33
  systemBg: "\x1b[48;5;236m\x1b[38;5;245m",
34
34
  };
35
35
  const brandPalette = ["\x1b[38;5;45m", "\x1b[38;5;81m", "\x1b[38;5;86m", "\x1b[38;5;118m", "\x1b[38;5;226m"];
36
+ const LARGE_LAUNCH_TITLE = [
37
+ " █████╗ ██████╗ ██╗███╗ ██╗████████╗██╗ ███████╗██╗ ██████╗ ██╗ ██╗",
38
+ "██╔══██╗██╔════╝ ██║████╗ ██║╚══██╔══╝██║ ██╔════╝██║ ██╔═══██╗██║ ██║",
39
+ "███████║██║ ███╗██║██╔██╗ ██║ ██║ ██║ █████╗ ██║ ██║ ██║██║ █╗ ██║",
40
+ "██╔══██║██║ ██║██║██║╚██╗██║ ██║ ██║ ██╔══╝ ██║ ██║ ██║██║███╗██║",
41
+ "██║ ██║╚██████╔╝██║██║ ╚████║ ██║ ██║ ██║ ███████╗╚██████╔╝╚███╔███╔╝",
42
+ "╚═╝ ╚═╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝ ",
43
+ ];
44
+ const COMPACT_LAUNCH_TITLE = ["AgInTi Flow"];
36
45
  const SLASH_COMMANDS = [
37
46
  "/help",
38
47
  "/status",
@@ -483,37 +492,62 @@ function shimmerText(text, frame) {
483
492
  .join("");
484
493
  }
485
494
 
486
- async function renderLaunchHeader(packageVersion = "") {
487
- const title = "AgInTi Flow";
495
+ function centerLine(value, width) {
496
+ const text = String(value || "");
497
+ return `${" ".repeat(Math.max(Math.floor((width - visualLength(text)) / 2), 0))}${text}`;
498
+ }
499
+
500
+ function launchTitleLines(contentWidth) {
501
+ const largeWidth = Math.max(...LARGE_LAUNCH_TITLE.map((line) => visualLength(line)));
502
+ return largeWidth <= contentWidth ? LARGE_LAUNCH_TITLE : COMPACT_LAUNCH_TITLE;
503
+ }
504
+
505
+ export function buildLaunchHeaderLines({ packageVersion = "", frame = 2, width = terminalWidth(), animated = true } = {}) {
488
506
  const subtitle = "web-first agent workspace";
507
+ const tagline = "browser + shell + files + docker + web search + scouts";
489
508
  const version = packageVersion ? `v${packageVersion}` : "";
490
- const width = Math.min(Math.max(terminalWidth() - 2, 58), 82);
491
- const top = `╭${"─".repeat(width)}╮`;
492
- const mid = `├${"─".repeat(width)}┤`;
493
- const bottom = `╰${"─".repeat(width)}╯`;
509
+ const terminalColumns = Math.max(Number(width) || 80, 50);
510
+ const contentWidth = Math.min(Math.max(terminalColumns - 8, 58), 112);
511
+ const titleLines = launchTitleLines(contentWidth).map((line, index) => centerLine(animated ? shimmerText(line, frame + index) : line, contentWidth));
512
+ const borderWidth = contentWidth + 2;
513
+ const border = "\x1b[38;5;45m";
514
+ const top = color(`╭${"─".repeat(borderWidth)}╮`, border);
515
+ const mid = color(`├${"─".repeat(borderWidth)}┤`, border);
516
+ const bottom = color(`╰${"─".repeat(borderWidth)}╯`, border);
517
+ const row = (content = "", code = "") => `${color("│", border)} ${code ? color(padVisible(content, contentWidth), code) : padVisible(content, contentWidth)} ${color("│", border)}`;
518
+ const versionLine = version ? centerLine(color(version, ansi.dim), contentWidth) : "";
519
+ const boxLines = [
520
+ top,
521
+ ...titleLines.map((line) => row(line)),
522
+ versionLine ? row(versionLine) : "",
523
+ row(centerLine(subtitle, contentWidth), ansi.dim),
524
+ mid,
525
+ row(centerLine(tagline, contentWidth), ansi.cyan),
526
+ bottom,
527
+ ].filter(Boolean);
528
+ const indent = " ".repeat(Math.max(Math.floor((terminalColumns - Math.max(...boxLines.map((line) => visualLength(line)))) / 2), 0));
529
+ return boxLines.map((line) => `${indent}${line}`);
530
+ }
494
531
 
532
+ async function renderLaunchHeader(packageVersion = "") {
495
533
  if (!useColor || process.env.AGINTIFLOW_NO_ANIMATION === "1") {
496
- console.log(` AgInTiFlow ${packageVersion || ""}`.trim());
534
+ console.log(buildLaunchHeaderLines({ packageVersion, animated: false }).join("\n"));
497
535
  return;
498
536
  }
499
537
 
538
+ const topPadding = Math.min(Math.max(Math.floor((terminalHeight() - 28) / 8), 0), 2);
539
+ const paddingLines = Array.from({ length: topPadding }, () => "");
540
+ let previousLineCount = 0;
500
541
  output.write(ansi.cursorHide);
501
542
  for (let frame = 0; frame < 18; frame += 1) {
502
- output.write(`\r${ansi.clearLine}${shimmerText(title, frame)} ${color("is starting", ansi.dim)}`);
543
+ const lines = [...paddingLines, ...buildLaunchHeaderLines({ packageVersion, frame, animated: true })];
544
+ if (previousLineCount > 0) output.write(`\x1b[${previousLineCount}A`);
545
+ output.write(lines.map((line) => `\r${ansi.clearLine}${line}`).join("\n"));
546
+ output.write("\n");
547
+ previousLineCount = lines.length;
503
548
  await sleep(32);
504
549
  }
505
- output.write(`\r${ansi.clearLine}`);
506
550
  output.write(ansi.cursorShow);
507
-
508
- const border = "\x1b[38;5;45m";
509
- const titleLine = `${shimmerText(title, 2)} ${color(version, ansi.dim)}`;
510
- const tagline = "browser + shell + files + docker + web search + scouts";
511
- console.log(color(top, border));
512
- console.log(`${color("│", border)} ${padVisible(titleLine, width - 2)} ${color("│", border)}`);
513
- console.log(`${color("│", border)} ${color(padVisible(subtitle, width - 2), ansi.dim)} ${color("│", border)}`);
514
- console.log(color(mid, border));
515
- console.log(`${color("│", border)} ${color(padVisible(tagline, width - 2), ansi.cyan)} ${color("│", border)}`);
516
- console.log(color(bottom, border));
517
551
  }
518
552
 
519
553
  function printHelp() {