@menteeai/menteeswe 0.1.25 → 0.1.26

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.
Files changed (2) hide show
  1. package/dist/cli.js +64 -12
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1306,7 +1306,7 @@ var init_loop = __esm({
1306
1306
  var version;
1307
1307
  var init_package = __esm({
1308
1308
  "package.json"() {
1309
- version = "0.1.25";
1309
+ version = "0.1.26";
1310
1310
  }
1311
1311
  });
1312
1312
 
@@ -1641,7 +1641,7 @@ __export(App_exports, {
1641
1641
  App: () => App
1642
1642
  });
1643
1643
  import { useEffect as useEffect2, useMemo as useMemo2, useRef, useState as useState3 } from "react";
1644
- import { Box as Box6, Text as Text6, useApp, useInput as useInput4, useStdout } from "ink";
1644
+ import { Box as Box6, Text as Text6, useApp, useInput as useInput4, useStdin, useStdout } from "ink";
1645
1645
  import TextInput2 from "ink-text-input";
1646
1646
  import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1647
1647
  function wrappedH(text, w) {
@@ -1673,6 +1673,7 @@ function TaskBlock({ text }) {
1673
1673
  function App(props) {
1674
1674
  const { exit } = useApp();
1675
1675
  const { stdout } = useStdout();
1676
+ const { stdin } = useStdin();
1676
1677
  const bus = useMemo2(() => new EventBus(), []);
1677
1678
  const bridge = useMemo2(() => new ApprovalBridge(), []);
1678
1679
  const [log, setLog] = useState3([]);
@@ -1709,13 +1710,18 @@ function App(props) {
1709
1710
  const stateRef = useRef({ running, approval, dialog, factoryResult, providerName, model });
1710
1711
  stateRef.current = { running, approval, dialog, factoryResult, providerName, model };
1711
1712
  const abortRef = useRef(null);
1713
+ const maxScrollRef = useRef(0);
1714
+ const scrollOffsetRef = useRef(0);
1715
+ scrollOffsetRef.current = scrollOffset;
1712
1716
  const appendLog = (text, noise = false, kind) => {
1713
1717
  if (!text) return;
1718
+ if (scrollOffsetRef.current > 0) setScrollOffset((o) => o + 1);
1714
1719
  counter.current += 1;
1715
1720
  const line = { id: counter.current, text, noise, kind };
1716
1721
  setLog((prev) => [...prev, line]);
1717
1722
  };
1718
1723
  const appendPatchEdit = (edit) => {
1724
+ if (scrollOffsetRef.current > 0) setScrollOffset((o) => o + 1);
1719
1725
  counter.current += 1;
1720
1726
  setLog((prev) => [...prev, { id: counter.current, text: "", noise: false, kind: "patch", edit }]);
1721
1727
  };
@@ -1806,6 +1812,28 @@ function App(props) {
1806
1812
  const timer = setInterval(() => setFrame((f) => (f + 1) % SPINNER_FRAMES.length), 80);
1807
1813
  return () => clearInterval(timer);
1808
1814
  }, [running]);
1815
+ useEffect2(() => {
1816
+ if (!stdin.isTTY) return;
1817
+ stdout.write("\x1B[?1000;1006h");
1818
+ let tail = "";
1819
+ const onMouseData = (chunk) => {
1820
+ tail += chunk.toString();
1821
+ const re = /\u001b\[<(\d+);\d+;\d+[Mm]/g;
1822
+ let match;
1823
+ while ((match = re.exec(tail)) !== null) {
1824
+ if (stateRef.current.dialog || stateRef.current.approval) continue;
1825
+ const cb = Number(match[1]);
1826
+ if (cb === 64) setScrollOffset((o) => Math.min(o + 3, maxScrollRef.current));
1827
+ else if (cb === 65) setScrollOffset((o) => Math.max(0, o - 3));
1828
+ }
1829
+ tail = tail.slice(-32);
1830
+ };
1831
+ stdin.on("data", onMouseData);
1832
+ return () => {
1833
+ stdin.off("data", onMouseData);
1834
+ stdout.write("\x1B[?1000;1006l");
1835
+ };
1836
+ }, [stdin, stdout]);
1809
1837
  useEffect2(() => {
1810
1838
  const turns = loadConversation(props.cwd);
1811
1839
  if (turns.length > 0) {
@@ -2047,13 +2075,21 @@ function App(props) {
2047
2075
  }
2048
2076
  if (!stateRef.current.dialog && !stateRef.current.approval) {
2049
2077
  if (key.pageUp) {
2050
- setScrollOffset((o) => o + 10);
2078
+ setScrollOffset((o) => Math.min(o + 10, maxScrollRef.current));
2051
2079
  return;
2052
2080
  }
2053
2081
  if (key.pageDown) {
2054
2082
  setScrollOffset((o) => Math.max(0, o - 10));
2055
2083
  return;
2056
2084
  }
2085
+ if (key.upArrow) {
2086
+ setScrollOffset((o) => Math.min(o + 3, maxScrollRef.current));
2087
+ return;
2088
+ }
2089
+ if (key.downArrow) {
2090
+ setScrollOffset((o) => Math.max(0, o - 3));
2091
+ return;
2092
+ }
2057
2093
  }
2058
2094
  if (stateRef.current.dialog || stateRef.current.approval || stateRef.current.running) return;
2059
2095
  if (key.meta && (input === "m" || input === "M")) openModelDialog();
@@ -2073,7 +2109,9 @@ function App(props) {
2073
2109
  const summaryH = taskSummary ? 1 + wrappedH(taskSummary, mainInnerW) : 0;
2074
2110
  const visible = useMemo2(() => {
2075
2111
  const filtered = log.filter((l) => (showDetails || !l.noise) && (l.kind !== "patch" || showEdits));
2076
- const sliceEnd = Math.max(0, filtered.length - scrollOffset);
2112
+ maxScrollRef.current = Math.max(0, filtered.length - 1);
2113
+ const offset = Math.min(scrollOffset, maxScrollRef.current);
2114
+ const sliceEnd = Math.max(0, filtered.length - offset);
2077
2115
  const budget = mainInnerH - answerH - summaryH - 2;
2078
2116
  let used = 0;
2079
2117
  let start = sliceEnd;
@@ -2094,13 +2132,27 @@ function App(props) {
2094
2132
  ] }, label);
2095
2133
  return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", height: rows, children: [
2096
2134
  /* @__PURE__ */ jsxs6(Box6, { flexDirection: "row", flexGrow: 1, children: [
2097
- /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", flexGrow: 1, borderStyle: "round", borderColor: "gray", paddingX: 1, children: [
2098
- visible.map(renderLine),
2099
- finalPending !== null ? /* @__PURE__ */ jsx6(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs6(Text6, { color: "green", children: [
2100
- typedText,
2101
- typing ? "\u258C" : ""
2102
- ] }) }) : null,
2103
- taskSummary ? /* @__PURE__ */ jsx6(Text6, { children: taskSummary }) : null
2135
+ /* @__PURE__ */ jsxs6(Box6, { flexDirection: "row", flexGrow: 1, borderStyle: "round", borderColor: "gray", paddingX: 1, children: [
2136
+ /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", flexGrow: 1, children: [
2137
+ visible.map(renderLine),
2138
+ finalPending !== null ? /* @__PURE__ */ jsx6(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs6(Text6, { color: "green", children: [
2139
+ typedText,
2140
+ typing ? "\u258C" : ""
2141
+ ] }) }) : null,
2142
+ taskSummary ? /* @__PURE__ */ jsx6(Text6, { children: taskSummary }) : null
2143
+ ] }),
2144
+ (() => {
2145
+ const total = maxScrollRef.current;
2146
+ if (total <= 0) return null;
2147
+ const H = Math.max(4, mainInnerH - 2);
2148
+ const offset = Math.min(scrollOffset, maxScrollRef.current);
2149
+ const frac = maxScrollRef.current > 0 ? offset / maxScrollRef.current : 0;
2150
+ const thumbLen = Math.max(1, Math.round(H * 0.25));
2151
+ const thumbStart = Math.round((1 - frac) * (H - thumbLen));
2152
+ const glyphs = [];
2153
+ for (let i = 0; i < H; i++) glyphs.push(i >= thumbStart && i < thumbStart + thumbLen ? "\u2588" : "\u2502");
2154
+ return /* @__PURE__ */ jsx6(Box6, { flexDirection: "column", width: 1, children: glyphs.map((g, i) => /* @__PURE__ */ jsx6(Text6, { color: g === "\u2588" ? "magenta" : "gray", children: g }, i)) });
2155
+ })()
2104
2156
  ] }),
2105
2157
  /* @__PURE__ */ jsxs6(Box6, { width: SIDEBAR_W, flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 1, children: [
2106
2158
  /* @__PURE__ */ jsx6(Text6, { bold: true, color: "magenta", children: "MenteE SWE \u{1F380}" }),
@@ -2221,7 +2273,7 @@ function App(props) {
2221
2273
  }
2222
2274
  )
2223
2275
  ] }),
2224
- /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: (scrollOffset > 0 ? `\u2191${scrollOffset} hidden \xB7 ` : "") + "Alt+M model \xB7 Ctrl+P provider \xB7 Ctrl+K key \xB7 Alt+D details \xB7 Alt+E edits \xB7 PgUp/PgDn scroll \xB7 /help".slice(
2276
+ /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: (scrollOffset > 0 ? `\u2191${scrollOffset} hidden \xB7 ` : "") + "Alt+M model \xB7 Ctrl+P provider \xB7 Ctrl+K key \xB7 Alt+D details \xB7 Alt+E edits \xB7 \u2191/\u2193\xB7PgUp/PgDn\xB7wheel scroll \xB7 /help".slice(
2225
2277
  0,
2226
2278
  Math.max(10, cols - (scrollOffset > 0 ? 16 : 0))
2227
2279
  ) })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@menteeai/menteeswe",
3
- "version": "0.1.25",
3
+ "version": "0.1.26",
4
4
  "description": "MenteE SWE — a model-agnostic autonomous software-engineering agent CLI. Bring your own intelligence: Kimi, GLM/Z.ai, and more.",
5
5
  "type": "module",
6
6
  "license": "MIT",