@buda-ai/connector 0.1.27 → 0.1.29
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/cli.js +145 -34
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -523,7 +523,7 @@ import path2 from "path";
|
|
|
523
523
|
// package.json
|
|
524
524
|
var package_default = {
|
|
525
525
|
name: "@buda-ai/connector",
|
|
526
|
-
version: "0.1.
|
|
526
|
+
version: "0.1.29",
|
|
527
527
|
private: false,
|
|
528
528
|
type: "module",
|
|
529
529
|
publishConfig: {
|
|
@@ -2215,6 +2215,13 @@ var ConnectorDeletedError = class extends Error {
|
|
|
2215
2215
|
this.name = "ConnectorDeletedError";
|
|
2216
2216
|
}
|
|
2217
2217
|
};
|
|
2218
|
+
var ConnectorUnauthorizedError = class extends Error {
|
|
2219
|
+
constructor(message) {
|
|
2220
|
+
super(message);
|
|
2221
|
+
this.name = "ConnectorUnauthorizedError";
|
|
2222
|
+
}
|
|
2223
|
+
};
|
|
2224
|
+
var UNREGISTER_TIMEOUT_MS = 3e3;
|
|
2218
2225
|
async function resolveConnectorScope(deviceId, launchConfig) {
|
|
2219
2226
|
const serverUrl = normalizeServerOrigin(getServerUrl(launchConfig));
|
|
2220
2227
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -2301,14 +2308,15 @@ function buildAuthHeaders(config, launchConfig) {
|
|
|
2301
2308
|
if (config.deviceToken) headers["X-Buda-Connector-Device-Token"] = config.deviceToken;
|
|
2302
2309
|
return headers;
|
|
2303
2310
|
}
|
|
2304
|
-
async function postJson(serverUrl, pathname, body, config, launchConfig) {
|
|
2311
|
+
async function postJson(serverUrl, pathname, body, config, launchConfig, options = {}) {
|
|
2305
2312
|
const response = await fetch(`${serverUrl}${pathname}`, {
|
|
2306
2313
|
method: "POST",
|
|
2307
2314
|
headers: {
|
|
2308
2315
|
"Content-Type": "application/json",
|
|
2309
2316
|
...buildAuthHeaders(config, launchConfig)
|
|
2310
2317
|
},
|
|
2311
|
-
body: JSON.stringify(body)
|
|
2318
|
+
body: JSON.stringify(body),
|
|
2319
|
+
...options.timeoutMs ? { signal: AbortSignal.timeout(options.timeoutMs) } : {}
|
|
2312
2320
|
});
|
|
2313
2321
|
if (!response.ok) {
|
|
2314
2322
|
const text2 = await response.text().catch(() => "");
|
|
@@ -2328,6 +2336,9 @@ async function postJson(serverUrl, pathname, body, config, launchConfig) {
|
|
|
2328
2336
|
if (errorCode === "connector_deleted") {
|
|
2329
2337
|
throw new ConnectorDeletedError(errorMessage3 || "Connector no longer exists");
|
|
2330
2338
|
}
|
|
2339
|
+
if (response.status === 401) {
|
|
2340
|
+
throw new ConnectorUnauthorizedError(errorMessage3 || "Connector authentication failed");
|
|
2341
|
+
}
|
|
2331
2342
|
throw new Error(`${pathname} failed: ${response.status} ${errorMessage3}`);
|
|
2332
2343
|
}
|
|
2333
2344
|
return await response.json();
|
|
@@ -2403,7 +2414,8 @@ async function unregisterConnector(config, launchConfig) {
|
|
|
2403
2414
|
connectorId: config.connectorId
|
|
2404
2415
|
},
|
|
2405
2416
|
config,
|
|
2406
|
-
launchConfig
|
|
2417
|
+
launchConfig,
|
|
2418
|
+
{ timeoutMs: UNREGISTER_TIMEOUT_MS }
|
|
2407
2419
|
).catch((error) => {
|
|
2408
2420
|
void writeLog("warn", `unregister failed: ${error instanceof Error ? error.message : error}`);
|
|
2409
2421
|
});
|
|
@@ -2601,6 +2613,7 @@ async function ensureStableConnectorRuntime() {
|
|
|
2601
2613
|
// src/daemon-client.ts
|
|
2602
2614
|
var START_TIMEOUT_MS = 45e3;
|
|
2603
2615
|
var BOOTSTRAP_TIMEOUT_MS = 5 * 6e4;
|
|
2616
|
+
var GRACEFUL_STOP_TIMEOUT_MS = 3e3;
|
|
2604
2617
|
var LOCK_ONLY_RECOVERY_MAX_AGE_MS = 5 * 6e4;
|
|
2605
2618
|
var POLL_INTERVAL_MS = 250;
|
|
2606
2619
|
var wait2 = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
@@ -2754,6 +2767,30 @@ var stopUnresponsiveDaemonProcess = async (pid) => {
|
|
|
2754
2767
|
if (await waitForProcessExit(pid, 3e3)) return;
|
|
2755
2768
|
throw new Error(`Timed-out Connector daemon PID ${pid} could not be stopped safely`);
|
|
2756
2769
|
};
|
|
2770
|
+
var waitForDaemonRelease = async (config, status, configRoot = getConfigRoot()) => {
|
|
2771
|
+
const deadline = Date.now() + GRACEFUL_STOP_TIMEOUT_MS;
|
|
2772
|
+
while (Date.now() < deadline) {
|
|
2773
|
+
if (!isProcessAlive2(status.pid)) return true;
|
|
2774
|
+
const current = await readPersistedDaemonStatus(config, configRoot).catch(() => null);
|
|
2775
|
+
if (!current || current.pid !== status.pid || current.instanceId !== status.instanceId) {
|
|
2776
|
+
return true;
|
|
2777
|
+
}
|
|
2778
|
+
await wait2(50);
|
|
2779
|
+
}
|
|
2780
|
+
return !isProcessAlive2(status.pid);
|
|
2781
|
+
};
|
|
2782
|
+
var stopLiveDaemon = async (config, status, configRoot = getConfigRoot(), command = "stop") => {
|
|
2783
|
+
const stopStatus = await requestDaemonControl(config, command, configRoot);
|
|
2784
|
+
if (command === "stop-if-idle" && !stopStatus.idle) return false;
|
|
2785
|
+
if (await waitForDaemonRelease(config, status, configRoot)) return true;
|
|
2786
|
+
const current = await readPersistedDaemonStatus(config, configRoot).catch(() => null);
|
|
2787
|
+
if (!current || current.pid !== status.pid || current.instanceId !== status.instanceId) {
|
|
2788
|
+
return true;
|
|
2789
|
+
}
|
|
2790
|
+
await stopUnresponsiveDaemonProcess(status.pid);
|
|
2791
|
+
return true;
|
|
2792
|
+
};
|
|
2793
|
+
var shouldRestartUnhealthyDaemonForEnrollment = (status, explicitEnrollment) => explicitEnrollment && status.idle && status.heartbeatHealthy === false;
|
|
2757
2794
|
var readDaemonLockOwnerPid = async (config) => {
|
|
2758
2795
|
const lockPath = `${getConnectorDaemonLockTarget(
|
|
2759
2796
|
config.serverUrl,
|
|
@@ -2817,6 +2854,12 @@ async function ensureConnectorDaemon(launchConfig, mode, options = {}) {
|
|
|
2817
2854
|
if (existingConfig) {
|
|
2818
2855
|
const existingStatus = await readLiveStatus(existingConfig);
|
|
2819
2856
|
if (existingStatus) {
|
|
2857
|
+
if (shouldRestartUnhealthyDaemonForEnrollment(
|
|
2858
|
+
existingStatus,
|
|
2859
|
+
Boolean(options.explicitEnrollment)
|
|
2860
|
+
) && await stopLiveDaemon(existingConfig, existingStatus, getConfigRoot(), "stop-if-idle")) {
|
|
2861
|
+
return await startInternalDaemonWithRecovery(launchConfig, mode, void 0, options);
|
|
2862
|
+
}
|
|
2820
2863
|
const preparedRuntime = !shouldReplaceDaemonVersion(existingStatus.version, CONNECTOR_RUNTIME_VERSION) || !existingStatus.idle ? void 0 : await ensureStableConnectorRuntime();
|
|
2821
2864
|
const replaced = await stopOlderIdleDaemon(existingConfig, existingStatus);
|
|
2822
2865
|
if (!replaced) {
|
|
@@ -2937,7 +2980,7 @@ async function stopLocalConnectorDaemon(connectorId, serverUrl, configRoot = get
|
|
|
2937
2980
|
if (!config) throw new Error(`Local Connector ${connectorId} was not found`);
|
|
2938
2981
|
const status = await readLiveStatus(config, configRoot);
|
|
2939
2982
|
if (!status) return;
|
|
2940
|
-
await
|
|
2983
|
+
await stopLiveDaemon(config, status, configRoot);
|
|
2941
2984
|
}
|
|
2942
2985
|
async function stopAllLocalConnectorDaemons(configRoot = getConfigRoot()) {
|
|
2943
2986
|
const configs = await listDeviceConfigs(configRoot);
|
|
@@ -2950,7 +2993,7 @@ ${config.connectorId}`, config);
|
|
|
2950
2993
|
const results = await Promise.allSettled(
|
|
2951
2994
|
[...identities.values()].map(async (config) => {
|
|
2952
2995
|
const status = await readLiveStatus(config, configRoot);
|
|
2953
|
-
if (status) await
|
|
2996
|
+
if (status) await stopLiveDaemon(config, status, configRoot);
|
|
2954
2997
|
})
|
|
2955
2998
|
);
|
|
2956
2999
|
const failures = results.filter((result) => result.status === "rejected");
|
|
@@ -4661,6 +4704,7 @@ var isAlreadyExists3 = (error) => error instanceof Error && "code" in error && e
|
|
|
4661
4704
|
// src/relay.ts
|
|
4662
4705
|
var RELAY_PING_INTERVAL_MS = 2e4;
|
|
4663
4706
|
var RELAY_PONG_TIMEOUT_MS = 1e4;
|
|
4707
|
+
var RELAY_ACTIVE_REQUEST_PONG_TIMEOUT_LIMIT = 2;
|
|
4664
4708
|
var RELAY_HANDSHAKE_TIMEOUT_MS = 1e4;
|
|
4665
4709
|
var RELAY_RECONNECT_MAX_MS = 3e4;
|
|
4666
4710
|
var RELAY_RECONNECT_JITTER = 0.2;
|
|
@@ -4766,6 +4810,7 @@ function startConnectorRelay(config, bunnyDaemon, relayProtocol, workspaceRegist
|
|
|
4766
4810
|
socket = ws;
|
|
4767
4811
|
const inflight = /* @__PURE__ */ new Map();
|
|
4768
4812
|
currentInflight = inflight;
|
|
4813
|
+
let consecutivePongTimeouts = 0;
|
|
4769
4814
|
let detached = false;
|
|
4770
4815
|
const detach = () => {
|
|
4771
4816
|
if (detached) return;
|
|
@@ -4778,6 +4823,7 @@ function startConnectorRelay(config, bunnyDaemon, relayProtocol, workspaceRegist
|
|
|
4778
4823
|
void writeLog("info", `relay connected ${relayUrl}`);
|
|
4779
4824
|
hadOpenConnection = true;
|
|
4780
4825
|
reconnectDelayMs = RELAY_RECONNECT_INTERVAL_MS;
|
|
4826
|
+
consecutivePongTimeouts = 0;
|
|
4781
4827
|
pingTimer = setInterval(() => {
|
|
4782
4828
|
if (ws.readyState !== WebSocket2.OPEN) return;
|
|
4783
4829
|
try {
|
|
@@ -4789,18 +4835,33 @@ function startConnectorRelay(config, bunnyDaemon, relayProtocol, workspaceRegist
|
|
|
4789
4835
|
}
|
|
4790
4836
|
if (pongTimer) clearTimeout(pongTimer);
|
|
4791
4837
|
pongTimer = setTimeout(() => {
|
|
4838
|
+
pongTimer = null;
|
|
4839
|
+
consecutivePongTimeouts += 1;
|
|
4840
|
+
if (inflight.size > 0 && consecutivePongTimeouts < RELAY_ACTIVE_REQUEST_PONG_TIMEOUT_LIMIT) {
|
|
4841
|
+
void writeLog(
|
|
4842
|
+
"warn",
|
|
4843
|
+
`relay pong timeout deferred while ${inflight.size} request(s) are active`
|
|
4844
|
+
);
|
|
4845
|
+
return;
|
|
4846
|
+
}
|
|
4792
4847
|
void writeLog("warn", "relay pong timeout, terminating");
|
|
4793
4848
|
ws.terminate();
|
|
4794
4849
|
}, RELAY_PONG_TIMEOUT_MS);
|
|
4795
4850
|
}, RELAY_PING_INTERVAL_MS);
|
|
4796
4851
|
});
|
|
4797
4852
|
ws.on("pong", () => {
|
|
4853
|
+
consecutivePongTimeouts = 0;
|
|
4798
4854
|
if (pongTimer) {
|
|
4799
4855
|
clearTimeout(pongTimer);
|
|
4800
4856
|
pongTimer = null;
|
|
4801
4857
|
}
|
|
4802
4858
|
});
|
|
4803
4859
|
ws.on("message", (raw) => {
|
|
4860
|
+
consecutivePongTimeouts = 0;
|
|
4861
|
+
if (pongTimer) {
|
|
4862
|
+
clearTimeout(pongTimer);
|
|
4863
|
+
pongTimer = null;
|
|
4864
|
+
}
|
|
4804
4865
|
void handleRelayMessage(
|
|
4805
4866
|
ws,
|
|
4806
4867
|
bunnyDaemon,
|
|
@@ -4976,7 +5037,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
|
|
|
4976
5037
|
});
|
|
4977
5038
|
executionIdentity = message.executionIdentity;
|
|
4978
5039
|
} catch (error) {
|
|
4979
|
-
sendRelayError(socket, message.requestId, error);
|
|
5040
|
+
await sendRelayError(socket, message.requestId, error).catch(() => void 0);
|
|
4980
5041
|
return;
|
|
4981
5042
|
}
|
|
4982
5043
|
}
|
|
@@ -5062,7 +5123,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
|
|
|
5062
5123
|
durationMs: Date.now() - codingRunStartedAt
|
|
5063
5124
|
});
|
|
5064
5125
|
}
|
|
5065
|
-
sendRelayMessage(socket, {
|
|
5126
|
+
await sendRelayMessage(socket, {
|
|
5066
5127
|
type: "start",
|
|
5067
5128
|
requestId: message.requestId,
|
|
5068
5129
|
status: response.status,
|
|
@@ -5082,7 +5143,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
|
|
|
5082
5143
|
while (true) {
|
|
5083
5144
|
const { value, done } = await reader.read();
|
|
5084
5145
|
if (done) break;
|
|
5085
|
-
sendRelayMessage(socket, {
|
|
5146
|
+
await sendRelayMessage(socket, {
|
|
5086
5147
|
type: "chunk",
|
|
5087
5148
|
requestId: message.requestId,
|
|
5088
5149
|
data: binaryResponse ? Buffer.from(value).toString("base64") : decoder?.decode(value, { stream: true }) ?? "",
|
|
@@ -5091,7 +5152,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
|
|
|
5091
5152
|
}
|
|
5092
5153
|
const tail = decoder?.decode() ?? "";
|
|
5093
5154
|
if (tail) {
|
|
5094
|
-
sendRelayMessage(socket, {
|
|
5155
|
+
await sendRelayMessage(socket, {
|
|
5095
5156
|
type: "chunk",
|
|
5096
5157
|
requestId: message.requestId,
|
|
5097
5158
|
data: tail
|
|
@@ -5102,7 +5163,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
|
|
|
5102
5163
|
reader.releaseLock();
|
|
5103
5164
|
}
|
|
5104
5165
|
}
|
|
5105
|
-
sendRelayMessage(socket, {
|
|
5166
|
+
await sendRelayMessage(socket, {
|
|
5106
5167
|
type: "end",
|
|
5107
5168
|
requestId: message.requestId
|
|
5108
5169
|
});
|
|
@@ -5114,14 +5175,16 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
|
|
|
5114
5175
|
});
|
|
5115
5176
|
}
|
|
5116
5177
|
} catch (error) {
|
|
5178
|
+
controller.abort();
|
|
5117
5179
|
if (codingRunTrace && codingRunStartedAt !== void 0) {
|
|
5118
5180
|
await writeLog("error", "relay request coding run error", {
|
|
5119
5181
|
...codingRunTrace,
|
|
5120
5182
|
status: codingRunStatus,
|
|
5121
|
-
durationMs: Date.now() - codingRunStartedAt
|
|
5183
|
+
durationMs: Date.now() - codingRunStartedAt,
|
|
5184
|
+
error: formatConnectorRelayError(error)
|
|
5122
5185
|
});
|
|
5123
5186
|
}
|
|
5124
|
-
sendRelayError(socket, message.requestId, error);
|
|
5187
|
+
await sendRelayError(socket, message.requestId, error).catch(() => void 0);
|
|
5125
5188
|
} finally {
|
|
5126
5189
|
inflight.delete(message.requestId);
|
|
5127
5190
|
}
|
|
@@ -5175,17 +5238,20 @@ var normalizeWorkspaceRequest = (request, mounts) => {
|
|
|
5175
5238
|
if (!mount || relative === void 0) {
|
|
5176
5239
|
throw new ConnectorRelayProtocolError("WORKSPACE_MISMATCH");
|
|
5177
5240
|
}
|
|
5178
|
-
const
|
|
5241
|
+
const systemEnv = body.systemEnv && typeof body.systemEnv === "object" && !Array.isArray(body.systemEnv) ? body.systemEnv : {};
|
|
5242
|
+
const workspaceEnv = {
|
|
5243
|
+
BUDA_AGENT_ROOT: mounts.agent,
|
|
5244
|
+
BUDA_SPACE_ROOT: mounts.space,
|
|
5245
|
+
BUDA_SYSTEM_ROOT: mounts.system
|
|
5246
|
+
};
|
|
5179
5247
|
return {
|
|
5180
5248
|
...request,
|
|
5181
5249
|
body: {
|
|
5182
5250
|
...body,
|
|
5183
5251
|
cwd: path12.join(mount, relative),
|
|
5184
|
-
|
|
5185
|
-
...
|
|
5186
|
-
|
|
5187
|
-
BUDA_SPACE_ROOT: mounts.space,
|
|
5188
|
-
BUDA_SYSTEM_ROOT: mounts.system
|
|
5252
|
+
systemEnv: {
|
|
5253
|
+
...systemEnv,
|
|
5254
|
+
...workspaceEnv
|
|
5189
5255
|
}
|
|
5190
5256
|
}
|
|
5191
5257
|
};
|
|
@@ -5217,17 +5283,24 @@ var normalizeConnectorFilesystemRequest = (request, mounts) => {
|
|
|
5217
5283
|
}
|
|
5218
5284
|
return request;
|
|
5219
5285
|
};
|
|
5220
|
-
function sendRelayError(socket, requestId, error) {
|
|
5221
|
-
sendRelayMessage(socket, {
|
|
5286
|
+
async function sendRelayError(socket, requestId, error) {
|
|
5287
|
+
await sendRelayMessage(socket, {
|
|
5222
5288
|
type: "error",
|
|
5223
5289
|
requestId,
|
|
5224
5290
|
error: error instanceof Error ? error.message : String(error),
|
|
5225
5291
|
...error instanceof ConnectorRelayProtocolError ? { code: error.code } : {}
|
|
5226
5292
|
});
|
|
5227
5293
|
}
|
|
5228
|
-
function sendRelayMessage(socket, message) {
|
|
5229
|
-
if (socket.readyState !== WebSocket2.OPEN)
|
|
5230
|
-
|
|
5294
|
+
async function sendRelayMessage(socket, message) {
|
|
5295
|
+
if (socket.readyState !== WebSocket2.OPEN) {
|
|
5296
|
+
throw new Error(`Connector relay socket closed before ${message.type} could be sent.`);
|
|
5297
|
+
}
|
|
5298
|
+
await new Promise((resolve, reject) => {
|
|
5299
|
+
socket.send(JSON.stringify(message), (error) => {
|
|
5300
|
+
if (error) reject(error);
|
|
5301
|
+
else resolve();
|
|
5302
|
+
});
|
|
5303
|
+
});
|
|
5231
5304
|
}
|
|
5232
5305
|
function headersToRecord(headers) {
|
|
5233
5306
|
const result = {};
|
|
@@ -5743,7 +5816,30 @@ import { mkdir as mkdir12 } from "fs/promises";
|
|
|
5743
5816
|
import path15 from "path";
|
|
5744
5817
|
var RECOVERED_DAEMON_STOP_TIMEOUT_MS = 1e4;
|
|
5745
5818
|
var RECOVERED_DAEMON_STOP_POLL_MS = 100;
|
|
5819
|
+
var SHUTDOWN_FORCE_EXIT_MS = 1e4;
|
|
5820
|
+
var SHUTDOWN_STEP_TIMEOUT_MS = 2e3;
|
|
5746
5821
|
var wait3 = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
5822
|
+
var runShutdownStep = async (label, operation) => {
|
|
5823
|
+
let timeout;
|
|
5824
|
+
try {
|
|
5825
|
+
await Promise.race([
|
|
5826
|
+
Promise.resolve().then(operation),
|
|
5827
|
+
new Promise((_, reject) => {
|
|
5828
|
+
timeout = setTimeout(
|
|
5829
|
+
() => reject(new Error(`${label} timed out after ${SHUTDOWN_STEP_TIMEOUT_MS}ms`)),
|
|
5830
|
+
SHUTDOWN_STEP_TIMEOUT_MS
|
|
5831
|
+
);
|
|
5832
|
+
})
|
|
5833
|
+
]);
|
|
5834
|
+
} catch (error) {
|
|
5835
|
+
await writeLog(
|
|
5836
|
+
"warn",
|
|
5837
|
+
`${label} failed during shutdown: ${error instanceof Error ? error.message : String(error)}`
|
|
5838
|
+
).catch(() => void 0);
|
|
5839
|
+
} finally {
|
|
5840
|
+
if (timeout) clearTimeout(timeout);
|
|
5841
|
+
}
|
|
5842
|
+
};
|
|
5747
5843
|
async function stopRecoveredIdleDaemon(config, configRoot) {
|
|
5748
5844
|
const stopStatus = await requestDaemonControl(config, "stop-if-idle", configRoot).catch(
|
|
5749
5845
|
() => null
|
|
@@ -5863,18 +5959,30 @@ async function runConnectorDaemon(launchConfig, options = {}) {
|
|
|
5863
5959
|
const shutdown = async (shutdownOptions = {}) => {
|
|
5864
5960
|
if (shuttingDown) return;
|
|
5865
5961
|
shuttingDown = true;
|
|
5962
|
+
const forceExit = options.exitOnShutdown === false ? void 0 : setTimeout(() => process.exit(0), SHUTDOWN_FORCE_EXIT_MS);
|
|
5866
5963
|
if (interval) clearInterval(interval);
|
|
5867
5964
|
relay.stop();
|
|
5868
5965
|
try {
|
|
5869
|
-
await
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5966
|
+
await Promise.all([
|
|
5967
|
+
runShutdownStep("browser session cleanup", closeAllBrowserSessions),
|
|
5968
|
+
...shutdownOptions.unregister === false ? [] : [
|
|
5969
|
+
runShutdownStep(
|
|
5970
|
+
"connector unregister",
|
|
5971
|
+
() => unregisterConnector(config, launchConfig)
|
|
5972
|
+
)
|
|
5973
|
+
],
|
|
5974
|
+
runShutdownStep(
|
|
5975
|
+
"embedded Bunny daemon shutdown",
|
|
5976
|
+
() => stopEmbeddedBunnyDaemon(activeBunnyDaemon)
|
|
5977
|
+
)
|
|
5978
|
+
]);
|
|
5874
5979
|
} finally {
|
|
5875
|
-
await
|
|
5876
|
-
|
|
5877
|
-
|
|
5980
|
+
await Promise.all([
|
|
5981
|
+
runShutdownStep("control channel shutdown", async () => control?.close()),
|
|
5982
|
+
runShutdownStep("daemon lock release", () => daemonLock.release()),
|
|
5983
|
+
runShutdownStep("console capture restore", async () => restoreConsole?.())
|
|
5984
|
+
]);
|
|
5985
|
+
if (forceExit) clearTimeout(forceExit);
|
|
5878
5986
|
if (options.exitOnShutdown !== false) process.exit(0);
|
|
5879
5987
|
}
|
|
5880
5988
|
};
|
|
@@ -5889,8 +5997,11 @@ async function runConnectorDaemon(launchConfig, options = {}) {
|
|
|
5889
5997
|
});
|
|
5890
5998
|
}).catch((error) => {
|
|
5891
5999
|
heartbeatHealthy = false;
|
|
5892
|
-
if (error instanceof ConnectorDeletedError) {
|
|
5893
|
-
void writeLog(
|
|
6000
|
+
if (error instanceof ConnectorDeletedError || error instanceof ConnectorUnauthorizedError) {
|
|
6001
|
+
void writeLog(
|
|
6002
|
+
"warn",
|
|
6003
|
+
error instanceof ConnectorDeletedError ? "connector deleted remotely; stopping daemon" : "connector authentication rejected remotely; stopping daemon"
|
|
6004
|
+
);
|
|
5894
6005
|
void shutdown({ unregister: false });
|
|
5895
6006
|
return;
|
|
5896
6007
|
}
|