@bridge_gpt/mcp-server 0.2.66 → 0.2.68

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 (171) hide show
  1. package/README.md +421 -83
  2. package/build/agent-capabilities/probes.js +15 -5
  3. package/build/agent-launchers/claude-executor-adapter.js +70 -16
  4. package/build/agent-launchers/executor-adapter.js +7 -4
  5. package/build/agents.generated.js +22 -2
  6. package/build/bitbucket-workspace-remote.js +136 -0
  7. package/build/bootstrap-project-identity.js +24 -0
  8. package/build/bounded-wait.js +67 -10
  9. package/build/bridge-permissions.js +829 -0
  10. package/build/claude-settings.js +18 -0
  11. package/build/cli-help.js +21 -0
  12. package/build/command-assets-doctor.js +24 -70
  13. package/build/command-provisioning.js +29 -5
  14. package/build/commands.generated.js +12 -12
  15. package/build/conductor/bridge-api-client.js +857 -1
  16. package/build/conductor/bring-up-facts.js +1 -1
  17. package/build/conductor/command-drift-production.js +92 -0
  18. package/build/conductor/command-drift.js +89 -0
  19. package/build/conductor/doctor.js +72 -29
  20. package/build/conductor/epic-branch-ci-inspection.js +1375 -0
  21. package/build/conductor/epic-implementer-cli.js +98 -28
  22. package/build/conductor/errors.js +4 -3
  23. package/build/conductor/gate-discovery.js +890 -0
  24. package/build/conductor/guided-repair.js +6 -2
  25. package/build/conductor/hook-runtime-qualification.js +1 -1
  26. package/build/conductor/install-doctor.js +15 -3
  27. package/build/conductor/json-output.js +63 -0
  28. package/build/conductor/merge-execution-contract.js +27 -8
  29. package/build/conductor/merge-execution-eligibility.js +3 -2
  30. package/build/conductor/pr-ci-producer.js +1 -1
  31. package/build/conductor/readiness-cli.js +113 -12
  32. package/build/conductor/readiness-sections.js +410 -9
  33. package/build/conductor/readiness.js +388 -33
  34. package/build/conductor/recovery-cli.js +310 -12
  35. package/build/conductor/recovery-operations.js +167 -3
  36. package/build/conductor/repair-contract.js +54 -3
  37. package/build/conductor/repository-workflow-remedy.js +125 -0
  38. package/build/conductor/tools.js +2 -2
  39. package/build/conductor-bundle-artifacts.js +8 -0
  40. package/build/connect-bitbucket-api.js +41 -6
  41. package/build/connect-bitbucket.js +106 -33
  42. package/build/credential-store.js +207 -47
  43. package/build/docs.generated.js +62 -3
  44. package/build/doctor.js +92 -1
  45. package/build/drive-epic-key.js +6 -5
  46. package/build/drive-epic.js +129 -61
  47. package/build/epic-coherence-input.js +2 -1
  48. package/build/epic-coherence-input.test-fixtures.js +4 -3
  49. package/build/epic-implementer-bin.js +1379 -28
  50. package/build/epic-implementer-bundle-cli.js +2 -2
  51. package/build/epic-workarounds-path.js +39 -0
  52. package/build/executor/cli.js +33 -2
  53. package/build/executor/completion-contract.js +66 -10
  54. package/build/executor/completion-supervision.js +4 -0
  55. package/build/executor/deps.js +4 -1
  56. package/build/executor/env.js +19 -0
  57. package/build/executor/gate-qualification-job.js +499 -0
  58. package/build/executor/guarded-fast-forward-push.js +129 -0
  59. package/build/executor/heartbeat.js +1 -1
  60. package/build/executor/http-client.js +20 -0
  61. package/build/executor/integration-job.js +122 -8
  62. package/build/executor/job-errors.js +33 -1
  63. package/build/executor/job-runner.js +813 -87
  64. package/build/executor/likely-tests.js +290 -0
  65. package/build/executor/live-worker-registry.js +1 -1
  66. package/build/executor/observation.js +37 -3
  67. package/build/executor/packaged-recipe.js +106 -0
  68. package/build/executor/permissions.js +115 -28
  69. package/build/executor/platform.js +1 -1
  70. package/build/executor/preflight.js +112 -26
  71. package/build/executor/process-containment.js +36 -12
  72. package/build/executor/process.js +15 -7
  73. package/build/executor/prompt-spec.js +33 -1
  74. package/build/executor/recently-failed-tests-file.js +71 -0
  75. package/build/executor/reconcile-overlap-job.js +41 -23
  76. package/build/executor/required-verification.js +1 -1
  77. package/build/executor/required-work-ledger.js +111 -18
  78. package/build/executor/resume-pre-spawn.js +2 -0
  79. package/build/executor/retirement.js +69 -0
  80. package/build/executor/runner.js +122 -13
  81. package/build/executor/service-unit.js +7 -1
  82. package/build/executor/test-clock.js +15 -0
  83. package/build/executor/types.js +32 -0
  84. package/build/executor/viewer-tabs.js +58 -8
  85. package/build/executor/worker-command.js +23 -7
  86. package/build/executor/worker-diagnostics.js +37 -0
  87. package/build/executor/worker-finalization.js +113 -34
  88. package/build/executor/worker-guard-hook.js +316 -58
  89. package/build/executor/worker-log.js +4 -3
  90. package/build/executor/worker-verification-guidance.js +37 -0
  91. package/build/executor/worktree.js +166 -8
  92. package/build/first-build-advisory.js +97 -0
  93. package/build/generated-assets-advisory.js +14 -0
  94. package/build/generated-assets-catalog.js +66 -0
  95. package/build/generated-assets-context.js +46 -0
  96. package/build/generated-assets-dependencies.js +26 -0
  97. package/build/generated-assets-doctor.js +50 -0
  98. package/build/generated-assets-health.js +65 -0
  99. package/build/generated-assets-host.js +17 -0
  100. package/build/generated-assets-inventory.js +17 -0
  101. package/build/generated-assets-paths.js +60 -0
  102. package/build/generated-assets-publisher.js +133 -0
  103. package/build/generated-assets-remedy.js +25 -0
  104. package/build/generated-assets-repair.js +72 -0
  105. package/build/generated-assets-session.js +71 -0
  106. package/build/generated-assets-test-support.js +35 -0
  107. package/build/index.js +1224 -1054
  108. package/build/init.js +54 -177
  109. package/build/install-bridge-conductor-gate.js +1372 -0
  110. package/build/install-bridge-conductor.js +296 -41
  111. package/build/install-bridge.js +547 -40
  112. package/build/mcp-install-state.js +50 -4
  113. package/build/merge-workflow-install.js +3 -4
  114. package/build/phase-context-git-probe.js +68 -0
  115. package/build/phase-result-artifacts.js +173 -5
  116. package/build/pipeline-utils.js +6 -2
  117. package/build/pipelines.generated.js +34 -160
  118. package/build/plan-execution-ledger.js +2 -32
  119. package/build/plane/alembic-head.js +12 -3
  120. package/build/plane/base-worktree-guard.js +147 -0
  121. package/build/plane/cli.js +217 -17
  122. package/build/plane/code-snapshot.js +468 -0
  123. package/build/plane/defaults.js +48 -3
  124. package/build/plane/endpoint.js +41 -0
  125. package/build/plane/manifest.js +136 -2
  126. package/build/plane/member-roster.js +94 -19
  127. package/build/plane/preflight.js +83 -2
  128. package/build/plane/process-cwd.js +67 -0
  129. package/build/plane/restart.js +542 -0
  130. package/build/plane/shutdown.js +31 -0
  131. package/build/plane/status.js +143 -8
  132. package/build/plane/supervisor.js +586 -179
  133. package/build/plane/types.js +54 -2
  134. package/build/printed-remedy-commands.js +52 -0
  135. package/build/readiness-check.js +1 -1
  136. package/build/readme.generated.js +1 -1
  137. package/build/repair-assets.js +93 -0
  138. package/build/review-generation.js +22 -0
  139. package/build/run-unit-tests-launcher.js +130 -49
  140. package/build/secret-redaction.js +33 -0
  141. package/build/setup-epic.js +152 -22
  142. package/build/sfcc/config.js +9 -0
  143. package/build/sfcc/credentials.js +100 -38
  144. package/build/sfcc/hostname.js +67 -0
  145. package/build/sfcc/permissions.js +17 -13
  146. package/build/sfcc/register.js +1 -1
  147. package/build/sfcc/tool-wrapper.js +39 -43
  148. package/build/sfcc/write-grants.js +17 -11
  149. package/build/sfcc/write-result.js +4 -3
  150. package/build/sfcc/writes-site-preference.js +20 -8
  151. package/build/start-tickets-prereqs.js +70 -16
  152. package/build/start-tickets.js +208 -36
  153. package/build/tool-error-envelope.js +61 -0
  154. package/build/tool-surface-gating.js +36 -0
  155. package/build/upgrade-cli.js +55 -1
  156. package/build/version.generated.js +3 -3
  157. package/build/visual-diff.js +22 -1
  158. package/build/worker-guard-hook-bin.js +4 -6
  159. package/build/worker-guard-hook-main.js +47 -0
  160. package/build/worktree-core.js +145 -6
  161. package/docs/EPIC-IMPLEMENTER-INSTALL.md +867 -0
  162. package/docs/EPIC-IMPLEMENTER.md +728 -0
  163. package/docs/install/mcp-tool-integrations.md +24 -15
  164. package/docs/install/sfcc-integration.md +12 -4
  165. package/package.json +3 -3
  166. package/pipelines/greenfield-setup.json +4 -128
  167. package/pipelines/implement-ticket.json +3 -2
  168. package/pipelines/plan-epic.json +0 -5
  169. package/pipelines/review-ticket.json +1 -1
  170. package/docs/CONDUCTOR.md +0 -605
  171. package/pipelines/idea-to-pr.json +0 -49
@@ -6,8 +6,8 @@
6
6
  * a hole in the roster (a member that crashed and was deliberately not
7
7
  * restarted) is precisely what this command exists to *show*.
8
8
  */
9
- import { planeManifestLifecycle, probeManifestMembers, readPlaneManifest, } from "./manifest.js";
10
- import { PLANE_RUNTIME_DIR, PLANE_RUNTIME_LOG_PATH, } from "./types.js";
9
+ import { planeManifestLifecycle, planeManifestSnapshot, probeManifestMembers, readPlaneManifest, } from "./manifest.js";
10
+ import { PLANE_RESTART_MIN_SCHEMA_VERSION, PLANE_RUNTIME_DIR, PLANE_RUNTIME_LOG_PATH, } from "./types.js";
11
11
  import { WORKER_STALE_EXIT_CODE } from "./worker-exit-code.js";
12
12
  /** Read the manifest and probe every recorded pid. Strictly read-only. */
13
13
  export async function getPlaneStatus(repoRoot, deps) {
@@ -35,6 +35,8 @@ export async function getPlaneStatus(repoRoot, deps) {
35
35
  unrecognizedMemberNames: read.unrecognizedMemberNames,
36
36
  lifecycle: planeManifestLifecycle(manifest),
37
37
  epicRunId: manifest.epicRunId ?? null,
38
+ snapshot: planeManifestSnapshot(manifest),
39
+ restartSupported: manifest.schemaVersion >= PLANE_RESTART_MIN_SCHEMA_VERSION,
38
40
  createdAt: manifest.createdAt,
39
41
  updatedAt: manifest.updatedAt,
40
42
  members: probeManifestMembers(manifest, deps.proc).map((probe) => ({
@@ -45,6 +47,10 @@ export async function getPlaneStatus(repoRoot, deps) {
45
47
  exitCode: probe.member.exitCode,
46
48
  exitSignal: probe.member.exitSignal,
47
49
  logPath: probe.member.logPath,
50
+ ...(probe.member.cwd !== undefined ? { cwd: probe.member.cwd } : {}),
51
+ ...(probe.member.restartFailure !== undefined
52
+ ? { restartFailure: probe.member.restartFailure }
53
+ : {}),
48
54
  })),
49
55
  };
50
56
  }
@@ -78,7 +84,19 @@ function describeLifecycle(phase) {
78
84
  "left running; nothing is claiming jobs. Wind it down with `plane down`.");
79
85
  }
80
86
  }
81
- /** One line per member: name, state, exit status where known, log path. */
87
+ /**
88
+ * Render a status result.
89
+ *
90
+ * The ORDER is the design (BAPI-1362): lifecycle and the bound run first, because
91
+ * they say whether touching the plane is safe at all; then the `Code snapshot`
92
+ * section, because what code the members run decides which recovery is safe; then
93
+ * the members, each with a text state and ONE next action. Nothing is carried by
94
+ * colour or by column alignment alone — every row starts with its member name and
95
+ * states its condition in words — so the output survives `TERM=dumb`, a pipe, a
96
+ * narrow terminal, and a screen reader. Long paths and commands are emitted whole
97
+ * on a line of their own rather than truncated, so the terminal wraps them and
98
+ * nothing the operator needs to copy is cut.
99
+ */
82
100
  export function formatPlaneStatus(result) {
83
101
  if (!result.ok)
84
102
  return `plane status FAILED: ${result.error}`;
@@ -93,10 +111,22 @@ export function formatPlaneStatus(result) {
93
111
  ` started ${result.createdAt}`,
94
112
  ` updated ${result.updatedAt}`,
95
113
  "",
114
+ "Code snapshot",
115
+ ...describeSnapshot(result.snapshot, result.restartSupported),
116
+ "",
117
+ "Members",
96
118
  ];
119
+ const context = {
120
+ supervisorLiveness: result.supervisorLiveness,
121
+ restartSupported: result.restartSupported,
122
+ ...(result.snapshot.kind === "pinned" ? { pinnedSha: result.snapshot.snapshot.sha } : {}),
123
+ };
97
124
  for (const member of result.members) {
98
125
  lines.push(` ${member.name.padEnd(12)} ${describeMemberState(member, result.supervisorLiveness)} ` +
99
126
  `${member.logPath}`);
127
+ const next = describeMemberNextAction(member, context);
128
+ if (next !== null)
129
+ lines.push(` next: ${next}`);
100
130
  }
101
131
  if (result.unrecognizedMemberNames.length > 0) {
102
132
  // Never a silent omission. The plane really has more members than the list
@@ -121,14 +151,53 @@ export function formatPlaneStatus(result) {
121
151
  // Members that genuinely ran and exited keep the original no-restart warning;
122
152
  // one that never started was not restarted for an entirely different reason,
123
153
  // and telling the operator to "read the log above" would be a dead end.
124
- const holes = result.members.filter((m) => m.liveness !== "alive" && !neverStarted.includes(m));
154
+ const holes = result.members.filter((m) => m.liveness !== "alive" && !neverStarted.includes(m) && m.state !== "restarting");
125
155
  if (holes.length > 0) {
126
156
  lines.push("");
127
157
  lines.push(`${holes.length} member(s) are not running. They are NOT restarted automatically — ` +
128
- "read the log(s) above, then `plane down` and `plane up` when you have a fix.");
158
+ "read the log(s) above, then use the `next:` action under each member.");
159
+ // A full wind-down is the remedy only when there is no live supervisor left to
160
+ // take a restart request. With one, every restartable member has a scoped fix
161
+ // and recommending `plane down` here would stop a bound run to repair one
162
+ // process.
163
+ if (result.supervisorLiveness !== "alive") {
164
+ lines.push("The supervisor is not running, so nothing can restart a member: wind the plane down " +
165
+ "with `plane down` (it stops the bound run first), then `plane up`.");
166
+ }
129
167
  }
130
168
  return lines.join("\n");
131
169
  }
170
+ /**
171
+ * The `Code snapshot` section's body lines (BAPI-1362).
172
+ *
173
+ * A pinned plane prints the FULL commit id and the complete path — never a
174
+ * shortened id, because this is the value an operator compares against `git
175
+ * rev-parse`. A legacy plane says so in exactly one recognizable phrase and
176
+ * invents nothing.
177
+ */
178
+ function describeSnapshot(snapshot, restartSupported) {
179
+ if (snapshot.kind === "pinned") {
180
+ return [
181
+ ` status Pinned`,
182
+ ` commit ${snapshot.snapshot.sha}`,
183
+ ` path ${snapshot.snapshot.path}`,
184
+ " note The server, worker, and observer run from this commit, so moving your",
185
+ " checkout does not change them. `plane restart <member>` reuses it.",
186
+ " `plane down && plane up` moves the plane to NEW code: use it between",
187
+ " runs, because it stops a bound run.",
188
+ ];
189
+ }
190
+ return [
191
+ " status Unpinned (legacy)",
192
+ " note This plane does not record a code snapshot, so its Python members were",
193
+ " launched from your checkout and follow it when it moves. No pinned",
194
+ " commit or path is reported because none exists.",
195
+ restartSupported
196
+ ? " `plane restart <member>` still works; it reuses each member's original launch."
197
+ : " It was started by an older build, so `plane restart` is unavailable for it.",
198
+ " To move it to new code, use `plane down && plane up` between runs (it stops a bound run).",
199
+ ];
200
+ }
132
201
  /**
133
202
  * True for a member the manifest still records as pre-spawn.
134
203
  *
@@ -140,19 +209,33 @@ function isPreStart(member) {
140
209
  return member.state === "spawning" && member.pid === null;
141
210
  }
142
211
  export function describeMemberState(member, supervisorLiveness) {
212
+ // A restart in progress or a failed restart is the operator's own action, not a
213
+ // crash, and is worded as such (BAPI-1362). Both are read BEFORE the exit
214
+ // branches below, because a failed restart may record an exit status too.
215
+ if (member.state === "restarting") {
216
+ return `restarting (replacing pid ${member.pid ?? "?"}; status may change shortly)`.padEnd(34);
217
+ }
218
+ if (member.restartFailure !== undefined) {
219
+ const process = member.liveness === "alive" ? `replacement pid ${member.pid ?? "?"} still running` : "no process running";
220
+ return `restart FAILED (${member.restartFailure}; ${process})`.padEnd(34);
221
+ }
143
222
  // Precedence below is unchanged and load-bearing: a live pid, then a recorded
144
223
  // signal, then a recorded code, then unverifiable liveness. The pre-start
145
224
  // cases are appended after all four, so they can only ever claim a member
146
225
  // about which nothing else is known.
147
226
  if (member.liveness === "alive") {
148
- return `running (pid ${member.pid ?? "?"})`.padEnd(34);
227
+ // `ready` is the manifest's record that the member passed its readiness gate;
228
+ // `running` alone means it was spawned and the gate was not (yet) confirmed.
229
+ const readiness = member.state === "ready" ? "ready" : "readiness not confirmed";
230
+ return `running (pid ${member.pid ?? "?"}, ${readiness})`.padEnd(34);
149
231
  }
150
232
  if (member.exitSignal !== null) {
151
233
  return `exited (signal ${member.exitSignal})`.padEnd(34);
152
234
  }
153
235
  if (member.exitCode !== null) {
154
- if ((member.name === "worker" || member.name === "observer") && member.exitCode === WORKER_STALE_EXIT_CODE) {
155
- return `exited (code 75: code changed; cycle the plane)`.padEnd(34);
236
+ if ((member.name === "worker" || member.name === "observer") &&
237
+ member.exitCode === WORKER_STALE_EXIT_CODE) {
238
+ return `exited (code 75: code on disk changed)`.padEnd(34);
156
239
  }
157
240
  return `exited (code ${member.exitCode})`.padEnd(34);
158
241
  }
@@ -172,3 +255,55 @@ export function describeMemberState(member, supervisorLiveness) {
172
255
  }
173
256
  return `exited (no recorded exit status)`.padEnd(34);
174
257
  }
258
+ /**
259
+ * The single safest next action for one member, or null when none is needed
260
+ * (BAPI-1362).
261
+ *
262
+ * Scoped by design. A restartable member that is down gets `plane restart
263
+ * <member>` — which replaces only that member and leaves the pinned commit and
264
+ * the bound run alone. An executor lane gets run-level recovery, because
265
+ * per-member restart is unavailable for it and `plane restart executor-N` would
266
+ * be refused. `plane down && plane up` is named only where it is genuinely the
267
+ * remedy: no live supervisor to take a request, or a pinned snapshot that is gone.
268
+ *
269
+ * Pure, and built from fixed prose plus the member name, which `isPlaneMemberName`
270
+ * has already bounded — nothing here can carry a path or a credential.
271
+ */
272
+ export function describeMemberNextAction(member, context) {
273
+ const isExecutor = member.name.startsWith("executor-");
274
+ const down = member.liveness !== "alive" && member.state !== "restarting" && !isPreStart(member);
275
+ const keeps = context.pinnedSha !== undefined
276
+ ? `it keeps the pinned commit ${context.pinnedSha.slice(0, 12)} and the bound run`
277
+ : "it leaves the rest of the plane and the bound run running";
278
+ if (member.state === "restarting") {
279
+ return "a restart is in progress — run `plane status` again shortly; do not start another.";
280
+ }
281
+ if (isExecutor) {
282
+ return down
283
+ ? "per-member restart is unavailable for an executor lane — recover at the run level (re-attach with `drive-epic`)."
284
+ : null;
285
+ }
286
+ if (!down && member.restartFailure === undefined)
287
+ return null;
288
+ if (context.supervisorLiveness !== "alive") {
289
+ return "the supervisor is not running, so this member cannot be restarted — `plane down`, then `plane up`.";
290
+ }
291
+ if (!context.restartSupported) {
292
+ return ("this plane was started by an older build, so `plane restart` is unavailable — " +
293
+ "between runs, `plane down && plane up` moves it to new code (it stops a bound run).");
294
+ }
295
+ switch (member.restartFailure) {
296
+ case "stop-incomplete":
297
+ return `the old process would not exit — inspect ${member.logPath}, then \`plane restart ${member.name}\` again.`;
298
+ case "readiness":
299
+ return (`the replacement did not become ready — inspect ${member.logPath}, then ` +
300
+ `\`plane restart ${member.name}\` again (${keeps}).`);
301
+ case "snapshot":
302
+ return ("the pinned code could not be revalidated — restore it, or between runs " +
303
+ "`plane down && plane up` moves the plane to new code (it stops a bound run).");
304
+ case "spawn":
305
+ return `the replacement could not be started — inspect ${member.logPath}, then \`plane restart ${member.name}\` again.`;
306
+ default:
307
+ return `\`plane restart ${member.name}\` — ${keeps}.`;
308
+ }
309
+ }