@vibedeckx/linux-x64 0.2.11 → 0.2.13
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 +200 -6
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -229047,6 +229047,7 @@ function buildReviewerPrompt(opts) {
|
|
|
229047
229047
|
const brief = opts.intentBrief || null;
|
|
229048
229048
|
const hasExcerpt = Boolean(intent || opts.taskContext || opts.authorSelfReport);
|
|
229049
229049
|
const scope = opts.scope && opts.scope.changedFiles.length > 0 ? opts.scope : null;
|
|
229050
|
+
const noDiffWithAnalysis = Boolean(opts.authorSelfReport) && opts.authorSelfReport.trim().length >= SELF_REPORT_MIN_CHARS;
|
|
229050
229051
|
return [
|
|
229051
229052
|
"You are a code reviewer agent. Another agent just completed work in this workspace; review it critically and independently.",
|
|
229052
229053
|
brief ? `
|
|
@@ -229067,15 +229068,18 @@ ${opts.taskContext}` : null,
|
|
|
229067
229068
|
${opts.reviewFocus}` : null,
|
|
229068
229069
|
scope ? `
|
|
229069
229070
|
## Scope \u2014 the change under review
|
|
229071
|
+
|
|
229070
229072
|
The reviewed turn changed exactly these files:
|
|
229071
229073
|
${scope.changedFiles.map((f2) => `- ${f2}`).join("\n")}
|
|
229074
|
+
|
|
229072
229075
|
It starts from commit \`${scope.startHead}\` \u2014 use \`git diff ${scope.startHead} -- <file>\` and \`git log ${scope.startHead}..HEAD\` to see the content.
|
|
229073
|
-
|
|
229076
|
+
|
|
229077
|
+
Confine your review to these files and changes. Other uncommitted or pre-existing changes in the worktree, or changes from other turns, are out of scope unless this change depends on them.` : opts.scope != null && opts.scope.changedFiles.length === 0 ? noDiffWithAnalysis ? "\n## Scope \u2014 the change under review\n\nThe reviewed turn changed no files. Its deliverable is the analysis and proposed approach in the author self-report above, not a diff \u2014 review THAT. Verify the diagnosis against the actual code: are the cited files/lines real and the described mechanism correct? Then stress-test the proposed fix as a plan, before implementation \u2014 correctness, side-effects, and completeness. If you instead conclude the turn should have produced a code change and didn't, say so. Do not review unrelated uncommitted or pre-existing changes in the worktree." : "\n## Scope \u2014 the change under review\n\nThe reviewed turn changed no files. Do not review unrelated uncommitted or pre-existing changes in the worktree \u2014 there is nothing in scope for this turn. If you believe the turn should have changed something, say so rather than reviewing out-of-scope code." : opts.scope === null ? "\n## Scope\n\nThe changed-file set could not be determined (scope unknown) \u2014 inspect `git diff`/`git status`/`git log` and judge the relevant range yourself." : null,
|
|
229074
229078
|
"\n## How to review",
|
|
229075
229079
|
"- Do NOT modify any files \u2014 you are in read-only review mode.",
|
|
229076
229080
|
"- Inspect the actual workspace state yourself: read the relevant files, run `git diff`, `git status` and `git log`.",
|
|
229077
229081
|
reviewTargetPromptLine(opts.target),
|
|
229078
|
-
"- Judge correctness, completeness against the task, and code quality. Be specific: reference files and lines.",
|
|
229082
|
+
noDiffWithAnalysis ? "- Judge correctness and completeness against the task. For this analysis/plan turn the work under review is the reasoning and the proposal, not code quality of a diff. Be specific: reference files and lines." : "- Judge correctness, completeness against the task, and code quality. Be specific: reference files and lines.",
|
|
229079
229083
|
"\nEnd your final message with a clear, actionable list of feedback items \u2014 or state explicitly that the work looks good.",
|
|
229080
229084
|
brief ? opts.authorSelfReport ? "\n(review context: distilled intent brief + author self-report + live workspace)" : "\n(review context: distilled intent brief + live workspace)" : hasExcerpt ? "\n(review context: deterministic excerpt of the source conversation + live workspace)" : "\n(review context: live workspace only \u2014 the source conversation was unavailable)"
|
|
229081
229085
|
].filter((l) => l !== null).join("\n");
|
|
@@ -238006,6 +238010,20 @@ var import_fastify_plugin23 = __toESM(require_plugin2(), 1);
|
|
|
238006
238010
|
import { randomBytes as randomBytes2, createHash as createHash3, verify as cryptoVerify } from "crypto";
|
|
238007
238011
|
var MACHINE_HANDSHAKE_TIMEOUT_MS = 5e3;
|
|
238008
238012
|
var routes22 = async (fastify2) => {
|
|
238013
|
+
fastify2.get("/api/reverse-connect/identity", async (req, reply) => {
|
|
238014
|
+
const token = req.headers["x-vibedeckx-connect-token"];
|
|
238015
|
+
if (typeof token !== "string" || token.length === 0) {
|
|
238016
|
+
return reply.code(401).send({ error: "Connect token required" });
|
|
238017
|
+
}
|
|
238018
|
+
const server = await fastify2.storage.remoteServers.getByToken(token);
|
|
238019
|
+
if (!server) {
|
|
238020
|
+
return reply.code(401).send({ error: "Invalid token" });
|
|
238021
|
+
}
|
|
238022
|
+
if (server.connection_mode !== "inbound") {
|
|
238023
|
+
return reply.code(403).send({ error: "Server is not configured for inbound connections" });
|
|
238024
|
+
}
|
|
238025
|
+
return { serverId: server.id, name: server.name };
|
|
238026
|
+
});
|
|
238009
238027
|
fastify2.after(() => {
|
|
238010
238028
|
fastify2.get(
|
|
238011
238029
|
"/api/reverse-connect",
|
|
@@ -241159,6 +241177,10 @@ var createServer = async (opts) => {
|
|
|
241159
241177
|
if (!API_KEY) return done();
|
|
241160
241178
|
if (!req.url.startsWith("/api/")) return done();
|
|
241161
241179
|
if (req.method === "OPTIONS") return done();
|
|
241180
|
+
const pathname = req.url.split("?")[0];
|
|
241181
|
+
if (pathname === "/api/config" || pathname === "/api/reverse-connect/identity") {
|
|
241182
|
+
return done();
|
|
241183
|
+
}
|
|
241162
241184
|
const providedKey = req.headers["x-vibedeckx-api-key"] || req.query?.apiKey;
|
|
241163
241185
|
if (!providedKey && authEnabled) {
|
|
241164
241186
|
return done();
|
|
@@ -241200,7 +241222,12 @@ var createServer = async (opts) => {
|
|
|
241200
241222
|
server.get("/api/config", async () => ({
|
|
241201
241223
|
authEnabled,
|
|
241202
241224
|
clerkPublishableKey: authEnabled ? process.env.CLERK_PUBLISHABLE_KEY : void 0,
|
|
241203
|
-
localProjectsEnabled: !noLocalProjects
|
|
241225
|
+
localProjectsEnabled: !noLocalProjects,
|
|
241226
|
+
// Capability flag for the reverse-connect identity preflight. Workers
|
|
241227
|
+
// check this before calling /api/reverse-connect/identity so an auth
|
|
241228
|
+
// middleware 401 from an older hub (which lacks the endpoint AND its
|
|
241229
|
+
// exemptions) is never confused with a genuinely rejected token.
|
|
241230
|
+
reverseConnectIdentity: true
|
|
241204
241231
|
}));
|
|
241205
241232
|
server.register(shared_services_default, { storage: opts.storage, authEnabled });
|
|
241206
241233
|
server.register(import_websocket2.default);
|
|
@@ -241211,6 +241238,7 @@ var createServer = async (opts) => {
|
|
|
241211
241238
|
server.decorateRequest("auth", null);
|
|
241212
241239
|
server.addHook("preHandler", async (req, reply) => {
|
|
241213
241240
|
if (req.headers.upgrade?.toLowerCase() === "websocket") return;
|
|
241241
|
+
if (req.url.split("?")[0] === "/api/reverse-connect/identity") return;
|
|
241214
241242
|
const headers = new Headers();
|
|
241215
241243
|
for (const [key, value] of Object.entries(req.headers)) {
|
|
241216
241244
|
if (value) headers.set(key, Array.isArray(value) ? value.join(",") : String(value));
|
|
@@ -241756,6 +241784,69 @@ import { spawn as spawn5 } from "node:child_process";
|
|
|
241756
241784
|
import { randomUUID as randomUUID22 } from "node:crypto";
|
|
241757
241785
|
import fs7 from "node:fs";
|
|
241758
241786
|
import path19 from "node:path";
|
|
241787
|
+
|
|
241788
|
+
// src/update-check.ts
|
|
241789
|
+
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-]+)*)?$/;
|
|
241790
|
+
async function fetchLatestPublishedVersion(pkg = "vibedeckx", fetchImpl = fetch) {
|
|
241791
|
+
try {
|
|
241792
|
+
const response = await fetchImpl(
|
|
241793
|
+
`https://registry.npmjs.org/${pkg}/latest`,
|
|
241794
|
+
{ signal: AbortSignal.timeout(4e3) }
|
|
241795
|
+
);
|
|
241796
|
+
if (!response.ok) return void 0;
|
|
241797
|
+
const body = await response.json();
|
|
241798
|
+
return typeof body.version === "string" && parseSemver(body.version) ? body.version : void 0;
|
|
241799
|
+
} catch {
|
|
241800
|
+
return void 0;
|
|
241801
|
+
}
|
|
241802
|
+
}
|
|
241803
|
+
function parseSemver(version2) {
|
|
241804
|
+
const match2 = SEMVER_RE.exec(version2);
|
|
241805
|
+
if (!match2) return void 0;
|
|
241806
|
+
return {
|
|
241807
|
+
core: [match2[1], match2[2], match2[3]],
|
|
241808
|
+
prerelease: match2[4]?.split(".")
|
|
241809
|
+
};
|
|
241810
|
+
}
|
|
241811
|
+
function compareNumericStrings(a, b2) {
|
|
241812
|
+
if (a.length !== b2.length) return a.length - b2.length;
|
|
241813
|
+
return a < b2 ? -1 : a > b2 ? 1 : 0;
|
|
241814
|
+
}
|
|
241815
|
+
function comparePrereleaseIdentifiers(a, b2) {
|
|
241816
|
+
const aNumeric = /^\d+$/.test(a);
|
|
241817
|
+
const bNumeric = /^\d+$/.test(b2);
|
|
241818
|
+
if (aNumeric && bNumeric) return compareNumericStrings(a, b2);
|
|
241819
|
+
if (aNumeric !== bNumeric) return aNumeric ? -1 : 1;
|
|
241820
|
+
return a < b2 ? -1 : a > b2 ? 1 : 0;
|
|
241821
|
+
}
|
|
241822
|
+
function compareSemver(a, b2) {
|
|
241823
|
+
for (let i = 0; i < 3; i += 1) {
|
|
241824
|
+
const compared = compareNumericStrings(a.core[i], b2.core[i]);
|
|
241825
|
+
if (compared !== 0) return compared;
|
|
241826
|
+
}
|
|
241827
|
+
if (!a.prerelease && !b2.prerelease) return 0;
|
|
241828
|
+
if (!a.prerelease) return 1;
|
|
241829
|
+
if (!b2.prerelease) return -1;
|
|
241830
|
+
const length = Math.max(a.prerelease.length, b2.prerelease.length);
|
|
241831
|
+
for (let i = 0; i < length; i += 1) {
|
|
241832
|
+
const aId = a.prerelease[i];
|
|
241833
|
+
const bId = b2.prerelease[i];
|
|
241834
|
+
if (aId === void 0) return -1;
|
|
241835
|
+
if (bId === void 0) return 1;
|
|
241836
|
+
const compared = comparePrereleaseIdentifiers(aId, bId);
|
|
241837
|
+
if (compared !== 0) return compared;
|
|
241838
|
+
}
|
|
241839
|
+
return 0;
|
|
241840
|
+
}
|
|
241841
|
+
function compareUpdateStatus(current, latest) {
|
|
241842
|
+
if (latest === void 0) return "unknown";
|
|
241843
|
+
const currentParsed = parseSemver(current);
|
|
241844
|
+
const latestParsed = parseSemver(latest);
|
|
241845
|
+
if (!currentParsed || !latestParsed) return "unknown";
|
|
241846
|
+
return compareSemver(latestParsed, currentParsed) > 0 ? "update-available" : "up-to-date";
|
|
241847
|
+
}
|
|
241848
|
+
|
|
241849
|
+
// src/connect-daemon.ts
|
|
241759
241850
|
var CONNECT_DAEMON_CHILD_ENV = "VIBEDECKX_INTERNAL_CONNECT_DAEMON";
|
|
241760
241851
|
var CONNECT_DAEMON_TOKEN_ENV = "VIBEDECKX_INTERNAL_CONNECT_TOKEN";
|
|
241761
241852
|
function buildDaemonChildArgs(argv) {
|
|
@@ -242303,18 +242394,31 @@ function inspectDaemonState(dataDir) {
|
|
|
242303
242394
|
const actualTicks = readLinuxProcessStartTicks(parsed.pid);
|
|
242304
242395
|
return actualTicks === parsed.processStartTicks ? { kind: "running", state: parsed } : { kind: "stale", state: parsed };
|
|
242305
242396
|
}
|
|
242306
|
-
function
|
|
242397
|
+
function describeUpdateStatus(current, latest) {
|
|
242398
|
+
switch (compareUpdateStatus(current, latest)) {
|
|
242399
|
+
case "update-available":
|
|
242400
|
+
return `(update available: ${latest})`;
|
|
242401
|
+
case "up-to-date":
|
|
242402
|
+
return "(up to date)";
|
|
242403
|
+
case "unknown":
|
|
242404
|
+
return "(update check failed)";
|
|
242405
|
+
}
|
|
242406
|
+
}
|
|
242407
|
+
async function describeConnectDaemon(dataDir, fetchLatestVersion = fetchLatestPublishedVersion) {
|
|
242307
242408
|
const inspection = inspectDaemonState(dataDir);
|
|
242308
242409
|
switch (inspection.kind) {
|
|
242309
|
-
case "running":
|
|
242410
|
+
case "running": {
|
|
242411
|
+
const latest = await fetchLatestVersion();
|
|
242310
242412
|
return {
|
|
242311
242413
|
exitCode: 0,
|
|
242312
242414
|
message: [
|
|
242313
242415
|
`Running (PID ${inspection.state.pid}, since ${inspection.state.startedAt})`,
|
|
242416
|
+
`Version: ${inspection.state.version} ${describeUpdateStatus(inspection.state.version, latest)}`,
|
|
242314
242417
|
`Target: ${inspection.state.connectTo}`,
|
|
242315
242418
|
`Logs: ${path19.join(dataDir, "logs", "vibedeckx.log")}`
|
|
242316
242419
|
].join("\n")
|
|
242317
242420
|
};
|
|
242421
|
+
}
|
|
242318
242422
|
case "missing":
|
|
242319
242423
|
return { exitCode: 1, message: "Vibedeckx connect is not running" };
|
|
242320
242424
|
case "stale":
|
|
@@ -242537,6 +242641,78 @@ function removeVerifiedStaleStateUnlocked(dataDir) {
|
|
|
242537
242641
|
}
|
|
242538
242642
|
}
|
|
242539
242643
|
|
|
242644
|
+
// src/connect-preflight.ts
|
|
242645
|
+
var CONNECT_IDENTITY_HEADER = "x-vibedeckx-connect-token";
|
|
242646
|
+
var PINNED_IDENTITY_SETTING_PREFIX = "reverse_pinned_identity:";
|
|
242647
|
+
function canonicalizeHubUrl(raw) {
|
|
242648
|
+
let url2;
|
|
242649
|
+
try {
|
|
242650
|
+
url2 = new URL(raw);
|
|
242651
|
+
} catch {
|
|
242652
|
+
throw new Error(`Invalid --connect-to URL: ${raw}`);
|
|
242653
|
+
}
|
|
242654
|
+
if (url2.protocol !== "http:" && url2.protocol !== "https:") {
|
|
242655
|
+
throw new Error(`--connect-to must be an http(s) URL, got: ${raw}`);
|
|
242656
|
+
}
|
|
242657
|
+
const pathname = url2.pathname.replace(/\/+$/, "");
|
|
242658
|
+
return `${url2.origin}${pathname}`;
|
|
242659
|
+
}
|
|
242660
|
+
function parsePin(raw) {
|
|
242661
|
+
try {
|
|
242662
|
+
const parsed = JSON.parse(raw);
|
|
242663
|
+
if (parsed && typeof parsed === "object") return parsed;
|
|
242664
|
+
} catch {
|
|
242665
|
+
}
|
|
242666
|
+
return {};
|
|
242667
|
+
}
|
|
242668
|
+
async function preflightIdentityCheck(opts) {
|
|
242669
|
+
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
242670
|
+
const hubUrl = canonicalizeHubUrl(opts.connectTo);
|
|
242671
|
+
let config2;
|
|
242672
|
+
try {
|
|
242673
|
+
const res2 = await fetchImpl(`${hubUrl}/api/config`);
|
|
242674
|
+
if (res2.ok) config2 = await res2.json();
|
|
242675
|
+
} catch {
|
|
242676
|
+
}
|
|
242677
|
+
if (config2?.reverseConnectIdentity !== true) return { checked: false };
|
|
242678
|
+
const res = await fetchImpl(`${hubUrl}/api/reverse-connect/identity`, {
|
|
242679
|
+
headers: { [CONNECT_IDENTITY_HEADER]: opts.token }
|
|
242680
|
+
});
|
|
242681
|
+
if (res.status === 401) {
|
|
242682
|
+
throw new Error("Connect token was rejected by the server (invalid or revoked)");
|
|
242683
|
+
}
|
|
242684
|
+
if (res.status === 403) {
|
|
242685
|
+
throw new Error("This token's remote is not configured for inbound connections");
|
|
242686
|
+
}
|
|
242687
|
+
if (!res.ok) {
|
|
242688
|
+
throw new Error(`Identity preflight failed with status ${res.status}`);
|
|
242689
|
+
}
|
|
242690
|
+
const body = await res.json();
|
|
242691
|
+
if (!body || typeof body.serverId !== "string" || body.serverId.length === 0) {
|
|
242692
|
+
throw new Error("Malformed identity response from server");
|
|
242693
|
+
}
|
|
242694
|
+
const identity = { serverId: body.serverId, name: body.name ?? "" };
|
|
242695
|
+
const key = `${PINNED_IDENTITY_SETTING_PREFIX}${hubUrl}`;
|
|
242696
|
+
const desired = JSON.stringify(identity);
|
|
242697
|
+
if (opts.force) {
|
|
242698
|
+
await opts.settings.set(key, desired);
|
|
242699
|
+
return { checked: true, identity };
|
|
242700
|
+
}
|
|
242701
|
+
const persisted = await opts.settings.getOrCreate(key, () => desired);
|
|
242702
|
+
const pinned = parsePin(persisted);
|
|
242703
|
+
if (pinned.serverId && pinned.serverId !== identity.serverId) {
|
|
242704
|
+
const pinnedLabel = pinned.name || pinned.serverId;
|
|
242705
|
+
const tokenLabel = identity.name || identity.serverId;
|
|
242706
|
+
throw new Error(
|
|
242707
|
+
`This machine previously served remote "${pinnedLabel}" on ${hubUrl}, but the provided token belongs to "${tokenLabel}". If this is intentional, re-run with --force to re-pin.`
|
|
242708
|
+
);
|
|
242709
|
+
}
|
|
242710
|
+
if (!pinned.serverId || pinned.name !== identity.name) {
|
|
242711
|
+
await opts.settings.set(key, desired);
|
|
242712
|
+
}
|
|
242713
|
+
return { checked: true, identity };
|
|
242714
|
+
}
|
|
242715
|
+
|
|
242540
242716
|
// ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
|
|
242541
242717
|
import process8 from "node:process";
|
|
242542
242718
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
@@ -243233,6 +243409,11 @@ var connectCommand = buildCommand({
|
|
|
243233
243409
|
brief: "Run in the background after initialization (Linux only)",
|
|
243234
243410
|
optional: true
|
|
243235
243411
|
},
|
|
243412
|
+
force: {
|
|
243413
|
+
kind: "boolean",
|
|
243414
|
+
brief: "Re-pin this machine to the token's remote, overriding the pinned-identity mismatch guard",
|
|
243415
|
+
optional: true
|
|
243416
|
+
},
|
|
243236
243417
|
port: {
|
|
243237
243418
|
kind: "parsed",
|
|
243238
243419
|
parse: parseInt,
|
|
@@ -243332,6 +243513,17 @@ var connectCommand = buildCommand({
|
|
|
243332
243513
|
console.log("Starting vibedeckx in reverse-connect mode...");
|
|
243333
243514
|
const dbPath = path21.join(dataDir, "data.sqlite");
|
|
243334
243515
|
storage = await createSqliteStorage(dbPath);
|
|
243516
|
+
const preflight = await preflightIdentityCheck({
|
|
243517
|
+
connectTo: flags["connect-to"],
|
|
243518
|
+
token,
|
|
243519
|
+
settings: storage.settings,
|
|
243520
|
+
force: flags.force ?? false
|
|
243521
|
+
});
|
|
243522
|
+
if (preflight.checked && preflight.identity) {
|
|
243523
|
+
console.log(
|
|
243524
|
+
`Remote identity verified: ${preflight.identity.name || preflight.identity.serverId}`
|
|
243525
|
+
);
|
|
243526
|
+
}
|
|
243335
243527
|
server = await createServer({
|
|
243336
243528
|
storage,
|
|
243337
243529
|
acceptRemote: true,
|
|
@@ -243404,7 +243596,9 @@ var connectStatusCommand = buildCommand({
|
|
|
243404
243596
|
parameters: { flags: connectManagementFlags },
|
|
243405
243597
|
func: async (flags) => {
|
|
243406
243598
|
assertConnectDaemonPlatform();
|
|
243407
|
-
const result = describeConnectDaemon(
|
|
243599
|
+
const result = await describeConnectDaemon(
|
|
243600
|
+
flags["data-dir"] ?? VIBEDECKX_HOME
|
|
243601
|
+
);
|
|
243408
243602
|
return reportDaemonCommandResult(result);
|
|
243409
243603
|
},
|
|
243410
243604
|
docs: { brief: "Show the connect daemon status" }
|