terminal-smart-cli 0.32.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/lib/i18n.js ADDED
@@ -0,0 +1,294 @@
1
+ // i18n do CLI — padrão pt-BR; troque com `ts idioma en`.
2
+ const STR = {
3
+ pt: {
4
+ tagline: 'agente DevOps no seu terminal',
5
+ help_examples: 'Exemplos',
6
+ help_groups: [
7
+ { title: 'Conversar', items: [
8
+ ['ts', 'abre o modo conversa — digite naturalmente'],
9
+ ['ts "pergunta"', 'resposta única e volta pro shell'],
10
+ ['cat log | ts "analise"', 'analisa o que vier do pipe'],
11
+ ['ts video <url> "..."', 'lê a transcrição de um vídeo e responde (yt-dlp)'],
12
+ ['ts arquivar <url>', 'salva a página como 1 HTML offline (monolith)'],
13
+ ['ts qr', 'QR pra continuar a conversa no celular'],
14
+ ['ts nova', 'zera o contexto da conversa'],
15
+ ] },
16
+ { title: 'Galeria de Skills (comunidade)', items: [
17
+ ['ts skills', 'lista as skills da comunidade (mais instaladas)'],
18
+ ['ts skills buscar "x"', 'busca skills por termo'],
19
+ ['ts skills ver <slug>', 'lê a skill INTEIRA antes de instalar'],
20
+ ['ts skills add <slug>', 'instala em ~/.ts/skills'],
21
+ ['ts skills publicar <pasta>', 'publica sua skill na galeria'],
22
+ ] },
23
+ { title: 'Memória (o agente lembra)', items: [
24
+ ['ts memoria', 'mostra a memória do projeto + global'],
25
+ ['ts memoria add "fato"', 'grava um fato (o agente sempre lê depois)'],
26
+ ['ts memoria add "x" -g', 'grava na memória global (todo projeto)'],
27
+ ] },
28
+ { title: 'Agente LOCAL (mãos nesta máquina)', items: [
29
+ ['ts agente "tarefa"', 'executa DE VERDADE aqui: comandos, arquivos, diagnóstico'],
30
+ ['ts agente "..." --yes', 'autônomo (destrutivo pede aprovação no Telegram)'],
31
+ ['ts agente --continuar "..."', 'retoma o trabalho anterior desta pasta'],
32
+ ['ts meta "objetivo grande"', 'MISSÃO: checklist + rodadas até terminar (noturno)'],
33
+ ['ts meta --status', 'estado da missão deste diretório'],
34
+ ['ts eval suite.json', 'avalia o agente numa suíte de casos (juiz de IA + nota)'],
35
+ ['ts acp', 'servidor Agent Client Protocol (conecta o ts a editores tipo Zed)'],
36
+ ] },
37
+ { title: 'Agentes na nuvem (orquestração)', items: [
38
+ ['ts run "objetivo"', 'planeja → você aprova → executa'],
39
+ ['ts run "..." --yes', 'sem perguntar (cron/scripts)'],
40
+ ['ts run "..." --json', 'saída JSON estruturada'],
41
+ ['ts runs · ts status <id>', 'acompanha execuções'],
42
+ ] },
43
+ { title: 'Conta', items: [
44
+ ['ts login · ts logout', 'conecta / desconecta este terminal'],
45
+ ['ts uso', 'créditos e consumo do mês'],
46
+ ['ts quem', 'conta conectada'],
47
+ ['ts idioma pt|en', 'idioma (padrão pt-BR)'],
48
+ ] },
49
+ ],
50
+ help_footer: 'Cada uso debita dos seus Smart Credits — acompanhe com `ts uso`.',
51
+ repl_hello: 'converse naturalmente — eu identifico se é pergunta, ação ou objetivo · /ajuda · sair',
52
+ onboard_title: 'Primeira vez? É só conversar — sem comando nenhum.',
53
+ onboard_lines: [
54
+ ['pergunte', '"por que o nginx devolve 502?"'],
55
+ ['peça pra eu FAZER', '"libere espaço em disco" — executo aqui'],
56
+ ['dê um objetivo grande', '"monte um kit de lançamento" — plano antes'],
57
+ ],
58
+ onboard_footer: 'Eu escolho o caminho. Perigoso? Confirmo antes. Atalhos: /ajuda',
59
+ route_agent: 'isso pede ações nesta máquina — agindo como agente (digite /chat antes da frase pra só conversar)',
60
+ route_run: 'objetivo grande — planejando com a equipe de agentes (você aprova antes de gastar)',
61
+ repl_account: (u, p) => `conta ${u} · plano ${p}`,
62
+ repl_credits: (c) => `${c} créditos`,
63
+ repl_help: [
64
+ ['digite qualquer coisa', 'conversa em linguagem natural'],
65
+ ['/agente "tarefa"', 'executa DE VERDADE nesta máquina (comandos, arquivos)'],
66
+ ['/run "objetivo"', 'orquestra agentes na nuvem (plano + aprovação)'],
67
+ ['cd <pasta> · pwd', 'muda/mostra a pasta de trabalho do agente'],
68
+ ['/runs', 'últimas orquestrações'],
69
+ ['/uso', 'créditos do mês'],
70
+ ['/nova', 'zera o contexto'],
71
+ ['sair', 'encerra'],
72
+ ],
73
+ ex1: 'ts "por que o nginx devolve 502 depois do deploy?"',
74
+ ex2: 'docker logs api --tail 200 | ts "tem erro grave aqui?"',
75
+ ex3: 'ts run "audite a segurança básica deste servidor" --yes',
76
+ login_title: 'Conectar este terminal',
77
+ login_step1: '1. Abra:',
78
+ login_step2: '2. Logado, digite o código:',
79
+ login_waiting: 'aguardando confirmação no site',
80
+ login_ok: (u) => `Conectado como ${u}. Pode usar: ts "sua pergunta"`,
81
+ login_expired: 'Código expirou (10 min). Rode `ts login` de novo.',
82
+ login_already: (u) => `Já conectado como ${u}. Use "ts logout" pra trocar de conta.`,
83
+ logout_ok: 'Terminal desconectado. Até logo!',
84
+ logout_none: 'Este terminal já estava desconectado.',
85
+ need_login: 'Este terminal não está conectado. Rode: ts login',
86
+ session_expired: 'Sessão expirada. Rode `ts login` pra reconectar.',
87
+ thinking: 'pensando',
88
+ receiving: 'recebendo',
89
+ new_conv: 'Conversa nova iniciada — o contexto anterior foi deixado pra trás.',
90
+ pipe_ctx: 'Contexto (entrada via pipe)',
91
+ plan_title: (id) => `Plano #${id}`,
92
+ plan_steps: 'etapas',
93
+ plan_est: (c) => `~${c} créditos`,
94
+ plan_approve: 'Aprovar e executar? (s/N) ',
95
+ plan_cancelled: 'Cancelado — nada foi executado nem cobrado além do plano.',
96
+ run_running: (st, done, total) => `executando · ${st} · ${done}/${total} etapas`,
97
+ run_done: 'Orquestração concluída',
98
+ run_failed: 'A orquestração falhou',
99
+ run_paused: (r) => `Pausada (${r}). Retome pela web ou app.`,
100
+ runs_title: 'Últimas orquestrações',
101
+ runs_empty: 'Nenhuma orquestração ainda. Comece com: ts run "objetivo"',
102
+ uso_title: 'Uso do mês',
103
+ uso_plan: 'Plano',
104
+ uso_remaining: 'restantes',
105
+ uso_unlimited: 'ilimitado',
106
+ uso_credits: 'créditos',
107
+ uso_last: 'Últimos usos',
108
+ quem_title: 'Conta conectada',
109
+ quem_user: 'Usuário',
110
+ quem_plan: 'Plano',
111
+ quem_server: 'Servidor',
112
+ quem_conv: 'Conversa ativa',
113
+ lang_set: (l) => `Idioma do CLI: ${l === 'en' ? 'English' : 'Português (Brasil)'}`,
114
+ lang_invalid: 'Idioma não suportado. Use: ts idioma pt ou ts idioma en',
115
+ err_conn: 'Não consegui falar com o servidor. Verifique sua internet e tente de novo.',
116
+ err_generic: 'Algo deu errado',
117
+ no_credits: 'Seus créditos acabaram. Gerencie em terminalsmart.com.br/planos',
118
+ ask_empty: 'Diga o que você precisa. Ex.: ts "como liberar a porta 443 no ufw?"',
119
+ chat_hint: 'digite sua mensagem · "sair" encerra · "/nova" zera o contexto',
120
+ chat_prompt: 'você › ',
121
+ chat_bye: 'Até logo! A conversa continua salva na web (/ia).',
122
+ agent_need: 'Descreva a tarefa. Ex.: ts agente "libere espaço em disco analisando as pastas maiores"',
123
+ agent_thinking: 'agente pensando',
124
+ agent_blocked: 'bloqueado (destrutivo)',
125
+ agent_approve: (cmd) => `O agente quer rodar um comando DESTRUTIVO:\n\n ${cmd}\n\n Permitir? (s/N) `,
126
+ agent_footer: (st, cr, s) => `${st} passo(s) · ${cr} créditos · ${s}s`,
127
+ agent_remote_wait: (ttl) => `comando destrutivo — pedido de aprovação enviado no seu Telegram (responda em até ${Math.round(ttl / 60)} min; sem resposta = negado)`,
128
+ meta_need: 'Descreva o objetivo. Ex.: ts meta "monte um site de portfólio completo nesta pasta" --budget 300',
129
+ meta_title: 'MISSÃO',
130
+ meta_exists: (g) => `Já existe uma missão em andamento neste diretório ("${g.slice(0, 60)}…"). Rode "ts meta" sem objetivo pra RETOMAR, ou use --novo pra recomeçar do zero.`,
131
+ meta_none: 'Nenhuma missão neste diretório. Comece com: ts meta "objetivo grande"',
132
+ meta_resuming: (done, total) => `retomando missão: ${done}/${total} itens concluídos`,
133
+ meta_round: (n, item, at) => `rodada ${n}${at > 1 ? ' (2ª tentativa)' : ''} · ${item}`,
134
+ meta_progress: (done, total, spent, budget) => `${done}/${total} itens · ${spent}/${budget} créditos`,
135
+ meta_done: 'Missão concluída',
136
+ meta_paused_budget: 'Teto de créditos atingido — rode "ts meta" de novo pra continuar (abre nova janela de créditos).',
137
+ meta_paused_rounds: 'Limite de rodadas atingido — rode "ts meta" de novo pra continuar.',
138
+ meta_blocked: 'Itens BLOQUEADOS (falharam 2x — resolva manualmente ou ajuste o objetivo):',
139
+ meta_planning: 'quebrando o objetivo em checklist',
140
+ meta_marking: 'conferindo evidências da rodada',
141
+ meta_notify_done: (goal, total, cr) => `✅ MISSÃO CONCLUÍDA no ts\n"${goal.slice(0, 100)}"\n${total} itens entregues · ${cr} créditos`,
142
+ meta_notify_paused: (goal, done, total, why) => `⏸ Missão pausada no ts (${why})\n"${goal.slice(0, 100)}"\n${done}/${total} itens · rode "ts meta" pra continuar`,
143
+ goal_short: 'Descreva o objetivo. Ex.: ts run "audite a segurança deste servidor"',
144
+ status_notfound: 'Orquestração não encontrada.',
145
+ version: 'versão',
146
+ },
147
+ en: {
148
+ tagline: 'your DevOps agent in the terminal',
149
+ help_examples: 'Examples',
150
+ help_groups: [
151
+ { title: 'Chat', items: [
152
+ ['ts', 'opens chat mode — just type naturally'],
153
+ ['ts "question"', 'one-shot answer, back to the shell'],
154
+ ['cat log | ts "analyze"', 'analyze piped input'],
155
+ ['ts video <url> "..."', 'reads a video transcript and answers (yt-dlp)'],
156
+ ['ts arquivar <url>', 'saves the page as 1 offline HTML (monolith)'],
157
+ ['ts qr', 'QR to continue the conversation on your phone'],
158
+ ['ts nova', 'reset the conversation context'],
159
+ ] },
160
+ { title: 'Skills gallery (community)', items: [
161
+ ['ts skills', 'list community skills (most installed)'],
162
+ ['ts skills buscar "x"', 'search skills by term'],
163
+ ['ts skills ver <slug>', 'read the WHOLE skill before installing'],
164
+ ['ts skills add <slug>', 'install to ~/.ts/skills'],
165
+ ['ts skills publicar <folder>', 'publish your skill to the gallery'],
166
+ ] },
167
+ { title: 'Memory (the agent remembers)', items: [
168
+ ['ts memoria', 'show project + global memory'],
169
+ ['ts memoria add "fact"', 'save a fact (the agent always reads it later)'],
170
+ ['ts memoria add "x" -g', 'save to global memory (every project)'],
171
+ ] },
172
+ { title: 'LOCAL agent (hands on this machine)', items: [
173
+ ['ts agente "task"', 'actually does it here: commands, files, diagnosis'],
174
+ ['ts agente "..." --yes', 'autonomous (destructive asks on Telegram)'],
175
+ ['ts agente --continuar "..."', 'resume this folder\'s previous work'],
176
+ ['ts meta "big goal"', 'MISSION: checklist + rounds until done (overnight)'],
177
+ ['ts meta --status', 'mission state for this directory'],
178
+ ['ts eval suite.json', 'grade the agent on a case suite (AI judge + score)'],
179
+ ['ts acp', 'Agent Client Protocol server (plug ts into editors like Zed)'],
180
+ ] },
181
+ { title: 'Cloud agents (orchestration)', items: [
182
+ ['ts run "goal"', 'plan → you approve → execute'],
183
+ ['ts run "..." --yes', 'no questions (cron/scripts)'],
184
+ ['ts run "..." --json', 'structured JSON output'],
185
+ ['ts runs · ts status <id>', 'follow executions'],
186
+ ] },
187
+ { title: 'Account', items: [
188
+ ['ts login · ts logout', 'connect / disconnect this terminal'],
189
+ ['ts uso', 'monthly credits and usage'],
190
+ ['ts quem', 'connected account'],
191
+ ['ts idioma pt|en', 'language (default pt-BR)'],
192
+ ] },
193
+ ],
194
+ help_footer: 'Every use debits your Smart Credits — track it with `ts uso`.',
195
+ repl_hello: 'chat naturally — I detect question, action or big goal · /help · exit',
196
+ onboard_title: 'First time? Just talk — no commands needed.',
197
+ onboard_lines: [
198
+ ['ask', '"why does nginx return 502?"'],
199
+ ['ask me to DO', '"free up disk space" — I act right here'],
200
+ ['give a big goal', '"build a launch kit" — plan shown first'],
201
+ ],
202
+ onboard_footer: 'I pick the path. Dangerous? I confirm first. Shortcuts: /help',
203
+ route_agent: 'this needs actions on this machine — acting as agent (prefix /chat to just talk)',
204
+ route_run: 'big goal — planning with the agent team (you approve before spending)',
205
+ repl_account: (u, p) => `account ${u} · plan ${p}`,
206
+ repl_credits: (c) => `${c} credits`,
207
+ repl_help: [
208
+ ['type anything', 'natural language chat'],
209
+ ['/agente "task"', 'actually does it on this machine (commands, files)'],
210
+ ['/run "goal"', 'orchestrate cloud agents (plan + approval)'],
211
+ ['cd <folder> · pwd', 'change/show the agent working folder'],
212
+ ['/runs', 'recent orchestrations'],
213
+ ['/uso', 'monthly credits'],
214
+ ['/nova', 'reset context'],
215
+ ['exit', 'quit'],
216
+ ],
217
+ ex1: 'ts "why is nginx returning 502 after deploy?"',
218
+ ex2: 'docker logs api --tail 200 | ts "any serious errors here?"',
219
+ ex3: 'ts run "run a basic security audit on this server" --yes',
220
+ login_title: 'Connect this terminal',
221
+ login_step1: '1. Open:',
222
+ login_step2: '2. Once logged in, enter the code:',
223
+ login_waiting: 'waiting for confirmation on the site',
224
+ login_ok: (u) => `Connected as ${u}. Try: ts "your question"`,
225
+ login_expired: 'Code expired (10 min). Run `ts login` again.',
226
+ login_already: (u) => `Already connected as ${u}. Use "ts logout" to switch accounts.`,
227
+ logout_ok: 'Terminal disconnected. See you!',
228
+ logout_none: 'This terminal was already disconnected.',
229
+ need_login: 'This terminal is not connected. Run: ts login',
230
+ session_expired: 'Session expired. Run `ts login` to reconnect.',
231
+ thinking: 'thinking',
232
+ receiving: 'receiving',
233
+ new_conv: 'Fresh conversation started — previous context left behind.',
234
+ pipe_ctx: 'Context (piped input)',
235
+ plan_title: (id) => `Plan #${id}`,
236
+ plan_steps: 'steps',
237
+ plan_est: (c) => `~${c} credits`,
238
+ plan_approve: 'Approve and run? (y/N) ',
239
+ plan_cancelled: 'Cancelled — nothing was executed or charged beyond planning.',
240
+ run_running: (st, done, total) => `running · ${st} · ${done}/${total} steps`,
241
+ run_done: 'Orchestration finished',
242
+ run_failed: 'Orchestration failed',
243
+ run_paused: (r) => `Paused (${r}). Resume on the web or app.`,
244
+ runs_title: 'Recent orchestrations',
245
+ runs_empty: 'No orchestrations yet. Start with: ts run "goal"',
246
+ uso_title: 'Monthly usage',
247
+ uso_plan: 'Plan',
248
+ uso_remaining: 'remaining',
249
+ uso_unlimited: 'unlimited',
250
+ uso_credits: 'credits',
251
+ uso_last: 'Recent usage',
252
+ quem_title: 'Connected account',
253
+ quem_user: 'User',
254
+ quem_plan: 'Plan',
255
+ quem_server: 'Server',
256
+ quem_conv: 'Active conversation',
257
+ lang_set: (l) => `CLI language: ${l === 'en' ? 'English' : 'Português (Brasil)'}`,
258
+ lang_invalid: 'Unsupported language. Use: ts idioma pt or ts idioma en',
259
+ err_conn: 'Could not reach the server. Check your connection and retry.',
260
+ err_generic: 'Something went wrong',
261
+ no_credits: 'You are out of credits. Manage at terminalsmart.com.br/planos',
262
+ ask_empty: 'Tell me what you need. E.g.: ts "how do I open port 443 on ufw?"',
263
+ chat_hint: 'type your message · "exit" quits · "/new" resets context',
264
+ chat_prompt: 'you › ',
265
+ chat_bye: 'See you! The conversation stays saved on the web (/ia).',
266
+ agent_need: 'Describe the task. E.g.: ts agente "free disk space by analyzing the largest folders"',
267
+ agent_thinking: 'agent thinking',
268
+ agent_blocked: 'blocked (destructive)',
269
+ agent_approve: (cmd) => `The agent wants to run a DESTRUCTIVE command:\n\n ${cmd}\n\n Allow? (y/N) `,
270
+ agent_footer: (st, cr, s) => `${st} step(s) · ${cr} credits · ${s}s`,
271
+ agent_remote_wait: (ttl) => `destructive command — approval request sent to your Telegram (answer within ${Math.round(ttl / 60)} min; no answer = denied)`,
272
+ meta_need: 'Describe the goal. E.g.: ts meta "build a complete portfolio site in this folder" --budget 300',
273
+ meta_title: 'MISSION',
274
+ meta_exists: (g) => `A mission is already in progress in this directory ("${g.slice(0, 60)}…"). Run "ts meta" without a goal to RESUME, or use --novo to start over.`,
275
+ meta_none: 'No mission in this directory. Start with: ts meta "big goal"',
276
+ meta_resuming: (done, total) => `resuming mission: ${done}/${total} items done`,
277
+ meta_round: (n, item, at) => `round ${n}${at > 1 ? ' (2nd attempt)' : ''} · ${item}`,
278
+ meta_progress: (done, total, spent, budget) => `${done}/${total} items · ${spent}/${budget} credits`,
279
+ meta_done: 'Mission accomplished',
280
+ meta_paused_budget: 'Credit ceiling reached — run "ts meta" again to continue (opens a new credit window).',
281
+ meta_paused_rounds: 'Round limit reached — run "ts meta" again to continue.',
282
+ meta_blocked: 'BLOCKED items (failed twice — fix manually or adjust the goal):',
283
+ meta_planning: 'breaking the goal into a checklist',
284
+ meta_marking: 'checking round evidence',
285
+ meta_notify_done: (goal, total, cr) => `✅ MISSION DONE on ts\n"${goal.slice(0, 100)}"\n${total} items delivered · ${cr} credits`,
286
+ meta_notify_paused: (goal, done, total, why) => `⏸ Mission paused on ts (${why})\n"${goal.slice(0, 100)}"\n${done}/${total} items · run "ts meta" to continue`,
287
+ goal_short: 'Describe the goal. E.g.: ts run "audit this server\'s security"',
288
+ status_notfound: 'Orchestration not found.',
289
+ version: 'version',
290
+ },
291
+ };
292
+
293
+ function t(lang) { return STR[lang] || STR.pt; }
294
+ module.exports = { t };
package/lib/memoria.js ADDED
@@ -0,0 +1,38 @@
1
+ // MEMÓRIA DE PROJETO (como o Claude "lembra"): fatos persistentes que o agente SEMPRE carrega
2
+ // e pode ATUALIZAR (ferramenta lembrar). Dois níveis:
3
+ // - GLOBAL: ~/.ts/memoria.md (vale em qualquer projeto — preferências, jeito de trabalhar)
4
+ // - PROJETO: <pasta>/.ts-memoria.md (o que este projeto é, decisões, armadilhas, comandos)
5
+ // Injetada no prompt do agente/missão em TODA rodada → ele não repete contexto nem esquece.
6
+ const fs = require('fs');
7
+ const os = require('os');
8
+ const path = require('path');
9
+
10
+ const GLOBAL = path.join(os.homedir(), '.ts', 'memoria.md');
11
+ const projFile = (dir) => path.join(dir || process.cwd(), '.ts-memoria.md');
12
+
13
+ function _read(f, cap) {
14
+ try { return fs.existsSync(f) ? fs.readFileSync(f, 'utf8').trim().slice(0, cap) : ''; } catch (_) { return ''; }
15
+ }
16
+
17
+ // Texto pronto pra injetar no prompt (global + projeto). Vazio se não houver nada.
18
+ function load(dir) {
19
+ const g = _read(GLOBAL, 4000);
20
+ const p = _read(projFile(dir), 6000);
21
+ let out = '';
22
+ if (g) out += 'MEMÓRIA GLOBAL (preferências/jeito de trabalhar do usuário):\n' + g + '\n\n';
23
+ if (p) out += 'MEMÓRIA DESTE PROJETO (o que ele é, decisões, armadilhas — RESPEITE e mantenha coerência):\n' + p + '\n';
24
+ return out.trim();
25
+ }
26
+
27
+ // Anexa um fato (o agente chama via ferramenta lembrar; ou o usuário via `ts memoria add`).
28
+ function append(dir, fato, global) {
29
+ const f = global ? GLOBAL : projFile(dir);
30
+ fs.mkdirSync(path.dirname(f), { recursive: true });
31
+ const header = global ? '# Memória global do Terminal Smart\n\n' : '# Memória deste projeto (Terminal Smart)\n\n';
32
+ const line = '- ' + String(fato || '').replace(/\s+/g, ' ').trim();
33
+ if (!line.slice(2).length) return null;
34
+ fs.appendFileSync(f, (fs.existsSync(f) ? '' : header) + line + '\n', 'utf8');
35
+ return f;
36
+ }
37
+
38
+ module.exports = { load, append, projFile, GLOBAL };