@bridge_gpt/mcp-server 0.2.52 → 0.2.53
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 +42 -12
- package/build/commands.generated.js +6 -4
- package/build/conductor/bridge-api-client.js +61 -0
- package/build/conductor/cli.js +23 -0
- package/build/conductor/doctor.js +428 -5
- package/build/conductor/install-doctor.js +65 -656
- package/build/conductor/readiness-cli.js +152 -0
- package/build/conductor/readiness-sections.js +666 -0
- package/build/conductor/readiness.js +710 -0
- package/build/conductor/tools.js +56 -3
- package/build/conductor-bin.js +21 -17
- package/build/index.js +4651 -4580
- package/build/install-doctor.js +154 -2
- package/build/pipelines.generated.js +3 -3
- package/build/plane/alembic-head.js +40 -11
- package/build/plane/build-freshness.js +22 -11
- package/build/plane/preflight.js +363 -48
- package/build/plane/types.js +36 -0
- package/build/readiness-check.js +412 -0
- package/build/readme.generated.js +1 -1
- package/build/version.generated.js +3 -3
- package/package.json +2 -2
- package/pipelines/{full-automation.json → idea-to-pr.json} +1 -1
|
@@ -13,10 +13,16 @@
|
|
|
13
13
|
* condition it guards is already reported loudly by the server at dispatch time.
|
|
14
14
|
*/
|
|
15
15
|
import path from "path";
|
|
16
|
+
import { planeCheckFinding, planeCheckPassed } from "./types.js";
|
|
16
17
|
/** Remediation embedded in a confirmed-mismatch diagnostic. */
|
|
17
18
|
export const PLANE_ALEMBIC_REMEDIATION = "alembic -c alembic.ini upgrade head";
|
|
18
19
|
/** Fixed prefix of the fail-open warning, so tests and greps can match it. */
|
|
19
20
|
export const PLANE_ALEMBIC_UNVERIFIED_PREFIX = "could not verify database migration head";
|
|
21
|
+
/** Structured fix for a confirmed migration mismatch. */
|
|
22
|
+
export const PLANE_ALEMBIC_MISMATCH_REMEDIATION = `run \`${PLANE_ALEMBIC_REMEDIATION}\` to bring the database up to the migration head, then retry.`;
|
|
23
|
+
/** Structured fix for an unverifiable migration head. Never blocking. */
|
|
24
|
+
export const PLANE_ALEMBIC_UNVERIFIED_REMEDIATION = "verify by hand with `alembic -c alembic.ini heads` and `alembic -c alembic.ini current`; " +
|
|
25
|
+
"startup continues, and the server reports CONTRACT_MIGRATION_BEHIND at dispatch if the database is behind.";
|
|
20
26
|
/**
|
|
21
27
|
* Path to the repository virtualenv's Alembic executable.
|
|
22
28
|
*
|
|
@@ -72,39 +78,62 @@ export function parseAlembicRevisions(output) {
|
|
|
72
78
|
export async function checkAlembicHead(repoRoot, deps) {
|
|
73
79
|
const alembic = resolveRepositoryAlembicCommand(repoRoot, deps.platform);
|
|
74
80
|
if (!(await deps.fileExists(alembic))) {
|
|
75
|
-
return unverified("the repository virtualenv Alembic executable was not found");
|
|
81
|
+
return unverified("the repository virtualenv Alembic executable was not found", "the repository virtualenv Alembic executable was not found");
|
|
76
82
|
}
|
|
77
83
|
const heads = await deps.execFile(alembic, ["-c", "alembic.ini", "heads"], { cwd: repoRoot });
|
|
78
84
|
if (!heads.ok) {
|
|
79
|
-
|
|
85
|
+
// The interpolated `error` stays in the legacy message for the operator at
|
|
86
|
+
// the terminal; the consolidated detail is fixed prose. In production that
|
|
87
|
+
// field is an errno code, but this outcome flows into a wider report and
|
|
88
|
+
// must not depend on every caller keeping it that way.
|
|
89
|
+
return unverified(`\`alembic heads\` did not complete (${heads.error})`, "`alembic heads` did not complete");
|
|
80
90
|
}
|
|
81
91
|
const current = await deps.execFile(alembic, ["-c", "alembic.ini", "current"], { cwd: repoRoot });
|
|
82
92
|
if (!current.ok) {
|
|
83
|
-
return unverified(`\`alembic current\` did not complete (${current.error})`);
|
|
93
|
+
return unverified(`\`alembic current\` did not complete (${current.error})`, "`alembic current` did not complete");
|
|
84
94
|
}
|
|
85
95
|
const headRevisions = parseAlembicRevisions(heads.stdout);
|
|
86
96
|
const currentRevisions = parseAlembicRevisions(current.stdout);
|
|
87
97
|
if (headRevisions === null || currentRevisions === null) {
|
|
88
|
-
return unverified("Alembic output did not contain a readable revision");
|
|
98
|
+
return unverified("Alembic output did not contain a readable revision", "Alembic output did not contain a readable revision");
|
|
89
99
|
}
|
|
90
100
|
const matches = headRevisions.length === currentRevisions.length &&
|
|
91
101
|
headRevisions.every((rev, i) => rev === currentRevisions[i]);
|
|
92
|
-
if (matches)
|
|
93
|
-
return
|
|
94
|
-
|
|
102
|
+
if (matches) {
|
|
103
|
+
return planeCheckPassed("alembic-head", ALEMBIC_CHECK_LABEL, "the database is at the repository migration head");
|
|
104
|
+
}
|
|
105
|
+
return planeCheckFinding({
|
|
95
106
|
check: "alembic-head",
|
|
96
107
|
severity: "blocking",
|
|
97
108
|
message: `the database is not at the migration head — heads [${headRevisions.join(", ")}], ` +
|
|
98
109
|
`current [${currentRevisions.join(", ")}]. A database behind the head blocks ` +
|
|
99
110
|
`conductor dispatch. Run \`${PLANE_ALEMBIC_REMEDIATION}\``,
|
|
100
|
-
|
|
111
|
+
remediation: PLANE_ALEMBIC_MISMATCH_REMEDIATION,
|
|
112
|
+
}, ALEMBIC_CHECK_LABEL,
|
|
113
|
+
// Revision ids are repository-authored slugs, not secrets, and they are the
|
|
114
|
+
// one fact that makes this finding actionable.
|
|
115
|
+
`database at [${currentRevisions.join(", ")}], repository head [${headRevisions.join(", ")}]`);
|
|
101
116
|
}
|
|
102
|
-
|
|
103
|
-
|
|
117
|
+
/** Human-readable name for the migration-head prerequisite. */
|
|
118
|
+
const ALEMBIC_CHECK_LABEL = "Database migration head";
|
|
119
|
+
/**
|
|
120
|
+
* The fail-open branch: warning severity, and never blocking.
|
|
121
|
+
*
|
|
122
|
+
* TWO details, deliberately. `messageDetail` is the legacy operator-facing prose
|
|
123
|
+
* and may name the command's own `error` field; `outcomeDetail` is fixed prose
|
|
124
|
+
* only, because the outcome flows into the consolidated readiness report. The
|
|
125
|
+
* production `execFile` adapter puts an errno code in `error`, but this
|
|
126
|
+
* separation means the consolidated report stays safe even if some caller ever
|
|
127
|
+
* puts raw stderr, an interpreter path, or a thrown message there.
|
|
128
|
+
*/
|
|
129
|
+
function unverified(messageDetail, outcomeDetail) {
|
|
130
|
+
const diagnostic = {
|
|
104
131
|
check: "alembic-head",
|
|
105
132
|
severity: "warning",
|
|
106
|
-
message: `${PLANE_ALEMBIC_UNVERIFIED_PREFIX}: ${
|
|
133
|
+
message: `${PLANE_ALEMBIC_UNVERIFIED_PREFIX}: ${messageDetail}. Startup continues — verify with ` +
|
|
107
134
|
`\`alembic -c alembic.ini heads\` and \`alembic -c alembic.ini current\` if a run ` +
|
|
108
135
|
"later reports CONTRACT_MIGRATION_BEHIND.",
|
|
136
|
+
remediation: PLANE_ALEMBIC_UNVERIFIED_REMEDIATION,
|
|
109
137
|
};
|
|
138
|
+
return planeCheckFinding(diagnostic, ALEMBIC_CHECK_LABEL, `${PLANE_ALEMBIC_UNVERIFIED_PREFIX}: ${outcomeDetail}`);
|
|
110
139
|
}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* can be older than a rebuild that overwrote files in place.
|
|
14
14
|
*/
|
|
15
15
|
import path from "path";
|
|
16
|
+
import { planeCheckFinding, planeCheckPassed } from "./types.js";
|
|
16
17
|
/** Remediation text embedded in every blocking build diagnostic. */
|
|
17
18
|
export const PLANE_BUILD_REMEDIATION = "cd mcp_server && npm run build";
|
|
18
19
|
/**
|
|
@@ -93,42 +94,49 @@ export async function findBuildMtime(executorEntrypoint, deps) {
|
|
|
93
94
|
* stale or absent build is exactly the failure this check exists to prevent, so
|
|
94
95
|
* unlike the Alembic check there is no fail-open branch.
|
|
95
96
|
*/
|
|
97
|
+
export const PLANE_BUILD_FIX_REMEDIATION = "run `cd mcp_server && npm run build` to rebuild the executor entrypoint, then retry.";
|
|
96
98
|
export async function checkPlaneBuildFreshness(repoRoot, deps) {
|
|
99
|
+
const label = "Executor build freshness";
|
|
97
100
|
const packageRoot = path.join(repoRoot, "mcp_server");
|
|
98
101
|
const buildDir = path.join(packageRoot, "build");
|
|
99
102
|
const executorEntrypoint = path.join(buildDir, "index.js");
|
|
100
103
|
const srcDir = path.join(packageRoot, "src");
|
|
101
104
|
const buildMtime = await findBuildMtime(executorEntrypoint, deps);
|
|
102
105
|
if (!buildMtime.ok) {
|
|
103
|
-
return {
|
|
106
|
+
return planeCheckFinding({
|
|
104
107
|
check: "executor-build",
|
|
105
108
|
severity: "blocking",
|
|
106
109
|
message: `the executor build entrypoint is missing or unreadable at ` +
|
|
107
110
|
`mcp_server/build/index.js — run \`${PLANE_BUILD_REMEDIATION}\``,
|
|
108
|
-
|
|
111
|
+
remediation: PLANE_BUILD_FIX_REMEDIATION,
|
|
112
|
+
}, label, "the executor build entrypoint is missing or unreadable");
|
|
109
113
|
}
|
|
110
114
|
const sourceMtime = await findNewestSourceMtime(srcDir, deps);
|
|
111
115
|
if (!sourceMtime.ok) {
|
|
112
|
-
return {
|
|
116
|
+
return planeCheckFinding({
|
|
113
117
|
check: "executor-build",
|
|
114
118
|
severity: "blocking",
|
|
115
119
|
message: `could not read mcp_server/src to compare against the build ` +
|
|
116
120
|
`(${sourceMtime.error}) — run \`${PLANE_BUILD_REMEDIATION}\``,
|
|
117
|
-
|
|
121
|
+
remediation: PLANE_BUILD_FIX_REMEDIATION,
|
|
122
|
+
}, label,
|
|
123
|
+
// `sourceMtime.error` is an errno code, already sanitized by `sanitize()`.
|
|
124
|
+
`the executor sources could not be read for comparison (${sourceMtime.error})`);
|
|
118
125
|
}
|
|
119
126
|
// Equality passes: a build written in the same millisecond as its newest
|
|
120
127
|
// source is current, and treating the boundary as stale would refuse a
|
|
121
128
|
// perfectly good build on a coarse-resolution filesystem.
|
|
122
129
|
if (sourceMtime.mtimeMs !== null && sourceMtime.mtimeMs > buildMtime.mtimeMs) {
|
|
123
|
-
return {
|
|
130
|
+
return planeCheckFinding({
|
|
124
131
|
check: "executor-build",
|
|
125
132
|
severity: "blocking",
|
|
126
133
|
message: "mcp_server/build/ is STALE — a source file under mcp_server/src is newer " +
|
|
127
134
|
`than mcp_server/build/index.js, so executors would run old code. ` +
|
|
128
135
|
`Run \`${PLANE_BUILD_REMEDIATION}\``,
|
|
129
|
-
|
|
136
|
+
remediation: PLANE_BUILD_FIX_REMEDIATION,
|
|
137
|
+
}, label, "mcp_server/build/ is stale — a source file is newer than the build entrypoint");
|
|
130
138
|
}
|
|
131
|
-
return
|
|
139
|
+
return planeCheckPassed("executor-build", label, "the executor build is present and current");
|
|
132
140
|
}
|
|
133
141
|
/**
|
|
134
142
|
* Fixed refusal prose for an unresolvable runtime re-exec target (BAPI-768).
|
|
@@ -153,13 +161,16 @@ export const PLANE_RUNTIME_ENTRYPOINT_REFUSAL = "the currently executing MCP bui
|
|
|
153
161
|
* degraded plane, it is no plane at all.
|
|
154
162
|
*/
|
|
155
163
|
export function checkPlaneRuntimeEntrypoint(resolution) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
164
|
+
const label = "Runtime re-exec entrypoint";
|
|
165
|
+
if (resolution.ok) {
|
|
166
|
+
return planeCheckPassed("runtime-entrypoint", label, "the executing build can re-enter itself");
|
|
167
|
+
}
|
|
168
|
+
return planeCheckFinding({
|
|
159
169
|
check: "runtime-entrypoint",
|
|
160
170
|
severity: "blocking",
|
|
161
171
|
message: PLANE_RUNTIME_ENTRYPOINT_REFUSAL,
|
|
162
|
-
|
|
172
|
+
remediation: PLANE_BUILD_FIX_REMEDIATION,
|
|
173
|
+
}, label, "the currently executing MCP build could not be re-entered");
|
|
163
174
|
}
|
|
164
175
|
function sanitize(err) {
|
|
165
176
|
const code = err?.code;
|