kimiflare 0.51.0 → 0.52.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/index.js CHANGED
@@ -915,6 +915,21 @@ function toOpenAIToolDefs(tools) {
915
915
  }
916
916
  }));
917
917
  }
918
+ function isValidStatus(s) {
919
+ return s === "pending" || s === "in_progress" || s === "completed";
920
+ }
921
+ function validateTasks(input) {
922
+ if (!Array.isArray(input)) throw new Error("tasks must be an array");
923
+ return input.map((t, i) => {
924
+ if (!t || typeof t !== "object") throw new Error(`tasks[${i}] must be an object`);
925
+ const rec = t;
926
+ const id = typeof rec.id === "string" && rec.id.length > 0 ? rec.id : String(i + 1);
927
+ const title = typeof rec.title === "string" ? rec.title.trim() : "";
928
+ if (!title) throw new Error(`tasks[${i}].title is required`);
929
+ const status = isValidStatus(rec.status) ? rec.status : "pending";
930
+ return { id, title, status };
931
+ });
932
+ }
918
933
  var init_registry = __esm({
919
934
  "src/tools/registry.ts"() {
920
935
  "use strict";
@@ -1556,8 +1571,8 @@ var require_node_gyp_build = __commonJS({
1556
1571
  var abi = process.versions.modules;
1557
1572
  var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
1558
1573
  var arch = process.env.npm_config_arch || os2.arch();
1559
- var platform3 = process.env.npm_config_platform || os2.platform();
1560
- var libc = process.env.LIBC || (isAlpine(platform3) ? "musl" : "glibc");
1574
+ var platform4 = process.env.npm_config_platform || os2.platform();
1575
+ var libc = process.env.LIBC || (isAlpine(platform4) ? "musl" : "glibc");
1561
1576
  var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
1562
1577
  var uv = (process.versions.uv || "").split(".")[0];
1563
1578
  module.exports = load;
@@ -1582,7 +1597,7 @@ var require_node_gyp_build = __commonJS({
1582
1597
  var nearby = resolve3(path.dirname(process.execPath));
1583
1598
  if (nearby) return nearby;
1584
1599
  var target = [
1585
- "platform=" + platform3,
1600
+ "platform=" + platform4,
1586
1601
  "arch=" + arch,
1587
1602
  "runtime=" + runtime,
1588
1603
  "abi=" + abi,
@@ -1597,7 +1612,7 @@ var require_node_gyp_build = __commonJS({
1597
1612
  throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
1598
1613
  function resolve3(dir2) {
1599
1614
  var tuples = readdirSync(path.join(dir2, "prebuilds")).map(parseTuple);
1600
- var tuple = tuples.filter(matchTuple(platform3, arch)).sort(compareTuples)[0];
1615
+ var tuple = tuples.filter(matchTuple(platform4, arch)).sort(compareTuples)[0];
1601
1616
  if (!tuple) return;
1602
1617
  var prebuilds = path.join(dir2, "prebuilds", tuple.name);
1603
1618
  var parsed = readdirSync(prebuilds).map(parseTags);
@@ -1623,17 +1638,17 @@ var require_node_gyp_build = __commonJS({
1623
1638
  function parseTuple(name) {
1624
1639
  var arr = name.split("-");
1625
1640
  if (arr.length !== 2) return;
1626
- var platform4 = arr[0];
1641
+ var platform5 = arr[0];
1627
1642
  var architectures = arr[1].split("+");
1628
- if (!platform4) return;
1643
+ if (!platform5) return;
1629
1644
  if (!architectures.length) return;
1630
1645
  if (!architectures.every(Boolean)) return;
1631
- return { name, platform: platform4, architectures };
1646
+ return { name, platform: platform5, architectures };
1632
1647
  }
1633
- function matchTuple(platform4, arch2) {
1648
+ function matchTuple(platform5, arch2) {
1634
1649
  return function(tuple) {
1635
1650
  if (tuple == null) return false;
1636
- if (tuple.platform !== platform4) return false;
1651
+ if (tuple.platform !== platform5) return false;
1637
1652
  return tuple.architectures.includes(arch2);
1638
1653
  };
1639
1654
  }
@@ -1701,8 +1716,8 @@ var require_node_gyp_build = __commonJS({
1701
1716
  if (process.env.ELECTRON_RUN_AS_NODE) return true;
1702
1717
  return typeof window !== "undefined" && window.process && window.process.type === "renderer";
1703
1718
  }
1704
- function isAlpine(platform4) {
1705
- return platform4 === "linux" && fs.existsSync("/etc/alpine-release");
1719
+ function isAlpine(platform5) {
1720
+ return platform5 === "linux" && fs.existsSync("/etc/alpine-release");
1706
1721
  }
1707
1722
  load.parseTags = parseTags;
1708
1723
  load.matchTags = matchTags;
@@ -2114,7 +2129,7 @@ var init_session_state = __esm({
2114
2129
  }
2115
2130
  });
2116
2131
 
2117
- // src/agent/compaction.ts
2132
+ // src/agent/artifact-compaction.ts
2118
2133
  function approxTokens2(n) {
2119
2134
  return Math.round(n / 4);
2120
2135
  }
@@ -2313,7 +2328,7 @@ function shouldCompact(opts2) {
2313
2328
  const { turns } = groupIntoTurns(opts2.messages);
2314
2329
  return tokens > tokenThreshold || turns.length > turnThreshold;
2315
2330
  }
2316
- function compactMessages(opts2) {
2331
+ function compactMessagesViaArtifacts(opts2) {
2317
2332
  const keepLastTurns = opts2.keepLastTurns ?? 4;
2318
2333
  const { prefix, turns } = groupIntoTurns(opts2.messages);
2319
2334
  const tokensBefore = estimatePromptTokens(opts2.messages);
@@ -2397,8 +2412,8 @@ function recallArtifacts(messages, store, state) {
2397
2412
  const recalled = store.recall(uniqueIds);
2398
2413
  return { ids: uniqueIds, recalled };
2399
2414
  }
2400
- var init_compaction = __esm({
2401
- "src/agent/compaction.ts"() {
2415
+ var init_artifact_compaction = __esm({
2416
+ "src/agent/artifact-compaction.ts"() {
2402
2417
  "use strict";
2403
2418
  init_session_state();
2404
2419
  }
@@ -2922,7 +2937,7 @@ var init_loop = __esm({
2922
2937
  init_extractors();
2923
2938
  init_strip_reasoning();
2924
2939
  init_code_mode();
2925
- init_compaction();
2940
+ init_artifact_compaction();
2926
2941
  init_logger();
2927
2942
  BudgetExhaustedError = class extends Error {
2928
2943
  constructor(message2 = "Cumulative input token budget exhausted") {
@@ -4182,34 +4197,12 @@ var init_browser = __esm({
4182
4197
  }
4183
4198
  });
4184
4199
 
4185
- // src/tasks-state.ts
4186
- function isValidStatus(s) {
4187
- return s === "pending" || s === "in_progress" || s === "completed";
4188
- }
4189
- function validateTasks(input) {
4190
- if (!Array.isArray(input)) throw new Error("tasks must be an array");
4191
- return input.map((t, i) => {
4192
- if (!t || typeof t !== "object") throw new Error(`tasks[${i}] must be an object`);
4193
- const rec = t;
4194
- const id = typeof rec.id === "string" && rec.id.length > 0 ? rec.id : String(i + 1);
4195
- const title = typeof rec.title === "string" ? rec.title.trim() : "";
4196
- if (!title) throw new Error(`tasks[${i}].title is required`);
4197
- const status = isValidStatus(rec.status) ? rec.status : "pending";
4198
- return { id, title, status };
4199
- });
4200
- }
4201
- var init_tasks_state = __esm({
4202
- "src/tasks-state.ts"() {
4203
- "use strict";
4204
- }
4205
- });
4206
-
4207
4200
  // src/tools/tasks.ts
4208
4201
  var tasksSetTool;
4209
4202
  var init_tasks = __esm({
4210
4203
  "src/tools/tasks.ts"() {
4211
4204
  "use strict";
4212
- init_tasks_state();
4205
+ init_registry();
4213
4206
  tasksSetTool = {
4214
4207
  name: "tasks_set",
4215
4208
  description: [
@@ -9486,7 +9479,7 @@ var init_supervisor = __esm({
9486
9479
  }
9487
9480
  });
9488
9481
 
9489
- // src/agent/compact.ts
9482
+ // src/agent/llm-summarize.ts
9490
9483
  function indexOfNthUserFromEnd(messages, n) {
9491
9484
  let seen = 0;
9492
9485
  for (let i = messages.length - 1; i >= 0; i--) {
@@ -9497,7 +9490,7 @@ function indexOfNthUserFromEnd(messages, n) {
9497
9490
  }
9498
9491
  return -1;
9499
9492
  }
9500
- async function compactMessages2(opts2) {
9493
+ async function summarizeMessagesViaLlm(opts2) {
9501
9494
  const keep = opts2.keepLastTurns ?? 4;
9502
9495
  const messages = opts2.messages;
9503
9496
  let prefixEnd = 0;
@@ -9559,8 +9552,8 @@ ${summary.trim()}`
9559
9552
  };
9560
9553
  }
9561
9554
  var SUMMARY_SYSTEM;
9562
- var init_compact = __esm({
9563
- "src/agent/compact.ts"() {
9555
+ var init_llm_summarize = __esm({
9556
+ "src/agent/llm-summarize.ts"() {
9564
9557
  "use strict";
9565
9558
  init_client();
9566
9559
  SUMMARY_SYSTEM = `You are summarizing a terminal coding session so it can fit back into a short context window. Produce a dense summary that captures:
@@ -10801,1214 +10794,1354 @@ var init_status = __esm({
10801
10794
  }
10802
10795
  });
10803
10796
 
10804
- // src/ui/permission.tsx
10805
- import { Box as Box7, Text as Text7 } from "ink";
10806
- import SelectInput from "ink-select-input";
10807
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
10808
- function PermissionModal({ tool, args, onDecide }) {
10809
- const theme = useTheme();
10810
- let render2;
10811
- try {
10812
- render2 = tool.render?.(args);
10813
- } catch {
10797
+ // node_modules/chalk/source/vendor/ansi-styles/index.js
10798
+ function assembleStyles() {
10799
+ const codes = /* @__PURE__ */ new Map();
10800
+ for (const [groupName, group] of Object.entries(styles)) {
10801
+ for (const [styleName, style] of Object.entries(group)) {
10802
+ styles[styleName] = {
10803
+ open: `\x1B[${style[0]}m`,
10804
+ close: `\x1B[${style[1]}m`
10805
+ };
10806
+ group[styleName] = styles[styleName];
10807
+ codes.set(style[0], style[1]);
10808
+ }
10809
+ Object.defineProperty(styles, groupName, {
10810
+ value: group,
10811
+ enumerable: false
10812
+ });
10814
10813
  }
10815
- const items = [
10816
- { label: "Allow once", value: "allow" },
10817
- { label: "Allow for this session", value: "allow_session" },
10818
- { label: "Deny", value: "deny" }
10819
- ];
10820
- return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: theme.permission, paddingX: 1, children: [
10821
- /* @__PURE__ */ jsx8(Text7, { color: theme.permission, bold: true, children: "Permission requested" }),
10822
- /* @__PURE__ */ jsxs7(Text7, { children: [
10823
- "tool: ",
10824
- /* @__PURE__ */ jsx8(Text7, { color: theme.tool, children: tool.name })
10825
- ] }),
10826
- render2?.title ? /* @__PURE__ */ jsxs7(Text7, { children: [
10827
- "action: ",
10828
- render2.title
10829
- ] }) : null,
10830
- render2?.diff ? /* @__PURE__ */ jsx8(Box7, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx8(DiffView, { ...render2.diff }) }) : /* @__PURE__ */ jsxs7(Text7, { color: theme.info.color, children: [
10831
- "args: ",
10832
- JSON.stringify(args)
10833
- ] }),
10834
- /* @__PURE__ */ jsx8(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx8(SelectInput, { items, onSelect: (item) => onDecide(item.value) }) })
10835
- ] });
10814
+ Object.defineProperty(styles, "codes", {
10815
+ value: codes,
10816
+ enumerable: false
10817
+ });
10818
+ styles.color.close = "\x1B[39m";
10819
+ styles.bgColor.close = "\x1B[49m";
10820
+ styles.color.ansi = wrapAnsi16();
10821
+ styles.color.ansi256 = wrapAnsi256();
10822
+ styles.color.ansi16m = wrapAnsi16m();
10823
+ styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
10824
+ styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
10825
+ styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
10826
+ Object.defineProperties(styles, {
10827
+ rgbToAnsi256: {
10828
+ value(red, green, blue) {
10829
+ if (red === green && green === blue) {
10830
+ if (red < 8) {
10831
+ return 16;
10832
+ }
10833
+ if (red > 248) {
10834
+ return 231;
10835
+ }
10836
+ return Math.round((red - 8) / 247 * 24) + 232;
10837
+ }
10838
+ return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
10839
+ },
10840
+ enumerable: false
10841
+ },
10842
+ hexToRgb: {
10843
+ value(hex) {
10844
+ const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
10845
+ if (!matches) {
10846
+ return [0, 0, 0];
10847
+ }
10848
+ let [colorString] = matches;
10849
+ if (colorString.length === 3) {
10850
+ colorString = [...colorString].map((character) => character + character).join("");
10851
+ }
10852
+ const integer = Number.parseInt(colorString, 16);
10853
+ return [
10854
+ /* eslint-disable no-bitwise */
10855
+ integer >> 16 & 255,
10856
+ integer >> 8 & 255,
10857
+ integer & 255
10858
+ /* eslint-enable no-bitwise */
10859
+ ];
10860
+ },
10861
+ enumerable: false
10862
+ },
10863
+ hexToAnsi256: {
10864
+ value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
10865
+ enumerable: false
10866
+ },
10867
+ ansi256ToAnsi: {
10868
+ value(code) {
10869
+ if (code < 8) {
10870
+ return 30 + code;
10871
+ }
10872
+ if (code < 16) {
10873
+ return 90 + (code - 8);
10874
+ }
10875
+ let red;
10876
+ let green;
10877
+ let blue;
10878
+ if (code >= 232) {
10879
+ red = ((code - 232) * 10 + 8) / 255;
10880
+ green = red;
10881
+ blue = red;
10882
+ } else {
10883
+ code -= 16;
10884
+ const remainder = code % 36;
10885
+ red = Math.floor(code / 36) / 5;
10886
+ green = Math.floor(remainder / 6) / 5;
10887
+ blue = remainder % 6 / 5;
10888
+ }
10889
+ const value = Math.max(red, green, blue) * 2;
10890
+ if (value === 0) {
10891
+ return 30;
10892
+ }
10893
+ let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
10894
+ if (value === 2) {
10895
+ result += 60;
10896
+ }
10897
+ return result;
10898
+ },
10899
+ enumerable: false
10900
+ },
10901
+ rgbToAnsi: {
10902
+ value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
10903
+ enumerable: false
10904
+ },
10905
+ hexToAnsi: {
10906
+ value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
10907
+ enumerable: false
10908
+ }
10909
+ });
10910
+ return styles;
10836
10911
  }
10837
- var init_permission = __esm({
10838
- "src/ui/permission.tsx"() {
10912
+ var ANSI_BACKGROUND_OFFSET, wrapAnsi16, wrapAnsi256, wrapAnsi16m, styles, modifierNames, foregroundColorNames, backgroundColorNames, colorNames, ansiStyles, ansi_styles_default;
10913
+ var init_ansi_styles = __esm({
10914
+ "node_modules/chalk/source/vendor/ansi-styles/index.js"() {
10839
10915
  "use strict";
10840
- init_diff_view();
10841
- init_theme_context();
10916
+ ANSI_BACKGROUND_OFFSET = 10;
10917
+ wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
10918
+ wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
10919
+ wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
10920
+ styles = {
10921
+ modifier: {
10922
+ reset: [0, 0],
10923
+ // 21 isn't widely supported and 22 does the same thing
10924
+ bold: [1, 22],
10925
+ dim: [2, 22],
10926
+ italic: [3, 23],
10927
+ underline: [4, 24],
10928
+ overline: [53, 55],
10929
+ inverse: [7, 27],
10930
+ hidden: [8, 28],
10931
+ strikethrough: [9, 29]
10932
+ },
10933
+ color: {
10934
+ black: [30, 39],
10935
+ red: [31, 39],
10936
+ green: [32, 39],
10937
+ yellow: [33, 39],
10938
+ blue: [34, 39],
10939
+ magenta: [35, 39],
10940
+ cyan: [36, 39],
10941
+ white: [37, 39],
10942
+ // Bright color
10943
+ blackBright: [90, 39],
10944
+ gray: [90, 39],
10945
+ // Alias of `blackBright`
10946
+ grey: [90, 39],
10947
+ // Alias of `blackBright`
10948
+ redBright: [91, 39],
10949
+ greenBright: [92, 39],
10950
+ yellowBright: [93, 39],
10951
+ blueBright: [94, 39],
10952
+ magentaBright: [95, 39],
10953
+ cyanBright: [96, 39],
10954
+ whiteBright: [97, 39]
10955
+ },
10956
+ bgColor: {
10957
+ bgBlack: [40, 49],
10958
+ bgRed: [41, 49],
10959
+ bgGreen: [42, 49],
10960
+ bgYellow: [43, 49],
10961
+ bgBlue: [44, 49],
10962
+ bgMagenta: [45, 49],
10963
+ bgCyan: [46, 49],
10964
+ bgWhite: [47, 49],
10965
+ // Bright color
10966
+ bgBlackBright: [100, 49],
10967
+ bgGray: [100, 49],
10968
+ // Alias of `bgBlackBright`
10969
+ bgGrey: [100, 49],
10970
+ // Alias of `bgBlackBright`
10971
+ bgRedBright: [101, 49],
10972
+ bgGreenBright: [102, 49],
10973
+ bgYellowBright: [103, 49],
10974
+ bgBlueBright: [104, 49],
10975
+ bgMagentaBright: [105, 49],
10976
+ bgCyanBright: [106, 49],
10977
+ bgWhiteBright: [107, 49]
10978
+ }
10979
+ };
10980
+ modifierNames = Object.keys(styles.modifier);
10981
+ foregroundColorNames = Object.keys(styles.color);
10982
+ backgroundColorNames = Object.keys(styles.bgColor);
10983
+ colorNames = [...foregroundColorNames, ...backgroundColorNames];
10984
+ ansiStyles = assembleStyles();
10985
+ ansi_styles_default = ansiStyles;
10842
10986
  }
10843
10987
  });
10844
10988
 
10845
- // src/ui/limit-modal.tsx
10846
- import { Box as Box8, Text as Text8 } from "ink";
10847
- import SelectInput2 from "ink-select-input";
10848
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
10849
- function LimitModal({ limit, onDecide }) {
10850
- const theme = useTheme();
10851
- const items = [
10852
- { label: "Continue", value: "continue" },
10853
- { label: "Stop", value: "stop" }
10854
- ];
10855
- return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: theme.error, paddingX: 1, children: [
10856
- /* @__PURE__ */ jsxs8(Text8, { color: theme.error, bold: true, children: [
10857
- "Tool-call limit reached (",
10858
- limit,
10859
- ")"
10860
- ] }),
10861
- /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
10862
- "This session has made ",
10863
- limit,
10864
- " tool calls. What would you like to do?"
10865
- ] }),
10866
- /* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx9(
10867
- SelectInput2,
10868
- {
10869
- items,
10870
- onSelect: (item) => onDecide(item.value)
10871
- }
10872
- ) })
10873
- ] });
10989
+ // node_modules/chalk/source/vendor/supports-color/index.js
10990
+ import process2 from "process";
10991
+ import os from "os";
10992
+ import tty from "tty";
10993
+ function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
10994
+ const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
10995
+ const position = argv.indexOf(prefix + flag);
10996
+ const terminatorPosition = argv.indexOf("--");
10997
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
10874
10998
  }
10875
- var init_limit_modal = __esm({
10876
- "src/ui/limit-modal.tsx"() {
10877
- "use strict";
10878
- init_theme_context();
10879
- }
10880
- });
10881
-
10882
- // src/util/fuzzy.ts
10883
- function fuzzyMatch(query, text) {
10884
- const queryLower = query.toLowerCase();
10885
- const textLower = text.toLowerCase();
10886
- const matchQuery = (normalizedQuery) => {
10887
- if (normalizedQuery.length === 0) return { matches: true, score: 0 };
10888
- if (normalizedQuery.length > textLower.length) return { matches: false, score: 0 };
10889
- let queryIndex = 0;
10890
- let score = 0;
10891
- let lastMatchIndex = -1;
10892
- let consecutiveMatches = 0;
10893
- for (let i = 0; i < textLower.length && queryIndex < normalizedQuery.length; i++) {
10894
- if (textLower[i] !== normalizedQuery[queryIndex]) continue;
10895
- const isWordBoundary = i === 0 || /[\s\-_./:]/.test(textLower[i - 1]);
10896
- if (lastMatchIndex === i - 1) {
10897
- consecutiveMatches++;
10898
- score -= consecutiveMatches * 5;
10899
- } else {
10900
- consecutiveMatches = 0;
10901
- if (lastMatchIndex >= 0) score += (i - lastMatchIndex - 1) * 2;
10902
- }
10903
- if (isWordBoundary) score -= 10;
10904
- score += i * 0.1;
10905
- lastMatchIndex = i;
10906
- queryIndex++;
10999
+ function envForceColor() {
11000
+ if ("FORCE_COLOR" in env) {
11001
+ if (env.FORCE_COLOR === "true") {
11002
+ return 1;
10907
11003
  }
10908
- if (queryIndex < normalizedQuery.length) return { matches: false, score: 0 };
10909
- if (normalizedQuery === textLower) score -= 100;
10910
- return { matches: true, score };
10911
- };
10912
- const primaryMatch = matchQuery(queryLower);
10913
- if (primaryMatch.matches) return primaryMatch;
10914
- const alphaNumericMatch = queryLower.match(/^(?<letters>[a-z]+)(?<digits>[0-9]+)$/);
10915
- const numericAlphaMatch = queryLower.match(/^(?<digits>[0-9]+)(?<letters>[a-z]+)$/);
10916
- const swappedQuery = alphaNumericMatch ? `${alphaNumericMatch.groups?.digits ?? ""}${alphaNumericMatch.groups?.letters ?? ""}` : numericAlphaMatch ? `${numericAlphaMatch.groups?.letters ?? ""}${numericAlphaMatch.groups?.digits ?? ""}` : "";
10917
- if (!swappedQuery) return primaryMatch;
10918
- const swappedMatch = matchQuery(swappedQuery);
10919
- if (!swappedMatch.matches) return primaryMatch;
10920
- return { matches: true, score: swappedMatch.score + 5 };
10921
- }
10922
- function fuzzyFilter(items, query, getText) {
10923
- const trimmed = query.trim();
10924
- if (trimmed.length === 0) return items;
10925
- const tokens = trimmed.split(/\s+/).filter((t) => t.length > 0);
10926
- if (tokens.length === 0) return items;
10927
- const scored = [];
10928
- for (const item of items) {
10929
- const text = getText(item);
10930
- let total = 0;
10931
- let allMatch = true;
10932
- for (const token of tokens) {
10933
- const m = fuzzyMatch(token, text);
10934
- if (!m.matches) {
10935
- allMatch = false;
10936
- break;
10937
- }
10938
- total += m.score;
11004
+ if (env.FORCE_COLOR === "false") {
11005
+ return 0;
10939
11006
  }
10940
- if (allMatch) scored.push({ item, score: total });
11007
+ return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
10941
11008
  }
10942
- scored.sort((a, b) => a.score - b.score);
10943
- return scored.map((s) => s.item);
10944
11009
  }
10945
- var init_fuzzy = __esm({
10946
- "src/util/fuzzy.ts"() {
10947
- "use strict";
11010
+ function translateLevel(level) {
11011
+ if (level === 0) {
11012
+ return false;
10948
11013
  }
10949
- });
10950
-
10951
- // src/ui/resume-picker.tsx
10952
- import { useState as useState3 } from "react";
10953
- import { Box as Box9, Text as Text9, useInput } from "ink";
10954
- import SelectInput3 from "ink-select-input";
10955
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
10956
- function ResumePicker({ sessions, onPick }) {
10957
- const theme = useTheme();
10958
- const [page, setPage] = useState3(0);
10959
- const [selectedIndex, setSelectedIndex] = useState3(0);
10960
- const [query, setQuery] = useState3("");
10961
- const filtered = query.trim() ? fuzzyFilter(sessions, query, (s) => `${s.title ?? s.firstPrompt} ${s.id}`) : sessions;
10962
- const totalPages = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE));
10963
- const safePage = Math.min(page, totalPages - 1);
10964
- const start = safePage * PAGE_SIZE;
10965
- const end = Math.min(start + PAGE_SIZE, filtered.length);
10966
- const pageSessions = filtered.slice(start, end);
10967
- useInput((input, key) => {
10968
- if (key.leftArrow && safePage > 0) {
10969
- setPage((p) => p - 1);
10970
- setSelectedIndex(0);
10971
- return;
11014
+ return {
11015
+ level,
11016
+ hasBasic: true,
11017
+ has256: level >= 2,
11018
+ has16m: level >= 3
11019
+ };
11020
+ }
11021
+ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
11022
+ const noFlagForceColor = envForceColor();
11023
+ if (noFlagForceColor !== void 0) {
11024
+ flagForceColor = noFlagForceColor;
11025
+ }
11026
+ const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
11027
+ if (forceColor === 0) {
11028
+ return 0;
11029
+ }
11030
+ if (sniffFlags) {
11031
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
11032
+ return 3;
10972
11033
  }
10973
- if (key.rightArrow && safePage < totalPages - 1) {
10974
- setPage((p) => p + 1);
10975
- setSelectedIndex(0);
10976
- return;
11034
+ if (hasFlag("color=256")) {
11035
+ return 2;
10977
11036
  }
10978
- if (key.backspace || key.delete) {
10979
- setQuery((q) => q.slice(0, -1));
10980
- setPage(0);
10981
- setSelectedIndex(0);
10982
- return;
11037
+ }
11038
+ if ("TF_BUILD" in env && "AGENT_NAME" in env) {
11039
+ return 1;
11040
+ }
11041
+ if (haveStream && !streamIsTTY && forceColor === void 0) {
11042
+ return 0;
11043
+ }
11044
+ const min = forceColor || 0;
11045
+ if (env.TERM === "dumb") {
11046
+ return min;
11047
+ }
11048
+ if (process2.platform === "win32") {
11049
+ const osRelease = os.release().split(".");
11050
+ if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
11051
+ return Number(osRelease[2]) >= 14931 ? 3 : 2;
10983
11052
  }
10984
- if (input.length === 1 && !key.ctrl && !key.meta && !key.return && !key.escape) {
10985
- setQuery((q) => q + input);
10986
- setPage(0);
10987
- setSelectedIndex(0);
10988
- return;
11053
+ return 1;
11054
+ }
11055
+ if ("CI" in env) {
11056
+ if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => key in env)) {
11057
+ return 3;
10989
11058
  }
10990
- if (input === "q" || key.escape) {
10991
- onPick(null);
10992
- return;
11059
+ if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
11060
+ return 1;
10993
11061
  }
10994
- });
10995
- if (sessions.length === 0) {
10996
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
10997
- /* @__PURE__ */ jsx10(Text9, { color: theme.accent, bold: true, children: "Resume a session" }),
10998
- /* @__PURE__ */ jsx10(Text9, { color: theme.info.color, children: "No saved sessions yet. Press Enter to dismiss." }),
10999
- /* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(
11000
- SelectInput3,
11001
- {
11002
- items: [{ label: "(back)", value: "__cancel__" }],
11003
- onSelect: () => onPick(null)
11004
- }
11005
- ) })
11006
- ] });
11062
+ return min;
11007
11063
  }
11008
- const items = pageSessions.map((s) => ({
11009
- label: `${formatDate(s.updatedAt)} \xB7 ${s.messageCount} msgs \xB7 ${s.title ?? s.firstPrompt}`,
11010
- value: s.id
11011
- }));
11012
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
11013
- /* @__PURE__ */ jsx10(Text9, { color: theme.accent, bold: true, children: "Resume a session" }),
11014
- /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, children: [
11015
- query ? `Search: ${query}\u258C` : "Type to search\u2026",
11016
- " \xB7 Page ",
11017
- safePage + 1,
11018
- " of ",
11019
- totalPages,
11020
- " (",
11021
- filtered.length,
11022
- " total)"
11023
- ] }),
11024
- /* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(
11025
- SelectInput3,
11026
- {
11027
- items,
11028
- initialIndex: selectedIndex,
11029
- onHighlight: (item) => {
11030
- const idx = items.findIndex((i) => i.value === item.value);
11031
- if (idx >= 0) setSelectedIndex(idx);
11032
- },
11033
- onSelect: (item) => {
11034
- const picked = sessions.find((s) => s.id === item.value) ?? null;
11035
- onPick(picked);
11036
- }
11037
- }
11038
- ) }),
11039
- /* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, children: [
11040
- safePage > 0 ? "\u2190 prev " : "",
11041
- safePage < totalPages - 1 ? "\u2192 next " : "",
11042
- "q: cancel"
11043
- ] }) })
11044
- ] });
11045
- }
11046
- function formatDate(iso) {
11047
- try {
11048
- const d = new Date(iso);
11049
- return d.toLocaleString(void 0, {
11050
- month: "short",
11051
- day: "numeric",
11052
- hour: "2-digit",
11053
- minute: "2-digit"
11054
- });
11055
- } catch {
11056
- return iso;
11064
+ if ("TEAMCITY_VERSION" in env) {
11065
+ return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
11057
11066
  }
11058
- }
11059
- var PAGE_SIZE;
11060
- var init_resume_picker = __esm({
11061
- "src/ui/resume-picker.tsx"() {
11062
- "use strict";
11063
- init_fuzzy();
11064
- init_theme_context();
11065
- PAGE_SIZE = 5;
11067
+ if (env.COLORTERM === "truecolor") {
11068
+ return 3;
11066
11069
  }
11067
- });
11068
-
11069
- // src/ui/checkpoint-picker.tsx
11070
- import { useState as useState4 } from "react";
11071
- import { Box as Box10, Text as Text10, useInput as useInput2 } from "ink";
11072
- import SelectInput4 from "ink-select-input";
11073
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
11074
- function CheckpointPicker({ session, checkpoints, onPick }) {
11075
- const theme = useTheme();
11076
- const [selectedIndex, setSelectedIndex] = useState4(0);
11077
- useInput2((input, key) => {
11078
- if (input === "q" || key.escape) {
11079
- onPick(null);
11080
- return;
11081
- }
11082
- });
11083
- const items = [
11084
- {
11085
- label: `Resume from beginning (${session.messageCount} msgs)`,
11086
- value: "__start__"
11087
- },
11088
- ...checkpoints.map((cp) => ({
11089
- label: `Resume from: "${cp.label}" \u2014 turn ${cp.turnIndex} \xB7 ${formatDate2(cp.timestamp)}`,
11090
- value: cp.id
11091
- }))
11092
- ];
11093
- return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
11094
- /* @__PURE__ */ jsx11(Text10, { color: theme.accent, bold: true, children: session.firstPrompt.slice(0, 50) }),
11095
- /* @__PURE__ */ jsxs10(Text10, { color: theme.info.color, children: [
11096
- session.messageCount,
11097
- " turns \xB7 ",
11098
- checkpoints.length,
11099
- " checkpoint",
11100
- checkpoints.length === 1 ? "" : "s"
11101
- ] }),
11102
- /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx11(
11103
- SelectInput4,
11104
- {
11105
- items,
11106
- initialIndex: selectedIndex,
11107
- onHighlight: (item) => {
11108
- const idx = items.findIndex((i) => i.value === item.value);
11109
- if (idx >= 0) setSelectedIndex(idx);
11110
- },
11111
- onSelect: (item) => {
11112
- if (item.value === "__start__") {
11113
- onPick("__start__");
11114
- } else {
11115
- onPick(item.value);
11116
- }
11117
- }
11070
+ if (env.TERM === "xterm-kitty") {
11071
+ return 3;
11072
+ }
11073
+ if (env.TERM === "xterm-ghostty") {
11074
+ return 3;
11075
+ }
11076
+ if (env.TERM === "wezterm") {
11077
+ return 3;
11078
+ }
11079
+ if ("TERM_PROGRAM" in env) {
11080
+ const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
11081
+ switch (env.TERM_PROGRAM) {
11082
+ case "iTerm.app": {
11083
+ return version >= 3 ? 3 : 2;
11118
11084
  }
11119
- ) }),
11120
- /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text10, { color: theme.info.color, children: "q: cancel / go back" }) })
11121
- ] });
11122
- }
11123
- function formatDate2(iso) {
11124
- try {
11125
- const d = new Date(iso);
11126
- return d.toLocaleString(void 0, {
11127
- month: "short",
11128
- day: "numeric",
11129
- hour: "2-digit",
11130
- minute: "2-digit"
11131
- });
11132
- } catch {
11133
- return iso;
11085
+ case "Apple_Terminal": {
11086
+ return 2;
11087
+ }
11088
+ }
11089
+ }
11090
+ if (/-256(color)?$/i.test(env.TERM)) {
11091
+ return 2;
11092
+ }
11093
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
11094
+ return 1;
11134
11095
  }
11096
+ if ("COLORTERM" in env) {
11097
+ return 1;
11098
+ }
11099
+ return min;
11135
11100
  }
11136
- var init_checkpoint_picker = __esm({
11137
- "src/ui/checkpoint-picker.tsx"() {
11101
+ function createSupportsColor(stream, options = {}) {
11102
+ const level = _supportsColor(stream, {
11103
+ streamIsTTY: stream && stream.isTTY,
11104
+ ...options
11105
+ });
11106
+ return translateLevel(level);
11107
+ }
11108
+ var env, flagForceColor, supportsColor, supports_color_default;
11109
+ var init_supports_color = __esm({
11110
+ "node_modules/chalk/source/vendor/supports-color/index.js"() {
11138
11111
  "use strict";
11139
- init_theme_context();
11112
+ ({ env } = process2);
11113
+ if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
11114
+ flagForceColor = 0;
11115
+ } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
11116
+ flagForceColor = 1;
11117
+ }
11118
+ supportsColor = {
11119
+ stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
11120
+ stderr: createSupportsColor({ isTTY: tty.isatty(2) })
11121
+ };
11122
+ supports_color_default = supportsColor;
11140
11123
  }
11141
11124
  });
11142
11125
 
11143
- // src/ui/task-list.tsx
11144
- import { useEffect as useEffect3, useRef, useState as useState5 } from "react";
11145
- import { Box as Box11, Text as Text11 } from "ink";
11146
- import Spinner4 from "ink-spinner";
11147
- import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
11148
- function TaskList({ tasks, startedAt, tokensDelta }) {
11149
- const theme = useTheme();
11150
- const [now2, setNow] = useState5(Date.now());
11151
- const [celebrating, setCelebrating] = useState5(false);
11152
- const tasksRef = useRef(tasks);
11153
- const prevAllDoneRef = useRef(false);
11154
- tasksRef.current = tasks;
11155
- useEffect3(() => {
11156
- if (startedAt === null) return;
11157
- const id = setInterval(() => {
11158
- setNow(Date.now());
11159
- const current = tasksRef.current;
11160
- if (current.length > 0 && current.every((t) => t.status === "completed")) {
11161
- clearInterval(id);
11162
- }
11163
- }, 1e3);
11164
- return () => clearInterval(id);
11165
- }, [startedAt]);
11166
- useEffect3(() => {
11167
- const allDone2 = tasks.length > 0 && tasks.every((t) => t.status === "completed");
11168
- if (allDone2 && !prevAllDoneRef.current) {
11169
- setCelebrating(true);
11170
- const id = setTimeout(() => setCelebrating(false), 1500);
11171
- return () => clearTimeout(id);
11172
- }
11173
- prevAllDoneRef.current = allDone2;
11174
- }, [tasks]);
11175
- if (tasks.length === 0) return null;
11176
- const active = tasks.find((t) => t.status === "in_progress");
11177
- const done = tasks.filter((t) => t.status === "completed").length;
11178
- const total = tasks.length;
11179
- const allDone = done === total;
11180
- const header = active ? active.title : allDone ? `${total} tasks done` : `${done}/${total}`;
11181
- const elapsed = startedAt ? formatElapsed3(now2 - startedAt) : null;
11182
- const headerStats = [elapsed, tokensDelta > 0 ? `\u2191 ${formatTokens3(tokensDelta)} tokens` : null].filter(Boolean).join(" \xB7 ");
11183
- const visibleTasks = tasks.slice(0, MAX_VISIBLE);
11184
- const hiddenPending = Math.max(0, tasks.length - visibleTasks.length);
11185
- return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", marginBottom: 1, children: [
11186
- /* @__PURE__ */ jsxs11(Box11, { children: [
11187
- /* @__PURE__ */ jsx12(Text11, { color: celebrating ? theme.palette.success : allDone ? "green" : theme.accent, bold: true, children: celebrating ? `\u2728 ${header}` : header }),
11188
- headerStats && /* @__PURE__ */ jsxs11(Text11, { color: theme.info.color, children: [
11189
- " ",
11190
- "(",
11191
- headerStats,
11192
- ")"
11193
- ] })
11194
- ] }),
11195
- visibleTasks.map((t) => /* @__PURE__ */ jsx12(TaskRow, { task: t }, t.id)),
11196
- hiddenPending > 0 && /* @__PURE__ */ jsxs11(Text11, { color: theme.info.color, children: [
11197
- " ",
11198
- "\u2026 +",
11199
- hiddenPending,
11200
- " more"
11201
- ] })
11202
- ] });
11203
- }
11204
- function TaskRow({ task }) {
11205
- const theme = useTheme();
11206
- if (task.status === "completed") {
11207
- return /* @__PURE__ */ jsxs11(Text11, { color: theme.info.color, children: [
11208
- " ",
11209
- "\u2713 ",
11210
- /* @__PURE__ */ jsx12(Text11, { strikethrough: true, children: task.title })
11211
- ] });
11212
- }
11213
- if (task.status === "in_progress") {
11214
- return /* @__PURE__ */ jsxs11(Text11, { color: theme.accent, bold: true, children: [
11215
- " ",
11216
- /* @__PURE__ */ jsx12(Spinner4, { type: "line" }),
11217
- " ",
11218
- task.title
11219
- ] });
11126
+ // node_modules/chalk/source/utilities.js
11127
+ function stringReplaceAll(string, substring, replacer) {
11128
+ let index = string.indexOf(substring);
11129
+ if (index === -1) {
11130
+ return string;
11220
11131
  }
11221
- return /* @__PURE__ */ jsxs11(Text11, { color: theme.info.color, children: [
11222
- " ",
11223
- "\u2610 ",
11224
- task.title
11225
- ] });
11226
- }
11227
- function formatElapsed3(ms) {
11228
- const total = Math.floor(ms / 1e3);
11229
- const m = Math.floor(total / 60);
11230
- const s = total % 60;
11231
- if (m === 0) return `${s}s`;
11232
- return `${m}m ${s}s`;
11132
+ const substringLength = substring.length;
11133
+ let endIndex = 0;
11134
+ let returnValue = "";
11135
+ do {
11136
+ returnValue += string.slice(endIndex, index) + substring + replacer;
11137
+ endIndex = index + substringLength;
11138
+ index = string.indexOf(substring, endIndex);
11139
+ } while (index !== -1);
11140
+ returnValue += string.slice(endIndex);
11141
+ return returnValue;
11233
11142
  }
11234
- function formatTokens3(n) {
11235
- if (n < 1e3) return String(n);
11236
- return `${(n / 1e3).toFixed(1)}k`;
11143
+ function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
11144
+ let endIndex = 0;
11145
+ let returnValue = "";
11146
+ do {
11147
+ const gotCR = string[index - 1] === "\r";
11148
+ returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
11149
+ endIndex = index + 1;
11150
+ index = string.indexOf("\n", endIndex);
11151
+ } while (index !== -1);
11152
+ returnValue += string.slice(endIndex);
11153
+ return returnValue;
11237
11154
  }
11238
- var MAX_VISIBLE;
11239
- var init_task_list = __esm({
11240
- "src/ui/task-list.tsx"() {
11155
+ var init_utilities = __esm({
11156
+ "node_modules/chalk/source/utilities.js"() {
11241
11157
  "use strict";
11242
- init_theme_context();
11243
- MAX_VISIBLE = 6;
11244
11158
  }
11245
11159
  });
11246
11160
 
11247
- // node_modules/chalk/source/vendor/ansi-styles/index.js
11248
- function assembleStyles() {
11249
- const codes = /* @__PURE__ */ new Map();
11250
- for (const [groupName, group] of Object.entries(styles)) {
11251
- for (const [styleName, style] of Object.entries(group)) {
11252
- styles[styleName] = {
11253
- open: `\x1B[${style[0]}m`,
11254
- close: `\x1B[${style[1]}m`
11161
+ // node_modules/chalk/source/index.js
11162
+ function createChalk(options) {
11163
+ return chalkFactory(options);
11164
+ }
11165
+ var stdoutColor, stderrColor, GENERATOR, STYLER, IS_EMPTY, levelMapping, styles2, applyOptions, chalkFactory, getModelAnsi, usedModels, proto, createStyler, createBuilder, applyStyle, chalk, chalkStderr, source_default;
11166
+ var init_source = __esm({
11167
+ "node_modules/chalk/source/index.js"() {
11168
+ "use strict";
11169
+ init_ansi_styles();
11170
+ init_supports_color();
11171
+ init_utilities();
11172
+ ({ stdout: stdoutColor, stderr: stderrColor } = supports_color_default);
11173
+ GENERATOR = /* @__PURE__ */ Symbol("GENERATOR");
11174
+ STYLER = /* @__PURE__ */ Symbol("STYLER");
11175
+ IS_EMPTY = /* @__PURE__ */ Symbol("IS_EMPTY");
11176
+ levelMapping = [
11177
+ "ansi",
11178
+ "ansi",
11179
+ "ansi256",
11180
+ "ansi16m"
11181
+ ];
11182
+ styles2 = /* @__PURE__ */ Object.create(null);
11183
+ applyOptions = (object, options = {}) => {
11184
+ if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
11185
+ throw new Error("The `level` option should be an integer from 0 to 3");
11186
+ }
11187
+ const colorLevel = stdoutColor ? stdoutColor.level : 0;
11188
+ object.level = options.level === void 0 ? colorLevel : options.level;
11189
+ };
11190
+ chalkFactory = (options) => {
11191
+ const chalk2 = (...strings) => strings.join(" ");
11192
+ applyOptions(chalk2, options);
11193
+ Object.setPrototypeOf(chalk2, createChalk.prototype);
11194
+ return chalk2;
11195
+ };
11196
+ Object.setPrototypeOf(createChalk.prototype, Function.prototype);
11197
+ for (const [styleName, style] of Object.entries(ansi_styles_default)) {
11198
+ styles2[styleName] = {
11199
+ get() {
11200
+ const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
11201
+ Object.defineProperty(this, styleName, { value: builder });
11202
+ return builder;
11203
+ }
11255
11204
  };
11256
- group[styleName] = styles[styleName];
11257
- codes.set(style[0], style[1]);
11258
11205
  }
11259
- Object.defineProperty(styles, groupName, {
11260
- value: group,
11261
- enumerable: false
11262
- });
11263
- }
11264
- Object.defineProperty(styles, "codes", {
11265
- value: codes,
11266
- enumerable: false
11267
- });
11268
- styles.color.close = "\x1B[39m";
11269
- styles.bgColor.close = "\x1B[49m";
11270
- styles.color.ansi = wrapAnsi16();
11271
- styles.color.ansi256 = wrapAnsi256();
11272
- styles.color.ansi16m = wrapAnsi16m();
11273
- styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
11274
- styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
11275
- styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
11276
- Object.defineProperties(styles, {
11277
- rgbToAnsi256: {
11278
- value(red, green, blue) {
11279
- if (red === green && green === blue) {
11280
- if (red < 8) {
11281
- return 16;
11282
- }
11283
- if (red > 248) {
11284
- return 231;
11285
- }
11286
- return Math.round((red - 8) / 247 * 24) + 232;
11206
+ styles2.visible = {
11207
+ get() {
11208
+ const builder = createBuilder(this, this[STYLER], true);
11209
+ Object.defineProperty(this, "visible", { value: builder });
11210
+ return builder;
11211
+ }
11212
+ };
11213
+ getModelAnsi = (model, level, type, ...arguments_) => {
11214
+ if (model === "rgb") {
11215
+ if (level === "ansi16m") {
11216
+ return ansi_styles_default[type].ansi16m(...arguments_);
11287
11217
  }
11288
- return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
11289
- },
11290
- enumerable: false
11291
- },
11292
- hexToRgb: {
11293
- value(hex) {
11294
- const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
11295
- if (!matches) {
11296
- return [0, 0, 0];
11218
+ if (level === "ansi256") {
11219
+ return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
11297
11220
  }
11298
- let [colorString] = matches;
11299
- if (colorString.length === 3) {
11300
- colorString = [...colorString].map((character) => character + character).join("");
11221
+ return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
11222
+ }
11223
+ if (model === "hex") {
11224
+ return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
11225
+ }
11226
+ return ansi_styles_default[type][model](...arguments_);
11227
+ };
11228
+ usedModels = ["rgb", "hex", "ansi256"];
11229
+ for (const model of usedModels) {
11230
+ styles2[model] = {
11231
+ get() {
11232
+ const { level } = this;
11233
+ return function(...arguments_) {
11234
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
11235
+ return createBuilder(this, styler, this[IS_EMPTY]);
11236
+ };
11301
11237
  }
11302
- const integer = Number.parseInt(colorString, 16);
11303
- return [
11304
- /* eslint-disable no-bitwise */
11305
- integer >> 16 & 255,
11306
- integer >> 8 & 255,
11307
- integer & 255
11308
- /* eslint-enable no-bitwise */
11309
- ];
11310
- },
11311
- enumerable: false
11312
- },
11313
- hexToAnsi256: {
11314
- value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
11315
- enumerable: false
11316
- },
11317
- ansi256ToAnsi: {
11318
- value(code) {
11319
- if (code < 8) {
11320
- return 30 + code;
11238
+ };
11239
+ const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
11240
+ styles2[bgModel] = {
11241
+ get() {
11242
+ const { level } = this;
11243
+ return function(...arguments_) {
11244
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
11245
+ return createBuilder(this, styler, this[IS_EMPTY]);
11246
+ };
11321
11247
  }
11322
- if (code < 16) {
11323
- return 90 + (code - 8);
11248
+ };
11249
+ }
11250
+ proto = Object.defineProperties(() => {
11251
+ }, {
11252
+ ...styles2,
11253
+ level: {
11254
+ enumerable: true,
11255
+ get() {
11256
+ return this[GENERATOR].level;
11257
+ },
11258
+ set(level) {
11259
+ this[GENERATOR].level = level;
11324
11260
  }
11325
- let red;
11326
- let green;
11327
- let blue;
11328
- if (code >= 232) {
11329
- red = ((code - 232) * 10 + 8) / 255;
11330
- green = red;
11331
- blue = red;
11332
- } else {
11333
- code -= 16;
11334
- const remainder = code % 36;
11335
- red = Math.floor(code / 36) / 5;
11336
- green = Math.floor(remainder / 6) / 5;
11337
- blue = remainder % 6 / 5;
11261
+ }
11262
+ });
11263
+ createStyler = (open3, close, parent) => {
11264
+ let openAll;
11265
+ let closeAll;
11266
+ if (parent === void 0) {
11267
+ openAll = open3;
11268
+ closeAll = close;
11269
+ } else {
11270
+ openAll = parent.openAll + open3;
11271
+ closeAll = close + parent.closeAll;
11272
+ }
11273
+ return {
11274
+ open: open3,
11275
+ close,
11276
+ openAll,
11277
+ closeAll,
11278
+ parent
11279
+ };
11280
+ };
11281
+ createBuilder = (self, _styler, _isEmpty) => {
11282
+ const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
11283
+ Object.setPrototypeOf(builder, proto);
11284
+ builder[GENERATOR] = self;
11285
+ builder[STYLER] = _styler;
11286
+ builder[IS_EMPTY] = _isEmpty;
11287
+ return builder;
11288
+ };
11289
+ applyStyle = (self, string) => {
11290
+ if (self.level <= 0 || !string) {
11291
+ return self[IS_EMPTY] ? "" : string;
11292
+ }
11293
+ let styler = self[STYLER];
11294
+ if (styler === void 0) {
11295
+ return string;
11296
+ }
11297
+ const { openAll, closeAll } = styler;
11298
+ if (string.includes("\x1B")) {
11299
+ while (styler !== void 0) {
11300
+ string = stringReplaceAll(string, styler.close, styler.open);
11301
+ styler = styler.parent;
11338
11302
  }
11339
- const value = Math.max(red, green, blue) * 2;
11340
- if (value === 0) {
11341
- return 30;
11303
+ }
11304
+ const lfIndex = string.indexOf("\n");
11305
+ if (lfIndex !== -1) {
11306
+ string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
11307
+ }
11308
+ return openAll + string + closeAll;
11309
+ };
11310
+ Object.defineProperties(createChalk.prototype, styles2);
11311
+ chalk = createChalk();
11312
+ chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
11313
+ source_default = chalk;
11314
+ }
11315
+ });
11316
+
11317
+ // src/ui/text-input.tsx
11318
+ import { useState as useState3, useEffect as useEffect3, useRef } from "react";
11319
+ import { Text as Text7, useInput } from "ink";
11320
+ import { jsx as jsx8 } from "react/jsx-runtime";
11321
+ function shouldTreatAsPaste(input) {
11322
+ if (input.length >= PASTE_CHAR_THRESHOLD) return true;
11323
+ const newlines = (input.match(/\n/g) ?? []).length;
11324
+ return newlines >= PASTE_NEWLINE_THRESHOLD;
11325
+ }
11326
+ function makePastePreview(input, lines, id) {
11327
+ const firstLine2 = input.split("\n")[0] ?? "";
11328
+ const cleaned = firstLine2.trim().replace(/\s+/g, " ");
11329
+ const preview = cleaned.length > 20 ? cleaned.slice(0, 20) + "\u2026" : cleaned;
11330
+ const text = preview || "(empty)";
11331
+ return `\u2997"${text}" (${lines} line${lines === 1 ? "" : "s"}) #${id}\u2998`;
11332
+ }
11333
+ function countLines(s) {
11334
+ return s.split("\n").length;
11335
+ }
11336
+ function findWordBoundaryForward(text, pos) {
11337
+ while (pos < text.length && /\w/.test(text[pos])) pos++;
11338
+ while (pos < text.length && !/\w/.test(text[pos])) pos++;
11339
+ return pos;
11340
+ }
11341
+ function findWordBoundaryBackward(text, pos) {
11342
+ while (pos > 0 && !/\w/.test(text[pos - 1])) pos--;
11343
+ while (pos > 0 && /\w/.test(text[pos - 1])) pos--;
11344
+ return pos;
11345
+ }
11346
+ function CustomTextInput({
11347
+ value,
11348
+ onChange,
11349
+ onSubmit,
11350
+ onHistoryUp,
11351
+ onHistoryDown,
11352
+ onClearQueueItem,
11353
+ focus = true,
11354
+ mask,
11355
+ enablePaste = false,
11356
+ cursorOffset: controlledCursor,
11357
+ onCursorChange,
11358
+ pickerActive = false,
11359
+ onPickerUp,
11360
+ onPickerDown,
11361
+ onPickerSelect,
11362
+ onPickerCancel,
11363
+ onCancel
11364
+ }) {
11365
+ const [internalCursor, setInternalCursor] = useState3(value.length);
11366
+ const cursorOffset = controlledCursor ?? internalCursor;
11367
+ const setCursorOffset = (offset) => {
11368
+ setInternalCursor(offset);
11369
+ onCursorChange?.(offset);
11370
+ };
11371
+ const pastesRef = useRef(/* @__PURE__ */ new Map());
11372
+ const pasteCounterRef = useRef(0);
11373
+ useEffect3(() => {
11374
+ if (!focus) return;
11375
+ const next = cursorOffset > value.length ? value.length : cursorOffset;
11376
+ if (next !== cursorOffset) {
11377
+ setCursorOffset(next);
11378
+ }
11379
+ }, [value, focus, cursorOffset]);
11380
+ useInput(
11381
+ (input, key) => {
11382
+ if (!focus) return;
11383
+ if (key.ctrl && input === "c") return;
11384
+ if (key.ctrl && input === "r") return;
11385
+ if (key.ctrl && input === "o") return;
11386
+ if (key.tab) return;
11387
+ if (pickerActive) {
11388
+ if (key.upArrow) {
11389
+ onPickerUp?.();
11390
+ return;
11342
11391
  }
11343
- let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
11344
- if (value === 2) {
11345
- result += 60;
11392
+ if (key.downArrow) {
11393
+ onPickerDown?.();
11394
+ return;
11346
11395
  }
11347
- return result;
11348
- },
11349
- enumerable: false
11350
- },
11351
- rgbToAnsi: {
11352
- value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
11353
- enumerable: false
11396
+ if (key.return) {
11397
+ onPickerSelect?.();
11398
+ return;
11399
+ }
11400
+ if (key.escape) {
11401
+ onPickerCancel?.();
11402
+ return;
11403
+ }
11404
+ }
11405
+ if (key.escape) {
11406
+ onCancel?.();
11407
+ setCursorOffset(0);
11408
+ return;
11409
+ }
11410
+ if (key.return) {
11411
+ let full = value;
11412
+ let hasPastes = false;
11413
+ if (enablePaste && pastesRef.current.size > 0) {
11414
+ for (const [placeholder, fullText] of pastesRef.current) {
11415
+ if (full.includes(placeholder)) {
11416
+ full = full.split(placeholder).join(fullText);
11417
+ hasPastes = true;
11418
+ }
11419
+ }
11420
+ }
11421
+ onSubmit(full, hasPastes ? value : void 0);
11422
+ pastesRef.current.clear();
11423
+ setCursorOffset(0);
11424
+ return;
11425
+ }
11426
+ if (key.upArrow) {
11427
+ onHistoryUp?.();
11428
+ return;
11429
+ }
11430
+ if (key.downArrow) {
11431
+ onHistoryDown?.();
11432
+ return;
11433
+ }
11434
+ let nextCursor = cursorOffset;
11435
+ let nextValue = value;
11436
+ let didDelete = false;
11437
+ if (key.leftArrow) {
11438
+ if (key.meta) {
11439
+ nextCursor = findWordBoundaryBackward(value, cursorOffset);
11440
+ } else {
11441
+ nextCursor = cursorOffset - 1;
11442
+ }
11443
+ } else if (key.rightArrow) {
11444
+ if (key.meta) {
11445
+ nextCursor = findWordBoundaryForward(value, cursorOffset);
11446
+ } else {
11447
+ nextCursor = cursorOffset + 1;
11448
+ }
11449
+ } else if (key.meta && input === "b") {
11450
+ nextCursor = findWordBoundaryBackward(value, cursorOffset);
11451
+ } else if (key.meta && input === "f") {
11452
+ nextCursor = findWordBoundaryForward(value, cursorOffset);
11453
+ } else if (key.meta && input === "d") {
11454
+ didDelete = true;
11455
+ const boundary = findWordBoundaryForward(value, cursorOffset);
11456
+ nextValue = value.slice(0, cursorOffset) + value.slice(boundary);
11457
+ } else if (key.home || key.ctrl && input === "a") {
11458
+ nextCursor = 0;
11459
+ } else if (key.end || key.ctrl && input === "e") {
11460
+ nextCursor = value.length;
11461
+ } else if (key.backspace) {
11462
+ didDelete = true;
11463
+ const tokenBoundary = enablePaste ? findPasteTokenEndingAt(value, cursorOffset, pastesRef.current) : -1;
11464
+ if (tokenBoundary >= 0) {
11465
+ const token = value.slice(tokenBoundary, cursorOffset);
11466
+ pastesRef.current.delete(token);
11467
+ nextValue = value.slice(0, tokenBoundary) + value.slice(cursorOffset);
11468
+ nextCursor = tokenBoundary;
11469
+ } else if (key.meta || key.ctrl && input === "w") {
11470
+ const boundary = findWordBoundaryBackward(value, cursorOffset);
11471
+ nextValue = value.slice(0, boundary) + value.slice(cursorOffset);
11472
+ nextCursor = boundary;
11473
+ } else if (key.ctrl) {
11474
+ const boundary = findWordBoundaryBackward(value, cursorOffset);
11475
+ nextValue = value.slice(0, boundary) + value.slice(cursorOffset);
11476
+ nextCursor = boundary;
11477
+ } else {
11478
+ if (cursorOffset > 0) {
11479
+ nextValue = value.slice(0, cursorOffset - 1) + value.slice(cursorOffset);
11480
+ nextCursor = cursorOffset - 1;
11481
+ }
11482
+ }
11483
+ } else if (key.delete) {
11484
+ didDelete = true;
11485
+ if (key.meta || key.ctrl) {
11486
+ const boundary = findWordBoundaryForward(value, cursorOffset);
11487
+ nextValue = value.slice(0, cursorOffset) + value.slice(boundary);
11488
+ } else {
11489
+ nextValue = value.slice(0, cursorOffset) + value.slice(cursorOffset + 1);
11490
+ }
11491
+ } else if (key.ctrl && input === "w") {
11492
+ didDelete = true;
11493
+ const boundary = findWordBoundaryBackward(value, cursorOffset);
11494
+ nextValue = value.slice(0, boundary) + value.slice(cursorOffset);
11495
+ nextCursor = boundary;
11496
+ } else if (key.ctrl && input === "u") {
11497
+ didDelete = true;
11498
+ nextValue = value.slice(cursorOffset);
11499
+ nextCursor = 0;
11500
+ } else if (key.ctrl && input === "k") {
11501
+ didDelete = true;
11502
+ nextValue = value.slice(0, cursorOffset);
11503
+ } else if (input.length > 0 && !key.ctrl && !key.meta) {
11504
+ let toInsert = input;
11505
+ if (enablePaste && shouldTreatAsPaste(input)) {
11506
+ const lines = countLines(input);
11507
+ const id = ++pasteCounterRef.current;
11508
+ const placeholder = makePastePreview(input, lines, id);
11509
+ pastesRef.current.set(placeholder, input);
11510
+ toInsert = placeholder;
11511
+ }
11512
+ nextValue = value.slice(0, cursorOffset) + toInsert + value.slice(cursorOffset);
11513
+ nextCursor = cursorOffset + toInsert.length;
11514
+ }
11515
+ if (nextCursor < 0) nextCursor = 0;
11516
+ if (nextCursor > nextValue.length) nextCursor = nextValue.length;
11517
+ if (didDelete && nextValue === "" && value !== "") {
11518
+ onClearQueueItem?.(value);
11519
+ }
11520
+ if (nextCursor !== cursorOffset) {
11521
+ setCursorOffset(nextCursor);
11522
+ }
11523
+ if (nextValue !== value) {
11524
+ onChange(nextValue);
11525
+ }
11354
11526
  },
11355
- hexToAnsi: {
11356
- value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
11357
- enumerable: false
11358
- }
11359
- });
11360
- return styles;
11527
+ { isActive: focus }
11528
+ );
11529
+ const displayValue = mask ? mask.repeat(value.length) : value;
11530
+ let renderedValue = "";
11531
+ let i = 0;
11532
+ for (const char of displayValue) {
11533
+ renderedValue += i === cursorOffset ? source_default.inverse(char) : char;
11534
+ i++;
11535
+ }
11536
+ if (displayValue.length === 0) {
11537
+ renderedValue = source_default.inverse(" ");
11538
+ } else if (cursorOffset === displayValue.length) {
11539
+ renderedValue += source_default.inverse(" ");
11540
+ }
11541
+ return /* @__PURE__ */ jsx8(Text7, { children: renderedValue });
11361
11542
  }
11362
- var ANSI_BACKGROUND_OFFSET, wrapAnsi16, wrapAnsi256, wrapAnsi16m, styles, modifierNames, foregroundColorNames, backgroundColorNames, colorNames, ansiStyles, ansi_styles_default;
11363
- var init_ansi_styles = __esm({
11364
- "node_modules/chalk/source/vendor/ansi-styles/index.js"() {
11543
+ function findPasteTokenEndingAt(value, pos, pastes) {
11544
+ if (pos <= 0 || value[pos - 1] !== "\u2998") return -1;
11545
+ for (const placeholder of pastes.keys()) {
11546
+ if (placeholder.length > pos) continue;
11547
+ const start = pos - placeholder.length;
11548
+ if (value.slice(start, pos) === placeholder) return start;
11549
+ }
11550
+ return -1;
11551
+ }
11552
+ var PASTE_CHAR_THRESHOLD, PASTE_NEWLINE_THRESHOLD;
11553
+ var init_text_input = __esm({
11554
+ "src/ui/text-input.tsx"() {
11365
11555
  "use strict";
11366
- ANSI_BACKGROUND_OFFSET = 10;
11367
- wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
11368
- wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
11369
- wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
11370
- styles = {
11371
- modifier: {
11372
- reset: [0, 0],
11373
- // 21 isn't widely supported and 22 does the same thing
11374
- bold: [1, 22],
11375
- dim: [2, 22],
11376
- italic: [3, 23],
11377
- underline: [4, 24],
11378
- overline: [53, 55],
11379
- inverse: [7, 27],
11380
- hidden: [8, 28],
11381
- strikethrough: [9, 29]
11382
- },
11383
- color: {
11384
- black: [30, 39],
11385
- red: [31, 39],
11386
- green: [32, 39],
11387
- yellow: [33, 39],
11388
- blue: [34, 39],
11389
- magenta: [35, 39],
11390
- cyan: [36, 39],
11391
- white: [37, 39],
11392
- // Bright color
11393
- blackBright: [90, 39],
11394
- gray: [90, 39],
11395
- // Alias of `blackBright`
11396
- grey: [90, 39],
11397
- // Alias of `blackBright`
11398
- redBright: [91, 39],
11399
- greenBright: [92, 39],
11400
- yellowBright: [93, 39],
11401
- blueBright: [94, 39],
11402
- magentaBright: [95, 39],
11403
- cyanBright: [96, 39],
11404
- whiteBright: [97, 39]
11405
- },
11406
- bgColor: {
11407
- bgBlack: [40, 49],
11408
- bgRed: [41, 49],
11409
- bgGreen: [42, 49],
11410
- bgYellow: [43, 49],
11411
- bgBlue: [44, 49],
11412
- bgMagenta: [45, 49],
11413
- bgCyan: [46, 49],
11414
- bgWhite: [47, 49],
11415
- // Bright color
11416
- bgBlackBright: [100, 49],
11417
- bgGray: [100, 49],
11418
- // Alias of `bgBlackBright`
11419
- bgGrey: [100, 49],
11420
- // Alias of `bgBlackBright`
11421
- bgRedBright: [101, 49],
11422
- bgGreenBright: [102, 49],
11423
- bgYellowBright: [103, 49],
11424
- bgBlueBright: [104, 49],
11425
- bgMagentaBright: [105, 49],
11426
- bgCyanBright: [106, 49],
11427
- bgWhiteBright: [107, 49]
11428
- }
11429
- };
11430
- modifierNames = Object.keys(styles.modifier);
11431
- foregroundColorNames = Object.keys(styles.color);
11432
- backgroundColorNames = Object.keys(styles.bgColor);
11433
- colorNames = [...foregroundColorNames, ...backgroundColorNames];
11434
- ansiStyles = assembleStyles();
11435
- ansi_styles_default = ansiStyles;
11556
+ init_source();
11557
+ PASTE_CHAR_THRESHOLD = 200;
11558
+ PASTE_NEWLINE_THRESHOLD = 1;
11436
11559
  }
11437
11560
  });
11438
11561
 
11439
- // node_modules/chalk/source/vendor/supports-color/index.js
11440
- import process2 from "process";
11441
- import os from "os";
11442
- import tty from "tty";
11443
- function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
11444
- const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
11445
- const position = argv.indexOf(prefix + flag);
11446
- const terminatorPosition = argv.indexOf("--");
11447
- return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
11448
- }
11449
- function envForceColor() {
11450
- if ("FORCE_COLOR" in env) {
11451
- if (env.FORCE_COLOR === "true") {
11452
- return 1;
11453
- }
11454
- if (env.FORCE_COLOR === "false") {
11455
- return 0;
11456
- }
11457
- return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
11458
- }
11562
+ // src/ui/permission.tsx
11563
+ import { useState as useState4, useCallback } from "react";
11564
+ import { Box as Box7, Text as Text8, useInput as useInput2 } from "ink";
11565
+ import { platform as platform2 } from "os";
11566
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
11567
+ function formatSelection(label, shortcut) {
11568
+ return `${label} [${MOD_KEY}+${shortcut}]`;
11459
11569
  }
11460
- function translateLevel(level) {
11461
- if (level === 0) {
11462
- return false;
11463
- }
11464
- return {
11465
- level,
11466
- hasBasic: true,
11467
- has256: level >= 2,
11468
- has16m: level >= 3
11469
- };
11470
- }
11471
- function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
11472
- const noFlagForceColor = envForceColor();
11473
- if (noFlagForceColor !== void 0) {
11474
- flagForceColor = noFlagForceColor;
11475
- }
11476
- const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
11477
- if (forceColor === 0) {
11478
- return 0;
11479
- }
11480
- if (sniffFlags) {
11481
- if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
11482
- return 3;
11483
- }
11484
- if (hasFlag("color=256")) {
11485
- return 2;
11486
- }
11487
- }
11488
- if ("TF_BUILD" in env && "AGENT_NAME" in env) {
11489
- return 1;
11490
- }
11491
- if (haveStream && !streamIsTTY && forceColor === void 0) {
11492
- return 0;
11493
- }
11494
- const min = forceColor || 0;
11495
- if (env.TERM === "dumb") {
11496
- return min;
11497
- }
11498
- if (process2.platform === "win32") {
11499
- const osRelease = os.release().split(".");
11500
- if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
11501
- return Number(osRelease[2]) >= 14931 ? 3 : 2;
11502
- }
11503
- return 1;
11504
- }
11505
- if ("CI" in env) {
11506
- if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => key in env)) {
11507
- return 3;
11508
- }
11509
- if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
11510
- return 1;
11511
- }
11512
- return min;
11513
- }
11514
- if ("TEAMCITY_VERSION" in env) {
11515
- return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
11516
- }
11517
- if (env.COLORTERM === "truecolor") {
11518
- return 3;
11519
- }
11520
- if (env.TERM === "xterm-kitty") {
11521
- return 3;
11522
- }
11523
- if (env.TERM === "xterm-ghostty") {
11524
- return 3;
11525
- }
11526
- if (env.TERM === "wezterm") {
11527
- return 3;
11570
+ function PermissionModal({ tool, args, onDecide, onFeedback }) {
11571
+ const theme = useTheme();
11572
+ const [selectedIndex, setSelectedIndex] = useState4(0);
11573
+ const [showHelp, setShowHelp] = useState4(false);
11574
+ const [feedbackActive, setFeedbackActive] = useState4(false);
11575
+ const [feedbackValue, setFeedbackValue] = useState4("");
11576
+ let render2;
11577
+ try {
11578
+ render2 = tool.render?.(args);
11579
+ } catch {
11528
11580
  }
11529
- if ("TERM_PROGRAM" in env) {
11530
- const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
11531
- switch (env.TERM_PROGRAM) {
11532
- case "iTerm.app": {
11533
- return version >= 3 ? 3 : 2;
11581
+ const handleSelect = useCallback(
11582
+ (index) => {
11583
+ const opt = OPTIONS[index];
11584
+ if (!opt) return;
11585
+ if (opt.value === "deny") {
11586
+ if (onFeedback) {
11587
+ setFeedbackActive(true);
11588
+ } else {
11589
+ onDecide("deny");
11590
+ }
11591
+ } else {
11592
+ onDecide(opt.value);
11534
11593
  }
11535
- case "Apple_Terminal": {
11536
- return 2;
11594
+ },
11595
+ [onDecide, onFeedback]
11596
+ );
11597
+ const handleFeedbackSubmit = useCallback(
11598
+ (text) => {
11599
+ onDecide("deny");
11600
+ if (text.trim()) {
11601
+ onFeedback?.(text);
11602
+ }
11603
+ setFeedbackActive(false);
11604
+ setFeedbackValue("");
11605
+ },
11606
+ [onDecide, onFeedback]
11607
+ );
11608
+ const handleFeedbackCancel = useCallback(() => {
11609
+ onDecide("deny");
11610
+ setFeedbackActive(false);
11611
+ setFeedbackValue("");
11612
+ }, [onDecide]);
11613
+ useInput2(
11614
+ (inputChar, key) => {
11615
+ if (showHelp) {
11616
+ setShowHelp(false);
11617
+ return;
11537
11618
  }
11538
- }
11539
- }
11540
- if (/-256(color)?$/i.test(env.TERM)) {
11541
- return 2;
11542
- }
11543
- if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
11544
- return 1;
11545
- }
11546
- if ("COLORTERM" in env) {
11547
- return 1;
11619
+ if (key.meta && inputChar === "1") {
11620
+ handleSelect(0);
11621
+ return;
11622
+ }
11623
+ if (key.meta && inputChar === "2") {
11624
+ handleSelect(1);
11625
+ return;
11626
+ }
11627
+ if (key.meta && inputChar === "3") {
11628
+ handleSelect(2);
11629
+ return;
11630
+ }
11631
+ if (key.upArrow || inputChar === "k") {
11632
+ setSelectedIndex((i) => Math.max(0, i - 1));
11633
+ return;
11634
+ }
11635
+ if (key.downArrow || inputChar === "j") {
11636
+ setSelectedIndex((i) => Math.min(OPTIONS.length - 1, i + 1));
11637
+ return;
11638
+ }
11639
+ if (key.return) {
11640
+ handleSelect(selectedIndex);
11641
+ return;
11642
+ }
11643
+ if (inputChar === "?") {
11644
+ setShowHelp(true);
11645
+ return;
11646
+ }
11647
+ if (key.escape) {
11648
+ onDecide("deny");
11649
+ }
11650
+ },
11651
+ { isActive: !feedbackActive }
11652
+ );
11653
+ if (showHelp) {
11654
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: theme.permission, paddingX: 1, children: [
11655
+ /* @__PURE__ */ jsx9(Text8, { color: theme.permission, bold: true, children: "Permission modal \u2014 keyboard shortcuts" }),
11656
+ /* @__PURE__ */ jsx9(Text8, { color: theme.info.color, children: "\u2191 / \u2193 or j / k \u2014 navigate options" }),
11657
+ /* @__PURE__ */ jsxs7(Text8, { color: theme.info.color, children: [
11658
+ MOD_KEY,
11659
+ "+1 / ",
11660
+ MOD_KEY,
11661
+ "+2 / ",
11662
+ MOD_KEY,
11663
+ "+3 \u2014 select option directly"
11664
+ ] }),
11665
+ /* @__PURE__ */ jsx9(Text8, { color: theme.info.color, children: "Enter \u2014 confirm selection" }),
11666
+ /* @__PURE__ */ jsx9(Text8, { color: theme.info.color, children: "Esc \u2014 deny and close" }),
11667
+ /* @__PURE__ */ jsx9(Text8, { color: theme.info.color, children: "? \u2014 toggle this help" }),
11668
+ /* @__PURE__ */ jsx9(Text8, { color: theme.info.color, children: "When feedback input is open:" }),
11669
+ /* @__PURE__ */ jsx9(Text8, { color: theme.info.color, children: " Enter \u2014 submit feedback and deny" }),
11670
+ /* @__PURE__ */ jsx9(Text8, { color: theme.info.color, children: " Esc \u2014 deny without feedback" }),
11671
+ /* @__PURE__ */ jsx9(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text8, { color: theme.accent, children: "Press any key to close" }) })
11672
+ ] });
11548
11673
  }
11549
- return min;
11550
- }
11551
- function createSupportsColor(stream, options = {}) {
11552
- const level = _supportsColor(stream, {
11553
- streamIsTTY: stream && stream.isTTY,
11554
- ...options
11555
- });
11556
- return translateLevel(level);
11674
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: theme.permission, paddingX: 1, children: [
11675
+ /* @__PURE__ */ jsx9(Text8, { color: theme.permission, bold: true, children: "Permission requested" }),
11676
+ /* @__PURE__ */ jsxs7(Text8, { children: [
11677
+ "tool: ",
11678
+ /* @__PURE__ */ jsx9(Text8, { color: theme.tool, children: tool.name })
11679
+ ] }),
11680
+ render2?.title ? /* @__PURE__ */ jsxs7(Text8, { children: [
11681
+ "action: ",
11682
+ render2.title
11683
+ ] }) : null,
11684
+ render2?.diff ? /* @__PURE__ */ jsx9(Box7, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx9(DiffView, { ...render2.diff }) }) : /* @__PURE__ */ jsxs7(Text8, { color: theme.info.color, children: [
11685
+ "args: ",
11686
+ JSON.stringify(args)
11687
+ ] }),
11688
+ /* @__PURE__ */ jsx9(Box7, { marginTop: 1, flexDirection: "column", children: OPTIONS.map((opt, i) => /* @__PURE__ */ jsxs7(
11689
+ Text8,
11690
+ {
11691
+ color: i === selectedIndex ? theme.accent : void 0,
11692
+ bold: i === selectedIndex,
11693
+ children: [
11694
+ i === selectedIndex ? "\u203A " : " ",
11695
+ formatSelection(opt.label, opt.key)
11696
+ ]
11697
+ },
11698
+ opt.value
11699
+ )) }),
11700
+ feedbackActive && /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
11701
+ /* @__PURE__ */ jsx9(Text8, { color: theme.palette.error, children: "Tell me what to do instead" }),
11702
+ /* @__PURE__ */ jsx9(Text8, { color: theme.info.color, dimColor: true, children: "Press Esc to deny without feedback" }),
11703
+ /* @__PURE__ */ jsx9(
11704
+ CustomTextInput,
11705
+ {
11706
+ value: feedbackValue,
11707
+ onChange: setFeedbackValue,
11708
+ onSubmit: handleFeedbackSubmit,
11709
+ onCancel: handleFeedbackCancel,
11710
+ focus: true
11711
+ }
11712
+ )
11713
+ ] })
11714
+ ] });
11557
11715
  }
11558
- var env, flagForceColor, supportsColor, supports_color_default;
11559
- var init_supports_color = __esm({
11560
- "node_modules/chalk/source/vendor/supports-color/index.js"() {
11716
+ var OPTIONS, MOD_KEY;
11717
+ var init_permission = __esm({
11718
+ "src/ui/permission.tsx"() {
11561
11719
  "use strict";
11562
- ({ env } = process2);
11563
- if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
11564
- flagForceColor = 0;
11565
- } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
11566
- flagForceColor = 1;
11567
- }
11568
- supportsColor = {
11569
- stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
11570
- stderr: createSupportsColor({ isTTY: tty.isatty(2) })
11571
- };
11572
- supports_color_default = supportsColor;
11720
+ init_diff_view();
11721
+ init_text_input();
11722
+ init_theme_context();
11723
+ OPTIONS = [
11724
+ { value: "allow", label: "Allow once", key: 1 },
11725
+ { value: "allow_session", label: "Allow for this session", key: 2 },
11726
+ { value: "deny", label: "Something else", key: 3 }
11727
+ ];
11728
+ MOD_KEY = platform2() === "darwin" ? "\u2325" : "Alt";
11573
11729
  }
11574
11730
  });
11575
11731
 
11576
- // node_modules/chalk/source/utilities.js
11577
- function stringReplaceAll(string, substring, replacer) {
11578
- let index = string.indexOf(substring);
11579
- if (index === -1) {
11580
- return string;
11581
- }
11582
- const substringLength = substring.length;
11583
- let endIndex = 0;
11584
- let returnValue = "";
11585
- do {
11586
- returnValue += string.slice(endIndex, index) + substring + replacer;
11587
- endIndex = index + substringLength;
11588
- index = string.indexOf(substring, endIndex);
11589
- } while (index !== -1);
11590
- returnValue += string.slice(endIndex);
11591
- return returnValue;
11592
- }
11593
- function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
11594
- let endIndex = 0;
11595
- let returnValue = "";
11596
- do {
11597
- const gotCR = string[index - 1] === "\r";
11598
- returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
11599
- endIndex = index + 1;
11600
- index = string.indexOf("\n", endIndex);
11601
- } while (index !== -1);
11602
- returnValue += string.slice(endIndex);
11603
- return returnValue;
11732
+ // src/ui/limit-modal.tsx
11733
+ import { Box as Box8, Text as Text9 } from "ink";
11734
+ import SelectInput from "ink-select-input";
11735
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
11736
+ function LimitModal({ limit, onDecide }) {
11737
+ const theme = useTheme();
11738
+ const items = [
11739
+ { label: "Continue", value: "continue" },
11740
+ { label: "Stop", value: "stop" }
11741
+ ];
11742
+ return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: theme.error, paddingX: 1, children: [
11743
+ /* @__PURE__ */ jsxs8(Text9, { color: theme.error, bold: true, children: [
11744
+ "Tool-call limit reached (",
11745
+ limit,
11746
+ ")"
11747
+ ] }),
11748
+ /* @__PURE__ */ jsxs8(Text9, { dimColor: true, children: [
11749
+ "This session has made ",
11750
+ limit,
11751
+ " tool calls. What would you like to do?"
11752
+ ] }),
11753
+ /* @__PURE__ */ jsx10(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx10(
11754
+ SelectInput,
11755
+ {
11756
+ items,
11757
+ onSelect: (item) => onDecide(item.value)
11758
+ }
11759
+ ) })
11760
+ ] });
11604
11761
  }
11605
- var init_utilities = __esm({
11606
- "node_modules/chalk/source/utilities.js"() {
11762
+ var init_limit_modal = __esm({
11763
+ "src/ui/limit-modal.tsx"() {
11607
11764
  "use strict";
11765
+ init_theme_context();
11608
11766
  }
11609
11767
  });
11610
11768
 
11611
- // node_modules/chalk/source/index.js
11612
- function createChalk(options) {
11613
- return chalkFactory(options);
11614
- }
11615
- var stdoutColor, stderrColor, GENERATOR, STYLER, IS_EMPTY, levelMapping, styles2, applyOptions, chalkFactory, getModelAnsi, usedModels, proto, createStyler, createBuilder, applyStyle, chalk, chalkStderr, source_default;
11616
- var init_source = __esm({
11617
- "node_modules/chalk/source/index.js"() {
11618
- "use strict";
11619
- init_ansi_styles();
11620
- init_supports_color();
11621
- init_utilities();
11622
- ({ stdout: stdoutColor, stderr: stderrColor } = supports_color_default);
11623
- GENERATOR = /* @__PURE__ */ Symbol("GENERATOR");
11624
- STYLER = /* @__PURE__ */ Symbol("STYLER");
11625
- IS_EMPTY = /* @__PURE__ */ Symbol("IS_EMPTY");
11626
- levelMapping = [
11627
- "ansi",
11628
- "ansi",
11629
- "ansi256",
11630
- "ansi16m"
11631
- ];
11632
- styles2 = /* @__PURE__ */ Object.create(null);
11633
- applyOptions = (object, options = {}) => {
11634
- if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
11635
- throw new Error("The `level` option should be an integer from 0 to 3");
11636
- }
11637
- const colorLevel = stdoutColor ? stdoutColor.level : 0;
11638
- object.level = options.level === void 0 ? colorLevel : options.level;
11639
- };
11640
- chalkFactory = (options) => {
11641
- const chalk2 = (...strings) => strings.join(" ");
11642
- applyOptions(chalk2, options);
11643
- Object.setPrototypeOf(chalk2, createChalk.prototype);
11644
- return chalk2;
11645
- };
11646
- Object.setPrototypeOf(createChalk.prototype, Function.prototype);
11647
- for (const [styleName, style] of Object.entries(ansi_styles_default)) {
11648
- styles2[styleName] = {
11649
- get() {
11650
- const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
11651
- Object.defineProperty(this, styleName, { value: builder });
11652
- return builder;
11653
- }
11654
- };
11655
- }
11656
- styles2.visible = {
11657
- get() {
11658
- const builder = createBuilder(this, this[STYLER], true);
11659
- Object.defineProperty(this, "visible", { value: builder });
11660
- return builder;
11661
- }
11662
- };
11663
- getModelAnsi = (model, level, type, ...arguments_) => {
11664
- if (model === "rgb") {
11665
- if (level === "ansi16m") {
11666
- return ansi_styles_default[type].ansi16m(...arguments_);
11667
- }
11668
- if (level === "ansi256") {
11669
- return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
11670
- }
11671
- return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
11672
- }
11673
- if (model === "hex") {
11674
- return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
11675
- }
11676
- return ansi_styles_default[type][model](...arguments_);
11677
- };
11678
- usedModels = ["rgb", "hex", "ansi256"];
11679
- for (const model of usedModels) {
11680
- styles2[model] = {
11681
- get() {
11682
- const { level } = this;
11683
- return function(...arguments_) {
11684
- const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
11685
- return createBuilder(this, styler, this[IS_EMPTY]);
11686
- };
11687
- }
11688
- };
11689
- const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
11690
- styles2[bgModel] = {
11691
- get() {
11692
- const { level } = this;
11693
- return function(...arguments_) {
11694
- const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
11695
- return createBuilder(this, styler, this[IS_EMPTY]);
11696
- };
11697
- }
11698
- };
11699
- }
11700
- proto = Object.defineProperties(() => {
11701
- }, {
11702
- ...styles2,
11703
- level: {
11704
- enumerable: true,
11705
- get() {
11706
- return this[GENERATOR].level;
11707
- },
11708
- set(level) {
11709
- this[GENERATOR].level = level;
11710
- }
11711
- }
11712
- });
11713
- createStyler = (open3, close, parent) => {
11714
- let openAll;
11715
- let closeAll;
11716
- if (parent === void 0) {
11717
- openAll = open3;
11718
- closeAll = close;
11769
+ // src/util/fuzzy.ts
11770
+ function fuzzyMatch(query, text) {
11771
+ const queryLower = query.toLowerCase();
11772
+ const textLower = text.toLowerCase();
11773
+ const matchQuery = (normalizedQuery) => {
11774
+ if (normalizedQuery.length === 0) return { matches: true, score: 0 };
11775
+ if (normalizedQuery.length > textLower.length) return { matches: false, score: 0 };
11776
+ let queryIndex = 0;
11777
+ let score = 0;
11778
+ let lastMatchIndex = -1;
11779
+ let consecutiveMatches = 0;
11780
+ for (let i = 0; i < textLower.length && queryIndex < normalizedQuery.length; i++) {
11781
+ if (textLower[i] !== normalizedQuery[queryIndex]) continue;
11782
+ const isWordBoundary = i === 0 || /[\s\-_./:]/.test(textLower[i - 1]);
11783
+ if (lastMatchIndex === i - 1) {
11784
+ consecutiveMatches++;
11785
+ score -= consecutiveMatches * 5;
11719
11786
  } else {
11720
- openAll = parent.openAll + open3;
11721
- closeAll = close + parent.closeAll;
11722
- }
11723
- return {
11724
- open: open3,
11725
- close,
11726
- openAll,
11727
- closeAll,
11728
- parent
11729
- };
11730
- };
11731
- createBuilder = (self, _styler, _isEmpty) => {
11732
- const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
11733
- Object.setPrototypeOf(builder, proto);
11734
- builder[GENERATOR] = self;
11735
- builder[STYLER] = _styler;
11736
- builder[IS_EMPTY] = _isEmpty;
11737
- return builder;
11738
- };
11739
- applyStyle = (self, string) => {
11740
- if (self.level <= 0 || !string) {
11741
- return self[IS_EMPTY] ? "" : string;
11742
- }
11743
- let styler = self[STYLER];
11744
- if (styler === void 0) {
11745
- return string;
11746
- }
11747
- const { openAll, closeAll } = styler;
11748
- if (string.includes("\x1B")) {
11749
- while (styler !== void 0) {
11750
- string = stringReplaceAll(string, styler.close, styler.open);
11751
- styler = styler.parent;
11752
- }
11787
+ consecutiveMatches = 0;
11788
+ if (lastMatchIndex >= 0) score += (i - lastMatchIndex - 1) * 2;
11753
11789
  }
11754
- const lfIndex = string.indexOf("\n");
11755
- if (lfIndex !== -1) {
11756
- string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
11790
+ if (isWordBoundary) score -= 10;
11791
+ score += i * 0.1;
11792
+ lastMatchIndex = i;
11793
+ queryIndex++;
11794
+ }
11795
+ if (queryIndex < normalizedQuery.length) return { matches: false, score: 0 };
11796
+ if (normalizedQuery === textLower) score -= 100;
11797
+ return { matches: true, score };
11798
+ };
11799
+ const primaryMatch = matchQuery(queryLower);
11800
+ if (primaryMatch.matches) return primaryMatch;
11801
+ const alphaNumericMatch = queryLower.match(/^(?<letters>[a-z]+)(?<digits>[0-9]+)$/);
11802
+ const numericAlphaMatch = queryLower.match(/^(?<digits>[0-9]+)(?<letters>[a-z]+)$/);
11803
+ const swappedQuery = alphaNumericMatch ? `${alphaNumericMatch.groups?.digits ?? ""}${alphaNumericMatch.groups?.letters ?? ""}` : numericAlphaMatch ? `${numericAlphaMatch.groups?.letters ?? ""}${numericAlphaMatch.groups?.digits ?? ""}` : "";
11804
+ if (!swappedQuery) return primaryMatch;
11805
+ const swappedMatch = matchQuery(swappedQuery);
11806
+ if (!swappedMatch.matches) return primaryMatch;
11807
+ return { matches: true, score: swappedMatch.score + 5 };
11808
+ }
11809
+ function fuzzyFilter(items, query, getText) {
11810
+ const trimmed = query.trim();
11811
+ if (trimmed.length === 0) return items;
11812
+ const tokens = trimmed.split(/\s+/).filter((t) => t.length > 0);
11813
+ if (tokens.length === 0) return items;
11814
+ const scored = [];
11815
+ for (const item of items) {
11816
+ const text = getText(item);
11817
+ let total = 0;
11818
+ let allMatch = true;
11819
+ for (const token of tokens) {
11820
+ const m = fuzzyMatch(token, text);
11821
+ if (!m.matches) {
11822
+ allMatch = false;
11823
+ break;
11757
11824
  }
11758
- return openAll + string + closeAll;
11759
- };
11760
- Object.defineProperties(createChalk.prototype, styles2);
11761
- chalk = createChalk();
11762
- chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
11763
- source_default = chalk;
11825
+ total += m.score;
11826
+ }
11827
+ if (allMatch) scored.push({ item, score: total });
11828
+ }
11829
+ scored.sort((a, b) => a.score - b.score);
11830
+ return scored.map((s) => s.item);
11831
+ }
11832
+ var init_fuzzy = __esm({
11833
+ "src/util/fuzzy.ts"() {
11834
+ "use strict";
11764
11835
  }
11765
11836
  });
11766
11837
 
11767
- // src/ui/text-input.tsx
11768
- import { useState as useState6, useEffect as useEffect4, useRef as useRef2 } from "react";
11769
- import { Text as Text12, useInput as useInput3 } from "ink";
11770
- import { jsx as jsx13 } from "react/jsx-runtime";
11771
- function shouldTreatAsPaste(input) {
11772
- if (input.length >= PASTE_CHAR_THRESHOLD) return true;
11773
- const newlines = (input.match(/\n/g) ?? []).length;
11774
- return newlines >= PASTE_NEWLINE_THRESHOLD;
11775
- }
11776
- function newPasteId() {
11777
- return Math.random().toString(36).slice(2, 7);
11778
- }
11779
- function countLines(s) {
11780
- return s.split("\n").length;
11781
- }
11782
- function findWordBoundaryForward(text, pos) {
11783
- while (pos < text.length && /\w/.test(text[pos])) pos++;
11784
- while (pos < text.length && !/\w/.test(text[pos])) pos++;
11785
- return pos;
11786
- }
11787
- function findWordBoundaryBackward(text, pos) {
11788
- while (pos > 0 && !/\w/.test(text[pos - 1])) pos--;
11789
- while (pos > 0 && /\w/.test(text[pos - 1])) pos--;
11790
- return pos;
11791
- }
11792
- function CustomTextInput({
11793
- value,
11794
- onChange,
11795
- onSubmit,
11796
- onHistoryUp,
11797
- onHistoryDown,
11798
- onClearQueueItem,
11799
- focus = true,
11800
- mask,
11801
- enablePaste = false,
11802
- cursorOffset: controlledCursor,
11803
- onCursorChange,
11804
- pickerActive = false,
11805
- onPickerUp,
11806
- onPickerDown,
11807
- onPickerSelect,
11808
- onPickerCancel
11809
- }) {
11810
- const [internalCursor, setInternalCursor] = useState6(value.length);
11811
- const cursorOffset = controlledCursor ?? internalCursor;
11812
- const setCursorOffset = (offset) => {
11813
- setInternalCursor(offset);
11814
- onCursorChange?.(offset);
11815
- };
11816
- const pastesRef = useRef2(/* @__PURE__ */ new Map());
11817
- useEffect4(() => {
11818
- if (!focus) return;
11819
- const next = cursorOffset > value.length ? value.length : cursorOffset;
11820
- if (next !== cursorOffset) {
11821
- setCursorOffset(next);
11838
+ // src/ui/resume-picker.tsx
11839
+ import { useState as useState5 } from "react";
11840
+ import { Box as Box9, Text as Text10, useInput as useInput3 } from "ink";
11841
+ import SelectInput2 from "ink-select-input";
11842
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
11843
+ function ResumePicker({ sessions, onPick }) {
11844
+ const theme = useTheme();
11845
+ const [page, setPage] = useState5(0);
11846
+ const [selectedIndex, setSelectedIndex] = useState5(0);
11847
+ const [query, setQuery] = useState5("");
11848
+ const filtered = query.trim() ? fuzzyFilter(sessions, query, (s) => `${s.title ?? s.firstPrompt} ${s.id}`) : sessions;
11849
+ const totalPages = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE));
11850
+ const safePage = Math.min(page, totalPages - 1);
11851
+ const start = safePage * PAGE_SIZE;
11852
+ const end = Math.min(start + PAGE_SIZE, filtered.length);
11853
+ const pageSessions = filtered.slice(start, end);
11854
+ useInput3((input, key) => {
11855
+ if (key.leftArrow && safePage > 0) {
11856
+ setPage((p) => p - 1);
11857
+ setSelectedIndex(0);
11858
+ return;
11822
11859
  }
11823
- }, [value, focus, cursorOffset]);
11824
- useInput3(
11825
- (input, key) => {
11826
- if (!focus) return;
11827
- if (key.ctrl && input === "c") return;
11828
- if (key.ctrl && input === "r") return;
11829
- if (key.ctrl && input === "o") return;
11830
- if (key.tab) return;
11831
- if (pickerActive) {
11832
- if (key.upArrow) {
11833
- onPickerUp?.();
11834
- return;
11835
- }
11836
- if (key.downArrow) {
11837
- onPickerDown?.();
11838
- return;
11839
- }
11840
- if (key.return) {
11841
- onPickerSelect?.();
11842
- return;
11843
- }
11844
- if (key.escape) {
11845
- onPickerCancel?.();
11846
- return;
11847
- }
11848
- }
11849
- if (key.return) {
11850
- let full = value;
11851
- let hasPastes = false;
11852
- if (enablePaste && pastesRef.current.size > 0) {
11853
- for (const [placeholder, fullText] of pastesRef.current) {
11854
- if (full.includes(placeholder)) {
11855
- full = full.split(placeholder).join(fullText);
11856
- hasPastes = true;
11857
- }
11858
- }
11859
- }
11860
- onSubmit(full, hasPastes ? value : void 0);
11861
- pastesRef.current.clear();
11862
- setCursorOffset(0);
11863
- return;
11864
- }
11865
- if (key.upArrow) {
11866
- onHistoryUp?.();
11867
- return;
11868
- }
11869
- if (key.downArrow) {
11870
- onHistoryDown?.();
11871
- return;
11872
- }
11873
- let nextCursor = cursorOffset;
11874
- let nextValue = value;
11875
- let didDelete = false;
11876
- if (key.leftArrow) {
11877
- if (key.meta) {
11878
- nextCursor = findWordBoundaryBackward(value, cursorOffset);
11879
- } else {
11880
- nextCursor = cursorOffset - 1;
11881
- }
11882
- } else if (key.rightArrow) {
11883
- if (key.meta) {
11884
- nextCursor = findWordBoundaryForward(value, cursorOffset);
11885
- } else {
11886
- nextCursor = cursorOffset + 1;
11887
- }
11888
- } else if (key.meta && input === "b") {
11889
- nextCursor = findWordBoundaryBackward(value, cursorOffset);
11890
- } else if (key.meta && input === "f") {
11891
- nextCursor = findWordBoundaryForward(value, cursorOffset);
11892
- } else if (key.meta && input === "d") {
11893
- didDelete = true;
11894
- const boundary = findWordBoundaryForward(value, cursorOffset);
11895
- nextValue = value.slice(0, cursorOffset) + value.slice(boundary);
11896
- } else if (key.home || key.ctrl && input === "a") {
11897
- nextCursor = 0;
11898
- } else if (key.end || key.ctrl && input === "e") {
11899
- nextCursor = value.length;
11900
- } else if (key.backspace) {
11901
- didDelete = true;
11902
- const tokenBoundary = enablePaste ? findPasteTokenEndingAt(value, cursorOffset, pastesRef.current) : -1;
11903
- if (tokenBoundary >= 0) {
11904
- const token = value.slice(tokenBoundary, cursorOffset);
11905
- pastesRef.current.delete(token);
11906
- nextValue = value.slice(0, tokenBoundary) + value.slice(cursorOffset);
11907
- nextCursor = tokenBoundary;
11908
- } else if (key.meta || key.ctrl && input === "w") {
11909
- const boundary = findWordBoundaryBackward(value, cursorOffset);
11910
- nextValue = value.slice(0, boundary) + value.slice(cursorOffset);
11911
- nextCursor = boundary;
11912
- } else if (key.ctrl) {
11913
- const boundary = findWordBoundaryBackward(value, cursorOffset);
11914
- nextValue = value.slice(0, boundary) + value.slice(cursorOffset);
11915
- nextCursor = boundary;
11916
- } else {
11917
- if (cursorOffset > 0) {
11918
- nextValue = value.slice(0, cursorOffset - 1) + value.slice(cursorOffset);
11919
- nextCursor = cursorOffset - 1;
11920
- }
11921
- }
11922
- } else if (key.delete) {
11923
- didDelete = true;
11924
- if (key.meta || key.ctrl) {
11925
- const boundary = findWordBoundaryForward(value, cursorOffset);
11926
- nextValue = value.slice(0, cursorOffset) + value.slice(boundary);
11927
- } else {
11928
- nextValue = value.slice(0, cursorOffset) + value.slice(cursorOffset + 1);
11860
+ if (key.rightArrow && safePage < totalPages - 1) {
11861
+ setPage((p) => p + 1);
11862
+ setSelectedIndex(0);
11863
+ return;
11864
+ }
11865
+ if (key.backspace || key.delete) {
11866
+ setQuery((q) => q.slice(0, -1));
11867
+ setPage(0);
11868
+ setSelectedIndex(0);
11869
+ return;
11870
+ }
11871
+ if (input.length === 1 && !key.ctrl && !key.meta && !key.return && !key.escape) {
11872
+ setQuery((q) => q + input);
11873
+ setPage(0);
11874
+ setSelectedIndex(0);
11875
+ return;
11876
+ }
11877
+ if (input === "q" || key.escape) {
11878
+ onPick(null);
11879
+ return;
11880
+ }
11881
+ });
11882
+ if (sessions.length === 0) {
11883
+ return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
11884
+ /* @__PURE__ */ jsx11(Text10, { color: theme.accent, bold: true, children: "Resume a session" }),
11885
+ /* @__PURE__ */ jsx11(Text10, { color: theme.info.color, children: "No saved sessions yet. Press Enter to dismiss." }),
11886
+ /* @__PURE__ */ jsx11(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx11(
11887
+ SelectInput2,
11888
+ {
11889
+ items: [{ label: "(back)", value: "__cancel__" }],
11890
+ onSelect: () => onPick(null)
11929
11891
  }
11930
- } else if (key.ctrl && input === "w") {
11931
- didDelete = true;
11932
- const boundary = findWordBoundaryBackward(value, cursorOffset);
11933
- nextValue = value.slice(0, boundary) + value.slice(cursorOffset);
11934
- nextCursor = boundary;
11935
- } else if (key.ctrl && input === "u") {
11936
- didDelete = true;
11937
- nextValue = value.slice(cursorOffset);
11938
- nextCursor = 0;
11939
- } else if (key.ctrl && input === "k") {
11940
- didDelete = true;
11941
- nextValue = value.slice(0, cursorOffset);
11942
- } else if (input.length > 0 && !key.ctrl && !key.meta) {
11943
- let toInsert = input;
11944
- if (enablePaste && shouldTreatAsPaste(input)) {
11945
- const lines = countLines(input);
11946
- const id = newPasteId();
11947
- const placeholder = `[pasted ${lines} line${lines === 1 ? "" : "s"} #${id}]`;
11948
- pastesRef.current.set(placeholder, input);
11949
- toInsert = placeholder;
11892
+ ) })
11893
+ ] });
11894
+ }
11895
+ const items = pageSessions.map((s) => ({
11896
+ label: `${formatDate(s.updatedAt)} \xB7 ${s.messageCount} msgs \xB7 ${s.title ?? s.firstPrompt}`,
11897
+ value: s.id
11898
+ }));
11899
+ return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
11900
+ /* @__PURE__ */ jsx11(Text10, { color: theme.accent, bold: true, children: "Resume a session" }),
11901
+ /* @__PURE__ */ jsxs9(Text10, { color: theme.info.color, children: [
11902
+ query ? `Search: ${query}\u258C` : "Type to search\u2026",
11903
+ " \xB7 Page ",
11904
+ safePage + 1,
11905
+ " of ",
11906
+ totalPages,
11907
+ " (",
11908
+ filtered.length,
11909
+ " total)"
11910
+ ] }),
11911
+ /* @__PURE__ */ jsx11(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx11(
11912
+ SelectInput2,
11913
+ {
11914
+ items,
11915
+ initialIndex: selectedIndex,
11916
+ onHighlight: (item) => {
11917
+ const idx = items.findIndex((i) => i.value === item.value);
11918
+ if (idx >= 0) setSelectedIndex(idx);
11919
+ },
11920
+ onSelect: (item) => {
11921
+ const picked = sessions.find((s) => s.id === item.value) ?? null;
11922
+ onPick(picked);
11950
11923
  }
11951
- nextValue = value.slice(0, cursorOffset) + toInsert + value.slice(cursorOffset);
11952
- nextCursor = cursorOffset + toInsert.length;
11953
- }
11954
- if (nextCursor < 0) nextCursor = 0;
11955
- if (nextCursor > nextValue.length) nextCursor = nextValue.length;
11956
- if (didDelete && nextValue === "" && value !== "") {
11957
- onClearQueueItem?.(value);
11958
- }
11959
- if (nextCursor !== cursorOffset) {
11960
- setCursorOffset(nextCursor);
11961
- }
11962
- if (nextValue !== value) {
11963
- onChange(nextValue);
11964
11924
  }
11925
+ ) }),
11926
+ /* @__PURE__ */ jsx11(Box9, { marginTop: 1, children: /* @__PURE__ */ jsxs9(Text10, { color: theme.info.color, children: [
11927
+ safePage > 0 ? "\u2190 prev " : "",
11928
+ safePage < totalPages - 1 ? "\u2192 next " : "",
11929
+ "q: cancel"
11930
+ ] }) })
11931
+ ] });
11932
+ }
11933
+ function formatDate(iso) {
11934
+ try {
11935
+ const d = new Date(iso);
11936
+ return d.toLocaleString(void 0, {
11937
+ month: "short",
11938
+ day: "numeric",
11939
+ hour: "2-digit",
11940
+ minute: "2-digit"
11941
+ });
11942
+ } catch {
11943
+ return iso;
11944
+ }
11945
+ }
11946
+ var PAGE_SIZE;
11947
+ var init_resume_picker = __esm({
11948
+ "src/ui/resume-picker.tsx"() {
11949
+ "use strict";
11950
+ init_fuzzy();
11951
+ init_theme_context();
11952
+ PAGE_SIZE = 5;
11953
+ }
11954
+ });
11955
+
11956
+ // src/ui/checkpoint-picker.tsx
11957
+ import { useState as useState6 } from "react";
11958
+ import { Box as Box10, Text as Text11, useInput as useInput4 } from "ink";
11959
+ import SelectInput3 from "ink-select-input";
11960
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
11961
+ function CheckpointPicker({ session, checkpoints, onPick }) {
11962
+ const theme = useTheme();
11963
+ const [selectedIndex, setSelectedIndex] = useState6(0);
11964
+ useInput4((input, key) => {
11965
+ if (input === "q" || key.escape) {
11966
+ onPick(null);
11967
+ return;
11968
+ }
11969
+ });
11970
+ const items = [
11971
+ {
11972
+ label: `Resume from beginning (${session.messageCount} msgs)`,
11973
+ value: "__start__"
11965
11974
  },
11966
- { isActive: focus }
11967
- );
11968
- const displayValue = mask ? mask.repeat(value.length) : value;
11969
- let renderedValue = "";
11970
- let i = 0;
11971
- for (const char of displayValue) {
11972
- renderedValue += i === cursorOffset ? source_default.inverse(char) : char;
11973
- i++;
11975
+ ...checkpoints.map((cp) => ({
11976
+ label: `Resume from: "${cp.label}" \u2014 turn ${cp.turnIndex} \xB7 ${formatDate2(cp.timestamp)}`,
11977
+ value: cp.id
11978
+ }))
11979
+ ];
11980
+ return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
11981
+ /* @__PURE__ */ jsx12(Text11, { color: theme.accent, bold: true, children: session.firstPrompt.slice(0, 50) }),
11982
+ /* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
11983
+ session.messageCount,
11984
+ " turns \xB7 ",
11985
+ checkpoints.length,
11986
+ " checkpoint",
11987
+ checkpoints.length === 1 ? "" : "s"
11988
+ ] }),
11989
+ /* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(
11990
+ SelectInput3,
11991
+ {
11992
+ items,
11993
+ initialIndex: selectedIndex,
11994
+ onHighlight: (item) => {
11995
+ const idx = items.findIndex((i) => i.value === item.value);
11996
+ if (idx >= 0) setSelectedIndex(idx);
11997
+ },
11998
+ onSelect: (item) => {
11999
+ if (item.value === "__start__") {
12000
+ onPick("__start__");
12001
+ } else {
12002
+ onPick(item.value);
12003
+ }
12004
+ }
12005
+ }
12006
+ ) }),
12007
+ /* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text11, { color: theme.info.color, children: "q: cancel / go back" }) })
12008
+ ] });
12009
+ }
12010
+ function formatDate2(iso) {
12011
+ try {
12012
+ const d = new Date(iso);
12013
+ return d.toLocaleString(void 0, {
12014
+ month: "short",
12015
+ day: "numeric",
12016
+ hour: "2-digit",
12017
+ minute: "2-digit"
12018
+ });
12019
+ } catch {
12020
+ return iso;
11974
12021
  }
11975
- if (displayValue.length === 0) {
11976
- renderedValue = source_default.inverse(" ");
11977
- } else if (cursorOffset === displayValue.length) {
11978
- renderedValue += source_default.inverse(" ");
12022
+ }
12023
+ var init_checkpoint_picker = __esm({
12024
+ "src/ui/checkpoint-picker.tsx"() {
12025
+ "use strict";
12026
+ init_theme_context();
11979
12027
  }
11980
- return /* @__PURE__ */ jsx13(Text12, { children: renderedValue });
12028
+ });
12029
+
12030
+ // src/ui/task-list.tsx
12031
+ import { useEffect as useEffect4, useRef as useRef2, useState as useState7 } from "react";
12032
+ import { Box as Box11, Text as Text12 } from "ink";
12033
+ import Spinner4 from "ink-spinner";
12034
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
12035
+ function TaskList({ tasks, startedAt, tokensDelta }) {
12036
+ const theme = useTheme();
12037
+ const [now2, setNow] = useState7(Date.now());
12038
+ const [celebrating, setCelebrating] = useState7(false);
12039
+ const tasksRef = useRef2(tasks);
12040
+ const prevAllDoneRef = useRef2(false);
12041
+ tasksRef.current = tasks;
12042
+ useEffect4(() => {
12043
+ if (startedAt === null) return;
12044
+ const id = setInterval(() => {
12045
+ setNow(Date.now());
12046
+ const current = tasksRef.current;
12047
+ if (current.length > 0 && current.every((t) => t.status === "completed")) {
12048
+ clearInterval(id);
12049
+ }
12050
+ }, 1e3);
12051
+ return () => clearInterval(id);
12052
+ }, [startedAt]);
12053
+ useEffect4(() => {
12054
+ const allDone2 = tasks.length > 0 && tasks.every((t) => t.status === "completed");
12055
+ if (allDone2 && !prevAllDoneRef.current) {
12056
+ setCelebrating(true);
12057
+ const id = setTimeout(() => setCelebrating(false), 1500);
12058
+ return () => clearTimeout(id);
12059
+ }
12060
+ prevAllDoneRef.current = allDone2;
12061
+ }, [tasks]);
12062
+ if (tasks.length === 0) return null;
12063
+ const active = tasks.find((t) => t.status === "in_progress");
12064
+ const done = tasks.filter((t) => t.status === "completed").length;
12065
+ const total = tasks.length;
12066
+ const allDone = done === total;
12067
+ const header = active ? active.title : allDone ? `${total} tasks done` : `${done}/${total}`;
12068
+ const elapsed = startedAt ? formatElapsed3(now2 - startedAt) : null;
12069
+ const headerStats = [elapsed, tokensDelta > 0 ? `\u2191 ${formatTokens3(tokensDelta)} tokens` : null].filter(Boolean).join(" \xB7 ");
12070
+ const visibleTasks = tasks.slice(0, MAX_VISIBLE);
12071
+ const hiddenPending = Math.max(0, tasks.length - visibleTasks.length);
12072
+ return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", marginBottom: 1, children: [
12073
+ /* @__PURE__ */ jsxs11(Box11, { children: [
12074
+ /* @__PURE__ */ jsx13(Text12, { color: celebrating ? theme.palette.success : allDone ? "green" : theme.accent, bold: true, children: celebrating ? `\u2728 ${header}` : header }),
12075
+ headerStats && /* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
12076
+ " ",
12077
+ "(",
12078
+ headerStats,
12079
+ ")"
12080
+ ] })
12081
+ ] }),
12082
+ visibleTasks.map((t) => /* @__PURE__ */ jsx13(TaskRow, { task: t }, t.id)),
12083
+ hiddenPending > 0 && /* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
12084
+ " ",
12085
+ "\u2026 +",
12086
+ hiddenPending,
12087
+ " more"
12088
+ ] })
12089
+ ] });
11981
12090
  }
11982
- function findPasteTokenEndingAt(value, pos, pastes) {
11983
- if (pos <= 0 || value[pos - 1] !== "]") return -1;
11984
- for (const placeholder of pastes.keys()) {
11985
- if (placeholder.length > pos) continue;
11986
- const start = pos - placeholder.length;
11987
- if (value.slice(start, pos) === placeholder) return start;
12091
+ function TaskRow({ task }) {
12092
+ const theme = useTheme();
12093
+ if (task.status === "completed") {
12094
+ return /* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
12095
+ " ",
12096
+ "\u2713 ",
12097
+ /* @__PURE__ */ jsx13(Text12, { strikethrough: true, children: task.title })
12098
+ ] });
11988
12099
  }
11989
- return -1;
12100
+ if (task.status === "in_progress") {
12101
+ return /* @__PURE__ */ jsxs11(Text12, { color: theme.accent, bold: true, children: [
12102
+ " ",
12103
+ /* @__PURE__ */ jsx13(Spinner4, { type: "line" }),
12104
+ " ",
12105
+ task.title
12106
+ ] });
12107
+ }
12108
+ return /* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
12109
+ " ",
12110
+ "\u2610 ",
12111
+ task.title
12112
+ ] });
11990
12113
  }
11991
- var PASTE_CHAR_THRESHOLD, PASTE_NEWLINE_THRESHOLD;
11992
- var init_text_input = __esm({
11993
- "src/ui/text-input.tsx"() {
12114
+ function formatElapsed3(ms) {
12115
+ const total = Math.floor(ms / 1e3);
12116
+ const m = Math.floor(total / 60);
12117
+ const s = total % 60;
12118
+ if (m === 0) return `${s}s`;
12119
+ return `${m}m ${s}s`;
12120
+ }
12121
+ function formatTokens3(n) {
12122
+ if (n < 1e3) return String(n);
12123
+ return `${(n / 1e3).toFixed(1)}k`;
12124
+ }
12125
+ var MAX_VISIBLE;
12126
+ var init_task_list = __esm({
12127
+ "src/ui/task-list.tsx"() {
11994
12128
  "use strict";
11995
- init_source();
11996
- PASTE_CHAR_THRESHOLD = 200;
11997
- PASTE_NEWLINE_THRESHOLD = 1;
12129
+ init_theme_context();
12130
+ MAX_VISIBLE = 6;
11998
12131
  }
11999
12132
  });
12000
12133
 
12001
12134
  // src/ui/onboarding.tsx
12002
- import { useState as useState7, useEffect as useEffect5, useCallback } from "react";
12003
- import { Box as Box12, Text as Text13, useInput as useInput4 } from "ink";
12004
- import SelectInput5 from "ink-select-input";
12135
+ import { useState as useState8, useEffect as useEffect5, useCallback as useCallback2 } from "react";
12136
+ import { Box as Box12, Text as Text13, useInput as useInput5 } from "ink";
12137
+ import SelectInput4 from "ink-select-input";
12005
12138
  import Spinner5 from "ink-spinner";
12006
12139
  import { exec } from "child_process";
12007
12140
  import { promisify as promisify2 } from "util";
12008
12141
  import { Fragment, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
12009
12142
  function openBrowser(url) {
12010
- const platform3 = process.platform;
12011
- const cmd = platform3 === "darwin" ? `open "${url}"` : platform3 === "win32" ? `start "" "${url}"` : `xdg-open "${url}"`;
12143
+ const platform4 = process.platform;
12144
+ const cmd = platform4 === "darwin" ? `open "${url}"` : platform4 === "win32" ? `start "" "${url}"` : `xdg-open "${url}"`;
12012
12145
  exec(cmd, (err) => {
12013
12146
  if (err) {
12014
12147
  }
@@ -12022,14 +12155,14 @@ function formatRemaining(ms) {
12022
12155
  }
12023
12156
  function Onboarding({ onDone, onCancel }) {
12024
12157
  const theme = useTheme();
12025
- const [step, setStep] = useState7("mode");
12026
- const [mode, setMode] = useState7("byok");
12027
- const [accountId, setAccountId] = useState7("");
12028
- const [apiToken, setApiToken] = useState7("");
12029
- const [model, setModel] = useState7(DEFAULT_MODEL);
12030
- const [savedPath, setSavedPath] = useState7(null);
12031
- const [cloudAuth, setCloudAuth] = useState7(null);
12032
- const [pollTick, setPollTick] = useState7(0);
12158
+ const [step, setStep] = useState8("mode");
12159
+ const [mode, setMode] = useState8("byok");
12160
+ const [accountId, setAccountId] = useState8("");
12161
+ const [apiToken, setApiToken] = useState8("");
12162
+ const [model, setModel] = useState8(DEFAULT_MODEL);
12163
+ const [savedPath, setSavedPath] = useState8(null);
12164
+ const [cloudAuth, setCloudAuth] = useState8(null);
12165
+ const [pollTick, setPollTick] = useState8(0);
12033
12166
  useEffect5(() => {
12034
12167
  if (step !== "cloudAuth" || !cloudAuth) return;
12035
12168
  if (cloudAuth.phase !== "polling") return;
@@ -12072,8 +12205,8 @@ function Onboarding({ onDone, onCancel }) {
12072
12205
  clearInterval(tick);
12073
12206
  };
12074
12207
  }, [step, cloudAuth]);
12075
- useInput4(
12076
- useCallback(
12208
+ useInput5(
12209
+ useCallback2(
12077
12210
  (_input, key) => {
12078
12211
  if (key.escape && onCancel) {
12079
12212
  onCancel();
@@ -12082,7 +12215,7 @@ function Onboarding({ onDone, onCancel }) {
12082
12215
  [onCancel]
12083
12216
  )
12084
12217
  );
12085
- const startCloudAuth = useCallback(async () => {
12218
+ const startCloudAuth = useCallback2(async () => {
12086
12219
  try {
12087
12220
  const codes = await generateDeviceCodes();
12088
12221
  await registerDevice(codes);
@@ -12179,7 +12312,7 @@ function Onboarding({ onDone, onCancel }) {
12179
12312
  step === "mode" && /* @__PURE__ */ jsxs12(Fragment, { children: [
12180
12313
  /* @__PURE__ */ jsx14(Text13, { children: "How do you want to connect?" }),
12181
12314
  /* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
12182
- SelectInput5,
12315
+ SelectInput4,
12183
12316
  {
12184
12317
  items: [
12185
12318
  { label: "Cloud (managed) \u2014 no API key needed", value: "cloud" },
@@ -12265,7 +12398,7 @@ function Onboarding({ onDone, onCancel }) {
12265
12398
  /* @__PURE__ */ jsx14(Text13, { color: theme.palette.error, children: "Authentication failed" }),
12266
12399
  /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, children: cloudAuth.message }),
12267
12400
  /* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
12268
- SelectInput5,
12401
+ SelectInput4,
12269
12402
  {
12270
12403
  items: [
12271
12404
  { label: "Retry", value: "retry" },
@@ -12544,25 +12677,17 @@ var init_worker_client = __esm({
12544
12677
  }
12545
12678
  });
12546
12679
 
12547
- // src/remote/tui-deploy.ts
12548
- var init_tui_deploy = __esm({
12549
- "src/remote/tui-deploy.ts"() {
12550
- "use strict";
12551
- init_deploy();
12552
- }
12553
- });
12554
-
12555
12680
  // src/ui/remote-dashboard.tsx
12556
- import { useEffect as useEffect6, useState as useState8 } from "react";
12557
- import { Box as Box14, Text as Text15, useInput as useInput5 } from "ink";
12558
- import SelectInput6 from "ink-select-input";
12681
+ import { useEffect as useEffect6, useState as useState9 } from "react";
12682
+ import { Box as Box14, Text as Text15, useInput as useInput6 } from "ink";
12683
+ import SelectInput5 from "ink-select-input";
12559
12684
  import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
12560
12685
  function RemoteDashboard({ onSelect, onCancel }) {
12561
12686
  const theme = useTheme();
12562
- const [sessions, setSessions] = useState8([]);
12563
- const [loading, setLoading] = useState8(true);
12564
- const [error, setError] = useState8(null);
12565
- const [refreshing, setRefreshing] = useState8(false);
12687
+ const [sessions, setSessions] = useState9([]);
12688
+ const [loading, setLoading] = useState9(true);
12689
+ const [error, setError] = useState9(null);
12690
+ const [refreshing, setRefreshing] = useState9(false);
12566
12691
  useEffect6(() => {
12567
12692
  loadSessions();
12568
12693
  }, []);
@@ -12599,7 +12724,7 @@ function RemoteDashboard({ onSelect, onCancel }) {
12599
12724
  setRefreshing(false);
12600
12725
  }
12601
12726
  }
12602
- useInput5((input, key) => {
12727
+ useInput6((input, key) => {
12603
12728
  if (input === "r" || input === "R") {
12604
12729
  void loadSessions();
12605
12730
  }
@@ -12636,7 +12761,7 @@ function RemoteDashboard({ onSelect, onCancel }) {
12636
12761
  refreshing ? "(refreshing...)" : ""
12637
12762
  ] }),
12638
12763
  /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
12639
- SelectInput6,
12764
+ SelectInput5,
12640
12765
  {
12641
12766
  items,
12642
12767
  onSelect: (item) => {
@@ -12677,8 +12802,8 @@ function RemoteSessionDetail({
12677
12802
  onCancel
12678
12803
  }) {
12679
12804
  const theme = useTheme();
12680
- const [cancelling, setCancelling] = useState8(false);
12681
- useInput5((input, key) => {
12805
+ const [cancelling, setCancelling] = useState9(false);
12806
+ useInput6((input, key) => {
12682
12807
  if (key.escape) {
12683
12808
  onBack();
12684
12809
  }
@@ -13575,21 +13700,21 @@ var init_save = __esm({
13575
13700
  });
13576
13701
 
13577
13702
  // src/ui/command-wizard.tsx
13578
- import { useState as useState9 } from "react";
13579
- import { Box as Box15, Text as Text16, useInput as useInput6, useWindowSize } from "ink";
13580
- import SelectInput7 from "ink-select-input";
13703
+ import { useState as useState10 } from "react";
13704
+ import { Box as Box15, Text as Text16, useInput as useInput7, useWindowSize } from "ink";
13705
+ import SelectInput6 from "ink-select-input";
13581
13706
  import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
13582
13707
  function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onSave }) {
13583
13708
  const theme = useTheme();
13584
- const [step, setStep] = useState9("name");
13585
- const [name, setName] = useState9(initial?.name ?? "");
13586
- const [description, setDescription] = useState9(initial?.description ?? "");
13587
- const [template, setTemplate] = useState9(initial?.template ?? "");
13588
- const [cmdMode, setCmdMode] = useState9(initial?.mode);
13589
- const [cmdEffort, setCmdEffort] = useState9(initial?.effort);
13590
- const [cmdModel, setCmdModel] = useState9(initial?.model);
13591
- const [source, setSource] = useState9(initial?.source ?? "project");
13592
- const [error, setError] = useState9(null);
13709
+ const [step, setStep] = useState10("name");
13710
+ const [name, setName] = useState10(initial?.name ?? "");
13711
+ const [description, setDescription] = useState10(initial?.description ?? "");
13712
+ const [template, setTemplate] = useState10(initial?.template ?? "");
13713
+ const [cmdMode, setCmdMode] = useState10(initial?.mode);
13714
+ const [cmdEffort, setCmdEffort] = useState10(initial?.effort);
13715
+ const [cmdModel, setCmdModel] = useState10(initial?.model);
13716
+ const [source, setSource] = useState10(initial?.source ?? "project");
13717
+ const [error, setError] = useState10(null);
13593
13718
  const { columns } = useWindowSize();
13594
13719
  const totalSteps = 5;
13595
13720
  const stepIndex = step === "name" ? 1 : step === "description" ? 2 : step === "template" ? 3 : step === "advanced" || step === "mode" || step === "effort" || step === "model" ? 4 : step === "location" ? 4 : 5;
@@ -13602,7 +13727,7 @@ function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onS
13602
13727
  if (existingNames.includes(trimmed) && !isEditingSelf(trimmed)) return `/${trimmed} already exists`;
13603
13728
  return null;
13604
13729
  };
13605
- useInput6((_input, key) => {
13730
+ useInput7((_input, key) => {
13606
13731
  if (key.escape) {
13607
13732
  onDone();
13608
13733
  }
@@ -13830,7 +13955,7 @@ ${template}`;
13830
13955
  ")"
13831
13956
  ] }),
13832
13957
  /* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(
13833
- SelectInput7,
13958
+ SelectInput6,
13834
13959
  {
13835
13960
  items,
13836
13961
  onSelect: (item) => {
@@ -13859,7 +13984,7 @@ ${template}`;
13859
13984
  ] }),
13860
13985
  /* @__PURE__ */ jsx17(Text16, { color: theme.info.color, children: "Saved to file but not yet enforced at runtime" }),
13861
13986
  /* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(
13862
- SelectInput7,
13987
+ SelectInput6,
13863
13988
  {
13864
13989
  items,
13865
13990
  onSelect: (item) => {
@@ -13887,7 +14012,7 @@ ${template}`;
13887
14012
  ")"
13888
14013
  ] }),
13889
14014
  /* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(
13890
- SelectInput7,
14015
+ SelectInput6,
13891
14016
  {
13892
14017
  items,
13893
14018
  onSelect: (item) => {
@@ -13933,7 +14058,7 @@ ${template}`;
13933
14058
  ")"
13934
14059
  ] }),
13935
14060
  /* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(
13936
- SelectInput7,
14061
+ SelectInput6,
13937
14062
  {
13938
14063
  items,
13939
14064
  onSelect: (item) => {
@@ -13966,7 +14091,7 @@ ${template}`;
13966
14091
  ] }),
13967
14092
  /* @__PURE__ */ jsx17(Box15, { marginTop: 1, flexDirection: "column", children: previewContent().split("\n").map((line, i) => /* @__PURE__ */ jsx17(Text16, { color: theme.info.color, children: line || " " }, i)) }),
13968
14093
  /* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(
13969
- SelectInput7,
14094
+ SelectInput6,
13970
14095
  {
13971
14096
  items,
13972
14097
  onSelect: (item) => handleConfirm(item.value)
@@ -14422,7 +14547,7 @@ var init_context_generator = __esm({
14422
14547
 
14423
14548
  // src/ui/command-picker.tsx
14424
14549
  import { Box as Box16, Text as Text17 } from "ink";
14425
- import SelectInput8 from "ink-select-input";
14550
+ import SelectInput7 from "ink-select-input";
14426
14551
  import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
14427
14552
  function CommandPicker({ commands, title, onPick }) {
14428
14553
  const theme = useTheme();
@@ -14436,7 +14561,7 @@ function CommandPicker({ commands, title, onPick }) {
14436
14561
  /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: title }),
14437
14562
  /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
14438
14563
  /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
14439
- SelectInput8,
14564
+ SelectInput7,
14440
14565
  {
14441
14566
  items,
14442
14567
  onSelect: (item) => {
@@ -14458,11 +14583,11 @@ var init_command_picker = __esm({
14458
14583
  });
14459
14584
 
14460
14585
  // src/ui/command-list.tsx
14461
- import { Box as Box17, Text as Text18, useInput as useInput7 } from "ink";
14586
+ import { Box as Box17, Text as Text18, useInput as useInput8 } from "ink";
14462
14587
  import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
14463
14588
  function CommandList({ commands, onDone }) {
14464
14589
  const theme = useTheme();
14465
- useInput7((_input, key) => {
14590
+ useInput8((_input, key) => {
14466
14591
  if (key.escape) {
14467
14592
  onDone();
14468
14593
  }
@@ -14531,20 +14656,20 @@ var init_command_list = __esm({
14531
14656
  });
14532
14657
 
14533
14658
  // src/ui/lsp-wizard.tsx
14534
- import { useState as useState10 } from "react";
14659
+ import { useState as useState11 } from "react";
14535
14660
  import { Box as Box18, Text as Text19 } from "ink";
14536
- import SelectInput9 from "ink-select-input";
14661
+ import SelectInput8 from "ink-select-input";
14537
14662
  import { spawn as spawn3 } from "child_process";
14538
14663
  import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
14539
14664
  function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
14540
14665
  const theme = useTheme();
14541
- const [page, setPage] = useState10("main");
14542
- const [selectedPreset, setSelectedPreset] = useState10(null);
14543
- const [customName, setCustomName] = useState10("");
14544
- const [customCommand, setCustomCommand] = useState10("");
14545
- const [installState, setInstallState] = useState10({ status: "idle", output: "" });
14546
- const [pendingServers, setPendingServers] = useState10(null);
14547
- const [pendingEnabled, setPendingEnabled] = useState10(true);
14666
+ const [page, setPage] = useState11("main");
14667
+ const [selectedPreset, setSelectedPreset] = useState11(null);
14668
+ const [customName, setCustomName] = useState11("");
14669
+ const [customCommand, setCustomCommand] = useState11("");
14670
+ const [installState, setInstallState] = useState11({ status: "idle", output: "" });
14671
+ const [pendingServers, setPendingServers] = useState11(null);
14672
+ const [pendingEnabled, setPendingEnabled] = useState11(true);
14548
14673
  const runInstall = (command) => {
14549
14674
  setInstallState({ status: "running", output: "Installing..." });
14550
14675
  const child = spawn3("bash", ["-lc", command], {
@@ -14650,7 +14775,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
14650
14775
  /* @__PURE__ */ jsx20(Text19, { color: theme.accent, bold: true, children: "LSP Servers" }),
14651
14776
  /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
14652
14777
  /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
14653
- SelectInput9,
14778
+ SelectInput8,
14654
14779
  {
14655
14780
  items: mainItems,
14656
14781
  onSelect: (item) => {
@@ -14681,7 +14806,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
14681
14806
  /* @__PURE__ */ jsx20(Text19, { color: theme.accent, bold: true, children: "Add LSP Server" }),
14682
14807
  /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, dimColor: false, children: "Select a language server to configure." }),
14683
14808
  /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
14684
- SelectInput9,
14809
+ SelectInput8,
14685
14810
  {
14686
14811
  items,
14687
14812
  onSelect: (item) => {
@@ -14720,7 +14845,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
14720
14845
  ] }),
14721
14846
  installState.output && /* @__PURE__ */ jsx20(Box18, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx20(Text19, { color: isSuccess ? theme.accent : theme.error, children: installState.output.slice(-500) }) }),
14722
14847
  /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
14723
- SelectInput9,
14848
+ SelectInput8,
14724
14849
  {
14725
14850
  items,
14726
14851
  onSelect: (item) => {
@@ -14761,7 +14886,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
14761
14886
  )
14762
14887
  ] }),
14763
14888
  /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
14764
- SelectInput9,
14889
+ SelectInput8,
14765
14890
  {
14766
14891
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
14767
14892
  onSelect: () => setPage("add")
@@ -14790,7 +14915,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
14790
14915
  )
14791
14916
  ] }),
14792
14917
  /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
14793
- SelectInput9,
14918
+ SelectInput8,
14794
14919
  {
14795
14920
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
14796
14921
  onSelect: () => setPage("custom-name")
@@ -14817,7 +14942,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
14817
14942
  /* @__PURE__ */ jsx20(Text19, { color: theme.accent, bold: true, children: "Save LSP Config" }),
14818
14943
  /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, dimColor: false, children: "Where should this server configuration be saved?" }),
14819
14944
  /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
14820
- SelectInput9,
14945
+ SelectInput8,
14821
14946
  {
14822
14947
  items,
14823
14948
  onSelect: (item) => {
@@ -14839,7 +14964,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
14839
14964
  /* @__PURE__ */ jsx20(Text19, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
14840
14965
  /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, children: "No servers configured." }),
14841
14966
  /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
14842
- SelectInput9,
14967
+ SelectInput8,
14843
14968
  {
14844
14969
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
14845
14970
  onSelect: () => setPage("main")
@@ -14863,7 +14988,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
14863
14988
  /* @__PURE__ */ jsx20(Text19, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
14864
14989
  /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, dimColor: false, children: "Select a server to toggle enabled/disabled." }),
14865
14990
  /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
14866
- SelectInput9,
14991
+ SelectInput8,
14867
14992
  {
14868
14993
  items,
14869
14994
  onSelect: (item) => {
@@ -14884,7 +15009,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
14884
15009
  /* @__PURE__ */ jsx20(Text19, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
14885
15010
  /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, children: "No servers configured." }),
14886
15011
  /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
14887
- SelectInput9,
15012
+ SelectInput8,
14888
15013
  {
14889
15014
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
14890
15015
  onSelect: () => setPage("main")
@@ -14904,7 +15029,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
14904
15029
  /* @__PURE__ */ jsx20(Text19, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
14905
15030
  /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, dimColor: false, children: "Select a server to remove from config." }),
14906
15031
  /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
14907
- SelectInput9,
15032
+ SelectInput8,
14908
15033
  {
14909
15034
  items,
14910
15035
  onSelect: (item) => {
@@ -14928,7 +15053,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
14928
15053
  return /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, children: ` ${k.padEnd(16)} ${status} ${s.command.join(" ")}` }, k);
14929
15054
  }) }),
14930
15055
  /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
14931
- SelectInput9,
15056
+ SelectInput8,
14932
15057
  {
14933
15058
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
14934
15059
  onSelect: () => setPage("main")
@@ -15055,7 +15180,7 @@ var init_lsp_wizard = __esm({
15055
15180
 
15056
15181
  // src/ui/theme-picker.tsx
15057
15182
  import { Box as Box19, Text as Text20 } from "ink";
15058
- import SelectInput10 from "ink-select-input";
15183
+ import SelectInput9 from "ink-select-input";
15059
15184
  import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
15060
15185
  function PaletteSwatches({ palette }) {
15061
15186
  const colors = [
@@ -15075,7 +15200,7 @@ function ThemePicker({ themes, onPick }) {
15075
15200
  return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: current.accent, paddingX: 1, children: [
15076
15201
  /* @__PURE__ */ jsx21(Text20, { color: current.accent, bold: true, children: "Pick a theme (restart to apply)" }),
15077
15202
  /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(
15078
- SelectInput10,
15203
+ SelectInput9,
15079
15204
  {
15080
15205
  items,
15081
15206
  onSelect: (item) => {
@@ -16498,15 +16623,15 @@ __export(app_exports, {
16498
16623
  shouldOpenMentionPicker: () => shouldOpenMentionPicker,
16499
16624
  shouldOpenSlashPicker: () => shouldOpenSlashPicker
16500
16625
  });
16501
- import React14, { useState as useState11, useRef as useRef3, useEffect as useEffect7, useCallback as useCallback2 } from "react";
16502
- import { Box as Box22, Text as Text23, useApp, useInput as useInput8, render } from "ink";
16503
- import SelectInput11 from "ink-select-input";
16626
+ import React15, { useState as useState12, useRef as useRef3, useEffect as useEffect7, useCallback as useCallback3 } from "react";
16627
+ import { Box as Box22, Text as Text23, useApp, useInput as useInput9, render } from "ink";
16628
+ import SelectInput10 from "ink-select-input";
16504
16629
  import { existsSync as existsSync4, statSync as statSync4 } from "fs";
16505
16630
  import { join as join27 } from "path";
16506
16631
  import { unlink as unlink4 } from "fs/promises";
16507
16632
  import { execSync as execSync2 } from "child_process";
16508
16633
  import { spawn as spawn4 } from "child_process";
16509
- import { platform as platform2 } from "os";
16634
+ import { platform as platform3 } from "os";
16510
16635
  import fg4 from "fast-glob";
16511
16636
  import { readFileSync as readFileSync3 } from "fs";
16512
16637
  import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
@@ -16649,7 +16774,7 @@ function gatewayUsageLookupFromConfig(cfg, meta) {
16649
16774
  };
16650
16775
  }
16651
16776
  function openBrowser2(url) {
16652
- const cmd = platform2() === "darwin" ? "open" : platform2() === "win32" ? "start" : "xdg-open";
16777
+ const cmd = platform3() === "darwin" ? "open" : platform3() === "win32" ? "start" : "xdg-open";
16653
16778
  const child = spawn4(cmd, [url], { detached: true, stdio: "ignore" });
16654
16779
  child.unref();
16655
16780
  }
@@ -16758,13 +16883,13 @@ function App({
16758
16883
  initialCloudDeviceId
16759
16884
  }) {
16760
16885
  const { exit } = useApp();
16761
- const [cfg, setCfg] = useState11(initialCfg);
16762
- const [lspScope, setLspScope] = useState11(initialLspScope);
16763
- const [lspProjectPath, setLspProjectPath] = useState11(initialLspProjectPath);
16764
- const [cloudToken, setCloudToken] = useState11(initialCloudToken);
16765
- const [cloudDeviceId, setCloudDeviceId] = useState11(initialCloudDeviceId);
16766
- const [events, setRawEvents] = useState11([]);
16767
- const setEvents = useCallback2(
16886
+ const [cfg, setCfg] = useState12(initialCfg);
16887
+ const [lspScope, setLspScope] = useState12(initialLspScope);
16888
+ const [lspProjectPath, setLspProjectPath] = useState12(initialLspProjectPath);
16889
+ const [cloudToken, setCloudToken] = useState12(initialCloudToken);
16890
+ const [cloudDeviceId, setCloudDeviceId] = useState12(initialCloudDeviceId);
16891
+ const [events, setRawEvents] = useState12([]);
16892
+ const setEvents = useCallback3(
16768
16893
  (updater) => {
16769
16894
  setRawEvents((prev) => {
16770
16895
  const next = typeof updater === "function" ? updater(prev) : updater;
@@ -16773,55 +16898,55 @@ function App({
16773
16898
  },
16774
16899
  []
16775
16900
  );
16776
- const [input, setInput] = useState11("");
16777
- const [busy, setBusy] = useState11(false);
16778
- const [usage, setUsage] = useState11(null);
16779
- const [sessionUsage, setSessionUsage] = useState11(null);
16780
- const [gatewayMeta, setGatewayMeta] = useState11(null);
16781
- const [cloudBudget, setCloudBudget] = useState11(null);
16782
- const [showReasoning, setShowReasoning] = useState11(false);
16783
- const [perm, setPerm] = useState11(null);
16784
- const [limitModal, setLimitModal] = useState11(null);
16785
- const [queue, setQueue] = useState11([]);
16786
- const [history, setHistory] = useState11([]);
16787
- const [historyIndex, setHistoryIndex] = useState11(-1);
16788
- const [draftInput, setDraftInput] = useState11("");
16789
- const [mode, setMode] = useState11("edit");
16790
- const [codeMode, setCodeMode] = useState11(false);
16901
+ const [input, setInput] = useState12("");
16902
+ const [busy, setBusy] = useState12(false);
16903
+ const [usage, setUsage] = useState12(null);
16904
+ const [sessionUsage, setSessionUsage] = useState12(null);
16905
+ const [gatewayMeta, setGatewayMeta] = useState12(null);
16906
+ const [cloudBudget, setCloudBudget] = useState12(null);
16907
+ const [showReasoning, setShowReasoning] = useState12(false);
16908
+ const [perm, setPerm] = useState12(null);
16909
+ const [limitModal, setLimitModal] = useState12(null);
16910
+ const [queue, setQueue] = useState12([]);
16911
+ const [history, setHistory] = useState12([]);
16912
+ const [historyIndex, setHistoryIndex] = useState12(-1);
16913
+ const [draftInput, setDraftInput] = useState12("");
16914
+ const [mode, setMode] = useState12("edit");
16915
+ const [codeMode, setCodeMode] = useState12(false);
16791
16916
  const filePickerEnabled = initialCfg?.filePicker ?? true;
16792
- const [effort, setEffort] = useState11(
16917
+ const [effort, setEffort] = useState12(
16793
16918
  initialCfg?.reasoningEffort ?? DEFAULT_REASONING_EFFORT
16794
16919
  );
16795
- const [resumeSessions, setResumeSessions] = useState11(null);
16796
- const [checkpointSession, setCheckpointSession] = useState11(null);
16797
- const [checkpointList, setCheckpointList] = useState11([]);
16798
- const [commandWizard, setCommandWizard] = useState11(null);
16799
- const [commandPicker, setCommandPicker] = useState11(null);
16800
- const [commandToDelete, setCommandToDelete] = useState11(null);
16801
- const [showCommandList, setShowCommandList] = useState11(false);
16802
- const [showLspWizard, setShowLspWizard] = useState11(false);
16803
- const [showRemoteDashboard, setShowRemoteDashboard] = useState11(false);
16804
- const [selectedRemoteSession, setSelectedRemoteSession] = useState11(null);
16805
- const [tasks, setTasks] = useState11([]);
16806
- const [tasksStartedAt, setTasksStartedAt] = useState11(null);
16807
- const [tasksStartTokens, setTasksStartTokens] = useState11(0);
16808
- const [turnStartedAt, setTurnStartedAt] = useState11(null);
16809
- const [turnPhase, setTurnPhase] = useState11("waiting");
16810
- const [currentToolName, setCurrentToolName] = useState11(null);
16811
- const [lastActivityAt, setLastActivityAt] = useState11(null);
16812
- const [verbose, setVerbose] = useState11(false);
16813
- const [hasUpdate, setHasUpdate] = useState11(initialUpdateResult?.hasUpdate ?? false);
16814
- const [latestVersion, setLatestVersion] = useState11(initialUpdateResult?.latestVersion ?? null);
16815
- const [theme, setTheme] = useState11(resolveTheme(initialCfg?.theme));
16816
- const [showThemePicker, setShowThemePicker] = useState11(false);
16817
- const [originalTheme, setOriginalTheme] = useState11(null);
16818
- const [skillsActive, setSkillsActive] = useState11(0);
16819
- const [memoryRecalled, setMemoryRecalled] = useState11(false);
16820
- const [intentTier, setIntentTier] = useState11(null);
16920
+ const [resumeSessions, setResumeSessions] = useState12(null);
16921
+ const [checkpointSession, setCheckpointSession] = useState12(null);
16922
+ const [checkpointList, setCheckpointList] = useState12([]);
16923
+ const [commandWizard, setCommandWizard] = useState12(null);
16924
+ const [commandPicker, setCommandPicker] = useState12(null);
16925
+ const [commandToDelete, setCommandToDelete] = useState12(null);
16926
+ const [showCommandList, setShowCommandList] = useState12(false);
16927
+ const [showLspWizard, setShowLspWizard] = useState12(false);
16928
+ const [showRemoteDashboard, setShowRemoteDashboard] = useState12(false);
16929
+ const [selectedRemoteSession, setSelectedRemoteSession] = useState12(null);
16930
+ const [tasks, setTasks] = useState12([]);
16931
+ const [tasksStartedAt, setTasksStartedAt] = useState12(null);
16932
+ const [tasksStartTokens, setTasksStartTokens] = useState12(0);
16933
+ const [turnStartedAt, setTurnStartedAt] = useState12(null);
16934
+ const [turnPhase, setTurnPhase] = useState12("waiting");
16935
+ const [currentToolName, setCurrentToolName] = useState12(null);
16936
+ const [lastActivityAt, setLastActivityAt] = useState12(null);
16937
+ const [verbose, setVerbose] = useState12(false);
16938
+ const [hasUpdate, setHasUpdate] = useState12(initialUpdateResult?.hasUpdate ?? false);
16939
+ const [latestVersion, setLatestVersion] = useState12(initialUpdateResult?.latestVersion ?? null);
16940
+ const [theme, setTheme] = useState12(resolveTheme(initialCfg?.theme));
16941
+ const [showThemePicker, setShowThemePicker] = useState12(false);
16942
+ const [originalTheme, setOriginalTheme] = useState12(null);
16943
+ const [skillsActive, setSkillsActive] = useState12(0);
16944
+ const [memoryRecalled, setMemoryRecalled] = useState12(false);
16945
+ const [intentTier, setIntentTier] = useState12(null);
16821
16946
  const skillsDirRef = useRef3(join27(process.cwd(), ".kimiflare", "skills"));
16822
- const [kimiMdStale, setKimiMdStale] = useState11(false);
16823
- const [gitBranch, setGitBranch] = useState11(null);
16824
- const [lastSessionTopic, setLastSessionTopic] = useState11(null);
16947
+ const [kimiMdStale, setKimiMdStale] = useState12(false);
16948
+ const [gitBranch, setGitBranch] = useState12(null);
16949
+ const [lastSessionTopic, setLastSessionTopic] = useState12(null);
16825
16950
  useEffect7(() => {
16826
16951
  setGitBranch(detectGitBranch());
16827
16952
  }, []);
@@ -16886,11 +17011,11 @@ ${wcagWarnings.join("\n")}` }
16886
17011
  cancelled = true;
16887
17012
  };
16888
17013
  }, [cfg?.cloudMode, initialCloudToken]);
16889
- const [cursorOffset, setCursorOffset] = useState11(0);
16890
- const [activePicker, setActivePicker] = useState11(null);
16891
- const [filePickerItems, setFilePickerItems] = useState11([]);
17014
+ const [cursorOffset, setCursorOffset] = useState12(0);
17015
+ const [activePicker, setActivePicker] = useState12(null);
17016
+ const [filePickerItems, setFilePickerItems] = useState12([]);
16892
17017
  const filePickerLoadedRef = useRef3(false);
16893
- const [customCommandsVersion, setCustomCommandsVersion] = useState11(0);
17018
+ const [customCommandsVersion, setCustomCommandsVersion] = useState12(0);
16894
17019
  const cacheStableRef = useRef3(initialCfg?.cacheStablePrompts !== false);
16895
17020
  const messagesRef = useRef3(
16896
17021
  makePrefixMessages(cacheStableRef.current, cfg?.model ?? DEFAULT_MODEL, "edit", ALL_TOOLS)
@@ -16941,11 +17066,11 @@ ${wcagWarnings.join("\n")}` }
16941
17066
  const MAX_RECENT_FILES = 10;
16942
17067
  const pickerAnchor = activePicker?.anchor ?? null;
16943
17068
  const pickerKind = activePicker?.kind ?? null;
16944
- const pickerQuery = React14.useMemo(() => {
17069
+ const pickerQuery = React15.useMemo(() => {
16945
17070
  if (pickerAnchor === null) return null;
16946
17071
  return input.slice(pickerAnchor + 1, cursorOffset);
16947
17072
  }, [input, cursorOffset, pickerAnchor]);
16948
- const filteredFileItems = React14.useMemo(() => {
17073
+ const filteredFileItems = React15.useMemo(() => {
16949
17074
  if (pickerKind !== "file" || pickerQuery === null) return [];
16950
17075
  const items = filterPickerItems(filePickerItems, pickerQuery).slice();
16951
17076
  const now2 = Date.now();
@@ -16960,7 +17085,7 @@ ${wcagWarnings.join("\n")}` }
16960
17085
  return a.name.localeCompare(b.name);
16961
17086
  });
16962
17087
  }, [pickerKind, filePickerItems, pickerQuery]);
16963
- const allSlashCommands = React14.useMemo(() => {
17088
+ const allSlashCommands = React15.useMemo(() => {
16964
17089
  const customs = customCommandsRef.current.filter((c) => !BUILTIN_COMMAND_NAMES.has(c.name.toLowerCase())).map((c) => ({
16965
17090
  name: c.name,
16966
17091
  description: c.description ?? "",
@@ -16968,7 +17093,7 @@ ${wcagWarnings.join("\n")}` }
16968
17093
  }));
16969
17094
  return [...BUILTIN_COMMANDS, ...customs];
16970
17095
  }, [customCommandsVersion]);
16971
- const filteredSlashItems = React14.useMemo(() => {
17096
+ const filteredSlashItems = React15.useMemo(() => {
16972
17097
  if (pickerKind !== "slash" || pickerQuery === null) return [];
16973
17098
  return fuzzyFilter(allSlashCommands, pickerQuery, (c) => c.name).slice(0, 50);
16974
17099
  }, [pickerKind, allSlashCommands, pickerQuery]);
@@ -17043,14 +17168,14 @@ ${wcagWarnings.join("\n")}` }
17043
17168
  setActivePicker({ ...activePicker, selected: max });
17044
17169
  }
17045
17170
  }, [filteredSlashItems.length, activePicker]);
17046
- const handlePickerUp = useCallback2(() => {
17171
+ const handlePickerUp = useCallback3(() => {
17047
17172
  setActivePicker((p) => {
17048
17173
  if (!p) return null;
17049
17174
  const next = Math.max(0, p.selected - 1);
17050
17175
  return next === p.selected ? p : { ...p, selected: next };
17051
17176
  });
17052
17177
  }, []);
17053
- const handlePickerDown = useCallback2(() => {
17178
+ const handlePickerDown = useCallback3(() => {
17054
17179
  setActivePicker((p) => {
17055
17180
  if (!p) return null;
17056
17181
  const max = p.kind === "file" ? Math.max(0, filteredFileItems.length - 1) : Math.max(0, filteredSlashItems.length - 1);
@@ -17058,7 +17183,7 @@ ${wcagWarnings.join("\n")}` }
17058
17183
  return next === p.selected ? p : { ...p, selected: next };
17059
17184
  });
17060
17185
  }, [filteredFileItems.length, filteredSlashItems.length]);
17061
- const handlePickerSelect = useCallback2(() => {
17186
+ const handlePickerSelect = useCallback3(() => {
17062
17187
  if (!activePicker) return;
17063
17188
  if (activePicker.kind === "file") {
17064
17189
  const item2 = filteredFileItems[activePicker.selected];
@@ -17077,7 +17202,7 @@ ${wcagWarnings.join("\n")}` }
17077
17202
  setActivePicker(null);
17078
17203
  submitRef.current(value);
17079
17204
  }, [activePicker, filteredFileItems, filteredSlashItems, input, cursorOffset]);
17080
- const handlePickerCancel = useCallback2(() => {
17205
+ const handlePickerCancel = useCallback3(() => {
17081
17206
  pickerCancelRef.current = cursorOffset;
17082
17207
  setActivePicker(null);
17083
17208
  }, [cursorOffset]);
@@ -17208,7 +17333,7 @@ ${wcagWarnings.join("\n")}` }
17208
17333
  }, 3e5);
17209
17334
  return () => clearInterval(id);
17210
17335
  }, []);
17211
- const reloadCustomCommands = useCallback2(async () => {
17336
+ const reloadCustomCommands = useCallback3(async () => {
17212
17337
  const { commands, warnings } = await loadCustomCommands(process.cwd());
17213
17338
  customCommandsRef.current = commands;
17214
17339
  setCustomCommandsVersion((v) => v + 1);
@@ -17335,7 +17460,7 @@ ${wcagWarnings.join("\n")}` }
17335
17460
  }, 30 * 60 * 1e3);
17336
17461
  return () => clearInterval(id);
17337
17462
  }, [cfg]);
17338
- const initMcp = useCallback2(async () => {
17463
+ const initMcp = useCallback3(async () => {
17339
17464
  if (!cfg?.mcpServers || mcpInitRef.current) return;
17340
17465
  mcpInitRef.current = true;
17341
17466
  const manager = mcpManagerRef.current;
@@ -17396,7 +17521,7 @@ ${wcagWarnings.join("\n")}` }
17396
17521
  ]);
17397
17522
  }
17398
17523
  }, [cfg]);
17399
- const initLsp = useCallback2(async () => {
17524
+ const initLsp = useCallback3(async () => {
17400
17525
  if (!cfg?.lspEnabled || !cfg?.lspServers || lspInitRef.current) {
17401
17526
  if (lspInitRef.current) return;
17402
17527
  if (!cfg?.lspEnabled) {
@@ -17467,7 +17592,7 @@ ${wcagWarnings.join("\n")}` }
17467
17592
  void initLsp();
17468
17593
  }
17469
17594
  }, [cfg, initMcp, initLsp]);
17470
- const ensureSessionId = useCallback2(() => {
17595
+ const ensureSessionId = useCallback3(() => {
17471
17596
  if (sessionIdRef.current) return sessionIdRef.current;
17472
17597
  const firstUser = messagesRef.current.find((m) => m.role === "user");
17473
17598
  let firstText = "session";
@@ -17480,7 +17605,7 @@ ${wcagWarnings.join("\n")}` }
17480
17605
  sessionIdRef.current = makeSessionId(firstText);
17481
17606
  return sessionIdRef.current;
17482
17607
  }, []);
17483
- const saveSessionSafe = useCallback2(async () => {
17608
+ const saveSessionSafe = useCallback3(async () => {
17484
17609
  if (!cfg) return;
17485
17610
  ensureSessionId();
17486
17611
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
@@ -17506,13 +17631,13 @@ ${wcagWarnings.join("\n")}` }
17506
17631
  ]);
17507
17632
  }
17508
17633
  }, [cfg, ensureSessionId]);
17509
- const onIterationEnd = useCallback2(
17634
+ const onIterationEnd = useCallback3(
17510
17635
  async (messages, signal) => {
17511
17636
  if (signal.aborted) return messages;
17512
17637
  if (!shouldCompact({ messages })) return messages;
17513
17638
  if (compiledContextRef.current) {
17514
17639
  const store = artifactStoreRef.current;
17515
- const result = compactMessages({
17640
+ const result = compactMessagesViaArtifacts({
17516
17641
  messages,
17517
17642
  state: sessionStateRef.current,
17518
17643
  store
@@ -17557,7 +17682,7 @@ ${wcagWarnings.join("\n")}` }
17557
17682
  }
17558
17683
  if (cfg && !signal.aborted) {
17559
17684
  try {
17560
- const result = await compactMessages2({
17685
+ const result = await summarizeMessagesViaLlm({
17561
17686
  accountId: cfg.accountId,
17562
17687
  apiToken: cfg.apiToken,
17563
17688
  model: cfg.model,
@@ -17584,7 +17709,7 @@ ${wcagWarnings.join("\n")}` }
17584
17709
  },
17585
17710
  [cfg]
17586
17711
  );
17587
- useInput8((inputChar, key) => {
17712
+ useInput9((inputChar, key) => {
17588
17713
  if (key.ctrl && inputChar === "c") {
17589
17714
  logger.info("input:ctrl+c", {
17590
17715
  busy: busyRef.current,
@@ -17698,7 +17823,7 @@ ${wcagWarnings.join("\n")}` }
17698
17823
  void lspManagerRef.current.stopAll().finally(() => exit());
17699
17824
  }
17700
17825
  };
17701
- const flushAssistantUpdates = useCallback2(() => {
17826
+ const flushAssistantUpdates = useCallback3(() => {
17702
17827
  flushTimeoutRef.current = null;
17703
17828
  const pending = pendingTextRef.current;
17704
17829
  if (pending.size === 0) return;
@@ -17716,7 +17841,7 @@ ${wcagWarnings.join("\n")}` }
17716
17841
  })
17717
17842
  );
17718
17843
  }, []);
17719
- const updateAssistant = useCallback2(
17844
+ const updateAssistant = useCallback3(
17720
17845
  (id, patch) => {
17721
17846
  const result = patch({ text: "", reasoning: "" });
17722
17847
  const assistantResult = result;
@@ -17745,7 +17870,7 @@ ${wcagWarnings.join("\n")}` }
17745
17870
  },
17746
17871
  [flushAssistantUpdates]
17747
17872
  );
17748
- const updateTool = useCallback2(
17873
+ const updateTool = useCallback3(
17749
17874
  (id, patch) => {
17750
17875
  setEvents(
17751
17876
  (evts) => evts.map(
@@ -17755,11 +17880,11 @@ ${wcagWarnings.join("\n")}` }
17755
17880
  },
17756
17881
  []
17757
17882
  );
17758
- const updateGatewayMeta = useCallback2((meta) => {
17883
+ const updateGatewayMeta = useCallback3((meta) => {
17759
17884
  gatewayMetaRef.current = meta;
17760
17885
  setGatewayMeta(meta);
17761
17886
  }, []);
17762
- const runCompact = useCallback2(async () => {
17887
+ const runCompact = useCallback3(async () => {
17763
17888
  if (!cfg) return;
17764
17889
  if (busy) {
17765
17890
  setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "can't compact while model is running" }]);
@@ -17773,7 +17898,7 @@ ${wcagWarnings.join("\n")}` }
17773
17898
  try {
17774
17899
  if (compiledContextRef.current) {
17775
17900
  const store = artifactStoreRef.current;
17776
- const result = compactMessages({
17901
+ const result = compactMessagesViaArtifacts({
17777
17902
  messages: messagesRef.current,
17778
17903
  state: sessionStateRef.current,
17779
17904
  store
@@ -17802,7 +17927,7 @@ ${wcagWarnings.join("\n")}` }
17802
17927
  await saveSessionSafe();
17803
17928
  }
17804
17929
  } else {
17805
- const result = await compactMessages2({
17930
+ const result = await summarizeMessagesViaLlm({
17806
17931
  accountId: cfg.accountId,
17807
17932
  apiToken: cfg.apiToken,
17808
17933
  model: cfg.model,
@@ -17855,11 +17980,11 @@ ${wcagWarnings.join("\n")}` }
17855
17980
  pendingToolCallsRef.current.clear();
17856
17981
  }
17857
17982
  }, [cfg, busy, saveSessionSafe]);
17858
- const openResumePicker = useCallback2(async () => {
17983
+ const openResumePicker = useCallback3(async () => {
17859
17984
  const sessions = await listSessions(200, process.cwd());
17860
17985
  setResumeSessions(sessions);
17861
17986
  }, []);
17862
- const runInit = useCallback2(async () => {
17987
+ const runInit = useCallback3(async () => {
17863
17988
  if (!cfg) return;
17864
17989
  if (busy) {
17865
17990
  setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "can't /init while model is running" }]);
@@ -18132,7 +18257,7 @@ ${wcagWarnings.join("\n")}` }
18132
18257
  pendingToolCallsRef.current.clear();
18133
18258
  }
18134
18259
  }, [cfg, busy, updateAssistant, updateTool, updateGatewayMeta]);
18135
- const handleThemePick = useCallback2(
18260
+ const handleThemePick = useCallback3(
18136
18261
  (picked) => {
18137
18262
  setShowThemePicker(false);
18138
18263
  if (!picked) return;
@@ -18150,7 +18275,7 @@ ${wcagWarnings.join("\n")}` }
18150
18275
  },
18151
18276
  []
18152
18277
  );
18153
- const doResumeSession = useCallback2(
18278
+ const doResumeSession = useCallback3(
18154
18279
  async (filePath, checkpointId) => {
18155
18280
  try {
18156
18281
  const file = checkpointId ? (await loadSessionFromCheckpoint(filePath, checkpointId)).file : await loadSession(filePath);
@@ -18202,7 +18327,7 @@ ${wcagWarnings.join("\n")}` }
18202
18327
  },
18203
18328
  []
18204
18329
  );
18205
- const handleResumePick = useCallback2(
18330
+ const handleResumePick = useCallback3(
18206
18331
  async (picked) => {
18207
18332
  setResumeSessions(null);
18208
18333
  if (!picked) return;
@@ -18224,7 +18349,7 @@ ${wcagWarnings.join("\n")}` }
18224
18349
  },
18225
18350
  [doResumeSession]
18226
18351
  );
18227
- const handleCheckpointPick = useCallback2(
18352
+ const handleCheckpointPick = useCallback3(
18228
18353
  async (checkpointId) => {
18229
18354
  const session = checkpointSession;
18230
18355
  setCheckpointSession(null);
@@ -18243,7 +18368,7 @@ ${wcagWarnings.join("\n")}` }
18243
18368
  },
18244
18369
  [checkpointSession, doResumeSession]
18245
18370
  );
18246
- const handleSlash = useCallback2(
18371
+ const handleSlash = useCallback3(
18247
18372
  (cmd) => {
18248
18373
  const raw = cmd.trim();
18249
18374
  const [head, ...rest] = raw.split(/\s+/);
@@ -19110,7 +19235,7 @@ ${lines.join("\n")}` }]);
19110
19235
  },
19111
19236
  [cfg, exit, usage, theme, mode, openResumePicker, runCompact, runInit, initMcp, setCfg, setShowRemoteDashboard, setSelectedRemoteSession]
19112
19237
  );
19113
- const handleCommandSave = useCallback2(
19238
+ const handleCommandSave = useCallback3(
19114
19239
  async (opts2) => {
19115
19240
  setCommandWizard(null);
19116
19241
  try {
@@ -19132,7 +19257,7 @@ ${lines.join("\n")}` }]);
19132
19257
  },
19133
19258
  [commandWizard, reloadCustomCommands, setEvents]
19134
19259
  );
19135
- const handleCommandDelete = useCallback2(
19260
+ const handleCommandDelete = useCallback3(
19136
19261
  async (cmd) => {
19137
19262
  setCommandToDelete(null);
19138
19263
  try {
@@ -19151,7 +19276,7 @@ ${lines.join("\n")}` }]);
19151
19276
  },
19152
19277
  [reloadCustomCommands, setEvents]
19153
19278
  );
19154
- const processMessage = useCallback2(
19279
+ const processMessage = useCallback3(
19155
19280
  async (text, displayText, opts2) => {
19156
19281
  if (!cfg) return;
19157
19282
  let trimmed = text.trim();
@@ -19537,7 +19662,7 @@ ${lines.join("\n")}` }]);
19537
19662
  if (shouldCompact({ messages: messagesRef.current })) {
19538
19663
  if (compiledContextRef.current) {
19539
19664
  const store = artifactStoreRef.current;
19540
- const result = compactMessages({
19665
+ const result = compactMessagesViaArtifacts({
19541
19666
  messages: messagesRef.current,
19542
19667
  state: sessionStateRef.current,
19543
19668
  store
@@ -19557,7 +19682,7 @@ ${lines.join("\n")}` }]);
19557
19682
  }
19558
19683
  } else {
19559
19684
  try {
19560
- const result = await compactMessages2({
19685
+ const result = await summarizeMessagesViaLlm({
19561
19686
  accountId: cfg.accountId,
19562
19687
  apiToken: cfg.apiToken,
19563
19688
  model: cfg.model,
@@ -19680,7 +19805,7 @@ ${lines.join("\n")}` }]);
19680
19805
  processMessage(next.full, next.display, { queuedKey: next.key });
19681
19806
  }
19682
19807
  }, [busy, queue, processMessage]);
19683
- const submit = useCallback2(
19808
+ const submit = useCallback3(
19684
19809
  (full, display) => {
19685
19810
  const trimmedFull = full.trim();
19686
19811
  if (!trimmedFull) return;
@@ -19881,7 +20006,7 @@ ${lines.join("\n")}` }]);
19881
20006
  ] }),
19882
20007
  /* @__PURE__ */ jsx24(Text23, { color: theme.info.color, children: commandToDelete.filepath }),
19883
20008
  /* @__PURE__ */ jsx24(Box22, { marginTop: 1, children: /* @__PURE__ */ jsx24(
19884
- SelectInput11,
20009
+ SelectInput10,
19885
20010
  {
19886
20011
  items: [
19887
20012
  { label: "Yes, delete", value: "yes", key: "yes" },
@@ -19922,6 +20047,9 @@ ${lines.join("\n")}` }]);
19922
20047
  perm.resolve(d);
19923
20048
  permResolveRef.current = null;
19924
20049
  setPerm(null);
20050
+ },
20051
+ onFeedback: (text) => {
20052
+ submitRef.current(text);
19925
20053
  }
19926
20054
  }
19927
20055
  ) : limitModal ? /* @__PURE__ */ jsx24(
@@ -20070,8 +20198,8 @@ var init_app = __esm({
20070
20198
  init_loop();
20071
20199
  init_supervisor();
20072
20200
  init_system_prompt();
20073
- init_compact();
20074
- init_compaction();
20201
+ init_llm_summarize();
20202
+ init_artifact_compaction();
20075
20203
  init_session_state();
20076
20204
  init_executor();
20077
20205
  init_manager3();
@@ -20095,7 +20223,7 @@ var init_app = __esm({
20095
20223
  init_config();
20096
20224
  init_worker_client();
20097
20225
  init_session_store();
20098
- init_tui_deploy();
20226
+ init_deploy();
20099
20227
  init_tui_auth();
20100
20228
  init_remote_dashboard();
20101
20229
  init_mode();