terminal-smart-cli 0.86.0 → 0.87.0

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.
Files changed (2) hide show
  1. package/bin/ts.js +11 -7
  2. package/package.json +1 -1
package/bin/ts.js CHANGED
@@ -37,11 +37,13 @@ function fmtK(n) { return n >= 1000 ? (n / 1000).toFixed(1) + 'k' : String(n); }
37
37
  // heredoc SQL a 1ª linha é o comando externo, ex "mysql -u root pw <<'SQL'"). Aceita:
38
38
  // s/N = sim/não neste passo · a = aprovar TUDO na sessão (full-auto) · v = ver o comando inteiro
39
39
  // Retorna true | false | 'all'.
40
- async function askDestructive(cmd, { en = false, warning = null } = {}) {
40
+ async function askDestructive(cmd, { en = false, warning = null, askFn = null } = {}) {
41
41
  const raw = String(cmd || '');
42
42
  const { shown, hidden } = ui.cmdSummary(raw);
43
43
  const more = hidden > 0 ? C.dim(` … +${hidden} ${en ? 'lines' : 'linhas'}`) : '';
44
44
  const desc = require('../lib/core').describeDestructive(raw, { en }); // o que a ação FAZ, em linguagem natural
45
+ // no REPL, reusa o readline do REPL (askFn) — criar um novo com ui.ask ESTRAGA o do REPL (teclado morre).
46
+ const _ask = askFn || ui.ask;
45
47
  let first = true;
46
48
  for (;;) {
47
49
  if (first) {
@@ -53,24 +55,26 @@ async function askDestructive(cmd, { en = false, warning = null } = {}) {
53
55
  first = false;
54
56
  }
55
57
  const q = C.dim(en ? ' (S) Yes · (N) No · (A) Always · (V) View command › ' : ' (S) Sim · (N) Não · (A) Sim sempre · (V) Ver comando › ');
56
- const a = String(await ui.ask(q)).trim().toLowerCase();
58
+ const a = String(await _ask(q)).trim().toLowerCase();
57
59
  if (['v', 'ver', 'view'].includes(a)) { console.log('\n' + raw.split('\n').map(l => ' ' + C.dim(l)).join('\n') + '\n'); continue; }
58
60
  if (['a', 'all', 'tudo', 'sempre', 'always'].includes(a)) return 'all';
59
61
  return ['s', 'sim', 'y', 'yes'].includes(a);
60
62
  }
61
63
  }
62
64
  // askLabelApprove: aprovação de um LABEL já formatado (skill/MCP, não é comando cru). s/N + a=tudo.
63
- async function askLabelApprove(label, { en = false } = {}) {
64
- const a = String(await ui.ask(C.warn('▲ ') + T.agent_approve(C.bold(label)) + C.dim(en ? '(a=all) ' : '(a=tudo) '))).trim().toLowerCase();
65
+ async function askLabelApprove(label, { en = false, askFn = null } = {}) {
66
+ const _ask = askFn || ui.ask;
67
+ const a = String(await _ask(C.warn('▲ ') + T.agent_approve(C.bold(label)) + C.dim(en ? '(a=all) ' : '(a=tudo) '))).trim().toLowerCase();
65
68
  if (['a', 'all', 'tudo'].includes(a)) return 'all';
66
69
  return ['s', 'sim', 'y', 'yes'].includes(a);
67
70
  }
68
71
  // Roteia o payload do askApprove do agente (obj destrutivo → resumo; string label → skill/MCP).
69
- async function askApproveRoute(payload) {
72
+ // askFn: quando vem do REPL, é o readline DELE — usar ui.ask novo aqui estragaria o teclado do REPL.
73
+ async function askApproveRoute(payload, askFn = null) {
70
74
  const en = cfg.lang === 'en';
71
75
  const isObj = payload && typeof payload === 'object';
72
76
  const cmd = isObj ? payload.cmd : String(payload);
73
- return (isObj && payload.kind === 'destructive') ? askDestructive(cmd, { en, warning: payload.warning }) : askLabelApprove(cmd, { en });
77
+ return (isObj && payload.kind === 'destructive') ? askDestructive(cmd, { en, warning: payload.warning, askFn }) : askLabelApprove(cmd, { en, askFn });
74
78
  }
75
79
  // Linha de STATUS por etapa (✓ verde / ✗ vermelho) sob a linha ⚙, com recuo `pad`.
76
80
  function stepDoneLine({ ok, evidence }, pad = ' ') {
@@ -926,7 +930,7 @@ async function agentCmd(words, { askFn, cwd: cwdIn = null, onCwd = null } = {})
926
930
  // headless (stream-json): não dá pra perguntar → NEGA o destrutivo e sinaliza o evento.
927
931
  if (streamJson) { const cmd = payload && typeof payload === 'object' ? payload.cmd : payload; _emit(core.AgentEvents.tool({ subtype: 'approval_denied', reason: 'headless (--stream-json): destructive command not auto-approved', command: cmd })); return false; }
928
932
  sp.stop();
929
- const r = await askApproveRoute(payload);
933
+ const r = await askApproveRoute(payload, askFn); // reusa o readline do REPL (não estraga o teclado)
930
934
  sp.start();
931
935
  return r;
932
936
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terminal-smart-cli",
3
- "version": "0.86.0",
3
+ "version": "0.87.0",
4
4
  "description": "Terminal Smart no seu terminal — pergunte, analise logs por pipe e orquestre agentes de IA. Comando: ts",
5
5
  "bin": {
6
6
  "ts": "bin/ts.js"