pipely-ai 1.3.6 → 1.4.2

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/index.js +92 -53
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -449,10 +449,17 @@ function printDockerHelp(os) {
449
449
 
450
450
  // ── Local Mode ──────────────────────────────────────
451
451
 
452
- const PIPELY_DIR = join(process.env.HOME || process.env.USERPROFILE || ".", ".pipely");
453
452
  const BUNDLE_REPO = "Pedro-Furtado/pipely-ai";
454
453
  const BUNDLE_NAME = "pipely-local.tar.gz";
455
454
 
455
+ function getLocalDir() {
456
+ return process.cwd();
457
+ }
458
+
459
+ function getBundleDir() {
460
+ return join(getLocalDir(), ".pipely");
461
+ }
462
+
456
463
  async function getLatestReleaseUrl() {
457
464
  return new Promise((resolve) => {
458
465
  const url = `https://api.github.com/repos/${BUNDLE_REPO}/releases/latest`;
@@ -500,37 +507,42 @@ function extractTarGz(file, dest) {
500
507
  }
501
508
 
502
509
  function getLocalEnvPath() {
503
- return join(PIPELY_DIR, ".env");
510
+ return join(getLocalDir(), ".env");
504
511
  }
505
512
 
506
513
  function isLocalInstalled() {
507
- return existsSync(join(PIPELY_DIR, "start.mjs")) && existsSync(join(PIPELY_DIR, "package.json"));
514
+ const bd = getBundleDir();
515
+ return existsSync(join(bd, "package.json")) && existsSync(join(bd, "server"));
508
516
  }
509
517
 
510
518
  function generateLocalEnv() {
511
519
  const jwtSecret = generateKey(64);
512
520
  const setupKey = randomUUID();
521
+ const dir = getLocalDir();
513
522
 
514
- const dbPath = join(PIPELY_DIR, "data", "pipely.db").replace(/\\/g, "/");
523
+ const dbPath = join(dir, "data", "pipely.db").replace(/\\/g, "/");
524
+ const frontendPath = join(getBundleDir(), "frontend").replace(/\\/g, "/");
515
525
  const env = `# Pipely AI — Local Mode
516
526
  DATABASE_URL=file:${dbPath}
517
527
  JWT_SECRET=${jwtSecret}
518
528
  OWNER_SETUP_KEY=${setupKey}
519
- FRONTEND_URL=http://localhost:3000
529
+ FRONTEND_URL=http://localhost:3333
520
530
  BACKEND_URL=http://localhost:3333
531
+ SERVE_FRONTEND=${frontendPath}
521
532
  POLL_INTERVAL_MS=60000
522
533
  PORT=3333
523
- VITE_API_URL=http://localhost:3333
524
534
  `;
525
535
  return { env, setupKey };
526
536
  }
527
537
 
528
538
  async function installLocal() {
529
539
  const os = detectOS();
540
+ const dir = getLocalDir();
541
+ const bundleDir = getBundleDir();
530
542
 
531
543
  // Check if already installed
532
544
  if (isLocalInstalled()) {
533
- console.log(` ${c.green}✓${c.reset} Pipely AI ja instalado em ${c.dim}${PIPELY_DIR}${c.reset}\n`);
545
+ console.log(` ${c.green}✓${c.reset} Pipely AI ja instalado em ${c.dim}${dir}${c.reset}\n`);
534
546
  console.log(` Iniciando...\n`);
535
547
  return runLocal();
536
548
  }
@@ -549,8 +561,8 @@ async function installLocal() {
549
561
  }
550
562
  console.log(`${c.green}✓${c.reset}`);
551
563
 
552
- const tmpFile = join(PIPELY_DIR, BUNDLE_NAME);
553
- mkdirSync(PIPELY_DIR, { recursive: true });
564
+ const tmpFile = join(dir, BUNDLE_NAME);
565
+ mkdirSync(bundleDir, { recursive: true });
554
566
 
555
567
  process.stdout.write(` Baixando bundle... `);
556
568
  try {
@@ -565,7 +577,7 @@ async function installLocal() {
565
577
  // Extract
566
578
  process.stdout.write(` Extraindo... `);
567
579
  try {
568
- extractTarGz(tmpFile, PIPELY_DIR);
580
+ extractTarGz(tmpFile, bundleDir);
569
581
  console.log(`${c.green}✓${c.reset}`);
570
582
  } catch (err) {
571
583
  console.log(`${c.red}✗${c.reset}`);
@@ -580,7 +592,7 @@ async function installLocal() {
580
592
  console.log(`\n ${c.magenta}── Instalando dependencias ────────────────${c.reset}\n`);
581
593
  try {
582
594
  execSync("npm install --production --no-fund --no-audit", {
583
- cwd: PIPELY_DIR,
595
+ cwd: bundleDir,
584
596
  stdio: "inherit",
585
597
  });
586
598
  console.log(`\n ${c.green}✓${c.reset} Dependencias instaladas`);
@@ -596,15 +608,16 @@ async function installLocal() {
596
608
  console.log(` ${c.green}✓${c.reset} .env gerado`);
597
609
 
598
610
  // Create data directory
599
- mkdirSync(join(PIPELY_DIR, "data"), { recursive: true });
611
+ mkdirSync(join(dir, "data"), { recursive: true });
600
612
 
601
613
  // Setup database
614
+ const dbPath = join(dir, "data", "pipely.db").replace(/\\/g, "/");
602
615
  process.stdout.write(` Criando banco de dados... `);
603
616
  try {
604
617
  execSync("npx prisma db push", {
605
- cwd: join(PIPELY_DIR, "server"),
618
+ cwd: join(bundleDir, "server"),
606
619
  stdio: "pipe",
607
- env: { ...process.env, DATABASE_URL: `file:${join(PIPELY_DIR, "data/pipely.db")}` },
620
+ env: { ...process.env, DATABASE_URL: `file:${dbPath}` },
608
621
  });
609
622
  console.log(`${c.green}✓${c.reset}`);
610
623
  } catch (err) {
@@ -614,19 +627,43 @@ async function installLocal() {
614
627
 
615
628
  console.log(`\n ${c.green}✓${c.reset} Instalacao concluida\n`);
616
629
 
617
- // Print summary and run
630
+ printLocalSummary(setupKey, dir);
631
+ return runLocal();
632
+ }
633
+
634
+ function printLocalSummary(setupKey, dir) {
618
635
  const line = "═".repeat(56);
619
636
  console.log(` ${c.green}${line}${c.reset}`);
620
- console.log(` ${c.green}${c.bold} PIPELY AI — LOCAL MODE${c.reset}`);
637
+ console.log(` ${c.green}${c.bold} PIPELY AI — PRONTO! (Local Mode)${c.reset}`);
621
638
  console.log(` ${c.green}${line}${c.reset}`);
622
639
  console.log("");
623
- console.log(` ${c.bold}Setup Key:${c.reset} ${c.yellow}${setupKey}${c.reset}`);
640
+ console.log(` ${c.bold}Endpoints:${c.reset}`);
641
+ console.log(` Frontend + API: ${c.cyan}http://localhost:3333${c.reset}`);
642
+ console.log(` Setup: ${c.cyan}http://localhost:3333/setup${c.reset}`);
643
+ console.log(` Agent Webhook: ${c.cyan}http://localhost:3335/webhook${c.reset}`);
644
+ console.log(` Health: ${c.cyan}http://localhost:3333/health${c.reset}`);
624
645
  console.log("");
625
- console.log(` ${c.bold}Diretorio:${c.reset} ${c.dim}${PIPELY_DIR}${c.reset}`);
626
- console.log(` ${c.bold}Banco de dados:${c.reset} ${c.dim}${join(PIPELY_DIR, "data/pipely.db")}${c.reset}`);
646
+ console.log(` ${c.bold}Chaves:${c.reset}`);
647
+ console.log(` Setup Key: ${c.yellow}${setupKey}${c.reset}`);
648
+ console.log("");
649
+ console.log(` ${c.bold}Arquivos:${c.reset}`);
650
+ console.log(` Diretorio: ${c.dim}${dir}${c.reset}`);
651
+ console.log(` Banco de dados: ${c.dim}${join(dir, "data/pipely.db")}${c.reset}`);
652
+ console.log(` Configuracao: ${c.dim}${join(dir, ".env")}${c.reset}`);
653
+ console.log("");
654
+ console.log(` ${c.bold}Proximo passo:${c.reset}`);
655
+ console.log(` 1. Acesse ${c.cyan}http://localhost:3333/setup${c.reset}`);
656
+ console.log(` 2. Use a Setup Key acima para criar sua conta`);
657
+ console.log(` 3. Configure WhatsApp e OpenAI nas paginas do app`);
658
+ console.log("");
659
+ console.log(` ${c.bold}Comandos:${c.reset}`);
660
+ console.log(` npx pipely-ai start ${c.dim}# Iniciar${c.reset}`);
661
+ console.log(` npx pipely-ai keys ${c.dim}# Ver chaves${c.reset}`);
662
+ console.log(` npx pipely-ai update ${c.dim}# Atualizar${c.reset}`);
663
+ console.log(` npx pipely-ai --local ${c.dim}# Forcar modo local${c.reset}`);
664
+ console.log("");
665
+ console.log(` ${c.green}${line}${c.reset}`);
627
666
  console.log("");
628
-
629
- return runLocal();
630
667
  }
631
668
 
632
669
  async function runLocal() {
@@ -635,52 +672,54 @@ async function runLocal() {
635
672
  process.exit(1);
636
673
  }
637
674
 
638
- console.log(` ${c.magenta}── Iniciando Pipely AI ────────────────────${c.reset}\n`);
675
+ const bundleDir = getBundleDir();
676
+
677
+ const line = "═".repeat(56);
678
+ console.log(` ${c.magenta}${line}${c.reset}`);
679
+ console.log(` ${c.magenta}${c.bold} PIPELY AI — Iniciando...${c.reset}`);
680
+ console.log(` ${c.magenta}${line}${c.reset}`);
681
+ console.log("");
639
682
 
640
683
  const envPath = getLocalEnvPath();
641
684
  const envContent = existsSync(envPath) ? readFileSync(envPath, "utf-8") : "";
642
685
  const envVars = {};
643
- for (const line of envContent.split("\n")) {
644
- const match = line.match(/^([A-Z_]+)=(.*)$/);
686
+ for (const envLine of envContent.split("\n")) {
687
+ const match = envLine.match(/^([A-Z_]+)=(.*)$/);
645
688
  if (match) envVars[match[1]] = match[2];
646
689
  }
647
690
 
648
691
  const childEnv = { ...process.env, ...envVars };
649
692
 
650
- // Start server
651
- const server = fork(join(PIPELY_DIR, "server/dist/index.js"), [], {
652
- cwd: join(PIPELY_DIR, "server"),
693
+ // Start server (serves frontend via SERVE_FRONTEND env)
694
+ const server = fork(join(bundleDir, "server/dist/index.js"), [], {
695
+ cwd: join(bundleDir, "server"),
653
696
  env: { ...childEnv, PORT: "3333" },
654
697
  stdio: "inherit",
655
698
  });
656
699
 
657
700
  // Start agent
658
- const agent = fork(join(PIPELY_DIR, "agent/dist/index.js"), [], {
659
- cwd: join(PIPELY_DIR, "agent"),
701
+ const agent = fork(join(bundleDir, "agent/dist/index.js"), [], {
702
+ cwd: join(bundleDir, "agent"),
660
703
  env: { ...childEnv, PORT: "3335" },
661
704
  stdio: "inherit",
662
705
  });
663
706
 
664
- // Serve frontend
665
- const frontendDir = join(PIPELY_DIR, "frontend");
666
- if (existsSync(frontendDir)) {
667
- const express = await import("express").catch(() => null);
668
- if (express) {
669
- const app = express.default();
670
- app.use(express.default.static(frontendDir));
671
- app.get(/^\/(?!api|health).*/, (_req, res) => {
672
- res.sendFile(join(frontendDir, "index.html"));
673
- });
674
- const fPort = envVars.FRONTEND_PORT || 3000;
675
- app.listen(fPort, () => {
676
- console.log(` ${c.cyan}Frontend:${c.reset} http://localhost:${fPort}`);
677
- console.log(` ${c.cyan}Backend:${c.reset} http://localhost:3333`);
678
- console.log(` ${c.cyan}Agent:${c.reset} http://localhost:3335`);
679
- console.log("");
680
- console.log(` Pressione ${c.bold}Ctrl+C${c.reset} para parar.\n`);
681
- });
682
- }
683
- }
707
+ // Wait for server to start then print endpoints
708
+ await sleep(2000);
709
+ console.log("");
710
+ console.log(` ${c.green}${line}${c.reset}`);
711
+ console.log(` ${c.green}${c.bold} PIPELY AI — Rodando${c.reset}`);
712
+ console.log(` ${c.green}${line}${c.reset}`);
713
+ console.log("");
714
+ console.log(` ${c.bold}Endpoints:${c.reset}`);
715
+ console.log(` Frontend + API: ${c.cyan}http://localhost:3333${c.reset}`);
716
+ console.log(` Agent Webhook: ${c.cyan}http://localhost:3335/webhook${c.reset}`);
717
+ console.log("");
718
+ console.log(` ${c.bold}Setup Key:${c.reset} ${c.yellow}${envVars.OWNER_SETUP_KEY || "ver .env"}${c.reset}`);
719
+ console.log("");
720
+ console.log(` Pressione ${c.bold}Ctrl+C${c.reset} para parar.`);
721
+ console.log(` ${c.green}${line}${c.reset}`);
722
+ console.log("");
684
723
 
685
724
  function shutdown() {
686
725
  console.log(`\n Parando...\n`);
@@ -1138,10 +1177,10 @@ async function install() {
1138
1177
 
1139
1178
  function cmdLocalKeys() {
1140
1179
  if (!isLocalInstalled()) {
1141
- console.log(`\n ${c.red}✗ Pipely AI nao instalado localmente${c.reset}\n`);
1180
+ console.log(`\n ${c.red}✗ Pipely AI nao instalado nesta pasta${c.reset}\n`);
1142
1181
  process.exit(1);
1143
1182
  }
1144
- const env = readEnvFile(PIPELY_DIR);
1183
+ const env = readEnvFile(getLocalDir());
1145
1184
  console.log("");
1146
1185
  console.log(` ${c.bold}PIPELY AI — Chaves (Local)${c.reset}\n`);
1147
1186
  if (env.OWNER_SETUP_KEY) {
@@ -1150,7 +1189,7 @@ function cmdLocalKeys() {
1150
1189
  if (env.JWT_SECRET) {
1151
1190
  console.log(` JWT Secret: ${c.yellow}${env.JWT_SECRET.slice(0, 16)}...${c.reset}`);
1152
1191
  }
1153
- console.log(`\n Diretorio: ${c.dim}${PIPELY_DIR}${c.reset}`);
1192
+ console.log(`\n Diretorio: ${c.dim}${getLocalDir()}${c.reset}`);
1154
1193
  console.log("");
1155
1194
  }
1156
1195
 
@@ -1204,7 +1243,7 @@ switch (command) {
1204
1243
  case "update":
1205
1244
  if (local) {
1206
1245
  // Delete and re-download bundle
1207
- try { rmSync(PIPELY_DIR, { recursive: true }); } catch {}
1246
+ try { rmSync(getBundleDir(), { recursive: true }); } catch {}
1208
1247
  console.log(`\n ${c.dim}Reinstalando...${c.reset}\n`);
1209
1248
  installLocal().catch((err) => {
1210
1249
  console.error(`\n ${c.red}Erro: ${err.message}${c.reset}\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pipely-ai",
3
- "version": "1.3.6",
3
+ "version": "1.4.2",
4
4
  "description": "Pipely AI — Instale, gerencie e atualize com um unico comando",
5
5
  "type": "module",
6
6
  "bin": {