vibora 6.2.4 → 6.2.5

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/vibora.js CHANGED
@@ -32629,7 +32629,7 @@ function installUv() {
32629
32629
  var package_default = {
32630
32630
  name: "vibora",
32631
32631
  private: true,
32632
- version: "6.2.4",
32632
+ version: "6.2.5",
32633
32633
  description: "The Vibe Engineer's Cockpit",
32634
32634
  license: "PolyForm-Shield-1.0.0",
32635
32635
  type: "module",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibora",
3
- "version": "6.2.4",
3
+ "version": "6.2.5",
4
4
  "description": "The Vibe Engineer's Cockpit",
5
5
  "license": "PolyForm-Shield-1.0.0",
6
6
  "repository": {
package/server/index.js CHANGED
@@ -10131,8 +10131,8 @@ var logger = (fn = console.log) => {
10131
10131
 
10132
10132
  // server/app.ts
10133
10133
  import { readFile as readFile5 } from "fs/promises";
10134
- import { join as join21 } from "path";
10135
- import { existsSync as existsSync16 } from "fs";
10134
+ import { join as join22 } from "path";
10135
+ import { existsSync as existsSync17 } from "fs";
10136
10136
 
10137
10137
  // server/routes/health.ts
10138
10138
  var app = new Hono2;
@@ -152866,6 +152866,9 @@ monitoringRoutes.get("/claude-usage", async (c) => {
152866
152866
 
152867
152867
  // server/routes/system.ts
152868
152868
  import { execSync as execSync8 } from "child_process";
152869
+ import { existsSync as existsSync14 } from "fs";
152870
+ import { join as join15 } from "path";
152871
+ import { homedir as homedir7 } from "os";
152869
152872
  var app13 = new Hono2;
152870
152873
  function isCommandAvailable(command) {
152871
152874
  try {
@@ -152875,10 +152878,27 @@ function isCommandAvailable(command) {
152875
152878
  return { installed: false };
152876
152879
  }
152877
152880
  }
152881
+ function isClaudeCodeInstalled() {
152882
+ const pathCheck = isCommandAvailable("claude");
152883
+ if (pathCheck.installed) {
152884
+ return pathCheck;
152885
+ }
152886
+ const commonPaths = [
152887
+ join15(homedir7(), ".claude", "local", "claude"),
152888
+ "/usr/local/bin/claude",
152889
+ "/opt/homebrew/bin/claude"
152890
+ ];
152891
+ for (const path9 of commonPaths) {
152892
+ if (existsSync14(path9)) {
152893
+ return { installed: true, path: path9 };
152894
+ }
152895
+ }
152896
+ return { installed: false };
152897
+ }
152878
152898
  app13.get("/dependencies", (c) => {
152879
152899
  const claudeInstalledFromEnv = process.env.VIBORA_CLAUDE_INSTALLED === "1";
152880
152900
  const claudeMissingFromEnv = process.env.VIBORA_CLAUDE_MISSING === "1";
152881
- const claudeCheck = claudeInstalledFromEnv ? { installed: true } : claudeMissingFromEnv ? { installed: false } : isCommandAvailable("claude");
152901
+ const claudeCheck = claudeInstalledFromEnv ? { installed: true } : claudeMissingFromEnv ? { installed: false } : isClaudeCodeInstalled();
152882
152902
  const dtachCheck = isCommandAvailable("dtach");
152883
152903
  return c.json({
152884
152904
  claudeCode: claudeCheck,
@@ -153125,11 +153145,11 @@ var nanoid = (size = 21) => {
153125
153145
 
153126
153146
  // server/services/compose-parser.ts
153127
153147
  import { readFile as readFile2, access } from "fs/promises";
153128
- import { join as join15 } from "path";
153148
+ import { join as join16 } from "path";
153129
153149
  var COMPOSE_FILE_NAMES = ["compose.yml", "compose.yaml", "docker-compose.yml", "docker-compose.yaml"];
153130
153150
  async function findComposeFile(repoPath) {
153131
153151
  for (const fileName of COMPOSE_FILE_NAMES) {
153132
- const filePath = join15(repoPath, fileName);
153152
+ const filePath = join16(repoPath, fileName);
153133
153153
  try {
153134
153154
  await access(filePath);
153135
153155
  return fileName;
@@ -153207,7 +153227,7 @@ async function parseComposeFile(repoPath, composeFileName) {
153207
153227
  if (!fileName) {
153208
153228
  throw new Error(`No compose file found in ${repoPath}`);
153209
153229
  }
153210
- const filePath = join15(repoPath, fileName);
153230
+ const filePath = join16(repoPath, fileName);
153211
153231
  const content = await readFile2(filePath, "utf-8");
153212
153232
  const parsed = $parse(content);
153213
153233
  if (!parsed || typeof parsed !== "object") {
@@ -153409,7 +153429,7 @@ async function runDocker(args, options = {}) {
153409
153429
  // server/services/docker-swarm.ts
153410
153430
  import { spawn as spawn5 } from "child_process";
153411
153431
  import { readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
153412
- import { join as join16 } from "path";
153432
+ import { join as join17 } from "path";
153413
153433
  async function runDocker2(args, options = {}, onOutput) {
153414
153434
  if (options.signal?.aborted) {
153415
153435
  return { stdout: "", stderr: "Aborted", exitCode: -1, aborted: true };
@@ -153499,8 +153519,8 @@ async function ensureSwarmMode() {
153499
153519
  }
153500
153520
  async function generateSwarmComposeFile(cwd, composeFile, projectName, externalNetwork) {
153501
153521
  const swarmFile = ".swarm-compose.yml";
153502
- const originalPath = join16(cwd, composeFile);
153503
- const swarmPath = join16(cwd, swarmFile);
153522
+ const originalPath = join17(cwd, composeFile);
153523
+ const swarmPath = join17(cwd, swarmFile);
153504
153524
  try {
153505
153525
  const content = await readFile3(originalPath, "utf-8");
153506
153526
  const parsed = $parse(content);
@@ -173236,7 +173256,7 @@ var cloudflare_default = Cloudflare;
173236
173256
  // server/services/cloudflare.ts
173237
173257
  import { generateKeyPairSync, createSign } from "crypto";
173238
173258
  import { mkdir as mkdir2, writeFile as writeFile3, readFile as readFile4, access as access2 } from "fs/promises";
173239
- import { join as join17 } from "path";
173259
+ import { join as join18 } from "path";
173240
173260
  var ORIGIN_CA_PERMISSION_ERROR = `Your Cloudflare API token needs additional permissions to generate SSL certificates.
173241
173261
 
173242
173262
  To fix this:
@@ -173344,12 +173364,12 @@ async function deleteDnsRecord(subdomain, domain) {
173344
173364
  }
173345
173365
  }
173346
173366
  function getCertDir(domain) {
173347
- return join17(getViboraDir(), "certs", domain);
173367
+ return join18(getViboraDir(), "certs", domain);
173348
173368
  }
173349
173369
  async function hasCertificate(domain) {
173350
173370
  const certDir = getCertDir(domain);
173351
- const certPath = join17(certDir, "cert.pem");
173352
- const keyPath = join17(certDir, "key.pem");
173371
+ const certPath = join18(certDir, "cert.pem");
173372
+ const keyPath = join18(certDir, "key.pem");
173353
173373
  try {
173354
173374
  await access2(certPath);
173355
173375
  await access2(keyPath);
@@ -173364,8 +173384,8 @@ async function getCertificatePaths(domain) {
173364
173384
  }
173365
173385
  const certDir = getCertDir(domain);
173366
173386
  return {
173367
- certPath: join17(certDir, "cert.pem"),
173368
- keyPath: join17(certDir, "key.pem")
173387
+ certPath: join18(certDir, "cert.pem"),
173388
+ keyPath: join18(certDir, "key.pem")
173369
173389
  };
173370
173390
  }
173371
173391
  function generateKeyAndCSR(hostnames) {
@@ -173479,8 +173499,8 @@ async function createOriginCACertificate(domain) {
173479
173499
  }
173480
173500
  const certDir = getCertDir(domain);
173481
173501
  await mkdir2(certDir, { recursive: true });
173482
- const certPath = join17(certDir, "cert.pem");
173483
- const keyPath = join17(certDir, "key.pem");
173502
+ const certPath = join18(certDir, "cert.pem");
173503
+ const keyPath = join18(certDir, "key.pem");
173484
173504
  await writeFile3(certPath, cert.certificate, "utf-8");
173485
173505
  await writeFile3(keyPath, privateKey, { mode: 384 });
173486
173506
  log2.deploy.info("Origin CA certificate created and saved", {
@@ -173506,7 +173526,7 @@ async function createOriginCACertificate(domain) {
173506
173526
 
173507
173527
  // server/services/traefik.ts
173508
173528
  import { writeFile as writeFile4, unlink as unlink2, access as access3, constants } from "fs/promises";
173509
- import { join as join18 } from "path";
173529
+ import { join as join19 } from "path";
173510
173530
  async function detectTraefik() {
173511
173531
  try {
173512
173532
  const dokployResult = await runDocker([
@@ -173586,9 +173606,9 @@ function parseTraefikContainer(container, type) {
173586
173606
  if (type === "dokploy") {
173587
173607
  configDir = "/etc/dokploy/traefik/dynamic";
173588
173608
  } else if (dynamicMount) {
173589
- configDir = dynamicMount.Source.includes("dynamic") ? dynamicMount.Source : join18(dynamicMount.Source, "dynamic");
173609
+ configDir = dynamicMount.Source.includes("dynamic") ? dynamicMount.Source : join19(dynamicMount.Source, "dynamic");
173590
173610
  } else {
173591
- configDir = type === "vibora" ? "/etc/vibora/traefik/dynamic" : "/etc/traefik/dynamic";
173611
+ configDir = "/etc/traefik/dynamic";
173592
173612
  }
173593
173613
  const networks = Object.keys(container.NetworkSettings?.Networks || {});
173594
173614
  const network = networks.find((n) => n === "dokploy-network") || networks.find((n) => n === "vibora-network") || networks.find((n) => !n.includes("bridge") && !n.includes("host")) || "dokploy-network";
@@ -173621,7 +173641,7 @@ function getConfigFilename(appId) {
173621
173641
  async function addRoute(config, appId, domain, upstreamUrl, options) {
173622
173642
  const routerId = `vibora-${appId}`;
173623
173643
  const filename = getConfigFilename(appId);
173624
- const filepath = join18(config.configDir, filename);
173644
+ const filepath = join19(config.configDir, filename);
173625
173645
  let tlsConfig;
173626
173646
  let tlsStores;
173627
173647
  if (options?.tlsCert) {
@@ -173692,7 +173712,7 @@ async function addRoute(config, appId, domain, upstreamUrl, options) {
173692
173712
  }
173693
173713
  async function removeRoute(config, appId) {
173694
173714
  const filename = getConfigFilename(appId);
173695
- const filepath = join18(config.configDir, filename);
173715
+ const filepath = join19(config.configDir, filename);
173696
173716
  try {
173697
173717
  await unlink2(filepath);
173698
173718
  log2.deploy.info("Removed Traefik route", { appId, filepath });
@@ -173710,14 +173730,18 @@ async function removeRoute(config, appId) {
173710
173730
 
173711
173731
  // server/services/traefik-docker.ts
173712
173732
  import { mkdir as mkdir3, writeFile as writeFile5, chmod } from "fs/promises";
173713
- import { existsSync as existsSync14 } from "fs";
173714
- import { join as join19 } from "path";
173733
+ import { existsSync as existsSync15 } from "fs";
173734
+ import { join as join20 } from "path";
173715
173735
  var TRAEFIK_CONTAINER_NAME = "vibora-traefik";
173716
173736
  var TRAEFIK_IMAGE = "traefik:v3";
173717
173737
  var TRAEFIK_NETWORK = "vibora-network";
173718
- var TRAEFIK_CONFIG_DIR = "/etc/vibora/traefik";
173719
- var TRAEFIK_DYNAMIC_DIR = "/etc/vibora/traefik/dynamic";
173720
173738
  var TRAEFIK_CERTS_MOUNT = "/certs";
173739
+ function getTraefikConfigDir() {
173740
+ return join20(getViboraDir(), "traefik");
173741
+ }
173742
+ function getTraefikDynamicDir() {
173743
+ return join20(getViboraDir(), "traefik", "dynamic");
173744
+ }
173721
173745
  async function getTraefikContainerStatus() {
173722
173746
  const result = await runDocker([
173723
173747
  "inspect",
@@ -173756,17 +173780,19 @@ async function ensureNetwork() {
173756
173780
  return { success: true };
173757
173781
  }
173758
173782
  function getCertsDir() {
173759
- return join19(getViboraDir(), "certs");
173783
+ return join20(getViboraDir(), "certs");
173760
173784
  }
173761
173785
  async function ensureConfigDirs() {
173762
- if (!existsSync14(TRAEFIK_CONFIG_DIR)) {
173763
- await mkdir3(TRAEFIK_CONFIG_DIR, { recursive: true });
173786
+ const configDir = getTraefikConfigDir();
173787
+ const dynamicDir = getTraefikDynamicDir();
173788
+ if (!existsSync15(configDir)) {
173789
+ await mkdir3(configDir, { recursive: true });
173764
173790
  }
173765
- if (!existsSync14(TRAEFIK_DYNAMIC_DIR)) {
173766
- await mkdir3(TRAEFIK_DYNAMIC_DIR, { recursive: true });
173791
+ if (!existsSync15(dynamicDir)) {
173792
+ await mkdir3(dynamicDir, { recursive: true });
173767
173793
  }
173768
173794
  const certsDir = getCertsDir();
173769
- if (!existsSync14(certsDir)) {
173795
+ if (!existsSync15(certsDir)) {
173770
173796
  await mkdir3(certsDir, { recursive: true });
173771
173797
  }
173772
173798
  }
@@ -173846,12 +173872,14 @@ async function startTraefikContainer(acmeEmail) {
173846
173872
  return networkResult;
173847
173873
  }
173848
173874
  await ensureConfigDirs();
173849
- const traefikConfigPath = join19(TRAEFIK_CONFIG_DIR, "traefik.yml");
173875
+ const configDir = getTraefikConfigDir();
173876
+ const dynamicDir = getTraefikDynamicDir();
173877
+ const traefikConfigPath = join20(configDir, "traefik.yml");
173850
173878
  await writeFile5(traefikConfigPath, generateTraefikConfig(acmeEmail), "utf-8");
173851
- const middlewaresPath = join19(TRAEFIK_DYNAMIC_DIR, "middlewares.yml");
173879
+ const middlewaresPath = join20(dynamicDir, "middlewares.yml");
173852
173880
  await writeFile5(middlewaresPath, generateMiddlewaresConfig(), "utf-8");
173853
- const acmePath = join19(TRAEFIK_CONFIG_DIR, "acme.json");
173854
- if (!existsSync14(acmePath)) {
173881
+ const acmePath = join20(configDir, "acme.json");
173882
+ if (!existsSync15(acmePath)) {
173855
173883
  await writeFile5(acmePath, "{}", "utf-8");
173856
173884
  await chmod(acmePath, 384);
173857
173885
  }
@@ -173867,11 +173895,11 @@ async function startTraefikContainer(acmeEmail) {
173867
173895
  "-v",
173868
173896
  "/var/run/docker.sock:/var/run/docker.sock:ro",
173869
173897
  "-v",
173870
- `${TRAEFIK_CONFIG_DIR}/traefik.yml:/etc/traefik/traefik.yml:ro`,
173898
+ `${configDir}/traefik.yml:/etc/traefik/traefik.yml:ro`,
173871
173899
  "-v",
173872
- `${TRAEFIK_CONFIG_DIR}/acme.json:/etc/traefik/acme.json`,
173900
+ `${configDir}/acme.json:/etc/traefik/acme.json`,
173873
173901
  "-v",
173874
- `${TRAEFIK_DYNAMIC_DIR}:/etc/traefik/dynamic:ro`,
173902
+ `${dynamicDir}:/etc/traefik/dynamic:ro`,
173875
173903
  "-v",
173876
173904
  `${certsDir}:${TRAEFIK_CERTS_MOUNT}:ro`,
173877
173905
  "--network",
@@ -173948,7 +173976,7 @@ async function getTraefikLogs(tail = 100) {
173948
173976
  }
173949
173977
  function getViboraTraefikConfig() {
173950
173978
  return {
173951
- configDir: TRAEFIK_DYNAMIC_DIR,
173979
+ configDir: getTraefikDynamicDir(),
173952
173980
  network: TRAEFIK_NETWORK,
173953
173981
  certResolver: "letsencrypt",
173954
173982
  containerName: TRAEFIK_CONTAINER_NAME,
@@ -175239,7 +175267,7 @@ app17.post("/traefik/start", async (c) => {
175239
175267
  status,
175240
175268
  containerName: TRAEFIK_CONTAINER_NAME,
175241
175269
  network: TRAEFIK_NETWORK,
175242
- configDir: TRAEFIK_DYNAMIC_DIR
175270
+ configDir: getTraefikDynamicDir()
175243
175271
  });
175244
175272
  });
175245
175273
  app17.post("/traefik/stop", async (c) => {
@@ -175327,9 +175355,9 @@ var deployment_default = app17;
175327
175355
  // server/app.ts
175328
175356
  function getDistPath() {
175329
175357
  if (process.env.VIBORA_PACKAGE_ROOT) {
175330
- return join21(process.env.VIBORA_PACKAGE_ROOT, "dist");
175358
+ return join22(process.env.VIBORA_PACKAGE_ROOT, "dist");
175331
175359
  }
175332
- return join21(process.cwd(), "dist");
175360
+ return join22(process.cwd(), "dist");
175333
175361
  }
175334
175362
  function createApp() {
175335
175363
  const app18 = new Hono2;
@@ -175402,15 +175430,15 @@ function createApp() {
175402
175430
  });
175403
175431
  };
175404
175432
  app18.get("/assets/*", async (c) => {
175405
- const assetPath = join21(distPath, c.req.path);
175406
- if (existsSync16(assetPath)) {
175433
+ const assetPath = join22(distPath, c.req.path);
175434
+ if (existsSync17(assetPath)) {
175407
175435
  return serveFile(assetPath);
175408
175436
  }
175409
175437
  return c.notFound();
175410
175438
  });
175411
175439
  app18.get("/sounds/*", async (c) => {
175412
- const soundPath = join21(distPath, c.req.path);
175413
- if (existsSync16(soundPath)) {
175440
+ const soundPath = join22(distPath, c.req.path);
175441
+ if (existsSync17(soundPath)) {
175414
175442
  return serveFile(soundPath);
175415
175443
  }
175416
175444
  return c.notFound();
@@ -175418,8 +175446,8 @@ function createApp() {
175418
175446
  const staticFiles = ["vibora-icon.png", "vibora-logo.jpeg", "vite.svg", "logo.png", "goat.jpeg"];
175419
175447
  for (const file of staticFiles) {
175420
175448
  app18.get(`/${file}`, async () => {
175421
- const filePath = join21(distPath, file);
175422
- if (existsSync16(filePath)) {
175449
+ const filePath = join22(distPath, file);
175450
+ if (existsSync17(filePath)) {
175423
175451
  return serveFile(filePath);
175424
175452
  }
175425
175453
  return new Response("Not Found", { status: 404 });
@@ -175430,7 +175458,7 @@ function createApp() {
175430
175458
  if (path10.startsWith("/api/") || path10.startsWith("/ws/") || path10 === "/health") {
175431
175459
  return next();
175432
175460
  }
175433
- const html = await readFile5(join21(distPath, "index.html"), "utf-8");
175461
+ const html = await readFile5(join22(distPath, "index.html"), "utf-8");
175434
175462
  return c.html(html);
175435
175463
  });
175436
175464
  }