@vibedeckx/linux-x64 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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, fp36, 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(fp36)) {
|
|
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, fp36, 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(fp36)) {
|
|
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(routes35) {
|
|
90115
|
+
return routes35.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 routes35 = node.routes;
|
|
90128
90128
|
if (options.method === void 0) {
|
|
90129
|
-
|
|
90129
|
+
routes35 = routes35.map(normalizeRoute);
|
|
90130
90130
|
}
|
|
90131
|
-
|
|
90131
|
+
routes35 = routes35.map((route) => {
|
|
90132
90132
|
route.metaData = getRouteMetaData(route, options);
|
|
90133
90133
|
return route;
|
|
90134
90134
|
});
|
|
90135
90135
|
if (options.method === void 0) {
|
|
90136
|
-
|
|
90136
|
+
routes35 = mergeSimilarRoutes(routes35);
|
|
90137
90137
|
}
|
|
90138
|
-
return
|
|
90138
|
+
return routes35.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(routes35) {
|
|
91406
91406
|
this.reset();
|
|
91407
|
-
for (const route of
|
|
91407
|
+
for (const route of routes35) {
|
|
91408
91408
|
const { method, path: path22, opts, handler, store } = route;
|
|
91409
91409
|
this._on(method, path22, opts, handler, store);
|
|
91410
91410
|
}
|
|
@@ -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 fp36 = pv + (!p2.parent ? "" : this.sep) + name25;
|
|
100616
|
+
return this.#fullpath = fp36;
|
|
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 fp36 = 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 routes35 = /* @__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 (routes35.has(route)) {
|
|
105453
105453
|
continue;
|
|
105454
105454
|
}
|
|
105455
|
-
|
|
105455
|
+
routes35.add(route);
|
|
105456
105456
|
setUpHeadAndGet(routeOpts, route, `/${file2}`, rootPath);
|
|
105457
105457
|
const key = path22.posix.basename(route);
|
|
105458
105458
|
if (indexes.has(key) && !indexDirs.has(key)) {
|
|
@@ -105747,7 +105747,7 @@ var require_static = __commonJS({
|
|
|
105747
105747
|
throw err;
|
|
105748
105748
|
}
|
|
105749
105749
|
}
|
|
105750
|
-
module.exports =
|
|
105750
|
+
module.exports = fp36(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 fp36 = 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 = fp36(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 fp36 = 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 = fp36(fastifyMultipart2, {
|
|
115473
115473
|
fastify: "5.x",
|
|
115474
115474
|
name: "@fastify/multipart"
|
|
115475
115475
|
});
|
|
@@ -154378,6 +154378,7 @@ var VIBEDECKX_HOME = path.join(homedir(), ".vibedeckx");
|
|
|
154378
154378
|
var DB_PATH = path.join(VIBEDECKX_HOME, "data.sqlite");
|
|
154379
154379
|
var DEFAULT_PORT = 5173;
|
|
154380
154380
|
var MIN_WORKER_VERSION = "0.0.0";
|
|
154381
|
+
var WORKER_VERSION_REPORTING_SINCE = "2026-08-03";
|
|
154381
154382
|
|
|
154382
154383
|
// src/load-env.ts
|
|
154383
154384
|
function getArg(argv, name25) {
|
|
@@ -169020,11 +169021,11 @@ function buildCommand(builderArgs) {
|
|
|
169020
169021
|
}
|
|
169021
169022
|
};
|
|
169022
169023
|
}
|
|
169023
|
-
function* generateRouteMapHelpLines(
|
|
169024
|
+
function* generateRouteMapHelpLines(routes35, docs, args) {
|
|
169024
169025
|
const { brief, fullDescription, hideRoute } = docs;
|
|
169025
169026
|
const { headers } = args.text;
|
|
169026
169027
|
yield args.ansiColor ? `\x1B[1m${headers.usage}\x1B[22m` : headers.usage;
|
|
169027
|
-
for (const [name25, route] of Object.entries(
|
|
169028
|
+
for (const [name25, route] of Object.entries(routes35)) {
|
|
169028
169029
|
if (!hideRoute || !hideRoute[name25] || args.includeHidden) {
|
|
169029
169030
|
const externalRouteName = args.config.caseStyle === "convert-camel-to-kebab" ? convertCamelCaseToKebabCase(name25) : name25;
|
|
169030
169031
|
yield ` ${route.formatUsageLine({
|
|
@@ -169054,7 +169055,7 @@ function* generateRouteMapHelpLines(routes34, docs, args) {
|
|
|
169054
169055
|
}
|
|
169055
169056
|
yield "";
|
|
169056
169057
|
yield args.ansiColor ? `\x1B[1m${headers.commands}\x1B[22m` : headers.commands;
|
|
169057
|
-
const visibleRoutes = Object.entries(
|
|
169058
|
+
const visibleRoutes = Object.entries(routes35).filter(
|
|
169058
169059
|
([name25]) => !hideRoute || !hideRoute[name25] || args.includeHidden
|
|
169059
169060
|
);
|
|
169060
169061
|
const rows = visibleRoutes.map(([internalRouteName, route]) => {
|
|
@@ -169082,24 +169083,24 @@ function* generateRouteMapHelpLines(routes34, docs, args) {
|
|
|
169082
169083
|
}
|
|
169083
169084
|
}
|
|
169084
169085
|
function buildRouteMap({
|
|
169085
|
-
routes:
|
|
169086
|
+
routes: routes35,
|
|
169086
169087
|
defaultCommand: defaultCommandRoute,
|
|
169087
169088
|
docs,
|
|
169088
169089
|
aliases
|
|
169089
169090
|
}) {
|
|
169090
|
-
if (Object.entries(
|
|
169091
|
+
if (Object.entries(routes35).length === 0) {
|
|
169091
169092
|
throw new InternalError("Route map must contain at least one route");
|
|
169092
169093
|
}
|
|
169093
169094
|
const activeAliases = aliases ?? {};
|
|
169094
169095
|
const aliasesByRoute = /* @__PURE__ */ new Map();
|
|
169095
169096
|
for (const [alias, routeName] of Object.entries(activeAliases)) {
|
|
169096
|
-
if (alias in
|
|
169097
|
+
if (alias in routes35) {
|
|
169097
169098
|
throw new InternalError(`Cannot use "${alias}" as an alias when a route with that name already exists`);
|
|
169098
169099
|
}
|
|
169099
169100
|
const routeAliases = aliasesByRoute.get(routeName) ?? [];
|
|
169100
169101
|
aliasesByRoute.set(routeName, [...routeAliases, alias]);
|
|
169101
169102
|
}
|
|
169102
|
-
const defaultCommand = defaultCommandRoute ?
|
|
169103
|
+
const defaultCommand = defaultCommandRoute ? routes35[defaultCommandRoute] : void 0;
|
|
169103
169104
|
if (defaultCommand && defaultCommand.kind === RouteMapSymbol) {
|
|
169104
169105
|
throw new InternalError(
|
|
169105
169106
|
`Cannot use "${defaultCommandRoute}" as the default command because it is not a Command`
|
|
@@ -169108,7 +169109,7 @@ function buildRouteMap({
|
|
|
169108
169109
|
const resolveRouteName = (input) => {
|
|
169109
169110
|
if (input in activeAliases) {
|
|
169110
169111
|
return activeAliases[input];
|
|
169111
|
-
} else if (input in
|
|
169112
|
+
} else if (input in routes35) {
|
|
169112
169113
|
return input;
|
|
169113
169114
|
}
|
|
169114
169115
|
};
|
|
@@ -169126,7 +169127,7 @@ function buildRouteMap({
|
|
|
169126
169127
|
return `${args.prefix.join(" ")} ${routeNames.join("|")} ...`;
|
|
169127
169128
|
},
|
|
169128
169129
|
formatHelp: (config2) => {
|
|
169129
|
-
const lines = [...generateRouteMapHelpLines(
|
|
169130
|
+
const lines = [...generateRouteMapHelpLines(routes35, docs, config2)];
|
|
169130
169131
|
const text2 = lines.join("\n");
|
|
169131
169132
|
return text2 + "\n";
|
|
169132
169133
|
},
|
|
@@ -169169,11 +169170,11 @@ function buildRouteMap({
|
|
|
169169
169170
|
},
|
|
169170
169171
|
getRoutingTargetForInput: (input) => {
|
|
169171
169172
|
const routeName = input in activeAliases ? activeAliases[input] : input;
|
|
169172
|
-
return
|
|
169173
|
+
return routes35[routeName];
|
|
169173
169174
|
},
|
|
169174
169175
|
getAllEntries() {
|
|
169175
169176
|
const hiddenRoutes = docs.hideRoute;
|
|
169176
|
-
return Object.entries(
|
|
169177
|
+
return Object.entries(routes35).map(([originalRouteName, target]) => {
|
|
169177
169178
|
return {
|
|
169178
169179
|
name: {
|
|
169179
169180
|
original: originalRouteName,
|
|
@@ -185911,8 +185912,6 @@ var mapProject = (row) => ({
|
|
|
185911
185912
|
path: row.path,
|
|
185912
185913
|
is_remote: fromDbBool(row.is_remote),
|
|
185913
185914
|
remote_path: row.remote_path ?? void 0,
|
|
185914
|
-
remote_url: row.remote_url ?? void 0,
|
|
185915
|
-
remote_api_key: row.remote_api_key ?? void 0,
|
|
185916
185915
|
agent_mode: row.agent_mode ?? "local",
|
|
185917
185916
|
executor_mode: row.executor_mode ?? "local",
|
|
185918
185917
|
sync_up_config: row.sync_up_config ? JSON.parse(row.sync_up_config) : void 0,
|
|
@@ -185928,10 +185927,10 @@ var createCoreRepos = (kdb, h) => ({
|
|
|
185928
185927
|
path: opts.path ?? null,
|
|
185929
185928
|
remote_path: opts.remote_path ?? null,
|
|
185930
185929
|
is_remote: h.toDbBool(false),
|
|
185931
|
-
|
|
185932
|
-
|
|
185933
|
-
//
|
|
185934
|
-
//
|
|
185930
|
+
// Dead columns: never populated by any current caller (kept only so
|
|
185931
|
+
// legacy DDL/back-compat readers relying on their presence don't break).
|
|
185932
|
+
// remote_url/remote_api_key are leftovers from the removed direct-URL
|
|
185933
|
+
// (outbound) transport — all remote traffic rides reverse-connect now.
|
|
185935
185934
|
remote_project_id: null,
|
|
185936
185935
|
agent_mode: opts.agent_mode ?? "local",
|
|
185937
185936
|
executor_mode: opts.executor_mode ?? "local",
|
|
@@ -186114,9 +186113,6 @@ var createRemoteServerRepos = (kdb, _h) => ({
|
|
|
186114
186113
|
await kdb.insertInto("remote_servers").values({
|
|
186115
186114
|
id,
|
|
186116
186115
|
name: server.name,
|
|
186117
|
-
url: null,
|
|
186118
|
-
api_key: null,
|
|
186119
|
-
connection_mode: "inbound",
|
|
186120
186116
|
connect_token: null,
|
|
186121
186117
|
connect_token_created_at: null,
|
|
186122
186118
|
last_connected_at: null,
|
|
@@ -186339,8 +186335,17 @@ var mapExecutorProcess = (row) => ({
|
|
|
186339
186335
|
status: row.status
|
|
186340
186336
|
});
|
|
186341
186337
|
var mapRemoteExecutorProcess = (row) => ({
|
|
186342
|
-
|
|
186343
|
-
|
|
186338
|
+
local_process_id: row.local_process_id,
|
|
186339
|
+
remote_server_id: row.remote_server_id,
|
|
186340
|
+
remote_process_id: row.remote_process_id,
|
|
186341
|
+
executor_id: row.executor_id,
|
|
186342
|
+
project_id: row.project_id,
|
|
186343
|
+
branch: row.branch,
|
|
186344
|
+
started_at: row.started_at,
|
|
186345
|
+
status: row.status,
|
|
186346
|
+
exit_code: row.exit_code,
|
|
186347
|
+
finished_at: row.finished_at,
|
|
186348
|
+
machine_id: row.machine_id
|
|
186344
186349
|
});
|
|
186345
186350
|
var createExecutorRepos = (kdb, h) => ({
|
|
186346
186351
|
executorGroups: {
|
|
@@ -187170,6 +187175,10 @@ var createSearchCacheRepos = (kdb, _h) => ({
|
|
|
187170
187175
|
]).executeTakeFirstOrThrow();
|
|
187171
187176
|
return { running: Number(row.running) };
|
|
187172
187177
|
},
|
|
187178
|
+
countRunningRemoteSessions: async () => {
|
|
187179
|
+
const row = await kdb.selectFrom("session_search_cache as c").innerJoin("remote_session_mappings as mapping", (join2) => join2.onRef("mapping.local_session_id", "=", "c.local_session_id").onRef("mapping.project_id", "=", "c.project_id").onRef("mapping.remote_server_id", "=", "c.target_id")).innerJoin("project_remotes as association", (join2) => join2.onRef("association.project_id", "=", "c.project_id").onRef("association.remote_server_id", "=", "c.target_id")).where("c.target_id", "!=", "local").where("c.deleted_at", "is", null).where("c.status", "=", "running").select([sql`count(*)`.as("n")]).executeTakeFirstOrThrow();
|
|
187180
|
+
return Number(row.n);
|
|
187181
|
+
},
|
|
187173
187182
|
updateRemoteSessionActivity: async (entry) => {
|
|
187174
187183
|
return kdb.transaction().execute(async (trx) => {
|
|
187175
187184
|
const authorized = await trx.selectFrom("remote_session_mappings as mapping").innerJoin("project_remotes as association", (join2) => join2.onRef("association.project_id", "=", "mapping.project_id").onRef("association.remote_server_id", "=", "mapping.remote_server_id")).select("mapping.branch").where("mapping.local_session_id", "=", entry.localSessionId).where("mapping.project_id", "=", entry.projectId).where("mapping.remote_server_id", "=", entry.targetId).where("mapping.remote_session_id", "=", entry.remoteSessionId).executeTakeFirst();
|
|
@@ -205171,6 +205180,13 @@ function findTurnOpeningUserEntry(entries, beforeIndex) {
|
|
|
205171
205180
|
}
|
|
205172
205181
|
return opening;
|
|
205173
205182
|
}
|
|
205183
|
+
function findLatestUserEntry(entries) {
|
|
205184
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
205185
|
+
const entry = entries[i];
|
|
205186
|
+
if (entry?.type === "user") return entry;
|
|
205187
|
+
}
|
|
205188
|
+
return void 0;
|
|
205189
|
+
}
|
|
205174
205190
|
function resolveNotificationDisposition(openingUserEntry) {
|
|
205175
205191
|
if (openingUserEntry?.type !== "user") return "result";
|
|
205176
205192
|
if (openingUserEntry.notificationDisposition) return openingUserEntry.notificationDisposition;
|
|
@@ -228160,6 +228176,10 @@ var AgentSessionManager = class {
|
|
|
228160
228176
|
if (event.type === "turn_started" || event.type === "text" || event.type === "thinking" || event.type === "tool_use" || event.type === "tool_result" || event.type === "approval_request") {
|
|
228161
228177
|
this.applyCompletionTimerAction(session, session.completion.noteTurnActivity());
|
|
228162
228178
|
}
|
|
228179
|
+
if (session.turnOpenSince === null && (event.type === "turn_started" || event.type === "text" || event.type === "thinking" || event.type === "tool_use" || event.type === "tool_result" || event.type === "approval_request")) {
|
|
228180
|
+
session.turnOpenSince = timestamp;
|
|
228181
|
+
session.turnDisposition = resolveNotificationDisposition(findLatestUserEntry(session.store.entries));
|
|
228182
|
+
}
|
|
228163
228183
|
if (session.status !== "running" && (event.type === "text" || event.type === "thinking" || event.type === "tool_use" || event.type === "tool_result" || event.type === "approval_request")) {
|
|
228164
228184
|
session.status = "running";
|
|
228165
228185
|
if (!session.skipDb) await this.storage.agentSessions.updateStatus(sessionId, "running");
|
|
@@ -230235,6 +230255,26 @@ function tryParseWsMessage(raw) {
|
|
|
230235
230255
|
return void 0;
|
|
230236
230256
|
}
|
|
230237
230257
|
}
|
|
230258
|
+
function isEntryPatchFrame(parsed) {
|
|
230259
|
+
if (!parsed || !("JsonPatch" in parsed)) return false;
|
|
230260
|
+
const ops = parsed.JsonPatch;
|
|
230261
|
+
if (!Array.isArray(ops)) return false;
|
|
230262
|
+
return ops.some((op) => typeof op?.path === "string" && op.path.startsWith("/entries/"));
|
|
230263
|
+
}
|
|
230264
|
+
function entryPatchFrames(messages) {
|
|
230265
|
+
const frames = [];
|
|
230266
|
+
for (const raw of messages) {
|
|
230267
|
+
if (isEntryPatchFrame(tryParseWsMessage(raw))) frames.push(raw);
|
|
230268
|
+
}
|
|
230269
|
+
return frames;
|
|
230270
|
+
}
|
|
230271
|
+
function isSequencePrefix(cached2, replay) {
|
|
230272
|
+
if (cached2.length > replay.length) return false;
|
|
230273
|
+
for (let i = 0; i < cached2.length; i++) {
|
|
230274
|
+
if (cached2[i] !== replay[i]) return false;
|
|
230275
|
+
}
|
|
230276
|
+
return true;
|
|
230277
|
+
}
|
|
230238
230278
|
async function persistRemoteSessionActivityFrame(storage, sessionId, remoteInfo, parsed, activityAt = Date.now()) {
|
|
230239
230279
|
const projectId = projectIdFromRemoteSessionId(sessionId, remoteInfo);
|
|
230240
230280
|
const statusEvent = statusEventFromRemotePatch(parsed, sessionId, remoteInfo);
|
|
@@ -230298,6 +230338,7 @@ function connectPersistentRemoteWs(sessionId, remoteInfo, cache2, reverseConnect
|
|
|
230298
230338
|
const raw = data.toString();
|
|
230299
230339
|
const parsed = tryParseWsMessage(raw);
|
|
230300
230340
|
if (!parsed) return;
|
|
230341
|
+
if ("keepalive" in parsed) return;
|
|
230301
230342
|
const kind = "JsonPatch" in parsed ? "JsonPatch" : "finished" in parsed ? "finished" : "taskCompleted" in parsed ? "taskCompleted" : "workflowRunUpdated" in parsed ? "workflowRunUpdated" : "processAlive" in parsed ? "processAlive" : "branchActivity" in parsed ? "branchActivity" : "Ready" in parsed ? "Ready" : "error" in parsed ? "error" : "other";
|
|
230302
230343
|
if (kind === "JsonPatch") {
|
|
230303
230344
|
const ops = parsed.JsonPatch;
|
|
@@ -230445,23 +230486,18 @@ function connectPersistentRemoteWs(sessionId, remoteInfo, cache2, reverseConnect
|
|
|
230445
230486
|
if ("Ready" in parsed) {
|
|
230446
230487
|
syncing = false;
|
|
230447
230488
|
const currentEntry = cache2.get(sessionId);
|
|
230448
|
-
const
|
|
230449
|
-
|
|
230450
|
-
|
|
230451
|
-
|
|
230489
|
+
const cachedSeq = entryPatchFrames(currentEntry.messages);
|
|
230490
|
+
const extendsCache = isSequencePrefix(cachedSeq, replayBuffer);
|
|
230491
|
+
if (extendsCache && replayBuffer.length > cachedSeq.length) {
|
|
230492
|
+
const delta = replayBuffer.slice(cachedSeq.length);
|
|
230493
|
+
console.log(`[AgentWS] Sync delta: ${delta.length} new entry patches for ${sessionId} (remote=${replayBuffer.length}, cached=${cachedSeq.length})`);
|
|
230452
230494
|
for (const msg of delta) {
|
|
230453
|
-
|
|
230454
|
-
cache2.appendMessage(sessionId, msg, !!(p2 && "JsonPatch" in p2));
|
|
230495
|
+
cache2.appendMessage(sessionId, msg, true);
|
|
230455
230496
|
cache2.broadcast(sessionId, msg);
|
|
230456
230497
|
}
|
|
230457
|
-
} else if (
|
|
230458
|
-
console.log(`[AgentWS] Sync
|
|
230459
|
-
|
|
230460
|
-
for (const msg of replayBuffer) {
|
|
230461
|
-
const p2 = tryParseWsMessage(msg);
|
|
230462
|
-
if (p2 && "JsonPatch" in p2) newPatchCount++;
|
|
230463
|
-
}
|
|
230464
|
-
cache2.replaceAll(sessionId, [...replayBuffer], newPatchCount);
|
|
230498
|
+
} else if (!extendsCache) {
|
|
230499
|
+
console.log(`[AgentWS] Sync replace for ${sessionId}: remote=${replayBuffer.length}, cached=${cachedSeq.length} (sequence diverged or shrank)`);
|
|
230500
|
+
cache2.replaceAll(sessionId, [...replayBuffer], replayBuffer.length);
|
|
230465
230501
|
const clearPatch = {
|
|
230466
230502
|
JsonPatch: [{
|
|
230467
230503
|
op: "replace",
|
|
@@ -230479,12 +230515,15 @@ function connectPersistentRemoteWs(sessionId, remoteInfo, cache2, reverseConnect
|
|
|
230479
230515
|
remoteWs.on("message", handleLiveMessage);
|
|
230480
230516
|
return;
|
|
230481
230517
|
}
|
|
230482
|
-
if (
|
|
230518
|
+
if (isEntryPatchFrame(parsed)) {
|
|
230483
230519
|
replayBuffer.push(raw);
|
|
230520
|
+
return;
|
|
230484
230521
|
}
|
|
230485
230522
|
if ("finished" in parsed) {
|
|
230486
230523
|
cache2.setFinished(sessionId);
|
|
230524
|
+
return;
|
|
230487
230525
|
}
|
|
230526
|
+
handleLiveMessage(data);
|
|
230488
230527
|
});
|
|
230489
230528
|
}
|
|
230490
230529
|
remoteWs.on("error", (error48) => {
|
|
@@ -238530,16 +238569,12 @@ function resolveUserId(authResult) {
|
|
|
238530
238569
|
}
|
|
238531
238570
|
|
|
238532
238571
|
// src/routes/project-routes.ts
|
|
238533
|
-
function sanitizeProject(project) {
|
|
238534
|
-
const { remote_api_key, ...safe } = project;
|
|
238535
|
-
return { ...safe, has_remote_api_key: !!remote_api_key };
|
|
238536
|
-
}
|
|
238537
238572
|
var routes2 = async (fastify2) => {
|
|
238538
238573
|
fastify2.get("/api/projects", async (req, reply) => {
|
|
238539
238574
|
const authResult = requireAuth(req, reply);
|
|
238540
238575
|
if (authResult === null) return;
|
|
238541
238576
|
const userId = resolveUserId(authResult);
|
|
238542
|
-
const projects =
|
|
238577
|
+
const projects = await fastify2.storage.projects.getAll(userId);
|
|
238543
238578
|
return reply.code(200).send({ projects });
|
|
238544
238579
|
});
|
|
238545
238580
|
fastify2.get("/api/projects/:id", async (req, reply) => {
|
|
@@ -238550,7 +238585,7 @@ var routes2 = async (fastify2) => {
|
|
|
238550
238585
|
if (!project) {
|
|
238551
238586
|
return reply.code(404).send({ error: "Project not found" });
|
|
238552
238587
|
}
|
|
238553
|
-
return reply.code(200).send({ project
|
|
238588
|
+
return reply.code(200).send({ project });
|
|
238554
238589
|
});
|
|
238555
238590
|
fastify2.post("/api/dialog/select-folder", async (req, reply) => {
|
|
238556
238591
|
const folderPath = await selectFolder();
|
|
@@ -238621,7 +238656,7 @@ var routes2 = async (fastify2) => {
|
|
|
238621
238656
|
agent_mode: agentMode,
|
|
238622
238657
|
executor_mode: executorMode
|
|
238623
238658
|
}, userId);
|
|
238624
|
-
return reply.code(201).send({ project
|
|
238659
|
+
return reply.code(201).send({ project });
|
|
238625
238660
|
});
|
|
238626
238661
|
fastify2.put("/api/projects/:id", async (req, reply) => {
|
|
238627
238662
|
const authResult = requireAuth(req, reply);
|
|
@@ -238661,7 +238696,7 @@ var routes2 = async (fastify2) => {
|
|
|
238661
238696
|
if (!updated) {
|
|
238662
238697
|
return reply.code(404).send({ error: "Project not found" });
|
|
238663
238698
|
}
|
|
238664
|
-
return reply.code(200).send({ project:
|
|
238699
|
+
return reply.code(200).send({ project: updated });
|
|
238665
238700
|
});
|
|
238666
238701
|
fastify2.delete("/api/projects/:id", async (req, reply) => {
|
|
238667
238702
|
const authResult = requireAuth(req, reply);
|
|
@@ -238800,11 +238835,101 @@ function requireUserFacingOrTrustedProxyUserId(request, reply) {
|
|
|
238800
238835
|
return authResult === void 0 && request.server.authEnabled ? void 0 : resolveUserId(authResult);
|
|
238801
238836
|
}
|
|
238802
238837
|
|
|
238838
|
+
// src/update-check.ts
|
|
238839
|
+
var SEMVER_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?$/;
|
|
238840
|
+
async function fetchLatestPublishedVersion(pkg = "vibedeckx", fetchImpl = fetch) {
|
|
238841
|
+
try {
|
|
238842
|
+
const response = await fetchImpl(
|
|
238843
|
+
`https://registry.npmjs.org/${pkg}/latest`,
|
|
238844
|
+
{ signal: AbortSignal.timeout(4e3) }
|
|
238845
|
+
);
|
|
238846
|
+
if (!response.ok) return void 0;
|
|
238847
|
+
const body = await response.json();
|
|
238848
|
+
return typeof body.version === "string" && parseSemver(body.version) ? body.version : void 0;
|
|
238849
|
+
} catch {
|
|
238850
|
+
return void 0;
|
|
238851
|
+
}
|
|
238852
|
+
}
|
|
238853
|
+
function parseSemver(version2) {
|
|
238854
|
+
const match2 = SEMVER_RE.exec(version2);
|
|
238855
|
+
if (!match2) return void 0;
|
|
238856
|
+
return {
|
|
238857
|
+
core: [match2[1], match2[2], match2[3]],
|
|
238858
|
+
prerelease: match2[4]?.split(".")
|
|
238859
|
+
};
|
|
238860
|
+
}
|
|
238861
|
+
function compareNumericStrings(a, b2) {
|
|
238862
|
+
if (a.length !== b2.length) return a.length - b2.length;
|
|
238863
|
+
return a < b2 ? -1 : a > b2 ? 1 : 0;
|
|
238864
|
+
}
|
|
238865
|
+
function comparePrereleaseIdentifiers(a, b2) {
|
|
238866
|
+
const aNumeric = /^\d+$/.test(a);
|
|
238867
|
+
const bNumeric = /^\d+$/.test(b2);
|
|
238868
|
+
if (aNumeric && bNumeric) return compareNumericStrings(a, b2);
|
|
238869
|
+
if (aNumeric !== bNumeric) return aNumeric ? -1 : 1;
|
|
238870
|
+
return a < b2 ? -1 : a > b2 ? 1 : 0;
|
|
238871
|
+
}
|
|
238872
|
+
function compareSemver(a, b2) {
|
|
238873
|
+
for (let i = 0; i < 3; i += 1) {
|
|
238874
|
+
const compared = compareNumericStrings(a.core[i], b2.core[i]);
|
|
238875
|
+
if (compared !== 0) return compared;
|
|
238876
|
+
}
|
|
238877
|
+
if (!a.prerelease && !b2.prerelease) return 0;
|
|
238878
|
+
if (!a.prerelease) return 1;
|
|
238879
|
+
if (!b2.prerelease) return -1;
|
|
238880
|
+
const length = Math.max(a.prerelease.length, b2.prerelease.length);
|
|
238881
|
+
for (let i = 0; i < length; i += 1) {
|
|
238882
|
+
const aId = a.prerelease[i];
|
|
238883
|
+
const bId = b2.prerelease[i];
|
|
238884
|
+
if (aId === void 0) return -1;
|
|
238885
|
+
if (bId === void 0) return 1;
|
|
238886
|
+
const compared = comparePrereleaseIdentifiers(aId, bId);
|
|
238887
|
+
if (compared !== 0) return compared;
|
|
238888
|
+
}
|
|
238889
|
+
return 0;
|
|
238890
|
+
}
|
|
238891
|
+
function compareVersionStrings(a, b2) {
|
|
238892
|
+
const parsedA = parseSemver(a);
|
|
238893
|
+
const parsedB = parseSemver(b2);
|
|
238894
|
+
if (!parsedA || !parsedB) return void 0;
|
|
238895
|
+
return compareSemver(parsedA, parsedB);
|
|
238896
|
+
}
|
|
238897
|
+
function compareUpdateStatus(current, latest) {
|
|
238898
|
+
if (latest === void 0) return "unknown";
|
|
238899
|
+
const currentParsed = parseSemver(current);
|
|
238900
|
+
const latestParsed = parseSemver(latest);
|
|
238901
|
+
if (!currentParsed || !latestParsed) return "unknown";
|
|
238902
|
+
return compareSemver(latestParsed, currentParsed) > 0 ? "update-available" : "up-to-date";
|
|
238903
|
+
}
|
|
238904
|
+
|
|
238803
238905
|
// src/routes/remote-server-routes.ts
|
|
238804
238906
|
function sanitizeServer(server) {
|
|
238805
238907
|
const { connect_token: _t, ...safe } = server;
|
|
238806
238908
|
return safe;
|
|
238807
238909
|
}
|
|
238910
|
+
var npmLatestCache;
|
|
238911
|
+
var npmLatestRefreshInFlight = false;
|
|
238912
|
+
function getLatestWorkerVersion() {
|
|
238913
|
+
const ttlMs = npmLatestCache?.value !== void 0 ? 60 * 60 * 1e3 : 5 * 60 * 1e3;
|
|
238914
|
+
const fresh = npmLatestCache !== void 0 && Date.now() - npmLatestCache.fetchedAt < ttlMs;
|
|
238915
|
+
if (!fresh && !npmLatestRefreshInFlight) {
|
|
238916
|
+
npmLatestRefreshInFlight = true;
|
|
238917
|
+
void fetchLatestPublishedVersion().then((value) => {
|
|
238918
|
+
npmLatestCache = { value, fetchedAt: Date.now() };
|
|
238919
|
+
}).finally(() => {
|
|
238920
|
+
npmLatestRefreshInFlight = false;
|
|
238921
|
+
});
|
|
238922
|
+
}
|
|
238923
|
+
return npmLatestCache?.value;
|
|
238924
|
+
}
|
|
238925
|
+
function workerUpdateStatus(workerVersion, latest) {
|
|
238926
|
+
if (!workerVersion) return "unreported";
|
|
238927
|
+
const vsMin = compareVersionStrings(workerVersion, MIN_WORKER_VERSION);
|
|
238928
|
+
if (vsMin !== void 0 && vsMin < 0) return "behind-min";
|
|
238929
|
+
const vsLatest = latest === void 0 ? void 0 : compareVersionStrings(workerVersion, latest);
|
|
238930
|
+
if (vsLatest !== void 0 && vsLatest < 0) return "behind-latest";
|
|
238931
|
+
return "current";
|
|
238932
|
+
}
|
|
238808
238933
|
var CROSS_REMOTE_ACCESS_VALUES = ["off", "read", "exec"];
|
|
238809
238934
|
var isCrossRemoteAccess = (value) => typeof value === "string" && CROSS_REMOTE_ACCESS_VALUES.includes(value);
|
|
238810
238935
|
var routes3 = async (fastify2) => {
|
|
@@ -238812,7 +238937,12 @@ var routes3 = async (fastify2) => {
|
|
|
238812
238937
|
const userId = requireUserFacingUserId(request, reply);
|
|
238813
238938
|
if (userId === null) return;
|
|
238814
238939
|
const servers = await fastify2.storage.remoteServers.getAll(userId);
|
|
238815
|
-
|
|
238940
|
+
const latest = getLatestWorkerVersion();
|
|
238941
|
+
return reply.send(servers.map((server) => ({
|
|
238942
|
+
...sanitizeServer(server),
|
|
238943
|
+
latest_worker_version: latest,
|
|
238944
|
+
worker_update_status: workerUpdateStatus(server.worker_version, latest)
|
|
238945
|
+
})));
|
|
238816
238946
|
});
|
|
238817
238947
|
fastify2.post("/api/remote-servers", async (request, reply) => {
|
|
238818
238948
|
const userId = requireUserFacingUserId(request, reply);
|
|
@@ -238971,12 +239101,94 @@ var routes3 = async (fastify2) => {
|
|
|
238971
239101
|
};
|
|
238972
239102
|
var remote_server_routes_default = (0, import_fastify_plugin4.default)(routes3, { name: "remote-server-routes" });
|
|
238973
239103
|
|
|
238974
|
-
// src/routes/
|
|
239104
|
+
// src/routes/worker-stats-routes.ts
|
|
238975
239105
|
var import_fastify_plugin5 = __toESM(require_plugin2(), 1);
|
|
239106
|
+
var API_KEY = process.env.VIBEDECKX_API_KEY || void 0;
|
|
239107
|
+
var STALE_WORKER_THRESHOLD_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
239108
|
+
var PHASE4_UNKNOWN_SHARE_MAX = 0.05;
|
|
239109
|
+
var PHASE4_DEPRECATION_DAYS = 60;
|
|
239110
|
+
function parseDbTimestamp3(ts) {
|
|
239111
|
+
if (!ts) return void 0;
|
|
239112
|
+
const ms = Date.parse(ts.replace(" ", "T") + "Z");
|
|
239113
|
+
return Number.isNaN(ms) ? void 0 : ms;
|
|
239114
|
+
}
|
|
239115
|
+
function countByVersion(versions) {
|
|
239116
|
+
const counts = {};
|
|
239117
|
+
for (const version2 of versions) {
|
|
239118
|
+
const key = version2 ?? "unknown";
|
|
239119
|
+
counts[key] = (counts[key] ?? 0) + 1;
|
|
239120
|
+
}
|
|
239121
|
+
return counts;
|
|
239122
|
+
}
|
|
239123
|
+
function oldestVersion(versions) {
|
|
239124
|
+
let oldest;
|
|
239125
|
+
for (const version2 of versions) {
|
|
239126
|
+
if (oldest === void 0) {
|
|
239127
|
+
oldest = version2;
|
|
239128
|
+
continue;
|
|
239129
|
+
}
|
|
239130
|
+
const cmp = compareVersionStrings(version2, oldest);
|
|
239131
|
+
if (cmp !== void 0 && cmp < 0) oldest = version2;
|
|
239132
|
+
}
|
|
239133
|
+
return oldest;
|
|
239134
|
+
}
|
|
239135
|
+
var routes4 = async (fastify2) => {
|
|
239136
|
+
fastify2.get("/api/admin/worker-version-stats", async (request, reply) => {
|
|
239137
|
+
const apiKeyHeader = request.headers["x-vibedeckx-api-key"];
|
|
239138
|
+
const isOperator = API_KEY !== void 0 && apiKeyHeader !== void 0 || !fastify2.authEnabled && API_KEY === void 0;
|
|
239139
|
+
if (!isOperator) return reply.code(404).send({ error: "Not found" });
|
|
239140
|
+
const now3 = Date.now();
|
|
239141
|
+
const servers = await fastify2.storage.remoteServers.getAll();
|
|
239142
|
+
const connected = servers.filter((server) => fastify2.reverseConnectManager.isConnected(server.id));
|
|
239143
|
+
const everActive = servers.filter((server) => server.last_connected_at !== void 0);
|
|
239144
|
+
const connectedVersions = connected.map((server) => server.worker_version);
|
|
239145
|
+
const unknownConnected = connectedVersions.filter((v2) => v2 === void 0).length;
|
|
239146
|
+
const unknownShareConnected = connected.length > 0 ? unknownConnected / connected.length : null;
|
|
239147
|
+
const daysSinceReporting = Math.floor(
|
|
239148
|
+
(now3 - Date.parse(WORKER_VERSION_REPORTING_SINCE)) / (24 * 60 * 60 * 1e3)
|
|
239149
|
+
);
|
|
239150
|
+
return reply.send({
|
|
239151
|
+
min_worker_version: MIN_WORKER_VERSION,
|
|
239152
|
+
reporting_since: WORKER_VERSION_REPORTING_SINCE,
|
|
239153
|
+
workers_total: servers.length,
|
|
239154
|
+
connected_workers: connected.length,
|
|
239155
|
+
// Two lenses on the distribution: _all accumulates dead rows forever
|
|
239156
|
+
// (abandoned trials), _connected is the one Phase 4 decisions use.
|
|
239157
|
+
versions_all: countByVersion(servers.map((server) => server.worker_version)),
|
|
239158
|
+
versions_connected: countByVersion(connectedVersions),
|
|
239159
|
+
oldest_connected_version: oldestVersion(
|
|
239160
|
+
connectedVersions.filter((v2) => v2 !== void 0)
|
|
239161
|
+
) ?? null,
|
|
239162
|
+
// Deploy blast radius: how many live tunnels a restart would sever, and
|
|
239163
|
+
// how many of those are mid-turn (the actual user harm — idle sessions
|
|
239164
|
+
// recover on reconnect).
|
|
239165
|
+
active_remote_sessions: fastify2.remoteSessionMap.size,
|
|
239166
|
+
active_turns: await fastify2.storage.searchCache.countRunningRemoteSessions(),
|
|
239167
|
+
// Upgrade-failure tripwire: workers that were active once but have been
|
|
239168
|
+
// offline > 7 days — the classic "daemon didn't come back" signature.
|
|
239169
|
+
stale_workers_7d: everActive.filter((server) => {
|
|
239170
|
+
if (fastify2.reverseConnectManager.isConnected(server.id)) return false;
|
|
239171
|
+
const lastSeen = parseDbTimestamp3(server.last_connected_at);
|
|
239172
|
+
return lastSeen !== void 0 && now3 - lastSeen > STALE_WORKER_THRESHOLD_MS;
|
|
239173
|
+
}).length,
|
|
239174
|
+
phase4_ready: {
|
|
239175
|
+
unknown_share_connected: unknownShareConnected,
|
|
239176
|
+
unknown_share_max: PHASE4_UNKNOWN_SHARE_MAX,
|
|
239177
|
+
days_since_reporting_release: daysSinceReporting,
|
|
239178
|
+
deprecation_days: PHASE4_DEPRECATION_DAYS,
|
|
239179
|
+
verdict: unknownShareConnected !== null && unknownShareConnected < PHASE4_UNKNOWN_SHARE_MAX && daysSinceReporting >= PHASE4_DEPRECATION_DAYS
|
|
239180
|
+
}
|
|
239181
|
+
});
|
|
239182
|
+
});
|
|
239183
|
+
};
|
|
239184
|
+
var worker_stats_routes_default = (0, import_fastify_plugin5.default)(routes4, { name: "worker-stats-routes" });
|
|
239185
|
+
|
|
239186
|
+
// src/routes/project-remote-routes.ts
|
|
239187
|
+
var import_fastify_plugin6 = __toESM(require_plugin2(), 1);
|
|
238976
239188
|
function sanitizeProjectRemote(pr) {
|
|
238977
239189
|
return pr;
|
|
238978
239190
|
}
|
|
238979
|
-
var
|
|
239191
|
+
var routes5 = async (fastify2) => {
|
|
238980
239192
|
fastify2.get(
|
|
238981
239193
|
"/api/projects/:id/remotes",
|
|
238982
239194
|
async (request, reply) => {
|
|
@@ -239076,12 +239288,12 @@ var routes4 = async (fastify2) => {
|
|
|
239076
239288
|
}
|
|
239077
239289
|
);
|
|
239078
239290
|
};
|
|
239079
|
-
var project_remote_routes_default = (0,
|
|
239291
|
+
var project_remote_routes_default = (0, import_fastify_plugin6.default)(routes5, { name: "project-remote-routes" });
|
|
239080
239292
|
|
|
239081
239293
|
// src/routes/executor-group-routes.ts
|
|
239082
|
-
var
|
|
239294
|
+
var import_fastify_plugin7 = __toESM(require_plugin2(), 1);
|
|
239083
239295
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
239084
|
-
var
|
|
239296
|
+
var routes6 = async (fastify2) => {
|
|
239085
239297
|
fastify2.get(
|
|
239086
239298
|
"/api/projects/:projectId/executor-groups",
|
|
239087
239299
|
async (req, reply) => {
|
|
@@ -239152,17 +239364,17 @@ var routes5 = async (fastify2) => {
|
|
|
239152
239364
|
}
|
|
239153
239365
|
);
|
|
239154
239366
|
};
|
|
239155
|
-
var executor_group_routes_default = (0,
|
|
239367
|
+
var executor_group_routes_default = (0, import_fastify_plugin7.default)(routes6, { name: "executor-group-routes" });
|
|
239156
239368
|
|
|
239157
239369
|
// src/routes/executor-routes.ts
|
|
239158
|
-
var
|
|
239370
|
+
var import_fastify_plugin8 = __toESM(require_plugin2(), 1);
|
|
239159
239371
|
import { randomUUID as randomUUID12 } from "crypto";
|
|
239160
239372
|
function normalizeSqlTimestamp(value) {
|
|
239161
239373
|
if (!value) return null;
|
|
239162
239374
|
if (value.includes("T") && /(Z|[+-]\d{2}:?\d{2})$/.test(value)) return value;
|
|
239163
239375
|
return value.replace(" ", "T") + "Z";
|
|
239164
239376
|
}
|
|
239165
|
-
var
|
|
239377
|
+
var routes7 = async (fastify2) => {
|
|
239166
239378
|
fastify2.get(
|
|
239167
239379
|
"/api/projects/:projectId/executors",
|
|
239168
239380
|
async (req, reply) => {
|
|
@@ -239301,13 +239513,13 @@ var routes6 = async (fastify2) => {
|
|
|
239301
239513
|
return reply.code(200).send({ success: true });
|
|
239302
239514
|
});
|
|
239303
239515
|
};
|
|
239304
|
-
var executor_routes_default = (0,
|
|
239516
|
+
var executor_routes_default = (0, import_fastify_plugin8.default)(routes7, { name: "executor-routes" });
|
|
239305
239517
|
|
|
239306
239518
|
// src/routes/process-routes.ts
|
|
239307
|
-
var
|
|
239519
|
+
var import_fastify_plugin9 = __toESM(require_plugin2(), 1);
|
|
239308
239520
|
import path9 from "path";
|
|
239309
239521
|
import { randomUUID as randomUUID13 } from "crypto";
|
|
239310
|
-
var
|
|
239522
|
+
var routes8 = async (fastify2) => {
|
|
239311
239523
|
fastify2.post("/api/path/execute", async (req, reply) => {
|
|
239312
239524
|
const userId = requireAuth(req, reply);
|
|
239313
239525
|
if (userId === null) return;
|
|
@@ -239519,10 +239731,10 @@ var routes7 = async (fastify2) => {
|
|
|
239519
239731
|
return reply.code(200).send({ processes });
|
|
239520
239732
|
});
|
|
239521
239733
|
};
|
|
239522
|
-
var process_routes_default = (0,
|
|
239734
|
+
var process_routes_default = (0, import_fastify_plugin9.default)(routes8, { name: "process-routes" });
|
|
239523
239735
|
|
|
239524
239736
|
// src/routes/worktree-routes.ts
|
|
239525
|
-
var
|
|
239737
|
+
var import_fastify_plugin10 = __toESM(require_plugin2(), 1);
|
|
239526
239738
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
239527
239739
|
async function getAllRemoteConfigs(fastify2, project) {
|
|
239528
239740
|
const remotes = await fastify2.storage.projectRemotes.getByProject(project.id);
|
|
@@ -239535,7 +239747,7 @@ async function getRemoteConfig(fastify2, project) {
|
|
|
239535
239747
|
const all = await getAllRemoteConfigs(fastify2, project);
|
|
239536
239748
|
return all.length > 0 ? all[0] : null;
|
|
239537
239749
|
}
|
|
239538
|
-
var
|
|
239750
|
+
var routes9 = async (fastify2) => {
|
|
239539
239751
|
fastify2.get("/api/path/branches", async (req, reply) => {
|
|
239540
239752
|
const projectPath = req.query.path;
|
|
239541
239753
|
if (!projectPath) {
|
|
@@ -240063,10 +240275,10 @@ var routes8 = async (fastify2) => {
|
|
|
240063
240275
|
});
|
|
240064
240276
|
});
|
|
240065
240277
|
};
|
|
240066
|
-
var worktree_routes_default = (0,
|
|
240278
|
+
var worktree_routes_default = (0, import_fastify_plugin10.default)(routes9, { name: "worktree-routes" });
|
|
240067
240279
|
|
|
240068
240280
|
// src/routes/diff-routes.ts
|
|
240069
|
-
var
|
|
240281
|
+
var import_fastify_plugin11 = __toESM(require_plugin2(), 1);
|
|
240070
240282
|
import path10 from "path";
|
|
240071
240283
|
import { readFileSync as readFileSync4 } from "fs";
|
|
240072
240284
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
@@ -240374,7 +240586,7 @@ async function getUntrackedFiles(cwd) {
|
|
|
240374
240586
|
}
|
|
240375
240587
|
return files;
|
|
240376
240588
|
}
|
|
240377
|
-
var
|
|
240589
|
+
var routes10 = async (fastify2) => {
|
|
240378
240590
|
fastify2.get("/api/path/diff", async (req, reply) => {
|
|
240379
240591
|
const projectPath = req.query.path;
|
|
240380
240592
|
if (!projectPath) {
|
|
@@ -240565,10 +240777,10 @@ var routes9 = async (fastify2) => {
|
|
|
240565
240777
|
}
|
|
240566
240778
|
});
|
|
240567
240779
|
};
|
|
240568
|
-
var diff_routes_default = (0,
|
|
240780
|
+
var diff_routes_default = (0, import_fastify_plugin11.default)(routes10, { name: "diff-routes" });
|
|
240569
240781
|
|
|
240570
240782
|
// src/routes/file-routes.ts
|
|
240571
|
-
var
|
|
240783
|
+
var import_fastify_plugin12 = __toESM(require_plugin2(), 1);
|
|
240572
240784
|
import path11 from "path";
|
|
240573
240785
|
import fs2 from "fs/promises";
|
|
240574
240786
|
import { createReadStream, constants as fsConstants } from "fs";
|
|
@@ -240791,7 +241003,7 @@ async function searchSymbol(basePath33, symbol26) {
|
|
|
240791
241003
|
}
|
|
240792
241004
|
return { hits, truncated };
|
|
240793
241005
|
}
|
|
240794
|
-
var
|
|
241006
|
+
var routes11 = async (fastify2) => {
|
|
240795
241007
|
fastify2.get("/api/path/browse", async (req, reply) => {
|
|
240796
241008
|
const projectPath = req.query.path;
|
|
240797
241009
|
if (!projectPath) {
|
|
@@ -241352,10 +241564,10 @@ var routes10 = async (fastify2) => {
|
|
|
241352
241564
|
}
|
|
241353
241565
|
});
|
|
241354
241566
|
};
|
|
241355
|
-
var file_routes_default = (0,
|
|
241567
|
+
var file_routes_default = (0, import_fastify_plugin12.default)(routes11, { name: "file-routes" });
|
|
241356
241568
|
|
|
241357
241569
|
// src/routes/agent-session-routes.ts
|
|
241358
|
-
var
|
|
241570
|
+
var import_fastify_plugin13 = __toESM(require_plugin2(), 1);
|
|
241359
241571
|
|
|
241360
241572
|
// src/utils/paste-file.ts
|
|
241361
241573
|
import { chmod, mkdir as mkdir4, open } from "node:fs/promises";
|
|
@@ -241406,7 +241618,7 @@ function messageTextLength(content) {
|
|
|
241406
241618
|
}
|
|
241407
241619
|
return n;
|
|
241408
241620
|
}
|
|
241409
|
-
var
|
|
241621
|
+
var routes12 = async (fastify2) => {
|
|
241410
241622
|
const instructionReceiverToken = randomUUID15();
|
|
241411
241623
|
const instructionDeliveryLocks = /* @__PURE__ */ new Map();
|
|
241412
241624
|
async function serializeInstructionDelivery(key, effect) {
|
|
@@ -242760,10 +242972,10 @@ var routes11 = async (fastify2) => {
|
|
|
242760
242972
|
return reply.code(200).send({ success: true, favorited });
|
|
242761
242973
|
});
|
|
242762
242974
|
};
|
|
242763
|
-
var agent_session_routes_default = (0,
|
|
242975
|
+
var agent_session_routes_default = (0, import_fastify_plugin13.default)(routes12, { name: "agent-session-routes" });
|
|
242764
242976
|
|
|
242765
242977
|
// src/routes/branch-activity-routes.ts
|
|
242766
|
-
var
|
|
242978
|
+
var import_fastify_plugin14 = __toESM(require_plugin2(), 1);
|
|
242767
242979
|
function toResponse(map2) {
|
|
242768
242980
|
return {
|
|
242769
242981
|
branches: Array.from(map2.entries()).map(([branch, state]) => ({
|
|
@@ -242778,7 +242990,7 @@ function fromResponse(resp) {
|
|
|
242778
242990
|
resp.branches.map((b2) => [b2.branch ?? "", { activity: b2.activity, since: b2.since }])
|
|
242779
242991
|
);
|
|
242780
242992
|
}
|
|
242781
|
-
var
|
|
242993
|
+
var routes13 = async (fastify2) => {
|
|
242782
242994
|
function proxyAuto(remoteServerId, method, apiPath, body) {
|
|
242783
242995
|
return proxyToRemoteAuto(remoteServerId, method, apiPath, body, {
|
|
242784
242996
|
reverseConnectManager: fastify2.reverseConnectManager
|
|
@@ -242843,10 +243055,10 @@ var routes12 = async (fastify2) => {
|
|
|
242843
243055
|
}
|
|
242844
243056
|
);
|
|
242845
243057
|
};
|
|
242846
|
-
var branch_activity_routes_default = (0,
|
|
243058
|
+
var branch_activity_routes_default = (0, import_fastify_plugin14.default)(routes13, { name: "branch-activity-routes" });
|
|
242847
243059
|
|
|
242848
243060
|
// src/routes/merge-status-routes.ts
|
|
242849
|
-
var
|
|
243061
|
+
var import_fastify_plugin15 = __toESM(require_plugin2(), 1);
|
|
242850
243062
|
function resolveTargets(comparisons, storedTargets) {
|
|
242851
243063
|
const sources = [];
|
|
242852
243064
|
const effective = comparisons.map((comparison) => {
|
|
@@ -242960,7 +243172,7 @@ function sendComputed(reply, repoPath, comparisons, repository) {
|
|
|
242960
243172
|
return reply.code(statusCode).send({ error: message });
|
|
242961
243173
|
}
|
|
242962
243174
|
}
|
|
242963
|
-
var
|
|
243175
|
+
var routes14 = async (fastify2) => {
|
|
242964
243176
|
fastify2.post(
|
|
242965
243177
|
"/api/path/branches/merge-status",
|
|
242966
243178
|
async (req, reply) => {
|
|
@@ -243082,11 +243294,11 @@ var routes13 = async (fastify2) => {
|
|
|
243082
243294
|
}
|
|
243083
243295
|
);
|
|
243084
243296
|
};
|
|
243085
|
-
var merge_status_routes_default = (0,
|
|
243297
|
+
var merge_status_routes_default = (0, import_fastify_plugin15.default)(routes14, { name: "merge-status-routes" });
|
|
243086
243298
|
|
|
243087
243299
|
// src/routes/chat-session-routes.ts
|
|
243088
|
-
var
|
|
243089
|
-
var
|
|
243300
|
+
var import_fastify_plugin16 = __toESM(require_plugin2(), 1);
|
|
243301
|
+
var routes15 = async (fastify2) => {
|
|
243090
243302
|
const getAuthorizedSession = (req, reply, sessionId) => {
|
|
243091
243303
|
const authResult = requireUserFacingUserId(req, reply);
|
|
243092
243304
|
if (authResult === null) return null;
|
|
@@ -243191,10 +243403,10 @@ var routes14 = async (fastify2) => {
|
|
|
243191
243403
|
return reply.send({ ok: true });
|
|
243192
243404
|
});
|
|
243193
243405
|
};
|
|
243194
|
-
var chat_session_routes_default = (0,
|
|
243406
|
+
var chat_session_routes_default = (0, import_fastify_plugin16.default)(routes15, { name: "chat-session-routes" });
|
|
243195
243407
|
|
|
243196
243408
|
// src/routes/project-chat-routes.ts
|
|
243197
|
-
var
|
|
243409
|
+
var import_fastify_plugin17 = __toESM(require_plugin2(), 1);
|
|
243198
243410
|
import { createHash as createHash6, randomUUID as randomUUID16 } from "crypto";
|
|
243199
243411
|
var MAX_TITLE_LENGTH = 200;
|
|
243200
243412
|
var MAX_MESSAGE_LENGTH = 1e5;
|
|
@@ -243307,7 +243519,7 @@ function parseWorkspaceSelectionBody(body) {
|
|
|
243307
243519
|
if (!requestId || requestId.length > MAX_TOOL_SELECTOR_ID || !workspaceId || workspaceId.length > MAX_TOOL_SELECTOR_ID) return null;
|
|
243308
243520
|
return { requestId, workspaceId };
|
|
243309
243521
|
}
|
|
243310
|
-
var
|
|
243522
|
+
var routes16 = async (fastify2) => {
|
|
243311
243523
|
const getOwnedThread = async (req, reply, threadId) => {
|
|
243312
243524
|
const authResult = requireAuth(req, reply);
|
|
243313
243525
|
if (authResult === null) return null;
|
|
@@ -243526,10 +243738,10 @@ var routes15 = async (fastify2) => {
|
|
|
243526
243738
|
}
|
|
243527
243739
|
});
|
|
243528
243740
|
};
|
|
243529
|
-
var project_chat_routes_default = (0,
|
|
243741
|
+
var project_chat_routes_default = (0, import_fastify_plugin17.default)(routes16, { name: "project-chat-routes" });
|
|
243530
243742
|
|
|
243531
243743
|
// src/routes/project-activity-routes.ts
|
|
243532
|
-
var
|
|
243744
|
+
var import_fastify_plugin18 = __toESM(require_plugin2(), 1);
|
|
243533
243745
|
|
|
243534
243746
|
// src/project-activity.ts
|
|
243535
243747
|
var RECENT_THREAD_LIMIT = 5;
|
|
@@ -243537,7 +243749,7 @@ var RECENT_SESSION_LIMIT = 8;
|
|
|
243537
243749
|
var RECENT_RUN_LIMIT = 5;
|
|
243538
243750
|
var PRIORITY_TASK_LIMIT = 5;
|
|
243539
243751
|
var ATTENTION_LIMIT = 10;
|
|
243540
|
-
var
|
|
243752
|
+
var parseDbTimestamp4 = (value) => {
|
|
243541
243753
|
if (!value) return null;
|
|
243542
243754
|
const explicitZone = /(?:Z|[+-]\d\d:\d\d)$/i.test(value);
|
|
243543
243755
|
const parsed = Date.parse(explicitZone ? value : `${value.replace(" ", "T")}Z`);
|
|
@@ -243562,8 +243774,8 @@ var localActivity = (session) => {
|
|
|
243562
243774
|
lastActiveAt: maxTimestamp(
|
|
243563
243775
|
session.last_user_message_at,
|
|
243564
243776
|
session.last_completed_at,
|
|
243565
|
-
|
|
243566
|
-
|
|
243777
|
+
parseDbTimestamp4(session.updated_at),
|
|
243778
|
+
parseDbTimestamp4(session.created_at)
|
|
243567
243779
|
),
|
|
243568
243780
|
lastUserMessageAt: session.last_user_message_at ?? null,
|
|
243569
243781
|
lastCompletedAt: session.last_completed_at ?? null
|
|
@@ -243627,7 +243839,7 @@ async function getProjectActivity(storage, projectId, userId) {
|
|
|
243627
243839
|
entityId: run2.id,
|
|
243628
243840
|
status: run2.status,
|
|
243629
243841
|
title: run2.scheduleName,
|
|
243630
|
-
occurredAtMs:
|
|
243842
|
+
occurredAtMs: parseDbTimestamp4(run2.finished_at ?? run2.started_at) ?? 0
|
|
243631
243843
|
}))
|
|
243632
243844
|
].sort((left, right) => right.occurredAtMs - left.occurredAtMs || right.entityId.localeCompare(left.entityId)).slice(0, ATTENTION_LIMIT).map(({ occurredAtMs, ...item }) => ({
|
|
243633
243845
|
...item,
|
|
@@ -243647,7 +243859,7 @@ async function getProjectActivity(storage, projectId, userId) {
|
|
|
243647
243859
|
}
|
|
243648
243860
|
|
|
243649
243861
|
// src/routes/project-activity-routes.ts
|
|
243650
|
-
var
|
|
243862
|
+
var routes17 = async (fastify2) => {
|
|
243651
243863
|
fastify2.get(
|
|
243652
243864
|
"/api/projects/:projectId/activity",
|
|
243653
243865
|
async (req, reply) => {
|
|
@@ -243663,12 +243875,12 @@ var routes16 = async (fastify2) => {
|
|
|
243663
243875
|
}
|
|
243664
243876
|
);
|
|
243665
243877
|
};
|
|
243666
|
-
var project_activity_routes_default = (0,
|
|
243878
|
+
var project_activity_routes_default = (0, import_fastify_plugin18.default)(routes17);
|
|
243667
243879
|
|
|
243668
243880
|
// src/routes/task-routes.ts
|
|
243669
|
-
var
|
|
243881
|
+
var import_fastify_plugin19 = __toESM(require_plugin2(), 1);
|
|
243670
243882
|
import { randomUUID as randomUUID17 } from "crypto";
|
|
243671
|
-
var
|
|
243883
|
+
var routes18 = async (fastify2) => {
|
|
243672
243884
|
fastify2.get(
|
|
243673
243885
|
"/api/projects/:projectId/tasks",
|
|
243674
243886
|
async (req, reply) => {
|
|
@@ -243828,12 +244040,12 @@ Description: ${description}`,
|
|
|
243828
244040
|
return reply.code(200).send({ success: true });
|
|
243829
244041
|
});
|
|
243830
244042
|
};
|
|
243831
|
-
var task_routes_default = (0,
|
|
244043
|
+
var task_routes_default = (0, import_fastify_plugin19.default)(routes18, { name: "task-routes" });
|
|
243832
244044
|
|
|
243833
244045
|
// src/routes/rule-routes.ts
|
|
243834
|
-
var
|
|
244046
|
+
var import_fastify_plugin20 = __toESM(require_plugin2(), 1);
|
|
243835
244047
|
import { randomUUID as randomUUID18 } from "crypto";
|
|
243836
|
-
var
|
|
244048
|
+
var routes19 = async (fastify2) => {
|
|
243837
244049
|
fastify2.get(
|
|
243838
244050
|
"/api/projects/:projectId/rules",
|
|
243839
244051
|
async (req, reply) => {
|
|
@@ -243919,12 +244131,12 @@ var routes18 = async (fastify2) => {
|
|
|
243919
244131
|
return reply.code(200).send({ success: true });
|
|
243920
244132
|
});
|
|
243921
244133
|
};
|
|
243922
|
-
var rule_routes_default = (0,
|
|
244134
|
+
var rule_routes_default = (0, import_fastify_plugin20.default)(routes19, { name: "rule-routes" });
|
|
243923
244135
|
|
|
243924
244136
|
// src/routes/command-routes.ts
|
|
243925
|
-
var
|
|
244137
|
+
var import_fastify_plugin21 = __toESM(require_plugin2(), 1);
|
|
243926
244138
|
import { randomUUID as randomUUID19 } from "crypto";
|
|
243927
|
-
var
|
|
244139
|
+
var routes20 = async (fastify2) => {
|
|
243928
244140
|
fastify2.get(
|
|
243929
244141
|
"/api/projects/:projectId/commands",
|
|
243930
244142
|
async (req, reply) => {
|
|
@@ -243993,10 +244205,10 @@ var routes19 = async (fastify2) => {
|
|
|
243993
244205
|
return reply.code(200).send({ success: true });
|
|
243994
244206
|
});
|
|
243995
244207
|
};
|
|
243996
|
-
var command_routes_default = (0,
|
|
244208
|
+
var command_routes_default = (0, import_fastify_plugin21.default)(routes20, { name: "command-routes" });
|
|
243997
244209
|
|
|
243998
244210
|
// src/routes/workflow-run-routes.ts
|
|
243999
|
-
var
|
|
244211
|
+
var import_fastify_plugin22 = __toESM(require_plugin2(), 1);
|
|
244000
244212
|
|
|
244001
244213
|
// src/utils/review-brief.ts
|
|
244002
244214
|
var BASE_TIMEOUT_MS = 15e3;
|
|
@@ -244328,7 +244540,7 @@ function errStatus(err) {
|
|
|
244328
244540
|
return 500;
|
|
244329
244541
|
}
|
|
244330
244542
|
}
|
|
244331
|
-
async function
|
|
244543
|
+
async function routes21(fastify2) {
|
|
244332
244544
|
const remoteRunMap = /* @__PURE__ */ new Map();
|
|
244333
244545
|
const TERMINAL_RUN_STATUSES = /* @__PURE__ */ new Set(["completed", "cancelled", "failed"]);
|
|
244334
244546
|
const trackRemoteRun = (localRun, info) => {
|
|
@@ -244793,10 +245005,10 @@ async function routes20(fastify2) {
|
|
|
244793
245005
|
return reply.send({ runs });
|
|
244794
245006
|
});
|
|
244795
245007
|
}
|
|
244796
|
-
var workflow_run_routes_default = (0,
|
|
245008
|
+
var workflow_run_routes_default = (0, import_fastify_plugin22.default)(routes21, { name: "workflow-run-routes" });
|
|
244797
245009
|
|
|
244798
245010
|
// src/routes/settings-routes.ts
|
|
244799
|
-
var
|
|
245011
|
+
var import_fastify_plugin23 = __toESM(require_plugin2(), 1);
|
|
244800
245012
|
var SettingsValidationError = class extends Error {
|
|
244801
245013
|
};
|
|
244802
245014
|
var DEFAULT_PROXY_CONFIG = { type: "none", host: "", port: 0 };
|
|
@@ -244860,7 +245072,7 @@ function requireSettingsUser(req, reply) {
|
|
|
244860
245072
|
if (auth === null) return null;
|
|
244861
245073
|
return resolveUserId(auth);
|
|
244862
245074
|
}
|
|
244863
|
-
var
|
|
245075
|
+
var routes22 = async (fastify2) => {
|
|
244864
245076
|
fastify2.get("/api/settings/agent-processes", async (req, reply) => {
|
|
244865
245077
|
if (requireAuth(req, reply) === null) return;
|
|
244866
245078
|
const saved = await fastify2.storage.settings.get("agentProcesses");
|
|
@@ -245134,11 +245346,11 @@ var routes21 = async (fastify2) => {
|
|
|
245134
245346
|
return reply.code(200).send(updated);
|
|
245135
245347
|
});
|
|
245136
245348
|
};
|
|
245137
|
-
var settings_routes_default = (0,
|
|
245349
|
+
var settings_routes_default = (0, import_fastify_plugin23.default)(routes22, { name: "settings-routes" });
|
|
245138
245350
|
|
|
245139
245351
|
// src/routes/translate-routes.ts
|
|
245140
|
-
var
|
|
245141
|
-
var
|
|
245352
|
+
var import_fastify_plugin24 = __toESM(require_plugin2(), 1);
|
|
245353
|
+
var routes23 = async (fastify2) => {
|
|
245142
245354
|
fastify2.post(
|
|
245143
245355
|
"/api/translate",
|
|
245144
245356
|
async (req, reply) => {
|
|
@@ -245179,10 +245391,10 @@ ${text2}`,
|
|
|
245179
245391
|
}
|
|
245180
245392
|
);
|
|
245181
245393
|
};
|
|
245182
|
-
var translate_routes_default = (0,
|
|
245394
|
+
var translate_routes_default = (0, import_fastify_plugin24.default)(routes23, { name: "translate-routes" });
|
|
245183
245395
|
|
|
245184
245396
|
// src/routes/websocket-routes.ts
|
|
245185
|
-
var
|
|
245397
|
+
var import_fastify_plugin25 = __toESM(require_plugin2(), 1);
|
|
245186
245398
|
|
|
245187
245399
|
// src/routes/executor-stream-handlers.ts
|
|
245188
245400
|
import { randomUUID as randomUUID20 } from "crypto";
|
|
@@ -245294,6 +245506,7 @@ function attachRemoteProcessStream(fastify2, processId, send, onTerminal) {
|
|
|
245294
245506
|
} catch {
|
|
245295
245507
|
}
|
|
245296
245508
|
if (!parsed) return;
|
|
245509
|
+
if ("keepalive" in parsed) return;
|
|
245297
245510
|
send(parsed);
|
|
245298
245511
|
if (parsed.type === "finished" || parsed.type === "error") terminalSignalSent = true;
|
|
245299
245512
|
if (parsed.type === "finished" || parsed.type === "error") {
|
|
@@ -245393,7 +245606,6 @@ async function verifyWsToken(token) {
|
|
|
245393
245606
|
}
|
|
245394
245607
|
async function authenticateWs(authEnabled, query, socket) {
|
|
245395
245608
|
if (!authEnabled) return { userId: null, kind: "solo" };
|
|
245396
|
-
if (process.env.VIBEDECKX_API_KEY && query.apiKey) return { userId: null, kind: "api_key" };
|
|
245397
245609
|
const reject = (error48) => {
|
|
245398
245610
|
try {
|
|
245399
245611
|
socket.send(JSON.stringify({ error: error48 }));
|
|
@@ -245449,8 +245661,49 @@ async function userOwnsSession(fastify2, sessionId, userId) {
|
|
|
245449
245661
|
return !!await fastify2.storage.projects.getById(session.project_id, userId);
|
|
245450
245662
|
}
|
|
245451
245663
|
|
|
245664
|
+
// src/utils/ws-heartbeat.ts
|
|
245665
|
+
var DEFAULT_INTERVAL_MS = 3e4;
|
|
245666
|
+
function attachWsHeartbeat(socket, { label, intervalMs = DEFAULT_INTERVAL_MS, keepalive = false }) {
|
|
245667
|
+
let awaitingPong = false;
|
|
245668
|
+
const markAlive = () => {
|
|
245669
|
+
awaitingPong = false;
|
|
245670
|
+
};
|
|
245671
|
+
socket.on("pong", markAlive);
|
|
245672
|
+
socket.on("message", markAlive);
|
|
245673
|
+
const timer = setInterval(() => {
|
|
245674
|
+
if (socket.readyState !== wrapper_default.OPEN) return;
|
|
245675
|
+
if (awaitingPong) {
|
|
245676
|
+
console.log(`[WsHeartbeat] ${label}: no pong within ${intervalMs * 2}ms \u2014 terminating dead socket`);
|
|
245677
|
+
try {
|
|
245678
|
+
socket.terminate();
|
|
245679
|
+
} catch {
|
|
245680
|
+
}
|
|
245681
|
+
return;
|
|
245682
|
+
}
|
|
245683
|
+
awaitingPong = true;
|
|
245684
|
+
try {
|
|
245685
|
+
socket.ping();
|
|
245686
|
+
} catch {
|
|
245687
|
+
}
|
|
245688
|
+
if (keepalive) {
|
|
245689
|
+
try {
|
|
245690
|
+
socket.send(JSON.stringify({ keepalive: Date.now() }));
|
|
245691
|
+
} catch {
|
|
245692
|
+
}
|
|
245693
|
+
}
|
|
245694
|
+
}, intervalMs);
|
|
245695
|
+
let cleaned = false;
|
|
245696
|
+
return () => {
|
|
245697
|
+
if (cleaned) return;
|
|
245698
|
+
cleaned = true;
|
|
245699
|
+
clearInterval(timer);
|
|
245700
|
+
socket.off("pong", markAlive);
|
|
245701
|
+
socket.off("message", markAlive);
|
|
245702
|
+
};
|
|
245703
|
+
}
|
|
245704
|
+
|
|
245452
245705
|
// src/routes/websocket-routes.ts
|
|
245453
|
-
var
|
|
245706
|
+
var routes24 = async (fastify2) => {
|
|
245454
245707
|
fastify2.reverseConnectManager.setStatusChangeHandler((remoteServerId, status) => {
|
|
245455
245708
|
if (status !== "online") return;
|
|
245456
245709
|
const cache2 = fastify2.remotePatchCache;
|
|
@@ -245507,10 +245760,14 @@ var routes23 = async (fastify2) => {
|
|
|
245507
245760
|
}
|
|
245508
245761
|
return;
|
|
245509
245762
|
}
|
|
245763
|
+
const stopHeartbeat = attachWsHeartbeat(socket, {
|
|
245764
|
+
label: `ProjectChatWS thread=${req.params.threadId}`
|
|
245765
|
+
});
|
|
245510
245766
|
let cleaned = false;
|
|
245511
245767
|
const cleanup = () => {
|
|
245512
245768
|
if (cleaned) return;
|
|
245513
245769
|
cleaned = true;
|
|
245770
|
+
stopHeartbeat();
|
|
245514
245771
|
unsubscribe();
|
|
245515
245772
|
};
|
|
245516
245773
|
socket.on("close", cleanup);
|
|
@@ -245542,11 +245799,9 @@ var routes23 = async (fastify2) => {
|
|
|
245542
245799
|
return;
|
|
245543
245800
|
}
|
|
245544
245801
|
console.log(`[WebSocket] Client connected for process ${processId}`);
|
|
245545
|
-
const
|
|
245546
|
-
|
|
245547
|
-
|
|
245548
|
-
}
|
|
245549
|
-
}, 3e4);
|
|
245802
|
+
const stopHeartbeat = attachWsHeartbeat(socket, {
|
|
245803
|
+
label: `ExecutorWS process=${processId}`
|
|
245804
|
+
});
|
|
245550
245805
|
const send = (msg) => {
|
|
245551
245806
|
try {
|
|
245552
245807
|
socket.send(JSON.stringify(msg));
|
|
@@ -245572,7 +245827,7 @@ var routes23 = async (fastify2) => {
|
|
|
245572
245827
|
});
|
|
245573
245828
|
socket.on("close", () => {
|
|
245574
245829
|
console.log(`[WebSocket] Client disconnected from process ${processId}`);
|
|
245575
|
-
|
|
245830
|
+
stopHeartbeat();
|
|
245576
245831
|
handle.cleanup();
|
|
245577
245832
|
});
|
|
245578
245833
|
}
|
|
@@ -245588,11 +245843,7 @@ var routes23 = async (fastify2) => {
|
|
|
245588
245843
|
return;
|
|
245589
245844
|
}
|
|
245590
245845
|
console.log(`[ExecutorMux] Client connected`);
|
|
245591
|
-
const
|
|
245592
|
-
if (socket.readyState === wrapper_default.OPEN) {
|
|
245593
|
-
socket.ping();
|
|
245594
|
-
}
|
|
245595
|
-
}, 3e4);
|
|
245846
|
+
const stopHeartbeat = attachWsHeartbeat(socket, { label: "ExecutorMux" });
|
|
245596
245847
|
const subs = /* @__PURE__ */ new Map();
|
|
245597
245848
|
const handleInputMap = /* @__PURE__ */ new Map();
|
|
245598
245849
|
const subscribeProcess = async (processId) => {
|
|
@@ -245651,7 +245902,7 @@ var routes23 = async (fastify2) => {
|
|
|
245651
245902
|
});
|
|
245652
245903
|
socket.on("close", () => {
|
|
245653
245904
|
console.log(`[ExecutorMux] Client disconnected; cleaning ${subs.size} subscriptions`);
|
|
245654
|
-
|
|
245905
|
+
stopHeartbeat();
|
|
245655
245906
|
for (const cleanup of subs.values()) cleanup();
|
|
245656
245907
|
subs.clear();
|
|
245657
245908
|
handleInputMap.clear();
|
|
@@ -245666,25 +245917,21 @@ var routes23 = async (fastify2) => {
|
|
|
245666
245917
|
console.log(`[AgentWS] Connection attempt for session ${sessionId} (auth=${fastify2.authEnabled})`);
|
|
245667
245918
|
let principalUserId = fastify2.authEnabled ? null : "local";
|
|
245668
245919
|
if (fastify2.authEnabled) {
|
|
245669
|
-
const apiKey = req.query.apiKey;
|
|
245670
245920
|
const token = req.query.token;
|
|
245671
|
-
|
|
245672
|
-
|
|
245673
|
-
|
|
245674
|
-
|
|
245675
|
-
|
|
245676
|
-
|
|
245677
|
-
|
|
245678
|
-
|
|
245679
|
-
|
|
245680
|
-
|
|
245681
|
-
|
|
245682
|
-
|
|
245683
|
-
socket.close();
|
|
245684
|
-
return;
|
|
245685
|
-
}
|
|
245686
|
-
principalUserId = userId;
|
|
245921
|
+
if (!token) {
|
|
245922
|
+
console.log(`[AgentWS] Auth rejected: no token (session=${sessionId})`);
|
|
245923
|
+
socket.send(JSON.stringify({ error: "Authentication required" }));
|
|
245924
|
+
socket.close();
|
|
245925
|
+
return;
|
|
245926
|
+
}
|
|
245927
|
+
const userId = await verifyWsToken(token);
|
|
245928
|
+
if (!userId) {
|
|
245929
|
+
console.log(`[AgentWS] Auth rejected: invalid token (session=${sessionId})`);
|
|
245930
|
+
socket.send(JSON.stringify({ error: "Invalid authentication token" }));
|
|
245931
|
+
socket.close();
|
|
245932
|
+
return;
|
|
245687
245933
|
}
|
|
245934
|
+
principalUserId = userId;
|
|
245688
245935
|
}
|
|
245689
245936
|
if (principalUserId !== null && !await userOwnsSession(fastify2, sessionId, principalUserId)) {
|
|
245690
245937
|
console.log(`[AgentWS] Ownership denied for session ${sessionId} (user=${principalUserId})`);
|
|
@@ -245699,15 +245946,15 @@ var routes23 = async (fastify2) => {
|
|
|
245699
245946
|
return;
|
|
245700
245947
|
}
|
|
245701
245948
|
console.log(`[AgentWS] Client connected for session ${sessionId}`);
|
|
245702
|
-
const
|
|
245703
|
-
|
|
245704
|
-
|
|
245705
|
-
|
|
245706
|
-
}, 3e4);
|
|
245949
|
+
const stopHeartbeat = attachWsHeartbeat(socket, {
|
|
245950
|
+
label: `AgentWS session=${sessionId}`,
|
|
245951
|
+
keepalive: true
|
|
245952
|
+
});
|
|
245707
245953
|
if (sessionId.startsWith("remote-")) {
|
|
245708
245954
|
const remoteInfo = fastify2.remoteSessionMap.get(sessionId);
|
|
245709
245955
|
if (!remoteInfo) {
|
|
245710
245956
|
console.log(`[AgentWS] Remote session ${sessionId} not found in map`);
|
|
245957
|
+
stopHeartbeat();
|
|
245711
245958
|
socket.send(JSON.stringify({ type: "error", message: "Remote session not found" }));
|
|
245712
245959
|
socket.close();
|
|
245713
245960
|
return;
|
|
@@ -245734,7 +245981,7 @@ var routes23 = async (fastify2) => {
|
|
|
245734
245981
|
}
|
|
245735
245982
|
cache2.addSubscriber(sessionId, socket);
|
|
245736
245983
|
socket.on("close", () => {
|
|
245737
|
-
|
|
245984
|
+
stopHeartbeat();
|
|
245738
245985
|
cache2.removeSubscriber(sessionId, socket);
|
|
245739
245986
|
});
|
|
245740
245987
|
return;
|
|
@@ -245775,7 +246022,7 @@ var routes23 = async (fastify2) => {
|
|
|
245775
246022
|
});
|
|
245776
246023
|
socket.on("close", () => {
|
|
245777
246024
|
console.log(`[AgentWS] Client disconnected from remote session ${sessionId}`);
|
|
245778
|
-
|
|
246025
|
+
stopHeartbeat();
|
|
245779
246026
|
cache2.removeSubscriber(sessionId, socket);
|
|
245780
246027
|
});
|
|
245781
246028
|
return;
|
|
@@ -245783,7 +246030,7 @@ var routes23 = async (fastify2) => {
|
|
|
245783
246030
|
const unsubscribe = fastify2.agentSessionManager.subscribe(sessionId, socket);
|
|
245784
246031
|
if (!unsubscribe) {
|
|
245785
246032
|
console.log(`[AgentWS] Session ${sessionId} not found`);
|
|
245786
|
-
|
|
246033
|
+
stopHeartbeat();
|
|
245787
246034
|
socket.send(JSON.stringify({ error: "Session not found" }));
|
|
245788
246035
|
socket.close();
|
|
245789
246036
|
return;
|
|
@@ -245802,7 +246049,7 @@ var routes23 = async (fastify2) => {
|
|
|
245802
246049
|
});
|
|
245803
246050
|
socket.on("close", () => {
|
|
245804
246051
|
console.log(`[AgentWS] Client disconnected from session ${sessionId}`);
|
|
245805
|
-
|
|
246052
|
+
stopHeartbeat();
|
|
245806
246053
|
unsubscribe?.();
|
|
245807
246054
|
});
|
|
245808
246055
|
}
|
|
@@ -245814,37 +246061,33 @@ var routes23 = async (fastify2) => {
|
|
|
245814
246061
|
const { sessionId } = req.params;
|
|
245815
246062
|
let principalUserId = fastify2.authEnabled ? null : "local";
|
|
245816
246063
|
if (fastify2.authEnabled) {
|
|
245817
|
-
const apiKey = req.query.apiKey;
|
|
245818
246064
|
const token = req.query.token;
|
|
245819
|
-
|
|
245820
|
-
|
|
245821
|
-
|
|
245822
|
-
|
|
245823
|
-
|
|
245824
|
-
socket.send(JSON.stringify({ error: "Authentication required" }));
|
|
245825
|
-
} catch {
|
|
245826
|
-
}
|
|
245827
|
-
try {
|
|
245828
|
-
socket.close();
|
|
245829
|
-
} catch {
|
|
245830
|
-
}
|
|
245831
|
-
return;
|
|
246065
|
+
if (!token) {
|
|
246066
|
+
console.log(`[ChatWS] Auth rejected: no token (session=${sessionId})`);
|
|
246067
|
+
try {
|
|
246068
|
+
socket.send(JSON.stringify({ error: "Authentication required" }));
|
|
246069
|
+
} catch {
|
|
245832
246070
|
}
|
|
245833
|
-
|
|
245834
|
-
|
|
245835
|
-
|
|
245836
|
-
|
|
245837
|
-
|
|
245838
|
-
|
|
245839
|
-
|
|
245840
|
-
|
|
245841
|
-
|
|
245842
|
-
|
|
245843
|
-
}
|
|
245844
|
-
|
|
246071
|
+
try {
|
|
246072
|
+
socket.close();
|
|
246073
|
+
} catch {
|
|
246074
|
+
}
|
|
246075
|
+
return;
|
|
246076
|
+
}
|
|
246077
|
+
const userId = await verifyWsToken(token);
|
|
246078
|
+
if (!userId) {
|
|
246079
|
+
console.log(`[ChatWS] Auth rejected: invalid token (session=${sessionId})`);
|
|
246080
|
+
try {
|
|
246081
|
+
socket.send(JSON.stringify({ error: "Invalid authentication token" }));
|
|
246082
|
+
} catch {
|
|
245845
246083
|
}
|
|
245846
|
-
|
|
246084
|
+
try {
|
|
246085
|
+
socket.close();
|
|
246086
|
+
} catch {
|
|
246087
|
+
}
|
|
246088
|
+
return;
|
|
245847
246089
|
}
|
|
246090
|
+
principalUserId = userId;
|
|
245848
246091
|
}
|
|
245849
246092
|
if (principalUserId !== null) {
|
|
245850
246093
|
const owned = fastify2.chatSessionManager.getSession(sessionId);
|
|
@@ -245862,15 +246105,11 @@ var routes23 = async (fastify2) => {
|
|
|
245862
246105
|
}
|
|
245863
246106
|
}
|
|
245864
246107
|
console.log(`[ChatWS] Client connected for session ${sessionId}`);
|
|
245865
|
-
const
|
|
245866
|
-
if (socket.readyState === wrapper_default.OPEN) {
|
|
245867
|
-
socket.ping();
|
|
245868
|
-
}
|
|
245869
|
-
}, 3e4);
|
|
246108
|
+
const stopHeartbeat = attachWsHeartbeat(socket, { label: `ChatWS session=${sessionId}` });
|
|
245870
246109
|
const unsubscribe = fastify2.chatSessionManager.subscribe(sessionId, socket);
|
|
245871
246110
|
if (!unsubscribe) {
|
|
245872
246111
|
console.log(`[ChatWS] Session ${sessionId} not found`);
|
|
245873
|
-
|
|
246112
|
+
stopHeartbeat();
|
|
245874
246113
|
socket.send(JSON.stringify({ error: "Session not found" }));
|
|
245875
246114
|
socket.close();
|
|
245876
246115
|
return;
|
|
@@ -245890,17 +246129,17 @@ var routes23 = async (fastify2) => {
|
|
|
245890
246129
|
});
|
|
245891
246130
|
socket.on("close", () => {
|
|
245892
246131
|
console.log(`[ChatWS] Client disconnected from session ${sessionId}`);
|
|
245893
|
-
|
|
246132
|
+
stopHeartbeat();
|
|
245894
246133
|
unsubscribe?.();
|
|
245895
246134
|
});
|
|
245896
246135
|
}
|
|
245897
246136
|
);
|
|
245898
246137
|
});
|
|
245899
246138
|
};
|
|
245900
|
-
var websocket_routes_default = (0,
|
|
246139
|
+
var websocket_routes_default = (0, import_fastify_plugin25.default)(routes24, { name: "websocket-routes" });
|
|
245901
246140
|
|
|
245902
246141
|
// src/routes/reverse-connect-routes.ts
|
|
245903
|
-
var
|
|
246142
|
+
var import_fastify_plugin26 = __toESM(require_plugin2(), 1);
|
|
245904
246143
|
import { randomBytes as randomBytes2, createHash as createHash7, verify as cryptoVerify } from "crypto";
|
|
245905
246144
|
|
|
245906
246145
|
// src/utils/rate-limited-warn.ts
|
|
@@ -245936,73 +246175,6 @@ function createRateLimitedWarn(windowMs, maxKeys) {
|
|
|
245936
246175
|
};
|
|
245937
246176
|
}
|
|
245938
246177
|
|
|
245939
|
-
// src/update-check.ts
|
|
245940
|
-
var SEMVER_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?$/;
|
|
245941
|
-
async function fetchLatestPublishedVersion(pkg = "vibedeckx", fetchImpl = fetch) {
|
|
245942
|
-
try {
|
|
245943
|
-
const response = await fetchImpl(
|
|
245944
|
-
`https://registry.npmjs.org/${pkg}/latest`,
|
|
245945
|
-
{ signal: AbortSignal.timeout(4e3) }
|
|
245946
|
-
);
|
|
245947
|
-
if (!response.ok) return void 0;
|
|
245948
|
-
const body = await response.json();
|
|
245949
|
-
return typeof body.version === "string" && parseSemver(body.version) ? body.version : void 0;
|
|
245950
|
-
} catch {
|
|
245951
|
-
return void 0;
|
|
245952
|
-
}
|
|
245953
|
-
}
|
|
245954
|
-
function parseSemver(version2) {
|
|
245955
|
-
const match2 = SEMVER_RE.exec(version2);
|
|
245956
|
-
if (!match2) return void 0;
|
|
245957
|
-
return {
|
|
245958
|
-
core: [match2[1], match2[2], match2[3]],
|
|
245959
|
-
prerelease: match2[4]?.split(".")
|
|
245960
|
-
};
|
|
245961
|
-
}
|
|
245962
|
-
function compareNumericStrings(a, b2) {
|
|
245963
|
-
if (a.length !== b2.length) return a.length - b2.length;
|
|
245964
|
-
return a < b2 ? -1 : a > b2 ? 1 : 0;
|
|
245965
|
-
}
|
|
245966
|
-
function comparePrereleaseIdentifiers(a, b2) {
|
|
245967
|
-
const aNumeric = /^\d+$/.test(a);
|
|
245968
|
-
const bNumeric = /^\d+$/.test(b2);
|
|
245969
|
-
if (aNumeric && bNumeric) return compareNumericStrings(a, b2);
|
|
245970
|
-
if (aNumeric !== bNumeric) return aNumeric ? -1 : 1;
|
|
245971
|
-
return a < b2 ? -1 : a > b2 ? 1 : 0;
|
|
245972
|
-
}
|
|
245973
|
-
function compareSemver(a, b2) {
|
|
245974
|
-
for (let i = 0; i < 3; i += 1) {
|
|
245975
|
-
const compared = compareNumericStrings(a.core[i], b2.core[i]);
|
|
245976
|
-
if (compared !== 0) return compared;
|
|
245977
|
-
}
|
|
245978
|
-
if (!a.prerelease && !b2.prerelease) return 0;
|
|
245979
|
-
if (!a.prerelease) return 1;
|
|
245980
|
-
if (!b2.prerelease) return -1;
|
|
245981
|
-
const length = Math.max(a.prerelease.length, b2.prerelease.length);
|
|
245982
|
-
for (let i = 0; i < length; i += 1) {
|
|
245983
|
-
const aId = a.prerelease[i];
|
|
245984
|
-
const bId = b2.prerelease[i];
|
|
245985
|
-
if (aId === void 0) return -1;
|
|
245986
|
-
if (bId === void 0) return 1;
|
|
245987
|
-
const compared = comparePrereleaseIdentifiers(aId, bId);
|
|
245988
|
-
if (compared !== 0) return compared;
|
|
245989
|
-
}
|
|
245990
|
-
return 0;
|
|
245991
|
-
}
|
|
245992
|
-
function compareVersionStrings(a, b2) {
|
|
245993
|
-
const parsedA = parseSemver(a);
|
|
245994
|
-
const parsedB = parseSemver(b2);
|
|
245995
|
-
if (!parsedA || !parsedB) return void 0;
|
|
245996
|
-
return compareSemver(parsedA, parsedB);
|
|
245997
|
-
}
|
|
245998
|
-
function compareUpdateStatus(current, latest) {
|
|
245999
|
-
if (latest === void 0) return "unknown";
|
|
246000
|
-
const currentParsed = parseSemver(current);
|
|
246001
|
-
const latestParsed = parseSemver(latest);
|
|
246002
|
-
if (!currentParsed || !latestParsed) return "unknown";
|
|
246003
|
-
return compareSemver(latestParsed, currentParsed) > 0 ? "update-available" : "up-to-date";
|
|
246004
|
-
}
|
|
246005
|
-
|
|
246006
246178
|
// src/routes/reverse-connect-routes.ts
|
|
246007
246179
|
function extractReportedVersion(frame) {
|
|
246008
246180
|
if (typeof frame.version !== "string" || frame.version.length === 0) return void 0;
|
|
@@ -246012,7 +246184,7 @@ function extractReportedVersion(frame) {
|
|
|
246012
246184
|
var MACHINE_HANDSHAKE_TIMEOUT_MS = 5e3;
|
|
246013
246185
|
var REJECT_LOG_WINDOW_MS = 3e4;
|
|
246014
246186
|
var REJECT_LOG_MAX_KEYS = 500;
|
|
246015
|
-
var
|
|
246187
|
+
var routes25 = async (fastify2) => {
|
|
246016
246188
|
const logRejectedUpgrade = createRateLimitedWarn(REJECT_LOG_WINDOW_MS, REJECT_LOG_MAX_KEYS);
|
|
246017
246189
|
fastify2.get("/api/reverse-connect/identity", async (req, reply) => {
|
|
246018
246190
|
const token = req.headers["x-vibedeckx-connect-token"];
|
|
@@ -246059,7 +246231,11 @@ var routes24 = async (fastify2) => {
|
|
|
246059
246231
|
console.log(`[ReverseConnect] Worker ${serverId} reported no version (pre-reporting release)`);
|
|
246060
246232
|
return;
|
|
246061
246233
|
}
|
|
246234
|
+
const previous = (await fastify2.storage.remoteServers.getById(serverId))?.worker_version;
|
|
246062
246235
|
await fastify2.storage.remoteServers.updateWorkerVersion(serverId, reported.version, reported.capabilities);
|
|
246236
|
+
if (previous !== reported.version) {
|
|
246237
|
+
console.log(`[ReverseConnect] Worker ${serverId} version ${previous ?? "unreported"} \u2192 ${reported.version}`);
|
|
246238
|
+
}
|
|
246063
246239
|
const cmp = compareVersionStrings(reported.version, MIN_WORKER_VERSION);
|
|
246064
246240
|
if (cmp !== void 0 && cmp < 0) {
|
|
246065
246241
|
console.warn(
|
|
@@ -246142,10 +246318,10 @@ var routes24 = async (fastify2) => {
|
|
|
246142
246318
|
);
|
|
246143
246319
|
});
|
|
246144
246320
|
};
|
|
246145
|
-
var reverse_connect_routes_default = (0,
|
|
246321
|
+
var reverse_connect_routes_default = (0, import_fastify_plugin26.default)(routes25, { name: "reverse-connect-routes" });
|
|
246146
246322
|
|
|
246147
246323
|
// src/routes/event-routes.ts
|
|
246148
|
-
var
|
|
246324
|
+
var import_fastify_plugin27 = __toESM(require_plugin2(), 1);
|
|
246149
246325
|
function toWireEvent(event) {
|
|
246150
246326
|
if (event.type === "executor:stopped" && (event.tailOutput !== void 0 || event.finalResult !== void 0)) {
|
|
246151
246327
|
const { tailOutput: _tailOutput, finalResult: _finalResult, ...rest } = event;
|
|
@@ -246153,31 +246329,28 @@ function toWireEvent(event) {
|
|
|
246153
246329
|
}
|
|
246154
246330
|
return event;
|
|
246155
246331
|
}
|
|
246156
|
-
var
|
|
246332
|
+
var routes26 = async (fastify2) => {
|
|
246157
246333
|
fastify2.get("/api/events", async (req, reply) => {
|
|
246158
246334
|
let userId = null;
|
|
246159
246335
|
if (fastify2.authEnabled) {
|
|
246160
|
-
const
|
|
246161
|
-
if (!
|
|
246162
|
-
|
|
246163
|
-
|
|
246164
|
-
|
|
246165
|
-
}
|
|
246166
|
-
|
|
246167
|
-
|
|
246168
|
-
|
|
246169
|
-
|
|
246170
|
-
|
|
246171
|
-
});
|
|
246172
|
-
if (!payload.sub) {
|
|
246173
|
-
return reply.code(401).send({ error: "Unauthorized" });
|
|
246174
|
-
}
|
|
246175
|
-
userId = payload.sub;
|
|
246176
|
-
} catch (err) {
|
|
246177
|
-
const reason = err?.reason;
|
|
246178
|
-
if (reason) console.log(`[EventsSSE] token verification failed: ${reason}`);
|
|
246336
|
+
const token = req.query.token;
|
|
246337
|
+
if (!token) {
|
|
246338
|
+
return reply.code(401).send({ error: "Unauthorized" });
|
|
246339
|
+
}
|
|
246340
|
+
try {
|
|
246341
|
+
const { verifyToken: verifyToken3 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
246342
|
+
const payload = await verifyToken3(token, {
|
|
246343
|
+
secretKey: process.env.CLERK_SECRET_KEY,
|
|
246344
|
+
clockSkewInMs: CLERK_CLOCK_SKEW_MS
|
|
246345
|
+
});
|
|
246346
|
+
if (!payload.sub) {
|
|
246179
246347
|
return reply.code(401).send({ error: "Unauthorized" });
|
|
246180
246348
|
}
|
|
246349
|
+
userId = payload.sub;
|
|
246350
|
+
} catch (err) {
|
|
246351
|
+
const reason = err?.reason;
|
|
246352
|
+
if (reason) console.log(`[EventsSSE] token verification failed: ${reason}`);
|
|
246353
|
+
return reply.code(401).send({ error: "Unauthorized" });
|
|
246181
246354
|
}
|
|
246182
246355
|
}
|
|
246183
246356
|
reply.raw.writeHead(200, {
|
|
@@ -246211,10 +246384,10 @@ var routes25 = async (fastify2) => {
|
|
|
246211
246384
|
await reply;
|
|
246212
246385
|
});
|
|
246213
246386
|
};
|
|
246214
|
-
var event_routes_default = (0,
|
|
246387
|
+
var event_routes_default = (0, import_fastify_plugin27.default)(routes26, { name: "event-routes" });
|
|
246215
246388
|
|
|
246216
246389
|
// src/routes/terminal-routes.ts
|
|
246217
|
-
var
|
|
246390
|
+
var import_fastify_plugin28 = __toESM(require_plugin2(), 1);
|
|
246218
246391
|
import path13 from "path";
|
|
246219
246392
|
|
|
246220
246393
|
// src/utils/path-project.ts
|
|
@@ -246242,7 +246415,7 @@ async function getRemoteConfig5(fastify2, project, remoteServerId) {
|
|
|
246242
246415
|
remotePath: target.remote_path
|
|
246243
246416
|
};
|
|
246244
246417
|
}
|
|
246245
|
-
var
|
|
246418
|
+
var routes27 = async (fastify2) => {
|
|
246246
246419
|
fastify2.post("/api/path/terminals", async (req, reply) => {
|
|
246247
246420
|
const { path: projectPath, branch } = req.body;
|
|
246248
246421
|
if (!projectPath) {
|
|
@@ -246418,11 +246591,11 @@ var routes26 = async (fastify2) => {
|
|
|
246418
246591
|
}
|
|
246419
246592
|
);
|
|
246420
246593
|
};
|
|
246421
|
-
var terminal_routes_default = (0,
|
|
246594
|
+
var terminal_routes_default = (0, import_fastify_plugin28.default)(routes27, { name: "terminal-routes" });
|
|
246422
246595
|
|
|
246423
246596
|
// src/routes/browser-routes.ts
|
|
246424
|
-
var
|
|
246425
|
-
var
|
|
246597
|
+
var import_fastify_plugin29 = __toESM(require_plugin2(), 1);
|
|
246598
|
+
var routes28 = async (fastify2) => {
|
|
246426
246599
|
const ensureProjectAccess = async (req, reply) => {
|
|
246427
246600
|
const userId = requireUserFacingUserId(req, reply);
|
|
246428
246601
|
if (userId === null) return null;
|
|
@@ -246493,10 +246666,10 @@ var routes27 = async (fastify2) => {
|
|
|
246493
246666
|
return reply.code(200).send({ ok: true });
|
|
246494
246667
|
});
|
|
246495
246668
|
};
|
|
246496
|
-
var browser_routes_default = (0,
|
|
246669
|
+
var browser_routes_default = (0, import_fastify_plugin29.default)(routes28, { name: "browser-routes" });
|
|
246497
246670
|
|
|
246498
246671
|
// src/routes/browser-proxy-routes.ts
|
|
246499
|
-
var
|
|
246672
|
+
var import_fastify_plugin30 = __toESM(require_plugin2(), 1);
|
|
246500
246673
|
import { randomUUID as randomUUID21 } from "crypto";
|
|
246501
246674
|
|
|
246502
246675
|
// src/utils/ssrf-guard.ts
|
|
@@ -246992,7 +247165,7 @@ function generateInjectedScript(projectId, targetOrigin, proxyWsPrefix) {
|
|
|
246992
247165
|
})();
|
|
246993
247166
|
</script>`;
|
|
246994
247167
|
}
|
|
246995
|
-
var
|
|
247168
|
+
var routes29 = async (fastify2) => {
|
|
246996
247169
|
fastify2.get("/api/projects/:id/browser/proxy/*", async (req, reply) => {
|
|
246997
247170
|
const userId = requireUserFacingOrTrustedProxyUserId(req, reply);
|
|
246998
247171
|
if (userId === null) return;
|
|
@@ -247061,7 +247234,7 @@ var routes28 = async (fastify2) => {
|
|
|
247061
247234
|
const { id: projectId } = req.params;
|
|
247062
247235
|
const principal = await authenticateWs(fastify2.authEnabled, req.query, socket);
|
|
247063
247236
|
if (!principal) return;
|
|
247064
|
-
const projectOwner = principal.
|
|
247237
|
+
const projectOwner = principal.userId ?? "local";
|
|
247065
247238
|
if (!await fastify2.storage.projects.getById(projectId, projectOwner)) {
|
|
247066
247239
|
try {
|
|
247067
247240
|
socket.send(JSON.stringify({ error: "Forbidden" }));
|
|
@@ -247164,10 +247337,10 @@ var routes28 = async (fastify2) => {
|
|
|
247164
247337
|
});
|
|
247165
247338
|
});
|
|
247166
247339
|
};
|
|
247167
|
-
var browser_proxy_routes_default = (0,
|
|
247340
|
+
var browser_proxy_routes_default = (0, import_fastify_plugin30.default)(routes29, { name: "browser-proxy-routes" });
|
|
247168
247341
|
|
|
247169
247342
|
// src/routes/cross-remote-target-routes.ts
|
|
247170
|
-
var
|
|
247343
|
+
var import_fastify_plugin31 = __toESM(require_plugin2(), 1);
|
|
247171
247344
|
import path14 from "path";
|
|
247172
247345
|
import { promises as fs3 } from "fs";
|
|
247173
247346
|
|
|
@@ -247247,7 +247420,7 @@ var clampTimeoutMs = (timeoutSec) => {
|
|
|
247247
247420
|
const requested = typeof timeoutSec === "number" && Number.isFinite(timeoutSec) && timeoutSec > 0 ? timeoutSec : DEFAULT_TIMEOUT_SEC;
|
|
247248
247421
|
return Math.min(requested, MAX_TIMEOUT_SEC) * 1e3;
|
|
247249
247422
|
};
|
|
247250
|
-
var
|
|
247423
|
+
var routes30 = async (fastify2) => {
|
|
247251
247424
|
fastify2.post(
|
|
247252
247425
|
"/api/path/cross-remote/exec",
|
|
247253
247426
|
async (request, reply) => {
|
|
@@ -247355,10 +247528,10 @@ var routes29 = async (fastify2) => {
|
|
|
247355
247528
|
return reply.send(result);
|
|
247356
247529
|
});
|
|
247357
247530
|
};
|
|
247358
|
-
var cross_remote_target_routes_default = (0,
|
|
247531
|
+
var cross_remote_target_routes_default = (0, import_fastify_plugin31.default)(routes30, { name: "cross-remote-target-routes" });
|
|
247359
247532
|
|
|
247360
247533
|
// src/routes/cross-remote-mcp-routes.ts
|
|
247361
|
-
var
|
|
247534
|
+
var import_fastify_plugin32 = __toESM(require_plugin2(), 1);
|
|
247362
247535
|
var PROTOCOL_VERSION = "2024-11-05";
|
|
247363
247536
|
var AUDIT_ARGS_MAX = 1024;
|
|
247364
247537
|
var NOT_ACCESSIBLE = "remote not found or not accessible";
|
|
@@ -247461,7 +247634,7 @@ var textResult = (text2, isError = false) => ({
|
|
|
247461
247634
|
content: [{ type: "text", text: text2 }],
|
|
247462
247635
|
...isError ? { isError: true } : {}
|
|
247463
247636
|
});
|
|
247464
|
-
var
|
|
247637
|
+
var routes31 = async (fastify2) => {
|
|
247465
247638
|
const guard = new SessionConcurrencyGuard();
|
|
247466
247639
|
let cachedSecret;
|
|
247467
247640
|
const getSecret = () => {
|
|
@@ -247582,10 +247755,10 @@ var routes30 = async (fastify2) => {
|
|
|
247582
247755
|
}
|
|
247583
247756
|
});
|
|
247584
247757
|
};
|
|
247585
|
-
var cross_remote_mcp_routes_default = (0,
|
|
247758
|
+
var cross_remote_mcp_routes_default = (0, import_fastify_plugin32.default)(routes31, { name: "cross-remote-mcp-routes" });
|
|
247586
247759
|
|
|
247587
247760
|
// src/routes/schedule-routes.ts
|
|
247588
|
-
var
|
|
247761
|
+
var import_fastify_plugin33 = __toESM(require_plugin2(), 1);
|
|
247589
247762
|
import { randomUUID as randomUUID22 } from "crypto";
|
|
247590
247763
|
import path15 from "path";
|
|
247591
247764
|
var RUN_TYPES = ["command", "prompt"];
|
|
@@ -247604,7 +247777,7 @@ function validateResolved(b2) {
|
|
|
247604
247777
|
if (cronError) return `Invalid cron expression: ${cronError}`;
|
|
247605
247778
|
return null;
|
|
247606
247779
|
}
|
|
247607
|
-
var
|
|
247780
|
+
var routes32 = async (fastify2) => {
|
|
247608
247781
|
const sendTerminalManualOutcome = (reply, request, replay) => {
|
|
247609
247782
|
if (!request.terminalStatus || request.terminalResponseStatus === null) return null;
|
|
247610
247783
|
const common = { runId: request.runId, status: request.terminalStatus, durable: true, replay };
|
|
@@ -247835,10 +248008,10 @@ var routes31 = async (fastify2) => {
|
|
|
247835
248008
|
}
|
|
247836
248009
|
);
|
|
247837
248010
|
};
|
|
247838
|
-
var schedule_routes_default = (0,
|
|
248011
|
+
var schedule_routes_default = (0, import_fastify_plugin33.default)(routes32, { name: "schedule-routes" });
|
|
247839
248012
|
|
|
247840
248013
|
// src/search/catalog.ts
|
|
247841
|
-
var
|
|
248014
|
+
var parseDbTimestamp5 = (ts) => {
|
|
247842
248015
|
if (!ts) return null;
|
|
247843
248016
|
const ms = Date.parse(ts.replace(" ", "T") + "Z");
|
|
247844
248017
|
return Number.isNaN(ms) ? null : ms;
|
|
@@ -247860,7 +248033,7 @@ async function buildSearchCatalog(deps, projectId, projectPath) {
|
|
|
247860
248033
|
id: s3.id,
|
|
247861
248034
|
branch: s3.branch === "" ? null : s3.branch,
|
|
247862
248035
|
title: s3.title ?? null,
|
|
247863
|
-
lastActiveAt: s3.last_user_message_at ??
|
|
248036
|
+
lastActiveAt: s3.last_user_message_at ?? parseDbTimestamp5(s3.updated_at),
|
|
247864
248037
|
favoritedAt: s3.favorited_at ?? null,
|
|
247865
248038
|
entryCount,
|
|
247866
248039
|
status: s3.status,
|
|
@@ -248127,10 +248300,10 @@ var searchRoutes = async (fastify2) => {
|
|
|
248127
248300
|
var search_routes_default = searchRoutes;
|
|
248128
248301
|
|
|
248129
248302
|
// src/routes/notification-routes.ts
|
|
248130
|
-
var
|
|
248303
|
+
var import_fastify_plugin34 = __toESM(require_plugin2(), 1);
|
|
248131
248304
|
var MAX_LIMIT = 500;
|
|
248132
248305
|
var DEFAULT_LIMIT = 100;
|
|
248133
|
-
var
|
|
248306
|
+
var routes33 = async (fastify2) => {
|
|
248134
248307
|
fastify2.get(
|
|
248135
248308
|
"/api/notifications",
|
|
248136
248309
|
async (req, reply) => {
|
|
@@ -248162,7 +248335,7 @@ var routes32 = async (fastify2) => {
|
|
|
248162
248335
|
return reply.code(200).send({ ok: true });
|
|
248163
248336
|
});
|
|
248164
248337
|
};
|
|
248165
|
-
var notification_routes_default = (0,
|
|
248338
|
+
var notification_routes_default = (0, import_fastify_plugin34.default)(routes33, { name: "notification-routes" });
|
|
248166
248339
|
|
|
248167
248340
|
// ../../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
|
|
248168
248341
|
import { Readable as Readable2 } from "stream";
|
|
@@ -248214,7 +248387,7 @@ var requestToProxyRequest = (req) => {
|
|
|
248214
248387
|
|
|
248215
248388
|
// ../../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
|
|
248216
248389
|
init_dist();
|
|
248217
|
-
var
|
|
248390
|
+
var import_fastify_plugin35 = __toESM(require_plugin2(), 1);
|
|
248218
248391
|
|
|
248219
248392
|
// ../../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
|
|
248220
248393
|
init_chunk_JW73PKED();
|
|
@@ -248502,7 +248675,7 @@ var plugin = (instance, opts, done) => {
|
|
|
248502
248675
|
instance.addHook(hookName, withClerkMiddleware(opts));
|
|
248503
248676
|
done();
|
|
248504
248677
|
};
|
|
248505
|
-
var clerkPlugin = (0,
|
|
248678
|
+
var clerkPlugin = (0, import_fastify_plugin35.default)(plugin, {
|
|
248506
248679
|
name: "@clerk/fastify",
|
|
248507
248680
|
fastify: "5.x"
|
|
248508
248681
|
});
|
|
@@ -249250,12 +249423,10 @@ async function shutdownLogging() {
|
|
|
249250
249423
|
}
|
|
249251
249424
|
|
|
249252
249425
|
// src/server.ts
|
|
249253
|
-
var
|
|
249426
|
+
var API_KEY2 = process.env.VIBEDECKX_API_KEY || void 0;
|
|
249254
249427
|
function requireAuth(req, reply) {
|
|
249255
249428
|
const server = req.server;
|
|
249256
249429
|
if (!server.authEnabled) return void 0;
|
|
249257
|
-
const apiKeyHeader = req.headers["x-vibedeckx-api-key"];
|
|
249258
|
-
if (API_KEY && apiKeyHeader) return void 0;
|
|
249259
249430
|
try {
|
|
249260
249431
|
const { userId } = getAuth(req);
|
|
249261
249432
|
if (!userId) {
|
|
@@ -249342,19 +249513,12 @@ var createServer = async (opts) => {
|
|
|
249342
249513
|
done();
|
|
249343
249514
|
});
|
|
249344
249515
|
server.addHook("onRequest", (req, reply, done) => {
|
|
249345
|
-
if (!
|
|
249346
|
-
if (!req.url.startsWith("/api/")) return done();
|
|
249516
|
+
if (!API_KEY2) return done();
|
|
249517
|
+
if (!req.url.startsWith("/api/admin/")) return done();
|
|
249347
249518
|
if (req.method === "OPTIONS") return done();
|
|
249348
|
-
const pathname = req.url.split("?")[0];
|
|
249349
|
-
if (pathname === "/api/config" || pathname === "/api/reverse-connect" || pathname === "/api/reverse-connect/identity") {
|
|
249350
|
-
return done();
|
|
249351
|
-
}
|
|
249352
249519
|
const providedKey = req.headers["x-vibedeckx-api-key"] || req.query?.apiKey;
|
|
249353
|
-
if (
|
|
249354
|
-
return
|
|
249355
|
-
}
|
|
249356
|
-
if (providedKey !== API_KEY) {
|
|
249357
|
-
return reply.code(401).send({ error: "Unauthorized" });
|
|
249520
|
+
if (providedKey !== API_KEY2) {
|
|
249521
|
+
return reply.code(404).send({ error: "Not found" });
|
|
249358
249522
|
}
|
|
249359
249523
|
done();
|
|
249360
249524
|
});
|
|
@@ -249430,6 +249594,7 @@ var createServer = async (opts) => {
|
|
|
249430
249594
|
server.register(reverse_connect_routes_default);
|
|
249431
249595
|
server.register(project_routes_default);
|
|
249432
249596
|
server.register(remote_server_routes_default);
|
|
249597
|
+
server.register(worker_stats_routes_default);
|
|
249433
249598
|
server.register(project_remote_routes_default);
|
|
249434
249599
|
server.register(search_routes_default);
|
|
249435
249600
|
server.register(executor_group_routes_default);
|
|
@@ -249919,14 +250084,10 @@ var ReverseConnectClient = class {
|
|
|
249919
250084
|
});
|
|
249920
250085
|
body = await response.text();
|
|
249921
250086
|
} else {
|
|
249922
|
-
const injectHeaders = { ...frame.headers ?? {} };
|
|
249923
|
-
if (process.env.VIBEDECKX_API_KEY) {
|
|
249924
|
-
injectHeaders["x-vibedeckx-api-key"] = process.env.VIBEDECKX_API_KEY;
|
|
249925
|
-
}
|
|
249926
250087
|
const response = await this.localServer.inject({
|
|
249927
250088
|
method: frame.method,
|
|
249928
250089
|
url: frame.path,
|
|
249929
|
-
headers:
|
|
250090
|
+
headers: frame.headers ?? {},
|
|
249930
250091
|
payload: frame.body
|
|
249931
250092
|
});
|
|
249932
250093
|
status = response.statusCode;
|
|
@@ -249966,11 +250127,7 @@ var ReverseConnectClient = class {
|
|
|
249966
250127
|
}
|
|
249967
250128
|
}
|
|
249968
250129
|
handleWsOpen(frame) {
|
|
249969
|
-
const
|
|
249970
|
-
...frame.query ? [frame.query] : [],
|
|
249971
|
-
...process.env.VIBEDECKX_API_KEY ? [`apiKey=${encodeURIComponent(process.env.VIBEDECKX_API_KEY)}`] : []
|
|
249972
|
-
];
|
|
249973
|
-
const wsUrl = `ws://127.0.0.1:${this.localPort}${frame.path}${queryParts.length ? `?${queryParts.join("&")}` : ""}`;
|
|
250130
|
+
const wsUrl = `ws://127.0.0.1:${this.localPort}${frame.path}${frame.query ? `?${frame.query}` : ""}`;
|
|
249974
250131
|
console.log(`[ReverseClient] Opening local WS channel ${frame.channelId} \u2192 ${frame.path}`);
|
|
249975
250132
|
const localWs = new wrapper_default(wsUrl);
|
|
249976
250133
|
localWs.on("open", () => {
|
|
@@ -251477,7 +251634,7 @@ var startCommand = buildCommand({
|
|
|
251477
251634
|
host: {
|
|
251478
251635
|
kind: "parsed",
|
|
251479
251636
|
parse: String,
|
|
251480
|
-
brief: "Network interface to bind (default: 127.0.0.1, loopback only). Use 0.0.0.0 to expose on all interfaces \u2014 only do so behind --auth
|
|
251637
|
+
brief: "Network interface to bind (default: 127.0.0.1, loopback only). Use 0.0.0.0 to expose on all interfaces \u2014 only do so behind --auth or an authenticating proxy.",
|
|
251481
251638
|
optional: true
|
|
251482
251639
|
},
|
|
251483
251640
|
auth: {
|
|
@@ -251548,11 +251705,16 @@ var startCommand = buildCommand({
|
|
|
251548
251705
|
const noLocalProjects = flags["no-local-projects"] ?? false;
|
|
251549
251706
|
const tls = loadTLSOptions(flags);
|
|
251550
251707
|
const isLoopbackHost = host === "127.0.0.1" || host === "::1" || host === "localhost";
|
|
251551
|
-
if (!isLoopbackHost && !authEnabled
|
|
251708
|
+
if (!isLoopbackHost && !authEnabled) {
|
|
251552
251709
|
console.warn(
|
|
251553
251710
|
`Warning: binding to ${host} exposes vibedeckx on the network with no authentication.
|
|
251554
|
-
Anyone who can reach this host can run commands via the executor API. Enable --auth or
|
|
251555
|
-
|
|
251711
|
+
Anyone who can reach this host can run commands via the executor API. Enable --auth, or put
|
|
251712
|
+
an authenticating proxy in front, or keep the default loopback bind (127.0.0.1).`
|
|
251713
|
+
);
|
|
251714
|
+
}
|
|
251715
|
+
if (process.env.VIBEDECKX_API_KEY) {
|
|
251716
|
+
console.log(
|
|
251717
|
+
"VIBEDECKX_API_KEY is set: it authenticates operator-only endpoints (/api/admin/*).\nIt does not lock the rest of the API and is not user authentication \u2014 use --auth or a\nproxy in front for that."
|
|
251556
251718
|
);
|
|
251557
251719
|
}
|
|
251558
251720
|
console.log(`Starting vibedeckx${tls ? " (HTTPS)" : ""}...`);
|
|
@@ -251828,7 +251990,7 @@ var connectRoutes = buildRouteMap({
|
|
|
251828
251990
|
defaultCommand: "run",
|
|
251829
251991
|
docs: { brief: "Connect to a Vibedeckx server as an inbound node" }
|
|
251830
251992
|
});
|
|
251831
|
-
var
|
|
251993
|
+
var routes34 = buildRouteMap({
|
|
251832
251994
|
routes: {
|
|
251833
251995
|
start: startCommand,
|
|
251834
251996
|
connect: connectRoutes
|
|
@@ -251838,7 +252000,7 @@ var routes33 = buildRouteMap({
|
|
|
251838
252000
|
brief: "Vibedeckx - AI-powered app generator"
|
|
251839
252001
|
}
|
|
251840
252002
|
});
|
|
251841
|
-
var program = buildApplication(
|
|
252003
|
+
var program = buildApplication(routes34, {
|
|
251842
252004
|
name: "vibedeckx",
|
|
251843
252005
|
versionInfo: {
|
|
251844
252006
|
currentVersion: readPackageVersion()
|