@vibedeckx/darwin-arm64 0.3.11 → 0.3.12
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 +493 -342
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -13356,12 +13356,12 @@ var require_semver = __commonJS({
|
|
|
13356
13356
|
}
|
|
13357
13357
|
function replaceHyphen(comp, options) {
|
|
13358
13358
|
const r = HYPHENRANGE_REGEXP;
|
|
13359
|
-
return comp.replace(r, (_3, from, fM, fm,
|
|
13359
|
+
return comp.replace(r, (_3, from, fM, fm, fp35, fpr, fb, to, tM, tm, tp, tpr) => {
|
|
13360
13360
|
if (isX(fM)) {
|
|
13361
13361
|
from = "";
|
|
13362
13362
|
} else if (isX(fm)) {
|
|
13363
13363
|
from = `>=${fM}.0.0${options?.includePrerelease ? "-0" : ""}`;
|
|
13364
|
-
} else if (isX(
|
|
13364
|
+
} else if (isX(fp35)) {
|
|
13365
13365
|
from = `>=${fM}.${fm}.0${options?.includePrerelease ? "-0" : ""}`;
|
|
13366
13366
|
} else if (fpr) {
|
|
13367
13367
|
from = `>=${from}`;
|
|
@@ -87525,12 +87525,12 @@ var require_range = __commonJS({
|
|
|
87525
87525
|
debug("replaceGTE0", comp, options);
|
|
87526
87526
|
return comp.trim().replace(re2[options.includePrerelease ? t.GTE0PRE : t.GTE0], "");
|
|
87527
87527
|
};
|
|
87528
|
-
var hyphenReplace = (incPr) => ($0, from, fM, fm,
|
|
87528
|
+
var hyphenReplace = (incPr) => ($0, from, fM, fm, fp35, fpr, fb, to, tM, tm, tp, tpr) => {
|
|
87529
87529
|
if (isX(fM)) {
|
|
87530
87530
|
from = "";
|
|
87531
87531
|
} else if (isX(fm)) {
|
|
87532
87532
|
from = `>=${fM}.0.0${incPr ? "-0" : ""}`;
|
|
87533
|
-
} else if (isX(
|
|
87533
|
+
} else if (isX(fp35)) {
|
|
87534
87534
|
from = `>=${fM}.${fm}.0${incPr ? "-0" : ""}`;
|
|
87535
87535
|
} else if (fpr) {
|
|
87536
87536
|
from = `>=${from}`;
|
|
@@ -90111,8 +90111,8 @@ var require_pretty_print = __commonJS({
|
|
|
90111
90111
|
serializedRoute += serializeMetaData(route.metaData);
|
|
90112
90112
|
return serializedRoute;
|
|
90113
90113
|
}
|
|
90114
|
-
function mergeSimilarRoutes(
|
|
90115
|
-
return
|
|
90114
|
+
function mergeSimilarRoutes(routes34) {
|
|
90115
|
+
return routes34.reduce((mergedRoutes, route) => {
|
|
90116
90116
|
for (const nodeRoute of mergedRoutes) {
|
|
90117
90117
|
if (deepEqual(route.opts.constraints, nodeRoute.opts.constraints) && deepEqual(route.metaData, nodeRoute.metaData)) {
|
|
90118
90118
|
nodeRoute.method += ", " + route.method;
|
|
@@ -90124,18 +90124,18 @@ var require_pretty_print = __commonJS({
|
|
|
90124
90124
|
}, []);
|
|
90125
90125
|
}
|
|
90126
90126
|
function serializeNode(node, prefix, options) {
|
|
90127
|
-
let
|
|
90127
|
+
let routes34 = node.routes;
|
|
90128
90128
|
if (options.method === void 0) {
|
|
90129
|
-
|
|
90129
|
+
routes34 = routes34.map(normalizeRoute);
|
|
90130
90130
|
}
|
|
90131
|
-
|
|
90131
|
+
routes34 = routes34.map((route) => {
|
|
90132
90132
|
route.metaData = getRouteMetaData(route, options);
|
|
90133
90133
|
return route;
|
|
90134
90134
|
});
|
|
90135
90135
|
if (options.method === void 0) {
|
|
90136
|
-
|
|
90136
|
+
routes34 = mergeSimilarRoutes(routes34);
|
|
90137
90137
|
}
|
|
90138
|
-
return
|
|
90138
|
+
return routes34.map(serializeRoute).join(`
|
|
90139
90139
|
${prefix}`);
|
|
90140
90140
|
}
|
|
90141
90141
|
function buildObjectTree(node, tree, prefix, options) {
|
|
@@ -91402,9 +91402,9 @@ var require_find_my_way = __commonJS({
|
|
|
91402
91402
|
pathIndex = paramEndIndex;
|
|
91403
91403
|
}
|
|
91404
91404
|
};
|
|
91405
|
-
Router.prototype._rebuild = function(
|
|
91405
|
+
Router.prototype._rebuild = function(routes34) {
|
|
91406
91406
|
this.reset();
|
|
91407
|
-
for (const route of
|
|
91407
|
+
for (const route of routes34) {
|
|
91408
91408
|
const { method, path: path22, opts, handler, store } = route;
|
|
91409
91409
|
this._on(method, path22, opts, handler, store);
|
|
91410
91410
|
}
|
|
@@ -93805,7 +93805,7 @@ var require_parse_url = __commonJS({
|
|
|
93805
93805
|
var require_form_data = __commonJS({
|
|
93806
93806
|
"../../node_modules/.pnpm/light-my-request@6.6.0/node_modules/light-my-request/lib/form-data.js"(exports, module) {
|
|
93807
93807
|
"use strict";
|
|
93808
|
-
var { randomUUID:
|
|
93808
|
+
var { randomUUID: randomUUID23 } = __require("node:crypto");
|
|
93809
93809
|
var { Readable: Readable4 } = __require("node:stream");
|
|
93810
93810
|
var textEncoder;
|
|
93811
93811
|
function isFormDataLike(payload) {
|
|
@@ -93813,7 +93813,7 @@ var require_form_data = __commonJS({
|
|
|
93813
93813
|
}
|
|
93814
93814
|
function formDataToStream(formdata) {
|
|
93815
93815
|
textEncoder = textEncoder ?? new TextEncoder();
|
|
93816
|
-
const boundary = `----formdata-${
|
|
93816
|
+
const boundary = `----formdata-${randomUUID23()}`;
|
|
93817
93817
|
const prefix = `--${boundary}\r
|
|
93818
93818
|
Content-Disposition: form-data`;
|
|
93819
93819
|
const escape2 = (str) => str.replace(/\n/g, "%0A").replace(/\r/g, "%0D").replace(/"/g, "%22");
|
|
@@ -100612,8 +100612,8 @@ var require_commonjs6 = __commonJS({
|
|
|
100612
100612
|
return this.#fullpath = this.name;
|
|
100613
100613
|
}
|
|
100614
100614
|
const pv = p2.fullpath();
|
|
100615
|
-
const
|
|
100616
|
-
return this.#fullpath =
|
|
100615
|
+
const fp35 = pv + (!p2.parent ? "" : this.sep) + name25;
|
|
100616
|
+
return this.#fullpath = fp35;
|
|
100617
100617
|
}
|
|
100618
100618
|
/**
|
|
100619
100619
|
* On platforms other than windows, this is identical to fullpath.
|
|
@@ -105329,7 +105329,7 @@ var require_static = __commonJS({
|
|
|
105329
105329
|
var { fileURLToPath: fileURLToPath4 } = __require("node:url");
|
|
105330
105330
|
var { statSync: statSync2 } = __require("node:fs");
|
|
105331
105331
|
var { glob } = require_commonjs7();
|
|
105332
|
-
var
|
|
105332
|
+
var fp35 = require_plugin2();
|
|
105333
105333
|
var send = require_send2();
|
|
105334
105334
|
var encodingNegotiator = require_accept_negotiator();
|
|
105335
105335
|
var contentDisposition = require_content_disposition();
|
|
@@ -105433,7 +105433,7 @@ var require_static = __commonJS({
|
|
|
105433
105433
|
} else {
|
|
105434
105434
|
const indexes = new Set(opts.index === void 0 ? ["index.html"] : [].concat(opts.index));
|
|
105435
105435
|
const indexDirs = /* @__PURE__ */ new Map();
|
|
105436
|
-
const
|
|
105436
|
+
const routes34 = /* @__PURE__ */ new Set();
|
|
105437
105437
|
const roots = Array.isArray(sendOptions.root) ? sendOptions.root : [sendOptions.root];
|
|
105438
105438
|
for (let rootPath of roots) {
|
|
105439
105439
|
rootPath = rootPath.split(path22.win32.sep).join(path22.posix.sep);
|
|
@@ -105449,10 +105449,10 @@ var require_static = __commonJS({
|
|
|
105449
105449
|
for (let file2 of files) {
|
|
105450
105450
|
file2 = file2.split(path22.win32.sep).join(path22.posix.sep);
|
|
105451
105451
|
const route = prefix + file2;
|
|
105452
|
-
if (
|
|
105452
|
+
if (routes34.has(route)) {
|
|
105453
105453
|
continue;
|
|
105454
105454
|
}
|
|
105455
|
-
|
|
105455
|
+
routes34.add(route);
|
|
105456
105456
|
setUpHeadAndGet(routeOpts, route, `/${file2}`, rootPath);
|
|
105457
105457
|
const key2 = path22.posix.basename(route);
|
|
105458
105458
|
if (indexes.has(key2) && !indexDirs.has(key2)) {
|
|
@@ -105747,7 +105747,7 @@ var require_static = __commonJS({
|
|
|
105747
105747
|
throw err;
|
|
105748
105748
|
}
|
|
105749
105749
|
}
|
|
105750
|
-
module.exports =
|
|
105750
|
+
module.exports = fp35(fastifyStatic2, {
|
|
105751
105751
|
fastify: "5.x",
|
|
105752
105752
|
name: "@fastify/static"
|
|
105753
105753
|
});
|
|
@@ -112390,7 +112390,7 @@ var require_websocket2 = __commonJS({
|
|
|
112390
112390
|
var { ServerResponse } = __require("node:http");
|
|
112391
112391
|
var { PassThrough } = __require("node:stream");
|
|
112392
112392
|
var { randomBytes: randomBytes3 } = __require("node:crypto");
|
|
112393
|
-
var
|
|
112393
|
+
var fp35 = require_plugin2();
|
|
112394
112394
|
var WebSocket2 = require_ws();
|
|
112395
112395
|
var Duplexify = require_duplexify();
|
|
112396
112396
|
var kWs = /* @__PURE__ */ Symbol("ws-socket");
|
|
@@ -112576,7 +112576,7 @@ var require_websocket2 = __commonJS({
|
|
|
112576
112576
|
}
|
|
112577
112577
|
next();
|
|
112578
112578
|
}
|
|
112579
|
-
module.exports =
|
|
112579
|
+
module.exports = fp35(fastifyWebsocket2, {
|
|
112580
112580
|
fastify: "5.x",
|
|
112581
112581
|
name: "@fastify/websocket"
|
|
112582
112582
|
});
|
|
@@ -115020,7 +115020,7 @@ var require_multipart2 = __commonJS({
|
|
|
115020
115020
|
"use strict";
|
|
115021
115021
|
var Busboy = require_main();
|
|
115022
115022
|
var os2 = __require("node:os");
|
|
115023
|
-
var
|
|
115023
|
+
var fp35 = require_plugin2();
|
|
115024
115024
|
var { createWriteStream: createWriteStream2 } = __require("node:fs");
|
|
115025
115025
|
var { unlink: unlink2 } = __require("node:fs/promises");
|
|
115026
115026
|
var path22 = __require("node:path");
|
|
@@ -115469,7 +115469,7 @@ var require_multipart2 = __commonJS({
|
|
|
115469
115469
|
}
|
|
115470
115470
|
});
|
|
115471
115471
|
}
|
|
115472
|
-
module.exports =
|
|
115472
|
+
module.exports = fp35(fastifyMultipart2, {
|
|
115473
115473
|
fastify: "5.x",
|
|
115474
115474
|
name: "@fastify/multipart"
|
|
115475
115475
|
});
|
|
@@ -169021,11 +169021,11 @@ function buildCommand(builderArgs) {
|
|
|
169021
169021
|
}
|
|
169022
169022
|
};
|
|
169023
169023
|
}
|
|
169024
|
-
function* generateRouteMapHelpLines(
|
|
169024
|
+
function* generateRouteMapHelpLines(routes34, docs, args) {
|
|
169025
169025
|
const { brief, fullDescription, hideRoute } = docs;
|
|
169026
169026
|
const { headers } = args.text;
|
|
169027
169027
|
yield args.ansiColor ? `\x1B[1m${headers.usage}\x1B[22m` : headers.usage;
|
|
169028
|
-
for (const [name25, route] of Object.entries(
|
|
169028
|
+
for (const [name25, route] of Object.entries(routes34)) {
|
|
169029
169029
|
if (!hideRoute || !hideRoute[name25] || args.includeHidden) {
|
|
169030
169030
|
const externalRouteName = args.config.caseStyle === "convert-camel-to-kebab" ? convertCamelCaseToKebabCase(name25) : name25;
|
|
169031
169031
|
yield ` ${route.formatUsageLine({
|
|
@@ -169055,7 +169055,7 @@ function* generateRouteMapHelpLines(routes35, docs, args) {
|
|
|
169055
169055
|
}
|
|
169056
169056
|
yield "";
|
|
169057
169057
|
yield args.ansiColor ? `\x1B[1m${headers.commands}\x1B[22m` : headers.commands;
|
|
169058
|
-
const visibleRoutes = Object.entries(
|
|
169058
|
+
const visibleRoutes = Object.entries(routes34).filter(
|
|
169059
169059
|
([name25]) => !hideRoute || !hideRoute[name25] || args.includeHidden
|
|
169060
169060
|
);
|
|
169061
169061
|
const rows = visibleRoutes.map(([internalRouteName, route]) => {
|
|
@@ -169083,24 +169083,24 @@ function* generateRouteMapHelpLines(routes35, docs, args) {
|
|
|
169083
169083
|
}
|
|
169084
169084
|
}
|
|
169085
169085
|
function buildRouteMap({
|
|
169086
|
-
routes:
|
|
169086
|
+
routes: routes34,
|
|
169087
169087
|
defaultCommand: defaultCommandRoute,
|
|
169088
169088
|
docs,
|
|
169089
169089
|
aliases
|
|
169090
169090
|
}) {
|
|
169091
|
-
if (Object.entries(
|
|
169091
|
+
if (Object.entries(routes34).length === 0) {
|
|
169092
169092
|
throw new InternalError("Route map must contain at least one route");
|
|
169093
169093
|
}
|
|
169094
169094
|
const activeAliases = aliases ?? {};
|
|
169095
169095
|
const aliasesByRoute = /* @__PURE__ */ new Map();
|
|
169096
169096
|
for (const [alias, routeName] of Object.entries(activeAliases)) {
|
|
169097
|
-
if (alias in
|
|
169097
|
+
if (alias in routes34) {
|
|
169098
169098
|
throw new InternalError(`Cannot use "${alias}" as an alias when a route with that name already exists`);
|
|
169099
169099
|
}
|
|
169100
169100
|
const routeAliases = aliasesByRoute.get(routeName) ?? [];
|
|
169101
169101
|
aliasesByRoute.set(routeName, [...routeAliases, alias]);
|
|
169102
169102
|
}
|
|
169103
|
-
const defaultCommand = defaultCommandRoute ?
|
|
169103
|
+
const defaultCommand = defaultCommandRoute ? routes34[defaultCommandRoute] : void 0;
|
|
169104
169104
|
if (defaultCommand && defaultCommand.kind === RouteMapSymbol) {
|
|
169105
169105
|
throw new InternalError(
|
|
169106
169106
|
`Cannot use "${defaultCommandRoute}" as the default command because it is not a Command`
|
|
@@ -169109,7 +169109,7 @@ function buildRouteMap({
|
|
|
169109
169109
|
const resolveRouteName = (input) => {
|
|
169110
169110
|
if (input in activeAliases) {
|
|
169111
169111
|
return activeAliases[input];
|
|
169112
|
-
} else if (input in
|
|
169112
|
+
} else if (input in routes34) {
|
|
169113
169113
|
return input;
|
|
169114
169114
|
}
|
|
169115
169115
|
};
|
|
@@ -169127,7 +169127,7 @@ function buildRouteMap({
|
|
|
169127
169127
|
return `${args.prefix.join(" ")} ${routeNames.join("|")} ...`;
|
|
169128
169128
|
},
|
|
169129
169129
|
formatHelp: (config2) => {
|
|
169130
|
-
const lines = [...generateRouteMapHelpLines(
|
|
169130
|
+
const lines = [...generateRouteMapHelpLines(routes34, docs, config2)];
|
|
169131
169131
|
const text2 = lines.join("\n");
|
|
169132
169132
|
return text2 + "\n";
|
|
169133
169133
|
},
|
|
@@ -169170,11 +169170,11 @@ function buildRouteMap({
|
|
|
169170
169170
|
},
|
|
169171
169171
|
getRoutingTargetForInput: (input) => {
|
|
169172
169172
|
const routeName = input in activeAliases ? activeAliases[input] : input;
|
|
169173
|
-
return
|
|
169173
|
+
return routes34[routeName];
|
|
169174
169174
|
},
|
|
169175
169175
|
getAllEntries() {
|
|
169176
169176
|
const hiddenRoutes = docs.hideRoute;
|
|
169177
|
-
return Object.entries(
|
|
169177
|
+
return Object.entries(routes34).map(([originalRouteName, target]) => {
|
|
169178
169178
|
return {
|
|
169179
169179
|
name: {
|
|
169180
169180
|
original: originalRouteName,
|
|
@@ -186340,10 +186340,6 @@ var createRemoteServerRepos = (kdb, _h) => ({
|
|
|
186340
186340
|
// src/storage/repositories/executors.ts
|
|
186341
186341
|
var mapExecutor = (row) => ({
|
|
186342
186342
|
...row,
|
|
186343
|
-
// The DB column is nullable (legacy DDL), but every real caller supplies a
|
|
186344
|
-
// group_id (routes/executor-routes.ts requires it; scheduler.ts/
|
|
186345
|
-
// process-routes.ts pass ""), so this never actually surfaces null.
|
|
186346
|
-
group_id: row.group_id ?? "",
|
|
186347
186343
|
executor_type: row.executor_type || "command",
|
|
186348
186344
|
prompt_provider: row.prompt_provider ?? null,
|
|
186349
186345
|
pty: fromDbBool(row.pty),
|
|
@@ -186367,49 +186363,19 @@ var mapRemoteExecutorProcess = (row) => ({
|
|
|
186367
186363
|
machine_id: row.machine_id
|
|
186368
186364
|
});
|
|
186369
186365
|
var createExecutorRepos = (kdb, h) => ({
|
|
186370
|
-
executorGroups: {
|
|
186371
|
-
create: async ({ id, project_id, name: name25, branch }) => {
|
|
186372
|
-
await kdb.insertInto("executor_groups").values({ id, project_id, name: name25, branch }).execute();
|
|
186373
|
-
const row = await kdb.selectFrom("executor_groups").selectAll().where("id", "=", id).executeTakeFirstOrThrow();
|
|
186374
|
-
return row;
|
|
186375
|
-
},
|
|
186376
|
-
getByProjectId: async (projectId) => {
|
|
186377
|
-
return kdb.selectFrom("executor_groups").selectAll().where("project_id", "=", projectId).orderBy("created_at", "asc").execute();
|
|
186378
|
-
},
|
|
186379
|
-
getById: async (id) => {
|
|
186380
|
-
return kdb.selectFrom("executor_groups").selectAll().where("id", "=", id).executeTakeFirst();
|
|
186381
|
-
},
|
|
186382
|
-
getByBranch: async (projectId, branch) => {
|
|
186383
|
-
return kdb.selectFrom("executor_groups").selectAll().where("project_id", "=", projectId).where("branch", "=", branch).executeTakeFirst();
|
|
186384
|
-
},
|
|
186385
|
-
createIfBranchFree: async ({ id, project_id, name: name25, branch }) => {
|
|
186386
|
-
const result = await kdb.insertInto("executor_groups").values({ id, project_id, name: name25, branch }).onConflict((oc) => oc.columns(["project_id", "branch"]).doNothing()).executeTakeFirst();
|
|
186387
|
-
const group2 = await kdb.selectFrom("executor_groups").selectAll().where("project_id", "=", project_id).where("branch", "=", branch).executeTakeFirstOrThrow();
|
|
186388
|
-
return { created: (result?.numInsertedOrUpdatedRows ?? 0n) > 0n, group: group2 };
|
|
186389
|
-
},
|
|
186390
|
-
update: async (id, opts) => {
|
|
186391
|
-
if (opts.name !== void 0) {
|
|
186392
|
-
await kdb.updateTable("executor_groups").set({ name: opts.name }).where("id", "=", id).execute();
|
|
186393
|
-
}
|
|
186394
|
-
return kdb.selectFrom("executor_groups").selectAll().where("id", "=", id).executeTakeFirst();
|
|
186395
|
-
},
|
|
186396
|
-
delete: async (id) => {
|
|
186397
|
-
await kdb.deleteFrom("executor_groups").where("id", "=", id).execute();
|
|
186398
|
-
}
|
|
186399
|
-
},
|
|
186400
186366
|
executors: {
|
|
186401
|
-
create: async ({ id, project_id,
|
|
186367
|
+
create: async ({ id, project_id, workspace_id, name: name25, command, executor_type, prompt_provider, cwd, pty: pty2 }) => {
|
|
186402
186368
|
await kdb.insertInto("executors").values((eb) => ({
|
|
186403
186369
|
id,
|
|
186404
186370
|
project_id,
|
|
186405
|
-
|
|
186371
|
+
workspace_id,
|
|
186406
186372
|
name: name25,
|
|
186407
186373
|
command,
|
|
186408
186374
|
executor_type: executor_type ?? "command",
|
|
186409
186375
|
prompt_provider: prompt_provider ?? null,
|
|
186410
186376
|
cwd: cwd ?? null,
|
|
186411
186377
|
pty: h.toDbBool(pty2 !== false),
|
|
186412
|
-
position: eb.selectFrom("executors").select(sql`coalesce(max(position), -1) + 1`.as("next_position")).where("
|
|
186378
|
+
position: eb.selectFrom("executors").select(sql`coalesce(max(position), -1) + 1`.as("next_position")).where("workspace_id", "=", workspace_id)
|
|
186413
186379
|
})).execute();
|
|
186414
186380
|
const row = await kdb.selectFrom("executors").selectAll().where("id", "=", id).executeTakeFirstOrThrow();
|
|
186415
186381
|
return mapExecutor(row);
|
|
@@ -186418,8 +186384,8 @@ var createExecutorRepos = (kdb, h) => ({
|
|
|
186418
186384
|
const rows = await kdb.selectFrom("executors").selectAll().where("project_id", "=", projectId).orderBy("position", "asc").execute();
|
|
186419
186385
|
return rows.map(mapExecutor);
|
|
186420
186386
|
},
|
|
186421
|
-
|
|
186422
|
-
const rows = await kdb.selectFrom("executors").selectAll().where("
|
|
186387
|
+
getByWorkspaceId: async (workspaceId) => {
|
|
186388
|
+
const rows = await kdb.selectFrom("executors").selectAll().where("workspace_id", "=", workspaceId).orderBy("position", "asc").execute();
|
|
186423
186389
|
return rows.map(mapExecutor);
|
|
186424
186390
|
},
|
|
186425
186391
|
getById: async (id) => {
|
|
@@ -186456,10 +186422,10 @@ var createExecutorRepos = (kdb, h) => ({
|
|
|
186456
186422
|
delete: async (id) => {
|
|
186457
186423
|
await kdb.deleteFrom("executors").where("id", "=", id).execute();
|
|
186458
186424
|
},
|
|
186459
|
-
reorder: async (
|
|
186425
|
+
reorder: async (workspaceId, orderedIds) => {
|
|
186460
186426
|
await kdb.transaction().execute(async (trx) => {
|
|
186461
186427
|
for (let i = 0; i < orderedIds.length; i++) {
|
|
186462
|
-
await trx.updateTable("executors").set({ position: i }).where("id", "=", orderedIds[i]).where("
|
|
186428
|
+
await trx.updateTable("executors").set({ position: i }).where("id", "=", orderedIds[i]).where("workspace_id", "=", workspaceId).execute();
|
|
186463
186429
|
}
|
|
186464
186430
|
});
|
|
186465
186431
|
}
|
|
@@ -203469,6 +203435,14 @@ var createWorkspaceRegistryRepo = (kdb, h) => ({
|
|
|
203469
203435
|
}
|
|
203470
203436
|
};
|
|
203471
203437
|
},
|
|
203438
|
+
getWorkspaceById: async (workspaceId) => {
|
|
203439
|
+
const row = await kdb.selectFrom("workspaces").selectAll().where("id", "=", workspaceId).executeTakeFirst();
|
|
203440
|
+
return row ? mapWorkspace(row) : void 0;
|
|
203441
|
+
},
|
|
203442
|
+
getWorkspaceByProjectBranch: async (projectId, branch) => {
|
|
203443
|
+
const row = await kdb.selectFrom("workspaces").selectAll().where("project_id", "=", projectId).where("branch", "=", branch).executeTakeFirst();
|
|
203444
|
+
return row ? mapWorkspace(row) : void 0;
|
|
203445
|
+
},
|
|
203472
203446
|
markCheckoutDeleted: async (checkoutId) => {
|
|
203473
203447
|
await kdb.transaction().execute(async (trx) => {
|
|
203474
203448
|
const checkout = await trx.selectFrom("workspace_checkouts").select(["workspace_id", "deleted_at"]).where("id", "=", checkoutId).executeTakeFirst();
|
|
@@ -203730,20 +203704,10 @@ var createDatabase = (dbPath) => {
|
|
|
203730
203704
|
CREATE INDEX IF NOT EXISTS idx_project_chat_operations_thread_status_created_id
|
|
203731
203705
|
ON project_chat_operations(thread_id, status, created_at, id);
|
|
203732
203706
|
|
|
203733
|
-
CREATE TABLE IF NOT EXISTS executor_groups (
|
|
203734
|
-
id TEXT PRIMARY KEY,
|
|
203735
|
-
project_id TEXT NOT NULL,
|
|
203736
|
-
name TEXT NOT NULL,
|
|
203737
|
-
branch TEXT NOT NULL DEFAULT '',
|
|
203738
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
203739
|
-
UNIQUE(project_id, branch),
|
|
203740
|
-
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
|
|
203741
|
-
);
|
|
203742
|
-
|
|
203743
203707
|
CREATE TABLE IF NOT EXISTS executors (
|
|
203744
203708
|
id TEXT PRIMARY KEY,
|
|
203745
203709
|
project_id TEXT NOT NULL,
|
|
203746
|
-
|
|
203710
|
+
workspace_id TEXT NOT NULL,
|
|
203747
203711
|
name TEXT NOT NULL,
|
|
203748
203712
|
command TEXT NOT NULL,
|
|
203749
203713
|
executor_type TEXT DEFAULT 'command',
|
|
@@ -203754,7 +203718,7 @@ var createDatabase = (dbPath) => {
|
|
|
203754
203718
|
disabled_targets TEXT DEFAULT '[]',
|
|
203755
203719
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
203756
203720
|
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
|
|
203757
|
-
FOREIGN KEY (
|
|
203721
|
+
FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE
|
|
203758
203722
|
);
|
|
203759
203723
|
|
|
203760
203724
|
CREATE TABLE IF NOT EXISTS executor_processes (
|
|
@@ -204265,31 +204229,6 @@ var createDatabase = (dbPath) => {
|
|
|
204265
204229
|
db.exec("CREATE INDEX IF NOT EXISTS idx_projects_user_id ON projects(user_id)");
|
|
204266
204230
|
}
|
|
204267
204231
|
db.exec("UPDATE projects SET user_id = 'local' WHERE user_id = ''");
|
|
204268
|
-
const hasGroupIdColumn = tableInfo.some((col) => col.name === "group_id");
|
|
204269
|
-
if (!hasGroupIdColumn) {
|
|
204270
|
-
db.exec(`
|
|
204271
|
-
CREATE TABLE IF NOT EXISTS executor_groups (
|
|
204272
|
-
id TEXT PRIMARY KEY,
|
|
204273
|
-
project_id TEXT NOT NULL,
|
|
204274
|
-
name TEXT NOT NULL,
|
|
204275
|
-
branch TEXT NOT NULL DEFAULT '',
|
|
204276
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
204277
|
-
UNIQUE(project_id, branch),
|
|
204278
|
-
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
|
|
204279
|
-
)
|
|
204280
|
-
`);
|
|
204281
|
-
db.exec("ALTER TABLE executors ADD COLUMN group_id TEXT REFERENCES executor_groups(id) ON DELETE CASCADE");
|
|
204282
|
-
const projects = db.prepare("SELECT DISTINCT project_id FROM executors").all();
|
|
204283
|
-
for (const { project_id } of projects) {
|
|
204284
|
-
const groupId = `default-${project_id}`;
|
|
204285
|
-
db.prepare(
|
|
204286
|
-
"INSERT OR IGNORE INTO executor_groups (id, project_id, name, branch) VALUES (@id, @project_id, 'Default', '')"
|
|
204287
|
-
).run({ id: groupId, project_id });
|
|
204288
|
-
db.prepare(
|
|
204289
|
-
"UPDATE executors SET group_id = @group_id WHERE project_id = @project_id AND group_id IS NULL"
|
|
204290
|
-
).run({ group_id: groupId, project_id });
|
|
204291
|
-
}
|
|
204292
|
-
}
|
|
204293
204232
|
const taskTableInfo = db.prepare("PRAGMA table_info(tasks)").all();
|
|
204294
204233
|
const hasAssignedBranchColumn = taskTableInfo.some((col) => col.name === "assigned_branch");
|
|
204295
204234
|
if (!hasAssignedBranchColumn) {
|
|
@@ -205115,6 +205054,79 @@ var createDatabase = (dbPath) => {
|
|
|
205115
205054
|
db.prepare(`DELETE FROM global_settings WHERE key IN (${placeholders})`).run(...USER_LEVEL_KEYS);
|
|
205116
205055
|
});
|
|
205117
205056
|
migrateUserSettings();
|
|
205057
|
+
const executorColsForWorkspace = db.prepare("PRAGMA table_info(executors)").all();
|
|
205058
|
+
if (executorColsForWorkspace.some((col) => col.name === "group_id")) {
|
|
205059
|
+
db.transaction(() => {
|
|
205060
|
+
const ensureWorkspace = db.prepare(
|
|
205061
|
+
`INSERT INTO workspaces (id, project_id, branch, status, error)
|
|
205062
|
+
VALUES (@id, @project_id, @branch, 'archived', NULL)
|
|
205063
|
+
ON CONFLICT(project_id, branch) DO NOTHING`
|
|
205064
|
+
);
|
|
205065
|
+
const groups = db.prepare(`
|
|
205066
|
+
SELECT DISTINCT g.project_id AS project_id, g.branch AS branch
|
|
205067
|
+
FROM executor_groups g
|
|
205068
|
+
JOIN executors e ON e.group_id = g.id
|
|
205069
|
+
JOIN projects p ON p.id = g.project_id
|
|
205070
|
+
`).all();
|
|
205071
|
+
for (const group2 of groups) {
|
|
205072
|
+
ensureWorkspace.run({ id: crypto5.randomUUID(), project_id: group2.project_id, branch: group2.branch });
|
|
205073
|
+
}
|
|
205074
|
+
const orphanProjects = db.prepare(`
|
|
205075
|
+
SELECT DISTINCT e.project_id AS project_id
|
|
205076
|
+
FROM executors e
|
|
205077
|
+
JOIN projects p ON p.id = e.project_id
|
|
205078
|
+
WHERE e.group_id IS NULL
|
|
205079
|
+
OR NOT EXISTS (SELECT 1 FROM executor_groups g WHERE g.id = e.group_id)
|
|
205080
|
+
`).all();
|
|
205081
|
+
for (const { project_id } of orphanProjects) {
|
|
205082
|
+
ensureWorkspace.run({ id: crypto5.randomUUID(), project_id, branch: "" });
|
|
205083
|
+
}
|
|
205084
|
+
db.exec(`
|
|
205085
|
+
CREATE TABLE executors_workspace_new (
|
|
205086
|
+
id TEXT PRIMARY KEY,
|
|
205087
|
+
project_id TEXT NOT NULL,
|
|
205088
|
+
workspace_id TEXT NOT NULL,
|
|
205089
|
+
name TEXT NOT NULL,
|
|
205090
|
+
command TEXT NOT NULL,
|
|
205091
|
+
executor_type TEXT DEFAULT 'command',
|
|
205092
|
+
prompt_provider TEXT,
|
|
205093
|
+
cwd TEXT,
|
|
205094
|
+
pty INTEGER DEFAULT 1,
|
|
205095
|
+
position INTEGER DEFAULT 0,
|
|
205096
|
+
disabled_targets TEXT DEFAULT '[]',
|
|
205097
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
205098
|
+
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
|
|
205099
|
+
FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE
|
|
205100
|
+
);
|
|
205101
|
+
|
|
205102
|
+
INSERT INTO executors_workspace_new
|
|
205103
|
+
(id, project_id, workspace_id, name, command, executor_type,
|
|
205104
|
+
prompt_provider, cwd, pty, position, disabled_targets, created_at)
|
|
205105
|
+
SELECT e.id, e.project_id, w.id, e.name, e.command, e.executor_type,
|
|
205106
|
+
e.prompt_provider, e.cwd, e.pty,
|
|
205107
|
+
ROW_NUMBER() OVER (
|
|
205108
|
+
PARTITION BY w.id ORDER BY e.position, e.created_at, e.id
|
|
205109
|
+
) - 1,
|
|
205110
|
+
e.disabled_targets, e.created_at
|
|
205111
|
+
FROM executors e
|
|
205112
|
+
LEFT JOIN executor_groups g ON g.id = e.group_id
|
|
205113
|
+
JOIN workspaces w
|
|
205114
|
+
ON w.project_id = e.project_id AND w.branch = COALESCE(g.branch, '');
|
|
205115
|
+
`);
|
|
205116
|
+
const dropped = db.prepare(
|
|
205117
|
+
"SELECT COUNT(*) AS n FROM executors WHERE id NOT IN (SELECT id FROM executors_workspace_new)"
|
|
205118
|
+
).get().n;
|
|
205119
|
+
if (dropped > 0) {
|
|
205120
|
+
console.warn(`[storage] executor\u2192workspace migration skipped ${dropped} executor(s) with no surviving project`);
|
|
205121
|
+
}
|
|
205122
|
+
db.exec(`
|
|
205123
|
+
DROP TABLE executors;
|
|
205124
|
+
ALTER TABLE executors_workspace_new RENAME TO executors;
|
|
205125
|
+
DROP TABLE IF EXISTS executor_groups;
|
|
205126
|
+
`);
|
|
205127
|
+
})();
|
|
205128
|
+
}
|
|
205129
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_executors_workspace ON executors(workspace_id, position)");
|
|
205118
205130
|
db.pragma("foreign_keys = ON");
|
|
205119
205131
|
return db;
|
|
205120
205132
|
};
|
|
@@ -206342,6 +206354,92 @@ ${GREEN}Done${info}${RESET}
|
|
|
206342
206354
|
}
|
|
206343
206355
|
return terminals;
|
|
206344
206356
|
}
|
|
206357
|
+
/**
|
|
206358
|
+
* Running processes — executor runs and interactive terminals alike — whose
|
|
206359
|
+
* working directory is `root` or below it. Used to clear a worktree before
|
|
206360
|
+
* it is deleted out from under them.
|
|
206361
|
+
*
|
|
206362
|
+
* Matching is by cwd rather than by branch on purpose: only terminals carry
|
|
206363
|
+
* a `branch`, executor runs are always recorded with `branch: null`, and on
|
|
206364
|
+
* a reverse-connect worker they are path-based with no executor row to join
|
|
206365
|
+
* through. The cwd is the one identity every spawn path records.
|
|
206366
|
+
*/
|
|
206367
|
+
getRunningProcessIdsUnderPath(root) {
|
|
206368
|
+
const resolvedRoot = path5.resolve(root);
|
|
206369
|
+
const ids = [];
|
|
206370
|
+
for (const [id, proc] of this.processes) {
|
|
206371
|
+
const relative = path5.relative(resolvedRoot, path5.resolve(proc.projectPath));
|
|
206372
|
+
const outside = relative === ".." || relative.startsWith(`..${path5.sep}`) || path5.isAbsolute(relative);
|
|
206373
|
+
if (relative !== "" && outside) continue;
|
|
206374
|
+
if (this.isRunning(id)) ids.push(id);
|
|
206375
|
+
}
|
|
206376
|
+
return ids;
|
|
206377
|
+
}
|
|
206378
|
+
/**
|
|
206379
|
+
* True once the tracked process has genuinely exited (or is no longer
|
|
206380
|
+
* tracked at all).
|
|
206381
|
+
*
|
|
206382
|
+
* Deliberately not `!isRunning()`: that helper treats `ChildProcess.killed`
|
|
206383
|
+
* as exited, and Node sets `killed` the moment a signal is *delivered*, so
|
|
206384
|
+
* it would report success while the process is still winding down. Real
|
|
206385
|
+
* exit is only observable through `exitCode`/`signalCode` for a child, or
|
|
206386
|
+
* the "finished" log the PTY exit handler appends.
|
|
206387
|
+
*/
|
|
206388
|
+
hasExited(processId) {
|
|
206389
|
+
const runningProcess = this.processes.get(processId);
|
|
206390
|
+
if (!runningProcess) return true;
|
|
206391
|
+
if (runningProcess.isPty) {
|
|
206392
|
+
return runningProcess.logs[runningProcess.logs.length - 1]?.type === "finished";
|
|
206393
|
+
}
|
|
206394
|
+
const childProcess2 = runningProcess.process;
|
|
206395
|
+
return childProcess2.exitCode !== null || childProcess2.signalCode !== null;
|
|
206396
|
+
}
|
|
206397
|
+
async waitForExit(processId, timeoutMs) {
|
|
206398
|
+
const deadline = Date.now() + timeoutMs;
|
|
206399
|
+
while (!this.hasExited(processId)) {
|
|
206400
|
+
if (Date.now() >= deadline) return false;
|
|
206401
|
+
await new Promise((resolve3) => setTimeout(resolve3, 25));
|
|
206402
|
+
}
|
|
206403
|
+
return true;
|
|
206404
|
+
}
|
|
206405
|
+
signalProcessGroup(processId, signal) {
|
|
206406
|
+
const runningProcess = this.processes.get(processId);
|
|
206407
|
+
if (!runningProcess) return;
|
|
206408
|
+
const pid = runningProcess.isPty ? runningProcess.process.pid : runningProcess.process.pid;
|
|
206409
|
+
if (!pid) return;
|
|
206410
|
+
try {
|
|
206411
|
+
process.kill(-pid, signal);
|
|
206412
|
+
} catch {
|
|
206413
|
+
try {
|
|
206414
|
+
process.kill(pid, signal);
|
|
206415
|
+
} catch {
|
|
206416
|
+
}
|
|
206417
|
+
}
|
|
206418
|
+
}
|
|
206419
|
+
/**
|
|
206420
|
+
* Stop a process and confirm it actually exited, escalating to SIGKILL when
|
|
206421
|
+
* SIGTERM is ignored. Returns false if it is still alive after that.
|
|
206422
|
+
*
|
|
206423
|
+
* `stop()` alone is not enough for a caller that needs the working directory
|
|
206424
|
+
* to be free — deleting a worktree — because it reports only that a signal
|
|
206425
|
+
* was delivered. SIGTERM is asynchronous and can be trapped or ignored, so
|
|
206426
|
+
* the process may still be writing into the tree when `stop()` resolves.
|
|
206427
|
+
*
|
|
206428
|
+
* What this confirms is the exit of the tracked process, and with it
|
|
206429
|
+
* whatever else shared its process group. A grandchild that detached into
|
|
206430
|
+
* its own group or session is not observable here and is not covered.
|
|
206431
|
+
*/
|
|
206432
|
+
async stopAndWait(processId, opts) {
|
|
206433
|
+
await this.stop(processId);
|
|
206434
|
+
if (await this.waitForExit(processId, opts?.termGraceMs ?? 3e3)) return true;
|
|
206435
|
+
console.warn(`[ProcessManager] Process ${processId} ignored SIGTERM, escalating to SIGKILL`);
|
|
206436
|
+
this.signalProcessGroup(processId, "SIGKILL");
|
|
206437
|
+
const exited = await this.waitForExit(processId, opts?.killGraceMs ?? 2e3);
|
|
206438
|
+
if (!exited) {
|
|
206439
|
+
console.error(`[ProcessManager] Process ${processId} survived SIGKILL \u2014 cannot confirm exit`);
|
|
206440
|
+
}
|
|
206441
|
+
return exited;
|
|
206442
|
+
}
|
|
206345
206443
|
/**
|
|
206346
206444
|
* Get all processes for a given executor ID with their status and logs
|
|
206347
206445
|
*/
|
|
@@ -207414,8 +207512,12 @@ function reconcileWorktreeBranches(projectPath, entries, sessionBranches = [], r
|
|
|
207414
207512
|
}
|
|
207415
207513
|
const rootEntry = entries[0];
|
|
207416
207514
|
const rootAnchor = rootEntry ? registryByPath.get(path6.resolve(rootEntry.path)) : void 0;
|
|
207417
|
-
const
|
|
207418
|
-
const
|
|
207515
|
+
const rootExpectedBranch = rootAnchor?.expectedBranch || void 0;
|
|
207516
|
+
const rootDrifted = rootExpectedBranch !== void 0 && rootEntry?.branch != null && rootEntry.branch !== rootExpectedBranch;
|
|
207517
|
+
const root = { branch: null };
|
|
207518
|
+
if (rootExpectedBranch) root.expectedBranch = rootExpectedBranch;
|
|
207519
|
+
if (rootDrifted) root.currentBranch = rootEntry?.branch ?? null;
|
|
207520
|
+
const worktrees = [root];
|
|
207419
207521
|
for (let i = 1; i < entries.length; i++) {
|
|
207420
207522
|
const entry = entries[i];
|
|
207421
207523
|
const anchor = registryByPath.get(path6.resolve(entry.path));
|
|
@@ -207462,6 +207564,15 @@ async function getRegisteredWorktreeBranches(storage, projectId, projectPath) {
|
|
|
207462
207564
|
if (existing.checkout.status === "creating" || existing.checkout.status === "error") {
|
|
207463
207565
|
await storage.workspaceRegistry.setCheckoutStatus(existing.checkout.id, "ready");
|
|
207464
207566
|
}
|
|
207567
|
+
if (index === 0 && existing.checkout.expected_branch === "" && entry.branch) {
|
|
207568
|
+
await storage.workspaceRegistry.registerReadyCheckout({
|
|
207569
|
+
projectId,
|
|
207570
|
+
branch: existing.workspace.branch,
|
|
207571
|
+
targetId: "local",
|
|
207572
|
+
worktreePath: entry.path,
|
|
207573
|
+
expectedBranch: entry.branch
|
|
207574
|
+
});
|
|
207575
|
+
}
|
|
207465
207576
|
continue;
|
|
207466
207577
|
}
|
|
207467
207578
|
if (registeredPaths.has(resolvedPath) || entry.branch === null && index > 0) continue;
|
|
@@ -230148,6 +230259,16 @@ var AgentSessionManager = class {
|
|
|
230148
230259
|
}
|
|
230149
230260
|
return results;
|
|
230150
230261
|
}
|
|
230262
|
+
/**
|
|
230263
|
+
* Ids of the sessions in one workspace that still own a live child process,
|
|
230264
|
+
* whatever their turn status. Deliberately broader than
|
|
230265
|
+
* `getRunningResidentProcesses`, which also demands `status === "running"`:
|
|
230266
|
+
* a resident process idling between turns is exactly the one that would be
|
|
230267
|
+
* orphaned when its worktree is deleted.
|
|
230268
|
+
*/
|
|
230269
|
+
getLiveSessionIdsForBranch(projectId, branch) {
|
|
230270
|
+
return [...this.sessions.values()].filter((session) => session.projectId === projectId && session.branch === branch && this.isProcessAlive(session)).map((session) => session.id);
|
|
230271
|
+
}
|
|
230151
230272
|
/**
|
|
230152
230273
|
* Check if a session is running
|
|
230153
230274
|
*/
|
|
@@ -230160,8 +230281,11 @@ var AgentSessionManager = class {
|
|
|
230160
230281
|
* (like pressing ESC in Claude Code). The session becomes dormant so the
|
|
230161
230282
|
* next user message will spawn a fresh process with full context replay.
|
|
230162
230283
|
* The WebSocket stays alive so the UI remains connected.
|
|
230284
|
+
*
|
|
230285
|
+
* `opts.note` overrides the system entry written into the conversation, for
|
|
230286
|
+
* stops the user did not press Stop for (e.g. the worktree being deleted).
|
|
230163
230287
|
*/
|
|
230164
|
-
async stopSession(sessionId) {
|
|
230288
|
+
async stopSession(sessionId, opts) {
|
|
230165
230289
|
const session = this.sessions.get(sessionId);
|
|
230166
230290
|
if (!session) {
|
|
230167
230291
|
return false;
|
|
@@ -230180,7 +230304,7 @@ var AgentSessionManager = class {
|
|
|
230180
230304
|
session.store.currentAssistantIndex = null;
|
|
230181
230305
|
await this.pushEntry(sessionId, {
|
|
230182
230306
|
type: "system",
|
|
230183
|
-
content: "Session stopped by user.",
|
|
230307
|
+
content: opts?.note ?? "Session stopped by user.",
|
|
230184
230308
|
timestamp: Date.now()
|
|
230185
230309
|
});
|
|
230186
230310
|
await this.endActiveTurn(session, "stopped");
|
|
@@ -230204,6 +230328,41 @@ var AgentSessionManager = class {
|
|
|
230204
230328
|
return false;
|
|
230205
230329
|
}
|
|
230206
230330
|
}
|
|
230331
|
+
/**
|
|
230332
|
+
* Stop a session and confirm its agent process actually exited, escalating
|
|
230333
|
+
* to SIGKILL when SIGTERM is ignored. Returns false if the process is still
|
|
230334
|
+
* alive after that.
|
|
230335
|
+
*
|
|
230336
|
+
* `stopSession` returns as soon as the signal has been sent, which is fine
|
|
230337
|
+
* for the Stop button but not for a caller that is about to delete the
|
|
230338
|
+
* session's working directory: an agent that traps SIGTERM to flush state
|
|
230339
|
+
* would keep writing into a tree that no longer exists.
|
|
230340
|
+
*
|
|
230341
|
+
* Confirms the tracked agent process, and with it whatever else shared its
|
|
230342
|
+
* process group. A grandchild that detached into its own group or session
|
|
230343
|
+
* (an MCP server started with `setsid`, say) is not observable here.
|
|
230344
|
+
*/
|
|
230345
|
+
async stopSessionAndWait(sessionId, opts) {
|
|
230346
|
+
const proc = this.sessions.get(sessionId)?.process ?? null;
|
|
230347
|
+
const stopped = await this.stopSession(sessionId, { note: opts?.note });
|
|
230348
|
+
if (!stopped || !proc) return stopped;
|
|
230349
|
+
if (await this.waitForProcessExit(proc, opts?.termGraceMs ?? 3e3)) return true;
|
|
230350
|
+
console.warn(`[AgentSession] Session ${sessionId} ignored SIGTERM, escalating to SIGKILL`);
|
|
230351
|
+
this.killProcess(proc, "SIGKILL");
|
|
230352
|
+
const exited = await this.waitForProcessExit(proc, opts?.killGraceMs ?? 2e3);
|
|
230353
|
+
if (!exited) {
|
|
230354
|
+
console.error(`[AgentSession] Session ${sessionId} survived SIGKILL \u2014 cannot confirm exit`);
|
|
230355
|
+
}
|
|
230356
|
+
return exited;
|
|
230357
|
+
}
|
|
230358
|
+
async waitForProcessExit(proc, timeoutMs) {
|
|
230359
|
+
const deadline = Date.now() + timeoutMs;
|
|
230360
|
+
while (proc.exitCode === null && proc.signalCode === null) {
|
|
230361
|
+
if (Date.now() >= deadline) return false;
|
|
230362
|
+
await new Promise((resolve3) => setTimeout(resolve3, 25));
|
|
230363
|
+
}
|
|
230364
|
+
return true;
|
|
230365
|
+
}
|
|
230207
230366
|
async hibernateSession(sessionId) {
|
|
230208
230367
|
const session = this.sessions.get(sessionId);
|
|
230209
230368
|
if (!session) return false;
|
|
@@ -232739,12 +232898,12 @@ var ChatSessionManager = class {
|
|
|
232739
232898
|
console.log(`[ChatSession] handleExecutorFinished: executor not found`);
|
|
232740
232899
|
return;
|
|
232741
232900
|
}
|
|
232742
|
-
const
|
|
232743
|
-
if (!
|
|
232744
|
-
console.log(`[ChatSession] handleExecutorFinished:
|
|
232901
|
+
const workspace = await this.storage.workspaceRegistry.getWorkspaceById(executor.workspace_id);
|
|
232902
|
+
if (!workspace) {
|
|
232903
|
+
console.log(`[ChatSession] handleExecutorFinished: workspace not found for executor.workspace_id=${executor.workspace_id}`);
|
|
232745
232904
|
return;
|
|
232746
232905
|
}
|
|
232747
|
-
const branch =
|
|
232906
|
+
const branch = workspace.branch || null;
|
|
232748
232907
|
const key2 = `${event.projectId}:${branch ?? ""}`;
|
|
232749
232908
|
const sessionId = this.sessionIndex.get(key2);
|
|
232750
232909
|
if (!sessionId) {
|
|
@@ -233771,11 +233930,11 @@ var ChatSessionManager = class {
|
|
|
233771
233930
|
tailLines: external_exports.number().min(1).max(100).default(20).describe("Number of recent output lines to include per executor")
|
|
233772
233931
|
}),
|
|
233773
233932
|
execute: async ({ tailLines }) => {
|
|
233774
|
-
const
|
|
233775
|
-
if (!
|
|
233776
|
-
return { executors: [], message: "No
|
|
233933
|
+
const workspace = await storage.workspaceRegistry.getWorkspaceByProjectBranch(projectId, branch ?? "");
|
|
233934
|
+
if (!workspace) {
|
|
233935
|
+
return { executors: [], message: "No workspace found for this branch." };
|
|
233777
233936
|
}
|
|
233778
|
-
const executors = await storage.executors.
|
|
233937
|
+
const executors = await storage.executors.getByWorkspaceId(workspace.id);
|
|
233779
233938
|
const now3 = Date.now();
|
|
233780
233939
|
const results = await Promise.all(executors.map(async (executor) => {
|
|
233781
233940
|
const lastRow = await storage.executorProcesses.getLastByExecutorId(executor.id);
|
|
@@ -233817,11 +233976,11 @@ var ChatSessionManager = class {
|
|
|
233817
233976
|
remote: external_exports.string().optional().describe("Remote server name or ID to run the executor on. If omitted, uses project executor_mode or runs locally.")
|
|
233818
233977
|
}),
|
|
233819
233978
|
execute: async ({ executorName, remote }) => {
|
|
233820
|
-
const
|
|
233821
|
-
if (!
|
|
233822
|
-
return { success: false, message: "No
|
|
233979
|
+
const workspace = await storage.workspaceRegistry.getWorkspaceByProjectBranch(projectId, branch ?? "");
|
|
233980
|
+
if (!workspace) {
|
|
233981
|
+
return { success: false, message: "No workspace found for this branch." };
|
|
233823
233982
|
}
|
|
233824
|
-
const executors = await storage.executors.
|
|
233983
|
+
const executors = await storage.executors.getByWorkspaceId(workspace.id);
|
|
233825
233984
|
const executor = executors.find(
|
|
233826
233985
|
(e) => e.name.toLowerCase() === executorName.toLowerCase()
|
|
233827
233986
|
);
|
|
@@ -233957,11 +234116,11 @@ var ChatSessionManager = class {
|
|
|
233957
234116
|
remote: external_exports.string().optional().describe("Remote server name or ID where the executor is running. If omitted, auto-detects.")
|
|
233958
234117
|
}),
|
|
233959
234118
|
execute: async ({ executorName, remote }) => {
|
|
233960
|
-
const
|
|
233961
|
-
if (!
|
|
233962
|
-
return { success: false, message: "No
|
|
234119
|
+
const workspace = await storage.workspaceRegistry.getWorkspaceByProjectBranch(projectId, branch ?? "");
|
|
234120
|
+
if (!workspace) {
|
|
234121
|
+
return { success: false, message: "No workspace found for this branch." };
|
|
233963
234122
|
}
|
|
233964
|
-
const executors = await storage.executors.
|
|
234123
|
+
const executors = await storage.executors.getByWorkspaceId(workspace.id);
|
|
233965
234124
|
const executor = executors.find(
|
|
233966
234125
|
(e) => e.name.toLowerCase() === executorName.toLowerCase()
|
|
233967
234126
|
);
|
|
@@ -239679,7 +239838,7 @@ var SchedulerService = class {
|
|
|
239679
239838
|
const executor = {
|
|
239680
239839
|
id: `schedule-${task.id}`,
|
|
239681
239840
|
project_id: task.project_id,
|
|
239682
|
-
|
|
239841
|
+
workspace_id: "",
|
|
239683
239842
|
name: task.name,
|
|
239684
239843
|
command: buildRunContent(task),
|
|
239685
239844
|
executor_type: task.run_type,
|
|
@@ -241459,91 +241618,15 @@ var routes5 = async (fastify2) => {
|
|
|
241459
241618
|
};
|
|
241460
241619
|
var project_remote_routes_default = (0, import_fastify_plugin6.default)(routes5, { name: "project-remote-routes" });
|
|
241461
241620
|
|
|
241462
|
-
// src/routes/executor-
|
|
241621
|
+
// src/routes/executor-routes.ts
|
|
241463
241622
|
var import_fastify_plugin7 = __toESM(require_plugin2(), 1);
|
|
241464
241623
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
241465
|
-
var routes6 = async (fastify2) => {
|
|
241466
|
-
fastify2.get(
|
|
241467
|
-
"/api/projects/:projectId/executor-groups",
|
|
241468
|
-
async (req, reply) => {
|
|
241469
|
-
const userId = requireUserFacingUserId(req, reply);
|
|
241470
|
-
if (userId === null) return;
|
|
241471
|
-
const project = await fastify2.storage.projects.getById(req.params.projectId, userId);
|
|
241472
|
-
if (!project) {
|
|
241473
|
-
return reply.code(404).send({ error: "Project not found" });
|
|
241474
|
-
}
|
|
241475
|
-
const groups = await fastify2.storage.executorGroups.getByProjectId(req.params.projectId);
|
|
241476
|
-
return reply.code(200).send({ groups });
|
|
241477
|
-
}
|
|
241478
|
-
);
|
|
241479
|
-
fastify2.get(
|
|
241480
|
-
"/api/projects/:projectId/executor-groups/by-branch",
|
|
241481
|
-
async (req, reply) => {
|
|
241482
|
-
const userId = requireUserFacingUserId(req, reply);
|
|
241483
|
-
if (userId === null) return;
|
|
241484
|
-
const project = await fastify2.storage.projects.getById(req.params.projectId, userId);
|
|
241485
|
-
if (!project) {
|
|
241486
|
-
return reply.code(404).send({ error: "Project not found" });
|
|
241487
|
-
}
|
|
241488
|
-
const branch = req.query.branch ?? "";
|
|
241489
|
-
const group2 = await fastify2.storage.executorGroups.getByBranch(req.params.projectId, branch);
|
|
241490
|
-
if (!group2) {
|
|
241491
|
-
return reply.code(404).send({ error: "Executor group not found for this branch" });
|
|
241492
|
-
}
|
|
241493
|
-
return reply.code(200).send({ group: group2 });
|
|
241494
|
-
}
|
|
241495
|
-
);
|
|
241496
|
-
fastify2.post("/api/projects/:projectId/executor-groups", async (req, reply) => {
|
|
241497
|
-
const userId = requireUserFacingUserId(req, reply);
|
|
241498
|
-
if (userId === null) return;
|
|
241499
|
-
const project = await fastify2.storage.projects.getById(req.params.projectId, userId);
|
|
241500
|
-
if (!project) {
|
|
241501
|
-
return reply.code(404).send({ error: "Project not found" });
|
|
241502
|
-
}
|
|
241503
|
-
const { name: name25, branch } = req.body;
|
|
241504
|
-
const id = randomUUID11();
|
|
241505
|
-
const result = await fastify2.storage.executorGroups.createIfBranchFree({
|
|
241506
|
-
id,
|
|
241507
|
-
project_id: req.params.projectId,
|
|
241508
|
-
name: name25,
|
|
241509
|
-
branch
|
|
241510
|
-
});
|
|
241511
|
-
if (!result.created) {
|
|
241512
|
-
return reply.code(409).send({ error: "An executor group already exists for this branch" });
|
|
241513
|
-
}
|
|
241514
|
-
return reply.code(201).send({ group: result.group });
|
|
241515
|
-
});
|
|
241516
|
-
fastify2.put("/api/executor-groups/:id", async (req, reply) => {
|
|
241517
|
-
const existing = await fastify2.storage.executorGroups.getById(req.params.id);
|
|
241518
|
-
if (!existing) {
|
|
241519
|
-
return reply.code(404).send({ error: "Executor group not found" });
|
|
241520
|
-
}
|
|
241521
|
-
const group2 = await fastify2.storage.executorGroups.update(req.params.id, req.body);
|
|
241522
|
-
return reply.code(200).send({ group: group2 });
|
|
241523
|
-
});
|
|
241524
|
-
fastify2.delete(
|
|
241525
|
-
"/api/executor-groups/:id",
|
|
241526
|
-
async (req, reply) => {
|
|
241527
|
-
const existing = await fastify2.storage.executorGroups.getById(req.params.id);
|
|
241528
|
-
if (!existing) {
|
|
241529
|
-
return reply.code(404).send({ error: "Executor group not found" });
|
|
241530
|
-
}
|
|
241531
|
-
await fastify2.storage.executorGroups.delete(req.params.id);
|
|
241532
|
-
return reply.code(200).send({ success: true });
|
|
241533
|
-
}
|
|
241534
|
-
);
|
|
241535
|
-
};
|
|
241536
|
-
var executor_group_routes_default = (0, import_fastify_plugin7.default)(routes6, { name: "executor-group-routes" });
|
|
241537
|
-
|
|
241538
|
-
// src/routes/executor-routes.ts
|
|
241539
|
-
var import_fastify_plugin8 = __toESM(require_plugin2(), 1);
|
|
241540
|
-
import { randomUUID as randomUUID12 } from "crypto";
|
|
241541
241624
|
function normalizeSqlTimestamp(value) {
|
|
241542
241625
|
if (!value) return null;
|
|
241543
241626
|
if (value.includes("T") && /(Z|[+-]\d{2}:?\d{2})$/.test(value)) return value;
|
|
241544
241627
|
return value.replace(" ", "T") + "Z";
|
|
241545
241628
|
}
|
|
241546
|
-
var
|
|
241629
|
+
var routes6 = async (fastify2) => {
|
|
241547
241630
|
fastify2.get(
|
|
241548
241631
|
"/api/projects/:projectId/executors",
|
|
241549
241632
|
async (req, reply) => {
|
|
@@ -241553,7 +241636,16 @@ var routes7 = async (fastify2) => {
|
|
|
241553
241636
|
if (!project) {
|
|
241554
241637
|
return reply.code(404).send({ error: "Project not found" });
|
|
241555
241638
|
}
|
|
241556
|
-
|
|
241639
|
+
let executors;
|
|
241640
|
+
if (req.query.branch === void 0) {
|
|
241641
|
+
executors = await fastify2.storage.executors.getByProjectId(req.params.projectId);
|
|
241642
|
+
} else {
|
|
241643
|
+
const workspace = await fastify2.storage.workspaceRegistry.getWorkspaceByProjectBranch(
|
|
241644
|
+
req.params.projectId,
|
|
241645
|
+
req.query.branch
|
|
241646
|
+
);
|
|
241647
|
+
executors = workspace ? await fastify2.storage.executors.getByWorkspaceId(workspace.id) : [];
|
|
241648
|
+
}
|
|
241557
241649
|
const executorIds = executors.map((e) => e.id);
|
|
241558
241650
|
const hasLocal = !!project.path;
|
|
241559
241651
|
const hasRemotes = (await fastify2.storage.projectRemotes.getByProject(req.params.projectId)).length > 0;
|
|
@@ -241595,17 +241687,24 @@ var routes7 = async (fastify2) => {
|
|
|
241595
241687
|
if (!project) {
|
|
241596
241688
|
return reply.code(404).send({ error: "Project not found" });
|
|
241597
241689
|
}
|
|
241598
|
-
const { name: name25, command, executor_type, prompt_provider, cwd, pty: pty2,
|
|
241599
|
-
if (
|
|
241600
|
-
return reply.code(400).send({ error: "
|
|
241690
|
+
const { name: name25, command, executor_type, prompt_provider, cwd, pty: pty2, branch } = req.body;
|
|
241691
|
+
if (branch === void 0) {
|
|
241692
|
+
return reply.code(400).send({ error: "branch is required" });
|
|
241693
|
+
}
|
|
241694
|
+
const workspace = await fastify2.storage.workspaceRegistry.getWorkspaceByProjectBranch(
|
|
241695
|
+
req.params.projectId,
|
|
241696
|
+
branch
|
|
241697
|
+
);
|
|
241698
|
+
if (!workspace) {
|
|
241699
|
+
return reply.code(400).send({ error: "No workspace for this branch" });
|
|
241601
241700
|
}
|
|
241602
241701
|
const parsedType2 = executor_type === "prompt" ? "prompt" : "command";
|
|
241603
241702
|
const parsedProvider = prompt_provider === "codex" ? "codex" : "claude";
|
|
241604
|
-
const id =
|
|
241703
|
+
const id = randomUUID11();
|
|
241605
241704
|
const executor = await fastify2.storage.executors.create({
|
|
241606
241705
|
id,
|
|
241607
241706
|
project_id: req.params.projectId,
|
|
241608
|
-
|
|
241707
|
+
workspace_id: workspace.id,
|
|
241609
241708
|
name: name25,
|
|
241610
241709
|
command,
|
|
241611
241710
|
executor_type: parsedType2,
|
|
@@ -241664,31 +241763,38 @@ var routes7 = async (fastify2) => {
|
|
|
241664
241763
|
if (!project) {
|
|
241665
241764
|
return reply.code(404).send({ error: "Project not found" });
|
|
241666
241765
|
}
|
|
241667
|
-
const { orderedIds,
|
|
241766
|
+
const { orderedIds, branch } = req.body;
|
|
241668
241767
|
if (!Array.isArray(orderedIds)) {
|
|
241669
241768
|
return reply.code(400).send({ error: "orderedIds must be an array" });
|
|
241670
241769
|
}
|
|
241671
|
-
if (
|
|
241672
|
-
return reply.code(400).send({ error: "
|
|
241770
|
+
if (branch === void 0) {
|
|
241771
|
+
return reply.code(400).send({ error: "branch is required" });
|
|
241673
241772
|
}
|
|
241674
|
-
const
|
|
241773
|
+
const workspace = await fastify2.storage.workspaceRegistry.getWorkspaceByProjectBranch(
|
|
241774
|
+
req.params.projectId,
|
|
241775
|
+
branch
|
|
241776
|
+
);
|
|
241777
|
+
if (!workspace) {
|
|
241778
|
+
return reply.code(400).send({ error: "No workspace for this branch" });
|
|
241779
|
+
}
|
|
241780
|
+
const existingExecutors = await fastify2.storage.executors.getByWorkspaceId(workspace.id);
|
|
241675
241781
|
const existingIds = new Set(existingExecutors.map((e) => e.id));
|
|
241676
241782
|
for (const id of orderedIds) {
|
|
241677
241783
|
if (!existingIds.has(id)) {
|
|
241678
|
-
return reply.code(400).send({ error: `Executor ${id} not found in
|
|
241784
|
+
return reply.code(400).send({ error: `Executor ${id} not found in workspace` });
|
|
241679
241785
|
}
|
|
241680
241786
|
}
|
|
241681
|
-
await fastify2.storage.executors.reorder(
|
|
241787
|
+
await fastify2.storage.executors.reorder(workspace.id, orderedIds);
|
|
241682
241788
|
return reply.code(200).send({ success: true });
|
|
241683
241789
|
});
|
|
241684
241790
|
};
|
|
241685
|
-
var executor_routes_default = (0,
|
|
241791
|
+
var executor_routes_default = (0, import_fastify_plugin7.default)(routes6, { name: "executor-routes" });
|
|
241686
241792
|
|
|
241687
241793
|
// src/routes/process-routes.ts
|
|
241688
|
-
var
|
|
241794
|
+
var import_fastify_plugin8 = __toESM(require_plugin2(), 1);
|
|
241689
241795
|
import path9 from "path";
|
|
241690
|
-
import { randomUUID as
|
|
241691
|
-
var
|
|
241796
|
+
import { randomUUID as randomUUID12 } from "crypto";
|
|
241797
|
+
var routes7 = async (fastify2) => {
|
|
241692
241798
|
fastify2.post("/api/path/execute", async (req, reply) => {
|
|
241693
241799
|
const userId = requireAuth(req, reply);
|
|
241694
241800
|
if (userId === null) return;
|
|
@@ -241705,9 +241811,9 @@ var routes8 = async (fastify2) => {
|
|
|
241705
241811
|
const resolvedBase = resolveWorktreePath(projectPath, branch ?? null);
|
|
241706
241812
|
const resolvedCwd = cwd ? path9.join(resolvedBase, cwd) : null;
|
|
241707
241813
|
const tempExecutor = {
|
|
241708
|
-
id:
|
|
241814
|
+
id: randomUUID12(),
|
|
241709
241815
|
project_id: project.id,
|
|
241710
|
-
|
|
241816
|
+
workspace_id: "",
|
|
241711
241817
|
name: "remote-command",
|
|
241712
241818
|
command,
|
|
241713
241819
|
executor_type: executor_type === "prompt" ? "prompt" : "command",
|
|
@@ -241737,7 +241843,11 @@ var routes8 = async (fastify2) => {
|
|
|
241737
241843
|
if (!project) {
|
|
241738
241844
|
return reply.code(404).send({ error: "Project not found" });
|
|
241739
241845
|
}
|
|
241740
|
-
const
|
|
241846
|
+
const workspace = await fastify2.storage.workspaceRegistry.getWorkspaceById(executor.workspace_id);
|
|
241847
|
+
if (!workspace) {
|
|
241848
|
+
return reply.code(400).send({ error: "Executor's workspace no longer exists" });
|
|
241849
|
+
}
|
|
241850
|
+
const branch = workspace.branch || null;
|
|
241741
241851
|
let executorMode = req.body?.target || project.executor_mode;
|
|
241742
241852
|
let useRemoteExecutor = executorMode !== "local";
|
|
241743
241853
|
if (useRemoteExecutor && executorMode === "remote") {
|
|
@@ -241900,10 +242010,10 @@ var routes8 = async (fastify2) => {
|
|
|
241900
242010
|
return reply.code(200).send({ processes });
|
|
241901
242011
|
});
|
|
241902
242012
|
};
|
|
241903
|
-
var process_routes_default = (0,
|
|
242013
|
+
var process_routes_default = (0, import_fastify_plugin8.default)(routes7, { name: "process-routes" });
|
|
241904
242014
|
|
|
241905
242015
|
// src/routes/worktree-routes.ts
|
|
241906
|
-
var
|
|
242016
|
+
var import_fastify_plugin9 = __toESM(require_plugin2(), 1);
|
|
241907
242017
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
241908
242018
|
|
|
241909
242019
|
// src/utils/path-project.ts
|
|
@@ -241949,7 +242059,37 @@ async function syncRemoteWorktreeList(fastify2, projectId, remote, data) {
|
|
|
241949
242059
|
worktrees
|
|
241950
242060
|
});
|
|
241951
242061
|
}
|
|
241952
|
-
var
|
|
242062
|
+
var WorktreeBusyError = class extends Error {
|
|
242063
|
+
};
|
|
242064
|
+
async function stopWorkspaceActivity(fastify2, opts) {
|
|
242065
|
+
const sessionIds = [...new Set(
|
|
242066
|
+
opts.projectIds.filter((id) => Boolean(id)).flatMap((id) => fastify2.agentSessionManager.getLiveSessionIdsForBranch(id, opts.branch))
|
|
242067
|
+
)];
|
|
242068
|
+
const processIds = fastify2.processManager.getRunningProcessIdsUnderPath(opts.worktreePath);
|
|
242069
|
+
if (sessionIds.length === 0 && processIds.length === 0) return;
|
|
242070
|
+
const survivors = [];
|
|
242071
|
+
const confirm = async (label, stop) => {
|
|
242072
|
+
try {
|
|
242073
|
+
if (!await stop()) survivors.push(label);
|
|
242074
|
+
} catch (error48) {
|
|
242075
|
+
console.error(`[worktree] Failed to stop ${label} before delete:`, error48);
|
|
242076
|
+
survivors.push(label);
|
|
242077
|
+
}
|
|
242078
|
+
};
|
|
242079
|
+
await Promise.all(sessionIds.map((sessionId) => confirm(`session ${sessionId}`, () => fastify2.agentSessionManager.stopSessionAndWait(sessionId, {
|
|
242080
|
+
note: "Session stopped: its worktree is being deleted."
|
|
242081
|
+
}))));
|
|
242082
|
+
await Promise.all(processIds.map((processId) => confirm(`process ${processId}`, () => fastify2.processManager.stopAndWait(processId))));
|
|
242083
|
+
if (survivors.length > 0) {
|
|
242084
|
+
throw new WorktreeBusyError(
|
|
242085
|
+
`Worktree still has running work that could not be stopped (${survivors.join(", ")}). Nothing was deleted; retry in a moment.`
|
|
242086
|
+
);
|
|
242087
|
+
}
|
|
242088
|
+
console.log(
|
|
242089
|
+
`[worktree] Stopped ${sessionIds.length} session(s) and ${processIds.length} process(es) in ${opts.worktreePath}`
|
|
242090
|
+
);
|
|
242091
|
+
}
|
|
242092
|
+
var routes8 = async (fastify2) => {
|
|
241953
242093
|
fastify2.get("/api/path/branches", async (req, reply) => {
|
|
241954
242094
|
const projectPath = req.query.path;
|
|
241955
242095
|
if (!projectPath) {
|
|
@@ -242083,6 +242223,11 @@ var routes9 = async (fastify2) => {
|
|
|
242083
242223
|
}
|
|
242084
242224
|
} catch {
|
|
242085
242225
|
}
|
|
242226
|
+
await stopWorkspaceActivity(fastify2, {
|
|
242227
|
+
projectIds: [pathProject?.id, `path:${projectPath}`],
|
|
242228
|
+
branch,
|
|
242229
|
+
worktreePath: worktreeAbsPath
|
|
242230
|
+
});
|
|
242086
242231
|
let branchToDelete = null;
|
|
242087
242232
|
try {
|
|
242088
242233
|
const entries = parseGitWorktreeList(projectPath);
|
|
@@ -242113,9 +242258,11 @@ var routes9 = async (fastify2) => {
|
|
|
242113
242258
|
return reply.code(200).send({ success: true });
|
|
242114
242259
|
} catch (error48) {
|
|
242115
242260
|
const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
|
|
242261
|
+
const busy = error48 instanceof WorktreeBusyError;
|
|
242116
242262
|
if (registered && !worktreeRemoved) {
|
|
242117
|
-
await fastify2.storage.workspaceRegistry.setCheckoutStatus(registered.checkout.id, "error", errorMessage).catch((registryError) => console.error("[worktree] Failed to record delete error:", registryError));
|
|
242263
|
+
await fastify2.storage.workspaceRegistry.setCheckoutStatus(registered.checkout.id, busy ? "ready" : "error", busy ? null : errorMessage).catch((registryError) => console.error("[worktree] Failed to record delete error:", registryError));
|
|
242118
242264
|
}
|
|
242265
|
+
if (busy) return reply.code(409).send({ error: errorMessage });
|
|
242119
242266
|
return reply.code(500).send({ error: `Failed to delete worktree: ${errorMessage}` });
|
|
242120
242267
|
}
|
|
242121
242268
|
});
|
|
@@ -242325,6 +242472,11 @@ var routes9 = async (fastify2) => {
|
|
|
242325
242472
|
} catch (err) {
|
|
242326
242473
|
if (err instanceof Error && err.message.includes("uncommitted changes")) throw err;
|
|
242327
242474
|
}
|
|
242475
|
+
await stopWorkspaceActivity(fastify2, {
|
|
242476
|
+
projectIds: [project.id],
|
|
242477
|
+
branch,
|
|
242478
|
+
worktreePath: worktreeAbsPath
|
|
242479
|
+
});
|
|
242328
242480
|
let branchToDelete = null;
|
|
242329
242481
|
try {
|
|
242330
242482
|
const entries = parseGitWorktreeList(project.path);
|
|
@@ -242355,7 +242507,7 @@ var routes9 = async (fastify2) => {
|
|
|
242355
242507
|
} catch (error48) {
|
|
242356
242508
|
if (registered && !worktreeRemoved) {
|
|
242357
242509
|
const message = error48 instanceof Error ? error48.message : "Local deletion failed";
|
|
242358
|
-
const status = message.includes("uncommitted changes") ? "ready" : "error";
|
|
242510
|
+
const status = message.includes("uncommitted changes") || error48 instanceof WorktreeBusyError ? "ready" : "error";
|
|
242359
242511
|
await fastify2.storage.workspaceRegistry.setCheckoutStatus(registered.checkout.id, status, status === "error" ? message : null).catch((registryError) => console.error("[worktree] Failed to record local delete error:", registryError));
|
|
242360
242512
|
}
|
|
242361
242513
|
throw error48;
|
|
@@ -242367,7 +242519,7 @@ var routes9 = async (fastify2) => {
|
|
|
242367
242519
|
return reply.code(200).send({ success: true });
|
|
242368
242520
|
} catch (error48) {
|
|
242369
242521
|
const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
|
|
242370
|
-
if (errorMessage.includes("uncommitted changes")) {
|
|
242522
|
+
if (errorMessage.includes("uncommitted changes") || error48 instanceof WorktreeBusyError) {
|
|
242371
242523
|
return reply.code(409).send({ error: errorMessage });
|
|
242372
242524
|
}
|
|
242373
242525
|
return reply.code(500).send({ error: `Failed to delete worktree: ${errorMessage}` });
|
|
@@ -242630,10 +242782,10 @@ var routes9 = async (fastify2) => {
|
|
|
242630
242782
|
});
|
|
242631
242783
|
});
|
|
242632
242784
|
};
|
|
242633
|
-
var worktree_routes_default = (0,
|
|
242785
|
+
var worktree_routes_default = (0, import_fastify_plugin9.default)(routes8, { name: "worktree-routes" });
|
|
242634
242786
|
|
|
242635
242787
|
// src/routes/diff-routes.ts
|
|
242636
|
-
var
|
|
242788
|
+
var import_fastify_plugin10 = __toESM(require_plugin2(), 1);
|
|
242637
242789
|
import path10 from "path";
|
|
242638
242790
|
import { readFileSync as readFileSync4 } from "fs";
|
|
242639
242791
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
@@ -242941,7 +243093,7 @@ async function getUntrackedFiles(cwd) {
|
|
|
242941
243093
|
}
|
|
242942
243094
|
return files;
|
|
242943
243095
|
}
|
|
242944
|
-
var
|
|
243096
|
+
var routes9 = async (fastify2) => {
|
|
242945
243097
|
fastify2.get("/api/path/diff", async (req, reply) => {
|
|
242946
243098
|
const projectPath = req.query.path;
|
|
242947
243099
|
if (!projectPath) {
|
|
@@ -243132,10 +243284,10 @@ var routes10 = async (fastify2) => {
|
|
|
243132
243284
|
}
|
|
243133
243285
|
});
|
|
243134
243286
|
};
|
|
243135
|
-
var diff_routes_default = (0,
|
|
243287
|
+
var diff_routes_default = (0, import_fastify_plugin10.default)(routes9, { name: "diff-routes" });
|
|
243136
243288
|
|
|
243137
243289
|
// src/routes/file-routes.ts
|
|
243138
|
-
var
|
|
243290
|
+
var import_fastify_plugin11 = __toESM(require_plugin2(), 1);
|
|
243139
243291
|
import path11 from "path";
|
|
243140
243292
|
import fs2 from "fs/promises";
|
|
243141
243293
|
import { createReadStream, constants as fsConstants } from "fs";
|
|
@@ -243358,7 +243510,7 @@ async function searchSymbol(basePath33, symbol26) {
|
|
|
243358
243510
|
}
|
|
243359
243511
|
return { hits, truncated };
|
|
243360
243512
|
}
|
|
243361
|
-
var
|
|
243513
|
+
var routes10 = async (fastify2) => {
|
|
243362
243514
|
fastify2.get("/api/path/browse", async (req, reply) => {
|
|
243363
243515
|
const projectPath = req.query.path;
|
|
243364
243516
|
if (!projectPath) {
|
|
@@ -243919,17 +244071,17 @@ var routes11 = async (fastify2) => {
|
|
|
243919
244071
|
}
|
|
243920
244072
|
});
|
|
243921
244073
|
};
|
|
243922
|
-
var file_routes_default = (0,
|
|
244074
|
+
var file_routes_default = (0, import_fastify_plugin11.default)(routes10, { name: "file-routes" });
|
|
243923
244075
|
|
|
243924
244076
|
// src/routes/agent-session-routes.ts
|
|
243925
|
-
var
|
|
244077
|
+
var import_fastify_plugin12 = __toESM(require_plugin2(), 1);
|
|
243926
244078
|
|
|
243927
244079
|
// src/utils/paste-file.ts
|
|
243928
244080
|
import { chmod, mkdir as mkdir4, open } from "node:fs/promises";
|
|
243929
244081
|
import { constants as fsConstants2 } from "node:fs";
|
|
243930
244082
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
243931
244083
|
import path12 from "node:path";
|
|
243932
|
-
import { randomUUID as
|
|
244084
|
+
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
243933
244085
|
var PASTE_DIR = path12.join(tmpdir2(), "vibedeckx-pastes");
|
|
243934
244086
|
var DIR_MODE = 448;
|
|
243935
244087
|
var FILE_MODE = 384;
|
|
@@ -243937,7 +244089,7 @@ var FILE_FLAGS = fsConstants2.O_WRONLY | fsConstants2.O_CREAT | fsConstants2.O_E
|
|
|
243937
244089
|
async function writePasteToTempFile(content) {
|
|
243938
244090
|
await mkdir4(PASTE_DIR, { recursive: true, mode: DIR_MODE });
|
|
243939
244091
|
await chmod(PASTE_DIR, DIR_MODE);
|
|
243940
|
-
const filePath = path12.join(PASTE_DIR, `${
|
|
244092
|
+
const filePath = path12.join(PASTE_DIR, `${randomUUID13()}.txt`);
|
|
243941
244093
|
const handle = await open(filePath, FILE_FLAGS, FILE_MODE);
|
|
243942
244094
|
try {
|
|
243943
244095
|
await handle.writeFile(content, "utf8");
|
|
@@ -244295,7 +244447,7 @@ async function distillConversation(storage, userId, messages, conversation, main
|
|
|
244295
244447
|
}
|
|
244296
244448
|
|
|
244297
244449
|
// src/routes/agent-session-routes.ts
|
|
244298
|
-
import { createHash as createHash6, randomUUID as
|
|
244450
|
+
import { createHash as createHash6, randomUUID as randomUUID14 } from "crypto";
|
|
244299
244451
|
|
|
244300
244452
|
// src/protocol/model-suggestions.ts
|
|
244301
244453
|
var MODEL_SUGGESTIONS = {
|
|
@@ -244320,8 +244472,8 @@ function messageTextLength(content) {
|
|
|
244320
244472
|
}
|
|
244321
244473
|
return n;
|
|
244322
244474
|
}
|
|
244323
|
-
var
|
|
244324
|
-
const instructionReceiverToken =
|
|
244475
|
+
var routes11 = async (fastify2) => {
|
|
244476
|
+
const instructionReceiverToken = randomUUID14();
|
|
244325
244477
|
const instructionDeliveryLocks = /* @__PURE__ */ new Map();
|
|
244326
244478
|
async function serializeInstructionDelivery(key2, effect) {
|
|
244327
244479
|
const previous = instructionDeliveryLocks.get(key2) ?? Promise.resolve();
|
|
@@ -244976,7 +245128,7 @@ var routes12 = async (fastify2) => {
|
|
|
244976
245128
|
return reply.code(400).send({ error: "Project has no local path" });
|
|
244977
245129
|
}
|
|
244978
245130
|
try {
|
|
244979
|
-
const preSessionId =
|
|
245131
|
+
const preSessionId = randomUUID14();
|
|
244980
245132
|
const crossRemoteMcp = await mintCrossRemoteMcpConfig(
|
|
244981
245133
|
{ storage: fastify2.storage },
|
|
244982
245134
|
{ userId, sessionId: preSessionId, sourceRemoteServerId: null }
|
|
@@ -245532,7 +245684,7 @@ var routes12 = async (fastify2) => {
|
|
|
245532
245684
|
messages
|
|
245533
245685
|
});
|
|
245534
245686
|
}
|
|
245535
|
-
const preSessionId =
|
|
245687
|
+
const preSessionId = randomUUID14();
|
|
245536
245688
|
const crossRemoteMcp = await mintCrossRemoteMcpConfig(
|
|
245537
245689
|
{ storage: fastify2.storage },
|
|
245538
245690
|
{ userId, sessionId: preSessionId, sourceRemoteServerId: null }
|
|
@@ -245792,10 +245944,10 @@ var routes12 = async (fastify2) => {
|
|
|
245792
245944
|
return reply.code(200).send({ success: true, favorited });
|
|
245793
245945
|
});
|
|
245794
245946
|
};
|
|
245795
|
-
var agent_session_routes_default = (0,
|
|
245947
|
+
var agent_session_routes_default = (0, import_fastify_plugin12.default)(routes11, { name: "agent-session-routes" });
|
|
245796
245948
|
|
|
245797
245949
|
// src/routes/branch-activity-routes.ts
|
|
245798
|
-
var
|
|
245950
|
+
var import_fastify_plugin13 = __toESM(require_plugin2(), 1);
|
|
245799
245951
|
function toResponse(map2) {
|
|
245800
245952
|
return {
|
|
245801
245953
|
branches: Array.from(map2.entries()).map(([branch, state]) => ({
|
|
@@ -245810,7 +245962,7 @@ function fromResponse(resp) {
|
|
|
245810
245962
|
resp.branches.map((b2) => [b2.branch ?? "", { activity: b2.activity, since: b2.since }])
|
|
245811
245963
|
);
|
|
245812
245964
|
}
|
|
245813
|
-
var
|
|
245965
|
+
var routes12 = async (fastify2) => {
|
|
245814
245966
|
function proxyAuto(remoteServerId, method, apiPath, body) {
|
|
245815
245967
|
return proxyToRemoteAuto(remoteServerId, method, apiPath, body, {
|
|
245816
245968
|
reverseConnectManager: fastify2.reverseConnectManager
|
|
@@ -245875,10 +246027,10 @@ var routes13 = async (fastify2) => {
|
|
|
245875
246027
|
}
|
|
245876
246028
|
);
|
|
245877
246029
|
};
|
|
245878
|
-
var branch_activity_routes_default = (0,
|
|
246030
|
+
var branch_activity_routes_default = (0, import_fastify_plugin13.default)(routes12, { name: "branch-activity-routes" });
|
|
245879
246031
|
|
|
245880
246032
|
// src/routes/merge-status-routes.ts
|
|
245881
|
-
var
|
|
246033
|
+
var import_fastify_plugin14 = __toESM(require_plugin2(), 1);
|
|
245882
246034
|
function resolveTargets(comparisons, storedTargets) {
|
|
245883
246035
|
const sources = [];
|
|
245884
246036
|
const effective = comparisons.map((comparison) => {
|
|
@@ -245992,7 +246144,7 @@ function sendComputed(reply, repoPath, comparisons, repository) {
|
|
|
245992
246144
|
return reply.code(statusCode).send({ error: message });
|
|
245993
246145
|
}
|
|
245994
246146
|
}
|
|
245995
|
-
var
|
|
246147
|
+
var routes13 = async (fastify2) => {
|
|
245996
246148
|
fastify2.post(
|
|
245997
246149
|
"/api/path/branches/merge-status",
|
|
245998
246150
|
async (req, reply) => {
|
|
@@ -246114,11 +246266,11 @@ var routes14 = async (fastify2) => {
|
|
|
246114
246266
|
}
|
|
246115
246267
|
);
|
|
246116
246268
|
};
|
|
246117
|
-
var merge_status_routes_default = (0,
|
|
246269
|
+
var merge_status_routes_default = (0, import_fastify_plugin14.default)(routes13, { name: "merge-status-routes" });
|
|
246118
246270
|
|
|
246119
246271
|
// src/routes/chat-session-routes.ts
|
|
246120
|
-
var
|
|
246121
|
-
var
|
|
246272
|
+
var import_fastify_plugin15 = __toESM(require_plugin2(), 1);
|
|
246273
|
+
var routes14 = async (fastify2) => {
|
|
246122
246274
|
const getAuthorizedSession = (req, reply, sessionId) => {
|
|
246123
246275
|
const authResult = requireUserFacingUserId(req, reply);
|
|
246124
246276
|
if (authResult === null) return null;
|
|
@@ -246223,11 +246375,11 @@ var routes15 = async (fastify2) => {
|
|
|
246223
246375
|
return reply.send({ ok: true });
|
|
246224
246376
|
});
|
|
246225
246377
|
};
|
|
246226
|
-
var chat_session_routes_default = (0,
|
|
246378
|
+
var chat_session_routes_default = (0, import_fastify_plugin15.default)(routes14, { name: "chat-session-routes" });
|
|
246227
246379
|
|
|
246228
246380
|
// src/routes/project-chat-routes.ts
|
|
246229
|
-
var
|
|
246230
|
-
import { createHash as createHash7, randomUUID as
|
|
246381
|
+
var import_fastify_plugin16 = __toESM(require_plugin2(), 1);
|
|
246382
|
+
import { createHash as createHash7, randomUUID as randomUUID15 } from "crypto";
|
|
246231
246383
|
var MAX_TITLE_LENGTH = 200;
|
|
246232
246384
|
var MAX_MESSAGE_LENGTH = 1e5;
|
|
246233
246385
|
var THREAD_PAGE_LIMIT = 50;
|
|
@@ -246339,7 +246491,7 @@ function parseWorkspaceSelectionBody(body) {
|
|
|
246339
246491
|
if (!requestId || requestId.length > MAX_TOOL_SELECTOR_ID || !workspaceId || workspaceId.length > MAX_TOOL_SELECTOR_ID) return null;
|
|
246340
246492
|
return { requestId, workspaceId };
|
|
246341
246493
|
}
|
|
246342
|
-
var
|
|
246494
|
+
var routes15 = async (fastify2) => {
|
|
246343
246495
|
const getOwnedThread = async (req, reply, threadId) => {
|
|
246344
246496
|
const authResult = requireAuth(req, reply);
|
|
246345
246497
|
if (authResult === null) return null;
|
|
@@ -246395,20 +246547,20 @@ var routes16 = async (fastify2) => {
|
|
|
246395
246547
|
if (!project) return reply.code(404).send({ error: "Project not found" });
|
|
246396
246548
|
const body = parseCreateBody(req.body);
|
|
246397
246549
|
if (!body) return reply.code(400).send({ error: "Body must contain only an optional non-empty message" });
|
|
246398
|
-
const createRequestId = body.createRequestId ??
|
|
246550
|
+
const createRequestId = body.createRequestId ?? randomUUID15();
|
|
246399
246551
|
const createPayloadHash = createHash7("sha256").update(JSON.stringify({ message: body.message ?? null })).digest("hex");
|
|
246400
246552
|
let accepted;
|
|
246401
246553
|
try {
|
|
246402
246554
|
accepted = await fastify2.storage.projectChatThreads.createIdempotent({
|
|
246403
|
-
id:
|
|
246555
|
+
id: randomUUID15(),
|
|
246404
246556
|
project_id: projectId,
|
|
246405
246557
|
user_id: userId,
|
|
246406
246558
|
title: null,
|
|
246407
246559
|
create_request_id: createRequestId,
|
|
246408
246560
|
create_payload_hash: createPayloadHash,
|
|
246409
246561
|
...body.message !== void 0 ? { initialTurn: {
|
|
246410
|
-
messageId:
|
|
246411
|
-
workItemId:
|
|
246562
|
+
messageId: randomUUID15(),
|
|
246563
|
+
workItemId: randomUUID15(),
|
|
246412
246564
|
content: body.message
|
|
246413
246565
|
} } : {}
|
|
246414
246566
|
});
|
|
@@ -246558,10 +246710,10 @@ var routes16 = async (fastify2) => {
|
|
|
246558
246710
|
}
|
|
246559
246711
|
});
|
|
246560
246712
|
};
|
|
246561
|
-
var project_chat_routes_default = (0,
|
|
246713
|
+
var project_chat_routes_default = (0, import_fastify_plugin16.default)(routes15, { name: "project-chat-routes" });
|
|
246562
246714
|
|
|
246563
246715
|
// src/routes/project-activity-routes.ts
|
|
246564
|
-
var
|
|
246716
|
+
var import_fastify_plugin17 = __toESM(require_plugin2(), 1);
|
|
246565
246717
|
|
|
246566
246718
|
// src/project-activity.ts
|
|
246567
246719
|
var RECENT_THREAD_LIMIT = 5;
|
|
@@ -246653,7 +246805,7 @@ async function getProjectActivity(storage, projectId, userId) {
|
|
|
246653
246805
|
}
|
|
246654
246806
|
|
|
246655
246807
|
// src/routes/project-activity-routes.ts
|
|
246656
|
-
var
|
|
246808
|
+
var routes16 = async (fastify2) => {
|
|
246657
246809
|
fastify2.get(
|
|
246658
246810
|
"/api/projects/:projectId/activity",
|
|
246659
246811
|
async (req, reply) => {
|
|
@@ -246669,12 +246821,12 @@ var routes17 = async (fastify2) => {
|
|
|
246669
246821
|
}
|
|
246670
246822
|
);
|
|
246671
246823
|
};
|
|
246672
|
-
var project_activity_routes_default = (0,
|
|
246824
|
+
var project_activity_routes_default = (0, import_fastify_plugin17.default)(routes16);
|
|
246673
246825
|
|
|
246674
246826
|
// src/routes/task-routes.ts
|
|
246675
|
-
var
|
|
246676
|
-
import { randomUUID as
|
|
246677
|
-
var
|
|
246827
|
+
var import_fastify_plugin18 = __toESM(require_plugin2(), 1);
|
|
246828
|
+
import { randomUUID as randomUUID16 } from "crypto";
|
|
246829
|
+
var routes17 = async (fastify2) => {
|
|
246678
246830
|
fastify2.get(
|
|
246679
246831
|
"/api/projects/:projectId/tasks",
|
|
246680
246832
|
async (req, reply) => {
|
|
@@ -246737,7 +246889,7 @@ Description: ${description}`,
|
|
|
246737
246889
|
title = description.length > 50 ? description.slice(0, 50) + "..." : description;
|
|
246738
246890
|
}
|
|
246739
246891
|
}
|
|
246740
|
-
const id =
|
|
246892
|
+
const id = randomUUID16();
|
|
246741
246893
|
const task = await fastify2.storage.tasks.create({
|
|
246742
246894
|
id,
|
|
246743
246895
|
project_id: req.params.projectId,
|
|
@@ -246834,12 +246986,12 @@ Description: ${description}`,
|
|
|
246834
246986
|
return reply.code(200).send({ success: true });
|
|
246835
246987
|
});
|
|
246836
246988
|
};
|
|
246837
|
-
var task_routes_default = (0,
|
|
246989
|
+
var task_routes_default = (0, import_fastify_plugin18.default)(routes17, { name: "task-routes" });
|
|
246838
246990
|
|
|
246839
246991
|
// src/routes/rule-routes.ts
|
|
246840
|
-
var
|
|
246841
|
-
import { randomUUID as
|
|
246842
|
-
var
|
|
246992
|
+
var import_fastify_plugin19 = __toESM(require_plugin2(), 1);
|
|
246993
|
+
import { randomUUID as randomUUID17 } from "crypto";
|
|
246994
|
+
var routes18 = async (fastify2) => {
|
|
246843
246995
|
fastify2.get(
|
|
246844
246996
|
"/api/projects/:projectId/rules",
|
|
246845
246997
|
async (req, reply) => {
|
|
@@ -246865,7 +247017,7 @@ var routes19 = async (fastify2) => {
|
|
|
246865
247017
|
if (!name25 || !content) {
|
|
246866
247018
|
return reply.code(400).send({ error: "name and content are required" });
|
|
246867
247019
|
}
|
|
246868
|
-
const id =
|
|
247020
|
+
const id = randomUUID17();
|
|
246869
247021
|
const rule = await fastify2.storage.rules.create({
|
|
246870
247022
|
id,
|
|
246871
247023
|
project_id: req.params.projectId,
|
|
@@ -246925,12 +247077,12 @@ var routes19 = async (fastify2) => {
|
|
|
246925
247077
|
return reply.code(200).send({ success: true });
|
|
246926
247078
|
});
|
|
246927
247079
|
};
|
|
246928
|
-
var rule_routes_default = (0,
|
|
247080
|
+
var rule_routes_default = (0, import_fastify_plugin19.default)(routes18, { name: "rule-routes" });
|
|
246929
247081
|
|
|
246930
247082
|
// src/routes/command-routes.ts
|
|
246931
|
-
var
|
|
246932
|
-
import { randomUUID as
|
|
246933
|
-
var
|
|
247083
|
+
var import_fastify_plugin20 = __toESM(require_plugin2(), 1);
|
|
247084
|
+
import { randomUUID as randomUUID18 } from "crypto";
|
|
247085
|
+
var routes19 = async (fastify2) => {
|
|
246934
247086
|
fastify2.get(
|
|
246935
247087
|
"/api/projects/:projectId/commands",
|
|
246936
247088
|
async (req, reply) => {
|
|
@@ -246956,7 +247108,7 @@ var routes20 = async (fastify2) => {
|
|
|
246956
247108
|
if (!name25 || !content) {
|
|
246957
247109
|
return reply.code(400).send({ error: "name and content are required" });
|
|
246958
247110
|
}
|
|
246959
|
-
const id =
|
|
247111
|
+
const id = randomUUID18();
|
|
246960
247112
|
const command = await fastify2.storage.commands.create({
|
|
246961
247113
|
id,
|
|
246962
247114
|
project_id: req.params.projectId,
|
|
@@ -246999,10 +247151,10 @@ var routes20 = async (fastify2) => {
|
|
|
246999
247151
|
return reply.code(200).send({ success: true });
|
|
247000
247152
|
});
|
|
247001
247153
|
};
|
|
247002
|
-
var command_routes_default = (0,
|
|
247154
|
+
var command_routes_default = (0, import_fastify_plugin20.default)(routes19, { name: "command-routes" });
|
|
247003
247155
|
|
|
247004
247156
|
// src/routes/workflow-run-routes.ts
|
|
247005
|
-
var
|
|
247157
|
+
var import_fastify_plugin21 = __toESM(require_plugin2(), 1);
|
|
247006
247158
|
function parseReviewerAgentType(raw) {
|
|
247007
247159
|
if (raw === void 0) return void 0;
|
|
247008
247160
|
return typeof raw === "string" && REVIEWER_AGENT_TYPES.has(raw) ? raw : null;
|
|
@@ -247036,7 +247188,7 @@ function errStatus(err) {
|
|
|
247036
247188
|
return 500;
|
|
247037
247189
|
}
|
|
247038
247190
|
}
|
|
247039
|
-
async function
|
|
247191
|
+
async function routes20(fastify2) {
|
|
247040
247192
|
const durableReviewFlights = /* @__PURE__ */ new Map();
|
|
247041
247193
|
const projectLocalSession = async (session) => {
|
|
247042
247194
|
const reader = fastify2.storage.agentSessions.getActivityById;
|
|
@@ -247603,10 +247755,10 @@ async function routes21(fastify2) {
|
|
|
247603
247755
|
return reply.send({ runs });
|
|
247604
247756
|
});
|
|
247605
247757
|
}
|
|
247606
|
-
var workflow_run_routes_default = (0,
|
|
247758
|
+
var workflow_run_routes_default = (0, import_fastify_plugin21.default)(routes20, { name: "workflow-run-routes" });
|
|
247607
247759
|
|
|
247608
247760
|
// src/routes/settings-routes.ts
|
|
247609
|
-
var
|
|
247761
|
+
var import_fastify_plugin22 = __toESM(require_plugin2(), 1);
|
|
247610
247762
|
var SettingsValidationError = class extends Error {
|
|
247611
247763
|
};
|
|
247612
247764
|
var DEFAULT_PROXY_CONFIG = { type: "none", host: "", port: 0 };
|
|
@@ -247670,7 +247822,7 @@ function requireSettingsUser(req, reply) {
|
|
|
247670
247822
|
if (auth === null) return null;
|
|
247671
247823
|
return resolveUserId(auth);
|
|
247672
247824
|
}
|
|
247673
|
-
var
|
|
247825
|
+
var routes21 = async (fastify2) => {
|
|
247674
247826
|
fastify2.get("/api/settings/agent-processes", async (req, reply) => {
|
|
247675
247827
|
if (requireAuth(req, reply) === null) return;
|
|
247676
247828
|
const saved = await fastify2.storage.settings.get("agentProcesses");
|
|
@@ -247944,11 +248096,11 @@ var routes22 = async (fastify2) => {
|
|
|
247944
248096
|
return reply.code(200).send(updated);
|
|
247945
248097
|
});
|
|
247946
248098
|
};
|
|
247947
|
-
var settings_routes_default = (0,
|
|
248099
|
+
var settings_routes_default = (0, import_fastify_plugin22.default)(routes21, { name: "settings-routes" });
|
|
247948
248100
|
|
|
247949
248101
|
// src/routes/translate-routes.ts
|
|
247950
|
-
var
|
|
247951
|
-
var
|
|
248102
|
+
var import_fastify_plugin23 = __toESM(require_plugin2(), 1);
|
|
248103
|
+
var routes22 = async (fastify2) => {
|
|
247952
248104
|
fastify2.post(
|
|
247953
248105
|
"/api/translate",
|
|
247954
248106
|
async (req, reply) => {
|
|
@@ -247989,13 +248141,13 @@ ${text2}`,
|
|
|
247989
248141
|
}
|
|
247990
248142
|
);
|
|
247991
248143
|
};
|
|
247992
|
-
var translate_routes_default = (0,
|
|
248144
|
+
var translate_routes_default = (0, import_fastify_plugin23.default)(routes22, { name: "translate-routes" });
|
|
247993
248145
|
|
|
247994
248146
|
// src/routes/websocket-routes.ts
|
|
247995
|
-
var
|
|
248147
|
+
var import_fastify_plugin24 = __toESM(require_plugin2(), 1);
|
|
247996
248148
|
|
|
247997
248149
|
// src/routes/executor-stream-handlers.ts
|
|
247998
|
-
import { randomUUID as
|
|
248150
|
+
import { randomUUID as randomUUID19 } from "crypto";
|
|
247999
248151
|
function attachLocalProcessStream(fastify2, processId, send, onTerminal) {
|
|
248000
248152
|
const noop4 = { cleanup: () => {
|
|
248001
248153
|
}, handleInput: () => {
|
|
@@ -248071,7 +248223,7 @@ function attachRemoteProcessStream(fastify2, processId, send, onTerminal) {
|
|
|
248071
248223
|
return;
|
|
248072
248224
|
}
|
|
248073
248225
|
console.log(`[diag:remote-stop] ${(/* @__PURE__ */ new Date()).toISOString()} attach processId=${processId} executorId=${info.executorId} server=${info.remoteServerId} transport=reverse-connect remoteProcessId=${info.remoteProcessId}`);
|
|
248074
|
-
const channelId =
|
|
248226
|
+
const channelId = randomUUID19();
|
|
248075
248227
|
const wsPath = `/api/executor-processes/${info.remoteProcessId}/logs`;
|
|
248076
248228
|
const adapter = new VirtualWsAdapter(
|
|
248077
248229
|
(data) => fastify2.reverseConnectManager.sendChannelData(info.remoteServerId, channelId, data),
|
|
@@ -248303,7 +248455,7 @@ function attachWsHeartbeat(socket, { label, intervalMs = DEFAULT_INTERVAL_MS, ke
|
|
|
248303
248455
|
}
|
|
248304
248456
|
|
|
248305
248457
|
// src/routes/websocket-routes.ts
|
|
248306
|
-
var
|
|
248458
|
+
var routes23 = async (fastify2) => {
|
|
248307
248459
|
fastify2.reverseConnectManager.setStatusChangeHandler((remoteServerId, status) => {
|
|
248308
248460
|
if (status !== "online") return;
|
|
248309
248461
|
const cache2 = fastify2.remotePatchCache;
|
|
@@ -248736,10 +248888,10 @@ var routes24 = async (fastify2) => {
|
|
|
248736
248888
|
);
|
|
248737
248889
|
});
|
|
248738
248890
|
};
|
|
248739
|
-
var websocket_routes_default = (0,
|
|
248891
|
+
var websocket_routes_default = (0, import_fastify_plugin24.default)(routes23, { name: "websocket-routes" });
|
|
248740
248892
|
|
|
248741
248893
|
// src/routes/reverse-connect-routes.ts
|
|
248742
|
-
var
|
|
248894
|
+
var import_fastify_plugin25 = __toESM(require_plugin2(), 1);
|
|
248743
248895
|
import { randomBytes as randomBytes2, createHash as createHash8, verify as cryptoVerify } from "crypto";
|
|
248744
248896
|
|
|
248745
248897
|
// src/utils/rate-limited-warn.ts
|
|
@@ -248784,7 +248936,7 @@ function extractReportedVersion(frame) {
|
|
|
248784
248936
|
var MACHINE_HANDSHAKE_TIMEOUT_MS = 5e3;
|
|
248785
248937
|
var REJECT_LOG_WINDOW_MS = 3e4;
|
|
248786
248938
|
var REJECT_LOG_MAX_KEYS = 500;
|
|
248787
|
-
var
|
|
248939
|
+
var routes24 = async (fastify2) => {
|
|
248788
248940
|
const logRejectedUpgrade = createRateLimitedWarn(REJECT_LOG_WINDOW_MS, REJECT_LOG_MAX_KEYS);
|
|
248789
248941
|
fastify2.get("/api/reverse-connect/identity", async (req, reply) => {
|
|
248790
248942
|
const token = req.headers["x-vibedeckx-connect-token"];
|
|
@@ -248918,10 +249070,10 @@ var routes25 = async (fastify2) => {
|
|
|
248918
249070
|
);
|
|
248919
249071
|
});
|
|
248920
249072
|
};
|
|
248921
|
-
var reverse_connect_routes_default = (0,
|
|
249073
|
+
var reverse_connect_routes_default = (0, import_fastify_plugin25.default)(routes24, { name: "reverse-connect-routes" });
|
|
248922
249074
|
|
|
248923
249075
|
// src/routes/event-routes.ts
|
|
248924
|
-
var
|
|
249076
|
+
var import_fastify_plugin26 = __toESM(require_plugin2(), 1);
|
|
248925
249077
|
function toWireEvent(event) {
|
|
248926
249078
|
if (event.type === "executor:stopped" && (event.tailOutput !== void 0 || event.finalResult !== void 0)) {
|
|
248927
249079
|
const { tailOutput: _tailOutput, finalResult: _finalResult, ...rest } = event;
|
|
@@ -248929,7 +249081,7 @@ function toWireEvent(event) {
|
|
|
248929
249081
|
}
|
|
248930
249082
|
return event;
|
|
248931
249083
|
}
|
|
248932
|
-
var
|
|
249084
|
+
var routes25 = async (fastify2) => {
|
|
248933
249085
|
fastify2.get("/api/events", async (req, reply) => {
|
|
248934
249086
|
let userId = null;
|
|
248935
249087
|
if (fastify2.authEnabled) {
|
|
@@ -248984,10 +249136,10 @@ var routes26 = async (fastify2) => {
|
|
|
248984
249136
|
await reply;
|
|
248985
249137
|
});
|
|
248986
249138
|
};
|
|
248987
|
-
var event_routes_default = (0,
|
|
249139
|
+
var event_routes_default = (0, import_fastify_plugin26.default)(routes25, { name: "event-routes" });
|
|
248988
249140
|
|
|
248989
249141
|
// src/routes/terminal-routes.ts
|
|
248990
|
-
var
|
|
249142
|
+
var import_fastify_plugin27 = __toESM(require_plugin2(), 1);
|
|
248991
249143
|
import path13 from "path";
|
|
248992
249144
|
async function getRemoteConfig5(fastify2, project, remoteServerId) {
|
|
248993
249145
|
const remotes = await fastify2.storage.projectRemotes.getByProject(project.id);
|
|
@@ -248998,7 +249150,7 @@ async function getRemoteConfig5(fastify2, project, remoteServerId) {
|
|
|
248998
249150
|
remotePath: target.remote_path
|
|
248999
249151
|
};
|
|
249000
249152
|
}
|
|
249001
|
-
var
|
|
249153
|
+
var routes26 = async (fastify2) => {
|
|
249002
249154
|
fastify2.post("/api/path/terminals", async (req, reply) => {
|
|
249003
249155
|
const { path: projectPath, branch } = req.body;
|
|
249004
249156
|
if (!projectPath) {
|
|
@@ -249174,11 +249326,11 @@ var routes27 = async (fastify2) => {
|
|
|
249174
249326
|
}
|
|
249175
249327
|
);
|
|
249176
249328
|
};
|
|
249177
|
-
var terminal_routes_default = (0,
|
|
249329
|
+
var terminal_routes_default = (0, import_fastify_plugin27.default)(routes26, { name: "terminal-routes" });
|
|
249178
249330
|
|
|
249179
249331
|
// src/routes/browser-routes.ts
|
|
249180
|
-
var
|
|
249181
|
-
var
|
|
249332
|
+
var import_fastify_plugin28 = __toESM(require_plugin2(), 1);
|
|
249333
|
+
var routes27 = async (fastify2) => {
|
|
249182
249334
|
const ensureProjectAccess = async (req, reply) => {
|
|
249183
249335
|
const userId = requireUserFacingUserId(req, reply);
|
|
249184
249336
|
if (userId === null) return null;
|
|
@@ -249249,11 +249401,11 @@ var routes28 = async (fastify2) => {
|
|
|
249249
249401
|
return reply.code(200).send({ ok: true });
|
|
249250
249402
|
});
|
|
249251
249403
|
};
|
|
249252
|
-
var browser_routes_default = (0,
|
|
249404
|
+
var browser_routes_default = (0, import_fastify_plugin28.default)(routes27, { name: "browser-routes" });
|
|
249253
249405
|
|
|
249254
249406
|
// src/routes/browser-proxy-routes.ts
|
|
249255
|
-
var
|
|
249256
|
-
import { randomUUID as
|
|
249407
|
+
var import_fastify_plugin29 = __toESM(require_plugin2(), 1);
|
|
249408
|
+
import { randomUUID as randomUUID20 } from "crypto";
|
|
249257
249409
|
|
|
249258
249410
|
// src/utils/ssrf-guard.ts
|
|
249259
249411
|
var import_undici2 = __toESM(require_undici(), 1);
|
|
@@ -249748,7 +249900,7 @@ function generateInjectedScript(projectId, targetOrigin, proxyWsPrefix) {
|
|
|
249748
249900
|
})();
|
|
249749
249901
|
</script>`;
|
|
249750
249902
|
}
|
|
249751
|
-
var
|
|
249903
|
+
var routes28 = async (fastify2) => {
|
|
249752
249904
|
fastify2.get("/api/projects/:id/browser/proxy/*", async (req, reply) => {
|
|
249753
249905
|
const userId = requireUserFacingOrTrustedProxyUserId(req, reply);
|
|
249754
249906
|
if (userId === null) return;
|
|
@@ -249843,7 +249995,7 @@ var routes29 = async (fastify2) => {
|
|
|
249843
249995
|
const rcm = fastify2.reverseConnectManager;
|
|
249844
249996
|
if (resolved.remoteServerId && rcm.isConnected(resolved.remoteServerId)) {
|
|
249845
249997
|
const remoteServerId = resolved.remoteServerId;
|
|
249846
|
-
const channelId =
|
|
249998
|
+
const channelId = randomUUID20();
|
|
249847
249999
|
const parsed = new URL(resolved.fetchUrl);
|
|
249848
250000
|
const wsPath = parsed.pathname;
|
|
249849
250001
|
const wsQuery = parsed.search ? parsed.search.slice(1) : void 0;
|
|
@@ -249920,10 +250072,10 @@ var routes29 = async (fastify2) => {
|
|
|
249920
250072
|
});
|
|
249921
250073
|
});
|
|
249922
250074
|
};
|
|
249923
|
-
var browser_proxy_routes_default = (0,
|
|
250075
|
+
var browser_proxy_routes_default = (0, import_fastify_plugin29.default)(routes28, { name: "browser-proxy-routes" });
|
|
249924
250076
|
|
|
249925
250077
|
// src/routes/cross-remote-target-routes.ts
|
|
249926
|
-
var
|
|
250078
|
+
var import_fastify_plugin30 = __toESM(require_plugin2(), 1);
|
|
249927
250079
|
import path14 from "path";
|
|
249928
250080
|
import { promises as fs3 } from "fs";
|
|
249929
250081
|
|
|
@@ -250003,7 +250155,7 @@ var clampTimeoutMs = (timeoutSec) => {
|
|
|
250003
250155
|
const requested = typeof timeoutSec === "number" && Number.isFinite(timeoutSec) && timeoutSec > 0 ? timeoutSec : DEFAULT_TIMEOUT_SEC;
|
|
250004
250156
|
return Math.min(requested, MAX_TIMEOUT_SEC) * 1e3;
|
|
250005
250157
|
};
|
|
250006
|
-
var
|
|
250158
|
+
var routes29 = async (fastify2) => {
|
|
250007
250159
|
fastify2.post(
|
|
250008
250160
|
"/api/path/cross-remote/exec",
|
|
250009
250161
|
async (request, reply) => {
|
|
@@ -250111,10 +250263,10 @@ var routes30 = async (fastify2) => {
|
|
|
250111
250263
|
return reply.send(result);
|
|
250112
250264
|
});
|
|
250113
250265
|
};
|
|
250114
|
-
var cross_remote_target_routes_default = (0,
|
|
250266
|
+
var cross_remote_target_routes_default = (0, import_fastify_plugin30.default)(routes29, { name: "cross-remote-target-routes" });
|
|
250115
250267
|
|
|
250116
250268
|
// src/routes/cross-remote-mcp-routes.ts
|
|
250117
|
-
var
|
|
250269
|
+
var import_fastify_plugin31 = __toESM(require_plugin2(), 1);
|
|
250118
250270
|
var PROTOCOL_VERSION = "2024-11-05";
|
|
250119
250271
|
var AUDIT_ARGS_MAX = 1024;
|
|
250120
250272
|
var NOT_ACCESSIBLE = "remote not found or not accessible";
|
|
@@ -250217,7 +250369,7 @@ var textResult = (text2, isError = false) => ({
|
|
|
250217
250369
|
content: [{ type: "text", text: text2 }],
|
|
250218
250370
|
...isError ? { isError: true } : {}
|
|
250219
250371
|
});
|
|
250220
|
-
var
|
|
250372
|
+
var routes30 = async (fastify2) => {
|
|
250221
250373
|
const guard = new SessionConcurrencyGuard();
|
|
250222
250374
|
let cachedSecret;
|
|
250223
250375
|
const getSecret = () => {
|
|
@@ -250338,11 +250490,11 @@ var routes31 = async (fastify2) => {
|
|
|
250338
250490
|
}
|
|
250339
250491
|
});
|
|
250340
250492
|
};
|
|
250341
|
-
var cross_remote_mcp_routes_default = (0,
|
|
250493
|
+
var cross_remote_mcp_routes_default = (0, import_fastify_plugin31.default)(routes30, { name: "cross-remote-mcp-routes" });
|
|
250342
250494
|
|
|
250343
250495
|
// src/routes/schedule-routes.ts
|
|
250344
|
-
var
|
|
250345
|
-
import { randomUUID as
|
|
250496
|
+
var import_fastify_plugin32 = __toESM(require_plugin2(), 1);
|
|
250497
|
+
import { randomUUID as randomUUID21 } from "crypto";
|
|
250346
250498
|
import path15 from "path";
|
|
250347
250499
|
var RUN_TYPES = ["command", "prompt"];
|
|
250348
250500
|
var CWD_MODES = ["branch", "directory"];
|
|
@@ -250360,7 +250512,7 @@ function validateResolved(b2) {
|
|
|
250360
250512
|
if (cronError) return `Invalid cron expression: ${cronError}`;
|
|
250361
250513
|
return null;
|
|
250362
250514
|
}
|
|
250363
|
-
var
|
|
250515
|
+
var routes31 = async (fastify2) => {
|
|
250364
250516
|
const sendTerminalManualOutcome = (reply, request, replay) => {
|
|
250365
250517
|
if (!request.terminalStatus || request.terminalResponseStatus === null) return null;
|
|
250366
250518
|
const common = { runId: request.runId, status: request.terminalStatus, durable: true, replay };
|
|
@@ -250431,7 +250583,7 @@ var routes32 = async (fastify2) => {
|
|
|
250431
250583
|
return reply.code(400).send({ error: "Unknown remote target" });
|
|
250432
250584
|
}
|
|
250433
250585
|
const schedule = await fastify2.storage.scheduledTasks.create({
|
|
250434
|
-
id:
|
|
250586
|
+
id: randomUUID21(),
|
|
250435
250587
|
project_id: req.params.projectId,
|
|
250436
250588
|
name: b2.name.trim(),
|
|
250437
250589
|
cron_expr: resolved.cron_expr,
|
|
@@ -250591,7 +250743,7 @@ var routes32 = async (fastify2) => {
|
|
|
250591
250743
|
}
|
|
250592
250744
|
);
|
|
250593
250745
|
};
|
|
250594
|
-
var schedule_routes_default = (0,
|
|
250746
|
+
var schedule_routes_default = (0, import_fastify_plugin32.default)(routes31, { name: "schedule-routes" });
|
|
250595
250747
|
|
|
250596
250748
|
// src/search/catalog.ts
|
|
250597
250749
|
var parseDbTimestamp5 = (ts) => {
|
|
@@ -250891,10 +251043,10 @@ var searchRoutes = async (fastify2) => {
|
|
|
250891
251043
|
var search_routes_default = searchRoutes;
|
|
250892
251044
|
|
|
250893
251045
|
// src/routes/notification-routes.ts
|
|
250894
|
-
var
|
|
251046
|
+
var import_fastify_plugin33 = __toESM(require_plugin2(), 1);
|
|
250895
251047
|
var MAX_LIMIT = 500;
|
|
250896
251048
|
var DEFAULT_LIMIT = 100;
|
|
250897
|
-
var
|
|
251049
|
+
var routes32 = async (fastify2) => {
|
|
250898
251050
|
fastify2.get(
|
|
250899
251051
|
"/api/notifications",
|
|
250900
251052
|
async (req, reply) => {
|
|
@@ -250926,7 +251078,7 @@ var routes33 = async (fastify2) => {
|
|
|
250926
251078
|
return reply.code(200).send({ ok: true });
|
|
250927
251079
|
});
|
|
250928
251080
|
};
|
|
250929
|
-
var notification_routes_default = (0,
|
|
251081
|
+
var notification_routes_default = (0, import_fastify_plugin33.default)(routes32, { name: "notification-routes" });
|
|
250930
251082
|
|
|
250931
251083
|
// ../../node_modules/.pnpm/@clerk+fastify@3.1.2_fastify@5.7.2_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@clerk/fastify/dist/chunk-RY4T2JMQ.mjs
|
|
250932
251084
|
import { Readable as Readable2 } from "stream";
|
|
@@ -250978,7 +251130,7 @@ var requestToProxyRequest = (req) => {
|
|
|
250978
251130
|
|
|
250979
251131
|
// ../../node_modules/.pnpm/@clerk+fastify@3.1.2_fastify@5.7.2_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@clerk/fastify/dist/index.mjs
|
|
250980
251132
|
init_dist();
|
|
250981
|
-
var
|
|
251133
|
+
var import_fastify_plugin34 = __toESM(require_plugin2(), 1);
|
|
250982
251134
|
|
|
250983
251135
|
// ../../node_modules/.pnpm/@clerk+backend@3.2.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@clerk/backend/dist/internal.mjs
|
|
250984
251136
|
init_chunk_JW73PKED();
|
|
@@ -251266,7 +251418,7 @@ var plugin = (instance, opts, done) => {
|
|
|
251266
251418
|
instance.addHook(hookName, withClerkMiddleware(opts));
|
|
251267
251419
|
done();
|
|
251268
251420
|
};
|
|
251269
|
-
var clerkPlugin = (0,
|
|
251421
|
+
var clerkPlugin = (0, import_fastify_plugin34.default)(plugin, {
|
|
251270
251422
|
name: "@clerk/fastify",
|
|
251271
251423
|
fastify: "5.x"
|
|
251272
251424
|
});
|
|
@@ -252188,7 +252340,6 @@ var createServer = async (opts) => {
|
|
|
252188
252340
|
server.register(worker_stats_routes_default);
|
|
252189
252341
|
server.register(project_remote_routes_default);
|
|
252190
252342
|
server.register(search_routes_default);
|
|
252191
|
-
server.register(executor_group_routes_default);
|
|
252192
252343
|
server.register(executor_routes_default);
|
|
252193
252344
|
server.register(schedule_routes_default);
|
|
252194
252345
|
server.register(process_routes_default);
|
|
@@ -252822,7 +252973,7 @@ var ReverseConnectClient = class {
|
|
|
252822
252973
|
|
|
252823
252974
|
// src/connect-daemon.ts
|
|
252824
252975
|
import { spawn as spawn5 } from "node:child_process";
|
|
252825
|
-
import { randomUUID as
|
|
252976
|
+
import { randomUUID as randomUUID22 } from "node:crypto";
|
|
252826
252977
|
import fs8 from "node:fs";
|
|
252827
252978
|
import path19 from "node:path";
|
|
252828
252979
|
var CONNECT_DAEMON_CHILD_ENV = "VIBEDECKX_INTERNAL_CONNECT_DAEMON";
|
|
@@ -253216,7 +253367,7 @@ function createDaemonStateLockCandidate(lockPath) {
|
|
|
253216
253367
|
schemaVersion: 1,
|
|
253217
253368
|
pid: process.pid,
|
|
253218
253369
|
processStartTicks,
|
|
253219
|
-
nonce:
|
|
253370
|
+
nonce: randomUUID22()
|
|
253220
253371
|
};
|
|
253221
253372
|
const candidatePath = `${lockPath}.candidate-${process.pid}-${owner.nonce}`;
|
|
253222
253373
|
fs8.mkdirSync(candidatePath, { mode: 448 });
|
|
@@ -254584,7 +254735,7 @@ var connectRoutes = buildRouteMap({
|
|
|
254584
254735
|
defaultCommand: "run",
|
|
254585
254736
|
docs: { brief: "Connect to a Vibedeckx server as an inbound node" }
|
|
254586
254737
|
});
|
|
254587
|
-
var
|
|
254738
|
+
var routes33 = buildRouteMap({
|
|
254588
254739
|
routes: {
|
|
254589
254740
|
start: startCommand,
|
|
254590
254741
|
connect: connectRoutes
|
|
@@ -254594,7 +254745,7 @@ var routes34 = buildRouteMap({
|
|
|
254594
254745
|
brief: "Vibedeckx - AI-powered app generator"
|
|
254595
254746
|
}
|
|
254596
254747
|
});
|
|
254597
|
-
var program = buildApplication(
|
|
254748
|
+
var program = buildApplication(routes33, {
|
|
254598
254749
|
name: "vibedeckx",
|
|
254599
254750
|
versionInfo: {
|
|
254600
254751
|
currentVersion: readPackageVersion()
|