@raysonmeng/agentbridge 0.1.6 → 0.1.7

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/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@raysonmeng/agentbridge",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Bridge between Claude Code and Codex — bidirectional agent communication via MCP Channel + JSON-RPC",
5
5
  "type": "module",
6
+ "packageManager": "bun@1.3.11",
7
+ "engines": {
8
+ "bun": ">=1.3.11"
9
+ },
6
10
  "bin": {
7
11
  "agentbridge": "dist/cli.js",
8
12
  "abg": "dist/cli.js"
@@ -12,21 +16,30 @@
12
16
  "plugins/",
13
17
  ".claude-plugin/",
14
18
  "scripts/postinstall.cjs",
19
+ "scripts/install-safety.cjs",
15
20
  "README.md",
16
21
  "LICENSE"
17
22
  ],
18
23
  "scripts": {
19
24
  "start": "bun run src/bridge.ts",
20
- "build:cli": "mkdir -p dist && bun build src/cli.ts --outfile dist/cli.js --target bun && chmod +x dist/cli.js",
21
- "build:plugin": "mkdir -p plugins/agentbridge/server && bun build src/bridge.ts --outfile plugins/agentbridge/server/bridge-server.js --target bun && bun build src/daemon.ts --outfile plugins/agentbridge/server/daemon.js --target bun",
25
+ "build:cli": "node scripts/build-bundles.mjs cli daemon",
26
+ "build:plugin": "node scripts/build-bundles.mjs bridge-plugin daemon-plugin",
27
+ "smoke:built": "bun scripts/smoke-built-cli.mjs",
28
+ "smoke:pack": "bun scripts/smoke-pack.mjs",
22
29
  "verify:plugin-sync": "node scripts/verify-plugin-sync.cjs",
23
30
  "postinstall": "node scripts/postinstall.cjs",
24
- "prepublishOnly": "bun run build:cli && bun run build:plugin",
31
+ "prepublishOnly": "bun run build:cli && bun run build:plugin && bun run verify:plugin-sync && bun scripts/check-plugin-versions.js",
25
32
  "validate:plugin": "claude plugin validate plugins/agentbridge && claude plugin validate .claude-plugin/marketplace.json",
26
33
  "test": "bun test src",
34
+ "e2e:transport": "bun scripts/e2e-codex-transport.mjs",
35
+ "install:global": "node scripts/install-global.mjs local",
36
+ "install:global:local": "node scripts/install-global.mjs local",
37
+ "install:global:npm": "node scripts/install-global.mjs npm",
38
+ "release:bump": "node scripts/bump-version.mjs",
27
39
  "typecheck": "tsc --noEmit",
28
40
  "validate:plugin-versions": "bun scripts/check-plugin-versions.js",
29
- "check": "tsc --noEmit && bun test src && bun run verify:plugin-sync && bun scripts/check-plugin-versions.js"
41
+ "check": "tsc --noEmit && bun test src && bun run verify:plugin-sync && bun scripts/check-plugin-versions.js",
42
+ "ci:local": "bun run check && bun run smoke:built && bun run smoke:pack"
30
43
  },
31
44
  "repository": {
32
45
  "type": "git",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentbridge",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
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",
@@ -1,6 +1,6 @@
1
1
  # AgentBridge Plugin
2
2
 
3
- Claude Code plugin for AgentBridge. This plugin packages the AgentBridge MCP frontend, dual-mode Claude transport (push channel delivery plus pull-mode `get_messages`), the `/agentbridge:init` command, and a non-blocking SessionStart health check.
3
+ Claude Code plugin for AgentBridge. This plugin packages the AgentBridge MCP frontend with push channel delivery (a failed push falls back to an in-memory queue drained by `get_messages`), the `/agentbridge:init` command, and a non-blocking SessionStart health check.
4
4
 
5
5
  ## Structure
6
6
 
@@ -38,6 +38,6 @@ This creates self-contained bundles at:
38
38
  ## Notes
39
39
 
40
40
  - The plugin frontend launches the sibling daemon bundle via `AGENTBRIDGE_DAEMON_ENTRY=./daemon.js`.
41
- - Claude delivery supports both push notifications and pull-mode polling via `get_messages`, depending on the runtime mode.
41
+ - Claude delivery is always push notifications. If a push fails, the message is queued and can be drained via `get_messages` (per-message fallback the legacy `AGENTBRIDGE_MODE=pull` mode was removed and the env var is ignored with a one-time warning).
42
42
  - The SessionStart hook is informational only. It never starts or stops the daemon.
43
43
  - The command at `/agentbridge:init` edits project-local `.agentbridge/` files only; plugin installation and marketplace registration remain terminal-side tasks (`agentbridge init` / `agentbridge dev`).
@@ -9,6 +9,16 @@ cooldown_seconds="${AGENTBRIDGE_HEALTH_HOOK_COOLDOWN_SECONDS:-120}"
9
9
  state_root="${AGENTBRIDGE_HOOK_STATE_DIR:-${TMPDIR:-/tmp}/agentbridge-hooks}"
10
10
  port="${AGENTBRIDGE_CONTROL_PORT:-4502}"
11
11
 
12
+ # In multi-pair mode the resolver exports AGENTBRIDGE_PAIR_ID, inherited here via
13
+ # the SessionStart hook env. Scope the suggested commands to that pair so the
14
+ # user is not sent to a different (cwd-derived) pair. Guard the charset (the
15
+ # resolver already restricts it) so nothing unsafe is interpolated into the JSON.
16
+ pair_id="${AGENTBRIDGE_PAIR_ID:-}"
17
+ pair_arg=""
18
+ if printf '%s' "$pair_id" | grep -Eq '^[A-Za-z0-9._-]+$'; then
19
+ pair_arg=" --pair ${pair_id}"
20
+ fi
21
+
12
22
  if ! command -v curl >/dev/null 2>&1; then
13
23
  exit 0
14
24
  fi
@@ -27,6 +37,15 @@ fi
27
37
 
28
38
  printf '%s' "$now" >"$stamp_file" 2>/dev/null || true
29
39
 
40
+ # In-session plugin-update reminder: compare the INSTALLED plugin version against
41
+ # the latest npm version cached by the CLI notifier (src/update-notifier.ts). This
42
+ # is how a user who updated the npm CLI but not the plugin learns of the mismatch
43
+ # from inside Claude Code. Best-effort + silent: never blocks the hook.
44
+ plugin_notice=""
45
+ if command -v bun >/dev/null 2>&1 && [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
46
+ plugin_notice="$(bun "${CLAUDE_PLUGIN_ROOT}/scripts/plugin-update-notice.mjs" "${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json" 2>/dev/null || true)"
47
+ fi
48
+
30
49
  health_json="$(curl -fsS --max-time 1 "http://127.0.0.1:${port}/healthz" 2>/dev/null || true)"
31
50
 
32
51
  if [ -n "$health_json" ]; then
@@ -37,15 +56,15 @@ if [ -n "$health_json" ]; then
37
56
 
38
57
  if [ "$tui_connected" = "true" ]; then
39
58
  cat <<EOF
40
- {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"AgentBridge is running. Daemon healthy, Codex TUI connected. Bridge is ready for communication."}}
59
+ {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"AgentBridge is running. Daemon healthy, Codex TUI connected. Bridge is ready for communication.${plugin_notice:+ $plugin_notice}"}}
41
60
  EOF
42
61
  else
43
62
  cat <<EOF
44
- {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"AgentBridge daemon is running but Codex TUI is not connected yet. Start Codex in another terminal with: agentbridge codex"}}
63
+ {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"AgentBridge daemon is running but Codex TUI is not connected yet. Start Codex in another terminal with: agentbridge codex${pair_arg}${plugin_notice:+ $plugin_notice}"}}
45
64
  EOF
46
65
  fi
47
66
  else
48
67
  cat <<EOF
49
- {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"AgentBridge daemon is not reachable on http://127.0.0.1:${port}/healthz yet. Start the bridge with: agentbridge claude (this terminal) + agentbridge codex (another terminal). If you're already using agentbridge claude, the daemon may still be starting up."}}
68
+ {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"AgentBridge daemon is not reachable on http://127.0.0.1:${port}/healthz yet. Start the bridge with: agentbridge claude${pair_arg} (this terminal) + agentbridge codex${pair_arg} (another terminal). If you're already using agentbridge claude${pair_arg}, the daemon may still be starting up.${plugin_notice:+ $plugin_notice}"}}
50
69
  EOF
51
70
  fi
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * In-session plugin-update reminder.
4
+ *
5
+ * The CLI notifier (src/update-notifier.ts) writes the latest npm version to the
6
+ * update-check cache. This script — invoked by the SessionStart hook
7
+ * (scripts/health-check.sh) — compares that `latest` against the INSTALLED
8
+ * plugin version (plugin.json, passed as argv[2]) and prints a one-line reminder
9
+ * to stdout if the plugin is behind. Prints NOTHING otherwise.
10
+ *
11
+ * Why a separate plugin-side reminder: the CLI prints its notice to the terminal
12
+ * before Claude Code's TUI takes over, so a user who updates npm but not the
13
+ * plugin would otherwise never see the mismatch from inside the session.
14
+ *
15
+ * Self-contained on purpose: the shipped plugin does not include src/, so the
16
+ * tiny state-dir resolution + stable-semver compare are inlined here. Keep them
17
+ * in sync with src/state-dir.ts (StateDirResolver) and src/version-utils.ts.
18
+ * Silent on ANY error — it must never break the SessionStart hook.
19
+ */
20
+ import { readFileSync } from "node:fs";
21
+ import { join } from "node:path";
22
+ import { homedir, platform } from "node:os";
23
+
24
+ /** Mirror of StateDirResolver (src/state-dir.ts). */
25
+ function stateDir() {
26
+ const override = process.env.AGENTBRIDGE_STATE_DIR;
27
+ if (override) return override;
28
+ if (platform() === "darwin") {
29
+ return join(homedir(), "Library", "Application Support", "AgentBridge");
30
+ }
31
+ const xdg = process.env.XDG_STATE_HOME ?? join(homedir(), ".local", "state");
32
+ return join(xdg, "agentbridge");
33
+ }
34
+
35
+ const STABLE = /^\d+\.\d+\.\d+$/;
36
+
37
+ /** Mirror of isStableUpgrade (src/version-utils.ts): stable latest strictly > stable current. */
38
+ function isStableUpgrade(current, latest) {
39
+ if (!STABLE.test(current) || !STABLE.test(latest)) return false;
40
+ const a = current.split(".").map(Number);
41
+ const b = latest.split(".").map(Number);
42
+ for (let i = 0; i < 3; i++) {
43
+ if (b[i] > a[i]) return true;
44
+ if (b[i] < a[i]) return false;
45
+ }
46
+ return false;
47
+ }
48
+
49
+ try {
50
+ // Honor the same opt-out as the CLI notifier (src/update-notifier.ts): a user
51
+ // who silenced update notices must not still get the in-session reminder.
52
+ if (process.env.NO_UPDATE_NOTIFIER || process.env.AGENTBRIDGE_NO_UPDATE_NOTIFIER) {
53
+ process.exit(0);
54
+ }
55
+
56
+ const pluginJsonPath = process.argv[2];
57
+ if (!pluginJsonPath) process.exit(0);
58
+
59
+ const current = JSON.parse(readFileSync(pluginJsonPath, "utf-8")).version;
60
+ const cache = JSON.parse(readFileSync(join(stateDir(), "update-check.json"), "utf-8"));
61
+ const latest = cache?.latest;
62
+
63
+ if (typeof current === "string" && typeof latest === "string" && isStableUpgrade(current, latest)) {
64
+ process.stdout.write(
65
+ `AgentBridge plugin update available: ${current} -> ${latest}. ` +
66
+ `Update the plugin with /plugin marketplace update agentbridge then /reload-plugins ` +
67
+ `(and the CLI with npm install -g @raysonmeng/agentbridge@latest) so the CLI and plugin versions match.`,
68
+ );
69
+ }
70
+ } catch {
71
+ // No cache yet / no plugin.json / malformed — stay silent.
72
+ }
73
+ process.exit(0);