vibora 3.9.0 → 4.3.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.
package/server/index.js
CHANGED
|
@@ -14285,7 +14285,7 @@ var log2 = {
|
|
|
14285
14285
|
};
|
|
14286
14286
|
|
|
14287
14287
|
// server/lib/settings.ts
|
|
14288
|
-
var CURRENT_SCHEMA_VERSION =
|
|
14288
|
+
var CURRENT_SCHEMA_VERSION = 4;
|
|
14289
14289
|
var CLAUDE_CODE_THEMES = ["light", "light-ansi", "light-daltonized", "dark", "dark-ansi", "dark-daltonized"];
|
|
14290
14290
|
var DEFAULT_SETTINGS = {
|
|
14291
14291
|
_schemaVersion: CURRENT_SCHEMA_VERSION,
|
|
@@ -20731,13 +20731,13 @@ var ZAI_ENV_VARS = [
|
|
|
20731
20731
|
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC"
|
|
20732
20732
|
];
|
|
20733
20733
|
function getTerminalEnv() {
|
|
20734
|
-
const { PORT: _PORT, ...
|
|
20734
|
+
const { PORT: _PORT, NODE_ENV: _NODE_ENV, ...envWithoutFiltered } = process.env;
|
|
20735
20735
|
const zaiSettings = getZAiSettings();
|
|
20736
20736
|
if (zaiSettings.enabled) {
|
|
20737
|
-
return
|
|
20737
|
+
return envWithoutFiltered;
|
|
20738
20738
|
}
|
|
20739
20739
|
const filtered = {};
|
|
20740
|
-
for (const [key, value] of Object.entries(
|
|
20740
|
+
for (const [key, value] of Object.entries(envWithoutFiltered)) {
|
|
20741
20741
|
if (!ZAI_ENV_VARS.includes(key) && value !== undefined) {
|
|
20742
20742
|
filtered[key] = value;
|
|
20743
20743
|
}
|
|
@@ -20809,7 +20809,9 @@ class TerminalSession {
|
|
|
20809
20809
|
TERM: "xterm-256color",
|
|
20810
20810
|
COLORTERM: "truecolor",
|
|
20811
20811
|
SSH_TTY: "/dev/pts/vibora",
|
|
20812
|
-
SSH_CONNECTION: "127.0.0.1 0 127.0.0.1 22"
|
|
20812
|
+
SSH_CONNECTION: "127.0.0.1 0 127.0.0.1 22",
|
|
20813
|
+
NODE_ENV: "",
|
|
20814
|
+
PORT: ""
|
|
20813
20815
|
}
|
|
20814
20816
|
});
|
|
20815
20817
|
log2.terminal.info("dtach session created", { terminalId: this.id });
|
|
@@ -20846,7 +20848,9 @@ class TerminalSession {
|
|
|
20846
20848
|
env: {
|
|
20847
20849
|
...getTerminalEnv(),
|
|
20848
20850
|
TERM: "xterm-256color",
|
|
20849
|
-
COLORTERM: "truecolor"
|
|
20851
|
+
COLORTERM: "truecolor",
|
|
20852
|
+
NODE_ENV: "",
|
|
20853
|
+
PORT: ""
|
|
20850
20854
|
}
|
|
20851
20855
|
});
|
|
20852
20856
|
this.setupPtyHandlers();
|
|
@@ -145341,11 +145345,19 @@ import * as fs4 from "fs";
|
|
|
145341
145345
|
import * as path6 from "path";
|
|
145342
145346
|
import * as os3 from "os";
|
|
145343
145347
|
function gitExec(cwd, args) {
|
|
145344
|
-
|
|
145345
|
-
|
|
145346
|
-
|
|
145347
|
-
|
|
145348
|
-
|
|
145348
|
+
try {
|
|
145349
|
+
return execSync3(`git ${args}`, {
|
|
145350
|
+
cwd,
|
|
145351
|
+
encoding: "utf-8",
|
|
145352
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
145353
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
145354
|
+
}).trim();
|
|
145355
|
+
} catch (err) {
|
|
145356
|
+
if (err && typeof err === "object" && "stderr" in err && err.stderr) {
|
|
145357
|
+
throw new Error(String(err.stderr).trim() || String(err));
|
|
145358
|
+
}
|
|
145359
|
+
throw err;
|
|
145360
|
+
}
|
|
145349
145361
|
}
|
|
145350
145362
|
function parseStatusCode(code) {
|
|
145351
145363
|
const index = code[0];
|
|
@@ -145790,10 +145802,28 @@ app3.post("/merge-to-main", async (c) => {
|
|
|
145790
145802
|
if (originalBranch !== defaultBranch) {
|
|
145791
145803
|
gitExec(repoPath, `checkout ${defaultBranch}`);
|
|
145792
145804
|
}
|
|
145805
|
+
let commitMessages = "";
|
|
145806
|
+
try {
|
|
145807
|
+
commitMessages = gitExec(repoPath, `log ${defaultBranch}..${worktreeBranch} --pretty=format:%s%n%b --reverse`);
|
|
145808
|
+
} catch {}
|
|
145809
|
+
const squashMessage = commitMessages.trim() || `Merge branch '${worktreeBranch}'`;
|
|
145810
|
+
const squashMsgPath = path6.join(repoPath, ".git", "SQUASH_MSG");
|
|
145793
145811
|
try {
|
|
145794
145812
|
gitExec(repoPath, `merge --squash ${worktreeBranch}`);
|
|
145795
|
-
|
|
145813
|
+
const tempFile = path6.join(repoPath, ".git", "SQUASH_MSG_TEMP");
|
|
145814
|
+
fs4.writeFileSync(tempFile, squashMessage);
|
|
145815
|
+
try {
|
|
145816
|
+
gitExec(repoPath, `commit -F "${tempFile}"`);
|
|
145817
|
+
} finally {
|
|
145818
|
+
fs4.unlinkSync(tempFile);
|
|
145819
|
+
if (fs4.existsSync(squashMsgPath)) {
|
|
145820
|
+
fs4.unlinkSync(squashMsgPath);
|
|
145821
|
+
}
|
|
145822
|
+
}
|
|
145796
145823
|
} catch (mergeErr) {
|
|
145824
|
+
if (fs4.existsSync(squashMsgPath)) {
|
|
145825
|
+
fs4.unlinkSync(squashMsgPath);
|
|
145826
|
+
}
|
|
145797
145827
|
try {
|
|
145798
145828
|
const mergeStatus = gitExec(repoPath, "status");
|
|
145799
145829
|
if (mergeStatus.includes("Unmerged paths") || mergeStatus.includes("fix conflicts")) {
|
|
@@ -145974,6 +146004,25 @@ app3.post("/sync-parent", async (c) => {
|
|
|
145974
146004
|
return c.json({ error: err instanceof Error ? err.message : "Failed to sync parent" }, 500);
|
|
145975
146005
|
}
|
|
145976
146006
|
});
|
|
146007
|
+
app3.get("/remote", (c) => {
|
|
146008
|
+
let repoPath = c.req.query("path");
|
|
146009
|
+
if (!repoPath) {
|
|
146010
|
+
return c.json({ error: "path parameter is required" }, 400);
|
|
146011
|
+
}
|
|
146012
|
+
if (repoPath.startsWith("~")) {
|
|
146013
|
+
repoPath = path6.join(os3.homedir(), repoPath.slice(1));
|
|
146014
|
+
}
|
|
146015
|
+
repoPath = path6.resolve(repoPath);
|
|
146016
|
+
if (!fs4.existsSync(repoPath)) {
|
|
146017
|
+
return c.json({ error: "Path does not exist" }, 404);
|
|
146018
|
+
}
|
|
146019
|
+
try {
|
|
146020
|
+
const remoteUrl = gitExec(repoPath, "remote get-url origin");
|
|
146021
|
+
return c.json({ remoteUrl });
|
|
146022
|
+
} catch {
|
|
146023
|
+
return c.json({ remoteUrl: null });
|
|
146024
|
+
}
|
|
146025
|
+
});
|
|
145977
146026
|
var git_default = app3;
|
|
145978
146027
|
|
|
145979
146028
|
// server/routes/filesystem.ts
|
|
@@ -146018,7 +146067,7 @@ function buildTree(dirPath, root, depth = 0, maxDepth = 20) {
|
|
|
146018
146067
|
try {
|
|
146019
146068
|
const items = fs5.readdirSync(dirPath);
|
|
146020
146069
|
for (const name of items) {
|
|
146021
|
-
if (
|
|
146070
|
+
if (EXCLUDED_DIRECTORIES.has(name))
|
|
146022
146071
|
continue;
|
|
146023
146072
|
try {
|
|
146024
146073
|
const itemPath = path7.join(dirPath, name);
|
|
@@ -147504,7 +147553,7 @@ var $visit = visit.visit;
|
|
|
147504
147553
|
var $visitAsync = visit.visitAsync;
|
|
147505
147554
|
|
|
147506
147555
|
// server/routes/copier.ts
|
|
147507
|
-
import { existsSync as existsSync11, readFileSync as readFileSync6, writeFileSync as
|
|
147556
|
+
import { existsSync as existsSync11, readFileSync as readFileSync6, writeFileSync as writeFileSync5, unlinkSync as unlinkSync5, mkdtempSync, rmSync as rmSync5 } from "fs";
|
|
147508
147557
|
import { join as join13 } from "path";
|
|
147509
147558
|
import { tmpdir } from "os";
|
|
147510
147559
|
import { execSync as execSync5 } from "child_process";
|
|
@@ -147652,7 +147701,7 @@ app10.post("/create", async (c) => {
|
|
|
147652
147701
|
}, 400);
|
|
147653
147702
|
}
|
|
147654
147703
|
const body = await c.req.json();
|
|
147655
|
-
const { templateSource, outputPath, answers, projectName } = body;
|
|
147704
|
+
const { templateSource, outputPath, answers, projectName, trust } = body;
|
|
147656
147705
|
if (!templateSource || !outputPath || !projectName) {
|
|
147657
147706
|
return c.json({ error: "templateSource, outputPath, and projectName are required" }, 400);
|
|
147658
147707
|
}
|
|
@@ -147670,9 +147719,10 @@ app10.post("/create", async (c) => {
|
|
|
147670
147719
|
filteredAnswers[key] = value;
|
|
147671
147720
|
}
|
|
147672
147721
|
answersFile = join13(tmpdir(), `copier-answers-${crypto.randomUUID()}.json`);
|
|
147673
|
-
|
|
147722
|
+
writeFileSync5(answersFile, JSON.stringify(filteredAnswers));
|
|
147674
147723
|
try {
|
|
147675
|
-
|
|
147724
|
+
const trustFlag = trust ? "--trust " : "";
|
|
147725
|
+
execSync5(`uvx copier copy --data-file "${answersFile}" --force --vcs-ref HEAD ${trustFlag}"${templatePath}" "${fullOutputPath}"`, {
|
|
147676
147726
|
encoding: "utf-8",
|
|
147677
147727
|
stdio: "pipe",
|
|
147678
147728
|
timeout: 120000
|
|
@@ -147709,7 +147759,7 @@ app10.post("/create", async (c) => {
|
|
|
147709
147759
|
return c.json({ error: err instanceof Error ? err.message : "Failed to create project" }, 500);
|
|
147710
147760
|
} finally {
|
|
147711
147761
|
if (answersFile && existsSync11(answersFile)) {
|
|
147712
|
-
|
|
147762
|
+
unlinkSync5(answersFile);
|
|
147713
147763
|
}
|
|
147714
147764
|
}
|
|
147715
147765
|
});
|
|
@@ -152395,6 +152445,28 @@ monitoringRoutes.get("/claude-usage", async (c) => {
|
|
|
152395
152445
|
return c.json(usage);
|
|
152396
152446
|
});
|
|
152397
152447
|
|
|
152448
|
+
// server/routes/system.ts
|
|
152449
|
+
import { execSync as execSync8 } from "child_process";
|
|
152450
|
+
var app13 = new Hono2;
|
|
152451
|
+
function isCommandAvailable(command) {
|
|
152452
|
+
try {
|
|
152453
|
+
const path9 = execSync8(`which ${command}`, { encoding: "utf-8" }).trim();
|
|
152454
|
+
return { installed: true, path: path9 };
|
|
152455
|
+
} catch {
|
|
152456
|
+
return { installed: false };
|
|
152457
|
+
}
|
|
152458
|
+
}
|
|
152459
|
+
app13.get("/dependencies", (c) => {
|
|
152460
|
+
const claudeMissingFromEnv = process.env.VIBORA_CLAUDE_MISSING === "1";
|
|
152461
|
+
const claudeCheck = claudeMissingFromEnv ? { installed: false } : isCommandAvailable("claude");
|
|
152462
|
+
const dtachCheck = isCommandAvailable("dtach");
|
|
152463
|
+
return c.json({
|
|
152464
|
+
claudeCode: claudeCheck,
|
|
152465
|
+
dtach: dtachCheck
|
|
152466
|
+
});
|
|
152467
|
+
});
|
|
152468
|
+
var system_default = app13;
|
|
152469
|
+
|
|
152398
152470
|
// server/app.ts
|
|
152399
152471
|
function getDistPath() {
|
|
152400
152472
|
if (process.env.VIBORA_PACKAGE_ROOT) {
|
|
@@ -152403,34 +152475,35 @@ function getDistPath() {
|
|
|
152403
152475
|
return join15(process.cwd(), "dist");
|
|
152404
152476
|
}
|
|
152405
152477
|
function createApp() {
|
|
152406
|
-
const
|
|
152407
|
-
|
|
152408
|
-
|
|
152478
|
+
const app14 = new Hono2;
|
|
152479
|
+
app14.use("*", logger());
|
|
152480
|
+
app14.use("*", cors({
|
|
152409
152481
|
origin: "*",
|
|
152410
152482
|
allowMethods: ["GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS"],
|
|
152411
152483
|
allowHeaders: ["Content-Type"]
|
|
152412
152484
|
}));
|
|
152413
|
-
|
|
152414
|
-
|
|
152415
|
-
|
|
152416
|
-
|
|
152417
|
-
|
|
152418
|
-
|
|
152419
|
-
|
|
152420
|
-
|
|
152421
|
-
|
|
152422
|
-
|
|
152423
|
-
|
|
152424
|
-
|
|
152425
|
-
|
|
152426
|
-
|
|
152485
|
+
app14.route("/health", health_default);
|
|
152486
|
+
app14.route("/api/tasks", tasks_default);
|
|
152487
|
+
app14.route("/api/git", git_default);
|
|
152488
|
+
app14.route("/api/fs", filesystem_default);
|
|
152489
|
+
app14.route("/api/config", config_default);
|
|
152490
|
+
app14.route("/api/uploads", uploads_default);
|
|
152491
|
+
app14.route("/api/worktrees", worktrees_default);
|
|
152492
|
+
app14.route("/api/terminal-view-state", terminal_view_state_default);
|
|
152493
|
+
app14.route("/api/repositories", repositories_default);
|
|
152494
|
+
app14.route("/api/copier", copier_default);
|
|
152495
|
+
app14.route("/api/linear", linear_default);
|
|
152496
|
+
app14.route("/api/github", github_default);
|
|
152497
|
+
app14.route("/api/monitoring", monitoringRoutes);
|
|
152498
|
+
app14.route("/api/system", system_default);
|
|
152499
|
+
app14.post("/api/logs", async (c) => {
|
|
152427
152500
|
const { entries } = await c.req.json();
|
|
152428
152501
|
for (const entry of entries) {
|
|
152429
152502
|
writeEntry(entry);
|
|
152430
152503
|
}
|
|
152431
152504
|
return c.json({ ok: true });
|
|
152432
152505
|
});
|
|
152433
|
-
|
|
152506
|
+
app14.post("/api/debug", async (c) => {
|
|
152434
152507
|
const body = await c.req.json();
|
|
152435
152508
|
const entry = {
|
|
152436
152509
|
ts: new Date().toISOString(),
|
|
@@ -152467,14 +152540,14 @@ function createApp() {
|
|
|
152467
152540
|
headers: { "Content-Type": mimeTypes2[ext2 || ""] || "application/octet-stream" }
|
|
152468
152541
|
});
|
|
152469
152542
|
};
|
|
152470
|
-
|
|
152543
|
+
app14.get("/assets/*", async (c) => {
|
|
152471
152544
|
const assetPath = join15(distPath, c.req.path);
|
|
152472
152545
|
if (existsSync13(assetPath)) {
|
|
152473
152546
|
return serveFile(assetPath);
|
|
152474
152547
|
}
|
|
152475
152548
|
return c.notFound();
|
|
152476
152549
|
});
|
|
152477
|
-
|
|
152550
|
+
app14.get("/sounds/*", async (c) => {
|
|
152478
152551
|
const soundPath = join15(distPath, c.req.path);
|
|
152479
152552
|
if (existsSync13(soundPath)) {
|
|
152480
152553
|
return serveFile(soundPath);
|
|
@@ -152483,7 +152556,7 @@ function createApp() {
|
|
|
152483
152556
|
});
|
|
152484
152557
|
const staticFiles = ["vibora-icon.png", "vibora-logo.jpeg", "vite.svg", "logo-dark.jpg", "logo-light.jpg", "goat.jpeg"];
|
|
152485
152558
|
for (const file of staticFiles) {
|
|
152486
|
-
|
|
152559
|
+
app14.get(`/${file}`, async () => {
|
|
152487
152560
|
const filePath = join15(distPath, file);
|
|
152488
152561
|
if (existsSync13(filePath)) {
|
|
152489
152562
|
return serveFile(filePath);
|
|
@@ -152491,7 +152564,7 @@ function createApp() {
|
|
|
152491
152564
|
return new Response("Not Found", { status: 404 });
|
|
152492
152565
|
});
|
|
152493
152566
|
}
|
|
152494
|
-
|
|
152567
|
+
app14.get("*", async (c, next) => {
|
|
152495
152568
|
const path9 = c.req.path;
|
|
152496
152569
|
if (path9.startsWith("/api/") || path9.startsWith("/ws/") || path9 === "/health") {
|
|
152497
152570
|
return next();
|
|
@@ -152500,11 +152573,11 @@ function createApp() {
|
|
|
152500
152573
|
return c.html(html);
|
|
152501
152574
|
});
|
|
152502
152575
|
}
|
|
152503
|
-
return
|
|
152576
|
+
return app14;
|
|
152504
152577
|
}
|
|
152505
152578
|
|
|
152506
152579
|
// server/services/pr-monitor.ts
|
|
152507
|
-
import { execSync as
|
|
152580
|
+
import { execSync as execSync9 } from "child_process";
|
|
152508
152581
|
var POLL_INTERVAL = 60000;
|
|
152509
152582
|
function parsePrUrl(url) {
|
|
152510
152583
|
const match3 = url.match(/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)/);
|
|
@@ -152519,7 +152592,7 @@ function checkPrStatus(prUrl) {
|
|
|
152519
152592
|
return null;
|
|
152520
152593
|
}
|
|
152521
152594
|
try {
|
|
152522
|
-
const output =
|
|
152595
|
+
const output = execSync9(`gh pr view ${parsed.number} --repo ${parsed.owner}/${parsed.repo} --json state,mergedAt`, { encoding: "utf-8", timeout: 1e4, stdio: ["pipe", "pipe", "pipe"] });
|
|
152523
152596
|
const data = JSON.parse(output);
|
|
152524
152597
|
return {
|
|
152525
152598
|
state: data.state,
|
|
@@ -152603,11 +152676,11 @@ setBroadcastDestroyed((terminalId) => {
|
|
|
152603
152676
|
payload: { terminalId }
|
|
152604
152677
|
});
|
|
152605
152678
|
});
|
|
152606
|
-
var
|
|
152607
|
-
var { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app:
|
|
152608
|
-
|
|
152679
|
+
var app14 = createApp();
|
|
152680
|
+
var { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app: app14 });
|
|
152681
|
+
app14.get("/ws/terminal", upgradeWebSocket(() => terminalWebSocketHandlers));
|
|
152609
152682
|
var server = serve({
|
|
152610
|
-
fetch:
|
|
152683
|
+
fetch: app14.fetch,
|
|
152611
152684
|
port: PORT,
|
|
152612
152685
|
hostname: HOST
|
|
152613
152686
|
}, (info) => {
|