termux-dev 1.4.16 → 1.4.18

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/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.16'),
487
+ ' ' + theme.boldFn('v1.4.18'),
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.16'),
502
+ indent + theme.boldFn('v1.4.18'),
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.16 • theme: ${currentTh.name})`)}`,
648
+ message: `${pc.bold('⚙️ Settings')} ${pc.dim(`(devx v1.4.18 • 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.16 by ApvCode)')}`,
689
+ name: `${currentTh.colorFn('✨ About devx')} ${pc.dim('(v1.4.18 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.16 — Terminal-Native AI Coding Agent\n` +
705
+ p.note(`⚡ devx v1.4.18 — 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.16')
801
+ .version('1.4.18')
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,7 @@ export function askPrompt(opts = {}) {
177
177
  selectedIndex = items.length - 1;
178
178
  if (selectedIndex < 0)
179
179
  selectedIndex = 0;
180
- // On very small screens (keyboard open on Android), limit dropdown aggressively
180
+ // Limit dropdown height gracefully so it always fits comfortably
181
181
  const maxDropdownRows = Math.max(2, Math.min(rows - 3, 6));
182
182
  const pageSize = Math.min(4, Math.max(2, Math.min(maxDropdownRows - 2, Math.floor(rows / 4))));
183
183
  const innerBoxWidth = Math.max(10, Math.min(cols - 8, 48));
@@ -238,9 +238,7 @@ export function askPrompt(opts = {}) {
238
238
  }
239
239
  dropdownLines.push(pc.dim('│') + ' ' + pc.dim('╰' + botBorderStr + '╯') + '\x1b[0m');
240
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.
243
- // 1. Format and write the Prompt line safely (guaranteed <= cols - 1 chars)
241
+ // 1. Format and write the Prompt line safely
244
242
  let inputDisplay = pc.dim('│') + ' ';
245
243
  let renderCursorCol = 3;
246
244
  if (input.length === 0) {
@@ -265,26 +263,33 @@ export function askPrompt(opts = {}) {
265
263
  renderCursorCol = 3 + (prefix ? 1 : 0) + (cursorPos - start);
266
264
  }
267
265
  }
268
- // Write prompt line (no \n — stays on same line)
266
+ // Write prompt line
269
267
  process.stdout.write(`\x1b[0m\r\x1b[2K${inputDisplay}\x1b[0m`);
270
- // 2. Draw dropdown below using \x1b[1B (cursor down) + \r without scrolling viewport
271
- const maxDropdowns = Math.max(dropdownLines.length, lastRenderedDropdownLines);
272
- if (maxDropdowns > 0) {
273
- // Save cursor position on the prompt line
274
- process.stdout.write('\x1b7');
275
- for (let i = 0; i < maxDropdowns; i++) {
276
- // Move to next line: \x1b[1B moves down 1 without scrolling, \r returns to col 0, \x1b[2K clears line
268
+ // 2. Draw or update dropdown lines safely
269
+ if (dropdownLines.length > lastRenderedDropdownLines) {
270
+ // Allocate additional new lines that don't exist yet
271
+ for (let i = 0; i < lastRenderedDropdownLines; i++) {
272
+ process.stdout.write(`\x1b[1B\r\x1b[0m\x1b[2K${dropdownLines[i]}\x1b[0m`);
273
+ }
274
+ for (let i = lastRenderedDropdownLines; i < dropdownLines.length; i++) {
275
+ process.stdout.write(`\n\x1b[0m\x1b[2K${dropdownLines[i]}\x1b[0m`);
276
+ }
277
+ process.stdout.write(`\x1b[${dropdownLines.length}A`);
278
+ lastRenderedDropdownLines = dropdownLines.length;
279
+ }
280
+ else if (lastRenderedDropdownLines > 0) {
281
+ // Redraw over existing lines without allocating new ones (0 scrolling!)
282
+ for (let i = 0; i < lastRenderedDropdownLines; i++) {
277
283
  process.stdout.write(`\x1b[1B\r\x1b[0m\x1b[2K`);
278
284
  if (i < dropdownLines.length) {
279
- process.stdout.write(dropdownLines[i] + '\x1b[0m');
285
+ process.stdout.write(`${dropdownLines[i]}\x1b[0m`);
280
286
  }
281
287
  }
282
- // Restore cursor position (back to prompt line)
283
- process.stdout.write('\x1b8');
288
+ process.stdout.write(`\x1b[${lastRenderedDropdownLines}A`);
289
+ lastRenderedDropdownLines = dropdownLines.length;
284
290
  }
285
- // 3. Place cursor precisely on the prompt line
291
+ // 3. Position cursor on the prompt line
286
292
  process.stdout.write(`\r\x1b[${renderCursorCol}C`);
287
- lastRenderedDropdownLines = dropdownLines.length;
288
293
  }
289
294
  render();
290
295
  function cleanup() {
@@ -301,11 +306,10 @@ export function askPrompt(opts = {}) {
301
306
  }
302
307
  function clearBoxAndExit(finalInput) {
303
308
  if (lastRenderedDropdownLines > 0) {
304
- process.stdout.write('\x1b7');
305
309
  for (let i = 0; i < lastRenderedDropdownLines; i++) {
306
310
  process.stdout.write(`\x1b[1B\r\x1b[0m\x1b[2K`);
307
311
  }
308
- process.stdout.write('\x1b8');
312
+ process.stdout.write(`\x1b[${lastRenderedDropdownLines}A`);
309
313
  lastRenderedDropdownLines = 0;
310
314
  }
311
315
  const fullText = expandPastes(finalInput);
@@ -360,11 +364,10 @@ export function askPrompt(opts = {}) {
360
364
  // Ctrl+C / SIGINT
361
365
  if (str === '\x03') {
362
366
  if (lastRenderedDropdownLines > 0) {
363
- process.stdout.write('\x1b7');
364
367
  for (let i = 0; i < lastRenderedDropdownLines; i++) {
365
368
  process.stdout.write(`\x1b[1B\r\x1b[0m\x1b[2K`);
366
369
  }
367
- process.stdout.write('\x1b8');
370
+ process.stdout.write(`\x1b[${lastRenderedDropdownLines}A`);
368
371
  lastRenderedDropdownLines = 0;
369
372
  }
370
373
  process.stdout.write(`\x1b[0m\r\x1b[2K\n`);
@@ -433,21 +436,23 @@ export function askPrompt(opts = {}) {
433
436
  if (str === '\t' || (str.length === 1 && str.charCodeAt(0) === 9)) {
434
437
  if (items.length > 0 && selectedIndex >= 0 && selectedIndex < items.length) {
435
438
  const selected = items[selectedIndex];
436
- input =
437
- input.slice(0, selected.replaceStart) +
438
- selected.replacement +
439
- input.slice(selected.replaceStart + selected.replaceLen);
440
- cursorPos = selected.replaceStart + selected.replacement.length;
441
- render();
439
+ if (input.startsWith('/')) {
440
+ input = selected.replacement + ' ';
441
+ cursorPos = input.length;
442
+ render();
443
+ return;
444
+ }
445
+ else {
446
+ input =
447
+ input.slice(0, selected.replaceStart) +
448
+ selected.replacement +
449
+ input.slice(selected.replaceStart + selected.replaceLen);
450
+ cursorPos = selected.replaceStart + selected.replacement.length;
451
+ render();
452
+ return;
453
+ }
442
454
  }
443
455
  else {
444
- if (lastRenderedDropdownLines > 0) {
445
- for (let i = 0; i < lastRenderedDropdownLines; i++) {
446
- process.stdout.write(`\n\x1b[0m\x1b[2K`);
447
- }
448
- process.stdout.write(`\x1b[0m\x1b[${lastRenderedDropdownLines}A`);
449
- lastRenderedDropdownLines = 0;
450
- }
451
456
  process.stdout.write(`\x1b[0m\r\x1b[2K`);
452
457
  cleanup();
453
458
  resolve(`__TOGGLE_MODE__:${input}`);
@@ -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.16 &bull; Terminal-Native AI Assistant</div>
142
+ <div class="footer">devx v1.4.18 &bull; Terminal-Native AI Assistant</div>
143
143
  </div>
144
144
  </body>
145
145
  </html>`;
@@ -63,7 +63,7 @@ export class MCPClient {
63
63
  capabilities: {},
64
64
  clientInfo: {
65
65
  name: 'devx',
66
- version: '1.4.16'
66
+ version: '1.4.18'
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.16",
3
+ "version": "1.4.18",
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",