swarm-code 0.1.20 → 0.1.21

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.
@@ -44,28 +44,31 @@ export function readTextInput(_prompt) {
44
44
  process.stdin.setRawMode(true);
45
45
  process.stdin.resume();
46
46
  process.stdin.setEncoding("utf-8");
47
- // Track how many terminal rows we've drawn so we can clear them
48
- let drawnRows = 0;
47
+ // How many rows below the top border the cursor sits after drawBox()
48
+ let cursorRowFromTop = 0;
49
+ let hasDrawn = false;
49
50
  function drawBox() {
50
51
  const out = process.stderr;
51
- // Clear previously drawn rows
52
- if (drawnRows > 0) {
53
- for (let i = 0; i < drawnRows; i++) {
54
- out.write("\x1b[1A\x1b[2K");
52
+ const promptVisibleLen = 2; // "❯ "
53
+ if (hasDrawn) {
54
+ // Move cursor from its current position back to the top border row
55
+ if (cursorRowFromTop > 0) {
56
+ out.write(`\x1b[${cursorRowFromTop}A`);
55
57
  }
58
+ out.write("\x1b[0G"); // go to column 0
59
+ out.write("\x1b[J"); // erase from cursor to end of screen
56
60
  }
61
+ hasDrawn = true;
57
62
  // Top border — thin dim line
58
63
  const topLine = `${BORDER_COLOR}${"─".repeat(w)}${RESET}`;
59
64
  out.write(`${topLine}\n`);
60
65
  // Content rows — dark background, full width
61
66
  const promptChar = `${ACCENT_COLOR}❯${RESET} `;
62
- const promptVisibleLen = 2; // "❯ "
63
67
  for (let i = 0; i < linesBuf.length; i++) {
64
68
  const lineText = linesBuf[i];
65
69
  const prefix = i === 0 ? promptChar : `${dim("·")} `;
66
- const prefixVisibleLen = promptVisibleLen;
67
70
  // How much space for text content
68
- const contentWidth = w - prefixVisibleLen;
71
+ const contentWidth = w - promptVisibleLen;
69
72
  // Truncate display if line is too long
70
73
  const displayText = lineText.length > contentWidth ? lineText.slice(0, contentWidth - 1) + "…" : lineText;
71
74
  const padding = Math.max(0, contentWidth - displayText.length);
@@ -76,7 +79,6 @@ export function readTextInput(_prompt) {
76
79
  out.write(`${bottomLine}\n`);
77
80
  // Hints
78
81
  out.write(`${dim(" enter submit esc exit")}\n`);
79
- drawnRows = linesBuf.length + 3; // top border + content lines + bottom border + hints
80
82
  // Position cursor inside the text area
81
83
  // We're at the bottom (after hints). Move up to the correct content row.
82
84
  const currentLineIdx = linesBuf.length - 1; // cursor is always on last line
@@ -85,6 +87,8 @@ export function readTextInput(_prompt) {
85
87
  // Move to correct column: prefix width + cursor position
86
88
  const col = promptVisibleLen + cursorPos + 1;
87
89
  out.write(`\x1b[${col}G`);
90
+ // Track where cursor ended up (row 0 = top border)
91
+ cursorRowFromTop = 1 + currentLineIdx;
88
92
  }
89
93
  // Initial draw
90
94
  process.stderr.write(HIDE_CURSOR);
@@ -106,8 +110,6 @@ export function readTextInput(_prompt) {
106
110
  linesBuf.push(line);
107
111
  cursorPos = line.length;
108
112
  }
109
- // Move cursor back to top of box before redraw
110
- moveCursorToBoxTop();
111
113
  drawBox();
112
114
  return;
113
115
  }
@@ -120,28 +122,24 @@ export function readTextInput(_prompt) {
120
122
  if (code === "C" && cursorPos < linesBuf[linesBuf.length - 1].length) {
121
123
  cursorPos++;
122
124
  i += 2;
123
- moveCursorToBoxTop();
124
125
  drawBox();
125
126
  continue;
126
127
  }
127
128
  if (code === "D" && cursorPos > 0) {
128
129
  cursorPos--;
129
130
  i += 2;
130
- moveCursorToBoxTop();
131
131
  drawBox();
132
132
  continue;
133
133
  }
134
134
  if (code === "H") {
135
135
  cursorPos = 0;
136
136
  i += 2;
137
- moveCursorToBoxTop();
138
137
  drawBox();
139
138
  continue;
140
139
  }
141
140
  if (code === "F") {
142
141
  cursorPos = linesBuf[linesBuf.length - 1].length;
143
142
  i += 2;
144
- moveCursorToBoxTop();
145
143
  drawBox();
146
144
  continue;
147
145
  }
@@ -179,7 +177,6 @@ export function readTextInput(_prompt) {
179
177
  const line = linesBuf[linesBuf.length - 1];
180
178
  linesBuf[linesBuf.length - 1] = line.slice(0, cursorPos - 1) + line.slice(cursorPos);
181
179
  cursorPos--;
182
- moveCursorToBoxTop();
183
180
  drawBox();
184
181
  }
185
182
  continue;
@@ -189,7 +186,6 @@ export function readTextInput(_prompt) {
189
186
  const line = linesBuf[linesBuf.length - 1];
190
187
  linesBuf[linesBuf.length - 1] = line.slice(0, cursorPos) + " " + line.slice(cursorPos);
191
188
  cursorPos += 2;
192
- moveCursorToBoxTop();
193
189
  drawBox();
194
190
  continue;
195
191
  }
@@ -198,31 +194,20 @@ export function readTextInput(_prompt) {
198
194
  const line = linesBuf[linesBuf.length - 1];
199
195
  linesBuf[linesBuf.length - 1] = line.slice(0, cursorPos) + ch + line.slice(cursorPos);
200
196
  cursorPos++;
201
- moveCursorToBoxTop();
202
197
  drawBox();
203
198
  }
204
199
  }
205
200
  };
206
- function moveCursorToBoxTop() {
207
- // From current cursor position (inside the text area), move to the line
208
- // before the top border so drawBox() can clear and redraw from there.
209
- // Current cursor is at content row (linesBuf.length - 1 from top border)
210
- // We need to go up past: content rows above cursor + top border
211
- // But drawBox handles clearing with drawnRows, so just go up to start
212
- const currentLineIdx = linesBuf.length - 1;
213
- const rowsUp = currentLineIdx + 1; // content lines above + top border
214
- if (rowsUp > 0) {
215
- process.stderr.write(`\x1b[${rowsUp}A`);
216
- }
217
- process.stderr.write("\x1b[0G");
218
- }
219
201
  function finishAndClear() {
220
202
  process.stdin.removeListener("data", onData);
221
203
  if (origRawMode !== undefined) {
222
204
  process.stdin.setRawMode(origRawMode);
223
205
  }
224
206
  // Move cursor to top of box and clear everything
225
- moveCursorToBoxTop();
207
+ if (cursorRowFromTop > 0) {
208
+ process.stderr.write(`\x1b[${cursorRowFromTop}A`);
209
+ }
210
+ process.stderr.write("\x1b[0G");
226
211
  process.stderr.write("\x1b[J"); // erase to end of screen
227
212
  // Write the submitted text as a clean line (so it's visible in scrollback)
228
213
  const fullText = linesBuf.join("\n").trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swarm-code",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "Open-source swarm-native coding agent orchestrator — spawns parallel coding agents in isolated git worktrees, built on RLM (arXiv:2512.24601)",
5
5
  "type": "module",
6
6
  "bin": {