@bridge_gpt/mcp-server 0.2.31 → 0.2.32
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 +53 -21
- package/build/credential-store.js +302 -18
- package/build/doctor.js +80 -35
- package/build/index.js +17 -16
- package/build/install-bridge.js +1477 -440
- package/build/install-doctor.js +37 -4
- package/build/readme.generated.js +1 -1
- package/build/start-tickets.js +12 -1
- package/build/version.generated.js +1 -1
- package/package.json +3 -2
package/build/doctor.js
CHANGED
|
@@ -20,7 +20,7 @@ import os from "os";
|
|
|
20
20
|
import path from "path";
|
|
21
21
|
import { createDefaultStartTicketsDeps } from "./start-tickets.js";
|
|
22
22
|
import { VERSION } from "./version.generated.js";
|
|
23
|
-
import { collectInstallStatusChecks, formatInstallStatusReport, resolveInstallDoctorTarget, } from "./install-doctor.js";
|
|
23
|
+
import { collectInstallStatusChecks, formatInstallStatusReport, formatInstallStatusFallbackReport, resolveInstallDoctorTarget, } from "./install-doctor.js";
|
|
24
24
|
import { parseDefaultOnEnvFlag } from "./env-flags.js";
|
|
25
25
|
import { createBridgeApiUrls } from "./bridge-api-urls.js";
|
|
26
26
|
import { probeToolSurface } from "./tool-surface-gating.js";
|
|
@@ -28,21 +28,37 @@ import { resolveBapiCredentials } from "./credential-store.js";
|
|
|
28
28
|
import { DEFAULT_AGENT_NAME, resolveAgentSpec, isAgentName, formatValidAgentNames, } from "./agent-registry.js";
|
|
29
29
|
import { getDoctorPrereqDescriptors, probePrerequisite, } from "./start-tickets-prereqs.js";
|
|
30
30
|
import { resolveProfiles } from "./mcp-profile.js";
|
|
31
|
+
/**
|
|
32
|
+
* The report/usage title (BAPI-669, U9b). `doctor` diagnoses the whole Bridge
|
|
33
|
+
* install — install status, prerequisites, launcher cache, and tool surface — so it
|
|
34
|
+
* is no longer titled as a start-tickets-only tool. Defined once and shared by
|
|
35
|
+
* {@link getDoctorUsage} and {@link buildDoctorReportHeader} so the two cannot drift.
|
|
36
|
+
*/
|
|
37
|
+
export const DOCTOR_REPORT_TITLE = "bridge doctor — read-only diagnostics";
|
|
31
38
|
/** User-facing usage text for the read-only `doctor` subcommand. */
|
|
32
39
|
export function getDoctorUsage() {
|
|
33
40
|
return [
|
|
34
41
|
"Usage:",
|
|
35
42
|
" npx -y @bridge_gpt/mcp-server doctor [--agent <name>]",
|
|
36
43
|
"",
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
// BAPI-669 (U9b): `doctor` is the general Bridge diagnostic command, not a
|
|
45
|
+
// start-tickets-only one — and its report leads with install status, so the
|
|
46
|
+
// usage text describes it in that order too.
|
|
47
|
+
`${DOCTOR_REPORT_TITLE}. It only checks your environment and prints manual`,
|
|
48
|
+
"install instructions — it does not install anything, modify your system, or",
|
|
49
|
+
"start the MCP server.",
|
|
40
50
|
"",
|
|
41
51
|
"Flags:",
|
|
42
52
|
" --agent claude|cursor-agent Agent to include in the prerequisite check (default: claude)",
|
|
43
53
|
" -h, --help Show this help",
|
|
44
54
|
"",
|
|
45
|
-
"
|
|
55
|
+
"The report opens with an advisory 'Install status' section (easy-install done",
|
|
56
|
+
"criteria): repo identity, credential resolution, server connectivity,",
|
|
57
|
+
"bootstrap-field completeness, integration credentials, and repository-indexing",
|
|
58
|
+
"state. It performs read-only GETs only and never affects the exit code.",
|
|
59
|
+
"",
|
|
60
|
+
"After that come the start-tickets prerequisite checks (for the current OS):",
|
|
61
|
+
"the start-tickets preflight prerequisites plus",
|
|
46
62
|
"uv, the selected agent's command, Bridge API credential resolution, and",
|
|
47
63
|
"worktree MCP registration reachability. Credential resolution reports the",
|
|
48
64
|
"source it would use (env vs. store target bapi:<repo>); it never reads or",
|
|
@@ -50,11 +66,6 @@ export function getDoctorUsage() {
|
|
|
50
66
|
"migrate a credential, use /install-bridge or the `credentials` subcommand —",
|
|
51
67
|
"doctor stays strictly read-only.",
|
|
52
68
|
"",
|
|
53
|
-
"The report also includes an advisory 'Install status' section (easy-install",
|
|
54
|
-
"done criteria): repo identity, credential resolution, server connectivity,",
|
|
55
|
-
"bootstrap-field completeness, and repository-indexing state. It performs",
|
|
56
|
-
"read-only GETs only and never affects the exit code.",
|
|
57
|
-
"",
|
|
58
69
|
"It also includes an advisory 'MCP tool surface' section (BAPI-641): what",
|
|
59
70
|
"dynamic capability gating would advertise for this repo. It performs at most",
|
|
60
71
|
"one read-only GET to /jira/mcp/tool-surface (none under the kill switch) and",
|
|
@@ -155,20 +166,31 @@ export async function collectDoctorResults(deps, agentName) {
|
|
|
155
166
|
return { ok: true, results };
|
|
156
167
|
}
|
|
157
168
|
/**
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
169
|
+
* The BROAD report header: title plus the run's platform / agent / profile
|
|
170
|
+
* metadata (BAPI-669, U9b). Split out from the prerequisite body so `runDoctorCli`
|
|
171
|
+
* has a clear insertion point for the Install-status section between the two — the
|
|
172
|
+
* ordering change is the whole point, and it must not require rewriting the
|
|
173
|
+
* prerequisite formatting below.
|
|
162
174
|
*/
|
|
163
|
-
export function
|
|
175
|
+
export function buildDoctorReportHeader(platform, agent) {
|
|
164
176
|
const activeGroups = Array.from(resolveProfiles(process.env.BRIDGE_MCP_PROFILE)).join(", ");
|
|
165
|
-
|
|
166
|
-
|
|
177
|
+
return [
|
|
178
|
+
DOCTOR_REPORT_TITLE,
|
|
167
179
|
`Platform: ${platform}`,
|
|
168
180
|
`Selected agent: ${agent.name} (command: ${agent.command})`,
|
|
169
181
|
`Active MCP Groups: \`${activeGroups}\``,
|
|
170
182
|
"",
|
|
171
183
|
];
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* The start-tickets PREREQUISITE section: one found/missing line per prerequisite,
|
|
187
|
+
* the exact manual install hint for each missing one (framed as manual instructions
|
|
188
|
+
* only), and the selected agent's auth note (especially the `cursor-agent login`
|
|
189
|
+
* reminder). Pure formatting — no probing. Byte-identical to what
|
|
190
|
+
* {@link formatDoctorReport} has always rendered below its header.
|
|
191
|
+
*/
|
|
192
|
+
export function formatDoctorPrereqSection(platform, collection) {
|
|
193
|
+
const lines = [];
|
|
172
194
|
if (!collection.ok) {
|
|
173
195
|
lines.push(`Platform '${platform}' is unsupported. start-tickets supports darwin, win32, and linux.`);
|
|
174
196
|
return lines.join("\n");
|
|
@@ -193,6 +215,17 @@ export function formatDoctorReport(platform, agent, collection) {
|
|
|
193
215
|
lines.push("For conductor ledger/native-module diagnostics, run: conductor doctor");
|
|
194
216
|
return lines.join("\n");
|
|
195
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Header + prerequisite section, composed. Retained as the single-call rendering
|
|
220
|
+
* used by direct callers and tests; `runDoctorCli` composes the two halves itself so
|
|
221
|
+
* it can slot Install status between them (BAPI-669, U9c).
|
|
222
|
+
*/
|
|
223
|
+
export function formatDoctorReport(platform, agent, collection) {
|
|
224
|
+
return [
|
|
225
|
+
...buildDoctorReportHeader(platform, agent),
|
|
226
|
+
formatDoctorPrereqSection(platform, collection),
|
|
227
|
+
].join("\n");
|
|
228
|
+
}
|
|
196
229
|
// ---------------------------------------------------------------------------
|
|
197
230
|
// Launcher-cache diagnostics (BAPI-451 W3, E-4/E-9) — strictly read-only.
|
|
198
231
|
//
|
|
@@ -504,25 +537,20 @@ export async function runDoctorCli(argv, overrides = {}) {
|
|
|
504
537
|
const deps = overrides.deps ?? createDefaultStartTicketsDeps();
|
|
505
538
|
const agent = resolveAgentSpec(parsed.options.agentName) ?? resolveAgentSpec(DEFAULT_AGENT_NAME);
|
|
506
539
|
const collection = await collectDoctorResults(deps, parsed.options.agentName);
|
|
507
|
-
|
|
508
|
-
//
|
|
509
|
-
//
|
|
510
|
-
//
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
const launcherInspections = await inspectLauncherCache(launcherDeps);
|
|
518
|
-
log(formatLauncherCacheReport(launcherInspections));
|
|
519
|
-
}
|
|
520
|
-
catch {
|
|
521
|
-
/* launcher-cache diagnostics are advisory; never block the doctor report */
|
|
522
|
-
}
|
|
540
|
+
// ---- Section order (BAPI-669, U9c) ----
|
|
541
|
+
// Broad header → Install status → start-tickets prerequisites → launcher cache →
|
|
542
|
+
// MCP tool surface. Install status renders FIRST and UNCONDITIONALLY: it answers
|
|
543
|
+
// "is this project actually set up?", which is what someone running `doctor` after
|
|
544
|
+
// an install is asking. There is deliberately no "invocation context" flag to gate
|
|
545
|
+
// the ordering on — the report has a single caller and carries no context, so
|
|
546
|
+
// always-first is both simpler and equivalent. The `installStatus: false` override
|
|
547
|
+
// remains a dependency-injection-only seam for hermetic tests; a normal CLI
|
|
548
|
+
// invocation never takes it.
|
|
549
|
+
log(buildDoctorReportHeader(deps.platform, agent).join("\n"));
|
|
523
550
|
// Advisory install-status section (easy-install done criteria). Read-only GETs
|
|
524
551
|
// only; any failure degrades to WARN/SKIP lines inside the section, and any
|
|
525
|
-
// unexpected throw
|
|
552
|
+
// unexpected throw renders the sanitized fallback rather than dropping the
|
|
553
|
+
// report's first section — the exit code is never affected either way.
|
|
526
554
|
if (overrides.installStatus !== false) {
|
|
527
555
|
try {
|
|
528
556
|
// Reuse fs deps injected on `deps` (doctor's credential probes place them
|
|
@@ -543,9 +571,26 @@ export async function runDoctorCli(argv, overrides = {}) {
|
|
|
543
571
|
log(formatInstallStatusReport(checks));
|
|
544
572
|
}
|
|
545
573
|
catch {
|
|
546
|
-
|
|
574
|
+
// Advisory, but never silently absent: the first section always renders.
|
|
575
|
+
log(formatInstallStatusFallbackReport());
|
|
547
576
|
}
|
|
548
577
|
}
|
|
578
|
+
log(formatDoctorPrereqSection(deps.platform, collection));
|
|
579
|
+
// Strictly read-only launcher-cache diagnostics (BAPI-451). Best-effort: a probe
|
|
580
|
+
// failure never changes the doctor exit code (cold-start readiness is advisory,
|
|
581
|
+
// not a hard prerequisite). The exit code remains driven by required prereqs.
|
|
582
|
+
try {
|
|
583
|
+
const launcherDeps = {
|
|
584
|
+
cwd: overrides.launcherProbe?.cwd ?? deps.cwd,
|
|
585
|
+
readFile: overrides.launcherProbe?.readFile ?? ((p) => readFile(p, "utf-8")),
|
|
586
|
+
probeNpxNoInstall: overrides.launcherProbe?.probeNpxNoInstall ?? probeNpxNoInstallDefault,
|
|
587
|
+
};
|
|
588
|
+
const launcherInspections = await inspectLauncherCache(launcherDeps);
|
|
589
|
+
log(formatLauncherCacheReport(launcherInspections));
|
|
590
|
+
}
|
|
591
|
+
catch {
|
|
592
|
+
/* launcher-cache diagnostics are advisory; never block the doctor report */
|
|
593
|
+
}
|
|
549
594
|
// Advisory MCP tool-surface capability section (BAPI-641). Strictly read-only:
|
|
550
595
|
// one 500 ms GET (or none, under the kill switch). Any timeout, malformed
|
|
551
596
|
// response, or unexpected throw degrades to a "fail-open to full surface" line
|