termux-dev 1.4.14 → 1.4.15

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/assets/banner.svg CHANGED
@@ -25,7 +25,7 @@
25
25
 
26
26
  <!-- Tagline & Badge -->
27
27
  <text x="425" y="142" font-family="system-ui, -apple-system, sans-serif" font-size="14" font-weight="600" fill="#8b949e" text-anchor="middle" letter-spacing="3">
28
- THE TERMINAL-NATIVE AI CODING AGENT <tspan fill="#00f2fe" font-weight="bold">v1.4.14</tspan>
28
+ THE TERMINAL-NATIVE AI CODING AGENT <tspan fill="#00f2fe" font-weight="bold">v1.4.15</tspan>
29
29
  </text>
30
30
 
31
31
  <!-- Top Accent Line -->
@@ -18,7 +18,7 @@ async function pingUrl(url) {
18
18
  const req = https.get(url, {
19
19
  timeout: 3000,
20
20
  headers: {
21
- 'User-Agent': 'devx-doctor/1.4.14'
21
+ 'User-Agent': 'devx-doctor/1.4.15'
22
22
  }
23
23
  }, (res) => {
24
24
  res.resume(); // consume response data to free up memory and release socket
@@ -35,7 +35,7 @@ export async function runHeadlessMode(userPrompt, config, options = {}) {
35
35
  });
36
36
  try {
37
37
  if (!isQuiet && !isJson) {
38
- console.log(pc.bold(pc.cyan(`⚡ devx v1.4.14 (headless) | ${planMode ? 'PLAN' : 'AGENT'} | ${config.model}`)));
38
+ console.log(pc.bold(pc.cyan(`⚡ devx v1.4.15 (headless) | ${planMode ? 'PLAN' : 'AGENT'} | ${config.model}`)));
39
39
  console.log(pc.dim(`Task: ${userPrompt}\n`));
40
40
  }
41
41
  for await (const event of agent.run(abortController.signal)) {
package/dist/cli/index.js CHANGED
@@ -484,7 +484,7 @@ function drawLogo() {
484
484
  theme.colorFn(' █▀▀▄ █▀▀▀ █ █ █ █'),
485
485
  theme.colorFn(' █ █ █▀▀▀ ▀▄▀ ▀▄▀ '),
486
486
  theme.colorFn(' █▄▄▀ █▄▄▄ ▀ ▀ ▀ '),
487
- ' ' + theme.boldFn('v1.4.14'),
487
+ ' ' + theme.boldFn('v1.4.15'),
488
488
  ''
489
489
  ];
490
490
  for (const line of logo) {
@@ -499,7 +499,7 @@ function drawLogo() {
499
499
  indent + theme.colorFn('▀▀▀█▀▀▀ █▀▀▀ █▀▀█ █▄ ▄█ █ █ ▀▄ ▄▀ █▀▀▄ █▀▀▀ █ █'),
500
500
  indent + theme.colorFn(' █ █▀▀▀ █▄▄▀ █ █ █ █ █ █ ▀▀ █ █ █▀▀▀ █ █'),
501
501
  indent + theme.colorFn(' █ █▄▄▄ █ ▀▄ █ █ ▀▄▄▀ ▄▀ ▀▄ █▄▄▀ █▄▄▄ ▀▄▀ '),
502
- indent + theme.boldFn('v1.4.14'),
502
+ indent + theme.boldFn('v1.4.15'),
503
503
  ''
504
504
  ];
505
505
  for (const line of logo) {
@@ -645,7 +645,7 @@ async function handleSettings(config) {
645
645
  const maxIterLabel = maxIter >= 9999 ? 'Unlimited' : `${maxIter} steps`;
646
646
  const currentTh = getCurrentTheme();
647
647
  const choice = await select({
648
- message: `${pc.bold('⚙️ Settings')} ${pc.dim(`(devx v1.4.14 • theme: ${currentTh.name})`)}`,
648
+ message: `${pc.bold('⚙️ Settings')} ${pc.dim(`(devx v1.4.15 • theme: ${currentTh.name})`)}`,
649
649
  choices: [
650
650
  {
651
651
  name: `🎨 Color Theme: ${currentTh.emoji} ${currentTh.name}`,
@@ -686,7 +686,7 @@ async function handleSettings(config) {
686
686
  description: 'Limit how many tool steps (file edits, terminal commands) agent can do per request'
687
687
  },
688
688
  {
689
- name: `${currentTh.colorFn('✨ About devx')} ${pc.dim('(v1.4.14 by ApvCode)')}`,
689
+ name: `${currentTh.colorFn('✨ About devx')} ${pc.dim('(v1.4.15 by ApvCode)')}`,
690
690
  value: 'about',
691
691
  description: 'Terminal-Native AI Coding Agent created by ApvCode (https://github.com/apvcode/Termux-Dev)'
692
692
  },
@@ -702,7 +702,7 @@ async function handleSettings(config) {
702
702
  continue;
703
703
  }
704
704
  if (choice === 'about') {
705
- p.note(`⚡ devx v1.4.14 — Terminal-Native AI Coding Agent\n` +
705
+ p.note(`⚡ devx v1.4.15 — Terminal-Native AI Coding Agent\n` +
706
706
  `🎨 Theme: ${currentTh.emoji} ${currentTh.name}\n` +
707
707
  `👤 Author: ApvCode (https://github.com/apvcode)\n` +
708
708
  `🌟 Repository: https://github.com/apvcode/Termux-Dev\n` +
@@ -798,7 +798,7 @@ export async function main() {
798
798
  program
799
799
  .name('devx')
800
800
  .description('Terminal-native AI coding assistant and vibe-coding agent')
801
- .version('1.4.14')
801
+ .version('1.4.15')
802
802
  .option('-p, --prompt <task>', 'Run one-shot task non-interactively (headless mode)')
803
803
  .option('-y, --yolo', 'Automatically approve all tool executions without confirmation')
804
804
  .option('-m, --model <model>', 'Specify AI model to use for this execution')
@@ -177,7 +177,9 @@ export function askPrompt(opts = {}) {
177
177
  selectedIndex = items.length - 1;
178
178
  if (selectedIndex < 0)
179
179
  selectedIndex = 0;
180
- const pageSize = Math.min(4, Math.max(2, Math.floor(rows / 4)));
180
+ // On very small screens (keyboard open on Android), limit dropdown aggressively
181
+ const maxDropdownRows = Math.max(2, Math.min(rows - 3, 6));
182
+ const pageSize = Math.min(4, Math.max(2, Math.min(maxDropdownRows - 2, Math.floor(rows / 4))));
181
183
  const innerBoxWidth = Math.max(10, Math.min(cols - 8, 48));
182
184
  const total = items.length;
183
185
  let startIndex = 0;
@@ -236,6 +238,8 @@ export function askPrompt(opts = {}) {
236
238
  }
237
239
  dropdownLines.push(pc.dim('│') + ' ' + pc.dim('╰' + botBorderStr + '╯') + '\x1b[0m');
238
240
  }
241
+ // === SAFE RENDERING: Use \x1b7/\x1b8 save/restore + \x1b[B (down) instead of \n ===
242
+ // This prevents hardware scroll when cursor is at the bottom of a small screen.
239
243
  // 1. Format and write the Prompt line safely (guaranteed <= cols - 1 chars)
240
244
  let inputDisplay = pc.dim('│') + ' ';
241
245
  let renderCursorCol = 3;
@@ -261,22 +265,35 @@ export function askPrompt(opts = {}) {
261
265
  renderCursorCol = 3 + (prefix ? 1 : 0) + (cursorPos - start);
262
266
  }
263
267
  }
268
+ // Write prompt line (no \n — stays on same line)
264
269
  process.stdout.write(`\x1b[0m\r\x1b[2K${inputDisplay}\x1b[0m`);
265
- // 2. Draw dropdown lines below, and clear extra lines from previous render
270
+ // 2. Draw dropdown below using \x1b[B (cursor down) + \r instead of \n
271
+ // \x1b[B moves cursor down WITHOUT scrolling if already at bottom — it just doesn't move.
272
+ // We first ensure enough blank lines exist by using \x1b[S (scroll up) if needed.
266
273
  const maxDropdowns = Math.max(dropdownLines.length, lastRenderedDropdownLines);
267
274
  if (maxDropdowns > 0) {
275
+ // Save cursor position
276
+ process.stdout.write('\x1b7');
277
+ // Ensure we have room: scroll terminal up if we're near the bottom
278
+ // Use \x1b[<n>S to scroll the viewport up, creating space below
279
+ if (dropdownLines.length > 0) {
280
+ const neededSpace = dropdownLines.length;
281
+ // Push content up to make room, then reposition
282
+ process.stdout.write(`\x1b[${neededSpace}S`);
283
+ // Move cursor back up by the same amount (it moved with the scroll)
284
+ process.stdout.write(`\x1b[${neededSpace}A`);
285
+ }
268
286
  for (let i = 0; i < maxDropdowns; i++) {
287
+ // Move to next line: \x1b[1B moves down 1, \r returns to col 0
288
+ process.stdout.write(`\x1b[1B\r\x1b[0m\x1b[2K`);
269
289
  if (i < dropdownLines.length) {
270
- process.stdout.write(`\n\x1b[0m\x1b[2K${dropdownLines[i]}\x1b[0m`);
271
- }
272
- else {
273
- process.stdout.write(`\n\x1b[0m\x1b[2K`);
290
+ process.stdout.write(dropdownLines[i] + '\x1b[0m');
274
291
  }
275
292
  }
276
- // Move cursor back up to input line (line 0)
277
- process.stdout.write(`\x1b[0m\x1b[${maxDropdowns}A`);
293
+ // Restore cursor position (back to prompt line)
294
+ process.stdout.write('\x1b8');
278
295
  }
279
- // 3. Place cursor precisely
296
+ // 3. Place cursor precisely on the prompt line
280
297
  process.stdout.write(`\r\x1b[${renderCursorCol}C`);
281
298
  lastRenderedDropdownLines = dropdownLines.length;
282
299
  }
@@ -295,10 +312,11 @@ export function askPrompt(opts = {}) {
295
312
  }
296
313
  function clearBoxAndExit(finalInput) {
297
314
  if (lastRenderedDropdownLines > 0) {
315
+ process.stdout.write('\x1b7');
298
316
  for (let i = 0; i < lastRenderedDropdownLines; i++) {
299
- process.stdout.write(`\n\x1b[0m\x1b[2K`);
317
+ process.stdout.write(`\x1b[1B\r\x1b[0m\x1b[2K`);
300
318
  }
301
- process.stdout.write(`\x1b[0m\x1b[${lastRenderedDropdownLines}A`);
319
+ process.stdout.write('\x1b8');
302
320
  lastRenderedDropdownLines = 0;
303
321
  }
304
322
  const fullText = expandPastes(finalInput);
@@ -353,10 +371,11 @@ export function askPrompt(opts = {}) {
353
371
  // Ctrl+C / SIGINT
354
372
  if (str === '\x03') {
355
373
  if (lastRenderedDropdownLines > 0) {
374
+ process.stdout.write('\x1b7');
356
375
  for (let i = 0; i < lastRenderedDropdownLines; i++) {
357
- process.stdout.write(`\n\x1b[0m\x1b[2K`);
376
+ process.stdout.write(`\x1b[1B\r\x1b[0m\x1b[2K`);
358
377
  }
359
- process.stdout.write(`\x1b[0m\x1b[${lastRenderedDropdownLines}A`);
378
+ process.stdout.write('\x1b8');
360
379
  lastRenderedDropdownLines = 0;
361
380
  }
362
381
  process.stdout.write(`\x1b[0m\r\x1b[2K\n`);
@@ -139,7 +139,7 @@ function renderDirectoryHtml(dirPath, relPath, files, port) {
139
139
  ${parentLink}
140
140
  ${items || '<li style="padding: 20px; text-align: center; color: #6e7681;">No visible files in this directory</li>'}
141
141
  </ul>
142
- <div class="footer">devx v1.4.14 &bull; Terminal-Native AI Assistant</div>
142
+ <div class="footer">devx v1.4.15 &bull; Terminal-Native AI Assistant</div>
143
143
  </div>
144
144
  </body>
145
145
  </html>`;
@@ -49,6 +49,13 @@ export class SmoothStreamer {
49
49
  else {
50
50
  take = 4;
51
51
  }
52
+ if (take < fullStr.length) {
53
+ const code = fullStr.charCodeAt(take - 1);
54
+ // If take ends on a high surrogate (0xD800..0xDBFF), advance by 1 to include low surrogate
55
+ if (code >= 0xD800 && code <= 0xDBFF) {
56
+ take++;
57
+ }
58
+ }
52
59
  const chunk = fullStr.slice(0, take);
53
60
  const rest = fullStr.slice(take);
54
61
  if (rest) {
@@ -63,7 +63,7 @@ export class MCPClient {
63
63
  capabilities: {},
64
64
  clientInfo: {
65
65
  name: 'devx',
66
- version: '1.4.14'
66
+ version: '1.4.15'
67
67
  }
68
68
  });
69
69
  if (!initResult) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "termux-dev",
3
- "version": "1.4.14",
3
+ "version": "1.4.15",
4
4
  "description": "Ultra-fast, terminal-native AI coding assistant and agent built for Android Termux, Windows, macOS, and Linux.",
5
5
  "main": "dist/cli/index.js",
6
6
  "type": "module",