terminal-smart-cli 0.97.58 → 0.97.59

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
@@ -243,7 +243,9 @@ async function personalAiCmd(args = []) {
243
243
  if (sub === 'status') return show(await api('/api/personal-ai/status',{token}));
244
244
  if (['usar','use','modo','mode'].includes(sub)) {
245
245
  const mode=String(args[1] || '').toLowerCase();
246
- const state=await api('/api/personal-ai/mode',{method:'POST',token,body:{mode}}); show(state); return;
246
+ const state=await api('/api/personal-ai/mode',{method:'POST',token,body:{mode}});
247
+ cfg = config.save({ forceTsCloud: mode === 'automatico' ? true : undefined });
248
+ show(state); return;
247
249
  }
248
250
  if (['desconectar','disconnect'].includes(sub)) {
249
251
  const provider=String(args[1] || '').toLowerCase();
@@ -1510,7 +1512,7 @@ async function agentCmd(words, { askFn, cwd: cwdIn = null, onCwd = null, maxIter
1510
1512
  } });
1511
1513
  if (shared?.ok && shared.promptBlock) sharedChannelPrompt = shared.promptBlock;
1512
1514
  const personalState = await api('/api/personal-ai/status', { token });
1513
- const personalReady = personalState?.ok && personalState.mode !== 'automatico'
1515
+ const personalReady = !cfg.forceTsCloud && personalState?.ok && personalState.mode !== 'automatico'
1514
1516
  && (personalState.mode === 'chatgpt' ? personalState.chatgpt
1515
1517
  : personalState.mode === 'claude' ? personalState.claude
1516
1518
  : personalState.chatgpt && personalState.claude);
@@ -2871,6 +2873,7 @@ async function conectarCmd(words) {
2871
2873
  // ts conectar nuvem — volta a usar os créditos do TS
2872
2874
  if (sub === 'nuvem' || sub === 'cloud' || sub === 'ts') {
2873
2875
  keyring.usar(null);
2876
+ cfg = config.save({ forceTsCloud: true });
2874
2877
  console.log(' ' + C.ok('✔ ') + (en ? 'back to TS Cloud (your credits).' : 'de volta ao TS Cloud (seus créditos).'));
2875
2878
  return;
2876
2879
  }
package/lib/agent.js CHANGED
@@ -835,6 +835,19 @@ function loopSig(name, input) {
835
835
  }
836
836
 
837
837
  const FILE_MUTATORS = new Set(['escrever_arquivo', 'editar_arquivo', 'editar_documento', 'editar_planilha']);
838
+ function normalizeFileToolInput(name, input, { cwd = process.cwd(), exclusiveTargets = [] } = {}) {
839
+ const out = input && typeof input === 'object' ? Object.assign({}, input) : {};
840
+ if (!FILE_MUTATORS.has(name)) return out;
841
+ const alias = out.caminho || out.path || out.arquivo || out.file || out.filename;
842
+ if (alias && String(alias).trim() && String(alias).trim() !== '.') {
843
+ out.caminho = alias;
844
+ return out;
845
+ }
846
+ if (exclusiveTargets.length === 1) {
847
+ out.caminho = path.relative(cwd, exclusiveTargets[0]) || exclusiveTargets[0];
848
+ }
849
+ return out;
850
+ }
838
851
  function mutationBatchConflicts(toolCalls, cwd) {
839
852
  const groups = new Map();
840
853
  for (const tc of (Array.isArray(toolCalls) ? toolCalls : [])) {
@@ -1812,6 +1825,7 @@ async function run(task, opts = {}) {
1812
1825
  for (const tc of tcs) {
1813
1826
  const name = (tc.function && tc.function.name) || '';
1814
1827
  let input = {}; try { input = JSON.parse((tc.function && tc.function.arguments) || '{}'); } catch (_) {}
1828
+ input = normalizeFileToolInput(name, input, { cwd, exclusiveTargets: _exclusiveFileTargets });
1815
1829
  let result;
1816
1830
  let _cachedContent = '';
1817
1831
  let _ran = false; // true só quando uma ferramenta REALMENTE executou (não gate/bloqueio) → status ✓/✗
@@ -2514,4 +2528,4 @@ async function run(task, opts = {}) {
2514
2528
  return { text: finalText, steps, credits: charged + _visionCredits, tokens: acc, model: usedModel, actions, messages, cwd, context: lastCtx, toolErrors: _toolErrs, lastToolError: _lastErr, guard: guardStopped, completion, verification: verifyReport, observability: _observability, report: _finalReport, orchestration: { plan: _planDecision, roles: _roleTrace, inspections: _inspectionTrace, phaseBudgets: _phaseBudgets, phaseUsage: _phaseUsage }, missionCache: _missionCache.stats() };
2515
2529
  }
2516
2530
 
2517
- module.exports = { run, llm, _test: { systemPrompt, projectBrief, inspectionGateDecision, independentInspectorDecision, candidateAdmitsIncomplete, isInspectionCommand, parseStageJson, materialDecisionPreflight, actionExpectedForTask, requiresActionEvidence, shouldRunPlanner, isComplexTask, validatePlannerDecision, planUpgradeLimit, commandRecoveryHint, windowsUnsupportedUnixCommand, mutationBatchConflicts, normalizePlannerDecision, normalizeInspectorDecision, winFor, estMsgsTok, COMPACT_AT, KEEP_TAIL, loopSig, isCycle, loopDecision, decideApproval, failureFingerprint, missionGuardDecision, missionBudgetSuggestion, missionTokenCap, missionTimeCap, modelCallWindow, modelCallCap, explicitExclusiveFileTargets, executorFallbackChain, forcedModelMismatch, isTransientModelError, executorCompletionCap, completionGateDecision, canCloseFromProofs, taskScopedToolDefs, explicitTaskWorkdir, restrictedGatewayDecision, validarModeloByok, scopeToolDefs, parseTextToolCalls, isUntrustedToolOutput, untrustedToolEnvelope, isRemoteDeployCommand, browserApprovalRequest } };
2531
+ module.exports = { run, llm, _test: { systemPrompt, projectBrief, inspectionGateDecision, independentInspectorDecision, candidateAdmitsIncomplete, isInspectionCommand, parseStageJson, materialDecisionPreflight, actionExpectedForTask, requiresActionEvidence, shouldRunPlanner, isComplexTask, validatePlannerDecision, planUpgradeLimit, commandRecoveryHint, windowsUnsupportedUnixCommand, mutationBatchConflicts, normalizeFileToolInput, normalizePlannerDecision, normalizeInspectorDecision, winFor, estMsgsTok, COMPACT_AT, KEEP_TAIL, loopSig, isCycle, loopDecision, decideApproval, failureFingerprint, missionGuardDecision, missionBudgetSuggestion, missionTokenCap, missionTimeCap, modelCallWindow, modelCallCap, explicitExclusiveFileTargets, executorFallbackChain, forcedModelMismatch, isTransientModelError, executorCompletionCap, completionGateDecision, canCloseFromProofs, taskScopedToolDefs, explicitTaskWorkdir, restrictedGatewayDecision, validarModeloByok, scopeToolDefs, parseTextToolCalls, isUntrustedToolOutput, untrustedToolEnvelope, isRemoteDeployCommand, browserApprovalRequest } };
package/lib/tools.js CHANGED
@@ -799,6 +799,9 @@ async function execute(name, input, opts = {}) {
799
799
  return { total: resultados.length, resultados, aviso: resultados.length < arquivos.length ? 'Lote limitado pelo teto de contexto; peca os trechos restantes em outro lote.' : undefined };
800
800
  }
801
801
  case 'escrever_arquivo': {
802
+ if (!input.caminho || !String(input.caminho).trim() || String(input.caminho).trim() === '.') {
803
+ return { erro: 'Informe o caminho completo do ARQUIVO em caminho (ex.: docs/relatorio.md). O diretório de trabalho sozinho não é um arquivo.' };
804
+ }
802
805
  let p = _abs(input.caminho, baseDir);
803
806
  { const g = _guardTsHome(p); if (g) return { erro: g }; }
804
807
  // Confinamento (missões): modelos fracos inventam pastas absolutas
@@ -832,6 +835,9 @@ async function execute(name, input, opts = {}) {
832
835
  } finally { held.lock.release(); }
833
836
  }
834
837
  case 'editar_arquivo': {
838
+ if (!input.caminho || !String(input.caminho).trim() || String(input.caminho).trim() === '.') {
839
+ return { erro: 'Informe o caminho completo do ARQUIVO em caminho (ex.: docs/relatorio.md). O diretório de trabalho sozinho não é um arquivo.' };
840
+ }
835
841
  // Edição por ÂNCORA (ideia do hashline do OMYP): troca SÓ o trecho buscado, sem
836
842
  // reescrever o arquivo — modelo barato edita com precisão, gasta menos tokens de
837
843
  // saída e não corre o risco de "perder" o resto do arquivo num rewrite.
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "terminal-smart-cli",
3
- "version": "0.97.58",
3
+ "version": "0.97.59",
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"
7
7
  },
8
8
  "scripts": {
9
- "test": "node test/durable-operation.test.js && node test/mission-tool-cache.test.js && node test/content-quality-runtime-files.test.js && node test/personal-agent-llm.test.js && node test/personal-inspector-efficiency.test.js && node test/personal-inspector-context.test.js && node test/planner-fallback.test.js"
9
+ "test": "node test/durable-operation.test.js && node test/mission-tool-cache.test.js && node test/content-quality-runtime-files.test.js && node test/personal-agent-llm.test.js && node test/personal-inspector-efficiency.test.js && node test/personal-inspector-context.test.js && node test/planner-fallback.test.js && node test/cli-agent-regressions.test.js"
10
10
  },
11
11
  "files": [
12
12
  "bin",