@bridge_gpt/mcp-server 0.2.56 → 0.2.57

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.
@@ -152,6 +152,7 @@ import { provisionHostTarget, createDefaultVendorProcessDeps, inspectBridgeApiPr
152
152
  import { adaptBridgeEntryForHostTarget, } from "./mcp-host-entry-adapter.js";
153
153
  import { MCP_SERVER_NAME, MCP_PACKAGE_NAME, resolveRegistrationKey, } from "./mcp-identity.js";
154
154
  import { DUPLICATE_REGISTRATION_GUIDANCE } from "./launcher-config-inspection.js";
155
+ import { codexHome, configureBridgeCodexProfile, inspectBridgeCodexProfile } from "./codex-bridge-profile.js";
155
156
  import { recordInstalledConductorCapability, recordInstalledExecutorServiceUnit, recordInstalledProjectArtifact, writeMcpInstallState, } from "./mcp-install-state.js";
156
157
  // BAPI-1207: opt-in cross-platform agent notes (AGENTS.md / CLAUDE.md).
157
158
  import { AGENT_GUIDANCE } from "./agent-guidance.generated.js";
@@ -517,6 +518,9 @@ export function getInstallBridgeUsage(baseUrl = DEFAULT_BAPI_BASE_URL) {
517
518
  " manual continuation instead). --tools= (empty) is",
518
519
  " an explicit empty selection: it writes nothing and",
519
520
  " launches nothing.",
521
+ " --codex-profile on|off Opt in to Bridge workflow MCP approvals for",
522
+ " Codex workers, or explicitly decline. With a",
523
+ " Codex TTY selection, the installer asks.",
520
524
  " --force Overwrite an existing real BAPI_API_KEY in a",
521
525
  " host config (or in the credential store) without",
522
526
  " prompting. It does NOT bypass the git-tracked",
@@ -614,6 +618,7 @@ export function parseInstallBridgeArgs(argv) {
614
618
  let invite;
615
619
  let email;
616
620
  let tools;
621
+ let codexProfile;
617
622
  // Track SUPPLIED-ness separately from the values: `--invite` is legitimately
618
623
  // valueless (prompt path) and `--api-key ""` is still a contradiction with it.
619
624
  let inviteSupplied = false;
@@ -699,6 +704,16 @@ export function parseInstallBridgeArgs(argv) {
699
704
  i = r.nextIndex;
700
705
  continue;
701
706
  }
707
+ if (arg === "--codex-profile" || arg.startsWith("--codex-profile=")) {
708
+ const r = readValue(arg, "--codex-profile", i);
709
+ if ("error" in r)
710
+ return { status: "error", message: r.error };
711
+ if (r.value !== "on" && r.value !== "off")
712
+ return { status: "error", message: "--codex-profile must be on or off." };
713
+ codexProfile = r.value;
714
+ i = r.nextIndex;
715
+ continue;
716
+ }
702
717
  if (arg === "--agent" || arg.startsWith("--agent=")) {
703
718
  const r = readValue(arg, "--agent", i);
704
719
  if ("error" in r)
@@ -749,7 +764,7 @@ export function parseInstallBridgeArgs(argv) {
749
764
  }
750
765
  return {
751
766
  status: "ok",
752
- options: { apiKey, repo, force, dryRun, agentName, invite, inviteMode: inviteSupplied, email, tools },
767
+ options: { apiKey, repo, force, dryRun, agentName, invite, inviteMode: inviteSupplied, email, tools, codexProfile },
753
768
  };
754
769
  }
755
770
  /**
@@ -4932,6 +4947,15 @@ export async function runInstallBridgeCli(argv, overrides = {}) {
4932
4947
  // global (Codex) or manual (Windsurf) target is provisioned by the
4933
4948
  // registry-driven emitter after the connectivity check.
4934
4949
  const selectedPlatforms = await resolveSelectedHostPlatforms(deps, options);
4950
+ if (options.codexProfile && !selectedPlatforms.includes("codex")) {
4951
+ errorLog("Error: --codex-profile requires Codex in --tools or the interactive selection.");
4952
+ return 1;
4953
+ }
4954
+ let codexProfileChoice = options.codexProfile;
4955
+ if (selectedPlatforms.includes("codex") && !options.dryRun && !codexProfileChoice && deps.isTTY && deps.promptLine) {
4956
+ const answer = (await deps.promptLine("Install the opt-in Bridge Codex approval profile for spawned workers? (y/N) ")).trim().toLowerCase();
4957
+ codexProfileChoice = answer === "y" || answer === "yes" ? "on" : "off";
4958
+ }
4935
4959
  const targets = hostConfigTargetsForPlatforms(selectedPlatforms);
4936
4960
  // Read-only detection (safe in dry-run) of global-config editors we can't write.
4937
4961
  const manualEditors = await detectManualEditors(deps);
@@ -5712,6 +5736,28 @@ export async function runInstallBridgeCli(argv, overrides = {}) {
5712
5736
  errorLog(" That host was left untouched. Re-run install-bridge once one entry is removed.");
5713
5737
  return 1;
5714
5738
  }
5739
+ if (selectedPlatforms.includes("codex")) {
5740
+ const home = codexHome(deps.env, deps.homedir());
5741
+ try {
5742
+ const profileDeps = {
5743
+ readFile: deps.readFile,
5744
+ writeFile: (p, data) => deps.writeFile(p, data, { encoding: "utf-8", mode: 0o600 }),
5745
+ mkdir: deps.mkdir,
5746
+ };
5747
+ const result = codexProfileChoice
5748
+ ? await configureBridgeCodexProfile(home, codexProfileChoice === "on" ? "enable" : "decline", profileDeps)
5749
+ : await inspectBridgeCodexProfile(home, deps.readFile);
5750
+ if (result.status === "active")
5751
+ log(" Codex Bridge approval profile installed; spawned workers use --profile bridge.");
5752
+ else if (result.status === "declined" || result.status === "missing")
5753
+ log(" Codex Bridge approval profile inactive; spawned workers use existing Codex approvals. Opt in with --codex-profile=on.");
5754
+ else
5755
+ log(` Codex Bridge approval profile ${result.status}; spawned workers will not use it. Inspect ${home}/bridge.config.toml and rerun with --codex-profile=on.`);
5756
+ }
5757
+ catch {
5758
+ log(" Codex Bridge approval profile could not be configured; spawned workers will not use it. Inspect CODEX_HOME and rerun with --codex-profile=on.");
5759
+ }
5760
+ }
5715
5761
  // Legacy manual-editor instructions cover editors that are DETECTED but were
5716
5762
  // NOT part of the selection (so the emitter above did not handle them). The two
5717
5763
  // editors are suppressed INDEPENDENTLY: Codex is dropped when it was selected
@@ -28,6 +28,7 @@
28
28
  * rather than reserialize unrelated content.
29
29
  */
30
30
  import { VERSION } from "./version.generated.js";
31
+ import { codexHome } from "./codex-home.js";
31
32
  import { refreshBridgeApiPackageSpec } from "./init.js";
32
33
  import { hostAdapterForTarget, } from "./mcp-host-targets.js";
33
34
  import { adaptBridgeEntryForHostTarget, } from "./mcp-host-entry-adapter.js";
@@ -56,6 +57,9 @@ function dirnameOf(p) {
56
57
  }
57
58
  /** Resolve a target's absolute path from injected cwd/homedir. */
58
59
  export function resolveTargetAbsPath(target, ctx) {
60
+ if (target.id === "codex" && ctx.env?.CODEX_HOME) {
61
+ return `${codexHome(ctx.env, ctx.homedir)}/config.toml`;
62
+ }
59
63
  if (target.scope === "project") {
60
64
  if (!target.relPath)
61
65
  throw new Error(`${target.id} missing relPath`);
@@ -15,6 +15,7 @@
15
15
  * platform is a matter of adding one entry to {@link MCP_HOST_TARGETS} plus its
16
16
  * `PlatformId` union member.
17
17
  */
18
+ import { codexHome } from "./codex-home.js";
18
19
  // ---------------------------------------------------------------------------
19
20
  // Path helpers (pure)
20
21
  // ---------------------------------------------------------------------------
@@ -190,6 +191,8 @@ export function getManualHostTargets() {
190
191
  * Project targets resolve below `ctx.cwd`; global targets below `ctx.homedir`.
191
192
  */
192
193
  export function resolveHostTargetPath(target, ctx) {
194
+ if (target.id === "codex" && ctx.env?.CODEX_HOME)
195
+ return `${codexHome(ctx.env, ctx.homedir)}/config.toml`;
193
196
  if (target.scope === "project") {
194
197
  if (!target.relPath) {
195
198
  throw new Error(`project target ${target.id} is missing relPath`);