@robota-sdk/agent-cli 3.0.0-beta.16 → 3.0.0-beta.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node/bin.cjs CHANGED
@@ -24,22 +24,273 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/cli.ts
27
- var import_node_util = require("util");
28
27
  var import_node_fs3 = require("fs");
29
28
  var import_node_path3 = require("path");
30
29
  var import_node_url = require("url");
31
- var readline = __toESM(require("readline"), 1);
32
30
  var import_agent_sdk2 = require("@robota-sdk/agent-sdk");
33
31
  var import_agent_sdk3 = require("@robota-sdk/agent-sdk");
34
32
 
33
+ // src/utils/cli-args.ts
34
+ var import_node_util = require("util");
35
+ var VALID_MODES = ["plan", "default", "acceptEdits", "bypassPermissions"];
36
+ function parsePermissionMode(raw) {
37
+ if (raw === void 0) return void 0;
38
+ if (!VALID_MODES.includes(raw)) {
39
+ process.stderr.write(`Invalid --permission-mode "${raw}". Valid: ${VALID_MODES.join(" | ")}
40
+ `);
41
+ process.exit(1);
42
+ }
43
+ return raw;
44
+ }
45
+ function parseMaxTurns(raw) {
46
+ if (raw === void 0) return void 0;
47
+ const n = parseInt(raw, 10);
48
+ if (isNaN(n) || n <= 0) {
49
+ process.stderr.write(`Invalid --max-turns "${raw}". Must be a positive integer.
50
+ `);
51
+ process.exit(1);
52
+ }
53
+ return n;
54
+ }
55
+ function parseCliArgs() {
56
+ const { values, positionals } = (0, import_node_util.parseArgs)({
57
+ allowPositionals: true,
58
+ options: {
59
+ p: { type: "boolean", short: "p", default: false },
60
+ c: { type: "boolean", short: "c", default: false },
61
+ r: { type: "string", short: "r" },
62
+ model: { type: "string" },
63
+ "permission-mode": { type: "string" },
64
+ "max-turns": { type: "string" },
65
+ version: { type: "boolean", default: false },
66
+ reset: { type: "boolean", default: false }
67
+ }
68
+ });
69
+ return {
70
+ positional: positionals,
71
+ printMode: values["p"] ?? false,
72
+ continueMode: values["c"] ?? false,
73
+ resumeId: values["r"],
74
+ model: values["model"],
75
+ permissionMode: parsePermissionMode(values["permission-mode"]),
76
+ maxTurns: parseMaxTurns(values["max-turns"]),
77
+ version: values["version"] ?? false,
78
+ reset: values["reset"] ?? false
79
+ };
80
+ }
81
+
82
+ // src/utils/settings-io.ts
83
+ var import_node_fs = require("fs");
84
+ var import_node_path = require("path");
85
+ function getUserSettingsPath() {
86
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? "/";
87
+ return (0, import_node_path.join)(home, ".robota", "settings.json");
88
+ }
89
+ function readSettings(path) {
90
+ if (!(0, import_node_fs.existsSync)(path)) return {};
91
+ return JSON.parse((0, import_node_fs.readFileSync)(path, "utf8"));
92
+ }
93
+ function writeSettings(path, settings) {
94
+ (0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(path), { recursive: true });
95
+ (0, import_node_fs.writeFileSync)(path, JSON.stringify(settings, null, 2) + "\n", "utf8");
96
+ }
97
+ function updateModelInSettings(settingsPath, modelId) {
98
+ const settings = readSettings(settingsPath);
99
+ const provider = settings.provider ?? {};
100
+ provider.model = modelId;
101
+ settings.provider = provider;
102
+ writeSettings(settingsPath, settings);
103
+ }
104
+ function deleteSettings(path) {
105
+ if ((0, import_node_fs.existsSync)(path)) {
106
+ (0, import_node_fs.unlinkSync)(path);
107
+ return true;
108
+ }
109
+ return false;
110
+ }
111
+
112
+ // src/print-terminal.ts
113
+ var readline = __toESM(require("readline"), 1);
114
+ var PrintTerminal = class {
115
+ write(text) {
116
+ process.stdout.write(text);
117
+ }
118
+ writeLine(text) {
119
+ process.stdout.write(text + "\n");
120
+ }
121
+ writeMarkdown(md) {
122
+ process.stdout.write(md);
123
+ }
124
+ writeError(text) {
125
+ process.stderr.write(text + "\n");
126
+ }
127
+ prompt(question) {
128
+ return new Promise((resolve) => {
129
+ const rl = readline.createInterface({
130
+ input: process.stdin,
131
+ output: process.stdout,
132
+ terminal: false,
133
+ historySize: 0
134
+ });
135
+ rl.question(question, (answer) => {
136
+ rl.close();
137
+ resolve(answer);
138
+ });
139
+ });
140
+ }
141
+ async select(options, initialIndex = 0) {
142
+ for (let i = 0; i < options.length; i++) {
143
+ const marker = i === initialIndex ? ">" : " ";
144
+ process.stdout.write(` ${marker} ${i + 1}) ${options[i]}
145
+ `);
146
+ }
147
+ const answer = await this.prompt(
148
+ ` Choose [1-${options.length}] (default: ${options[initialIndex]}): `
149
+ );
150
+ const trimmed = answer.trim().toLowerCase();
151
+ if (trimmed === "") return initialIndex;
152
+ const num = parseInt(trimmed, 10);
153
+ if (!isNaN(num) && num >= 1 && num <= options.length) return num - 1;
154
+ return initialIndex;
155
+ }
156
+ spinner(_message) {
157
+ return { stop() {
158
+ }, update() {
159
+ } };
160
+ }
161
+ };
162
+
35
163
  // src/ui/render.tsx
36
164
  var import_ink10 = require("ink");
37
165
 
38
166
  // src/ui/App.tsx
39
167
  var import_react6 = require("react");
40
168
  var import_ink9 = require("ink");
41
- var import_node_fs2 = require("fs");
42
- var import_node_path2 = require("path");
169
+
170
+ // src/commands/slash-executor.ts
171
+ var VALID_MODES2 = ["plan", "default", "acceptEdits", "bypassPermissions"];
172
+ var HELP_TEXT = [
173
+ "Available commands:",
174
+ " /help \u2014 Show this help",
175
+ " /clear \u2014 Clear conversation",
176
+ " /compact [instr] \u2014 Compact context (optional focus instructions)",
177
+ " /mode [m] \u2014 Show/change permission mode",
178
+ " /cost \u2014 Show session info",
179
+ " /reset \u2014 Delete settings and exit",
180
+ " /exit \u2014 Exit CLI"
181
+ ].join("\n");
182
+ function handleHelp(addMessage) {
183
+ addMessage({ role: "system", content: HELP_TEXT });
184
+ return { handled: true };
185
+ }
186
+ function handleClear(addMessage, clearMessages, session) {
187
+ clearMessages();
188
+ session.clearHistory();
189
+ addMessage({ role: "system", content: "Conversation cleared." });
190
+ return { handled: true };
191
+ }
192
+ async function handleCompact(args, session, addMessage) {
193
+ const instructions = args.trim() || void 0;
194
+ const before = session.getContextState().usedPercentage;
195
+ addMessage({ role: "system", content: "Compacting context..." });
196
+ await session.compact(instructions);
197
+ const after = session.getContextState().usedPercentage;
198
+ addMessage({
199
+ role: "system",
200
+ content: `Context compacted: ${Math.round(before)}% -> ${Math.round(after)}%`
201
+ });
202
+ return { handled: true };
203
+ }
204
+ function handleMode(arg, session, addMessage) {
205
+ if (!arg) {
206
+ addMessage({ role: "system", content: `Current mode: ${session.getPermissionMode()}` });
207
+ } else if (VALID_MODES2.includes(arg)) {
208
+ session.setPermissionMode(arg);
209
+ addMessage({ role: "system", content: `Permission mode set to: ${arg}` });
210
+ } else {
211
+ addMessage({ role: "system", content: `Invalid mode. Valid: ${VALID_MODES2.join(" | ")}` });
212
+ }
213
+ return { handled: true };
214
+ }
215
+ function handleModel(modelId, addMessage) {
216
+ if (!modelId) {
217
+ addMessage({ role: "system", content: "Select a model from the /model submenu." });
218
+ return { handled: true };
219
+ }
220
+ return { handled: true, pendingModelId: modelId };
221
+ }
222
+ function handleCost(session, addMessage) {
223
+ addMessage({
224
+ role: "system",
225
+ content: `Session: ${session.getSessionId()}
226
+ Messages: ${session.getMessageCount()}`
227
+ });
228
+ return { handled: true };
229
+ }
230
+ function handlePermissions(session, addMessage) {
231
+ const mode = session.getPermissionMode();
232
+ const sessionAllowed = session.getSessionAllowedTools();
233
+ const lines = [`Permission mode: ${mode}`];
234
+ if (sessionAllowed.length > 0) {
235
+ lines.push(`Session-approved tools: ${sessionAllowed.join(", ")}`);
236
+ } else {
237
+ lines.push("No session-approved tools.");
238
+ }
239
+ addMessage({ role: "system", content: lines.join("\n") });
240
+ return { handled: true };
241
+ }
242
+ function handleContext(session, addMessage) {
243
+ const ctx = session.getContextState();
244
+ addMessage({
245
+ role: "system",
246
+ content: `Context: ${ctx.usedTokens.toLocaleString()} / ${ctx.maxTokens.toLocaleString()} tokens (${Math.round(ctx.usedPercentage)}%)`
247
+ });
248
+ return { handled: true };
249
+ }
250
+ function handleReset(addMessage) {
251
+ const settingsPath = getUserSettingsPath();
252
+ if (deleteSettings(settingsPath)) {
253
+ addMessage({ role: "system", content: `Deleted ${settingsPath}. Exiting...` });
254
+ } else {
255
+ addMessage({ role: "system", content: "No user settings found." });
256
+ }
257
+ return { handled: true, exitRequested: true };
258
+ }
259
+ async function executeSlashCommand(cmd, args, session, addMessage, clearMessages, registry) {
260
+ switch (cmd) {
261
+ case "help":
262
+ return handleHelp(addMessage);
263
+ case "clear":
264
+ return handleClear(addMessage, clearMessages, session);
265
+ case "compact":
266
+ return handleCompact(args, session, addMessage);
267
+ case "mode":
268
+ return handleMode(args.split(/\s+/)[0] || void 0, session, addMessage);
269
+ case "model":
270
+ return handleModel(args.split(/\s+/)[0] || void 0, addMessage);
271
+ case "cost":
272
+ return handleCost(session, addMessage);
273
+ case "permissions":
274
+ return handlePermissions(session, addMessage);
275
+ case "context":
276
+ return handleContext(session, addMessage);
277
+ case "reset":
278
+ return handleReset(addMessage);
279
+ case "exit":
280
+ return { handled: true, exitRequested: true };
281
+ default: {
282
+ const skillCmd = registry.getCommands().find((c) => c.name === cmd && c.source === "skill");
283
+ if (skillCmd) {
284
+ addMessage({ role: "system", content: `Invoking skill: ${cmd}` });
285
+ return { handled: false };
286
+ }
287
+ addMessage({ role: "system", content: `Unknown command "/${cmd}". Type /help for help.` });
288
+ return { handled: true };
289
+ }
290
+ }
291
+ }
292
+
293
+ // src/ui/App.tsx
43
294
  var import_agent_sdk = require("@robota-sdk/agent-sdk");
44
295
  var import_agent_core3 = require("@robota-sdk/agent-core");
45
296
 
@@ -130,8 +381,8 @@ var BuiltinCommandSource = class {
130
381
  };
131
382
 
132
383
  // src/commands/skill-source.ts
133
- var import_node_fs = require("fs");
134
- var import_node_path = require("path");
384
+ var import_node_fs2 = require("fs");
385
+ var import_node_path2 = require("path");
135
386
  var import_node_os = require("os");
136
387
  function parseFrontmatter(content) {
137
388
  const lines = content.split("\n");
@@ -154,14 +405,14 @@ function parseFrontmatter(content) {
154
405
  return name ? { name, description } : null;
155
406
  }
156
407
  function scanSkillsDir(skillsDir) {
157
- if (!(0, import_node_fs.existsSync)(skillsDir)) return [];
408
+ if (!(0, import_node_fs2.existsSync)(skillsDir)) return [];
158
409
  const commands = [];
159
- const entries = (0, import_node_fs.readdirSync)(skillsDir, { withFileTypes: true });
410
+ const entries = (0, import_node_fs2.readdirSync)(skillsDir, { withFileTypes: true });
160
411
  for (const entry of entries) {
161
412
  if (!entry.isDirectory()) continue;
162
- const skillFile = (0, import_node_path.join)(skillsDir, entry.name, "SKILL.md");
163
- if (!(0, import_node_fs.existsSync)(skillFile)) continue;
164
- const content = (0, import_node_fs.readFileSync)(skillFile, "utf-8");
413
+ const skillFile = (0, import_node_path2.join)(skillsDir, entry.name, "SKILL.md");
414
+ if (!(0, import_node_fs2.existsSync)(skillFile)) continue;
415
+ const content = (0, import_node_fs2.readFileSync)(skillFile, "utf-8");
165
416
  const frontmatter = parseFrontmatter(content);
166
417
  commands.push({
167
418
  name: frontmatter?.name ?? entry.name,
@@ -181,8 +432,8 @@ var SkillCommandSource = class {
181
432
  }
182
433
  getCommands() {
183
434
  if (this.cachedCommands) return this.cachedCommands;
184
- const projectSkills = scanSkillsDir((0, import_node_path.join)(this.cwd, ".agents", "skills"));
185
- const userSkills = scanSkillsDir((0, import_node_path.join)((0, import_node_os.homedir)(), ".claude", "skills"));
435
+ const projectSkills = scanSkillsDir((0, import_node_path2.join)(this.cwd, ".agents", "skills"));
436
+ const userSkills = scanSkillsDir((0, import_node_path2.join)((0, import_node_os.homedir)(), ".claude", "skills"));
186
437
  const seen = new Set(projectSkills.map((cmd) => cmd.name));
187
438
  const merged = [...projectSkills];
188
439
  for (const cmd of userSkills) {
@@ -724,6 +975,33 @@ function PermissionPrompt({ request }) {
724
975
  ] });
725
976
  }
726
977
 
978
+ // src/utils/tool-call-extractor.ts
979
+ var TOOL_ARG_MAX_LENGTH = 80;
980
+ var TOOL_ARG_TRUNCATE_LENGTH = 77;
981
+ function extractToolCalls(history, startIndex) {
982
+ const lines = [];
983
+ for (let i = startIndex; i < history.length; i++) {
984
+ const msg = history[i];
985
+ if (msg.role === "assistant" && msg.toolCalls) {
986
+ for (const tc of msg.toolCalls) {
987
+ const value = parseFirstArgValue(tc.function.arguments);
988
+ const truncated = value.length > TOOL_ARG_MAX_LENGTH ? value.slice(0, TOOL_ARG_TRUNCATE_LENGTH) + "..." : value;
989
+ lines.push(`${tc.function.name}(${truncated})`);
990
+ }
991
+ }
992
+ }
993
+ return lines;
994
+ }
995
+ function parseFirstArgValue(argsJson) {
996
+ try {
997
+ const parsed = JSON.parse(argsJson);
998
+ const firstVal = Object.values(parsed)[0];
999
+ return typeof firstVal === "string" ? firstVal : JSON.stringify(firstVal);
1000
+ } catch {
1001
+ return argsJson;
1002
+ }
1003
+ }
1004
+
727
1005
  // src/ui/App.tsx
728
1006
  var import_jsx_runtime9 = require("react/jsx-runtime");
729
1007
  var msgIdCounter = 0;
@@ -806,121 +1084,23 @@ function useMessages() {
806
1084
  }, []);
807
1085
  return { messages, setMessages, addMessage };
808
1086
  }
809
- var HELP_TEXT = [
810
- "Available commands:",
811
- " /help \u2014 Show this help",
812
- " /clear \u2014 Clear conversation",
813
- " /compact [instr] \u2014 Compact context (optional focus instructions)",
814
- " /mode [m] \u2014 Show/change permission mode",
815
- " /cost \u2014 Show session info",
816
- " /reset \u2014 Delete settings and exit",
817
- " /exit \u2014 Exit CLI"
818
- ].join("\n");
819
- function handleModeCommand(arg, session, addMessage) {
820
- const validModes = ["plan", "default", "acceptEdits", "bypassPermissions"];
821
- if (!arg) {
822
- addMessage({ role: "system", content: `Current mode: ${session.getPermissionMode()}` });
823
- } else if (validModes.includes(arg)) {
824
- session.setPermissionMode(arg);
825
- addMessage({ role: "system", content: `Permission mode set to: ${arg}` });
826
- } else {
827
- addMessage({ role: "system", content: `Invalid mode. Valid: ${validModes.join(" | ")}` });
828
- }
829
- return true;
830
- }
831
- async function executeSlashCommand(cmd, parts, session, addMessage, setMessages, exit, registry, pendingModelChangeRef, setPendingModelId) {
832
- switch (cmd) {
833
- case "help":
834
- addMessage({ role: "system", content: HELP_TEXT });
835
- return true;
836
- case "clear":
837
- setMessages([]);
838
- session.clearHistory();
839
- addMessage({ role: "system", content: "Conversation cleared." });
840
- return true;
841
- case "compact": {
842
- const instructions = parts.slice(1).join(" ").trim() || void 0;
843
- const before = session.getContextState().usedPercentage;
844
- addMessage({ role: "system", content: "Compacting context..." });
845
- await session.compact(instructions);
846
- const after = session.getContextState().usedPercentage;
847
- addMessage({
848
- role: "system",
849
- content: `Context compacted: ${Math.round(before)}% -> ${Math.round(after)}%`
850
- });
851
- return true;
852
- }
853
- case "mode":
854
- return handleModeCommand(parts[1], session, addMessage);
855
- case "model": {
856
- const modelId = parts[1];
857
- if (!modelId) {
858
- addMessage({ role: "system", content: "Select a model from the /model submenu." });
859
- return true;
860
- }
861
- pendingModelChangeRef.current = modelId;
862
- setPendingModelId(modelId);
863
- return true;
864
- }
865
- case "cost":
866
- addMessage({
867
- role: "system",
868
- content: `Session: ${session.getSessionId()}
869
- Messages: ${session.getMessageCount()}`
870
- });
871
- return true;
872
- case "permissions": {
873
- const mode = session.getPermissionMode();
874
- const sessionAllowed = session.getSessionAllowedTools();
875
- const lines = [`Permission mode: ${mode}`];
876
- if (sessionAllowed.length > 0) {
877
- lines.push(`Session-approved tools: ${sessionAllowed.join(", ")}`);
878
- } else {
879
- lines.push("No session-approved tools.");
880
- }
881
- addMessage({ role: "system", content: lines.join("\n") });
882
- return true;
883
- }
884
- case "context": {
885
- const ctx = session.getContextState();
886
- addMessage({
887
- role: "system",
888
- content: `Context: ${ctx.usedTokens.toLocaleString()} / ${ctx.maxTokens.toLocaleString()} tokens (${Math.round(ctx.usedPercentage)}%)`
889
- });
890
- return true;
891
- }
892
- case "reset": {
893
- const home = process.env.HOME ?? process.env.USERPROFILE ?? "/";
894
- const settingsPath = `${home}/.robota/settings.json`;
895
- if ((0, import_node_fs2.existsSync)(settingsPath)) {
896
- (0, import_node_fs2.unlinkSync)(settingsPath);
897
- addMessage({ role: "system", content: `Deleted ${settingsPath}. Exiting...` });
898
- } else {
899
- addMessage({ role: "system", content: "No user settings found." });
900
- }
901
- setTimeout(() => exit(), 500);
902
- return true;
903
- }
904
- case "exit":
905
- exit();
906
- return true;
907
- default: {
908
- const skillCmd = registry.getCommands().find((c) => c.name === cmd && c.source === "skill");
909
- if (skillCmd) {
910
- addMessage({ role: "system", content: `Invoking skill: ${cmd}` });
911
- return false;
912
- }
913
- addMessage({ role: "system", content: `Unknown command "/${cmd}". Type /help for help.` });
914
- return true;
915
- }
916
- }
917
- }
1087
+ var EXIT_DELAY_MS = 500;
918
1088
  function useSlashCommands(session, addMessage, setMessages, exit, registry, pendingModelChangeRef, setPendingModelId) {
919
1089
  return (0, import_react6.useCallback)(
920
1090
  async (input) => {
921
1091
  const parts = input.slice(1).split(/\s+/);
922
1092
  const cmd = parts[0]?.toLowerCase() ?? "";
923
- return executeSlashCommand(cmd, parts, session, addMessage, setMessages, exit, registry, pendingModelChangeRef, setPendingModelId);
1093
+ const args = parts.slice(1).join(" ");
1094
+ const clearMessages = () => setMessages([]);
1095
+ const result = await executeSlashCommand(cmd, args, session, addMessage, clearMessages, registry);
1096
+ if (result.pendingModelId) {
1097
+ pendingModelChangeRef.current = result.pendingModelId;
1098
+ setPendingModelId(result.pendingModelId);
1099
+ }
1100
+ if (result.exitRequested) {
1101
+ setTimeout(() => exit(), EXIT_DELAY_MS);
1102
+ }
1103
+ return result.handled;
924
1104
  },
925
1105
  [session, addMessage, setMessages, exit, registry, pendingModelChangeRef, setPendingModelId]
926
1106
  );
@@ -946,24 +1126,10 @@ async function runSessionPrompt(prompt, session, addMessage, clearStreamingText,
946
1126
  const response = await session.run(prompt);
947
1127
  clearStreamingText();
948
1128
  const history = session.getHistory();
949
- const toolLines = [];
950
- for (let i = historyBefore; i < history.length; i++) {
951
- const msg = history[i];
952
- if (msg.role === "assistant" && msg.toolCalls) {
953
- for (const tc of msg.toolCalls) {
954
- let value = "";
955
- try {
956
- const parsed = JSON.parse(tc.function.arguments);
957
- const firstVal = Object.values(parsed)[0];
958
- value = typeof firstVal === "string" ? firstVal : JSON.stringify(firstVal);
959
- } catch {
960
- value = tc.function.arguments;
961
- }
962
- const truncated = value.length > 80 ? value.slice(0, 77) + "..." : value;
963
- toolLines.push(`${tc.function.name}(${truncated})`);
964
- }
965
- }
966
- }
1129
+ const toolLines = extractToolCalls(
1130
+ history,
1131
+ historyBefore
1132
+ );
967
1133
  if (toolLines.length > 0) {
968
1134
  addMessage({ role: "tool", content: toolLines.join("\n"), toolName: `${toolLines.length} tools` });
969
1135
  }
@@ -1102,17 +1268,8 @@ function App(props) {
1102
1268
  pendingModelChangeRef.current = null;
1103
1269
  if (index === 0) {
1104
1270
  try {
1105
- const home = process.env.HOME ?? process.env.USERPROFILE ?? "/";
1106
- const settingsPath = (0, import_node_path2.join)(home, ".robota", "settings.json");
1107
- let settings = {};
1108
- if ((0, import_node_fs2.existsSync)(settingsPath)) {
1109
- settings = JSON.parse((0, import_node_fs2.readFileSync)(settingsPath, "utf8"));
1110
- }
1111
- const provider = settings.provider ?? {};
1112
- provider.model = pendingModelId;
1113
- settings.provider = provider;
1114
- (0, import_node_fs2.mkdirSync)((0, import_node_path2.join)(home, ".robota"), { recursive: true });
1115
- (0, import_node_fs2.writeFileSync)(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
1271
+ const settingsPath = getUserSettingsPath();
1272
+ updateModelInSettings(settingsPath, pendingModelId);
1116
1273
  addMessage({ role: "system", content: `Model changed to ${(0, import_agent_core3.getModelName)(pendingModelId)}. Restarting...` });
1117
1274
  setTimeout(() => exit(), 500);
1118
1275
  } catch (err) {
@@ -1175,7 +1332,6 @@ function renderApp(options) {
1175
1332
 
1176
1333
  // src/cli.ts
1177
1334
  var import_meta = {};
1178
- var VALID_MODES = ["plan", "default", "acceptEdits", "bypassPermissions"];
1179
1335
  function readVersion() {
1180
1336
  try {
1181
1337
  const thisFile = (0, import_node_url.fileURLToPath)(import_meta.url);
@@ -1196,103 +1352,6 @@ function readVersion() {
1196
1352
  return "0.0.0";
1197
1353
  }
1198
1354
  }
1199
- function parsePermissionMode(raw) {
1200
- if (raw === void 0) return void 0;
1201
- if (!VALID_MODES.includes(raw)) {
1202
- process.stderr.write(`Invalid --permission-mode "${raw}". Valid: ${VALID_MODES.join(" | ")}
1203
- `);
1204
- process.exit(1);
1205
- }
1206
- return raw;
1207
- }
1208
- function parseMaxTurns(raw) {
1209
- if (raw === void 0) return void 0;
1210
- const n = parseInt(raw, 10);
1211
- if (isNaN(n) || n <= 0) {
1212
- process.stderr.write(`Invalid --max-turns "${raw}". Must be a positive integer.
1213
- `);
1214
- process.exit(1);
1215
- }
1216
- return n;
1217
- }
1218
- function parseCliArgs() {
1219
- const { values, positionals } = (0, import_node_util.parseArgs)({
1220
- allowPositionals: true,
1221
- options: {
1222
- p: { type: "boolean", short: "p", default: false },
1223
- c: { type: "boolean", short: "c", default: false },
1224
- r: { type: "string", short: "r" },
1225
- model: { type: "string" },
1226
- "permission-mode": { type: "string" },
1227
- "max-turns": { type: "string" },
1228
- version: { type: "boolean", default: false },
1229
- reset: { type: "boolean", default: false }
1230
- }
1231
- });
1232
- return {
1233
- positional: positionals,
1234
- printMode: values["p"] ?? false,
1235
- continueMode: values["c"] ?? false,
1236
- resumeId: values["r"],
1237
- model: values["model"],
1238
- permissionMode: parsePermissionMode(values["permission-mode"]),
1239
- maxTurns: parseMaxTurns(values["max-turns"]),
1240
- version: values["version"] ?? false,
1241
- reset: values["reset"] ?? false
1242
- };
1243
- }
1244
- var PrintTerminal = class {
1245
- write(text) {
1246
- process.stdout.write(text);
1247
- }
1248
- writeLine(text) {
1249
- process.stdout.write(text + "\n");
1250
- }
1251
- writeMarkdown(md) {
1252
- process.stdout.write(md);
1253
- }
1254
- writeError(text) {
1255
- process.stderr.write(text + "\n");
1256
- }
1257
- prompt(question) {
1258
- return new Promise((resolve) => {
1259
- const rl = readline.createInterface({
1260
- input: process.stdin,
1261
- output: process.stdout,
1262
- terminal: false,
1263
- historySize: 0
1264
- });
1265
- rl.question(question, (answer) => {
1266
- rl.close();
1267
- resolve(answer);
1268
- });
1269
- });
1270
- }
1271
- async select(options, initialIndex = 0) {
1272
- for (let i = 0; i < options.length; i++) {
1273
- const marker = i === initialIndex ? ">" : " ";
1274
- process.stdout.write(` ${marker} ${i + 1}) ${options[i]}
1275
- `);
1276
- }
1277
- const answer = await this.prompt(
1278
- ` Choose [1-${options.length}] (default: ${options[initialIndex]}): `
1279
- );
1280
- const trimmed = answer.trim().toLowerCase();
1281
- if (trimmed === "") return initialIndex;
1282
- const num = parseInt(trimmed, 10);
1283
- if (!isNaN(num) && num >= 1 && num <= options.length) return num - 1;
1284
- return initialIndex;
1285
- }
1286
- spinner(_message) {
1287
- return { stop() {
1288
- }, update() {
1289
- } };
1290
- }
1291
- };
1292
- function getUserSettingsPath() {
1293
- const home = process.env.HOME ?? process.env.USERPROFILE ?? "/";
1294
- return (0, import_node_path3.join)(home, ".robota", "settings.json");
1295
- }
1296
1355
  async function ensureConfig(cwd) {
1297
1356
  const userPath = getUserSettingsPath();
1298
1357
  const projectPath = (0, import_node_path3.join)(cwd, ".robota", "settings.json");
@@ -1358,8 +1417,7 @@ async function ensureConfig(cwd) {
1358
1417
  }
1359
1418
  function resetConfig() {
1360
1419
  const userPath = getUserSettingsPath();
1361
- if ((0, import_node_fs3.existsSync)(userPath)) {
1362
- (0, import_node_fs3.unlinkSync)(userPath);
1420
+ if (deleteSettings(userPath)) {
1363
1421
  process.stdout.write(`Deleted ${userPath}
1364
1422
  `);
1365
1423
  } else {
package/dist/node/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startCli
4
- } from "./chunk-OZHWJAII.js";
4
+ } from "./chunk-4WB3L3RU.js";
5
5
 
6
6
  // src/bin.ts
7
7
  process.on("uncaughtException", (err) => {