opencode-auto-agent 1.3.1 → 1.3.2

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": "opencode-auto-agent",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "Scaffold and run an AI agent team powered by Ralphy + OpenCode. Presets for Java, Spring Boot, Next.js, and more.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/lib/ui.js CHANGED
@@ -428,12 +428,12 @@ export function table(headers, rows) {
428
428
  return Math.max(stripAnsi(h).length, maxData) + 2;
429
429
  });
430
430
 
431
- const headerLine = headers.map((h, i) => c.bold(h.padEnd(colWidths[i]))).join(c.gray(" \u2502 "));
431
+ const headerLine = headers.map((h, i) => c.bold(padAnsiEnd(h, colWidths[i]))).join(c.gray(" \u2502 "));
432
432
  console.log(` ${headerLine}`);
433
433
  console.log(` ${colWidths.map((w) => c.gray(BOX.h.repeat(w))).join(c.gray("\u2500\u253c\u2500"))}`);
434
434
 
435
435
  for (const row of rows) {
436
- const line = row.map((cell, i) => String(cell || "").padEnd(colWidths[i])).join(c.gray(" \u2502 "));
436
+ const line = row.map((cell, i) => padAnsiEnd(cell, colWidths[i])).join(c.gray(" \u2502 "));
437
437
  console.log(` ${line}`);
438
438
  }
439
439
  }
@@ -448,6 +448,13 @@ export function stripAnsi(str) {
448
448
  return str.replace(/\x1b\[[0-9;]*m/g, "");
449
449
  }
450
450
 
451
+ function padAnsiEnd(value, width) {
452
+ const text = String(value || "");
453
+ const visible = stripAnsi(text).length;
454
+ if (visible >= width) return text;
455
+ return text + " ".repeat(width - visible);
456
+ }
457
+
451
458
  /**
452
459
  * Truncate a string to maxLen, adding ellipsis if needed.
453
460
  */
@@ -1,7 +1,7 @@
1
1
  import test from "node:test";
2
2
  import assert from "node:assert/strict";
3
3
 
4
- import { buildSelectedIndexSet, getVisibleWindow, getMaxVisibleMenuItems } from "./ui.js";
4
+ import { buildSelectedIndexSet, getVisibleWindow, getMaxVisibleMenuItems, table, c, stripAnsi } from "./ui.js";
5
5
 
6
6
  test("buildSelectedIndexSet keeps original indexes", () => {
7
7
  const items = [
@@ -39,3 +39,35 @@ test("getMaxVisibleMenuItems enforces safe min/max", () => {
39
39
  assert.equal(getMaxVisibleMenuItems(12), 6);
40
40
  assert.equal(getMaxVisibleMenuItems(40), 20);
41
41
  });
42
+
43
+ test("table aligns ANSI-styled cells", () => {
44
+ const output = [];
45
+ const originalLog = console.log;
46
+ console.log = (line) => output.push(stripAnsi(String(line)));
47
+
48
+ try {
49
+ table(
50
+ ["Agent Role", "Model", "Mode"],
51
+ [
52
+ [c.bold("orchestrator"), c.cyan("google/gemini-3-pro"), c.gray("primary")],
53
+ [c.bold("qa"), c.cyan("openai/gpt-5.3-codex"), c.gray("subagent")],
54
+ ]
55
+ );
56
+ } finally {
57
+ console.log = originalLog;
58
+ }
59
+
60
+ assert.ok(output.length >= 4);
61
+ const firstRow = output[2];
62
+ const secondRow = output[3];
63
+
64
+ const firstSeps = [...firstRow.matchAll(/│/g)].map((m) => m.index);
65
+ const secondSeps = [...secondRow.matchAll(/│/g)].map((m) => m.index);
66
+
67
+ assert.equal(firstSeps.length, 2);
68
+ assert.equal(secondSeps.length, 2);
69
+ assert.deepEqual(firstSeps, secondSeps);
70
+ assert.ok(firstRow.includes("orchestrator"));
71
+ assert.ok(firstRow.includes("google/gemini-3-pro"));
72
+ assert.ok(secondRow.includes("openai/gpt-5.3-codex"));
73
+ });