reasonix 0.12.15 → 0.12.16

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/cli/index.js CHANGED
@@ -11613,6 +11613,22 @@ function extOf(p) {
11613
11613
  const m = /\.[^./\\]+$/.exec(p);
11614
11614
  return m ? m[0] : "";
11615
11615
  }
11616
+ var lineCountCache = /* @__PURE__ */ new Map();
11617
+ var LINE_COUNT_CACHE_LIMIT = 256;
11618
+ function getCachedLineCount(fullPath, mtimeMs) {
11619
+ const hit = lineCountCache.get(fullPath);
11620
+ if (!hit || hit.mtimeMs !== mtimeMs) return null;
11621
+ lineCountCache.delete(fullPath);
11622
+ lineCountCache.set(fullPath, hit);
11623
+ return hit.lineCount;
11624
+ }
11625
+ function setCachedLineCount(fullPath, mtimeMs, lineCount) {
11626
+ if (lineCountCache.size >= LINE_COUNT_CACHE_LIMIT) {
11627
+ const oldest = lineCountCache.keys().next().value;
11628
+ if (oldest !== void 0) lineCountCache.delete(oldest);
11629
+ }
11630
+ lineCountCache.set(fullPath, { mtimeMs, lineCount });
11631
+ }
11616
11632
  function validateCitation(url, projectRoot) {
11617
11633
  const parts = parseCitationUrl(url);
11618
11634
  if (!parts || !parts.path) return { ok: false, reason: "empty path" };
@@ -11636,11 +11652,14 @@ function validateCitation(url, projectRoot) {
11636
11652
  if (!stat) return { ok: false, reason: "file not found" };
11637
11653
  if (!stat.isFile()) return { ok: false, reason: "not a file" };
11638
11654
  if (parts.startLine === void 0) return { ok: true };
11639
- let lineCount;
11640
- try {
11641
- lineCount = readFileSync19(fullPath, "utf8").split("\n").length;
11642
- } catch {
11643
- return { ok: false, reason: "unreadable" };
11655
+ let lineCount = getCachedLineCount(fullPath, stat.mtimeMs);
11656
+ if (lineCount === null) {
11657
+ try {
11658
+ lineCount = readFileSync19(fullPath, "utf8").split("\n").length;
11659
+ } catch {
11660
+ return { ok: false, reason: "unreadable" };
11661
+ }
11662
+ setCachedLineCount(fullPath, stat.mtimeMs, lineCount);
11644
11663
  }
11645
11664
  if (parts.startLine < 1 || parts.startLine > lineCount) {
11646
11665
  return { ok: false, reason: `line ${parts.startLine} > ${lineCount}` };
@@ -12216,23 +12235,33 @@ function gradientCells(width, glyph = GLYPH.block) {
12216
12235
 
12217
12236
  // src/cli/ui/ticker.tsx
12218
12237
  import React10, { createContext as createContext2, useContext as useContext2, useEffect as useEffect2, useState as useState3 } from "react";
12219
- var TICK_MS = 120;
12220
- var TickContext = createContext2(0);
12238
+ var FAST_TICK_MS = 120;
12239
+ var SLOW_TICK_MS = 1e3;
12240
+ var FastTickContext = createContext2(0);
12241
+ var SlowTickContext = createContext2(0);
12221
12242
  function TickerProvider({ children, disabled }) {
12222
- const [tick, setTick] = useState3(0);
12243
+ const [fast, setFast] = useState3(0);
12244
+ const [slow, setSlow] = useState3(0);
12223
12245
  useEffect2(() => {
12224
12246
  if (disabled) return;
12225
- const id = setInterval(() => setTick((t2) => t2 + 1), TICK_MS);
12226
- return () => clearInterval(id);
12247
+ const fastId = setInterval(() => setFast((t2) => t2 + 1), FAST_TICK_MS);
12248
+ const slowId = setInterval(() => setSlow((t2) => t2 + 1), SLOW_TICK_MS);
12249
+ return () => {
12250
+ clearInterval(fastId);
12251
+ clearInterval(slowId);
12252
+ };
12227
12253
  }, [disabled]);
12228
- return /* @__PURE__ */ React10.createElement(TickContext.Provider, { value: tick }, children);
12254
+ return /* @__PURE__ */ React10.createElement(FastTickContext.Provider, { value: fast }, /* @__PURE__ */ React10.createElement(SlowTickContext.Provider, { value: slow }, children));
12229
12255
  }
12230
12256
  function useTick() {
12231
- return useContext2(TickContext);
12257
+ return useContext2(FastTickContext);
12258
+ }
12259
+ function useSlowTick() {
12260
+ return useContext2(SlowTickContext);
12232
12261
  }
12233
12262
  function useElapsedSeconds() {
12234
12263
  const [start] = useState3(() => Date.now());
12235
- useTick();
12264
+ useSlowTick();
12236
12265
  return Math.floor((Date.now() - start) / 1e3);
12237
12266
  }
12238
12267
 
@@ -12563,9 +12592,7 @@ function Elapsed() {
12563
12592
  return /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, `${mm}:${ss}`);
12564
12593
  }
12565
12594
  function PulsingAssistantGlyph() {
12566
- const tick = useTick();
12567
- const on = Math.floor(tick / 4) % 2 === 0;
12568
- return /* @__PURE__ */ React11.createElement(Text8, { color: "green", bold: true }, on ? ROLE_GLYPH.assistant : ROLE_GLYPH.assistantPulse);
12595
+ return /* @__PURE__ */ React11.createElement(Text8, { color: "green", bold: true }, ROLE_GLYPH.assistant);
12569
12596
  }
12570
12597
  function StreamingAssistant({ event }) {
12571
12598
  if (event.branchProgress) {
@@ -12582,6 +12609,7 @@ function StreamingAssistant({ event }) {
12582
12609
  const preFirstByte = !event.text && !event.reasoning && !toolCallBuild;
12583
12610
  const reasoningOnly = !event.text && !!event.reasoning && !toolCallBuild;
12584
12611
  const toolCallOnly = !event.text && !event.reasoning && !!toolCallBuild;
12612
+ const PILL_WIDTH = 8;
12585
12613
  let pillBg;
12586
12614
  let pillText;
12587
12615
  let label;
@@ -12609,6 +12637,7 @@ function StreamingAssistant({ event }) {
12609
12637
  }
12610
12638
  label = parts.join(" \xB7 ");
12611
12639
  }
12640
+ pillText = pillText.padEnd(PILL_WIDTH);
12612
12641
  return /* @__PURE__ */ React11.createElement(Box9, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React11.createElement(Box9, null, /* @__PURE__ */ React11.createElement(PulsingAssistantGlyph, null), /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Pulse, null), /* @__PURE__ */ React11.createElement(Text8, null, " "), /* @__PURE__ */ React11.createElement(Text8, { backgroundColor: pillBg, color: "black", bold: true }, ` ${pillText} `), /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, ` ${label} `), /* @__PURE__ */ React11.createElement(Elapsed, null)), reasoningTail ? /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 3 }, /* @__PURE__ */ React11.createElement(Text8, { color: "#c4b5fd", italic: true, dimColor: true }, "\u21B3 ", reasoningTail)) : null, tail ? /* @__PURE__ */ React11.createElement(Box9, { paddingLeft: 3 }, /* @__PURE__ */ React11.createElement(Text8, { dimColor: true }, "\u25B8 ", tail)) : preFirstByte ? (
12613
12642
  // Non-dim amber: first-time users misread the dim version as
12614
12643
  // "app frozen". The reassurance has to be VISIBLE to do its job.
@@ -12631,7 +12660,8 @@ function formatReadyTail(tb) {
12631
12660
  return ` \xB7 ${n} ready`;
12632
12661
  }
12633
12662
  function lastLine(s, maxChars) {
12634
- const flat = s.replace(/\s+/g, " ").trim();
12663
+ const tailSlice = s.length > maxChars * 4 ? s.slice(-maxChars * 4) : s;
12664
+ const flat = tailSlice.replace(/\s+/g, " ").trim();
12635
12665
  if (!flat) return "";
12636
12666
  return flat.length <= maxChars ? flat : `\u2026${flat.slice(-maxChars)}`;
12637
12667
  }
@@ -12658,7 +12688,7 @@ function ModeStatusBar({
12658
12688
  undoArmed,
12659
12689
  jobs: jobs2
12660
12690
  }) {
12661
- useTick();
12691
+ useSlowTick();
12662
12692
  const running = jobs2?.runningCount() ?? 0;
12663
12693
  const jobsTag = running > 0 ? /* @__PURE__ */ React12.createElement(Text9, { color: "yellow", bold: true }, ` \xB7 \u23F5 ${running} job${running === 1 ? "" : "s"}`) : null;
12664
12694
  if (planMode) {
@@ -12685,7 +12715,7 @@ function ModePill({
12685
12715
  function UndoBanner({
12686
12716
  banner
12687
12717
  }) {
12688
- useTick();
12718
+ useSlowTick();
12689
12719
  const remainingMs = Math.max(0, banner.expiresAt - Date.now());
12690
12720
  const remainingSec = Math.ceil(remainingMs / 1e3);
12691
12721
  const ok = banner.results.filter((r) => r.status === "applied" || r.status === "created").length;
@@ -17270,7 +17300,13 @@ function useSubagent({ session, setHistorical }) {
17270
17300
  }
17271
17301
 
17272
17302
  // src/cli/ui/App.tsx
17273
- var FLUSH_INTERVAL_MS = 100;
17303
+ var FLUSH_INTERVAL_MS = (() => {
17304
+ const raw = process.env.REASONIX_FLUSH_MS;
17305
+ if (!raw) return 33;
17306
+ const parsed = Number(raw);
17307
+ if (!Number.isFinite(parsed) || parsed < 16 || parsed > 1e3) return 33;
17308
+ return Math.round(parsed);
17309
+ })();
17274
17310
  var PLAIN_UI = process.env.REASONIX_UI === "plain";
17275
17311
  function LoopStatusRow({
17276
17312
  loop: loop2