terminal-smart-cli 0.44.0 → 0.46.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 CHANGED
@@ -1380,6 +1380,39 @@ async function nova() {
1380
1380
  console.log(ui.okLine(T.new_conv));
1381
1381
  }
1382
1382
 
1383
+ // RECALL cross-sessão (estilo deja-vu): busca um termo em TODAS as sessões passadas do
1384
+ // agente (~/.ts/agente/*.json, uma por pasta de projeto) — "já lidei com isso antes, e onde?".
1385
+ // 100% LOCAL, sem rede: usa as sessões que o `ts agente` já salva por pasta.
1386
+ function recallCmd(args) {
1387
+ const _fs = require('fs'), _p = require('path'), _os = require('os');
1388
+ const termo = (args || []).join(' ').trim();
1389
+ if (!termo) { console.error(ui.infoLine(cfg.lang === 'en' ? 'Usage: ts recall <term> — searches your past agent sessions' : 'Uso: ts recall <termo> — busca nas suas sessões passadas do agente')); process.exit(2); }
1390
+ const dir = _p.join(_os.homedir(), '.ts', 'agente');
1391
+ let files = []; try { files = _fs.readdirSync(dir).filter(f => f.endsWith('.json')); } catch (_) {}
1392
+ const rx = new RegExp(termo.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i');
1393
+ const hits = [];
1394
+ for (const f of files) {
1395
+ let s; try { s = JSON.parse(_fs.readFileSync(_p.join(dir, f), 'utf8')); } catch (_) { continue; }
1396
+ const folder = s.cwd ? _p.basename(s.cwd) : '?';
1397
+ for (const m of (s.messages || [])) {
1398
+ if (m.role === 'system') continue; // pula o prompt injetado (ruído, não é conversa)
1399
+ const txt = typeof m.content === 'string' ? m.content : JSON.stringify(m.content || '');
1400
+ const i = txt.search(rx);
1401
+ if (i >= 0) { const snip = txt.slice(Math.max(0, i - 60), i + 140).replace(/\s+/g, ' ').trim(); hits.push({ folder, at: s.at || '', role: m.role || '?', snip }); }
1402
+ }
1403
+ }
1404
+ if (JSON_OUT) { console.log(JSON.stringify({ termo, hits })); return; }
1405
+ if (!hits.length) { console.log(ui.infoLine((cfg.lang === 'en' ? 'No past session mentions ' : 'Nenhuma sessão passada menciona ') + C.cyan('"' + termo + '"'))); return; }
1406
+ hits.sort((a, b) => String(b.at).localeCompare(String(a.at)));
1407
+ const lines = [];
1408
+ for (const h of hits.slice(0, 12)) {
1409
+ lines.push(C.cyan(h.folder) + C.dim(' · ' + String(h.at).slice(0, 10) + ' · ' + h.role));
1410
+ lines.push(' ' + C.dim(h.snip.slice(0, 180)));
1411
+ }
1412
+ const title = 'Recall: "' + termo + '" (' + hits.length + (cfg.lang === 'en' ? ' hits' : ' resultados') + ')';
1413
+ console.log('\n' + ui.box(lines, { title }) + '\n');
1414
+ }
1415
+
1383
1416
  // ── Dispatcher ───────────────────────────────────────────────────────────────
1384
1417
  (async () => {
1385
1418
  const cmd = (POS[0] || '').toLowerCase();
@@ -1407,6 +1440,7 @@ async function nova() {
1407
1440
  case 'acp': return acpCmd();
1408
1441
  case 'skills': case 'skill': return skillsCmd(POS.slice(1));
1409
1442
  case 'memoria': case 'memória': case 'memory': return memoriaCmd(POS.slice(1));
1443
+ case 'recall': case 'lembrei': case 'sessoes': case 'sessões': return recallCmd(POS.slice(1));
1410
1444
  case 'vps': case 'servidor': return vpsCmd(POS.slice(1));
1411
1445
  case 'meta': case 'missao': case 'mission': return metaCmd();
1412
1446
  case 'runs': return runsCmd();
package/lib/i18n.js CHANGED
@@ -26,6 +26,7 @@ const STR = {
26
26
  ['ts memoria', 'mostra a memória do projeto + global'],
27
27
  ['ts memoria add "fato"', 'grava um fato (o agente sempre lê depois)'],
28
28
  ['ts memoria add "x" -g', 'grava na memória global (todo projeto)'],
29
+ ['ts recall "termo"', 'busca "já vi isso?" nas suas sessões passadas'],
29
30
  ] },
30
31
  { title: 'Agente LOCAL (mãos nesta máquina)', items: [
31
32
  ['ts agente "tarefa"', 'executa DE VERDADE aqui: comandos, arquivos, diagnóstico'],
@@ -174,6 +175,7 @@ const STR = {
174
175
  ['ts memoria', 'show project + global memory'],
175
176
  ['ts memoria add "fact"', 'save a fact (the agent always reads it later)'],
176
177
  ['ts memoria add "x" -g', 'save to global memory (every project)'],
178
+ ['ts recall "term"', 'search your past sessions ("seen this before?")'],
177
179
  ] },
178
180
  { title: 'LOCAL agent (hands on this machine)', items: [
179
181
  ['ts agente "task"', 'actually does it here: commands, files, diagnosis'],
package/lib/meta.js CHANGED
@@ -1035,6 +1035,13 @@ async function run(goal, opts = {}) {
1035
1035
  save(st, dir);
1036
1036
  } else {
1037
1037
  st.status = 'running';
1038
+ // RESUME = tentativa LIMPA. Sem isto, missão pausada por estagnação RE-TRAVA na hora
1039
+ // (contador/fp/erro-de-build persistidos no estado). Zera o watchdog + escalonamentos e
1040
+ // LIMPA o buildError velho → o gate RE-RODA do zero (pega fix de ambiente/harness que
1041
+ // resolveu o erro fora do código, ex: porta que estava ocupada). Se ainda falhar DE VERDADE,
1042
+ // os contadores re-acumulam normalmente nesta janela e o watchdog corta como sempre.
1043
+ st.stagnant = 0; st.lastFp = null; st.escalations = 0;
1044
+ st.buildError = ''; st.lastBuildSig = '';
1038
1045
  if (opts.addBudget) st.budget += opts.addBudget;
1039
1046
  else if (st.creditsSpent >= st.budget) st.budget = st.creditsSpent + budget; // nova janela ao retomar
1040
1047
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terminal-smart-cli",
3
- "version": "0.44.0",
3
+ "version": "0.46.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"