terminal-smart-cli 0.46.0 → 0.47.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.
Files changed (2) hide show
  1. package/bin/ts.js +81 -0
  2. package/package.json +1 -1
package/bin/ts.js CHANGED
@@ -1333,6 +1333,86 @@ async function metaCmd() {
1333
1333
  }
1334
1334
 
1335
1335
  // ── Uso / conta / idioma ─────────────────────────────────────────────────────
1336
+ // ── ts cloud — caixa de dev na nuvem (Fase 1) ────────────────────────────────
1337
+ async function cloudCmd(args) {
1338
+ const token = needToken();
1339
+ const en = (cfg.lang === 'en');
1340
+ const sub = String(args[0] || 'status').toLowerCase();
1341
+ const rest = args.slice(1).filter(a => !a.startsWith('-'));
1342
+ const call = (path, opts = {}) => api('/api/cloud/' + path, { token, ...opts });
1343
+
1344
+ if (sub === 'up' || sub === 'start' || sub === 'ligar') {
1345
+ console.log(C.dim(en ? 'provisioning your cloud box…' : 'provisionando sua caixa na nuvem…'));
1346
+ try {
1347
+ const r = await call('up', { method: 'POST', body: {}, timeoutMs: 120000 });
1348
+ if (!r.ok) { console.log(ui.errLine(r.error || 'falha')); if (r.code === 'plan_required') console.log(C.dim(en ? 'Get Ultra at terminalsmart.com.br/planos' : 'Assine o Ultra em terminalsmart.com.br/planos')); return; }
1349
+ console.log('\n' + ui.box([
1350
+ C.ok(en ? 'Cloud box is up!' : 'Caixa na nuvem no ar!'), '',
1351
+ C.dim('URL: ') + C.bold(r.url),
1352
+ C.dim(en ? 'box: ' : 'caixa: ') + r.box,
1353
+ ], { title: 'ts cloud' }) + '\n');
1354
+ console.log(C.dim(en ? 'Build in the cloud:' : 'Construa na nuvem:') + ' ts cloud meta "' + (en ? 'your goal' : 'seu objetivo') + '"');
1355
+ } catch (e) { console.log(ui.errLine(e.code === 'auth' ? T.need_login : (e.message || 'falha'))); }
1356
+ return;
1357
+ }
1358
+
1359
+ if (sub === 'status' || sub === 'url') {
1360
+ const r = await call('status');
1361
+ if (!r.exists) { console.log(ui.infoLine(en ? 'No cloud box yet. Run: ts cloud up' : 'Nenhuma caixa ainda. Rode: ts cloud up')); return; }
1362
+ if (sub === 'url') { console.log(r.url); return; }
1363
+ console.log('\n' + ui.box([
1364
+ C.dim('status: ') + (r.running ? C.ok(en ? 'running' : 'no ar') : C.err(en ? 'stopped' : 'parada')),
1365
+ C.dim('URL: ') + C.bold(r.url),
1366
+ C.dim(en ? 'port: ' : 'porta: ') + r.port,
1367
+ ], { title: 'ts cloud' }) + '\n');
1368
+ return;
1369
+ }
1370
+
1371
+ if (sub === 'exec' || sub === 'sh' || sub === 'run') {
1372
+ const cmd = rest.join(' ').trim();
1373
+ if (!cmd) { console.log(ui.errLine(en ? 'usage: ts cloud exec "<command>"' : 'uso: ts cloud exec "<comando>"')); return; }
1374
+ const r = await call('exec', { method: 'POST', body: { cmd }, timeoutMs: 300000 });
1375
+ if (r.out) process.stdout.write(r.out);
1376
+ if (!r.ok && r.error) console.log(ui.errLine(r.error));
1377
+ return;
1378
+ }
1379
+
1380
+ if (sub === 'meta' || sub === 'missao' || sub === 'missão') {
1381
+ const goal = rest.join(' ').trim();
1382
+ if (!goal) { console.log(ui.errLine(en ? 'usage: ts cloud meta "<goal>"' : 'uso: ts cloud meta "<objetivo>"')); return; }
1383
+ let st = await call('status');
1384
+ if (!st.exists) { console.log(C.dim(en ? 'creating box…' : 'criando caixa…')); const up = await call('up', { method: 'POST', body: {}, timeoutMs: 120000 }); if (!up.ok) { console.log(ui.errLine(up.error || 'falha')); if (up.code === 'plan_required') console.log(C.dim('terminalsmart.com.br/planos')); return; } }
1385
+ console.log(C.dim(en ? 'running ts meta inside the cloud box (may take a while)…' : 'rodando ts meta dentro da caixa (pode demorar)…'));
1386
+ const safe = goal.replace(/(["\\$`])/g, '\\$1');
1387
+ // build com ts meta e, ao terminar, EXPÕE o app na porta 3000 (mapeada pro subdomínio):
1388
+ // npm start se houver, senão serve estático. Assim a caixa fica no ar de verdade.
1389
+ const expose = 'pkill -f "http.server 3000" 2>/dev/null; pkill -f "PORT=3000" 2>/dev/null; ' +
1390
+ 'if [ -f package.json ] && grep -q \'"start"\' package.json; then (PORT=3000 nohup npm start >/tmp/app.log 2>&1 &); ' +
1391
+ 'elif [ -f index.html ] || ls *.html >/dev/null 2>&1; then (nohup python3 -m http.server 3000 >/tmp/app.log 2>&1 &); fi; sleep 2; echo "[ts cloud] app exposto na porta 3000"';
1392
+ const r = await call('exec', { method: 'POST', body: { cmd: 'cd /workspace && ts meta "' + safe + '" --yes 2>&1 | tail -50; ' + expose }, timeoutMs: 1800000 });
1393
+ if (r.out) process.stdout.write(r.out);
1394
+ const u = await call('status'); if (u && u.url) console.log('\n' + ui.okLine((en ? 'Live at: ' : 'No ar em: ') + u.url));
1395
+ return;
1396
+ }
1397
+
1398
+ if (sub === 'down' || sub === 'stop' || sub === 'parar' || sub === 'destroy' || sub === 'apagar') {
1399
+ const destroy = (sub === 'destroy' || sub === 'apagar' || FLAGS.has('--destroy'));
1400
+ const r = await call('down', { method: 'POST', body: { destroy } });
1401
+ console.log(r.ok ? ui.okLine(destroy ? (en ? 'box destroyed' : 'caixa apagada') : (en ? 'box stopped' : 'caixa parada')) : ui.errLine(r.error || 'falha'));
1402
+ return;
1403
+ }
1404
+
1405
+ console.log('\n' + ui.box([
1406
+ C.bold('ts cloud') + C.dim(en ? ' — your dev box in the cloud' : ' — sua caixa de dev na nuvem'), '',
1407
+ C.dim('up') + ' ' + (en ? 'create/start your box + public URL' : 'cria/liga sua caixa + URL pública'),
1408
+ C.dim('meta "…"') + ' ' + (en ? 'the agent builds your app in the cloud' : 'o agente constrói seu app na nuvem'),
1409
+ C.dim('exec "…"') + ' ' + (en ? 'run a shell command in the box' : 'roda um comando na caixa'),
1410
+ C.dim('url') + ' ' + (en ? 'print the public URL' : 'mostra a URL pública'),
1411
+ C.dim('status') + ' ' + (en ? 'box status' : 'status da caixa'),
1412
+ C.dim('down') + ' ' + (en ? 'stop the box (--destroy to remove)' : 'para a caixa (--destroy pra remover)'),
1413
+ ], { title: 'ts cloud' }) + '\n');
1414
+ }
1415
+
1336
1416
  async function uso() {
1337
1417
  const token = needToken();
1338
1418
  const r = await api('/api/credits', { token });
@@ -1442,6 +1522,7 @@ function recallCmd(args) {
1442
1522
  case 'memoria': case 'memória': case 'memory': return memoriaCmd(POS.slice(1));
1443
1523
  case 'recall': case 'lembrei': case 'sessoes': case 'sessões': return recallCmd(POS.slice(1));
1444
1524
  case 'vps': case 'servidor': return vpsCmd(POS.slice(1));
1525
+ case 'cloud': case 'nuvem': return cloudCmd(POS.slice(1));
1445
1526
  case 'meta': case 'missao': case 'mission': return metaCmd();
1446
1527
  case 'runs': return runsCmd();
1447
1528
  case 'status': return statusCmd(POS[1]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terminal-smart-cli",
3
- "version": "0.46.0",
3
+ "version": "0.47.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"