ys-code-agent 2.0.1 → 3.0.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.
@@ -14023,16 +14023,13 @@ var init_CommandPopup = __esm({
14023
14023
  }
14024
14024
  getCategorizedCommands() {
14025
14025
  const cats = [];
14026
- const seen = /* @__PURE__ */ new Set();
14027
- for (const cmd of this.filteredCommands) {
14028
- if (seen.has(cmd.command)) continue;
14029
- seen.add(cmd.command);
14030
- }
14026
+ const added = /* @__PURE__ */ new Set();
14031
14027
  const order = ["system", "files", "git", "agents", "code", "memory", "settings"];
14032
14028
  for (const cat of order) {
14033
- const cmds = this.filteredCommands.filter((c) => c.category === cat && !seen.has(c.command));
14029
+ const cmds = this.filteredCommands.filter((c) => c.category === cat && !added.has(c.command));
14034
14030
  if (cmds.length > 0) {
14035
14031
  cats.push({ category: cat, commands: cmds });
14032
+ cmds.forEach((c) => added.add(c.command));
14036
14033
  }
14037
14034
  }
14038
14035
  return cats;
@@ -14072,13 +14069,62 @@ init_config();
14072
14069
  init_logger();
14073
14070
 
14074
14071
  // src/providers/base.ts
14075
- var BaseProvider = class {
14072
+ var BaseProvider = class _BaseProvider {
14076
14073
  config;
14077
14074
  modelConfig;
14078
14075
  constructor(config, modelConfig) {
14079
14076
  this.config = config;
14080
14077
  this.modelConfig = modelConfig;
14081
14078
  }
14079
+ static convertToOpenAITools(tools) {
14080
+ return tools.map((schema) => {
14081
+ const properties = {};
14082
+ for (const [key, param] of Object.entries(schema.parameters)) {
14083
+ const prop = {
14084
+ type: param.type,
14085
+ description: param.description
14086
+ };
14087
+ if (param.enum) prop.enum = param.enum;
14088
+ if (param.minimum !== void 0) prop.minimum = param.minimum;
14089
+ if (param.maximum !== void 0) prop.maximum = param.maximum;
14090
+ properties[key] = prop;
14091
+ }
14092
+ return {
14093
+ type: "function",
14094
+ function: {
14095
+ name: schema.name,
14096
+ description: schema.description,
14097
+ parameters: {
14098
+ type: "object",
14099
+ properties,
14100
+ required: schema.required
14101
+ }
14102
+ }
14103
+ };
14104
+ });
14105
+ }
14106
+ static convertToAnthropicTools(tools) {
14107
+ return tools.map((schema) => {
14108
+ const properties = {};
14109
+ for (const [key, param] of Object.entries(schema.parameters)) {
14110
+ const prop = {
14111
+ type: param.type,
14112
+ description: param.description
14113
+ };
14114
+ if (param.enum) prop.enum = param.enum;
14115
+ properties[key] = prop;
14116
+ }
14117
+ return {
14118
+ name: schema.name,
14119
+ description: schema.description,
14120
+ input_schema: {
14121
+ type: "object",
14122
+ properties,
14123
+ required: schema.required
14124
+ }
14125
+ };
14126
+ });
14127
+ }
14082
14128
  getApiKey() {
14083
14129
  return this.config.apiKey || process.env[`${this.config.type.toUpperCase()}_API_KEY`] || "";
14084
14130
  }
@@ -14106,7 +14152,7 @@ var BaseProvider = class {
14106
14152
  body.stop = this.modelConfig.stop;
14107
14153
  }
14108
14154
  if (tools && tools.length > 0) {
14109
- body.tools = tools;
14155
+ body.tools = _BaseProvider.convertToOpenAITools(tools);
14110
14156
  body.tool_choice = "auto";
14111
14157
  }
14112
14158
  return body;
@@ -14315,28 +14361,6 @@ var AnthropicProvider = class extends BaseProvider {
14315
14361
  "anthropic-version": "2023-06-01"
14316
14362
  };
14317
14363
  }
14318
- buildRequestBody(messages, tools) {
14319
- const systemMessages = messages.filter((m) => m.role === "system");
14320
- const chatMessages = messages.filter((m) => m.role !== "system");
14321
- const body = {
14322
- model: this.modelConfig.model,
14323
- messages: chatMessages.map((m) => ({
14324
- role: m.role === "assistant" ? "assistant" : "user",
14325
- content: m.content
14326
- })),
14327
- max_tokens: this.modelConfig.maxTokens,
14328
- temperature: this.modelConfig.temperature,
14329
- top_p: this.modelConfig.topP,
14330
- stream: false
14331
- };
14332
- if (systemMessages.length > 0) {
14333
- body.system = systemMessages.map((m) => ({ type: "text", text: m.content }));
14334
- }
14335
- if (tools && tools.length > 0) {
14336
- body.tools = tools;
14337
- }
14338
- return body;
14339
- }
14340
14364
  convertMessages(messages) {
14341
14365
  const systemMessages = [];
14342
14366
  const chatMessages = [];
@@ -14367,7 +14391,7 @@ var AnthropicProvider = class extends BaseProvider {
14367
14391
  body.system = systemMessages;
14368
14392
  }
14369
14393
  if (tools && tools.length > 0) {
14370
- body.tools = tools;
14394
+ body.tools = BaseProvider.convertToAnthropicTools(tools);
14371
14395
  }
14372
14396
  const response = await this.fetchWithRetry(url, {
14373
14397
  method: "POST",
@@ -14417,7 +14441,7 @@ var AnthropicProvider = class extends BaseProvider {
14417
14441
  body.system = systemMessages;
14418
14442
  }
14419
14443
  if (tools && tools.length > 0) {
14420
- body.tools = tools;
14444
+ body.tools = BaseProvider.convertToAnthropicTools(tools);
14421
14445
  }
14422
14446
  const response = await this.fetchWithRetry(url, {
14423
14447
  method: "POST",
@@ -15126,27 +15150,35 @@ init_session();
15126
15150
  init_project();
15127
15151
  init_utils();
15128
15152
  var logger13 = getLogger("agent");
15129
- var SYSTEM_PROMPT = `You are YS Code Agent, an advanced AI coding assistant that helps users write, debug, and understand code.
15153
+ var SYSTEM_PROMPT = `You are YS Code Agent \u2014 a production-grade terminal AI coding assistant.
15154
+ You have DIRECT access to the filesystem and terminal through tool calls.
15130
15155
 
15131
- You have access to a set of tools that let you read, write, and edit files, search code, execute commands, and more.
15156
+ ## CRITICAL RULE \u2014 USE TOOLS, DON'T JUST TALK
15157
+ When the user asks you to make, create, write, or build something \u2014 USE the write_file tool to actually create the file on disk.
15158
+ When the user asks to read, show, or check something \u2014 USE the read_file tool.
15159
+ When the user asks to run, execute, or test something \u2014 USE the run_command tool.
15160
+ When the user asks to search or find something \u2014 USE the search_files tool.
15161
+ NEVER just show code in chat without writing it to disk when the user asks to create something.
15132
15162
 
15133
- When working on tasks:
15134
- 1. First understand the request thoroughly
15135
- 2. Make a plan before executing
15136
- 3. Read relevant files to understand existing code
15137
- 4. Write or edit code as needed
15138
- 5. Run tests or commands to verify
15139
- 6. Fix any issues that arise
15140
- 7. Report results clearly
15163
+ ## Available Tools
15164
+ - write_file: Write content to a file (creates/overwrites)
15165
+ - read_file: Read file contents from disk
15166
+ - edit_file: Edit specific parts of a file
15167
+ - delete_file: Delete a file
15168
+ - run_command: Execute a shell command
15169
+ - search_files: Search for text in files
15170
+ - glob: Find files matching a pattern
15171
+ - list_directory: List directory contents
15172
+ - git: Execute git commands
15173
+ - web_fetch: Fetch content from a URL
15174
+ - memory: Read/write project memory
15141
15175
 
15142
- Always follow these rules:
15143
- - Write clean, maintainable code following existing patterns
15144
- - Make minimal changes to achieve the goal
15145
- - Verify changes work correctly
15146
- - Be concise in explanations
15147
- - Use the tools available to you effectively
15148
- - Ask for clarification when needed
15149
- - Never execute dangerous commands without confirmation`;
15176
+ ## Response Format
15177
+ - Use clear section headers for complex responses
15178
+ - Show file paths when referencing code
15179
+ - Keep responses concise but complete
15180
+ - After writing files, confirm with a summary of what was created
15181
+ - Use markdown formatting in your responses`;
15150
15182
  var Agent = class {
15151
15183
  state;
15152
15184
  provider = null;
@@ -15643,7 +15675,6 @@ init_logger();
15643
15675
  init_source();
15644
15676
  init_logger();
15645
15677
  init_config();
15646
- init_phoneOptimizer();
15647
15678
  init_CommandPopup();
15648
15679
 
15649
15680
  // src/ui/WelcomeScreen.ts
@@ -15800,7 +15831,28 @@ function getSessionId() {
15800
15831
  }
15801
15832
  }
15802
15833
 
15834
+ // src/utils/renderMarkdown.ts
15835
+ init_source();
15836
+ function renderMarkdown(text) {
15837
+ let result = text;
15838
+ result = result.replace(/^### (.+)$/gm, (_, m) => source_default.cyan.bold(m));
15839
+ result = result.replace(/^## (.+)$/gm, (_, m) => source_default.yellow.bold(m));
15840
+ result = result.replace(/^# (.+)$/gm, (_, m) => source_default.white.bold.underline(m));
15841
+ result = result.replace(/\*\*(.+?)\*\*/g, (_, m) => source_default.bold(m));
15842
+ result = result.replace(/\*(.+?)\*/g, (_, m) => source_default.italic(m));
15843
+ result = result.replace(/`([^`]+)`/g, (_, m) => source_default.bgGray.white(` ${m} `));
15844
+ result = result.replace(
15845
+ /```[\w]*\n([\s\S]+?)```/g,
15846
+ (_, code) => code.split("\n").map((l) => source_default.gray("\u2502 ") + source_default.green(l)).join("\n")
15847
+ );
15848
+ result = result.replace(/^[-*] (.+)$/gm, (_, m) => source_default.cyan(" \u25C6 ") + m);
15849
+ result = result.replace(/^(\d+)\. (.+)$/gm, (_, n, m) => source_default.yellow(` ${n}. `) + m);
15850
+ result = result.replace(/^---+$/gm, source_default.gray("\u2500".repeat(60)));
15851
+ return result;
15852
+ }
15853
+
15803
15854
  // src/ui/index.ts
15855
+ var import_readline = require("readline");
15804
15856
  var logger15 = getLogger("ui");
15805
15857
  var INDICATORS = {
15806
15858
  idle: "\u25CB",
@@ -15824,24 +15876,21 @@ var TUI = class {
15824
15876
  status = "idle";
15825
15877
  approvalMode = "normal";
15826
15878
  agentMode = "chat";
15827
- outputLines = [];
15828
- maxOutputLines = 1e3;
15829
15879
  onInput = null;
15830
- onSpecialKey = null;
15880
+ onCancelRequest = null;
15831
15881
  running = false;
15832
15882
  commandPopup;
15833
- inputBuffer = "";
15834
15883
  inputHistory = [];
15835
15884
  historyIndex = -1;
15836
- cursorPos = 0;
15837
15885
  popupActive = false;
15838
15886
  cancelRequested = false;
15839
- onCancelRequest = null;
15840
- stdinRaw = false;
15887
+ inputBuffer = "";
15888
+ cursorPos = 0;
15889
+ popupLineCount = 0;
15890
+ prevInput = null;
15841
15891
  constructor() {
15842
15892
  this.commandPopup = new CommandPopup();
15843
15893
  this.loadHistory();
15844
- this.setupRawMode();
15845
15894
  }
15846
15895
  loadHistory() {
15847
15896
  try {
@@ -15865,332 +15914,273 @@ var TUI = class {
15865
15914
  } catch {
15866
15915
  }
15867
15916
  }
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
15917
  setOnCancelRequest(cb) {
15878
15918
  this.onCancelRequest = cb;
15879
15919
  }
15880
15920
  start() {
15881
15921
  this.running = true;
15882
- this.showPrompt();
15883
- this.startKeyListener();
15884
- }
15885
- startKeyListener() {
15886
15922
  if (!process.stdin.isTTY) {
15887
15923
  this.startLineMode();
15888
15924
  return;
15889
15925
  }
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;
15908
- }
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;
15926
+ this.startTTYMode();
15927
+ }
15928
+ startLineMode() {
15929
+ const { createInterface } = require("readline");
15930
+ const rl = createInterface({ input: process.stdin, output: process.stdout, prompt: "" });
15931
+ rl.on("line", (line) => {
15932
+ const trimmed = line.trim();
15933
+ if (trimmed && this.onInput) {
15934
+ this.addHistory(trimmed);
15935
+ this.onInput(trimmed);
15938
15936
  }
15939
- if (input === "\f") {
15940
- void this.handleSpecialKey("ctrl_l");
15941
- return;
15937
+ rl.prompt();
15938
+ });
15939
+ rl.on("SIGINT", () => process.exit(0));
15940
+ rl.prompt();
15941
+ }
15942
+ startTTYMode() {
15943
+ try {
15944
+ process.stdin.setRawMode?.(true);
15945
+ } catch {
15946
+ }
15947
+ (0, import_readline.emitKeypressEvents)(process.stdin);
15948
+ this.inputBuffer = "";
15949
+ this.cursorPos = 0;
15950
+ this.popupLineCount = 0;
15951
+ process.stdin.on("keypress", this.handleKeypress.bind(this));
15952
+ this.renderScreen();
15953
+ }
15954
+ async handleKeypress(str, key) {
15955
+ if (!this.running) return;
15956
+ if (!key) key = {};
15957
+ const k = key.name || "";
15958
+ const c = key.ctrl || false;
15959
+ if (this.popupActive) {
15960
+ await this.handlePopupKeypress(str, key);
15961
+ return;
15962
+ }
15963
+ if (k === "escape") {
15964
+ if (this.inputBuffer.length > 0) {
15965
+ this.inputBuffer = "";
15966
+ this.cursorPos = 0;
15942
15967
  }
15943
- if (input === "") {
15944
- void this.handleSpecialKey("ctrl_a");
15945
- return;
15968
+ this.renderScreen();
15969
+ return;
15970
+ }
15971
+ if (k === "return" || k === "enter") {
15972
+ const input = this.inputBuffer.trim();
15973
+ this.inputBuffer = "";
15974
+ this.cursorPos = 0;
15975
+ if (input) {
15976
+ this.addHistory(input);
15977
+ if (this.onInput) {
15978
+ await this.onInput(input);
15979
+ }
15946
15980
  }
15947
- if (input === "") {
15948
- void this.handleSpecialKey("ctrl_e");
15949
- return;
15981
+ this.renderScreen();
15982
+ return;
15983
+ }
15984
+ if (k === "backspace") {
15985
+ if (this.cursorPos > 0) {
15986
+ this.inputBuffer = this.inputBuffer.slice(0, this.cursorPos - 1) + this.inputBuffer.slice(this.cursorPos);
15987
+ this.cursorPos--;
15950
15988
  }
15951
- if (input === "\n" || input === "\r") {
15952
- return;
15989
+ this.renderScreen();
15990
+ return;
15991
+ }
15992
+ if (k === "up") {
15993
+ if (this.inputHistory.length > 0) {
15994
+ if (this.historyIndex === -1) {
15995
+ this.historyIndex = this.inputHistory.length - 1;
15996
+ } else if (this.historyIndex > 0) {
15997
+ this.historyIndex--;
15998
+ }
15999
+ this.inputBuffer = this.inputHistory[this.historyIndex];
16000
+ this.cursorPos = this.inputBuffer.length;
15953
16001
  }
15954
- if (input === " ") {
15955
- void this.handleSpecialKey("tab");
15956
- return;
16002
+ this.renderScreen();
16003
+ return;
16004
+ }
16005
+ if (k === "down") {
16006
+ if (this.historyIndex >= 0) {
16007
+ this.historyIndex++;
16008
+ if (this.historyIndex >= this.inputHistory.length) {
16009
+ this.historyIndex = -1;
16010
+ this.inputBuffer = "";
16011
+ } else {
16012
+ this.inputBuffer = this.inputHistory[this.historyIndex];
16013
+ }
16014
+ this.cursorPos = this.inputBuffer.length;
15957
16015
  }
15958
- if (input === "") {
15959
- void this.handleSpecialKey("ctrl_o");
15960
- return;
16016
+ this.renderScreen();
16017
+ return;
16018
+ }
16019
+ if (k === "left") {
16020
+ if (this.cursorPos > 0) this.cursorPos--;
16021
+ this.renderScreen();
16022
+ return;
16023
+ }
16024
+ if (k === "right") {
16025
+ if (this.cursorPos < this.inputBuffer.length) this.cursorPos++;
16026
+ this.renderScreen();
16027
+ return;
16028
+ }
16029
+ if (k === "tab") {
16030
+ this.handleTab();
16031
+ this.renderScreen();
16032
+ return;
16033
+ }
16034
+ if (c && k === "c") {
16035
+ if (this.cancelRequested || this.status === "thinking" || this.status === "executing") {
16036
+ if (this.onCancelRequest) this.onCancelRequest();
16037
+ } else {
16038
+ this.printLine("");
16039
+ this.printLine(source_default.yellow("Use /exit to quit, or press Ctrl+C again to force quit"));
16040
+ this.cancelRequested = true;
16041
+ setTimeout(() => {
16042
+ this.cancelRequested = false;
16043
+ }, 2e3);
15961
16044
  }
15962
- if (input === "") {
15963
- void this.handleSpecialKey("ctrl_x");
16045
+ this.renderScreen();
16046
+ return;
16047
+ }
16048
+ if (c && k === "l") {
16049
+ this.clear();
16050
+ this.renderScreen();
16051
+ return;
16052
+ }
16053
+ if (c && k === "x") {
16054
+ await this.openExternalEditor();
16055
+ return;
16056
+ }
16057
+ if (c && k === "a") {
16058
+ this.cursorPos = 0;
16059
+ this.renderScreen();
16060
+ return;
16061
+ }
16062
+ if (c && k === "e") {
16063
+ this.cursorPos = this.inputBuffer.length;
16064
+ this.renderScreen();
16065
+ return;
16066
+ }
16067
+ if (str && str.length === 1 && str.charCodeAt(0) >= 32) {
16068
+ this.inputBuffer = this.inputBuffer.slice(0, this.cursorPos) + str + this.inputBuffer.slice(this.cursorPos);
16069
+ this.cursorPos++;
16070
+ if (str === "/") {
16071
+ this.popupActive = true;
16072
+ this.commandPopup.open();
16073
+ this.commandPopup.setFilter("");
16074
+ this.renderScreen();
15964
16075
  return;
15965
16076
  }
15966
- this.inputBuffer = this.inputBuffer.slice(0, this.cursorPos) + input + this.inputBuffer.slice(this.cursorPos);
15967
- this.cursorPos += input.length;
15968
- if (input === "/") {
16077
+ if (this.inputBuffer.startsWith("/") && this.inputBuffer.length > 1) {
15969
16078
  this.popupActive = true;
15970
16079
  this.commandPopup.open();
15971
- this.commandPopup.setFilter(input);
15972
- } 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
- }
16080
+ this.commandPopup.setFilter(this.inputBuffer.slice(1));
16081
+ this.renderScreen();
16082
+ return;
15978
16083
  }
15979
- this.renderScreen();
15980
- });
15981
- process.stdin.on("end", () => {
15982
- });
16084
+ }
16085
+ this.renderScreen();
15983
16086
  }
15984
- startLineMode() {
15985
- const { createInterface } = require("readline");
15986
- const rl = createInterface({ input: process.stdin, output: process.stdout, prompt: "" });
15987
- 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);
16087
+ clearPopupLines() {
16088
+ if (this.popupLineCount > 0) {
16089
+ try {
16090
+ (0, import_readline.moveCursor)(process.stdout, 0, -(this.popupLineCount + 1));
16091
+ } catch {
15992
16092
  }
15993
- this.inputBuffer = "";
15994
- this.showPrompt();
15995
- });
15996
- rl.on("SIGINT", () => process.exit(0));
15997
- this.showPrompt();
16093
+ for (let i = 0; i <= this.popupLineCount; i++) {
16094
+ try {
16095
+ (0, import_readline.cursorTo)(process.stdout, 0);
16096
+ (0, import_readline.clearLine)(process.stdout, 1);
16097
+ process.stdout.write("\n");
16098
+ } catch {
16099
+ }
16100
+ }
16101
+ this.popupLineCount = 0;
16102
+ }
15998
16103
  }
15999
- handlePopupKey(input) {
16000
- if (input === "\x1B") {
16104
+ async handlePopupKeypress(str, key) {
16105
+ const k = key.name || "";
16106
+ if (k === "escape") {
16107
+ this.clearPopupLines();
16001
16108
  this.popupActive = false;
16002
16109
  this.commandPopup.close();
16003
16110
  this.inputBuffer = "";
16004
16111
  this.cursorPos = 0;
16112
+ this.renderScreen();
16005
16113
  return;
16006
16114
  }
16007
- if (input === "\x1B[A" || input === "\x1BOA") {
16115
+ if (k === "up") {
16008
16116
  this.commandPopup.moveUp();
16117
+ this.renderScreen();
16009
16118
  return;
16010
16119
  }
16011
- if (input === "\x1B[B" || input === "\x1BOB") {
16120
+ if (k === "down") {
16012
16121
  this.commandPopup.moveDown();
16122
+ this.renderScreen();
16013
16123
  return;
16014
16124
  }
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;
16125
+ if (k === "return" || k === "enter") {
16126
+ const cmd = this.commandPopup.getSelectedCommand();
16127
+ this.popupActive = false;
16128
+ this.commandPopup.close();
16129
+ this.clearPopupLines();
16130
+ if (cmd) {
16131
+ const fullInput = `/${cmd} `;
16132
+ if (this.onInput) {
16133
+ await this.onInput(fullInput.trim());
16134
+ }
16023
16135
  }
16136
+ this.renderScreen();
16024
16137
  return;
16025
16138
  }
16026
- if (input === " ") {
16027
- const selectedCmd = this.commandPopup.getSelectedCommand();
16028
- if (selectedCmd) {
16139
+ if (k === "backspace") {
16140
+ this.commandPopup.deleteChar();
16141
+ const filter = this.commandPopup.getFilterText();
16142
+ if (filter.length === 0) {
16143
+ this.clearPopupLines();
16029
16144
  this.popupActive = false;
16030
16145
  this.commandPopup.close();
16031
- const fullCmd = `/${selectedCmd} `;
16032
- this.inputBuffer = fullCmd;
16033
- this.cursorPos = fullCmd.length;
16146
+ this.inputBuffer = "/";
16147
+ this.cursorPos = 1;
16034
16148
  }
16149
+ this.renderScreen();
16035
16150
  return;
16036
16151
  }
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();
16152
+ if (str && str.length === 1 && str.charCodeAt(0) >= 32) {
16153
+ this.commandPopup.appendChar(str);
16154
+ this.renderScreen();
16047
16155
  return;
16048
16156
  }
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
- }
16054
16157
  }
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":
16158
+ handleTab() {
16159
+ const match = this.inputBuffer.match(/^\/?(\w*)$/);
16160
+ if (match) {
16161
+ const partial = match[1].toLowerCase();
16162
+ const { ALL_COMMANDS: ALL_COMMANDS2 } = (init_CommandPopup(), __toCommonJS(CommandPopup_exports));
16163
+ const cmds = ALL_COMMANDS2.map((c) => c.command).filter((c) => c.startsWith(partial));
16164
+ if (cmds.length === 1) {
16165
+ this.inputBuffer = `/${cmds[0]} `;
16125
16166
  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
16167
  }
16171
16168
  }
16172
16169
  }
16173
- getAllCommands() {
16174
- const { ALL_COMMANDS: ALL_COMMANDS2 } = (init_CommandPopup(), __toCommonJS(CommandPopup_exports));
16175
- return ALL_COMMANDS2.map((c) => c.command);
16176
- }
16177
16170
  async openExternalEditor() {
16178
16171
  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");
16172
+ const { writeFileSync: writeFileSync7, unlinkSync: unlinkSync4, existsSync: existsSync11, mkdirSync: mkdirSync7, readFileSync: readFileSync11 } = await import("fs");
16181
16173
  const tmpDir = "/tmp/ys-agent";
16182
16174
  if (!existsSync11(tmpDir)) mkdirSync7(tmpDir, { recursive: true });
16183
- const tmpFile = join8(tmpDir, `input-${Date.now()}.md`);
16175
+ const tmpFile = `/tmp/ys-agent/input-${Date.now()}.md`;
16184
16176
  writeFileSync7(tmpFile, this.inputBuffer, "utf-8");
16185
16177
  const { execSync: execSync4 } = await import("child_process");
16186
16178
  try {
16187
16179
  execSync4(`${editor} "${tmpFile}"`, { stdio: "inherit" });
16188
- const { readFileSync: readFileSync11 } = await import("fs");
16189
16180
  const content = readFileSync11(tmpFile, "utf-8").trim();
16190
16181
  if (content) {
16191
16182
  this.inputBuffer = content;
16192
16183
  this.cursorPos = content.length;
16193
- this.renderScreen();
16194
16184
  }
16195
16185
  } catch {
16196
16186
  }
@@ -16198,6 +16188,69 @@ var TUI = class {
16198
16188
  unlinkSync4(tmpFile);
16199
16189
  } catch {
16200
16190
  }
16191
+ this.renderScreen();
16192
+ }
16193
+ renderScreen() {
16194
+ if (!process.stdout.isTTY) return;
16195
+ const promptLine2 = this.buildPromptLine();
16196
+ if (this.popupLineCount > 0) {
16197
+ try {
16198
+ (0, import_readline.moveCursor)(process.stdout, 0, -(this.popupLineCount + 1));
16199
+ } catch {
16200
+ }
16201
+ }
16202
+ if (this.popupActive && this.commandPopup.isVisible()) {
16203
+ const popup = this.commandPopup.render();
16204
+ const popupLines = popup.split("\n");
16205
+ this.popupLineCount = popupLines.length;
16206
+ for (const l of popupLines) {
16207
+ try {
16208
+ (0, import_readline.cursorTo)(process.stdout, 0);
16209
+ (0, import_readline.clearLine)(process.stdout, 1);
16210
+ process.stdout.write(l + "\n");
16211
+ } catch {
16212
+ }
16213
+ }
16214
+ } else {
16215
+ this.popupLineCount = 0;
16216
+ }
16217
+ try {
16218
+ (0, import_readline.cursorTo)(process.stdout, 0);
16219
+ (0, import_readline.clearLine)(process.stdout, 1);
16220
+ process.stdout.write(promptLine2);
16221
+ } catch {
16222
+ }
16223
+ }
16224
+ buildPromptPrefix() {
16225
+ const statusIndicator = STATUS_COLORS[this.status](INDICATORS[this.status]);
16226
+ const config = configManager.getConfig();
16227
+ const model = config.model.model;
16228
+ const modelShort = model.length > 18 ? model.slice(0, 16) + "\u2026" : model;
16229
+ let modeBadge2 = "";
16230
+ if (this.agentMode === "plan") modeBadge2 = source_default.blue(" [plan]");
16231
+ else if (this.agentMode === "goal") modeBadge2 = source_default.magenta(" [goal]");
16232
+ else if (this.agentMode === "arena") modeBadge2 = source_default.yellow(" [arena]");
16233
+ let approvalBadge2 = "";
16234
+ if (this.approvalMode === "safe") approvalBadge2 = source_default.cyan(" [safe]");
16235
+ else if (this.approvalMode === "yolo") approvalBadge2 = source_default.red(" [yolo]");
16236
+ return `${statusIndicator} ${source_default.cyan("ys")} ${source_default.yellow(`[${modelShort}]`)}${modeBadge2}${approvalBadge2} ${source_default.gray("\u203A")} `;
16237
+ }
16238
+ buildPromptLine() {
16239
+ const prefix = this.buildPromptPrefix();
16240
+ const input = this.inputBuffer || "";
16241
+ const cursor = source_default.gray("\u2588");
16242
+ let line;
16243
+ if (this.cursorPos >= input.length) {
16244
+ line = prefix + input + cursor;
16245
+ } else {
16246
+ const before = input.slice(0, this.cursorPos);
16247
+ const after = input.slice(this.cursorPos);
16248
+ line = prefix + before + cursor + after;
16249
+ }
16250
+ return line;
16251
+ }
16252
+ showPrompt() {
16253
+ if (this.running) this.renderScreen();
16201
16254
  }
16202
16255
  addHistory(input) {
16203
16256
  if (this.inputHistory[this.inputHistory.length - 1] !== input) {
@@ -16206,52 +16259,68 @@ var TUI = class {
16206
16259
  this.historyIndex = -1;
16207
16260
  this.saveHistory();
16208
16261
  }
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");
16262
+ setOnInput(handler) {
16263
+ this.onInput = handler;
16264
+ }
16265
+ setStatus(status) {
16266
+ this.status = status;
16267
+ }
16268
+ setApprovalMode(mode) {
16269
+ this.approvalMode = mode;
16270
+ }
16271
+ setAgentMode(mode) {
16272
+ this.agentMode = mode;
16273
+ }
16274
+ getApprovalMode() {
16275
+ return this.approvalMode;
16276
+ }
16277
+ getAgentMode() {
16278
+ return this.agentMode;
16279
+ }
16280
+ printLine(line) {
16281
+ if (!process.stdout.isTTY) {
16282
+ console.log(line);
16283
+ return;
16284
+ }
16214
16285
  try {
16215
- cursorToSync(process.stdout, 0, (process.stdout.rows || 24) - lines.length);
16216
- process.stdout.write(output);
16286
+ (0, import_readline.cursorTo)(process.stdout, 0);
16287
+ (0, import_readline.clearLine)(process.stdout, 1);
16288
+ process.stdout.write(line + "\n");
16217
16289
  } catch {
16290
+ console.log(line);
16218
16291
  }
16219
16292
  }
16220
- buildDisplayLines() {
16221
- const lines = [];
16222
- if (this.popupActive) {
16223
- const popupLines = this.commandPopup.render().split("\n");
16224
- lines.push(...popupLines);
16293
+ printAssistant(message) {
16294
+ const rendered = renderMarkdown(message);
16295
+ for (const line of rendered.split("\n")) {
16296
+ this.printLine(line);
16225
16297
  }
16226
- lines.push(this.buildPromptLine());
16227
- return lines;
16228
16298
  }
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();
16299
+ printWarning(message) {
16300
+ this.printLine(source_default.yellow(`\u26A0 ${message}`));
16239
16301
  }
16240
- clear() {
16241
- console.clear();
16302
+ printError(error) {
16303
+ const w = Math.max(Math.min(process.stdout.columns || 80, 56), 10);
16304
+ this.printLine(source_default.red(`\u2554${"\u2550".repeat(w)}\u2557`));
16305
+ 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`));
16306
+ this.printLine(source_default.red(`\u255A${"\u2550".repeat(w)}\u255D`));
16242
16307
  }
16243
- clearOutputLine() {
16244
- try {
16245
- const { cursorTo, clearLine } = require("readline");
16246
- cursorTo(process.stdout, 0);
16247
- clearLine(process.stdout, 1);
16248
- } catch {
16308
+ printToolCall(toolName, args) {
16309
+ const argsStr = Object.entries(args).slice(0, 3).map(([k, v]) => `${k}=${String(v).slice(0, 50)}`).join(", ");
16310
+ this.printLine(source_default.gray(` \u26A1 ${toolName}(${argsStr}${Object.keys(args).length > 3 ? ", ..." : ""})`));
16311
+ }
16312
+ printToolResult(result) {
16313
+ if (result.success) {
16314
+ this.printLine(source_default.gray(` \u2713 ${source_default.green("success")}`));
16315
+ } else {
16316
+ this.printLine(source_default.gray(` \u2715 ${source_default.red(result.error || "failed")}`));
16249
16317
  }
16250
16318
  }
16319
+ showStatusBar(_info) {
16320
+ }
16251
16321
  printWelcome() {
16252
16322
  const welcome = generateWelcome();
16253
- const lines = welcome.split("\n");
16254
- for (const line of lines) {
16323
+ for (const line of welcome.split("\n")) {
16255
16324
  this.printLine(line);
16256
16325
  }
16257
16326
  this.printLine("");
@@ -16312,183 +16381,24 @@ var TUI = class {
16312
16381
  lines.push(bottom);
16313
16382
  for (const l of lines) this.printLine(l);
16314
16383
  }
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;
16384
+ clear() {
16385
+ console.clear();
16382
16386
  }
16383
- printLine(line) {
16384
- if (!process.stdout.isTTY) {
16385
- console.log(line);
16386
- return;
16387
- }
16387
+ stop() {
16388
+ this.running = false;
16389
+ process.stdin.removeAllListeners("keypress");
16388
16390
  try {
16389
- const { cursorTo, clearLine } = require("readline");
16390
- cursorTo(process.stdout, 0);
16391
- clearLine(process.stdout, 1);
16392
- console.log(line);
16391
+ process.stdin.setRawMode?.(false);
16393
16392
  } catch {
16394
- console.log(line);
16395
- }
16396
- this.outputLines.push(line);
16397
- if (this.outputLines.length > this.maxOutputLines) {
16398
- this.outputLines.shift();
16399
16393
  }
16400
16394
  }
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 ? ", ..." : ""})`));
16418
- }
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")}`));
16424
- }
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("");
16464
- }
16465
16395
  destroy() {
16466
- if (this.stdinRaw && process.stdin.isTTY) {
16467
- try {
16468
- process.stdin.setRawMode?.(false);
16469
- } catch {
16470
- }
16471
- }
16472
- process.stdin.removeAllListeners("data");
16396
+ this.stop();
16473
16397
  }
16474
16398
  getOutputLineCount() {
16475
- return this.outputLines.length;
16399
+ return 0;
16476
16400
  }
16477
16401
  };
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
16402
  var tui = new TUI();
16493
16403
 
16494
16404
  // src/cli/interactive.ts
@@ -17713,7 +17623,7 @@ reg({
17713
17623
  Session Recap:`));
17714
17624
  tui.printLine(` ID: ${source_default.yellow(session.id.slice(0, 8))}`);
17715
17625
  tui.printLine(` Name: ${source_default.yellow(session.name)}`);
17716
- tui.printLine(` Duration: ${source_default.yellow(formatDuration3(duration))}`);
17626
+ tui.printLine(` Duration: ${source_default.yellow(formatDuration2(duration))}`);
17717
17627
  tui.printLine(` Messages: ${source_default.yellow(String(messages.length))} (${userMsgs.length} user, ${asstMsgs.length} assistant)`);
17718
17628
  return true;
17719
17629
  }
@@ -18295,7 +18205,7 @@ function getProgressBar(pct, width) {
18295
18205
  const color = pct > 80 ? source_default.red : pct > 50 ? source_default.yellow : source_default.green;
18296
18206
  return color(fillChar.repeat(filled)) + source_default.gray(emptyChar.repeat(empty));
18297
18207
  }
18298
- function formatDuration3(ms) {
18208
+ function formatDuration2(ms) {
18299
18209
  if (ms < 1e3) return `${ms}ms`;
18300
18210
  if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
18301
18211
  const m = Math.floor(ms / 6e4);
@@ -18829,10 +18739,10 @@ var InteractiveMode = class {
18829
18739
  const config = configManager.getConfig();
18830
18740
  const provider = configManager.getActiveProvider();
18831
18741
  if (!provider.apiKey && !process.env[`${provider.type.toUpperCase()}_API_KEY`]) {
18832
- console.log(source_default.yellow(`
18742
+ tui.printLine(source_default.yellow(`
18833
18743
  \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"));
18744
+ tui.printLine(source_default.gray(` Set ${provider.type.toUpperCase()}_API_KEY environment variable`));
18745
+ tui.printLine(source_default.gray(" Or use /provider <name> to switch to a configured provider"));
18836
18746
  }
18837
18747
  }
18838
18748
  async handleInput(input) {
@@ -18898,7 +18808,7 @@ var InteractiveMode = class {
18898
18808
  // src/cli/index.ts
18899
18809
  var import_fs10 = require("fs");
18900
18810
  var logger18 = getLogger("cli");
18901
- var APP_VERSION = true ? "2.0.1" : "1.0.0";
18811
+ var APP_VERSION = true ? "3.0.0" : "1.0.0";
18902
18812
  var program2 = new Command();
18903
18813
  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
18814
  initializeTools();
@@ -19181,6 +19091,7 @@ async function main() {
19181
19091
  return;
19182
19092
  }
19183
19093
  applyGlobalOptions(rawArgs);
19094
+ initializeTools();
19184
19095
  showBanner();
19185
19096
  const interactive = new InteractiveMode();
19186
19097
  await interactive.start();