@hackerrank/astra-cli 0.1.32 → 0.1.33

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hackerrank/astra-cli",
3
- "version": "0.1.32",
3
+ "version": "0.1.33",
4
4
  "description": "Minimal zero-dependency AI coding agent for the HackerRank AI Gateway.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -538,7 +538,7 @@ async function main() {
538
538
  `${Number(args.steps) > 0 ? ` turns<=${args.steps}` : ""}\x1b[0m`
539
539
  );
540
540
  console.error(`\x1b[2m[astra] workspace -> ${benchRun.workspace}\x1b[0m`);
541
- console.error(`\x1b[2m[astra] session -> ${sessionId}\x1b[0m`);
541
+ console.error(`\x1b[2m[astra] To resume session use: astra --resume ${sessionId}\x1b[0m`);
542
542
  } else {
543
543
  console.error(
544
544
  `\x1b[2m[astra] bench · model=${modelId} cwd=${cmdCwd}` +
@@ -618,7 +618,7 @@ async function main() {
618
618
  : "") +
619
619
  `\x1b[0m`
620
620
  );
621
- console.error(`\x1b[2m[astra] session -> ${sessionId}\x1b[0m`);
621
+ console.error(`\x1b[2m[astra] To resume session use: astra --resume ${sessionId}\x1b[0m`);
622
622
  }
623
623
  if (result.submission) console.log(result.submission);
624
624
 
package/src/repl.js CHANGED
@@ -159,11 +159,12 @@ function footerLines(agent, model, yolo, mode = "agent") {
159
159
  C.dim(rule),
160
160
  modeTag + " " + C.cyan(repoLabel()) + " " + C.dim(modelBits.join(" ")),
161
161
  C.dim(usage),
162
- C.dim("shift+return: newline · opt+left/right: model · opt+up/down: reasoning · shift+tab: mode"),
162
+ C.dim("shift+return: newline · opt+left/right: model · opt+up/down: reasoning · opt+tab: mode · ctrl+y: yolo"),
163
163
  ];
164
164
  }
165
165
 
166
166
  const FOOTER_LINES = 4; // divider + repo/model + usage + shortcuts
167
+ const LOADER_LINES = 1; // permanently reserved row below the divider
167
168
  const PROMPT_PREFIX = C.green("› "); // live input row (minimal)
168
169
  const HISTORY_PREFIX = C.green("you › "); // echoed into transcript/history
169
170
  const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
@@ -310,16 +311,16 @@ export class Screen {
310
311
  get rows() { return this.out.rows || 24; }
311
312
 
312
313
  get promptLines() {
313
- if (this._busy) return 1;
314
314
  const visual = computeVisualLines(this.buf, this.promptLabel || PROMPT_PREFIX, this.cols);
315
- const maxLines = Math.max(1, Math.floor((this.rows - FOOTER_LINES) / 2));
315
+ const maxLines = Math.max(1, Math.floor((this.rows - FOOTER_LINES - LOADER_LINES) / 2));
316
316
  return Math.min(visual.length, maxLines);
317
317
  }
318
318
 
319
- get reserved() { return FOOTER_LINES + this.promptLines; }
319
+ get reserved() { return FOOTER_LINES + LOADER_LINES + this.promptLines; }
320
320
  get scrollBottom() { return Math.max(1, this.rows - this.reserved); }
321
321
  get footerTop() { return this.scrollBottom + 1; }
322
- get promptRow() { return this.footerTop + 1; }
322
+ get loaderRow() { return this.footerTop + 1; }
323
+ get promptRow() { return this.loaderRow + LOADER_LINES; }
323
324
  get statusStartRow() { return this.promptRow + this.promptLines; }
324
325
 
325
326
  /** Enter sticky mode: set scroll margin, park cursor, start listening. */
@@ -384,12 +385,16 @@ export class Screen {
384
385
  this.out.write(`\x1b[${this.footerTop};1H`);
385
386
  this.out.write(this.footer[0] || "");
386
387
 
387
- // Draw prompt (or busy spinner)
388
+ // The loader has its own permanently reserved row. This prevents a busy
389
+ // transition from moving the input or status rows and causing terminal flicker.
388
390
  if (this._busy) {
389
- this.out.write(`\x1b[${this.promptRow};1H`);
391
+ this.out.write(`\x1b[${this.loaderRow};1H`);
390
392
  const frame = SPINNER_FRAMES[this._busyFrame % SPINNER_FRAMES.length];
391
393
  this.out.write(C.cyan(frame + " ") + C.dim(this._busyLabel + "…"));
392
- } else {
394
+ }
395
+
396
+ // Draw the input below the reserved loader row.
397
+ if (!this._busy) {
393
398
  const visual = computeVisualLines(this.buf, this.promptLabel || PROMPT_PREFIX, this.cols);
394
399
  const visibleLines = visual.slice(-this.promptLines);
395
400
  for (let i = 0; i < visibleLines.length; i++) {
@@ -529,6 +534,13 @@ export class Screen {
529
534
  this.onToggleMode();
530
535
  return;
531
536
  }
537
+
538
+ // Yolo toggle: Ctrl+Y
539
+ if (this.onToggleYolo && s === "\x19") {
540
+ this._clearEscLatch();
541
+ this.onToggleYolo();
542
+ return;
543
+ }
532
544
  {
533
545
  const opt = matchOptionArrow(s, false);
534
546
  if (opt) {
@@ -649,9 +661,10 @@ Interactive commands:
649
661
 
650
662
  Keyboard shortcuts:
651
663
  shift+return insert a newline for multi-line input (alt/opt+enter also works)
652
- alt/opt+tab switch agent / bench mode (shift+tab also works)
664
+ opt+tab switch agent / bench mode
653
665
  opt+left/right cycle the model
654
666
  opt+up/down cycle reasoning effort (off/low/medium/high)
667
+ ctrl+y toggle auto-run of commands (yolo mode)
655
668
  esc clear the input line
656
669
  `;
657
670
 
@@ -692,6 +705,13 @@ async function runStickyRepl(agent, model, yolo, intro = [], { runBench = null }
692
705
  refresh();
693
706
  };
694
707
 
708
+
709
+ // Ctrl+Y toggles yolo (auto-run) mode.
710
+ screen.onToggleYolo = () => {
711
+ yolo = !yolo;
712
+ log(C.dim(`[astra] auto-run ${yolo ? "ON" : "OFF"}.`));
713
+ refresh();
714
+ };
695
715
  // Option+Left/Right cycles the model; Option+Up/Down cycles reasoning effort.
696
716
  // Changes apply to the live model and are cached as the preferred agent
697
717
  // prefs so the next `astra` launch reuses them.