@raysonmeng/agentbridge 0.1.2 → 0.1.4

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.
@@ -12,7 +12,7 @@
12
12
  {
13
13
  "name": "agentbridge",
14
14
  "description": "Bridge Claude Code and Codex through a shared daemon, push channel delivery, and reply/get_messages tools.",
15
- "version": "0.1.2",
15
+ "version": "0.1.4",
16
16
  "author": {
17
17
  "name": "AgentBridge Contributors",
18
18
  "email": "raysonmeng@qq.com"
package/dist/cli.js CHANGED
@@ -1012,7 +1012,7 @@ var init_kill = __esm(() => {
1012
1012
  var require_package = __commonJS((exports, module) => {
1013
1013
  module.exports = {
1014
1014
  name: "@raysonmeng/agentbridge",
1015
- version: "0.1.2",
1015
+ version: "0.1.4",
1016
1016
  description: "Bridge between Claude Code and Codex \u2014 bidirectional agent communication via MCP Channel + JSON-RPC",
1017
1017
  type: "module",
1018
1018
  bin: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raysonmeng/agentbridge",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Bridge between Claude Code and Codex — bidirectional agent communication via MCP Channel + JSON-RPC",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentbridge",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Bridge Claude Code and Codex with a shared daemon, push channel delivery, and bidirectional reply tooling.",
5
5
  "author": {
6
6
  "name": "AgentBridge Contributors",
@@ -9,8 +9,52 @@ import { spawn, execSync } from "child_process";
9
9
  import { createInterface } from "readline";
10
10
  import { EventEmitter } from "events";
11
11
  import { appendFileSync } from "fs";
12
+
13
+ // src/app-server-protocol.ts
14
+ var APP_SERVER_TRACKED_REQUEST_METHODS = [
15
+ "thread/start",
16
+ "thread/resume",
17
+ "turn/start"
18
+ ];
19
+ var APP_SERVER_SERVER_REQUEST_METHODS = [
20
+ "item/permissions/requestApproval",
21
+ "item/fileChange/requestApproval",
22
+ "item/commandExecution/requestApproval"
23
+ ];
24
+ var APP_SERVER_NOTIFICATION_METHODS = [
25
+ "turn/started",
26
+ "turn/completed",
27
+ "item/started",
28
+ "item/agentMessage/delta",
29
+ "item/completed"
30
+ ];
31
+ var TRACKED_REQUEST_METHOD_SET = new Set(APP_SERVER_TRACKED_REQUEST_METHODS);
32
+ var SERVER_REQUEST_METHOD_SET = new Set(APP_SERVER_SERVER_REQUEST_METHODS);
33
+ var NOTIFICATION_METHOD_SET = new Set(APP_SERVER_NOTIFICATION_METHODS);
34
+ function isObjectRecord(value) {
35
+ return typeof value === "object" && value !== null && !Array.isArray(value);
36
+ }
37
+ function isTrackedAppServerRequestMethod(method) {
38
+ return typeof method === "string" && TRACKED_REQUEST_METHOD_SET.has(method);
39
+ }
40
+ function isAppServerRequestMessage(value) {
41
+ if (!isObjectRecord(value))
42
+ return false;
43
+ return (typeof value.id === "number" || typeof value.id === "string") && typeof value.method === "string";
44
+ }
45
+ function isAppServerNotification(value) {
46
+ if (!isObjectRecord(value))
47
+ return false;
48
+ return value.id === undefined && typeof value.method === "string" && NOTIFICATION_METHOD_SET.has(value.method);
49
+ }
50
+ function isAppServerResponseMessage(value) {
51
+ if (!isObjectRecord(value))
52
+ return false;
53
+ return (typeof value.id === "number" || typeof value.id === "string") && value.method === undefined && (("result" in value) || ("error" in value));
54
+ }
55
+
56
+ // src/codex-adapter.ts
12
57
  var LOG_FILE = "/tmp/agentbridge.log";
13
- var TRACKED_REQUEST_METHODS = new Set(["thread/start", "thread/resume", "turn/start"]);
14
58
 
15
59
  class CodexAdapter extends EventEmitter {
16
60
  static RESPONSE_TRACKING_TTL_MS = 30000;
@@ -320,16 +364,21 @@ class CodexAdapter extends EventEmitter {
320
364
  handleAppServerPayload(raw) {
321
365
  try {
322
366
  const parsed = JSON.parse(raw);
323
- if (parsed.id === undefined) {
324
- const forwarded = this.patchResponse(parsed, raw);
325
- this.interceptServerMessage(parsed);
367
+ if (isAppServerNotification(parsed) || typeof parsed === "object" && parsed !== null && !("id" in parsed)) {
368
+ const notificationLike = parsed;
369
+ const forwarded = this.patchResponse(notificationLike, raw);
370
+ this.interceptServerMessage(notificationLike);
326
371
  return forwarded;
327
372
  }
328
- if (parsed.method !== undefined) {
373
+ if (isAppServerRequestMessage(parsed)) {
329
374
  this.handleServerRequest(parsed, raw);
330
375
  return null;
331
376
  }
332
- return this.handleAppServerResponse(parsed, raw);
377
+ if (isAppServerResponseMessage(parsed)) {
378
+ return this.handleAppServerResponse(parsed, raw);
379
+ }
380
+ this.log(`Dropping unclassifiable app-server message: ${raw.slice(0, 100)}`);
381
+ return null;
333
382
  } catch {
334
383
  return raw;
335
384
  }
@@ -392,7 +441,7 @@ class CodexAdapter extends EventEmitter {
392
441
  return null;
393
442
  }
394
443
  patchResponse(parsed, raw) {
395
- if (parsed.error && parsed.id !== undefined) {
444
+ if (isAppServerResponseMessage(parsed) && parsed.error && parsed.id !== undefined) {
396
445
  const errMsg = parsed.error.message ?? "";
397
446
  if (errMsg.includes("rate limits") || errMsg.includes("rateLimits")) {
398
447
  this.log(`Patching rateLimits error \u2192 mock success (id: ${parsed.id})`);
@@ -427,8 +476,9 @@ class CodexAdapter extends EventEmitter {
427
476
  }
428
477
  interceptServerMessage(msg, connId) {
429
478
  this.handleTrackedResponse(msg, connId);
430
- if (msg.method)
479
+ if ("method" in msg && typeof msg.method === "string" && isAppServerNotification(msg)) {
431
480
  this.handleServerNotification(msg);
481
+ }
432
482
  }
433
483
  handleServerNotification(msg) {
434
484
  const { method, params } = msg;
@@ -443,7 +493,10 @@ class CodexAdapter extends EventEmitter {
443
493
  break;
444
494
  }
445
495
  case "item/agentMessage/delta": {
446
- const buf = this.agentMessageBuffers.get(params?.itemId);
496
+ const itemId = params?.itemId;
497
+ if (typeof itemId !== "string")
498
+ break;
499
+ const buf = this.agentMessageBuffers.get(itemId);
447
500
  if (buf && params?.delta)
448
501
  buf.push(params.delta);
449
502
  break;
@@ -488,14 +541,16 @@ class CodexAdapter extends EventEmitter {
488
541
  return `${connId ?? this.tuiConnId}:${base}`;
489
542
  }
490
543
  trackPendingRequest(message, connId, _proxyId) {
491
- const method = message?.method;
492
- const key = this.pendingKey(message?.id, connId);
493
- this.log(`[track] method=${method} id=${message?.id} (type=${typeof message?.id}) key=${key}`);
494
- if (!key || !TRACKED_REQUEST_METHODS.has(method))
544
+ const rpcId = "id" in message ? message.id : undefined;
545
+ const method = "method" in message && typeof message.method === "string" ? message.method : undefined;
546
+ const key = this.pendingKey(rpcId, connId);
547
+ this.log(`[track] method=${method} id=${rpcId} (type=${typeof rpcId}) key=${key}`);
548
+ if (!key || !isTrackedAppServerRequestMethod(method))
495
549
  return;
496
550
  const pending = { method };
497
551
  if (method === "turn/start") {
498
- const threadId = message?.params?.threadId;
552
+ const params = "params" in message && typeof message.params === "object" && message.params !== null ? message.params : undefined;
553
+ const threadId = params?.threadId;
499
554
  if (typeof threadId === "string" && threadId.length > 0) {
500
555
  pending.threadId = threadId;
501
556
  }