@runfusion/fusion 0.2.3 → 0.2.5

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/bin.js +69 -36
  2. package/package.json +3 -3
package/dist/bin.js CHANGED
@@ -136867,7 +136867,7 @@ function UtilitiesPanel({ isFocused }) {
136867
136867
  { key: "t", label: "Toggle Engine Pause" },
136868
136868
  { key: "?", label: "Help" }
136869
136869
  ];
136870
- return /* @__PURE__ */ jsx(Panel, { title: "Utilities", isFocused, flexShrink: 0, children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: actions.map((action) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
136870
+ return /* @__PURE__ */ jsx(Panel, { title: "Utilities", isFocused, flexGrow: 1, children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: actions.map((action) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
136871
136871
  /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
136872
136872
  "[",
136873
136873
  action.key,
@@ -136878,30 +136878,32 @@ function UtilitiesPanel({ isFocused }) {
136878
136878
  }
136879
136879
  function HelpOverlay() {
136880
136880
  const shortcuts = [
136881
- ["[b]", "Board view (interactive mode)"],
136881
+ ["[m] / [s]", "Main (status mode)"],
136882
+ ["[b]", "Board view"],
136882
136883
  ["[a]", "Agents view"],
136883
136884
  ["[g]", "Settings view"],
136884
136885
  ["[t]", "Git view"],
136885
- ["[s]", "Status mode"],
136886
- ["[1] / [2] / [3]", "Board / Agents / Settings (interactive)"],
136887
- ["[Tab]", "Cycle focused panel forward"],
136888
- ["[Shift+Tab]", "Cycle focused panel backward"],
136889
- ["[1-5]", "Jump to panel by number (status mode)"],
136890
- ["[\u2192] / [n]", "Next panel (status mode)"],
136891
- ["[\u2190] / [p]", "Previous panel (status mode)"],
136886
+ ["[e]", "Explorer (file browser)"],
136887
+ ["[Tab]", "Cycle focused panel / pane forward"],
136888
+ ["[Shift+Tab]", "Cycle focused panel / pane backward"],
136889
+ ["[1-5]", "Jump to panel (Main: System/Logs/Utilities/Stats/Settings)"],
136890
+ ["[\u2190 / \u2192]", "Switch pane (Agents, Settings, Files, Git)"],
136891
+ ["[\u2192] / [n]", "Next panel (Main)"],
136892
+ ["[\u2190] / [p]", "Previous panel (Main)"],
136892
136893
  ["[r]", "Refresh stats (Utilities)"],
136893
136894
  ["[c]", "Clear logs (Utilities)"],
136894
- ["[t]", "Toggle engine pause (Utilities)"],
136895
- ["[\u2191/\u2193/k/j]", "Navigate log entries (Logs)"],
136896
- ["[Home/End]", "First/last log entry (Logs)"],
136897
- ["[Enter/Space/e]", "Expand log entry (Logs)"],
136898
- ["[w]", "Toggle word wrap (Logs)"],
136899
- ["[f]", "Cycle severity filter (Logs)"],
136900
- ["[s/x]", "Start/stop agent (Agents view)"],
136901
- ["[D]", "Delete agent \u2014 requires confirm (Agents view)"],
136902
- ["[r]", "Refresh agent detail (Agents view)"],
136903
- ["[Space]", "Toggle boolean (Settings view)"],
136904
- ["[+/-]", "Adjust number (Settings view)"],
136895
+ ["[\u2191/\u2193/k/j]", "Navigate list / log entries"],
136896
+ ["[Home / G]", "First / last log entry (Logs)"],
136897
+ ["[Enter/Space]", "Expand log entry (Logs)"],
136898
+ ["[w]", "Toggle word wrap (Logs / Files)"],
136899
+ ["[f]", "Cycle severity filter (Main, any panel)"],
136900
+ ["[Space]", "Toggle boolean (Settings)"],
136901
+ ["[+/-]", "Adjust number (Settings)"],
136902
+ ["[p]", "Project picker (Board, Files)"],
136903
+ ["[n]", "New task (Board)"],
136904
+ ["[D]", "Delete agent \u2014 requires confirm (Agents)"],
136905
+ ["[P] / [F]", "Push / fetch (Git)"],
136906
+ ["[.]", "Toggle hidden files (Files)"],
136905
136907
  ["[?] / [h]", "Toggle help"],
136906
136908
  ["[q]", "Quit"],
136907
136909
  ["[Ctrl+C]", "Force quit"]
@@ -136913,13 +136915,13 @@ function HelpOverlay() {
136913
136915
  return /* @__PURE__ */ jsxs(Box, { borderStyle: "round", borderColor: "cyanBright", flexDirection: "column", backgroundColor: "black", children: [
136914
136916
  /* @__PURE__ */ jsx(Text, { backgroundColor: "black", bold: true, color: "white", children: titleRow }),
136915
136917
  /* @__PURE__ */ jsx(Text, { backgroundColor: "black", children: " " }),
136916
- shortcuts.map(([key, desc]) => {
136918
+ shortcuts.map(([key, desc], i) => {
136917
136919
  const keyCell = ` ${key.padEnd(rowKeyWidth - 1)} `;
136918
136920
  const descCell = ` ${desc.padEnd(rowDescWidth)} `;
136919
136921
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
136920
136922
  /* @__PURE__ */ jsx(Text, { backgroundColor: "black", color: "yellow", children: keyCell }),
136921
136923
  /* @__PURE__ */ jsx(Text, { backgroundColor: "black", color: "white", children: descCell })
136922
- ] }, key);
136924
+ ] }, i);
136923
136925
  })
136924
136926
  ] });
136925
136927
  }
@@ -136932,7 +136934,7 @@ function StatusModeGrid({
136932
136934
  const bodyRows = Math.max(8, rows - 7);
136933
136935
  const logsAvailableRows = Math.max(4, bodyRows - 4);
136934
136936
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [
136935
- /* @__PURE__ */ jsx(MainHeader, { state }),
136937
+ /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(MainHeader, { state }) }),
136936
136938
  /* @__PURE__ */ jsxs(Box, { flexDirection: "row", flexGrow: 1, overflow: "hidden", children: [
136937
136939
  /* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 5, overflow: "hidden", children: [
136938
136940
  /* @__PURE__ */ jsx(SystemPanel, { state, isFocused: focused === "system" }),
@@ -136953,7 +136955,7 @@ function StatusModeGrid({
136953
136955
  ] })
136954
136956
  ] })
136955
136957
  ] }),
136956
- /* @__PURE__ */ jsx(StatusBar, { state, controller })
136958
+ /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(StatusBar, { state, controller }) })
136957
136959
  ] });
136958
136960
  }
136959
136961
  function StatusModeSingle({
@@ -136976,9 +136978,9 @@ function StatusModeSingle({
136976
136978
  }
136977
136979
  };
136978
136980
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [
136979
- /* @__PURE__ */ jsx(MainHeader, { state }),
136981
+ /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(MainHeader, { state }) }),
136980
136982
  /* @__PURE__ */ jsx(Box, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: activePanel() }),
136981
- /* @__PURE__ */ jsx(StatusBar, { state, controller })
136983
+ /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(StatusBar, { state, controller }) })
136982
136984
  ] });
136983
136985
  }
136984
136986
  function StatusBar({ state, controller: _controller }) {
@@ -136996,9 +136998,9 @@ function StatusBar({ state, controller: _controller }) {
136996
136998
  statusParts.push(systemInfo.baseUrl);
136997
136999
  statusParts.push(formatUptime(Date.now() - systemInfo.startTimeMs));
136998
137000
  }
136999
- return /* @__PURE__ */ jsxs(Box, { justifyContent: "space-between", paddingX: 1, children: [
137000
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: hotkeys.join(" \xB7 ") }),
137001
- statusParts.length > 0 && /* @__PURE__ */ jsx(Text, { dimColor: true, children: statusParts.join(" | ") })
137001
+ return /* @__PURE__ */ jsxs(Box, { justifyContent: "space-between", paddingX: 1, flexShrink: 0, children: [
137002
+ /* @__PURE__ */ jsx(Text, { dimColor: true, wrap: "truncate-end", children: hotkeys.join(" \xB7 ") }),
137003
+ statusParts.length > 0 && /* @__PURE__ */ jsx(Text, { dimColor: true, wrap: "truncate-end", children: statusParts.join(" | ") })
137002
137004
  ] });
137003
137005
  }
137004
137006
  function MainHeader({ state }) {
@@ -137006,7 +137008,6 @@ function MainHeader({ state }) {
137006
137008
  const interactiveView = state.interactiveView;
137007
137009
  const { stdout } = useStdout();
137008
137010
  const cols = stdout?.columns ?? 80;
137009
- const rows = stdout?.rows ?? 24;
137010
137011
  const tabs = [
137011
137012
  { key: "m", label: "Main", kind: "main" },
137012
137013
  { key: "b", label: "Board", kind: "interactive", view: "board" },
@@ -137015,7 +137016,6 @@ function MainHeader({ state }) {
137015
137016
  { key: "t", label: "Git", kind: "interactive", view: "git" },
137016
137017
  { key: "e", label: "Explorer", kind: "interactive", view: "files" }
137017
137018
  ];
137018
- if (rows < 10) return null;
137019
137019
  const showHelpHint = cols >= 110;
137020
137020
  const fullLabels = cols >= 90;
137021
137021
  const tiny = cols < 50;
@@ -137023,12 +137023,12 @@ function MainHeader({ state }) {
137023
137023
  const isActive = (t) => t.kind === "main" ? !inInteractive : inInteractive && t.view === interactiveView;
137024
137024
  if (tiny) {
137025
137025
  const active = tabs.find(isActive);
137026
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, paddingX: 1, children: [
137026
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, paddingX: 1, flexShrink: 0, overflow: "hidden", children: [
137027
137027
  /* @__PURE__ */ jsx(MiniLogo, {}),
137028
137028
  active && /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(Text, { backgroundColor: "cyan", color: "black", bold: true, children: ` ${active.key} ${active.label} ` }) })
137029
137029
  ] });
137030
137030
  }
137031
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, paddingX: 1, paddingY: 0, children: [
137031
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, paddingX: 1, paddingY: 0, flexShrink: 0, overflow: "hidden", children: [
137032
137032
  /* @__PURE__ */ jsx(MiniLogo, {}),
137033
137033
  /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) }),
137034
137034
  tabs.map((t) => {
@@ -139066,6 +139066,15 @@ function InteractiveMode({ state, controller }) {
139066
139066
  function DashboardApp({ controller }) {
139067
139067
  const { exit } = useApp();
139068
139068
  const { stdout } = useStdout();
139069
+ const [, setResizeTick] = useState2(0);
139070
+ useEffect2(() => {
139071
+ if (!stdout) return;
139072
+ const onResize = () => setResizeTick((t) => t + 1);
139073
+ stdout.on("resize", onResize);
139074
+ return () => {
139075
+ stdout.off("resize", onResize);
139076
+ };
139077
+ }, [stdout]);
139069
139078
  const cols = stdout?.columns ?? 80;
139070
139079
  const rows = stdout?.rows ?? 24;
139071
139080
  const state = useSyncExternalStore(
@@ -139216,14 +139225,15 @@ function DashboardApp({ controller }) {
139216
139225
  }
139217
139226
  }
139218
139227
  });
139228
+ const layoutKey = `${cols}x${rows}`;
139219
139229
  if (!state.systemInfo) {
139220
- return /* @__PURE__ */ jsx(Box, { flexDirection: "column", height: rows, children: /* @__PURE__ */ jsx(SplashScreen, { loadingStatus: state.loadingStatus }) });
139230
+ return /* @__PURE__ */ jsx(Box, { flexDirection: "column", height: rows, width: cols, overflow: "hidden", children: /* @__PURE__ */ jsx(SplashScreen, { loadingStatus: state.loadingStatus }) }, layoutKey);
139221
139231
  }
139222
139232
  const isNarrow = cols < 80 || rows < 20;
139223
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", height: rows, children: [
139233
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", height: rows, width: cols, overflow: "hidden", children: [
139224
139234
  state.mode === "interactive" ? /* @__PURE__ */ jsx(InteractiveMode, { state, controller }) : isNarrow ? /* @__PURE__ */ jsx(StatusModeSingle, { state, controller }) : /* @__PURE__ */ jsx(StatusModeGrid, { state, rows, controller }),
139225
139235
  state.showHelp && /* @__PURE__ */ jsx(Box, { position: "absolute", marginTop: 3, marginLeft: 4, children: /* @__PURE__ */ jsx(HelpOverlay, {}) })
139226
- ] });
139236
+ ] }, layoutKey);
139227
139237
  }
139228
139238
  var LOGO_COLORS, NARROW_THRESHOLD, SPLASH_MIN_COLS, SPLASH_MIN_ROWS, LARGE_LOGO_MIN_COLS, LARGE_LOGO_MIN_ROWS, PREFIX_WIDTH, PANEL_ORDER, KANBAN_COLUMNS, COLUMN_COLORS, STEP_ICON, STEP_COLOR, MAX_LOG_ENTRIES2, INITIAL_LOG_LIMIT, SETTING_DEFS, FILES_DENYLIST;
139229
139239
  var init_app = __esm({
@@ -139318,7 +139328,11 @@ var init_controller = __esm({
139318
139328
  // notify() invalidates this; getSnapshot() rebuilds on demand.
139319
139329
  cachedSnapshot = null;
139320
139330
  // Ink instance — set when start() is called.
139331
+ // Loose type — the real Ink Instance has additional methods (clear,
139332
+ // rerender, etc.) that we use defensively below.
139321
139333
  inkInstance = null;
139334
+ // Resize listener attached at start(), detached at stop().
139335
+ resizeListener = null;
139322
139336
  // Uptime ticker to keep footer time live.
139323
139337
  uptimeTimer = null;
139324
139338
  // System stats sampler — process memory + CPU%.
@@ -139547,9 +139561,21 @@ var init_controller = __esm({
139547
139561
  const { render } = await import("ink");
139548
139562
  const { createElement } = await import("react");
139549
139563
  const { DashboardApp: DashboardApp2 } = await Promise.resolve().then(() => (init_app(), app_exports));
139564
+ if (process.stdout?.isTTY && typeof process.stdout.write === "function") {
139565
+ process.stdout.write("\x1B[?1049h\x1B[H");
139566
+ }
139550
139567
  this.inkInstance = render(
139551
139568
  createElement(DashboardApp2, { controller: this })
139552
139569
  );
139570
+ this.resizeListener = () => {
139571
+ try {
139572
+ this.inkInstance?.clear?.();
139573
+ } catch {
139574
+ }
139575
+ };
139576
+ if (process.stdout && typeof process.stdout.on === "function") {
139577
+ process.stdout.on("resize", this.resizeListener);
139578
+ }
139553
139579
  this.uptimeTimer = setInterval(() => {
139554
139580
  if (this.isRunning) this.notify();
139555
139581
  }, 5e3);
@@ -139571,10 +139597,17 @@ var init_controller = __esm({
139571
139597
  clearInterval(this.systemStatsTimer);
139572
139598
  this.systemStatsTimer = null;
139573
139599
  }
139600
+ if (this.resizeListener && process.stdout && typeof process.stdout.off === "function") {
139601
+ process.stdout.off("resize", this.resizeListener);
139602
+ this.resizeListener = null;
139603
+ }
139574
139604
  if (this.inkInstance) {
139575
139605
  this.inkInstance.unmount();
139576
139606
  this.inkInstance = null;
139577
139607
  }
139608
+ if (process.stdout?.isTTY && typeof process.stdout.write === "function") {
139609
+ process.stdout.write("\x1B[?1049l");
139610
+ }
139578
139611
  }
139579
139612
  // ── Private helpers ────────────────────────────────────────────────────────
139580
139613
  clampSelectedLogIndex(entries) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runfusion/fusion",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "license": "MIT",
5
5
  "description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
6
6
  "homepage": "https://github.com/Runfusion/Fusion#readme",
@@ -76,9 +76,9 @@
76
76
  "vitest": "^3.1.0",
77
77
  "yaml": "^2.8.3",
78
78
  "@fusion/core": "0.1.0",
79
- "@fusion/pi-claude-cli": "0.3.1",
80
79
  "@fusion/dashboard": "0.1.0",
81
- "@fusion/engine": "0.1.0"
80
+ "@fusion/engine": "0.1.0",
81
+ "@fusion/pi-claude-cli": "0.3.1"
82
82
  },
83
83
  "repository": {
84
84
  "type": "git",