@bridge_gpt/mcp-server 0.2.10 → 0.2.12
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 +3 -3
- package/build/commands.generated.js +6 -6
- package/build/conductor/bridge-api-client.js +2 -1
- package/build/conductor/cli.js +16 -16
- package/build/conductor/doctor.js +1 -1
- package/build/conductor/epic-reconcile.js +213 -16
- package/build/conductor/epic-runtime.js +89 -6
- package/build/conductor/epic-state.js +85 -11
- package/build/conductor/errors.js +12 -0
- package/build/conductor/git-ci-types.js +10 -0
- package/build/conductor/git-producer.js +4 -4
- package/build/conductor/merge-ledger.js +7 -7
- package/build/conductor/pr-ci-producer.js +6 -6
- package/build/conductor/pr-review-producer.js +2 -2
- package/build/conductor/producer-ledger.js +5 -5
- package/build/conductor/spec-review-producer.js +88 -0
- package/build/conductor/store.js +97 -25
- package/build/conductor/supervisor-ledger.js +2 -2
- package/build/conductor/supervisor-merge.js +5 -5
- package/build/conductor/supervisor-message-relay.js +1 -1
- package/build/conductor/supervisor-runtime.js +10 -10
- package/build/conductor/taxonomy.js +5 -0
- package/build/conductor/tools.js +5 -5
- package/build/conductor-bin.js +12350 -19
- package/build/conductor-claude-hook-bin.js +167 -17
- package/build/decision-page-schema.js +26 -0
- package/build/doctor.js +200 -0
- package/build/index.js +23705 -3630
- package/build/install-bridge.js +80 -0
- package/build/pipelines.generated.js +70 -48
- package/build/readme.generated.js +1 -1
- package/build/version.generated.js +1 -1
- package/package.json +7 -4
- package/pipelines/check-ci-ticket.json +2 -2
- package/pipelines/implement-ticket.json +2 -2
- package/pipelines/learn-repository.json +84 -42
- package/smoke-test/SMOKE-TEST.md +11 -17
package/build/install-bridge.js
CHANGED
|
@@ -34,10 +34,12 @@
|
|
|
34
34
|
* gitignored) and the user-scoped credential store (Step 4).
|
|
35
35
|
*/
|
|
36
36
|
import { readFile, writeFile, mkdir, stat, rename, chmod, unlink } from "fs/promises";
|
|
37
|
+
import { spawn } from "child_process";
|
|
37
38
|
import os from "os";
|
|
38
39
|
import path from "path";
|
|
39
40
|
import readline from "readline";
|
|
40
41
|
import { runInit, buildBridgeApiEntry } from "./init.js";
|
|
42
|
+
import { VERSION } from "./version.generated.js";
|
|
41
43
|
import { validateRepoName } from "./bridge-config.js";
|
|
42
44
|
import { resolveStartTicketsRepoName } from "./start-tickets-repo.js";
|
|
43
45
|
import { upsertBapiCredential, getPrimaryCredentialStorePath, } from "./credential-store.js";
|
|
@@ -45,6 +47,23 @@ import { DEFAULT_AGENT_NAME, resolveAgentSpec, isAgentName, formatValidAgentName
|
|
|
45
47
|
import { buildGenericAgentShellCommand, getDefaultSpawnTerminalTabForPlatform, detectTerminal, createDefaultStartTicketsDeps, } from "./start-tickets.js";
|
|
46
48
|
/** Redaction sentinel — the API-key value is NEVER printed; this stands in. */
|
|
47
49
|
export const REDACTED_API_KEY = "<REDACTED>";
|
|
50
|
+
/**
|
|
51
|
+
* Always-surfaced success-path note (BAPI-451 W3, E-3). The pinned launcher's
|
|
52
|
+
* FIRST cold launch can resolve/download the package inline; if the MCP client's
|
|
53
|
+
* connect deadline is very short it may time out before the handshake. Pre-warming
|
|
54
|
+
* (below) makes this rare, but the note is surfaced unconditionally so the
|
|
55
|
+
* fail-soft backstop is always discoverable.
|
|
56
|
+
*/
|
|
57
|
+
export const MCP_TIMEOUT_GUIDANCE = "Note: if your MCP client has a very short connect deadline, raise MCP_TIMEOUT for the first launch " +
|
|
58
|
+
"(the initial npx package resolution/download can exceed a short connect timeout).";
|
|
59
|
+
/** The exact, version-pinned launcher spec the pre-warm spawns (fast-exiting --version). */
|
|
60
|
+
export function buildPrewarmArgs() {
|
|
61
|
+
return ["-y", `@bridge_gpt/mcp-server@${VERSION}`, "--version"];
|
|
62
|
+
}
|
|
63
|
+
/** Secret-free preview of the pre-warm command (no env, no key). */
|
|
64
|
+
export function buildPrewarmCommandPreview() {
|
|
65
|
+
return `npx ${buildPrewarmArgs().join(" ")}`;
|
|
66
|
+
}
|
|
48
67
|
/** The natural-language sequential prompt handed to the spawned agent session. */
|
|
49
68
|
export const INSTALL_BRIDGE_AGENT_PROMPT = "Please execute the /install-bridge command. Once it completes successfully, execute the /learn-repository command.";
|
|
50
69
|
/** Default base URL when `BAPI_BASE_URL` is unset (mirrors index.ts). */
|
|
@@ -198,6 +217,44 @@ function promptLineViaReadline(promptText) {
|
|
|
198
217
|
});
|
|
199
218
|
});
|
|
200
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* Default pre-warm spawner (BAPI-451 W3). Spawns array-based (`shell: false`) so
|
|
222
|
+
* no argument is ever shell-interpreted, ignores all child stdio (node-gyp /
|
|
223
|
+
* download noise stays out of the CLI UX), bounds the run with a 60s timeout, and
|
|
224
|
+
* passes a SANITIZED env clone with `BAPI_API_KEY` deleted — the `--version`
|
|
225
|
+
* pre-warm never needs the key, and it must never reach an npm lifecycle script.
|
|
226
|
+
* Always resolves (never rejects): a spawn error / non-zero exit / timeout becomes
|
|
227
|
+
* `{ ok: false, warning }` with secret-free warning text.
|
|
228
|
+
*/
|
|
229
|
+
function spawnPrewarmDefault(command, args, env) {
|
|
230
|
+
return new Promise((resolve) => {
|
|
231
|
+
const sanitizedEnv = { ...env };
|
|
232
|
+
delete sanitizedEnv.BAPI_API_KEY;
|
|
233
|
+
try {
|
|
234
|
+
const child = spawn(command, args, {
|
|
235
|
+
shell: false,
|
|
236
|
+
stdio: "ignore",
|
|
237
|
+
timeout: 60_000,
|
|
238
|
+
env: sanitizedEnv,
|
|
239
|
+
});
|
|
240
|
+
child.on("error", () => resolve({ ok: false, warning: "the pre-warm process could not be started" }));
|
|
241
|
+
child.on("close", (code, signal) => {
|
|
242
|
+
if (signal) {
|
|
243
|
+
resolve({ ok: false, warning: `the pre-warm process timed out or was terminated (${signal})` });
|
|
244
|
+
}
|
|
245
|
+
else if (code === 0) {
|
|
246
|
+
resolve({ ok: true });
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
resolve({ ok: false, warning: `the pre-warm process exited with code ${code}` });
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
resolve({ ok: false, warning: "the pre-warm process could not be started" });
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
}
|
|
201
258
|
/** Build default deps from the live process. */
|
|
202
259
|
export function createDefaultInstallBridgeDeps() {
|
|
203
260
|
const isTTY = Boolean(process.stdin.isTTY);
|
|
@@ -217,6 +274,7 @@ export function createDefaultInstallBridgeDeps() {
|
|
|
217
274
|
promptSecret: isTTY ? promptSecretViaReadline : undefined,
|
|
218
275
|
promptLine: isTTY ? promptLineViaReadline : undefined,
|
|
219
276
|
fetch: (...args) => fetch(...args),
|
|
277
|
+
spawnPrewarm: spawnPrewarmDefault,
|
|
220
278
|
runInit,
|
|
221
279
|
upsertCredential: upsertBapiCredential,
|
|
222
280
|
buildShellCommand: buildGenericAgentShellCommand,
|
|
@@ -472,6 +530,8 @@ export function buildDryRunPreview(plan) {
|
|
|
472
530
|
...(plan.manualEditors.length > 0
|
|
473
531
|
? [` ${plan.manualEditors.join(" + ")}: detected (global config) — manual setup instructions would be printed.`]
|
|
474
532
|
: []),
|
|
533
|
+
`Step 3b — pre-warm the version-pinned launcher bucket (fail-open, env sanitized — BAPI_API_KEY removed): ${plan.prewarmCommand}`,
|
|
534
|
+
MCP_TIMEOUT_GUIDANCE,
|
|
475
535
|
`Step 4 — persist routing credential: target ${plan.credentialTarget} at ${plan.credentialStorePath}`,
|
|
476
536
|
`Step 5 — spawn agent session: ${plan.spawnCommand}`,
|
|
477
537
|
];
|
|
@@ -590,6 +650,7 @@ export async function runInstallBridgeCli(argv, overrides = {}) {
|
|
|
590
650
|
credentialTarget: `bapi:${repoName}`,
|
|
591
651
|
credentialStorePath,
|
|
592
652
|
pingUrl: buildPingUrl(baseUrl, repoName),
|
|
653
|
+
prewarmCommand: buildPrewarmCommandPreview(),
|
|
593
654
|
spawnCommand,
|
|
594
655
|
};
|
|
595
656
|
// ---- --dry-run: preview every step, strictly no side effects ----
|
|
@@ -639,6 +700,25 @@ export async function runInstallBridgeCli(argv, overrides = {}) {
|
|
|
639
700
|
const manualInstructions = buildManualHostInstructions(entry, manualEditors);
|
|
640
701
|
if (manualInstructions)
|
|
641
702
|
log(manualInstructions);
|
|
703
|
+
// ---- Step 3b — pre-warm the @${VERSION}-pinned _npx bucket (BAPI-451 W3) ----
|
|
704
|
+
// The launcher just written is pinned to @${VERSION}, a DIFFERENT _npx bucket
|
|
705
|
+
// than the @latest bucket this `npx … install-bridge` invocation warmed. Spawn
|
|
706
|
+
// the exact pinned launcher once with the fast-exiting `--version` flag so the
|
|
707
|
+
// first real MCP launch resolves from a warm bucket instead of paying the cold
|
|
708
|
+
// install inline (which can exceed the client's connect deadline). Strictly
|
|
709
|
+
// fail-open: a failure warns (secret-free) but never fails the install.
|
|
710
|
+
log(" pre-warming the version-pinned launcher bucket…");
|
|
711
|
+
const prewarm = await deps.spawnPrewarm("npx", buildPrewarmArgs(), deps.env);
|
|
712
|
+
if (prewarm.ok) {
|
|
713
|
+
log(" launcher bucket warmed (the first MCP launch will not pay a cold install).");
|
|
714
|
+
log(` ${MCP_TIMEOUT_GUIDANCE}`);
|
|
715
|
+
}
|
|
716
|
+
else {
|
|
717
|
+
// Escalate to a stronger, still secret-free warning when pre-warm didn't
|
|
718
|
+
// complete cleanly — but the install itself still succeeds (exit unaffected).
|
|
719
|
+
errorLog(`Warning: could not pre-warm the version-pinned launcher bucket${prewarm.warning ? ` (${prewarm.warning})` : ""}. ` +
|
|
720
|
+
`The first MCP launch may pay a one-time cold install and could be slow. ${MCP_TIMEOUT_GUIDANCE}`);
|
|
721
|
+
}
|
|
642
722
|
// ---- Step 4 — persist routing credential (non-blocking / fail-open) ----
|
|
643
723
|
log("Step 4/5 — persisting routing credential…");
|
|
644
724
|
try {
|