@bridge_gpt/mcp-server 0.2.53 → 0.2.54
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 +86 -10
- package/build/agent-launchers/claude.js +3 -3
- package/build/agent-launchers/prompt.js +8 -11
- package/build/base-ref.js +33 -9
- package/build/bounded-wait.js +174 -0
- package/build/commands.generated.js +1 -1
- package/build/conductor/bridge-api-client.js +36 -8
- package/build/conductor/epic-runtime.js +133 -97
- package/build/conductor/readiness.js +85 -0
- package/build/conductor/run-branch.js +137 -0
- package/build/conductor/test-run-branch-vectors.js +165 -0
- package/build/conductor-bin.js +5 -5
- package/build/doctor.js +68 -1
- package/build/drive-epic.js +287 -51
- package/build/executor/claim-scope.js +104 -0
- package/build/executor/cli.js +14 -25
- package/build/executor/env-file-guard.js +82 -3
- package/build/executor/job-runner.js +60 -0
- package/build/index.js +128 -400
- package/build/local-artifact-storage.js +130 -0
- package/build/pipelines.generated.js +16 -9
- package/build/plane/cli.js +285 -36
- package/build/plane/manifest.js +209 -1
- package/build/plane/member-roster.js +70 -0
- package/build/plane/shutdown.js +14 -1
- package/build/plane/status.js +35 -1
- package/build/plane/supervisor.js +546 -164
- package/build/plane/types.js +25 -2
- package/build/polling-policy.js +72 -0
- package/build/readme.generated.js +1 -1
- package/build/review-generation.js +219 -0
- package/build/run-unit-tests-launcher.js +5 -0
- package/build/setup-epic.js +514 -23
- package/build/ticket-key-utils.js +4 -3
- package/build/ticket-review-artifact-gate.js +461 -0
- package/build/upgrade-cli.js +5 -26
- package/build/version.generated.js +3 -3
- package/docs/install/mcp-tool-integrations.md +23 -1
- package/package.json +1 -1
- package/pipelines/review-ticket.json +17 -4
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BAPI-1127 — TypeScript-side loader for the SHARED cross-runtime vector table.
|
|
3
|
+
*
|
|
4
|
+
* `tests/pytest/fixtures/run_branch_vectors.json` lives at the repository root,
|
|
5
|
+
* outside this package, because it is not this package's fixture: it is the
|
|
6
|
+
* contract between this package and the Python server, and both sides read the
|
|
7
|
+
* same bytes. Python reaches it from `tests/pytest/models/`; this module is how
|
|
8
|
+
* the compiled `node:test` suites reach it.
|
|
9
|
+
*
|
|
10
|
+
* **Why `readFileSync` and not a JSON import.** Importing the JSON would require
|
|
11
|
+
* `resolveJsonModule` plus a widened `include` in `tsconfig.json`, which would
|
|
12
|
+
* inline a test fixture into the PUBLISHED bundle. `build/**\/*.test.js` is
|
|
13
|
+
* excluded from the package `files` list, so a compiled test reading a
|
|
14
|
+
* repository-root path ships nothing; a JSON module baked into the emitted
|
|
15
|
+
* source would.
|
|
16
|
+
*
|
|
17
|
+
* **Why the path is searched rather than computed.** The compiled test executes
|
|
18
|
+
* from `mcp_server/build/conductor/`, not `mcp_server/src/conductor/`, so a
|
|
19
|
+
* hard-coded `../../../` is correct for exactly one of the two and silently
|
|
20
|
+
* wrong for the other. Walking up until the fixture is found is correct from
|
|
21
|
+
* either, and from any CI checkout depth.
|
|
22
|
+
*
|
|
23
|
+
* Nothing here is reachable from the MCP server runtime — it is imported only by
|
|
24
|
+
* `*.test.ts` — so it adds no startup cost and touches no stdio.
|
|
25
|
+
*/
|
|
26
|
+
import { readFileSync } from "node:fs";
|
|
27
|
+
import path from "node:path";
|
|
28
|
+
import { fileURLToPath } from "node:url";
|
|
29
|
+
/** Repository-root-relative location of the shared table. */
|
|
30
|
+
const FIXTURE_RELATIVE_PATH = path.join("tests", "pytest", "fixtures", "run_branch_vectors.json");
|
|
31
|
+
function repositoryRoot() {
|
|
32
|
+
let dir = path.dirname(fileURLToPath(import.meta.url));
|
|
33
|
+
// 8 levels is far more than the 3 either real layout needs; the loop exists to
|
|
34
|
+
// be layout-independent, not to search the whole filesystem.
|
|
35
|
+
for (let i = 0; i < 8; i++) {
|
|
36
|
+
try {
|
|
37
|
+
readFileSync(path.join(dir, FIXTURE_RELATIVE_PATH));
|
|
38
|
+
return dir;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
const parent = path.dirname(dir);
|
|
42
|
+
if (parent === dir)
|
|
43
|
+
break;
|
|
44
|
+
dir = parent;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`run_branch_vectors.json not found above ${fileURLToPath(import.meta.url)}. ` +
|
|
48
|
+
"The shared cross-runtime vector table is required; this suite must not " +
|
|
49
|
+
"pass without it.");
|
|
50
|
+
}
|
|
51
|
+
function readDocument() {
|
|
52
|
+
const fixturePath = path.join(repositoryRoot(), FIXTURE_RELATIVE_PATH);
|
|
53
|
+
let raw;
|
|
54
|
+
try {
|
|
55
|
+
raw = readFileSync(fixturePath, "utf8");
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
throw new Error(`shared vector fixture is unreadable at ${fixturePath}: ${String(err)}`);
|
|
59
|
+
}
|
|
60
|
+
let parsed;
|
|
61
|
+
try {
|
|
62
|
+
parsed = JSON.parse(raw);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
throw new Error(`shared vector fixture is not valid JSON (${fixturePath}): ${String(err)}`);
|
|
66
|
+
}
|
|
67
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
68
|
+
throw new Error(`shared vector fixture is not a JSON object (${fixturePath}).`);
|
|
69
|
+
}
|
|
70
|
+
return parsed;
|
|
71
|
+
}
|
|
72
|
+
/** JSON `null` means "no declaration"; TypeScript spells that `undefined`. */
|
|
73
|
+
function nullToUndefined(value) {
|
|
74
|
+
return value === null ? undefined : value;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Load the shared resolution vectors, THROWING on every vacuous state.
|
|
78
|
+
*
|
|
79
|
+
* A missing, unreadable, malformed, or empty table is a failure and never a
|
|
80
|
+
* skip: a parity suite that quietly parametrizes zero cases reports green while
|
|
81
|
+
* proving nothing, which is the exact outcome these vectors exist to prevent.
|
|
82
|
+
*/
|
|
83
|
+
export function loadResolutionVectors() {
|
|
84
|
+
const raw = readDocument()["resolution_vectors"];
|
|
85
|
+
if (!Array.isArray(raw)) {
|
|
86
|
+
throw new Error("shared vector fixture has no 'resolution_vectors' array.");
|
|
87
|
+
}
|
|
88
|
+
if (raw.length === 0) {
|
|
89
|
+
throw new Error("shared vector fixture declares zero resolution vectors; every parity " +
|
|
90
|
+
"assertion below would be vacuous.");
|
|
91
|
+
}
|
|
92
|
+
return raw.map((entry, index) => {
|
|
93
|
+
if (!entry || typeof entry !== "object") {
|
|
94
|
+
throw new Error(`resolution vector #${index} is not an object.`);
|
|
95
|
+
}
|
|
96
|
+
const e = entry;
|
|
97
|
+
if (typeof e["id"] !== "string" || e["id"].length === 0) {
|
|
98
|
+
throw new Error(`resolution vector #${index} has no id.`);
|
|
99
|
+
}
|
|
100
|
+
if (typeof e["policy_present"] !== "boolean") {
|
|
101
|
+
throw new Error(`resolution vector ${e["id"]} has no boolean policy_present.`);
|
|
102
|
+
}
|
|
103
|
+
if (!("expected_declared_branch" in e)) {
|
|
104
|
+
throw new Error(`resolution vector ${e["id"]} has no expected_declared_branch.`);
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
id: e["id"],
|
|
108
|
+
note: typeof e["note"] === "string" ? e["note"] : "",
|
|
109
|
+
policyPresent: e["policy_present"],
|
|
110
|
+
policyJson: e["policy_present"] ? e["policy_json"] : undefined,
|
|
111
|
+
expectedDeclaredBranch: nullToUndefined(e["expected_declared_branch"]),
|
|
112
|
+
typescriptEffectiveBase: nullToUndefined(e["typescript_effective_base"]),
|
|
113
|
+
typescriptEffectiveErrorType: nullToUndefined(e["typescript_effective_error_type"]),
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/** Load the shared branch-name validity vectors, with the same loud failures. */
|
|
118
|
+
export function loadBranchNameVectors() {
|
|
119
|
+
const raw = readDocument()["branch_name_validation"];
|
|
120
|
+
if (!Array.isArray(raw)) {
|
|
121
|
+
throw new Error("shared vector fixture has no 'branch_name_validation' array.");
|
|
122
|
+
}
|
|
123
|
+
if (raw.length === 0) {
|
|
124
|
+
throw new Error("shared vector fixture declares zero branch-name vectors; every validator " +
|
|
125
|
+
"assertion below would be vacuous.");
|
|
126
|
+
}
|
|
127
|
+
return raw.map((entry, index) => {
|
|
128
|
+
if (!entry || typeof entry !== "object") {
|
|
129
|
+
throw new Error(`branch-name vector #${index} is not an object.`);
|
|
130
|
+
}
|
|
131
|
+
const e = entry;
|
|
132
|
+
if (typeof e["id"] !== "string" || e["id"].length === 0) {
|
|
133
|
+
throw new Error(`branch-name vector #${index} has no id.`);
|
|
134
|
+
}
|
|
135
|
+
if (typeof e["input"] !== "string") {
|
|
136
|
+
throw new Error(`branch-name vector ${e["id"]} has a non-string input.`);
|
|
137
|
+
}
|
|
138
|
+
if (typeof e["valid"] !== "boolean") {
|
|
139
|
+
throw new Error(`branch-name vector ${e["id"]} has no boolean 'valid'.`);
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
id: e["id"],
|
|
143
|
+
note: typeof e["note"] === "string" ? e["note"] : "",
|
|
144
|
+
input: e["input"],
|
|
145
|
+
valid: e["valid"],
|
|
146
|
+
errorType: nullToUndefined(e["error_type"]),
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The substring each `error_type` must appear as in a validator diagnostic.
|
|
152
|
+
*
|
|
153
|
+
* The adapters assert the ACTUAL message, not merely that some error occurred,
|
|
154
|
+
* so a validator that started reporting the wrong rule would fail rather than
|
|
155
|
+
* pass on a coincidentally-truthy result. Kept here, beside the loader, because
|
|
156
|
+
* both the TypeScript validator suite and the effective-base suite need it.
|
|
157
|
+
*/
|
|
158
|
+
export const ERROR_TYPE_MESSAGE_FRAGMENTS = {
|
|
159
|
+
empty: "must not be empty",
|
|
160
|
+
too_long: "255 characters or fewer",
|
|
161
|
+
leading_hyphen: "must not start with '-'",
|
|
162
|
+
double_dot: "must not contain '..'",
|
|
163
|
+
lock_suffix: "must not end with '.lock'",
|
|
164
|
+
control_character: "must not contain control characters",
|
|
165
|
+
};
|