agent-transport-system 0.7.98 → 0.7.99
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/ats.js +281 -82
- package/dist/ats.js.map +1 -1
- package/package.json +1 -1
package/dist/ats.js
CHANGED
|
@@ -32,7 +32,7 @@ import { ReadStream, WriteStream } from "node:tty";
|
|
|
32
32
|
import { performance } from "node:perf_hooks";
|
|
33
33
|
|
|
34
34
|
//#region package.json
|
|
35
|
-
var version = "0.7.
|
|
35
|
+
var version = "0.7.99";
|
|
36
36
|
var package_default = {
|
|
37
37
|
$schema: "https://www.schemastore.org/package.json",
|
|
38
38
|
name: "agent-transport-system",
|
|
@@ -4386,7 +4386,7 @@ async function getDaemonRuntimeStatus(pathInput = {}) {
|
|
|
4386
4386
|
autoStart: state.autoStart,
|
|
4387
4387
|
reason: "invalid_pid"
|
|
4388
4388
|
};
|
|
4389
|
-
if (!isPidAlive$
|
|
4389
|
+
if (!isPidAlive$6(state.pid)) return {
|
|
4390
4390
|
status: "stale",
|
|
4391
4391
|
mode: state.mode,
|
|
4392
4392
|
pid: state.pid,
|
|
@@ -4624,7 +4624,7 @@ async function ensureDaemonControlPlaneToken(pathInput = {}) {
|
|
|
4624
4624
|
async function readDaemonControlPlaneToken(pathInput = {}) {
|
|
4625
4625
|
return (await readDaemonTokenState(pathInput))?.token ?? null;
|
|
4626
4626
|
}
|
|
4627
|
-
function isPidAlive$
|
|
4627
|
+
function isPidAlive$6(pid) {
|
|
4628
4628
|
try {
|
|
4629
4629
|
process.kill(pid, 0);
|
|
4630
4630
|
return true;
|
|
@@ -7486,7 +7486,7 @@ function resolveDefaultAuthBaseUrl(env) {
|
|
|
7486
7486
|
|
|
7487
7487
|
//#endregion
|
|
7488
7488
|
//#region ../../packages/utils/dist/index.js
|
|
7489
|
-
function sleep
|
|
7489
|
+
function sleep(ms) {
|
|
7490
7490
|
return new Promise((resolve) => {
|
|
7491
7491
|
setTimeout(resolve, ms);
|
|
7492
7492
|
});
|
|
@@ -22805,7 +22805,6 @@ function nowIsoString() {
|
|
|
22805
22805
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
22806
22806
|
}
|
|
22807
22807
|
const toErrorMessage$30 = toErrorMessage$43;
|
|
22808
|
-
const sleep = sleep$1;
|
|
22809
22808
|
function dirnamePath(path) {
|
|
22810
22809
|
const lastSlash = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
|
|
22811
22810
|
if (lastSlash <= 0) return ".";
|
|
@@ -33779,7 +33778,7 @@ async function recoverStaleSkillsInstallLock(lockPath) {
|
|
|
33779
33778
|
});
|
|
33780
33779
|
if (!lockRaw) return true;
|
|
33781
33780
|
const pid = resolveLockPid(parseLockMeta(lockRaw));
|
|
33782
|
-
if (pid && isPidAlive$
|
|
33781
|
+
if (pid && isPidAlive$5(pid)) return false;
|
|
33783
33782
|
const latestLockRaw = await readFile(lockPath, "utf8").catch((error) => {
|
|
33784
33783
|
if (getErrorCode$2(error) === "ENOENT") return "";
|
|
33785
33784
|
throw error;
|
|
@@ -33809,7 +33808,7 @@ function resolveLockPid(meta) {
|
|
|
33809
33808
|
const pid = meta.pid;
|
|
33810
33809
|
return typeof pid === "number" && Number.isInteger(pid) ? pid : null;
|
|
33811
33810
|
}
|
|
33812
|
-
function isPidAlive$
|
|
33811
|
+
function isPidAlive$5(pid) {
|
|
33813
33812
|
try {
|
|
33814
33813
|
process$1.kill(pid, 0);
|
|
33815
33814
|
return true;
|
|
@@ -37584,7 +37583,7 @@ async function waitForCondition(input) {
|
|
|
37584
37583
|
const pollMs = input.pollMs ?? SYSTEM_SERVICE_POLL_MS;
|
|
37585
37584
|
while (Date.now() < deadline) {
|
|
37586
37585
|
if (await input.until()) return;
|
|
37587
|
-
await sleep
|
|
37586
|
+
await sleep(pollMs);
|
|
37588
37587
|
}
|
|
37589
37588
|
throw await input.onTimeout();
|
|
37590
37589
|
}
|
|
@@ -38803,7 +38802,7 @@ function resolveObservedRuntimeCommandEntryPath(input) {
|
|
|
38803
38802
|
function resolveRuntimeLeaseIssue(runtimeLease) {
|
|
38804
38803
|
if (!runtimeLease) return "runtime_lease_missing";
|
|
38805
38804
|
if (!Number.isInteger(runtimeLease.pid) || runtimeLease.pid <= 0) return "invalid_pid";
|
|
38806
|
-
if (!isPidAlive$
|
|
38805
|
+
if (!isPidAlive$4(runtimeLease.pid)) return "process_not_alive";
|
|
38807
38806
|
if (isRuntimeLeaseHeartbeatStale(runtimeLease)) return "heartbeat_stale";
|
|
38808
38807
|
return null;
|
|
38809
38808
|
}
|
|
@@ -38831,7 +38830,7 @@ function resolveModePriority(mode) {
|
|
|
38831
38830
|
default: return 2;
|
|
38832
38831
|
}
|
|
38833
38832
|
}
|
|
38834
|
-
function isPidAlive$
|
|
38833
|
+
function isPidAlive$4(pid) {
|
|
38835
38834
|
try {
|
|
38836
38835
|
process$1.kill(pid, 0);
|
|
38837
38836
|
return true;
|
|
@@ -38942,7 +38941,7 @@ async function waitForDaemonSystemServiceToStop(input) {
|
|
|
38942
38941
|
if (!(await input.manager.status().catch(() => null))?.running && currentRuntime?.status !== "running") return true;
|
|
38943
38942
|
if (currentRuntime?.status === "stale" && !currentRuntime.managedBySystemService) return true;
|
|
38944
38943
|
if (currentRuntime?.status === "not_running") return true;
|
|
38945
|
-
await sleep
|
|
38944
|
+
await sleep(pollMs);
|
|
38946
38945
|
}
|
|
38947
38946
|
const finalRuntime = await readCurrentObservedDaemonRuntimeStatus().catch(() => null);
|
|
38948
38947
|
if (finalRuntime?.status === "not_running") return true;
|
|
@@ -39848,7 +39847,7 @@ async function waitForSystemServiceStartup(input) {
|
|
|
39848
39847
|
state: "running",
|
|
39849
39848
|
runtimeStatus: inventory.runtimeStatus
|
|
39850
39849
|
};
|
|
39851
|
-
await sleep
|
|
39850
|
+
await sleep(input.pollMs);
|
|
39852
39851
|
}
|
|
39853
39852
|
const finalInventory = await inspectDaemonServiceInventory({
|
|
39854
39853
|
expectedVersion: input.expectedVersion,
|
|
@@ -48348,6 +48347,39 @@ function resolveLocalAgentEnabledErrorCode$1(error) {
|
|
|
48348
48347
|
return normalized?.includes(".") ? normalized : "agents.unexpected_error";
|
|
48349
48348
|
}
|
|
48350
48349
|
|
|
48350
|
+
//#endregion
|
|
48351
|
+
//#region src/local-service/carrier/stop-aware-delay.ts
|
|
48352
|
+
function createStopAwareDelay() {
|
|
48353
|
+
let interrupted = false;
|
|
48354
|
+
const pendingInterruptNotifiers = /* @__PURE__ */ new Set();
|
|
48355
|
+
return {
|
|
48356
|
+
interrupt: () => {
|
|
48357
|
+
if (interrupted) return;
|
|
48358
|
+
interrupted = true;
|
|
48359
|
+
for (const notifyInterrupted of pendingInterruptNotifiers) notifyInterrupted();
|
|
48360
|
+
pendingInterruptNotifiers.clear();
|
|
48361
|
+
},
|
|
48362
|
+
wait: (delayMs) => {
|
|
48363
|
+
if (interrupted) return Promise.resolve("interrupted");
|
|
48364
|
+
return new Promise((resolve) => {
|
|
48365
|
+
let timer = null;
|
|
48366
|
+
const notifyInterrupted = () => {
|
|
48367
|
+
if (timer) {
|
|
48368
|
+
clearTimeout(timer);
|
|
48369
|
+
timer = null;
|
|
48370
|
+
}
|
|
48371
|
+
resolve("interrupted");
|
|
48372
|
+
};
|
|
48373
|
+
pendingInterruptNotifiers.add(notifyInterrupted);
|
|
48374
|
+
timer = setTimeout(() => {
|
|
48375
|
+
pendingInterruptNotifiers.delete(notifyInterrupted);
|
|
48376
|
+
resolve("elapsed");
|
|
48377
|
+
}, delayMs);
|
|
48378
|
+
});
|
|
48379
|
+
}
|
|
48380
|
+
};
|
|
48381
|
+
}
|
|
48382
|
+
|
|
48351
48383
|
//#endregion
|
|
48352
48384
|
//#region src/local-service/carrier/service-runner.ts
|
|
48353
48385
|
var DaemonStreamAuthenticationRequiredError = class extends Error {
|
|
@@ -48536,6 +48568,7 @@ const runDaemonServiceLoop = async (input) => {
|
|
|
48536
48568
|
})
|
|
48537
48569
|
});
|
|
48538
48570
|
let stopRequested = false;
|
|
48571
|
+
const reconnectBackoffDelay = createStopAwareDelay();
|
|
48539
48572
|
let reconnectAttempt = 0;
|
|
48540
48573
|
let activeSocket = null;
|
|
48541
48574
|
const currentSocketRef = {
|
|
@@ -48599,6 +48632,7 @@ const runDaemonServiceLoop = async (input) => {
|
|
|
48599
48632
|
if (stopRequested) return;
|
|
48600
48633
|
stopRequested = true;
|
|
48601
48634
|
connectionState.set("stopping");
|
|
48635
|
+
reconnectBackoffDelay.interrupt();
|
|
48602
48636
|
activeSocket?.close(1e3, "shutdown");
|
|
48603
48637
|
};
|
|
48604
48638
|
const onSigint = () => {
|
|
@@ -48651,6 +48685,10 @@ const runDaemonServiceLoop = async (input) => {
|
|
|
48651
48685
|
headers: authContext.headers,
|
|
48652
48686
|
openTimeoutMs: DAEMON_STREAM_CONNECT_TIMEOUT_MS
|
|
48653
48687
|
});
|
|
48688
|
+
if (stopRequested) {
|
|
48689
|
+
ws.close(1e3, "shutdown");
|
|
48690
|
+
break;
|
|
48691
|
+
}
|
|
48654
48692
|
activeSocket = ws;
|
|
48655
48693
|
emitRunLine({
|
|
48656
48694
|
presenter: input.presenter,
|
|
@@ -48709,59 +48747,14 @@ const runDaemonServiceLoop = async (input) => {
|
|
|
48709
48747
|
requestActiveRouteCatalogSync = null;
|
|
48710
48748
|
if (stopRequested) break;
|
|
48711
48749
|
reconnectAttempt += 1;
|
|
48712
|
-
const
|
|
48713
|
-
const failureReason = classifyConnectionFailureReason(errorMessage);
|
|
48714
|
-
const authState = error instanceof DaemonStreamAuthenticationRequiredError ? error.authState : null;
|
|
48715
|
-
const backoffMs = resolveServiceConnectionReconnectBackoffMs({
|
|
48716
|
-
attempt: reconnectAttempt,
|
|
48717
|
-
reason: failureReason
|
|
48718
|
-
});
|
|
48719
|
-
noteReconnectFailureState({
|
|
48720
|
-
authState,
|
|
48750
|
+
const backoffMs = noteRunLoopReconnectScheduled({
|
|
48721
48751
|
connectionState,
|
|
48722
|
-
|
|
48723
|
-
|
|
48724
|
-
reconnectAttempt
|
|
48725
|
-
});
|
|
48726
|
-
const reconcileDecision = resolveRouteRegistrationReconcileDecision({
|
|
48727
|
-
driftDetected: true,
|
|
48728
|
-
foregroundActive: mode === "foreground"
|
|
48729
|
-
});
|
|
48730
|
-
emitDriftDetectedEvidence({
|
|
48731
|
-
action: reconcileDecision.action,
|
|
48732
|
-
backoffMs,
|
|
48733
|
-
driftClass: reconcileDecision.driftClass,
|
|
48734
|
-
error: errorMessage,
|
|
48735
|
-
foregroundActive: reconcileDecision.foregroundActive,
|
|
48736
|
-
lifecycleLocked: reconcileDecision.lifecycleLocked,
|
|
48737
|
-
owner: reconcileDecision.owner,
|
|
48738
|
-
reconnectAttempt,
|
|
48739
|
-
skipReason: reconcileDecision.skipReason
|
|
48740
|
-
});
|
|
48741
|
-
emitReconcileStartedEvidence({
|
|
48742
|
-
action: reconcileDecision.action,
|
|
48743
|
-
backoffMs,
|
|
48744
|
-
driftClass: reconcileDecision.driftClass,
|
|
48745
|
-
error: errorMessage,
|
|
48746
|
-
foregroundActive: reconcileDecision.foregroundActive,
|
|
48747
|
-
lifecycleLocked: reconcileDecision.lifecycleLocked,
|
|
48748
|
-
owner: reconcileDecision.owner,
|
|
48749
|
-
reconnectAttempt,
|
|
48750
|
-
skipReason: reconcileDecision.skipReason
|
|
48751
|
-
});
|
|
48752
|
-
emitRunLine({
|
|
48752
|
+
error,
|
|
48753
|
+
foregroundActive: mode === "foreground",
|
|
48753
48754
|
presenter: input.presenter,
|
|
48754
|
-
|
|
48755
|
-
text: `daemon stream reconnect scheduled in ${String(backoffMs)}ms (${errorMessage})`,
|
|
48756
|
-
payload: {
|
|
48757
|
-
attempt: reconnectAttempt,
|
|
48758
|
-
authState,
|
|
48759
|
-
backoffMs,
|
|
48760
|
-
error: errorMessage,
|
|
48761
|
-
reason: failureReason
|
|
48762
|
-
}
|
|
48755
|
+
reconnectAttempt
|
|
48763
48756
|
});
|
|
48764
|
-
await
|
|
48757
|
+
await reconnectBackoffDelay.wait(backoffMs);
|
|
48765
48758
|
}
|
|
48766
48759
|
} finally {
|
|
48767
48760
|
process.off("SIGINT", onSigint);
|
|
@@ -49072,6 +49065,61 @@ function createRunLoopConnectionStateTracker(presenter) {
|
|
|
49072
49065
|
}).catch(() => void 0);
|
|
49073
49066
|
} });
|
|
49074
49067
|
}
|
|
49068
|
+
function noteRunLoopReconnectScheduled(input) {
|
|
49069
|
+
const errorMessage = toErrorMessage$30(input.error);
|
|
49070
|
+
const failureReason = classifyConnectionFailureReason(errorMessage);
|
|
49071
|
+
const authState = input.error instanceof DaemonStreamAuthenticationRequiredError ? input.error.authState : null;
|
|
49072
|
+
const backoffMs = resolveServiceConnectionReconnectBackoffMs({
|
|
49073
|
+
attempt: input.reconnectAttempt,
|
|
49074
|
+
reason: failureReason
|
|
49075
|
+
});
|
|
49076
|
+
noteReconnectFailureState({
|
|
49077
|
+
authState,
|
|
49078
|
+
connectionState: input.connectionState,
|
|
49079
|
+
errorMessage,
|
|
49080
|
+
failureReason,
|
|
49081
|
+
reconnectAttempt: input.reconnectAttempt
|
|
49082
|
+
});
|
|
49083
|
+
const reconcileDecision = resolveRouteRegistrationReconcileDecision({
|
|
49084
|
+
driftDetected: true,
|
|
49085
|
+
foregroundActive: input.foregroundActive
|
|
49086
|
+
});
|
|
49087
|
+
emitDriftDetectedEvidence({
|
|
49088
|
+
action: reconcileDecision.action,
|
|
49089
|
+
backoffMs,
|
|
49090
|
+
driftClass: reconcileDecision.driftClass,
|
|
49091
|
+
error: errorMessage,
|
|
49092
|
+
foregroundActive: reconcileDecision.foregroundActive,
|
|
49093
|
+
lifecycleLocked: reconcileDecision.lifecycleLocked,
|
|
49094
|
+
owner: reconcileDecision.owner,
|
|
49095
|
+
reconnectAttempt: input.reconnectAttempt,
|
|
49096
|
+
skipReason: reconcileDecision.skipReason
|
|
49097
|
+
});
|
|
49098
|
+
emitReconcileStartedEvidence({
|
|
49099
|
+
action: reconcileDecision.action,
|
|
49100
|
+
backoffMs,
|
|
49101
|
+
driftClass: reconcileDecision.driftClass,
|
|
49102
|
+
error: errorMessage,
|
|
49103
|
+
foregroundActive: reconcileDecision.foregroundActive,
|
|
49104
|
+
lifecycleLocked: reconcileDecision.lifecycleLocked,
|
|
49105
|
+
owner: reconcileDecision.owner,
|
|
49106
|
+
reconnectAttempt: input.reconnectAttempt,
|
|
49107
|
+
skipReason: reconcileDecision.skipReason
|
|
49108
|
+
});
|
|
49109
|
+
emitRunLine({
|
|
49110
|
+
presenter: input.presenter,
|
|
49111
|
+
code: "daemon.run.reconnect",
|
|
49112
|
+
text: `daemon stream reconnect scheduled in ${String(backoffMs)}ms (${errorMessage})`,
|
|
49113
|
+
payload: {
|
|
49114
|
+
attempt: input.reconnectAttempt,
|
|
49115
|
+
authState,
|
|
49116
|
+
backoffMs,
|
|
49117
|
+
error: errorMessage,
|
|
49118
|
+
reason: failureReason
|
|
49119
|
+
}
|
|
49120
|
+
});
|
|
49121
|
+
return backoffMs;
|
|
49122
|
+
}
|
|
49075
49123
|
function noteReconnectFailureState(input) {
|
|
49076
49124
|
if (input.failureReason === "auth_rejected") {
|
|
49077
49125
|
input.connectionState.set("authentication_required", {
|
|
@@ -52570,6 +52618,150 @@ async function cleanupStaleDaemonRuntimeDataBackups(input = {}) {
|
|
|
52570
52618
|
}
|
|
52571
52619
|
}
|
|
52572
52620
|
|
|
52621
|
+
//#endregion
|
|
52622
|
+
//#region src/local-service/lifecycle/daemon-service-stalled-force-kill.ts
|
|
52623
|
+
const FORCE_KILL_MIN_HEARTBEAT_STALL_MS = 600 * 1e3;
|
|
52624
|
+
const FORCE_KILL_EXIT_WAIT_MS = 2e3;
|
|
52625
|
+
const FORCE_KILL_EXIT_POLL_MS = 100;
|
|
52626
|
+
function resolveStalledDaemonForceKillVerdict(input) {
|
|
52627
|
+
const lease = input.runtimeLease;
|
|
52628
|
+
if (!lease) return {
|
|
52629
|
+
decision: "skip",
|
|
52630
|
+
reason: "runtime_lease_missing",
|
|
52631
|
+
pid: null,
|
|
52632
|
+
heartbeatStalledMs: null
|
|
52633
|
+
};
|
|
52634
|
+
if (!Number.isInteger(lease.pid) || lease.pid <= 0) return {
|
|
52635
|
+
decision: "skip",
|
|
52636
|
+
reason: "lease_pid_invalid",
|
|
52637
|
+
pid: null,
|
|
52638
|
+
heartbeatStalledMs: null
|
|
52639
|
+
};
|
|
52640
|
+
const ownedProcess = input.ownedProcesses.find((candidate) => candidate.pid === lease.pid && candidate.ownership !== "unknown");
|
|
52641
|
+
if (!ownedProcess) return {
|
|
52642
|
+
decision: "skip",
|
|
52643
|
+
reason: "lease_pid_not_owned",
|
|
52644
|
+
pid: lease.pid,
|
|
52645
|
+
heartbeatStalledMs: null
|
|
52646
|
+
};
|
|
52647
|
+
if (ownedProcess.mode === "foreground") return {
|
|
52648
|
+
decision: "skip",
|
|
52649
|
+
reason: "foreground_process",
|
|
52650
|
+
pid: lease.pid,
|
|
52651
|
+
heartbeatStalledMs: null
|
|
52652
|
+
};
|
|
52653
|
+
const freshnessTimestamp = lease.heartbeatAt ?? lease.updatedAt;
|
|
52654
|
+
const heartbeatMs = Date.parse(freshnessTimestamp);
|
|
52655
|
+
if (Number.isNaN(heartbeatMs)) return {
|
|
52656
|
+
decision: "skip",
|
|
52657
|
+
reason: "heartbeat_unparseable",
|
|
52658
|
+
pid: lease.pid,
|
|
52659
|
+
heartbeatStalledMs: null
|
|
52660
|
+
};
|
|
52661
|
+
const heartbeatStalledMs = input.nowMs - heartbeatMs;
|
|
52662
|
+
if (heartbeatStalledMs < FORCE_KILL_MIN_HEARTBEAT_STALL_MS) return {
|
|
52663
|
+
decision: "skip",
|
|
52664
|
+
reason: "heartbeat_fresh",
|
|
52665
|
+
pid: lease.pid,
|
|
52666
|
+
heartbeatStalledMs
|
|
52667
|
+
};
|
|
52668
|
+
return {
|
|
52669
|
+
decision: "force_kill",
|
|
52670
|
+
pid: lease.pid,
|
|
52671
|
+
heartbeatStalledMs
|
|
52672
|
+
};
|
|
52673
|
+
}
|
|
52674
|
+
const defaultStalledDaemonForceKillDeps = {
|
|
52675
|
+
emitLifecycleEvent: emitDaemonLifecycleEvent,
|
|
52676
|
+
killProcess: (pid, signal) => process$1.kill(pid, signal),
|
|
52677
|
+
listOwnedProcesses: async () => await listDaemonOwnedProcesses({ ignoreProcessIds: [process$1.pid, process$1.ppid].filter((pid) => Number.isInteger(pid) && pid > 0) }),
|
|
52678
|
+
nowMs: () => Date.now(),
|
|
52679
|
+
readRuntimeLease: async () => await readDaemonRuntimeLease(),
|
|
52680
|
+
waitForProcessExit: async (pid) => {
|
|
52681
|
+
const deadline = Date.now() + FORCE_KILL_EXIT_WAIT_MS;
|
|
52682
|
+
while (Date.now() < deadline) {
|
|
52683
|
+
if (!isPidAlive$3(pid)) return true;
|
|
52684
|
+
await sleep(FORCE_KILL_EXIT_POLL_MS);
|
|
52685
|
+
}
|
|
52686
|
+
return !isPidAlive$3(pid);
|
|
52687
|
+
}
|
|
52688
|
+
};
|
|
52689
|
+
async function forceKillStalledDaemonAfterStopTimeout(input, deps = defaultStalledDaemonForceKillDeps) {
|
|
52690
|
+
const [runtimeLease, ownedProcesses] = await Promise.all([deps.readRuntimeLease().catch(() => null), deps.listOwnedProcesses().catch(() => [])]);
|
|
52691
|
+
const verdict = resolveStalledDaemonForceKillVerdict({
|
|
52692
|
+
nowMs: deps.nowMs(),
|
|
52693
|
+
ownedProcesses,
|
|
52694
|
+
runtimeLease
|
|
52695
|
+
});
|
|
52696
|
+
if (verdict.decision === "skip") {
|
|
52697
|
+
await deps.emitLifecycleEvent({
|
|
52698
|
+
type: "process_stop.action",
|
|
52699
|
+
result: "force_kill_skipped",
|
|
52700
|
+
metadata: {
|
|
52701
|
+
heartbeatStalledMs: verdict.heartbeatStalledMs,
|
|
52702
|
+
pid: verdict.pid,
|
|
52703
|
+
reason: verdict.reason,
|
|
52704
|
+
signal: "SIGKILL",
|
|
52705
|
+
stage: input.stage
|
|
52706
|
+
}
|
|
52707
|
+
});
|
|
52708
|
+
return {
|
|
52709
|
+
killed: false,
|
|
52710
|
+
verdict
|
|
52711
|
+
};
|
|
52712
|
+
}
|
|
52713
|
+
try {
|
|
52714
|
+
deps.killProcess(verdict.pid, "SIGKILL");
|
|
52715
|
+
} catch (error) {
|
|
52716
|
+
if (!isProcessGoneError(error)) {
|
|
52717
|
+
await deps.emitLifecycleEvent({
|
|
52718
|
+
type: "process_stop.action",
|
|
52719
|
+
result: "force_kill_failed",
|
|
52720
|
+
metadata: {
|
|
52721
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
52722
|
+
heartbeatStalledMs: verdict.heartbeatStalledMs,
|
|
52723
|
+
pid: verdict.pid,
|
|
52724
|
+
reason: "stalled_heartbeat_after_stop_timeout",
|
|
52725
|
+
signal: "SIGKILL",
|
|
52726
|
+
stage: input.stage
|
|
52727
|
+
}
|
|
52728
|
+
});
|
|
52729
|
+
return {
|
|
52730
|
+
killed: false,
|
|
52731
|
+
verdict
|
|
52732
|
+
};
|
|
52733
|
+
}
|
|
52734
|
+
}
|
|
52735
|
+
const exited = await deps.waitForProcessExit(verdict.pid);
|
|
52736
|
+
await deps.emitLifecycleEvent({
|
|
52737
|
+
type: "process_stop.action",
|
|
52738
|
+
result: "force_killed",
|
|
52739
|
+
metadata: {
|
|
52740
|
+
exitObserved: exited,
|
|
52741
|
+
heartbeatStalledMs: verdict.heartbeatStalledMs,
|
|
52742
|
+
pid: verdict.pid,
|
|
52743
|
+
reason: "stalled_heartbeat_after_stop_timeout",
|
|
52744
|
+
signal: "SIGKILL",
|
|
52745
|
+
stage: input.stage
|
|
52746
|
+
}
|
|
52747
|
+
});
|
|
52748
|
+
return {
|
|
52749
|
+
killed: true,
|
|
52750
|
+
verdict
|
|
52751
|
+
};
|
|
52752
|
+
}
|
|
52753
|
+
function isProcessGoneError(error) {
|
|
52754
|
+
return error instanceof Error && error.code === "ESRCH";
|
|
52755
|
+
}
|
|
52756
|
+
function isPidAlive$3(pid) {
|
|
52757
|
+
try {
|
|
52758
|
+
process$1.kill(pid, 0);
|
|
52759
|
+
return true;
|
|
52760
|
+
} catch (error) {
|
|
52761
|
+
return !(error instanceof Error && error.code === "ESRCH");
|
|
52762
|
+
}
|
|
52763
|
+
}
|
|
52764
|
+
|
|
52573
52765
|
//#endregion
|
|
52574
52766
|
//#region src/local-service/lifecycle/daemon-service-lifecycle.ts
|
|
52575
52767
|
const STRICT_TEARDOWN_VERIFY_WAIT_MS$1 = 15e3;
|
|
@@ -53126,8 +53318,11 @@ async function stopLifecycleRuntime(input) {
|
|
|
53126
53318
|
stage: "stop_or_drain"
|
|
53127
53319
|
});
|
|
53128
53320
|
if (await stopDaemonProcessWithTimeout(runtimeStatus.pid, "SIGTERM", input.drainWaitMs)) return;
|
|
53129
|
-
if (
|
|
53130
|
-
|
|
53321
|
+
if (input.forceKillAfterDrainTimeout) {
|
|
53322
|
+
await stopDaemonProcess$1(runtimeStatus.pid, "SIGKILL");
|
|
53323
|
+
return;
|
|
53324
|
+
}
|
|
53325
|
+
if (!(await forceKillStalledDaemonAfterStopTimeout({ stage: "stop_or_drain" })).killed) throw new DaemonServiceLifecycleDrainTimeoutError(input.drainWaitMs);
|
|
53131
53326
|
}
|
|
53132
53327
|
async function ensureLifecycleRuntimeStopped() {
|
|
53133
53328
|
const runtimeAfterStop = await readCurrentObservedDaemonRuntimeStatus();
|
|
@@ -53142,11 +53337,15 @@ async function ensureLifecycleRuntimeStopped() {
|
|
|
53142
53337
|
}
|
|
53143
53338
|
async function waitForLifecycleRuntimeStopped(input) {
|
|
53144
53339
|
if (input.inventory.runtimeStatus.managedBySystemService || input.inventory.serviceManagerStatus?.installed === true || input.inventory.serviceManagerStatus?.running === true) {
|
|
53145
|
-
if (!await waitForDaemonSystemServiceToStop({
|
|
53340
|
+
if (!(await waitForDaemonSystemServiceToStop({
|
|
53146
53341
|
manager: input.serviceManager,
|
|
53147
53342
|
waitMs: STRICT_TEARDOWN_VERIFY_WAIT_MS$1,
|
|
53148
53343
|
pollMs: STRICT_TEARDOWN_VERIFY_POLL_MS$1
|
|
53149
|
-
})) {
|
|
53344
|
+
}) || (await forceKillStalledDaemonAfterStopTimeout({ stage: "wait_stopped" })).killed && await waitForDaemonSystemServiceToStop({
|
|
53345
|
+
manager: input.serviceManager,
|
|
53346
|
+
waitMs: STRICT_TEARDOWN_VERIFY_WAIT_MS$1,
|
|
53347
|
+
pollMs: STRICT_TEARDOWN_VERIFY_POLL_MS$1
|
|
53348
|
+
}))) {
|
|
53150
53349
|
const runtimeAfterWait = await readCurrentObservedDaemonRuntimeStatus();
|
|
53151
53350
|
throw new DaemonServiceLifecycleStageError({
|
|
53152
53351
|
message: `ATS service is still running after stop phase (pid=${String(runtimeAfterWait.pid)}).`,
|
|
@@ -53167,7 +53366,7 @@ async function ensureNoOwnedProcessesRemain() {
|
|
|
53167
53366
|
return;
|
|
53168
53367
|
}
|
|
53169
53368
|
}
|
|
53170
|
-
await sleep
|
|
53369
|
+
await sleep(STRICT_TEARDOWN_VERIFY_POLL_MS$1);
|
|
53171
53370
|
}
|
|
53172
53371
|
const [ownedProcesses, runtimeStatus] = await Promise.all([listDaemonOwnedProcesses({ ignoreProcessIds: [process$1.pid, process$1.ppid].filter((pid) => Number.isInteger(pid) && pid > 0) }), readCurrentObservedDaemonRuntimeStatus()]);
|
|
53173
53372
|
if (ownedProcesses.length > 0) throw new DaemonServiceLifecycleStageError({
|
|
@@ -53190,7 +53389,7 @@ async function waitForLegacySharedServiceCleanup(input) {
|
|
|
53190
53389
|
});
|
|
53191
53390
|
lastInventory = inventory;
|
|
53192
53391
|
if (!(inventory.legacySharedService?.present === true || inventory.anomalies.some((anomaly) => anomaly.code === "legacy_shared_service_present"))) return;
|
|
53193
|
-
await sleep
|
|
53392
|
+
await sleep(STRICT_TEARDOWN_VERIFY_POLL_MS$1);
|
|
53194
53393
|
}
|
|
53195
53394
|
throw new DaemonServiceLifecycleStageError({
|
|
53196
53395
|
message: "ATS Service legacy shared registration is still present after cleanup. reason=legacy_shared_service_present",
|
|
@@ -53414,7 +53613,7 @@ async function waitForVerifiedLifecycleInventory(input) {
|
|
|
53414
53613
|
});
|
|
53415
53614
|
lastInventory = inventory;
|
|
53416
53615
|
lastError = verificationError;
|
|
53417
|
-
await sleep
|
|
53616
|
+
await sleep(STRICT_TEARDOWN_VERIFY_POLL_MS$1);
|
|
53418
53617
|
}
|
|
53419
53618
|
throw new DaemonServiceLifecycleStageError({
|
|
53420
53619
|
message: lastError ?? "ATS could not verify the final local service inventory state.",
|
|
@@ -53553,7 +53752,7 @@ async function waitForProcessToExit$1(pid, timeoutMs) {
|
|
|
53553
53752
|
const deadline = Date.now() + timeoutMs;
|
|
53554
53753
|
while (Date.now() < deadline) {
|
|
53555
53754
|
if (!isPidAlive$2(pid)) return true;
|
|
53556
|
-
await sleep
|
|
53755
|
+
await sleep(STRICT_TEARDOWN_VERIFY_POLL_MS$1);
|
|
53557
53756
|
}
|
|
53558
53757
|
return !isPidAlive$2(pid);
|
|
53559
53758
|
}
|
|
@@ -54204,7 +54403,7 @@ async function terminateDaemonOwnedProcess(pid) {
|
|
|
54204
54403
|
const deadline = Date.now() + AUTO_HEAL_DUPLICATE_WAIT_MS;
|
|
54205
54404
|
while (Date.now() < deadline) {
|
|
54206
54405
|
if (!isPidAlive$1(pid)) return;
|
|
54207
|
-
await sleep
|
|
54406
|
+
await sleep(AUTO_HEAL_DUPLICATE_POLL_MS);
|
|
54208
54407
|
}
|
|
54209
54408
|
if (isPidAlive$1(pid)) process$1.kill(pid, "SIGKILL");
|
|
54210
54409
|
}
|
|
@@ -54417,7 +54616,7 @@ async function waitForDaemonStartupAlignmentSettlement(input) {
|
|
|
54417
54616
|
cliScriptPath: input.cliScriptPath
|
|
54418
54617
|
}).catch(() => null);
|
|
54419
54618
|
if (!inventory) {
|
|
54420
|
-
await sleep
|
|
54619
|
+
await sleep(input.pollMs);
|
|
54421
54620
|
continue;
|
|
54422
54621
|
}
|
|
54423
54622
|
const decision = resolveDaemonServiceAlignmentDecision({
|
|
@@ -54438,7 +54637,7 @@ async function waitForDaemonStartupAlignmentSettlement(input) {
|
|
|
54438
54637
|
cooldownUntil: null,
|
|
54439
54638
|
backupDataPath: null
|
|
54440
54639
|
};
|
|
54441
|
-
await sleep
|
|
54640
|
+
await sleep(input.pollMs);
|
|
54442
54641
|
}
|
|
54443
54642
|
return null;
|
|
54444
54643
|
}
|
|
@@ -56640,7 +56839,7 @@ async function verifySystemServiceRemovedAfterStrictTeardown(input) {
|
|
|
56640
56839
|
}
|
|
56641
56840
|
}
|
|
56642
56841
|
if (allRemoved) return;
|
|
56643
|
-
await sleep
|
|
56842
|
+
await sleep(STRICT_TEARDOWN_VERIFY_POLL_MS);
|
|
56644
56843
|
}
|
|
56645
56844
|
for (const manager of managers) {
|
|
56646
56845
|
const finalManagerStatus = await manager.status().catch((error) => {
|
|
@@ -56677,7 +56876,7 @@ async function ensureRuntimeCleanAfterStrictTeardown(input) {
|
|
|
56677
56876
|
if ((await input.deps.readCurrentObservedDaemonRuntimeStatus()).status === "not_running") return;
|
|
56678
56877
|
}
|
|
56679
56878
|
}
|
|
56680
|
-
await sleep
|
|
56879
|
+
await sleep(STRICT_TEARDOWN_VERIFY_POLL_MS);
|
|
56681
56880
|
}
|
|
56682
56881
|
const [ownedProcesses, finalRuntime] = await Promise.all([input.deps.listDaemonOwnedProcesses({ ignoreProcessIds: [process.pid] }), input.deps.readCurrentObservedDaemonRuntimeStatus()]);
|
|
56683
56882
|
if (finalRuntime.status === "running") throw createStrictTeardownError({
|
|
@@ -57284,7 +57483,7 @@ async function runDaemonAfterReinstallStartWithRetry(input) {
|
|
|
57284
57483
|
if (result.ok || isDaemonRunAlreadyRunningReason(result.reason) || normalizeDaemonRunReason(result.reason) === "cancelled") process.exitCode = previousExitCode;
|
|
57285
57484
|
if (normalizeDaemonRunReason(result.reason) === "start_failed" && attempt < REINSTALL_START_RETRY_ATTEMPTS) {
|
|
57286
57485
|
process.exitCode = previousExitCode;
|
|
57287
|
-
await sleep
|
|
57486
|
+
await sleep(input.startRetryDelayMs);
|
|
57288
57487
|
continue;
|
|
57289
57488
|
}
|
|
57290
57489
|
return {
|
|
@@ -57294,7 +57493,7 @@ async function runDaemonAfterReinstallStartWithRetry(input) {
|
|
|
57294
57493
|
} catch (error) {
|
|
57295
57494
|
if (attempt < REINSTALL_START_RETRY_ATTEMPTS) {
|
|
57296
57495
|
process.exitCode = previousExitCode;
|
|
57297
|
-
await sleep
|
|
57496
|
+
await sleep(input.startRetryDelayMs);
|
|
57298
57497
|
continue;
|
|
57299
57498
|
}
|
|
57300
57499
|
const startupDiagnostic = await readDaemonStartFailureLogDiagnostic({ cursor: startFailureLogCursor });
|
|
@@ -57390,7 +57589,7 @@ async function waitForDaemonHealthyAfterReinstall(input) {
|
|
|
57390
57589
|
}).catch(() => null);
|
|
57391
57590
|
if (inventory && isDaemonInventoryRunningAndAligned(inventory)) return inventory.runtimeStatus;
|
|
57392
57591
|
lastRuntime = inventory?.runtimeStatus ?? await readCurrentObservedDaemonRuntimeStatus();
|
|
57393
|
-
await sleep
|
|
57592
|
+
await sleep(REINSTALL_VERIFY_POLL_MS);
|
|
57394
57593
|
}
|
|
57395
57594
|
const statusText = lastRuntime ? describeDaemonRuntimeStatus(lastRuntime) : "No runtime status available.";
|
|
57396
57595
|
throw new Error(`ATS Service repair verification timed out after ${String(input.verifyWaitMs)}ms. ${statusText}`);
|
|
@@ -59465,7 +59664,7 @@ async function waitForDetachedBackgroundProcessStartup(child, startupDelayMs, st
|
|
|
59465
59664
|
reason: startupLifecycle,
|
|
59466
59665
|
startupOutput: startupOutput.summary()
|
|
59467
59666
|
}));
|
|
59468
|
-
await sleep
|
|
59667
|
+
await sleep(startupPollMs);
|
|
59469
59668
|
}
|
|
59470
59669
|
const finalStatus = await readCurrentObservedDaemonRuntimeStatus().catch(() => null);
|
|
59471
59670
|
if (finalStatus?.status === "running" && finalStatus.pid === child.pid) return;
|
|
@@ -64860,7 +65059,7 @@ async function waitForExecutionReadinessAfterBinding(input) {
|
|
|
64860
65059
|
requestContext: input.requestContext
|
|
64861
65060
|
});
|
|
64862
65061
|
if (isAgentExecutionReadyOrConnecting(latest.agentExecutionReadiness)) return latest;
|
|
64863
|
-
await sleep
|
|
65062
|
+
await sleep(EXECUTION_READINESS_AFTER_BINDING_RETRY_DELAY_MS);
|
|
64864
65063
|
}
|
|
64865
65064
|
return latest;
|
|
64866
65065
|
}
|
|
@@ -99705,7 +99904,7 @@ async function runPrepareSessionExecutor(input) {
|
|
|
99705
99904
|
if (error instanceof PrepareSessionConnectionInterruptedError && reconnectAttempts < PREPARE_SESSION_MAX_RECONNECT_ATTEMPTS) {
|
|
99706
99905
|
reconnectAttempts += 1;
|
|
99707
99906
|
emitHumanStatus(input, "Reconnecting", ["ATS Web connection was interrupted.", "Reconnecting to the setup session..."]);
|
|
99708
|
-
await sleep
|
|
99907
|
+
await sleep(PREPARE_SESSION_RECONNECT_DELAY_MS);
|
|
99709
99908
|
initial = await resolvePrepareSessionToken({
|
|
99710
99909
|
gatewayUrl: input.gatewayUrl,
|
|
99711
99910
|
opaqueToken: input.startSession
|
|
@@ -100483,7 +100682,7 @@ async function connectSelectedLocalAgentsToAts(input) {
|
|
|
100483
100682
|
} catch (error) {
|
|
100484
100683
|
if (!isTransientSelectedAgentConnectionError(error) || attempt >= REPORT_RUNTIME_CONNECTION_MAX_ATTEMPTS) throw error;
|
|
100485
100684
|
lastTransientError = error;
|
|
100486
|
-
await sleep
|
|
100685
|
+
await sleep(REPORT_RUNTIME_CONNECTION_RETRY_DELAY_MS);
|
|
100487
100686
|
}
|
|
100488
100687
|
throw lastTransientError ?? /* @__PURE__ */ new Error("ATS could not connect local agents.");
|
|
100489
100688
|
}
|