@bridge_gpt/mcp-server 0.2.18 → 0.2.19

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 (81) hide show
  1. package/CONDUCTOR.md +75 -0
  2. package/README.md +2 -2
  3. package/build/agent-capabilities/probe-context.js +13 -3
  4. package/build/agent-capabilities/probes.js +262 -11
  5. package/build/agent-capabilities/reporter.js +1 -0
  6. package/build/agents.generated.js +1 -1
  7. package/build/backend-warnings.js +44 -0
  8. package/build/claude-settings.js +129 -0
  9. package/build/commands.generated.js +1 -0
  10. package/build/conductor/bridge-api-client.js +7 -7
  11. package/build/conductor/cli.js +65 -12
  12. package/build/conductor/deny-enforcement-preflight.js +96 -0
  13. package/build/conductor/doctor.js +183 -2
  14. package/build/conductor/epic-reconcile.js +9 -1
  15. package/build/conductor/epic-runtime.js +403 -43
  16. package/build/conductor/epic-state.js +7 -0
  17. package/build/conductor/errors.js +115 -3
  18. package/build/conductor/event-accessors.js +28 -10
  19. package/build/conductor/merge-ledger.js +6 -4
  20. package/build/conductor/pr-ci-producer.js +17 -2
  21. package/build/conductor/producer-ledger.js +1 -1
  22. package/build/conductor/store.js +161 -18
  23. package/build/conductor/supervisor-merge.js +32 -5
  24. package/build/conductor/taxonomy.js +8 -0
  25. package/build/conductor/tools.js +28 -6
  26. package/build/conductor/worker-ledger-cli.js +244 -0
  27. package/build/conductor-bin.js +1884 -6917
  28. package/build/doctor.js +8 -0
  29. package/build/executor/cli.js +229 -0
  30. package/build/executor/credentials.js +65 -0
  31. package/build/executor/deps.js +117 -0
  32. package/build/executor/env.js +79 -0
  33. package/build/executor/heartbeat.js +59 -0
  34. package/build/executor/http-client.js +131 -0
  35. package/build/executor/index.js +10 -0
  36. package/build/executor/job-errors.js +55 -0
  37. package/build/executor/job-log-registry.js +110 -0
  38. package/build/executor/job-runner.js +688 -0
  39. package/build/executor/job-types.js +60 -0
  40. package/build/executor/merge-job.js +155 -0
  41. package/build/executor/observation.js +123 -0
  42. package/build/executor/permissions.js +79 -0
  43. package/build/executor/preflight.js +144 -0
  44. package/build/executor/process.js +81 -0
  45. package/build/executor/prompt-spec.js +235 -0
  46. package/build/executor/results.js +134 -0
  47. package/build/executor/resume-pre-spawn.js +179 -0
  48. package/build/executor/runner.js +98 -0
  49. package/build/executor/terminal-mutation.js +34 -0
  50. package/build/executor/test-clock.js +109 -0
  51. package/build/executor/types.js +18 -0
  52. package/build/executor/verdict-artifact.js +53 -0
  53. package/build/executor/viewer-tabs.js +78 -0
  54. package/build/executor/watch-cli.js +113 -0
  55. package/build/executor/worker-command.js +106 -0
  56. package/build/executor/worker-finalization.js +97 -0
  57. package/build/executor/worker-log.js +92 -0
  58. package/build/executor/worktree-gc.js +134 -0
  59. package/build/executor/worktree-inspection.js +86 -0
  60. package/build/executor/worktree.js +103 -0
  61. package/build/index.js +11222 -8544
  62. package/build/mcp-invoke.js +19 -3
  63. package/build/mcp-provisioning.js +31 -25
  64. package/build/mcp-registration-doctor.js +27 -7
  65. package/build/mcp-server-invocation.js +152 -0
  66. package/build/pipelines.generated.js +1 -1
  67. package/build/readme.generated.js +1 -1
  68. package/build/sfcc/reads-site-preference.js +52 -19
  69. package/build/start-tickets-conductor.js +25 -93
  70. package/build/start-tickets-prereqs.js +152 -1
  71. package/build/start-tickets.js +96 -158
  72. package/build/version.generated.js +1 -1
  73. package/build/visual-diff-worker.js +313 -0
  74. package/build/visual-diff.js +632 -0
  75. package/build/worktree-core.js +202 -0
  76. package/package.json +8 -4
  77. package/public/css/main.min.css +39 -0
  78. package/public/css/main.min.css.map +1 -1
  79. package/public/js/main.min.js +7924 -1
  80. package/public/js/main.min.js.map +1 -1
  81. package/smoke-test/SMOKE-TEST.md +2 -1
@@ -8,8 +8,110 @@
8
8
  * migration, no event emission, and no scheduler unit creation.
9
9
  */
10
10
  import { spawnSync } from "node:child_process";
11
+ import { existsSync, readFileSync } from "node:fs";
11
12
  import { doctorConductorLedger } from "./store.js";
12
13
  import { inspectConductorGitHooks } from "./git-hooks.js";
14
+ import { resolveMcpShimInvocationForRuntime, resolvePackageRootFromModuleUrl, } from "../mcp-server-invocation.js";
15
+ /**
16
+ * Explicit not-run state for the `deny_enforcement` section when the probe is
17
+ * skipped via `--no-deny-probe`. Enforcement is UNVERIFIED, so the state is
18
+ * fail-safe: `enforced: false` with `status: "skip"` distinguishing a deliberate
19
+ * skip from a probed FATAL failure.
20
+ */
21
+ export function skippedDenyEnforcementResult() {
22
+ return {
23
+ enforced: false,
24
+ layer: "none",
25
+ degraded: true,
26
+ status: "skip",
27
+ detail: "deny-enforcement preflight skipped via --no-deny-probe (no agent spawned)",
28
+ warnings: [
29
+ "Deny-enforcement preflight was SKIPPED (--no-deny-probe): enforcement is UNVERIFIED " +
30
+ "on this host. Do not treat this report as evidence the deny layer works.",
31
+ ],
32
+ };
33
+ }
34
+ /**
35
+ * Default reader for the package.json text (BAPI-526). Resolves the package root
36
+ * from this module's URL and reads `<packageRoot>/package.json`. Throws internally
37
+ * when the root cannot be resolved so the caller degrades to `engines_node: null`.
38
+ */
39
+ export async function defaultReadPackageJson() {
40
+ const packageRoot = resolvePackageRootFromModuleUrl(import.meta.url);
41
+ if (!packageRoot) {
42
+ throw new Error("unable to resolve package root for package.json");
43
+ }
44
+ return readFileSync(`${packageRoot}/package.json`, "utf8");
45
+ }
46
+ /**
47
+ * Parse package.json text and return `engines.node` when it is a string; `null`
48
+ * otherwise. Never throws on malformed JSON — returns `null`.
49
+ */
50
+ export function readExpectedNodeEngine(packageJsonText) {
51
+ try {
52
+ const pkg = JSON.parse(packageJsonText);
53
+ const node = pkg.engines?.node;
54
+ return typeof node === "string" ? node : null;
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
60
+ /**
61
+ * Build the read-only native-ledger inspection (BAPI-526). Composes the ledger
62
+ * doctor's native-load result with the expected Node engine and the resolved MCP
63
+ * shim invocation. Never opens the ledger, never throws to callers, and never
64
+ * includes raw package paths, stack traces, or the absolute server entry path.
65
+ */
66
+ export async function inspectNativeLedger(nativeLoad, deps = {}) {
67
+ const warnings = [];
68
+ // Expected Node engine (fail-soft to null on any read/parse failure).
69
+ let engines_node = null;
70
+ try {
71
+ const readPkg = deps.readPackageJson ?? defaultReadPackageJson;
72
+ engines_node = readExpectedNodeEngine(await readPkg());
73
+ }
74
+ catch {
75
+ engines_node = null;
76
+ }
77
+ // MCP shim invocation (resolvable absolute-build-path vs npm-channel fallback).
78
+ const invocation = deps.resolveMcpInvocation
79
+ ? deps.resolveMcpInvocation()
80
+ : resolveMcpShimInvocationForRuntime({
81
+ moduleUrl: import.meta.url,
82
+ nodeExecutable: "node",
83
+ argv1: process.argv[1],
84
+ fileExists: existsSync,
85
+ });
86
+ // Path-safe: expose only the node executable for the absolute form (never the
87
+ // server entry path), and null for the npm-channel fallback.
88
+ const mcp_shim_node = invocation.form === "absolute-build-path" ? invocation.nodeExecutable : null;
89
+ const binding_loads = nativeLoad.loads;
90
+ const failure_kind = nativeLoad.failure_kind;
91
+ if (nativeLoad.degraded && nativeLoad.warning) {
92
+ warnings.push(nativeLoad.warning);
93
+ }
94
+ if (invocation.form !== "absolute-build-path") {
95
+ warnings.push("Worker MCP registration would use the npm-channel fallback (no resolvable on-disk build entry); " +
96
+ "registration reliability depends on the package being published.");
97
+ }
98
+ if (engines_node === null) {
99
+ warnings.push("Could not read package.json engines.node; expected Node version is unknown.");
100
+ }
101
+ const degraded = nativeLoad.degraded || invocation.form !== "absolute-build-path" || engines_node === null;
102
+ return {
103
+ cli_node_version: process.version,
104
+ engines_node,
105
+ mcp_shim_node,
106
+ mcp_registration_form: invocation.form,
107
+ module: nativeLoad.module,
108
+ node_modules_abi: nativeLoad.node_modules_abi,
109
+ binding_loads,
110
+ failure_kind,
111
+ degraded,
112
+ warnings,
113
+ };
114
+ }
13
115
  /**
14
116
  * Inspect the local schedule metadata store for a registered epic-tick schedule.
15
117
  * Strictly read-only: composes orchestrateScheduleList (read-only list path) and
@@ -175,21 +277,58 @@ export async function buildConductorDoctorReport(deps = {}) {
175
277
  const inspectHooks = deps.inspectHooks ?? inspectConductorGitHooks;
176
278
  const epicTick = await inspectEpicTickSchedule(deps.scheduleDeps, deps.orchestrateList);
177
279
  const mcp_profile = inspectMcpProfile(deps.env ?? process.env, epicTick);
280
+ // Resolve the ledger once so the native-load probe reflects the same report.
281
+ const ledger = await doctorLedger();
282
+ const native_ledger = await inspectNativeLedger(ledger.native_load, deps);
283
+ const deny_enforcement = deps.skipDenyProbe
284
+ ? skippedDenyEnforcementResult()
285
+ : await inspectDenyEnforcementSafe(deps.inspectDenyEnforcement);
178
286
  return {
179
- ledger: await doctorLedger(),
287
+ ledger,
180
288
  git_hooks: inspectHooks(deps.hooksDeps),
181
289
  epic_tick: epicTick,
182
290
  mcp_profile,
183
291
  local_merge: inspectLocalMerge(deps.runCommand),
292
+ native_ledger,
293
+ deny_enforcement,
184
294
  };
185
295
  }
296
+ /**
297
+ * Run the deny-enforcement inspector and convert any thrown exception into degraded
298
+ * report data — a deny-probe failure must never throw out of doctor. The underlying
299
+ * predicate is already exception-safe; this is defense-in-depth for an injected fake.
300
+ */
301
+ async function inspectDenyEnforcementSafe(inspect) {
302
+ try {
303
+ let run = inspect;
304
+ if (!run) {
305
+ // Lazy import keeps the agent-capabilities graph out of doctor.ts's static
306
+ // module graph (see the import-site comment above).
307
+ const mod = await import("./deny-enforcement-preflight.js");
308
+ run = mod.runDenyEnforcementPreflight;
309
+ }
310
+ return await run();
311
+ }
312
+ catch (err) {
313
+ const msg = err instanceof Error ? err.message : String(err);
314
+ return {
315
+ enforced: false,
316
+ layer: "none",
317
+ degraded: true,
318
+ warnings: [
319
+ `Deny-layer enforcement inspection failed: ${msg}`,
320
+ "The executor claim loop MUST refuse to claim jobs until the deny layer is enforced.",
321
+ ],
322
+ };
323
+ }
324
+ }
186
325
  /**
187
326
  * Render the combined doctor report as human-readable text: ledger health,
188
327
  * git hooks section, and an Epic Supervisor Schedule section using semantic
189
328
  * status tags consistent with the git hooks section's visual hierarchy.
190
329
  */
191
330
  export function formatConductorDoctorReport(report) {
192
- const { ledger, git_hooks, epic_tick, mcp_profile, local_merge } = report;
331
+ const { ledger, git_hooks, epic_tick, mcp_profile, local_merge, native_ledger, deny_enforcement } = report;
193
332
  const lines = [
194
333
  "Conductor ledger doctor",
195
334
  "───────────────────────",
@@ -270,5 +409,47 @@ export function formatConductorDoctorReport(report) {
270
409
  for (const w of local_merge.warnings)
271
410
  lines.push(` - ${w}`);
272
411
  }
412
+ lines.push("");
413
+ lines.push("Native ledger module (required for conductor coordination)");
414
+ lines.push("─────────────────────────────────────────────────────────");
415
+ const nativeTag = native_ledger.binding_loads && !native_ledger.degraded ? "[OK]" : "[WARNING] degraded";
416
+ // Strictly diagnostic — reports the skew but never suggests an automatic
417
+ // install/rebuild/migration (BAPI-526 is detection only).
418
+ lines.push(`binding loads: ${native_ledger.binding_loads} ${nativeTag}`);
419
+ lines.push(`module: ${native_ledger.module}`);
420
+ lines.push(`CLI Node: ${native_ledger.cli_node_version}`);
421
+ lines.push(`engines.node: ${native_ledger.engines_node ?? "n/a"}`);
422
+ lines.push(`MCP shim Node: ${native_ledger.mcp_shim_node ?? "n/a"}`);
423
+ lines.push(`NODE_MODULE_VERSION: ${native_ledger.node_modules_abi}`);
424
+ lines.push(`registration form: ${native_ledger.mcp_registration_form}`);
425
+ lines.push(`failure kind: ${native_ledger.failure_kind}`);
426
+ lines.push(`degraded: ${native_ledger.degraded}`);
427
+ if (native_ledger.warnings.length > 0) {
428
+ lines.push("native ledger warnings:");
429
+ for (const w of native_ledger.warnings)
430
+ lines.push(` - ${w}`);
431
+ }
432
+ lines.push("");
433
+ lines.push("Deny-layer enforcement preflight (required for executor claim)");
434
+ lines.push("─────────────────────────────────────────────────────────────");
435
+ // OK when enforced by settings-deny (non-degraded); WARNING when relying on the
436
+ // PreToolUse fallback; SKIPPED when the probe was deliberately not run
437
+ // (--no-deny-probe, enforcement unverified); FATAL when nothing enforces — the
438
+ // executor must refuse to claim.
439
+ const denyTag = deny_enforcement.status === "skip"
440
+ ? "[SKIPPED] probe not run (--no-deny-probe) — enforcement unverified"
441
+ : !deny_enforcement.enforced
442
+ ? "[FATAL] deny not enforced — executor must refuse to claim jobs"
443
+ : deny_enforcement.degraded
444
+ ? "[WARNING] degraded — relying on PreToolUse fallback"
445
+ : "[OK]";
446
+ lines.push(`enforced: ${deny_enforcement.enforced} ${denyTag}`);
447
+ lines.push(`layer: ${deny_enforcement.layer}`);
448
+ lines.push(`degraded: ${deny_enforcement.degraded}`);
449
+ if (deny_enforcement.warnings.length > 0) {
450
+ lines.push("deny enforcement warnings:");
451
+ for (const w of deny_enforcement.warnings)
452
+ lines.push(` - ${w}`);
453
+ }
273
454
  return lines.join("\n");
274
455
  }
@@ -78,7 +78,15 @@ export async function reconcileEpic(access, observed, plan, deps, supervisorConf
78
78
  deps.log(`[epic-reconcile] folded ${signal.signal_type} for ${signal.ticket_key} → ${signal.next_status}`);
79
79
  // BAPI-442: fire teardown + Jira transition strictly after merge.succeeded
80
80
  // CAS → done. Both are fail-open: errors are logged and never abort the pass.
81
- if (signal.signal_type === "merge.succeeded") {
81
+ // BAPI-527: additionally require next_status === "done". Post-merge parse
82
+ // (parse-after-merge) folds a merge.succeeded signal to `parse_pending` while
83
+ // the repository re-index runs, and to `blocked` on permanent parse failure —
84
+ // teardown/Jira transition must NOT fire in either of those non-done folds, or
85
+ // the merged branch/worktree would be torn down (and Jira transitioned) before
86
+ // the ticket is truly done. They fire only once the ticket actually reaches
87
+ // `done` (either an immediate merge.succeeded fold when parse-after-merge is
88
+ // off, or the later parse-success fold that re-tags next_status back to "done").
89
+ if (signal.signal_type === "merge.succeeded" && signal.next_status === "done") {
82
90
  if (supervisorConfig?.teardown_enabled && deps.teardownSeam) {
83
91
  await deps.teardownSeam(observed.epic_key, signal.ticket_key).catch((e) => {
84
92
  const safeMsg = e instanceof Error ? e.constructor.name : "teardown error";