@stevezhou/sisu 0.1.8 → 0.1.9

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/logo.js CHANGED
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "sisuTreeArt", { enumerable: true, get: function
18
18
  Object.defineProperty(exports, "sisuTreeLines", { enumerable: true, get: function () { return tree_1.sisuTreeLines; } });
19
19
  const mark_2 = require("./mark");
20
20
  const mobius_1 = require("./mobius");
21
+ const theme_1 = require("./pager/theme");
21
22
  const RESET = '\x1b[0m';
22
23
  const INK = '\x1b[38;2;220;214;204m';
23
24
  const INK_DIM = '\x1b[38;2;140;132;120m';
@@ -33,24 +34,8 @@ function sisuMobiusArt(columns = 80, phase = 0, color = false) {
33
34
  function sisuWordmark() {
34
35
  return ['思溯', 'SISU'].join('\n');
35
36
  }
36
- /** Terminal cells, not JS string length — CJK and ∞ must sit on the grid. */
37
37
  function displayWidth(text) {
38
- let width = 0;
39
- for (const ch of stripAnsi(text)) {
40
- const code = ch.codePointAt(0) ?? 0;
41
- width += isWide(code) ? 2 : 1;
42
- }
43
- return width;
44
- }
45
- function isWide(code) {
46
- return ((code >= 0x1100 && code <= 0x115f) ||
47
- (code >= 0x2e80 && code <= 0xa4cf && code !== 0x303f) ||
48
- (code >= 0xac00 && code <= 0xd7a3) ||
49
- (code >= 0xf900 && code <= 0xfaff) ||
50
- (code >= 0xfe10 && code <= 0xfe19) ||
51
- (code >= 0xfe30 && code <= 0xfe6f) ||
52
- (code >= 0xff00 && code <= 0xff60) ||
53
- (code >= 0xffe0 && code <= 0xffe6));
38
+ return (0, theme_1.visibleWidth)(text);
54
39
  }
55
40
  function paint(text, prefix, color) {
56
41
  if (!color || !text)
@@ -67,7 +52,7 @@ function lockup(color) {
67
52
  const inf = infinityMark(color);
68
53
  const name = paint('思溯', INK, color);
69
54
  const latin = paint('SiSu', INK_DIM, color);
70
- return [`${inf} ${name}`, ` ${latin}`];
55
+ return [`${inf} ${name}`, latin];
71
56
  }
72
57
  function padLeft(text, n) {
73
58
  return `${' '.repeat(Math.max(0, n))}${text}`;
package/dist/pager/app.js CHANGED
@@ -106,7 +106,7 @@ async function runPager(io, transport, options = {}) {
106
106
  const paint = (phase = logo_1.SISU_STILL_PHASE) => {
107
107
  if (!running)
108
108
  return;
109
- io.write(`\x1b[H${(0, render_1.renderPager)(state, cols, rows, theme, { phase })}`);
109
+ io.write(`\x1b[H${(0, render_1.renderPager)(state, cols, rows, theme, { phase })}\x1b[J`);
110
110
  };
111
111
  const playIntro = async () => {
112
112
  const frames = Math.max(2, options.introFrames ?? 32);
@@ -156,13 +156,17 @@ function renderPager(state, cols, rows, themeName = 'dark', view = {}) {
156
156
  const laid = layoutScrollback(state, width, theme);
157
157
  const lastEntry = Math.max(0, state.entries.length - 1);
158
158
  const visibleScroll = windowAroundSelected(laid.lines, laid.entryOf, state.selected, scrollBudget, lastEntry);
159
- const body = [];
160
- body.push(...welcome.slice(0, welcomeTake));
161
- while (body.length + visibleScroll.length < welcomeTake + scrollBudget) {
162
- body.push('');
163
- }
164
- body.push(...visibleScroll);
165
- body.push(...slash.slice(0, slashTake));
159
+ const shownWelcome = welcome.slice(0, welcomeTake);
160
+ const extra = Math.max(0, welcomeTake + scrollBudget - shownWelcome.length - visibleScroll.length);
161
+ const padTop = isIdleWelcome(state) && visibleScroll.length === 0 ? Math.floor(extra / 2) : 0;
162
+ const padBot = extra - padTop;
163
+ const body = [
164
+ ...Array.from({ length: padTop }, () => ''),
165
+ ...shownWelcome,
166
+ ...Array.from({ length: padBot }, () => ''),
167
+ ...visibleScroll,
168
+ ...slash.slice(0, slashTake),
169
+ ];
166
170
  const lines = body.map((line) => (0, theme_1.padVisible)(line, width));
167
171
  if (statusRows > 0) {
168
172
  lines.push((0, theme_1.padVisible)(theme.dim(state.statusLine ?? ''), width));
@@ -42,8 +42,26 @@ function getTheme(name = 'dark') {
42
42
  function stripAnsi(s) {
43
43
  return s.replace(/\x1b\[[0-9;]*m/g, '');
44
44
  }
45
+ function isWide(code) {
46
+ return ((code >= 0x1100 && code <= 0x115f) ||
47
+ (code >= 0x2e80 && code <= 0xa4cf && code !== 0x303f) ||
48
+ (code >= 0xac00 && code <= 0xd7a3) ||
49
+ (code >= 0xf900 && code <= 0xfaff) ||
50
+ (code >= 0xfe10 && code <= 0xfe19) ||
51
+ (code >= 0xfe30 && code <= 0xfe6f) ||
52
+ (code >= 0xff00 && code <= 0xff60) ||
53
+ (code >= 0xffe0 && code <= 0xffe6));
54
+ }
55
+ function charWidth(ch) {
56
+ const code = ch.codePointAt(0) ?? 0;
57
+ return isWide(code) ? 2 : 1;
58
+ }
59
+ /** Terminal cells, not JS string length — CJK is two cells. */
45
60
  function visibleWidth(line) {
46
- return stripAnsi(line).length;
61
+ let width = 0;
62
+ for (const ch of stripAnsi(line))
63
+ width += charWidth(ch);
64
+ return width;
47
65
  }
48
66
  function clipVisible(line, width) {
49
67
  if (width <= 0)
@@ -55,23 +73,29 @@ function clipVisible(line, width) {
55
73
  const re = /\x1b\[[0-9;]*m/g;
56
74
  let last = 0;
57
75
  let match = re.exec(line);
58
- while (match) {
59
- for (let i = last; i < match.index && seen < width; i += 1) {
60
- out += line[i];
61
- seen += 1;
76
+ const take = (from, to) => {
77
+ let i = from;
78
+ while (i < to && seen < width) {
79
+ const code = line.charCodeAt(i);
80
+ const wide = code >= 0xd800 && code <= 0xdbff;
81
+ const ch = wide ? line.slice(i, i + 2) : line[i];
82
+ const step = charWidth(ch);
83
+ if (seen + step > width)
84
+ break;
85
+ out += ch;
86
+ seen += step;
87
+ i += ch.length;
62
88
  }
89
+ };
90
+ while (match) {
91
+ take(last, match.index);
63
92
  if (seen >= width)
64
93
  break;
65
94
  out += match[0];
66
95
  last = match.index + match[0].length;
67
96
  match = re.exec(line);
68
97
  }
69
- for (let i = last; i < line.length && seen < width; i += 1) {
70
- if (line[i] === '\x1b')
71
- break;
72
- out += line[i];
73
- seen += 1;
74
- }
98
+ take(last, line.length);
75
99
  return out + RESET;
76
100
  }
77
101
  function padVisible(line, cols) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stevezhou/sisu",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "SiSu CLI — one login, cloud quota, local workspace",
5
5
  "license": "UNLICENSED",
6
6
  "homepage": "https://www.sisu.chat",