@wrongstack/tui 0.82.6 → 0.84.1

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/index.js CHANGED
@@ -8,6 +8,7 @@ import { routeImagesForModel } from '@wrongstack/runtime/vision';
8
8
  import { getIndexState, onIndexStateChange, getProcessRegistry } from '@wrongstack/tools';
9
9
  import { readClipboardImage } from '@wrongstack/runtime/clipboard';
10
10
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
11
+ import { expectDefined as expectDefined$1 } from '@wrongstack/core/utils';
11
12
  import { spawn } from 'child_process';
12
13
 
13
14
  // src/run-tui.ts
@@ -1933,14 +1934,6 @@ function detectLang(fenceInfo) {
1933
1934
  const tag = fenceInfo.trim().toLowerCase().split(/\s+/)[0] ?? "";
1934
1935
  return LANG_ALIASES[tag] ?? "plain";
1935
1936
  }
1936
-
1937
- // src/markdown-table.ts
1938
- function expectDefined2(value) {
1939
- if (value === null || value === void 0) {
1940
- throw new Error("Expected value to be defined");
1941
- }
1942
- return value;
1943
- }
1944
1937
  var ROW_RE = /^\s*\|.*\|\s*$/;
1945
1938
  var SEP_RE = /^\s*\|[\s\-:|]+\|\s*$/;
1946
1939
  function detectTable(lines, start) {
@@ -2024,14 +2017,14 @@ function computeWidths(allRows, cols, maxWidth, sepWidths) {
2024
2017
  const stripped = stripInlineMarkers(cell);
2025
2018
  const w = longestWord(stripped);
2026
2019
  const total = strWidth(stripped);
2027
- natural[c] = Math.max(expectDefined2(natural[c]), w, total);
2020
+ natural[c] = Math.max(expectDefined$1(natural[c]), w, total);
2028
2021
  }
2029
2022
  }
2030
2023
  if (sepWidths) {
2031
2024
  for (let c = 0; c < cols && c < sepWidths.length; c++) {
2032
2025
  const sepW = sepWidths[c];
2033
2026
  if (sepW != null) {
2034
- natural[c] = Math.max(expectDefined2(natural[c]), sepW);
2027
+ natural[c] = Math.max(expectDefined$1(natural[c]), sepW);
2035
2028
  }
2036
2029
  }
2037
2030
  }
@@ -2043,7 +2036,7 @@ function computeWidths(allRows, cols, maxWidth, sepWidths) {
2043
2036
  let maxIdx = -1;
2044
2037
  let maxVal = MIN_COL_WIDTH;
2045
2038
  for (let i = 0; i < cols; i++) {
2046
- const w = expectDefined2(widths[i]);
2039
+ const w = expectDefined$1(widths[i]);
2047
2040
  if (w > maxVal) {
2048
2041
  maxVal = w;
2049
2042
  maxIdx = i;
@@ -2103,7 +2096,7 @@ function strWidth(s2) {
2103
2096
  if (i < len) i++;
2104
2097
  continue;
2105
2098
  }
2106
- const code = expectDefined2(s2.codePointAt(i));
2099
+ const code = expectDefined$1(s2.codePointAt(i));
2107
2100
  const cpLen = code > 65535 ? 2 : 1;
2108
2101
  if (code === 8205 || // ZWJ — Zero Width Joiner (emoji sequences)
2109
2102
  code === 8203 || // ZWSP — Zero Width Space
@@ -2134,7 +2127,6 @@ function strWidth(s2) {
2134
2127
  code >= 8960 && code <= 9215 || // Miscellaneous Technical
2135
2128
  code >= 11088 && code <= 11093 || // Stars and similar
2136
2129
  code >= 10548 && code <= 10549 || // Arrow forms
2137
- code >= 8592 && code <= 8703 || // Arrows
2138
2130
  code >= 9632 && code <= 9727 || // Geometric Shapes
2139
2131
  code >= 9664 && code <= 9726 || // More Geometric Shapes (includes ▶)
2140
2132
  code >= 9984 && code <= 10175) {
@@ -4429,6 +4421,8 @@ function SettingsPicker({
4429
4421
  }
4430
4422
  function SlashMenu({ query, matches, selected }) {
4431
4423
  const placeholder = query ? `/${query}` : "/";
4424
+ const { stdout } = useStdout();
4425
+ const termRows = stdout?.rows ?? 24;
4432
4426
  const rows = [];
4433
4427
  let lastCategory = "";
4434
4428
  for (let i = 0; i < matches.length; i++) {
@@ -4439,12 +4433,29 @@ function SlashMenu({ query, matches, selected }) {
4439
4433
  }
4440
4434
  rows.push({ type: "item", match: m, index: i });
4441
4435
  }
4436
+ const overhead = 1 + 2 + 2 + 2 + 6;
4437
+ const maxBodyRows = Math.max(4, termRows - overhead);
4438
+ const selectedRowIdx = rows.findIndex((r) => r.type === "item" && r.index === selected);
4439
+ const visible = windowRows(rows, selectedRowIdx < 0 ? 0 : selectedRowIdx, maxBodyRows);
4440
+ const hiddenAbove = visible.start;
4441
+ const hiddenBelow = rows.length - visible.end;
4442
4442
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
4443
4443
  /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
4444
4444
  placeholder || "/",
4445
- " \u2014 \u2191/\u2193 select, Enter dispatch, Tab autocomplete, Esc close"
4445
+ " \u2014 \u2191/\u2193 select, Enter dispatch, Tab autocomplete, Esc close",
4446
+ matches.length > 0 ? ` (${selected + 1}/${matches.length})` : ""
4447
+ ] }),
4448
+ hiddenAbove > 0 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
4449
+ " ",
4450
+ "\u2191 ",
4451
+ hiddenAbove,
4452
+ " more"
4453
+ ] }),
4454
+ visible.contextHeader && /* @__PURE__ */ jsxs(Text, { bold: true, color: "yellow", dimColor: true, children: [
4455
+ " ",
4456
+ visible.contextHeader
4446
4457
  ] }),
4447
- rows.map((row) => {
4458
+ visible.rows.map((row) => {
4448
4459
  if (row.type === "header") {
4449
4460
  return /* @__PURE__ */ jsxs(Text, { bold: true, color: "yellow", dimColor: true, children: [
4450
4461
  " ",
@@ -4465,9 +4476,41 @@ function SlashMenu({ query, matches, selected }) {
4465
4476
  ] })
4466
4477
  ] }, m.name);
4467
4478
  }),
4479
+ hiddenBelow > 0 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
4480
+ " ",
4481
+ "\u2193 ",
4482
+ hiddenBelow,
4483
+ " more"
4484
+ ] }),
4468
4485
  matches.length === 0 && /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No matching commands" })
4469
4486
  ] });
4470
4487
  }
4488
+ function windowRows(rows, focus, max) {
4489
+ if (rows.length <= max) {
4490
+ return { rows, start: 0, end: rows.length, contextHeader: null };
4491
+ }
4492
+ let start = focus - Math.floor(max / 2);
4493
+ if (start < 0) start = 0;
4494
+ let end = start + max;
4495
+ if (end > rows.length) {
4496
+ end = rows.length;
4497
+ start = end - max;
4498
+ }
4499
+ let contextHeader = null;
4500
+ if (start > 0) {
4501
+ const first = rows[start];
4502
+ if (first && first.type === "item") {
4503
+ for (let i = start - 1; i >= 0; i--) {
4504
+ const r = rows[i];
4505
+ if (r && r.type === "header") {
4506
+ contextHeader = r.category;
4507
+ break;
4508
+ }
4509
+ }
4510
+ }
4511
+ }
4512
+ return { rows: rows.slice(start, end), start, end, contextHeader };
4513
+ }
4471
4514
  function TodosMonitor({ todos }) {
4472
4515
  const { stdout } = useStdout();
4473
4516
  const done = todos.filter((t) => t.status === "completed").length;