ys-code-agent 2.0.0 → 2.0.2

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.
@@ -4011,7 +4011,7 @@ var init_config = __esm({
4011
4011
  summarizationThreshold: 50
4012
4012
  },
4013
4013
  logging: {
4014
- level: "info",
4014
+ level: "warn",
4015
4015
  file: (0, import_path.join)((0, import_os.homedir)(), ".ys-code-agent", "logs", "agent.log"),
4016
4016
  maxSize: 10485760,
4017
4017
  maxFiles: 5,
@@ -4250,6 +4250,9 @@ var init_config = __esm({
4250
4250
  });
4251
4251
 
4252
4252
  // src/logger/index.ts
4253
+ function setConsoleSuppressed(v) {
4254
+ consoleSuppressed = v;
4255
+ }
4253
4256
  function getLogger(module2) {
4254
4257
  if (!loggers.has(module2)) {
4255
4258
  loggers.set(module2, new Logger(module2));
@@ -4263,13 +4266,18 @@ function renameSync(oldPath, newPath) {
4263
4266
  } catch {
4264
4267
  }
4265
4268
  }
4269
+ function setAllLevels(level) {
4270
+ for (const logger19 of loggers.values()) {
4271
+ logger19.setLevel(level);
4272
+ }
4273
+ }
4266
4274
  function destroyAll() {
4267
4275
  for (const logger19 of loggers.values()) {
4268
4276
  logger19.destroy();
4269
4277
  }
4270
4278
  loggers.clear();
4271
4279
  }
4272
- var import_fs2, import_path2, LOG_LEVELS, Logger, loggers;
4280
+ var import_fs2, import_path2, LOG_LEVELS, consoleSuppressed, Logger, loggers;
4273
4281
  var init_logger = __esm({
4274
4282
  "src/logger/index.ts"() {
4275
4283
  "use strict";
@@ -4282,6 +4290,7 @@ var init_logger = __esm({
4282
4290
  warn: 2,
4283
4291
  error: 3
4284
4292
  };
4293
+ consoleSuppressed = true;
4285
4294
  Logger = class {
4286
4295
  level;
4287
4296
  filePath;
@@ -4371,7 +4380,7 @@ var init_logger = __esm({
4371
4380
  message,
4372
4381
  data
4373
4382
  };
4374
- if (this.consoleOutput) {
4383
+ if (this.consoleOutput && !consoleSuppressed) {
4375
4384
  const formatted = this.formatLog(entry);
4376
4385
  switch (level) {
4377
4386
  case "error":
@@ -13794,10 +13803,10 @@ var init_phoneOptimizer = __esm({
13794
13803
  return !!(process.env.PREFIX?.includes("termux") || process.env.HOME?.includes("com.termux") || process.env.TERMUX_VERSION);
13795
13804
  },
13796
13805
  get terminalWidth() {
13797
- return process.stdout.columns ?? 80;
13806
+ return Math.max(process.stdout.columns ?? 80, 20);
13798
13807
  },
13799
13808
  get terminalHeight() {
13800
- return process.stdout.rows ?? 24;
13809
+ return Math.max(process.stdout.rows ?? 24, 10);
13801
13810
  },
13802
13811
  get isNarrow() {
13803
13812
  return this.terminalWidth < 60;
@@ -13825,7 +13834,9 @@ var init_phoneOptimizer = __esm({
13825
13834
  return (0, import_os2.homedir)();
13826
13835
  },
13827
13836
  getWelcomeBoxWidth() {
13828
- return Math.min(this.terminalWidth - 4, 56);
13837
+ const raw = this.terminalWidth - 4;
13838
+ const clamped = Math.min(raw, 56);
13839
+ return Math.max(clamped, 20);
13829
13840
  },
13830
13841
  getPopupHeight() {
13831
13842
  if (this.isNarrow) return 6;
@@ -13836,7 +13847,7 @@ var init_phoneOptimizer = __esm({
13836
13847
  return !this.isTermux || !this.lowMemory;
13837
13848
  },
13838
13849
  showCompactWelcome() {
13839
- return this.isNarrow || this.terminalWidth < 50;
13850
+ return this.terminalWidth < 60;
13840
13851
  }
13841
13852
  };
13842
13853
  }
@@ -13988,7 +13999,7 @@ var init_CommandPopup = __esm({
13988
13999
  if (!this.visible) return "";
13989
14000
  const pw = phoneConfig.getPopupHeight();
13990
14001
  const maxHeight = Math.min(pw + 2, process.stdout.rows ? process.stdout.rows - 4 : 12);
13991
- const width = Math.min(process.stdout.columns ? process.stdout.columns - 4 : 60, 60);
14002
+ const width = Math.max(Math.min(process.stdout.columns ? process.stdout.columns - 4 : 60, 60), 10);
13992
14003
  const top = `\u250C\u2500${source_default.cyan(" Commands ")}${"\u2500".repeat(Math.max(0, width - 11))}\u2510`;
13993
14004
  const categorized = this.getCategorizedCommands();
13994
14005
  const lines = [];
@@ -15632,7 +15643,6 @@ init_logger();
15632
15643
  init_source();
15633
15644
  init_logger();
15634
15645
  init_config();
15635
- init_phoneOptimizer();
15636
15646
  init_CommandPopup();
15637
15647
 
15638
15648
  // src/ui/WelcomeScreen.ts
@@ -15640,6 +15650,12 @@ init_source();
15640
15650
  init_config();
15641
15651
  init_phoneOptimizer();
15642
15652
  var animateState = 0;
15653
+ function safeLen(s) {
15654
+ return s.replace(/\x1b\[[0-9;]*m/g, "").length;
15655
+ }
15656
+ function safeRepeat(n) {
15657
+ return n > 0 ? " ".repeat(n) : "";
15658
+ }
15643
15659
  function generateWelcome() {
15644
15660
  if (phoneConfig.showCompactWelcome()) {
15645
15661
  return generateCompactWelcome();
@@ -15657,11 +15673,12 @@ function generateFullWelcome() {
15657
15673
  const diamond = animateState ? "\u25C6" : "\u25C7";
15658
15674
  const lines = [top];
15659
15675
  const titleRaw = ` ${diamond} YS CODE AGENT ${diamond} `;
15660
- const titlePad = Math.floor((w - titleRaw.length) / 2);
15661
- lines.push(`\u2551${" ".repeat(titlePad)}${source_default.cyan(titleRaw)}${" ".repeat(w - titlePad - titleRaw.length)}\u2551`);
15676
+ const titleStyled = source_default.cyan(titleRaw);
15677
+ const titlePad = Math.floor((w - safeLen(titleStyled)) / 2);
15678
+ lines.push(`\u2551${safeRepeat(titlePad)}${titleStyled}${safeRepeat(w - titlePad - safeLen(titleStyled))}\u2551`);
15662
15679
  const subtitle = source_default.gray("AI-Powered Terminal Coding Assistant");
15663
- const subPad = Math.floor((w - subtitle.length) / 2);
15664
- lines.push(`\u2551${" ".repeat(subPad)}${subtitle}${" ".repeat(w - subPad - subtitle.length)}\u2551`);
15680
+ const subPad = Math.floor((w - safeLen(subtitle)) / 2);
15681
+ lines.push(`\u2551${safeRepeat(subPad)}${subtitle}${safeRepeat(w - subPad - safeLen(subtitle))}\u2551`);
15665
15682
  lines.push(`\u2560${"\u2550".repeat(w)}\u2563`);
15666
15683
  const rows = [
15667
15684
  ["Provider", source_default.yellow(provider.name), "Model", source_default.yellow(modelShort)],
@@ -15673,16 +15690,16 @@ function generateFullWelcome() {
15673
15690
  for (const [label1, val1, label2, val2] of rows) {
15674
15691
  const part1 = `\u2551 ${source_default.white(label1)}: ${val1}`;
15675
15692
  const part2 = `${source_default.white(label2)}: ${val2}`;
15676
- const spacing = w - part1.length - part2.length - 1;
15693
+ const spacing = w - safeLen(part1) - safeLen(part2) - 1;
15677
15694
  const spaceStr = spacing > 0 ? " ".repeat(spacing) : " ";
15678
15695
  lines.push(`${part1}${spaceStr}${part2} ${source_default.gray("\u2502")}`);
15679
15696
  }
15680
15697
  lines.push(`\u2560${"\u2550".repeat(w)}\u2563`);
15681
15698
  const tipLine = ` ${source_default.gray("Type")} ${source_default.cyan("/")}${source_default.gray(" for commands")} ${source_default.gray("|")} ${source_default.cyan("?")}${source_default.gray(" for shortcuts")}`;
15682
- const tipPad = Math.floor((w - tipLine.length) / 2);
15683
- lines.push(`\u2551${" ".repeat(tipPad)}${tipLine}${" ".repeat(w - tipPad - tipLine.length)}\u2551`);
15699
+ const tipPad = Math.floor((w - safeLen(tipLine)) / 2);
15700
+ lines.push(`\u2551${safeRepeat(tipPad)}${tipLine}${safeRepeat(w - tipPad - safeLen(tipLine))}\u2551`);
15684
15701
  const projectLine = getProjectLine(w);
15685
- lines.push(`\u2551${projectLine}${" ".repeat(w - projectLine.length)}\u2551`);
15702
+ lines.push(`\u2551${projectLine}${safeRepeat(w - safeLen(projectLine))}\u2551`);
15686
15703
  lines.push(bottom);
15687
15704
  return lines.join("\n");
15688
15705
  }
@@ -15694,10 +15711,10 @@ function generateCompactWelcome() {
15694
15711
  const top = `\u2554${"\u2550".repeat(w)}\u2557`;
15695
15712
  const bottom = `\u255A${"\u2550".repeat(w)}\u255D`;
15696
15713
  const title = `${source_default.cyan("\u25C6 YS AGENT")} ${source_default.yellow(modelShort)}`;
15697
- const titlePad = Math.floor((w - title.length) / 2);
15714
+ const titlePad = Math.max(0, Math.floor((w - safeLen(title)) / 2));
15698
15715
  return [
15699
15716
  top,
15700
- `\u2551${" ".repeat(titlePad)}${title}${" ".repeat(w - titlePad - title.length)}\u2551`,
15717
+ `\u2551${safeRepeat(titlePad)}${title}${safeRepeat(w - titlePad - safeLen(title))}\u2551`,
15701
15718
  `\u2551 ${source_default.gray("Tools:")} ${source_default.green(`${countActiveTools()} Active`)} ${source_default.gray("Mode:")} ${source_default.cyan(getModeString())} \u2551`,
15702
15719
  `\u2551 ${source_default.gray("/ for commands | ? for shortcuts")} \u2551`,
15703
15720
  bottom
@@ -15713,6 +15730,9 @@ function getProjectLine(maxWidth) {
15713
15730
  let line = ` ${source_default.gray("\u{1F4C1}")} ${source_default.white(displayPath)}`;
15714
15731
  if (projectType) line += ` ${source_default.gray(`(${projectType})`)}`;
15715
15732
  if (gitBranch2) line += ` ${source_default.gray("\u2387")} ${source_default.yellow(gitBranch2)}`;
15733
+ if (safeLen(line) > maxWidth) {
15734
+ line = ` ${source_default.gray("\u{1F4C1}")} ${source_default.white(displayPath)}`;
15735
+ }
15716
15736
  return line;
15717
15737
  } catch {
15718
15738
  return "";
@@ -15780,6 +15800,7 @@ function getSessionId() {
15780
15800
  }
15781
15801
 
15782
15802
  // src/ui/index.ts
15803
+ var import_readline = require("readline");
15783
15804
  var logger15 = getLogger("ui");
15784
15805
  var INDICATORS = {
15785
15806
  idle: "\u25CB",
@@ -15803,24 +15824,18 @@ var TUI = class {
15803
15824
  status = "idle";
15804
15825
  approvalMode = "normal";
15805
15826
  agentMode = "chat";
15806
- outputLines = [];
15807
- maxOutputLines = 1e3;
15808
15827
  onInput = null;
15809
- onSpecialKey = null;
15828
+ onCancelRequest = null;
15810
15829
  running = false;
15811
15830
  commandPopup;
15812
- inputBuffer = "";
15813
15831
  inputHistory = [];
15814
15832
  historyIndex = -1;
15815
- cursorPos = 0;
15816
15833
  popupActive = false;
15817
15834
  cancelRequested = false;
15818
- onCancelRequest = null;
15819
- stdinRaw = false;
15835
+ rl = null;
15820
15836
  constructor() {
15821
15837
  this.commandPopup = new CommandPopup();
15822
15838
  this.loadHistory();
15823
- this.setupRawMode();
15824
15839
  }
15825
15840
  loadHistory() {
15826
15841
  try {
@@ -15844,341 +15859,85 @@ var TUI = class {
15844
15859
  } catch {
15845
15860
  }
15846
15861
  }
15847
- setupRawMode() {
15848
- if (!process.stdin.isTTY) return;
15849
- try {
15850
- process.stdin.setRawMode?.(true);
15851
- this.stdinRaw = true;
15852
- } catch {
15853
- this.stdinRaw = false;
15854
- }
15855
- }
15856
15862
  setOnCancelRequest(cb) {
15857
15863
  this.onCancelRequest = cb;
15858
15864
  }
15859
15865
  start() {
15860
15866
  this.running = true;
15861
- this.clear();
15862
- this.printWelcome();
15863
- this.showPrompt();
15864
- this.startKeyListener();
15865
- }
15866
- startKeyListener() {
15867
15867
  if (!process.stdin.isTTY) {
15868
15868
  this.startLineMode();
15869
15869
  return;
15870
15870
  }
15871
- process.stdin.on("data", (data) => {
15872
- if (!this.running) return;
15873
- const input = data.toString("utf-8");
15874
- if (this.popupActive) {
15875
- this.handlePopupKey(input);
15876
- this.renderScreen();
15877
- return;
15878
- }
15879
- if (input === "\x1B" || input === "\x1B[" || input === "\x1B[" && data.length > 2) {
15880
- if (input === "\x1B") {
15881
- if (this.inputBuffer.length === 0) {
15882
- void this.handleSpecialKey("escape");
15883
- } else {
15884
- this.inputBuffer = "";
15885
- this.cursorPos = 0;
15886
- this.renderScreen();
15887
- }
15888
- return;
15871
+ this.startTTYMode();
15872
+ }
15873
+ startTTYMode() {
15874
+ const self = this;
15875
+ this.rl = (0, import_readline.createInterface)({
15876
+ input: process.stdin,
15877
+ output: process.stdout,
15878
+ prompt: "",
15879
+ historySize: 0,
15880
+ removeHistoryDuplicates: true
15881
+ });
15882
+ this.rl.on("line", async (line) => {
15883
+ const trimmed = line.trim();
15884
+ if (trimmed) {
15885
+ this.addHistory(trimmed);
15886
+ if (this.onInput) {
15887
+ await this.onInput(trimmed);
15889
15888
  }
15890
- return;
15891
- }
15892
- if (input === "\x1B[A") {
15893
- void this.handleSpecialKey("up");
15894
- return;
15895
- }
15896
- if (input === "\x1B[B") {
15897
- void this.handleSpecialKey("down");
15898
- return;
15899
- }
15900
- if (input === "\x1B[C") {
15901
- void this.handleSpecialKey("right");
15902
- return;
15903
- }
15904
- if (input === "\x1B[D") {
15905
- void this.handleSpecialKey("left");
15906
- return;
15907
- }
15908
- if (input === "\r" || input === "\n") {
15909
- void this.handleSpecialKey("enter");
15910
- return;
15911
- }
15912
- if (input === "\x7F" || input === "\b") {
15913
- void this.handleSpecialKey("backspace");
15914
- return;
15915
- }
15916
- if (input === "") {
15917
- void this.handleSpecialKey("ctrl_c");
15918
- return;
15919
15889
  }
15920
- if (input === "\f") {
15921
- void this.handleSpecialKey("ctrl_l");
15922
- return;
15923
- }
15924
- if (input === "") {
15925
- void this.handleSpecialKey("ctrl_a");
15926
- return;
15927
- }
15928
- if (input === "") {
15929
- void this.handleSpecialKey("ctrl_e");
15930
- return;
15931
- }
15932
- if (input === "\n" || input === "\r") {
15933
- return;
15934
- }
15935
- if (input === " ") {
15936
- void this.handleSpecialKey("tab");
15937
- return;
15938
- }
15939
- if (input === "") {
15940
- void this.handleSpecialKey("ctrl_o");
15941
- return;
15942
- }
15943
- if (input === "") {
15944
- void this.handleSpecialKey("ctrl_x");
15945
- return;
15946
- }
15947
- this.inputBuffer = this.inputBuffer.slice(0, this.cursorPos) + input + this.inputBuffer.slice(this.cursorPos);
15948
- this.cursorPos += input.length;
15949
- if (input === "/") {
15950
- this.popupActive = true;
15951
- this.commandPopup.open();
15952
- this.commandPopup.setFilter(input);
15890
+ this.showPrompt();
15891
+ });
15892
+ this.rl.on("SIGINT", () => {
15893
+ if (this.cancelRequested || this.status === "thinking" || this.status === "executing") {
15894
+ if (this.onCancelRequest) this.onCancelRequest();
15953
15895
  } else {
15954
- if (this.inputBuffer.startsWith("/") && this.inputBuffer.length > 1) {
15955
- this.popupActive = true;
15956
- this.commandPopup.open();
15957
- this.commandPopup.setFilter(this.inputBuffer);
15958
- }
15896
+ process.stdout.write("\n");
15897
+ this.printLine(source_default.yellow("Use /exit to quit, or press Ctrl+C again to force quit"));
15898
+ this.cancelRequested = true;
15899
+ setTimeout(() => {
15900
+ this.cancelRequested = false;
15901
+ }, 2e3);
15959
15902
  }
15960
- this.renderScreen();
15903
+ this.showPrompt();
15961
15904
  });
15962
- process.stdin.on("end", () => {
15905
+ this.rl.on("close", () => {
15906
+ process.exit(0);
15963
15907
  });
15908
+ this.showPrompt();
15964
15909
  }
15965
15910
  startLineMode() {
15966
- const { createInterface } = require("readline");
15967
- const rl = createInterface({ input: process.stdin, output: process.stdout, prompt: "" });
15911
+ const rl = (0, import_readline.createInterface)({ input: process.stdin, output: process.stdout, prompt: "" });
15968
15912
  rl.on("line", (line) => {
15969
- this.inputBuffer = line.trim();
15970
- if (this.inputBuffer && this.onInput) {
15971
- this.addHistory(this.inputBuffer);
15972
- this.onInput(this.inputBuffer);
15913
+ const trimmed = line.trim();
15914
+ if (trimmed && this.onInput) {
15915
+ this.addHistory(trimmed);
15916
+ this.onInput(trimmed);
15973
15917
  }
15974
- this.inputBuffer = "";
15975
- this.showPrompt();
15918
+ rl.prompt();
15976
15919
  });
15977
15920
  rl.on("SIGINT", () => process.exit(0));
15978
- this.showPrompt();
15979
- }
15980
- handlePopupKey(input) {
15981
- if (input === "\x1B") {
15982
- this.popupActive = false;
15983
- this.commandPopup.close();
15984
- this.inputBuffer = "";
15985
- this.cursorPos = 0;
15986
- return;
15987
- }
15988
- if (input === "\x1B[A" || input === "\x1BOA") {
15989
- this.commandPopup.moveUp();
15990
- return;
15991
- }
15992
- if (input === "\x1B[B" || input === "\x1BOB") {
15993
- this.commandPopup.moveDown();
15994
- return;
15995
- }
15996
- if (input === "\r" || input === "\n") {
15997
- const selectedCmd = this.commandPopup.getSelectedCommand();
15998
- if (selectedCmd) {
15999
- this.popupActive = false;
16000
- this.commandPopup.close();
16001
- const fullCmd = `/${selectedCmd} `;
16002
- this.inputBuffer = fullCmd;
16003
- this.cursorPos = fullCmd.length;
16004
- }
16005
- return;
16006
- }
16007
- if (input === " ") {
16008
- const selectedCmd = this.commandPopup.getSelectedCommand();
16009
- if (selectedCmd) {
16010
- this.popupActive = false;
16011
- this.commandPopup.close();
16012
- const fullCmd = `/${selectedCmd} `;
16013
- this.inputBuffer = fullCmd;
16014
- this.cursorPos = fullCmd.length;
16015
- }
16016
- return;
16017
- }
16018
- if (input === "\x7F" || input === "\b") {
16019
- const currentFilter = this.commandPopup.getFilterText();
16020
- if (currentFilter.length <= 1) {
16021
- this.popupActive = false;
16022
- this.commandPopup.close();
16023
- this.inputBuffer = "";
16024
- this.cursorPos = 0;
16025
- return;
16026
- }
16027
- this.commandPopup.deleteChar();
16028
- return;
16029
- }
16030
- if (input.length === 1 && input.charCodeAt(0) >= 32) {
16031
- this.commandPopup.appendChar(input);
16032
- this.inputBuffer = this.commandPopup.getFilterText();
16033
- this.cursorPos = this.inputBuffer.length;
16034
- }
15921
+ rl.prompt();
16035
15922
  }
16036
- async handleSpecialKey(key) {
16037
- switch (key) {
16038
- case "escape":
16039
- if (this.inputBuffer.length > 0) {
16040
- this.inputBuffer = "";
16041
- this.cursorPos = 0;
16042
- this.renderScreen();
16043
- }
16044
- break;
16045
- case "enter":
16046
- if (this.inputBuffer.trim()) {
16047
- this.addHistory(this.inputBuffer.trim());
16048
- const msg = this.inputBuffer.trim();
16049
- this.inputBuffer = "";
16050
- this.cursorPos = 0;
16051
- this.clearOutputLine();
16052
- if (this.onInput) this.onInput(msg);
16053
- }
16054
- this.renderScreen();
16055
- break;
16056
- case "backspace":
16057
- if (this.cursorPos > 0) {
16058
- this.inputBuffer = this.inputBuffer.slice(0, this.cursorPos - 1) + this.inputBuffer.slice(this.cursorPos);
16059
- this.cursorPos--;
16060
- this.updatePopupFilter();
16061
- }
16062
- this.renderScreen();
16063
- break;
16064
- case "up":
16065
- if (this.inputHistory.length > 0) {
16066
- if (this.historyIndex === -1) {
16067
- this.historyIndex = this.inputHistory.length - 1;
16068
- } else if (this.historyIndex > 0) {
16069
- this.historyIndex--;
16070
- }
16071
- this.inputBuffer = this.inputHistory[this.historyIndex];
16072
- this.cursorPos = this.inputBuffer.length;
16073
- this.renderScreen();
16074
- }
16075
- break;
16076
- case "down":
16077
- if (this.historyIndex >= 0) {
16078
- this.historyIndex++;
16079
- if (this.historyIndex >= this.inputHistory.length) {
16080
- this.historyIndex = -1;
16081
- this.inputBuffer = "";
16082
- } else {
16083
- this.inputBuffer = this.inputHistory[this.historyIndex];
16084
- }
16085
- this.cursorPos = this.inputBuffer.length;
16086
- this.renderScreen();
16087
- }
16088
- break;
16089
- case "left":
16090
- if (this.cursorPos > 0) {
16091
- this.cursorPos--;
16092
- this.renderScreen();
16093
- }
16094
- break;
16095
- case "right":
16096
- if (this.cursorPos < this.inputBuffer.length) {
16097
- this.cursorPos++;
16098
- this.renderScreen();
16099
- }
16100
- break;
16101
- case "ctrl_a":
16102
- this.cursorPos = 0;
16103
- this.renderScreen();
16104
- break;
16105
- case "ctrl_e":
16106
- this.cursorPos = this.inputBuffer.length;
16107
- this.renderScreen();
16108
- break;
16109
- case "ctrl_c":
16110
- if (this.cancelRequested || this.status === "thinking" || this.status === "executing") {
16111
- if (this.onCancelRequest) this.onCancelRequest();
16112
- } else {
16113
- this.printLine("\n" + source_default.yellow("Use /exit to quit, or press Ctrl+C again to force quit"));
16114
- this.cancelRequested = true;
16115
- setTimeout(() => {
16116
- this.cancelRequested = false;
16117
- }, 2e3);
16118
- }
16119
- break;
16120
- case "ctrl_l":
16121
- this.clear();
16122
- this.printWelcome();
16123
- this.showPrompt();
16124
- break;
16125
- case "tab": {
16126
- const match = this.inputBuffer.match(/^\/?(\w*)$/);
16127
- if (match) {
16128
- const partial = match[1].toLowerCase();
16129
- const cmds = this.getAllCommands().filter((c) => c.startsWith(partial));
16130
- if (cmds.length === 1) {
16131
- this.inputBuffer = `/${cmds[0]} `;
16132
- this.cursorPos = this.inputBuffer.length;
16133
- this.renderScreen();
16134
- }
16135
- }
16136
- break;
16137
- }
16138
- case "ctrl_o":
16139
- break;
16140
- case "ctrl_x":
16141
- void this.openExternalEditor();
16142
- break;
16143
- }
16144
- }
16145
- updatePopupFilter() {
16146
- if (this.popupActive) {
16147
- this.commandPopup.setFilter(this.inputBuffer);
16148
- if (this.inputBuffer === "/" || this.inputBuffer === "") {
16149
- this.popupActive = false;
16150
- this.commandPopup.close();
16151
- }
16152
- }
16153
- }
16154
- getAllCommands() {
16155
- const { ALL_COMMANDS: ALL_COMMANDS2 } = (init_CommandPopup(), __toCommonJS(CommandPopup_exports));
16156
- return ALL_COMMANDS2.map((c) => c.command);
15923
+ buildPromptPrefix() {
15924
+ const statusIndicator = STATUS_COLORS[this.status](INDICATORS[this.status]);
15925
+ const config = configManager.getConfig();
15926
+ const model = config.model.model;
15927
+ const modelShort = model.length > 18 ? model.slice(0, 16) + "\u2026" : model;
15928
+ let modeBadge2 = "";
15929
+ if (this.agentMode === "plan") modeBadge2 = source_default.blue(" [plan]");
15930
+ else if (this.agentMode === "goal") modeBadge2 = source_default.magenta(" [goal]");
15931
+ else if (this.agentMode === "arena") modeBadge2 = source_default.yellow(" [arena]");
15932
+ let approvalBadge2 = "";
15933
+ if (this.approvalMode === "safe") approvalBadge2 = source_default.cyan(" [safe]");
15934
+ else if (this.approvalMode === "yolo") approvalBadge2 = source_default.red(" [yolo]");
15935
+ return `${statusIndicator} ${source_default.cyan("ys")} ${source_default.yellow(`[${modelShort}]`)}${modeBadge2}${approvalBadge2} ${source_default.gray("\u203A")} `;
16157
15936
  }
16158
- async openExternalEditor() {
16159
- const editor = process.env.EDITOR || "nano";
16160
- const { writeFileSync: writeFileSync7, unlinkSync: unlinkSync4, existsSync: existsSync11, mkdirSync: mkdirSync7 } = await import("fs");
16161
- const { join: join8 } = await import("path");
16162
- const tmpDir = "/tmp/ys-agent";
16163
- if (!existsSync11(tmpDir)) mkdirSync7(tmpDir, { recursive: true });
16164
- const tmpFile = join8(tmpDir, `input-${Date.now()}.md`);
16165
- writeFileSync7(tmpFile, this.inputBuffer, "utf-8");
16166
- const { execSync: execSync4 } = await import("child_process");
16167
- try {
16168
- execSync4(`${editor} "${tmpFile}"`, { stdio: "inherit" });
16169
- const { readFileSync: readFileSync11 } = await import("fs");
16170
- const content = readFileSync11(tmpFile, "utf-8").trim();
16171
- if (content) {
16172
- this.inputBuffer = content;
16173
- this.cursorPos = content.length;
16174
- this.renderScreen();
16175
- }
16176
- } catch {
16177
- }
16178
- try {
16179
- unlinkSync4(tmpFile);
16180
- } catch {
16181
- }
15937
+ showPrompt() {
15938
+ if (!this.running || !this.rl) return;
15939
+ this.rl.setPrompt(this.buildPromptPrefix());
15940
+ this.rl.prompt(true);
16182
15941
  }
16183
15942
  addHistory(input) {
16184
15943
  if (this.inputHistory[this.inputHistory.length - 1] !== input) {
@@ -16187,52 +15946,68 @@ var TUI = class {
16187
15946
  this.historyIndex = -1;
16188
15947
  this.saveHistory();
16189
15948
  }
16190
- renderScreen() {
16191
- if (!process.stdout.isTTY) return;
16192
- const lines = this.buildDisplayLines();
16193
- const clearSeq = `\x1B[0J\x1B[${process.stdout.rows || 24};0H`;
16194
- const output = clearSeq + lines.join("\n");
16195
- try {
16196
- cursorToSync(process.stdout, 0, (process.stdout.rows || 24) - lines.length);
16197
- process.stdout.write(output);
16198
- } catch {
16199
- }
15949
+ setOnInput(handler) {
15950
+ this.onInput = handler;
16200
15951
  }
16201
- buildDisplayLines() {
16202
- const lines = [];
16203
- if (this.popupActive) {
16204
- const popupLines = this.commandPopup.render().split("\n");
16205
- lines.push(...popupLines);
15952
+ setStatus(status) {
15953
+ this.status = status;
15954
+ if (this.rl) {
15955
+ this.rl.setPrompt(this.buildPromptPrefix());
16206
15956
  }
16207
- lines.push(this.buildPromptLine());
16208
- return lines;
16209
15957
  }
16210
- stop() {
16211
- this.running = false;
16212
- if (this.stdinRaw && process.stdin.isTTY) {
16213
- try {
16214
- process.stdin.setRawMode?.(false);
16215
- } catch {
16216
- }
16217
- }
16218
- process.stdin.removeAllListeners("data");
16219
- this.showShutdownScreen();
15958
+ setApprovalMode(mode) {
15959
+ this.approvalMode = mode;
16220
15960
  }
16221
- clear() {
16222
- console.clear();
15961
+ setAgentMode(mode) {
15962
+ this.agentMode = mode;
15963
+ }
15964
+ getApprovalMode() {
15965
+ return this.approvalMode;
15966
+ }
15967
+ getAgentMode() {
15968
+ return this.agentMode;
16223
15969
  }
16224
- clearOutputLine() {
15970
+ printLine(line) {
15971
+ if (!process.stdout.isTTY) {
15972
+ console.log(line);
15973
+ return;
15974
+ }
16225
15975
  try {
16226
- const { cursorTo, clearLine } = require("readline");
16227
- cursorTo(process.stdout, 0);
16228
- clearLine(process.stdout, 1);
15976
+ (0, import_readline.cursorTo)(process.stdout, 0);
15977
+ (0, import_readline.clearLine)(process.stdout, 1);
15978
+ process.stdout.write(line + "\n");
16229
15979
  } catch {
15980
+ console.log(line);
16230
15981
  }
16231
15982
  }
15983
+ printAssistant(message) {
15984
+ this.printLine(source_default.green(message));
15985
+ }
15986
+ printWarning(message) {
15987
+ this.printLine(source_default.yellow(`\u26A0 ${message}`));
15988
+ }
15989
+ printError(error) {
15990
+ const w = Math.max(Math.min(process.stdout.columns || 80, 56), 10);
15991
+ this.printLine(source_default.red(`\u2554${"\u2550".repeat(w)}\u2557`));
15992
+ this.printLine(source_default.red(`\u2551`) + ` ${source_default.red("\u2717")} ${source_default.white(error)}${" ".repeat(Math.max(0, w - error.length - 7))}` + source_default.red(`\u2551`));
15993
+ this.printLine(source_default.red(`\u255A${"\u2550".repeat(w)}\u255D`));
15994
+ }
15995
+ printToolCall(toolName, args) {
15996
+ const argsStr = Object.entries(args).slice(0, 3).map(([k, v]) => `${k}=${String(v).slice(0, 50)}`).join(", ");
15997
+ this.printLine(source_default.gray(` \u26A1 ${toolName}(${argsStr}${Object.keys(args).length > 3 ? ", ..." : ""})`));
15998
+ }
15999
+ printToolResult(result) {
16000
+ if (result.success) {
16001
+ this.printLine(source_default.gray(` \u2713 ${source_default.green("success")}`));
16002
+ } else {
16003
+ this.printLine(source_default.gray(` \u2715 ${source_default.red(result.error || "failed")}`));
16004
+ }
16005
+ }
16006
+ showStatusBar(_info) {
16007
+ }
16232
16008
  printWelcome() {
16233
16009
  const welcome = generateWelcome();
16234
- const lines = welcome.split("\n");
16235
- for (const line of lines) {
16010
+ for (const line of welcome.split("\n")) {
16236
16011
  this.printLine(line);
16237
16012
  }
16238
16013
  this.printLine("");
@@ -16245,13 +16020,13 @@ var TUI = class {
16245
16020
  }
16246
16021
  printHelp() {
16247
16022
  const { ALL_COMMANDS: ALL_COMMANDS2 } = (init_CommandPopup(), __toCommonJS(CommandPopup_exports));
16248
- const w = Math.min(process.stdout.columns || 80, 72);
16023
+ const w = Math.max(Math.min(process.stdout.columns || 80, 72), 30);
16249
16024
  const top = `\u2554${"\u2550".repeat(w)}\u2557`;
16250
16025
  const bottom = `\u255A${"\u2550".repeat(w)}\u255D`;
16251
16026
  const lines = [top];
16252
16027
  const title = ` YS Code Agent \u2014 Commands `;
16253
- const titlePad = Math.floor((w - title.length) / 2);
16254
- lines.push(`\u2551${" ".repeat(titlePad)}${source_default.cyan(title)}${" ".repeat(w - titlePad - title.length)}\u2551`);
16028
+ const titlePad = Math.max(0, Math.floor((w - title.length) / 2));
16029
+ lines.push(`\u2551${" ".repeat(titlePad)}${source_default.cyan(title)}${" ".repeat(Math.max(0, w - titlePad - title.length))}\u2551`);
16255
16030
  lines.push(`\u2560${"\u2550".repeat(w)}\u2563`);
16256
16031
  const categories = {};
16257
16032
  for (const cmd of ALL_COMMANDS2) {
@@ -16293,183 +16068,24 @@ var TUI = class {
16293
16068
  lines.push(bottom);
16294
16069
  for (const l of lines) this.printLine(l);
16295
16070
  }
16296
- printWarning(message) {
16297
- const w = Math.min(process.stdout.columns || 80, 60);
16298
- const top = `\u2554${"\u2550".repeat(w)}\u2557`;
16299
- const bottom = `\u255A${"\u2550".repeat(w)}\u255D`;
16300
- this.printLine("");
16301
- this.printLine(source_default.yellow(top));
16302
- const warnLine = ` \u26A0 ${source_default.yellow(message)}`;
16303
- const pad = Math.max(0, w - warnLine.length);
16304
- this.printLine(`\u2551${warnLine}${" ".repeat(pad)}\u2551`);
16305
- this.printLine(source_default.yellow(bottom));
16306
- }
16307
- showPrompt() {
16308
- if (!this.running) return;
16309
- const promptLine2 = this.buildPromptLine();
16310
- if (phoneConfig.isTermux) {
16311
- this.printLine(promptLine2);
16312
- } else {
16313
- this.renderScreen();
16314
- }
16315
- }
16316
- buildPromptLine() {
16317
- const statusIndicator = STATUS_COLORS[this.status](INDICATORS[this.status]);
16318
- const config = configManager.getConfig();
16319
- const model = config.model.model;
16320
- const modelShort = model.length > 18 ? model.slice(0, 16) + "\u2026" : model;
16321
- let modeBadge2 = "";
16322
- if (this.agentMode === "plan") modeBadge2 = source_default.blue(" [plan]");
16323
- else if (this.agentMode === "goal") modeBadge2 = source_default.magenta(" [goal]");
16324
- else if (this.agentMode === "arena") modeBadge2 = source_default.yellow(" [arena]");
16325
- let approvalBadge2 = "";
16326
- if (this.approvalMode === "safe") approvalBadge2 = source_default.cyan(" [safe]");
16327
- else if (this.approvalMode === "yolo") approvalBadge2 = source_default.red(" [yolo]");
16328
- const promptStr = `${statusIndicator} ${source_default.cyan("ys")} ${source_default.yellow(`[${modelShort}]`)}${modeBadge2}${approvalBadge2} ${source_default.gray("\u203A")} `;
16329
- const inputStr = this.inputBuffer || " ";
16330
- const cursorChar = phoneConfig.isTermux ? "\u2588" : "\u2588";
16331
- const cursor = source_default.gray(cursorChar);
16332
- const displayedInput = inputStr.length > 0 ? inputStr : "";
16333
- let cursorLine = "";
16334
- if (this.cursorPos >= displayedInput.length) {
16335
- cursorLine = promptStr + displayedInput + cursor;
16336
- } else {
16337
- const before = displayedInput.slice(0, this.cursorPos);
16338
- const after = displayedInput.slice(this.cursorPos);
16339
- cursorLine = promptStr + before + cursor + after;
16340
- }
16341
- return cursorLine + "\n" + source_default.gray(` \u{1F4A1} / for commands | \u2191\u2193 history | Tab complete`);
16342
- }
16343
- setOnInput(handler) {
16344
- this.onInput = handler;
16345
- }
16346
- setOnSpecialKey(handler) {
16347
- this.onSpecialKey = handler;
16348
- }
16349
- setStatus(status) {
16350
- this.status = status;
16351
- }
16352
- setApprovalMode(mode) {
16353
- this.approvalMode = mode;
16354
- }
16355
- setAgentMode(mode) {
16356
- this.agentMode = mode;
16357
- }
16358
- getApprovalMode() {
16359
- return this.approvalMode;
16360
- }
16361
- getAgentMode() {
16362
- return this.agentMode;
16363
- }
16364
- printLine(line) {
16365
- if (!process.stdout.isTTY) {
16366
- console.log(line);
16367
- return;
16368
- }
16369
- try {
16370
- const { cursorTo, clearLine } = require("readline");
16371
- cursorTo(process.stdout, 0);
16372
- clearLine(process.stdout, 1);
16373
- console.log(line);
16374
- } catch {
16375
- console.log(line);
16376
- }
16377
- this.outputLines.push(line);
16378
- if (this.outputLines.length > this.maxOutputLines) {
16379
- this.outputLines.shift();
16380
- }
16381
- }
16382
- printAssistant(message) {
16383
- this.printLine("");
16384
- const formatted = source_default.green(message);
16385
- this.printLine(formatted);
16386
- }
16387
- printError(error) {
16388
- const w = Math.min(process.stdout.columns || 80, 56);
16389
- const top = `\u2554${"\u2550".repeat(w)}\u2557`;
16390
- const bottom = `\u255A${"\u2550".repeat(w)}\u255D`;
16391
- this.printLine("");
16392
- this.printLine(source_default.red(top));
16393
- this.printLine(`\u2551 ${source_default.red("\u2717")} ${source_default.white(error)}${" ".repeat(Math.max(0, w - error.length - 7))}\u2551`);
16394
- this.printLine(source_default.red(bottom));
16395
- }
16396
- printToolCall(toolName, args) {
16397
- const argsStr = Object.entries(args).slice(0, 3).map(([k, v]) => `${k}=${String(v).slice(0, 50)}`).join(", ");
16398
- this.printLine(source_default.gray(` \u26A1 ${toolName}(${argsStr}${Object.keys(args).length > 3 ? ", ..." : ""})`));
16071
+ clear() {
16072
+ console.clear();
16399
16073
  }
16400
- printToolResult(result) {
16401
- if (result.success) {
16402
- this.printLine(source_default.gray(` \u2713 ${source_default.green("success")}`));
16403
- } else {
16404
- this.printLine(source_default.gray(` \u2715 ${source_default.red(result.error || "failed")}`));
16074
+ stop() {
16075
+ this.running = false;
16076
+ if (this.rl) {
16077
+ this.rl.close();
16078
+ this.rl = null;
16405
16079
  }
16406
- }
16407
- showStatusBar(info) {
16408
- const statusColor = STATUS_COLORS[info.status];
16409
- const statusIcon = INDICATORS[info.status];
16410
- const truncated = info.task ? info.task.slice(0, 40) + (info.task.length > 40 ? "..." : "") : "";
16411
- const parts = [
16412
- `${statusColor(`${statusIcon} ${info.status}`)}`,
16413
- source_default.gray(`msgs:${info.messages}`),
16414
- source_default.gray(`tok:${info.tokens}`)
16415
- ];
16416
- if (info.provider) parts.push(source_default.gray(`prov:${info.provider}`));
16417
- if (truncated) parts.push(source_default.gray(`task:${truncated}`));
16418
- }
16419
- showShutdownScreen() {
16420
- const w = Math.min(process.stdout.columns || 80, 50);
16421
- const top = `\u256D${"\u2500".repeat(w)}\u256E`;
16422
- const bottom = `\u2570${"\u2500".repeat(w)}\u256F`;
16423
- console.log("");
16424
- console.log(source_default.cyan(top));
16425
- console.log(`\u2502${" ".repeat(w)}\u2502`);
16426
- const titleLine = " \u25C6 YS Code Agent \u2014 Session Complete ";
16427
- const titlePad = Math.floor((w - titleLine.length) / 2);
16428
- console.log(`\u2502${" ".repeat(titlePad)}${source_default.cyan(titleLine)}${" ".repeat(w - titlePad - titleLine.length)}\u2502`);
16429
- console.log(`\u2502${" ".repeat(w)}\u2502`);
16430
- const { sessionManager: sessionManager2 } = (init_session(), __toCommonJS(session_exports));
16431
- const session = sessionManager2.getCurrentSession();
16432
- if (session) {
16433
- const sessionId = session.id.slice(0, 8);
16434
- const duration = formatDuration2(Date.now() - session.createdAt);
16435
- const msgCount = session.state.messages.length;
16436
- console.log(`\u2502 ${source_default.white("Session")}: ${source_default.yellow(sessionId.padEnd(w - 13))}\u2502`);
16437
- console.log(`\u2502 ${source_default.white("Duration")}: ${source_default.yellow(duration.padEnd(w - 14))}\u2502`);
16438
- console.log(`\u2502 ${source_default.white("Messages")}: ${source_default.yellow(String(msgCount).padEnd(w - 14))}\u2502`);
16439
- }
16440
- console.log(`\u2502${" ".repeat(w)}\u2502`);
16441
- console.log(`\u2502 ${source_default.gray("Session saved. Resume with:")} ${source_default.yellow("ys --resume <session>")}${" ".repeat(Math.max(0, w - 43))}\u2502`);
16442
- console.log(`\u2502${" ".repeat(w)}\u2502`);
16443
- console.log(source_default.cyan(bottom));
16444
- console.log("");
16080
+ process.stdin.removeAllListeners("data");
16445
16081
  }
16446
16082
  destroy() {
16447
- if (this.stdinRaw && process.stdin.isTTY) {
16448
- try {
16449
- process.stdin.setRawMode?.(false);
16450
- } catch {
16451
- }
16452
- }
16453
- process.stdin.removeAllListeners("data");
16083
+ this.stop();
16454
16084
  }
16455
16085
  getOutputLineCount() {
16456
- return this.outputLines.length;
16086
+ return 0;
16457
16087
  }
16458
16088
  };
16459
- function formatDuration2(ms) {
16460
- if (ms < 1e3) return `${ms}ms`;
16461
- if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
16462
- const m = Math.floor(ms / 6e4);
16463
- const s = Math.floor(ms % 6e4 / 1e3);
16464
- return `${m}m ${s}s`;
16465
- }
16466
- function cursorToSync(stream, x, y) {
16467
- try {
16468
- const { cursorTo } = require("readline");
16469
- cursorTo(stream, x, y);
16470
- } catch {
16471
- }
16472
- }
16473
16089
  var tui = new TUI();
16474
16090
 
16475
16091
  // src/cli/interactive.ts
@@ -16519,7 +16135,7 @@ ${(0, import_path8.relative)(process.cwd(), fullPath) || "."}/`));
16519
16135
  const ext = (0, import_path8.extname)(fullPath);
16520
16136
  const lang = getLanguageFromExtension(ext);
16521
16137
  tui.printLine(source_default.cyan(`
16522
- \u2554\u2550 ${(0, import_path8.basename)(fullPath)} (${lang}) \u2550${"\u2550".repeat(Math.min(40, phoneConfig.terminalWidth - 20))}\u2557`));
16138
+ \u2554\u2550 ${(0, import_path8.basename)(fullPath)} (${lang}) \u2550${"\u2550".repeat(Math.max(0, Math.min(40, phoneConfig.terminalWidth - 20)))}\u2557`));
16523
16139
  tui.printLine(source_default.gray(` Path: ${(0, import_path8.relative)(process.cwd(), fullPath)} | ${lines.length} lines | ${formatBytes(stat.size)}`));
16524
16140
  tui.printLine("");
16525
16141
  const maxLines = showAll ? lines.length : Math.min(lines.length, 100);
@@ -16843,8 +16459,8 @@ function getTemplate(ext) {
16843
16459
  }
16844
16460
  function promptConfirm(defaultYes) {
16845
16461
  return new Promise((resolve6) => {
16846
- const { createInterface } = require("readline");
16847
- const rl = createInterface({ input: process.stdin, output: process.stdout });
16462
+ const { createInterface: createInterface2 } = require("readline");
16463
+ const rl = createInterface2({ input: process.stdin, output: process.stdout });
16848
16464
  const prompt = defaultYes ? "[Y/n] " : "[y/N] ";
16849
16465
  rl.question(prompt, (answer) => {
16850
16466
  rl.close();
@@ -17140,8 +16756,8 @@ function showGitHelp() {
17140
16756
  }
17141
16757
  function promptWithOptions() {
17142
16758
  return new Promise((resolve6) => {
17143
- const { createInterface } = require("readline");
17144
- const rl = createInterface({ input: process.stdin, output: process.stdout });
16759
+ const { createInterface: createInterface2 } = require("readline");
16760
+ const rl = createInterface2({ input: process.stdin, output: process.stdout });
17145
16761
  rl.question("", (answer) => {
17146
16762
  rl.close();
17147
16763
  const a = answer.trim().toLowerCase();
@@ -17153,8 +16769,8 @@ function promptWithOptions() {
17153
16769
  }
17154
16770
  function promptLine() {
17155
16771
  return new Promise((resolve6) => {
17156
- const { createInterface } = require("readline");
17157
- const rl = createInterface({ input: process.stdin, output: process.stdout });
16772
+ const { createInterface: createInterface2 } = require("readline");
16773
+ const rl = createInterface2({ input: process.stdin, output: process.stdout });
17158
16774
  rl.question("> ", (answer) => {
17159
16775
  rl.close();
17160
16776
  resolve6(answer.trim());
@@ -17416,7 +17032,7 @@ async function arenaStart(prompt) {
17416
17032
  const activeProv = configManager.getActiveProvider();
17417
17033
  const keySet = !!(activeProv.apiKey || process.env.OPENROUTER_API_KEY);
17418
17034
  if (!keySet) {
17419
- tui.printLine(`\u2551 ${source_default.red("\u2717 No API key configured for OpenRouter")}${" ".repeat(w - 44)}\u2551`);
17035
+ tui.printLine(`\u2551 ${source_default.red("\u2717 No API key configured for OpenRouter")}${" ".repeat(Math.max(0, w - 44))}\u2551`);
17420
17036
  tui.printLine(source_default.cyan(`\u255A${"\u2550".repeat(w)}\u255D`));
17421
17037
  return true;
17422
17038
  }
@@ -17438,8 +17054,8 @@ async function handleTasks(args) {
17438
17054
  const w = Math.min(phoneConfig.terminalWidth - 2, 50);
17439
17055
  tui.printLine(source_default.cyan(`
17440
17056
  \u2554\u2550 Background Tasks ${"\u2550".repeat(Math.max(0, w - 18))}\u2557`));
17441
- tui.printLine(`\u2551 ${source_default.gray("No background tasks running")}${" ".repeat(w - 30)}\u2551`);
17442
- tui.printLine(`\u2551 ${source_default.gray("Use /background <command> to run a task")}${" ".repeat(w - 45)}\u2551`);
17057
+ tui.printLine(`\u2551 ${source_default.gray("No background tasks running")}${" ".repeat(Math.max(0, w - 30))}\u2551`);
17058
+ tui.printLine(`\u2551 ${source_default.gray("Use /background <command> to run a task")}${" ".repeat(Math.max(0, w - 45))}\u2551`);
17443
17059
  tui.printLine(source_default.cyan(`\u255A${"\u2550".repeat(w)}\u255D`));
17444
17060
  }
17445
17061
  return true;
@@ -17694,7 +17310,7 @@ reg({
17694
17310
  Session Recap:`));
17695
17311
  tui.printLine(` ID: ${source_default.yellow(session.id.slice(0, 8))}`);
17696
17312
  tui.printLine(` Name: ${source_default.yellow(session.name)}`);
17697
- tui.printLine(` Duration: ${source_default.yellow(formatDuration3(duration))}`);
17313
+ tui.printLine(` Duration: ${source_default.yellow(formatDuration2(duration))}`);
17698
17314
  tui.printLine(` Messages: ${source_default.yellow(String(messages.length))} (${userMsgs.length} user, ${asstMsgs.length} assistant)`);
17699
17315
  return true;
17700
17316
  }
@@ -18269,14 +17885,14 @@ function approvalBadge(m) {
18269
17885
  return map[m] || source_default.gray(m);
18270
17886
  }
18271
17887
  function getProgressBar(pct, width) {
18272
- const filled = Math.round(pct / 100 * width);
18273
- const empty = width - filled;
17888
+ const filled = Math.max(0, Math.min(Math.round(pct / 100 * width), width));
17889
+ const empty = Math.max(0, width - filled);
18274
17890
  const fillChar = "\u2588";
18275
17891
  const emptyChar = "\u2591";
18276
17892
  const color = pct > 80 ? source_default.red : pct > 50 ? source_default.yellow : source_default.green;
18277
17893
  return color(fillChar.repeat(filled)) + source_default.gray(emptyChar.repeat(empty));
18278
17894
  }
18279
- function formatDuration3(ms) {
17895
+ function formatDuration2(ms) {
18280
17896
  if (ms < 1e3) return `${ms}ms`;
18281
17897
  if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
18282
17898
  const m = Math.floor(ms / 6e4);
@@ -18629,8 +18245,8 @@ reg({
18629
18245
  tui.printLine(source_default.gray(" 1. Build the project"));
18630
18246
  tui.printLine(source_default.gray(" 2. Publish to npm registry"));
18631
18247
  tui.printLine(source_default.yellow("\n Continue? [y/N]"));
18632
- const { createInterface } = await import("readline");
18633
- const rl = createInterface({ input: process.stdin, output: process.stdout });
18248
+ const { createInterface: createInterface2 } = await import("readline");
18249
+ const rl = createInterface2({ input: process.stdin, output: process.stdout });
18634
18250
  rl.question("", async (answer) => {
18635
18251
  rl.close();
18636
18252
  if (answer.trim().toLowerCase() !== "y") {
@@ -18810,10 +18426,10 @@ var InteractiveMode = class {
18810
18426
  const config = configManager.getConfig();
18811
18427
  const provider = configManager.getActiveProvider();
18812
18428
  if (!provider.apiKey && !process.env[`${provider.type.toUpperCase()}_API_KEY`]) {
18813
- console.log(source_default.yellow(`
18429
+ tui.printLine(source_default.yellow(`
18814
18430
  \u26A0 No API key configured for ${provider.name}`));
18815
- console.log(source_default.gray(` Set ${provider.type.toUpperCase()}_API_KEY environment variable`));
18816
- console.log(source_default.gray(" Or use /provider <name> to switch to a configured provider"));
18431
+ tui.printLine(source_default.gray(` Set ${provider.type.toUpperCase()}_API_KEY environment variable`));
18432
+ tui.printLine(source_default.gray(" Or use /provider <name> to switch to a configured provider"));
18817
18433
  }
18818
18434
  }
18819
18435
  async handleInput(input) {
@@ -18879,7 +18495,7 @@ var InteractiveMode = class {
18879
18495
  // src/cli/index.ts
18880
18496
  var import_fs10 = require("fs");
18881
18497
  var logger18 = getLogger("cli");
18882
- var APP_VERSION = true ? "2.0.0" : "1.0.0";
18498
+ var APP_VERSION = true ? "2.0.2" : "1.0.0";
18883
18499
  var program2 = new Command();
18884
18500
  program2.name("ys").description("YS Code Agent - AI-Powered Terminal Coding Agent").version(APP_VERSION).option("-c, --config <path>", "Path to config file").option("-m, --model <model>", "Model to use").option("-p, --provider <provider>", "Provider to use").option("-d, --directory <path>", "Working directory").option("--read-only", "Enable read-only mode").option("--sandbox", "Enable sandbox mode").option("--verbose", "Enable verbose logging").option("--non-interactive", "Run in non-interactive mode").hook("preAction", () => {
18885
18501
  initializeTools();
@@ -18887,6 +18503,7 @@ program2.name("ys").description("YS Code Agent - AI-Powered Terminal Coding Agen
18887
18503
  program2.command("chat").description("Start interactive chat session").argument("[message]", "Initial message").action(async (message) => {
18888
18504
  try {
18889
18505
  const interactive = new InteractiveMode();
18506
+ showBanner();
18890
18507
  await interactive.start(message);
18891
18508
  } catch (error) {
18892
18509
  console.error(source_default.red("Fatal error:"), error);
@@ -19081,36 +18698,89 @@ program2.command("doctor").description("Run system diagnostics").action(async ()
19081
18698
  console.log(` Previous tasks: ${context.longTerm.previousTasks.length}`);
19082
18699
  console.log(source_default.green("\n\u2713 Diagnostics complete\n"));
19083
18700
  });
19084
- async function main() {
19085
- program2.parse(process.argv);
19086
- const options = program2.opts();
19087
- if (options.config) {
19088
- const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config(), config_exports));
19089
- const customConfig = new ConfigManager2(options.config);
19090
- }
19091
- if (options.model) {
19092
- configManager.set("model.model", options.model);
19093
- }
19094
- if (options.provider) {
19095
- configManager.setActiveProvider(options.provider);
19096
- }
19097
- if (options.directory) {
19098
- process.chdir(options.directory);
19099
- }
19100
- if (options.readOnly) {
19101
- configManager.set("security.readOnlyMode", true);
19102
- }
19103
- if (options.sandbox) {
19104
- configManager.set("security.sandboxMode", true);
18701
+ function showBanner() {
18702
+ const config = configManager.getConfig();
18703
+ const provider = configManager.getActiveProvider();
18704
+ const w = Math.min(process.stdout.columns || 80, 54);
18705
+ const top = `\u2554${"\u2550".repeat(w)}\u2557`;
18706
+ const bottom = `\u255A${"\u2550".repeat(w)}\u255D`;
18707
+ const versionLine = ` YS Code Agent v${APP_VERSION} `;
18708
+ const versionPad = Math.max(0, Math.floor((w - versionLine.length) / 2));
18709
+ const tagline = "AI-Powered Terminal Coding Agent";
18710
+ const taglinePad = Math.max(0, Math.floor((w - tagline.length) / 2));
18711
+ console.log("");
18712
+ console.log(source_default.cyan(top));
18713
+ console.log(`\u2551${" ".repeat(versionPad)}${source_default.white(versionLine)}${" ".repeat(Math.max(0, w - versionPad - versionLine.length))}\u2551`);
18714
+ console.log(`\u2551${" ".repeat(taglinePad)}${source_default.gray(tagline)}${" ".repeat(Math.max(0, w - taglinePad - tagline.length))}\u2551`);
18715
+ console.log(source_default.cyan(bottom));
18716
+ const cwd = process.cwd();
18717
+ const home = process.env.HOME || "/home";
18718
+ const displayPath = cwd.startsWith(home) ? "~" + cwd.slice(home.length) : cwd;
18719
+ const branch = getGitBranch2();
18720
+ console.log(` ${source_default.gray("Provider:")} ${source_default.cyan(provider.name)}`);
18721
+ console.log(` ${source_default.gray("Model:")} ${source_default.yellow(config.model.model)}`);
18722
+ console.log(` ${source_default.gray("Directory:")} ${source_default.white(displayPath)}${branch ? ` ${source_default.gray("\u2387")} ${source_default.yellow(branch)}` : ""}`);
18723
+ console.log(` ${source_default.gray("Memory:")} ${source_default.green("\u2713 Enabled")}`);
18724
+ try {
18725
+ const { toolRegistry: toolRegistry2 } = (init_tools(), __toCommonJS(tools_exports));
18726
+ const tools = toolRegistry2.getToolNames();
18727
+ console.log(` ${source_default.gray("Tools:")} ${source_default.green(`${tools.length} available`)}`);
18728
+ } catch {
19105
18729
  }
19106
- if (options.verbose) {
19107
- configManager.set("logging.level", "debug");
18730
+ console.log("");
18731
+ }
18732
+ function getGitBranch2() {
18733
+ try {
18734
+ const fs = require("fs");
18735
+ const head = fs.readFileSync(".git/HEAD", "utf-8").trim();
18736
+ const match = head.match(/ref: refs\/heads\/(.+)/);
18737
+ return match ? match[1] : null;
18738
+ } catch {
18739
+ return null;
19108
18740
  }
19109
- const noCommand = process.argv.length <= 2 || process.argv[2]?.startsWith("-");
19110
- if (noCommand) {
19111
- const interactive = new InteractiveMode();
19112
- await interactive.start();
18741
+ }
18742
+ function applyGlobalOptions(rawArgs) {
18743
+ let verbose = false;
18744
+ for (let i = 0; i < rawArgs.length; i++) {
18745
+ const arg = rawArgs[i];
18746
+ if (arg === "--verbose") {
18747
+ verbose = true;
18748
+ } else if (arg === "--read-only") {
18749
+ configManager.set("security.readOnlyMode", true);
18750
+ } else if (arg === "--sandbox") {
18751
+ configManager.set("security.sandboxMode", true);
18752
+ } else if (arg === "--non-interactive") {
18753
+ configManager.set("nonInteractive", true);
18754
+ } else if ((arg === "--config" || arg === "-c") && i + 1 < rawArgs.length) {
18755
+ const { ConfigManager: ConfigManager2 } = (init_config(), __toCommonJS(config_exports));
18756
+ new ConfigManager2(rawArgs[++i]);
18757
+ } else if ((arg === "--model" || arg === "-m") && i + 1 < rawArgs.length) {
18758
+ configManager.set("model.model", rawArgs[++i]);
18759
+ } else if ((arg === "--provider" || arg === "-p") && i + 1 < rawArgs.length) {
18760
+ configManager.setActiveProvider(rawArgs[++i]);
18761
+ } else if ((arg === "--directory" || arg === "-d") && i + 1 < rawArgs.length) {
18762
+ process.chdir(rawArgs[++i]);
18763
+ }
18764
+ }
18765
+ setAllLevels(verbose ? "debug" : "warn");
18766
+ setConsoleSuppressed(!verbose);
18767
+ }
18768
+ async function main() {
18769
+ const rawArgs = process.argv.slice(2);
18770
+ const knownCommands = new Set(program2.commands.map((c) => c.name()));
18771
+ const firstArg = rawArgs.find((a) => !a.startsWith("-"));
18772
+ const hasKnownCommand = firstArg ? knownCommands.has(firstArg) : false;
18773
+ const hasHelpFlag = rawArgs.includes("--help") || rawArgs.includes("-h");
18774
+ const hasVersionFlag = rawArgs.includes("--version") || rawArgs.includes("-V");
18775
+ if (hasKnownCommand || hasHelpFlag || hasVersionFlag) {
18776
+ applyGlobalOptions(rawArgs);
18777
+ program2.parse(process.argv);
18778
+ return;
19113
18779
  }
18780
+ applyGlobalOptions(rawArgs);
18781
+ showBanner();
18782
+ const interactive = new InteractiveMode();
18783
+ await interactive.start();
19114
18784
  }
19115
18785
  main().catch((error) => {
19116
18786
  console.error(source_default.red("Fatal error:"), error);