fluxflow-cli 3.12.2 → 3.13.0

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/fluxflow.js CHANGED
@@ -3731,7 +3731,7 @@ var init_MultilineInput = __esm({
3731
3731
  });
3732
3732
 
3733
3733
  // src/utils/theme.js
3734
- var CHAOS_PRESETS, THEMES, getThemeColors;
3734
+ var CHAOS_PRESETS, THEMES, cachedChaosPreset, getThemeColors;
3735
3735
  var init_theme = __esm({
3736
3736
  "src/utils/theme.js"() {
3737
3737
  CHAOS_PRESETS = [
@@ -3979,6 +3979,153 @@ var init_theme = __esm({
3979
3979
  logoBodyAnsi: "\x1B[35m",
3980
3980
  logoMutedAnsi: "\x1B[90m",
3981
3981
  logoGradient: ["#ffb3d9", "#ff3399"]
3982
+ },
3983
+ {
3984
+ name: "Radioactive Slime",
3985
+ text: "#ccff00",
3986
+ textMuted: "#99cc00",
3987
+ textDim: "#669900",
3988
+ textInverted: "#0a0f00",
3989
+ border: "#ccff00",
3990
+ borderMuted: "#99cc00",
3991
+ borderDim: "#669900",
3992
+ bg: void 0,
3993
+ cardBg: "#0f1400",
3994
+ highlightBg: "#1a2400",
3995
+ activeBg: "#2a3b00",
3996
+ inputBg: "#1a2400",
3997
+ inputBorder: "#1a2400",
3998
+ inputText: "#ccff00",
3999
+ inputPlaceholder: "#669900",
4000
+ inputPrompt: "#cc00ff",
4001
+ codeBg: "#050a00",
4002
+ codeBorder: "#99cc00",
4003
+ userMsgBg: "#1a2400",
4004
+ userMsgBorder: "#1a2400",
4005
+ userMsgText: "#ccff00",
4006
+ diffRemovalBg: "#2a0033",
4007
+ diffAdditionBg: "#0f3300",
4008
+ diffRemovalText: "#ff00cc",
4009
+ diffAdditionText: "#00ff33",
4010
+ diffRemovalHighlightColor: "#ff33cc",
4011
+ diffRemovalHighlightBg: "#4d0066",
4012
+ diffAdditionHighlightColor: "#33ff66",
4013
+ diffAdditionHighlightBg: "#1a6600",
4014
+ diffRemovalNum: "#ff00cc",
4015
+ diffAdditionNum: "#00ff33",
4016
+ diffRemovalPrefix: "#ff33cc",
4017
+ diffAdditionPrefix: "#33ff66",
4018
+ primary: "#ccff00",
4019
+ secondary: "#cc00ff",
4020
+ accent: "#ff00cc",
4021
+ success: "#00ff33",
4022
+ warning: "#ffcc00",
4023
+ danger: "#ff0033",
4024
+ info: "#00ccff",
4025
+ statusOn: "#ccff00",
4026
+ statusOff: "#669900",
4027
+ logoTextAnsi: "\x1B[1;38;5;190m",
4028
+ logoBodyAnsi: "\x1B[38;5;190m",
4029
+ logoMutedAnsi: "\x1B[90m",
4030
+ logoGradient: ["#ccff00", "#cc00ff"]
4031
+ },
4032
+ {
4033
+ name: "Cosmic Void",
4034
+ text: "#f0f8ff",
4035
+ textMuted: "#a6aeb5",
4036
+ textDim: "#5e656e",
4037
+ textInverted: "#010103",
4038
+ border: "#f0f8ff",
4039
+ borderMuted: "#a6aeb5",
4040
+ borderDim: "#5e656e",
4041
+ bg: void 0,
4042
+ cardBg: "#05030d",
4043
+ highlightBg: "#0b081a",
4044
+ activeBg: "#171133",
4045
+ inputBg: "#0b081a",
4046
+ inputBorder: "#0b081a",
4047
+ inputText: "#f0f8ff",
4048
+ inputPlaceholder: "#5e656e",
4049
+ inputPrompt: "#ff007f",
4050
+ codeBg: "#020108",
4051
+ codeBorder: "#a6aeb5",
4052
+ userMsgBg: "#0b081a",
4053
+ userMsgBorder: "#0b081a",
4054
+ userMsgText: "#f0f8ff",
4055
+ diffRemovalBg: "#2e0a29",
4056
+ diffAdditionBg: "#091c33",
4057
+ diffRemovalText: "#ff33a6",
4058
+ diffAdditionText: "#33d6ff",
4059
+ diffRemovalHighlightColor: "#ff66c2",
4060
+ diffRemovalHighlightBg: "#5c1452",
4061
+ diffAdditionHighlightColor: "#66e0ff",
4062
+ diffAdditionHighlightBg: "#123866",
4063
+ diffRemovalNum: "#ff33a6",
4064
+ diffAdditionNum: "#33d6ff",
4065
+ diffRemovalPrefix: "#ff66c2",
4066
+ diffAdditionPrefix: "#66e0ff",
4067
+ primary: "#f0f8ff",
4068
+ secondary: "#ff007f",
4069
+ accent: "#9d00ff",
4070
+ success: "#33d6ff",
4071
+ warning: "#ffcc00",
4072
+ danger: "#ff0040",
4073
+ info: "#9d00ff",
4074
+ statusOn: "#f0f8ff",
4075
+ statusOff: "#5e656e",
4076
+ logoTextAnsi: "\x1B[1;38;5;231m",
4077
+ logoBodyAnsi: "\x1B[38;5;231m",
4078
+ logoMutedAnsi: "\x1B[38;5;240m",
4079
+ logoGradient: ["#ffffff", "#9d00ff"]
4080
+ },
4081
+ {
4082
+ name: "Magma Eruption",
4083
+ text: "#ff4d00",
4084
+ textMuted: "#cc3d00",
4085
+ textDim: "#802600",
4086
+ textInverted: "#0d0300",
4087
+ border: "#ff4d00",
4088
+ borderMuted: "#cc3d00",
4089
+ borderDim: "#802600",
4090
+ bg: void 0,
4091
+ cardBg: "#1a0600",
4092
+ highlightBg: "#260a00",
4093
+ activeBg: "#401100",
4094
+ inputBg: "#260a00",
4095
+ inputBorder: "#260a00",
4096
+ inputText: "#ff4d00",
4097
+ inputPlaceholder: "#802600",
4098
+ inputPrompt: "#ffcc00",
4099
+ codeBg: "#080200",
4100
+ codeBorder: "#cc3d00",
4101
+ userMsgBg: "#260a00",
4102
+ userMsgBorder: "#260a00",
4103
+ userMsgText: "#ff4d00",
4104
+ diffRemovalBg: "#2e0a0a",
4105
+ diffAdditionBg: "#1f1400",
4106
+ diffRemovalText: "#ff3333",
4107
+ diffAdditionText: "#ffaa00",
4108
+ diffRemovalHighlightColor: "#ff6666",
4109
+ diffRemovalHighlightBg: "#5c1414",
4110
+ diffAdditionHighlightColor: "#ffcc33",
4111
+ diffAdditionHighlightBg: "#3d2900",
4112
+ diffRemovalNum: "#ff3333",
4113
+ diffAdditionNum: "#ffaa00",
4114
+ diffRemovalPrefix: "#ff6666",
4115
+ diffAdditionPrefix: "#ffcc33",
4116
+ primary: "#ff4d00",
4117
+ secondary: "#ffcc00",
4118
+ accent: "#ff0040",
4119
+ success: "#ffaa00",
4120
+ warning: "#ffff00",
4121
+ danger: "#ff0000",
4122
+ info: "#ff8800",
4123
+ statusOn: "#ff4d00",
4124
+ statusOff: "#802600",
4125
+ logoTextAnsi: "\x1B[1;38;5;202m",
4126
+ logoBodyAnsi: "\x1B[38;5;202m",
4127
+ logoMutedAnsi: "\x1B[38;5;236m",
4128
+ logoGradient: ["#ff4d00", "#ff0000"]
3982
4129
  }
3983
4130
  ];
3984
4131
  THEMES = {
@@ -4337,17 +4484,129 @@ var init_theme = __esm({
4337
4484
  logoBodyAnsi: "\x1B[30m",
4338
4485
  logoMutedAnsi: "\x1B[38;5;244m",
4339
4486
  logoGradient: ["#0077ff", "#ff00ff"]
4487
+ },
4488
+ "Synthwave 84": {
4489
+ id: "Synthwave 84",
4490
+ name: "Synthwave 84",
4491
+ text: "#fdfdfd",
4492
+ textMuted: "#a08eb7",
4493
+ textDim: "#705c8a",
4494
+ textInverted: "#1a1025",
4495
+ textExclusive: "#e3dcf0",
4496
+ textMutedExclusive: "#b9abc9",
4497
+ border: "#fc28a8",
4498
+ borderMuted: "#a21568",
4499
+ borderDim: "#5c0a3a",
4500
+ bg: void 0,
4501
+ cardBg: "#261b38",
4502
+ highlightBg: "#35254d",
4503
+ activeBg: "#4c3570",
4504
+ inputBg: "#35254d",
4505
+ inputBorder: "#35254d",
4506
+ inputText: "#fdfdfd",
4507
+ inputPlaceholder: "#a08eb7",
4508
+ inputPrompt: "#03e8fc",
4509
+ codeBg: "#1e142b",
4510
+ codeBorder: "#a21568",
4511
+ userMsgBg: "#35254d",
4512
+ userMsgBorder: "#35254d",
4513
+ userMsgText: "#fdfdfd",
4514
+ diffRemovalBg: "#471434",
4515
+ diffAdditionBg: "#144743",
4516
+ diffRemovalText: "#ff4081",
4517
+ diffAdditionText: "#00e5ff",
4518
+ diffRemovalHighlightColor: "#ff79a1",
4519
+ diffRemovalHighlightBg: "#6b1e4e",
4520
+ diffAdditionHighlightColor: "#66f5ff",
4521
+ diffAdditionHighlightBg: "#1e6b65",
4522
+ diffRemovalNum: "#ff4081",
4523
+ diffAdditionNum: "#00e5ff",
4524
+ diffRemovalPrefix: "#ff79a1",
4525
+ diffAdditionPrefix: "#66f5ff",
4526
+ primary: "#fdfdfd",
4527
+ secondary: "#03e8fc",
4528
+ accent: "#fc28a8",
4529
+ success: "#00e5ff",
4530
+ warning: "#ffc107",
4531
+ danger: "#ff4081",
4532
+ info: "#b388ff",
4533
+ statusOn: "#03e8fc",
4534
+ statusOff: "#a08eb7",
4535
+ logoTextAnsi: "\x1B[1;35m",
4536
+ logoBodyAnsi: "\x1B[35m",
4537
+ logoMutedAnsi: "\x1B[90m",
4538
+ logoGradient: ["#fc28a8", "#03e8fc"]
4539
+ },
4540
+ "Forest Sprite": {
4541
+ id: "Forest Sprite",
4542
+ name: "Forest Sprite",
4543
+ text: "#d6e6d1",
4544
+ textMuted: "#95b38d",
4545
+ textDim: "#628059",
4546
+ textInverted: "#161c14",
4547
+ textExclusive: "#eaf2e8",
4548
+ textMutedExclusive: "#a9c7a2",
4549
+ border: "#74a862",
4550
+ borderMuted: "#477038",
4551
+ borderDim: "#2b4720",
4552
+ bg: void 0,
4553
+ cardBg: "#1f291c",
4554
+ highlightBg: "#2a3826",
4555
+ activeBg: "#3a4d35",
4556
+ inputBg: "#2a3826",
4557
+ inputBorder: "#2a3826",
4558
+ inputText: "#d6e6d1",
4559
+ inputPlaceholder: "#95b38d",
4560
+ inputPrompt: "#8feb73",
4561
+ codeBg: "#161e14",
4562
+ codeBorder: "#477038",
4563
+ userMsgBg: "#2a3826",
4564
+ userMsgBorder: "#2a3826",
4565
+ userMsgText: "#d6e6d1",
4566
+ diffRemovalBg: "#3b231c",
4567
+ diffAdditionBg: "#203b1c",
4568
+ diffRemovalText: "#db6242",
4569
+ diffAdditionText: "#59cc3f",
4570
+ diffRemovalHighlightColor: "#f0896c",
4571
+ diffRemovalHighlightBg: "#5c362a",
4572
+ diffAdditionHighlightColor: "#80e368",
4573
+ diffAdditionHighlightBg: "#305929",
4574
+ diffRemovalNum: "#db6242",
4575
+ diffAdditionNum: "#59cc3f",
4576
+ diffRemovalPrefix: "#f0896c",
4577
+ diffAdditionPrefix: "#80e368",
4578
+ primary: "#d6e6d1",
4579
+ secondary: "#8feb73",
4580
+ accent: "#e69835",
4581
+ success: "#59cc3f",
4582
+ warning: "#e69835",
4583
+ danger: "#db6242",
4584
+ info: "#73b4eb",
4585
+ statusOn: "#8feb73",
4586
+ statusOff: "#95b38d",
4587
+ logoTextAnsi: "\x1B[1;32m",
4588
+ logoBodyAnsi: "\x1B[32m",
4589
+ logoMutedAnsi: "\x1B[90m",
4590
+ logoGradient: ["#8feb73", "#e69835"]
4340
4591
  }
4341
4592
  };
4593
+ cachedChaosPreset = null;
4342
4594
  getThemeColors = (themeName = "Dark") => {
4343
- if (themeName === "Chaos" || themeName === "Mystery") {
4344
- const randomPreset = CHAOS_PRESETS[Math.floor(Math.random() * CHAOS_PRESETS.length)];
4345
- return { ...randomPreset, id: "Chaos" };
4346
- }
4347
- if (THEMES[themeName]) return THEMES[themeName];
4348
- if (themeName === "GitHub") return THEMES["GitHub Dark"];
4349
- if (themeName === "Transparent") return THEMES["Transparent Dark"];
4350
- return THEMES.Dark;
4595
+ let colors;
4596
+ if (themeName === "Mystery" || themeName === "Chaos") {
4597
+ if (!cachedChaosPreset) {
4598
+ cachedChaosPreset = CHAOS_PRESETS[Math.floor(Math.random() * CHAOS_PRESETS.length)];
4599
+ }
4600
+ colors = { ...cachedChaosPreset, id: "Mystery" };
4601
+ } else {
4602
+ cachedChaosPreset = null;
4603
+ if (THEMES[themeName]) colors = THEMES[themeName];
4604
+ else if (themeName === "GitHub") colors = THEMES["GitHub Dark"];
4605
+ else if (themeName === "Transparent") colors = THEMES["Transparent Dark"];
4606
+ else colors = THEMES.Dark;
4607
+ }
4608
+ const codeColor = colors.codeText || colors.secondary || colors.info || colors.logoGradient && colors.logoGradient[0] || "cyan";
4609
+ return { ...colors, codeText: codeColor };
4351
4610
  };
4352
4611
  }
4353
4612
  });
@@ -4788,7 +5047,7 @@ var init_terminal = __esm({
4788
5047
  return `${coloredArt[0]}
4789
5048
  ${coloredArt[1]} ${textColor}Selected Provider: ${provider}${reset}
4790
5049
  ${coloredArt[2]}
4791
- ${coloredArt[3]} ${textColor}FLUX FLOW ${grey("v" + version)}${reset}
5050
+ ${coloredArt[3]} ${textColor}FluxFlow ${grey("v" + version)}${reset}
4792
5051
  ${coloredArt[4]}
4793
5052
  ${coloredArt[5]} ${bodyColor}See /help for additional commands.${reset}
4794
5053
  ${coloredArt[6]} ${grey(quote)}
@@ -4970,12 +5229,13 @@ var init_ChatLayout = __esm({
4970
5229
  if (!text) return null;
4971
5230
  const colors = getThemeColors(theme);
4972
5231
  const textColor = color || colors.text;
5232
+ const highlightColor = colors.codeText || colors.logoGradient && colors.logoGradient[0] || colors.info || colors.secondary || "cyan";
4973
5233
  const parts = text.split(REGEX_MD_TOKENS);
4974
5234
  return /* @__PURE__ */ React4.createElement(Text4, { color: textColor, wrap: "anywhere", italic }, parts.map((part, j) => {
4975
5235
  if (!part) return null;
4976
5236
  if (part.startsWith("```") && part.endsWith("```")) {
4977
5237
  const content = part.slice(3, -3);
4978
- return /* @__PURE__ */ React4.createElement(Text4, { key: j, color: "cyan" }, content);
5238
+ return /* @__PURE__ */ React4.createElement(Text4, { key: j, color: highlightColor }, content);
4979
5239
  }
4980
5240
  if (part.startsWith("**") && part.endsWith("**")) {
4981
5241
  return /* @__PURE__ */ React4.createElement(Text4, { key: j, bold: true, color: textColor }, /* @__PURE__ */ React4.createElement(InlineMarkdown, { text: part.slice(2, -2), color: textColor, theme }));
@@ -4989,12 +5249,12 @@ var init_ChatLayout = __esm({
4989
5249
  return p1.split("/").pop().split("\\").pop().replace(REGEX_COLON_L, "#L");
4990
5250
  });
4991
5251
  const hasFileRef = content.includes("@[");
4992
- return /* @__PURE__ */ React4.createElement(Text4, { key: j, color: "cyan", bold: hasFileRef }, formatted);
5252
+ return /* @__PURE__ */ React4.createElement(Text4, { key: j, color: highlightColor, bold: hasFileRef }, formatted);
4993
5253
  }
4994
5254
  if (part.startsWith("@[") && part.endsWith("]")) {
4995
5255
  const filePath = part.slice(2, -1);
4996
5256
  const basename = filePath.split("/").pop().split("\\").pop().replace(REGEX_COLON_L, "#L");
4997
- return /* @__PURE__ */ React4.createElement(Text4, { key: j, color: "cyan", bold: true }, basename);
5257
+ return /* @__PURE__ */ React4.createElement(Text4, { key: j, color: highlightColor, bold: true }, basename);
4998
5258
  }
4999
5259
  if (part.startsWith("\\(") && part.endsWith("\\)") || part.startsWith("\\[") && part.endsWith("\\]")) {
5000
5260
  const content = part.slice(2, -2);
@@ -5006,14 +5266,14 @@ var init_ChatLayout = __esm({
5006
5266
  }
5007
5267
  if (part.startsWith("[") && (part.includes("](") || part.includes("] ("))) {
5008
5268
  const match = part.match(REGEX_MD_LINK_PAREN);
5009
- if (match) return /* @__PURE__ */ React4.createElement(Text4, { key: j }, /* @__PURE__ */ React4.createElement(Text4, { color: "cyan", underline: true, bold: true }, match[1]), /* @__PURE__ */ React4.createElement(Text4, { color: "gray", italic: true }, " (", match[2], ")"));
5269
+ if (match) return /* @__PURE__ */ React4.createElement(Text4, { key: j }, /* @__PURE__ */ React4.createElement(Text4, { color: highlightColor, underline: true, bold: true }, match[1]), /* @__PURE__ */ React4.createElement(Text4, { color: "gray", italic: true }, " (", match[2], ")"));
5010
5270
  }
5011
5271
  if (part.startsWith("[") && (part.includes("][") || part.includes("] ["))) {
5012
5272
  const match = part.match(REGEX_MD_LINK_BRACKET);
5013
- if (match) return /* @__PURE__ */ React4.createElement(Text4, { key: j }, /* @__PURE__ */ React4.createElement(Text4, { color: "cyan", underline: true, bold: true }, match[1]), /* @__PURE__ */ React4.createElement(Text4, { color: "gray", italic: true }, " [", match[2], "]"));
5273
+ if (match) return /* @__PURE__ */ React4.createElement(Text4, { key: j }, /* @__PURE__ */ React4.createElement(Text4, { color: highlightColor, underline: true, bold: true }, match[1]), /* @__PURE__ */ React4.createElement(Text4, { color: "gray", italic: true }, " [", match[2], "]"));
5014
5274
  }
5015
5275
  if (part.startsWith("http")) {
5016
- return /* @__PURE__ */ React4.createElement(Text4, { key: j, color: "cyan", underline: true, italic: true }, part);
5276
+ return /* @__PURE__ */ React4.createElement(Text4, { key: j, color: highlightColor, underline: true, italic: true }, part);
5017
5277
  }
5018
5278
  return renderLatexText(part, j);
5019
5279
  }));
@@ -5021,6 +5281,7 @@ var init_ChatLayout = __esm({
5021
5281
  TableRenderer = React4.memo(({ buffer, terminalWidth = 80, theme = "Dark" }) => {
5022
5282
  if (buffer.length < 2) return null;
5023
5283
  const colors = getThemeColors(theme);
5284
+ const headerColor = colors.codeText || colors.secondary || colors.info || "cyan";
5024
5285
  const rows = buffer.map((line) => {
5025
5286
  const parts = line.split("|");
5026
5287
  if (parts[0] !== void 0 && parts[0].trim() === "") parts.shift();
@@ -5034,7 +5295,7 @@ var init_ChatLayout = __esm({
5034
5295
  const colChars = Math.floor(availableWidth / header.length) - 2;
5035
5296
  return (
5036
5297
  // Table MarginY here
5037
- /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: colors.borderMuted, paddingX: 1, marginY: 0, width: terminalWidth - 2 }, /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "row", borderStyle: "single", borderBottom: true, borderTop: false, borderLeft: false, borderRight: false, borderColor: colors.borderMuted, marginBottom: 1, paddingBottom: 0, width: "100%" }, header.map((cell, i) => /* @__PURE__ */ React4.createElement(Box3, { key: i, flexBasis: `${colPercentage}%`, flexGrow: 1, flexShrink: 0, paddingRight: 2 }, /* @__PURE__ */ React4.createElement(InlineMarkdown, { text: wrapText(cell, colChars), color: "cyan", theme })))), data.map((row, ri) => /* @__PURE__ */ React4.createElement(Box3, { key: ri, flexDirection: "row", marginBottom: ri === data.length - 1 ? 0 : 1, width: "100%" }, row.map((cell, ci) => /* @__PURE__ */ React4.createElement(Box3, { key: ci, flexBasis: `${colPercentage}%`, flexGrow: 1, flexShrink: 0, paddingRight: 2, flexDirection: "column" }, /* @__PURE__ */ React4.createElement(InlineMarkdown, { text: wrapText(cell, colChars), color: colors.text, theme }))))))
5298
+ /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: colors.borderMuted, paddingX: 1, marginY: 0, width: terminalWidth - 2 }, /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "row", borderStyle: "single", borderBottom: true, borderTop: false, borderLeft: false, borderRight: false, borderColor: colors.borderMuted, marginBottom: 1, paddingBottom: 0, width: "100%" }, header.map((cell, i) => /* @__PURE__ */ React4.createElement(Box3, { key: i, flexBasis: `${colPercentage}%`, flexGrow: 1, flexShrink: 0, paddingRight: 2 }, /* @__PURE__ */ React4.createElement(InlineMarkdown, { text: wrapText(cell, colChars), color: headerColor, theme })))), data.map((row, ri) => /* @__PURE__ */ React4.createElement(Box3, { key: ri, flexDirection: "row", marginBottom: ri === data.length - 1 ? 0 : 1, width: "100%" }, row.map((cell, ci) => /* @__PURE__ */ React4.createElement(Box3, { key: ci, flexBasis: `${colPercentage}%`, flexGrow: 1, flexShrink: 0, paddingRight: 2, flexDirection: "column" }, /* @__PURE__ */ React4.createElement(InlineMarkdown, { text: wrapText(cell, colChars), color: colors.text, theme }))))))
5038
5299
  );
5039
5300
  });
5040
5301
  MarkdownText = React4.memo(({ text, color, columns = 80, italic = false, theme = "Dark" }) => {
@@ -5412,7 +5673,9 @@ var init_ChatLayout = __esm({
5412
5673
  { cmd: "/mode", desc: "Toggle Flux/Flow modes" },
5413
5674
  { cmd: "/thinking", desc: "Set AI reasoning depth" },
5414
5675
  { cmd: "/model", desc: "Switch AI model" },
5676
+ { cmd: "/provider", desc: "Select AI Provider" },
5415
5677
  { cmd: "/settings", desc: "Configure system prefs" },
5678
+ { cmd: "/theme", desc: "Customize UI color theme" },
5416
5679
  { cmd: "/key", desc: "Manage API keys" },
5417
5680
  { cmd: "/profile", desc: "Edit developer persona" },
5418
5681
  { cmd: "/memory", desc: "Manage agent memory" },
@@ -6068,7 +6331,7 @@ var init_arg_parser = __esm({
6068
6331
 
6069
6332
  // src/data/main_tools.js
6070
6333
  import { execSync } from "child_process";
6071
- var _isPsAvailable, isPsAvailable, TOOL_PROTOCOL;
6334
+ var _isPsAvailable, isPsAvailable, _cachedAdvanceRollback, TOOL_PROTOCOL;
6072
6335
  var init_main_tools = __esm({
6073
6336
  async "src/data/main_tools.js"() {
6074
6337
  await init_exec_command();
@@ -6084,7 +6347,12 @@ var init_main_tools = __esm({
6084
6347
  }
6085
6348
  return _isPsAvailable;
6086
6349
  };
6087
- TOOL_PROTOCOL = (mode, osDetected, isMultiModal, aiProvider, advanceRollback = false, enableSubAgents = true) => `
6350
+ _cachedAdvanceRollback = null;
6351
+ TOOL_PROTOCOL = (mode, osDetected, isMultiModal, aiProvider, advanceRollback = false, enableSubAgents = true) => {
6352
+ if (_cachedAdvanceRollback === null) {
6353
+ _cachedAdvanceRollback = advanceRollback;
6354
+ }
6355
+ return `
6088
6356
  -- TOOL DEFINITIONS --
6089
6357
  Tool calls: ONLY use [tool:functions.ToolName(args)]
6090
6358
  **NO OTHER SYNTAX/MARKERS/BOUNDARY ALLOWED**
@@ -6108,7 +6376,7 @@ ${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative; FIRST ARGUMENT, path se
6108
6376
  6. [tool:functions.SearchKeyword(keyword="...", path="optional, target directory or filename", subString="true optional", regex="false for keyword, optional")]. Project-wide search. path limits scope to a file/dir. Find definitions/logic without full reads. Locate relevant code. Defaults: subString=false, regex=true
6109
6377
  7. [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `WINDOWS POWERSHELL` : `WINDOWS CMD ONLY` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user
6110
6378
  8. [tool:functions.Todo(method="create/append/get", tasks=[ARRAY OF STRINGS], markDone=[ARRAY OF TASK STRINGS])]. Task list, no Markdown in arrays. Analyze request: if multi-task, break it down & create Todos BEFORE starting. \`tasks\` & \`markDone\` optional with \`get\`. Use \`get + markDone\` to complete tasks, or \`create + markDone\` to create completed tasks. **UPDATE EVERY TURN**${enableSubAgents ? '\n9. [tool:functions.Await(time="seconds")]. For waiting without exiting agent loop, 15s - 180s' : ""}
6111
- ${advanceRollback ? `
6379
+ ${_cachedAdvanceRollback ? `
6112
6380
  - EMERGENCY SAFETY TOOLS -
6113
6381
  Info: \`initial\` = user prompt for current task. Revert \`id\` = turn BEFORE the disaster tool (e.g. disaster:\`turn_3\` \u2192 revert:\`turn_2\`). Reason explicitly if needed.
6114
6382
  1. [tool:functions.EmergencyRollback(method="getCheckpoint/forceRevert", id="...")]. Rollback workspace to a checkpoint in THIS agent loop.
@@ -6130,6 +6398,7 @@ Invocations:
6130
6398
  - **Escape quotes: \\" for code strings**
6131
6399
  - **Literal escapes: Double-escape sequences (e.g., \\\\n)**
6132
6400
  - **File structure: Real newlines for code formatting**`.trim();
6401
+ };
6133
6402
  }
6134
6403
  });
6135
6404
 
@@ -6822,13 +7091,21 @@ function SettingsMenu({
6822
7091
  saveSettings: saveSettings2,
6823
7092
  quotas,
6824
7093
  setMessages,
6825
- aiProvider
7094
+ aiProvider,
7095
+ initialSelectingTheme = false,
7096
+ onCloseTheme = null,
7097
+ setProviderReturnView = null
6826
7098
  }) {
7099
+ const activeTheme = systemSettings.theme === "Chaos" || systemSettings.theme === "Mystery" ? "Mystery" : systemSettings.theme || "Dark";
7100
+ const defaultIdx = themeOptions.indexOf(activeTheme);
6827
7101
  const [activeColumn, setActiveColumn] = useState6("categories");
6828
7102
  const [selectedCategoryIndex, setSelectedCategoryIndex] = useState6(0);
6829
7103
  const [selectedItemIndex, setSelectedItemIndex] = useState6(0);
6830
7104
  const [editingItem, setEditingItem] = useState6(null);
6831
7105
  const [editValue, setEditValue] = useState6("");
7106
+ const [isSelectingTheme, setIsSelectingTheme] = useState6(initialSelectingTheme);
7107
+ const [themeIndex, setThemeIndex] = useState6(defaultIdx >= 0 ? defaultIdx : 0);
7108
+ const [initialTheme, setInitialTheme] = useState6(systemSettings.theme || "Dark");
6832
7109
  const [currentMemory, setCurrentMemory] = useState6(0);
6833
7110
  const [maxMemory, setMaxMemory] = useState6(0);
6834
7111
  const [memoryUnit, setMemoryUnit] = useState6("MB");
@@ -6903,6 +7180,28 @@ function SettingsMenu({
6903
7180
  const currentCatId = CATEGORIES[selectedCategoryIndex].id;
6904
7181
  const currentItems = getCategoryItems(currentCatId);
6905
7182
  useInput3((input, key) => {
7183
+ if (isSelectingTheme) {
7184
+ if (key.upArrow) {
7185
+ const nextIdx = (themeIndex - 1 + themeOptions.length) % themeOptions.length;
7186
+ setThemeIndex(nextIdx);
7187
+ } else if (key.downArrow) {
7188
+ const nextIdx = (themeIndex + 1) % themeOptions.length;
7189
+ setThemeIndex(nextIdx);
7190
+ } else if (key.return) {
7191
+ const selectedTheme = themeOptions[themeIndex];
7192
+ setSystemSettings((s) => {
7193
+ const newSysSettings = { ...s, theme: selectedTheme };
7194
+ saveSettings2({ systemSettings: newSysSettings, apiTier, quotas });
7195
+ return newSysSettings;
7196
+ });
7197
+ if (onCloseTheme) onCloseTheme();
7198
+ else setIsSelectingTheme(false);
7199
+ } else if (key.escape) {
7200
+ if (onCloseTheme) onCloseTheme();
7201
+ else setIsSelectingTheme(false);
7202
+ }
7203
+ return;
7204
+ }
6906
7205
  if (editingItem) {
6907
7206
  if (key.escape) {
6908
7207
  setEditingItem(null);
@@ -7012,6 +7311,7 @@ function SettingsMenu({
7012
7311
  } else if (item.value === "apiTier") {
7013
7312
  setActiveView("apiTier");
7014
7313
  } else if (item.value === "aiProvider") {
7314
+ if (setProviderReturnView) setProviderReturnView("settings");
7015
7315
  setActiveView("selectProvider");
7016
7316
  } else if (item.value === "advanceRollback") {
7017
7317
  if (!systemSettings.advanceRollback) {
@@ -7081,18 +7381,24 @@ function SettingsMenu({
7081
7381
  return newSysSettings;
7082
7382
  });
7083
7383
  } else if (item.value === "theme") {
7084
- const options = ["Dark", "Light", "GitHub Dark", "GitHub Light", "Transparent Dark", "Transparent Light", "Chaos"];
7085
- const activeTheme = systemSettings.theme === "Mystery" ? "Chaos" : systemSettings.theme || "Dark";
7086
- const currentIndex = options.indexOf(activeTheme);
7087
- const nextIndex = (currentIndex + 1) % options.length;
7088
- setSystemSettings((s) => {
7089
- const newSysSettings = { ...s, theme: options[nextIndex] };
7090
- saveSettings2({ systemSettings: newSysSettings, apiTier, quotas });
7091
- return newSysSettings;
7092
- });
7384
+ const activeTheme2 = systemSettings.theme === "Chaos" || systemSettings.theme === "Mystery" ? "Mystery" : systemSettings.theme || "Dark";
7385
+ const idx = themeOptions.indexOf(activeTheme2);
7386
+ setThemeIndex(idx >= 0 ? idx : 0);
7387
+ setInitialTheme(systemSettings.theme || "Dark");
7388
+ setIsSelectingTheme(true);
7093
7389
  }
7094
7390
  };
7095
7391
  const colors = getThemeColors(systemSettings.theme);
7392
+ if (isSelectingTheme) {
7393
+ const previewThemeName = themeOptions[themeIndex];
7394
+ const previewColors = getThemeColors(previewThemeName);
7395
+ return /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", borderStyle: "round", borderColor: previewColors.border, padding: 1, width: "100%", minHeight: 32 }, /* @__PURE__ */ React7.createElement(Box6, { marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.text, bold: true }, "Choose your color scheme:")), /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "row", width: "100%", flexGrow: 1 }, /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", width: "30%", paddingRight: 1 }, themeOptions.map((tName, index) => {
7396
+ const isSelected = themeIndex === index;
7397
+ const isSaved = (systemSettings.theme || "Dark") === tName;
7398
+ const isForest = tName === "Forest Sprite";
7399
+ return /* @__PURE__ */ React7.createElement(Box6, { key: tName, paddingX: 0 }, /* @__PURE__ */ React7.createElement(Text7, { color: isSelected ? previewColors.text : previewColors.textDim, bold: isSelected }, isSelected ? "> " : " ", tName, isForest && /* @__PURE__ */ React7.createElement(Text7, { color: isSelected ? previewColors.success || "#52b788" : "green", bold: true }, " \u2605"), isSaved ? /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.primary || "cyan", italic: true }, " (saved)") : ""));
7400
+ })), /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", flexGrow: 1, borderStyle: "round", borderColor: previewColors.borderMuted, paddingX: 2, paddingY: 1, backgroundColor: previewColors.cardBg }, /* @__PURE__ */ React7.createElement(Box6, { marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.secondary || "cyan", bold: true }, "> ", "you: "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.text }, "add a greeting function")), /* @__PURE__ */ React7.createElement(Box6, { marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.success || "green" }, " Here's the change:")), /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", marginLeft: 2, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, null, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.textDim }, "3 "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.textDim }, ' import "fmt"')), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.textDim }, "4"), /* @__PURE__ */ React7.createElement(Box6, { backgroundColor: previewColors.diffRemovalBg }, /* @__PURE__ */ React7.createElement(Text7, null, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffRemovalNum || previewColors.diffRemovalText }, "5 "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffRemovalPrefix || previewColors.diffRemovalText }, "- "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffRemovalText }, "func "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffRemovalHighlightColor || previewColors.diffRemovalText, backgroundColor: previewColors.diffRemovalHighlightBg, bold: true }, "main()"), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffRemovalText }, " {"))), /* @__PURE__ */ React7.createElement(Box6, { backgroundColor: previewColors.diffAdditionBg }, /* @__PURE__ */ React7.createElement(Text7, null, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffAdditionNum || previewColors.diffAdditionText }, "5 "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffAdditionPrefix || previewColors.diffAdditionText }, "+ "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffAdditionText }, "func "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffAdditionHighlightColor || previewColors.diffAdditionText, backgroundColor: previewColors.diffAdditionHighlightBg, bold: true }, "greet(name string)"), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffAdditionText }, " {"))), /* @__PURE__ */ React7.createElement(Box6, { backgroundColor: previewColors.diffAdditionBg }, /* @__PURE__ */ React7.createElement(Text7, null, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffAdditionNum || previewColors.diffAdditionText }, "6 "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffAdditionPrefix || previewColors.diffAdditionText }, "+ "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffAdditionText }, " "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.diffAdditionHighlightColor || previewColors.diffAdditionText, backgroundColor: previewColors.diffAdditionHighlightBg }, 'fmt.Printf("Hello, %s!\\n", name)'))), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.textDim }, "7 }")), /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.textDim }, "\u25BE Thought Process"), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.textMuted }, " I need to add a greeting function. I'll use fmt.Printf.")), /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text7, null, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.warning || "yellow" }, "\u2699 tool: "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.text }, "write_file main.go")), /* @__PURE__ */ React7.createElement(Text7, null, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.accent || "magenta" }, "\u29BF task: "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.text }, "Implementing greeting")), /* @__PURE__ */ React7.createElement(Text7, null, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.danger || "red" }, "X error: "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.text }, "compilation failed")), /* @__PURE__ */ React7.createElement(Text7, null, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.warning || "yellow" }, "\u26A0 warning: "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.text }, "deprecation warning")), /* @__PURE__ */ React7.createElement(Text7, null, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.info || "blue" }, "\u2192 link: "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.info || "blue", underline: true }, "file:///path/to/main.go")), /* @__PURE__ */ React7.createElement(Text7, null, /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.accent || "magenta" }, "\u2605 accent: "), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.text }, "highlighted text")), /* @__PURE__ */ React7.createElement(Text7, { color: previewColors.textDim }, "\xB7 dim: press Enter to continue")))), /* @__PURE__ */ React7.createElement(Box6, { paddingX: 1, marginTop: 1, flexDirection: "row", justifyContent: "space-between" }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", italic: true }, "\u25B2\u25BC Navigate \u2022 ENTER to Select \u2022 ESC to Cancel"), /* @__PURE__ */ React7.createElement(Text7, { color: "gray" }, "Previewing: ", themeOptions[themeIndex], themeOptions[themeIndex] === "Forest Sprite" ? " \u2605" : "")));
7401
+ }
7096
7402
  return /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", borderStyle: "round", borderColor: colors.border, padding: 0, width: "100%", minHeight: 32 }, /* @__PURE__ */ React7.createElement(Box6, { paddingX: 1, paddingY: 0, marginBottom: 0, borderStyle: "single", borderColor: colors.borderMuted, width: "100%" }, /* @__PURE__ */ React7.createElement(Text7, { color: colors.text, bold: true }, "SYSTEM CONFIGURATION")), /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "row", width: "100%", minHeight: 26 }, /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", width: "30%", maxWidth: 40, borderStyle: "round", borderColor: activeColumn === "categories" ? colors.border : colors.borderMuted, padding: 1, paddingY: 0 }, /* @__PURE__ */ React7.createElement(Box6, { marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: activeColumn === "categories" ? colors.text : colors.textDim, bold: true, underline: true }, "CATEGORIES")), CATEGORIES.map((cat, index) => {
7097
7403
  const isSelected = selectedCategoryIndex === index;
7098
7404
  const isExit = cat.id === "exit";
@@ -7181,11 +7487,12 @@ function SettingsMenu({
7181
7487
  return elements;
7182
7488
  })() : /* @__PURE__ */ React7.createElement(Box6, { paddingX: 1, flexDirection: "column", width: "100%" }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", italic: true }, CATEGORIES[selectedCategoryIndex].desc), currentCatId === "exit" && /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Box6, { key: "pty-notice", marginTop: 19, paddingX: 0 }, /* @__PURE__ */ React7.createElement(Text7, { color: colors.text }, isPtyAvailable ? "\u2713 Advance Interactive Terminal Supported" : "\u26A0 Interactive Terminal is Limited")), /* @__PURE__ */ React7.createElement(Box6, { key: "memory-load-2026", paddingX: 0 }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray" }, "Memory Load: ", currentMemory, "/", maxMemory, " ", memoryUnit)))))), /* @__PURE__ */ React7.createElement(Box6, { paddingX: 1, marginTop: 0, flexDirection: "row", justifyContent: "space-between" }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", italic: true }, activeColumn === "categories" ? "\u25B2\u25BC Select Category \u2022 Enter/\u25BA to configure" : "\u25B2\u25BC Select Option \u2022 Enter to Toggle \u2022 \u25C4/ESC to go back"), activeColumn === "categories" && /* @__PURE__ */ React7.createElement(Text7, { color: "gray" }, CATEGORIES[selectedCategoryIndex].desc)));
7183
7489
  }
7184
- var CATEGORIES, getActivePreset, truncateCSV;
7490
+ var themeOptions, CATEGORIES, getActivePreset, truncateCSV;
7185
7491
  var init_SettingsMenu = __esm({
7186
7492
  async "src/components/SettingsMenu.jsx"() {
7187
7493
  await init_exec_command();
7188
7494
  init_theme();
7495
+ themeOptions = [...Object.keys(THEMES), "Mystery"];
7189
7496
  CATEGORIES = [
7190
7497
  { id: "appearance", label: "Appearance", desc: "Customize UI theme & rendering options" },
7191
7498
  { id: "memory", label: "Memory", desc: "Manage system context & agent's memory" },
@@ -12535,18 +12842,19 @@ var init_ai = __esm({
12535
12842
  let attempts = 0;
12536
12843
  const maxAttempts = 6;
12537
12844
  let hasYielded = false;
12538
- let baseUrl = process.env.NVIDIA_BASE_URL || "https://integrate.api.nvidia.com/v1/chat/completions";
12539
- if (!baseUrl.endsWith("/chat/completions")) {
12540
- baseUrl = baseUrl.replace(/\/+$/, "") + "/chat/completions";
12845
+ let _baseUrl = process.env.NVIDIA_BASE_URL || "https://integrate.api.nvidia.com/v1/chat/completions";
12846
+ let _apiKey = process.env.NVIDIA_API_KEY && process.env.NVIDIA_BASE_URL ? process.env.NVIDIA_API_KEY : apiKey;
12847
+ if (!_baseUrl.endsWith("/chat/completions")) {
12848
+ _baseUrl = _baseUrl.replace(/\/+$/, "") + "/chat/completions";
12541
12849
  }
12542
12850
  while (attempts < maxAttempts) {
12543
12851
  attempts++;
12544
12852
  try {
12545
- const response = await fetchWithBackoff(baseUrl, {
12853
+ const response = await fetchWithBackoff(_baseUrl, {
12546
12854
  method: "POST",
12547
12855
  headers: {
12548
12856
  "Content-Type": "application/json",
12549
- "Authorization": `Bearer ${apiKey}`
12857
+ "Authorization": `Bearer ${_apiKey}`
12550
12858
  },
12551
12859
  body: JSON.stringify(body),
12552
12860
  signal
@@ -17616,7 +17924,8 @@ var init_witty_phrases = __esm({
17616
17924
  // src/components/RevertModal.jsx
17617
17925
  import React14, { useState as useState13 } from "react";
17618
17926
  import { Box as Box13, Text as Text14, useInput as useInput8 } from "ink";
17619
- function RevertModal({ prompts, onSelect, onClose }) {
17927
+ function RevertModal({ prompts, onSelect, onClose, theme = "Dark" }) {
17928
+ const colors = getThemeColors(theme);
17620
17929
  const [selectedIndex, setSelectedIndex] = useState13(0);
17621
17930
  useInput8((input, key) => {
17622
17931
  if (key.escape) onClose();
@@ -17637,7 +17946,7 @@ function RevertModal({ prompts, onSelect, onClose }) {
17637
17946
  }
17638
17947
  }
17639
17948
  const visiblePrompts = prompts.slice(startIndex, startIndex + MAX_VISIBLE);
17640
- return /* @__PURE__ */ React14.createElement(Box13, { flexDirection: "column", borderStyle: "round", borderColor: "grey", padding: 0, width: "100%" }, /* @__PURE__ */ React14.createElement(Box13, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true }, "CODEBASE TIME TRAVEL: SELECT UNDO POINT")), /* @__PURE__ */ React14.createElement(Box13, { paddingX: 2, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, null, "Select a prompt to revert the codebase back to the state ", /* @__PURE__ */ React14.createElement(Text14, { bold: true, color: "cyan" }, "immediately before"), " it was executed:")), prompts.length === 0 ? /* @__PURE__ */ React14.createElement(Box13, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React14.createElement(Text14, { italic: true, color: "gray" }, "No prompt checkpoints found for this session.")) : /* @__PURE__ */ React14.createElement(Box13, { flexDirection: "column", width: "100%" }, startIndex > 0 && /* @__PURE__ */ React14.createElement(Box13, { paddingX: 2, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, "\u25B2 (+", startIndex, " more prompts above)")), visiblePrompts.map((p, index) => {
17949
+ return /* @__PURE__ */ React14.createElement(Box13, { flexDirection: "column", borderStyle: "round", borderColor: colors.borderMuted, padding: 0, width: "100%" }, /* @__PURE__ */ React14.createElement(Box13, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: colors.text, bold: true }, "CODEBASE TIME TRAVEL: SELECT UNDO POINT")), /* @__PURE__ */ React14.createElement(Box13, { paddingX: 2, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: colors.text }, "Select a prompt to revert the codebase back to the state ", /* @__PURE__ */ React14.createElement(Text14, { bold: true, color: colors.secondary || "cyan" }, "immediately before"), " it was executed:")), prompts.length === 0 ? /* @__PURE__ */ React14.createElement(Box13, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React14.createElement(Text14, { italic: true, color: colors.textMuted }, "No prompt checkpoints found for this session.")) : /* @__PURE__ */ React14.createElement(Box13, { flexDirection: "column", width: "100%" }, startIndex > 0 && /* @__PURE__ */ React14.createElement(Box13, { paddingX: 2, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: colors.textMuted }, "\u25B2 (+", startIndex, " more prompts above)")), visiblePrompts.map((p, index) => {
17641
17950
  const actualIndex = startIndex + index;
17642
17951
  const isSelected = actualIndex === selectedIndex;
17643
17952
  const dateStr = formatDate2(p.timestamp);
@@ -17647,12 +17956,12 @@ function RevertModal({ prompts, onSelect, onClose }) {
17647
17956
  {
17648
17957
  key: p.id,
17649
17958
  paddingX: 1,
17650
- backgroundColor: isSelected ? "#444444" : void 0,
17959
+ backgroundColor: isSelected ? colors.highlightBg : void 0,
17651
17960
  width: "100%"
17652
17961
  },
17653
- /* @__PURE__ */ React14.createElement(Box13, { flexGrow: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: isSelected ? "white" : "grey", bold: isSelected }, isSelected ? "\u276F " : " ", '"', formatPromptPreview(p.prompt), '"', /* @__PURE__ */ React14.createElement(Text14, { color: `${isSelected ? "white" : "grey"}`, dimColor: true }, " [", dateStr, " \u2022 ", fileCount, " file(s) changed]")))
17962
+ /* @__PURE__ */ React14.createElement(Box13, { flexGrow: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: isSelected ? colors.text : colors.textMuted, bold: isSelected }, isSelected ? "\u276F " : " ", '"', formatPromptPreview(p.prompt), '"', /* @__PURE__ */ React14.createElement(Text14, { color: colors.textMuted }, " [", dateStr, " \u2022 ", fileCount, " file(s) changed]")))
17654
17963
  );
17655
- }), startIndex + MAX_VISIBLE < prompts.length && /* @__PURE__ */ React14.createElement(Box13, { paddingX: 2, marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, "\u25BC (+", prompts.length - (startIndex + MAX_VISIBLE), " more prompts below)"))), /* @__PURE__ */ React14.createElement(
17964
+ }), startIndex + MAX_VISIBLE < prompts.length && /* @__PURE__ */ React14.createElement(Box13, { paddingX: 2, marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: colors.textMuted }, "\u25BC (+", prompts.length - (startIndex + MAX_VISIBLE), " more prompts below)"))), /* @__PURE__ */ React14.createElement(
17656
17965
  Box13,
17657
17966
  {
17658
17967
  marginTop: 1,
@@ -17661,9 +17970,9 @@ function RevertModal({ prompts, onSelect, onClose }) {
17661
17970
  borderLeft: false,
17662
17971
  borderRight: false,
17663
17972
  borderBottom: false,
17664
- borderColor: "grey"
17973
+ borderColor: colors.borderMuted
17665
17974
  },
17666
- /* @__PURE__ */ React14.createElement(Text14, { color: "grey", italic: true }, "\u2191\u2193 navigate \u2022 Enter select undo point \u2022 Esc close")
17975
+ /* @__PURE__ */ React14.createElement(Text14, { color: colors.textMuted, italic: true }, "\u2191\u2193 navigate \u2022 Enter select undo point \u2022 Esc close")
17667
17976
  ));
17668
17977
  }
17669
17978
  function formatPromptPreview(prompt) {
@@ -17694,6 +18003,7 @@ function formatDate2(timestamp) {
17694
18003
  var init_RevertModal = __esm({
17695
18004
  "src/components/RevertModal.jsx"() {
17696
18005
  init_terminal();
18006
+ init_theme();
17697
18007
  }
17698
18008
  });
17699
18009
 
@@ -18180,6 +18490,7 @@ function App({ args = [] }) {
18180
18490
  const [quotas, setQuotas] = useState15({ limitMode: "Daily", agentLimit: 99999999, tokenLimit: 99999999999999, backgroundLimit: 999999, searchLimit: 100, customModelId: "", customLimit: 0, providerBudgets: {} });
18181
18491
  const [inputConfig, setInputConfig] = useState15(null);
18182
18492
  const [budgetReturnView, setBudgetReturnView] = useState15("chat");
18493
+ const [providerReturnView, setProviderReturnView] = useState15("settings");
18183
18494
  const [providerBudgetQueue, setProviderBudgetQueue] = useState15([]);
18184
18495
  const [providerBudgetCursor, setProviderBudgetCursor] = useState15(0);
18185
18496
  const [pbsCursor, setPbsCursor] = useState15(0);
@@ -19255,6 +19566,10 @@ function App({ args = [] }) {
19255
19566
  desc: "Select Agent Model",
19256
19567
  subs: getModels(aiProvider, apiTier)
19257
19568
  },
19569
+ {
19570
+ cmd: "/provider",
19571
+ desc: "Select AI Provider"
19572
+ },
19258
19573
  {
19259
19574
  cmd: "/mode",
19260
19575
  desc: "Toggle Flux/Flow modes",
@@ -19264,6 +19579,7 @@ function App({ args = [] }) {
19264
19579
  ]
19265
19580
  },
19266
19581
  { cmd: "/settings", desc: "Configure system prefs" },
19582
+ { cmd: "/theme", desc: "Customize UI color theme" },
19267
19583
  { cmd: "/key", desc: "Manage API keys" },
19268
19584
  { cmd: "/profile", desc: "Edit developer persona" },
19269
19585
  { cmd: "/memory", desc: "Manage agent memory" },
@@ -19771,6 +20087,16 @@ ${cleanText}`, color: "magenta" }];
19771
20087
  setActiveView("settings");
19772
20088
  break;
19773
20089
  }
20090
+ case "/provider":
20091
+ case "/providers": {
20092
+ setProviderReturnView("chat");
20093
+ setActiveView("selectProvider");
20094
+ break;
20095
+ }
20096
+ case "/theme": {
20097
+ setActiveView("theme");
20098
+ break;
20099
+ }
19774
20100
  case "/key": {
19775
20101
  setActiveView("key");
19776
20102
  break;
@@ -21105,7 +21431,26 @@ Selection: ${val}`,
21105
21431
  saveSettings,
21106
21432
  quotas,
21107
21433
  setMessages,
21108
- aiProvider
21434
+ aiProvider,
21435
+ setProviderReturnView
21436
+ }
21437
+ );
21438
+ case "theme":
21439
+ return /* @__PURE__ */ React16.createElement(
21440
+ SettingsMenu,
21441
+ {
21442
+ systemSettings,
21443
+ setSystemSettings,
21444
+ apiTier,
21445
+ setActiveView,
21446
+ setInputConfig,
21447
+ saveSettings,
21448
+ quotas,
21449
+ setMessages,
21450
+ aiProvider,
21451
+ initialSelectingTheme: true,
21452
+ onCloseTheme: () => setActiveView("chat"),
21453
+ setProviderReturnView
21109
21454
  }
21110
21455
  );
21111
21456
  case "selectProvider":
@@ -21119,12 +21464,12 @@ Selection: ${val}`,
21119
21464
  { label: "DeepSeek (Paid)", value: "DeepSeek" },
21120
21465
  { label: "Mistral (Free/Paid) [EXPERIMENTAL]", value: "Mistral" },
21121
21466
  { label: "OpenRouter (Free/Paid) [EXPERIMENTAL]", value: "OpenRouter" },
21122
- { label: "Back", value: "settings" }
21467
+ { label: "Back", value: providerReturnView }
21123
21468
  ],
21124
21469
  theme: systemSettings.theme,
21125
21470
  onSelect: async (item) => {
21126
- if (item.value === "settings" || item.value === "Back") {
21127
- setActiveView("settings");
21471
+ if (item.value === providerReturnView || item.value === "settings" || item.value === "Back") {
21472
+ setActiveView(providerReturnView);
21128
21473
  return;
21129
21474
  }
21130
21475
  const selectedProvider = item.value;
@@ -21151,19 +21496,19 @@ Selection: ${val}`,
21151
21496
  isMeta: true
21152
21497
  }
21153
21498
  ]);
21154
- setActiveView("settings");
21499
+ setActiveView(providerReturnView);
21155
21500
  } else {
21156
21501
  setInputConfig({
21157
21502
  label: `Enter ${selectedProvider} API Key:`,
21158
21503
  key: "providerKey",
21159
21504
  provider: selectedProvider,
21160
21505
  value: "",
21161
- returnView: "settings"
21506
+ returnView: providerReturnView
21162
21507
  });
21163
21508
  setActiveView("input");
21164
21509
  }
21165
21510
  },
21166
- onClose: () => setActiveView("settings")
21511
+ onClose: () => setActiveView(providerReturnView)
21167
21512
  }
21168
21513
  );
21169
21514
  case "apiTier": {
@@ -21522,7 +21867,7 @@ Selection: ${val}`,
21522
21867
  }
21523
21868
  )));
21524
21869
  case "advanceRollbackDanger":
21525
- return /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "grey", paddingX: 2, paddingY: 1, paddingTop: 0, width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { color: "white", bold: true }, "\u26A0 Emergency Rollback Notice"), /* @__PURE__ */ React16.createElement(Text16, { marginTop: 1 }, "When enabled, full repo snapshots exist only during active AI turns."), /* @__PURE__ */ React16.createElement(Text16, { marginTop: 1 }, "If catastrophic changes occur during a turn, avoid abruptly stopping the agent unless absolutely necessary (external damages out of codebase)."), /* @__PURE__ */ React16.createElement(Text16, null, "The agent may be able to automatically restore the repo to a safe state."), /* @__PURE__ */ React16.createElement(Text16, { marginTop: 1 }, "Once the turn ends, emergency snapshots are deleted and standard /revert takes over which may not retain full repo content."), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(
21870
+ return /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "grey", paddingX: 2, paddingY: 1, paddingTop: 0, width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { color: "white", bold: true }, "\u26A0 Emergency Rollback Notice"), /* @__PURE__ */ React16.createElement(Text16, { marginTop: 1 }, "When enabled, full repo snapshots exist only during active AI turns."), /* @__PURE__ */ React16.createElement(Text16, { marginTop: 1 }, "If catastrophic changes occur during a turn, avoid abruptly stopping the agent unless absolutely necessary (external damages out of codebase)."), /* @__PURE__ */ React16.createElement(Text16, null, "The agent may be able to automatically restore the repo to a safe state."), /* @__PURE__ */ React16.createElement(Text16, { marginTop: 1 }, "Once the turn ends, emergency snapshots are deleted and standard /revert takes over which may not retain full repo content."), /* @__PURE__ */ React16.createElement(Text16, { marginTop: 1 }, "(Requires Restart to take effect)"), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(
21526
21871
  CommandMenu,
21527
21872
  {
21528
21873
  title: "Confirm",
@@ -21708,7 +22053,8 @@ Selection: ${val}`,
21708
22053
  setActiveView("chat");
21709
22054
  }
21710
22055
  },
21711
- onClose: () => setActiveView("chat")
22056
+ onClose: () => setActiveView("chat"),
22057
+ theme: systemSettings.theme
21712
22058
  }
21713
22059
  ));
21714
22060
  case "resume":
@@ -22674,12 +23020,12 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
22674
23020
  /btw <question> Send raw inquiry to the agent mid-turn
22675
23021
  /image setup key <default|custom> Configure image API key strategy
22676
23022
  /budget Set or View budget limits
22677
- /image setup quality <low...premium> Configure default image generation quality
22678
- /image stats Show image quota stats
22679
23023
  /mode <flux|flow> Toggle Flux/Flow modes
22680
23024
  /thinking <Fast|Low|Medium|High|xHigh> Set AI reasoning depth
22681
23025
  /model <model_name> Switch Model for Agent
23026
+ /provider Select AI Provider
22682
23027
  /settings Configure system preferences
23028
+ /theme Customize UI color theme
22683
23029
  /key Manage API keys
22684
23030
  /profile Edit developer persona
22685
23031
  /memory Manage agent memory
package/model_config.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 0,
3
- "release": 20260728,
3
+ "release": 20260729,
4
4
  "fallbacks": {
5
5
  "janitor_default": "gemini-3.1-flash-lite",
6
6
  "janitor_attempts_fallback": "gemma-4-26b-a4b-it",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "3.12.2",
4
- "date": "2026-07-28",
3
+ "version": "3.13.0",
4
+ "date": "2026-07-29",
5
5
  "description": "A High-Fidelity Agentic CLI with Sub-Agents for the Flux Era.",
6
6
  "keywords": [
7
7
  "ai",