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.
- package/bin/ts.js +11 -7
- 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
|
|
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
|
|
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
|
-
|
|
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
|
},
|