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.
- package/index.js +92 -53
- 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(
|
|
510
|
+
return join(getLocalDir(), ".env");
|
|
504
511
|
}
|
|
505
512
|
|
|
506
513
|
function isLocalInstalled() {
|
|
507
|
-
|
|
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(
|
|
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:
|
|
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}${
|
|
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(
|
|
553
|
-
mkdirSync(
|
|
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,
|
|
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:
|
|
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(
|
|
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(
|
|
618
|
+
cwd: join(bundleDir, "server"),
|
|
606
619
|
stdio: "pipe",
|
|
607
|
-
env: { ...process.env, DATABASE_URL: `file:${
|
|
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
|
-
|
|
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 —
|
|
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}
|
|
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}
|
|
626
|
-
console.log(`
|
|
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
|
-
|
|
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
|
|
644
|
-
const match =
|
|
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(
|
|
652
|
-
cwd: join(
|
|
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(
|
|
659
|
-
cwd: join(
|
|
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
|
-
//
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
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
|
|
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(
|
|
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}${
|
|
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(
|
|
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`);
|