@akshar5/cohall 0.4.3 → 0.4.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.5](https://github.com/AksharP5/cohall/compare/v0.4.4...v0.4.5) (2026-08-07)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **relay:** keep upgrades available and forget stale devices ([#32](https://github.com/AksharP5/cohall/issues/32)) ([d5b054d](https://github.com/AksharP5/cohall/commit/d5b054db37b8e2737af7540cac4f74f64e457a7f))
9
+
10
+ ## [0.4.4](https://github.com/AksharP5/cohall/compare/v0.4.3...v0.4.4) (2026-08-07)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **upgrade:** retain delegated restart receipts ([2c7e9c7](https://github.com/AksharP5/cohall/commit/2c7e9c713baff421c21f3780991f9ffcb0536d1d))
16
+
3
17
  ## [0.4.3](https://github.com/AksharP5/cohall/compare/v0.4.2...v0.4.3) (2026-08-07)
4
18
 
5
19
 
package/README.md CHANGED
@@ -228,6 +228,8 @@ current, ensuring an older loaded process is replaced. Cohall refuses to restart
228
228
  a service configured to use a different global installation; run that service's
229
229
  executable directly or update its service definition first. Use `cohall upgrade --dry-run` to inspect the plan or
230
230
  `cohall upgrade --no-restart` to update files without restarting services.
231
+ Linux relays can use the packaged systemd socket unit so new connections remain
232
+ available while the relay process is replaced; see [service setup](docs/services.md).
231
233
  Environment variables override stored values:
232
234
 
233
235
  | Variable | Purpose |
@@ -250,6 +252,11 @@ Environment variables override stored values:
250
252
  | `COHALL_RELAY_ALLOW_REMOTE` | Explicit non-loopback binding opt-in |
251
253
 
252
254
  The owner token can create pairing credentials, list sessions, and revoke them.
255
+ `cohall forget <device-id>` removes an offline device from discovery after
256
+ confirming it has no outstanding tasks, revokes its device credential, and
257
+ preserves its completed task history. On the relay host, owner commands read the
258
+ protected local owner-token file automatically; remote owner commands require
259
+ `COHALL_TOKEN`.
253
260
  Ordinary client and device credentials are role-separated, device-bound where
254
261
  applicable, expiring, and stored only as SHA-256 hashes by the relay.
255
262
 
package/bin/cohall.js CHANGED
@@ -17,7 +17,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
17
 
18
18
  // packages/protocol/src/index.ts
19
19
  import { Schema } from "effect";
20
- var version = "0.4.3", bounded = (maxLength) => Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(maxLength)), optionalText = (maxLength) => Schema.String.check(Schema.isMaxLength(maxLength)), boundedArray = (schema, maxLength) => Schema.Array(schema).check(Schema.isMaxLength(maxLength)), uuid = (name) => Schema.String.check(Schema.isUUID(4)).pipe(Schema.brand(name)), isoTimestamp = (name) => Schema.String.check(Schema.isPattern(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?Z$/, {
20
+ var version = "0.4.5", bounded = (maxLength) => Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(maxLength)), optionalText = (maxLength) => Schema.String.check(Schema.isMaxLength(maxLength)), boundedArray = (schema, maxLength) => Schema.Array(schema).check(Schema.isMaxLength(maxLength)), uuid = (name) => Schema.String.check(Schema.isUUID(4)).pipe(Schema.brand(name)), isoTimestamp = (name) => Schema.String.check(Schema.isPattern(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?Z$/, {
21
21
  expected: "an ISO-8601 UTC timestamp"
22
22
  })).pipe(Schema.brand(name)), DeviceId, ThreadId, MessageId, TaskId, AuthSessionId, Timestamp, Platform, Provider, DeviceStatus, TaskStatus, TaskTraceEventKind, MessageRole, ConnectionRole, AuthSession, CreatePairingInput, PairingCredential, ExchangePairingInput, SessionCredential, PairingResult, Capability, Workspace, Device, Thread, Message, Task, TaskTraceEvent, TaskTrace, ThreadContext, CreateTaskInput, SocketEvent, ErrorResponse, terminalTaskStatuses, isTerminalTask = (task) => terminalTaskStatuses.has(task.status), now = () => Timestamp.make(new Date().toISOString()), makeDeviceId = () => DeviceId.make(crypto.randomUUID()), makeThreadId = () => ThreadId.make(crypto.randomUUID()), makeMessageId = () => MessageId.make(crypto.randomUUID()), makeTaskId = () => TaskId.make(crypto.randomUUID()), makeAuthSessionId = () => AuthSessionId.make(crypto.randomUUID()), decodeCreatePairingInput, decodeExchangePairingInput, decodeCreateTaskInput, decodeDevice, decodeSocketEvent;
23
23
  var init_src = __esm(() => {
@@ -330,6 +330,9 @@ class Hub {
330
330
  }
331
331
  }
332
332
  }
333
+ closeDevice(deviceId) {
334
+ this.#devices.get(deviceId)?.close(4003, "Device forgotten");
335
+ }
333
336
  hasDevice(deviceId) {
334
337
  return this.#devices.get(deviceId)?.readyState === WebSocket2.OPEN;
335
338
  }
@@ -588,11 +591,35 @@ var PersistenceError, Service2, operationError = (operation) => (cause) => new P
588
591
  });
589
592
  const listDevices = Effect9.fn("RelayStore.listDevices")(function* () {
590
593
  const rows = yield* Effect9.try({
591
- try: () => db.query("SELECT * FROM devices ORDER BY name COLLATE NOCASE, id").all(),
594
+ try: () => db.query("SELECT * FROM devices WHERE forgotten_at IS NULL ORDER BY name COLLATE NOCASE, id").all(),
592
595
  catch: operationError("RelayStore.listDevices")
593
596
  });
594
597
  return yield* Effect9.forEach(rows, deviceFromRow);
595
598
  });
599
+ const forgetDevice = Effect9.fn("RelayStore.forgetDevice")(function* (deviceId) {
600
+ const row = yield* Effect9.try({
601
+ try: () => db.transaction(() => {
602
+ const device = db.query("SELECT * FROM devices WHERE id = ? AND forgotten_at IS NULL").get(deviceId);
603
+ if (device === null) {
604
+ throw new Error(`Unknown device ${deviceId}`);
605
+ }
606
+ if (device.status !== "offline") {
607
+ throw new Error(`Device ${deviceId} must be offline before it can be forgotten`);
608
+ }
609
+ const outstanding = db.query(`SELECT COUNT(*) AS count FROM tasks
610
+ WHERE target_device_id = ? AND status NOT IN ('completed', 'failed', 'cancelled')`).get(deviceId);
611
+ if ((outstanding?.count ?? 0) > 0) {
612
+ throw new Error(`Device ${deviceId} still has outstanding tasks`);
613
+ }
614
+ const timestamp = now();
615
+ db.query("UPDATE devices SET forgotten_at = ? WHERE id = ?").run(timestamp, deviceId);
616
+ db.query("UPDATE auth_sessions SET revoked_at = ? WHERE bound_device_id = ? AND revoked_at IS NULL").run(timestamp, deviceId);
617
+ return device;
618
+ })(),
619
+ catch: operationError("RelayStore.forgetDevice")
620
+ });
621
+ return yield* deviceFromRow(row);
622
+ });
596
623
  const recover = Effect9.fn("RelayStore.recover")(function* () {
597
624
  yield* Effect9.try({
598
625
  try: () => db.transaction(() => {
@@ -620,7 +647,8 @@ var PersistenceError, Service2, operationError = (operation) => (cause) => new P
620
647
  architecture = excluded.architecture, status = excluded.status,
621
648
  providers_json = excluded.providers_json, capabilities_json = excluded.capabilities_json,
622
649
  workspaces_json = excluded.workspaces_json, version = excluded.version,
623
- last_seen_at = excluded.last_seen_at, connected_at = excluded.connected_at`).run(device.id, device.name, device.hostname, device.platform, device.architecture, device.status, JSON.stringify(device.providers), JSON.stringify(device.capabilities), JSON.stringify(device.workspaces), device.version, device.lastSeenAt, device.connectedAt ?? null),
650
+ last_seen_at = excluded.last_seen_at, connected_at = excluded.connected_at,
651
+ forgotten_at = NULL`).run(device.id, device.name, device.hostname, device.platform, device.architecture, device.status, JSON.stringify(device.providers), JSON.stringify(device.capabilities), JSON.stringify(device.workspaces), device.version, device.lastSeenAt, device.connectedAt ?? null),
624
652
  catch: operationError("RelayStore.upsertDevice")
625
653
  });
626
654
  return device;
@@ -983,6 +1011,7 @@ var PersistenceError, Service2, operationError = (operation) => (cause) => new P
983
1011
  return Service2.of({
984
1012
  recover,
985
1013
  listDevices,
1014
+ forgetDevice,
986
1015
  upsertDevice,
987
1016
  heartbeat: (deviceId, status) => updateDeviceStatus(deviceId, status),
988
1017
  markDeviceOffline: (deviceId) => updateDeviceStatus(deviceId, "offline"),
@@ -1017,7 +1046,7 @@ var PersistenceError, Service2, operationError = (operation) => (cause) => new P
1017
1046
  platform TEXT NOT NULL, architecture TEXT NOT NULL, status TEXT NOT NULL,
1018
1047
  providers_json TEXT NOT NULL, capabilities_json TEXT NOT NULL,
1019
1048
  workspaces_json TEXT NOT NULL, version TEXT NOT NULL, last_seen_at TEXT NOT NULL,
1020
- connected_at TEXT
1049
+ connected_at TEXT, forgotten_at TEXT
1021
1050
  );
1022
1051
  CREATE TABLE IF NOT EXISTS threads (
1023
1052
  id TEXT PRIMARY KEY, title TEXT NOT NULL, created_at TEXT NOT NULL,
@@ -1065,6 +1094,10 @@ var PersistenceError, Service2, operationError = (operation) => (cause) => new P
1065
1094
  );
1066
1095
  CREATE INDEX IF NOT EXISTS auth_sessions_token ON auth_sessions(token_hash);
1067
1096
  `);
1097
+ const deviceColumns = db.query("PRAGMA table_info(devices)").all();
1098
+ if (!deviceColumns.some((column) => column.name === "forgotten_at")) {
1099
+ db.exec("ALTER TABLE devices ADD COLUMN forgotten_at TEXT");
1100
+ }
1068
1101
  },
1069
1102
  catch: operationError("RelayStore.migrate")
1070
1103
  }), layer2 = (path) => Layer2.effect(Service2, Effect9.acquireRelease(Effect9.try({
@@ -1084,7 +1117,8 @@ var init_store = __esm(() => {
1084
1117
  // apps/relay/src/main.ts
1085
1118
  var exports_main = {};
1086
1119
  __export(exports_main, {
1087
- runRelay: () => runRelay
1120
+ runRelay: () => runRelay,
1121
+ relayListenOptions: () => relayListenOptions
1088
1122
  });
1089
1123
  import { Effect as Effect10, ManagedRuntime, Schema as Schema11 } from "effect";
1090
1124
  import { createHash as createHash2, timingSafeEqual } from "node:crypto";
@@ -1092,7 +1126,22 @@ import { access as access4, chmod as chmod5 } from "node:fs/promises";
1092
1126
  import { createServer } from "node:http";
1093
1127
  import { platform as platform5 } from "node:os";
1094
1128
  import { WebSocketServer } from "ws";
1095
- var RequestError, json = (value, status = 200) => Response.json(value, {
1129
+ var RequestError, relayListenOptions = (configuration, environment = process.env, pid = process.pid) => {
1130
+ const listenPid = Number(environment.LISTEN_PID);
1131
+ const listenFds = Number(environment.LISTEN_FDS);
1132
+ if (listenPid !== pid || !Number.isInteger(listenFds) || listenFds < 1) {
1133
+ return { host: configuration.host, port: configuration.port };
1134
+ }
1135
+ const descriptorNames = environment.LISTEN_FDNAMES?.split(":") ?? [];
1136
+ const namedIndex = descriptorNames.indexOf("cohall-relay");
1137
+ if (namedIndex >= 0 && namedIndex < listenFds) {
1138
+ return { fd: 3 + namedIndex };
1139
+ }
1140
+ if (listenFds === 1) {
1141
+ return { fd: 3 };
1142
+ }
1143
+ throw new Error("Cohall received multiple systemd sockets but none was named cohall-relay");
1144
+ }, json = (value, status = 200) => Response.json(value, {
1096
1145
  status,
1097
1146
  headers: {
1098
1147
  "cache-control": "no-store",
@@ -1414,6 +1463,22 @@ Content-Length: 0\r
1414
1463
  if (url.pathname === "/api/devices" && request.method === "GET") {
1415
1464
  return json(yield* store.listDevices());
1416
1465
  }
1466
+ const forgetDevice = url.pathname.match(/^\/api\/devices\/([^/]+)\/forget$/);
1467
+ if (request.method === "POST" && forgetDevice?.[1] !== undefined) {
1468
+ if (principal !== "owner") {
1469
+ return yield* new RequestError({ status: 403, message: "Owner token required" });
1470
+ }
1471
+ const id = yield* pathId(DeviceId, forgetDevice[1]);
1472
+ if (hub.hasDevice(id)) {
1473
+ return yield* new RequestError({
1474
+ status: 409,
1475
+ message: `Device ${id} must be offline before it can be forgotten`
1476
+ });
1477
+ }
1478
+ const forgotten = yield* store.forgetDevice(id);
1479
+ hub.closeDevice(id);
1480
+ return json(forgotten);
1481
+ }
1417
1482
  if (url.pathname === "/api/tasks" && request.method === "POST") {
1418
1483
  const input = yield* body(request, decodeCreateTaskInput);
1419
1484
  const target = yield* chooseDevice(input, sourceDeviceId);
@@ -1444,7 +1509,7 @@ Content-Length: 0\r
1444
1509
  }
1445
1510
  return yield* new RequestError({ status: 404, message: "Route not found" });
1446
1511
  }).pipe(Effect10.mapError((cause) => cause instanceof RequestError ? cause : new RequestError({
1447
- status: cause._tag !== "RelayStore.PersistenceError" ? 500 : cause.message.startsWith("Unknown") ? 404 : cause.message.includes("outstanding task limit") ? 429 : 500,
1512
+ status: cause._tag !== "RelayStore.PersistenceError" ? 500 : cause.message.startsWith("Unknown") ? 404 : cause.message.includes("outstanding task limit") ? 429 : cause.message.includes("must be offline") || cause.message.includes("still has outstanding tasks") ? 409 : 500,
1448
1513
  message: cause.message
1449
1514
  })));
1450
1515
  return run2(effect).catch((cause) => cause instanceof RequestError ? json({ error: cause.status === 500 ? "Relay request failed" : cause.message }, cause.status) : json({ error: "Relay request failed" }, 500));
@@ -1543,12 +1608,14 @@ Content-Length: 0\r
1543
1608
  });
1544
1609
  await new Promise((resolve3, reject) => {
1545
1610
  server.once("error", reject);
1546
- server.listen(configuration.port, configuration.host, () => {
1611
+ server.listen(relayListenOptions(configuration), () => {
1547
1612
  server.off("error", reject);
1548
1613
  resolve3();
1549
1614
  });
1550
1615
  });
1551
- console.log(`Cohall relay listening on http://${configuration.host}:${configuration.port}`);
1616
+ const address = server.address();
1617
+ const listener = typeof address === "string" ? address : address?.family === "IPv6" ? `[${address.address}]:${address.port}` : `${address?.address ?? configuration.host}:${address?.port ?? configuration.port}`;
1618
+ console.log(`Cohall relay listening on http://${listener}`);
1552
1619
  let stopping = false;
1553
1620
  const shutdown = async () => {
1554
1621
  if (stopping) {
@@ -1684,6 +1751,7 @@ var make = (options) => {
1684
1751
  });
1685
1752
  return Service.of({
1686
1753
  devices: () => request("RelayClient.devices", "/api/devices", Schema2.Array(Device)),
1754
+ forgetDevice: (deviceId) => request("RelayClient.forgetDevice", `/api/devices/${encodeURIComponent(deviceId)}/forget`, Device, { method: "POST" }),
1687
1755
  createTask: (input) => request("RelayClient.createTask", "/api/tasks", Task, {
1688
1756
  method: "POST",
1689
1757
  body: JSON.stringify(input)
@@ -2323,6 +2391,15 @@ var defaultConfigDirectory = () => {
2323
2391
  }
2324
2392
  return join2(process.env.XDG_CONFIG_HOME ?? join2(homedir2(), ".config"), "cohall");
2325
2393
  };
2394
+ var defaultRelayDataDirectory = () => {
2395
+ if (platform2() === "win32") {
2396
+ return join2(process.env.LOCALAPPDATA ?? join2(homedir2(), "AppData", "Local"), "Cohall");
2397
+ }
2398
+ if (platform2() === "darwin") {
2399
+ return join2(homedir2(), "Library", "Application Support", "Cohall", "relay");
2400
+ }
2401
+ return join2(process.env.XDG_DATA_HOME ?? join2(homedir2(), ".local", "share"), "cohall");
2402
+ };
2326
2403
  var configurationPath = () => resolve(process.env.COHALL_CONFIG ?? join2(defaultConfigDirectory(), "config.json"));
2327
2404
  var normalizeRelayUrl = (input) => {
2328
2405
  const url = new URL(input);
@@ -2454,9 +2531,12 @@ var loadClientConfiguration = Effect3.tryPromise({
2454
2531
  var loadOwnerConfiguration = Effect3.tryPromise({
2455
2532
  try: async () => {
2456
2533
  const stored = await storedOrDefaults();
2457
- const token = process.env.COHALL_TOKEN;
2458
- if (token === undefined) {
2459
- throw new Error("No owner credential. Set COHALL_TOKEN on the owner-authenticated machine.");
2534
+ const ownerTokenPath = join2(resolve(process.env.COHALL_DATA_DIR ?? defaultRelayDataDirectory()), "owner-token");
2535
+ const token = process.env.COHALL_TOKEN ?? await readFile(ownerTokenPath, "utf8").then((value) => value.trim()).catch(() => {
2536
+ return;
2537
+ });
2538
+ if (token === undefined || token.length === 0) {
2539
+ throw new Error("No owner credential. Run this command on the relay host or set COHALL_TOKEN.");
2460
2540
  }
2461
2541
  return ClientConfiguration.make({
2462
2542
  relayUrl: normalizeRelayUrl(process.env.COHALL_RELAY_URL ?? stored.relayUrl),
@@ -2803,7 +2883,7 @@ var installedVersion = async (entrypoint) => {
2803
2883
  return metadata.version;
2804
2884
  };
2805
2885
  var restartReceiptPath = () => join3(dirname2(configurationPath()), "upgrade-restart.json");
2806
- var restartServices = async (runner, services, statePath, state) => {
2886
+ var restartServices = async (runner, services, statePath, state, preserveDeviceReceipt) => {
2807
2887
  let current = state;
2808
2888
  for (const service of services) {
2809
2889
  current = { ...current, restartingService: service.id };
@@ -2823,6 +2903,9 @@ var restartServices = async (runner, services, statePath, state) => {
2823
2903
  await writeReceipt(statePath, current);
2824
2904
  throw cause;
2825
2905
  }
2906
+ if (service.device && preserveDeviceReceipt) {
2907
+ return current;
2908
+ }
2826
2909
  current = {
2827
2910
  version: current.version,
2828
2911
  fromVersion: current.fromVersion,
@@ -2834,6 +2917,7 @@ var restartServices = async (runner, services, statePath, state) => {
2834
2917
  }
2835
2918
  return current;
2836
2919
  };
2920
+ var reportedRestartServices = (receipt) => receipt.restartingService === undefined || receipt.restartedServices.includes(receipt.restartingService) ? receipt.restartedServices : [...receipt.restartedServices, receipt.restartingService];
2837
2921
  var upgrade = async (options) => {
2838
2922
  const runner = options.runner ?? defaultRunner;
2839
2923
  const runtimePlatform = options.platform ?? process.platform;
@@ -2877,16 +2961,18 @@ var upgrade = async (options) => {
2877
2961
  };
2878
2962
  if (remaining.length > 0) {
2879
2963
  await writeReceipt(statePath, resumed);
2880
- resumed = await restartServices(runner, remaining, statePath, resumed);
2964
+ resumed = await restartServices(runner, remaining, statePath, resumed, options.delegated === true);
2965
+ }
2966
+ if (resumed.restartingService === undefined) {
2967
+ await rm2(statePath, { force: true });
2881
2968
  }
2882
- await rm2(statePath, { force: true });
2883
2969
  return {
2884
2970
  upgraded: previous.fromVersion !== previous.version,
2885
2971
  from_version: previous.fromVersion,
2886
2972
  installed_version: previous.version,
2887
2973
  requested_version: previous.version,
2888
2974
  package_manager: previous.packageManager,
2889
- services_restarted: resumed.restartedServices,
2975
+ services_restarted: reportedRestartServices(resumed),
2890
2976
  services_pending_restart: [],
2891
2977
  resumed_after_restart: true,
2892
2978
  dry_run: false
@@ -2943,15 +3029,17 @@ var upgrade = async (options) => {
2943
3029
  restartedServices: []
2944
3030
  };
2945
3031
  await writeReceipt(statePath, initial);
2946
- const completed = await restartServices(runner, services, statePath, initial);
2947
- await rm2(statePath, { force: true });
3032
+ const completed = await restartServices(runner, services, statePath, initial, options.delegated === true);
3033
+ if (completed.restartingService === undefined) {
3034
+ await rm2(statePath, { force: true });
3035
+ }
2948
3036
  return {
2949
3037
  upgraded,
2950
3038
  from_version: options.currentVersion,
2951
3039
  installed_version: nextVersion,
2952
3040
  requested_version: target,
2953
3041
  package_manager: installation.manager,
2954
- services_restarted: completed.restartedServices,
3042
+ services_restarted: reportedRestartServices(completed),
2955
3043
  services_pending_restart: [],
2956
3044
  resumed_after_restart: false,
2957
3045
  dry_run: false
@@ -3005,6 +3093,7 @@ Usage:
3005
3093
  cohall pair [--label name] [--client-only]
3006
3094
  cohall sessions
3007
3095
  cohall revoke <session-id>
3096
+ cohall forget <device-id>
3008
3097
  cohall doctor
3009
3098
  cohall upgrade [--to version|latest] [--no-restart] [--dry-run]
3010
3099
  cohall device
@@ -3193,7 +3282,8 @@ var runCli = async (command, raw) => {
3193
3282
  currentVersion: version,
3194
3283
  ...target === undefined ? {} : { target },
3195
3284
  restart: !arguments_.options.has("no-restart"),
3196
- dryRun: arguments_.options.has("dry-run")
3285
+ dryRun: arguments_.options.has("dry-run"),
3286
+ delegated: process.env.COHALL_PROVIDER !== undefined
3197
3287
  }));
3198
3288
  return;
3199
3289
  }
@@ -3377,7 +3467,7 @@ var runCli = async (command, raw) => {
3377
3467
  });
3378
3468
  return;
3379
3469
  }
3380
- if (command === "pair" || command === "sessions" || command === "revoke") {
3470
+ if (command === "pair" || command === "sessions" || command === "revoke" || command === "forget") {
3381
3471
  const { configuration: configuration2, relay: relay2 } = await ownerClient();
3382
3472
  if (command === "pair") {
3383
3473
  allowOptions(arguments_, ["client-only", "label"]);
@@ -3398,6 +3488,11 @@ var runCli = async (command, raw) => {
3398
3488
  print(await Effect5.runPromise(relay2.authSessions()));
3399
3489
  return;
3400
3490
  }
3491
+ if (command === "forget") {
3492
+ allowOptions(arguments_, []);
3493
+ print(await Effect5.runPromise(relay2.forgetDevice(Schema7.decodeUnknownSync(DeviceId)(identifier(arguments_, "device id")))));
3494
+ return;
3495
+ }
3401
3496
  allowOptions(arguments_, []);
3402
3497
  print(await Effect5.runPromise(relay2.revokeAuthSession(Schema7.decodeUnknownSync(AuthSessionId)(identifier(arguments_, "session id")))));
3403
3498
  return;
@@ -3916,4 +4011,4 @@ await main().catch((cause) => {
3916
4011
  process.exitCode = 1;
3917
4012
  });
3918
4013
 
3919
- //# debugId=97BAA6242519D1EB64756E2164756E21
4014
+ //# debugId=37D716D68AD41D2A64756E2164756E21