@essentialai/cogent-plugin 3.17.0 → 3.19.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogent",
3
- "version": "3.17.0",
3
+ "version": "3.19.0",
4
4
  "description": "Inter-session communication bridge for Claude Code with Slack integration. Enables CC agents and Slack team members to communicate in real time.",
5
5
  "author": {
6
6
  "name": "Essential AI Solutions",
@@ -192,7 +192,7 @@ Your peer identity: **peerId=\`${peerId}\`**, **label=\`${label}\`**
192
192
  ### On Session Start
193
193
  1. Find your Claude Code session ID:
194
194
  \`\`\`bash
195
- ls -t ~/.claude/projects/$(pwd | sed 's/[^a-zA-Z0-9-]/-/g')/*.jsonl 2>/dev/null | head -1 | xargs -I{} basename {} .jsonl
195
+ ls -t "\${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/projects/$(pwd | sed 's/[^a-zA-Z0-9-]/-/g')/*.jsonl 2>/dev/null | head -1 | xargs -I{} basename {} .jsonl
196
196
  \`\`\`
197
197
  2. Register yourself on the bridge:
198
198
  - Use \`cogent_register_peer\` with peerId="${peerId}", label="${label}"
@@ -1259,8 +1259,8 @@ var init_parseUtil = __esm({
1259
1259
  init_errors();
1260
1260
  init_en();
1261
1261
  makeIssue = (params) => {
1262
- const { data, path: path16, errorMaps, issueData } = params;
1263
- const fullPath = [...path16, ...issueData.path || []];
1262
+ const { data, path: path17, errorMaps, issueData } = params;
1263
+ const fullPath = [...path17, ...issueData.path || []];
1264
1264
  const fullIssue = {
1265
1265
  ...issueData,
1266
1266
  path: fullPath
@@ -1540,11 +1540,11 @@ var init_types = __esm({
1540
1540
  init_parseUtil();
1541
1541
  init_util();
1542
1542
  ParseInputLazyPath = class {
1543
- constructor(parent, value, path16, key) {
1543
+ constructor(parent, value, path17, key) {
1544
1544
  this._cachedPath = [];
1545
1545
  this.parent = parent;
1546
1546
  this.data = value;
1547
- this._path = path16;
1547
+ this._path = path17;
1548
1548
  this._key = key;
1549
1549
  }
1550
1550
  get path() {
@@ -4996,10 +4996,10 @@ function assignProp(target, prop, value) {
4996
4996
  configurable: true
4997
4997
  });
4998
4998
  }
4999
- function getElementAtPath(obj, path16) {
5000
- if (!path16)
4999
+ function getElementAtPath(obj, path17) {
5000
+ if (!path17)
5001
5001
  return obj;
5002
- return path16.reduce((acc, key) => acc?.[key], obj);
5002
+ return path17.reduce((acc, key) => acc?.[key], obj);
5003
5003
  }
5004
5004
  function promiseAllObject(promisesObj) {
5005
5005
  const keys = Object.keys(promisesObj);
@@ -5248,11 +5248,11 @@ function aborted(x, startIndex = 0) {
5248
5248
  }
5249
5249
  return false;
5250
5250
  }
5251
- function prefixIssues(path16, issues) {
5251
+ function prefixIssues(path17, issues) {
5252
5252
  return issues.map((iss) => {
5253
5253
  var _a;
5254
5254
  (_a = iss).path ?? (_a.path = []);
5255
- iss.path.unshift(path16);
5255
+ iss.path.unshift(path17);
5256
5256
  return iss;
5257
5257
  });
5258
5258
  }
@@ -17058,8 +17058,8 @@ var require_utils = __commonJS({
17058
17058
  }
17059
17059
  return ind;
17060
17060
  }
17061
- function removeDotSegments(path16) {
17062
- let input = path16;
17061
+ function removeDotSegments(path17) {
17062
+ let input = path17;
17063
17063
  const output = [];
17064
17064
  let nextSlash = -1;
17065
17065
  let len = 0;
@@ -17258,8 +17258,8 @@ var require_schemes = __commonJS({
17258
17258
  wsComponent.secure = void 0;
17259
17259
  }
17260
17260
  if (wsComponent.resourceName) {
17261
- const [path16, query] = wsComponent.resourceName.split("?");
17262
- wsComponent.path = path16 && path16 !== "/" ? path16 : void 0;
17261
+ const [path17, query] = wsComponent.resourceName.split("?");
17262
+ wsComponent.path = path17 && path17 !== "/" ? path17 : void 0;
17263
17263
  wsComponent.query = query;
17264
17264
  wsComponent.resourceName = void 0;
17265
17265
  }
@@ -21729,8 +21729,8 @@ var require_parseUtil = __commonJS({
21729
21729
  var errors_js_1 = require_errors2();
21730
21730
  var en_js_1 = __importDefault(require_en());
21731
21731
  var makeIssue2 = (params) => {
21732
- const { data, path: path16, errorMaps, issueData } = params;
21733
- const fullPath = [...path16, ...issueData.path || []];
21732
+ const { data, path: path17, errorMaps, issueData } = params;
21733
+ const fullPath = [...path17, ...issueData.path || []];
21734
21734
  const fullIssue = {
21735
21735
  ...issueData,
21736
21736
  path: fullPath
@@ -21884,11 +21884,11 @@ var require_types2 = __commonJS({
21884
21884
  var parseUtil_js_1 = require_parseUtil();
21885
21885
  var util_js_1 = require_util2();
21886
21886
  var ParseInputLazyPath2 = class {
21887
- constructor(parent, value, path16, key) {
21887
+ constructor(parent, value, path17, key) {
21888
21888
  this._cachedPath = [];
21889
21889
  this.parent = parent;
21890
21890
  this.data = value;
21891
- this._path = path16;
21891
+ this._path = path17;
21892
21892
  this._key = key;
21893
21893
  }
21894
21894
  get path() {
@@ -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.17.0") {
26393
- return "3.17.0";
26392
+ if ("3.19.0") {
26393
+ return "3.19.0";
26394
26394
  }
26395
26395
  try {
26396
26396
  const require2 = createRequire(import.meta.url);
@@ -27016,21 +27016,45 @@ var init_peer_registry = __esm({
27016
27016
  }
27017
27017
  });
27018
27018
 
27019
+ // src/services/agent-config.ts
27020
+ import os4 from "node:os";
27021
+ import path8 from "node:path";
27022
+ function claudeConfigDir() {
27023
+ const override = process.env.CLAUDE_CONFIG_DIR?.trim();
27024
+ return override ? override : path8.join(os4.homedir(), ".claude");
27025
+ }
27026
+ function codexHomeDir() {
27027
+ const override = process.env.CODEX_HOME?.trim();
27028
+ return override ? override : path8.join(os4.homedir(), ".codex");
27029
+ }
27030
+ function buildResumeEnv(source, vendorPrefix, preserve) {
27031
+ const keep = new Set(preserve);
27032
+ return Object.fromEntries(
27033
+ Object.entries(source).filter(
27034
+ ([key]) => (!key.startsWith(vendorPrefix) || keep.has(key)) && key !== "MCP_TRANSPORT"
27035
+ )
27036
+ );
27037
+ }
27038
+ var init_agent_config = __esm({
27039
+ "src/services/agent-config.ts"() {
27040
+ "use strict";
27041
+ }
27042
+ });
27043
+
27019
27044
  // src/services/cc-cli.ts
27020
27045
  import { spawn } from "node:child_process";
27021
27046
  import fs7 from "node:fs/promises";
27022
- import os4 from "node:os";
27023
- import path8 from "node:path";
27047
+ import path9 from "node:path";
27024
27048
  async function listCandidates(cwd) {
27025
27049
  try {
27026
27050
  const escapedCwd = cwd.replace(/[^a-zA-Z0-9-]/g, "-");
27027
- const projectDir = path8.join(os4.homedir(), ".claude", "projects", escapedCwd);
27051
+ const projectDir = path9.join(claudeConfigDir(), "projects", escapedCwd);
27028
27052
  const entries = await fs7.readdir(projectDir);
27029
27053
  const jsonlFiles = entries.filter((f) => f.endsWith(".jsonl"));
27030
27054
  return await Promise.all(
27031
27055
  jsonlFiles.map(async (f) => ({
27032
27056
  sessionId: f.replace(".jsonl", ""),
27033
- mtimeMs: (await fs7.stat(path8.join(projectDir, f))).mtimeMs
27057
+ mtimeMs: (await fs7.stat(path9.join(projectDir, f))).mtimeMs
27034
27058
  }))
27035
27059
  );
27036
27060
  } catch {
@@ -27045,9 +27069,8 @@ async function detectCurrentSession(cwd) {
27045
27069
  }
27046
27070
  async function validateSession(sessionId, cwd) {
27047
27071
  const projectHash = cwd.replace(/[^a-zA-Z0-9-]/g, "-");
27048
- const sessionPath = path8.join(
27049
- os4.homedir(),
27050
- ".claude",
27072
+ const sessionPath = path9.join(
27073
+ claudeConfigDir(),
27051
27074
  "projects",
27052
27075
  projectHash,
27053
27076
  `${sessionId}.jsonl`
@@ -27085,11 +27108,7 @@ function execClaude(sessionId, message, cwd, timeoutMs) {
27085
27108
  "-p",
27086
27109
  truncated
27087
27110
  ];
27088
- const cleanEnv = Object.fromEntries(
27089
- Object.entries(process.env).filter(
27090
- ([key]) => !key.startsWith("CLAUDE") && key !== "MCP_TRANSPORT"
27091
- )
27092
- );
27111
+ const cleanEnv = buildResumeEnv(process.env, "CLAUDE", ["CLAUDE_CONFIG_DIR"]);
27093
27112
  cleanEnv.COGENT_CHECK_ON_STOP = "0";
27094
27113
  const child = spawn(config2.COGENT_CLAUDE_PATH, args, {
27095
27114
  cwd,
@@ -27214,6 +27233,7 @@ var init_cc_cli = __esm({
27214
27233
  "src/services/cc-cli.ts"() {
27215
27234
  "use strict";
27216
27235
  init_config();
27236
+ init_agent_config();
27217
27237
  }
27218
27238
  });
27219
27239
 
@@ -27345,14 +27365,14 @@ var init_codex_preflight = __esm({
27345
27365
 
27346
27366
  // src/services/health-check.ts
27347
27367
  import fs9 from "node:fs/promises";
27348
- import path9 from "node:path";
27368
+ import path10 from "node:path";
27349
27369
  import { execFile as execFile3 } from "node:child_process";
27350
27370
  function getStatePath2() {
27351
- return path9.join(getConfig().COGENT_STATE_PATH, "cogent-state.json");
27371
+ return path10.join(getConfig().COGENT_STATE_PATH, "cogent-state.json");
27352
27372
  }
27353
27373
  async function checkStateFile() {
27354
27374
  const statePath = getStatePath2();
27355
- const dir = path9.dirname(statePath);
27375
+ const dir = path10.dirname(statePath);
27356
27376
  try {
27357
27377
  await fs9.access(dir, fs9.constants.R_OK | fs9.constants.W_OK);
27358
27378
  } catch {
@@ -27430,7 +27450,7 @@ async function checkHealth() {
27430
27450
  return {
27431
27451
  healthy,
27432
27452
  mcpServerVersion: SERVER_VERSION,
27433
- statePath: path9.join(config2.COGENT_STATE_PATH, "cogent-state.json"),
27453
+ statePath: path10.join(config2.COGENT_STATE_PATH, "cogent-state.json"),
27434
27454
  claudePath: config2.COGENT_CLAUDE_PATH,
27435
27455
  checks,
27436
27456
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
@@ -27569,7 +27589,7 @@ var init_http_backend = __esm({
27569
27589
  * in cloud mode we ignore it and use this.sessionId (the cloud session).
27570
27590
  */
27571
27591
  async registerPeer(peerId, _sessionId, cwd, label, clientVersion, mode, _channelSessionId, capabilities, workspaceId, threadId) {
27572
- const path16 = PATHS.peers.replace(":sessionId", this.sessionId);
27592
+ const path17 = PATHS.peers.replace(":sessionId", this.sessionId);
27573
27593
  const body = {
27574
27594
  peerId,
27575
27595
  cwd,
@@ -27597,7 +27617,7 @@ var init_http_backend = __esm({
27597
27617
  body.role = roleCap.slice("role:".length);
27598
27618
  }
27599
27619
  }
27600
- return this.http.post(path16, body);
27620
+ return this.http.post(path17, body);
27601
27621
  }
27602
27622
  /**
27603
27623
  * Deregister a peer from the cloud session.
@@ -27609,9 +27629,9 @@ var init_http_backend = __esm({
27609
27629
  * local mail creds. A 404 (peer not found) resolves to `{ removed: false, ... }`, not a throw.
27610
27630
  */
27611
27631
  async deregisterPeer(peerId) {
27612
- const path16 = PATHS.peer.replace(":sessionId", this.sessionId).replace(":peerId", peerId);
27632
+ const path17 = PATHS.peer.replace(":sessionId", this.sessionId).replace(":peerId", peerId);
27613
27633
  try {
27614
- const headers = await this.http.delete(path16, {});
27634
+ const headers = await this.http.delete(path17, {});
27615
27635
  const mailboxDeprovisioned = headers.get(MAILBOX_DEPROVISIONED_HEADER) === "true";
27616
27636
  return { removed: true, mailboxDeprovisioned };
27617
27637
  } catch {
@@ -27632,8 +27652,8 @@ var init_http_backend = __esm({
27632
27652
  * GET /api/sessions/:sessionId/peers
27633
27653
  */
27634
27654
  async listPeers() {
27635
- const path16 = PATHS.peers.replace(":sessionId", this.sessionId);
27636
- const result = await this.http.get(path16);
27655
+ const path17 = PATHS.peers.replace(":sessionId", this.sessionId);
27656
+ const result = await this.http.get(path17);
27637
27657
  return result.peers;
27638
27658
  }
27639
27659
  /**
@@ -27641,8 +27661,8 @@ var init_http_backend = __esm({
27641
27661
  * Calls the lightweight heartbeat endpoint on the cloud relay server.
27642
27662
  */
27643
27663
  async updateLastSeen(peerId) {
27644
- const path16 = PATHS.heartbeat.replace(":sessionId", this.sessionId);
27645
- await this.http.post(path16, { peerId });
27664
+ const path17 = PATHS.heartbeat.replace(":sessionId", this.sessionId);
27665
+ await this.http.post(path17, { peerId });
27646
27666
  }
27647
27667
  /**
27648
27668
  * Record a message in the cloud session.
@@ -27653,7 +27673,7 @@ var init_http_backend = __esm({
27653
27673
  * the input record to construct a full MessageRecord.
27654
27674
  */
27655
27675
  async recordMessage(record2) {
27656
- const path16 = PATHS.messages.replace(":sessionId", this.sessionId);
27676
+ const path17 = PATHS.messages.replace(":sessionId", this.sessionId);
27657
27677
  const body = {
27658
27678
  fromPeerId: record2.fromPeerId,
27659
27679
  toPeerId: record2.toPeerId,
@@ -27665,7 +27685,7 @@ var init_http_backend = __esm({
27665
27685
  if (record2.attachments && record2.attachments.length > 0) {
27666
27686
  body.attachments = record2.attachments;
27667
27687
  }
27668
- const resp = await this.http.post(path16, body);
27688
+ const resp = await this.http.post(path17, body);
27669
27689
  return {
27670
27690
  ...record2,
27671
27691
  id: resp.id,
@@ -27679,7 +27699,7 @@ var init_http_backend = __esm({
27679
27699
  * Supports optional peerId filter and limit (default 300).
27680
27700
  */
27681
27701
  async getHistory(peerId, limit, includeRelayEchoes, metadataOnly, dedupInferredEchoes) {
27682
- const path16 = PATHS.messages.replace(":sessionId", this.sessionId);
27702
+ const path17 = PATHS.messages.replace(":sessionId", this.sessionId);
27683
27703
  const query = {};
27684
27704
  if (peerId) {
27685
27705
  query.peerId = peerId;
@@ -27694,7 +27714,7 @@ var init_http_backend = __esm({
27694
27714
  if (dedupInferredEchoes) {
27695
27715
  query.dedupInferredEchoes = "true";
27696
27716
  }
27697
- const result = await this.http.get(path16, query);
27717
+ const result = await this.http.get(path17, query);
27698
27718
  return result.messages;
27699
27719
  }
27700
27720
  /**
@@ -27705,12 +27725,12 @@ var init_http_backend = __esm({
27705
27725
  * so that get-history shows the actual response (not null).
27706
27726
  */
27707
27727
  async updateMessageResponse(messageId, response, durationMs, pending) {
27708
- const path16 = PATHS.message.replace(":sessionId", this.sessionId).replace(":messageId", messageId);
27728
+ const path17 = PATHS.message.replace(":sessionId", this.sessionId).replace(":messageId", messageId);
27709
27729
  const body = { response, durationMs };
27710
27730
  if (pending === true) {
27711
27731
  body.pending = true;
27712
27732
  }
27713
- await this.http.patch(path16, body);
27733
+ await this.http.patch(path17, body);
27714
27734
  }
27715
27735
  /**
27716
27736
  * Validate a session.
@@ -27852,8 +27872,8 @@ var init_http_client = __esm({
27852
27872
  * Perform an authenticated GET request.
27853
27873
  * Appends query parameters to the URL if provided.
27854
27874
  */
27855
- async get(path16, query) {
27856
- const url = new URL(path16, this.baseUrl);
27875
+ async get(path17, query) {
27876
+ const url = new URL(path17, this.baseUrl);
27857
27877
  if (query) {
27858
27878
  for (const [k, v] of Object.entries(query)) {
27859
27879
  url.searchParams.set(k, v);
@@ -27868,8 +27888,8 @@ var init_http_client = __esm({
27868
27888
  /**
27869
27889
  * Perform an authenticated POST request with a JSON body.
27870
27890
  */
27871
- async post(path16, body) {
27872
- const url = new URL(path16, this.baseUrl);
27891
+ async post(path17, body) {
27892
+ const url = new URL(path17, this.baseUrl);
27873
27893
  const resp = await this.fetchWithTimeout(url, {
27874
27894
  method: "POST",
27875
27895
  headers: this.headers(),
@@ -27887,8 +27907,8 @@ var init_http_client = __esm({
27887
27907
  * Perform an authenticated PATCH request with a JSON body.
27888
27908
  * Used to update existing resources (e.g., message response fields).
27889
27909
  */
27890
- async patch(path16, body) {
27891
- const url = new URL(path16, this.baseUrl);
27910
+ async patch(path17, body) {
27911
+ const url = new URL(path17, this.baseUrl);
27892
27912
  const resp = await this.fetchWithTimeout(url, {
27893
27913
  method: "PATCH",
27894
27914
  headers: this.headers(),
@@ -27913,8 +27933,8 @@ var init_http_client = __esm({
27913
27933
  * "Malformed JSON in request body" 400 from cogent-server <=3.1.2 when
27914
27934
  * any client (including third-party tools) DELETEd a peer without a body.
27915
27935
  */
27916
- async delete(path16, body) {
27917
- const url = new URL(path16, this.baseUrl);
27936
+ async delete(path17, body) {
27937
+ const url = new URL(path17, this.baseUrl);
27918
27938
  const headers = {
27919
27939
  "Authorization": `Bearer ${this.token}`
27920
27940
  };
@@ -27979,6 +27999,9 @@ function isCloudEndpoint(value) {
27979
27999
  function isCloudMode() {
27980
28000
  return _backend instanceof HttpBackend;
27981
28001
  }
28002
+ function isCloudDeferred(endpoint) {
28003
+ return !!endpoint && isCloudEndpoint(endpoint) && !isCloudMode();
28004
+ }
27982
28005
  function createBackend(endpoint, sessionId, token) {
27983
28006
  if (endpoint && isCloudEndpoint(endpoint)) {
27984
28007
  if (!sessionId || !token) {
@@ -32094,14 +32117,14 @@ var init_ws_client = __esm({
32094
32117
  if (this.pollTimer) return;
32095
32118
  const poll = async () => {
32096
32119
  try {
32097
- const path16 = `/api/sessions/${this.opts.sessionId}/poll`;
32120
+ const path17 = `/api/sessions/${this.opts.sessionId}/poll`;
32098
32121
  const query = {
32099
32122
  peerId: this.opts.peerId
32100
32123
  };
32101
32124
  if (this.lastMessageId) {
32102
32125
  query.lastMessageId = this.lastMessageId;
32103
32126
  }
32104
- const result = await this.opts.http.get(path16, query);
32127
+ const result = await this.opts.http.get(path17, query);
32105
32128
  if (result.messages && result.messages.length > 0) {
32106
32129
  this.opts.onMessages(result.messages);
32107
32130
  this.lastMessageId = result.messages[result.messages.length - 1].id;
@@ -32160,7 +32183,7 @@ var init_cloud = __esm({
32160
32183
  import { spawn as spawn2 } from "node:child_process";
32161
32184
  import fs10 from "node:fs/promises";
32162
32185
  import os5 from "node:os";
32163
- import path10 from "node:path";
32186
+ import path11 from "node:path";
32164
32187
  import { randomUUID } from "node:crypto";
32165
32188
  import { createReadStream } from "node:fs";
32166
32189
  import { createInterface as createInterface2 } from "node:readline";
@@ -32188,7 +32211,7 @@ function execCodex(sessionId, message, cwd, timeoutMs) {
32188
32211
  const config2 = getConfig();
32189
32212
  const effectiveTimeout = timeoutMs ?? config2.COGENT_TIMEOUT_MS;
32190
32213
  const truncated = config2.COGENT_CHAR_LIMIT > 0 && message.length > config2.COGENT_CHAR_LIMIT ? message.slice(0, config2.COGENT_CHAR_LIMIT) + "\n...[truncated]" : message;
32191
- const lastMsgFile = path10.join(os5.tmpdir(), `cogent-codex-${randomUUID()}.txt`);
32214
+ const lastMsgFile = path11.join(os5.tmpdir(), `cogent-codex-${randomUUID()}.txt`);
32192
32215
  const args = [
32193
32216
  "exec",
32194
32217
  "resume",
@@ -32199,11 +32222,7 @@ function execCodex(sessionId, message, cwd, timeoutMs) {
32199
32222
  lastMsgFile,
32200
32223
  truncated
32201
32224
  ];
32202
- const cleanEnv = Object.fromEntries(
32203
- Object.entries(process.env).filter(
32204
- ([key]) => !key.startsWith("CODEX") && key !== "MCP_TRANSPORT"
32205
- )
32206
- );
32225
+ const cleanEnv = buildResumeEnv(process.env, "CODEX", ["CODEX_HOME"]);
32207
32226
  cleanEnv.COGENT_CHECK_ON_STOP = "0";
32208
32227
  const child = spawn2(config2.COGENT_CODEX_PATH, args, {
32209
32228
  cwd,
@@ -32295,7 +32314,7 @@ async function listRolloutFiles(root) {
32295
32314
  return;
32296
32315
  }
32297
32316
  for (const e of entries) {
32298
- const full = path10.join(dir, e.name);
32317
+ const full = path11.join(dir, e.name);
32299
32318
  if (e.isDirectory()) await walk(full);
32300
32319
  else if (e.isFile() && e.name.endsWith(".jsonl")) out.push(full);
32301
32320
  }
@@ -32327,10 +32346,10 @@ async function readSessionMeta(file) {
32327
32346
  }
32328
32347
  }
32329
32348
  function codexSessionsRoot() {
32330
- return path10.join(os5.homedir(), ".codex", "sessions");
32349
+ return path11.join(codexHomeDir(), "sessions");
32331
32350
  }
32332
32351
  async function cwdCanonicals(cwd) {
32333
- const resolved = path10.resolve(cwd);
32352
+ const resolved = path11.resolve(cwd);
32334
32353
  const forms = /* @__PURE__ */ new Set([resolved]);
32335
32354
  try {
32336
32355
  forms.add(await fs10.realpath(resolved));
@@ -32339,7 +32358,7 @@ async function cwdCanonicals(cwd) {
32339
32358
  return forms;
32340
32359
  }
32341
32360
  function metaCwdMatches(metaCwd, forms) {
32342
- return forms.has(path10.resolve(metaCwd));
32361
+ return forms.has(path11.resolve(metaCwd));
32343
32362
  }
32344
32363
  async function detectCurrentCodexSession(cwd) {
32345
32364
  try {
@@ -32398,6 +32417,7 @@ var init_codex_cli = __esm({
32398
32417
  "src/services/codex-cli.ts"() {
32399
32418
  "use strict";
32400
32419
  init_config();
32420
+ init_agent_config();
32401
32421
  sandboxOverride = null;
32402
32422
  SANDBOX_FAILURE_RE = /bwrap:|setting up uid ?map|\/proc\/self\/(uid|gid)_map|newuidmap|user namespaces?|RTM_NEWADDR|unshare[^\n]*(Operation not permitted|Permission denied)|clone3?[^\n]*(EPERM|not permitted)/i;
32403
32423
  }
@@ -33599,11 +33619,12 @@ __export(startup_exports, {
33599
33619
  cloudInbox: () => cloudInbox,
33600
33620
  cloudWsClient: () => cloudWsClient,
33601
33621
  reinitCloudBackend: () => reinitCloudBackend,
33622
+ runPreflights: () => runPreflights,
33602
33623
  runStartup: () => runStartup,
33603
33624
  triggerReRegistration: () => triggerReRegistration
33604
33625
  });
33605
33626
  import os6 from "node:os";
33606
- import path11 from "node:path";
33627
+ import path12 from "node:path";
33607
33628
  import fs11 from "node:fs/promises";
33608
33629
  import readline2 from "node:readline";
33609
33630
  import { execFile as execFile5 } from "node:child_process";
@@ -33654,7 +33675,7 @@ First run detected. Where should cogent-bridge store its data?
33654
33675
  }
33655
33676
  async function validateStateDir(statePath) {
33656
33677
  await fs11.mkdir(statePath, { recursive: true });
33657
- const testFile = path11.join(statePath, ".write-test");
33678
+ const testFile = path12.join(statePath, ".write-test");
33658
33679
  try {
33659
33680
  await fs11.writeFile(testFile, "test", "utf-8");
33660
33681
  await fs11.unlink(testFile);
@@ -33803,10 +33824,10 @@ async function runStartup() {
33803
33824
  if (envStatePath) {
33804
33825
  statePath = envStatePath;
33805
33826
  } else {
33806
- const defaultPath = path11.join(os6.homedir(), ".cogent");
33827
+ const defaultPath = path12.join(os6.homedir(), ".cogent");
33807
33828
  statePath = await firstRunPrompt(defaultPath);
33808
33829
  }
33809
- if (!envStatePath && statePath !== path11.join(os6.homedir(), ".cogent")) {
33830
+ if (!envStatePath && statePath !== path12.join(os6.homedir(), ".cogent")) {
33810
33831
  process.env.COGENT_STATE_PATH = statePath;
33811
33832
  } else if (!envStatePath) {
33812
33833
  process.env.COGENT_STATE_PATH = statePath;
@@ -33826,7 +33847,8 @@ async function runStartup() {
33826
33847
  } else {
33827
33848
  try {
33828
33849
  const resolveResp = await fetch(
33829
- `${effectiveEndpoint}/api/sessions/resolve/${encodeURIComponent(effectiveSessionId)}`
33850
+ `${effectiveEndpoint}/api/sessions/resolve/${encodeURIComponent(effectiveSessionId)}`,
33851
+ { signal: AbortSignal.timeout(2500) }
33830
33852
  );
33831
33853
  if (resolveResp.ok) {
33832
33854
  const resolved = await resolveResp.json();
@@ -33883,7 +33905,7 @@ async function runStartup() {
33883
33905
  }
33884
33906
  initLogger(
33885
33907
  config2.COGENT_LOG_LEVEL,
33886
- path11.join(config2.COGENT_STATE_PATH, "logs")
33908
+ path12.join(config2.COGENT_STATE_PATH, "logs")
33887
33909
  );
33888
33910
  if (isCloud && effectiveSessionId && effectiveToken) {
33889
33911
  cloudInbox = new MessageInbox();
@@ -33904,6 +33926,13 @@ async function runStartup() {
33904
33926
  await validateStateDir(config2.COGENT_STATE_PATH);
33905
33927
  await checkClaudeCli2(config2.COGENT_CLAUDE_PATH);
33906
33928
  }
33929
+ const mode = isCloud ? "cloud" : "local";
33930
+ logger.info(
33931
+ `Startup complete. Mode: ${mode}, State: ${config2.COGENT_STATE_PATH}, Log level: ${config2.COGENT_LOG_LEVEL}`
33932
+ );
33933
+ }
33934
+ async function runPreflights() {
33935
+ const config2 = getConfig();
33907
33936
  if (config2.COGENT_PLATFORM === "codex") {
33908
33937
  await preflightCodex(config2.COGENT_CODEX_PATH);
33909
33938
  const sandbox = await preflightCodexSandbox(config2);
@@ -33913,10 +33942,6 @@ async function runStartup() {
33913
33942
  } else {
33914
33943
  await preflightClaude(config2.COGENT_CLAUDE_PATH);
33915
33944
  }
33916
- const mode = isCloud ? "cloud" : "local";
33917
- logger.info(
33918
- `Startup complete. Mode: ${mode}, State: ${config2.COGENT_STATE_PATH}, Log level: ${config2.COGENT_LOG_LEVEL}`
33919
- );
33920
33945
  }
33921
33946
  var UUID_V4_RE, execFileAsync3, PERSIST_PATH, legacyWarnEmitted, cloudWsClient, cloudInbox, cloudHttpClient, reRegistrationInProgress;
33922
33947
  var init_startup = __esm({
@@ -33940,7 +33965,7 @@ var init_startup = __esm({
33940
33965
  init_auto_relay();
33941
33966
  UUID_V4_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
33942
33967
  execFileAsync3 = promisify4(execFile5);
33943
- PERSIST_PATH = path11.join(os6.homedir(), ".cogent-config.json");
33968
+ PERSIST_PATH = path12.join(os6.homedir(), ".cogent-config.json");
33944
33969
  legacyWarnEmitted = false;
33945
33970
  cloudWsClient = null;
33946
33971
  cloudInbox = null;
@@ -33952,11 +33977,11 @@ var init_startup = __esm({
33952
33977
  // src/cloud/mail-credential-store.ts
33953
33978
  import crypto3 from "node:crypto";
33954
33979
  import fs12 from "node:fs/promises";
33955
- import path12 from "node:path";
33980
+ import path13 from "node:path";
33956
33981
  import os7 from "node:os";
33957
33982
  function defaultMailCredentialPath(cwd = process.cwd()) {
33958
- const hash = crypto3.createHash("sha256").update(path12.resolve(cwd)).digest("hex").slice(0, 16);
33959
- return path12.join(os7.homedir(), ".cogent", "mail-credentials", `${hash}.json`);
33983
+ const hash = crypto3.createHash("sha256").update(path13.resolve(cwd)).digest("hex").slice(0, 16);
33984
+ return path13.join(os7.homedir(), ".cogent", "mail-credentials", `${hash}.json`);
33960
33985
  }
33961
33986
  function resolveMailCredentialPath(credentialPath) {
33962
33987
  if (credentialPath) return credentialPath;
@@ -33974,7 +33999,7 @@ async function loadMailCredentials(credentialPath) {
33974
33999
  }
33975
34000
  async function saveMailCredentials(creds, credentialPath) {
33976
34001
  const filePath = resolveMailCredentialPath(credentialPath);
33977
- await fs12.mkdir(path12.dirname(filePath), { recursive: true, mode: 448 });
34002
+ await fs12.mkdir(path13.dirname(filePath), { recursive: true, mode: 448 });
33978
34003
  await fs12.writeFile(filePath, JSON.stringify(creds, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
33979
34004
  await fs12.chmod(filePath, 384);
33980
34005
  }
@@ -34053,11 +34078,11 @@ function registerRegisterPeerTool(server) {
34053
34078
  const hasCloudEndpointConfig = config2.COGENT_ENDPOINT && isCloudEndpoint(config2.COGENT_ENDPOINT);
34054
34079
  let sessionCreated = false;
34055
34080
  let cloudSessionId;
34081
+ let cloudToken;
34056
34082
  let autoSecret;
34057
34083
  if (hasCloudEndpointConfig && config2.COGENT_ENDPOINT) {
34058
34084
  let endpoint = config2.COGENT_ENDPOINT;
34059
34085
  cloudSessionId = config2.COGENT_SESSION_ID;
34060
- let cloudToken;
34061
34086
  if (!cloudSessionId) {
34062
34087
  const trustPersisted = hasJoinedInProcess() || process.env.COGENT_TRUST_PERSISTED_CREDENTIALS === "1";
34063
34088
  if (trustPersisted) {
@@ -34112,6 +34137,15 @@ function registerRegisterPeerTool(server) {
34112
34137
  );
34113
34138
  }
34114
34139
  }
34140
+ if (!cloudToken && isCloudDeferred(config2.COGENT_ENDPOINT)) {
34141
+ return errorResult(
34142
+ new BridgeError(
34143
+ "JOIN_NOT_CONFIRMED" /* JOIN_NOT_CONFIRMED */,
34144
+ "Cloud endpoint + COGENT_SESSION_ID are configured but this bridge has not joined the channel (no session token \u2014 the relay was unreachable or the session label did not resolve at startup). cogent_register_peer will NOT register against local state (that would leave you on no channel while other local agents' data sits on this host).",
34145
+ "Call cogent_join_session with the channel name + secret (+ Org_ID for Team channels) and confirm it returns success, then retry cogent_register_peer."
34146
+ )
34147
+ );
34148
+ }
34115
34149
  const backend = getBackend();
34116
34150
  const existing = await backend.getPeer(peerId);
34117
34151
  const channelSessionId = sessionId;
@@ -34297,6 +34331,13 @@ function registerSendMessageTool(server) {
34297
34331
  },
34298
34332
  async ({ fromPeerId, toPeerId, message }) => {
34299
34333
  try {
34334
+ if (isCloudDeferred(getConfig().COGENT_ENDPOINT)) {
34335
+ return successResult({
34336
+ success: false,
34337
+ notJoined: true,
34338
+ error: "Not connected to a channel yet \u2014 call cogent_join_session (or cogent_register_peer) first. Message not sent (cross-channel send is blocked until you join)."
34339
+ });
34340
+ }
34300
34341
  const backend = getBackend();
34301
34342
  const from = await backend.getPeer(fromPeerId);
34302
34343
  if (!from) {
@@ -35014,6 +35055,14 @@ function registerListPeersTool(server) {
35014
35055
  },
35015
35056
  async () => {
35016
35057
  try {
35058
+ if (isCloudDeferred(getConfig().COGENT_ENDPOINT)) {
35059
+ return successResult({
35060
+ peers: [],
35061
+ count: 0,
35062
+ notJoined: true,
35063
+ hint: "Not connected to a channel yet \u2014 call cogent_join_session (or cogent_register_peer) first. Local peers are withheld to prevent cross-channel disclosure."
35064
+ });
35065
+ }
35017
35066
  const backend = getBackend();
35018
35067
  const peers = await backend.listPeers();
35019
35068
  const staleTimeout = getConfig().COGENT_STALE_TIMEOUT_MS;
@@ -35078,6 +35127,16 @@ function registerGetHistoryTool(server) {
35078
35127
  },
35079
35128
  async ({ peerId, limit, includeRelayEchoes, metadataOnly, dedupInferredEchoes }) => {
35080
35129
  try {
35130
+ if (isCloudDeferred(getConfig().COGENT_ENDPOINT)) {
35131
+ return successResult({
35132
+ messages: [],
35133
+ count: 0,
35134
+ truncated: false,
35135
+ totalAvailable: 0,
35136
+ notJoined: true,
35137
+ hint: "Not connected to a channel yet \u2014 call cogent_join_session (or cogent_register_peer) first. Local history is withheld to prevent cross-channel disclosure."
35138
+ });
35139
+ }
35081
35140
  const backend = getBackend();
35082
35141
  const messages = await backend.getHistory(
35083
35142
  peerId,
@@ -35114,6 +35173,7 @@ var init_get_history = __esm({
35114
35173
  "use strict";
35115
35174
  import_zod12 = __toESM(require_zod(), 1);
35116
35175
  init_backend();
35176
+ init_config();
35117
35177
  init_errors4();
35118
35178
  init_logger();
35119
35179
  MAX_RESULT_CHARS = 5e4;
@@ -35139,6 +35199,14 @@ function registerDeregisterPeerTool(server) {
35139
35199
  },
35140
35200
  async ({ peerId }) => {
35141
35201
  try {
35202
+ if (isCloudDeferred(getConfig().COGENT_ENDPOINT)) {
35203
+ return successResult({
35204
+ success: false,
35205
+ notJoined: true,
35206
+ removed: false,
35207
+ message: "Not connected to a channel yet \u2014 call cogent_join_session (or cogent_register_peer) first. Nothing to deregister."
35208
+ });
35209
+ }
35142
35210
  const backend = getBackend();
35143
35211
  const { removed, mailboxDeprovisioned } = await backend.deregisterPeer(peerId);
35144
35212
  if (removed) heartbeat.stop();
@@ -35167,6 +35235,7 @@ var init_deregister_peer = __esm({
35167
35235
  "use strict";
35168
35236
  import_zod13 = __toESM(require_zod(), 1);
35169
35237
  init_backend();
35238
+ init_config();
35170
35239
  init_errors4();
35171
35240
  init_logger();
35172
35241
  init_heartbeat();
@@ -35640,12 +35709,12 @@ var init_setup_mail = __esm({
35640
35709
 
35641
35710
  // src/mail/mail-sender.ts
35642
35711
  import fs13 from "node:fs/promises";
35643
- import path13 from "node:path";
35712
+ import path14 from "node:path";
35644
35713
  async function buildAndSendMail(sender, creds, params) {
35645
35714
  const attachments = [];
35646
35715
  for (const p of params.attachmentPaths ?? []) {
35647
35716
  const content = await fs13.readFile(p);
35648
- attachments.push({ filename: path13.basename(p), content });
35717
+ attachments.push({ filename: path14.basename(p), content });
35649
35718
  }
35650
35719
  const { messageId } = await sender.send({
35651
35720
  from: creds.address,
@@ -35774,14 +35843,14 @@ var init_send_mail = __esm({
35774
35843
 
35775
35844
  // src/mail/mail-fetcher.ts
35776
35845
  import fs14 from "node:fs/promises";
35777
- import path14 from "node:path";
35846
+ import path15 from "node:path";
35778
35847
  async function saveAttachments(attachments, downloadDir) {
35779
35848
  if (attachments.length === 0) return [];
35780
35849
  await fs14.mkdir(downloadDir, { recursive: true });
35781
35850
  const saved = [];
35782
35851
  for (const a of attachments) {
35783
- const name = path14.basename(a.filename) || "attachment";
35784
- const savedPath = path14.join(downloadDir, name);
35852
+ const name = path15.basename(a.filename) || "attachment";
35853
+ const savedPath = path15.join(downloadDir, name);
35785
35854
  await fs14.writeFile(savedPath, a.content);
35786
35855
  saved.push({ filename: name, savedPath, size: a.content.length });
35787
35856
  }
@@ -35914,7 +35983,7 @@ var init_mail_fetcher = __esm({
35914
35983
 
35915
35984
  // src/tools/fetch-mail.ts
35916
35985
  import os8 from "node:os";
35917
- import path15 from "node:path";
35986
+ import path16 from "node:path";
35918
35987
  function registerFetchMailTool(server, deps = {}) {
35919
35988
  const makeFetcher = deps.fetcherFactory ?? ((creds) => new ImapflowMailFetcher(creds));
35920
35989
  server.registerTool(
@@ -35976,7 +36045,7 @@ var init_fetch_mail = __esm({
35976
36045
  init_mail_fetcher();
35977
36046
  init_auth_error();
35978
36047
  init_validate();
35979
- DEFAULT_DOWNLOAD_DIR = path15.join(os8.homedir(), ".cogent", "mail-downloads");
36048
+ DEFAULT_DOWNLOAD_DIR = path16.join(os8.homedir(), ".cogent", "mail-downloads");
35980
36049
  }
35981
36050
  });
35982
36051
 
@@ -36115,6 +36184,11 @@ async function main() {
36115
36184
  `${SERVER_NAME} v${SERVER_VERSION} running on stdio
36116
36185
  `
36117
36186
  );
36187
+ void runPreflights().catch((err) => {
36188
+ logger.warn(
36189
+ `Preflight error (non-fatal): ${err instanceof Error ? err.message : String(err)}`
36190
+ );
36191
+ });
36118
36192
  void checkForUpdate(SERVER_VERSION).then((nudge) => {
36119
36193
  setLastNudge(nudge);
36120
36194
  if (nudge) process.stderr.write(`${nudge}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@essentialai/cogent-plugin",
3
- "version": "3.17.0",
3
+ "version": "3.19.0",
4
4
  "description": "Cogent — Claude Code plugin (skills + slash-commands + MCP server) for the cross-agent comms fabric.",
5
5
  "author": { "name": "Essential AI Solutions Ltd.", "url": "https://essentialai.uk" },
6
6
  "homepage": "https://cogent.tools",