@robota-sdk/agent-cli 3.0.0-beta.50 → 3.0.0-beta.52

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.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startCli
4
- } from "./chunk-QNBFMSI5.js";
4
+ } from "./chunk-QZUCO4ZK.js";
5
5
 
6
6
  // src/bin.ts
7
7
  process.on("uncaughtException", (err) => {
@@ -169,6 +169,26 @@ import { randomUUID } from "crypto";
169
169
 
170
170
  // src/ui/tui-state-manager.ts
171
171
  var MAX_RENDERED_MESSAGES = 100;
172
+ var STREAMING_DEBOUNCE_MS = 300;
173
+ function createDebouncedNotify(notify, ms) {
174
+ let timer = null;
175
+ return {
176
+ schedule() {
177
+ if (!timer) {
178
+ timer = setTimeout(() => {
179
+ timer = null;
180
+ notify();
181
+ }, ms);
182
+ }
183
+ },
184
+ flush() {
185
+ if (timer) {
186
+ clearTimeout(timer);
187
+ timer = null;
188
+ }
189
+ }
190
+ };
191
+ }
172
192
  var TuiStateManager = class {
173
193
  // ── Rendering state ───────────────────────────────────────────
174
194
  history = [];
@@ -182,6 +202,7 @@ var TuiStateManager = class {
182
202
  onChange = null;
183
203
  // ── Internal ──────────────────────────────────────────────────
184
204
  streamBuf = "";
205
+ debouncedStreamNotify = createDebouncedNotify(() => this.notify(), STREAMING_DEBOUNCE_MS);
185
206
  notify() {
186
207
  this.onChange?.();
187
208
  }
@@ -189,7 +210,7 @@ var TuiStateManager = class {
189
210
  onTextDelta = (delta) => {
190
211
  this.streamBuf += delta;
191
212
  this.streamingText = this.streamBuf;
192
- this.notify();
213
+ this.debouncedStreamNotify.schedule();
193
214
  };
194
215
  onToolStart = (state) => {
195
216
  this.activeTools = [...this.activeTools, state];
@@ -207,6 +228,7 @@ var TuiStateManager = class {
207
228
  onThinking = (thinking) => {
208
229
  this.isThinking = thinking;
209
230
  if (thinking) {
231
+ this.debouncedStreamNotify.flush();
210
232
  this.streamBuf = "";
211
233
  this.streamingText = "";
212
234
  this.activeTools = [];
@@ -216,6 +238,7 @@ var TuiStateManager = class {
216
238
  this.notify();
217
239
  };
218
240
  onComplete = (result) => {
241
+ this.debouncedStreamNotify.flush();
219
242
  this.streamBuf = "";
220
243
  this.streamingText = "";
221
244
  this.activeTools = [];
@@ -227,12 +250,14 @@ var TuiStateManager = class {
227
250
  this.notify();
228
251
  };
229
252
  onInterrupted = () => {
253
+ this.debouncedStreamNotify.flush();
230
254
  this.streamBuf = "";
231
255
  this.streamingText = "";
232
256
  this.activeTools = [];
233
257
  this.notify();
234
258
  };
235
259
  onError = () => {
260
+ this.debouncedStreamNotify.flush();
236
261
  this.streamBuf = "";
237
262
  this.streamingText = "";
238
263
  this.activeTools = [];
@@ -917,7 +942,8 @@ function CjkTextInput({
917
942
  placeholder = "",
918
943
  focus = true,
919
944
  showCursor = true,
920
- availableWidth
945
+ availableWidth,
946
+ cursorHint = null
921
947
  }) {
922
948
  const valueRef = useRef2(value);
923
949
  const cursorRef = useRef2(value.length);
@@ -926,7 +952,7 @@ function CjkTextInput({
926
952
  const pasteBufferRef = useRef2("");
927
953
  if (value !== valueRef.current) {
928
954
  valueRef.current = value;
929
- cursorRef.current = value.length;
955
+ cursorRef.current = cursorHint != null ? Math.min(cursorHint, value.length) : value.length;
930
956
  }
931
957
  useInput(
932
958
  (input, key) => {
@@ -948,7 +974,7 @@ function CjkTextInput({
948
974
  isPastingRef.current = false;
949
975
  if (text.length > 0) {
950
976
  if (text.includes("\n") && onPaste) {
951
- onPaste(text);
977
+ onPaste(text, cursorRef.current);
952
978
  } else {
953
979
  const printable2 = filterPrintable(text);
954
980
  if (printable2.length > 0) {
@@ -987,7 +1013,7 @@ function CjkTextInput({
987
1013
  return;
988
1014
  }
989
1015
  if (input.length > 1 && (input.includes("\n") || input.includes("\r")) && onPaste) {
990
- onPaste(input.replace(/\r\n?/g, "\n"));
1016
+ onPaste(input.replace(/\r\n?/g, "\n"), cursorRef.current);
991
1017
  return;
992
1018
  }
993
1019
  if (key.leftArrow) {
@@ -1186,6 +1212,7 @@ function InputArea({
1186
1212
  sessionName
1187
1213
  }) {
1188
1214
  const [value, setValue] = useState4("");
1215
+ const [cursorHint, setCursorHint] = useState4(null);
1189
1216
  const pasteStore = useRef3(/* @__PURE__ */ new Map());
1190
1217
  const { stdout } = useStdout();
1191
1218
  const terminalColumns = stdout?.columns ?? 80;
@@ -1199,13 +1226,15 @@ function InputArea({
1199
1226
  isSubcommandMode,
1200
1227
  setShowPopup
1201
1228
  } = useAutocomplete(value, registry);
1202
- const handlePaste = useCallback2((text) => {
1229
+ const handlePaste = useCallback2((text, cursorPosition) => {
1203
1230
  pasteIdRef.current += 1;
1204
1231
  const id = pasteIdRef.current;
1205
1232
  pasteStore.current.set(id, text);
1206
1233
  const lineCount = text.split("\n").length;
1207
1234
  const label = `[Pasted text #${id} +${lineCount} lines]`;
1208
- setValue((prev) => prev ? `${prev} ${label}` : label);
1235
+ const newCursorPos = cursorPosition + label.length;
1236
+ setCursorHint(newCursorPos);
1237
+ setValue((prev) => prev.slice(0, cursorPosition) + label + prev.slice(cursorPosition));
1209
1238
  }, []);
1210
1239
  const tabCompleteCommand = useCallback2(
1211
1240
  (cmd) => {
@@ -1320,11 +1349,15 @@ function InputArea({
1320
1349
  CjkTextInput,
1321
1350
  {
1322
1351
  value,
1323
- onChange: setValue,
1352
+ onChange: (v) => {
1353
+ setValue(v);
1354
+ setCursorHint(null);
1355
+ },
1324
1356
  onSubmit: handleSubmit,
1325
1357
  onPaste: handlePaste,
1326
1358
  placeholder: "Type a message or /help",
1327
- availableWidth
1359
+ availableWidth,
1360
+ cursorHint
1328
1361
  }
1329
1362
  )
1330
1363
  ] }) })
@@ -197,6 +197,26 @@ var import_node_crypto = require("crypto");
197
197
 
198
198
  // src/ui/tui-state-manager.ts
199
199
  var MAX_RENDERED_MESSAGES = 100;
200
+ var STREAMING_DEBOUNCE_MS = 300;
201
+ function createDebouncedNotify(notify, ms) {
202
+ let timer = null;
203
+ return {
204
+ schedule() {
205
+ if (!timer) {
206
+ timer = setTimeout(() => {
207
+ timer = null;
208
+ notify();
209
+ }, ms);
210
+ }
211
+ },
212
+ flush() {
213
+ if (timer) {
214
+ clearTimeout(timer);
215
+ timer = null;
216
+ }
217
+ }
218
+ };
219
+ }
200
220
  var TuiStateManager = class {
201
221
  // ── Rendering state ───────────────────────────────────────────
202
222
  history = [];
@@ -210,6 +230,7 @@ var TuiStateManager = class {
210
230
  onChange = null;
211
231
  // ── Internal ──────────────────────────────────────────────────
212
232
  streamBuf = "";
233
+ debouncedStreamNotify = createDebouncedNotify(() => this.notify(), STREAMING_DEBOUNCE_MS);
213
234
  notify() {
214
235
  this.onChange?.();
215
236
  }
@@ -217,7 +238,7 @@ var TuiStateManager = class {
217
238
  onTextDelta = (delta) => {
218
239
  this.streamBuf += delta;
219
240
  this.streamingText = this.streamBuf;
220
- this.notify();
241
+ this.debouncedStreamNotify.schedule();
221
242
  };
222
243
  onToolStart = (state) => {
223
244
  this.activeTools = [...this.activeTools, state];
@@ -235,6 +256,7 @@ var TuiStateManager = class {
235
256
  onThinking = (thinking) => {
236
257
  this.isThinking = thinking;
237
258
  if (thinking) {
259
+ this.debouncedStreamNotify.flush();
238
260
  this.streamBuf = "";
239
261
  this.streamingText = "";
240
262
  this.activeTools = [];
@@ -244,6 +266,7 @@ var TuiStateManager = class {
244
266
  this.notify();
245
267
  };
246
268
  onComplete = (result) => {
269
+ this.debouncedStreamNotify.flush();
247
270
  this.streamBuf = "";
248
271
  this.streamingText = "";
249
272
  this.activeTools = [];
@@ -255,12 +278,14 @@ var TuiStateManager = class {
255
278
  this.notify();
256
279
  };
257
280
  onInterrupted = () => {
281
+ this.debouncedStreamNotify.flush();
258
282
  this.streamBuf = "";
259
283
  this.streamingText = "";
260
284
  this.activeTools = [];
261
285
  this.notify();
262
286
  };
263
287
  onError = () => {
288
+ this.debouncedStreamNotify.flush();
264
289
  this.streamBuf = "";
265
290
  this.streamingText = "";
266
291
  this.activeTools = [];
@@ -940,7 +965,8 @@ function CjkTextInput({
940
965
  placeholder = "",
941
966
  focus = true,
942
967
  showCursor = true,
943
- availableWidth
968
+ availableWidth,
969
+ cursorHint = null
944
970
  }) {
945
971
  const valueRef = (0, import_react4.useRef)(value);
946
972
  const cursorRef = (0, import_react4.useRef)(value.length);
@@ -949,7 +975,7 @@ function CjkTextInput({
949
975
  const pasteBufferRef = (0, import_react4.useRef)("");
950
976
  if (value !== valueRef.current) {
951
977
  valueRef.current = value;
952
- cursorRef.current = value.length;
978
+ cursorRef.current = cursorHint != null ? Math.min(cursorHint, value.length) : value.length;
953
979
  }
954
980
  (0, import_ink4.useInput)(
955
981
  (input, key) => {
@@ -971,7 +997,7 @@ function CjkTextInput({
971
997
  isPastingRef.current = false;
972
998
  if (text.length > 0) {
973
999
  if (text.includes("\n") && onPaste) {
974
- onPaste(text);
1000
+ onPaste(text, cursorRef.current);
975
1001
  } else {
976
1002
  const printable2 = filterPrintable(text);
977
1003
  if (printable2.length > 0) {
@@ -1010,7 +1036,7 @@ function CjkTextInput({
1010
1036
  return;
1011
1037
  }
1012
1038
  if (input.length > 1 && (input.includes("\n") || input.includes("\r")) && onPaste) {
1013
- onPaste(input.replace(/\r\n?/g, "\n"));
1039
+ onPaste(input.replace(/\r\n?/g, "\n"), cursorRef.current);
1014
1040
  return;
1015
1041
  }
1016
1042
  if (key.leftArrow) {
@@ -1209,6 +1235,7 @@ function InputArea({
1209
1235
  sessionName
1210
1236
  }) {
1211
1237
  const [value, setValue] = (0, import_react6.useState)("");
1238
+ const [cursorHint, setCursorHint] = (0, import_react6.useState)(null);
1212
1239
  const pasteStore = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
1213
1240
  const { stdout } = (0, import_ink7.useStdout)();
1214
1241
  const terminalColumns = stdout?.columns ?? 80;
@@ -1222,13 +1249,15 @@ function InputArea({
1222
1249
  isSubcommandMode,
1223
1250
  setShowPopup
1224
1251
  } = useAutocomplete(value, registry);
1225
- const handlePaste = (0, import_react6.useCallback)((text) => {
1252
+ const handlePaste = (0, import_react6.useCallback)((text, cursorPosition) => {
1226
1253
  pasteIdRef.current += 1;
1227
1254
  const id = pasteIdRef.current;
1228
1255
  pasteStore.current.set(id, text);
1229
1256
  const lineCount = text.split("\n").length;
1230
1257
  const label = `[Pasted text #${id} +${lineCount} lines]`;
1231
- setValue((prev) => prev ? `${prev} ${label}` : label);
1258
+ const newCursorPos = cursorPosition + label.length;
1259
+ setCursorHint(newCursorPos);
1260
+ setValue((prev) => prev.slice(0, cursorPosition) + label + prev.slice(cursorPosition));
1232
1261
  }, []);
1233
1262
  const tabCompleteCommand = (0, import_react6.useCallback)(
1234
1263
  (cmd) => {
@@ -1343,11 +1372,15 @@ function InputArea({
1343
1372
  CjkTextInput,
1344
1373
  {
1345
1374
  value,
1346
- onChange: setValue,
1375
+ onChange: (v) => {
1376
+ setValue(v);
1377
+ setCursorHint(null);
1378
+ },
1347
1379
  onSubmit: handleSubmit,
1348
1380
  onPaste: handlePaste,
1349
1381
  placeholder: "Type a message or /help",
1350
- availableWidth
1382
+ availableWidth,
1383
+ cursorHint
1351
1384
  }
1352
1385
  )
1353
1386
  ] }) })
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  startCli
3
- } from "./chunk-QNBFMSI5.js";
3
+ } from "./chunk-QZUCO4ZK.js";
4
4
  export {
5
5
  startCli
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robota-sdk/agent-cli",
3
- "version": "3.0.0-beta.50",
3
+ "version": "3.0.0-beta.52",
4
4
  "description": "AI coding assistant CLI built on Robota SDK",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,7 +33,7 @@
33
33
  "dist"
34
34
  ],
35
35
  "dependencies": {
36
- "@robota-sdk/agent-sessions": "3.0.0-beta.50",
36
+ "@robota-sdk/agent-sessions": "3.0.0-beta.52",
37
37
  "chalk": "^5.3.0",
38
38
  "cli-highlight": "^2.1.0",
39
39
  "ink": "^6.8.0",
@@ -44,10 +44,10 @@
44
44
  "marked-terminal": "^7.3.0",
45
45
  "react": "19.2.4",
46
46
  "string-width": "^8.2.0",
47
- "@robota-sdk/agent-core": "3.0.0-beta.50",
48
- "@robota-sdk/agent-provider-anthropic": "3.0.0-beta.50",
49
- "@robota-sdk/agent-transport-headless": "3.0.0-beta.50",
50
- "@robota-sdk/agent-sdk": "3.0.0-beta.50"
47
+ "@robota-sdk/agent-core": "3.0.0-beta.52",
48
+ "@robota-sdk/agent-transport-headless": "3.0.0-beta.52",
49
+ "@robota-sdk/agent-sdk": "3.0.0-beta.52",
50
+ "@robota-sdk/agent-provider-anthropic": "3.0.0-beta.52"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/marked": "^6.0.0",