terminal-smart-cli 0.66.0 → 0.67.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
@@ -1186,10 +1186,17 @@ async function metaCmd() {
1186
1186
  // CRITÉRIOS EXECUTÁVEIS (verify): --criterios <arquivo.json> = a PROVA de que a missão
1187
1187
  // cumpriu o pedido (não basta compilar/abrir). Falhou → missão sai "NÃO verificada".
1188
1188
  let criteria = [];
1189
+ const _verify = require('../lib/verify');
1189
1190
  const _critFile = (() => { const i = rawArgs.findIndex(a => a === '--criterios' || a === '--criteria'); return i >= 0 ? rawArgs[i + 1] : null; })();
1190
1191
  if (_critFile) {
1191
- try { const j = JSON.parse(require('fs').readFileSync(_critFile, 'utf8')); criteria = Array.isArray(j) ? j : (j.criteria || []); }
1192
+ try { const j = JSON.parse(require('fs').readFileSync(_critFile, 'utf8')); const comp = _verify.compileCriteria(j); criteria = comp.criteria;
1193
+ if (comp.dropped.length) console.log(' ' + C.dim((cfg.lang === 'en' ? 'ignored ' : 'ignorei ') + comp.dropped.length + (cfg.lang === 'en' ? ' invalid criterion(s)' : ' critério(s) inválido(s)'))); }
1192
1194
  catch (e) { console.error(ui.errLine((cfg.lang === 'en' ? 'criteria file: ' : 'arquivo de critérios: ') + (e.message || e))); process.exit(2); }
1195
+ } else if (FLAGS.has('--provar') || FLAGS.has('--prove')) {
1196
+ // TaskSpec automático: deriva os critérios da stack (testes) — sem json na mão.
1197
+ criteria = _verify.deriveFromStack(dir);
1198
+ if (criteria.length) console.log(' ' + C.dim((cfg.lang === 'en' ? 'auto-derived proof: ' : 'prova auto-derivada: ') + criteria.map(c => c.label || c.type).join(' · ')) + '\n');
1199
+ else console.log(' ' + C.dim(cfg.lang === 'en' ? '--provar: no test command detected in this project (nothing to auto-prove)' : '--provar: nenhum comando de teste detectado neste projeto (nada a auto-provar)') + '\n');
1193
1200
  }
1194
1201
 
1195
1202
  const existing = metaMod.load(dir);
package/lib/i18n.js CHANGED
@@ -44,6 +44,7 @@ const STR = {
44
44
  ['ts agente "..." --navegador', 'EXPERIMENTAL: dá um Chrome real ao agente (abrir/ler/clicar/print+visão)'],
45
45
  ['ts meta "objetivo grande"', 'MISSÃO: checklist + rodadas até terminar (noturno)'],
46
46
  ['ts meta "..." --criterios prova.json', 'só declara "verificada" se os critérios executáveis (verify) passarem de verdade'],
47
+ ['ts meta "..." --provar', 'auto-deriva a prova da stack (roda os testes do projeto) — sem escrever json'],
47
48
  ['ts meta --status', 'estado da missão deste diretório'],
48
49
  ['ts eval suite.json', 'avalia o agente numa suíte de casos (juiz de IA + nota)'],
49
50
  ['ts verificar --cmd "npm test" --url ... --porta N', 'PROVA determinística de conclusão (build/http/porta/arquivo); exit 1 pra CI'],
package/lib/verify.js CHANGED
@@ -101,4 +101,31 @@ async function runAll(criteria, opts = {}) {
101
101
  return { allOk: results.length > 0 && passed === results.length, passed, total: results.length, results };
102
102
  }
103
103
 
104
- module.exports = { runCriterion, runAll, VERIFIERS, VERIFIER_TYPES, _labelFor };
104
+ // ── COMPILADOR de critérios (TaskSpec): o LLM/usuário PROPÕE, o harness VALIDA ────
105
+ // Aceita só tipos conhecidos com os campos obrigatórios preenchidos; descarta o resto
106
+ // (o modelo não impõe critério malformado). Determinístico. Retorna { criteria, dropped }.
107
+ const _REQUIRED = { command: ['cmd'], file_exists: ['path'], file_absent: ['path'], file_contains: ['path', 'text'], http: ['url'], port: ['port'] };
108
+ function compileCriteria(raw) {
109
+ const list = Array.isArray(raw) ? raw : (raw && Array.isArray(raw.criteria) ? raw.criteria : []);
110
+ const criteria = [], dropped = [];
111
+ for (const c of list) {
112
+ if (!c || typeof c !== 'object' || !_REQUIRED[c.type]) { dropped.push(c); continue; }
113
+ const missing = _REQUIRED[c.type].some(k => c[k] === undefined || c[k] === null || c[k] === '');
114
+ if (missing) { dropped.push(c); continue; }
115
+ const clean = { type: c.type };
116
+ for (const k of ['cmd', 'exit', 'path', 'text', 'regex', 'flags', 'absent', 'url', 'method', 'status', 'contains', 'port', 'host', 'timeout_s', 'label']) if (c[k] !== undefined) clean[k] = c[k];
117
+ criteria.push(clean);
118
+ }
119
+ return { criteria, dropped };
120
+ }
121
+
122
+ // Deriva critérios DETERMINÍSTICOS da stack (os TESTES, que os gates de build/run NÃO cobrem).
123
+ // "A missão só é verificada se os testes passarem" — TaskSpec automático, zero json na mão.
124
+ function deriveFromStack(cwd) {
125
+ let st; try { st = require('./stack').detectStack(cwd); } catch (_) { return []; }
126
+ const out = [];
127
+ for (const t of (st.test || [])) { if (/test/i.test(t)) out.push({ type: 'command', cmd: t, exit: 0, label: 'testes passam (' + t + ')' }); }
128
+ return out;
129
+ }
130
+
131
+ module.exports = { runCriterion, runAll, compileCriteria, deriveFromStack, VERIFIERS, VERIFIER_TYPES, _labelFor };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terminal-smart-cli",
3
- "version": "0.66.0",
3
+ "version": "0.67.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"