@autohq/cli 0.1.400 → 0.1.401
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/agent-bridge.js +133 -4
- package/dist/index.js +133 -4
- package/package.json +1 -1
package/dist/agent-bridge.js
CHANGED
|
@@ -30819,7 +30819,7 @@ Object.assign(lookup, {
|
|
|
30819
30819
|
// package.json
|
|
30820
30820
|
var package_default = {
|
|
30821
30821
|
name: "@autohq/cli",
|
|
30822
|
-
version: "0.1.
|
|
30822
|
+
version: "0.1.401",
|
|
30823
30823
|
license: "SEE LICENSE IN README.md",
|
|
30824
30824
|
publishConfig: {
|
|
30825
30825
|
access: "public"
|
|
@@ -30912,6 +30912,7 @@ var AgentBridgeOutputAckTimeoutError = class extends Error {
|
|
|
30912
30912
|
this.name = "AgentBridgeOutputAckTimeoutError";
|
|
30913
30913
|
}
|
|
30914
30914
|
};
|
|
30915
|
+
var AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_TIMEOUT_MS = 6e4;
|
|
30915
30916
|
async function runAgentBridgeSocket(options) {
|
|
30916
30917
|
const socket = lookup(`${options.bridgeUrl}${RUNTIME_BRIDGE_NAMESPACE}`, {
|
|
30917
30918
|
auth: {
|
|
@@ -30923,6 +30924,13 @@ async function runAgentBridgeSocket(options) {
|
|
|
30923
30924
|
});
|
|
30924
30925
|
let handler = null;
|
|
30925
30926
|
const reconnectLoop = createReconnectLoop(socket);
|
|
30927
|
+
const terminalAuthDrain = createTerminalAuthDrainController({
|
|
30928
|
+
socket,
|
|
30929
|
+
token: options.token,
|
|
30930
|
+
getHandler: () => handler,
|
|
30931
|
+
writeOutput: options.writeOutput,
|
|
30932
|
+
runtimeLogger: options.runtimeLogger
|
|
30933
|
+
});
|
|
30926
30934
|
let hasConnected = false;
|
|
30927
30935
|
await new Promise((resolve2, reject) => {
|
|
30928
30936
|
const shutdown = () => {
|
|
@@ -30934,15 +30942,23 @@ async function runAgentBridgeSocket(options) {
|
|
|
30934
30942
|
process.once("SIGINT", shutdown);
|
|
30935
30943
|
process.once("SIGTERM", shutdown);
|
|
30936
30944
|
socket.on("connect_error", (error51) => {
|
|
30945
|
+
if (terminalAuthDrain.handleConnectError(error51)) {
|
|
30946
|
+
return;
|
|
30947
|
+
}
|
|
30937
30948
|
if (!hasConnected) {
|
|
30938
30949
|
reject(error51);
|
|
30939
30950
|
return;
|
|
30940
30951
|
}
|
|
30941
30952
|
if (isTerminalAuthError(error51)) {
|
|
30942
30953
|
reconnectLoop.stop();
|
|
30943
|
-
|
|
30944
|
-
|
|
30945
|
-
|
|
30954
|
+
void terminalAuthDrain.begin().catch((drainError) => {
|
|
30955
|
+
options.writeOutput?.(
|
|
30956
|
+
`agent_bridge_terminal_auth_drain_failed error=${errorMessage(drainError)}`
|
|
30957
|
+
);
|
|
30958
|
+
}).finally(() => {
|
|
30959
|
+
socket.disconnect();
|
|
30960
|
+
reject(new AgentBridgeTerminalAuthError(error51.message));
|
|
30961
|
+
});
|
|
30946
30962
|
return;
|
|
30947
30963
|
}
|
|
30948
30964
|
options.writeOutput?.(
|
|
@@ -30955,6 +30971,9 @@ async function runAgentBridgeSocket(options) {
|
|
|
30955
30971
|
return;
|
|
30956
30972
|
}
|
|
30957
30973
|
options.writeOutput?.(`agent_bridge_disconnected reason=${reason}`);
|
|
30974
|
+
if (terminalAuthDrain.suppressesReconnect()) {
|
|
30975
|
+
return;
|
|
30976
|
+
}
|
|
30958
30977
|
reconnectLoop.start();
|
|
30959
30978
|
});
|
|
30960
30979
|
socket.on(
|
|
@@ -30993,6 +31012,9 @@ async function runAgentBridgeSocket(options) {
|
|
|
30993
31012
|
})
|
|
30994
31013
|
);
|
|
30995
31014
|
socket.on(RUNTIME_BRIDGE_CONNECTED_EVENT, (rawContext) => {
|
|
31015
|
+
if (terminalAuthDrain.handleConnected(rawContext)) {
|
|
31016
|
+
return;
|
|
31017
|
+
}
|
|
30996
31018
|
const context = RuntimeBridgeConnectedPayloadSchema.parse(rawContext);
|
|
30997
31019
|
if (!handler) {
|
|
30998
31020
|
reject(new Error("Bridge connected before bootstrap completed"));
|
|
@@ -31237,6 +31259,113 @@ function createReconnectLoop(socket) {
|
|
|
31237
31259
|
};
|
|
31238
31260
|
return { start, stop };
|
|
31239
31261
|
}
|
|
31262
|
+
function createTerminalAuthDrainController(input) {
|
|
31263
|
+
let terminalAuthExit = false;
|
|
31264
|
+
let state = null;
|
|
31265
|
+
const settle = (callback) => {
|
|
31266
|
+
const current = state;
|
|
31267
|
+
if (!current) {
|
|
31268
|
+
return;
|
|
31269
|
+
}
|
|
31270
|
+
clearTimeout(current.timeout);
|
|
31271
|
+
state = null;
|
|
31272
|
+
callback();
|
|
31273
|
+
};
|
|
31274
|
+
const begin = () => {
|
|
31275
|
+
terminalAuthExit = true;
|
|
31276
|
+
if (state) {
|
|
31277
|
+
return state.promise;
|
|
31278
|
+
}
|
|
31279
|
+
const handler = input.getHandler();
|
|
31280
|
+
handler?.shutdown?.();
|
|
31281
|
+
if (!handler) {
|
|
31282
|
+
input.writeOutput?.(
|
|
31283
|
+
"agent_bridge_terminal_auth_drain_skipped reason=no_handler"
|
|
31284
|
+
);
|
|
31285
|
+
return Promise.resolve();
|
|
31286
|
+
}
|
|
31287
|
+
const startedAt = Date.now();
|
|
31288
|
+
let resolveDrain = () => {
|
|
31289
|
+
};
|
|
31290
|
+
let rejectDrain = () => {
|
|
31291
|
+
};
|
|
31292
|
+
const promise2 = new Promise((resolve2, reject) => {
|
|
31293
|
+
resolveDrain = resolve2;
|
|
31294
|
+
rejectDrain = reject;
|
|
31295
|
+
});
|
|
31296
|
+
const timeout = setTimeout(() => {
|
|
31297
|
+
settle(() => {
|
|
31298
|
+
rejectDrain(
|
|
31299
|
+
new Error(
|
|
31300
|
+
`Timed out draining pending bridge output after terminal auth in ${AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_TIMEOUT_MS}ms`
|
|
31301
|
+
)
|
|
31302
|
+
);
|
|
31303
|
+
});
|
|
31304
|
+
}, AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_TIMEOUT_MS);
|
|
31305
|
+
timeout.unref?.();
|
|
31306
|
+
state = {
|
|
31307
|
+
promise: promise2,
|
|
31308
|
+
reject: rejectDrain,
|
|
31309
|
+
resolve: resolveDrain,
|
|
31310
|
+
startedAt,
|
|
31311
|
+
timeout
|
|
31312
|
+
};
|
|
31313
|
+
input.writeOutput?.("agent_bridge_terminal_auth_drain_started");
|
|
31314
|
+
input.runtimeLogger?.warn("agent_bridge_terminal_auth_drain_started");
|
|
31315
|
+
input.socket.auth = { token: input.token, terminalDrain: true };
|
|
31316
|
+
input.socket.connect();
|
|
31317
|
+
return promise2;
|
|
31318
|
+
};
|
|
31319
|
+
const handleConnected = (rawContext) => {
|
|
31320
|
+
const current = state;
|
|
31321
|
+
if (!current) {
|
|
31322
|
+
return false;
|
|
31323
|
+
}
|
|
31324
|
+
void (async () => {
|
|
31325
|
+
const context = RuntimeBridgeConnectedPayloadSchema.parse(rawContext);
|
|
31326
|
+
input.writeOutput?.(
|
|
31327
|
+
`agent_bridge_terminal_auth_drain_connected session_id=${context.sessionId} runtime_id=${context.runtimeId} bridge_lease_id=${context.bridgeLeaseId}`
|
|
31328
|
+
);
|
|
31329
|
+
input.runtimeLogger?.warn("agent_bridge_terminal_auth_drain_connected", {
|
|
31330
|
+
session_id: context.sessionId,
|
|
31331
|
+
runtime_id: context.runtimeId,
|
|
31332
|
+
bridge_lease_id: context.bridgeLeaseId
|
|
31333
|
+
});
|
|
31334
|
+
const handler = input.getHandler();
|
|
31335
|
+
if (!handler) {
|
|
31336
|
+
throw new Error("Terminal auth drain connected without a handler");
|
|
31337
|
+
}
|
|
31338
|
+
await handler.replayPendingOutputs();
|
|
31339
|
+
settle(() => {
|
|
31340
|
+
input.writeOutput?.(
|
|
31341
|
+
`agent_bridge_terminal_auth_drain_completed duration_ms=${Date.now() - current.startedAt}`
|
|
31342
|
+
);
|
|
31343
|
+
input.runtimeLogger?.warn(
|
|
31344
|
+
"agent_bridge_terminal_auth_drain_completed",
|
|
31345
|
+
{ duration_ms: Date.now() - current.startedAt }
|
|
31346
|
+
);
|
|
31347
|
+
current.resolve();
|
|
31348
|
+
});
|
|
31349
|
+
})().catch((error51) => {
|
|
31350
|
+
settle(() => current.reject(error51));
|
|
31351
|
+
});
|
|
31352
|
+
return true;
|
|
31353
|
+
};
|
|
31354
|
+
const handleConnectError = (error51) => {
|
|
31355
|
+
const current = state;
|
|
31356
|
+
if (!current) {
|
|
31357
|
+
return false;
|
|
31358
|
+
}
|
|
31359
|
+
settle(() => current.reject(error51));
|
|
31360
|
+
return true;
|
|
31361
|
+
};
|
|
31362
|
+
return {
|
|
31363
|
+
begin,
|
|
31364
|
+
handleConnected,
|
|
31365
|
+
handleConnectError,
|
|
31366
|
+
suppressesReconnect: () => terminalAuthExit || state !== null
|
|
31367
|
+
};
|
|
31368
|
+
}
|
|
31240
31369
|
function bridgeForwardingHeaders(url3) {
|
|
31241
31370
|
if (!isNgrokFreeUrl(url3)) {
|
|
31242
31371
|
return {};
|
package/dist/index.js
CHANGED
|
@@ -35072,7 +35072,7 @@ var init_package = __esm({
|
|
|
35072
35072
|
"package.json"() {
|
|
35073
35073
|
package_default = {
|
|
35074
35074
|
name: "@autohq/cli",
|
|
35075
|
-
version: "0.1.
|
|
35075
|
+
version: "0.1.401",
|
|
35076
35076
|
license: "SEE LICENSE IN README.md",
|
|
35077
35077
|
publishConfig: {
|
|
35078
35078
|
access: "public"
|
|
@@ -45523,6 +45523,7 @@ var AgentBridgeOutputAckTimeoutError = class extends Error {
|
|
|
45523
45523
|
this.name = "AgentBridgeOutputAckTimeoutError";
|
|
45524
45524
|
}
|
|
45525
45525
|
};
|
|
45526
|
+
var AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_TIMEOUT_MS = 6e4;
|
|
45526
45527
|
async function runAgentBridgeSocket(options) {
|
|
45527
45528
|
const socket = io(`${options.bridgeUrl}${RUNTIME_BRIDGE_NAMESPACE}`, {
|
|
45528
45529
|
auth: {
|
|
@@ -45534,6 +45535,13 @@ async function runAgentBridgeSocket(options) {
|
|
|
45534
45535
|
});
|
|
45535
45536
|
let handler = null;
|
|
45536
45537
|
const reconnectLoop = createReconnectLoop(socket);
|
|
45538
|
+
const terminalAuthDrain = createTerminalAuthDrainController({
|
|
45539
|
+
socket,
|
|
45540
|
+
token: options.token,
|
|
45541
|
+
getHandler: () => handler,
|
|
45542
|
+
writeOutput: options.writeOutput,
|
|
45543
|
+
runtimeLogger: options.runtimeLogger
|
|
45544
|
+
});
|
|
45537
45545
|
let hasConnected = false;
|
|
45538
45546
|
await new Promise((resolve4, reject) => {
|
|
45539
45547
|
const shutdown = () => {
|
|
@@ -45545,15 +45553,23 @@ async function runAgentBridgeSocket(options) {
|
|
|
45545
45553
|
process.once("SIGINT", shutdown);
|
|
45546
45554
|
process.once("SIGTERM", shutdown);
|
|
45547
45555
|
socket.on("connect_error", (error51) => {
|
|
45556
|
+
if (terminalAuthDrain.handleConnectError(error51)) {
|
|
45557
|
+
return;
|
|
45558
|
+
}
|
|
45548
45559
|
if (!hasConnected) {
|
|
45549
45560
|
reject(error51);
|
|
45550
45561
|
return;
|
|
45551
45562
|
}
|
|
45552
45563
|
if (isTerminalAuthError(error51)) {
|
|
45553
45564
|
reconnectLoop.stop();
|
|
45554
|
-
|
|
45555
|
-
|
|
45556
|
-
|
|
45565
|
+
void terminalAuthDrain.begin().catch((drainError) => {
|
|
45566
|
+
options.writeOutput?.(
|
|
45567
|
+
`agent_bridge_terminal_auth_drain_failed error=${errorMessage(drainError)}`
|
|
45568
|
+
);
|
|
45569
|
+
}).finally(() => {
|
|
45570
|
+
socket.disconnect();
|
|
45571
|
+
reject(new AgentBridgeTerminalAuthError(error51.message));
|
|
45572
|
+
});
|
|
45557
45573
|
return;
|
|
45558
45574
|
}
|
|
45559
45575
|
options.writeOutput?.(
|
|
@@ -45566,6 +45582,9 @@ async function runAgentBridgeSocket(options) {
|
|
|
45566
45582
|
return;
|
|
45567
45583
|
}
|
|
45568
45584
|
options.writeOutput?.(`agent_bridge_disconnected reason=${reason}`);
|
|
45585
|
+
if (terminalAuthDrain.suppressesReconnect()) {
|
|
45586
|
+
return;
|
|
45587
|
+
}
|
|
45569
45588
|
reconnectLoop.start();
|
|
45570
45589
|
});
|
|
45571
45590
|
socket.on(
|
|
@@ -45604,6 +45623,9 @@ async function runAgentBridgeSocket(options) {
|
|
|
45604
45623
|
})
|
|
45605
45624
|
);
|
|
45606
45625
|
socket.on(RUNTIME_BRIDGE_CONNECTED_EVENT, (rawContext) => {
|
|
45626
|
+
if (terminalAuthDrain.handleConnected(rawContext)) {
|
|
45627
|
+
return;
|
|
45628
|
+
}
|
|
45607
45629
|
const context = RuntimeBridgeConnectedPayloadSchema.parse(rawContext);
|
|
45608
45630
|
if (!handler) {
|
|
45609
45631
|
reject(new Error("Bridge connected before bootstrap completed"));
|
|
@@ -45848,6 +45870,113 @@ function createReconnectLoop(socket) {
|
|
|
45848
45870
|
};
|
|
45849
45871
|
return { start, stop };
|
|
45850
45872
|
}
|
|
45873
|
+
function createTerminalAuthDrainController(input) {
|
|
45874
|
+
let terminalAuthExit = false;
|
|
45875
|
+
let state = null;
|
|
45876
|
+
const settle = (callback) => {
|
|
45877
|
+
const current = state;
|
|
45878
|
+
if (!current) {
|
|
45879
|
+
return;
|
|
45880
|
+
}
|
|
45881
|
+
clearTimeout(current.timeout);
|
|
45882
|
+
state = null;
|
|
45883
|
+
callback();
|
|
45884
|
+
};
|
|
45885
|
+
const begin = () => {
|
|
45886
|
+
terminalAuthExit = true;
|
|
45887
|
+
if (state) {
|
|
45888
|
+
return state.promise;
|
|
45889
|
+
}
|
|
45890
|
+
const handler = input.getHandler();
|
|
45891
|
+
handler?.shutdown?.();
|
|
45892
|
+
if (!handler) {
|
|
45893
|
+
input.writeOutput?.(
|
|
45894
|
+
"agent_bridge_terminal_auth_drain_skipped reason=no_handler"
|
|
45895
|
+
);
|
|
45896
|
+
return Promise.resolve();
|
|
45897
|
+
}
|
|
45898
|
+
const startedAt = Date.now();
|
|
45899
|
+
let resolveDrain = () => {
|
|
45900
|
+
};
|
|
45901
|
+
let rejectDrain = () => {
|
|
45902
|
+
};
|
|
45903
|
+
const promise2 = new Promise((resolve4, reject) => {
|
|
45904
|
+
resolveDrain = resolve4;
|
|
45905
|
+
rejectDrain = reject;
|
|
45906
|
+
});
|
|
45907
|
+
const timeout = setTimeout(() => {
|
|
45908
|
+
settle(() => {
|
|
45909
|
+
rejectDrain(
|
|
45910
|
+
new Error(
|
|
45911
|
+
`Timed out draining pending bridge output after terminal auth in ${AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_TIMEOUT_MS}ms`
|
|
45912
|
+
)
|
|
45913
|
+
);
|
|
45914
|
+
});
|
|
45915
|
+
}, AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_TIMEOUT_MS);
|
|
45916
|
+
timeout.unref?.();
|
|
45917
|
+
state = {
|
|
45918
|
+
promise: promise2,
|
|
45919
|
+
reject: rejectDrain,
|
|
45920
|
+
resolve: resolveDrain,
|
|
45921
|
+
startedAt,
|
|
45922
|
+
timeout
|
|
45923
|
+
};
|
|
45924
|
+
input.writeOutput?.("agent_bridge_terminal_auth_drain_started");
|
|
45925
|
+
input.runtimeLogger?.warn("agent_bridge_terminal_auth_drain_started");
|
|
45926
|
+
input.socket.auth = { token: input.token, terminalDrain: true };
|
|
45927
|
+
input.socket.connect();
|
|
45928
|
+
return promise2;
|
|
45929
|
+
};
|
|
45930
|
+
const handleConnected = (rawContext) => {
|
|
45931
|
+
const current = state;
|
|
45932
|
+
if (!current) {
|
|
45933
|
+
return false;
|
|
45934
|
+
}
|
|
45935
|
+
void (async () => {
|
|
45936
|
+
const context = RuntimeBridgeConnectedPayloadSchema.parse(rawContext);
|
|
45937
|
+
input.writeOutput?.(
|
|
45938
|
+
`agent_bridge_terminal_auth_drain_connected session_id=${context.sessionId} runtime_id=${context.runtimeId} bridge_lease_id=${context.bridgeLeaseId}`
|
|
45939
|
+
);
|
|
45940
|
+
input.runtimeLogger?.warn("agent_bridge_terminal_auth_drain_connected", {
|
|
45941
|
+
session_id: context.sessionId,
|
|
45942
|
+
runtime_id: context.runtimeId,
|
|
45943
|
+
bridge_lease_id: context.bridgeLeaseId
|
|
45944
|
+
});
|
|
45945
|
+
const handler = input.getHandler();
|
|
45946
|
+
if (!handler) {
|
|
45947
|
+
throw new Error("Terminal auth drain connected without a handler");
|
|
45948
|
+
}
|
|
45949
|
+
await handler.replayPendingOutputs();
|
|
45950
|
+
settle(() => {
|
|
45951
|
+
input.writeOutput?.(
|
|
45952
|
+
`agent_bridge_terminal_auth_drain_completed duration_ms=${Date.now() - current.startedAt}`
|
|
45953
|
+
);
|
|
45954
|
+
input.runtimeLogger?.warn(
|
|
45955
|
+
"agent_bridge_terminal_auth_drain_completed",
|
|
45956
|
+
{ duration_ms: Date.now() - current.startedAt }
|
|
45957
|
+
);
|
|
45958
|
+
current.resolve();
|
|
45959
|
+
});
|
|
45960
|
+
})().catch((error51) => {
|
|
45961
|
+
settle(() => current.reject(error51));
|
|
45962
|
+
});
|
|
45963
|
+
return true;
|
|
45964
|
+
};
|
|
45965
|
+
const handleConnectError = (error51) => {
|
|
45966
|
+
const current = state;
|
|
45967
|
+
if (!current) {
|
|
45968
|
+
return false;
|
|
45969
|
+
}
|
|
45970
|
+
settle(() => current.reject(error51));
|
|
45971
|
+
return true;
|
|
45972
|
+
};
|
|
45973
|
+
return {
|
|
45974
|
+
begin,
|
|
45975
|
+
handleConnected,
|
|
45976
|
+
handleConnectError,
|
|
45977
|
+
suppressesReconnect: () => terminalAuthExit || state !== null
|
|
45978
|
+
};
|
|
45979
|
+
}
|
|
45851
45980
|
function bridgeForwardingHeaders(url2) {
|
|
45852
45981
|
if (!isNgrokFreeUrl(url2)) {
|
|
45853
45982
|
return {};
|