ys-code-agent 2.0.1 → 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.
@@ -15643,7 +15643,6 @@ init_logger();
15643
15643
  init_source();
15644
15644
  init_logger();
15645
15645
  init_config();
15646
- init_phoneOptimizer();
15647
15646
  init_CommandPopup();
15648
15647
 
15649
15648
  // src/ui/WelcomeScreen.ts
@@ -15801,6 +15800,7 @@ function getSessionId() {
15801
15800
  }
15802
15801
 
15803
15802
  // src/ui/index.ts
15803
+ var import_readline = require("readline");
15804
15804
  var logger15 = getLogger("ui");
15805
15805
  var INDICATORS = {
15806
15806
  idle: "\u25CB",
@@ -15824,24 +15824,18 @@ var TUI = class {
15824
15824
  status = "idle";
15825
15825
  approvalMode = "normal";
15826
15826
  agentMode = "chat";
15827
- outputLines = [];
15828
- maxOutputLines = 1e3;
15829
15827
  onInput = null;
15830
- onSpecialKey = null;
15828
+ onCancelRequest = null;
15831
15829
  running = false;
15832
15830
  commandPopup;
15833
- inputBuffer = "";
15834
15831
  inputHistory = [];
15835
15832
  historyIndex = -1;
15836
- cursorPos = 0;
15837
15833
  popupActive = false;
15838
15834
  cancelRequested = false;
15839
- onCancelRequest = null;
15840
- stdinRaw = false;
15835
+ rl = null;
15841
15836
  constructor() {
15842
15837
  this.commandPopup = new CommandPopup();
15843
15838
  this.loadHistory();
15844
- this.setupRawMode();
15845
15839
  }
15846
15840
  loadHistory() {
15847
15841
  try {
@@ -15865,339 +15859,85 @@ var TUI = class {
15865
15859
  } catch {
15866
15860
  }
15867
15861
  }
15868
- setupRawMode() {
15869
- if (!process.stdin.isTTY) return;
15870
- try {
15871
- process.stdin.setRawMode?.(true);
15872
- this.stdinRaw = true;
15873
- } catch {
15874
- this.stdinRaw = false;
15875
- }
15876
- }
15877
15862
  setOnCancelRequest(cb) {
15878
15863
  this.onCancelRequest = cb;
15879
15864
  }
15880
15865
  start() {
15881
15866
  this.running = true;
15882
- this.showPrompt();
15883
- this.startKeyListener();
15884
- }
15885
- startKeyListener() {
15886
15867
  if (!process.stdin.isTTY) {
15887
15868
  this.startLineMode();
15888
15869
  return;
15889
15870
  }
15890
- process.stdin.on("data", (data) => {
15891
- if (!this.running) return;
15892
- const input = data.toString("utf-8");
15893
- if (this.popupActive) {
15894
- this.handlePopupKey(input);
15895
- this.renderScreen();
15896
- return;
15897
- }
15898
- if (input === "\x1B" || input === "\x1B[" || input === "\x1B[" && data.length > 2) {
15899
- if (input === "\x1B") {
15900
- if (this.inputBuffer.length === 0) {
15901
- void this.handleSpecialKey("escape");
15902
- } else {
15903
- this.inputBuffer = "";
15904
- this.cursorPos = 0;
15905
- this.renderScreen();
15906
- }
15907
- 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);
15908
15888
  }
15909
- return;
15910
- }
15911
- if (input === "\x1B[A") {
15912
- void this.handleSpecialKey("up");
15913
- return;
15914
- }
15915
- if (input === "\x1B[B") {
15916
- void this.handleSpecialKey("down");
15917
- return;
15918
- }
15919
- if (input === "\x1B[C") {
15920
- void this.handleSpecialKey("right");
15921
- return;
15922
- }
15923
- if (input === "\x1B[D") {
15924
- void this.handleSpecialKey("left");
15925
- return;
15926
- }
15927
- if (input === "\r" || input === "\n") {
15928
- void this.handleSpecialKey("enter");
15929
- return;
15930
- }
15931
- if (input === "\x7F" || input === "\b") {
15932
- void this.handleSpecialKey("backspace");
15933
- return;
15934
- }
15935
- if (input === "") {
15936
- void this.handleSpecialKey("ctrl_c");
15937
- return;
15938
- }
15939
- if (input === "\f") {
15940
- void this.handleSpecialKey("ctrl_l");
15941
- return;
15942
- }
15943
- if (input === "") {
15944
- void this.handleSpecialKey("ctrl_a");
15945
- return;
15946
15889
  }
15947
- if (input === "") {
15948
- void this.handleSpecialKey("ctrl_e");
15949
- return;
15950
- }
15951
- if (input === "\n" || input === "\r") {
15952
- return;
15953
- }
15954
- if (input === " ") {
15955
- void this.handleSpecialKey("tab");
15956
- return;
15957
- }
15958
- if (input === "") {
15959
- void this.handleSpecialKey("ctrl_o");
15960
- return;
15961
- }
15962
- if (input === "") {
15963
- void this.handleSpecialKey("ctrl_x");
15964
- return;
15965
- }
15966
- this.inputBuffer = this.inputBuffer.slice(0, this.cursorPos) + input + this.inputBuffer.slice(this.cursorPos);
15967
- this.cursorPos += input.length;
15968
- if (input === "/") {
15969
- this.popupActive = true;
15970
- this.commandPopup.open();
15971
- 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();
15972
15895
  } else {
15973
- if (this.inputBuffer.startsWith("/") && this.inputBuffer.length > 1) {
15974
- this.popupActive = true;
15975
- this.commandPopup.open();
15976
- this.commandPopup.setFilter(this.inputBuffer);
15977
- }
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);
15978
15902
  }
15979
- this.renderScreen();
15903
+ this.showPrompt();
15980
15904
  });
15981
- process.stdin.on("end", () => {
15905
+ this.rl.on("close", () => {
15906
+ process.exit(0);
15982
15907
  });
15908
+ this.showPrompt();
15983
15909
  }
15984
15910
  startLineMode() {
15985
- const { createInterface } = require("readline");
15986
- const rl = createInterface({ input: process.stdin, output: process.stdout, prompt: "" });
15911
+ const rl = (0, import_readline.createInterface)({ input: process.stdin, output: process.stdout, prompt: "" });
15987
15912
  rl.on("line", (line) => {
15988
- this.inputBuffer = line.trim();
15989
- if (this.inputBuffer && this.onInput) {
15990
- this.addHistory(this.inputBuffer);
15991
- this.onInput(this.inputBuffer);
15913
+ const trimmed = line.trim();
15914
+ if (trimmed && this.onInput) {
15915
+ this.addHistory(trimmed);
15916
+ this.onInput(trimmed);
15992
15917
  }
15993
- this.inputBuffer = "";
15994
- this.showPrompt();
15918
+ rl.prompt();
15995
15919
  });
15996
15920
  rl.on("SIGINT", () => process.exit(0));
15997
- this.showPrompt();
15998
- }
15999
- handlePopupKey(input) {
16000
- if (input === "\x1B") {
16001
- this.popupActive = false;
16002
- this.commandPopup.close();
16003
- this.inputBuffer = "";
16004
- this.cursorPos = 0;
16005
- return;
16006
- }
16007
- if (input === "\x1B[A" || input === "\x1BOA") {
16008
- this.commandPopup.moveUp();
16009
- return;
16010
- }
16011
- if (input === "\x1B[B" || input === "\x1BOB") {
16012
- this.commandPopup.moveDown();
16013
- return;
16014
- }
16015
- if (input === "\r" || input === "\n") {
16016
- const selectedCmd = this.commandPopup.getSelectedCommand();
16017
- if (selectedCmd) {
16018
- this.popupActive = false;
16019
- this.commandPopup.close();
16020
- const fullCmd = `/${selectedCmd} `;
16021
- this.inputBuffer = fullCmd;
16022
- this.cursorPos = fullCmd.length;
16023
- }
16024
- return;
16025
- }
16026
- if (input === " ") {
16027
- const selectedCmd = this.commandPopup.getSelectedCommand();
16028
- if (selectedCmd) {
16029
- this.popupActive = false;
16030
- this.commandPopup.close();
16031
- const fullCmd = `/${selectedCmd} `;
16032
- this.inputBuffer = fullCmd;
16033
- this.cursorPos = fullCmd.length;
16034
- }
16035
- return;
16036
- }
16037
- if (input === "\x7F" || input === "\b") {
16038
- const currentFilter = this.commandPopup.getFilterText();
16039
- if (currentFilter.length <= 1) {
16040
- this.popupActive = false;
16041
- this.commandPopup.close();
16042
- this.inputBuffer = "";
16043
- this.cursorPos = 0;
16044
- return;
16045
- }
16046
- this.commandPopup.deleteChar();
16047
- return;
16048
- }
16049
- if (input.length === 1 && input.charCodeAt(0) >= 32) {
16050
- this.commandPopup.appendChar(input);
16051
- this.inputBuffer = this.commandPopup.getFilterText();
16052
- this.cursorPos = this.inputBuffer.length;
16053
- }
15921
+ rl.prompt();
16054
15922
  }
16055
- async handleSpecialKey(key) {
16056
- switch (key) {
16057
- case "escape":
16058
- if (this.inputBuffer.length > 0) {
16059
- this.inputBuffer = "";
16060
- this.cursorPos = 0;
16061
- this.renderScreen();
16062
- }
16063
- break;
16064
- case "enter":
16065
- if (this.inputBuffer.trim()) {
16066
- this.addHistory(this.inputBuffer.trim());
16067
- const msg = this.inputBuffer.trim();
16068
- this.inputBuffer = "";
16069
- this.cursorPos = 0;
16070
- this.clearOutputLine();
16071
- if (this.onInput) this.onInput(msg);
16072
- }
16073
- this.renderScreen();
16074
- break;
16075
- case "backspace":
16076
- if (this.cursorPos > 0) {
16077
- this.inputBuffer = this.inputBuffer.slice(0, this.cursorPos - 1) + this.inputBuffer.slice(this.cursorPos);
16078
- this.cursorPos--;
16079
- this.updatePopupFilter();
16080
- }
16081
- this.renderScreen();
16082
- break;
16083
- case "up":
16084
- if (this.inputHistory.length > 0) {
16085
- if (this.historyIndex === -1) {
16086
- this.historyIndex = this.inputHistory.length - 1;
16087
- } else if (this.historyIndex > 0) {
16088
- this.historyIndex--;
16089
- }
16090
- this.inputBuffer = this.inputHistory[this.historyIndex];
16091
- this.cursorPos = this.inputBuffer.length;
16092
- this.renderScreen();
16093
- }
16094
- break;
16095
- case "down":
16096
- if (this.historyIndex >= 0) {
16097
- this.historyIndex++;
16098
- if (this.historyIndex >= this.inputHistory.length) {
16099
- this.historyIndex = -1;
16100
- this.inputBuffer = "";
16101
- } else {
16102
- this.inputBuffer = this.inputHistory[this.historyIndex];
16103
- }
16104
- this.cursorPos = this.inputBuffer.length;
16105
- this.renderScreen();
16106
- }
16107
- break;
16108
- case "left":
16109
- if (this.cursorPos > 0) {
16110
- this.cursorPos--;
16111
- this.renderScreen();
16112
- }
16113
- break;
16114
- case "right":
16115
- if (this.cursorPos < this.inputBuffer.length) {
16116
- this.cursorPos++;
16117
- this.renderScreen();
16118
- }
16119
- break;
16120
- case "ctrl_a":
16121
- this.cursorPos = 0;
16122
- this.renderScreen();
16123
- break;
16124
- case "ctrl_e":
16125
- this.cursorPos = this.inputBuffer.length;
16126
- this.renderScreen();
16127
- break;
16128
- case "ctrl_c":
16129
- if (this.cancelRequested || this.status === "thinking" || this.status === "executing") {
16130
- if (this.onCancelRequest) this.onCancelRequest();
16131
- } else {
16132
- this.printLine("\n" + source_default.yellow("Use /exit to quit, or press Ctrl+C again to force quit"));
16133
- this.cancelRequested = true;
16134
- setTimeout(() => {
16135
- this.cancelRequested = false;
16136
- }, 2e3);
16137
- }
16138
- break;
16139
- case "ctrl_l":
16140
- this.clear();
16141
- this.printWelcome();
16142
- this.showPrompt();
16143
- break;
16144
- case "tab": {
16145
- const match = this.inputBuffer.match(/^\/?(\w*)$/);
16146
- if (match) {
16147
- const partial = match[1].toLowerCase();
16148
- const cmds = this.getAllCommands().filter((c) => c.startsWith(partial));
16149
- if (cmds.length === 1) {
16150
- this.inputBuffer = `/${cmds[0]} `;
16151
- this.cursorPos = this.inputBuffer.length;
16152
- this.renderScreen();
16153
- }
16154
- }
16155
- break;
16156
- }
16157
- case "ctrl_o":
16158
- break;
16159
- case "ctrl_x":
16160
- void this.openExternalEditor();
16161
- break;
16162
- }
16163
- }
16164
- updatePopupFilter() {
16165
- if (this.popupActive) {
16166
- this.commandPopup.setFilter(this.inputBuffer);
16167
- if (this.inputBuffer === "/" || this.inputBuffer === "") {
16168
- this.popupActive = false;
16169
- this.commandPopup.close();
16170
- }
16171
- }
16172
- }
16173
- getAllCommands() {
16174
- const { ALL_COMMANDS: ALL_COMMANDS2 } = (init_CommandPopup(), __toCommonJS(CommandPopup_exports));
16175
- 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")} `;
16176
15936
  }
16177
- async openExternalEditor() {
16178
- const editor = process.env.EDITOR || "nano";
16179
- const { writeFileSync: writeFileSync7, unlinkSync: unlinkSync4, existsSync: existsSync11, mkdirSync: mkdirSync7 } = await import("fs");
16180
- const { join: join8 } = await import("path");
16181
- const tmpDir = "/tmp/ys-agent";
16182
- if (!existsSync11(tmpDir)) mkdirSync7(tmpDir, { recursive: true });
16183
- const tmpFile = join8(tmpDir, `input-${Date.now()}.md`);
16184
- writeFileSync7(tmpFile, this.inputBuffer, "utf-8");
16185
- const { execSync: execSync4 } = await import("child_process");
16186
- try {
16187
- execSync4(`${editor} "${tmpFile}"`, { stdio: "inherit" });
16188
- const { readFileSync: readFileSync11 } = await import("fs");
16189
- const content = readFileSync11(tmpFile, "utf-8").trim();
16190
- if (content) {
16191
- this.inputBuffer = content;
16192
- this.cursorPos = content.length;
16193
- this.renderScreen();
16194
- }
16195
- } catch {
16196
- }
16197
- try {
16198
- unlinkSync4(tmpFile);
16199
- } catch {
16200
- }
15937
+ showPrompt() {
15938
+ if (!this.running || !this.rl) return;
15939
+ this.rl.setPrompt(this.buildPromptPrefix());
15940
+ this.rl.prompt(true);
16201
15941
  }
16202
15942
  addHistory(input) {
16203
15943
  if (this.inputHistory[this.inputHistory.length - 1] !== input) {
@@ -16206,52 +15946,68 @@ var TUI = class {
16206
15946
  this.historyIndex = -1;
16207
15947
  this.saveHistory();
16208
15948
  }
16209
- renderScreen() {
16210
- if (!process.stdout.isTTY) return;
16211
- const lines = this.buildDisplayLines();
16212
- const clearSeq = `\x1B[0J\x1B[${process.stdout.rows || 24};0H`;
16213
- const output = clearSeq + lines.join("\n");
16214
- try {
16215
- cursorToSync(process.stdout, 0, (process.stdout.rows || 24) - lines.length);
16216
- process.stdout.write(output);
16217
- } catch {
16218
- }
15949
+ setOnInput(handler) {
15950
+ this.onInput = handler;
16219
15951
  }
16220
- buildDisplayLines() {
16221
- const lines = [];
16222
- if (this.popupActive) {
16223
- const popupLines = this.commandPopup.render().split("\n");
16224
- lines.push(...popupLines);
15952
+ setStatus(status) {
15953
+ this.status = status;
15954
+ if (this.rl) {
15955
+ this.rl.setPrompt(this.buildPromptPrefix());
16225
15956
  }
16226
- lines.push(this.buildPromptLine());
16227
- return lines;
16228
15957
  }
16229
- stop() {
16230
- this.running = false;
16231
- if (this.stdinRaw && process.stdin.isTTY) {
16232
- try {
16233
- process.stdin.setRawMode?.(false);
16234
- } catch {
16235
- }
16236
- }
16237
- process.stdin.removeAllListeners("data");
16238
- this.showShutdownScreen();
15958
+ setApprovalMode(mode) {
15959
+ this.approvalMode = mode;
16239
15960
  }
16240
- clear() {
16241
- console.clear();
15961
+ setAgentMode(mode) {
15962
+ this.agentMode = mode;
15963
+ }
15964
+ getApprovalMode() {
15965
+ return this.approvalMode;
16242
15966
  }
16243
- clearOutputLine() {
15967
+ getAgentMode() {
15968
+ return this.agentMode;
15969
+ }
15970
+ printLine(line) {
15971
+ if (!process.stdout.isTTY) {
15972
+ console.log(line);
15973
+ return;
15974
+ }
16244
15975
  try {
16245
- const { cursorTo, clearLine } = require("readline");
16246
- cursorTo(process.stdout, 0);
16247
- 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");
16248
15979
  } catch {
15980
+ console.log(line);
16249
15981
  }
16250
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
+ }
16251
16008
  printWelcome() {
16252
16009
  const welcome = generateWelcome();
16253
- const lines = welcome.split("\n");
16254
- for (const line of lines) {
16010
+ for (const line of welcome.split("\n")) {
16255
16011
  this.printLine(line);
16256
16012
  }
16257
16013
  this.printLine("");
@@ -16312,183 +16068,24 @@ var TUI = class {
16312
16068
  lines.push(bottom);
16313
16069
  for (const l of lines) this.printLine(l);
16314
16070
  }
16315
- printWarning(message) {
16316
- const w = Math.max(Math.min(process.stdout.columns || 80, 60), 10);
16317
- const top = `\u2554${"\u2550".repeat(w)}\u2557`;
16318
- const bottom = `\u255A${"\u2550".repeat(w)}\u255D`;
16319
- this.printLine("");
16320
- this.printLine(source_default.yellow(top));
16321
- const warnLine = ` \u26A0 ${source_default.yellow(message)}`;
16322
- const pad = Math.max(0, w - warnLine.length);
16323
- this.printLine(`\u2551${warnLine}${" ".repeat(pad)}\u2551`);
16324
- this.printLine(source_default.yellow(bottom));
16325
- }
16326
- showPrompt() {
16327
- if (!this.running) return;
16328
- const promptLine2 = this.buildPromptLine();
16329
- if (phoneConfig.isTermux) {
16330
- this.printLine(promptLine2);
16331
- } else {
16332
- this.renderScreen();
16333
- }
16334
- }
16335
- buildPromptLine() {
16336
- const statusIndicator = STATUS_COLORS[this.status](INDICATORS[this.status]);
16337
- const config = configManager.getConfig();
16338
- const model = config.model.model;
16339
- const modelShort = model.length > 18 ? model.slice(0, 16) + "\u2026" : model;
16340
- let modeBadge2 = "";
16341
- if (this.agentMode === "plan") modeBadge2 = source_default.blue(" [plan]");
16342
- else if (this.agentMode === "goal") modeBadge2 = source_default.magenta(" [goal]");
16343
- else if (this.agentMode === "arena") modeBadge2 = source_default.yellow(" [arena]");
16344
- let approvalBadge2 = "";
16345
- if (this.approvalMode === "safe") approvalBadge2 = source_default.cyan(" [safe]");
16346
- else if (this.approvalMode === "yolo") approvalBadge2 = source_default.red(" [yolo]");
16347
- const promptStr = `${statusIndicator} ${source_default.cyan("ys")} ${source_default.yellow(`[${modelShort}]`)}${modeBadge2}${approvalBadge2} ${source_default.gray("\u203A")} `;
16348
- const inputStr = this.inputBuffer || " ";
16349
- const cursorChar = phoneConfig.isTermux ? "\u2588" : "\u2588";
16350
- const cursor = source_default.gray(cursorChar);
16351
- const displayedInput = inputStr.length > 0 ? inputStr : "";
16352
- let cursorLine = "";
16353
- if (this.cursorPos >= displayedInput.length) {
16354
- cursorLine = promptStr + displayedInput + cursor;
16355
- } else {
16356
- const before = displayedInput.slice(0, this.cursorPos);
16357
- const after = displayedInput.slice(this.cursorPos);
16358
- cursorLine = promptStr + before + cursor + after;
16359
- }
16360
- return cursorLine + "\n" + source_default.gray(` \u{1F4A1} / for commands | \u2191\u2193 history | Tab complete`);
16361
- }
16362
- setOnInput(handler) {
16363
- this.onInput = handler;
16364
- }
16365
- setOnSpecialKey(handler) {
16366
- this.onSpecialKey = handler;
16367
- }
16368
- setStatus(status) {
16369
- this.status = status;
16370
- }
16371
- setApprovalMode(mode) {
16372
- this.approvalMode = mode;
16373
- }
16374
- setAgentMode(mode) {
16375
- this.agentMode = mode;
16376
- }
16377
- getApprovalMode() {
16378
- return this.approvalMode;
16379
- }
16380
- getAgentMode() {
16381
- return this.agentMode;
16382
- }
16383
- printLine(line) {
16384
- if (!process.stdout.isTTY) {
16385
- console.log(line);
16386
- return;
16387
- }
16388
- try {
16389
- const { cursorTo, clearLine } = require("readline");
16390
- cursorTo(process.stdout, 0);
16391
- clearLine(process.stdout, 1);
16392
- console.log(line);
16393
- } catch {
16394
- console.log(line);
16395
- }
16396
- this.outputLines.push(line);
16397
- if (this.outputLines.length > this.maxOutputLines) {
16398
- this.outputLines.shift();
16399
- }
16400
- }
16401
- printAssistant(message) {
16402
- this.printLine("");
16403
- const formatted = source_default.green(message);
16404
- this.printLine(formatted);
16405
- }
16406
- printError(error) {
16407
- const w = Math.max(Math.min(process.stdout.columns || 80, 56), 10);
16408
- const top = `\u2554${"\u2550".repeat(w)}\u2557`;
16409
- const bottom = `\u255A${"\u2550".repeat(w)}\u255D`;
16410
- this.printLine("");
16411
- this.printLine(source_default.red(top));
16412
- this.printLine(`\u2551 ${source_default.red("\u2717")} ${source_default.white(error)}${" ".repeat(Math.max(0, w - error.length - 7))}\u2551`);
16413
- this.printLine(source_default.red(bottom));
16414
- }
16415
- printToolCall(toolName, args) {
16416
- const argsStr = Object.entries(args).slice(0, 3).map(([k, v]) => `${k}=${String(v).slice(0, 50)}`).join(", ");
16417
- this.printLine(source_default.gray(` \u26A1 ${toolName}(${argsStr}${Object.keys(args).length > 3 ? ", ..." : ""})`));
16071
+ clear() {
16072
+ console.clear();
16418
16073
  }
16419
- printToolResult(result) {
16420
- if (result.success) {
16421
- this.printLine(source_default.gray(` \u2713 ${source_default.green("success")}`));
16422
- } else {
16423
- 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;
16424
16079
  }
16425
- }
16426
- showStatusBar(info) {
16427
- const statusColor = STATUS_COLORS[info.status];
16428
- const statusIcon = INDICATORS[info.status];
16429
- const truncated = info.task ? info.task.slice(0, 40) + (info.task.length > 40 ? "..." : "") : "";
16430
- const parts = [
16431
- `${statusColor(`${statusIcon} ${info.status}`)}`,
16432
- source_default.gray(`msgs:${info.messages}`),
16433
- source_default.gray(`tok:${info.tokens}`)
16434
- ];
16435
- if (info.provider) parts.push(source_default.gray(`prov:${info.provider}`));
16436
- if (truncated) parts.push(source_default.gray(`task:${truncated}`));
16437
- }
16438
- showShutdownScreen() {
16439
- const w = Math.max(Math.min(process.stdout.columns || 80, 50), 30);
16440
- const top = `\u256D${"\u2500".repeat(w)}\u256E`;
16441
- const bottom = `\u2570${"\u2500".repeat(w)}\u256F`;
16442
- console.log("");
16443
- console.log(source_default.cyan(top));
16444
- console.log(`\u2502${" ".repeat(w)}\u2502`);
16445
- const titleLine = " \u25C6 YS Code Agent \u2014 Session Complete ";
16446
- const titlePad = Math.max(0, Math.floor((w - titleLine.length) / 2));
16447
- console.log(`\u2502${" ".repeat(titlePad)}${source_default.cyan(titleLine)}${" ".repeat(Math.max(0, w - titlePad - titleLine.length))}\u2502`);
16448
- console.log(`\u2502${" ".repeat(w)}\u2502`);
16449
- const { sessionManager: sessionManager2 } = (init_session(), __toCommonJS(session_exports));
16450
- const session = sessionManager2.getCurrentSession();
16451
- if (session) {
16452
- const sessionId = session.id.slice(0, 8);
16453
- const duration = formatDuration2(Date.now() - session.createdAt);
16454
- const msgCount = session.state.messages.length;
16455
- console.log(`\u2502 ${source_default.white("Session")}: ${source_default.yellow(sessionId.padEnd(w - 13))}\u2502`);
16456
- console.log(`\u2502 ${source_default.white("Duration")}: ${source_default.yellow(duration.padEnd(w - 14))}\u2502`);
16457
- console.log(`\u2502 ${source_default.white("Messages")}: ${source_default.yellow(String(msgCount).padEnd(w - 14))}\u2502`);
16458
- }
16459
- console.log(`\u2502${" ".repeat(w)}\u2502`);
16460
- console.log(`\u2502 ${source_default.gray("Session saved. Resume with:")} ${source_default.yellow("ys --resume <session>")}${" ".repeat(Math.max(0, w - 43))}\u2502`);
16461
- console.log(`\u2502${" ".repeat(w)}\u2502`);
16462
- console.log(source_default.cyan(bottom));
16463
- console.log("");
16080
+ process.stdin.removeAllListeners("data");
16464
16081
  }
16465
16082
  destroy() {
16466
- if (this.stdinRaw && process.stdin.isTTY) {
16467
- try {
16468
- process.stdin.setRawMode?.(false);
16469
- } catch {
16470
- }
16471
- }
16472
- process.stdin.removeAllListeners("data");
16083
+ this.stop();
16473
16084
  }
16474
16085
  getOutputLineCount() {
16475
- return this.outputLines.length;
16086
+ return 0;
16476
16087
  }
16477
16088
  };
16478
- function formatDuration2(ms) {
16479
- if (ms < 1e3) return `${ms}ms`;
16480
- if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
16481
- const m = Math.floor(ms / 6e4);
16482
- const s = Math.floor(ms % 6e4 / 1e3);
16483
- return `${m}m ${s}s`;
16484
- }
16485
- function cursorToSync(stream, x, y) {
16486
- try {
16487
- const { cursorTo } = require("readline");
16488
- cursorTo(stream, x, y);
16489
- } catch {
16490
- }
16491
- }
16492
16089
  var tui = new TUI();
16493
16090
 
16494
16091
  // src/cli/interactive.ts
@@ -16862,8 +16459,8 @@ function getTemplate(ext) {
16862
16459
  }
16863
16460
  function promptConfirm(defaultYes) {
16864
16461
  return new Promise((resolve6) => {
16865
- const { createInterface } = require("readline");
16866
- 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 });
16867
16464
  const prompt = defaultYes ? "[Y/n] " : "[y/N] ";
16868
16465
  rl.question(prompt, (answer) => {
16869
16466
  rl.close();
@@ -17159,8 +16756,8 @@ function showGitHelp() {
17159
16756
  }
17160
16757
  function promptWithOptions() {
17161
16758
  return new Promise((resolve6) => {
17162
- const { createInterface } = require("readline");
17163
- 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 });
17164
16761
  rl.question("", (answer) => {
17165
16762
  rl.close();
17166
16763
  const a = answer.trim().toLowerCase();
@@ -17172,8 +16769,8 @@ function promptWithOptions() {
17172
16769
  }
17173
16770
  function promptLine() {
17174
16771
  return new Promise((resolve6) => {
17175
- const { createInterface } = require("readline");
17176
- 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 });
17177
16774
  rl.question("> ", (answer) => {
17178
16775
  rl.close();
17179
16776
  resolve6(answer.trim());
@@ -17713,7 +17310,7 @@ reg({
17713
17310
  Session Recap:`));
17714
17311
  tui.printLine(` ID: ${source_default.yellow(session.id.slice(0, 8))}`);
17715
17312
  tui.printLine(` Name: ${source_default.yellow(session.name)}`);
17716
- tui.printLine(` Duration: ${source_default.yellow(formatDuration3(duration))}`);
17313
+ tui.printLine(` Duration: ${source_default.yellow(formatDuration2(duration))}`);
17717
17314
  tui.printLine(` Messages: ${source_default.yellow(String(messages.length))} (${userMsgs.length} user, ${asstMsgs.length} assistant)`);
17718
17315
  return true;
17719
17316
  }
@@ -18295,7 +17892,7 @@ function getProgressBar(pct, width) {
18295
17892
  const color = pct > 80 ? source_default.red : pct > 50 ? source_default.yellow : source_default.green;
18296
17893
  return color(fillChar.repeat(filled)) + source_default.gray(emptyChar.repeat(empty));
18297
17894
  }
18298
- function formatDuration3(ms) {
17895
+ function formatDuration2(ms) {
18299
17896
  if (ms < 1e3) return `${ms}ms`;
18300
17897
  if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
18301
17898
  const m = Math.floor(ms / 6e4);
@@ -18648,8 +18245,8 @@ reg({
18648
18245
  tui.printLine(source_default.gray(" 1. Build the project"));
18649
18246
  tui.printLine(source_default.gray(" 2. Publish to npm registry"));
18650
18247
  tui.printLine(source_default.yellow("\n Continue? [y/N]"));
18651
- const { createInterface } = await import("readline");
18652
- 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 });
18653
18250
  rl.question("", async (answer) => {
18654
18251
  rl.close();
18655
18252
  if (answer.trim().toLowerCase() !== "y") {
@@ -18829,10 +18426,10 @@ var InteractiveMode = class {
18829
18426
  const config = configManager.getConfig();
18830
18427
  const provider = configManager.getActiveProvider();
18831
18428
  if (!provider.apiKey && !process.env[`${provider.type.toUpperCase()}_API_KEY`]) {
18832
- console.log(source_default.yellow(`
18429
+ tui.printLine(source_default.yellow(`
18833
18430
  \u26A0 No API key configured for ${provider.name}`));
18834
- console.log(source_default.gray(` Set ${provider.type.toUpperCase()}_API_KEY environment variable`));
18835
- 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"));
18836
18433
  }
18837
18434
  }
18838
18435
  async handleInput(input) {
@@ -18898,7 +18495,7 @@ var InteractiveMode = class {
18898
18495
  // src/cli/index.ts
18899
18496
  var import_fs10 = require("fs");
18900
18497
  var logger18 = getLogger("cli");
18901
- var APP_VERSION = true ? "2.0.1" : "1.0.0";
18498
+ var APP_VERSION = true ? "2.0.2" : "1.0.0";
18902
18499
  var program2 = new Command();
18903
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", () => {
18904
18501
  initializeTools();