terminal-smart-cli 0.97.15 → 0.97.17

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 CHANGED
@@ -163,7 +163,7 @@ const STR = {
163
163
  chat_bye: 'Até logo! A conversa continua salva na web (/ia).',
164
164
  agent_need: 'Descreva a tarefa. Ex.: ts agente "libere espaço em disco analisando as pastas maiores"',
165
165
  agent_thinking: 'agente pensando',
166
- agent_blocked: 'bloqueado (destrutivo)',
166
+ agent_blocked: 'bloqueado pelo harness',
167
167
  agent_approve: (cmd) => `O agente quer rodar um comando DESTRUTIVO:\n\n ${cmd}\n\n Permitir? (s/N) `,
168
168
  agent_footer: (st, cr, s) => `${st} passo(s) · ${cr} créditos · ${s}`,
169
169
  agent_footer_byok: (st, prov, s) => `${st} passo(s) · sua chave (${prov}) · ${s}`,
@@ -332,7 +332,7 @@ const STR = {
332
332
  chat_bye: 'See you! The conversation stays saved on the web (/ia).',
333
333
  agent_need: 'Describe the task. E.g.: ts agente "free disk space by analyzing the largest folders"',
334
334
  agent_thinking: 'agent thinking',
335
- agent_blocked: 'blocked (destructive)',
335
+ agent_blocked: 'blocked by harness',
336
336
  agent_approve: (cmd) => `The agent wants to run a DESTRUCTIVE command:\n\n ${cmd}\n\n Allow? (y/N) `,
337
337
  agent_footer: (st, cr, s) => `${st} step(s) · ${cr} credits · ${s}`,
338
338
  agent_footer_byok: (st, prov, s) => `${st} step(s) · your key (${prov}) · ${s}`,
package/lib/meta.js CHANGED
@@ -45,18 +45,20 @@ function toolsForMetaItem(item, goal) {
45
45
 
46
46
  // Connect each checklist item to a concrete artifact. Planner criteria have
47
47
  // priority; deterministic fallbacks cover later items that exceed the criteria cap.
48
- function artifactForMetaItem(item, st) {
49
- const list = Array.isArray(st && st.checklist) ? st.checklist : [];
50
- const index = Math.max(0, list.indexOf(item));
51
- const criterion = Array.isArray(st && st.criteria) ? st.criteria[index] : null;
52
- if (criterion && criterion.type === 'file_exists' && criterion.path) return String(criterion.path);
48
+ function artifactForMetaItem(item, st, dir = '') {
53
49
  const d = String(item && item.desc || '').toLowerCase();
50
+ const criteria = Array.isArray(st && st.criteria) ? st.criteria : [];
51
+ const namedCriterion = criteria.find(c => c && c.path && d.includes(path.basename(String(c.path)).toLowerCase()));
52
+ if (namedCriterion) return String(namedCriterion.path);
54
53
  if (/controller.*8 dire|8 dire.*controller/.test(d)) return 'src/player_controller.gd';
55
54
  if (/combate b[aá]sico|sistema de combate/.test(d)) return 'src/combat_system.gd';
56
55
  if (/interface|\bui\b|\bhud\b/.test(d)) return 'docs/UI_SPEC.md';
57
56
  if (/80-100 monstros|lista.*monstros/.test(d)) return 'data/monsters.json';
58
57
  if (/economia|zeny|vending/.test(d)) return 'docs/ECONOMY.md';
59
58
  if (/prioriza|\bmvp\b.*alpha|roadmap/.test(d)) return 'docs/ROADMAP.md';
59
+ // Em projeto web de arquivo único, itens funcionais/visuais alteram o app real.
60
+ // Critérios globais não correspondem por posição aos itens do checklist.
61
+ if (dir && fs.existsSync(path.join(dir, 'index.html')) && !/readme|instru[çc][õo]es|documenta[çc][ãa]o/.test(d)) return 'index.html';
60
62
  return `artifacts/${String(item && item.id || 'item').replace(/[^a-z0-9_-]/gi, '_')}.md`;
61
63
  }
62
64
 
@@ -1366,7 +1368,7 @@ async function run(goal, opts = {}) {
1366
1368
  }
1367
1369
 
1368
1370
  const item = pend[0];
1369
- const expectedArtifact = artifactForMetaItem(item, st);
1371
+ const expectedArtifact = artifactForMetaItem(item, st, dir);
1370
1372
  // A process can be interrupted after a read-only round but before the
1371
1373
  // no-artifact branch persists `directArtifact`. Recover that evidence on
1372
1374
  // resume instead of repeating the same exploratory attempt.
@@ -1630,13 +1632,17 @@ async function run(goal, opts = {}) {
1630
1632
  if (expectedNow && !wroteExpectedNow) {
1631
1633
  item.attempts = Math.max(0, (item.attempts || 1) - 1);
1632
1634
  item.avoidModels = [...new Set([...(item.avoidModels || []), String(out.model || roundModel || 'automatico')])];
1633
- item.directArtifact = true;
1635
+ const expectedTarget = path.isAbsolute(expectedArtifact) ? expectedArtifact : path.resolve(dir, expectedArtifact);
1636
+ // Conteúdo direto é seguro para um artefato NOVO. Para código existente ele poderia
1637
+ // substituir o projeto inteiro por uma resposta parcial do item; nesse caso troque o
1638
+ // executor e obrigue uma edição real, preservando o arquivo atual.
1639
+ item.directArtifact = !fs.existsSync(expectedTarget);
1634
1640
  const failedModel = String(out.model || roundModel || 'glm-5.2');
1635
- item.directModel = /glm/i.test(failedModel) ? 'glm-5.2' : failedModel;
1641
+ if (item.directArtifact) item.directModel = /glm/i.test(failedModel) ? 'glm-5.2' : failedModel;
1636
1642
  st.status = 'paused'; st.pause_reason = 'model_no_action';
1637
1643
  st.budget = st.creditsSpent;
1638
1644
  save(st, dir);
1639
- onAlert({ type: 'retry', text: `O modelo ${out.model || roundModel || 'automatico'} respondeu, mas executou zero ferramentas. Nao marquei falha do item; a retomada usara outro executor.` });
1645
+ onAlert({ type: 'retry', text: `O modelo ${out.model || roundModel || 'automatico'} não persistiu o artefato esperado. Não marquei o item como concluído; a retomada usará outro executor sem substituir código existente.` });
1640
1646
  return st;
1641
1647
  }
1642
1648
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terminal-smart-cli",
3
- "version": "0.97.15",
3
+ "version": "0.97.17",
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"