@bridge_gpt/mcp-server 0.2.41 → 0.2.43

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 (88) hide show
  1. package/README.md +330 -191
  2. package/build/agent-capabilities/cli.js +2 -1
  3. package/build/agent-launchers/claude-executor-adapter.js +17 -4
  4. package/build/agents.generated.js +2 -2
  5. package/build/claude-review-workflow.js +510 -45
  6. package/build/claude-user-config-doctor.js +42 -11
  7. package/build/cli-release.js +2 -1
  8. package/build/commands.generated.js +6 -5
  9. package/build/conduct-epic/bridge-client.js +354 -113
  10. package/build/conduct-epic/checkpoint-store.js +17 -0
  11. package/build/conduct-epic/cli.js +947 -99
  12. package/build/conduct-epic/cut-protocol.js +327 -0
  13. package/build/conduct-epic/spawn.js +14 -2
  14. package/build/conductor/bridge-api-client.js +148 -1
  15. package/build/conductor/cli.js +109 -1
  16. package/build/conductor/doctor.js +101 -16
  17. package/build/conductor/epic-reconcile.js +72 -19
  18. package/build/conductor/epic-runtime.js +15 -3
  19. package/build/conductor/errors.js +47 -0
  20. package/build/conductor/git-hooks.js +205 -11
  21. package/build/conductor/install-doctor.js +230 -1
  22. package/build/conductor/local-merge.js +130 -28
  23. package/build/conductor/recovery-cli.js +313 -0
  24. package/build/conductor/recovery-operations.js +219 -0
  25. package/build/conductor/tools.js +32 -3
  26. package/build/conductor/worker-ledger-cli.js +27 -1
  27. package/build/conductor-bin.js +20 -16
  28. package/build/credentials-cli.js +3 -2
  29. package/build/docs.generated.js +2 -1
  30. package/build/doctor.js +120 -44
  31. package/build/drive-epic.js +375 -0
  32. package/build/executor/cli.js +48 -1
  33. package/build/executor/env.js +21 -0
  34. package/build/executor/http-client.js +71 -3
  35. package/build/executor/index-scope.js +39 -0
  36. package/build/executor/job-errors.js +9 -0
  37. package/build/executor/job-log-registry.js +69 -0
  38. package/build/executor/job-runner.js +198 -29
  39. package/build/executor/live-worker-registry.js +83 -0
  40. package/build/executor/observation.js +259 -6
  41. package/build/executor/platform.js +147 -3
  42. package/build/executor/process.js +58 -14
  43. package/build/executor/runner.js +454 -48
  44. package/build/executor/test-clock.js +3 -2
  45. package/build/executor/worker-finalization.js +233 -56
  46. package/build/executor/worktree.js +8 -1
  47. package/build/index-scope-contract.js +96 -0
  48. package/build/index.js +2277 -270
  49. package/build/init.js +83 -22
  50. package/build/install-bridge-conductor.js +323 -14
  51. package/build/install-bridge.js +225 -47
  52. package/build/install-doctor.js +23 -9
  53. package/build/install-reexec.js +2 -1
  54. package/build/launcher-config-inspection.js +83 -22
  55. package/build/mcp-host-config.js +331 -67
  56. package/build/mcp-host-targets.js +45 -21
  57. package/build/mcp-identity.js +92 -0
  58. package/build/mcp-install-state.js +94 -1
  59. package/build/mcp-invoke.js +2 -1
  60. package/build/mcp-provisioning.js +45 -12
  61. package/build/mcp-registration-doctor.js +35 -13
  62. package/build/mcp-server-invocation.js +4 -2
  63. package/build/merge-pull-request.js +208 -9
  64. package/build/pipelines.generated.js +305 -15
  65. package/build/plane/cli.js +73 -7
  66. package/build/plane/defaults.js +18 -5
  67. package/build/plane/manifest.js +90 -0
  68. package/build/plane/preflight.js +100 -10
  69. package/build/plane/shutdown.js +71 -3
  70. package/build/plane/test-fakes.js +9 -1
  71. package/build/readme.generated.js +1 -1
  72. package/build/regression-check.js +3 -2
  73. package/build/review-tickets.js +8 -7
  74. package/build/run-unit-tests-launcher.js +149 -6
  75. package/build/schedule-run.js +3 -2
  76. package/build/setup-epic.js +531 -82
  77. package/build/sfcc/tool-wrapper.js +15 -0
  78. package/build/start-tickets-prereqs.js +11 -6
  79. package/build/start-tickets.js +91 -85
  80. package/build/update-check.js +3 -2
  81. package/build/upgrade-advice.js +2 -1
  82. package/build/upgrade-cli.js +50 -18
  83. package/build/version.generated.js +2 -1
  84. package/build/worktree-core.js +31 -17
  85. package/docs/CONDUCTOR.md +22 -0
  86. package/docs/install/mcp-tool-integrations.md +19 -3
  87. package/package.json +2 -2
  88. package/pipelines/greenfield-setup.json +286 -0
@@ -22,27 +22,34 @@
22
22
  * carries config bodies, `env` maps, credential values, or raw error text.
23
23
  */
24
24
  import path from "path";
25
- /** The npm package every Bridge launcher spec names. */
26
- export const BRIDGE_PACKAGE_NAME = "@bridge_gpt/mcp-server";
25
+ import { getProjectJsonTargets, hostAdapterForTarget } from "./mcp-host-targets.js";
26
+ import { LEGACY_SERVER_NAMES, MCP_SERVER_NAME, MCP_PACKAGE_NAME, resolveRegistrationKey, } from "./mcp-identity.js";
27
+ /**
28
+ * The npm package every Bridge launcher spec names. Retained as a compatibility
29
+ * alias — `doctor.ts` still imports this name — assigned from the shared
30
+ * constant so there is no duplicate package-name literal.
31
+ */
32
+ export const BRIDGE_PACKAGE_NAME = MCP_PACKAGE_NAME;
27
33
  /**
28
34
  * The subcommand token that marks a worktree shim registration. A shim points at
29
35
  * a sibling worktree's server rather than a published package, so no pin applies
30
36
  * and no rewrite is ever safe (BAPI-714 / worktree provisioning).
31
37
  */
32
38
  const WORKTREE_SHIM_TOKEN = "mcp-invoke";
33
- /** The MCP server entry key every Bridge registration uses. */
34
- export const BRIDGE_ENTRY_KEY = "bridge-api";
35
39
  /**
36
40
  * Every project-local MCP config Bridge registers into. Exported so `doctor`,
37
41
  * `init`, and `upgrade` can no longer drift apart on which paths exist or which
38
42
  * root key each one uses. Callers that need a different *order* should map over
39
43
  * their own list and use {@link launcherTargetFor} for the metadata.
44
+ *
45
+ * Derived from the shared host-target registry's project-scoped JSON targets
46
+ * (Claude Code, Cursor, Copilot VS Code, in that registry order) rather than
47
+ * duplicating each path/root-key pair here.
40
48
  */
41
- export const LAUNCHER_CONFIG_TARGETS = [
42
- { relPath: ".mcp.json", topLevelKey: "mcpServers" },
43
- { relPath: ".cursor/mcp.json", topLevelKey: "mcpServers" },
44
- { relPath: ".vscode/mcp.json", topLevelKey: "servers" },
45
- ];
49
+ export const LAUNCHER_CONFIG_TARGETS = getProjectJsonTargets().map((target) => ({
50
+ relPath: target.relPath,
51
+ topLevelKey: hostAdapterForTarget(target).topLevelKey,
52
+ }));
46
53
  /** Look up a target's metadata by relative path, or `undefined` if unknown. */
47
54
  export function launcherTargetFor(relPath) {
48
55
  return LAUNCHER_CONFIG_TARGETS.find((t) => t.relPath === relPath);
@@ -123,26 +130,52 @@ export function parseLauncherPin(args) {
123
130
  export function isWorktreeShimArgs(args) {
124
131
  return Array.isArray(args) && args.some((a) => a === WORKTREE_SHIM_TOKEN);
125
132
  }
133
+ /**
134
+ * The one sentence every duplicate-registration diagnostic renders (BAPI-807).
135
+ *
136
+ * It names BOTH keys and instructs a manual removal, deliberately without
137
+ * choosing one: Bridge cannot know which registration the user meant to keep,
138
+ * and a wrong guess destroys a working configuration. Exported so `doctor`, the
139
+ * worktree registration probe, and the Claude scope inspector cannot drift into
140
+ * three different wordings for the same fault.
141
+ */
142
+ export const DUPLICATE_REGISTRATION_GUIDANCE = `duplicate Bridge registrations: this config carries both \`${MCP_SERVER_NAME}\` and ` +
143
+ `\`${LEGACY_SERVER_NAMES.join("`, `")}\`. Confirm which registration you want to keep, ` +
144
+ "then remove the unintended entry manually. Bridge will not choose for you.";
126
145
  /** Human-readable text for each reason code (no dynamic content). */
127
146
  const REASON_TEXT = {
128
147
  "file-unreadable": "the file exists but could not be read",
129
148
  "invalid-json": "the file is not valid JSON",
130
149
  "root-not-object": "the JSON root is not an object",
131
150
  "servers-not-object": "the servers section is not an object",
132
- "entry-not-object": "the bridge-api entry is not an object",
133
- "no-package-token": "the bridge-api launcher has no recognizable @bridge_gpt/mcp-server token",
151
+ "entry-not-object": "the Bridge entry is not an object",
152
+ "no-package-token": `the Bridge launcher has no recognizable ${MCP_PACKAGE_NAME} token`,
134
153
  "version-range": "the launcher pin is a version range, which an automated repin must not rewrite",
135
154
  "non-release-specifier": "the launcher pin is a dist-tag or channel, not an exact release",
136
155
  "malformed-version": "the launcher pin is not a valid MAJOR.MINOR.PATCH release",
137
156
  "pinned-ahead-of-target": "the launcher pin is newer than the target version and must not be downgraded",
157
+ "duplicate-registration": DUPLICATE_REGISTRATION_GUIDANCE,
138
158
  };
139
159
  /** Render a reason code as sanitized prose. */
140
160
  export function describeLauncherReason(reason) {
141
161
  return REASON_TEXT[reason];
142
162
  }
143
- /** True for the two actions that must abort a mutation run before any write. */
163
+ /**
164
+ * True for the actions that must abort a mutation run before any write.
165
+ *
166
+ * `duplicate-registration` joins `invalid` and `unsupported` here (BAPI-807) so
167
+ * every existing mutating caller — `init`'s preflight, `upgrade`'s preflight,
168
+ * install — blocks on a both-key config through the gate it already had, rather
169
+ * than each needing its own new branch it might forget.
170
+ */
144
171
  export function isPrerequisiteFailure(inspection) {
145
- return inspection.action === "invalid" || inspection.action === "unsupported";
172
+ return (inspection.action === "invalid" ||
173
+ inspection.action === "unsupported" ||
174
+ inspection.action === "duplicate-registration");
175
+ }
176
+ /** True when this config carries both a canonical and a legacy registration. */
177
+ export function isDuplicateRegistration(inspection) {
178
+ return inspection.action === "duplicate-registration";
146
179
  }
147
180
  /**
148
181
  * True when this target carries a standard launcher whose pin participates in
@@ -156,7 +189,7 @@ export function isApplicableStandardLauncher(inspection) {
156
189
  inspection.action === "normalize-unpinned"));
157
190
  }
158
191
  /**
159
- * Inspect every project-local MCP config's `bridge-api` launcher, read-only.
192
+ * Inspect every project-local MCP config's Bridge launcher, read-only.
160
193
  *
161
194
  * Every target always produces exactly one result, so a caller can render one
162
195
  * line per config without re-deriving which paths it looked at. Only an `ENOENT`
@@ -179,6 +212,8 @@ async function inspectOne(target, options) {
179
212
  targetVersion,
180
213
  spec: null,
181
214
  currentVersion: null,
215
+ registrationKey: null,
216
+ legacyRegistration: false,
182
217
  };
183
218
  let raw;
184
219
  try {
@@ -242,10 +277,26 @@ async function inspectOne(target, options) {
242
277
  reason: "servers-not-object",
243
278
  };
244
279
  }
245
- const entry = isPlainObject(servers)
246
- ? servers[BRIDGE_ENTRY_KEY]
247
- : undefined;
248
- if (entry === undefined) {
280
+ // BAPI-807: WHICH key this config's Bridge entry lives under is resolved once,
281
+ // here, through the shared identity resolver — never assumed to be the
282
+ // canonical name. A legacy `bridge-api` entry is a real, permanently supported
283
+ // registration; treating it as absence is what would make `init` add a second
284
+ // entry beside it.
285
+ const resolution = resolveRegistrationKey(servers);
286
+ if (resolution.state === "conflict") {
287
+ // Both keys present. Gate BEFORE reading either entry: which one is "the"
288
+ // registration is exactly the question a human has to answer, and every
289
+ // downstream classification would have to pick one to proceed.
290
+ return {
291
+ ...base,
292
+ filePresent: true,
293
+ bridgeEntryPresent: true,
294
+ shape: "custom",
295
+ action: "duplicate-registration",
296
+ reason: "duplicate-registration",
297
+ };
298
+ }
299
+ if (resolution.state === "absent") {
249
300
  // A valid host config that simply has no Bridge registration yet. Other
250
301
  // servers in the same file are deliberately not inspected or reported.
251
302
  return {
@@ -256,9 +307,19 @@ async function inspectOne(target, options) {
256
307
  action: "add",
257
308
  };
258
309
  }
310
+ const registrationKey = resolution.key;
311
+ // Every classification below is computed identically for a canonical and a
312
+ // legacy entry — the resolved key changes only which property was read, never
313
+ // the launcher-shape, package-pin, worktree-shim, or readiness verdict.
314
+ const keyed = {
315
+ ...base,
316
+ registrationKey,
317
+ legacyRegistration: resolution.state === "legacy",
318
+ };
319
+ const entry = servers[registrationKey];
259
320
  if (!isPlainObject(entry)) {
260
321
  return {
261
- ...base,
322
+ ...keyed,
262
323
  filePresent: true,
263
324
  bridgeEntryPresent: true,
264
325
  shape: "custom",
@@ -272,7 +333,7 @@ async function inspectOne(target, options) {
272
333
  // package token at all, and must not be misread as an unsupported launcher.
273
334
  if (isWorktreeShimArgs(args)) {
274
335
  return {
275
- ...base,
336
+ ...keyed,
276
337
  filePresent: true,
277
338
  bridgeEntryPresent: true,
278
339
  shape: "worktree-shim",
@@ -282,7 +343,7 @@ async function inspectOne(target, options) {
282
343
  const pin = parseLauncherPin(args);
283
344
  if (!pin) {
284
345
  return {
285
- ...base,
346
+ ...keyed,
286
347
  filePresent: true,
287
348
  bridgeEntryPresent: true,
288
349
  shape: "custom",
@@ -291,7 +352,7 @@ async function inspectOne(target, options) {
291
352
  };
292
353
  }
293
354
  const common = {
294
- ...base,
355
+ ...keyed,
295
356
  filePresent: true,
296
357
  bridgeEntryPresent: true,
297
358
  shape: "standard",