lazyclaw 4.2.1 → 4.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.
Files changed (2) hide show
  1. package/cli.mjs +49 -39
  2. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -1484,28 +1484,28 @@ function _attachGhostAutocomplete(rl) {
1484
1484
  // Width-management rule: every inner line is forced through
1485
1485
  // `.padEnd(W)` so a stray width miscount can't punch the right
1486
1486
  // border off the box (which is exactly the bug v3.99.5 shipped:
1487
- // v4.2.2 — restore the original v3.99.11-era banner: a figlet
1488
- // "lazy" wordmark (small font, 4 rows) inside a 30-col rounded box
1489
- // with a "LazyClaw |__/ v<ver>" caption sharing the last inner row
1490
- // with the descender of the `y`. This is the banner that shipped
1491
- // before the helmet-mascot / 8-bit-crab / emoji detours, and the one
1492
- // the user kept in muscle memory.
1487
+ // v4.2.2 — boxed figlet "lazy" wordmark, single-colour orange. The
1488
+ // previous mixed-colour banner (helmet-red letter art + ink-beige
1489
+ // caption) read as "two banners glued together" because the colour
1490
+ // changed mid-box. We use one warm orange (#F08246) for everything
1491
+ // border, letter art, caption so the eye reads it as one badge.
1493
1492
  //
1494
- // Layout invariant: every inner row is exactly 30 visible cells (no
1495
- // double-width glyphs, all chars are 1 cell in any monospace font),
1496
- // so the right edge `│` always lands in the same column.
1493
+ // Letter art is figlet "standard" (6 rows) rather than the v3.99.11
1494
+ // "small" (4 rows), because small renders as a pixel mush in most
1495
+ // terminal fonts. Standard's strokes are wide enough that the
1496
+ // letters read as `l a z y` even at small terminal sizes.
1497
1497
  //
1498
- // _renderMascot / _renderMascotTiny are kept as stubs because the
1499
- // _renderBanner caller still passes a row array around; they no
1500
- // longer drive separate art for working/done/error since the box-
1501
- // banner has no good place to flash those states. The router and
1502
- // loop runners that used to ask for a state-coloured tiny mascot can
1503
- // keep importing the helper; it just returns the wordmark.
1498
+ // Layout invariant: every inner row is exactly INNER_W visible cells
1499
+ // (no double-width glyphs, all chars are 1 cell in any monospace
1500
+ // font), so the right edge `│` always lands in the same column.
1501
+ //
1502
+ // _renderMascot / _renderMascotTiny are kept as stubs so any leftover
1503
+ // caller doesn't crash; no state-coloured art is produced any more.
1504
+
1505
+ const _ORANGE_RGB = '241;130;70'; // #F18246
1506
+ function _orange(s) { return `\x1b[38;2;${_ORANGE_RGB}m${s}\x1b[0m`; }
1504
1507
 
1505
1508
  function _renderMascot() {
1506
- // Banner builds its own art; this stub exists so any leftover
1507
- // caller doesn't crash. One element so .map() and length checks
1508
- // behave like the legacy shape.
1509
1509
  return ['lazyclaw'];
1510
1510
  }
1511
1511
 
@@ -1513,39 +1513,49 @@ function _renderMascotTiny() {
1513
1513
  return 'lazyclaw';
1514
1514
  }
1515
1515
 
1516
+ // figlet "standard" "lazy", trimmed of leading blank line. Each row
1517
+ // is left-padded by two spaces inside the box, and every row is then
1518
+ // padded to INNER_W cells.
1519
+ const _LAZY_STANDARD = [
1520
+ ' _ ',
1521
+ '| | __ _ _____ _ ',
1522
+ '| |/ _` |_ / | | | ',
1523
+ '| | (_| |/ /| |_| | ',
1524
+ '|_|\\__,_/___|\\__, | ',
1525
+ ' |___/ ',
1526
+ ];
1527
+
1528
+ const _INNER_W = 32; // 2 left pad + 20 letter art + caption headroom
1529
+
1516
1530
  function _renderBanner(version) {
1517
- const helmet = (s) => `\x1b[38;2;195;61;42m${s}\x1b[0m`;
1518
- const ink = (s) => `\x1b[38;2;241;234;217m${s}\x1b[0m`;
1519
1531
  const v = String(version || '?.?.?');
1520
- // Caption shares the final inner row with the `|__/` descender of
1521
- // the `y` from figlet-small, exactly like the v3.99.11 screenshot.
1522
- const cap = ` LazyClaw |__/ v${v}`.padEnd(30, ' ').slice(0, 30);
1523
- const top = '╭' + '─'.repeat(30) + '╮';
1524
- const bot = '╰' + '─'.repeat(30) + '╯';
1525
- const wrap = (inner) => helmet('│') + inner + helmet('│');
1532
+ const cap = ` LazyClaw v${v}`;
1533
+ const padInner = (s) => ' ' + s.padEnd(_INNER_W - 2, ' ');
1534
+ const wrap = (inner) => _orange('│') + _orange(inner) + _orange('│');
1535
+ const top = _orange('╭' + '─'.repeat(_INNER_W) + '╮');
1536
+ const bot = _orange('╰' + '─'.repeat(_INNER_W) + '╯');
1526
1537
  return [
1527
- helmet(top),
1528
- wrap(helmet(' _ ')),
1529
- wrap(helmet(' | |__ _ _____ _ _ ')),
1530
- wrap(helmet(` | / _\` |_ / || | '_| `)),
1531
- wrap(helmet(` |_\\__,_/__\\_, |_| `)),
1532
- wrap(ink(cap)),
1533
- helmet(bot),
1538
+ top,
1539
+ ..._LAZY_STANDARD.map((row) => wrap(padInner(row))),
1540
+ wrap(padInner(cap)),
1541
+ bot,
1534
1542
  ];
1535
1543
  }
1536
1544
 
1537
1545
  function _printChatBanner(activeProvName, activeModel, version) {
1538
1546
  if (!process.stdout.isTTY) return;
1539
- const dim = (s) => `\x1b[2m${s}\x1b[0m`;
1540
- const ok = (s) => `\x1b[32m${s}\x1b[0m`;
1547
+ // Single-hue header: labels dim-orange, values/emphasis full-orange, so the
1548
+ // four caption rows below the box read as part of the same warm badge.
1549
+ const dimOrange = (s) => `\x1b[2m\x1b[38;2;${_ORANGE_RGB}m${s}\x1b[0m`;
1550
+ const orange = _orange;
1541
1551
  const lines = [
1542
1552
  '',
1543
1553
  ..._renderBanner(version),
1544
1554
  '',
1545
- ` ${dim('provider ·')} ${ok(activeProvName)}`,
1546
- ` ${dim('model ·')} ${ok(activeModel || '(default)')}`,
1547
- ` ${dim('slash ·')} /help · /model · /provider · /exit`,
1548
- ` ${dim('hint ·')} → ${dim('to accept the suggested command,')} Tab ${dim('to cycle')}`,
1555
+ ` ${dimOrange('provider ·')} ${orange(activeProvName)}`,
1556
+ ` ${dimOrange('model ·')} ${orange(activeModel || '(default)')}`,
1557
+ ` ${dimOrange('slash ·')} ${orange('/help · /model · /provider · /exit')}`,
1558
+ ` ${dimOrange('hint ·')} ${orange('')} ${dimOrange('to accept the suggested command,')} ${orange('Tab')} ${dimOrange('to cycle')}`,
1549
1559
  '',
1550
1560
  ];
1551
1561
  process.stdout.write(lines.join('\n') + '\n');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lazyclaw",
3
- "version": "4.2.1",
3
+ "version": "4.2.2",
4
4
  "description": "Lazy, elegant terminal CLI for chatting with Claude / OpenAI / Gemini / Ollama, orchestrating multi-step LLM workflows, and running multi-agent Slack teams with cross-task memory. Banner-on-launch, slash-command ghost autocomplete, persistent sessions, local HTTP gateway.",
5
5
  "keywords": [
6
6
  "claude",