@bridge_gpt/mcp-server 0.2.39 → 0.2.42
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 +10 -10
- package/build/agent-capabilities/cli.js +2 -1
- package/build/agent-launchers/claude-executor-adapter.js +17 -4
- package/build/claude-user-config-doctor.js +42 -11
- package/build/cli-release.js +2 -1
- package/build/commands.generated.js +4 -4
- package/build/conduct-epic/bridge-client.js +354 -113
- package/build/conduct-epic/checkpoint-store.js +75 -2
- package/build/conduct-epic/cli.js +795 -109
- package/build/conduct-epic/cut-protocol.js +327 -0
- package/build/conduct-epic/pr-state.js +113 -24
- package/build/conduct-epic/spawn.js +14 -2
- package/build/conductor/bridge-api-client.js +27 -1
- package/build/conductor/cli.js +46 -1
- package/build/conductor/doctor.js +101 -16
- package/build/conductor/epic-reconcile.js +72 -19
- package/build/conductor/epic-runtime.js +15 -3
- package/build/conductor/errors.js +47 -0
- package/build/conductor/git-hooks.js +205 -11
- package/build/conductor/install-doctor.js +230 -1
- package/build/conductor/local-merge.js +130 -28
- package/build/conductor/tools.js +32 -3
- package/build/conductor/worker-ledger-cli.js +27 -1
- package/build/conductor-bin.js +15 -15
- package/build/credentials-cli.js +3 -2
- package/build/doctor.js +107 -41
- package/build/executor/cli.js +48 -1
- package/build/executor/env.js +21 -0
- package/build/executor/index-scope.js +39 -0
- package/build/executor/job-log-registry.js +69 -0
- package/build/executor/job-runner.js +148 -26
- package/build/executor/live-worker-registry.js +83 -0
- package/build/executor/observation.js +167 -6
- package/build/executor/platform.js +147 -3
- package/build/executor/process.js +58 -14
- package/build/executor/runner.js +235 -48
- package/build/executor/test-clock.js +3 -2
- package/build/index-scope-contract.js +96 -0
- package/build/index.js +153 -204
- package/build/init.js +83 -22
- package/build/install-bridge-conductor.js +323 -14
- package/build/install-bridge.js +202 -38
- package/build/install-doctor.js +23 -9
- package/build/install-reexec.js +2 -1
- package/build/launcher-config-inspection.js +83 -22
- package/build/mcp-host-config.js +331 -67
- package/build/mcp-host-targets.js +45 -21
- package/build/mcp-identity.js +92 -0
- package/build/mcp-install-state.js +94 -1
- package/build/mcp-invoke.js +2 -1
- package/build/mcp-provisioning.js +45 -12
- package/build/mcp-registration-doctor.js +35 -13
- package/build/mcp-server-invocation.js +4 -2
- package/build/merge-pull-request.js +208 -9
- package/build/pipelines.generated.js +3 -3
- package/build/plane/defaults.js +4 -1
- package/build/plane/preflight.js +81 -10
- package/build/plane/test-fakes.js +9 -1
- package/build/readme.generated.js +1 -1
- package/build/regression-check.js +3 -2
- package/build/review-tickets.js +8 -7
- package/build/run-unit-tests-launcher.js +74 -1
- package/build/schedule-run.js +3 -2
- package/build/setup-epic.js +453 -78
- package/build/sfcc/tool-wrapper.js +15 -0
- package/build/start-tickets-prereqs.js +11 -6
- package/build/start-tickets.js +91 -85
- package/build/update-check.js +3 -2
- package/build/upgrade-advice.js +2 -1
- package/build/upgrade-cli.js +50 -18
- package/build/version.generated.js +1 -1
- package/docs/CONDUCTOR.md +22 -0
- package/docs/install/mcp-tool-integrations.md +19 -3
- package/package.json +2 -2
package/build/plane/preflight.js
CHANGED
|
@@ -44,6 +44,11 @@ export async function runPlanePreflight(repoRoot, deps) {
|
|
|
44
44
|
return { ok: false, diagnostics };
|
|
45
45
|
add(await checkClaudeLogin(deps));
|
|
46
46
|
const credentials = await checkBridgeCredentials(repoRoot, deps);
|
|
47
|
+
// Advisories first, then the failure. An insecure credentials file and an
|
|
48
|
+
// unresolvable credential are independent facts and can both be true, so the
|
|
49
|
+
// advisory is appended unconditionally rather than only on the success path.
|
|
50
|
+
for (const advisory of credentials.advisories)
|
|
51
|
+
add(advisory);
|
|
47
52
|
if (!credentials.ok)
|
|
48
53
|
add(credentials.diagnostic);
|
|
49
54
|
add(await checkPlaneBuildFreshness(repoRoot, { fs: deps.fs }));
|
|
@@ -145,6 +150,24 @@ export async function checkClaudeLogin(deps) {
|
|
|
145
150
|
* Both go through the shared resolvers. This is the shell-spawned credential
|
|
146
151
|
* rule: a plane member is launched from a spawned shell, which never sees
|
|
147
152
|
* `.mcp.json` env — that file is visible only to the MCP server process.
|
|
153
|
+
*
|
|
154
|
+
* ## Permission policy stays with the shared resolver (BAPI-773)
|
|
155
|
+
*
|
|
156
|
+
* The resolver owns the group/world-permission rule and the prose it warns
|
|
157
|
+
* with; plane neither re-implements that policy nor duplicates its threshold.
|
|
158
|
+
* What plane owns is *delivery*: the resolver writes its advisory to a `stderr`
|
|
159
|
+
* sink, and an unstructured write straight to the process stream would either
|
|
160
|
+
* be lost among the structured diagnostics `plane up` renders or interleave
|
|
161
|
+
* with them unpredictably. So the sink here is a line buffer, and each captured
|
|
162
|
+
* line becomes a non-blocking `"warning"` diagnostic that flows through the
|
|
163
|
+
* same rendering path as every other preflight finding.
|
|
164
|
+
*
|
|
165
|
+
* The resolver's warning is only as good as the mode it is given, which is why
|
|
166
|
+
* the stat adapter forwards the real one. When a successful stat carries no
|
|
167
|
+
* mode at all, `0o777` is substituted *deliberately*: an unknown mode is
|
|
168
|
+
* reported rather than silently treated as safe. A stat that rejects is left to
|
|
169
|
+
* reject — fabricating a successful stat out of a filesystem failure would
|
|
170
|
+
* invent a permission fact that was never observed.
|
|
148
171
|
*/
|
|
149
172
|
export async function checkBridgeCredentials(repoRoot, deps) {
|
|
150
173
|
const repo = await deps.resolveRepoName({
|
|
@@ -153,8 +176,11 @@ export async function checkBridgeCredentials(repoRoot, deps) {
|
|
|
153
176
|
readFile: deps.fs.readFile,
|
|
154
177
|
});
|
|
155
178
|
if (!repo.ok) {
|
|
179
|
+
// Nothing has called the credential resolver yet, so there is no advisory
|
|
180
|
+
// source to have captured from.
|
|
156
181
|
return {
|
|
157
182
|
ok: false,
|
|
183
|
+
advisories: [],
|
|
158
184
|
diagnostic: {
|
|
159
185
|
check: "bridge-credentials",
|
|
160
186
|
severity: "blocking",
|
|
@@ -163,6 +189,7 @@ export async function checkBridgeCredentials(repoRoot, deps) {
|
|
|
163
189
|
},
|
|
164
190
|
};
|
|
165
191
|
}
|
|
192
|
+
const warnings = createResolverWarningBuffer();
|
|
166
193
|
let result;
|
|
167
194
|
try {
|
|
168
195
|
result = await deps.resolveCredentials(repo.repoName, {
|
|
@@ -171,23 +198,22 @@ export async function checkBridgeCredentials(repoRoot, deps) {
|
|
|
171
198
|
platform: deps.platform,
|
|
172
199
|
readFile: deps.fs.readFile,
|
|
173
200
|
stat: async (filePath) => {
|
|
174
|
-
//
|
|
175
|
-
//
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return { mode: 0o600 };
|
|
180
|
-
},
|
|
181
|
-
stderr: () => {
|
|
182
|
-
/* the resolver's advisory warnings are not part of plane output */
|
|
201
|
+
// A rejection propagates untouched: only a *successful* stat that
|
|
202
|
+
// happens to carry no mode falls back, and it falls back to fully open
|
|
203
|
+
// so the resolver warns instead of staying silent about an unknown.
|
|
204
|
+
const statResult = await deps.fs.stat(filePath);
|
|
205
|
+
return { mode: statResult.mode !== undefined ? statResult.mode : 0o777 };
|
|
183
206
|
},
|
|
207
|
+
stderr: warnings.write,
|
|
184
208
|
});
|
|
185
209
|
}
|
|
186
210
|
catch {
|
|
187
211
|
// Sanitized: a resolver throw becomes a category, never exception text
|
|
188
|
-
// (which could echo file contents).
|
|
212
|
+
// (which could echo file contents). Advisories captured before the throw
|
|
213
|
+
// are still real observations and are kept.
|
|
189
214
|
return {
|
|
190
215
|
ok: false,
|
|
216
|
+
advisories: warnings.drain(),
|
|
191
217
|
diagnostic: {
|
|
192
218
|
check: "bridge-credentials",
|
|
193
219
|
severity: "blocking",
|
|
@@ -199,6 +225,7 @@ export async function checkBridgeCredentials(repoRoot, deps) {
|
|
|
199
225
|
if (!result.ok) {
|
|
200
226
|
return {
|
|
201
227
|
ok: false,
|
|
228
|
+
advisories: warnings.drain(),
|
|
202
229
|
diagnostic: {
|
|
203
230
|
check: "bridge-credentials",
|
|
204
231
|
severity: "blocking",
|
|
@@ -213,6 +240,50 @@ export async function checkBridgeCredentials(repoRoot, deps) {
|
|
|
213
240
|
repoName: repo.repoName,
|
|
214
241
|
apiKey: result.credentials.apiKey,
|
|
215
242
|
source: result.credentials.source,
|
|
243
|
+
advisories: warnings.drain(),
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Line buffer for the shared credential resolver's `stderr` sink.
|
|
248
|
+
*
|
|
249
|
+
* The resolver is free to emit a single warning across several callback
|
|
250
|
+
* invocations, so a chunk is not a line: text is accumulated and only split on
|
|
251
|
+
* a newline boundary. Whatever remains unterminated when the resolver finishes
|
|
252
|
+
* is flushed as a final line by `drain`, which is why a resolver that writes
|
|
253
|
+
* `"third warning"` with no trailing newline still produces a diagnostic.
|
|
254
|
+
*
|
|
255
|
+
* Nothing here writes to a process stream. That is the entire point.
|
|
256
|
+
*/
|
|
257
|
+
function createResolverWarningBuffer() {
|
|
258
|
+
const lines = [];
|
|
259
|
+
let pending = "";
|
|
260
|
+
const push = (line) => {
|
|
261
|
+
const trimmed = line.replace(/\r$/, "");
|
|
262
|
+
if (trimmed.length === 0)
|
|
263
|
+
return;
|
|
264
|
+
lines.push(trimmed);
|
|
265
|
+
};
|
|
266
|
+
return {
|
|
267
|
+
write: (message) => {
|
|
268
|
+
pending += message;
|
|
269
|
+
const segments = pending.split("\n");
|
|
270
|
+
// The final segment is whatever followed the last newline — possibly the
|
|
271
|
+
// start of a line the resolver has not finished writing yet.
|
|
272
|
+
pending = segments.pop() ?? "";
|
|
273
|
+
for (const segment of segments)
|
|
274
|
+
push(segment);
|
|
275
|
+
},
|
|
276
|
+
drain: () => {
|
|
277
|
+
if (pending.length > 0) {
|
|
278
|
+
push(pending);
|
|
279
|
+
pending = "";
|
|
280
|
+
}
|
|
281
|
+
return lines.map((message) => ({
|
|
282
|
+
check: "bridge-credentials",
|
|
283
|
+
severity: "warning",
|
|
284
|
+
message,
|
|
285
|
+
}));
|
|
286
|
+
},
|
|
216
287
|
};
|
|
217
288
|
}
|
|
218
289
|
/**
|
|
@@ -16,6 +16,7 @@ export function dirent(name, kind) {
|
|
|
16
16
|
export function createFakeFs(options = {}) {
|
|
17
17
|
const files = new Map(Object.entries(options.files ?? {}));
|
|
18
18
|
const mtimes = new Map(Object.entries(options.mtimes ?? {}));
|
|
19
|
+
const modes = new Map(Object.entries(options.modes ?? {}));
|
|
19
20
|
const dirs = new Map(Object.entries(options.dirs ?? {}));
|
|
20
21
|
const readErrors = new Map(Object.entries(options.readErrors ?? {}));
|
|
21
22
|
const calls = {
|
|
@@ -29,6 +30,7 @@ export function createFakeFs(options = {}) {
|
|
|
29
30
|
return {
|
|
30
31
|
files,
|
|
31
32
|
mtimes,
|
|
33
|
+
modes,
|
|
32
34
|
calls,
|
|
33
35
|
failNextCreateWith: (code) => {
|
|
34
36
|
pendingCreateFailure = code;
|
|
@@ -80,7 +82,13 @@ export function createFakeFs(options = {}) {
|
|
|
80
82
|
throw errno(failure);
|
|
81
83
|
if (!files.has(filePath) && !dirs.has(filePath))
|
|
82
84
|
throw errno("ENOENT");
|
|
83
|
-
|
|
85
|
+
const mode = modes.get(filePath);
|
|
86
|
+
const result = { mtimeMs: mtimes.get(filePath) ?? 0 };
|
|
87
|
+
// Assigned only when the fixture supplied one: an absent `mode` must stay
|
|
88
|
+
// absent, not become `undefined`-shaped-but-present.
|
|
89
|
+
if (mode !== undefined)
|
|
90
|
+
result.mode = mode;
|
|
91
|
+
return result;
|
|
84
92
|
},
|
|
85
93
|
readdir: async (dirPath) => {
|
|
86
94
|
const entries = dirs.get(dirPath);
|