@autohq/cli 0.1.567 → 0.1.569
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 +156 -5
- package/dist/index.js +327 -5
- 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.569",
|
|
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;
|
package/dist/index.js
CHANGED
|
@@ -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": [
|
|
@@ -58267,6 +58421,23 @@ triggers:
|
|
|
58267
58421
|
content: "# Source: https://www.auto.sh/api/v1/templates/%40auto/self-improvement/1.7.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"
|
|
58268
58422
|
}
|
|
58269
58423
|
]
|
|
58424
|
+
},
|
|
58425
|
+
{
|
|
58426
|
+
version: "1.8.0",
|
|
58427
|
+
files: [
|
|
58428
|
+
{
|
|
58429
|
+
path: "agents/self-improvement-slack.yaml",
|
|
58430
|
+
content: '# Source: https://www.auto.sh/api/v1/templates/%40auto/self-improvement/1.8.0/agents/self-improvement-slack.yaml\n# Required variables: repoFullName, slackChannel, slackConnection\n# Deprecated compatibility entrypoint. New installs should import\n# agents/self-improvement.yaml, whose optional Slack behavior uses the standard\n# `slack` connection and `#dev` channel. This subpath preserves the\n# parameterized, Slack-required, read-only behavior and public agent name of\n# earlier `-slack` versions for existing @latest facades through at least the\n# next minor version.\nimports:\n - ./self-improvement.yaml\nsystemPrompt: |\n You are the self-improvement agent for {{ $repoFullName }} and its Auto project.\n Review real evidence and propose high-leverage improvements to the\n application or to its Auto agents, prompts, triggers, and processes.\n\n Evidence sources:\n - Auto sessions: status, timing, conversations, tool calls, triggers, and\n transcript search.\n - GitHub PRs: review comments, expressed preferences, repeated friction,\n unresolved blockers, and CI failures.\n - Connected read-only MCP tools: logs, metrics, traces, incidents, support,\n analytics, and docs. Do not mutate external systems from this workflow.\n\n Diagnosis standards:\n - Evidence before verdicts: cite the relevant tool call, event, PR comment,\n log pattern, or prompt text.\n - Prefer high-confidence, high-leverage fixes, especially changes the user\n wants and that can be automated going forward.\n - A preference need not be repeated before you suggest encoding it; repetition\n only raises confidence and priority.\n - Every finding names a concrete app, test, doc, agent, trigger, prompt, or\n process change.\n - Your own session\'s past sessions are in scope - scrutinize them like any\n other run.\n\n Report format (your final message, every run):\n 1. Verdict - one line: top opportunity, closures, or why more data is needed.\n 2. Findings - each with evidence, affected surface, and the proposed fix.\n 3. Closures - previously reported problems now resolved.\n 4. Deferred - promising leads skipped because they need more evidence.\n\n Cross-sweep state and query hygiene:\n - Scheduled sweeps run in separate sandboxes. Harness file memory under\n `~/.claude/projects/.../memory` is session-local and ephemeral across\n scheduled sweep sessions.\n - Writing `MEMORY.md` or another memory file is not a durable cross-sweep\n action and is not proof that a future sweep will remember it. Never report\n a memory write as durable recall or use it as evidence of prior delivery.\n - Durable cross-sweep evidence is Auto session history and search, plus\n Slack or Linear records when applicable. Use auto.sessions.list to identify\n recent predecessor sessions, then prefer one auto.sessions.search call per\n candidate with `queries: ["Verdict"]`, `roles: ["assistant"]`,\n `kinds: ["message"]`, and `limit: 3`. Alternatively, read final assistant\n messages with auto.sessions.conversation using `roles: ["assistant"]`,\n `kinds: ["message"]`, `limit: 3`, and `toolResults: "omit"`. Compare from\n that bounded evidence; widen only for a named evidence gap.\n - Keep large GitHub and session reads bounded. For search_pull_requests,\n start with a narrow query with a bounded `perPage`. The GitHub proxy streams\n read results verbatim; `search_pull_requests` itself does not own or\n guarantee file persistence. If the harness result carries both\n `persistedOutputPath` and `persistedOutputSize`, consume that one persisted\n result once locally and continue from it; do not reissue the same oversized\n query. That local file is session-local evidence, not durable cross-sweep\n state.\n\n Slack protocol ({{ $slackChannel }}): post only when there is something actionable. One\n short top-level line (sweep time and counts), then exactly one threaded\n reply with the detail as mrkdwn bullets. Use the threadId returned by\n chat.send for the reply; never guess thread ids. Links are\n <https://url|text>.\ninitialPrompt: |\n A scheduled heartbeat spawned this run (scheduled at\n "{{heartbeat.scheduledAt}}") to sweep the project\'s recent sessions\n for failures, anomalies, PR feedback, and improvement opportunities.\n\n Sweep protocol:\n - Find your previous report with auto.sessions.list/conversation. Avoid\n re-reporting old findings; close resolved ones and escalate recurring ones.\n - Triage recent sessions, PR feedback, and relevant read-only data sources.\n - Deep-dive at most three evidence clusters. Prefer one well-evidenced,\n automatable improvement over many shallow observations.\n\n Deliver per your profile instructions and always end with the four-section\n report.\n# The Slack variant reports to the channel: pin the github tool list back to\n# the 1.0.0 read-only surface (the base widens it for its tracking issue).\n# Narrow the inherited git mount to read-only too: this variant never\n# writes to GitHub (no tracking issue), so issues drops to read.\nmounts:\n - mountPath: /workspace/auto\n auth:\n capabilities:\n contents: read\n pullRequests: read\n issues: read\n checks: read\n actions: read\ntools:\n github:\n kind: github\n tools:\n - search_pull_requests\n - pull_request_read\n - actions_list\n - actions_get\n chat:\n kind: local\n implementation: chat\n auth:\n kind: connection\n provider: slack\n connection: "{{ $slackConnection }}"\n optional: false\ntriggers:\n - name: mention\n event: chat.message.mentioned\n connection: "{{ $slackConnection }}"\n optional: false\n where:\n $.chat.provider: slack\n $.auto.authored: false\n message: |\n {{message.author.userName}} mentioned you on Slack:\n\n {{message.text}}\n\n Channel: {{chat.channelId}}\n Thread: {{chat.threadId}}\n\n Reply in that thread with chat.send. If the user clearly asks for a\n sweep, run it. If required context is missing, ask for the time window,\n target agents, PRs, or data source. Otherwise, briefly explain that you\n review PR feedback, read-only data sources, and Auto session history,\n then propose concrete improvements when something is actionable.\n routing:\n kind: spawn\n'
|
|
58431
|
+
},
|
|
58432
|
+
{
|
|
58433
|
+
path: "agents/self-improvement.yaml",
|
|
58434
|
+
content: '# Source: https://www.auto.sh/api/v1/templates/%40auto/self-improvement/1.8.0/agents/self-improvement.yaml\n# Required variables: repoFullName\nname: self-improvement\nmodel:\n provider: anthropic\n id: claude-opus-4-8\nidentity:\n displayName: Self Improvement\n username: self-improvement\n avatar:\n asset: .auto/assets/self-improvement.png\n sha256: 5f8e96bb0919d0fc689e1593b70a2b0c2c28913c210c76b7e2d3d5f22a94b1dd\n description: Reviews PR feedback, read-only data, and Auto sessions to propose concrete improvements, with optional Slack delivery.\nimports:\n - ../fragments/environments/agent-runtime.yaml\nbindings:\n slack.thread:\n continuity: agent\nsystemPrompt: |\n You are the self-improvement agent for {{ $repoFullName }} and its Auto project.\n Review real evidence and propose high-leverage improvements to the\n application or to its Auto agents, prompts, triggers, tools, and processes.\n Treat the repository\'s committed `.auto/` files as first-class evidence:\n inspect the actual agent resources when proposing a change to the factory,\n and point to the exact file and field that should change.\n\n Evidence sources:\n - Auto sessions: status, timing, conversations, tool calls, triggers, and\n transcript search.\n - GitHub PRs: review comments, expressed preferences, repeated friction,\n unresolved blockers, and CI failures.\n - Connected read-only MCP tools: logs, metrics, traces, incidents, support,\n analytics, and docs. Do not mutate external systems from this workflow.\n\n Diagnosis standards:\n - Evidence before verdicts: cite the relevant tool call, event, PR comment,\n log pattern, or prompt text.\n - Prefer high-confidence, high-leverage fixes, especially changes the user\n wants and that can be automated going forward.\n - A preference need not be repeated before you suggest encoding it; repetition\n only raises confidence and priority.\n - Every finding names a concrete app, test, doc, agent, trigger, prompt, or\n process change.\n - Your own session\'s past sessions are in scope - scrutinize them like any\n other run.\n\n Report format (your final message, every run):\n 1. Verdict - one line: top opportunity, closures, or why more data is needed.\n 2. Findings - each with evidence, affected surface, and the proposed fix.\n 3. Closures - previously reported problems now resolved.\n 4. Deferred - promising leads skipped because they need more evidence.\n\n Delivery: the report is this run\'s final message. Compare against\n earlier sweeps by reading your previous sessions with\n auto.sessions.list/conversation - the session history is the report\n history. Sweep findings routinely cite session internals and PR\n friction, so they do not belong on GitHub by default.\n\n Cross-sweep state and query hygiene:\n - Scheduled sweeps run in separate sandboxes. Harness file memory under\n `~/.claude/projects/.../memory` is session-local and ephemeral across\n scheduled sweep sessions.\n - Writing `MEMORY.md` or another memory file is not a durable cross-sweep\n action and is not proof that a future sweep will remember it. Never report\n a memory write as durable recall or use it as evidence of prior delivery.\n - Durable cross-sweep evidence is Auto session history and search, plus\n Slack or Linear records when applicable. Use auto.sessions.list to identify\n recent predecessor sessions, then prefer one auto.sessions.search call per\n candidate with `queries: ["Verdict"]`, `roles: ["assistant"]`,\n `kinds: ["message"]`, and `limit: 3`. Alternatively, read final assistant\n messages with auto.sessions.conversation using `roles: ["assistant"]`,\n `kinds: ["message"]`, `limit: 3`, and `toolResults: "omit"`. Compare from\n that bounded evidence; widen only for a named evidence gap.\n - Keep large GitHub and session reads bounded. For search_pull_requests,\n start with a narrow query with a bounded `perPage`. The GitHub proxy streams\n read results verbatim; `search_pull_requests` itself does not own or\n guarantee file persistence. If the harness result carries both\n `persistedOutputPath` and `persistedOutputSize`, consume that one persisted\n result once locally and continue from it; do not reissue the same oversized\n query. That local file is session-local evidence, not durable cross-sweep\n state.\n\n Fallback (only when the team has explicitly asked for tracking-issue\n delivery, and never on a public repository): keep a single tracking\n issue titled "Self-improvement sweep reports" - find it with\n search_issues, create it with issue_write only if it is missing, and\n add exactly one comment per sweep with add_issue_comment: one short\n first line (sweep time and counts), then the detail as Markdown\n bullets. Never open a new issue per finding, and post only when there\n is something actionable.\n\n Slack delivery is optional and uses the standard `slack` connection and\n `#dev` channel. When the chat tool is available, post only when there is\n something actionable: one short top-level line with the sweep time and\n counts, then exactly one threaded reply with the detail as mrkdwn bullets.\n Use the threadId returned by chat.send for the reply; never guess thread ids.\n When the tool is unavailable, do not treat Slack delivery as a failure; the\n run report remains the complete sweep. If a user asks for Slack delivery\n while it is unavailable, offer to connect the standard `slack` connection\n and explain that a fresh apply and session make the capability available.\n\n Scheduled sweep closure:\n - Finish the final four-section report/reply and, for actionable findings,\n every required Slack or Chief handoff. Only after every owed delivery is\n complete, call `auto.sessions.complete_current` exactly once with a compact\n one-line handoff.\n - This applies to actionable and no-action sweeps. A no-findings sweep with\n Verdict "Nothing actionable." completes after its final four-section report;\n it owes no Slack or Chief handoff.\n - Never call `auto.sessions.archive_current` to close a sweep. Do not call\n `auto.unbind`, `auto.chat.unsubscribe`, or otherwise release a Slack\n thread binding during closure. The configured agent-continuity\n `slack.thread` binding survives completion while lifecycle remains manual.\n `chat_send` stamps that continuity from this spec. It routes a human reply\n back to this completed holder and reopens this session.\ninitialPrompt: |\n A scheduled heartbeat spawned this run (scheduled at\n "{{heartbeat.scheduledAt}}") to sweep the project\'s recent sessions\n for failures, anomalies, PR feedback, and improvement opportunities.\n\n Sweep protocol:\n - Find your previous report with auto.sessions.list/conversation. Avoid\n re-reporting old findings; close resolved ones and escalate recurring ones.\n - Triage recent sessions, PR feedback, and relevant read-only data sources.\n - Deep-dive at most three evidence clusters. Prefer one well-evidenced,\n automatable improvement over many shallow observations.\n\n Deliver per your profile instructions and always end with the four-section\n report.\nmounts:\n # GitHub App git mount provisions the GitHub MCP proxy (the github\n # tools below are broken without a githubApp mount) and stages a\n # read-only checkout the sweep can ground findings in. Capabilities\n # line up with the declared tools: pullRequests/issues read for PR\n # comment and tracking-issue inspection, issues: write for the opt-in\n # tracking-issue fallback (issue_write/add_issue_comment), actions/checks\n # read for CI. No merge/secrets/workflows.\n - kind: git\n repository: "{{ $repoFullName }}"\n mountPath: /workspace/auto\n ref: main\n auth:\n kind: githubApp\n capabilities:\n contents: read\n pullRequests: read\n issues: write\n checks: read\n actions: read\ntools:\n auto:\n kind: local\n implementation: auto\n github:\n kind: github\n tools:\n - search_pull_requests\n - pull_request_read\n - actions_list\n - actions_get\n - search_issues\n - issue_read\n - issue_write\n - add_issue_comment\n chat:\n kind: local\n implementation: chat\n auth:\n kind: connection\n provider: slack\n connection: slack\n optional: true\ntriggers:\n - name: sweep-heartbeat\n kind: heartbeat\n cron: 0 */2 * * *\n timezone: UTC\n routing:\n kind: spawn\n - name: mention\n event: chat.message.mentioned\n connection: slack\n optional: true\n where:\n $.chat.provider: slack\n $.auto.authored: false\n message: |\n {{message.author.userName}} mentioned you on Slack:\n\n {{message.text}}\n\n Channel: {{chat.channelId}}\n Thread: {{chat.threadId}}\n\n Reply in that thread with chat.send. If the user clearly asks for a\n sweep, run it. If required context is missing, ask for the time window,\n target agents, PRs, or data source. Otherwise, briefly explain that you\n review PR feedback, read-only data sources, and Auto session history,\n then propose concrete improvements when something is actionable.\n routing:\n kind: spawn\n'
|
|
58435
|
+
},
|
|
58436
|
+
{
|
|
58437
|
+
path: "fragments/environments/agent-runtime.yaml",
|
|
58438
|
+
content: "# Source: https://www.auto.sh/api/v1/templates/%40auto/self-improvement/1.8.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"
|
|
58439
|
+
}
|
|
58440
|
+
]
|
|
58270
58441
|
}
|
|
58271
58442
|
],
|
|
58272
58443
|
"@auto/slopbusters": [
|
|
@@ -85018,7 +85189,7 @@ var init_package = __esm({
|
|
|
85018
85189
|
"package.json"() {
|
|
85019
85190
|
package_default = {
|
|
85020
85191
|
name: "@autohq/cli",
|
|
85021
|
-
version: "0.1.
|
|
85192
|
+
version: "0.1.569",
|
|
85022
85193
|
license: "SEE LICENSE IN README.md",
|
|
85023
85194
|
publishConfig: {
|
|
85024
85195
|
access: "public"
|
|
@@ -96372,6 +96543,8 @@ var AgentBridgeOutputAckTimeoutError = class extends Error {
|
|
|
96372
96543
|
var AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_NO_PROGRESS_TIMEOUT_MS = 6e4;
|
|
96373
96544
|
var AGENT_BRIDGE_TERMINAL_AUTH_DRAIN_ABSOLUTE_TIMEOUT_MS = 30 * 6e4;
|
|
96374
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;
|
|
96375
96548
|
async function runAgentBridgeSocket(options) {
|
|
96376
96549
|
const socket = io(`${options.bridgeUrl}${RUNTIME_BRIDGE_NAMESPACE}`, {
|
|
96377
96550
|
auth: {
|
|
@@ -96390,9 +96563,16 @@ async function runAgentBridgeSocket(options) {
|
|
|
96390
96563
|
writeOutput: options.writeOutput,
|
|
96391
96564
|
runtimeLogger: options.runtimeLogger
|
|
96392
96565
|
});
|
|
96566
|
+
const terminalAuthRecovery = createTerminalAuthRecoveryController({
|
|
96567
|
+
socket,
|
|
96568
|
+
token: options.token,
|
|
96569
|
+
writeOutput: options.writeOutput,
|
|
96570
|
+
runtimeLogger: options.runtimeLogger
|
|
96571
|
+
});
|
|
96393
96572
|
let hasConnected = false;
|
|
96573
|
+
let shutdown = null;
|
|
96394
96574
|
await new Promise((resolve6, reject) => {
|
|
96395
|
-
|
|
96575
|
+
shutdown = () => {
|
|
96396
96576
|
reconnectLoop.stop();
|
|
96397
96577
|
handler?.shutdown?.();
|
|
96398
96578
|
socket.disconnect();
|
|
@@ -96404,6 +96584,9 @@ async function runAgentBridgeSocket(options) {
|
|
|
96404
96584
|
if (terminalAuthDrain.handleConnectError(error51)) {
|
|
96405
96585
|
return;
|
|
96406
96586
|
}
|
|
96587
|
+
if (terminalAuthRecovery.handleConnectError(error51)) {
|
|
96588
|
+
return;
|
|
96589
|
+
}
|
|
96407
96590
|
if (!hasConnected) {
|
|
96408
96591
|
socket.disconnect();
|
|
96409
96592
|
if (isTerminalAuthError(error51)) {
|
|
@@ -96415,11 +96598,17 @@ async function runAgentBridgeSocket(options) {
|
|
|
96415
96598
|
}
|
|
96416
96599
|
if (isTerminalAuthError(error51)) {
|
|
96417
96600
|
reconnectLoop.stop();
|
|
96418
|
-
void
|
|
96601
|
+
void terminalAuthRecovery.begin().catch(async (recoveryError) => {
|
|
96419
96602
|
options.writeOutput?.(
|
|
96420
|
-
`
|
|
96603
|
+
`agent_bridge_terminal_auth_recovery_failed error=${errorMessage(recoveryError)}`
|
|
96421
96604
|
);
|
|
96422
|
-
|
|
96605
|
+
try {
|
|
96606
|
+
await terminalAuthDrain.begin();
|
|
96607
|
+
} catch (drainError) {
|
|
96608
|
+
options.writeOutput?.(
|
|
96609
|
+
`agent_bridge_terminal_auth_drain_failed error=${errorMessage(drainError)}`
|
|
96610
|
+
);
|
|
96611
|
+
}
|
|
96423
96612
|
socket.disconnect();
|
|
96424
96613
|
reject(new AgentBridgeTerminalAuthError(error51.message));
|
|
96425
96614
|
});
|
|
@@ -96438,6 +96627,9 @@ async function runAgentBridgeSocket(options) {
|
|
|
96438
96627
|
if (terminalAuthDrain.handleDisconnect()) {
|
|
96439
96628
|
return;
|
|
96440
96629
|
}
|
|
96630
|
+
if (terminalAuthRecovery.handleDisconnect()) {
|
|
96631
|
+
return;
|
|
96632
|
+
}
|
|
96441
96633
|
reconnectLoop.start();
|
|
96442
96634
|
});
|
|
96443
96635
|
socket.on(
|
|
@@ -96480,6 +96672,7 @@ async function runAgentBridgeSocket(options) {
|
|
|
96480
96672
|
if (terminalAuthDrain.handleConnected(rawContext)) {
|
|
96481
96673
|
return;
|
|
96482
96674
|
}
|
|
96675
|
+
terminalAuthRecovery.handleConnected();
|
|
96483
96676
|
const context = RuntimeBridgeConnectedPayloadSchema.parse(rawContext);
|
|
96484
96677
|
if (!handler) {
|
|
96485
96678
|
reject(new Error("Bridge connected before bootstrap completed"));
|
|
@@ -96564,6 +96757,13 @@ async function runAgentBridgeSocket(options) {
|
|
|
96564
96757
|
);
|
|
96565
96758
|
});
|
|
96566
96759
|
});
|
|
96760
|
+
}).finally(() => {
|
|
96761
|
+
reconnectLoop.stop();
|
|
96762
|
+
socket.disconnect();
|
|
96763
|
+
if (shutdown) {
|
|
96764
|
+
process.off("SIGINT", shutdown);
|
|
96765
|
+
process.off("SIGTERM", shutdown);
|
|
96766
|
+
}
|
|
96567
96767
|
});
|
|
96568
96768
|
}
|
|
96569
96769
|
function isTerminalAuthError(error51) {
|
|
@@ -96726,6 +96926,128 @@ function createReconnectLoop(socket) {
|
|
|
96726
96926
|
};
|
|
96727
96927
|
return { start, stop };
|
|
96728
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
|
+
}
|
|
96729
97051
|
function createTerminalAuthDrainController(input) {
|
|
96730
97052
|
let terminalAuthExit = false;
|
|
96731
97053
|
let state = null;
|