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 +34 -0
- package/lib/i18n.js +2 -0
- package/lib/meta.js +7 -0
- package/package.json +1 -1
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
|
}
|