@robota-sdk/agent-cli 3.0.0-beta.6 → 3.0.0-beta.8
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 +124 -2
- package/dist/node/bin.js +1 -1
- package/dist/node/{chunk-4DYVT4WI.js → chunk-ICKV3U6G.js} +125 -3
- package/dist/node/index.cjs +124 -2
- package/dist/node/index.js +1 -1
- package/package.json +3 -3
package/dist/node/bin.cjs
CHANGED
|
@@ -119,6 +119,7 @@ function createBuiltinCommands() {
|
|
|
119
119
|
{ name: "cost", description: "Show session info", source: "builtin" },
|
|
120
120
|
{ name: "context", description: "Context window info", source: "builtin" },
|
|
121
121
|
{ name: "permissions", description: "Permission rules", source: "builtin" },
|
|
122
|
+
{ name: "reset", description: "Delete settings and exit", source: "builtin" },
|
|
122
123
|
{ name: "exit", description: "Exit CLI", source: "builtin" }
|
|
123
124
|
];
|
|
124
125
|
}
|
|
@@ -774,6 +775,7 @@ var HELP_TEXT = [
|
|
|
774
775
|
" /compact [instr] \u2014 Compact context (optional focus instructions)",
|
|
775
776
|
" /mode [m] \u2014 Show/change permission mode",
|
|
776
777
|
" /cost \u2014 Show session info",
|
|
778
|
+
" /reset \u2014 Delete settings and exit",
|
|
777
779
|
" /exit \u2014 Exit CLI"
|
|
778
780
|
].join("\n");
|
|
779
781
|
function handleModeCommand(arg, session, addMessage) {
|
|
@@ -839,6 +841,19 @@ Messages: ${session.getMessageCount()}`
|
|
|
839
841
|
});
|
|
840
842
|
return true;
|
|
841
843
|
}
|
|
844
|
+
case "reset": {
|
|
845
|
+
const { existsSync: exists, unlinkSync: unlink } = await import("fs");
|
|
846
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "/";
|
|
847
|
+
const settingsPath = `${home}/.robota/settings.json`;
|
|
848
|
+
if (exists(settingsPath)) {
|
|
849
|
+
unlink(settingsPath);
|
|
850
|
+
addMessage({ role: "system", content: `Deleted ${settingsPath}. Exiting...` });
|
|
851
|
+
} else {
|
|
852
|
+
addMessage({ role: "system", content: "No user settings found." });
|
|
853
|
+
}
|
|
854
|
+
setTimeout(() => exit(), 500);
|
|
855
|
+
return true;
|
|
856
|
+
}
|
|
842
857
|
case "exit":
|
|
843
858
|
exit();
|
|
844
859
|
return true;
|
|
@@ -879,9 +894,32 @@ function StreamingIndicator({ text }) {
|
|
|
879
894
|
async function runSessionPrompt(prompt, session, addMessage, clearStreamingText, setIsThinking, setContextPercentage) {
|
|
880
895
|
setIsThinking(true);
|
|
881
896
|
clearStreamingText();
|
|
897
|
+
const historyBefore = session.getHistory().length;
|
|
882
898
|
try {
|
|
883
899
|
const response = await session.run(prompt);
|
|
884
900
|
clearStreamingText();
|
|
901
|
+
const history = session.getHistory();
|
|
902
|
+
const toolLines = [];
|
|
903
|
+
for (let i = historyBefore; i < history.length; i++) {
|
|
904
|
+
const msg = history[i];
|
|
905
|
+
if (msg.role === "assistant" && msg.toolCalls) {
|
|
906
|
+
for (const tc of msg.toolCalls) {
|
|
907
|
+
let value = "";
|
|
908
|
+
try {
|
|
909
|
+
const parsed = JSON.parse(tc.function.arguments);
|
|
910
|
+
const firstVal = Object.values(parsed)[0];
|
|
911
|
+
value = typeof firstVal === "string" ? firstVal : JSON.stringify(firstVal);
|
|
912
|
+
} catch {
|
|
913
|
+
value = tc.function.arguments;
|
|
914
|
+
}
|
|
915
|
+
const truncated = value.length > 80 ? value.slice(0, 77) + "..." : value;
|
|
916
|
+
toolLines.push(`${tc.function.name}(${truncated})`);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
if (toolLines.length > 0) {
|
|
921
|
+
addMessage({ role: "tool", content: toolLines.join("\n"), toolName: `${toolLines.length} tools` });
|
|
922
|
+
}
|
|
885
923
|
addMessage({ role: "assistant", content: response || "(empty response)" });
|
|
886
924
|
setContextPercentage(session.getContextState().usedPercentage);
|
|
887
925
|
} catch (err) {
|
|
@@ -1098,7 +1136,8 @@ function parseCliArgs() {
|
|
|
1098
1136
|
model: { type: "string" },
|
|
1099
1137
|
"permission-mode": { type: "string" },
|
|
1100
1138
|
"max-turns": { type: "string" },
|
|
1101
|
-
version: { type: "boolean", default: false }
|
|
1139
|
+
version: { type: "boolean", default: false },
|
|
1140
|
+
reset: { type: "boolean", default: false }
|
|
1102
1141
|
}
|
|
1103
1142
|
});
|
|
1104
1143
|
return {
|
|
@@ -1109,7 +1148,8 @@ function parseCliArgs() {
|
|
|
1109
1148
|
model: values["model"],
|
|
1110
1149
|
permissionMode: parsePermissionMode(values["permission-mode"]),
|
|
1111
1150
|
maxTurns: parseMaxTurns(values["max-turns"]),
|
|
1112
|
-
version: values["version"] ?? false
|
|
1151
|
+
version: values["version"] ?? false,
|
|
1152
|
+
reset: values["reset"] ?? false
|
|
1113
1153
|
};
|
|
1114
1154
|
}
|
|
1115
1155
|
var PrintTerminal = class {
|
|
@@ -1160,6 +1200,83 @@ var PrintTerminal = class {
|
|
|
1160
1200
|
} };
|
|
1161
1201
|
}
|
|
1162
1202
|
};
|
|
1203
|
+
function getUserSettingsPath() {
|
|
1204
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "/";
|
|
1205
|
+
return (0, import_node_path2.join)(home, ".robota", "settings.json");
|
|
1206
|
+
}
|
|
1207
|
+
async function ensureConfig(cwd) {
|
|
1208
|
+
const userPath = getUserSettingsPath();
|
|
1209
|
+
const projectPath = (0, import_node_path2.join)(cwd, ".robota", "settings.json");
|
|
1210
|
+
const localPath = (0, import_node_path2.join)(cwd, ".robota", "settings.local.json");
|
|
1211
|
+
if ((0, import_node_fs2.existsSync)(userPath) || (0, import_node_fs2.existsSync)(projectPath) || (0, import_node_fs2.existsSync)(localPath)) {
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1214
|
+
process.stdout.write("\n");
|
|
1215
|
+
process.stdout.write(" Welcome to Robota CLI!\n");
|
|
1216
|
+
process.stdout.write(" No configuration found. Let's set up your API key.\n");
|
|
1217
|
+
process.stdout.write("\n");
|
|
1218
|
+
const apiKey = await new Promise((resolve) => {
|
|
1219
|
+
process.stdout.write(" Anthropic API key: ");
|
|
1220
|
+
let input = "";
|
|
1221
|
+
const stdin = process.stdin;
|
|
1222
|
+
const wasRaw = stdin.isRaw;
|
|
1223
|
+
stdin.setRawMode(true);
|
|
1224
|
+
stdin.resume();
|
|
1225
|
+
stdin.setEncoding("utf8");
|
|
1226
|
+
const onData = (data) => {
|
|
1227
|
+
for (const ch of data) {
|
|
1228
|
+
if (ch === "\r" || ch === "\n") {
|
|
1229
|
+
stdin.removeListener("data", onData);
|
|
1230
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
1231
|
+
stdin.pause();
|
|
1232
|
+
process.stdout.write("\n");
|
|
1233
|
+
resolve(input.trim());
|
|
1234
|
+
return;
|
|
1235
|
+
} else if (ch === "\x7F" || ch === "\b") {
|
|
1236
|
+
if (input.length > 0) {
|
|
1237
|
+
input = input.slice(0, -1);
|
|
1238
|
+
process.stdout.write("\b \b");
|
|
1239
|
+
}
|
|
1240
|
+
} else if (ch === "") {
|
|
1241
|
+
process.stdout.write("\n");
|
|
1242
|
+
process.exit(0);
|
|
1243
|
+
} else if (ch.charCodeAt(0) >= 32) {
|
|
1244
|
+
input += ch;
|
|
1245
|
+
process.stdout.write("*");
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
stdin.on("data", onData);
|
|
1250
|
+
});
|
|
1251
|
+
if (!apiKey) {
|
|
1252
|
+
process.stderr.write("\n No API key provided. Exiting.\n");
|
|
1253
|
+
process.exit(1);
|
|
1254
|
+
}
|
|
1255
|
+
const settingsDir = (0, import_node_path2.dirname)(userPath);
|
|
1256
|
+
(0, import_node_fs2.mkdirSync)(settingsDir, { recursive: true });
|
|
1257
|
+
const settings = {
|
|
1258
|
+
provider: {
|
|
1259
|
+
name: "anthropic",
|
|
1260
|
+
model: "claude-sonnet-4-6",
|
|
1261
|
+
apiKey
|
|
1262
|
+
}
|
|
1263
|
+
};
|
|
1264
|
+
(0, import_node_fs2.writeFileSync)(userPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
1265
|
+
process.stdout.write(`
|
|
1266
|
+
Config saved to ${userPath}
|
|
1267
|
+
|
|
1268
|
+
`);
|
|
1269
|
+
}
|
|
1270
|
+
function resetConfig() {
|
|
1271
|
+
const userPath = getUserSettingsPath();
|
|
1272
|
+
if ((0, import_node_fs2.existsSync)(userPath)) {
|
|
1273
|
+
(0, import_node_fs2.unlinkSync)(userPath);
|
|
1274
|
+
process.stdout.write(`Deleted ${userPath}
|
|
1275
|
+
`);
|
|
1276
|
+
} else {
|
|
1277
|
+
process.stdout.write("No user settings found.\n");
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1163
1280
|
async function startCli() {
|
|
1164
1281
|
const args = parseCliArgs();
|
|
1165
1282
|
if (args.version) {
|
|
@@ -1167,7 +1284,12 @@ async function startCli() {
|
|
|
1167
1284
|
`);
|
|
1168
1285
|
return;
|
|
1169
1286
|
}
|
|
1287
|
+
if (args.reset) {
|
|
1288
|
+
resetConfig();
|
|
1289
|
+
return;
|
|
1290
|
+
}
|
|
1170
1291
|
const cwd = process.cwd();
|
|
1292
|
+
await ensureConfig(cwd);
|
|
1171
1293
|
const [config, context, projectInfo] = await Promise.all([
|
|
1172
1294
|
(0, import_agent_sdk2.loadConfig)(cwd),
|
|
1173
1295
|
(0, import_agent_sdk2.loadContext)(cwd),
|
package/dist/node/bin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/cli.ts
|
|
2
2
|
import { parseArgs } from "util";
|
|
3
|
-
import { readFileSync as readFileSync2 } from "fs";
|
|
3
|
+
import { readFileSync as readFileSync2, existsSync as existsSync2, mkdirSync, writeFileSync, unlinkSync } from "fs";
|
|
4
4
|
import { join as join2, dirname } from "path";
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
6
|
import * as readline from "readline";
|
|
@@ -102,6 +102,7 @@ function createBuiltinCommands() {
|
|
|
102
102
|
{ name: "cost", description: "Show session info", source: "builtin" },
|
|
103
103
|
{ name: "context", description: "Context window info", source: "builtin" },
|
|
104
104
|
{ name: "permissions", description: "Permission rules", source: "builtin" },
|
|
105
|
+
{ name: "reset", description: "Delete settings and exit", source: "builtin" },
|
|
105
106
|
{ name: "exit", description: "Exit CLI", source: "builtin" }
|
|
106
107
|
];
|
|
107
108
|
}
|
|
@@ -757,6 +758,7 @@ var HELP_TEXT = [
|
|
|
757
758
|
" /compact [instr] \u2014 Compact context (optional focus instructions)",
|
|
758
759
|
" /mode [m] \u2014 Show/change permission mode",
|
|
759
760
|
" /cost \u2014 Show session info",
|
|
761
|
+
" /reset \u2014 Delete settings and exit",
|
|
760
762
|
" /exit \u2014 Exit CLI"
|
|
761
763
|
].join("\n");
|
|
762
764
|
function handleModeCommand(arg, session, addMessage) {
|
|
@@ -822,6 +824,19 @@ Messages: ${session.getMessageCount()}`
|
|
|
822
824
|
});
|
|
823
825
|
return true;
|
|
824
826
|
}
|
|
827
|
+
case "reset": {
|
|
828
|
+
const { existsSync: exists, unlinkSync: unlink } = await import("fs");
|
|
829
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "/";
|
|
830
|
+
const settingsPath = `${home}/.robota/settings.json`;
|
|
831
|
+
if (exists(settingsPath)) {
|
|
832
|
+
unlink(settingsPath);
|
|
833
|
+
addMessage({ role: "system", content: `Deleted ${settingsPath}. Exiting...` });
|
|
834
|
+
} else {
|
|
835
|
+
addMessage({ role: "system", content: "No user settings found." });
|
|
836
|
+
}
|
|
837
|
+
setTimeout(() => exit(), 500);
|
|
838
|
+
return true;
|
|
839
|
+
}
|
|
825
840
|
case "exit":
|
|
826
841
|
exit();
|
|
827
842
|
return true;
|
|
@@ -862,9 +877,32 @@ function StreamingIndicator({ text }) {
|
|
|
862
877
|
async function runSessionPrompt(prompt, session, addMessage, clearStreamingText, setIsThinking, setContextPercentage) {
|
|
863
878
|
setIsThinking(true);
|
|
864
879
|
clearStreamingText();
|
|
880
|
+
const historyBefore = session.getHistory().length;
|
|
865
881
|
try {
|
|
866
882
|
const response = await session.run(prompt);
|
|
867
883
|
clearStreamingText();
|
|
884
|
+
const history = session.getHistory();
|
|
885
|
+
const toolLines = [];
|
|
886
|
+
for (let i = historyBefore; i < history.length; i++) {
|
|
887
|
+
const msg = history[i];
|
|
888
|
+
if (msg.role === "assistant" && msg.toolCalls) {
|
|
889
|
+
for (const tc of msg.toolCalls) {
|
|
890
|
+
let value = "";
|
|
891
|
+
try {
|
|
892
|
+
const parsed = JSON.parse(tc.function.arguments);
|
|
893
|
+
const firstVal = Object.values(parsed)[0];
|
|
894
|
+
value = typeof firstVal === "string" ? firstVal : JSON.stringify(firstVal);
|
|
895
|
+
} catch {
|
|
896
|
+
value = tc.function.arguments;
|
|
897
|
+
}
|
|
898
|
+
const truncated = value.length > 80 ? value.slice(0, 77) + "..." : value;
|
|
899
|
+
toolLines.push(`${tc.function.name}(${truncated})`);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
if (toolLines.length > 0) {
|
|
904
|
+
addMessage({ role: "tool", content: toolLines.join("\n"), toolName: `${toolLines.length} tools` });
|
|
905
|
+
}
|
|
868
906
|
addMessage({ role: "assistant", content: response || "(empty response)" });
|
|
869
907
|
setContextPercentage(session.getContextState().usedPercentage);
|
|
870
908
|
} catch (err) {
|
|
@@ -1080,7 +1118,8 @@ function parseCliArgs() {
|
|
|
1080
1118
|
model: { type: "string" },
|
|
1081
1119
|
"permission-mode": { type: "string" },
|
|
1082
1120
|
"max-turns": { type: "string" },
|
|
1083
|
-
version: { type: "boolean", default: false }
|
|
1121
|
+
version: { type: "boolean", default: false },
|
|
1122
|
+
reset: { type: "boolean", default: false }
|
|
1084
1123
|
}
|
|
1085
1124
|
});
|
|
1086
1125
|
return {
|
|
@@ -1091,7 +1130,8 @@ function parseCliArgs() {
|
|
|
1091
1130
|
model: values["model"],
|
|
1092
1131
|
permissionMode: parsePermissionMode(values["permission-mode"]),
|
|
1093
1132
|
maxTurns: parseMaxTurns(values["max-turns"]),
|
|
1094
|
-
version: values["version"] ?? false
|
|
1133
|
+
version: values["version"] ?? false,
|
|
1134
|
+
reset: values["reset"] ?? false
|
|
1095
1135
|
};
|
|
1096
1136
|
}
|
|
1097
1137
|
var PrintTerminal = class {
|
|
@@ -1142,6 +1182,83 @@ var PrintTerminal = class {
|
|
|
1142
1182
|
} };
|
|
1143
1183
|
}
|
|
1144
1184
|
};
|
|
1185
|
+
function getUserSettingsPath() {
|
|
1186
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "/";
|
|
1187
|
+
return join2(home, ".robota", "settings.json");
|
|
1188
|
+
}
|
|
1189
|
+
async function ensureConfig(cwd) {
|
|
1190
|
+
const userPath = getUserSettingsPath();
|
|
1191
|
+
const projectPath = join2(cwd, ".robota", "settings.json");
|
|
1192
|
+
const localPath = join2(cwd, ".robota", "settings.local.json");
|
|
1193
|
+
if (existsSync2(userPath) || existsSync2(projectPath) || existsSync2(localPath)) {
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
process.stdout.write("\n");
|
|
1197
|
+
process.stdout.write(" Welcome to Robota CLI!\n");
|
|
1198
|
+
process.stdout.write(" No configuration found. Let's set up your API key.\n");
|
|
1199
|
+
process.stdout.write("\n");
|
|
1200
|
+
const apiKey = await new Promise((resolve) => {
|
|
1201
|
+
process.stdout.write(" Anthropic API key: ");
|
|
1202
|
+
let input = "";
|
|
1203
|
+
const stdin = process.stdin;
|
|
1204
|
+
const wasRaw = stdin.isRaw;
|
|
1205
|
+
stdin.setRawMode(true);
|
|
1206
|
+
stdin.resume();
|
|
1207
|
+
stdin.setEncoding("utf8");
|
|
1208
|
+
const onData = (data) => {
|
|
1209
|
+
for (const ch of data) {
|
|
1210
|
+
if (ch === "\r" || ch === "\n") {
|
|
1211
|
+
stdin.removeListener("data", onData);
|
|
1212
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
1213
|
+
stdin.pause();
|
|
1214
|
+
process.stdout.write("\n");
|
|
1215
|
+
resolve(input.trim());
|
|
1216
|
+
return;
|
|
1217
|
+
} else if (ch === "\x7F" || ch === "\b") {
|
|
1218
|
+
if (input.length > 0) {
|
|
1219
|
+
input = input.slice(0, -1);
|
|
1220
|
+
process.stdout.write("\b \b");
|
|
1221
|
+
}
|
|
1222
|
+
} else if (ch === "") {
|
|
1223
|
+
process.stdout.write("\n");
|
|
1224
|
+
process.exit(0);
|
|
1225
|
+
} else if (ch.charCodeAt(0) >= 32) {
|
|
1226
|
+
input += ch;
|
|
1227
|
+
process.stdout.write("*");
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
};
|
|
1231
|
+
stdin.on("data", onData);
|
|
1232
|
+
});
|
|
1233
|
+
if (!apiKey) {
|
|
1234
|
+
process.stderr.write("\n No API key provided. Exiting.\n");
|
|
1235
|
+
process.exit(1);
|
|
1236
|
+
}
|
|
1237
|
+
const settingsDir = dirname(userPath);
|
|
1238
|
+
mkdirSync(settingsDir, { recursive: true });
|
|
1239
|
+
const settings = {
|
|
1240
|
+
provider: {
|
|
1241
|
+
name: "anthropic",
|
|
1242
|
+
model: "claude-sonnet-4-6",
|
|
1243
|
+
apiKey
|
|
1244
|
+
}
|
|
1245
|
+
};
|
|
1246
|
+
writeFileSync(userPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
1247
|
+
process.stdout.write(`
|
|
1248
|
+
Config saved to ${userPath}
|
|
1249
|
+
|
|
1250
|
+
`);
|
|
1251
|
+
}
|
|
1252
|
+
function resetConfig() {
|
|
1253
|
+
const userPath = getUserSettingsPath();
|
|
1254
|
+
if (existsSync2(userPath)) {
|
|
1255
|
+
unlinkSync(userPath);
|
|
1256
|
+
process.stdout.write(`Deleted ${userPath}
|
|
1257
|
+
`);
|
|
1258
|
+
} else {
|
|
1259
|
+
process.stdout.write("No user settings found.\n");
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1145
1262
|
async function startCli() {
|
|
1146
1263
|
const args = parseCliArgs();
|
|
1147
1264
|
if (args.version) {
|
|
@@ -1149,7 +1266,12 @@ async function startCli() {
|
|
|
1149
1266
|
`);
|
|
1150
1267
|
return;
|
|
1151
1268
|
}
|
|
1269
|
+
if (args.reset) {
|
|
1270
|
+
resetConfig();
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1152
1273
|
const cwd = process.cwd();
|
|
1274
|
+
await ensureConfig(cwd);
|
|
1153
1275
|
const [config, context, projectInfo] = await Promise.all([
|
|
1154
1276
|
loadConfig(cwd),
|
|
1155
1277
|
loadContext(cwd),
|
package/dist/node/index.cjs
CHANGED
|
@@ -135,6 +135,7 @@ function createBuiltinCommands() {
|
|
|
135
135
|
{ name: "cost", description: "Show session info", source: "builtin" },
|
|
136
136
|
{ name: "context", description: "Context window info", source: "builtin" },
|
|
137
137
|
{ name: "permissions", description: "Permission rules", source: "builtin" },
|
|
138
|
+
{ name: "reset", description: "Delete settings and exit", source: "builtin" },
|
|
138
139
|
{ name: "exit", description: "Exit CLI", source: "builtin" }
|
|
139
140
|
];
|
|
140
141
|
}
|
|
@@ -790,6 +791,7 @@ var HELP_TEXT = [
|
|
|
790
791
|
" /compact [instr] \u2014 Compact context (optional focus instructions)",
|
|
791
792
|
" /mode [m] \u2014 Show/change permission mode",
|
|
792
793
|
" /cost \u2014 Show session info",
|
|
794
|
+
" /reset \u2014 Delete settings and exit",
|
|
793
795
|
" /exit \u2014 Exit CLI"
|
|
794
796
|
].join("\n");
|
|
795
797
|
function handleModeCommand(arg, session, addMessage) {
|
|
@@ -855,6 +857,19 @@ Messages: ${session.getMessageCount()}`
|
|
|
855
857
|
});
|
|
856
858
|
return true;
|
|
857
859
|
}
|
|
860
|
+
case "reset": {
|
|
861
|
+
const { existsSync: exists, unlinkSync: unlink } = await import("fs");
|
|
862
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "/";
|
|
863
|
+
const settingsPath = `${home}/.robota/settings.json`;
|
|
864
|
+
if (exists(settingsPath)) {
|
|
865
|
+
unlink(settingsPath);
|
|
866
|
+
addMessage({ role: "system", content: `Deleted ${settingsPath}. Exiting...` });
|
|
867
|
+
} else {
|
|
868
|
+
addMessage({ role: "system", content: "No user settings found." });
|
|
869
|
+
}
|
|
870
|
+
setTimeout(() => exit(), 500);
|
|
871
|
+
return true;
|
|
872
|
+
}
|
|
858
873
|
case "exit":
|
|
859
874
|
exit();
|
|
860
875
|
return true;
|
|
@@ -895,9 +910,32 @@ function StreamingIndicator({ text }) {
|
|
|
895
910
|
async function runSessionPrompt(prompt, session, addMessage, clearStreamingText, setIsThinking, setContextPercentage) {
|
|
896
911
|
setIsThinking(true);
|
|
897
912
|
clearStreamingText();
|
|
913
|
+
const historyBefore = session.getHistory().length;
|
|
898
914
|
try {
|
|
899
915
|
const response = await session.run(prompt);
|
|
900
916
|
clearStreamingText();
|
|
917
|
+
const history = session.getHistory();
|
|
918
|
+
const toolLines = [];
|
|
919
|
+
for (let i = historyBefore; i < history.length; i++) {
|
|
920
|
+
const msg = history[i];
|
|
921
|
+
if (msg.role === "assistant" && msg.toolCalls) {
|
|
922
|
+
for (const tc of msg.toolCalls) {
|
|
923
|
+
let value = "";
|
|
924
|
+
try {
|
|
925
|
+
const parsed = JSON.parse(tc.function.arguments);
|
|
926
|
+
const firstVal = Object.values(parsed)[0];
|
|
927
|
+
value = typeof firstVal === "string" ? firstVal : JSON.stringify(firstVal);
|
|
928
|
+
} catch {
|
|
929
|
+
value = tc.function.arguments;
|
|
930
|
+
}
|
|
931
|
+
const truncated = value.length > 80 ? value.slice(0, 77) + "..." : value;
|
|
932
|
+
toolLines.push(`${tc.function.name}(${truncated})`);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
if (toolLines.length > 0) {
|
|
937
|
+
addMessage({ role: "tool", content: toolLines.join("\n"), toolName: `${toolLines.length} tools` });
|
|
938
|
+
}
|
|
901
939
|
addMessage({ role: "assistant", content: response || "(empty response)" });
|
|
902
940
|
setContextPercentage(session.getContextState().usedPercentage);
|
|
903
941
|
} catch (err) {
|
|
@@ -1114,7 +1152,8 @@ function parseCliArgs() {
|
|
|
1114
1152
|
model: { type: "string" },
|
|
1115
1153
|
"permission-mode": { type: "string" },
|
|
1116
1154
|
"max-turns": { type: "string" },
|
|
1117
|
-
version: { type: "boolean", default: false }
|
|
1155
|
+
version: { type: "boolean", default: false },
|
|
1156
|
+
reset: { type: "boolean", default: false }
|
|
1118
1157
|
}
|
|
1119
1158
|
});
|
|
1120
1159
|
return {
|
|
@@ -1125,7 +1164,8 @@ function parseCliArgs() {
|
|
|
1125
1164
|
model: values["model"],
|
|
1126
1165
|
permissionMode: parsePermissionMode(values["permission-mode"]),
|
|
1127
1166
|
maxTurns: parseMaxTurns(values["max-turns"]),
|
|
1128
|
-
version: values["version"] ?? false
|
|
1167
|
+
version: values["version"] ?? false,
|
|
1168
|
+
reset: values["reset"] ?? false
|
|
1129
1169
|
};
|
|
1130
1170
|
}
|
|
1131
1171
|
var PrintTerminal = class {
|
|
@@ -1176,6 +1216,83 @@ var PrintTerminal = class {
|
|
|
1176
1216
|
} };
|
|
1177
1217
|
}
|
|
1178
1218
|
};
|
|
1219
|
+
function getUserSettingsPath() {
|
|
1220
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "/";
|
|
1221
|
+
return (0, import_node_path2.join)(home, ".robota", "settings.json");
|
|
1222
|
+
}
|
|
1223
|
+
async function ensureConfig(cwd) {
|
|
1224
|
+
const userPath = getUserSettingsPath();
|
|
1225
|
+
const projectPath = (0, import_node_path2.join)(cwd, ".robota", "settings.json");
|
|
1226
|
+
const localPath = (0, import_node_path2.join)(cwd, ".robota", "settings.local.json");
|
|
1227
|
+
if ((0, import_node_fs2.existsSync)(userPath) || (0, import_node_fs2.existsSync)(projectPath) || (0, import_node_fs2.existsSync)(localPath)) {
|
|
1228
|
+
return;
|
|
1229
|
+
}
|
|
1230
|
+
process.stdout.write("\n");
|
|
1231
|
+
process.stdout.write(" Welcome to Robota CLI!\n");
|
|
1232
|
+
process.stdout.write(" No configuration found. Let's set up your API key.\n");
|
|
1233
|
+
process.stdout.write("\n");
|
|
1234
|
+
const apiKey = await new Promise((resolve) => {
|
|
1235
|
+
process.stdout.write(" Anthropic API key: ");
|
|
1236
|
+
let input = "";
|
|
1237
|
+
const stdin = process.stdin;
|
|
1238
|
+
const wasRaw = stdin.isRaw;
|
|
1239
|
+
stdin.setRawMode(true);
|
|
1240
|
+
stdin.resume();
|
|
1241
|
+
stdin.setEncoding("utf8");
|
|
1242
|
+
const onData = (data) => {
|
|
1243
|
+
for (const ch of data) {
|
|
1244
|
+
if (ch === "\r" || ch === "\n") {
|
|
1245
|
+
stdin.removeListener("data", onData);
|
|
1246
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
1247
|
+
stdin.pause();
|
|
1248
|
+
process.stdout.write("\n");
|
|
1249
|
+
resolve(input.trim());
|
|
1250
|
+
return;
|
|
1251
|
+
} else if (ch === "\x7F" || ch === "\b") {
|
|
1252
|
+
if (input.length > 0) {
|
|
1253
|
+
input = input.slice(0, -1);
|
|
1254
|
+
process.stdout.write("\b \b");
|
|
1255
|
+
}
|
|
1256
|
+
} else if (ch === "") {
|
|
1257
|
+
process.stdout.write("\n");
|
|
1258
|
+
process.exit(0);
|
|
1259
|
+
} else if (ch.charCodeAt(0) >= 32) {
|
|
1260
|
+
input += ch;
|
|
1261
|
+
process.stdout.write("*");
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
stdin.on("data", onData);
|
|
1266
|
+
});
|
|
1267
|
+
if (!apiKey) {
|
|
1268
|
+
process.stderr.write("\n No API key provided. Exiting.\n");
|
|
1269
|
+
process.exit(1);
|
|
1270
|
+
}
|
|
1271
|
+
const settingsDir = (0, import_node_path2.dirname)(userPath);
|
|
1272
|
+
(0, import_node_fs2.mkdirSync)(settingsDir, { recursive: true });
|
|
1273
|
+
const settings = {
|
|
1274
|
+
provider: {
|
|
1275
|
+
name: "anthropic",
|
|
1276
|
+
model: "claude-sonnet-4-6",
|
|
1277
|
+
apiKey
|
|
1278
|
+
}
|
|
1279
|
+
};
|
|
1280
|
+
(0, import_node_fs2.writeFileSync)(userPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
1281
|
+
process.stdout.write(`
|
|
1282
|
+
Config saved to ${userPath}
|
|
1283
|
+
|
|
1284
|
+
`);
|
|
1285
|
+
}
|
|
1286
|
+
function resetConfig() {
|
|
1287
|
+
const userPath = getUserSettingsPath();
|
|
1288
|
+
if ((0, import_node_fs2.existsSync)(userPath)) {
|
|
1289
|
+
(0, import_node_fs2.unlinkSync)(userPath);
|
|
1290
|
+
process.stdout.write(`Deleted ${userPath}
|
|
1291
|
+
`);
|
|
1292
|
+
} else {
|
|
1293
|
+
process.stdout.write("No user settings found.\n");
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1179
1296
|
async function startCli() {
|
|
1180
1297
|
const args = parseCliArgs();
|
|
1181
1298
|
if (args.version) {
|
|
@@ -1183,7 +1300,12 @@ async function startCli() {
|
|
|
1183
1300
|
`);
|
|
1184
1301
|
return;
|
|
1185
1302
|
}
|
|
1303
|
+
if (args.reset) {
|
|
1304
|
+
resetConfig();
|
|
1305
|
+
return;
|
|
1306
|
+
}
|
|
1186
1307
|
const cwd = process.cwd();
|
|
1308
|
+
await ensureConfig(cwd);
|
|
1187
1309
|
const [config, context, projectInfo] = await Promise.all([
|
|
1188
1310
|
(0, import_agent_sdk2.loadConfig)(cwd),
|
|
1189
1311
|
(0, import_agent_sdk2.loadContext)(cwd),
|
package/dist/node/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@robota-sdk/agent-cli",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.8",
|
|
4
4
|
"description": "AI coding assistant CLI built on Robota SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"marked-terminal": "^7.3.0",
|
|
36
36
|
"react": "19.2.4",
|
|
37
37
|
"string-width": "^8.2.0",
|
|
38
|
-
"@robota-sdk/agent-core": "3.0.0-beta.
|
|
39
|
-
"@robota-sdk/agent-sdk": "3.0.0-beta.
|
|
38
|
+
"@robota-sdk/agent-core": "3.0.0-beta.8",
|
|
39
|
+
"@robota-sdk/agent-sdk": "3.0.0-beta.8"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/marked": "^6.0.0",
|