dex-termux-cli 0.3.0-beta.4 → 0.3.0-beta.5

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/README.md CHANGED
@@ -7,12 +7,12 @@
7
7
  <h1 align="center">Dex Termux CLI</h1>
8
8
 
9
9
  <p align="center">
10
- CLI visual para Termux y Linux con busqueda guiada, tree legible, contexto de proyecto, version visible y flujos seguros para Python, Node y PHP.
10
+ CLI visual para Termux y Linux con busqueda guiada, tree legible, contexto de proyecto, version visible y flujos seguros para Python, Node, PHP, Ruby, Go, Rust y Java.
11
11
  </p>
12
12
 
13
13
  <p align="center">
14
14
  <img alt="platform" src="https://img.shields.io/badge/platform-Termux%20%7C%20Linux-111111?style=flat-square&labelColor=F97316&color=1F2937">
15
- <img alt="safe-mode" src="https://img.shields.io/badge/safe%20mode-Python%20%7C%20Node%20%7C%20PHP-111111?style=flat-square&labelColor=2563EB&color=1F2937">
15
+ <img alt="safe-mode" src="https://img.shields.io/badge/safe%20mode-7%20languages-111111?style=flat-square&labelColor=2563EB&color=1F2937">
16
16
  <img alt="channel" src="https://img.shields.io/badge/channel-beta-111111?style=flat-square&labelColor=B45309&color=1F2937">
17
17
  </p>
18
18
 
@@ -20,7 +20,9 @@
20
20
  <strong>Explorar.</strong> <strong>Entender.</strong> <strong>Instalar.</strong> <strong>Entrar al modo seguro.</strong>
21
21
  </p>
22
22
 
23
- > Estado actual: beta `0.3.0-beta.1` con soporte seguro para Python, Node y PHP, contexto de proyecto y modo de plataforma `auto | termux | linux`.
23
+ > Estado actual: beta `0.3.0-beta.5` muy temprana. La base principal ya funciona, pero Dex sigue en una etapa de ajuste fuerte y aun hay partes incompletas o inestables.
24
+
25
+ > Importante: la base de sesiones y apertura de nuevas terminales (`dex sessions`) sigue sin terminar. Existe trabajo inicial, pero no debe considerarse lista, estable ni parte cerrada de esta beta.
24
26
 
25
27
  ## Vision general
26
28
 
@@ -77,12 +79,16 @@ El modo actual se guarda en `~/.config/dex/config.json`.
77
79
 
78
80
  ## Estado real de la beta
79
81
 
82
+ - esta release sigue en fase muy beta y no debe leerse como build final o pulida
80
83
  - `dex -m`, `-a`, `-b`, `-t`, `-v`, `-c` y `--prompt-context` funcionan
81
84
  - `dex -a` ahora abre una shell de acceso rapido con prompt propio y atajos. En Termux apunta a Android storage y en Linux apunta a HOME
82
85
  - `dex -i` funciona en proyectos validos y ahora usa el root detectado del proyecto aunque entres desde una subcarpeta
83
86
  - `dex -r` funciona para proyectos soportados, hereda mejor el root del proyecto y en Termux exige Android storage
84
87
  - el modo seguro real ya cubre Python, Node, PHP, Ruby, Go, Rust y Java
88
+ - `dex -t` usa por defecto la vista maxima y acepta presets `--mini`, `--med/--medio` y `--max/--maximo`
89
+ - la deteccion del contexto prioriza el proyecto mas cercano para evitar falsos padres al navegar por subcarpetas
85
90
  - `dex -e` ya resuelve su data interna sin depender del directorio actual
91
+ - `dex sessions` sigue en desarrollo y no debe usarse como funcion estable: falta endurecer estado, attach/detach, persistencia y flujo real de nuevas terminales
86
92
 
87
93
  ## Roadmap inmediato
88
94
 
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dex-termux-cli",
3
- "version": "0.3.0-beta.4",
3
+ "version": "0.3.0-beta.5",
4
4
  "type": "module",
5
5
  "description": "Visual CLI for Termux and Linux with guided search, readable tree views, project context, version checks, Android mode, and safe flows for Python, Node, PHP, Ruby, Go, Rust, and Java.",
6
6
  "keywords": [
@@ -46,5 +46,9 @@
46
46
  },
47
47
  "engines": {
48
48
  "node": ">=18"
49
+ },
50
+ "dependencies": {
51
+ "figures": "^6.1.0",
52
+ "node-pty": "^1.1.0"
49
53
  }
50
54
  }
package/src/app/main.js CHANGED
@@ -7,6 +7,8 @@ import { runInstallCommand } from '../commands/install.js';
7
7
  import { runMenuCommand } from '../commands/menu.js';
8
8
  import { runSafeShellCommand } from '../commands/safe-shell.js';
9
9
  import { runSearchCommand } from '../commands/search.js';
10
+ import { runSessionsCommand } from '../commands/sessions.js';
11
+ import { runSessionsDaemonCommand } from '../commands/sessions-daemon.js';
10
12
  import { runTreeCommand } from '../commands/tree.js';
11
13
  import { runVersionCommand } from '../commands/version.js';
12
14
  import { printHelp, printProjectContextLine } from '../ui/output.js';
@@ -20,8 +22,9 @@ export async function main(argv = process.argv.slice(2)) {
20
22
  const isPromptOnly = parsed.command === 'prompt-context' || parsed.command === 'prompt-project-root' || parsed.command === 'prompt-project-path';
21
23
  const isContextOnly = parsed.command === 'context';
22
24
  const isVersionOnly = parsed.command === 'version';
25
+ const isDaemonOnly = parsed.command === 'sessions-daemon';
23
26
 
24
- if (config.features.projectBadge && !isPromptOnly && !isContextOnly && !isVersionOnly) {
27
+ if (config.features.projectBadge && !isPromptOnly && !isContextOnly && !isVersionOnly && !isDaemonOnly) {
25
28
  const context = await detectProjectContext();
26
29
  if (context) {
27
30
  printProjectContextLine(formatProjectContext(context));
@@ -73,6 +76,16 @@ export async function main(argv = process.argv.slice(2)) {
73
76
  return;
74
77
  }
75
78
 
79
+ if (parsed.command === 'sessions') {
80
+ await runSessionsCommand(parsed);
81
+ return;
82
+ }
83
+
84
+ if (parsed.command === 'sessions-daemon') {
85
+ await runSessionsDaemonCommand();
86
+ return;
87
+ }
88
+
76
89
  if (parsed.command === 'tree') {
77
90
  await runTreeCommand(parsed);
78
91
  return;
@@ -4,6 +4,8 @@ import path from 'node:path';
4
4
  import { spawn } from 'node:child_process';
5
5
  import { getUserConfigPath, loadUserConfig } from '../core/config.js';
6
6
  import { resolveInteractiveShell } from '../utils/shell.js';
7
+ import { buildShellSegmentIconFunction, getPromptIcon } from '../utils/path-icons.js';
8
+ import { getAccentColorCode, getLinuxSetupTheme, formatPromptBrand } from '../utils/prompt-theme.js';
7
9
  import {
8
10
  getQuickAccessAliases,
9
11
  getQuickAccessLabel,
@@ -38,7 +40,7 @@ export async function runAndroidShellCommand() {
38
40
  }
39
41
 
40
42
  const interactiveShell = await resolveAndroidInteractiveShell(platformMode);
41
- const shellSession = await createQuickAccessShellSession(platformMode, interactiveShell);
43
+ const shellSession = await createQuickAccessShellSession(platformMode, interactiveShell, getLinuxSetupTheme(config));
42
44
 
43
45
  console.log(getQuickAccessTitle(platformMode));
44
46
  console.log('');
@@ -107,7 +109,7 @@ async function resolveAndroidInteractiveShell(platformMode) {
107
109
  return interactiveShell;
108
110
  }
109
111
 
110
- async function createQuickAccessShellSession(platformMode, interactiveShell) {
112
+ async function createQuickAccessShellSession(platformMode, interactiveShell, promptTheme) {
111
113
  const tmpBase = await fs.mkdtemp(path.join(os.tmpdir(), 'dex-shell-'));
112
114
  const aliases = getQuickAccessAliases(platformMode);
113
115
  const root = getQuickAccessRoot(platformMode);
@@ -118,6 +120,7 @@ async function createQuickAccessShellSession(platformMode, interactiveShell) {
118
120
  label,
119
121
  shellName: interactiveShell.shellName,
120
122
  platformMode,
123
+ promptTheme,
121
124
  });
122
125
 
123
126
  if (interactiveShell.shellName === 'bash') {
@@ -153,63 +156,78 @@ async function createQuickAccessShellSession(platformMode, interactiveShell) {
153
156
  };
154
157
  }
155
158
 
156
- function buildShellRc({ aliases, root, label, shellName, platformMode }) {
157
- if (platformMode === 'termux') {
158
- return buildTermuxShellRc(shellName);
159
- }
160
-
161
- return buildLinuxShellRc({ aliases, root, label, shellName });
162
- }
163
-
164
- function buildTermuxShellRc(shellName) {
165
- const lines = [
166
- '# dex quick access shell',
167
- 'export PATH="$HOME/bin:$PATH"',
168
- ];
169
-
170
- if (shellName === 'zsh') {
171
- lines.push('[[ -f "$HOME/.zshrc" ]] && source "$HOME/.zshrc"');
172
- lines.push('printf "Dex: acceso rapido cargado en %s\\n" "$PWD"');
173
- return lines.join('\n') + '\n';
174
- }
175
-
176
- if (shellName === 'bash') {
177
- lines.push('[[ -f "$HOME/.bashrc" ]] && source "$HOME/.bashrc"');
178
- lines.push('printf "Dex: acceso rapido cargado en %s\\n" "$PWD"');
179
- return lines.join('\n') + '\n';
180
- }
181
-
182
- lines.push('printf "Dex: acceso rapido cargado en %s\\n" "$PWD"');
183
- return lines.join('\n') + '\n';
159
+ function buildShellRc({ aliases, root, label, shellName, platformMode, promptTheme }) {
160
+ return buildQuickAccessShellRc({ aliases, root, label, shellName, platformMode, promptTheme });
184
161
  }
185
162
 
186
- function buildLinuxShellRc({ aliases, root, label, shellName }) {
163
+ function buildQuickAccessShellRc({ aliases, root, label, shellName, platformMode, promptTheme }) {
187
164
  const aliasLines = Object.entries(aliases).map(([name, target]) => `alias ${name}='cd "${target}"'`);
165
+ const rootIcon = platformMode === 'termux' ? getPromptIcon('android') : getPromptIcon('home');
166
+ const promptMarker = getPromptIcon('prompt');
167
+ const isLinuxTheme = platformMode === 'linux';
168
+ const accentColorCode = isLinuxTheme ? getAccentColorCode(promptTheme.accentColor) : 45;
169
+ const promptBrand = isLinuxTheme ? formatPromptBrand(promptTheme) : `Dex@${platformMode}`;
170
+ const useIconPathStyle = !isLinuxTheme || promptTheme.pathStyle === 'icons';
171
+ const rootPrefix = !isLinuxTheme
172
+ ? `${rootIcon} ${label}`
173
+ : promptTheme.pathStyle === 'ascii'
174
+ ? '[home]'
175
+ : promptTheme.pathStyle === 'text'
176
+ ? label
177
+ : `${rootIcon} ${label}`;
188
178
  const commonLines = [
189
179
  '# dex quick access shell',
190
180
  'export PATH="$HOME/bin:$PATH"',
191
181
  `export DEX_QUICK_ROOT="${root}"`,
192
182
  `export DEX_QUICK_LABEL="${label}"`,
183
+ `export DEX_QUICK_ROOT_ICON="${rootIcon}"`,
184
+ `export DEX_QUICK_ROOT_PREFIX="${rootPrefix}"`,
193
185
  ...aliasLines,
186
+ buildShellSegmentIconFunction('_dex_quick_icon_for_segment'),
187
+ '_dex_quick_iconize_label() {',
188
+ ' input="$1"',
189
+ ' first_mode="$2"',
190
+ ' output=""',
191
+ ' remaining="$input"',
192
+ ' while [ -n "$remaining" ]; do',
193
+ ' segment="${remaining%%/*}"',
194
+ ' if [ "$remaining" = "$segment" ]; then',
195
+ ' remaining=""',
196
+ ' else',
197
+ ' remaining="${remaining#*/}"',
198
+ ' fi',
199
+ ' [ -z "$segment" ] && continue',
200
+ ' if [ -z "$output" ] && [ "$first_mode" = "project" ]; then',
201
+ useIconPathStyle ? ` icon="${getPromptIcon('project')}"` : ' icon=""',
202
+ ' else',
203
+ useIconPathStyle ? ' icon="$(_dex_quick_icon_for_segment "$segment")"' : ' icon=""',
204
+ ' fi',
205
+ ' if [ -n "$output" ]; then',
206
+ ' output="$output/"',
207
+ ' fi',
208
+ useIconPathStyle ? ' output="${output}${icon} ${segment}"' : ' output="${output}${segment}"',
209
+ ' done',
210
+ ' printf "%s" "$output"',
211
+ '}',
194
212
  ];
195
213
 
196
214
  if (shellName === 'zsh') {
197
215
  return [
198
216
  ...commonLines,
199
217
  '[[ -f "$HOME/.zshrc" ]] && source "$HOME/.zshrc"',
200
- '_dex_linux_project_root_zsh() {',
218
+ '_dex_quick_project_root() {',
201
219
  ' local helper',
202
220
  ' helper="$(command -v dex-project-context 2>/dev/null)"',
203
221
  ' [[ -z "$helper" ]] && return',
204
222
  ' "$helper" --root 2>/dev/null',
205
223
  '}',
206
- '_dex_linux_project_path_zsh() {',
224
+ '_dex_quick_project_path() {',
207
225
  ' local helper',
208
226
  ' helper="$(command -v dex-project-context 2>/dev/null)"',
209
227
  ' [[ -z "$helper" ]] && return',
210
228
  ' "$helper" --path 2>/dev/null',
211
229
  '}',
212
- '_dex_linux_project_badge_zsh() {',
230
+ '_dex_quick_project_badge_zsh() {',
213
231
  ' local helper context',
214
232
  ' helper="$(command -v dex-project-context 2>/dev/null)"',
215
233
  ' [[ -z "$helper" ]] && return',
@@ -217,35 +235,49 @@ function buildLinuxShellRc({ aliases, root, label, shellName }) {
217
235
  ' [[ -z "$context" ]] && return',
218
236
  ' print -n "%F{81}[$context]%f"',
219
237
  '}',
220
- '_dex_linux_path_label_zsh() {',
221
- ' local project_name project_path current relative',
222
- ' project_name="$(_dex_linux_project_root_zsh)"',
223
- ' project_path="$(_dex_linux_project_path_zsh)"',
238
+ '_dex_quick_path_label_zsh() {',
239
+ ' local project_name project_path current relative label rendered',
240
+ ' project_name="$(_dex_quick_project_root)"',
241
+ ' project_path="$(_dex_quick_project_path)"',
224
242
  ' current="$PWD"',
225
243
  ' if [[ -n "$project_name" && -n "$project_path" ]]; then',
226
244
  ' project_name="${project_name##*/}"',
227
245
  ' if [[ "$current" == "$project_path" ]]; then',
228
- ' print -r -- "$project_name"',
246
+ ' rendered="$(_dex_quick_iconize_label "$project_name" project)"',
247
+ ' print -r -- "${DEX_QUICK_ROOT_PREFIX}/${rendered}"',
229
248
  ' return',
230
249
  ' fi',
231
250
  ' relative="${current#$project_path/}"',
232
251
  ' if [[ "$relative" != "$current" ]]; then',
233
- ' print -r -- "$project_name/$relative"',
252
+ ' label="${project_name}/${relative}"',
253
+ ' rendered="$(_dex_quick_iconize_label "$label" project)"',
254
+ ' print -r -- "${DEX_QUICK_ROOT_PREFIX}/${rendered}"',
234
255
  ' return',
235
256
  ' fi',
236
257
  ' fi',
237
- ' print -r -- "%~"',
258
+ ' if [[ "$current" == "$DEX_QUICK_ROOT" ]]; then',
259
+ ' print -r -- "${DEX_QUICK_ROOT_PREFIX}"',
260
+ ' return',
261
+ ' fi',
262
+ ' relative="${current#$DEX_QUICK_ROOT/}"',
263
+ ' if [[ "$relative" != "$current" ]]; then',
264
+ ' rendered="$(_dex_quick_iconize_label "$relative")"',
265
+ ' print -r -- "${DEX_QUICK_ROOT_PREFIX}/${rendered}"',
266
+ ' return',
267
+ ' fi',
268
+ ' rendered="$(_dex_quick_iconize_label "$current")"',
269
+ ' print -r -- "$rendered"',
238
270
  '}',
239
- '_dex_linux_prompt_zsh() {',
271
+ '_dex_quick_prompt_zsh() {',
240
272
  ' local badge path_label',
241
- ' badge="$(_dex_linux_project_badge_zsh)"',
242
- ' path_label="$(_dex_linux_path_label_zsh)"',
243
- " PROMPT=$'%F{45}Dex@linux%f %F{117}'\"${path_label}\"$'%f\\n%F{45}>%f '",
273
+ ' badge="$(_dex_quick_project_badge_zsh)"',
274
+ ' path_label="$(_dex_quick_path_label_zsh)"',
275
+ ` PROMPT=$'%F{38;5;${accentColorCode}m}${promptBrand}%f %F{117}'"\${path_label}"$'%f\\n%F{38;5;${accentColorCode}m}${promptMarker}%f '`,
244
276
  ' RPROMPT="$badge"',
245
277
  '}',
246
278
  'autoload -Uz add-zsh-hook 2>/dev/null || true',
247
- 'add-zsh-hook precmd _dex_linux_prompt_zsh 2>/dev/null || true',
248
- '_dex_linux_prompt_zsh',
279
+ 'add-zsh-hook precmd _dex_quick_prompt_zsh 2>/dev/null || true',
280
+ '_dex_quick_prompt_zsh',
249
281
  'printf "Dex: acceso rapido cargado en %s\\n" "$PWD"',
250
282
  ].join('\n') + '\n';
251
283
  }
@@ -253,19 +285,20 @@ function buildLinuxShellRc({ aliases, root, label, shellName }) {
253
285
  if (shellName === 'bash') {
254
286
  return [
255
287
  ...commonLines,
256
- '_dex_linux_project_root_bash() {',
288
+ '[[ -f "$HOME/.bashrc" ]] && source "$HOME/.bashrc"',
289
+ '_dex_quick_project_root() {',
257
290
  ' local helper',
258
291
  ' helper="$(command -v dex-project-context 2>/dev/null)"',
259
292
  ' [[ -z "$helper" ]] && return',
260
293
  ' "$helper" --root 2>/dev/null',
261
294
  '}',
262
- '_dex_linux_project_path_bash() {',
295
+ '_dex_quick_project_path() {',
263
296
  ' local helper',
264
297
  ' helper="$(command -v dex-project-context 2>/dev/null)"',
265
298
  ' [[ -z "$helper" ]] && return',
266
299
  ' "$helper" --path 2>/dev/null',
267
300
  '}',
268
- '_dex_linux_project_badge_bash() {',
301
+ '_dex_quick_project_badge_bash() {',
269
302
  ' local helper context',
270
303
  ' helper="$(command -v dex-project-context 2>/dev/null)"',
271
304
  ' [[ -z "$helper" ]] && return',
@@ -273,40 +306,54 @@ function buildLinuxShellRc({ aliases, root, label, shellName }) {
273
306
  ' [[ -z "$context" ]] && return',
274
307
  ' printf "\\[\\e[38;5;81m\\][%s]\\[\\e[0m\\]" "$context"',
275
308
  '}',
276
- '_dex_linux_path_label_bash() {',
277
- ' local project_name project_path current relative',
278
- ' project_name="$(_dex_linux_project_root_bash)"',
279
- ' project_path="$(_dex_linux_project_path_bash)"',
309
+ '_dex_quick_path_label_bash() {',
310
+ ' local project_name project_path current relative label rendered',
311
+ ' project_name="$(_dex_quick_project_root)"',
312
+ ' project_path="$(_dex_quick_project_path)"',
280
313
  ' current="$PWD"',
281
314
  ' if [[ -n "$project_name" && -n "$project_path" ]]; then',
282
315
  ' project_name="${project_name##*/}"',
283
316
  ' if [[ "$current" == "$project_path" ]]; then',
284
- ' printf "%s" "$project_name"',
317
+ ' rendered="$(_dex_quick_iconize_label "$project_name" project)"',
318
+ ' printf "%s" "${DEX_QUICK_ROOT_PREFIX}/${rendered}"',
285
319
  ' return',
286
320
  ' fi',
287
321
  ' relative="${current#$project_path/}"',
288
322
  ' if [[ "$relative" != "$current" ]]; then',
289
- ' printf "%s/%s" "$project_name" "$relative"',
323
+ ' label="${project_name}/${relative}"',
324
+ ' rendered="$(_dex_quick_iconize_label "$label" project)"',
325
+ ' printf "%s" "${DEX_QUICK_ROOT_PREFIX}/${rendered}"',
290
326
  ' return',
291
327
  ' fi',
292
328
  ' fi',
293
- ' printf "%s" "\\w"',
329
+ ' if [[ "$current" == "$DEX_QUICK_ROOT" ]]; then',
330
+ ' printf "%s" "${DEX_QUICK_ROOT_PREFIX}"',
331
+ ' return',
332
+ ' fi',
333
+ ' relative="${current#$DEX_QUICK_ROOT/}"',
334
+ ' if [[ "$relative" != "$current" ]]; then',
335
+ ' rendered="$(_dex_quick_iconize_label "$relative")"',
336
+ ' printf "%s" "${DEX_QUICK_ROOT_PREFIX}/${rendered}"',
337
+ ' return',
338
+ ' fi',
339
+ ' rendered="$(_dex_quick_iconize_label "$current")"',
340
+ ' printf "%s" "$rendered"',
294
341
  '}',
295
- '_dex_linux_prompt_bash() {',
342
+ '_dex_quick_prompt_bash() {',
296
343
  ' local badge path_label',
297
- ' badge="$(_dex_linux_project_badge_bash)"',
298
- ' path_label="$(_dex_linux_path_label_bash)"',
299
- ' PS1="\\[\\e[38;5;45m\\]Dex@linux\\[\\e[0m\\] \\[\\e[38;5;117m\\]${path_label}\\[\\e[0m\\] ${badge}\\n\\[\\e[38;5;45m\\]>\\[\\e[0m\\] "',
344
+ ' badge="$(_dex_quick_project_badge_bash)"',
345
+ ' path_label="$(_dex_quick_path_label_bash)"',
346
+ ` PS1="\\[\\e[38;5;${accentColorCode}m\\]${promptBrand}\\[\\e[0m\\] \\[\\e[38;5;117m\\]\${path_label}\\[\\e[0m\\] \${badge}\\n\\[\\e[38;5;${accentColorCode}m\\]${promptMarker}\\[\\e[0m\\] "`,
300
347
  '}',
301
- 'PROMPT_COMMAND=_dex_linux_prompt_bash',
302
- '_dex_linux_prompt_bash',
348
+ 'PROMPT_COMMAND=_dex_quick_prompt_bash',
349
+ '_dex_quick_prompt_bash',
303
350
  'printf "Dex: acceso rapido cargado en %s\\n" "$PWD"',
304
351
  ].join('\n') + '\n';
305
352
  }
306
353
 
307
354
  return [
308
355
  ...commonLines,
309
- `export PS1='[dex ${label}] \\w \\$ '`,
356
+ `export PS1='[${promptBrand}] ${rootPrefix} ${promptMarker} '`,
310
357
  'printf "Dex: acceso rapido cargado en %s\\n" "$PWD"',
311
358
  ].join('\n') + '\n';
312
359
  }