@bridge_gpt/mcp-server 0.2.39 → 0.2.42

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 (74) hide show
  1. package/README.md +10 -10
  2. package/build/agent-capabilities/cli.js +2 -1
  3. package/build/agent-launchers/claude-executor-adapter.js +17 -4
  4. package/build/claude-user-config-doctor.js +42 -11
  5. package/build/cli-release.js +2 -1
  6. package/build/commands.generated.js +4 -4
  7. package/build/conduct-epic/bridge-client.js +354 -113
  8. package/build/conduct-epic/checkpoint-store.js +75 -2
  9. package/build/conduct-epic/cli.js +795 -109
  10. package/build/conduct-epic/cut-protocol.js +327 -0
  11. package/build/conduct-epic/pr-state.js +113 -24
  12. package/build/conduct-epic/spawn.js +14 -2
  13. package/build/conductor/bridge-api-client.js +27 -1
  14. package/build/conductor/cli.js +46 -1
  15. package/build/conductor/doctor.js +101 -16
  16. package/build/conductor/epic-reconcile.js +72 -19
  17. package/build/conductor/epic-runtime.js +15 -3
  18. package/build/conductor/errors.js +47 -0
  19. package/build/conductor/git-hooks.js +205 -11
  20. package/build/conductor/install-doctor.js +230 -1
  21. package/build/conductor/local-merge.js +130 -28
  22. package/build/conductor/tools.js +32 -3
  23. package/build/conductor/worker-ledger-cli.js +27 -1
  24. package/build/conductor-bin.js +15 -15
  25. package/build/credentials-cli.js +3 -2
  26. package/build/doctor.js +107 -41
  27. package/build/executor/cli.js +48 -1
  28. package/build/executor/env.js +21 -0
  29. package/build/executor/index-scope.js +39 -0
  30. package/build/executor/job-log-registry.js +69 -0
  31. package/build/executor/job-runner.js +148 -26
  32. package/build/executor/live-worker-registry.js +83 -0
  33. package/build/executor/observation.js +167 -6
  34. package/build/executor/platform.js +147 -3
  35. package/build/executor/process.js +58 -14
  36. package/build/executor/runner.js +235 -48
  37. package/build/executor/test-clock.js +3 -2
  38. package/build/index-scope-contract.js +96 -0
  39. package/build/index.js +153 -204
  40. package/build/init.js +83 -22
  41. package/build/install-bridge-conductor.js +323 -14
  42. package/build/install-bridge.js +202 -38
  43. package/build/install-doctor.js +23 -9
  44. package/build/install-reexec.js +2 -1
  45. package/build/launcher-config-inspection.js +83 -22
  46. package/build/mcp-host-config.js +331 -67
  47. package/build/mcp-host-targets.js +45 -21
  48. package/build/mcp-identity.js +92 -0
  49. package/build/mcp-install-state.js +94 -1
  50. package/build/mcp-invoke.js +2 -1
  51. package/build/mcp-provisioning.js +45 -12
  52. package/build/mcp-registration-doctor.js +35 -13
  53. package/build/mcp-server-invocation.js +4 -2
  54. package/build/merge-pull-request.js +208 -9
  55. package/build/pipelines.generated.js +3 -3
  56. package/build/plane/defaults.js +4 -1
  57. package/build/plane/preflight.js +81 -10
  58. package/build/plane/test-fakes.js +9 -1
  59. package/build/readme.generated.js +1 -1
  60. package/build/regression-check.js +3 -2
  61. package/build/review-tickets.js +8 -7
  62. package/build/run-unit-tests-launcher.js +74 -1
  63. package/build/schedule-run.js +3 -2
  64. package/build/setup-epic.js +453 -78
  65. package/build/sfcc/tool-wrapper.js +15 -0
  66. package/build/start-tickets-prereqs.js +11 -6
  67. package/build/start-tickets.js +91 -85
  68. package/build/update-check.js +3 -2
  69. package/build/upgrade-advice.js +2 -1
  70. package/build/upgrade-cli.js +50 -18
  71. package/build/version.generated.js +1 -1
  72. package/docs/CONDUCTOR.md +22 -0
  73. package/docs/install/mcp-tool-integrations.md +19 -3
  74. package/package.json +2 -2
package/README.md CHANGED
@@ -23,7 +23,7 @@ account — it will ask.
23
23
 
24
24
  - Adds slash commands and agent definitions for your editor (`.claude/commands/`,
25
25
  `.cursor/commands/`, and the equivalents your editor uses).
26
- - Registers a `bridge-api` MCP server in your editor's MCP config, leaving any
26
+ - Registers a `bridge` MCP server in your editor's MCP config, leaving any
27
27
  other servers you have configured untouched.
28
28
  - Creates `.bridge/` for your project manifest and pipeline definitions.
29
29
  - Writes nothing outside your project root except your Bridge credential, which is
@@ -160,7 +160,7 @@ to ask for it.
160
160
 
161
161
  **"My editor doesn't see any Bridge tools."** Two usual causes. First, the config
162
162
  was written somewhere your editor is not looking — re-run the installer from the
163
- directory your editor actually opens, and check that a `bridge-api` entry exists in
163
+ directory your editor actually opens, and check that a `bridge` entry exists in
164
164
  that project's MCP config. Second, the editor has not been reloaded since the file
165
165
  was written; restart it. In Claude Code, also confirm you accepted the trust prompt
166
166
  for the project's `.mcp.json`.
@@ -278,7 +278,7 @@ No `package.json` is required:
278
278
  npx -y @bridge_gpt/mcp-server --init
279
279
  ```
280
280
 
281
- Then add a `bridge-api` entry to your host's MCP config, filling in your repository
281
+ Then add a `bridge` entry to your host's MCP config, filling in your repository
282
282
  name and API key. Add `"serve"` as the last launcher argument, as shown — it is the
283
283
  explicit way to say "start the MCP server."
284
284
 
@@ -288,7 +288,7 @@ explicit way to say "start the MCP server."
288
288
  ```json
289
289
  {
290
290
  "mcpServers": {
291
- "bridge-api": {
291
+ "bridge": {
292
292
  "command": "npx",
293
293
  "args": ["-y", "@bridge_gpt/mcp-server", "serve"],
294
294
  "env": {
@@ -309,7 +309,7 @@ explicit way to say "start the MCP server."
309
309
  ```json
310
310
  {
311
311
  "servers": {
312
- "bridge-api": {
312
+ "bridge": {
313
313
  "command": "npx",
314
314
  "args": ["-y", "@bridge_gpt/mcp-server", "serve"],
315
315
  "env": {
@@ -330,7 +330,7 @@ explicit way to say "start the MCP server."
330
330
  ```json
331
331
  {
332
332
  "mcpServers": {
333
- "bridge-api": {
333
+ "bridge": {
334
334
  "command": "npx",
335
335
  "args": ["-y", "@bridge_gpt/mcp-server", "serve"],
336
336
  "env": {
@@ -355,7 +355,7 @@ Windsurf only supports global MCP configuration.
355
355
  ```json
356
356
  {
357
357
  "mcpServers": {
358
- "bridge-api": {
358
+ "bridge": {
359
359
  "command": "npx",
360
360
  "args": ["-y", "@bridge_gpt/mcp-server", "serve"],
361
361
  "env": {
@@ -374,11 +374,11 @@ Windsurf only supports global MCP configuration.
374
374
  <summary><strong>OpenAI Codex (~/.codex/config.toml)</strong></summary>
375
375
 
376
376
  ```toml
377
- [mcp_servers.bridge-api]
377
+ [mcp_servers.bridge]
378
378
  command = "npx"
379
379
  args = ["-y", "@bridge_gpt/mcp-server", "serve"]
380
380
 
381
- [mcp_servers.bridge-api.env]
381
+ [mcp_servers.bridge.env]
382
382
  BAPI_BASE_URL = "https://bridgegpt-api.com"
383
383
  BAPI_REPO_NAME = "your-repo"
384
384
  BAPI_API_KEY = "your-api-key"
@@ -456,7 +456,7 @@ For invocation, prefer the slash command — it's deterministic. A free-text exa
456
456
  metadata in scripts/sync_mcp_tool_catalog.py — never the JSON artifact and never the
457
457
  text between the markers. Generation order is: sync_mcp_tool_catalog.py, then
458
458
  sync_mcp_server_readme.py, then `cd mcp_server && npm run build` (which bundles this
459
- file into readme.generated.ts, served as the MCP resource bridge-api://readme).
459
+ file into readme.generated.ts, served as the MCP resource bridge://readme).
460
460
  Everything outside the marker pair — including the sections below it — is hand-written. -->
461
461
 
462
462
  <!-- BEGIN GENERATED: mcp-tool-documentation (managed by scripts/sync_mcp_server_readme.py — DO NOT EDIT BY HAND) -->
@@ -12,10 +12,11 @@ import { createDefaultAgentCapabilitiesDeps } from "./default-deps.js";
12
12
  import { formatCapabilityJson, formatCapabilityReport } from "./reporter.js";
13
13
  import { collectCapabilityResults, hasFailureOrHang } from "./runner.js";
14
14
  import { listProbeIds } from "./probes.js";
15
+ import { MCP_PACKAGE_NAME } from "../mcp-identity.js";
15
16
  export function getAgentCapabilitiesUsage() {
16
17
  return [
17
18
  "Usage:",
18
- " npx -y @bridge_gpt/mcp-server agent-capabilities [--agent <name|all>] [--only <ids>] [--json]",
19
+ ` npx -y ${MCP_PACKAGE_NAME} agent-capabilities [--agent <name|all>] [--only <ids>] [--json]`,
19
20
  "",
20
21
  "Empirically validates what an agent CLI can do (binary resolution, headless",
21
22
  "print mode + exit, .claude/commands resolution, preamble drift-check, output",
@@ -6,6 +6,7 @@ import { provisionExecutorDenyLayer } from "../executor/permissions.js";
6
6
  import { SUPPORTED_EXECUTOR_PLATFORMS, evaluateExecutorPlatform } from "../executor/platform.js";
7
7
  import { normalizeMcpServerNames } from "../executor/observation.js";
8
8
  import { supported } from "./executor-adapter.js";
9
+ import { MCP_SERVER_NAME } from "../mcp-identity.js";
9
10
  /** Stable identity of this reference implementation. */
10
11
  export const CLAUDE_ADAPTER_ID = "claude-reference";
11
12
  /** Registry strategy identifier that selects this adapter's factory. */
@@ -15,7 +16,7 @@ export const CLAUDE_ADAPTER_VERSION = "1.0.0";
15
16
  /** The one operator-owned credential name this adapter forwards. */
16
17
  export const CLAUDE_OAUTH_TOKEN_ENV = "CLAUDE_CODE_OAUTH_TOKEN";
17
18
  /** The provisioned MCP server a Claude worker requires. */
18
- export const CLAUDE_REQUIRED_MCP_SERVER_NAME = "bridge-api";
19
+ export const CLAUDE_REQUIRED_MCP_SERVER_NAME = MCP_SERVER_NAME;
19
20
  /** Fixed replacement written in place of a redacted secret value. */
20
21
  export const CLAUDE_REDACTION_REPLACEMENT = "[redacted]";
21
22
  /** Upper bound on retained version text, matching preflight's existing cap. */
@@ -221,6 +222,11 @@ export function buildClaudeArgv(prompt, alias, mcpConfigPath, posture) {
221
222
  * validation, logging, or fallback. A non-string or absent value is silently
222
223
  * skipped rather than synthesized. `ANTHROPIC_API_KEY` has no equivalent branch
223
224
  * and cannot reach a worker environment through any path in this function.
225
+ *
226
+ * `options` is forwarded to the generic builder unchanged, including BAPI-844's
227
+ * `indexScope`. This adapter neither reads nor validates the scope: it is not an
228
+ * agent-specific credential decision, so it stays owned by the generic builder,
229
+ * where the deny-list and the shared shape check both live.
224
230
  */
225
231
  export function buildClaudeWorkerEnv(parentEnv, options = {}) {
226
232
  const env = buildExecutorBaseWorkerEnv(parentEnv, options);
@@ -252,9 +258,16 @@ export function createClaudeExecutorAdapter(spec, deps = {}) {
252
258
  };
253
259
  const headlessInvocation = {
254
260
  buildSpawnShape(input) {
255
- const envOptions = input.effectiveBaseBranch === undefined
256
- ? {}
257
- : { effectiveBaseBranch: input.effectiveBaseBranch };
261
+ // Each option is included only when the input carries it, so an unscoped
262
+ // job on a legacy base still produces the exact `{}` the pre-existing
263
+ // fixtures pin — an explicit `undefined` would be a different object.
264
+ const envOptions = {};
265
+ if (input.effectiveBaseBranch !== undefined) {
266
+ envOptions.effectiveBaseBranch = input.effectiveBaseBranch;
267
+ }
268
+ if (input.indexScope !== undefined) {
269
+ envOptions.indexScope = input.indexScope;
270
+ }
258
271
  return {
259
272
  executable: spec.command,
260
273
  argv: buildClaudeArgv(input.prompt, input.modelAlias, input.mcpConfigPath, input.posture),
@@ -39,8 +39,8 @@
39
39
  */
40
40
  import { isBridgeApiShimEntry, readJsonIfPresent } from "./mcp-registration-doctor.js";
41
41
  import { normalizeWorktreePathForRegistration, pathApiForProvisioningPlatform, } from "./mcp-provisioning.js";
42
- /** The registration key both the provisioner and a user config would use. */
43
- const BRIDGE_API_SERVER_NAME = "bridge-api";
42
+ import { MCP_SERVER_NAME, resolveRegistrationKey, } from "./mcp-identity.js";
43
+ import { DUPLICATE_REGISTRATION_GUIDANCE } from "./launcher-config-inspection.js";
44
44
  /** The Claude user configuration file name, at the home directory root. */
45
45
  const CLAUDE_USER_CONFIG_FILENAME = ".claude.json";
46
46
  /**
@@ -217,9 +217,22 @@ export async function inspectClaudeUserConfigForMcpShadowing(input, deps) {
217
217
  }
218
218
  if (!servers)
219
219
  continue;
220
- if (!Object.prototype.hasOwnProperty.call(servers, BRIDGE_API_SERVER_NAME))
220
+ // BAPI-807: every recognized key is inspected at every supported scope. A
221
+ // legacy `bridge-api` registration shadows exactly as much as a canonical
222
+ // one, so checking only the canonical name would silently stop reporting the
223
+ // collisions this inspector exists to surface.
224
+ const resolution = resolveRegistrationKey(servers);
225
+ if (resolution.state === "conflict") {
226
+ // Two Bridge registrations at one scope. Reported as its own diagnostic
227
+ // rather than treating either as authoritative — which of them Claude
228
+ // loads is not something this inspector can know.
229
+ diagnostics.push({ kind: "duplicate-registration", configPath, scope: lookup.scope });
221
230
  continue;
222
- const entry = servers[BRIDGE_API_SERVER_NAME];
231
+ }
232
+ if (resolution.state === "absent")
233
+ continue;
234
+ const registrationKey = resolution.key;
235
+ const entry = servers[registrationKey];
223
236
  const classification = classifyEntry(entry, lookup.allowedPaths);
224
237
  if (classification.verdict === "safe")
225
238
  continue;
@@ -238,6 +251,7 @@ export async function inspectClaudeUserConfigForMcpShadowing(input, deps) {
238
251
  const finding = {
239
252
  scopes: [lookup.scope],
240
253
  configPath,
254
+ registrationKey,
241
255
  shape: classification.shape,
242
256
  envKeyNames: envKeyNamesOf(entry),
243
257
  };
@@ -290,7 +304,9 @@ export function formatClaudeMcpShadowFinding(finding) {
290
304
  const envNote = finding.envKeyNames.length > 0
291
305
  ? ` (env keys: ${finding.envKeyNames.join(", ")})`
292
306
  : "";
293
- return (`${finding.configPath} registers a '${BRIDGE_API_SERVER_NAME}' MCP server at ${scopes}: ` +
307
+ // The KEY is rendered dynamically from the finding (BAPI-807); the entry body,
308
+ // its arguments, and its env VALUES remain unrendered — only key names appear.
309
+ return (`${finding.configPath} registers a '${finding.registrationKey}' MCP server at ${scopes}: ` +
294
310
  `${SHAPE_LABELS[finding.shape]}${envNote}`);
295
311
  }
296
312
  /** Render one degraded diagnostic as a fixed, path-only sentence. */
@@ -301,18 +317,33 @@ export function formatClaudeUserConfigDiagnostic(diagnostic) {
301
317
  case "malformed":
302
318
  return `${diagnostic.configPath} contains malformed JSON; Claude MCP shadowing could not be checked`;
303
319
  case "inconclusive-user-shim":
304
- return (`${diagnostic.configPath} registers a user-scope '${BRIDGE_API_SERVER_NAME}' shim for an ` +
320
+ return (`${diagnostic.configPath} registers a user-scope Bridge shim for an ` +
305
321
  "unverifiable project root (the main repository path could not be resolved)");
322
+ case "duplicate-registration":
323
+ return (`${diagnostic.configPath} at ${SCOPE_LABELS[diagnostic.scope]}: ` +
324
+ DUPLICATE_REGISTRATION_GUIDANCE);
306
325
  }
307
326
  }
308
327
  /**
309
- * The exact remediation command every shadowing advisory carries (BAPI-790).
328
+ * Build the remediation command for ONE registration key (BAPI-807).
310
329
  *
311
330
  * A same-named registration is almost always a local-scope leftover, and this is
312
- * the one command that removes it. Centralized so the executor advisory, the
313
- * doctor prerequisite, and the operator runbook cannot drift apart.
331
+ * the one command that removes it. It is generated from the key that was
332
+ * actually found rather than fixed, because a command naming the wrong key
333
+ * silently succeeds-as-no-op and teaches the operator to distrust the advisory.
334
+ */
335
+ export function claudeMcpShadowingRemediationCommand(registrationKey) {
336
+ return `claude mcp remove ${registrationKey} -s local`;
337
+ }
338
+ /**
339
+ * The remediation command for the CANONICAL key.
340
+ *
341
+ * Retained as a named constant — the doctor prerequisite and the operator
342
+ * runbook reference one shared string — but every advisory rendered from an
343
+ * actual finding uses {@link claudeMcpShadowingRemediationCommand} with that
344
+ * finding's own key instead.
314
345
  */
315
- export const CLAUDE_MCP_SHADOWING_REMEDIATION_COMMAND = "claude mcp remove bridge-api -s local";
346
+ export const CLAUDE_MCP_SHADOWING_REMEDIATION_COMMAND = claudeMcpShadowingRemediationCommand(MCP_SERVER_NAME);
316
347
  /**
317
348
  * The SINGLE policy every consumer (executor preflight, per-worktree enforcement,
318
349
  * doctor) applies to an inspection result, so none of them re-derives
@@ -338,6 +369,6 @@ export function evaluateClaudeMcpShadowingPolicy(inspection) {
338
369
  // trailing sentence changes from a refusal to an advisory.
339
370
  const findingMessages = inspection.findings.map((finding) => `${formatClaudeMcpShadowFinding(finding)}. Advisory only: strict worker MCP loading ` +
340
371
  "means this registration is not loaded by a worker, and the per-spawn MCP surface " +
341
- `assertion verifies that. To clear it: ${CLAUDE_MCP_SHADOWING_REMEDIATION_COMMAND}`);
372
+ `assertion verifies that. To clear it: ${claudeMcpShadowingRemediationCommand(finding.registrationKey)}`);
342
373
  return { ok: true, warnings: [...findingMessages, ...warnings] };
343
374
  }
@@ -15,8 +15,9 @@
15
15
  * logs, because both callers treat "no usable version" as "keep using the local
16
16
  * copy" rather than as an error worth reporting to the user.
17
17
  */
18
+ import { MCP_PACKAGE_NAME } from "./mcp-identity.js";
18
19
  /** The npm registry endpoint carrying the latest published release metadata. */
19
- export const NPM_LATEST_ENDPOINT = "https://registry.npmjs.org/@bridge_gpt/mcp-server/latest";
20
+ export const NPM_LATEST_ENDPOINT = `https://registry.npmjs.org/${MCP_PACKAGE_NAME}/latest`;
20
21
  /**
21
22
  * Hard bound on the registry lookup. Owned here rather than duplicated at each
22
23
  * call site: `install` is a first-time user's very first contact with Bridge, so