@menteeai/menteeswe 0.1.24 → 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 +187 -64
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -408,8 +408,8 @@ function formatEvent(event) {
408
408
  const req = typeof event.data?.request === "number" ? event.data.request : 0;
409
409
  const inTok = typeof event.data?.inputTokens === "number" ? event.data.inputTokens : 0;
410
410
  const outTok = typeof event.data?.outputTokens === "number" ? event.data.outputTokens : 0;
411
- const fmtK = (n) => n >= 1e3 ? `${(n / 1e3).toFixed(1)}k` : String(n);
412
- return chalk.dim(` \u21C5 req #${req} \xB7 ctx ${fmtK(inTok)} tok \xB7 out ${fmtK(outTok)} tok`);
411
+ const fmtK2 = (n) => n >= 1e3 ? `${(n / 1e3).toFixed(1)}k` : String(n);
412
+ return chalk.dim(` \u21C5 req #${req} \xB7 ctx ${fmtK2(inTok)} tok \xB7 out ${fmtK2(outTok)} tok`);
413
413
  }
414
414
  case "info":
415
415
  return chalk.cyan.bold(`\u{1F4AD} ${event.message ?? ""}`);
@@ -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.24";
1309
+ version = "0.1.26";
1310
1310
  }
1311
1311
  });
1312
1312
 
@@ -1641,9 +1641,29 @@ __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, Static, 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
+ function wrappedH(text, w) {
1648
+ const width = Math.max(10, w - 2);
1649
+ let n = 0;
1650
+ for (const ln of text.split("\n")) n += Math.max(1, Math.ceil(ln.length / width));
1651
+ return n;
1652
+ }
1653
+ function lineH(l, w) {
1654
+ if (l.kind === "task") return 3 + wrappedH(l.text, w);
1655
+ if (l.kind === "answer") return 2 + wrappedH(l.text, w);
1656
+ if (l.kind === "patch" && l.edit) {
1657
+ const c = compactChanges(l.edit.old, l.edit.new);
1658
+ const removed = c.removed.slice(0, 24);
1659
+ const added = c.added.slice(0, 24);
1660
+ let h = 3;
1661
+ for (const ln of removed) h += Math.max(1, Math.ceil((ln.length + 3) / Math.max(10, w - 2)));
1662
+ for (const ln of added) h += Math.max(1, Math.ceil((ln.length + 3) / Math.max(10, w - 2)));
1663
+ return h;
1664
+ }
1665
+ return wrappedH(l.text, w);
1666
+ }
1647
1667
  function TaskBlock({ text }) {
1648
1668
  return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 1, children: [
1649
1669
  /* @__PURE__ */ jsx6(Text6, { color: "magenta", bold: true, children: "\u25B8 Task" }),
@@ -1653,6 +1673,7 @@ function TaskBlock({ text }) {
1653
1673
  function App(props) {
1654
1674
  const { exit } = useApp();
1655
1675
  const { stdout } = useStdout();
1676
+ const { stdin } = useStdin();
1656
1677
  const bus = useMemo2(() => new EventBus(), []);
1657
1678
  const bridge = useMemo2(() => new ApprovalBridge(), []);
1658
1679
  const [log, setLog] = useState3([]);
@@ -1681,25 +1702,26 @@ function App(props) {
1681
1702
  const [showEdits, setShowEdits] = useState3(true);
1682
1703
  const [taskSummary, setTaskSummary] = useState3(null);
1683
1704
  const [tokenTotals, setTokenTotals] = useState3({ totalIn: 0, totalOut: 0 });
1705
+ const [scrollOffset, setScrollOffset] = useState3(0);
1706
+ const [session, setSession] = useState3({ tasks: 0, requests: 0, toolCalls: 0, iterations: 0, files: 0 });
1684
1707
  const finalTextRef = useRef(null);
1685
1708
  const pendingTool = useRef(null);
1686
1709
  const counter = useRef(0);
1687
1710
  const stateRef = useRef({ running, approval, dialog, factoryResult, providerName, model });
1688
1711
  stateRef.current = { running, approval, dialog, factoryResult, providerName, model };
1689
1712
  const abortRef = useRef(null);
1690
- const showDetailsRef = useRef(showDetails);
1691
- showDetailsRef.current = showDetails;
1692
- const showEditsRef = useRef(showEdits);
1693
- showEditsRef.current = showEdits;
1713
+ const maxScrollRef = useRef(0);
1714
+ const scrollOffsetRef = useRef(0);
1715
+ scrollOffsetRef.current = scrollOffset;
1694
1716
  const appendLog = (text, noise = false, kind) => {
1695
1717
  if (!text) return;
1696
- if (noise && !showDetailsRef.current) return;
1718
+ if (scrollOffsetRef.current > 0) setScrollOffset((o) => o + 1);
1697
1719
  counter.current += 1;
1698
1720
  const line = { id: counter.current, text, noise, kind };
1699
1721
  setLog((prev) => [...prev, line]);
1700
1722
  };
1701
1723
  const appendPatchEdit = (edit) => {
1702
- if (!showEditsRef.current) return;
1724
+ if (scrollOffsetRef.current > 0) setScrollOffset((o) => o + 1);
1703
1725
  counter.current += 1;
1704
1726
  setLog((prev) => [...prev, { id: counter.current, text: "", noise: false, kind: "patch", edit }]);
1705
1727
  };
@@ -1730,8 +1752,20 @@ function App(props) {
1730
1752
  const totalOut = typeof event.data?.totalOut === "number" ? event.data.totalOut : 0;
1731
1753
  setTokenTotals({ totalIn, totalOut });
1732
1754
  }
1755
+ if (event.type === "model_request") {
1756
+ setSession((s) => ({ ...s, requests: s.requests + 1 }));
1757
+ }
1758
+ if (event.type === "tool_completed") {
1759
+ setSession((s) => ({ ...s, toolCalls: s.toolCalls + 1 }));
1760
+ }
1733
1761
  if (event.type === "task_completed") {
1734
1762
  setTaskSummary(formatEvent(event));
1763
+ setSession((s) => ({
1764
+ ...s,
1765
+ tasks: s.tasks + 1,
1766
+ iterations: s.iterations + (typeof event.data?.iterations === "number" ? event.data.iterations : 0),
1767
+ files: s.files + (Array.isArray(event.data?.modifiedFiles) ? event.data.modifiedFiles.length : 0)
1768
+ }));
1735
1769
  const text = typeof event.data?.finalText === "string" ? event.data.finalText.trim() : "";
1736
1770
  if (text) {
1737
1771
  finalTextRef.current = text;
@@ -1778,6 +1812,28 @@ function App(props) {
1778
1812
  const timer = setInterval(() => setFrame((f) => (f + 1) % SPINNER_FRAMES.length), 80);
1779
1813
  return () => clearInterval(timer);
1780
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]);
1781
1837
  useEffect2(() => {
1782
1838
  const turns = loadConversation(props.cwd);
1783
1839
  if (turns.length > 0) {
@@ -1947,6 +2003,7 @@ function App(props) {
1947
2003
  setRunning(true);
1948
2004
  setTaskSummary(null);
1949
2005
  setTokenTotals({ totalIn: 0, totalOut: 0 });
2006
+ setScrollOffset(0);
1950
2007
  const ac = new AbortController();
1951
2008
  abortRef.current = ac;
1952
2009
  try {
@@ -2016,42 +2073,115 @@ function App(props) {
2016
2073
  setShowEdits((v) => !v);
2017
2074
  return;
2018
2075
  }
2076
+ if (!stateRef.current.dialog && !stateRef.current.approval) {
2077
+ if (key.pageUp) {
2078
+ setScrollOffset((o) => Math.min(o + 10, maxScrollRef.current));
2079
+ return;
2080
+ }
2081
+ if (key.pageDown) {
2082
+ setScrollOffset((o) => Math.max(0, o - 10));
2083
+ return;
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
+ }
2093
+ }
2019
2094
  if (stateRef.current.dialog || stateRef.current.approval || stateRef.current.running) return;
2020
2095
  if (key.meta && (input === "m" || input === "M")) openModelDialog();
2021
2096
  else if (key.ctrl && input === "p") setDialog({ kind: "provider" });
2022
2097
  else if (key.ctrl && input === "k") setDialog({ kind: "key" });
2023
2098
  });
2024
2099
  const modelLabel = model ?? factoryResult.provider?.defaultModel ?? (factoryResult.error ? "no key" : "");
2025
- const header = /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginBottom: 1, children: [
2026
- /* @__PURE__ */ jsx6(Text6, { color: "cyan", children: BANNER }),
2027
- /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
2028
- "v",
2029
- version,
2030
- " \xB7 ",
2031
- providerName,
2032
- modelLabel ? `:${modelLabel}` : "",
2033
- " \xB7 details ",
2034
- showDetails ? "open" : "collapsed",
2035
- " \xB7 edits ",
2036
- showEdits ? "open" : "collapsed",
2037
- " \xB7 ",
2038
- props.cwd
2039
- ] }),
2040
- /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Alt+M model \xB7 Ctrl+P provider \xB7 Ctrl+K key \xB7 Alt+D details \xB7 Alt+E edits \xB7 /help" })
2041
- ] }, "header");
2042
2100
  const cols = stdout.columns || 80;
2043
- const marquee = thinkingText.slice(-Math.max(1, cols - 4));
2044
- return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
2045
- /* @__PURE__ */ jsx6(Static, { items: [{ key: "header", text: header }], children: (item) => /* @__PURE__ */ jsx6(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 1, children: item.text }, item.key) }),
2046
- /* @__PURE__ */ jsx6(Static, { items: log, children: (line) => line.kind === "answer" ? /* @__PURE__ */ jsx6(AnswerBlock, { text: line.text }, line.id) : line.kind === "task" ? /* @__PURE__ */ jsx6(TaskBlock, { text: line.text }, line.id) : line.kind === "patch" && line.edit ? /* @__PURE__ */ jsx6(CurrentEditBox, { edit: line.edit }, line.id) : /* @__PURE__ */ jsx6(Text6, { children: line.text }, line.id) }),
2047
- finalPending !== null ? /* @__PURE__ */ jsx6(Box6, { marginTop: 1, flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs6(Text6, { color: "green", children: [
2048
- typedText,
2049
- typing ? "\u258C" : ""
2050
- ] }) }) : null,
2051
- taskSummary ? /* @__PURE__ */ jsx6(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text6, { children: taskSummary }) }) : null,
2101
+ const rows = stdout.rows || 24;
2102
+ const SIDEBAR_W = 26;
2103
+ const inspectorVisible = detailsOpen && inspectorIndex !== null && toolHistory[inspectorIndex] !== void 0;
2104
+ const footerRows = (dialog ? 10 : approval ? 5 : 2) + (inspectorVisible ? 7 : 0);
2105
+ const mainInnerH = Math.max(6, rows - footerRows - 2);
2106
+ const mainInnerW = Math.max(20, cols - SIDEBAR_W - 4);
2107
+ const marquee = thinkingText.slice(-Math.max(1, mainInnerW - 4));
2108
+ const answerH = finalPending !== null ? 2 + wrappedH(typedText, mainInnerW) : 0;
2109
+ const summaryH = taskSummary ? 1 + wrappedH(taskSummary, mainInnerW) : 0;
2110
+ const visible = useMemo2(() => {
2111
+ const filtered = log.filter((l) => (showDetails || !l.noise) && (l.kind !== "patch" || showEdits));
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);
2115
+ const budget = mainInnerH - answerH - summaryH - 2;
2116
+ let used = 0;
2117
+ let start = sliceEnd;
2118
+ while (start > 0) {
2119
+ const prev = filtered[start - 1];
2120
+ if (!prev) break;
2121
+ const h = lineH(prev, mainInnerW);
2122
+ if (used + h > budget) break;
2123
+ used += h;
2124
+ start--;
2125
+ }
2126
+ return filtered.slice(start, sliceEnd);
2127
+ }, [log, showDetails, showEdits, scrollOffset, mainInnerH, mainInnerW, answerH, summaryH]);
2128
+ const renderLine = (line) => line.kind === "answer" ? /* @__PURE__ */ jsx6(AnswerBlock, { text: line.text }, line.id) : line.kind === "task" ? /* @__PURE__ */ jsx6(TaskBlock, { text: line.text }, line.id) : line.kind === "patch" && line.edit ? /* @__PURE__ */ jsx6(CurrentEditBox, { edit: line.edit }, line.id) : /* @__PURE__ */ jsx6(Text6, { children: line.text }, line.id);
2129
+ const statRow = (label, value) => /* @__PURE__ */ jsxs6(Box6, { flexDirection: "row", justifyContent: "space-between", children: [
2130
+ /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: label }),
2131
+ /* @__PURE__ */ jsx6(Text6, { children: value })
2132
+ ] }, label);
2133
+ return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", height: rows, children: [
2134
+ /* @__PURE__ */ jsxs6(Box6, { flexDirection: "row", flexGrow: 1, children: [
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
+ })()
2156
+ ] }),
2157
+ /* @__PURE__ */ jsxs6(Box6, { width: SIDEBAR_W, flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 1, children: [
2158
+ /* @__PURE__ */ jsx6(Text6, { bold: true, color: "magenta", children: "MenteE SWE \u{1F380}" }),
2159
+ /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
2160
+ "v",
2161
+ version
2162
+ ] }),
2163
+ /* @__PURE__ */ jsx6(Text6, { children: " " }),
2164
+ statRow("provider", providerName),
2165
+ statRow("model", modelLabel.length > 18 ? modelLabel.slice(0, 17) + "\u2026" : modelLabel),
2166
+ statRow("phase", running ? PHASE_LABEL[phase] ?? "working" : "idle"),
2167
+ /* @__PURE__ */ jsx6(Text6, { children: " " }),
2168
+ statRow("tasks", String(session.tasks)),
2169
+ statRow("requests", String(session.requests)),
2170
+ statRow("\u2191 in", fmtK(tokenTotals.totalIn)),
2171
+ statRow("\u2193 out", fmtK(tokenTotals.totalOut)),
2172
+ statRow("tool calls", String(session.toolCalls)),
2173
+ statRow("iterations", String(session.iterations)),
2174
+ statRow("files", String(session.files)),
2175
+ statRow("details", showDetails ? "on" : "off"),
2176
+ statRow("edits", showEdits ? "on" : "off"),
2177
+ /* @__PURE__ */ jsx6(Text6, { children: " " }),
2178
+ /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "menteeai.org" }),
2179
+ /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "@menteeaiorg" })
2180
+ ] })
2181
+ ] }),
2052
2182
  detailsOpen && inspectorIndex !== null && toolHistory[inspectorIndex] ? (() => {
2053
2183
  const rec = toolHistory[inspectorIndex];
2054
- const outLines = rec.output.split("\n").slice(0, 24).join("\n");
2184
+ const outLines = rec.output.split("\n").slice(0, 20).join("\n");
2055
2185
  return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: "gray", paddingX: 1, children: [
2056
2186
  /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
2057
2187
  " tool details (",
@@ -2118,26 +2248,20 @@ function App(props) {
2118
2248
  if (decision === "always") bus.emit("info", "Approved for the rest of this session.");
2119
2249
  }
2120
2250
  }
2121
- ) : running ? /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
2122
- /* @__PURE__ */ jsxs6(Box6, { children: [
2123
- /* @__PURE__ */ jsxs6(Text6, { color: "yellow", children: [
2124
- SPINNER_FRAMES[frame],
2125
- " "
2126
- ] }),
2127
- /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
2128
- "agent ",
2129
- PHASE_LABEL[phase] ?? "working",
2130
- "\u2026",
2131
- tokenTotals.totalIn + tokenTotals.totalOut > 0 ? ` \xB7 ${((tokenTotals.totalIn + tokenTotals.totalOut) / 1e3).toFixed(1)}k tok` : "",
2132
- " (Ctrl+C to exit)"
2133
- ] })
2251
+ ) : running ? /* @__PURE__ */ jsxs6(Box6, { flexDirection: "row", children: [
2252
+ /* @__PURE__ */ jsxs6(Text6, { color: "yellow", children: [
2253
+ SPINNER_FRAMES[frame],
2254
+ " "
2134
2255
  ] }),
2135
- thinkingText ? /* @__PURE__ */ jsxs6(Box6, { children: [
2136
- /* @__PURE__ */ jsx6(Text6, { color: "cyan", children: "\u{1F4AD} " }),
2137
- /* @__PURE__ */ jsx6(Text6, { color: "cyan", dimColor: true, children: marquee }),
2138
- /* @__PURE__ */ jsx6(Text6, { color: "cyan", children: "\u258C" })
2139
- ] }) : null
2140
- ] }) : /* @__PURE__ */ jsxs6(Box6, { children: [
2256
+ /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
2257
+ "agent ",
2258
+ PHASE_LABEL[phase] ?? "working",
2259
+ "\u2026",
2260
+ tokenTotals.totalIn + tokenTotals.totalOut > 0 ? ` \xB7 ${fmtK(tokenTotals.totalIn + tokenTotals.totalOut)} tok` : "",
2261
+ " \xB7 ",
2262
+ thinkingText ? `\u{1F4AD} ${marquee}` : "Ctrl+C to cancel"
2263
+ ] })
2264
+ ] }) : /* @__PURE__ */ jsxs6(Box6, { flexDirection: "row", children: [
2141
2265
  /* @__PURE__ */ jsx6(Text6, { color: "cyan", bold: true, children: "\u25B8 " }),
2142
2266
  /* @__PURE__ */ jsx6(
2143
2267
  TextInput2,
@@ -2148,10 +2272,14 @@ function App(props) {
2148
2272
  placeholder: "Describe a task, or /help"
2149
2273
  }
2150
2274
  )
2151
- ] })
2275
+ ] }),
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(
2277
+ 0,
2278
+ Math.max(10, cols - (scrollOffset > 0 ? 16 : 0))
2279
+ ) })
2152
2280
  ] });
2153
2281
  }
2154
- var SPINNER_FRAMES, PHASE_LABEL, PROVIDER_NAMES, PROVIDER_DESCRIPTIONS, BANNER;
2282
+ var SPINNER_FRAMES, PHASE_LABEL, PROVIDER_NAMES, PROVIDER_DESCRIPTIONS, fmtK;
2155
2283
  var init_App = __esm({
2156
2284
  "src/tui/App.tsx"() {
2157
2285
  "use strict";
@@ -2190,12 +2318,7 @@ var init_App = __esm({
2190
2318
  nvidia: "NVIDIA NIM \xB7 build.nvidia.com hosted models",
2191
2319
  mock: "offline testing \xB7 no network"
2192
2320
  };
2193
- BANNER = ` __ __ \u{1F380}
2194
- | \\/ |
2195
- | |
2196
- | |
2197
- MenteE SWE \u2014 https://menteeai.org
2198
- Twitter: x.com/menteeaiorg`;
2321
+ fmtK = (n) => n >= 1e3 ? `${(n / 1e3).toFixed(1)}k` : String(n);
2199
2322
  }
2200
2323
  });
2201
2324
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@menteeai/menteeswe",
3
- "version": "0.1.24",
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",