@bridge_gpt/mcp-server 0.2.26 → 0.2.28
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 +32 -24
- package/build/commands.generated.js +2 -2
- package/build/conductor/bridge-api-client.js +98 -1
- package/build/conductor/epic-reconcile.js +28 -0
- package/build/conductor/epic-runtime.js +28 -1
- package/build/conductor-bin.js +68 -9267
- package/build/conductor-claude-hook-bin.js +2 -172
- package/build/connect-github-api.js +9 -0
- package/build/connect-github.js +10 -0
- package/build/decision-page-template.js +2 -31
- package/build/doctor.js +2 -2
- package/build/env-flags.js +23 -0
- package/build/index.js +4699 -37043
- package/build/init.js +80 -56
- package/build/install-bridge.js +451 -153
- package/build/mcp-host-targets.js +12 -0
- package/build/readme.generated.js +1 -1
- package/build/setup-epic.js +198 -4
- package/build/start-tickets.js +25 -4
- package/build/tool-surface-gating.js +13 -2
- package/build/version.generated.js +1 -1
- package/package.json +3 -5
- package/design-assets/favicon/android-chrome-192x192.png +0 -0
- package/design-assets/favicon/android-chrome-512x512.png +0 -0
- package/design-assets/favicon/apple-touch-icon.png +0 -0
- package/design-assets/favicon/favicon-16x16.png +0 -0
- package/design-assets/favicon/favicon.ico +0 -0
- package/design-assets/favicon/site.webmanifest +0 -1
- package/public/css/main.min.css +0 -4971
- package/public/css/main.min.css.map +0 -1
- package/public/fonts/OFL.txt +0 -93
- package/public/fonts/SourceSansPro-Black.ttf +0 -0
- package/public/fonts/SourceSansPro-BlackItalic.ttf +0 -0
- package/public/fonts/SourceSansPro-Bold.ttf +0 -0
- package/public/fonts/SourceSansPro-BoldItalic.ttf +0 -0
- package/public/fonts/SourceSansPro-ExtraLight.ttf +0 -0
- package/public/fonts/SourceSansPro-ExtraLightItalic.ttf +0 -0
- package/public/fonts/SourceSansPro-Italic.ttf +0 -0
- package/public/fonts/SourceSansPro-Light.ttf +0 -0
- package/public/fonts/SourceSansPro-LightItalic.ttf +0 -0
- package/public/fonts/SourceSansPro-Regular.ttf +0 -0
- package/public/fonts/SourceSansPro-SemiBold.ttf +0 -0
- package/public/fonts/SourceSansPro-SemiBoldItalic.ttf +0 -0
- package/public/img/bridge-logo-160x51.webp +0 -0
- package/public/img/bridge-logo-300x92.webp +0 -0
- package/public/img/favicon/android-chrome-192x192.png +0 -0
- package/public/img/favicon/android-chrome-512x512.png +0 -0
- package/public/img/favicon/apple-touch-icon.png +0 -0
- package/public/img/favicon/favicon-16x16.png +0 -0
- package/public/img/favicon/favicon-32x32.png +0 -0
- package/public/img/favicon/favicon.ico +0 -0
- package/public/img/favicon/site.webmanifest +0 -1
- package/public/img/installation/bitbucket/app-password-1.png +0 -0
- package/public/img/installation/bitbucket/app-password-2.png +0 -0
- package/public/img/installation/bitbucket/create-token-1.png +0 -0
- package/public/img/installation/bitbucket/create-token-2.png +0 -0
- package/public/img/installation/bitbucket/webhook-1.png +0 -0
- package/public/img/installation/github/github-review-webhook.png +0 -0
- package/public/img/installation/jira/credentials/api-key.png +0 -0
- package/public/img/installation/jira/webhook/create-rule.png +0 -0
- package/public/img/installation/jira/webhook/project-settings.png +0 -0
- package/public/img/installation/jira/webhook/rule-create-1.png +0 -0
- package/public/img/installation/jira/webhook/rule-create-2.png +0 -0
- package/public/img/installation/jira/webhook/rule-create-3.png +0 -0
- package/public/img/installation/pinecone/pinecone-api-key.png +0 -0
- package/public/img/installation/pinecone/pinecone-index.png +0 -0
- package/public/js/main.min.js +0 -10409
- package/public/js/main.min.js.map +0 -1
- package/smoke-test/SMOKE-TEST.md +0 -560
- package/smoke-test/smoke-test-mcp.md +0 -23
package/build/init.js
CHANGED
|
@@ -33,9 +33,16 @@ export function buildBridgeApiEntry(cwd) {
|
|
|
33
33
|
// where 0.2.6 persisted despite an upgrade). Pinning keeps the running
|
|
34
34
|
// configuration predictable and visible in version control. The `install-bridge`
|
|
35
35
|
// config write reuses this same entry so both install paths agree.
|
|
36
|
+
//
|
|
37
|
+
// `--prefer-offline` makes npx resolve the (immutable, exact-pinned) version
|
|
38
|
+
// from the local npm cache and skip the redundant registry-metadata round-trip
|
|
39
|
+
// on every boot, only hitting the network on a genuine cache miss (unlike
|
|
40
|
+
// `--offline`, it falls back automatically). It cannot resurrect a stale build
|
|
41
|
+
// — the BAPI-429 hazard above was specific to UNPINNED specs; here the exact
|
|
42
|
+
// `@${VERSION}` is immutable, so a cache hit is always the right build.
|
|
36
43
|
return {
|
|
37
44
|
command: "npx",
|
|
38
|
-
args: ["-y", `@bridge_gpt/mcp-server@${VERSION}`],
|
|
45
|
+
args: ["-y", "--prefer-offline", `@bridge_gpt/mcp-server@${VERSION}`],
|
|
39
46
|
env: {
|
|
40
47
|
BAPI_BASE_URL: "https://bridgegpt-api.com",
|
|
41
48
|
BAPI_REPO_NAME: "YOUR_REPO_NAME",
|
|
@@ -143,6 +150,32 @@ async function ensureGitignored(cwd, filePath) {
|
|
|
143
150
|
mkdir: (p, options) => mkdir(p, options),
|
|
144
151
|
});
|
|
145
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Read-compare-write a single scaffold file. Returns "skipped" when the target
|
|
155
|
+
* already holds identical bytes (no write), "overwritten" when it existed with
|
|
156
|
+
* different bytes, and "written" when it was absent. Optionally ensures `mkdirDir`
|
|
157
|
+
* exists first (used by the DOCS phase, whose targets span different subdirs).
|
|
158
|
+
*
|
|
159
|
+
* Extracted so the COMMANDS/DOCS/AGENTS phases can run their per-file work
|
|
160
|
+
* concurrently via Promise.all instead of one-await-at-a-time: on a slow disk the
|
|
161
|
+
* sequential syscalls dominated `runInit`. The caller applies each outcome to its
|
|
162
|
+
* summary Sets AFTER the batch, iterating the ordered results, so behavior and
|
|
163
|
+
* console output are byte-for-byte identical to the sequential version.
|
|
164
|
+
*/
|
|
165
|
+
async function scaffoldFile(target, content, mkdirDir) {
|
|
166
|
+
if (mkdirDir !== undefined)
|
|
167
|
+
await mkdir(mkdirDir, { recursive: true });
|
|
168
|
+
let existed = false;
|
|
169
|
+
try {
|
|
170
|
+
const existing = await readFile(target, "utf-8");
|
|
171
|
+
if (existing === content)
|
|
172
|
+
return "skipped";
|
|
173
|
+
existed = true;
|
|
174
|
+
}
|
|
175
|
+
catch { /* file doesn't exist */ }
|
|
176
|
+
await writeFile(target, content, "utf-8");
|
|
177
|
+
return existed ? "overwritten" : "written";
|
|
178
|
+
}
|
|
146
179
|
/**
|
|
147
180
|
* Core initialization logic shared by --init and --upgrade.
|
|
148
181
|
* Runs all scaffolding phases without calling process.exit().
|
|
@@ -272,22 +305,22 @@ export async function runInit(cwd) {
|
|
|
272
305
|
const writtenFiles = new Set();
|
|
273
306
|
const skippedFiles = new Set();
|
|
274
307
|
const overwrittenFiles = new Set();
|
|
308
|
+
const commandEntries = Object.entries(COMMANDS);
|
|
275
309
|
for (const dir of commandDirs) {
|
|
276
310
|
await mkdir(dir, { recursive: true });
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
overwrittenFiles.add(filename);
|
|
311
|
+
// Per-file read/compare/write runs concurrently; outcomes are applied to the
|
|
312
|
+
// Sets afterward in entry order so the summary counts are unchanged.
|
|
313
|
+
const outcomes = await Promise.all(commandEntries.map(([filename, content]) => scaffoldFile(path.join(dir, filename), content)));
|
|
314
|
+
commandEntries.forEach(([filename], i) => {
|
|
315
|
+
const outcome = outcomes[i];
|
|
316
|
+
if (outcome === "skipped") {
|
|
317
|
+
skippedFiles.add(filename);
|
|
318
|
+
return;
|
|
286
319
|
}
|
|
287
|
-
|
|
288
|
-
|
|
320
|
+
if (outcome === "overwritten")
|
|
321
|
+
overwrittenFiles.add(filename);
|
|
289
322
|
writtenFiles.add(filename);
|
|
290
|
-
}
|
|
323
|
+
});
|
|
291
324
|
}
|
|
292
325
|
// A file written in any directory takes priority over skipped
|
|
293
326
|
for (const f of writtenFiles)
|
|
@@ -312,20 +345,21 @@ export async function runInit(cwd) {
|
|
|
312
345
|
// project root; content is never secret.
|
|
313
346
|
const docsWritten = new Set();
|
|
314
347
|
const docsSkipped = new Set();
|
|
315
|
-
|
|
348
|
+
const docEntries = Object.entries(DOCS);
|
|
349
|
+
// Each doc target may live in a different subdir, so mkdir(dirname) happens
|
|
350
|
+
// per-file inside scaffoldFile. Outcomes applied in entry order below preserve
|
|
351
|
+
// the insertion order of the joined summary list.
|
|
352
|
+
const docOutcomes = await Promise.all(docEntries.map(([relTarget, content]) => {
|
|
316
353
|
const target = path.join(cwd, relTarget);
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
await writeFile(target, content, "utf-8");
|
|
327
|
-
docsWritten.add(relTarget);
|
|
328
|
-
}
|
|
354
|
+
return scaffoldFile(target, content, path.dirname(target));
|
|
355
|
+
}));
|
|
356
|
+
docEntries.forEach(([relTarget], i) => {
|
|
357
|
+
// DOCS tracks only written vs skipped; an overwrite counts as written.
|
|
358
|
+
if (docOutcomes[i] === "skipped")
|
|
359
|
+
docsSkipped.add(relTarget);
|
|
360
|
+
else
|
|
361
|
+
docsWritten.add(relTarget);
|
|
362
|
+
});
|
|
329
363
|
const docsTotal = Object.keys(DOCS).length;
|
|
330
364
|
if (docsTotal > 0) {
|
|
331
365
|
console.log(`\nDocumentation: scaffolded ${docsTotal} doc asset${docsTotal === 1 ? "" : "s"}`);
|
|
@@ -341,42 +375,32 @@ export async function runInit(cwd) {
|
|
|
341
375
|
// Always scaffold to .claude/agents/
|
|
342
376
|
const claudeAgentsDir = path.join(cwd, ".claude", "agents");
|
|
343
377
|
await mkdir(claudeAgentsDir, { recursive: true });
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
378
|
+
const agentEntries = Object.entries(AGENTS);
|
|
379
|
+
// Apply a batch of ordered outcomes to the agent Sets (same branches as the
|
|
380
|
+
// original per-file loop: skipped → skipped; overwritten → overwritten+written;
|
|
381
|
+
// written → written).
|
|
382
|
+
const applyAgentOutcomes = (filenames, outcomes) => {
|
|
383
|
+
filenames.forEach((filename, i) => {
|
|
384
|
+
const outcome = outcomes[i];
|
|
385
|
+
if (outcome === "skipped") {
|
|
351
386
|
agentSkipped.add(filename);
|
|
352
|
-
|
|
387
|
+
return;
|
|
353
388
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}
|
|
389
|
+
if (outcome === "overwritten")
|
|
390
|
+
agentOverwritten.add(filename);
|
|
391
|
+
agentWritten.add(filename);
|
|
392
|
+
});
|
|
393
|
+
};
|
|
394
|
+
const claudeAgentFilenames = agentEntries.map(([key]) => `${key}.md`);
|
|
395
|
+
const claudeAgentOutcomes = await Promise.all(agentEntries.map(([key, agent]) => scaffoldFile(path.join(claudeAgentsDir, `${key}.md`), reconstructAgentMarkdown(agent.frontmatter, agent.body))));
|
|
396
|
+
applyAgentOutcomes(claudeAgentFilenames, claudeAgentOutcomes);
|
|
360
397
|
// Scaffold to .github/agents/ for VS Code / Copilot
|
|
361
398
|
if (ideDetection.vscode) {
|
|
362
399
|
const copilotAgentsDir = path.join(cwd, ".github", "agents");
|
|
363
400
|
await mkdir(copilotAgentsDir, { recursive: true });
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
const target = path.join(copilotAgentsDir, filename);
|
|
368
|
-
try {
|
|
369
|
-
const existing = await readFile(target, "utf-8");
|
|
370
|
-
if (existing === content) {
|
|
371
|
-
agentSkipped.add(filename);
|
|
372
|
-
continue;
|
|
373
|
-
}
|
|
374
|
-
agentOverwritten.add(filename);
|
|
375
|
-
}
|
|
376
|
-
catch { /* file doesn't exist */ }
|
|
377
|
-
await writeFile(target, content, "utf-8");
|
|
378
|
-
agentWritten.add(filename);
|
|
379
|
-
}
|
|
401
|
+
const copilotAgentFilenames = agentEntries.map(([key]) => `${key}.agent.md`);
|
|
402
|
+
const copilotAgentOutcomes = await Promise.all(agentEntries.map(([key, agent]) => scaffoldFile(path.join(copilotAgentsDir, `${key}.agent.md`), translateAgentToCopilot(agent.frontmatter, agent.body))));
|
|
403
|
+
applyAgentOutcomes(copilotAgentFilenames, copilotAgentOutcomes);
|
|
380
404
|
}
|
|
381
405
|
// TODO: Add Cursor agent scaffolding when Cursor publishes a formal agent spec
|
|
382
406
|
// A file written in any directory takes priority over skipped
|