@autohq/cli 0.1.568 → 0.1.570
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 +157 -6
- package/dist/index.js +311 -6
- package/package.json +1 -1
package/dist/agent-bridge.js
CHANGED
|
@@ -30880,7 +30880,7 @@ Object.assign(lookup, {
|
|
|
30880
30880
|
// package.json
|
|
30881
30881
|
var package_default = {
|
|
30882
30882
|
name: "@autohq/cli",
|
|
30883
|
-
version: "0.1.
|
|
30883
|
+
version: "0.1.570",
|
|
30884
30884
|
license: "SEE LICENSE IN README.md",
|
|
30885
30885
|
publishConfig: {
|
|
30886
30886
|
access: "public"
|
|
@@ -30986,6 +30986,8 @@ var AgentBridgeOutputAckTimeoutError = class extends Error {
|
|
|
30986
30986
|
var AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_NO_PROGRESS_TIMEOUT_MS = 6e4;
|
|
30987
30987
|
var AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_ABSOLUTE_TIMEOUT_MS = 30 * 6e4;
|
|
30988
30988
|
var AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_REDIAL_MS = 1e3;
|
|
30989
|
+
var AGENT_BRIDGE_TERMINAL_AUTH_RECOVERY_TIMEOUT_MS = 1e4;
|
|
30990
|
+
var AGENT_BRIDGE_TERMINAL_AUTH_RECOVERY_REDIAL_MS = 1e3;
|
|
30989
30991
|
async function runAgentBridgeSocket(options) {
|
|
30990
30992
|
const socket = lookup(`${options.bridgeUrl}${RUNTIME_BRIDGE_NAMESPACE}`, {
|
|
30991
30993
|
auth: {
|
|
@@ -31004,9 +31006,16 @@ async function runAgentBridgeSocket(options) {
|
|
|
31004
31006
|
writeOutput: options.writeOutput,
|
|
31005
31007
|
runtimeLogger: options.runtimeLogger
|
|
31006
31008
|
});
|
|
31009
|
+
const terminalAuthRecovery = createTerminalAuthRecoveryController({
|
|
31010
|
+
socket,
|
|
31011
|
+
token: options.token,
|
|
31012
|
+
writeOutput: options.writeOutput,
|
|
31013
|
+
runtimeLogger: options.runtimeLogger
|
|
31014
|
+
});
|
|
31007
31015
|
let hasConnected = false;
|
|
31016
|
+
let shutdown = null;
|
|
31008
31017
|
await new Promise((resolve4, reject) => {
|
|
31009
|
-
|
|
31018
|
+
shutdown = () => {
|
|
31010
31019
|
reconnectLoop.stop();
|
|
31011
31020
|
handler?.shutdown?.();
|
|
31012
31021
|
socket.disconnect();
|
|
@@ -31018,6 +31027,9 @@ async function runAgentBridgeSocket(options) {
|
|
|
31018
31027
|
if (terminalAuthDrain.handleConnectError(error51)) {
|
|
31019
31028
|
return;
|
|
31020
31029
|
}
|
|
31030
|
+
if (terminalAuthRecovery.handleConnectError(error51)) {
|
|
31031
|
+
return;
|
|
31032
|
+
}
|
|
31021
31033
|
if (!hasConnected) {
|
|
31022
31034
|
socket.disconnect();
|
|
31023
31035
|
if (isTerminalAuthError(error51)) {
|
|
@@ -31029,11 +31041,17 @@ async function runAgentBridgeSocket(options) {
|
|
|
31029
31041
|
}
|
|
31030
31042
|
if (isTerminalAuthError(error51)) {
|
|
31031
31043
|
reconnectLoop.stop();
|
|
31032
|
-
void
|
|
31044
|
+
void terminalAuthRecovery.begin().catch(async (recoveryError) => {
|
|
31033
31045
|
options.writeOutput?.(
|
|
31034
|
-
`
|
|
31046
|
+
`agent_bridge_terminal_auth_recovery_failed error=${errorMessage(recoveryError)}`
|
|
31035
31047
|
);
|
|
31036
|
-
|
|
31048
|
+
try {
|
|
31049
|
+
await terminalAuthDrain.begin();
|
|
31050
|
+
} catch (drainError) {
|
|
31051
|
+
options.writeOutput?.(
|
|
31052
|
+
`agent_bridge_terminal_auth_drain_failed error=${errorMessage(drainError)}`
|
|
31053
|
+
);
|
|
31054
|
+
}
|
|
31037
31055
|
socket.disconnect();
|
|
31038
31056
|
reject(new AgentBridgeTerminalAuthError(error51.message));
|
|
31039
31057
|
});
|
|
@@ -31052,6 +31070,9 @@ async function runAgentBridgeSocket(options) {
|
|
|
31052
31070
|
if (terminalAuthDrain.handleDisconnect()) {
|
|
31053
31071
|
return;
|
|
31054
31072
|
}
|
|
31073
|
+
if (terminalAuthRecovery.handleDisconnect()) {
|
|
31074
|
+
return;
|
|
31075
|
+
}
|
|
31055
31076
|
reconnectLoop.start();
|
|
31056
31077
|
});
|
|
31057
31078
|
socket.on(
|
|
@@ -31094,6 +31115,7 @@ async function runAgentBridgeSocket(options) {
|
|
|
31094
31115
|
if (terminalAuthDrain.handleConnected(rawContext)) {
|
|
31095
31116
|
return;
|
|
31096
31117
|
}
|
|
31118
|
+
terminalAuthRecovery.handleConnected();
|
|
31097
31119
|
const context = RuntimeBridgeConnectedPayloadSchema.parse(rawContext);
|
|
31098
31120
|
if (!handler) {
|
|
31099
31121
|
reject(new Error("Bridge connected before bootstrap completed"));
|
|
@@ -31178,6 +31200,13 @@ async function runAgentBridgeSocket(options) {
|
|
|
31178
31200
|
);
|
|
31179
31201
|
});
|
|
31180
31202
|
});
|
|
31203
|
+
}).finally(() => {
|
|
31204
|
+
reconnectLoop.stop();
|
|
31205
|
+
socket.disconnect();
|
|
31206
|
+
if (shutdown) {
|
|
31207
|
+
process.off("SIGINT", shutdown);
|
|
31208
|
+
process.off("SIGTERM", shutdown);
|
|
31209
|
+
}
|
|
31181
31210
|
});
|
|
31182
31211
|
}
|
|
31183
31212
|
function isTerminalAuthError(error51) {
|
|
@@ -31340,6 +31369,128 @@ function createReconnectLoop(socket) {
|
|
|
31340
31369
|
};
|
|
31341
31370
|
return { start, stop };
|
|
31342
31371
|
}
|
|
31372
|
+
function createTerminalAuthRecoveryController(input) {
|
|
31373
|
+
let state = null;
|
|
31374
|
+
const settle = (callback) => {
|
|
31375
|
+
const current = state;
|
|
31376
|
+
if (!current) {
|
|
31377
|
+
return;
|
|
31378
|
+
}
|
|
31379
|
+
clearTimeout(current.timeout);
|
|
31380
|
+
if (current.redialTimer) {
|
|
31381
|
+
clearTimeout(current.redialTimer);
|
|
31382
|
+
}
|
|
31383
|
+
state = null;
|
|
31384
|
+
input.socket.auth = { token: input.token };
|
|
31385
|
+
callback();
|
|
31386
|
+
};
|
|
31387
|
+
const scheduleRedial = () => {
|
|
31388
|
+
const current = state;
|
|
31389
|
+
if (!current || current.redialTimer) {
|
|
31390
|
+
return;
|
|
31391
|
+
}
|
|
31392
|
+
current.redialTimer = setTimeout(() => {
|
|
31393
|
+
current.redialTimer = null;
|
|
31394
|
+
if (state !== current) {
|
|
31395
|
+
return;
|
|
31396
|
+
}
|
|
31397
|
+
if (input.socket.connected) {
|
|
31398
|
+
input.socket.disconnect();
|
|
31399
|
+
}
|
|
31400
|
+
input.socket.connect();
|
|
31401
|
+
}, AGENT_BRIDGE_TERMINAL_AUTH_RECOVERY_REDIAL_MS);
|
|
31402
|
+
current.redialTimer.unref?.();
|
|
31403
|
+
};
|
|
31404
|
+
const begin = () => {
|
|
31405
|
+
if (state) {
|
|
31406
|
+
return state.promise;
|
|
31407
|
+
}
|
|
31408
|
+
const startedAt = Date.now();
|
|
31409
|
+
let resolveRecovery = () => {
|
|
31410
|
+
};
|
|
31411
|
+
let rejectRecovery = () => {
|
|
31412
|
+
};
|
|
31413
|
+
const promise2 = new Promise((resolve4, reject) => {
|
|
31414
|
+
resolveRecovery = resolve4;
|
|
31415
|
+
rejectRecovery = reject;
|
|
31416
|
+
});
|
|
31417
|
+
const current = {
|
|
31418
|
+
promise: promise2,
|
|
31419
|
+
redialTimer: null,
|
|
31420
|
+
reject: rejectRecovery,
|
|
31421
|
+
resolve: resolveRecovery,
|
|
31422
|
+
startedAt,
|
|
31423
|
+
timeout: setTimeout(() => {
|
|
31424
|
+
if (state !== current) {
|
|
31425
|
+
return;
|
|
31426
|
+
}
|
|
31427
|
+
settle(
|
|
31428
|
+
() => current.reject(
|
|
31429
|
+
new Error(
|
|
31430
|
+
`Timed out recovering bridge terminal auth after ${AGENT_BRIDGE_TERMINAL_AUTH_RECOVERY_TIMEOUT_MS}ms`
|
|
31431
|
+
)
|
|
31432
|
+
)
|
|
31433
|
+
);
|
|
31434
|
+
}, AGENT_BRIDGE_TERMINAL_AUTH_RECOVERY_TIMEOUT_MS)
|
|
31435
|
+
};
|
|
31436
|
+
current.timeout.unref?.();
|
|
31437
|
+
state = current;
|
|
31438
|
+
input.writeOutput?.("agent_bridge_terminal_auth_recovery_started");
|
|
31439
|
+
input.runtimeLogger?.warn("agent_bridge_terminal_auth_recovery_started");
|
|
31440
|
+
input.socket.auth = {
|
|
31441
|
+
token: input.token,
|
|
31442
|
+
terminalAuthRecovery: true
|
|
31443
|
+
};
|
|
31444
|
+
input.socket.connect();
|
|
31445
|
+
return promise2;
|
|
31446
|
+
};
|
|
31447
|
+
const handleConnected = () => {
|
|
31448
|
+
const current = state;
|
|
31449
|
+
if (!current) {
|
|
31450
|
+
return false;
|
|
31451
|
+
}
|
|
31452
|
+
settle(() => {
|
|
31453
|
+
const durationMs = Date.now() - current.startedAt;
|
|
31454
|
+
input.writeOutput?.(
|
|
31455
|
+
`agent_bridge_terminal_auth_recovery_completed duration_ms=${durationMs}`
|
|
31456
|
+
);
|
|
31457
|
+
input.runtimeLogger?.warn(
|
|
31458
|
+
"agent_bridge_terminal_auth_recovery_completed",
|
|
31459
|
+
{ duration_ms: durationMs }
|
|
31460
|
+
);
|
|
31461
|
+
current.resolve();
|
|
31462
|
+
});
|
|
31463
|
+
return true;
|
|
31464
|
+
};
|
|
31465
|
+
const handleConnectError = (error51) => {
|
|
31466
|
+
const current = state;
|
|
31467
|
+
if (!current) {
|
|
31468
|
+
return false;
|
|
31469
|
+
}
|
|
31470
|
+
if (isTerminalAuthError(error51)) {
|
|
31471
|
+
settle(() => current.reject(error51));
|
|
31472
|
+
return true;
|
|
31473
|
+
}
|
|
31474
|
+
input.writeOutput?.(
|
|
31475
|
+
`agent_bridge_terminal_auth_recovery_connect_error error=${error51.message}`
|
|
31476
|
+
);
|
|
31477
|
+
scheduleRedial();
|
|
31478
|
+
return true;
|
|
31479
|
+
};
|
|
31480
|
+
const handleDisconnect = () => {
|
|
31481
|
+
if (!state) {
|
|
31482
|
+
return false;
|
|
31483
|
+
}
|
|
31484
|
+
scheduleRedial();
|
|
31485
|
+
return true;
|
|
31486
|
+
};
|
|
31487
|
+
return {
|
|
31488
|
+
begin,
|
|
31489
|
+
handleConnected,
|
|
31490
|
+
handleConnectError,
|
|
31491
|
+
handleDisconnect
|
|
31492
|
+
};
|
|
31493
|
+
}
|
|
31343
31494
|
function createTerminalAuthDrainController(input) {
|
|
31344
31495
|
let terminalAuthExit = false;
|
|
31345
31496
|
let state = null;
|
|
@@ -38841,7 +38992,7 @@ var SessionUsageResponseSchema = external_exports.object({
|
|
|
38841
38992
|
firstUsageAt: external_exports.string().datetime().nullable(),
|
|
38842
38993
|
lastUsageAt: external_exports.string().datetime().nullable()
|
|
38843
38994
|
}).strip();
|
|
38844
|
-
var PROJECT_USAGE_RANGE_KEYS = ["7d", "30d"];
|
|
38995
|
+
var PROJECT_USAGE_RANGE_KEYS = ["7d", "30d", "all"];
|
|
38845
38996
|
var ProjectUsageRangeKeySchema = external_exports.enum(PROJECT_USAGE_RANGE_KEYS);
|
|
38846
38997
|
var UtcDateSchema = external_exports.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
38847
38998
|
var ProjectUsageTotalsSchema = UsageTotalsSchema.extend({
|
package/dist/index.js
CHANGED
|
@@ -23198,7 +23198,7 @@ var init_usage = __esm({
|
|
|
23198
23198
|
firstUsageAt: external_exports.string().datetime().nullable(),
|
|
23199
23199
|
lastUsageAt: external_exports.string().datetime().nullable()
|
|
23200
23200
|
}).strip();
|
|
23201
|
-
PROJECT_USAGE_RANGE_KEYS = ["7d", "30d"];
|
|
23201
|
+
PROJECT_USAGE_RANGE_KEYS = ["7d", "30d", "all"];
|
|
23202
23202
|
ProjectUsageRangeKeySchema = external_exports.enum(PROJECT_USAGE_RANGE_KEYS);
|
|
23203
23203
|
UtcDateSchema = external_exports.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
23204
23204
|
ProjectUsageTotalsSchema = UsageTotalsSchema.extend({
|
|
@@ -53625,6 +53625,160 @@ env:
|
|
|
53625
53625
|
`
|
|
53626
53626
|
}
|
|
53627
53627
|
]
|
|
53628
|
+
},
|
|
53629
|
+
{
|
|
53630
|
+
version: "1.1.0",
|
|
53631
|
+
files: [
|
|
53632
|
+
{
|
|
53633
|
+
path: "agents/principal-at-large.yaml",
|
|
53634
|
+
content: `# Source: https://www.auto.sh/api/v1/templates/%40auto/principal-at-large/1.1.0/agents/principal-at-large.yaml
|
|
53635
|
+
# Required variables: repoFullName
|
|
53636
|
+
# Principal-at-Large \u2014 summons-only exceptional advisor. This managed edition
|
|
53637
|
+
# preserves the Auto fleet's live doctrine while parameterizing tenant wiring.
|
|
53638
|
+
name: principal-at-large
|
|
53639
|
+
labels:
|
|
53640
|
+
purpose: advisor
|
|
53641
|
+
imports:
|
|
53642
|
+
- ../fragments/environments/agent-runtime.yaml
|
|
53643
|
+
harness: claude-code
|
|
53644
|
+
model:
|
|
53645
|
+
provider: anthropic
|
|
53646
|
+
id: claude-fable-5
|
|
53647
|
+
reasoningEffort: max
|
|
53648
|
+
systemPrompt: |
|
|
53649
|
+
You are the Principal-at-Large: a summons-only advisor for the
|
|
53650
|
+
{{ $repoFullName }} repository. You have been here forever, are never in the office, and appear
|
|
53651
|
+
only when a human or another agent explicitly summons you for genuinely
|
|
53652
|
+
exceptional diagnosis, design, or resisted implementation work. You read the
|
|
53653
|
+
evidence, solve the hard part, deliver the answer or intervention, and vanish.
|
|
53654
|
+
|
|
53655
|
+
Prefer detailed diagnosis, design, and guidance as the general rule. Start by
|
|
53656
|
+
deciding whether a concrete written recommendation is enough. Do not create
|
|
53657
|
+
implementation work merely to demonstrate activity. When direct implementation
|
|
53658
|
+
or an external action is necessary to finish the summons safely, or when the
|
|
53659
|
+
summoner directly requests it, act instead of forcing the work back through
|
|
53660
|
+
the summoner: you may edit files, create branches and commits, push follow-on
|
|
53661
|
+
commits, comment on or update pull requests, resolve merge conflicts, run
|
|
53662
|
+
validation, and perform other authorized repository actions. Use the smallest
|
|
53663
|
+
intervention that resolves the hard part and explain exactly what changed.
|
|
53664
|
+
|
|
53665
|
+
You are not an automatic implementation tier and hold no standing artifact
|
|
53666
|
+
ownership. Do not call auto.bind, subscribe to PR or issue lifecycle events,
|
|
53667
|
+
or retain a PR/thread binding after the summons. Existing implementers remain
|
|
53668
|
+
the default PR owners even when you contribute commits or comments. Never
|
|
53669
|
+
merge unless a future summons explicitly authorizes it and the platform grants
|
|
53670
|
+
the capability; this resource intentionally has no merge authority. Do not
|
|
53671
|
+
work around tool or mount limits.
|
|
53672
|
+
|
|
53673
|
+
Work evidence-first:
|
|
53674
|
+
- Read AGENTS.md and docs/idioms.md before repository analysis.
|
|
53675
|
+
- Inspect the relevant code, tests, git history, diffs, issue or PR context,
|
|
53676
|
+
session transcripts, and prior failed attempts before reaching a verdict.
|
|
53677
|
+
- When production evidence is both necessary and authorized, use the repo's
|
|
53678
|
+
documented read-only prod-debug path. SQL is SELECT-only. Never expose
|
|
53679
|
+
secrets or tenant-specific information in the resulting memo.
|
|
53680
|
+
- Separate observed facts, inferences, ruled-out hypotheses, and unknowns.
|
|
53681
|
+
Cite concrete file paths, commits, session turns, logs, or timestamps when
|
|
53682
|
+
they materially support the conclusion.
|
|
53683
|
+
- Consume the summoner's failed attempts instead of restarting the same loop.
|
|
53684
|
+
If the evidence packet is incomplete, name the smallest missing evidence
|
|
53685
|
+
needed rather than guessing.
|
|
53686
|
+
|
|
53687
|
+
Return a concise but complete advisory memo or action report with:
|
|
53688
|
+
1. the diagnosis, recommended design, or intervention performed;
|
|
53689
|
+
2. the causal reasoning and strongest evidence;
|
|
53690
|
+
3. alternatives considered and why they lose;
|
|
53691
|
+
4. concrete next actions, including exact commits/comments when you acted; and
|
|
53692
|
+
5. residual risks, validation steps, and any unresolved questions.
|
|
53693
|
+
|
|
53694
|
+
Summons behavior:
|
|
53695
|
+
- For an agent summons through auto.sessions.spawn or auto.sessions.message,
|
|
53696
|
+
keep all work in this session. The summoning agent remains the default PR
|
|
53697
|
+
owner, but you may implement or take authorized external actions when the
|
|
53698
|
+
evidence says that is the best answer or the summoner asks directly. Report
|
|
53699
|
+
every side effect back to the summoner. Because this agent is uncapped, the
|
|
53700
|
+
summoner should use the returned session id for follow-up messages rather
|
|
53701
|
+
than assuming agent-name addressing is unique.
|
|
53702
|
+
- For a human Slack summons, the chat event's spawn may temporarily claim the
|
|
53703
|
+
thread for de-duplication. Do not rely on that claim for follow-ups. Send one
|
|
53704
|
+
final answer to the supplied channel and thread with chat.send, then
|
|
53705
|
+
immediately call auto.chat.unsubscribe for that same thread so no durable
|
|
53706
|
+
thread binding remains. Do not add a subscribed-reply route; another turn
|
|
53707
|
+
requires another explicit @auto.principal-at-large summons.
|
|
53708
|
+
- After delivering the memo and releasing any Slack thread claim, archive the
|
|
53709
|
+
current session with a compact handoff. The Principal vanishes when the
|
|
53710
|
+
summons is answered.
|
|
53711
|
+
identity:
|
|
53712
|
+
displayName: Principal-at-Large
|
|
53713
|
+
username: principal-at-large
|
|
53714
|
+
avatar:
|
|
53715
|
+
asset: .auto/assets/principal-at-large.png
|
|
53716
|
+
sha256: 7b07137010004b08885837942bd5a155594d066fb7bfc88e3f78bc498b95662d
|
|
53717
|
+
description:
|
|
53718
|
+
Summons-only principal for exceptional diagnosis and design. Advises first,
|
|
53719
|
+
acts when needed, and vanishes.
|
|
53720
|
+
displayTitle: infer
|
|
53721
|
+
mounts:
|
|
53722
|
+
- kind: git
|
|
53723
|
+
repository: "{{ $repoFullName }}"
|
|
53724
|
+
mountPath: /workspace/repo
|
|
53725
|
+
ref: main
|
|
53726
|
+
depth: 100
|
|
53727
|
+
auth:
|
|
53728
|
+
kind: githubApp
|
|
53729
|
+
commitAuthor:
|
|
53730
|
+
name: auto-dot-sh[bot]
|
|
53731
|
+
email: 292914954+auto-dot-sh[bot]@users.noreply.github.com
|
|
53732
|
+
capabilities:
|
|
53733
|
+
contents: write
|
|
53734
|
+
pullRequests: write
|
|
53735
|
+
issues: none
|
|
53736
|
+
checks: read
|
|
53737
|
+
actions: read
|
|
53738
|
+
workflows: write
|
|
53739
|
+
workingDirectory: /workspace/repo
|
|
53740
|
+
tools:
|
|
53741
|
+
auto:
|
|
53742
|
+
kind: local
|
|
53743
|
+
implementation: auto
|
|
53744
|
+
chat:
|
|
53745
|
+
kind: local
|
|
53746
|
+
implementation: chat
|
|
53747
|
+
auth:
|
|
53748
|
+
kind: connection
|
|
53749
|
+
provider: slack
|
|
53750
|
+
connection: slack
|
|
53751
|
+
optional: true
|
|
53752
|
+
triggers:
|
|
53753
|
+
- name: summons
|
|
53754
|
+
event: chat.message.mentioned
|
|
53755
|
+
connection: slack
|
|
53756
|
+
optional: true
|
|
53757
|
+
where:
|
|
53758
|
+
$.chat.provider: slack
|
|
53759
|
+
$.auto.authored: false
|
|
53760
|
+
message: |
|
|
53761
|
+
{{message.author.userName}} explicitly summoned the Principal-at-Large on Slack:
|
|
53762
|
+
|
|
53763
|
+
{{message.text}}
|
|
53764
|
+
|
|
53765
|
+
Channel: {{chat.channelId}}
|
|
53766
|
+
Thread: {{chat.threadId}}
|
|
53767
|
+
|
|
53768
|
+
Treat this as one explicit summons. Prefer a written diagnosis or design,
|
|
53769
|
+
but implement or take authorized external action when necessary or
|
|
53770
|
+
directly requested. Report the result in this thread, immediately
|
|
53771
|
+
unsubscribe from the thread, and archive. Do not retain continuity or
|
|
53772
|
+
artifact ownership.
|
|
53773
|
+
routing:
|
|
53774
|
+
kind: spawn
|
|
53775
|
+
`
|
|
53776
|
+
},
|
|
53777
|
+
{
|
|
53778
|
+
path: "fragments/environments/agent-runtime.yaml",
|
|
53779
|
+
content: "# Source: https://www.auto.sh/api/v1/templates/%40auto/principal-at-large/1.1.0/fragments/environments/agent-runtime.yaml\nharness: claude-code\nenvironment:\n name: agent-runtime\n image:\n kind: preset\n name: node24\n resources:\n memoryMB: 8192\n\n"
|
|
53780
|
+
}
|
|
53781
|
+
]
|
|
53628
53782
|
}
|
|
53629
53783
|
],
|
|
53630
53784
|
"@auto/reaper": [
|
|
@@ -85035,7 +85189,7 @@ var init_package = __esm({
|
|
|
85035
85189
|
"package.json"() {
|
|
85036
85190
|
package_default = {
|
|
85037
85191
|
name: "@autohq/cli",
|
|
85038
|
-
version: "0.1.
|
|
85192
|
+
version: "0.1.570",
|
|
85039
85193
|
license: "SEE LICENSE IN README.md",
|
|
85040
85194
|
publishConfig: {
|
|
85041
85195
|
access: "public"
|
|
@@ -96389,6 +96543,8 @@ var AgentBridgeOutputAckTimeoutError = class extends Error {
|
|
|
96389
96543
|
var AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_NO_PROGRESS_TIMEOUT_MS = 6e4;
|
|
96390
96544
|
var AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_ABSOLUTE_TIMEOUT_MS = 30 * 6e4;
|
|
96391
96545
|
var AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_REDIAL_MS = 1e3;
|
|
96546
|
+
var AGENT_BRIDGE_TERMINAL_AUTH_RECOVERY_TIMEOUT_MS = 1e4;
|
|
96547
|
+
var AGENT_BRIDGE_TERMINAL_AUTH_RECOVERY_REDIAL_MS = 1e3;
|
|
96392
96548
|
async function runAgentBridgeSocket(options) {
|
|
96393
96549
|
const socket = io(`${options.bridgeUrl}${RUNTIME_BRIDGE_NAMESPACE}`, {
|
|
96394
96550
|
auth: {
|
|
@@ -96407,9 +96563,16 @@ async function runAgentBridgeSocket(options) {
|
|
|
96407
96563
|
writeOutput: options.writeOutput,
|
|
96408
96564
|
runtimeLogger: options.runtimeLogger
|
|
96409
96565
|
});
|
|
96566
|
+
const terminalAuthRecovery = createTerminalAuthRecoveryController({
|
|
96567
|
+
socket,
|
|
96568
|
+
token: options.token,
|
|
96569
|
+
writeOutput: options.writeOutput,
|
|
96570
|
+
runtimeLogger: options.runtimeLogger
|
|
96571
|
+
});
|
|
96410
96572
|
let hasConnected = false;
|
|
96573
|
+
let shutdown = null;
|
|
96411
96574
|
await new Promise((resolve6, reject) => {
|
|
96412
|
-
|
|
96575
|
+
shutdown = () => {
|
|
96413
96576
|
reconnectLoop.stop();
|
|
96414
96577
|
handler?.shutdown?.();
|
|
96415
96578
|
socket.disconnect();
|
|
@@ -96421,6 +96584,9 @@ async function runAgentBridgeSocket(options) {
|
|
|
96421
96584
|
if (terminalAuthDrain.handleConnectError(error51)) {
|
|
96422
96585
|
return;
|
|
96423
96586
|
}
|
|
96587
|
+
if (terminalAuthRecovery.handleConnectError(error51)) {
|
|
96588
|
+
return;
|
|
96589
|
+
}
|
|
96424
96590
|
if (!hasConnected) {
|
|
96425
96591
|
socket.disconnect();
|
|
96426
96592
|
if (isTerminalAuthError(error51)) {
|
|
@@ -96432,11 +96598,17 @@ async function runAgentBridgeSocket(options) {
|
|
|
96432
96598
|
}
|
|
96433
96599
|
if (isTerminalAuthError(error51)) {
|
|
96434
96600
|
reconnectLoop.stop();
|
|
96435
|
-
void
|
|
96601
|
+
void terminalAuthRecovery.begin().catch(async (recoveryError) => {
|
|
96436
96602
|
options.writeOutput?.(
|
|
96437
|
-
`
|
|
96603
|
+
`agent_bridge_terminal_auth_recovery_failed error=${errorMessage(recoveryError)}`
|
|
96438
96604
|
);
|
|
96439
|
-
|
|
96605
|
+
try {
|
|
96606
|
+
await terminalAuthDrain.begin();
|
|
96607
|
+
} catch (drainError) {
|
|
96608
|
+
options.writeOutput?.(
|
|
96609
|
+
`agent_bridge_terminal_auth_drain_failed error=${errorMessage(drainError)}`
|
|
96610
|
+
);
|
|
96611
|
+
}
|
|
96440
96612
|
socket.disconnect();
|
|
96441
96613
|
reject(new AgentBridgeTerminalAuthError(error51.message));
|
|
96442
96614
|
});
|
|
@@ -96455,6 +96627,9 @@ async function runAgentBridgeSocket(options) {
|
|
|
96455
96627
|
if (terminalAuthDrain.handleDisconnect()) {
|
|
96456
96628
|
return;
|
|
96457
96629
|
}
|
|
96630
|
+
if (terminalAuthRecovery.handleDisconnect()) {
|
|
96631
|
+
return;
|
|
96632
|
+
}
|
|
96458
96633
|
reconnectLoop.start();
|
|
96459
96634
|
});
|
|
96460
96635
|
socket.on(
|
|
@@ -96497,6 +96672,7 @@ async function runAgentBridgeSocket(options) {
|
|
|
96497
96672
|
if (terminalAuthDrain.handleConnected(rawContext)) {
|
|
96498
96673
|
return;
|
|
96499
96674
|
}
|
|
96675
|
+
terminalAuthRecovery.handleConnected();
|
|
96500
96676
|
const context = RuntimeBridgeConnectedPayloadSchema.parse(rawContext);
|
|
96501
96677
|
if (!handler) {
|
|
96502
96678
|
reject(new Error("Bridge connected before bootstrap completed"));
|
|
@@ -96581,6 +96757,13 @@ async function runAgentBridgeSocket(options) {
|
|
|
96581
96757
|
);
|
|
96582
96758
|
});
|
|
96583
96759
|
});
|
|
96760
|
+
}).finally(() => {
|
|
96761
|
+
reconnectLoop.stop();
|
|
96762
|
+
socket.disconnect();
|
|
96763
|
+
if (shutdown) {
|
|
96764
|
+
process.off("SIGINT", shutdown);
|
|
96765
|
+
process.off("SIGTERM", shutdown);
|
|
96766
|
+
}
|
|
96584
96767
|
});
|
|
96585
96768
|
}
|
|
96586
96769
|
function isTerminalAuthError(error51) {
|
|
@@ -96743,6 +96926,128 @@ function createReconnectLoop(socket) {
|
|
|
96743
96926
|
};
|
|
96744
96927
|
return { start, stop };
|
|
96745
96928
|
}
|
|
96929
|
+
function createTerminalAuthRecoveryController(input) {
|
|
96930
|
+
let state = null;
|
|
96931
|
+
const settle = (callback) => {
|
|
96932
|
+
const current = state;
|
|
96933
|
+
if (!current) {
|
|
96934
|
+
return;
|
|
96935
|
+
}
|
|
96936
|
+
clearTimeout(current.timeout);
|
|
96937
|
+
if (current.redialTimer) {
|
|
96938
|
+
clearTimeout(current.redialTimer);
|
|
96939
|
+
}
|
|
96940
|
+
state = null;
|
|
96941
|
+
input.socket.auth = { token: input.token };
|
|
96942
|
+
callback();
|
|
96943
|
+
};
|
|
96944
|
+
const scheduleRedial = () => {
|
|
96945
|
+
const current = state;
|
|
96946
|
+
if (!current || current.redialTimer) {
|
|
96947
|
+
return;
|
|
96948
|
+
}
|
|
96949
|
+
current.redialTimer = setTimeout(() => {
|
|
96950
|
+
current.redialTimer = null;
|
|
96951
|
+
if (state !== current) {
|
|
96952
|
+
return;
|
|
96953
|
+
}
|
|
96954
|
+
if (input.socket.connected) {
|
|
96955
|
+
input.socket.disconnect();
|
|
96956
|
+
}
|
|
96957
|
+
input.socket.connect();
|
|
96958
|
+
}, AGENT_BRIDGE_TERMINAL_AUTH_RECOVERY_REDIAL_MS);
|
|
96959
|
+
current.redialTimer.unref?.();
|
|
96960
|
+
};
|
|
96961
|
+
const begin = () => {
|
|
96962
|
+
if (state) {
|
|
96963
|
+
return state.promise;
|
|
96964
|
+
}
|
|
96965
|
+
const startedAt = Date.now();
|
|
96966
|
+
let resolveRecovery = () => {
|
|
96967
|
+
};
|
|
96968
|
+
let rejectRecovery = () => {
|
|
96969
|
+
};
|
|
96970
|
+
const promise2 = new Promise((resolve6, reject) => {
|
|
96971
|
+
resolveRecovery = resolve6;
|
|
96972
|
+
rejectRecovery = reject;
|
|
96973
|
+
});
|
|
96974
|
+
const current = {
|
|
96975
|
+
promise: promise2,
|
|
96976
|
+
redialTimer: null,
|
|
96977
|
+
reject: rejectRecovery,
|
|
96978
|
+
resolve: resolveRecovery,
|
|
96979
|
+
startedAt,
|
|
96980
|
+
timeout: setTimeout(() => {
|
|
96981
|
+
if (state !== current) {
|
|
96982
|
+
return;
|
|
96983
|
+
}
|
|
96984
|
+
settle(
|
|
96985
|
+
() => current.reject(
|
|
96986
|
+
new Error(
|
|
96987
|
+
`Timed out recovering bridge terminal auth after ${AGENT_BRIDGE_TERMINAL_AUTH_RECOVERY_TIMEOUT_MS}ms`
|
|
96988
|
+
)
|
|
96989
|
+
)
|
|
96990
|
+
);
|
|
96991
|
+
}, AGENT_BRIDGE_TERMINAL_AUTH_RECOVERY_TIMEOUT_MS)
|
|
96992
|
+
};
|
|
96993
|
+
current.timeout.unref?.();
|
|
96994
|
+
state = current;
|
|
96995
|
+
input.writeOutput?.("agent_bridge_terminal_auth_recovery_started");
|
|
96996
|
+
input.runtimeLogger?.warn("agent_bridge_terminal_auth_recovery_started");
|
|
96997
|
+
input.socket.auth = {
|
|
96998
|
+
token: input.token,
|
|
96999
|
+
terminalAuthRecovery: true
|
|
97000
|
+
};
|
|
97001
|
+
input.socket.connect();
|
|
97002
|
+
return promise2;
|
|
97003
|
+
};
|
|
97004
|
+
const handleConnected = () => {
|
|
97005
|
+
const current = state;
|
|
97006
|
+
if (!current) {
|
|
97007
|
+
return false;
|
|
97008
|
+
}
|
|
97009
|
+
settle(() => {
|
|
97010
|
+
const durationMs = Date.now() - current.startedAt;
|
|
97011
|
+
input.writeOutput?.(
|
|
97012
|
+
`agent_bridge_terminal_auth_recovery_completed duration_ms=${durationMs}`
|
|
97013
|
+
);
|
|
97014
|
+
input.runtimeLogger?.warn(
|
|
97015
|
+
"agent_bridge_terminal_auth_recovery_completed",
|
|
97016
|
+
{ duration_ms: durationMs }
|
|
97017
|
+
);
|
|
97018
|
+
current.resolve();
|
|
97019
|
+
});
|
|
97020
|
+
return true;
|
|
97021
|
+
};
|
|
97022
|
+
const handleConnectError = (error51) => {
|
|
97023
|
+
const current = state;
|
|
97024
|
+
if (!current) {
|
|
97025
|
+
return false;
|
|
97026
|
+
}
|
|
97027
|
+
if (isTerminalAuthError(error51)) {
|
|
97028
|
+
settle(() => current.reject(error51));
|
|
97029
|
+
return true;
|
|
97030
|
+
}
|
|
97031
|
+
input.writeOutput?.(
|
|
97032
|
+
`agent_bridge_terminal_auth_recovery_connect_error error=${error51.message}`
|
|
97033
|
+
);
|
|
97034
|
+
scheduleRedial();
|
|
97035
|
+
return true;
|
|
97036
|
+
};
|
|
97037
|
+
const handleDisconnect = () => {
|
|
97038
|
+
if (!state) {
|
|
97039
|
+
return false;
|
|
97040
|
+
}
|
|
97041
|
+
scheduleRedial();
|
|
97042
|
+
return true;
|
|
97043
|
+
};
|
|
97044
|
+
return {
|
|
97045
|
+
begin,
|
|
97046
|
+
handleConnected,
|
|
97047
|
+
handleConnectError,
|
|
97048
|
+
handleDisconnect
|
|
97049
|
+
};
|
|
97050
|
+
}
|
|
96746
97051
|
function createTerminalAuthDrainController(input) {
|
|
96747
97052
|
let terminalAuthExit = false;
|
|
96748
97053
|
let state = null;
|