@noir-ai/cli 1.15.0-beta.1 → 1.16.0-beta.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/tui/index.js CHANGED
@@ -23,14 +23,18 @@ import {
23
23
  runHost,
24
24
  runPromptFrom,
25
25
  writeTranscript
26
- } from "./chunk-5KWETEMF.js";
27
- import "./chunk-TPNJEN4B.js";
26
+ } from "./chunk-6AUAIEFG.js";
27
+ import "./chunk-CQU2INJH.js";
28
28
  import {
29
29
  c,
30
30
  contentWidth,
31
+ displayWidth,
31
32
  divider,
33
+ padToWidth,
34
+ terminalWidth,
35
+ truncateToWidth,
32
36
  useColor
33
- } from "./chunk-KETMM3BA.js";
37
+ } from "./chunk-KVJIPKVE.js";
34
38
 
35
39
  // src/tui/index.tsx
36
40
  import { SUPPORTED_HOSTS } from "@noir-ai/adapters";
@@ -97,7 +101,7 @@ async function captureProcessOutput(fn) {
97
101
  import { Text as Text2 } from "ink";
98
102
 
99
103
  // src/tui/hints.ts
100
- var FOOTER_HINT = "?/h/Ctrl+K palette \xB7 Ctrl+F find \xB7 Ctrl+T transcripts \xB7 \u2191/\u2193 scroll \xB7 Enter run \xB7 q/Esc quit \xB7 Ctrl+C exit";
104
+ var FOOTER_HINT = "q/Esc quit \xB7 Ctrl+C exit \xB7 ?/h/Ctrl+K palette \xB7 Ctrl+F find \xB7 Ctrl+T transcripts \xB7 \u2191/\u2193 scroll \xB7 Enter run";
101
105
  var RUNNING_HINT = "running\u2026 (Ctrl+C to force exit)";
102
106
  var LIST_NAV_HINT = "\u2191/\u2193 navigate \xB7 Enter run \xB7 Esc close \xB7 Tab view";
103
107
  var RUN_HINT = "streaming \u2014 Esc cancels the host";
@@ -124,7 +128,8 @@ var HELP_ENTRIES = [
124
128
  // src/tui/Footer.tsx
125
129
  import { jsx as jsx2 } from "react/jsx-runtime";
126
130
  function Footer({ running }) {
127
- return /* @__PURE__ */ jsx2(Text2, { children: c.dim(running ? RUNNING_HINT : FOOTER_HINT) });
131
+ const hint = truncateToWidth(running ? RUNNING_HINT : FOOTER_HINT, terminalWidth());
132
+ return /* @__PURE__ */ jsx2(Text2, { children: c.dim(hint) });
128
133
  }
129
134
 
130
135
  // src/tui/format.ts
@@ -225,7 +230,7 @@ function OutputPane({
225
230
  return /* @__PURE__ */ jsxs3(Fragment, { children: [
226
231
  title !== void 0 ? /* @__PURE__ */ jsx4(Text4, { wrap: "truncate-end", children: c.dim(`\u2500\u2500 ${title} \u2500\u2500`) }) : null,
227
232
  rows.map((row) => {
228
- const truncated = row.text.length > width ? `${row.text.slice(0, Math.max(1, width - 1))}\u2026` : row.text;
233
+ const truncated = displayWidth(row.text) > width ? truncateToWidth(row.text, width) : row.text;
229
234
  return /* @__PURE__ */ jsx4(Text4, { wrap: "truncate-end", children: truncated }, row.key);
230
235
  })
231
236
  ] });
@@ -237,9 +242,16 @@ import { Box as Box3, Text as Text5 } from "ink";
237
242
  // src/tui/Panel.tsx
238
243
  import { Box as Box2 } from "ink";
239
244
  import { jsx as jsx5 } from "react/jsx-runtime";
245
+ var PANEL_CHROME = 4;
246
+ function panelWidth(maxWidth) {
247
+ const full = contentWidth() + PANEL_CHROME;
248
+ return maxWidth != null ? Math.min(full, maxWidth) : full;
249
+ }
250
+ function panelTextWidth(padding = 0, maxWidth) {
251
+ return Math.max(0, panelWidth(maxWidth) - PANEL_CHROME - padding * 2);
252
+ }
240
253
  function Panel({ children, maxWidth }) {
241
- const full = contentWidth() + 4;
242
- const width = maxWidth != null ? Math.min(full, maxWidth) : full;
254
+ const width = panelWidth(maxWidth);
243
255
  const borderColor = useColor() ? "gray" : void 0;
244
256
  return /* @__PURE__ */ jsx5(
245
257
  Box2,
@@ -257,9 +269,8 @@ function Panel({ children, maxWidth }) {
257
269
  // src/tui/overlays/PostRunOverlay.tsx
258
270
  import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
259
271
  var OVERLAY_WIDTH = 64;
260
- function truncate(text, max) {
261
- return text.length > max ? `${text.slice(0, Math.max(1, max - 1))}\u2026` : text;
262
- }
272
+ var ROW_MARKER_WIDTH = 2;
273
+ var LABEL_COLUMN_WIDTH = 26;
263
274
  function PostRunOverlay({
264
275
  options,
265
276
  active,
@@ -268,6 +279,9 @@ function PostRunOverlay({
268
279
  result
269
280
  }) {
270
281
  const listFocused = value === void 0 && !working && result === void 0;
282
+ const rowWidth = panelTextWidth(1, OVERLAY_WIDTH);
283
+ const labelColumn = Math.max(0, Math.min(LABEL_COLUMN_WIDTH, rowWidth));
284
+ const hintColumn = Math.max(0, rowWidth - labelColumn);
271
285
  const elements = [
272
286
  /* @__PURE__ */ jsx6(Box3, { paddingX: 1, children: /* @__PURE__ */ jsxs4(Text5, { children: [
273
287
  c.bold("\u25B8 run finished "),
@@ -278,9 +292,13 @@ function PostRunOverlay({
278
292
  const row = options[i];
279
293
  if (!row) continue;
280
294
  const focused = listFocused && i === active;
281
- const body = focused ? `${truncate(row.label, 28).padEnd(30)}${truncate(row.hint, 30)}` : truncate(row.label, 60);
295
+ const marker = focused || !listFocused ? "\u25B8 " : " ";
296
+ const body = focused ? padToWidth(
297
+ `${marker}${truncateToWidth(row.label, labelColumn - ROW_MARKER_WIDTH)}`,
298
+ labelColumn
299
+ ) + truncateToWidth(row.hint, hintColumn) : `${marker}${truncateToWidth(row.label, rowWidth - ROW_MARKER_WIDTH)}`;
282
300
  elements.push(
283
- /* @__PURE__ */ jsx6(Box3, { paddingX: 1, children: /* @__PURE__ */ jsx6(Text5, { children: focused ? c.inverse(`\u25B8 ${body}`) : c.dim(listFocused ? ` ${body}` : `\u25B8 ${body}`) }) }, row.value)
301
+ /* @__PURE__ */ jsx6(Box3, { paddingX: 1, children: /* @__PURE__ */ jsx6(Text5, { children: focused ? c.inverse(body) : c.dim(body) }) }, row.value)
284
302
  );
285
303
  }
286
304
  if (value !== void 0) {
@@ -773,7 +791,7 @@ function RunMode({
773
791
  }
774
792
  }
775
793
  ) }),
776
- /* @__PURE__ */ jsx8(Box4, { paddingX: 1, children: /* @__PURE__ */ jsx8(Text7, { children: divider() }) }),
794
+ /* @__PURE__ */ jsx8(Box4, { paddingX: 1, children: /* @__PURE__ */ jsx8(Text7, { children: divider(panelTextWidth(1)) }) }),
777
795
  /* @__PURE__ */ jsx8(Box4, { flexDirection: "column", paddingX: 1, children: /* @__PURE__ */ jsx8(
778
796
  OutputPane,
779
797
  {
@@ -1176,7 +1194,7 @@ function wrap(text, width) {
1176
1194
  let cur = "";
1177
1195
  for (const w of words) {
1178
1196
  if (cur.length === 0) cur = w;
1179
- else if (`${cur} ${w}`.length <= width) cur = `${cur} ${w}`;
1197
+ else if (displayWidth(`${cur} ${w}`) <= width) cur = `${cur} ${w}`;
1180
1198
  else {
1181
1199
  lines.push(cur);
1182
1200
  cur = w;
@@ -1187,7 +1205,7 @@ function wrap(text, width) {
1187
1205
  }
1188
1206
  function truncateLabel(label) {
1189
1207
  const max = LABEL_WIDTH - 2;
1190
- return label.length > max ? `${label.slice(0, max - 1)}\u2026` : label;
1208
+ return truncateToWidth(label, max);
1191
1209
  }
1192
1210
  function placeholder(corpus) {
1193
1211
  if (corpus === "commands") return "type to search commands";
@@ -1238,9 +1256,9 @@ function Palette({ corpus, query, active, rows, arg }) {
1238
1256
  const focused = isActive && arg === void 0;
1239
1257
  const prefix = focused ? "\u25B8 " : " ";
1240
1258
  const label = truncateLabel(row.primary);
1241
- const labelCol = (prefix + label).padEnd(LABEL_WIDTH);
1259
+ const labelCol = padToWidth(prefix + label, LABEL_WIDTH);
1242
1260
  const hintRaw = row.argv ? `/${row.argv.join(" ")}` : row.secondary;
1243
- const hint = hintRaw.length > HINT_WIDTH ? `${hintRaw.slice(0, HINT_WIDTH - 1)}\u2026` : hintRaw;
1261
+ const hint = truncateToWidth(hintRaw, HINT_WIDTH);
1244
1262
  if (focused) {
1245
1263
  elements.push(
1246
1264
  /* @__PURE__ */ jsx11(Box7, { paddingX: 1, children: /* @__PURE__ */ jsx11(Text10, { children: c.inverse(`${labelCol}${hint}`) }) }, row.key)
@@ -1712,7 +1730,7 @@ function App({
1712
1730
  /* @__PURE__ */ jsx12(Header, { tagline: "dashboard" }),
1713
1731
  /* @__PURE__ */ jsxs10(Panel, { children: [
1714
1732
  /* @__PURE__ */ jsx12(Box8, { paddingX: 1, children: /* @__PURE__ */ jsx12(StatusBar, { payload, loading }) }),
1715
- /* @__PURE__ */ jsx12(Box8, { paddingX: 1, children: /* @__PURE__ */ jsx12(Text11, { children: divider() }) }),
1733
+ /* @__PURE__ */ jsx12(Box8, { paddingX: 1, children: /* @__PURE__ */ jsx12(Text11, { children: divider(panelTextWidth(1)) }) }),
1716
1734
  /* @__PURE__ */ jsx12(Box8, { flexDirection: "column", paddingX: 1, children: /* @__PURE__ */ jsx12(OutputPane, { lines: paneLines, scrollOffset, title: paneTitle }) })
1717
1735
  ] }),
1718
1736
  /* @__PURE__ */ jsx12(CommandInput, { buffer, running }),