@essentialai/cogent-bridge-bundled 3.23.9 โ†’ 3.24.0

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.
Files changed (2) hide show
  1. package/cogent-bridge.mjs +202 -3
  2. package/package.json +1 -1
package/cogent-bridge.mjs CHANGED
@@ -26389,8 +26389,8 @@ var init_stdio2 = __esm({
26389
26389
  // src/constants.ts
26390
26390
  import { createRequire } from "node:module";
26391
26391
  function resolveVersion() {
26392
- if ("3.23.9") {
26393
- return "3.23.9";
26392
+ if ("3.24.0") {
26393
+ return "3.24.0";
26394
26394
  }
26395
26395
  try {
26396
26396
  const require2 = createRequire(import.meta.url);
@@ -35122,6 +35122,113 @@ var init_auto_relay = __esm({
35122
35122
  }
35123
35123
  });
35124
35124
 
35125
+ // src/services/peer-presence.ts
35126
+ function autoPresenceEnabled(env = process.env) {
35127
+ const v = env.COGENT_AUTO_PRESENCE;
35128
+ if (v === void 0 || v === "") return true;
35129
+ return !/^(0|false|no|off)$/i.test(v.trim());
35130
+ }
35131
+ async function restorePresence(deps) {
35132
+ try {
35133
+ if (!deps.isCloudConfigured()) {
35134
+ return { state: "local", restored: false, detail: "local mode \u2014 presence does not apply" };
35135
+ }
35136
+ if (deps.alreadyRegisteredInProcess()) {
35137
+ return { state: "online", restored: false, detail: "registered by this process" };
35138
+ }
35139
+ const creds = await deps.loadCredentials();
35140
+ if (!creds || !creds.endpoint || !creds.sessionId || !creds.token) {
35141
+ return {
35142
+ state: "deferred",
35143
+ restored: false,
35144
+ detail: "no stored channel credentials for this working directory \u2014 join a channel first"
35145
+ };
35146
+ }
35147
+ if (!creds.peerId) {
35148
+ return {
35149
+ state: "deferred",
35150
+ restored: false,
35151
+ detail: "channel credentials exist but name no peer \u2014 nothing was registered here"
35152
+ };
35153
+ }
35154
+ const peerId = creds.peerId;
35155
+ if (deps.peerAlreadyServed(peerId)) {
35156
+ return {
35157
+ state: "online",
35158
+ restored: false,
35159
+ detail: `peer '${peerId}' is already served by a live bridge for this working directory`
35160
+ };
35161
+ }
35162
+ if (!autoPresenceEnabled(deps.env ?? process.env)) {
35163
+ return {
35164
+ state: "offline",
35165
+ restored: false,
35166
+ detail: `peer '${peerId}' is not registered and COGENT_AUTO_PRESENCE is off \u2014 this agent is absent from its channel`
35167
+ };
35168
+ }
35169
+ await deps.goOnline({
35170
+ peerId,
35171
+ endpoint: creds.endpoint,
35172
+ sessionId: creds.sessionId,
35173
+ token: creds.token,
35174
+ cwd: deps.cwd(),
35175
+ // ๐Ÿ”ด THE PEER'S DISPLAY LABEL IS NOT PERSISTED ANYWHERE โ€” only the CHANNEL's is,
35176
+ // in credentials.label (create-session.ts writes `label: data.label`; join-session
35177
+ // writes the resolved channel label). Using that would label the agent after the
35178
+ // channel: a restore once put "paymentorchestrator" beside a sibling called "POFE".
35179
+ // peerId is the one identifier we hold that genuinely names this agent. The
35180
+ // operator's chosen label returns on the next cogent_register_peer, which carries it.
35181
+ label: peerId,
35182
+ // ๐Ÿ”ด WITHOUT THIS THE RESTORE CANNOT RECLAIM ITS OWN PEER. A re-join issues a NEW
35183
+ // token, and AUD-003 ownership is proven by the token that CREATED the peer or by
35184
+ // the secret issued with it. Omitting it means an entry owned by an earlier token
35185
+ // answers PEER_NOT_YOURS and the agent stays offline โ€” precisely the state this
35186
+ // module exists to leave. The secret is in the credential file; send it.
35187
+ peerSecret: creds.peerSecret
35188
+ });
35189
+ return {
35190
+ state: "online",
35191
+ restored: true,
35192
+ peerId,
35193
+ // Says what THIS process did. Whether the relay now lists the peer is the relay's
35194
+ // state, and asserting it from here would be a success nobody measured.
35195
+ detail: `re-registered peer '${peerId}' from stored credentials`
35196
+ };
35197
+ } catch (err) {
35198
+ const reason = err instanceof Error ? err.message : String(err);
35199
+ return {
35200
+ state: "offline",
35201
+ restored: false,
35202
+ detail: `presence restore failed: ${reason}`
35203
+ };
35204
+ }
35205
+ }
35206
+ function setPresence(outcome) {
35207
+ lastPresence = outcome;
35208
+ }
35209
+ function getPresence() {
35210
+ return lastPresence;
35211
+ }
35212
+ function logPresence(outcome) {
35213
+ if (outcome.state === "online" && outcome.restored) {
35214
+ logger.info(
35215
+ `Presence: offline -> online \u2014 ${outcome.detail}. This agent is addressable on its channel again, and leftover bridges for this checkout are now reapable.`
35216
+ );
35217
+ } else if (outcome.state === "offline") {
35218
+ logger.warn(`Presence: OFFLINE \u2014 ${outcome.detail}.`);
35219
+ } else {
35220
+ logger.debug(`Presence: ${outcome.state} \u2014 ${outcome.detail}.`);
35221
+ }
35222
+ }
35223
+ var lastPresence;
35224
+ var init_peer_presence = __esm({
35225
+ "src/services/peer-presence.ts"() {
35226
+ "use strict";
35227
+ init_logger();
35228
+ lastPresence = null;
35229
+ }
35230
+ });
35231
+
35125
35232
  // src/services/heartbeat.ts
35126
35233
  var HeartbeatService, heartbeat;
35127
35234
  var init_heartbeat = __esm({
@@ -35353,8 +35460,10 @@ __export(startup_exports, {
35353
35460
  cloudWsClient: () => cloudWsClient,
35354
35461
  hasPendingLabelResolve: () => hasPendingLabelResolve,
35355
35462
  isCloudMode: () => isCloudMode2,
35463
+ presenceRegisterArgs: () => presenceRegisterArgs,
35356
35464
  reinitCloudBackend: () => reinitCloudBackend,
35357
35465
  resolvePendingLabel: () => resolvePendingLabel,
35466
+ restorePeerPresence: () => restorePeerPresence,
35358
35467
  runPreflights: () => runPreflights,
35359
35468
  runStartup: () => runStartup,
35360
35469
  setInboxNotifier: () => setInboxNotifier,
@@ -35485,6 +35594,58 @@ async function triggerReRegistration() {
35485
35594
  reRegistrationInProgress = false;
35486
35595
  }
35487
35596
  }
35597
+ function presenceRegisterArgs(p) {
35598
+ return [
35599
+ p.peerId,
35600
+ p.sessionId,
35601
+ p.cwd,
35602
+ p.label,
35603
+ CLIENT_VERSION,
35604
+ "agent",
35605
+ void 0,
35606
+ // channelSessionId โ€” not tracked on a presence restore
35607
+ void 0,
35608
+ // capabilities โ€” likewise
35609
+ deriveWorkspaceId(p.cwd),
35610
+ p.sessionId,
35611
+ // threadId
35612
+ p.peerSecret
35613
+ // AUD-003 ownership proof โ€” reclaims a peer owned by an earlier token
35614
+ ];
35615
+ }
35616
+ async function restorePeerPresence() {
35617
+ const outcome = await restorePresence({
35618
+ // The endpoint being a relay URL is what makes presence meaningful. We deliberately do
35619
+ // NOT gate on the active backend being the cloud one: at startup it is still the
35620
+ // deferred FileBackend placeholder, and gating on it made this whole path inert
35621
+ // (measured: "skipped: not-cloud-mode" with valid credentials on disk).
35622
+ isCloudConfigured: () => {
35623
+ const ep = getConfig().COGENT_ENDPOINT;
35624
+ return !!ep && isCloudEndpoint(ep);
35625
+ },
35626
+ alreadyRegisteredInProcess: () => autoRelay.getDiagnostics().registered,
35627
+ peerAlreadyServed: (peerId) => {
35628
+ try {
35629
+ return listLiveBridges(process.cwd(), peerId).some((b) => b.pid !== process.pid);
35630
+ } catch {
35631
+ return false;
35632
+ }
35633
+ },
35634
+ loadCredentials: () => loadCredentials(),
35635
+ cwd: () => process.cwd(),
35636
+ goOnline: async ({ peerId, endpoint, sessionId, token, cwd, label, peerSecret }) => {
35637
+ await reinitCloudBackend(endpoint, sessionId, token);
35638
+ const backend = getBackend();
35639
+ await backend.registerPeer(...presenceRegisterArgs({ peerId, sessionId, cwd, label, peerSecret }));
35640
+ autoRelay.setLocalPeer(peerId, sessionId, cwd, "agent", label, sessionId);
35641
+ if (cloudWsClient) cloudWsClient.setPeerId(peerId);
35642
+ heartbeat.restart();
35643
+ }
35644
+ });
35645
+ setPresence(outcome);
35646
+ logPresence(outcome);
35647
+ return outcome;
35648
+ }
35488
35649
  function createCloudWsClient(endpoint, sessionId, token, http, inbox, pollIntervalMs) {
35489
35650
  const client = new CloudWsClient({
35490
35651
  endpoint,
@@ -35736,6 +35897,8 @@ var init_startup = __esm({
35736
35897
  init_cloud();
35737
35898
  init_http_client();
35738
35899
  init_auto_relay();
35900
+ init_peer_presence();
35901
+ init_wake_ownership();
35739
35902
  init_heartbeat();
35740
35903
  init_codex_preflight();
35741
35904
  init_codex_cli();
@@ -37113,6 +37276,18 @@ function registerDeregisterPeerTool(server) {
37113
37276
  logger.warn("failed to clear local mail credentials after deprovision", { error: err });
37114
37277
  }
37115
37278
  }
37279
+ if (removed) {
37280
+ try {
37281
+ const creds = await loadCredentials();
37282
+ if (creds?.peerId === peerId) {
37283
+ const { peerId: _dropped, peerSecret: _secret, ...rest } = creds;
37284
+ await saveCredentials({ ...rest, savedAt: (/* @__PURE__ */ new Date()).toISOString() });
37285
+ logger.info("cleared stored peerId after deregister", { peerId });
37286
+ }
37287
+ } catch (err) {
37288
+ logger.warn("failed to clear stored peerId after deregister", { error: err });
37289
+ }
37290
+ }
37116
37291
  return successResult({
37117
37292
  success: removed,
37118
37293
  message: removed ? `Peer '${peerId}' deregistered` : `Peer '${peerId}' was not registered`
@@ -37135,6 +37310,7 @@ var init_deregister_peer = __esm({
37135
37310
  init_logger();
37136
37311
  init_heartbeat();
37137
37312
  init_mail_credential_store();
37313
+ init_credential_store();
37138
37314
  }
37139
37315
  });
37140
37316
 
@@ -37238,7 +37414,24 @@ function registerHealthCheckTool(server) {
37238
37414
  // never has an upstream relay version to report).
37239
37415
  ...cloud ? { wsHealth, relayVersion, deliveryPath, lastWsError: delivery?.lastWsError ?? null } : {}
37240
37416
  },
37241
- autoRelay: autoRelay.getDiagnostics()
37417
+ autoRelay: autoRelay.getDiagnostics(),
37418
+ // PRESENCE โ€” the agent's own view of whether it is IN its channel, so it can
37419
+ // answer "am I reachable?" without inferring it from transport internals.
37420
+ // "online" registered ยท "offline" owns a peer but is not registered (nobody can
37421
+ // reach it) ยท "deferred" never joined ยท "local" no relay.
37422
+ // services/peer-presence.ts carries the vocabulary and how each state arises.
37423
+ presence: (() => {
37424
+ const p = getPresence();
37425
+ if (!p) {
37426
+ return { state: "unknown", detail: "presence has not been evaluated yet" };
37427
+ }
37428
+ return {
37429
+ state: p.state,
37430
+ restored: p.restored,
37431
+ detail: p.detail,
37432
+ ..."peerId" in p ? { peerId: p.peerId } : {}
37433
+ };
37434
+ })()
37242
37435
  };
37243
37436
  return successResult(enriched);
37244
37437
  } catch (err) {
@@ -37258,6 +37451,7 @@ var init_health_check2 = __esm({
37258
37451
  init_errors4();
37259
37452
  init_logger();
37260
37453
  init_auto_relay();
37454
+ init_peer_presence();
37261
37455
  }
37262
37456
  });
37263
37457
 
@@ -94019,6 +94213,11 @@ async function main() {
94019
94213
  `Preflight error (non-fatal): ${err instanceof Error ? err.message : String(err)}`
94020
94214
  );
94021
94215
  });
94216
+ void restorePeerPresence().catch((err) => {
94217
+ logger.warn(
94218
+ `Presence restore error (non-fatal): ${err instanceof Error ? err.message : String(err)}`
94219
+ );
94220
+ });
94022
94221
  startUpdateCheckLoop(SERVER_VERSION);
94023
94222
  logger.info(
94024
94223
  "Server ready. Tools: cogent_register_peer, cogent_deregister_peer, cogent_send_message, cogent_list_peers, cogent_get_history, cogent_health_check, cogent_create_session, cogent_join_session"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@essentialai/cogent-bridge-bundled",
3
- "version": "3.23.9",
3
+ "version": "3.24.0",
4
4
  "description": "Zero-dependency, pre-bundled Cogent MCP bridge โ€” a single self-contained file for fast cold `npx` startup (used by the Codex plugin, whose MCP startup window is short). Functionally identical to @essentialai/cogent-bridge; carries no npm dependencies so `npx` skips dependency install.",
5
5
  "type": "module",
6
6
  "bin": {