termux-dev 1.4.0 → 1.4.1

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.0</tspan>
28
+ THE TERMINAL-NATIVE AI CODING AGENT <tspan fill="#00f2fe" font-weight="bold">v1.4.1</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.0'
21
+ 'User-Agent': 'devx-doctor/1.4.1'
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.0 (headless) | ${planMode ? 'PLAN' : 'AGENT'} | ${config.model}`)));
38
+ console.log(pc.bold(pc.cyan(`⚡ devx v1.4.1 (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.0'),
487
+ ' ' + theme.boldFn('v1.4.1'),
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.0'),
502
+ indent + theme.boldFn('v1.4.1'),
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.0 • theme: ${currentTh.name})`)}`,
648
+ message: `${pc.bold('⚙️ Settings')} ${pc.dim(`(devx v1.4.1 • 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.0 by ApvCode)')}`,
689
+ name: `${currentTh.colorFn('✨ About devx')} ${pc.dim('(v1.4.1 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.0 — Terminal-Native AI Coding Agent\n` +
705
+ p.note(`⚡ devx v1.4.1 — 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` +
@@ -771,7 +771,7 @@ export async function main() {
771
771
  program
772
772
  .name('devx')
773
773
  .description('Terminal-native AI coding assistant and vibe-coding agent')
774
- .version('1.4.0')
774
+ .version('1.4.1')
775
775
  .option('-p, --prompt <task>', 'Run one-shot task non-interactively (headless mode)')
776
776
  .option('-y, --yolo', 'Automatically approve all tool executions without confirmation')
777
777
  .option('-m, --model <model>', 'Specify AI model to use for this execution')
@@ -1936,11 +1936,4 @@ process.on('exit', () => {
1936
1936
  }
1937
1937
  catch { }
1938
1938
  });
1939
- process.on('SIGINT', () => {
1940
- try {
1941
- MCPManager.getInstance().stopAll();
1942
- }
1943
- catch { }
1944
- process.exit(130);
1945
- });
1946
1939
  main().catch(console.error);
@@ -152,18 +152,27 @@ export function askPrompt(opts = {}) {
152
152
  }
153
153
  return result;
154
154
  }
155
+ function stripAnsi(str) {
156
+ return str.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, '');
157
+ }
155
158
  function render() {
156
159
  if (disposed)
157
160
  return;
158
161
  const items = getDropdownItems();
159
162
  const dropdownLines = [];
163
+ const cols = Math.max(28, process.stdout.columns || 80);
164
+ const rows = Math.max(8, process.stdout.rows || 24);
160
165
  if (items.length > 0) {
161
166
  if (selectedIndex >= items.length)
162
167
  selectedIndex = 0;
163
168
  if (selectedIndex < 0)
164
169
  selectedIndex = items.length - 1;
165
- const boxWidth = Math.min((process.stdout.columns || 80) - 6, 60);
166
- const pageSize = Math.min(5, Math.max(3, Math.floor(((process.stdout.rows || 24) - 4) / 2)));
170
+ // Ensure inner box width strictly fits: innerBoxWidth + 5 <= cols - 2
171
+ const innerBoxWidth = Math.max(16, Math.min(cols - 8, 54));
172
+ const isNarrowOrShort = rows <= 16 || cols < 50;
173
+ const pageSize = isNarrowOrShort
174
+ ? Math.max(2, Math.min(3, rows - 5))
175
+ : Math.min(5, Math.max(3, Math.floor((rows - 4) / 2)));
167
176
  const total = items.length;
168
177
  let startIndex = 0;
169
178
  if (total > pageSize) {
@@ -174,26 +183,47 @@ export function askPrompt(opts = {}) {
174
183
  const endIndex = Math.min(startIndex + pageSize, total);
175
184
  const hasMoreUp = startIndex > 0;
176
185
  const hasMoreDown = endIndex < total;
177
- let topBorderStr = '─'.repeat(boxWidth);
186
+ let topBorderStr = '─'.repeat(innerBoxWidth);
178
187
  if (hasMoreUp) {
179
- const mid = Math.max(0, Math.floor(boxWidth / 2) - 2);
180
- topBorderStr = '─'.repeat(mid) + ' ▲ ' + '─'.repeat(Math.max(0, boxWidth - mid - 3));
188
+ const mid = Math.max(0, Math.floor(innerBoxWidth / 2) - 2);
189
+ topBorderStr = '─'.repeat(mid) + ' ▲ ' + '─'.repeat(Math.max(0, innerBoxWidth - mid - 3));
181
190
  }
182
- let botBorderStr = '─'.repeat(boxWidth);
191
+ let botBorderStr = '─'.repeat(innerBoxWidth);
183
192
  if (hasMoreDown) {
184
- const mid = Math.max(0, Math.floor(boxWidth / 2) - 2);
185
- botBorderStr = '─'.repeat(mid) + ' ▼ ' + '─'.repeat(Math.max(0, boxWidth - mid - 3));
193
+ const mid = Math.max(0, Math.floor(innerBoxWidth / 2) - 2);
194
+ botBorderStr = '─'.repeat(mid) + ' ▼ ' + '─'.repeat(Math.max(0, innerBoxWidth - mid - 3));
186
195
  }
187
196
  dropdownLines.push(pc.dim('│') + ' ' + pc.dim('╭' + topBorderStr + '╮'));
188
197
  for (let i = startIndex; i < endIndex; i++) {
189
198
  const item = items[i];
190
199
  const isSelected = i === selectedIndex;
191
- const labelStr = item.label.length > 20 ? item.label.slice(0, 19) + '' : item.label.padEnd(20);
192
- const maxDescLen = Math.max(6, boxWidth - 25);
193
- const descStr = item.desc.length > maxDescLen ? item.desc.slice(0, maxDescLen - 3) + '...' : item.desc.padEnd(maxDescLen);
194
- let row = ` ${isSelected ? theme.colorFn('›') : ' '} ${isSelected ? theme.boldFn(labelStr) : pc.white(labelStr)} ${pc.gray(descStr)} `;
195
- if (isSelected) {
196
- row = theme.badgeFn(`› ${labelStr} ${descStr}`);
200
+ const pointer = isSelected ? '› ' : ' ';
201
+ const availWidth = innerBoxWidth - 2;
202
+ let row = '';
203
+ if (availWidth < 20) {
204
+ // Very narrow mobile screen: show command name only
205
+ const labelStr = item.label.length > availWidth ? item.label.slice(0, availWidth - 1) + '…' : item.label.padEnd(availWidth);
206
+ const plain = pointer + labelStr;
207
+ row = isSelected ? theme.badgeFn(plain) : (pointer + theme.boldFn(labelStr));
208
+ }
209
+ else {
210
+ // Show command name and truncated description
211
+ const labelMax = Math.min(15, Math.floor(availWidth * 0.45));
212
+ const labelStr = item.label.length > labelMax ? item.label.slice(0, labelMax - 1) + '…' : item.label.padEnd(labelMax);
213
+ const descMax = availWidth - labelMax - 1;
214
+ const descStr = item.desc.length > descMax ? item.desc.slice(0, descMax - 1) + '…' : item.desc.padEnd(descMax);
215
+ const plain = `${pointer}${labelStr} ${descStr}`;
216
+ if (isSelected) {
217
+ row = theme.badgeFn(plain);
218
+ }
219
+ else {
220
+ row = `${pointer}${theme.boldFn(labelStr)} ${pc.gray(descStr)}`;
221
+ }
222
+ }
223
+ // Safety guarantee: exact visible width must match innerBoxWidth
224
+ const currentLen = stripAnsi(row).length;
225
+ if (currentLen < innerBoxWidth) {
226
+ row += ' '.repeat(innerBoxWidth - currentLen);
197
227
  }
198
228
  dropdownLines.push(pc.dim('│') + ' ' + pc.dim('│') + row + pc.dim('│'));
199
229
  }
@@ -202,7 +232,9 @@ export function askPrompt(opts = {}) {
202
232
  // 1. Draw/update input line (line 0)
203
233
  let inputDisplay = pc.dim('│') + ' ';
204
234
  if (input.length === 0) {
205
- inputDisplay += pc.dim(placeholder);
235
+ const maxPlace = Math.max(12, cols - 8);
236
+ const displayPlace = placeholder.length > maxPlace ? placeholder.slice(0, maxPlace - 1) + '…' : placeholder;
237
+ inputDisplay += pc.dim(displayPlace);
206
238
  }
207
239
  else {
208
240
  inputDisplay += formatInputWithBadges(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.0 &bull; Terminal-Native AI Assistant</div>
142
+ <div class="footer">devx v1.4.1 &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.0'
66
+ version: '1.4.1'
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.0",
3
+ "version": "1.4.1",
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",