@noir-ai/cli 1.9.2 → 1.9.3-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
@@ -2577,7 +2577,7 @@ if (isMainModule) {
2577
2577
  }
2578
2578
 
2579
2579
  // src/tui/App.tsx
2580
- import { Box as Box5, Text as Text9, useApp, useInput as useInput3 } from "ink";
2580
+ import { Box as Box6, Text as Text9, useApp, useInput as useInput3 } from "ink";
2581
2581
  import { useEffect, useState as useState4 } from "react";
2582
2582
 
2583
2583
  // src/tui/CommandInput.tsx
@@ -2589,7 +2589,11 @@ function CommandInput({ buffer, running }) {
2589
2589
  }
2590
2590
  let body;
2591
2591
  if (buffer.length === 0) {
2592
- body = /* @__PURE__ */ jsx(Text, { children: c.dim("type a /command (e.g. /status, /sync, /task next), or q to quit") });
2592
+ body = /* @__PURE__ */ jsxs(Text, { children: [
2593
+ /* @__PURE__ */ jsx(Text, { children: c.dim("\u258C") }),
2594
+ " ",
2595
+ /* @__PURE__ */ jsx(Text, { children: c.dim("type a /command (e.g. /status, /sync, /task next), or q to quit") })
2596
+ ] });
2593
2597
  } else {
2594
2598
  const isCommand = buffer.startsWith("/");
2595
2599
  body = /* @__PURE__ */ jsxs(Text, { children: [
@@ -2669,9 +2673,20 @@ function Header({ tagline }) {
2669
2673
  }
2670
2674
 
2671
2675
  // src/tui/HomeMenu.tsx
2672
- import { Box as Box2, Text as Text4, useInput } from "ink";
2676
+ import { Box as Box3, Text as Text4, useInput } from "ink";
2673
2677
  import { useState } from "react";
2674
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
2678
+
2679
+ // src/tui/Panel.tsx
2680
+ import { Box as Box2 } from "ink";
2681
+ import { jsx as jsx4 } from "react/jsx-runtime";
2682
+ function Panel({ children, maxWidth }) {
2683
+ const full = contentWidth() + 4;
2684
+ const width = maxWidth != null ? Math.min(full, maxWidth) : full;
2685
+ return /* @__PURE__ */ jsx4(Box2, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, width, children });
2686
+ }
2687
+
2688
+ // src/tui/HomeMenu.tsx
2689
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
2675
2690
  function flatten(sections) {
2676
2691
  const rows = [];
2677
2692
  for (const section of sections) {
@@ -2718,7 +2733,7 @@ function HomeMenu({ sections, onSelect, onClose }) {
2718
2733
  if (!row) continue;
2719
2734
  const { section, action } = row;
2720
2735
  if (section.id !== lastSectionId) {
2721
- rowsEl.push(/* @__PURE__ */ jsx4(Text4, { children: c.dim(`\u2500\u2500 ${section.label} \u2500\u2500`) }, `sec:${section.id}`));
2736
+ rowsEl.push(/* @__PURE__ */ jsx5(Text4, { children: c.dim(`\u2500\u2500 ${section.label} \u2500\u2500`) }, `sec:${section.id}`));
2722
2737
  lastSectionId = section.id;
2723
2738
  }
2724
2739
  const isActive = i === activeRowIndex(active, rows);
@@ -2727,19 +2742,19 @@ function HomeMenu({ sections, onSelect, onClose }) {
2727
2742
  /* @__PURE__ */ jsxs3(Text4, { children: [
2728
2743
  prefix,
2729
2744
  isActive ? c.accent(action.label) : action.label,
2730
- /* @__PURE__ */ jsx4(Text4, { children: c.dim(` ${action.hint}`) })
2745
+ /* @__PURE__ */ jsx5(Text4, { children: c.dim(` ${action.hint}`) })
2731
2746
  ] }, action.id)
2732
2747
  );
2733
2748
  }
2734
- return /* @__PURE__ */ jsxs3(Box2, { flexDirection: "column", children: [
2735
- /* @__PURE__ */ jsxs3(Box2, { flexDirection: "column", borderStyle: "round", borderColor: "gray", width: contentWidth() + 4, children: [
2736
- /* @__PURE__ */ jsx4(Box2, { paddingX: 1, children: /* @__PURE__ */ jsxs3(Text4, { children: [
2749
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
2750
+ /* @__PURE__ */ jsxs3(Panel, { children: [
2751
+ /* @__PURE__ */ jsx5(Box3, { paddingX: 1, children: /* @__PURE__ */ jsxs3(Text4, { children: [
2737
2752
  c.bold("\u25B8 home "),
2738
- /* @__PURE__ */ jsx4(Text4, { children: c.dim(`quick actions (${rows.length})`) })
2753
+ /* @__PURE__ */ jsx5(Text4, { children: c.dim(`quick actions (${rows.length})`) })
2739
2754
  ] }) }),
2740
- rowsEl.map((row) => /* @__PURE__ */ jsx4(Box2, { paddingX: 1, children: row }, row.key ?? "row"))
2755
+ rowsEl.map((row) => /* @__PURE__ */ jsx5(Box3, { paddingX: 1, children: row }, row.key ?? "row"))
2741
2756
  ] }),
2742
- /* @__PURE__ */ jsx4(Text4, { children: c.dim("\u2191/\u2193 navigate \xB7 Enter run \xB7 Esc close") })
2757
+ /* @__PURE__ */ jsx5(Text4, { children: c.dim("\u2191/\u2193 navigate \xB7 Enter run \xB7 Esc close") })
2743
2758
  ] });
2744
2759
  }
2745
2760
  function activeRowIndex(active, rows) {
@@ -2779,7 +2794,7 @@ function useInputBuffer() {
2779
2794
 
2780
2795
  // src/tui/OutputPane.tsx
2781
2796
  import { Text as Text5 } from "ink";
2782
- import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2797
+ import { Fragment, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
2783
2798
  function toRows(visible, baseIndex) {
2784
2799
  const rows = [];
2785
2800
  const seen = /* @__PURE__ */ new Map();
@@ -2813,13 +2828,13 @@ function OutputPane({
2813
2828
  }) {
2814
2829
  const width = contentWidth();
2815
2830
  if (lines.length === 0) {
2816
- return /* @__PURE__ */ jsx5(Text5, { children: c.dim("(no output \u2014 type a /command, or ? for help)") });
2831
+ return /* @__PURE__ */ jsx6(Text5, { children: c.dim("(no output \u2014 type a /command, or ? for help)") });
2817
2832
  }
2818
2833
  const maxOffset = Math.max(0, lines.length - height);
2819
2834
  const offset = Math.min(Math.max(0, scrollOffset), maxOffset);
2820
2835
  const rows = toRows(lines.slice(offset, offset + height), offset);
2821
2836
  return /* @__PURE__ */ jsxs4(Fragment, { children: [
2822
- title !== void 0 ? /* @__PURE__ */ jsx5(Text5, { wrap: "truncate-end", children: c.dim(`\u2500\u2500 ${title} \u2500\u2500`) }) : null,
2837
+ title !== void 0 ? /* @__PURE__ */ jsx6(Text5, { wrap: "truncate-end", children: c.dim(`\u2500\u2500 ${title} \u2500\u2500`) }) : null,
2823
2838
  rows.map((row) => {
2824
2839
  const truncated = row.text.length > width ? `${row.text.slice(0, Math.max(1, width - 1))}\u2026` : row.text;
2825
2840
  let body = truncated;
@@ -2828,19 +2843,19 @@ function OutputPane({
2828
2843
  } else if (highlightQuery !== void 0 && highlightQuery.length > 0) {
2829
2844
  body = highlightFirst(truncated, highlightQuery);
2830
2845
  }
2831
- return /* @__PURE__ */ jsx5(Text5, { wrap: "truncate-end", children: body }, row.key);
2846
+ return /* @__PURE__ */ jsx6(Text5, { wrap: "truncate-end", children: body }, row.key);
2832
2847
  })
2833
2848
  ] });
2834
2849
  }
2835
2850
 
2836
2851
  // src/tui/overlays/ConfirmOverlay.tsx
2837
- import { Box as Box3, Text as Text6 } from "ink";
2838
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
2852
+ import { Box as Box4, Text as Text6 } from "ink";
2853
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
2839
2854
  function ConfirmOverlay({ argv }) {
2840
- return /* @__PURE__ */ jsx6(Box3, { borderStyle: "round", borderColor: "yellow", paddingX: 1, width: contentWidth() + 4, children: /* @__PURE__ */ jsxs5(Text6, { children: [
2855
+ return /* @__PURE__ */ jsx7(Panel, { children: /* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsxs5(Text6, { children: [
2841
2856
  c.warn(`! run /${argv.join(" ")}? (y/N)`),
2842
- /* @__PURE__ */ jsx6(Text6, { children: c.dim(" [y approve \xB7 n/Esc back to palette]") })
2843
- ] }) });
2857
+ /* @__PURE__ */ jsx7(Text6, { children: c.dim(" [y approve \xB7 n/Esc back to palette]") })
2858
+ ] }) }) });
2844
2859
  }
2845
2860
 
2846
2861
  // src/tui/overlays/SearchMode.ts
@@ -2947,9 +2962,10 @@ var handRolledMatcher = {
2947
2962
  };
2948
2963
 
2949
2964
  // src/tui/palette/Palette.tsx
2950
- import { Box as Box4, Text as Text7, useInput as useInput2 } from "ink";
2965
+ import { Box as Box5, Text as Text7, useInput as useInput2 } from "ink";
2951
2966
  import { useState as useState3 } from "react";
2952
- import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
2967
+ import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
2968
+ var PALETTE_WIDTH = 64;
2953
2969
  var VISIBLE_ROWS = 10;
2954
2970
  var MATCH_LIMIT = 20;
2955
2971
  function rankPalette(query, matcher, commands, recent) {
@@ -2967,14 +2983,18 @@ function rankPalette(query, matcher, commands, recent) {
2967
2983
  indices: m.matchedIndices
2968
2984
  }));
2969
2985
  }
2986
+ function truncateLabel(label) {
2987
+ const max = Math.max(20, PALETTE_WIDTH - 8);
2988
+ return label.length > max ? `${label.slice(0, max - 1)}\u2026` : label;
2989
+ }
2970
2990
  function highlight(label, matchedIndices) {
2971
2991
  const set = new Set(matchedIndices);
2972
2992
  const chars = [];
2973
2993
  for (let i = 0; i < label.length; i++) {
2974
2994
  const ch = label[i] ?? "";
2975
- chars.push(set.has(i) ? /* @__PURE__ */ jsx7(Text7, { children: c.accent(ch) }, i) : /* @__PURE__ */ jsx7(Text7, { children: ch }, i));
2995
+ chars.push(set.has(i) ? /* @__PURE__ */ jsx8(Text7, { children: c.accent(ch) }, i) : /* @__PURE__ */ jsx8(Text7, { children: ch }, i));
2976
2996
  }
2977
- return /* @__PURE__ */ jsx7(Fragment2, { children: chars });
2997
+ return /* @__PURE__ */ jsx8(Fragment2, { children: chars });
2978
2998
  }
2979
2999
  function Palette({
2980
3000
  commands,
@@ -3019,14 +3039,14 @@ function Palette({
3019
3039
  }
3020
3040
  });
3021
3041
  const rows = [
3022
- /* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsxs6(Text7, { children: [
3042
+ /* @__PURE__ */ jsx8(Box5, { paddingX: 1, children: /* @__PURE__ */ jsxs6(Text7, { children: [
3023
3043
  c.bold("\u25B8 palette "),
3024
- /* @__PURE__ */ jsx7(Text7, { children: c.dim(`search (${visible.length} shown)`) })
3044
+ /* @__PURE__ */ jsx8(Text7, { children: c.dim(`search (${visible.length} shown)`) })
3025
3045
  ] }) }, "header"),
3026
- /* @__PURE__ */ jsx7(Box4, { borderStyle: "round", borderColor: "gray", paddingX: 1, width: contentWidth() + 4, children: /* @__PURE__ */ jsxs6(Text7, { children: [
3046
+ /* @__PURE__ */ jsx8(Box5, { paddingX: 1, children: /* @__PURE__ */ jsxs6(Text7, { children: [
3027
3047
  c.dim("> "),
3028
3048
  query,
3029
- /* @__PURE__ */ jsx7(Text7, { children: c.dim("\u258C") })
3049
+ /* @__PURE__ */ jsx8(Text7, { children: c.dim("\u258C") })
3030
3050
  ] }) }, "query")
3031
3051
  ];
3032
3052
  let lastCategory = null;
@@ -3035,29 +3055,29 @@ function Palette({
3035
3055
  if (query.length === 0) {
3036
3056
  if (isRecent && lastCategory !== "recent") {
3037
3057
  rows.push(
3038
- /* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsx7(Text7, { children: c.dim("\u2500\u2500 recent \u2500\u2500") }) }, "cat:recent")
3058
+ /* @__PURE__ */ jsx8(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx8(Text7, { children: c.dim("\u2500\u2500 recent \u2500\u2500") }) }, "cat:recent")
3039
3059
  );
3040
3060
  lastCategory = "recent";
3041
3061
  } else if (!isRecent && cmd.category !== lastCategory) {
3042
3062
  rows.push(
3043
- /* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsx7(Text7, { children: c.dim(`\u2500\u2500 ${cmd.category} \u2500\u2500`) }) }, `cat:${cmd.category}`)
3063
+ /* @__PURE__ */ jsx8(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx8(Text7, { children: c.dim(`\u2500\u2500 ${cmd.category} \u2500\u2500`) }) }, `cat:${cmd.category}`)
3044
3064
  );
3045
3065
  lastCategory = cmd.category;
3046
3066
  }
3047
3067
  }
3048
3068
  const prefix = cmd.id === visible[active]?.cmd.id ? "\u25B8 " : " ";
3049
3069
  rows.push(
3050
- /* @__PURE__ */ jsx7(Box4, { paddingX: 1, children: /* @__PURE__ */ jsxs6(Text7, { children: [
3051
- isRecent && query.length === 0 ? /* @__PURE__ */ jsx7(Text7, { children: c.dim("\u21BA ") }) : null,
3070
+ /* @__PURE__ */ jsx8(Box5, { paddingX: 1, children: /* @__PURE__ */ jsxs6(Text7, { children: [
3071
+ isRecent && query.length === 0 ? /* @__PURE__ */ jsx8(Text7, { children: c.dim("\u21BA ") }) : null,
3052
3072
  prefix,
3053
- highlight(cmd.label, indices),
3054
- /* @__PURE__ */ jsx7(Text7, { children: c.dim(` ${cmd.description}`) })
3073
+ highlight(truncateLabel(cmd.label), indices),
3074
+ /* @__PURE__ */ jsx8(Text7, { children: c.dim(` ${cmd.description}`) })
3055
3075
  ] }) }, cmd.id)
3056
3076
  );
3057
3077
  }
3058
- return /* @__PURE__ */ jsxs6(Box4, { flexDirection: "column", children: [
3059
- /* @__PURE__ */ jsx7(Box4, { flexDirection: "column", borderStyle: "round", borderColor: "gray", width: contentWidth() + 4, children: rows }),
3060
- /* @__PURE__ */ jsx7(Text7, { children: c.dim("\u2191/\u2193 navigate \xB7 Enter run \xB7 Esc close") })
3078
+ return /* @__PURE__ */ jsxs6(Box5, { flexDirection: "column", children: [
3079
+ /* @__PURE__ */ jsx8(Panel, { maxWidth: PALETTE_WIDTH, children: rows }),
3080
+ /* @__PURE__ */ jsx8(Text7, { children: c.dim("\u2191/\u2193 navigate \xB7 Enter run \xB7 Esc close") })
3061
3081
  ] });
3062
3082
  }
3063
3083
  function recentDeduped(recent, commands) {
@@ -3067,16 +3087,16 @@ function recentDeduped(recent, commands) {
3067
3087
 
3068
3088
  // src/tui/StatusBar.tsx
3069
3089
  import { Text as Text8 } from "ink";
3070
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
3090
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
3071
3091
  function Cell({
3072
3092
  label,
3073
3093
  value,
3074
3094
  accent
3075
3095
  }) {
3076
3096
  return /* @__PURE__ */ jsxs7(Text8, { children: [
3077
- /* @__PURE__ */ jsx8(Text8, { children: c.dim(`${label}:`) }),
3097
+ /* @__PURE__ */ jsx9(Text8, { children: c.dim(`${label}:`) }),
3078
3098
  " ",
3079
- /* @__PURE__ */ jsx8(Text8, { children: accent ? c.accent(value) : value })
3099
+ /* @__PURE__ */ jsx9(Text8, { children: accent ? c.accent(value) : value })
3080
3100
  ] });
3081
3101
  }
3082
3102
  function StatusBar({ payload, loading }) {
@@ -3086,12 +3106,12 @@ function StatusBar({ payload, loading }) {
3086
3106
  const daemonRunning = payload?.daemon.running === true;
3087
3107
  const daemon = payload === null && loading ? "\u2026" : daemonRunning ? "up" : "down";
3088
3108
  return /* @__PURE__ */ jsxs7(Text8, { children: [
3089
- /* @__PURE__ */ jsx8(Cell, { label: "host", value: host, accent: true }),
3090
- /* @__PURE__ */ jsx8(Text8, { children: c.dim(" \xB7 ") }),
3091
- /* @__PURE__ */ jsx8(Cell, { label: "mode", value: mode }),
3092
- /* @__PURE__ */ jsx8(Text8, { children: c.dim(" \xB7 ") }),
3093
- /* @__PURE__ */ jsx8(Cell, { label: "phase", value: phase }),
3094
- /* @__PURE__ */ jsx8(Text8, { children: c.dim(" \xB7 ") }),
3109
+ /* @__PURE__ */ jsx9(Cell, { label: "host", value: host, accent: true }),
3110
+ /* @__PURE__ */ jsx9(Text8, { children: c.dim(" \xB7 ") }),
3111
+ /* @__PURE__ */ jsx9(Cell, { label: "mode", value: mode }),
3112
+ /* @__PURE__ */ jsx9(Text8, { children: c.dim(" \xB7 ") }),
3113
+ /* @__PURE__ */ jsx9(Cell, { label: "phase", value: phase }),
3114
+ /* @__PURE__ */ jsx9(Text8, { children: c.dim(" \xB7 ") }),
3095
3115
  /* @__PURE__ */ jsxs7(Text8, { children: [
3096
3116
  c.dim("daemon:"),
3097
3117
  " ",
@@ -3101,7 +3121,7 @@ function StatusBar({ payload, loading }) {
3101
3121
  }
3102
3122
 
3103
3123
  // src/tui/App.tsx
3104
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
3124
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
3105
3125
  function App({
3106
3126
  deps,
3107
3127
  initialPayload = null,
@@ -3400,12 +3420,12 @@ function App({
3400
3420
  void recordRuns(argv);
3401
3421
  }
3402
3422
  if (help) {
3403
- return /* @__PURE__ */ jsx9(Help, {});
3423
+ return /* @__PURE__ */ jsx10(Help, {});
3404
3424
  }
3405
3425
  if (mode.kind === "palette") {
3406
- return /* @__PURE__ */ jsxs8(Box5, { flexDirection: "column", children: [
3407
- /* @__PURE__ */ jsx9(Header, { tagline: "palette" }),
3408
- /* @__PURE__ */ jsx9(
3426
+ return /* @__PURE__ */ jsxs8(Box6, { flexDirection: "column", children: [
3427
+ /* @__PURE__ */ jsx10(Header, { tagline: "palette" }),
3428
+ /* @__PURE__ */ jsx10(
3409
3429
  Palette,
3410
3430
  {
3411
3431
  commands: deps.commands ?? [],
@@ -3415,13 +3435,13 @@ function App({
3415
3435
  onClose: () => setMode({ kind: "dashboard" })
3416
3436
  }
3417
3437
  ),
3418
- /* @__PURE__ */ jsx9(Footer, { running: false })
3438
+ /* @__PURE__ */ jsx10(Footer, { running: false })
3419
3439
  ] });
3420
3440
  }
3421
3441
  if (mode.kind === "home") {
3422
- return /* @__PURE__ */ jsxs8(Box5, { flexDirection: "column", children: [
3423
- /* @__PURE__ */ jsx9(Header, { tagline: "home" }),
3424
- /* @__PURE__ */ jsx9(
3442
+ return /* @__PURE__ */ jsxs8(Box6, { flexDirection: "column", children: [
3443
+ /* @__PURE__ */ jsx10(Header, { tagline: "home" }),
3444
+ /* @__PURE__ */ jsx10(
3425
3445
  HomeMenu,
3426
3446
  {
3427
3447
  sections: homeSections,
@@ -3429,99 +3449,90 @@ function App({
3429
3449
  onClose: () => setMode({ kind: "dashboard" })
3430
3450
  }
3431
3451
  ),
3432
- /* @__PURE__ */ jsx9(Footer, { running: false })
3452
+ /* @__PURE__ */ jsx10(Footer, { running: false })
3433
3453
  ] });
3434
3454
  }
3435
3455
  if (mode.kind === "confirm") {
3436
- return /* @__PURE__ */ jsxs8(Box5, { flexDirection: "column", children: [
3437
- /* @__PURE__ */ jsx9(Header, { tagline: "confirm" }),
3438
- /* @__PURE__ */ jsx9(ConfirmOverlay, { argv: mode.argv }),
3439
- /* @__PURE__ */ jsx9(Footer, { running: false })
3456
+ return /* @__PURE__ */ jsxs8(Box6, { flexDirection: "column", children: [
3457
+ /* @__PURE__ */ jsx10(Header, { tagline: "confirm" }),
3458
+ /* @__PURE__ */ jsx10(ConfirmOverlay, { argv: mode.argv }),
3459
+ /* @__PURE__ */ jsx10(Footer, { running: false })
3440
3460
  ] });
3441
3461
  }
3442
3462
  if (mode.kind === "search") {
3443
3463
  const activeLine = mode.active >= 0 ? mode.matches[mode.active] : void 0;
3444
3464
  const matchCount = mode.matches.length;
3445
- return /* @__PURE__ */ jsxs8(Box5, { flexDirection: "column", children: [
3446
- /* @__PURE__ */ jsx9(Header, { tagline: "search" }),
3447
- /* @__PURE__ */ jsx9(
3448
- Box5,
3465
+ return /* @__PURE__ */ jsxs8(Box6, { flexDirection: "column", children: [
3466
+ /* @__PURE__ */ jsx10(Header, { tagline: "search" }),
3467
+ /* @__PURE__ */ jsx10(Panel, { children: /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(
3468
+ OutputPane,
3449
3469
  {
3450
- flexDirection: "column",
3451
- borderStyle: "round",
3452
- borderColor: "gray",
3453
- width: contentWidth() + 4,
3454
- children: /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(
3455
- OutputPane,
3456
- {
3457
- lines: searchLines,
3458
- scrollOffset,
3459
- title: output?.title,
3460
- highlightQuery: mode.query,
3461
- activeLine
3462
- }
3463
- ) })
3470
+ lines: searchLines,
3471
+ scrollOffset,
3472
+ title: output?.title,
3473
+ highlightQuery: mode.query,
3474
+ activeLine
3464
3475
  }
3465
- ),
3466
- /* @__PURE__ */ jsx9(Box5, { borderStyle: "round", borderColor: "gray", paddingX: 1, width: contentWidth() + 4, children: /* @__PURE__ */ jsxs8(Text9, { children: [
3476
+ ) }) }),
3477
+ /* @__PURE__ */ jsx10(Box6, { borderStyle: "round", borderColor: "gray", paddingX: 1, children: /* @__PURE__ */ jsxs8(Text9, { children: [
3467
3478
  c.dim("search: "),
3468
3479
  mode.query.length > 0 ? mode.query : c.dim("(type to filter output)"),
3469
- /* @__PURE__ */ jsx9(Text9, { children: c.dim(" \u258C") })
3480
+ /* @__PURE__ */ jsx10(Text9, { children: c.dim(" \u258C") })
3470
3481
  ] }) }),
3471
- /* @__PURE__ */ jsx9(Text9, { children: c.dim(
3482
+ /* @__PURE__ */ jsx10(Text9, { children: c.dim(
3472
3483
  matchCount === 0 ? "no matches \xB7 Esc exit" : `${mode.active + 1}/${matchCount} matches \xB7 n/Enter next \xB7 N prev \xB7 Esc exit`
3473
3484
  ) }),
3474
- /* @__PURE__ */ jsx9(Footer, { running: false })
3485
+ /* @__PURE__ */ jsx10(Footer, { running: false })
3475
3486
  ] });
3476
3487
  }
3477
3488
  const snapshotLines = formatStatusPayload(payload);
3478
3489
  const paneLines = output?.lines ?? snapshotLines ?? [];
3479
3490
  const paneTitle = output?.title ?? "snapshot";
3480
- return /* @__PURE__ */ jsxs8(Box5, { flexDirection: "column", children: [
3481
- /* @__PURE__ */ jsx9(Header, { tagline: "dashboard" }),
3482
- /* @__PURE__ */ jsxs8(Box5, { flexDirection: "column", borderStyle: "round", borderColor: "gray", width: contentWidth() + 4, children: [
3483
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(StatusBar, { payload, loading }) }),
3484
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: divider() }) }),
3485
- /* @__PURE__ */ jsx9(Box5, { flexDirection: "column", paddingX: 1, children: /* @__PURE__ */ jsx9(OutputPane, { lines: paneLines, scrollOffset, title: paneTitle }) })
3491
+ return /* @__PURE__ */ jsxs8(Box6, { flexDirection: "column", children: [
3492
+ /* @__PURE__ */ jsx10(Header, { tagline: "dashboard" }),
3493
+ /* @__PURE__ */ jsxs8(Panel, { children: [
3494
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(StatusBar, { payload, loading }) }),
3495
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: divider() }) }),
3496
+ /* @__PURE__ */ jsx10(Box6, { flexDirection: "column", paddingX: 1, children: /* @__PURE__ */ jsx10(OutputPane, { lines: paneLines, scrollOffset, title: paneTitle }) })
3486
3497
  ] }),
3487
- /* @__PURE__ */ jsx9(CommandInput, { buffer, running }),
3488
- notice !== null ? /* @__PURE__ */ jsx9(Text9, { children: c.dim(notice) }) : null,
3489
- /* @__PURE__ */ jsx9(Footer, { running })
3498
+ /* @__PURE__ */ jsx10(CommandInput, { buffer, running }),
3499
+ notice !== null ? /* @__PURE__ */ jsx10(Text9, { children: c.dim(notice) }) : null,
3500
+ /* @__PURE__ */ jsx10(Footer, { running })
3490
3501
  ] });
3491
3502
  }
3492
3503
  function Help() {
3493
- return /* @__PURE__ */ jsxs8(Box5, { flexDirection: "column", children: [
3494
- /* @__PURE__ */ jsx9(Header, { tagline: "help" }),
3495
- /* @__PURE__ */ jsxs8(Box5, { flexDirection: "column", borderStyle: "round", borderColor: "gray", width: contentWidth() + 4, children: [
3496
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.bold("Keybindings") }) }),
3497
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" /&lt;command&gt; run a Noir sub-command (e.g. /status, /sync, /task next)") }) }),
3498
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" Enter run the typed /command") }) }),
3499
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" Esc back: clear input \u2192 dismiss output \u2192 quit") }) }),
3500
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" q quit (when the input is empty)") }) }),
3501
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" h open the curated home quick-actions (home menu)") }) }),
3502
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" \u2191 / \u2193 scroll the output pane") }) }),
3503
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" ? toggle this help") }) }),
3504
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" Ctrl+K open the command palette") }) }),
3505
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" Ctrl+F find in the dispatched output pane") }) }),
3506
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" n / N next / previous match in search (Enter = next)") }) }),
3507
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" y / n approve / decline a destructive command prompt") }) }),
3508
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" Ctrl+C force exit") }) }),
3509
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: divider() }) }),
3510
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.bold("Home menu (h)") }) }),
3511
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" The curated quick actions mirror the bare-`noir` home menu:") }) }),
3512
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(
3504
+ return /* @__PURE__ */ jsxs8(Box6, { flexDirection: "column", children: [
3505
+ /* @__PURE__ */ jsx10(Header, { tagline: "help" }),
3506
+ /* @__PURE__ */ jsxs8(Panel, { children: [
3507
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.bold("Keybindings") }) }),
3508
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" /&lt;command&gt; run a Noir sub-command (e.g. /status, /sync, /task next)") }) }),
3509
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" Enter run the typed /command") }) }),
3510
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" Esc back: clear input \u2192 dismiss output \u2192 quit") }) }),
3511
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" q quit (when the input is empty)") }) }),
3512
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" h open the curated home quick-actions (home menu)") }) }),
3513
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" \u2191 / \u2193 scroll the output pane") }) }),
3514
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" ? toggle this help") }) }),
3515
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" Ctrl+K open the command palette") }) }),
3516
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" Ctrl+F find in the dispatched output pane") }) }),
3517
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" n / N next / previous match in search (Enter = next)") }) }),
3518
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" y / n approve / decline a destructive command prompt") }) }),
3519
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" Ctrl+C force exit") }) }),
3520
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: divider() }) }),
3521
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.bold("Home menu (h)") }) }),
3522
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" The curated quick actions mirror the bare-`noir` home menu:") }) }),
3523
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(
3513
3524
  " Status &amp; context \xB7 Memory \xB7 Workflow \xB7 Setup &amp; maintenance \xB7 Dashboard"
3514
3525
  ) }) }),
3515
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: divider() }) }),
3516
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.bold("Commands") }) }),
3517
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" Dispatched through the same routing as `noir` at the prompt.") }) }),
3518
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(
3526
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: divider() }) }),
3527
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.bold("Commands") }) }),
3528
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" Dispatched through the same routing as `noir` at the prompt.") }) }),
3529
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(
3519
3530
  " /status /sync /doctor /context search &lt;q&gt; /task next /memory recall &lt;q&gt;"
3520
3531
  ) }) }),
3521
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" Commands that need their own interactive prompts (e.g. a /sync with a") }) }),
3522
- /* @__PURE__ */ jsx9(Box5, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text9, { children: c.dim(" conflict) are best run directly \u2014 exit first with q.") }) })
3532
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" Commands that need their own interactive prompts (e.g. a /sync with a") }) }),
3533
+ /* @__PURE__ */ jsx10(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text9, { children: c.dim(" conflict) are best run directly \u2014 exit first with q.") }) })
3523
3534
  ] }),
3524
- /* @__PURE__ */ jsx9(Text9, { children: c.dim("press ? / Esc / q to close this help") })
3535
+ /* @__PURE__ */ jsx10(Text9, { children: c.dim("press ? / Esc / q to close this help") })
3525
3536
  ] });
3526
3537
  }
3527
3538
 
@@ -3581,7 +3592,7 @@ function recordRecent(projectId, argv) {
3581
3592
  }
3582
3593
 
3583
3594
  // src/tui/index.tsx
3584
- import { jsx as jsx10 } from "react/jsx-runtime";
3595
+ import { jsx as jsx11 } from "react/jsx-runtime";
3585
3596
  function defaultFetchStatus(opts) {
3586
3597
  return async () => {
3587
3598
  try {
@@ -3592,13 +3603,15 @@ function defaultFetchStatus(opts) {
3592
3603
  };
3593
3604
  }
3594
3605
  async function runTui(opts, dispatch) {
3606
+ process.stdout.write("\x1B[2J\x1B[H");
3595
3607
  const deps = await buildTuiDeps(opts, dispatch);
3596
- const instance = render(/* @__PURE__ */ jsx10(App, { deps }));
3608
+ const instance = render(/* @__PURE__ */ jsx11(App, { deps }));
3597
3609
  await instance.waitUntilExit();
3598
3610
  }
3599
3611
  async function runPalette(opts, dispatch) {
3612
+ process.stdout.write("\x1B[2J\x1B[H");
3600
3613
  const deps = await buildTuiDeps(opts, dispatch);
3601
- const instance = render(/* @__PURE__ */ jsx10(App, { deps, initialMode: { kind: "palette" } }));
3614
+ const instance = render(/* @__PURE__ */ jsx11(App, { deps, initialMode: { kind: "palette" } }));
3602
3615
  await instance.waitUntilExit();
3603
3616
  }
3604
3617
  async function buildTuiDeps(opts, dispatch) {