@modelstatus/cli 0.1.55 → 0.1.57

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": "@modelstatus/cli",
3
- "version": "0.1.55",
3
+ "version": "0.1.57",
4
4
  "description": "Track which AI models you use, where, and never get surprised by a retirement. Free offline model-health for any repo (mm status), browser sign-in for cloud inventory + alerts.",
5
5
  "keywords": [
6
6
  "llm",
package/src/tui/app.js CHANGED
@@ -44,13 +44,15 @@ const CHROME_ROWS = 10;
44
44
  // the frame, NEGATIVE grows it past the reported height.
45
45
  // - 1 everywhere: a full-height ink frame write+newlines its bottom line and
46
46
  // scrolls the buffer up 1/render; the 1-row reserve keeps the last line blank.
47
- // - -7 in Warp: empirically (the user dialing it live in their Warp), the frame
48
- // must be GROWN ~7 rows past stdout.rows or the top clips — Warp's block model
47
+ // - -11 in Warp: empirically (the user dialing it live in their Warp), the frame
48
+ // must be GROWN past stdout.rows or the top clips — Warp's block model
49
49
  // reports/handles the alt-screen height such that a flush-height frame rides too
50
50
  // high. So in Warp we render TALLER, which pushes the window down into view.
51
+ // -7 revealed the body but still clipped the 4 chrome rows above it (top border,
52
+ // traffic lights, the TAB-STRIP nav, blank); -11 pushes those into view too.
51
53
  // Gated on Warp (a negative reserve elsewhere would over-grow + clip the top of
52
54
  // a normal full-screen terminal).
53
- const WARP_RESERVE = -7;
55
+ const WARP_RESERVE = -11;
54
56
 
55
57
  /** True when running under Warp (TERM_PROGRAM=WarpTerminal, or any WARP_* env, or
56
58
  * TERM_PROGRAM merely containing "warp" — broad so detection doesn't silently
@@ -88,22 +90,19 @@ function useTermDims() {
88
90
  const [dims, setDims] = React.useState({ cols: (stdout && stdout.columns) || 80, rows: (stdout && stdout.rows) || 24 });
89
91
  React.useEffect(() => {
90
92
  if (!stdout) return undefined;
91
- // Functional update that returns the SAME object when nothing changed, so a
92
- // re-measure that finds identical dims doesn't trigger a needless re-render.
93
+ // Re-measure ONLY on a genuine resize event NEVER poll with timers.
94
+ // ROOT CAUSE of the Warp clip: process.stdout.rows changes a beat AFTER the
95
+ // alt-screen transition settles, and a re-render with those changed dims
96
+ // SCROLLS the window's top (the header) off-screen in Warp. The dims read at
97
+ // mount render correctly; a "more accurate" later value is actually worse. So
98
+ // we keep the mount-time dims and only react to real resizes (functional
99
+ // update returns the SAME object when nothing changed → no needless render).
93
100
  const on = () => setDims((prev) => {
94
101
  const cols = stdout.columns || 80, rows = stdout.rows || 24;
95
102
  return prev.cols === cols && prev.rows === rows ? prev : { cols, rows };
96
103
  });
97
104
  stdout.on("resize", on);
98
- // Re-measure a few beats after mount. When the TUI REMOUNTS right after the
99
- // game leaves the alternate screen, some terminals (notably Warp's block
100
- // model) re-flow the viewport a moment LATER and report stdout.{columns,rows}
101
- // stale at mount-time — so the first frame is too SHORT and Ink falls back to
102
- // cursor-up diffing, which drifts/scrolls the window off the top (and Ctrl-L
103
- // can't fix it because it redraws at the same wrong height). These one-shot
104
- // re-reads pick up the settled size and snap the window back to full screen.
105
- const timers = [60, 250, 600, 1200].map((ms) => setTimeout(on, ms));
106
- return () => { stdout.off("resize", on); timers.forEach(clearTimeout); };
105
+ return () => { stdout.off("resize", on); };
107
106
  }, [stdout]);
108
107
  const fw = Number(process.env.MM_TUI_WIDTH);
109
108
  const fh = Number(process.env.MM_TUI_HEIGHT);
@@ -83,13 +83,13 @@ export async function playGameInTui({ dir, width, height, initialView = "scan",
83
83
  // remounted tree fills the whole terminal from the top (same as Ctrl-L).
84
84
  // RECYCLE Warp's alt screen (leave + re-enter) to force it back into clean
85
85
  // full-screen mode — Warp drops that presentation during the game round-trip
86
- // and its block header otherwise bleeds over the top rows. Then PAUSE before
87
- // remounting: Warp reports its stable full-screen height a beat AFTER the
88
- // ?1049h transition, so rendering immediately measures a transient (too-tall)
89
- // size and clips a few rows off the top. The settle lets the height stabilize
90
- // first; useTermDims also re-measures post-mount as a backstop.
86
+ // and its block header otherwise bleeds over the top rows. Then remount RIGHT
87
+ // AWAY (just a tick to flush the write): this reads the dims at mount the same
88
+ // way a FRESH launch does those render perfectly. Do NOT wait for Warp to
89
+ // "settle" its reported height; the settled value is the one that clips (see
90
+ // useTermDims we no longer poll for it).
91
91
  try { process.stdout.write("\x1b[?1049l\x1b[?1049h\x1b[2J\x1b[H"); } catch { /* ignore */ }
92
- await new Promise((r) => setTimeout(r, 200));
92
+ await new Promise((r) => setImmediate(r));
93
93
  appController.remount({ initialView, fresh: false });
94
94
  } catch (e) {
95
95
  if (onError) onError(e); else throw e;