@sentropic/h2a-runtime 0.90.0 → 0.90.2

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/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { projectStatusForH2a } from "./status-projection.js";
3
+ import type { ProcView } from "./proc-cpu.js";
3
4
  import { type RegistryEntry } from "./registry.js";
4
- import { reclaimProposals, type SessionLease } from "./session-lease.js";
5
+ import { reclaimProposals, type SessionLease, type SessionLeaseFleetAudit, type SessionLeaseWorker } from "./session-lease.js";
5
6
  import { projectRemoteAgents } from "./agents-projection.js";
6
7
  export declare const packageName = "@sentropic/h2a-runtime";
7
8
  export declare const H2A_RUNTIME_CLI_API_VERSION = 1;
@@ -93,6 +94,7 @@ export declare function acquireSessionLease(sessionId: string, opts: {
93
94
  holder: string;
94
95
  workspace?: string;
95
96
  agentPane?: string;
97
+ worker?: SessionLeaseWorker;
96
98
  }): SessionLease | undefined;
97
99
  /** What one supervising pass over the session leases did. */
98
100
  export type SessionLeaseSupervision = {
@@ -113,6 +115,19 @@ export type SessionLeaseSupervision = {
113
115
  * Its only output beyond the store is a list of PROPOSALS.
114
116
  */
115
117
  export declare function superviseSessionLeases(sessions: ReadonlyArray<RegistryEntry>, now?: string): SessionLeaseSupervision;
118
+ /** Relaunch one managed session while its lease carries the bounded protection. */
119
+ export declare function relaunchSessionWithLease(input: {
120
+ sessionId: string;
121
+ tmuxSession: string;
122
+ command: string;
123
+ resolvingBoundMs?: number;
124
+ }): boolean;
125
+ /** One on-demand fleet-wide read-back audit; it never runs from rendering. */
126
+ export declare function auditLiveSessionLeases(sessions?: ReadonlyArray<RegistryEntry>, now?: string): SessionLeaseFleetAudit & {
127
+ reaped: string[];
128
+ liveLeaseCount: number;
129
+ procView: ProcView;
130
+ };
116
131
  /**
117
132
  * Reliability slice 1 — RESUME a throttled HEADLESS LOCAL job. Relaunch the SAME
118
133
  * job in the SAME `runCwd` it already ran in (its recorded `cwd` — NOT a fresh
@@ -142,6 +157,13 @@ export { main as dispatch };
142
157
  */
143
158
  export declare function projectAgentsForH2a(): ReturnType<typeof projectRemoteAgents>;
144
159
  export { projectStatusForH2a };
160
+ /**
161
+ * Status-bar writer surface, consumed by `@sentropic/h2a`'s
162
+ * `status --write-bars` loop via lazy `import()`: enumerate the sessions whose
163
+ * installed bar expects prepared files, and resolve where those files live.
164
+ */
165
+ export { listStatusBarTargets, statusBarFilesForSession, statusBarRoot } from "./tmux.js";
166
+ export type { StatusBarTarget } from "./tmux.js";
145
167
  /** Open the detailed watcher only for an exact, currently managed session. */
146
168
  export declare function openStatusWindowForH2a(session: string): boolean;
147
169
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import { transmittedSecrets, secretsSummary } from "./secrets.js";
15
15
  import { localConvStat, remoteConvStat, alignment } from "./convsync.js";
16
16
  import { gitAlignment, localAncestry, localGitStat, remoteGitStat, } from "./gitdiff.js";
17
17
  import { syncConversation } from "./sync.js";
18
- import { attachLocalSession, attachPodTmux, capturePane, capturePaneVisible, clearPaneComposer, conductorRunning, currentTmuxSessionName, currentTmuxSessionIs, ensureManagedTmuxProfile, ensureHeadlessTerminal, existingLocalSessionSlugs, fanoutLabels, findLocalSession, killLocalSession, localSessionGatewayEnvStatus, listLocalSessions, listLocalSessionsWithDiagnostics, localSessionIdle, localSessionPanePid, localSessionName, paneTreeCpuMs, paneWorkerPid, pasteLiteralBlock, submitPane, installH2aStatusSurface, managedSessionCandidates, parseManagedSessionName, openH2aStatusWindow, persistLaunchContext, readLaunchContext, relaunchInSession, resolveAgentPane, resolveAgentPaneForInstance, resolveLocalSession, runLocalCliForeground, sendKeysLiteral, sessionAttached, sessionAttachedCount, setLocalSessionDisplayName, slugify, cleanupHeadlessPromptFile, startH2aWindow, startH2aWindowVerified, startHeadlessSession, startLocalSession, tmuxAvailable, uninstallH2aStatusSurface, } from "./tmux.js";
18
+ import { attachLocalSession, attachPodTmux, capturePane, capturePaneVisible, clearPaneComposer, conductorRunning, currentTmuxSessionName, currentTmuxSessionIs, ensureManagedTmuxProfile, ensureHeadlessTerminal, existingLocalSessionSlugs, fanoutLabels, findLocalSession, killLocalSession, localSessionGatewayEnvStatus, listLocalSessions, listH2aStatusSurfaces, listLocalSessionsWithDiagnostics, localSessionIdle, localSessionPanePid, localSessionName, paneProcessObservation, paneTreeCpuMs, paneWorkerAttribution, paneWorkerAttributionFromView, paneWorkerPid, pasteLiteralBlock, submitPane, installH2aStatusSurface, managedSessionCandidates, parseManagedSessionName, openH2aStatusWindow, persistLaunchContext, readLaunchContext, readFleetProcView, relaunchInSession, resolveAgentPane, resolveAgentPaneForInstance, resolveLocalSession, sessionRelaunchSafety, runLocalCliForeground, sendKeysLiteral, sessionAttached, sessionAttachedCount, setLocalSessionDisplayName, slugify, cleanupHeadlessPromptFile, startH2aWindow, startH2aWindowVerified, startHeadlessSession, startLocalSession, tmuxAvailable, uninstallH2aStatusSurface, } from "./tmux.js";
19
19
  import { deliverInitialPrompt, sleepSync, } from "./prompt-delivery.js";
20
20
  import { buildLaunchContext } from "./launch-context.js";
21
21
  import { migrateTmuxNames } from "./tmux-name-migration.js";
@@ -25,7 +25,7 @@ import { planRelaunch } from "./relaunch.js";
25
25
  import { isHumanFacingSession, readConversationCustomTitle, readLastLayout, reconcileRunConvIds, restore as restoreLayout, } from "./restore.js";
26
26
  import { getLayoutConfig } from "./config.js";
27
27
  import { advanceJob, coerceRegistryTool, enroll, enrollFromRun, isLive, listJobs, listLocalForLs, loadRegistry, loadRegistryWithDiagnostics, resolveLocalTmuxSessionForName, tryClaimSlot, withRegistryLock, resolveRegistryPath, } from "./registry.js";
28
- import { SessionLeaseStore, decideSessionBeat, isSessionLeaseAbandoned, planLeaseSupervision, reclaimProposals, resolveSessionLeasePath, } from "./session-lease.js";
28
+ import { auditSessionLeaseFleet, countLiveSessionLeases, SessionLeaseStore, decideSessionBeat, isSessionLeaseAlive, isSessionLeaseAbandoned, isSessionLeaseDeadBoot, planLeaseSupervision, reclaimProposals, resolveSessionLeasePath, } from "./session-lease.js";
29
29
  import { aimdEffectiveCap, assertDelegateEffort, assertSafeName, buildDelegateArgs, buildJobRows, buildRemoteDelegate, buildThrottleResumeArgs, canDelegateAtDepth, childDepthEnvValue, clampDepth, clampRemoteDepthBudget, conductorAdvisory, DEFAULT_MAX_CONCURRENT, DEPTH_ENV, inheritedDepthBudget, isDelegateType, isThrottleResumeDue, jitteredBackoffMs, JOB_ID_ENV, jobDir, planNextStarts, planThrottleStep, readJobResult, THROTTLE_MAX_ATTEMPTS, reconcileRemoteJobs, renderJobsTable, resolveJobCwd, runTrackMirror, sweepStaleJobs, trackItemNewArgs, trackItemRealizeArgs, } from "./delegate.js";
30
30
  import { detectThrottle, THROTTLE_TAIL_LINES } from "./throttle-signatures.js";
31
31
  import { interactiveResumeNudge, planInteractiveResume, } from "./interactive-throttle.js";
@@ -1014,12 +1014,15 @@ function sessionLeaseStore() {
1014
1014
  * to compute a rate against.
1015
1015
  */
1016
1016
  export function acquireSessionLease(sessionId, opts) {
1017
- const cpuMs = opts.agentPane ? paneTreeCpuMs(opts.agentPane) : undefined;
1017
+ // CPU baseline and worker identity share one /proc walk at acquire time.
1018
+ const observation = opts.agentPane ? paneProcessObservation(opts.agentPane) : undefined;
1019
+ const worker = opts.worker ?? observation?.worker;
1018
1020
  return sessionLeaseStore().acquire({
1019
1021
  sessionId,
1020
1022
  holder: opts.holder,
1021
1023
  ...(opts.workspace !== undefined ? { workspace: opts.workspace } : {}),
1022
- ...(cpuMs !== undefined ? { cpuMs } : {}),
1024
+ ...(observation?.cpuMs !== undefined ? { cpuMs: observation.cpuMs } : {}),
1025
+ ...(worker !== undefined ? { worker } : {}),
1023
1026
  });
1024
1027
  }
1025
1028
  /**
@@ -1040,6 +1043,9 @@ export function superviseSessionLeases(sessions, now = new Date().toISOString())
1040
1043
  unreadable: [],
1041
1044
  proposals: [],
1042
1045
  };
1046
+ const procView = readFleetProcView();
1047
+ // R3: prior-boot corpses are reaped silently before any proposal pass.
1048
+ store.reapDeadBootLeases(procView);
1043
1049
  const leases = store.readAll();
1044
1050
  const byId = new Map(leases.map((lease) => [lease.sessionId, lease]));
1045
1051
  for (const step of planLeaseSupervision(leases, sessions)) {
@@ -1055,27 +1061,77 @@ export function superviseSessionLeases(sessions, now = new Date().toISOString())
1055
1061
  if (step.action === "leave")
1056
1062
  continue;
1057
1063
  const pane = step.tmuxSession ? resolveAgentPane(step.tmuxSession) : undefined;
1064
+ let currentLease = lease;
1065
+ // R1 lazy migration: old leases remain alive until this pass can resolve
1066
+ // their worker. Resolve from the pass-wide snapshot, never by spawning a
1067
+ // /proc walk for every lease.
1068
+ if (currentLease.worker === undefined && pane !== undefined) {
1069
+ const worker = paneWorkerAttributionFromView(pane, procView);
1070
+ if (worker !== undefined) {
1071
+ currentLease = store.populateWorker({
1072
+ sessionId: currentLease.sessionId,
1073
+ token: currentLease.token,
1074
+ worker,
1075
+ });
1076
+ }
1077
+ }
1078
+ if (!isSessionLeaseAlive(currentLease, procView, now)) {
1079
+ result.unreadable.push(currentLease.sessionId);
1080
+ continue;
1081
+ }
1058
1082
  const cpuMsNow = pane ? paneTreeCpuMs(pane) : undefined;
1059
- const decision = decideSessionBeat({ lease, cpuMsNow, now });
1083
+ const decision = decideSessionBeat({ lease: currentLease, cpuMsNow, now });
1060
1084
  if (decision.action === "beat" && cpuMsNow !== undefined) {
1061
- store.heartbeat({ sessionId: lease.sessionId, token: lease.token, cpuMs: cpuMsNow });
1062
- result.beaten.push(lease.sessionId);
1085
+ store.heartbeat({ sessionId: currentLease.sessionId, token: currentLease.token, cpuMs: cpuMsNow });
1086
+ result.beaten.push(currentLease.sessionId);
1063
1087
  }
1064
1088
  else if (decision.action === "observe" && cpuMsNow !== undefined) {
1065
- store.observe({ sessionId: lease.sessionId, token: lease.token, cpuMs: cpuMsNow });
1066
- result.observed.push(lease.sessionId);
1089
+ store.observe({ sessionId: currentLease.sessionId, token: currentLease.token, cpuMs: cpuMsNow });
1090
+ result.observed.push(currentLease.sessionId);
1067
1091
  }
1068
1092
  else {
1069
- result.unreadable.push(lease.sessionId);
1093
+ result.unreadable.push(currentLease.sessionId);
1070
1094
  }
1071
1095
  }
1072
1096
  catch {
1073
1097
  // a rejected write (raced re-acquisition, torn store) must not stop the pass
1074
1098
  }
1075
1099
  }
1076
- result.proposals = reclaimProposals(store.readAll(), now);
1100
+ result.proposals = reclaimProposals(store.readAll(), now, procView);
1077
1101
  return result;
1078
1102
  }
1103
+ /** Relaunch one managed session while its lease carries the bounded protection. */
1104
+ export function relaunchSessionWithLease(input) {
1105
+ const store = sessionLeaseStore();
1106
+ const lease = store.forSession(input.sessionId);
1107
+ if (lease === undefined)
1108
+ return relaunchInSession(input.tmuxSession, input.command);
1109
+ const pane = resolveAgentPane(input.tmuxSession);
1110
+ const outcome = store.relaunch({
1111
+ sessionId: lease.sessionId,
1112
+ token: lease.token,
1113
+ ...(input.resolvingBoundMs !== undefined
1114
+ ? { resolvingBoundMs: input.resolvingBoundMs }
1115
+ : {}),
1116
+ act: () => relaunchInSession(input.tmuxSession, input.command),
1117
+ resolveWorker: () => (pane ? paneWorkerAttribution(pane) : undefined),
1118
+ });
1119
+ return outcome.succeeded;
1120
+ }
1121
+ /** One on-demand fleet-wide read-back audit; it never runs from rendering. */
1122
+ export function auditLiveSessionLeases(sessions = listJobs(), now = new Date().toISOString()) {
1123
+ const store = sessionLeaseStore();
1124
+ const leases = store.readAll();
1125
+ const procView = readFleetProcView();
1126
+ const report = auditSessionLeaseFleet(sessions.map((session) => ({
1127
+ sessionId: session.id,
1128
+ ...(session.tmuxSession !== undefined ? { tmuxSession: session.tmuxSession } : {}),
1129
+ ...(session.jobState !== undefined ? { jobState: session.jobState } : {}),
1130
+ })), leases, listH2aStatusSurfaces(), procView, now);
1131
+ const liveLeaseCount = countLiveSessionLeases(leases, procView, now);
1132
+ const reaped = store.reapDeadBootLeases(procView);
1133
+ return { ...report, reaped, liveLeaseCount, procView };
1134
+ }
1079
1135
  /** Human-readable duration for lease reporting ("41m", "2h13m"). */
1080
1136
  function formatIdle(ms) {
1081
1137
  const minutes = Math.floor(ms / 60_000);
@@ -4553,11 +4609,14 @@ export async function main(argv) {
4553
4609
  .command("leases")
4554
4610
  .description("Session slot leases (machine-scoped): who holds a concurrency slot, when it last proved it was working, and which slots are reclaimable. READ-ONLY — it kills nothing and frees nothing.")
4555
4611
  .option("--probe", "before reporting, run one supervising pass: beat the leases of sessions whose pane is burning CPU, record the others")
4612
+ .option("--audit", "run one on-demand fleet-wide read-back audit (one tmux FORMAT call and one /proc scan)")
4556
4613
  .action((opts) => {
4557
4614
  const now = new Date().toISOString();
4558
4615
  if (opts.probe === true)
4559
4616
  superviseSessionLeases(listJobs(), now);
4560
- const leases = sessionLeaseStore().readAll();
4617
+ const audit = opts.audit === true ? auditLiveSessionLeases(listJobs(), now) : undefined;
4618
+ const store = sessionLeaseStore();
4619
+ const leases = store.readAll();
4561
4620
  if (leases.length === 0) {
4562
4621
  process.stdout.write("no session leases\n");
4563
4622
  return;
@@ -4568,17 +4627,33 @@ export async function main(argv) {
4568
4627
  .sort((a, b) => Date.parse(a.heartbeatAt) - Date.parse(b.heartbeatAt))
4569
4628
  .map((lease) => {
4570
4629
  const idle = nowMs - Date.parse(lease.heartbeatAt);
4571
- const state = isSessionLeaseAbandoned(lease, now) ? "RECLAIMABLE" : "held";
4630
+ const state = audit
4631
+ ? isSessionLeaseAlive(lease, audit.procView, now)
4632
+ ? "held"
4633
+ : "RECLAIMABLE"
4634
+ : isSessionLeaseAbandoned(lease, now)
4635
+ ? "RECLAIMABLE"
4636
+ : "held";
4572
4637
  return (`${lease.sessionId.padEnd(24)} ${state.padEnd(12)} ` +
4573
4638
  `idle ${formatIdle(idle).padEnd(7)} ttl ${formatIdle(lease.ttlMs).padEnd(6)} ` +
4574
4639
  `holder ${lease.holder}`);
4575
4640
  });
4576
4641
  process.stdout.write(`${rows.join("\n")}\n`);
4577
- const reclaimable = reclaimProposals(leases, now).length;
4642
+ const reclaimable = audit
4643
+ ? reclaimProposals(leases, now, audit.procView).length
4644
+ : reclaimProposals(leases, now).length;
4578
4645
  if (reclaimable > 0) {
4579
4646
  process.stderr.write(`[h2a] ${reclaimable} slot(s) reclaimable — free one with: h2a jobs reclaim <id> ` +
4580
4647
  "(the session's tmux window is left running and can still be attached)\n");
4581
4648
  }
4649
+ if (audit) {
4650
+ if (audit.reaped.length > 0) {
4651
+ process.stderr.write(`[h2a] audit reaped prior-boot lease(s): ${audit.reaped.join(", ")}\n`);
4652
+ }
4653
+ if (audit.missingStatusSurface.length > 0) {
4654
+ process.stderr.write(`[h2a] audit status-surface drift: ${audit.missingStatusSurface.join(", ")}\n`);
4655
+ }
4656
+ }
4582
4657
  });
4583
4658
  jobsCommand
4584
4659
  .command("reclaim <id>")
@@ -4586,15 +4661,21 @@ export async function main(argv) {
4586
4661
  .action((id) => {
4587
4662
  const now = new Date().toISOString();
4588
4663
  const store = sessionLeaseStore();
4589
- const lease = store.forSession(id);
4664
+ let lease = store.forSession(id);
4590
4665
  if (!lease) {
4591
4666
  process.stderr.write(`[h2a] no session lease for "${id}" — nothing to reclaim (see: h2a jobs leases)\n`);
4592
4667
  process.exitCode = 1;
4593
4668
  return;
4594
4669
  }
4670
+ const procView = readFleetProcView();
4671
+ if (isSessionLeaseDeadBoot(lease, procView)) {
4672
+ store.reapDeadBootLeases(procView);
4673
+ process.stdout.write(`reaped ${id} — lease belonged to a prior boot\n`);
4674
+ return;
4675
+ }
4595
4676
  // The one guard that matters: a session still proving it works keeps its
4596
4677
  // slot, whatever the operator believes. Reclaiming is not arbitration.
4597
- if (!isSessionLeaseAbandoned(lease, now)) {
4678
+ if (isSessionLeaseAlive(lease, procView, now)) {
4598
4679
  const idle = Date.parse(now) - Date.parse(lease.heartbeatAt);
4599
4680
  process.stderr.write(`[h2a] refusing to reclaim ${id}: its lease still beats (last proof of work ` +
4600
4681
  `${formatIdle(idle)} ago, TTL ${formatIdle(lease.ttlMs)}). It is working.\n`);
@@ -5477,7 +5558,10 @@ export async function main(argv) {
5477
5558
  })(),
5478
5559
  slug: s.slug,
5479
5560
  name: s.name,
5480
- idle: localSessionIdle(s.name),
5561
+ ...(() => {
5562
+ const safety = sessionRelaunchSafety(s.name);
5563
+ return { ...safety, livenessReason: safety.reason };
5564
+ })(),
5481
5565
  })), {
5482
5566
  ...(forced ? { force: true } : {}),
5483
5567
  ...(opts.all && !opts.includeAgents
@@ -5510,7 +5594,15 @@ export async function main(argv) {
5510
5594
  if (!forced) {
5511
5595
  let ok = 0;
5512
5596
  for (const action of plan.actions) {
5513
- if (relaunchInSession(action.name, action.cmd)) {
5597
+ const sessionId = entryByTmuxSession.get(action.name)?.id;
5598
+ const relaunched = sessionId !== undefined
5599
+ ? relaunchSessionWithLease({
5600
+ sessionId,
5601
+ tmuxSession: action.name,
5602
+ command: action.cmd,
5603
+ })
5604
+ : relaunchInSession(action.name, action.cmd);
5605
+ if (relaunched) {
5514
5606
  ok += 1;
5515
5607
  process.stderr.write(`[h2a] relaunched ${action.slug}: ${action.cmd}\n`);
5516
5608
  }
@@ -5576,8 +5668,17 @@ export async function main(argv) {
5576
5668
  process.exitCode = 1;
5577
5669
  return;
5578
5670
  }
5671
+ const finalReady = [];
5672
+ for (const item of ready) {
5673
+ const safety = sessionRelaunchSafety(item.action.name);
5674
+ if (safety.activelyWorking) {
5675
+ process.stderr.write(`[h2a] skipped ${item.action.slug}: ${safety.reason}\n`);
5676
+ continue;
5677
+ }
5678
+ finalReady.push(item);
5679
+ }
5579
5680
  let ok = 0;
5580
- for (const { action, entry, sessionClass } of ready) {
5681
+ for (const { action, entry, sessionClass } of finalReady) {
5581
5682
  if (!killLocalSession(action.name)) {
5582
5683
  process.stderr.write(`[h2a] FAILED to force-restart ${action.slug}: tmux session ${action.name} could not be killed.\n`);
5583
5684
  continue;
@@ -5701,6 +5802,9 @@ export async function main(argv) {
5701
5802
  });
5702
5803
  let nudged = 0;
5703
5804
  if (apply) {
5805
+ const leaseIdByTmuxSession = new Map(loadRegistry()
5806
+ .filter((entry) => entry.tmuxSession !== undefined)
5807
+ .map((entry) => [entry.tmuxSession, entry.id]));
5704
5808
  for (const r of plan.toResume) {
5705
5809
  // DOUBLE-CHECK the attached guard at the moment of action (the pure plan
5706
5810
  // already excluded attached panes, but re-read in case a human just
@@ -5709,7 +5813,14 @@ export async function main(argv) {
5709
5813
  process.stderr.write(`[h2a] ${r.name} (${r.type}) just got attached — skipping the nudge\n`);
5710
5814
  continue;
5711
5815
  }
5712
- const ok = relaunchInSession(r.name, interactiveResumeNudge(r.type));
5816
+ const sessionId = leaseIdByTmuxSession.get(r.name);
5817
+ const ok = sessionId !== undefined
5818
+ ? relaunchSessionWithLease({
5819
+ sessionId,
5820
+ tmuxSession: r.name,
5821
+ command: interactiveResumeNudge(r.type),
5822
+ })
5823
+ : relaunchInSession(r.name, interactiveResumeNudge(r.type));
5713
5824
  if (ok) {
5714
5825
  nudged += 1;
5715
5826
  throttleState.set(r.name, r.next);
@@ -7035,6 +7146,12 @@ export function projectAgentsForH2a() {
7035
7146
  return projectRemoteAgents({ jobs: listJobs(), localRows: listLocalForLs() });
7036
7147
  }
7037
7148
  export { projectStatusForH2a };
7149
+ /**
7150
+ * Status-bar writer surface, consumed by `@sentropic/h2a`'s
7151
+ * `status --write-bars` loop via lazy `import()`: enumerate the sessions whose
7152
+ * installed bar expects prepared files, and resolve where those files live.
7153
+ */
7154
+ export { listStatusBarTargets, statusBarFilesForSession, statusBarRoot } from "./tmux.js";
7038
7155
  /** Open the detailed watcher only for an exact, currently managed session. */
7039
7156
  export function openStatusWindowForH2a(session) {
7040
7157
  const exact = listLocalSessions().find((item) => item.name === session);