@vibedeckx/linux-x64 0.2.7 → 0.2.8
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 +196 -20
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -223742,17 +223742,13 @@ async function generateSessionTitleWithModel(model, userMessage, options = {}) {
|
|
|
223742
223742
|
}
|
|
223743
223743
|
} : void 0;
|
|
223744
223744
|
try {
|
|
223745
|
-
const result = await
|
|
223746
|
-
|
|
223747
|
-
|
|
223748
|
-
|
|
223749
|
-
|
|
223750
|
-
|
|
223751
|
-
|
|
223752
|
-
new Promise(
|
|
223753
|
-
(_3, reject) => setTimeout(() => reject(new Error("title generation timed out")), AI_TIMEOUT_MS)
|
|
223754
|
-
)
|
|
223755
|
-
]);
|
|
223745
|
+
const result = await generateText({
|
|
223746
|
+
model,
|
|
223747
|
+
system: SYSTEM_PROMPT,
|
|
223748
|
+
prompt: buildPrompt(userMessage),
|
|
223749
|
+
timeout: AI_TIMEOUT_MS,
|
|
223750
|
+
experimental_telemetry: telemetry
|
|
223751
|
+
});
|
|
223756
223752
|
const text2 = result.text ?? "";
|
|
223757
223753
|
const sanitized = sanitizeTitle(text2);
|
|
223758
223754
|
return sanitized.length > 0 ? sanitized : null;
|
|
@@ -228722,6 +228718,18 @@ var WorkflowError = class extends Error {
|
|
|
228722
228718
|
}
|
|
228723
228719
|
code;
|
|
228724
228720
|
};
|
|
228721
|
+
var MAX_CONTEXT_CHARS = 2e3;
|
|
228722
|
+
var MAX_SELF_REPORT_CHARS = 4e3;
|
|
228723
|
+
var SELF_REPORT_MIN_CHARS = 80;
|
|
228724
|
+
function cap(text2, max) {
|
|
228725
|
+
return text2.length > max ? text2.slice(0, max) + "\u2026" : text2;
|
|
228726
|
+
}
|
|
228727
|
+
function userTextOf(e) {
|
|
228728
|
+
if (e.type !== "user") return null;
|
|
228729
|
+
if (typeof e.content === "string") return e.content;
|
|
228730
|
+
const text2 = e.content.filter((p2) => p2.type === "text").map((p2) => p2.text).join("\n");
|
|
228731
|
+
return text2 || null;
|
|
228732
|
+
}
|
|
228725
228733
|
function extractLatestTurnEndIndex(entries) {
|
|
228726
228734
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
228727
228735
|
if (entries[i]?.type === "turn_end") return i;
|
|
@@ -228745,21 +228753,64 @@ function extractTaskContextBefore(entries, turnEndIndex) {
|
|
|
228745
228753
|
}
|
|
228746
228754
|
return null;
|
|
228747
228755
|
}
|
|
228756
|
+
function extractFirstUserMessage(entries) {
|
|
228757
|
+
for (let i = 0; i < entries.length; i++) {
|
|
228758
|
+
const e = entries[i];
|
|
228759
|
+
if (e?.type !== "user" || e.event) continue;
|
|
228760
|
+
const text2 = userTextOf(e)?.trim();
|
|
228761
|
+
if (text2) return cap(text2, MAX_CONTEXT_CHARS);
|
|
228762
|
+
}
|
|
228763
|
+
return null;
|
|
228764
|
+
}
|
|
228765
|
+
function extractAuthorSelfReport(entries, beforeIndex, opts) {
|
|
228766
|
+
let fallback = null;
|
|
228767
|
+
for (let i = beforeIndex - 1; i >= 0; i--) {
|
|
228768
|
+
const e = entries[i];
|
|
228769
|
+
if (e?.type === "user" && opts?.withinTurn) break;
|
|
228770
|
+
if (e?.type !== "assistant" || typeof e.content !== "string") continue;
|
|
228771
|
+
const text2 = e.content.trim();
|
|
228772
|
+
if (!text2) continue;
|
|
228773
|
+
if (text2.length >= SELF_REPORT_MIN_CHARS) return cap(text2, MAX_SELF_REPORT_CHARS);
|
|
228774
|
+
if (fallback === null) fallback = text2;
|
|
228775
|
+
}
|
|
228776
|
+
return fallback;
|
|
228777
|
+
}
|
|
228778
|
+
function selfReportSection(report) {
|
|
228779
|
+
if (!report) return null;
|
|
228780
|
+
return [
|
|
228781
|
+
"\n## Author's self-report (unverified)",
|
|
228782
|
+
"The implementing agent described its own work as follows. Treat every claim as unverified \u2014 check each one against the actual code, and look for problems the self-report does not mention.",
|
|
228783
|
+
"<author-self-report>",
|
|
228784
|
+
report,
|
|
228785
|
+
"</author-self-report>"
|
|
228786
|
+
].join("\n");
|
|
228787
|
+
}
|
|
228748
228788
|
function buildReviewerPrompt(opts) {
|
|
228789
|
+
const intent = opts.originalIntent !== opts.taskContext ? opts.originalIntent : null;
|
|
228790
|
+
const brief = opts.intentBrief || null;
|
|
228791
|
+
const hasExcerpt = Boolean(intent || opts.taskContext || opts.authorSelfReport);
|
|
228749
228792
|
return [
|
|
228750
228793
|
"You are a code reviewer agent. Another agent just completed work in this workspace; review it critically and independently.",
|
|
228794
|
+
brief ? `
|
|
228795
|
+
## Intent brief (distilled from the source conversation)
|
|
228796
|
+
${brief}` : null,
|
|
228797
|
+
!brief && intent ? `
|
|
228798
|
+
## Original request (the user's first message in this session, verbatim)
|
|
228799
|
+
${intent}` : null,
|
|
228751
228800
|
opts.taskContext ? `
|
|
228752
228801
|
## Original task
|
|
228753
228802
|
${opts.taskContext}` : null,
|
|
228803
|
+
brief ? null : selfReportSection(opts.authorSelfReport),
|
|
228754
228804
|
opts.reviewFocus ? `
|
|
228755
228805
|
## Review focus (from the user)
|
|
228756
228806
|
${opts.reviewFocus}` : null,
|
|
228757
228807
|
"\n## How to review",
|
|
228758
228808
|
"- Do NOT modify any files \u2014 you are in read-only review mode.",
|
|
228759
228809
|
"- Inspect the actual workspace state yourself: read the relevant files, run `git diff`, `git status` and `git log`.",
|
|
228760
|
-
|
|
228810
|
+
reviewTargetPromptLine(opts.target),
|
|
228761
228811
|
"- Judge correctness, completeness against the task, and code quality. Be specific: reference files and lines.",
|
|
228762
|
-
"\nEnd your final message with a clear, actionable list of feedback items \u2014 or state explicitly that the work looks good."
|
|
228812
|
+
"\nEnd your final message with a clear, actionable list of feedback items \u2014 or state explicitly that the work looks good.",
|
|
228813
|
+
brief ? "\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)"
|
|
228763
228814
|
].filter((l) => l !== null).join("\n");
|
|
228764
228815
|
}
|
|
228765
228816
|
function reviewTargetPromptLine(target) {
|
|
@@ -228772,11 +228823,13 @@ function buildRereviewerPrompt(opts) {
|
|
|
228772
228823
|
opts.taskContext ? `
|
|
228773
228824
|
## Latest source turn
|
|
228774
228825
|
${opts.taskContext}` : null,
|
|
228826
|
+
selfReportSection(opts.authorSelfReport),
|
|
228775
228827
|
opts.reviewFocus ? `
|
|
228776
228828
|
## Review focus
|
|
228777
228829
|
${opts.reviewFocus}` : null,
|
|
228778
228830
|
"\n## How to review",
|
|
228779
228831
|
"- Verify whether your previous feedback was addressed correctly.",
|
|
228832
|
+
"- Treat the changed areas as new code: look for bugs the fix itself may have introduced, not only whether your old items were closed.",
|
|
228780
228833
|
"- Check for regressions and remaining correctness or test gaps.",
|
|
228781
228834
|
"- Do NOT modify files \u2014 remain in read-only review mode.",
|
|
228782
228835
|
reviewTargetPromptLine(opts.target),
|
|
@@ -228968,6 +229021,9 @@ var WorkflowEngine = class {
|
|
|
228968
229021
|
}
|
|
228969
229022
|
const prompt = buildRereviewerPrompt({
|
|
228970
229023
|
taskContext: extractTaskContextBefore(entries, turnEndIndex),
|
|
229024
|
+
// Scoped to the fix turn: an older turn's summary would describe the
|
|
229025
|
+
// pre-review state and mislead the acceptance pass.
|
|
229026
|
+
authorSelfReport: extractAuthorSelfReport(entries, turnEndIndex, { withinTurn: true }),
|
|
228971
229027
|
reviewFocus: opts.reviewFocus ?? null,
|
|
228972
229028
|
target
|
|
228973
229029
|
});
|
|
@@ -228996,6 +229052,9 @@ var WorkflowEngine = class {
|
|
|
228996
229052
|
).catch((err) => console.warn(`[WorkflowEngine] failed to set reviewer title for ${reviewerId}:`, err));
|
|
228997
229053
|
const prompt = buildReviewerPrompt({
|
|
228998
229054
|
taskContext,
|
|
229055
|
+
originalIntent: extractFirstUserMessage(entries),
|
|
229056
|
+
authorSelfReport: extractAuthorSelfReport(entries, turnEndIndex),
|
|
229057
|
+
intentBrief: opts.intentBrief ?? null,
|
|
228999
229058
|
reviewFocus: opts.reviewFocus ?? null,
|
|
229000
229059
|
target
|
|
229001
229060
|
});
|
|
@@ -236053,6 +236112,87 @@ var command_routes_default = (0, import_fastify_plugin18.default)(routes17, { na
|
|
|
236053
236112
|
|
|
236054
236113
|
// src/routes/workflow-run-routes.ts
|
|
236055
236114
|
var import_fastify_plugin19 = __toESM(require_plugin2(), 1);
|
|
236115
|
+
|
|
236116
|
+
// src/utils/review-brief.ts
|
|
236117
|
+
var AI_TIMEOUT_MS2 = 15e3;
|
|
236118
|
+
var PER_MESSAGE_MAX_CHARS = 1500;
|
|
236119
|
+
var TOTAL_INPUT_MAX_CHARS = 24e3;
|
|
236120
|
+
var HEAD_CHARS = 8e3;
|
|
236121
|
+
var TAIL_CHARS = 15e3;
|
|
236122
|
+
var BRIEF_MAX_CHARS = 4e3;
|
|
236123
|
+
var SYSTEM_PROMPT2 = [
|
|
236124
|
+
"You distill a coding-agent conversation into an intent brief for an independent code reviewer.",
|
|
236125
|
+
"The reviewer will NOT see the conversation \u2014 only your brief plus the actual code, so capture what the code alone cannot show:",
|
|
236126
|
+
"1. The original request and its goal.",
|
|
236127
|
+
"2. Constraints and explicit user decisions, including approaches the user rejected.",
|
|
236128
|
+
"3. The intended scope of the changes.",
|
|
236129
|
+
"4. Trade-offs or limitations that were acknowledged and accepted.",
|
|
236130
|
+
"Do NOT include the agent's reasoning, self-assessment, or claims that the work is correct or complete \u2014 the reviewer must judge that independently.",
|
|
236131
|
+
"Write concise markdown bullets under those numbered headings, under 400 words total, in the same language as the conversation. Reply with the brief only."
|
|
236132
|
+
].join("\n");
|
|
236133
|
+
function capText(text2, max) {
|
|
236134
|
+
return text2.length > max ? text2.slice(0, max) + "\u2026" : text2;
|
|
236135
|
+
}
|
|
236136
|
+
function serializeConversationForBrief(messages) {
|
|
236137
|
+
const lines = [];
|
|
236138
|
+
for (const msg of messages) {
|
|
236139
|
+
if (!msg) continue;
|
|
236140
|
+
if (msg.type === "user" && !msg.event) {
|
|
236141
|
+
const text2 = extractUserText(msg.content).trim();
|
|
236142
|
+
if (text2) lines.push(`User: ${capText(text2, PER_MESSAGE_MAX_CHARS)}`);
|
|
236143
|
+
} else if (msg.type === "assistant" && typeof msg.content === "string") {
|
|
236144
|
+
const text2 = msg.content.trim();
|
|
236145
|
+
if (text2) lines.push(`Agent: ${capText(text2, PER_MESSAGE_MAX_CHARS)}`);
|
|
236146
|
+
}
|
|
236147
|
+
}
|
|
236148
|
+
const full = lines.join("\n\n");
|
|
236149
|
+
if (full.length <= TOTAL_INPUT_MAX_CHARS) return full;
|
|
236150
|
+
return `${full.slice(0, HEAD_CHARS)}
|
|
236151
|
+
|
|
236152
|
+
[\u2026 middle of the conversation omitted \u2026]
|
|
236153
|
+
|
|
236154
|
+
${full.slice(-TAIL_CHARS)}`;
|
|
236155
|
+
}
|
|
236156
|
+
async function generateIntentBriefWithModel(model, conversation, options = {}) {
|
|
236157
|
+
if (conversation.trim().length === 0) return null;
|
|
236158
|
+
const telemetry = options.userId ? {
|
|
236159
|
+
isEnabled: true,
|
|
236160
|
+
functionId: "review-intent-brief",
|
|
236161
|
+
metadata: {
|
|
236162
|
+
userId: options.userId,
|
|
236163
|
+
tags: ["vibedeckx", "review-intent-brief"]
|
|
236164
|
+
}
|
|
236165
|
+
} : void 0;
|
|
236166
|
+
try {
|
|
236167
|
+
const result = await generateText({
|
|
236168
|
+
model,
|
|
236169
|
+
system: SYSTEM_PROMPT2,
|
|
236170
|
+
prompt: `Distill this conversation into an intent brief:
|
|
236171
|
+
|
|
236172
|
+
${conversation}`,
|
|
236173
|
+
timeout: AI_TIMEOUT_MS2,
|
|
236174
|
+
experimental_telemetry: telemetry
|
|
236175
|
+
});
|
|
236176
|
+
const text2 = (result.text ?? "").trim();
|
|
236177
|
+
return text2.length > 0 ? capText(text2, BRIEF_MAX_CHARS) : null;
|
|
236178
|
+
} catch (error48) {
|
|
236179
|
+
console.warn("[ReviewBrief] AI generation failed:", error48.message);
|
|
236180
|
+
return null;
|
|
236181
|
+
}
|
|
236182
|
+
}
|
|
236183
|
+
async function generateIntentBrief(storage, userId, messages) {
|
|
236184
|
+
try {
|
|
236185
|
+
if (!await isChatModelConfigured(storage, userId)) return null;
|
|
236186
|
+
const conversation = serializeConversationForBrief(messages);
|
|
236187
|
+
if (!conversation) return null;
|
|
236188
|
+
return await generateIntentBriefWithModel(await resolveFastChatModel(storage, userId), conversation, { userId });
|
|
236189
|
+
} catch (error48) {
|
|
236190
|
+
console.warn("[ReviewBrief] generation failed:", error48.message);
|
|
236191
|
+
return null;
|
|
236192
|
+
}
|
|
236193
|
+
}
|
|
236194
|
+
|
|
236195
|
+
// src/routes/workflow-run-routes.ts
|
|
236056
236196
|
function parseReviewerAgentType(raw) {
|
|
236057
236197
|
if (raw === void 0) return void 0;
|
|
236058
236198
|
return typeof raw === "string" && REVIEWER_AGENT_TYPES.has(raw) ? raw : null;
|
|
@@ -236128,12 +236268,29 @@ async function routes18(fastify2) {
|
|
|
236128
236268
|
}
|
|
236129
236269
|
bareReviewerSessionId = reviewerInfo.remoteSessionId;
|
|
236130
236270
|
}
|
|
236271
|
+
let intentBrief2;
|
|
236272
|
+
if (!bareReviewerSessionId) {
|
|
236273
|
+
try {
|
|
236274
|
+
const historyResult = await proxyAuto(
|
|
236275
|
+
remoteInfo,
|
|
236276
|
+
"GET",
|
|
236277
|
+
`/api/agent-sessions/${remoteInfo.remoteSessionId}`
|
|
236278
|
+
);
|
|
236279
|
+
if (historyResult.ok) {
|
|
236280
|
+
const messages = historyResult.data.messages ?? [];
|
|
236281
|
+
intentBrief2 = await generateIntentBrief(fastify2.storage, resolveUserId(userId), messages) ?? void 0;
|
|
236282
|
+
}
|
|
236283
|
+
} catch (err) {
|
|
236284
|
+
console.warn("[WorkflowRuns] intent brief generation failed (remote source):", err);
|
|
236285
|
+
}
|
|
236286
|
+
}
|
|
236131
236287
|
const result = await proxyAuto(remoteInfo, "POST", "/api/path/workflow-runs", {
|
|
236132
236288
|
sourceSessionId: remoteInfo.remoteSessionId,
|
|
236133
236289
|
reviewFocus,
|
|
236134
236290
|
sourceTurnEndIndex,
|
|
236135
236291
|
reviewerAgentType,
|
|
236136
|
-
reviewerSessionId: bareReviewerSessionId
|
|
236292
|
+
reviewerSessionId: bareReviewerSessionId,
|
|
236293
|
+
intentBrief: intentBrief2
|
|
236137
236294
|
});
|
|
236138
236295
|
if (!result.ok) return sendProxyFailure(reply, result);
|
|
236139
236296
|
const bareRun = result.data.run;
|
|
@@ -236199,6 +236356,18 @@ async function routes18(fastify2) {
|
|
|
236199
236356
|
if (branch !== void 0 && (branch || null) !== runBranch) {
|
|
236200
236357
|
return reply.code(400).send({ error: "branch does not match source session" });
|
|
236201
236358
|
}
|
|
236359
|
+
let intentBrief;
|
|
236360
|
+
if (!reviewerSessionId) {
|
|
236361
|
+
try {
|
|
236362
|
+
intentBrief = await generateIntentBrief(
|
|
236363
|
+
fastify2.storage,
|
|
236364
|
+
resolveUserId(userId),
|
|
236365
|
+
fastify2.agentSessionManager.getMessages(sourceSessionId)
|
|
236366
|
+
) ?? void 0;
|
|
236367
|
+
} catch (err) {
|
|
236368
|
+
console.warn("[WorkflowRuns] intent brief generation failed (local source):", err);
|
|
236369
|
+
}
|
|
236370
|
+
}
|
|
236202
236371
|
try {
|
|
236203
236372
|
const run2 = await fastify2.workflowEngine.startAdhocReview({
|
|
236204
236373
|
project: { id: project.id, path: project.path },
|
|
@@ -236207,7 +236376,8 @@ async function routes18(fastify2) {
|
|
|
236207
236376
|
reviewFocus,
|
|
236208
236377
|
sourceTurnEndIndex,
|
|
236209
236378
|
reviewerAgentType,
|
|
236210
|
-
reviewerSessionId
|
|
236379
|
+
reviewerSessionId,
|
|
236380
|
+
intentBrief
|
|
236211
236381
|
});
|
|
236212
236382
|
return reply.code(201).send({ run: run2 });
|
|
236213
236383
|
} catch (err) {
|
|
@@ -236253,7 +236423,7 @@ async function routes18(fastify2) {
|
|
|
236253
236423
|
projectId,
|
|
236254
236424
|
remoteInfo.remoteServerId,
|
|
236255
236425
|
bareCandidate.sessionId,
|
|
236256
|
-
remoteInfo.branch
|
|
236426
|
+
remoteInfo.branch ?? null
|
|
236257
236427
|
);
|
|
236258
236428
|
}
|
|
236259
236429
|
return reply.send({ candidate: candidate2 });
|
|
@@ -236385,6 +236555,11 @@ async function routes18(fastify2) {
|
|
|
236385
236555
|
if (userId === null) return;
|
|
236386
236556
|
const { sourceSessionId, reviewFocus, sourceTurnEndIndex } = req.body ?? {};
|
|
236387
236557
|
if (!sourceSessionId) return reply.code(400).send({ error: "sourceSessionId is required" });
|
|
236558
|
+
const intentBriefRaw = req.body?.intentBrief;
|
|
236559
|
+
if (intentBriefRaw !== void 0 && typeof intentBriefRaw !== "string") {
|
|
236560
|
+
return reply.code(400).send({ error: "intentBrief must be a string" });
|
|
236561
|
+
}
|
|
236562
|
+
const intentBrief = intentBriefRaw?.trim() ? intentBriefRaw.length > 8e3 ? intentBriefRaw.slice(0, 8e3) + "\u2026" : intentBriefRaw : void 0;
|
|
236388
236563
|
const reviewerAgentType = parseReviewerAgentType(req.body?.reviewerAgentType);
|
|
236389
236564
|
if (reviewerAgentType === null) return reply.code(400).send({ error: "reviewerAgentType must be one of: claude-code, codex" });
|
|
236390
236565
|
const reviewerSessionIdRaw = req.body?.reviewerSessionId;
|
|
@@ -236408,7 +236583,8 @@ async function routes18(fastify2) {
|
|
|
236408
236583
|
reviewFocus,
|
|
236409
236584
|
sourceTurnEndIndex,
|
|
236410
236585
|
reviewerAgentType,
|
|
236411
|
-
reviewerSessionId
|
|
236586
|
+
reviewerSessionId,
|
|
236587
|
+
intentBrief
|
|
236412
236588
|
});
|
|
236413
236589
|
return reply.code(201).send({ run: run2 });
|
|
236414
236590
|
} catch (err) {
|
|
@@ -238737,10 +238913,10 @@ var routes27 = async (fastify2) => {
|
|
|
238737
238913
|
if (offset >= stat2.size) {
|
|
238738
238914
|
return reply.send({ content: "", truncated: false, size: stat2.size });
|
|
238739
238915
|
}
|
|
238740
|
-
const
|
|
238916
|
+
const cap2 = Math.min(limit, MAX_OUTPUT_BYTES);
|
|
238741
238917
|
handle = await fs3.open(filePath, "r");
|
|
238742
|
-
const buffer = Buffer.alloc(
|
|
238743
|
-
const { bytesRead } = await handle.read(buffer, 0,
|
|
238918
|
+
const buffer = Buffer.alloc(cap2);
|
|
238919
|
+
const { bytesRead } = await handle.read(buffer, 0, cap2, offset);
|
|
238744
238920
|
return reply.send({
|
|
238745
238921
|
content: buffer.subarray(0, bytesRead).toString("utf8"),
|
|
238746
238922
|
truncated: offset + bytesRead < stat2.size,
|