@vibedeckx/linux-x64 0.3.37 → 0.3.39
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/dist/bin.js +203 -132
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -66967,7 +66967,7 @@ var require_sonic_boom = __commonJS({
|
|
|
66967
66967
|
if (!(this instanceof SonicBoom)) {
|
|
66968
66968
|
return new SonicBoom(opts);
|
|
66969
66969
|
}
|
|
66970
|
-
let { fd, dest, minLength, maxLength, maxWrite, periodicFlush, sync, append = true, mkdir:
|
|
66970
|
+
let { fd, dest, minLength, maxLength, maxWrite, periodicFlush, sync, append = true, mkdir: mkdir6, retryEAGAIN, fsync, contentMode, mode } = opts || {};
|
|
66971
66971
|
fd = fd || dest;
|
|
66972
66972
|
this._len = 0;
|
|
66973
66973
|
this.fd = -1;
|
|
@@ -66992,7 +66992,7 @@ var require_sonic_boom = __commonJS({
|
|
|
66992
66992
|
this.append = append || false;
|
|
66993
66993
|
this.mode = mode;
|
|
66994
66994
|
this.retryEAGAIN = retryEAGAIN || (() => true);
|
|
66995
|
-
this.mkdir =
|
|
66995
|
+
this.mkdir = mkdir6 || false;
|
|
66996
66996
|
let fsWriteSync;
|
|
66997
66997
|
let fsWrite;
|
|
66998
66998
|
if (contentMode === kContentModeBuffer) {
|
|
@@ -100215,7 +100215,7 @@ var require_commonjs6 = __commonJS({
|
|
|
100215
100215
|
var node_url_1 = __require("node:url");
|
|
100216
100216
|
var fs_1 = __require("fs");
|
|
100217
100217
|
var actualFS = __importStar(__require("node:fs"));
|
|
100218
|
-
var
|
|
100218
|
+
var realpathSync2 = fs_1.realpathSync.native;
|
|
100219
100219
|
var promises_1 = __require("node:fs/promises");
|
|
100220
100220
|
var minipass_1 = require_commonjs5();
|
|
100221
100221
|
var defaultFS = {
|
|
@@ -100223,7 +100223,7 @@ var require_commonjs6 = __commonJS({
|
|
|
100223
100223
|
readdir: fs_1.readdir,
|
|
100224
100224
|
readdirSync: fs_1.readdirSync,
|
|
100225
100225
|
readlinkSync: fs_1.readlinkSync,
|
|
100226
|
-
realpathSync,
|
|
100226
|
+
realpathSync: realpathSync2,
|
|
100227
100227
|
promises: {
|
|
100228
100228
|
lstat: promises_1.lstat,
|
|
100229
100229
|
readdir: promises_1.readdir,
|
|
@@ -115594,7 +115594,7 @@ var require_token_io = __commonJS({
|
|
|
115594
115594
|
});
|
|
115595
115595
|
module.exports = __toCommonJS2(token_io_exports);
|
|
115596
115596
|
var import_path16 = __toESM3(__require("path"));
|
|
115597
|
-
var
|
|
115597
|
+
var import_fs11 = __toESM3(__require("fs"));
|
|
115598
115598
|
var import_os4 = __toESM3(__require("os"));
|
|
115599
115599
|
var import_token_error = require_token_error();
|
|
115600
115600
|
function findRootDir() {
|
|
@@ -115602,7 +115602,7 @@ var require_token_io = __commonJS({
|
|
|
115602
115602
|
let dir = process.cwd();
|
|
115603
115603
|
while (dir !== import_path16.default.dirname(dir)) {
|
|
115604
115604
|
const pkgPath = import_path16.default.join(dir, ".vercel");
|
|
115605
|
-
if (
|
|
115605
|
+
if (import_fs11.default.existsSync(pkgPath)) {
|
|
115606
115606
|
return dir;
|
|
115607
115607
|
}
|
|
115608
115608
|
dir = import_path16.default.dirname(dir);
|
|
@@ -128873,7 +128873,7 @@ var require_snapshot_utils = __commonJS({
|
|
|
128873
128873
|
var require_snapshot_recorder = __commonJS({
|
|
128874
128874
|
"../../node_modules/.pnpm/undici@7.22.0/node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
|
|
128875
128875
|
"use strict";
|
|
128876
|
-
var { writeFile: writeFile2, readFile: readFile2, mkdir:
|
|
128876
|
+
var { writeFile: writeFile2, readFile: readFile2, mkdir: mkdir6 } = __require("node:fs/promises");
|
|
128877
128877
|
var { dirname, resolve: resolve3 } = __require("node:path");
|
|
128878
128878
|
var { setTimeout: setTimeout3, clearTimeout: clearTimeout2 } = __require("node:timers");
|
|
128879
128879
|
var { InvalidArgumentError: InvalidArgumentError4, UndiciError } = require_errors7();
|
|
@@ -129105,7 +129105,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
129105
129105
|
throw new InvalidArgumentError4("Snapshot path is required");
|
|
129106
129106
|
}
|
|
129107
129107
|
const resolvedPath = resolve3(path26);
|
|
129108
|
-
await
|
|
129108
|
+
await mkdir6(dirname(resolvedPath), { recursive: true });
|
|
129109
129109
|
const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
|
|
129110
129110
|
hash: hash2,
|
|
129111
129111
|
snapshot
|
|
@@ -154483,6 +154483,7 @@ var DB_PATH = path.join(VIBEDECKX_HOME, "data.sqlite");
|
|
|
154483
154483
|
var DEFAULT_PORT = 5173;
|
|
154484
154484
|
var MIN_WORKER_VERSION = "0.0.0";
|
|
154485
154485
|
var WORKER_VERSION_REPORTING_SINCE = "2026-08-03";
|
|
154486
|
+
var TUNNEL_MAX_FRAME_BYTES = 32 * 1024 * 1024;
|
|
154486
154487
|
|
|
154487
154488
|
// src/load-env.ts
|
|
154488
154489
|
function getArg(argv, name25) {
|
|
@@ -208664,6 +208665,7 @@ function parseRows(rows, sessionIdForLog) {
|
|
|
208664
208665
|
import path7 from "path";
|
|
208665
208666
|
import { createHash } from "crypto";
|
|
208666
208667
|
import { execSync, execFileSync as execFileSync2 } from "child_process";
|
|
208668
|
+
import { mkdirSync as mkdirSync2, realpathSync } from "fs";
|
|
208667
208669
|
var WORKTREE_BASE_DIR = "/var/tmp/vibedeckx/worktrees";
|
|
208668
208670
|
var WORKTREE_LIST_TTL_MS = 1e4;
|
|
208669
208671
|
var worktreeListCache = /* @__PURE__ */ new Map();
|
|
@@ -208676,35 +208678,41 @@ function isSubpath(basePath33, targetPath) {
|
|
|
208676
208678
|
const relative = path7.relative(basePath33, targetPath);
|
|
208677
208679
|
return relative === "" || !relative.startsWith("..") && !path7.isAbsolute(relative);
|
|
208678
208680
|
}
|
|
208681
|
+
function canonicalPath(target) {
|
|
208682
|
+
try {
|
|
208683
|
+
return realpathSync(target);
|
|
208684
|
+
} catch {
|
|
208685
|
+
return path7.resolve(target);
|
|
208686
|
+
}
|
|
208687
|
+
}
|
|
208679
208688
|
function isTrustedWorktreePath(projectPath, worktreePath) {
|
|
208680
|
-
const normalizedWorktreePath =
|
|
208681
|
-
if (normalizedWorktreePath ===
|
|
208682
|
-
const managedBase =
|
|
208689
|
+
const normalizedWorktreePath = canonicalPath(worktreePath);
|
|
208690
|
+
if (normalizedWorktreePath === canonicalPath(projectPath)) return true;
|
|
208691
|
+
const managedBase = canonicalPath(getWorktreeBaseForProject(projectPath));
|
|
208683
208692
|
return isSubpath(managedBase, normalizedWorktreePath);
|
|
208684
208693
|
}
|
|
208685
|
-
function
|
|
208694
|
+
function readWorktreeRecords(projectPath) {
|
|
208686
208695
|
const output = execSync("git worktree list --porcelain", {
|
|
208687
208696
|
cwd: projectPath,
|
|
208688
208697
|
encoding: "utf-8",
|
|
208689
208698
|
stdio: ["pipe", "pipe", "pipe"]
|
|
208690
208699
|
});
|
|
208691
|
-
const
|
|
208692
|
-
const
|
|
208693
|
-
for (const block of blocks) {
|
|
208694
|
-
const lines = block.split("\n");
|
|
208700
|
+
const records = [];
|
|
208701
|
+
for (const block of output.trim().split("\n\n")) {
|
|
208695
208702
|
let worktreePath = "";
|
|
208696
208703
|
let branch = null;
|
|
208697
|
-
let
|
|
208698
|
-
for (const line of
|
|
208704
|
+
let prunable = false;
|
|
208705
|
+
for (const line of block.split("\n")) {
|
|
208699
208706
|
if (line.startsWith("worktree ")) worktreePath = line.slice(9);
|
|
208700
208707
|
else if (line.startsWith("branch refs/heads/")) branch = line.slice(18);
|
|
208701
|
-
else if (line === "prunable" || line.startsWith("prunable "))
|
|
208702
|
-
}
|
|
208703
|
-
if (worktreePath && !isPrunable && isTrustedWorktreePath(projectPath, worktreePath)) {
|
|
208704
|
-
entries.push({ path: worktreePath, branch });
|
|
208708
|
+
else if (line === "prunable" || line.startsWith("prunable ")) prunable = true;
|
|
208705
208709
|
}
|
|
208710
|
+
if (worktreePath) records.push({ path: worktreePath, branch, prunable });
|
|
208706
208711
|
}
|
|
208707
|
-
return
|
|
208712
|
+
return records;
|
|
208713
|
+
}
|
|
208714
|
+
function readWorktreeListFromGit(projectPath) {
|
|
208715
|
+
return readWorktreeRecords(projectPath).filter((record2) => !record2.prunable && isTrustedWorktreePath(projectPath, record2.path)).map(({ path: worktreePath, branch }) => ({ path: worktreePath, branch }));
|
|
208708
208716
|
}
|
|
208709
208717
|
function parseGitWorktreeList(projectPath) {
|
|
208710
208718
|
const now3 = Date.now();
|
|
@@ -208738,6 +208746,76 @@ function pruneWorktrees(projectPath) {
|
|
|
208738
208746
|
function invalidateWorktreeListCache(projectPath) {
|
|
208739
208747
|
worktreeListCache.delete(projectPath);
|
|
208740
208748
|
}
|
|
208749
|
+
function branchExists(projectPath, branch) {
|
|
208750
|
+
try {
|
|
208751
|
+
execFileSync2("git", ["rev-parse", "--verify", `refs/heads/${branch}`], {
|
|
208752
|
+
cwd: projectPath,
|
|
208753
|
+
encoding: "utf-8",
|
|
208754
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
208755
|
+
});
|
|
208756
|
+
return true;
|
|
208757
|
+
} catch {
|
|
208758
|
+
return false;
|
|
208759
|
+
}
|
|
208760
|
+
}
|
|
208761
|
+
function planWorktreeAdd(projectPath, branch, startPoint) {
|
|
208762
|
+
const exists2 = branchExists(projectPath, branch);
|
|
208763
|
+
if (exists2) {
|
|
208764
|
+
pruneWorktrees(projectPath);
|
|
208765
|
+
const existing = parseGitWorktreeList(projectPath).find((e) => e.branch === branch);
|
|
208766
|
+
if (existing) {
|
|
208767
|
+
if (canonicalPath(existing.path) === canonicalPath(projectPath)) {
|
|
208768
|
+
throw Object.assign(
|
|
208769
|
+
new Error(`Branch '${branch}' is checked out in the main workspace`),
|
|
208770
|
+
{ statusCode: 409 }
|
|
208771
|
+
);
|
|
208772
|
+
}
|
|
208773
|
+
return { worktreePath: existing.path, adopted: true, addArgs: null };
|
|
208774
|
+
}
|
|
208775
|
+
}
|
|
208776
|
+
const worktreePath = resolveWorktreePath(projectPath, branch);
|
|
208777
|
+
return {
|
|
208778
|
+
worktreePath,
|
|
208779
|
+
adopted: exists2,
|
|
208780
|
+
addArgs: exists2 ? ["worktree", "add", worktreePath, branch] : ["worktree", "add", "-b", branch, worktreePath, startPoint]
|
|
208781
|
+
};
|
|
208782
|
+
}
|
|
208783
|
+
function liveWorktreeRecord(projectPath, worktreePath) {
|
|
208784
|
+
const target = canonicalPath(worktreePath);
|
|
208785
|
+
const match2 = readWorktreeRecords(projectPath).find((record2) => !record2.prunable && canonicalPath(record2.path) === target);
|
|
208786
|
+
return match2 ? { path: match2.path, branch: match2.branch } : null;
|
|
208787
|
+
}
|
|
208788
|
+
function worktreeRecordExists(projectPath, worktreePath) {
|
|
208789
|
+
try {
|
|
208790
|
+
return liveWorktreeRecord(projectPath, worktreePath) !== null;
|
|
208791
|
+
} catch {
|
|
208792
|
+
return null;
|
|
208793
|
+
}
|
|
208794
|
+
}
|
|
208795
|
+
function deleteBranchAfterRemoval(projectPath, branch) {
|
|
208796
|
+
if (!branchExists(projectPath, branch)) return null;
|
|
208797
|
+
try {
|
|
208798
|
+
execFileSync2("git", ["branch", "-d", branch], {
|
|
208799
|
+
cwd: projectPath,
|
|
208800
|
+
encoding: "utf-8",
|
|
208801
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
208802
|
+
});
|
|
208803
|
+
return null;
|
|
208804
|
+
} catch (error48) {
|
|
208805
|
+
const stderr = String(error48?.stderr ?? "");
|
|
208806
|
+
return { branch, unmerged: /not fully merged/i.test(stderr) };
|
|
208807
|
+
}
|
|
208808
|
+
}
|
|
208809
|
+
function applyWorktreeAdd(projectPath, plan) {
|
|
208810
|
+
if (!plan.addArgs) return;
|
|
208811
|
+
mkdirSync2(getWorktreeBaseForProject(projectPath), { recursive: true });
|
|
208812
|
+
execFileSync2("git", plan.addArgs, {
|
|
208813
|
+
cwd: projectPath,
|
|
208814
|
+
encoding: "utf-8",
|
|
208815
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
208816
|
+
});
|
|
208817
|
+
invalidateWorktreeListCache(projectPath);
|
|
208818
|
+
}
|
|
208741
208819
|
function resolveWorktreePath(projectPath, branch) {
|
|
208742
208820
|
if (!branch) return projectPath;
|
|
208743
208821
|
try {
|
|
@@ -247390,7 +247468,6 @@ var process_routes_default = (0, import_fastify_plugin8.default)(routes7, { name
|
|
|
247390
247468
|
|
|
247391
247469
|
// src/routes/worktree-routes.ts
|
|
247392
247470
|
var import_fastify_plugin9 = __toESM(require_plugin2(), 1);
|
|
247393
|
-
import { mkdir as mkdir4 } from "fs/promises";
|
|
247394
247471
|
|
|
247395
247472
|
// src/utils/path-project.ts
|
|
247396
247473
|
async function ensurePathProjectId(fastify2, projectPath) {
|
|
@@ -247412,7 +247489,8 @@ async function getAllRemoteConfigs(fastify2, project) {
|
|
|
247412
247489
|
const remotes = await fastify2.storage.projectRemotes.getByProject(project.id);
|
|
247413
247490
|
return remotes.map((r) => ({
|
|
247414
247491
|
serverId: r.remote_server_id,
|
|
247415
|
-
remotePath: r.remote_path
|
|
247492
|
+
remotePath: r.remote_path,
|
|
247493
|
+
serverName: r.server_name
|
|
247416
247494
|
}));
|
|
247417
247495
|
}
|
|
247418
247496
|
async function getRemoteConfig(fastify2, project) {
|
|
@@ -247435,6 +247513,30 @@ async function ensurePathProject(fastify2, projectPath) {
|
|
|
247435
247513
|
if (!project) throw new Error(`Path project '${projectId}' was not persisted`);
|
|
247436
247514
|
return project;
|
|
247437
247515
|
}
|
|
247516
|
+
function removeWorktreeIfPresent(execFileSync8, projectPath, worktreePath) {
|
|
247517
|
+
try {
|
|
247518
|
+
execFileSync8("git", ["worktree", "remove", worktreePath], {
|
|
247519
|
+
cwd: projectPath,
|
|
247520
|
+
encoding: "utf-8",
|
|
247521
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
247522
|
+
});
|
|
247523
|
+
} catch (error48) {
|
|
247524
|
+
if (worktreeRecordExists(projectPath, worktreePath) !== false) throw error48;
|
|
247525
|
+
pruneWorktrees(projectPath);
|
|
247526
|
+
}
|
|
247527
|
+
}
|
|
247528
|
+
async function assertPathIsFree(fastify2, opts) {
|
|
247529
|
+
const registered = await fastify2.storage.workspaceRegistry.listByProject(opts.projectId, opts.targetId);
|
|
247530
|
+
const target = canonicalPath(opts.worktreePath);
|
|
247531
|
+
const owner = registered.find((row) => row.workspace.branch !== opts.branch && canonicalPath(row.checkout.worktree_path) === target);
|
|
247532
|
+
if (!owner) return;
|
|
247533
|
+
throw Object.assign(
|
|
247534
|
+
new Error(
|
|
247535
|
+
`That worktree already belongs to workspace '${owner.workspace.branch || "main"}'`
|
|
247536
|
+
),
|
|
247537
|
+
{ statusCode: 409 }
|
|
247538
|
+
);
|
|
247539
|
+
}
|
|
247438
247540
|
async function syncRemoteWorktreeList(fastify2, projectId, remote, data) {
|
|
247439
247541
|
const worktrees = data?.worktrees;
|
|
247440
247542
|
if (!Array.isArray(worktrees)) return;
|
|
@@ -247534,37 +247636,27 @@ var routes8 = async (fastify2) => {
|
|
|
247534
247636
|
console.log(`[worktree] ${requestId} Creating: branch=${trimmedBranch}, base=${startPoint}, path=${projectPath}`);
|
|
247535
247637
|
let pendingCheckoutId = null;
|
|
247536
247638
|
try {
|
|
247537
|
-
const
|
|
247538
|
-
try {
|
|
247539
|
-
execFileSync8("git", ["rev-parse", "--verify", `refs/heads/${trimmedBranch}`], {
|
|
247540
|
-
cwd: projectPath,
|
|
247541
|
-
encoding: "utf-8",
|
|
247542
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
247543
|
-
});
|
|
247544
|
-
return reply.code(409).send({ error: `Branch '${trimmedBranch}' already exists` });
|
|
247545
|
-
} catch {
|
|
247546
|
-
}
|
|
247547
|
-
const worktreeAbsolutePath = resolveWorktreePath(projectPath, trimmedBranch);
|
|
247639
|
+
const plan = planWorktreeAdd(projectPath, trimmedBranch, startPoint);
|
|
247548
247640
|
const project = await ensurePathProject(fastify2, projectPath);
|
|
247641
|
+
await assertPathIsFree(fastify2, {
|
|
247642
|
+
projectId: project.id,
|
|
247643
|
+
branch: trimmedBranch,
|
|
247644
|
+
targetId: "local",
|
|
247645
|
+
worktreePath: plan.worktreePath
|
|
247646
|
+
});
|
|
247549
247647
|
const pending = await fastify2.storage.workspaceRegistry.beginCheckout({
|
|
247550
247648
|
projectId: project.id,
|
|
247551
247649
|
branch: trimmedBranch,
|
|
247552
247650
|
targetId: "local",
|
|
247553
|
-
worktreePath:
|
|
247651
|
+
worktreePath: plan.worktreePath,
|
|
247554
247652
|
expectedBranch: trimmedBranch
|
|
247555
247653
|
});
|
|
247556
247654
|
pendingCheckoutId = pending.checkout.id;
|
|
247557
|
-
|
|
247558
|
-
execFileSync8("git", ["worktree", "add", "-b", trimmedBranch, worktreeAbsolutePath, startPoint], {
|
|
247559
|
-
cwd: projectPath,
|
|
247560
|
-
encoding: "utf-8",
|
|
247561
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
247562
|
-
});
|
|
247563
|
-
invalidateWorktreeListCache(projectPath);
|
|
247655
|
+
applyWorktreeAdd(projectPath, plan);
|
|
247564
247656
|
await fastify2.storage.workspaceRegistry.setCheckoutStatus(pending.checkout.id, "ready");
|
|
247565
|
-
console.log(`[worktree] ${requestId} Created: branch=${trimmedBranch}`);
|
|
247657
|
+
console.log(`[worktree] ${requestId} ${plan.adopted ? "Adopted" : "Created"}: branch=${trimmedBranch}`);
|
|
247566
247658
|
return reply.code(201).send({
|
|
247567
|
-
worktree: { branch: trimmedBranch, worktreePath:
|
|
247659
|
+
worktree: { branch: trimmedBranch, worktreePath: plan.worktreePath, adopted: plan.adopted }
|
|
247568
247660
|
});
|
|
247569
247661
|
} catch (error48) {
|
|
247570
247662
|
const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
|
|
@@ -247573,6 +247665,8 @@ var routes8 = async (fastify2) => {
|
|
|
247573
247665
|
}
|
|
247574
247666
|
const stderr = error48?.stderr || "";
|
|
247575
247667
|
console.error(`[worktree] ${requestId} Failed: ${errorMessage}${stderr ? `, stderr: ${stderr}` : ""}`);
|
|
247668
|
+
const statusCode = error48?.statusCode;
|
|
247669
|
+
if (statusCode) return reply.code(statusCode).send({ error: errorMessage });
|
|
247576
247670
|
return reply.code(500).send({ error: `Failed to create worktree: ${errorMessage}` });
|
|
247577
247671
|
}
|
|
247578
247672
|
});
|
|
@@ -247614,34 +247708,19 @@ var routes8 = async (fastify2) => {
|
|
|
247614
247708
|
branch,
|
|
247615
247709
|
worktreePath: worktreeAbsPath
|
|
247616
247710
|
});
|
|
247617
|
-
let branchToDelete =
|
|
247711
|
+
let branchToDelete = branch;
|
|
247618
247712
|
try {
|
|
247619
|
-
|
|
247620
|
-
const match2 = entries.find((e) => e.path === worktreeAbsPath);
|
|
247621
|
-
if (match2) branchToDelete = match2.branch;
|
|
247713
|
+
branchToDelete = liveWorktreeRecord(projectPath, worktreeAbsPath)?.branch ?? branch;
|
|
247622
247714
|
} catch {
|
|
247623
247715
|
}
|
|
247624
|
-
execFileSync8
|
|
247625
|
-
cwd: projectPath,
|
|
247626
|
-
encoding: "utf-8",
|
|
247627
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
247628
|
-
});
|
|
247716
|
+
removeWorktreeIfPresent(execFileSync8, projectPath, worktreeAbsPath);
|
|
247629
247717
|
worktreeRemoved = true;
|
|
247630
247718
|
invalidateWorktreeListCache(projectPath);
|
|
247631
|
-
|
|
247632
|
-
try {
|
|
247633
|
-
execFileSync8("git", ["branch", "-d", branchToDelete], {
|
|
247634
|
-
cwd: projectPath,
|
|
247635
|
-
encoding: "utf-8",
|
|
247636
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
247637
|
-
});
|
|
247638
|
-
} catch {
|
|
247639
|
-
}
|
|
247640
|
-
}
|
|
247719
|
+
const branchRetained = branchToDelete ? deleteBranchAfterRemoval(projectPath, branchToDelete) : null;
|
|
247641
247720
|
if (registered) {
|
|
247642
247721
|
await fastify2.storage.workspaceRegistry.markCheckoutDeleted(registered.checkout.id);
|
|
247643
247722
|
}
|
|
247644
|
-
return reply.code(200).send({ success: true });
|
|
247723
|
+
return reply.code(200).send({ success: true, branchRetained });
|
|
247645
247724
|
} catch (error48) {
|
|
247646
247725
|
const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
|
|
247647
247726
|
const busy = error48 instanceof WorktreeBusyError;
|
|
@@ -247756,7 +247835,11 @@ var routes8 = async (fastify2) => {
|
|
|
247756
247835
|
} else {
|
|
247757
247836
|
const targetRemote = await fastify2.storage.projectRemotes.getByProjectAndServer(project.id, requestedTarget);
|
|
247758
247837
|
if (!targetRemote) return reply.code(400).send({ error: "Unknown remote target" });
|
|
247759
|
-
remoteConfig = {
|
|
247838
|
+
remoteConfig = {
|
|
247839
|
+
serverId: targetRemote.remote_server_id,
|
|
247840
|
+
remotePath: targetRemote.remote_path,
|
|
247841
|
+
serverName: targetRemote.server_name
|
|
247842
|
+
};
|
|
247760
247843
|
}
|
|
247761
247844
|
if (remoteConfig) {
|
|
247762
247845
|
const result = await proxyToRemoteAuto(
|
|
@@ -247806,7 +247889,11 @@ var routes8 = async (fastify2) => {
|
|
|
247806
247889
|
} else {
|
|
247807
247890
|
const targetRemote = await fastify2.storage.projectRemotes.getByProjectAndServer(project.id, requestedTarget);
|
|
247808
247891
|
if (!targetRemote) return reply.code(400).send({ error: "Unknown remote target" });
|
|
247809
|
-
remoteConfig = {
|
|
247892
|
+
remoteConfig = {
|
|
247893
|
+
serverId: targetRemote.remote_server_id,
|
|
247894
|
+
remotePath: targetRemote.remote_path,
|
|
247895
|
+
serverName: targetRemote.server_name
|
|
247896
|
+
};
|
|
247810
247897
|
}
|
|
247811
247898
|
if (remoteConfig) {
|
|
247812
247899
|
const result = await proxyToRemoteAuto(
|
|
@@ -247950,17 +248037,19 @@ var routes8 = async (fastify2) => {
|
|
|
247950
248037
|
await Promise.allSettled(
|
|
247951
248038
|
remoteConfigs.map(async (rc) => {
|
|
247952
248039
|
const key2 = rc.serverId;
|
|
248040
|
+
const label = rc.serverName;
|
|
247953
248041
|
try {
|
|
247954
248042
|
const result = await deleteOnRemote(rc);
|
|
247955
248043
|
if (result.ok) {
|
|
247956
|
-
|
|
248044
|
+
const data = result.data;
|
|
248045
|
+
results2[key2] = { success: true, label, branchRetained: data?.branchRetained };
|
|
247957
248046
|
} else {
|
|
247958
248047
|
const data = result.data;
|
|
247959
|
-
results2[key2] = { success: false, error: data.error || "Remote deletion failed" };
|
|
248048
|
+
results2[key2] = { success: false, label, error: data.error || "Remote deletion failed" };
|
|
247960
248049
|
}
|
|
247961
248050
|
} catch (error48) {
|
|
247962
248051
|
const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
|
|
247963
|
-
results2[key2] = { success: false, error: errorMessage };
|
|
248052
|
+
results2[key2] = { success: false, label, error: errorMessage };
|
|
247964
248053
|
}
|
|
247965
248054
|
})
|
|
247966
248055
|
);
|
|
@@ -247999,33 +248088,19 @@ var routes8 = async (fastify2) => {
|
|
|
247999
248088
|
branch,
|
|
248000
248089
|
worktreePath: worktreeAbsPath
|
|
248001
248090
|
});
|
|
248002
|
-
let branchToDelete =
|
|
248091
|
+
let branchToDelete = branch;
|
|
248003
248092
|
try {
|
|
248004
|
-
|
|
248005
|
-
const match2 = entries.find((e) => e.path === worktreeAbsPath);
|
|
248006
|
-
if (match2) branchToDelete = match2.branch;
|
|
248093
|
+
branchToDelete = liveWorktreeRecord(project.path, worktreeAbsPath)?.branch ?? branch;
|
|
248007
248094
|
} catch {
|
|
248008
248095
|
}
|
|
248009
|
-
execFileSync8
|
|
248010
|
-
cwd: project.path,
|
|
248011
|
-
encoding: "utf-8",
|
|
248012
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
248013
|
-
});
|
|
248096
|
+
removeWorktreeIfPresent(execFileSync8, project.path, worktreeAbsPath);
|
|
248014
248097
|
worktreeRemoved = true;
|
|
248015
248098
|
invalidateWorktreeListCache(project.path);
|
|
248016
|
-
|
|
248017
|
-
try {
|
|
248018
|
-
execFileSync8("git", ["branch", "-d", branchToDelete], {
|
|
248019
|
-
cwd: project.path,
|
|
248020
|
-
encoding: "utf-8",
|
|
248021
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
248022
|
-
});
|
|
248023
|
-
} catch {
|
|
248024
|
-
}
|
|
248025
|
-
}
|
|
248099
|
+
const branchRetained = branchToDelete ? deleteBranchAfterRemoval(project.path, branchToDelete) : null;
|
|
248026
248100
|
if (registered) {
|
|
248027
248101
|
await fastify2.storage.workspaceRegistry.markCheckoutDeleted(registered.checkout.id);
|
|
248028
248102
|
}
|
|
248103
|
+
return branchRetained;
|
|
248029
248104
|
} catch (error48) {
|
|
248030
248105
|
if (registered && !worktreeRemoved) {
|
|
248031
248106
|
const message = error48 instanceof Error ? error48.message : "Local deletion failed";
|
|
@@ -248037,8 +248112,8 @@ var routes8 = async (fastify2) => {
|
|
|
248037
248112
|
};
|
|
248038
248113
|
if (!hasRemote) {
|
|
248039
248114
|
try {
|
|
248040
|
-
await deleteLocal();
|
|
248041
|
-
return reply.code(200).send({ success: true });
|
|
248115
|
+
const branchRetained = await deleteLocal();
|
|
248116
|
+
return reply.code(200).send({ success: true, branchRetained });
|
|
248042
248117
|
} catch (error48) {
|
|
248043
248118
|
const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
|
|
248044
248119
|
if (errorMessage.includes("uncommitted changes") || error48 instanceof WorktreeBusyError) {
|
|
@@ -248049,8 +248124,7 @@ var routes8 = async (fastify2) => {
|
|
|
248049
248124
|
}
|
|
248050
248125
|
const results = {};
|
|
248051
248126
|
try {
|
|
248052
|
-
await deleteLocal();
|
|
248053
|
-
results.local = { success: true };
|
|
248127
|
+
results.local = { success: true, label: "local", branchRetained: await deleteLocal() };
|
|
248054
248128
|
} catch (error48) {
|
|
248055
248129
|
const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
|
|
248056
248130
|
return reply.code(500).send({ error: `Failed to delete local worktree: ${errorMessage}` });
|
|
@@ -248058,17 +248132,19 @@ var routes8 = async (fastify2) => {
|
|
|
248058
248132
|
await Promise.allSettled(
|
|
248059
248133
|
remoteConfigs.map(async (rc) => {
|
|
248060
248134
|
const key2 = remoteConfigs.length === 1 ? "remote" : rc.serverId;
|
|
248135
|
+
const label = rc.serverName;
|
|
248061
248136
|
try {
|
|
248062
248137
|
const remoteResult = await deleteOnRemote(rc);
|
|
248063
248138
|
if (remoteResult.ok) {
|
|
248064
|
-
|
|
248139
|
+
const remoteData = remoteResult.data;
|
|
248140
|
+
results[key2] = { success: true, label, branchRetained: remoteData?.branchRetained };
|
|
248065
248141
|
} else {
|
|
248066
248142
|
const remoteData = remoteResult.data;
|
|
248067
|
-
results[key2] = { success: false, error: remoteData.error || "Remote deletion failed" };
|
|
248143
|
+
results[key2] = { success: false, label, error: remoteData.error || "Remote deletion failed" };
|
|
248068
248144
|
}
|
|
248069
248145
|
} catch (error48) {
|
|
248070
248146
|
const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
|
|
248071
|
-
results[key2] = { success: false, error: errorMessage };
|
|
248147
|
+
results[key2] = { success: false, label, error: errorMessage };
|
|
248072
248148
|
}
|
|
248073
248149
|
})
|
|
248074
248150
|
);
|
|
@@ -248182,20 +248258,21 @@ var routes8 = async (fastify2) => {
|
|
|
248182
248258
|
const settled = await Promise.allSettled(
|
|
248183
248259
|
remoteConfigs.map(async (rc) => {
|
|
248184
248260
|
const key2 = rc.serverId;
|
|
248261
|
+
const label = rc.serverName;
|
|
248185
248262
|
console.log(`[worktree] Creating remote worktree: project=${req.params.id}, branch=${trimmedBranch}, serverId=${rc.serverId}`);
|
|
248186
248263
|
try {
|
|
248187
248264
|
const result = await createOnRemote(rc);
|
|
248188
248265
|
if (result.ok) {
|
|
248189
248266
|
const data = result.data;
|
|
248190
|
-
results2[key2] = { success: true, worktree: data.worktree };
|
|
248267
|
+
results2[key2] = { success: true, label, worktree: data.worktree, adopted: data.worktree?.adopted };
|
|
248191
248268
|
} else {
|
|
248192
248269
|
const data = result.data;
|
|
248193
248270
|
console.error(`[worktree] Remote failed: serverId=${rc.serverId}, requestId=${result.requestId}, error=${JSON.stringify(result.data)}`);
|
|
248194
|
-
results2[key2] = { success: false, error: data.error || "Remote creation failed", errorCode: result.errorCode, requestId: result.requestId };
|
|
248271
|
+
results2[key2] = { success: false, label, error: data.error || "Remote creation failed", errorCode: result.errorCode, requestId: result.requestId };
|
|
248195
248272
|
}
|
|
248196
248273
|
} catch (error48) {
|
|
248197
248274
|
const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
|
|
248198
|
-
results2[key2] = { success: false, error: errorMessage };
|
|
248275
|
+
results2[key2] = { success: false, label, error: errorMessage };
|
|
248199
248276
|
}
|
|
248200
248277
|
})
|
|
248201
248278
|
);
|
|
@@ -248210,35 +248287,24 @@ var routes8 = async (fastify2) => {
|
|
|
248210
248287
|
return reply.code(201).send({ worktree: { branch: trimmedBranch }, results: results2 });
|
|
248211
248288
|
}
|
|
248212
248289
|
const createLocal = async () => {
|
|
248213
|
-
const
|
|
248214
|
-
|
|
248215
|
-
|
|
248216
|
-
|
|
248217
|
-
|
|
248218
|
-
|
|
248219
|
-
|
|
248220
|
-
throw new Error(`Branch '${trimmedBranch}' already exists`);
|
|
248221
|
-
} catch (err) {
|
|
248222
|
-
if (err instanceof Error && err.message.includes("already exists")) throw err;
|
|
248223
|
-
}
|
|
248224
|
-
const worktreeAbsolutePath = resolveWorktreePath(project.path, trimmedBranch);
|
|
248290
|
+
const plan = planWorktreeAdd(project.path, trimmedBranch, localStartPoint);
|
|
248291
|
+
await assertPathIsFree(fastify2, {
|
|
248292
|
+
projectId: project.id,
|
|
248293
|
+
branch: trimmedBranch,
|
|
248294
|
+
targetId: "local",
|
|
248295
|
+
worktreePath: plan.worktreePath
|
|
248296
|
+
});
|
|
248225
248297
|
const pending = await fastify2.storage.workspaceRegistry.beginCheckout({
|
|
248226
248298
|
projectId: project.id,
|
|
248227
248299
|
branch: trimmedBranch,
|
|
248228
248300
|
targetId: "local",
|
|
248229
|
-
worktreePath:
|
|
248301
|
+
worktreePath: plan.worktreePath,
|
|
248230
248302
|
expectedBranch: trimmedBranch
|
|
248231
248303
|
});
|
|
248232
248304
|
try {
|
|
248233
|
-
|
|
248234
|
-
execFileSync8("git", ["worktree", "add", "-b", trimmedBranch, worktreeAbsolutePath, localStartPoint], {
|
|
248235
|
-
cwd: project.path,
|
|
248236
|
-
encoding: "utf-8",
|
|
248237
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
248238
|
-
});
|
|
248239
|
-
invalidateWorktreeListCache(project.path);
|
|
248305
|
+
applyWorktreeAdd(project.path, plan);
|
|
248240
248306
|
await fastify2.storage.workspaceRegistry.setCheckoutStatus(pending.checkout.id, "ready");
|
|
248241
|
-
return { branch: trimmedBranch };
|
|
248307
|
+
return { branch: trimmedBranch, adopted: plan.adopted };
|
|
248242
248308
|
} catch (error48) {
|
|
248243
248309
|
const message = error48 instanceof Error ? error48.message : "Local creation failed";
|
|
248244
248310
|
await fastify2.storage.workspaceRegistry.setCheckoutStatus(pending.checkout.id, "error", message).catch((registryError) => console.error("[worktree] Failed to record local checkout error:", registryError));
|
|
@@ -248251,6 +248317,8 @@ var routes8 = async (fastify2) => {
|
|
|
248251
248317
|
return reply.code(201).send({ worktree });
|
|
248252
248318
|
} catch (error48) {
|
|
248253
248319
|
const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
|
|
248320
|
+
const statusCode = error48?.statusCode;
|
|
248321
|
+
if (statusCode) return reply.code(statusCode).send({ error: errorMessage });
|
|
248254
248322
|
if (errorMessage.includes("already exists")) {
|
|
248255
248323
|
return reply.code(409).send({ error: errorMessage });
|
|
248256
248324
|
}
|
|
@@ -248261,7 +248329,7 @@ var routes8 = async (fastify2) => {
|
|
|
248261
248329
|
let localWorktree;
|
|
248262
248330
|
try {
|
|
248263
248331
|
localWorktree = await createLocal();
|
|
248264
|
-
results.local = { success: true, worktree: localWorktree };
|
|
248332
|
+
results.local = { success: true, label: "local", worktree: localWorktree, adopted: localWorktree.adopted };
|
|
248265
248333
|
} catch (error48) {
|
|
248266
248334
|
const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
|
|
248267
248335
|
return reply.code(500).send({ error: `Failed to create local worktree: ${errorMessage}` });
|
|
@@ -248269,17 +248337,19 @@ var routes8 = async (fastify2) => {
|
|
|
248269
248337
|
await Promise.allSettled(
|
|
248270
248338
|
remoteConfigs.map(async (rc) => {
|
|
248271
248339
|
const key2 = remoteConfigs.length === 1 ? "remote" : rc.serverId;
|
|
248340
|
+
const label = rc.serverName;
|
|
248272
248341
|
console.log(`[worktree] Creating remote worktree: project=${req.params.id}, branch=${trimmedBranch}, serverId=${rc.serverId}`);
|
|
248273
248342
|
try {
|
|
248274
248343
|
const remoteResult = await createOnRemote(rc);
|
|
248275
248344
|
if (remoteResult.ok) {
|
|
248276
248345
|
const remoteData = remoteResult.data;
|
|
248277
|
-
results[key2] = { success: true, worktree: remoteData.worktree };
|
|
248346
|
+
results[key2] = { success: true, label, worktree: remoteData.worktree, adopted: remoteData.worktree?.adopted };
|
|
248278
248347
|
} else {
|
|
248279
248348
|
const remoteData = remoteResult.data;
|
|
248280
248349
|
console.error(`[worktree] Remote failed: serverId=${rc.serverId}, requestId=${remoteResult.requestId}, errorCode=${remoteResult.errorCode}, status=${remoteResult.status}, duration=${remoteResult.durationMs}ms, error=${JSON.stringify(remoteResult.data)}`);
|
|
248281
248350
|
results[key2] = {
|
|
248282
248351
|
success: false,
|
|
248352
|
+
label,
|
|
248283
248353
|
error: remoteData.error || "Remote creation failed",
|
|
248284
248354
|
errorCode: remoteResult.errorCode,
|
|
248285
248355
|
requestId: remoteResult.requestId
|
|
@@ -248287,7 +248357,7 @@ var routes8 = async (fastify2) => {
|
|
|
248287
248357
|
}
|
|
248288
248358
|
} catch (error48) {
|
|
248289
248359
|
const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
|
|
248290
|
-
results[key2] = { success: false, error: errorMessage };
|
|
248360
|
+
results[key2] = { success: false, label, error: errorMessage };
|
|
248291
248361
|
}
|
|
248292
248362
|
})
|
|
248293
248363
|
);
|
|
@@ -249599,7 +249669,7 @@ var file_routes_default = (0, import_fastify_plugin11.default)(routes10, { name:
|
|
|
249599
249669
|
var import_fastify_plugin12 = __toESM(require_plugin2(), 1);
|
|
249600
249670
|
|
|
249601
249671
|
// src/utils/paste-file.ts
|
|
249602
|
-
import { chmod, mkdir as
|
|
249672
|
+
import { chmod, mkdir as mkdir4, open as open2 } from "node:fs/promises";
|
|
249603
249673
|
import { constants as fsConstants2 } from "node:fs";
|
|
249604
249674
|
import path15 from "node:path";
|
|
249605
249675
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
@@ -249645,7 +249715,7 @@ var DIR_MODE = 448;
|
|
|
249645
249715
|
var FILE_MODE = 384;
|
|
249646
249716
|
var FILE_FLAGS = fsConstants2.O_WRONLY | fsConstants2.O_CREAT | fsConstants2.O_EXCL | fsConstants2.O_NOFOLLOW;
|
|
249647
249717
|
async function writePasteToTempFile(content) {
|
|
249648
|
-
await
|
|
249718
|
+
await mkdir4(PASTE_DIR, { recursive: true, mode: DIR_MODE });
|
|
249649
249719
|
await chmod(PASTE_DIR, DIR_MODE);
|
|
249650
249720
|
const filePath = path15.join(PASTE_DIR, `${randomUUID15()}.txt`);
|
|
249651
249721
|
const handle = await open2(filePath, FILE_FLAGS, FILE_MODE);
|
|
@@ -249659,11 +249729,12 @@ async function writePasteToTempFile(content) {
|
|
|
249659
249729
|
}
|
|
249660
249730
|
|
|
249661
249731
|
// src/utils/attachment-file.ts
|
|
249662
|
-
import { chmod as chmod2, mkdir as
|
|
249732
|
+
import { chmod as chmod2, mkdir as mkdir5, open as open3 } from "node:fs/promises";
|
|
249663
249733
|
import { constants as fsConstants3 } from "node:fs";
|
|
249664
249734
|
import path16 from "node:path";
|
|
249665
249735
|
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
249666
|
-
var MAX_ATTACHMENT_BYTES =
|
|
249736
|
+
var MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
249737
|
+
var ATTACHMENT_BODY_LIMIT = Math.ceil(MAX_ATTACHMENT_BYTES * 4 / 3) + 1024 * 1024;
|
|
249667
249738
|
var DIR_MODE2 = 448;
|
|
249668
249739
|
var FILE_MODE2 = 384;
|
|
249669
249740
|
var FILE_FLAGS2 = fsConstants3.O_WRONLY | fsConstants3.O_CREAT | fsConstants3.O_EXCL | fsConstants3.O_NOFOLLOW;
|
|
@@ -249681,10 +249752,10 @@ function sanitizeAttachmentName(raw) {
|
|
|
249681
249752
|
}
|
|
249682
249753
|
async function writeAttachmentToTempFile(rawName, data) {
|
|
249683
249754
|
const name25 = sanitizeAttachmentName(rawName);
|
|
249684
|
-
await
|
|
249755
|
+
await mkdir5(ATTACHMENT_DIR, { recursive: true, mode: DIR_MODE2 });
|
|
249685
249756
|
await chmod2(ATTACHMENT_DIR, DIR_MODE2);
|
|
249686
249757
|
const dir = path16.join(ATTACHMENT_DIR, randomUUID16());
|
|
249687
|
-
await
|
|
249758
|
+
await mkdir5(dir, { mode: DIR_MODE2 });
|
|
249688
249759
|
const filePath = path16.join(dir, name25);
|
|
249689
249760
|
const handle = await open3(filePath, FILE_FLAGS2, FILE_MODE2);
|
|
249690
249761
|
try {
|
|
@@ -251454,7 +251525,7 @@ var routes11 = async (fastify2) => {
|
|
|
251454
251525
|
return reply.code(500).send({ error: `Failed to write paste: ${msg}` });
|
|
251455
251526
|
}
|
|
251456
251527
|
});
|
|
251457
|
-
fastify2.post("/api/agent-sessions/:sessionId/attachment", { bodyLimit:
|
|
251528
|
+
fastify2.post("/api/agent-sessions/:sessionId/attachment", { bodyLimit: ATTACHMENT_BODY_LIMIT }, async (req, reply) => {
|
|
251458
251529
|
const { name: name25, mediaType, contentBase64 } = req.body ?? {};
|
|
251459
251530
|
if (typeof name25 !== "string" || name25.length === 0) {
|
|
251460
251531
|
return reply.code(400).send({ error: "name must be a non-empty string" });
|
|
@@ -264311,7 +264382,7 @@ var ReverseConnectClient = class {
|
|
|
264311
264382
|
this.dialStartedAt = Date.now();
|
|
264312
264383
|
this.closingSince = 0;
|
|
264313
264384
|
const ws = new wrapper_default(connectUrl, {
|
|
264314
|
-
maxPayload:
|
|
264385
|
+
maxPayload: TUNNEL_MAX_FRAME_BYTES,
|
|
264315
264386
|
handshakeTimeout: HANDSHAKE_TIMEOUT_MS
|
|
264316
264387
|
});
|
|
264317
264388
|
this.ws = ws;
|