flockbay 0.10.21 → 0.10.22
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/{index-By332wvJ.mjs → index-BjZUYSzh.mjs} +353 -16
- package/dist/{index-Bhkn02hu.cjs → index-DQTqwzYd.cjs} +353 -16
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/{runCodex-d2KQX2mn.mjs → runCodex-B7fGICdv.mjs} +11 -11
- package/dist/{runCodex-CH4lz1QX.cjs → runCodex-CaWagdzG.cjs} +11 -11
- package/dist/{runGemini-DNSymY04.cjs → runGemini-8w5P093W.cjs} +135 -20
- package/dist/{runGemini-Cn0C7MS1.mjs → runGemini-CK43WQk8.mjs} +135 -20
- package/dist/{types-mXJc7o0P.mjs → types-CMWcip0F.mjs} +41 -3
- package/dist/{types-DeH24uWs.cjs → types-Z2OYpI8c.cjs} +41 -2
- package/package.json +1 -1
|
@@ -4,8 +4,8 @@ import { randomUUID, createHash } from 'node:crypto';
|
|
|
4
4
|
import os from 'node:os';
|
|
5
5
|
import path, { resolve, join as join$1, basename } from 'node:path';
|
|
6
6
|
import { mkdir, writeFile, readFile } from 'node:fs/promises';
|
|
7
|
-
import { l as logger, b as packageJson, A as ApiClient, r as readSettings, p as projectPath, c as configuration } from './types-
|
|
8
|
-
import { s as shouldCountToolCall, c as consumeToolQuota, f as formatQuotaDeniedReason, h as hashObject, i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, g as buildProjectCapsule, a as setLatestUserImages, b as MessageBuffer, w as withUserImagesMarker, r as registerKillSessionHandler, d as startFlockbayServer, o as extractUserImagesMarker, p as getLatestUserImages, P as PLATFORM_SYSTEM_PROMPT, j as autoFinalizeCoordinationWorkItem, E as ElicitationHub, k as detectScreenshotsForGate, m as stopCaffeinate } from './index-
|
|
7
|
+
import { l as logger, b as packageJson, A as ApiClient, r as readSettings, p as projectPath, c as configuration } from './types-CMWcip0F.mjs';
|
|
8
|
+
import { s as shouldCountToolCall, c as consumeToolQuota, f as formatQuotaDeniedReason, h as hashObject, i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, g as buildProjectCapsule, a as setLatestUserImages, b as MessageBuffer, w as withUserImagesMarker, r as registerKillSessionHandler, d as startFlockbayServer, o as extractUserImagesMarker, p as getLatestUserImages, P as PLATFORM_SYSTEM_PROMPT, j as autoFinalizeCoordinationWorkItem, E as ElicitationHub, k as detectScreenshotsForGate, m as stopCaffeinate } from './index-BjZUYSzh.mjs';
|
|
9
9
|
import { spawn, spawnSync } from 'node:child_process';
|
|
10
10
|
import { ndJsonStream, ClientSideConnection } from '@agentclientprotocol/sdk';
|
|
11
11
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
@@ -43,6 +43,17 @@ const KNOWN_TOOL_PATTERNS = {
|
|
|
43
43
|
save_memory: ["save_memory", "save-memory"],
|
|
44
44
|
think: ["think"]
|
|
45
45
|
};
|
|
46
|
+
const MCP_FLOCKBAY_TOOL_RE = /\bmcp__flockbay__[a-z0-9_]+\b/gi;
|
|
47
|
+
const UNREAL_MCP_TOOL_RE = /\bunreal_mcp_[a-z0-9_]+\b/gi;
|
|
48
|
+
function extractFirstToolNameFromText(text) {
|
|
49
|
+
if (!text) return null;
|
|
50
|
+
const lower = text.toLowerCase();
|
|
51
|
+
const mcpMatch = lower.match(MCP_FLOCKBAY_TOOL_RE);
|
|
52
|
+
if (mcpMatch && mcpMatch[0]) return mcpMatch[0];
|
|
53
|
+
const unrealMatch = lower.match(UNREAL_MCP_TOOL_RE);
|
|
54
|
+
if (unrealMatch && unrealMatch[0]) return `mcp__flockbay__${unrealMatch[0]}`;
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
46
57
|
function isInvestigationTool(toolCallId, toolKind) {
|
|
47
58
|
return toolCallId.includes("codebase_investigator") || toolCallId.includes("investigator") || typeof toolKind === "string" && toolKind.includes("investigator");
|
|
48
59
|
}
|
|
@@ -77,20 +88,30 @@ function determineToolName(toolName, toolCallId, input, params, context) {
|
|
|
77
88
|
if (idToolName) {
|
|
78
89
|
return idToolName;
|
|
79
90
|
}
|
|
91
|
+
const idTextToolName = extractFirstToolNameFromText(toolCallId);
|
|
92
|
+
if (idTextToolName) {
|
|
93
|
+
return idTextToolName;
|
|
94
|
+
}
|
|
80
95
|
if (input && typeof input === "object") {
|
|
81
|
-
const inputStr = JSON.stringify(input)
|
|
96
|
+
const inputStr = JSON.stringify(input);
|
|
97
|
+
const extracted = extractFirstToolNameFromText(inputStr);
|
|
98
|
+
if (extracted) return extracted;
|
|
99
|
+
const inputLower = inputStr.toLowerCase();
|
|
82
100
|
for (const [toolName2, patterns] of Object.entries(KNOWN_TOOL_PATTERNS)) {
|
|
83
101
|
for (const pattern of patterns) {
|
|
84
|
-
if (
|
|
102
|
+
if (inputLower.includes(pattern.toLowerCase())) {
|
|
85
103
|
return toolName2;
|
|
86
104
|
}
|
|
87
105
|
}
|
|
88
106
|
}
|
|
89
107
|
}
|
|
90
|
-
const paramsStr = JSON.stringify(params)
|
|
108
|
+
const paramsStr = JSON.stringify(params);
|
|
109
|
+
const paramsExtracted = extractFirstToolNameFromText(paramsStr);
|
|
110
|
+
if (paramsExtracted) return paramsExtracted;
|
|
111
|
+
const paramsLower = paramsStr.toLowerCase();
|
|
91
112
|
for (const [toolName2, patterns] of Object.entries(KNOWN_TOOL_PATTERNS)) {
|
|
92
113
|
for (const pattern of patterns) {
|
|
93
|
-
if (
|
|
114
|
+
if (paramsLower.includes(pattern.toLowerCase())) {
|
|
94
115
|
return toolName2;
|
|
95
116
|
}
|
|
96
117
|
}
|
|
@@ -327,7 +348,7 @@ class AcpSdkBackend {
|
|
|
327
348
|
this.emit({
|
|
328
349
|
type: "status",
|
|
329
350
|
status: "error",
|
|
330
|
-
detail: "Model not found. Available models: gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite"
|
|
351
|
+
detail: "Model not found. Available models: gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite, gemini-3-pro-preview, gemini-3-flash-preview"
|
|
331
352
|
});
|
|
332
353
|
} else if (/authentication required/i.test(text) || /login required/i.test(text) || /invalid.*(api key|key)/i.test(text) || /permission denied/i.test(text)) {
|
|
333
354
|
const excerpt = this.stderrExcerpt(20);
|
|
@@ -1830,7 +1851,7 @@ class GeminiPermissionHandler {
|
|
|
1830
1851
|
const decision = result.decision;
|
|
1831
1852
|
const reason = result.reason;
|
|
1832
1853
|
const kind = decision === "approved" || decision === "approved_for_session" ? "policy_allow" : decision === "abort" && reason === "permission_prompt_required" ? "policy_prompt" : "policy_block";
|
|
1833
|
-
const summary = kind === "policy_allow" ? "Allowed." : kind === "policy_prompt" ? "Waiting for permission to run this tool." : reason ? `Blocked: ${reason}` : "Blocked by
|
|
1854
|
+
const summary = kind === "policy_allow" ? "Allowed." : kind === "policy_prompt" ? "Waiting for permission to run this tool." : reason ? `Blocked: ${reason}` : "Blocked by Policy.";
|
|
1834
1855
|
const nextSteps = [];
|
|
1835
1856
|
if (kind === "policy_block" && typeof reason === "string") {
|
|
1836
1857
|
if (reason.includes("docs_index_read") || reason.includes("Documentation index")) nextSteps.push("Call `mcp__flockbay__docs_index_read`.");
|
|
@@ -2568,6 +2589,30 @@ ${transcript}`;
|
|
|
2568
2589
|
logger.debug("[Gemini] Failed to send ready push", pushError);
|
|
2569
2590
|
}
|
|
2570
2591
|
};
|
|
2592
|
+
let pendingTurnCompletion = null;
|
|
2593
|
+
const beginTurnCompletionWait = () => {
|
|
2594
|
+
if (pendingTurnCompletion) {
|
|
2595
|
+
logger.debug("[Gemini] beginTurnCompletionWait called while a turn is already pending; replacing pending wait");
|
|
2596
|
+
try {
|
|
2597
|
+
pendingTurnCompletion.resolve("error");
|
|
2598
|
+
} catch {
|
|
2599
|
+
}
|
|
2600
|
+
pendingTurnCompletion = null;
|
|
2601
|
+
}
|
|
2602
|
+
let resolve2;
|
|
2603
|
+
const promise = new Promise((res) => {
|
|
2604
|
+
resolve2 = res;
|
|
2605
|
+
});
|
|
2606
|
+
pendingTurnCompletion = { sawRunning: false, resolve: resolve2, promise };
|
|
2607
|
+
return promise;
|
|
2608
|
+
};
|
|
2609
|
+
const maybeResolveTurnCompletion = (status) => {
|
|
2610
|
+
if (!pendingTurnCompletion) return;
|
|
2611
|
+
if (!pendingTurnCompletion.sawRunning) return;
|
|
2612
|
+
const pending = pendingTurnCompletion;
|
|
2613
|
+
pendingTurnCompletion = null;
|
|
2614
|
+
pending.resolve(status);
|
|
2615
|
+
};
|
|
2571
2616
|
const emitReadyIfIdle = () => {
|
|
2572
2617
|
if (shouldExit) {
|
|
2573
2618
|
return false;
|
|
@@ -2595,10 +2640,36 @@ ${transcript}`;
|
|
|
2595
2640
|
let wasSessionCreated = false;
|
|
2596
2641
|
let abortNote = null;
|
|
2597
2642
|
let abortNoteSentToSession = false;
|
|
2643
|
+
let abortRequested = false;
|
|
2644
|
+
let readySentForAbort = false;
|
|
2645
|
+
function normalizeCancelNote(input) {
|
|
2646
|
+
if (typeof input === "string") return input.trim() ? input.trim() : null;
|
|
2647
|
+
if (!input || typeof input !== "object") return null;
|
|
2648
|
+
const note = typeof input.note === "string" ? String(input.note).trim() : "";
|
|
2649
|
+
if (note) return note;
|
|
2650
|
+
const reason = typeof input.reason === "string" ? String(input.reason).trim() : "";
|
|
2651
|
+
if (reason) return reason;
|
|
2652
|
+
return null;
|
|
2653
|
+
}
|
|
2654
|
+
function makeAbortError(message = "Aborted") {
|
|
2655
|
+
const error = new Error(message);
|
|
2656
|
+
error.name = "AbortError";
|
|
2657
|
+
return error;
|
|
2658
|
+
}
|
|
2659
|
+
function abortable(signal, promise) {
|
|
2660
|
+
if (signal.aborted) return Promise.reject(makeAbortError());
|
|
2661
|
+
return new Promise((resolve2, reject) => {
|
|
2662
|
+
const onAbort = () => reject(makeAbortError());
|
|
2663
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
2664
|
+
promise.then(resolve2, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
2665
|
+
});
|
|
2666
|
+
}
|
|
2598
2667
|
async function handleAbort(note, options) {
|
|
2599
2668
|
logger.debug("[Gemini] Abort requested - stopping current task");
|
|
2600
|
-
|
|
2601
|
-
|
|
2669
|
+
abortRequested = true;
|
|
2670
|
+
const normalizedNote = normalizeCancelNote(note);
|
|
2671
|
+
if (normalizedNote) {
|
|
2672
|
+
abortNote = normalizedNote;
|
|
2602
2673
|
abortNoteSentToSession = Boolean(options?.alreadySentToSession);
|
|
2603
2674
|
}
|
|
2604
2675
|
session.sendCodexMessage({
|
|
@@ -2609,6 +2680,13 @@ ${transcript}`;
|
|
|
2609
2680
|
diffProcessor.reset();
|
|
2610
2681
|
try {
|
|
2611
2682
|
abortController.abort();
|
|
2683
|
+
if (pendingTurnCompletion) {
|
|
2684
|
+
try {
|
|
2685
|
+
pendingTurnCompletion.resolve("error");
|
|
2686
|
+
} catch {
|
|
2687
|
+
}
|
|
2688
|
+
pendingTurnCompletion = null;
|
|
2689
|
+
}
|
|
2612
2690
|
messageQueue.reset();
|
|
2613
2691
|
if (geminiBackend && acpSessionId) {
|
|
2614
2692
|
await geminiBackend.cancel(acpSessionId);
|
|
@@ -2747,6 +2825,7 @@ ${transcript}`;
|
|
|
2747
2825
|
};
|
|
2748
2826
|
let accumulatedResponse = "";
|
|
2749
2827
|
let isResponseInProgress = false;
|
|
2828
|
+
let currentResponseMessageId = null;
|
|
2750
2829
|
function setupGeminiMessageHandler(backend) {
|
|
2751
2830
|
backend.onMessage((msg) => {
|
|
2752
2831
|
switch (msg.type) {
|
|
@@ -2776,6 +2855,9 @@ ${transcript}`;
|
|
|
2776
2855
|
if (msg.status === "running") {
|
|
2777
2856
|
thinking = true;
|
|
2778
2857
|
session.keepAlive(thinking, "remote");
|
|
2858
|
+
if (pendingTurnCompletion) {
|
|
2859
|
+
pendingTurnCompletion.sawRunning = true;
|
|
2860
|
+
}
|
|
2779
2861
|
session.sendCodexMessage({
|
|
2780
2862
|
type: "task_started",
|
|
2781
2863
|
id: randomUUID()
|
|
@@ -2820,11 +2902,14 @@ ${transcript}`;
|
|
|
2820
2902
|
accumulatedResponse = "";
|
|
2821
2903
|
isResponseInProgress = false;
|
|
2822
2904
|
}
|
|
2905
|
+
maybeResolveTurnCompletion(msg.status);
|
|
2823
2906
|
} else if (msg.status === "error") {
|
|
2824
2907
|
thinking = false;
|
|
2825
2908
|
session.keepAlive(thinking, "remote");
|
|
2826
2909
|
accumulatedResponse = "";
|
|
2827
2910
|
isResponseInProgress = false;
|
|
2911
|
+
currentResponseMessageId = null;
|
|
2912
|
+
maybeResolveTurnCompletion("error");
|
|
2828
2913
|
const errorMessage = stringifyErrorish(msg.detail || "Unknown error");
|
|
2829
2914
|
messageBuffer.addMessage(`Error: ${errorMessage}`, "status");
|
|
2830
2915
|
session.sendCodexMessage({
|
|
@@ -3048,7 +3133,7 @@ ${transcript}`;
|
|
|
3048
3133
|
const actualModel = determineGeminiModel(modelToUse, localConfigForModel);
|
|
3049
3134
|
logger.debug(`[gemini] Model change - modelToUse=${modelToUse}, actualModel=${actualModel}`);
|
|
3050
3135
|
logger.debug("[gemini] Starting new ACP session with model:", actualModel);
|
|
3051
|
-
const { sessionId } = await geminiBackend.startSession();
|
|
3136
|
+
const { sessionId } = await abortable(abortController.signal, geminiBackend.startSession());
|
|
3052
3137
|
acpSessionId = sessionId;
|
|
3053
3138
|
startedSessionThisTurn = true;
|
|
3054
3139
|
logger.debug(`[gemini] New ACP session started: ${acpSessionId}`);
|
|
@@ -3065,6 +3150,15 @@ ${transcript}`;
|
|
|
3065
3150
|
let retryThisTurn = false;
|
|
3066
3151
|
let skipAutoFinalize = false;
|
|
3067
3152
|
try {
|
|
3153
|
+
const turnSignal = abortController.signal;
|
|
3154
|
+
const sendPromptAndWait = async (prompt) => {
|
|
3155
|
+
if (!geminiBackend || !acpSessionId) {
|
|
3156
|
+
throw new Error("Gemini backend or session not initialized");
|
|
3157
|
+
}
|
|
3158
|
+
const completion = beginTurnCompletionWait();
|
|
3159
|
+
await abortable(turnSignal, geminiBackend.sendPrompt(acpSessionId, prompt));
|
|
3160
|
+
return await abortable(turnSignal, completion);
|
|
3161
|
+
};
|
|
3068
3162
|
if (first || !wasSessionCreated) {
|
|
3069
3163
|
if (!geminiBackend) {
|
|
3070
3164
|
await refreshGeminiCloudToken("before-backend-create");
|
|
@@ -3089,7 +3183,7 @@ ${transcript}`;
|
|
|
3089
3183
|
if (!acpSessionId) {
|
|
3090
3184
|
logger.debug("[gemini] Starting ACP session...");
|
|
3091
3185
|
updatePermissionMode(message.mode.permissionMode);
|
|
3092
|
-
const { sessionId } = await geminiBackend.startSession();
|
|
3186
|
+
const { sessionId } = await abortable(turnSignal, geminiBackend.startSession());
|
|
3093
3187
|
acpSessionId = sessionId;
|
|
3094
3188
|
startedSessionThisTurn = true;
|
|
3095
3189
|
logger.debug(`[gemini] ACP session started: ${acpSessionId}`);
|
|
@@ -3130,18 +3224,27 @@ ${originalUserMessage}` : originalUserMessage;
|
|
|
3130
3224
|
...promptImages.map((img) => ({ type: "image", data: img.base64, mimeType: img.mimeType }))
|
|
3131
3225
|
];
|
|
3132
3226
|
logger.debug(`[gemini] Sending multimodal prompt blocks (textLength=${promptText.length}, images=${promptImages.length})`);
|
|
3133
|
-
await
|
|
3227
|
+
const status = await sendPromptAndWait(blocks);
|
|
3228
|
+
if (status !== "idle") {
|
|
3229
|
+
skipAutoFinalize = true;
|
|
3230
|
+
}
|
|
3134
3231
|
} else {
|
|
3135
3232
|
logger.debug(`[gemini] Sending prompt to Gemini (length: ${promptText.length}): ${promptText.substring(0, 100)}...`);
|
|
3136
3233
|
logger.debug(`[gemini] Full prompt: ${promptText}`);
|
|
3137
|
-
await
|
|
3234
|
+
const status = await sendPromptAndWait(promptText);
|
|
3235
|
+
if (status !== "idle") {
|
|
3236
|
+
skipAutoFinalize = true;
|
|
3237
|
+
}
|
|
3138
3238
|
}
|
|
3139
3239
|
logger.debug("[gemini] Prompt sent successfully");
|
|
3140
|
-
if (!screenshotGate.inAutoReview && screenshotGate.paths.length > 0) {
|
|
3240
|
+
if (!skipAutoFinalize && !screenshotGate.inAutoReview && screenshotGate.paths.length > 0) {
|
|
3141
3241
|
screenshotGate.inAutoReview = true;
|
|
3142
3242
|
messageBuffer.addMessage("Auto-reviewing screenshots\u2026", "status");
|
|
3143
3243
|
const blocks = await buildScreenshotReviewBlocks(screenshotGate.paths);
|
|
3144
|
-
await
|
|
3244
|
+
const status = await sendPromptAndWait(blocks);
|
|
3245
|
+
if (status !== "idle") {
|
|
3246
|
+
skipAutoFinalize = true;
|
|
3247
|
+
}
|
|
3145
3248
|
screenshotGate.inAutoReview = false;
|
|
3146
3249
|
}
|
|
3147
3250
|
if (first) {
|
|
@@ -3150,14 +3253,21 @@ ${originalUserMessage}` : originalUserMessage;
|
|
|
3150
3253
|
} catch (error) {
|
|
3151
3254
|
logger.debug("[gemini] Error in gemini session:", error);
|
|
3152
3255
|
const isAbortError = error instanceof Error && error.name === "AbortError";
|
|
3153
|
-
|
|
3256
|
+
const treatAsAbort = abortRequested || isAbortError;
|
|
3257
|
+
if (treatAsAbort) {
|
|
3154
3258
|
skipAutoFinalize = true;
|
|
3155
|
-
|
|
3259
|
+
readySentForAbort = true;
|
|
3260
|
+
const note = abortNote || "Canceled by user";
|
|
3156
3261
|
abortNote = null;
|
|
3157
3262
|
const alreadySent = abortNoteSentToSession;
|
|
3158
3263
|
abortNoteSentToSession = false;
|
|
3264
|
+
abortRequested = false;
|
|
3265
|
+
accumulatedResponse = "";
|
|
3266
|
+
isResponseInProgress = false;
|
|
3267
|
+
currentResponseMessageId = null;
|
|
3159
3268
|
messageBuffer.addMessage(note, "status");
|
|
3160
3269
|
if (!alreadySent) session.sendSessionEvent({ type: "message", message: note });
|
|
3270
|
+
session.sendSessionEvent({ type: "ready" });
|
|
3161
3271
|
} else {
|
|
3162
3272
|
const rawErrorString = error instanceof Error ? error.message : String(error);
|
|
3163
3273
|
const looksLikeAuthOrQuotaError = /unauthenticated|unauthorized|invalid (api )?key|api key not valid|permission denied|forbidden|expired|quota|usage limit|rate limit|resource exhausted|resource_exhausted|status 401|status 403|status 429|\b401\b|\b403\b|\b429\b/i.test(rawErrorString);
|
|
@@ -3189,7 +3299,7 @@ ${originalUserMessage}` : originalUserMessage;
|
|
|
3189
3299
|
const errorString = String(error);
|
|
3190
3300
|
if (errorCode === 404 || errorDetails.includes("notFound") || errorDetails.includes("404") || errorMessage.includes("not found") || errorMessage.includes("404")) {
|
|
3191
3301
|
const currentModel2 = displayedModel || "gemini-2.5-pro";
|
|
3192
|
-
errorMsg = `Model "${currentModel2}" not found. Available models: gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite`;
|
|
3302
|
+
errorMsg = `Model "${currentModel2}" not found. Available models: gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite, gemini-3-pro-preview, gemini-3-flash-preview`;
|
|
3193
3303
|
} else if (errorCode === 429 || errorDetails.includes("429") || errorMessage.includes("429") || errorString.includes("429") || errorDetails.includes("rateLimitExceeded") || errorDetails.includes("RESOURCE_EXHAUSTED") || errorMessage.includes("Rate limit exceeded") || errorMessage.includes("Resource exhausted") || errorString.includes("rateLimitExceeded") || errorString.includes("RESOURCE_EXHAUSTED")) {
|
|
3194
3304
|
errorMsg = "Gemini API rate limit exceeded. Please wait a moment and try again. The API will retry automatically.";
|
|
3195
3305
|
} else if (errorDetails.includes("quota") || errorMessage.includes("quota") || errorString.includes("quota")) {
|
|
@@ -3213,6 +3323,7 @@ ${originalUserMessage}` : originalUserMessage;
|
|
|
3213
3323
|
permissionHandler.reset();
|
|
3214
3324
|
reasoningProcessor.abort();
|
|
3215
3325
|
diffProcessor.reset();
|
|
3326
|
+
abortRequested = false;
|
|
3216
3327
|
thinking = false;
|
|
3217
3328
|
session.keepAlive(thinking, "remote");
|
|
3218
3329
|
if (!retryThisTurn) {
|
|
@@ -3242,7 +3353,11 @@ ${originalUserMessage}` : originalUserMessage;
|
|
|
3242
3353
|
});
|
|
3243
3354
|
}
|
|
3244
3355
|
}
|
|
3245
|
-
|
|
3356
|
+
if (readySentForAbort) {
|
|
3357
|
+
readySentForAbort = false;
|
|
3358
|
+
} else {
|
|
3359
|
+
emitReadyIfIdle();
|
|
3360
|
+
}
|
|
3246
3361
|
}
|
|
3247
3362
|
logger.debug(`[gemini] Main loop: turn completed, continuing to next iteration (queue size: ${messageQueue.size()})`);
|
|
3248
3363
|
}
|
|
@@ -11,7 +11,7 @@ import { readFile, unlink, open, stat, mkdir, writeFile, rename } from 'node:fs/
|
|
|
11
11
|
import * as z from 'zod';
|
|
12
12
|
import { z as z$1 } from 'zod';
|
|
13
13
|
import { spawn } from 'child_process';
|
|
14
|
-
import {
|
|
14
|
+
import { readdir, mkdir as mkdir$1, realpath, stat as stat$1, rm, readFile as readFile$1, open as open$1, writeFile as writeFile$1, chmod } from 'fs/promises';
|
|
15
15
|
import { randomUUID, createHash } from 'crypto';
|
|
16
16
|
import { dirname, resolve, join as join$1, relative } from 'path';
|
|
17
17
|
import { fileURLToPath } from 'url';
|
|
@@ -21,7 +21,7 @@ import net from 'node:net';
|
|
|
21
21
|
import { spawn as spawn$1 } from 'node:child_process';
|
|
22
22
|
|
|
23
23
|
var name = "flockbay";
|
|
24
|
-
var version = "0.10.
|
|
24
|
+
var version = "0.10.22";
|
|
25
25
|
var description = "Flockbay CLI (local agent + daemon)";
|
|
26
26
|
var author = "Eduardo Orellana";
|
|
27
27
|
var license = "UNLICENSED";
|
|
@@ -1570,6 +1570,44 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, coordinatio
|
|
|
1570
1570
|
};
|
|
1571
1571
|
}
|
|
1572
1572
|
});
|
|
1573
|
+
rpcHandlerManager.registerHandler("fs_list_dir", async (data) => {
|
|
1574
|
+
const p = String(data?.path || "").trim();
|
|
1575
|
+
if (!p) return { success: false, error: "missing_path" };
|
|
1576
|
+
try {
|
|
1577
|
+
const out = [];
|
|
1578
|
+
const items = await readdir(p, { withFileTypes: true });
|
|
1579
|
+
for (const d of items) {
|
|
1580
|
+
out.push({
|
|
1581
|
+
name: d.name,
|
|
1582
|
+
isDir: d.isDirectory(),
|
|
1583
|
+
isFile: d.isFile(),
|
|
1584
|
+
isSymlink: d.isSymbolicLink()
|
|
1585
|
+
});
|
|
1586
|
+
}
|
|
1587
|
+
out.sort((a, b) => {
|
|
1588
|
+
if (a.isDir !== b.isDir) return a.isDir ? -1 : 1;
|
|
1589
|
+
return a.name.localeCompare(b.name);
|
|
1590
|
+
});
|
|
1591
|
+
return { success: true, path: p, entries: out };
|
|
1592
|
+
} catch (error) {
|
|
1593
|
+
const e = error;
|
|
1594
|
+
const msg = e?.message ? String(e.message) : String(error);
|
|
1595
|
+
return { success: false, path: p, error: msg };
|
|
1596
|
+
}
|
|
1597
|
+
});
|
|
1598
|
+
rpcHandlerManager.registerHandler("fs_mkdir", async (data) => {
|
|
1599
|
+
const p = String(data?.path || "").trim();
|
|
1600
|
+
if (!p) return { success: false, error: "missing_path" };
|
|
1601
|
+
const recursive = data?.recursive !== false;
|
|
1602
|
+
try {
|
|
1603
|
+
await mkdir$1(p, { recursive });
|
|
1604
|
+
return { success: true, path: p };
|
|
1605
|
+
} catch (error) {
|
|
1606
|
+
const e = error;
|
|
1607
|
+
const msg = e?.message ? String(e.message) : String(error);
|
|
1608
|
+
return { success: false, path: p, error: msg };
|
|
1609
|
+
}
|
|
1610
|
+
});
|
|
1573
1611
|
rpcHandlerManager.registerHandler(
|
|
1574
1612
|
"unreal-mcp-bridge-status",
|
|
1575
1613
|
async (params) => {
|
|
@@ -3774,4 +3812,4 @@ const RawJSONLinesSchema = z$1.discriminatedUnion("type", [
|
|
|
3774
3812
|
}).passthrough()
|
|
3775
3813
|
]);
|
|
3776
3814
|
|
|
3777
|
-
export { ApiClient as A, RawJSONLinesSchema as R, ApiSessionClient as a, packageJson as b, configuration as c, backoff as d, delay as e, readDaemonState as f, clearDaemonState as g, readCredentials as h, unrealMcpPythonDir as i, acquireDaemonLock as j, writeDaemonState as k, logger as l, ApiMachineClient as m, releaseDaemonLock as n, clearCredentials as o, projectPath as p, clearMachineId as q, readSettings as r, sendUnrealMcpTcpCommand as s, installUnrealMcpPluginToEngine as t, updateSettings as u,
|
|
3815
|
+
export { ApiClient as A, RawJSONLinesSchema as R, ApiSessionClient as a, packageJson as b, configuration as c, backoff as d, delay as e, readDaemonState as f, clearDaemonState as g, readCredentials as h, unrealMcpPythonDir as i, acquireDaemonLock as j, writeDaemonState as k, logger as l, ApiMachineClient as m, releaseDaemonLock as n, clearCredentials as o, projectPath as p, clearMachineId as q, readSettings as r, sendUnrealMcpTcpCommand as s, installUnrealMcpPluginToEngine as t, updateSettings as u, buildAndInstallUnrealMcpPlugin as v, writeCredentials as w, getLatestDaemonLog as x, normalizeServerUrlForNode as y };
|
|
@@ -42,7 +42,7 @@ function _interopNamespaceDefault(e) {
|
|
|
42
42
|
var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
|
|
43
43
|
|
|
44
44
|
var name = "flockbay";
|
|
45
|
-
var version = "0.10.
|
|
45
|
+
var version = "0.10.22";
|
|
46
46
|
var description = "Flockbay CLI (local agent + daemon)";
|
|
47
47
|
var author = "Eduardo Orellana";
|
|
48
48
|
var license = "UNLICENSED";
|
|
@@ -770,7 +770,7 @@ class RpcHandlerManager {
|
|
|
770
770
|
}
|
|
771
771
|
}
|
|
772
772
|
|
|
773
|
-
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-
|
|
773
|
+
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-Z2OYpI8c.cjs', document.baseURI).href))));
|
|
774
774
|
function projectPath() {
|
|
775
775
|
const path = path$1.resolve(__dirname$1, "..");
|
|
776
776
|
return path;
|
|
@@ -1591,6 +1591,44 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, coordinatio
|
|
|
1591
1591
|
};
|
|
1592
1592
|
}
|
|
1593
1593
|
});
|
|
1594
|
+
rpcHandlerManager.registerHandler("fs_list_dir", async (data) => {
|
|
1595
|
+
const p = String(data?.path || "").trim();
|
|
1596
|
+
if (!p) return { success: false, error: "missing_path" };
|
|
1597
|
+
try {
|
|
1598
|
+
const out = [];
|
|
1599
|
+
const items = await fs$3.readdir(p, { withFileTypes: true });
|
|
1600
|
+
for (const d of items) {
|
|
1601
|
+
out.push({
|
|
1602
|
+
name: d.name,
|
|
1603
|
+
isDir: d.isDirectory(),
|
|
1604
|
+
isFile: d.isFile(),
|
|
1605
|
+
isSymlink: d.isSymbolicLink()
|
|
1606
|
+
});
|
|
1607
|
+
}
|
|
1608
|
+
out.sort((a, b) => {
|
|
1609
|
+
if (a.isDir !== b.isDir) return a.isDir ? -1 : 1;
|
|
1610
|
+
return a.name.localeCompare(b.name);
|
|
1611
|
+
});
|
|
1612
|
+
return { success: true, path: p, entries: out };
|
|
1613
|
+
} catch (error) {
|
|
1614
|
+
const e = error;
|
|
1615
|
+
const msg = e?.message ? String(e.message) : String(error);
|
|
1616
|
+
return { success: false, path: p, error: msg };
|
|
1617
|
+
}
|
|
1618
|
+
});
|
|
1619
|
+
rpcHandlerManager.registerHandler("fs_mkdir", async (data) => {
|
|
1620
|
+
const p = String(data?.path || "").trim();
|
|
1621
|
+
if (!p) return { success: false, error: "missing_path" };
|
|
1622
|
+
const recursive = data?.recursive !== false;
|
|
1623
|
+
try {
|
|
1624
|
+
await fs$3.mkdir(p, { recursive });
|
|
1625
|
+
return { success: true, path: p };
|
|
1626
|
+
} catch (error) {
|
|
1627
|
+
const e = error;
|
|
1628
|
+
const msg = e?.message ? String(e.message) : String(error);
|
|
1629
|
+
return { success: false, path: p, error: msg };
|
|
1630
|
+
}
|
|
1631
|
+
});
|
|
1594
1632
|
rpcHandlerManager.registerHandler(
|
|
1595
1633
|
"unreal-mcp-bridge-status",
|
|
1596
1634
|
async (params) => {
|
|
@@ -3801,6 +3839,7 @@ exports.ApiSessionClient = ApiSessionClient;
|
|
|
3801
3839
|
exports.RawJSONLinesSchema = RawJSONLinesSchema;
|
|
3802
3840
|
exports.acquireDaemonLock = acquireDaemonLock;
|
|
3803
3841
|
exports.backoff = backoff;
|
|
3842
|
+
exports.buildAndInstallUnrealMcpPlugin = buildAndInstallUnrealMcpPlugin;
|
|
3804
3843
|
exports.clearCredentials = clearCredentials;
|
|
3805
3844
|
exports.clearDaemonState = clearDaemonState;
|
|
3806
3845
|
exports.clearMachineId = clearMachineId;
|