@bridge_gpt/mcp-server 0.2.38 → 0.2.39
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.
- package/README.md +189 -14
- package/build/agent-capabilities/probe-context.js +2 -1
- package/build/agent-launchers/claude-executor-adapter.js +392 -0
- package/build/agent-launchers/executor-adapter-inspection.js +163 -0
- package/build/agent-launchers/executor-adapter-registry.js +90 -0
- package/build/agent-launchers/executor-adapter.js +136 -0
- package/build/agent-registry.js +28 -0
- package/build/agents.generated.js +1 -1
- package/build/claude-login.js +85 -0
- package/build/claude-user-config-doctor.js +59 -33
- package/build/commands.generated.js +12 -11
- package/build/conduct-epic/bridge-client.js +345 -0
- package/build/conduct-epic/checkpoint-store.js +423 -0
- package/build/conduct-epic/cli.js +1732 -0
- package/build/conduct-epic/lock.js +302 -0
- package/build/conduct-epic/pr-state.js +197 -0
- package/build/conduct-epic/spawn.js +101 -0
- package/build/conductor/bridge-api-client.js +37 -2
- package/build/conductor/doctor.js +11 -1
- package/build/conductor/install-doctor.js +184 -10
- package/build/conductor-bin.js +7 -7
- package/build/credential-store.js +10 -4
- package/build/credentials-cli.js +34 -19
- package/build/docs.generated.js +1 -1
- package/build/doctor.js +579 -88
- package/build/executor/agent-identity.js +32 -0
- package/build/executor/cli.js +50 -39
- package/build/executor/deps.js +15 -1
- package/build/executor/env.js +56 -45
- package/build/executor/index.js +9 -1
- package/build/executor/install-preflight.js +138 -0
- package/build/executor/job-errors.js +200 -0
- package/build/executor/job-runner.js +619 -268
- package/build/executor/observation.js +165 -0
- package/build/executor/permissions.js +163 -36
- package/build/executor/platform.js +54 -0
- package/build/executor/preflight.js +175 -67
- package/build/executor/process.js +39 -7
- package/build/executor/runner.js +19 -0
- package/build/executor/service-lifecycle.js +269 -0
- package/build/executor/service-unit.js +121 -12
- package/build/executor/stale-artifacts.js +70 -0
- package/build/executor/test-clock.js +188 -24
- package/build/executor/worker-command.js +22 -58
- package/build/executor/worker-log.js +82 -0
- package/build/executor/worktree-lock.js +264 -0
- package/build/index.js +527 -357
- package/build/install-bridge-conductor.js +376 -38
- package/build/install-bridge.js +414 -114
- package/build/install-doctor.js +13 -0
- package/build/install-reexec.js +5 -3
- package/build/mcp-install-state.js +130 -0
- package/build/mcp-profile.js +11 -2
- package/build/mcp-provisioning.js +15 -0
- package/build/merge-pull-request.js +562 -0
- package/build/phase-result-artifacts.js +450 -0
- package/build/pipeline-orchestrator.js +4 -0
- package/build/pipeline-utils.js +16 -0
- package/build/pipelines.generated.js +7 -7
- package/build/plane/preflight.js +18 -14
- package/build/plane/supervisor.js +8 -1
- package/build/project-root.js +34 -0
- package/build/readme.generated.js +1 -1
- package/build/run-unit-tests-launcher.js +36 -9
- package/build/setup-epic.js +57 -4
- package/build/sfcc/permissions.js +25 -6
- package/build/sfcc/reads-site-preference.js +6 -0
- package/build/sfcc/register.js +61 -23
- package/build/sfcc/registration-inventory.js +89 -0
- package/build/sfcc/setup-status.js +18 -34
- package/build/sfcc/tool-wrapper.js +294 -17
- package/build/sfcc/write-grants.js +33 -1
- package/build/sfcc/write-guard.js +41 -12
- package/build/sfcc/writes-custom-object-def.js +6 -2
- package/build/sfcc/writes-site-preference.js +6 -1
- package/build/sfcc/writes-system-object.js +11 -2
- package/build/sfcc/writes.js +13 -8
- package/build/start-tickets-prereqs.js +25 -15
- package/build/start-tickets.js +123 -21
- package/build/version.generated.js +1 -1
- package/build/worktree-core.js +9 -3
- package/docs/install/mcp-tool-integrations.md +54 -9
- package/docs/install/sfcc-integration.md +71 -24
- package/package.json +3 -3
- package/build/executor/worker-config-isolation.js +0 -287
|
@@ -1,3 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Executor-local named error helpers (BAPI-535, TDD §7/§9).
|
|
3
|
+
*
|
|
4
|
+
* Fail-loud executor conditions carry an explicit, stable `errorKind` so the
|
|
5
|
+
* runner can post the right `/fail` payload without coupling the executor to the
|
|
6
|
+
* v1 conductor error/ledger graph (see `types.ts` for the boundary contract).
|
|
7
|
+
* These are the ONLY named executor failure kinds this slice introduces:
|
|
8
|
+
*
|
|
9
|
+
* - `MissingVerdictArtifact` — a `spec_review`/`smoke` job exited cleanly but its
|
|
10
|
+
* fixed-path `<worktree>/.conductor/result.json` was missing/unreadable/invalid
|
|
11
|
+
* (TDD §9: "a verdict can never be silently absent").
|
|
12
|
+
* - `WorktreeLostBeforePush` — a `resume` job's worktree is gone AND its branch was
|
|
13
|
+
* never pushed, so there is nothing to recreate from (TDD §7).
|
|
14
|
+
* - `BranchMismatch` — a `resume` worktree is on the wrong branch; working there
|
|
15
|
+
* would corrupt an unrelated branch, so abort rather than proceed (TDD §7).
|
|
16
|
+
* - `WorkerFinalizationMissingRemoteBranchAndPr` — an implementation-style job
|
|
17
|
+
* (BAPI-551) exited cleanly but produced neither a PR URL nor a pushed origin
|
|
18
|
+
* branch, stranding the implement gate; see `worker-finalization.ts`.
|
|
19
|
+
* - `WorkerFinalizationPrBaseMismatch` — an implementation-style job (BAPI-586)
|
|
20
|
+
* opened a PR whose base branch is not the run base, so `claude-review.yml`
|
|
21
|
+
* (triggered only on `branches: [main]`) never fires and the `code_review`
|
|
22
|
+
* gate would hang forever; see `worker-finalization.ts`.
|
|
23
|
+
* - `WorkerFinalizationSavedButUnfinalized` — an implementation-style job
|
|
24
|
+
* (BAPI-762) exited cleanly, and an origin branch exists at an authoritative
|
|
25
|
+
* tip that does NOT match the worker's own HEAD — durable work exists on
|
|
26
|
+
* origin, but not this worker's latest commit. Distinct from
|
|
27
|
+
* `WorkerFinalizationMissingRemoteBranchAndPr` (which covers "no evidence any
|
|
28
|
+
* work reached origin") because this case has positive proof of recoverable
|
|
29
|
+
* state: an operator can resume/finalize from the existing branch rather than
|
|
30
|
+
* re-running from scratch; see `worker-finalization.ts`.
|
|
31
|
+
* - `ContractError.WorkerConfigIsolation` — a per-job isolated Claude config
|
|
32
|
+
* directory could not be established (unsupported platform, unsupported auth
|
|
33
|
+
* layout, unseedable directory, or a missing required MCP registration), so
|
|
34
|
+
* the worker would have fallen back to the operator's configuration and
|
|
35
|
+
* inherited operator-scoped MCP servers. Fail-CLOSED (BAPI-731 WS-A);
|
|
36
|
+
* see `worker-config-isolation.ts`.
|
|
37
|
+
* - `ContractError.PreSpawnVerification` — the prepared worktree was not
|
|
38
|
+
* provably clean at the expected commit immediately before spawn, so the
|
|
39
|
+
* attempt could have committed leftover unrelated work (the F11a class).
|
|
40
|
+
* Fail-CLOSED, including on a DEGRADED git read: "could not verify" is
|
|
41
|
+
* never reported as "verified clean" (BAPI-731 WS-E).
|
|
42
|
+
* - `ContractError.McpSurfaceMismatch` — the worker reported, on its own
|
|
43
|
+
* `system`/`init` event, a set of loaded MCP servers that is not the set
|
|
44
|
+
* provisioned into its worktree. Either it inherited a server it was never
|
|
45
|
+
* granted, or a provisioned server is missing, or the event could not be read
|
|
46
|
+
* at all. Fail-CLOSED and mid-flight: the worker is terminated before it does
|
|
47
|
+
* work (BAPI-790); see `createMcpSurfaceObserver` in `observation.ts`.
|
|
48
|
+
* - `ContractError.RequiredMcpRegistration` — the prepared worktree's
|
|
49
|
+
* `.mcp.json` is absent, unreadable, malformed, or carries no `bridge-api`
|
|
50
|
+
* entry. Since a worker loads MCP servers strictly from that file, it would
|
|
51
|
+
* run with no Bridge tools and exit "cleanly" having done nothing
|
|
52
|
+
* (RUN-FINDINGS-2026-08-05 F2). Fail-CLOSED, pre-spawn. Renamed from the
|
|
53
|
+
* isolation-era kind by BAPI-790, because the condition is now about the file
|
|
54
|
+
* itself rather than about an isolation directory.
|
|
55
|
+
* - `ContractError.WorkerStartupFatal` — the worker exited non-zero having
|
|
56
|
+
* emitted no stream-json event whatsoever, i.e. it died before reporting its
|
|
57
|
+
* MCP surface. Distinguished from an ordinary `WorkerCrashed` because the
|
|
58
|
+
* known cause under strict MCP loading is an enterprise `managed-mcp.json`
|
|
59
|
+
* policy rejecting the strict flags, and the executor deliberately does NOT
|
|
60
|
+
* retry without them (BAPI-790).
|
|
61
|
+
* - `ContractError.ClaudeNotAuthenticated` — the worker's own stream-json
|
|
62
|
+
* terminal `result` event reports one of the two Claude CLI authentication
|
|
63
|
+
* failures measured and recorded in
|
|
64
|
+
* `docs/claude/claude-cli-config-isolation-inventory.md` (Findings 4/5): no
|
|
65
|
+
* credential at all (`Not logged in · Please run /login`), or a present but
|
|
66
|
+
* invalid/expired `CLAUDE_CODE_OAUTH_TOKEN` (`OAuth access token is
|
|
67
|
+
* invalid`, HTTP 401). Since BAPI-791 removed spawn-time credential
|
|
68
|
+
* resolution, authentication is no longer checked before spawning — it
|
|
69
|
+
* succeeds or fails at the real worker spawn, and a recognized failure here
|
|
70
|
+
* is reported with this fixed, secret-free kind instead of a generic
|
|
71
|
+
* `WorkerCrashed`.
|
|
72
|
+
* - `ContractError.ExecutorAdapterUnavailable` — the configured agent has no
|
|
73
|
+
* usable executor adapter (BAPI-781): unknown agent, no adapter registration,
|
|
74
|
+
* an unimplemented strategy, an identity mismatch against the registry, a
|
|
75
|
+
* missing/unsupported required capability, or a spawn shape inconsistent with
|
|
76
|
+
* what the adapter declared. Fail-CLOSED and pre-spawn. This exists so the
|
|
77
|
+
* refusal is DISTINGUISHABLE from a worker that ran and failed: the
|
|
78
|
+
* alternative to reporting it is defaulting to Claude's behavior for an agent
|
|
79
|
+
* nobody implemented, which would spawn a real worker under containment the
|
|
80
|
+
* operator never declared.
|
|
81
|
+
*
|
|
82
|
+
* These kinds are deliberately DISTINCT from each other so the refusals stay
|
|
83
|
+
* tellable apart in `executor_jobs.error_kind`.
|
|
84
|
+
*
|
|
85
|
+
* RETIRED (BAPI-790), kept exported so historical rows stay decodable and so a
|
|
86
|
+
* reader who greps a stored `error_kind` still lands on its definition:
|
|
87
|
+
* - `ContractError.WorkerConfigIsolation` and
|
|
88
|
+
* `ContractError.BridgeCredentialUnavailable` belonged to the per-job Claude
|
|
89
|
+
* config-directory isolation retired by BAPI-790. Nothing posts them now.
|
|
90
|
+
* - `ContractError.McpShadowing` was the BAPI-727 shadowing refusal, now an
|
|
91
|
+
* advisory warning — strict loading means an operator registration cannot
|
|
92
|
+
* shadow a worker.
|
|
93
|
+
*/
|
|
94
|
+
import { normalizeMcpServerNames } from "./observation.js";
|
|
1
95
|
/** Stable executor failure-kind constants (posted verbatim as `error_kind`). */
|
|
2
96
|
export const MissingVerdictArtifact = "MissingVerdictArtifact";
|
|
3
97
|
export const WorktreeLostBeforePush = "WorktreeLostBeforePush";
|
|
@@ -8,6 +102,112 @@ export const WorkerFinalizationSavedButUnfinalized = "WorkerFinalizationSavedBut
|
|
|
8
102
|
export const WorkerConfigIsolation = "ContractError.WorkerConfigIsolation";
|
|
9
103
|
export const PreSpawnVerification = "ContractError.PreSpawnVerification";
|
|
10
104
|
export const BridgeCredentialUnavailable = "ContractError.BridgeCredentialUnavailable";
|
|
105
|
+
export const McpSurfaceMismatch = "ContractError.McpSurfaceMismatch";
|
|
106
|
+
export const WorkerStartupFatal = "ContractError.WorkerStartupFatal";
|
|
107
|
+
export const RequiredMcpRegistration = "ContractError.RequiredMcpRegistration";
|
|
108
|
+
export const ClaudeNotAuthenticated = "ContractError.ClaudeNotAuthenticated";
|
|
109
|
+
export const WorktreeBusy = "ContractError.WorktreeBusy";
|
|
110
|
+
export const ExecutorAdapterUnavailable = "ContractError.ExecutorAdapterUnavailable";
|
|
111
|
+
/**
|
|
112
|
+
* BAPI-814/D1: a previous attempt's `.conductor/result.json` / `critique.md`
|
|
113
|
+
* could not be removed before the worker spawned. Fail-closed on purpose — the
|
|
114
|
+
* alternative is running an attempt that may read a stale verdict as its own.
|
|
115
|
+
*/
|
|
116
|
+
export const StaleArtifactCleanupFailed = "ContractError.StaleArtifactCleanupFailed";
|
|
117
|
+
/** Rendered in place of an empty name list, so "none" is never ambiguous. */
|
|
118
|
+
export const EMPTY_MCP_SERVER_NAME_MARKER = "none";
|
|
119
|
+
/** Bound the rendered name lists so a pathological registration cannot spam a job row. */
|
|
120
|
+
const MCP_SURFACE_NAME_LIMIT = 20;
|
|
121
|
+
/**
|
|
122
|
+
* Render a name list for a containment diagnostic: already-normalized names,
|
|
123
|
+
* comma-joined, bounded, with a fixed marker for the empty case.
|
|
124
|
+
*
|
|
125
|
+
* NAMES ONLY, and that is a hard constraint rather than a stylistic one. This
|
|
126
|
+
* text is posted to the server as `error_message` and stored on the job row, so
|
|
127
|
+
* anything else that could ride along — a registration command, an argv array, an
|
|
128
|
+
* env block, the `.mcp.json` path (which contains a username), or a raw stream
|
|
129
|
+
* line — would turn a containment failure into a disclosure.
|
|
130
|
+
*/
|
|
131
|
+
function formatMcpServerNameList(names) {
|
|
132
|
+
// Normalized HERE rather than trusted from the caller. Both call sites already
|
|
133
|
+
// pass normalized sets, but determinism is the property that makes two job rows
|
|
134
|
+
// comparable, and a guarantee that depends on every caller remembering to
|
|
135
|
+
// normalize is not a guarantee.
|
|
136
|
+
const normalized = normalizeMcpServerNames(names);
|
|
137
|
+
if (normalized.length === 0)
|
|
138
|
+
return EMPTY_MCP_SERVER_NAME_MARKER;
|
|
139
|
+
const shown = normalized.slice(0, MCP_SURFACE_NAME_LIMIT);
|
|
140
|
+
const suffix = normalized.length > shown.length ? `, +${normalized.length - shown.length} more` : "";
|
|
141
|
+
return `${shown.join(", ")}${suffix}`;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The fixed message posted with {@link McpSurfaceMismatch}.
|
|
145
|
+
*
|
|
146
|
+
* Deterministic for a given pair of name sets: both sides arrive already sorted
|
|
147
|
+
* and deduplicated from `normalizeMcpServerNames`, so the same mismatch always
|
|
148
|
+
* renders the same text and an operator can compare two job rows directly.
|
|
149
|
+
*/
|
|
150
|
+
export function formatMcpSurfaceMismatch(expected, observed) {
|
|
151
|
+
return ("worker MCP surface mismatch: the worker reported loading a different set of MCP servers " +
|
|
152
|
+
"than its worktree provisions, so it was terminated before doing work. " +
|
|
153
|
+
`Expected: ${formatMcpServerNameList(expected)}. Observed: ${formatMcpServerNameList(observed)}. ` +
|
|
154
|
+
"An observed set of 'none' means the init event's server list could not be read at all. " +
|
|
155
|
+
"Check that the installed Claude CLI supports --strict-mcp-config and that nothing adds MCP " +
|
|
156
|
+
"servers outside the worktree registration.");
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* The fixed message posted with {@link WorkerStartupFatal}.
|
|
160
|
+
*
|
|
161
|
+
* States only what was OBSERVED — a non-zero exit with no stream-json output —
|
|
162
|
+
* and names enterprise managed MCP policy as the known cause to check, without
|
|
163
|
+
* claiming to have identified it. That distinction is deliberate: the enterprise
|
|
164
|
+
* `managed-mcp.json` fatal signature has not been measured on any host available
|
|
165
|
+
* to this repository (see inventory Finding 6), so asserting it would be a guess
|
|
166
|
+
* printed as a diagnosis.
|
|
167
|
+
*/
|
|
168
|
+
export const WORKER_STARTUP_FATAL_MESSAGE = "the worker exited before reporting its MCP surface: it produced no stream-json output at all " +
|
|
169
|
+
"and exited non-zero, which is a fatal startup failure rather than a failure during work. The " +
|
|
170
|
+
"known cause under strict MCP loading is an enterprise managed MCP policy (managed-mcp.json) " +
|
|
171
|
+
"rejecting --strict-mcp-config; also verify the installed Claude CLI supports the strict MCP " +
|
|
172
|
+
"flags. The executor does not retry without them, because falling back to unscoped loading " +
|
|
173
|
+
"would silently restore full inheritance of the operator's MCP servers.";
|
|
174
|
+
/**
|
|
175
|
+
* The fixed message posted with {@link ClaudeNotAuthenticated}.
|
|
176
|
+
*
|
|
177
|
+
* Names only the two remediation paths, never the raw stream-json content that
|
|
178
|
+
* triggered classification — the adapter's detector returns a verdict and a
|
|
179
|
+
* reason code, never the matched line. The headless alternative names the
|
|
180
|
+
* environment variable only, never a value.
|
|
181
|
+
*/
|
|
182
|
+
export const CLAUDE_NOT_AUTHENTICATED_MESSAGE = "the worker could not authenticate as the Claude CLI. Run `claude login` on this host; on a " +
|
|
183
|
+
"headless host with no interactive login available, export CLAUDE_CODE_OAUTH_TOKEN yourself " +
|
|
184
|
+
"before starting the executor.";
|
|
185
|
+
/**
|
|
186
|
+
* The fixed message posted with {@link WorktreeBusy} (BAPI-793).
|
|
187
|
+
*
|
|
188
|
+
* FIXED, and carrying no identity at all — not the worktree path, not the
|
|
189
|
+
* conflicting job's id, not a claim token. This string is stored on the job row
|
|
190
|
+
* and read back by anyone with access to the run, while the worktree path
|
|
191
|
+
* contains an operator's username and the claim token is a fencing credential.
|
|
192
|
+
* The attributable detail (this job, the conflicting job, ticket, repo, worktree
|
|
193
|
+
* basename) goes to the executor's OWN stderr instead, where it stays on the
|
|
194
|
+
* host that already has all of it.
|
|
195
|
+
*/
|
|
196
|
+
export const WORKTREE_BUSY_MESSAGE = "another executor job already holds this ticket's worktree, so no worker was started for this " +
|
|
197
|
+
"job. Two workers in one working tree corrupt each other's edits, index, and commits, so the " +
|
|
198
|
+
"second claim is refused rather than allowed in. The refusal is expected when two jobs exist " +
|
|
199
|
+
"for one ticket; the job that holds the worktree continues normally, and this one is safe to " +
|
|
200
|
+
"retry once it finishes. See the executor's stderr for the conflicting job id.";
|
|
201
|
+
// The Claude-specific matcher that used to live here moved into the Claude
|
|
202
|
+
// executor adapter as `classifyClaudeAuthFailure` (BAPI-781). Recognizing one
|
|
203
|
+
// CLI's not-logged-in output is precisely a per-agent capability, and leaving it
|
|
204
|
+
// in a generic error module meant every future agent's auth failure would have
|
|
205
|
+
// to be recognized by Claude's shape or not at all.
|
|
206
|
+
//
|
|
207
|
+
// The ERROR KIND and the fixed message above stay here on purpose: mapping a
|
|
208
|
+
// classification onto a stable executor failure remains executor-owned, so an
|
|
209
|
+
// adapter cannot invent its own error kinds or its own operator-facing
|
|
210
|
+
// remediation text.
|
|
11
211
|
/** Bound a failure message so no unbounded/secret-bearing text is posted. */
|
|
12
212
|
const ERROR_MESSAGE_MAX_CHARS = 300;
|
|
13
213
|
/**
|