@bridge_gpt/mcp-server 0.2.38 → 0.2.41

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 (85) hide show
  1. package/README.md +189 -14
  2. package/build/agent-capabilities/probe-context.js +2 -1
  3. package/build/agent-launchers/claude-executor-adapter.js +392 -0
  4. package/build/agent-launchers/executor-adapter-inspection.js +163 -0
  5. package/build/agent-launchers/executor-adapter-registry.js +90 -0
  6. package/build/agent-launchers/executor-adapter.js +136 -0
  7. package/build/agent-registry.js +28 -0
  8. package/build/agents.generated.js +1 -1
  9. package/build/claude-login.js +85 -0
  10. package/build/claude-user-config-doctor.js +59 -33
  11. package/build/commands.generated.js +12 -11
  12. package/build/conduct-epic/bridge-client.js +345 -0
  13. package/build/conduct-epic/checkpoint-store.js +479 -0
  14. package/build/conduct-epic/cli.js +1765 -0
  15. package/build/conduct-epic/lock.js +302 -0
  16. package/build/conduct-epic/pr-state.js +286 -0
  17. package/build/conduct-epic/spawn.js +101 -0
  18. package/build/conductor/bridge-api-client.js +37 -2
  19. package/build/conductor/doctor.js +11 -1
  20. package/build/conductor/install-doctor.js +184 -10
  21. package/build/conductor-bin.js +7 -7
  22. package/build/credential-store.js +10 -4
  23. package/build/credentials-cli.js +34 -19
  24. package/build/docs.generated.js +1 -1
  25. package/build/doctor.js +579 -88
  26. package/build/executor/agent-identity.js +32 -0
  27. package/build/executor/cli.js +50 -39
  28. package/build/executor/deps.js +15 -1
  29. package/build/executor/env.js +56 -45
  30. package/build/executor/index.js +9 -1
  31. package/build/executor/install-preflight.js +138 -0
  32. package/build/executor/job-errors.js +200 -0
  33. package/build/executor/job-runner.js +619 -268
  34. package/build/executor/observation.js +165 -0
  35. package/build/executor/permissions.js +163 -36
  36. package/build/executor/platform.js +54 -0
  37. package/build/executor/preflight.js +175 -67
  38. package/build/executor/process.js +39 -7
  39. package/build/executor/runner.js +19 -0
  40. package/build/executor/service-lifecycle.js +269 -0
  41. package/build/executor/service-unit.js +121 -12
  42. package/build/executor/stale-artifacts.js +70 -0
  43. package/build/executor/test-clock.js +188 -24
  44. package/build/executor/worker-command.js +22 -58
  45. package/build/executor/worker-log.js +82 -0
  46. package/build/executor/worktree-lock.js +264 -0
  47. package/build/index.js +527 -357
  48. package/build/install-bridge-conductor.js +376 -38
  49. package/build/install-bridge.js +414 -114
  50. package/build/install-doctor.js +13 -0
  51. package/build/install-reexec.js +5 -3
  52. package/build/mcp-install-state.js +130 -0
  53. package/build/mcp-profile.js +11 -2
  54. package/build/mcp-provisioning.js +15 -0
  55. package/build/merge-pull-request.js +562 -0
  56. package/build/phase-result-artifacts.js +450 -0
  57. package/build/pipeline-orchestrator.js +4 -0
  58. package/build/pipeline-utils.js +16 -0
  59. package/build/pipelines.generated.js +7 -7
  60. package/build/plane/preflight.js +18 -14
  61. package/build/plane/supervisor.js +8 -1
  62. package/build/project-root.js +34 -0
  63. package/build/readme.generated.js +1 -1
  64. package/build/run-unit-tests-launcher.js +36 -9
  65. package/build/setup-epic.js +57 -4
  66. package/build/sfcc/permissions.js +25 -6
  67. package/build/sfcc/reads-site-preference.js +6 -0
  68. package/build/sfcc/register.js +61 -23
  69. package/build/sfcc/registration-inventory.js +89 -0
  70. package/build/sfcc/setup-status.js +18 -34
  71. package/build/sfcc/tool-wrapper.js +294 -17
  72. package/build/sfcc/write-grants.js +33 -1
  73. package/build/sfcc/write-guard.js +41 -12
  74. package/build/sfcc/writes-custom-object-def.js +6 -2
  75. package/build/sfcc/writes-site-preference.js +6 -1
  76. package/build/sfcc/writes-system-object.js +11 -2
  77. package/build/sfcc/writes.js +13 -8
  78. package/build/start-tickets-prereqs.js +25 -15
  79. package/build/start-tickets.js +123 -21
  80. package/build/version.generated.js +1 -1
  81. package/build/worktree-core.js +9 -3
  82. package/docs/install/mcp-tool-integrations.md +54 -9
  83. package/docs/install/sfcc-integration.md +71 -24
  84. package/package.json +3 -3
  85. package/build/executor/worker-config-isolation.js +0 -287
package/README.md CHANGED
@@ -32,8 +32,9 @@ account — it will ask.
32
32
  **Prerequisites**
33
33
 
34
34
  - **Node.js 18 or newer** (`node --version`), which is what provides `npx`.
35
- - **A project directory** — run the command from the folder your editor opens, the
36
- one containing `package.json` or your repository root.
35
+ - **A project directory** — run the command from the folder your editor opens: your
36
+ repository root, the one containing `.git`. No `package.json` is required SFCC
37
+ cartridge repos, Python, Go, Rust, and other non-Node projects work the same way.
37
38
  - **An MCP-capable editor**: Claude Code, GitHub Copilot, Cursor, Windsurf, or
38
39
  OpenAI Codex.
39
40
  - **No Bridge account needed.** The installer can create one for you from just an
@@ -254,7 +255,7 @@ created or spent.
254
255
  | `--repo <name>` | Name the registered repository instead of resolving or asking for it |
255
256
  | `--tools <list>` | Configure specific MCP hosts without the picker (e.g. `claude-code,cursor`) |
256
257
  | `--agent claude\|cursor-agent` | Which agent to open for the final configuration step (default `claude`) |
257
- | `--dry-run` | Preview every step without writing, contacting Bridge, or opening anything |
258
+ | `--dry-run` | Preview every step without writing, contacting Bridge, resolving or prompting for a credential, or opening anything. Genuinely inert: it returns before the project-root prompt, before the repository is resolved, and before any tool-selection prompt, so a value it cannot know locally (an unresolved repository name, an unselected tool) is shown as **not yet known** rather than guessed |
258
259
  | `--force` | Overwrite an existing stored key without asking |
259
260
  | `-h`, `--help` | Full usage |
260
261
 
@@ -269,7 +270,9 @@ different way to arrive, and the installer will not guess between them.
269
270
  The installer configures your editors for you. Do this only if you would rather
270
271
  write the config yourself, or if you use a host it cannot write automatically.
271
272
 
272
- Scaffold the project files without configuring anything:
273
+ Scaffold the project files without configuring anything. Run it from the same
274
+ project root `install` uses — your repository root, the one containing `.git`.
275
+ No `package.json` is required:
273
276
 
274
277
  ```bash
275
278
  npx -y @bridge_gpt/mcp-server --init
@@ -753,9 +756,11 @@ Behind-the-scenes capabilities an agent gains from the MCP tools — mostly invo
753
756
 
754
757
  ## Salesforce B2C Commerce (SFCC) Tools
755
758
 
756
- Salesforce's official MCP server, `@salesforce/b2c-dx-mcp`, covers developer-experience tasks — cartridge deploy, step debugging, docs search, logs/MRT, and SCAPI Custom API scaffolding. As of its current toolset it has no way to *read* the platform's object model, custom objects, or site configuration — exactly the context an AI coding agent needs to write correct Commerce code and to inspect a sandbox before touching it. Bridge's SFCC tools install side-by-side with `b2c-dx-mcp` (they don't duplicate its surface) and close that gap with **read-only OCAPI Data API introspection** of system objects, custom object definitions, and site preferences.
759
+ Salesforce's official MCP server, `@salesforce/b2c-dx-mcp`, covers developer-experience tasks — cartridge deploy, step debugging, docs search, logs/MRT, and SCAPI Custom API scaffolding. As of its current toolset it has no way to *read* the platform's object model, custom objects, or site configuration — exactly the context an AI coding agent needs to write correct Commerce code and to inspect a sandbox before touching it. Bridge's SFCC tools install side-by-side with `b2c-dx-mcp` (they don't duplicate its surface) and close that gap with **OCAPI Data API introspection** of system objects, custom object definitions, and site preferences — plus, behind a separate opt-in, a small set of sandbox-bounded writes.
757
760
 
758
- **v1 is read-only and developer-sandbox-only** no writes, and non-sandbox instances are rejected. Credentials stay local (in `dw.json` or `SFCC_*` env vars) and are never sent to Bridge.
761
+ **Every SFCC tool is restricted to a developer sandbox, and the restriction is checked at invocation time against the hostname your credentials actually resolve to** — not against anything the caller passes in. If `dw.json` or `SFCC_HOSTNAME` names a host Bridge does not recognize as a developer sandbox, every SFCC tool refuses with a `403` before contacting it. See [Sandbox enforcement](#sandbox-enforcement).
762
+
763
+ **Credentials stay local** — in `dw.json` or `SFCC_*` env vars — and are never sent to Bridge. The `sfcc` profile registers read-only tools; the nine destructive write tools require the separate `sfcc-write` opt-in (see [Read and write profiles](#read-and-write-profiles)).
759
764
 
760
765
  For a step-by-step OCAPI client setup guide (including the Business Manager permissions grant), see [docs/install/sfcc-integration.md](./docs/install/sfcc-integration.md).
761
766
 
@@ -780,40 +785,91 @@ The two diagnostic tools (`sfcc_setup_status`, `check_permissions`) are always a
780
785
 
781
786
  Accepted key spellings: `hostname`/`host`, `client-id`/`clientId`/`client_id`, `client-secret`/`clientSecret`/`client_secret`. Prefer a single config — a multi-entry `configs[]` array forces you to pass an explicit `instance` on every call. `dw.json` is auto-added to git exclude and must never be committed. Alternatively, export `SFCC_HOSTNAME` / `SFCC_CLIENT_ID` / `SFCC_CLIENT_SECRET` in the MCP server environment.
782
787
 
783
- **3. Enable the read tools.** Add `sfcc` to `BRIDGE_MCP_PROFILE` in the MCP server `env` block (it is comma-separated; `full` also works), then **restart the MCP client**:
788
+ **3. Enable the tools you want.** Add the groups to `BRIDGE_MCP_PROFILE` in the MCP server `env` block (it is comma-separated), then **restart the MCP client**:
784
789
 
785
790
  ```json
786
791
  "env": { "BRIDGE_MCP_PROFILE": "sfcc" }
787
792
  ```
788
793
 
789
- Without this, only the diagnostic tools are registered.
794
+ `sfcc` gives the eight read tools plus `sfcc_log_query`. For the nine destructive write tools as well, use `"sfcc,sfcc-write"`; `full` expands to every group and is therefore write-capable. Without any of these, only the diagnostic tools are registered.
790
795
 
791
796
  **4. Verify and grant OCAPI access.** Ask your agent to run `sfcc_setup_status` (expect all checks ✓), then `check_permissions`. If it reports HTTP 401/403, it prints the exact OCAPI Settings JSON to paste in Business Manager (**Administration → Site Development → Open Commerce API Settings → Data API** tab); save it there and re-run. Restart the MCP client after any credential or env change — a running session does not pick them up.
792
797
 
793
798
  </details>
794
799
 
800
+ ### Sandbox enforcement
801
+
802
+ Every SFCC tool — all twenty, reads and writes alike, including the diagnostics —
803
+ passes through one check before its own logic runs: **the hostname your
804
+ credentials actually resolve to must be a recognized developer sandbox.**
805
+
806
+ - The check reads `credentials.hostname`, the value that goes into the OCAPI
807
+ URL. It does not read the `instance` tool argument. Omitting `instance`, or
808
+ passing `instance: "sandbox"`, has no effect on the decision — neither one
809
+ selects or proves anything about the target. A dotted `instance` still
810
+ *selects* a host through the documented credential precedence, but the host it
811
+ selects is then validated like any other, so `check_permissions` cannot be
812
+ aimed at a named production instance.
813
+ - It **fails closed.** An unrecognized, malformed, or unparseable hostname is
814
+ refused with HTTP `403`, `error.code: "TARGET_NOT_SANDBOX"`, and
815
+ `error.details.failure_class: "target-not-sandbox"`, before any request leaves
816
+ your machine.
817
+
818
+ The accepted hostname forms are:
819
+
820
+ | Form | Example |
821
+ |---|---|
822
+ | `<realm>-<nnn>.sandbox.<region>.dx.commercecloud.salesforce.com` | `zzzz-001.sandbox.us01.dx.commercecloud.salesforce.com` |
823
+ | `<realm>-<nnn>.sandbox.dx.commercecloud.salesforce.com` | `zzzz-001.sandbox.dx.commercecloud.salesforce.com` |
824
+ | `<realm>-<nnn>.dx.commercecloud.salesforce.com` | `zyis-001.dx.commercecloud.salesforce.com` |
825
+
826
+ Anything else is refused. In particular, hosts whose leading label names an
827
+ environment (`production-…`, `staging-…`, `development-…`) are rejected even
828
+ when they otherwise fit a form above, and the legacy `*.demandware.net` domain
829
+ is not accepted at all — sandbox, staging, and production instances share that
830
+ domain with no suffix that separates them.
831
+
832
+ ### Read and write profiles
833
+
834
+ `sfcc` and `sfcc-write` are **independent** groups. Neither implies the other.
835
+
836
+ | `BRIDGE_MCP_PROFILE` | SFCC tools registered |
837
+ |---|---|
838
+ | unset / `core` | `sfcc_setup_status`, `check_permissions` only |
839
+ | `sfcc` | the above + 8 OCAPI read tools + `sfcc_log_query` |
840
+ | `sfcc-write` | the above diagnostics + the 9 destructive write tools |
841
+ | `sfcc,sfcc-write` | all 20 |
842
+ | `full` | all 20 — `full` includes `sfcc-write` and is therefore write-capable |
843
+
844
+ **Migration.** Enabling `sfcc` used to register the nine write tools as well. It
845
+ no longer does. If you were relying on SFCC writes through
846
+ `BRIDGE_MCP_PROFILE=sfcc`, change it to `BRIDGE_MCP_PROFILE=sfcc,sfcc-write`.
847
+ Users of `BRIDGE_MCP_PROFILE=full` keep write access and need no change.
848
+
795
849
  ### Tools
796
850
 
797
- All SFCC tools are read-only and target a developer sandbox. An oversized response is saved in full to `BAPI_DOCS_DIR/sfcc/` and replaced by a parseable JSON descriptor — `truncated: true`, the `saved_path` it was written to, and the `page` metadata (`returned`, `total` when OCAPI supplied one, `has_more`) so the collection metadata survives even though the data itself is on disk. If that save fails, the complete payload is returned inline instead, still as parseable JSON.
851
+ The `sfcc` profile registers **read-only** tools: eight OCAPI reads plus `sfcc_log_query`. The **nine destructive write tools** are registered only by the separate `sfcc-write` profile see [Read and write profiles](#read-and-write-profiles). Both surfaces are bounded to a developer sandbox by the same invocation-time check.
852
+
853
+ An oversized response is saved in full to `BAPI_DOCS_DIR/sfcc/` and replaced by a parseable JSON descriptor — `truncated: true`, the `saved_path` it was written to, and the `page` metadata (`returned`, `total` when OCAPI supplied one, `has_more`) — so the collection metadata survives even though the data itself is on disk. If that save fails, the complete payload is returned inline instead, still as parseable JSON.
798
854
 
799
855
  Attribute-definition reads and writes can return an attribute's `default_value` at `projection: "full"`, and Bridge withholds it — every key is preserved except that one, whose value becomes `[REDACTED_BY_BRIDGE]` — from the inline response, the saved file, and a successful write echo alike. Attribute defaults are intentionally unavailable through this MCP surface; Business Manager is the supported path to read one.
800
856
 
801
857
  **Diagnostics** (always available, no profile needed)
802
858
  - `sfcc_setup_status` — report on every prerequisite: Bridge API key, repo name, `version` config, `dw.json` presence/uniqueness, AM (OCAPI) token acquisition, and the independent **SFCC Log Query (WebDAV)** capability that gates `sfcc_log_query`.
803
- - `check_permissions` — probe OCAPI access via `GET /system_object_definitions`; on 401/403, print the exact OCAPI Settings JSON to paste in Business Manager (split read-only vs. write/import grants).
859
+ - `check_permissions` — probe OCAPI access via `GET /system_object_definitions`; on 401/403, print the exact OCAPI Settings JSON to paste in Business Manager (read/search grants for the `sfcc` tools, mutation grants for the `sfcc-write` tools). An explicit `instance` hostname is still subject to the sandbox check below.
804
860
 
805
861
  **System object model** (needs the `sfcc` profile)
806
862
  - `system_object_list` — list system object types (Product, Order, Customer, …).
807
863
  - `system_object_get` — fetch one system object type's definition.
808
864
  - `system_object_attribute_search` — search a type's attribute definitions; prefer this over a full dump when hunting a specific `c_` custom attribute.
809
865
 
810
- **Custom object definitions** (needs the `sfcc` profile)
866
+ **Custom object definitions** (reads need `sfcc`; the two writes need `sfcc-write`)
811
867
  - `custom_object_definition_attributes_get` — fetch attribute definitions for a known custom object type (`default_value` withheld). OCAPI cannot enumerate custom object type *IDs* directly, so `object_type` must be known — but it is discoverable: call `system_object_list` at `projection: "full"` for each custom type's `display_name` and `attribute_definition_count`, derive a candidate id (e.g. strip spaces from `"Product Quality Result"` → `ProductQualityResult`), and confirm it by checking that this tool's returned attribute count matches that row's `attribute_definition_count`.
812
868
  - `custom_object_definition_attribute_search` — search attribute definitions within a known custom object type (`default_value` withheld). Read-only — creating a custom object *type* isn't possible via OCAPI; that's a future v2 metadata-import capability. Same discovery path as above applies to `object_type`.
813
869
  - `custom_object_definition_attribute_create` — **write** (sandbox only): create an attribute definition on a known custom object type via `PUT /custom_object_definitions/{type}/attribute_definitions/{id}`. TYPE creation is never attempted (the type must pre-exist). Echoes paste-ready OCAPI grant JSON on 403.
814
870
  - `custom_object_definition_attribute_update` — **write** (sandbox only): update an attribute definition via an ETag-conditional `PATCH …/attribute_definitions/{id}`; surfaces 409/412 conflicts and echoes grant JSON on 403.
815
871
 
816
- **Site preferences** (needs the `sfcc` profile; sandbox only)
872
+ **Site preferences** (reads need `sfcc`; the write needs `sfcc-write`; sandbox only)
817
873
  - `site_preference_get` — read a preference group's effective preferences.
818
874
  - `site_preference_search` — search/filter preferences within a group.
819
875
  - `site_preference_values_set` — **write** (sandbox only): set custom preference values via `PATCH /site_preferences/preference_groups/{group}/sandbox` with a flat map of `c_`-prefixed ids to string/number/boolean/string[] values. A bad group returns 404 `CustomPreferenceGroupNotFoundException`; echoes grant JSON on 403.
@@ -883,6 +939,12 @@ npx -y @bridge_gpt/mcp-server doctor [--agent <name>]
883
939
 
884
940
  The report always leads with the advisory **`Install status`** section (repo identity, credential resolution, server connectivity, bootstrap-field completeness, integration credentials, indexing state) **before** the `start-tickets` prerequisite diagnostics; the launcher-cache and MCP tool-surface sections follow. `Install status` is read-only GETs only and never affects the exit code.
885
941
 
942
+ The report also includes a **Claude login** advisory: whether the host's own
943
+ `~/.claude.json` carries a login marker. This is informational only — it never
944
+ blocks the doctor run and cannot guarantee the next worker spawn will
945
+ authenticate. See
946
+ [Claude login for conductor workers](#claude-login-for-conductor-workers).
947
+
886
948
  It is **read-only**: it never installs anything, modifies your system, adds an npm `postinstall`, spawns a terminal, or starts the MCP server, and there is no `--fix`. For each prerequisite it prints found/missing and, when missing, the exact per-OS install command **as a manual instruction you run yourself**. The checked set is the `start-tickets` preflight prerequisites **plus `uv`** **plus the selected agent's command** (`claude` by default, or `cursor-agent` with `--agent cursor-agent`). The Worktrunk binary is probed via the resolved name (honoring `BAPI_WORKTRUNK_BIN`), not a hard-coded one. **Exit code:** `0` when all required prerequisites are present, non-zero when any is missing or the platform is unsupported. A failing `start-tickets` preflight now hints you to run `doctor` for an actionable diagnostics report.
887
949
 
888
950
  ### `setup-epic`
@@ -901,6 +963,78 @@ Once the plan is approved, the **server-side reconciler** picks the run up withi
901
963
  npx -y @bridge_gpt/mcp-server executor --repo <name>
902
964
  ```
903
965
 
966
+ ### `conduct-epic`
967
+
968
+ The deterministic half of the `/conduct-epic` loop: it owns the epic branch, a
969
+ versioned local checkpoint, a per-epic lock, and the read-only probes the loop
970
+ decides on. It never creates or mutates an `epic_run` — that is the server-side
971
+ v2 reconciler's job, and `init` refuses to start when one is already active.
972
+
973
+ ```
974
+ npx -y @bridge_gpt/mcp-server conduct-epic <verb> [flags]
975
+ ```
976
+
977
+ **Verbs**
978
+
979
+ | Verb | Flags |
980
+ | --- | --- |
981
+ | `init <EPIC>` | `--tickets K1,K2,…` (required), `--base-branch <b>`, `--checkpoint-path <p>`, `--dry-run`, `--json` |
982
+ | `status <EPIC>` | `--json` (required), `--checkpoint-path <p>` |
983
+ | `checkpoint set <EPIC>` | `--ticket <KEY>` (required), `--field <name> <value>` (repeatable), `--journal "<line>"`, `--checkpoint-path <p>` |
984
+ | `finish <EPIC>` | `--checkpoint-path <p>`, `--json` |
985
+ | `spawn <EPIC>` | `--ticket <KEY>` and `--prompt-file <path>` (required), `--agent claude\|cursor-agent`, `--checkpoint-path <p>`, `--json` |
986
+
987
+ **Local state.** Everything lives *outside* the repository, under
988
+ `~/.config/bridge/conduct/<repo>/` (honoring `XDG_CONFIG_HOME`), so it resolves
989
+ identically from the main checkout and from any worktree and can never be
990
+ committed by an agent running `git add`:
991
+
992
+ | Path | Purpose |
993
+ | --- | --- |
994
+ | `<EPIC>.json` | the version-1 checkpoint (file `0600`, directory `0700`) |
995
+ | `<EPIC>.json.prev` | the previous valid checkpoint, retained on every write |
996
+ | `<EPIC>.lock` | the per-epic lock |
997
+ | `<EPIC>/prompts/<KEY>-<kind>-<n>.md` | prompt files the caller writes for `spawn` |
998
+
999
+ `status` prints the resolved `checkpoint_path`. To unpark a run a human edits the
1000
+ checkpoint (`needs_human` → `null`, plus the ticket's `status`/counters);
1001
+ `last_seen_head`, `ci_last_poll`, and `lock` are observational and are never
1002
+ hand-edited.
1003
+
1004
+ **`init` runs ONE preflight** that reports *every* failure in a single pass and
1005
+ writes nothing unless all of them pass: `gh auth status`; Worktrunk resolves
1006
+ (honoring `BAPI_WORKTRUNK_BIN`); Bridge credentials resolve; `auto_merge_enabled`
1007
+ is on — or is turned on by PUTting the *complete* effective config back with just
1008
+ that flag flipped, which prints a line beginning `announced:`; at least one
1009
+ required CI check exists (an empty required set would make the done gate pass
1010
+ vacuously); no active server-side `epic_run` for the key; the lock is free or its
1011
+ owner is provably dead; the base branch exists on `origin` after `git fetch`; and
1012
+ the indexed-branch override is either absent or this epic's own — a re-`init`
1013
+ after a crash is accepted and its `original_base_branch` becomes the default base,
1014
+ while a *foreign* override is refused by name. `resolve-ci-checks` is called
1015
+ exactly once either way, because that call is what warms the `poll-ci-checks`
1016
+ cache the first `status` depends on. Only then does `init` push
1017
+ `epic/<EPIC>` to `origin` at the fetched base tip (no local checkout), repoint the
1018
+ index, write the checkpoint, and take the lock. `--dry-run` prints the validated
1019
+ plan and mutates nothing. A second `init` refuses with `already initialized`.
1020
+
1021
+ **Failure posture is split on purpose.** In `status`, each probe fails *open*: a
1022
+ `gh`, CI, review, or parse failure leaves that sub-object `null`, adds an entry to
1023
+ `probe_errors`, and the command still exits `0` with a complete object — the loop
1024
+ must be able to read its own checkpoint during a GitHub outage. Everything else
1025
+ fails *closed*: a corrupt or wrong-version checkpoint makes every verb but `init`
1026
+ exit non-zero **without rewriting it**, and `checkpoint set`, `spawn`, and
1027
+ `finish` refuse a lock held by another live process. `status` never takes the lock.
1028
+
1029
+ **Exit codes.** `0` on success — including a missing checkpoint
1030
+ (`checkpoint_exists: false`) and an idempotent second `finish`. Non-zero on any
1031
+ other failure, with a one-line reason on stderr. With `--json`, stdout is exactly
1032
+ one JSON object carrying `ok`.
1033
+
1034
+ **Credentials** resolve only from `BAPI_API_KEY` or the user-scoped
1035
+ `bapi:<repo>` credential target, travel only in the `X-API-Key` header, and never
1036
+ appear in a command argument, in stdout/stderr, or in a journal line.
1037
+
904
1038
  ### Conductor (epic & multi-agent orchestration)
905
1039
 
906
1040
  Conductor is an **opt-in, off-by-default** layer for epic supervision, inter-agent messaging, done-gate evaluation, local git-hook event producers, and conditional auto-merge. Its full reference — the v2 architecture (server-side reconciler + local executor), `setup-epic`, `conductor install-git-hooks`, the supervisor `done_gate_config` / `auto_merge_enabled` settings, and the observability stream — lives in **[CONDUCTOR.md](./docs/CONDUCTOR.md)**.
@@ -964,7 +1098,7 @@ If a custom pipeline has the same key as a built-in pipeline, the custom version
964
1098
  | `BAPI_MCP_TOOL_SURFACE_GATING_ENABLED` | No | _(enabled)_ | MCP-local kill switch for **dynamic tool-surface capability gating** (see [Dynamic tool-surface gating](#dynamic-tool-surface-gating-capability-availability)). Default-on; set to `false`/`0`/`no`/`off`/`disabled` to skip the startup probe, the recurring poll, and the custom `tools/list` handler entirely, restoring the SDK's previous full profile-derived surface. Fail-open: any probe timeout, unreachable backend, non-2xx, malformed payload, incomplete evaluation, or unsupported schema advertises the full profile |
965
1099
  | `BAPI_MCP_TOOL_SURFACE_POLL_ENABLED` | No | _(disabled)_ | Opt IN to the recurring tool-surface **poll**. Default-**off**: a session gates once via the startup probe and never re-probes. Set to `true`/`1`/`yes`/`on`/`enabled` to restore the jittered 12–18 s heartbeat that pushes `notifications/tools/list_changed` on mid-session capability changes. No effect when gating itself is disabled |
966
1100
  | `CURSOR_API_KEY` | No | _(none)_ | API key used to authenticate `cursor-agent` when launching `start-tickets`/scheduled runs with `--agent cursor-agent`. Not needed for the default Claude Code agent |
967
- | `BRIDGE_MCP_PROFILE` | No | `core` | Startup-time tool registration profile — a **comma-separated** list of groups controlling which tool groups are registered when the server starts. `core` is always implicitly included. Valid groups: `core` (default — normal coding tools only), `conductor` (+ 8 conductor/event/supervisor tools), `pipeline-authoring` (+ 5 pipeline run/admin tools — `get_pipeline_recipe` is NOT gated; it stays in `core` because the recipe-driven slash commands depend on it), `sfcc` (+ the 7 heavy SFCC read tools — see [Salesforce B2C Commerce (SFCC) Tools](#salesforce-b2c-commerce-sfcc-tools); the `sfcc_setup_status`/`check_permissions` diagnostics are always registered regardless), and `full` (shortcut that expands to every group). Example: `sfcc,conductor`. Unknown, blank, or malformed tokens are dropped (falling back to `core`). Dynamic mid-session switching via `tools/list_changed` is unsupported — groups are resolved once at process startup. Conductor/epic sessions launched via `start-tickets --conductor` automatically inject `BRIDGE_MCP_PROFILE=conductor` at the spawn boundary; a normal `start-tickets` run stays on `core`. |
1101
+ | `BRIDGE_MCP_PROFILE` | No | `core` | Startup-time tool registration profile — a **comma-separated** list of groups controlling which tool groups are registered when the server starts. `core` is always implicitly included. Valid groups: `core` (default — normal coding tools only), `conductor` (+ 8 conductor/event/supervisor tools), `pipeline-authoring` (+ 5 pipeline run/admin tools — `get_pipeline_recipe` is NOT gated; it stays in `core` because the recipe-driven slash commands depend on it), `sfcc` (+ the 8 heavy SFCC read tools and `sfcc_log_query` read-only, see [Salesforce B2C Commerce (SFCC) Tools](#salesforce-b2c-commerce-sfcc-tools); the `sfcc_setup_status`/`check_permissions` diagnostics are always registered regardless), `sfcc-write` (+ the 9 destructive SFCC write tools — independent of `sfcc`, which does not enable them; see [Read and write profiles](#read-and-write-profiles)), and `full` (shortcut that expands to every group, **including `sfcc-write`**). Example: `sfcc,conductor`; use `sfcc,sfcc-write` for reads plus writes. Unknown, blank, or malformed tokens are dropped (falling back to `core`). Dynamic mid-session switching via `tools/list_changed` is unsupported — groups are resolved once at process startup. Conductor/epic sessions launched via `start-tickets --conductor` automatically inject `BRIDGE_MCP_PROFILE=conductor` at the spawn boundary; a normal `start-tickets` run stays on `core`. |
968
1102
 
969
1103
  ## Dynamic tool-surface gating (capability availability)
970
1104
 
@@ -1084,6 +1218,47 @@ work. Two supported paths write it for you:
1084
1218
 
1085
1219
  Run it without `--write-credentials` to preview; add the flag to write the store.
1086
1220
 
1221
+ ### Claude login for conductor workers
1222
+
1223
+ Conductor workers are **not** isolated into a private Claude configuration
1224
+ directory — they run with the executor host's own `HOME`, so a worker
1225
+ authenticates the same way any interactive `claude` invocation on that host
1226
+ does. The prerequisite is simple: run
1227
+
1228
+ ```bash
1229
+ claude login
1230
+ ```
1231
+
1232
+ on the executor host, once, the normal way. Bridge never stores, resolves, mints,
1233
+ rotates, validates, or diagnoses this credential — it is entirely the operator's
1234
+ own Claude CLI state, exactly as if you were running `claude` at the terminal
1235
+ yourself.
1236
+
1237
+ **Headless hosts.** If the executor host has no interactive login session
1238
+ available (a service-launched executor, a CI-style runner), export
1239
+ `CLAUDE_CODE_OAUTH_TOKEN` into the **executor process's own environment**
1240
+ yourself before starting it:
1241
+
1242
+ ```bash
1243
+ export CLAUDE_CODE_OAUTH_TOKEN="$(claude setup-token)" # run once, wherever you can browser-login
1244
+ ```
1245
+
1246
+ Bridge forwards that value **unchanged**, byte-for-byte, into the direct worker
1247
+ process environment — nothing else. It is never written to disk, never placed in
1248
+ a generated launchd/systemd service unit, never placed in project configuration
1249
+ (`.mcp.json` / `.cursor/mcp.json`), and never sent to Bridge servers. There is no
1250
+ credential store entry for it and no lifecycle tracking: expiry, rotation, and
1251
+ validity are entirely the operator's own responsibility, the same as any other
1252
+ value you choose to export into a process environment.
1253
+
1254
+ **`ANTHROPIC_API_KEY` is never forwarded to a worker**, under any circumstance —
1255
+ there is no fallback path for it.
1256
+
1257
+ `mcp-server doctor` reports a single advisory **Claude login** line — whether
1258
+ `~/.claude.json` on the host it runs on carries a login marker. This is
1259
+ informational only: it cannot confirm the next worker spawn will authenticate,
1260
+ and it never blocks the doctor run or changes its exit code.
1261
+
1087
1262
  ## Reference
1088
1263
 
1089
1264
  The full surface, for when you need the complete enumeration. Day-to-day, use [Usage Documentation](#usage-documentation) instead — you don't call MCP tools directly; you ask your AI assistant to perform a task, or compose tools into a pipeline.
@@ -1100,7 +1275,7 @@ The authoritative tool catalog covers **92 tools** (enumerated below). What's ac
1100
1275
  - **Other AI** — `second_opinion`, `generate_image`, `generate_decision_page`, `visual_diff` (deterministic pixel diff of a rendered URL vs a design comp)
1101
1276
  - **Ticket lifecycle** — `track_ticket`, `update_ticket_state`, `get_ticket_state`, `get_ticket_state_tree` (live repo-wide lifecycle + dependency tree; read-only, no mutation parameter)
1102
1277
  - **Jira status** — `get_jira_transitions`, `update_jira_status`, `resolve_target_status`
1103
- - **Repository & CI** — `parse_repository`, `get_parse_status`, `regenerate_directory_map`, `create_pull_request`, `resolve_ci_checks`, `poll_ci_checks`
1278
+ - **Repository & CI** — `parse_repository`, `get_parse_status`, `regenerate_directory_map`, `create_pull_request`, `merge_pull_request`, `resolve_ci_checks`, `poll_ci_checks`
1104
1279
  - **Pipelines & automation** — `list_pipelines`, `get_pipeline_recipe`, `run_pipeline`, `resume_pipeline`, `list_pipeline_runs`, `delete_pipeline_run`, `run_full_automation`, `resume_full_automation`
1105
1280
  - **Config** — `get_project_standards`, `config_field` (operations: `get`, `update`, `list`)
1106
1281
 
@@ -32,7 +32,8 @@ export function buildHeadlessArgs(agentName, opts) {
32
32
  }
33
33
  // claude (and any positional-prompt agent without a cwd flag)
34
34
  const args = ["-p"];
35
- // BAPI-725: exactly ONE permission form, matching `buildClaudeExecutorArgv`.
35
+ // BAPI-725: exactly ONE permission form, matching the Claude executor
36
+ // adapter's argv builder (`agent-launchers/claude-executor-adapter.ts`).
36
37
  // `permissionMode` wins when both are supplied — emitting both would let the
37
38
  // skip flag take effect and the probe would report on a posture it never ran.
38
39
  if (opts.permissionMode === "acceptEdits") {