@bridge_gpt/mcp-server 0.2.65 → 0.2.67
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 +269 -82
- package/build/agent-capabilities/probes.js +15 -5
- package/build/agent-launchers/claude-executor-adapter.js +55 -34
- package/build/agent-launchers/executor-adapter.js +34 -4
- package/build/agents.generated.js +1 -1
- package/build/bounded-wait.js +67 -10
- package/build/bridge-config.js +104 -0
- package/build/codex-bridge-profile.js +10 -1
- package/build/commands.generated.js +12 -12
- package/build/conductor/bridge-api-client.js +372 -10
- package/build/conductor/bring-up-facts.js +1 -1
- package/build/conductor/doctor.js +3 -3
- package/build/conductor/epic-child-continuation.js +61 -34
- package/build/conductor/epic-implementer-cli.js +34 -6
- package/build/conductor/errors.js +4 -3
- package/build/conductor/guided-repair.js +327 -0
- package/build/conductor/hook-runtime-qualification.js +1 -1
- package/build/conductor/merge-execution-contract.js +27 -8
- package/build/conductor/merge-execution-eligibility.js +3 -2
- package/build/conductor/pr-ci-producer.js +1 -1
- package/build/conductor/readiness-cli.js +46 -9
- package/build/conductor/readiness-sections.js +41 -6
- package/build/conductor/readiness.js +204 -30
- package/build/conductor/recovery-cli.js +703 -20
- package/build/conductor/recovery-operations.js +392 -3
- package/build/conductor/repair-contract.js +112 -3
- package/build/conductor/repository-workflow-remedy.js +125 -0
- package/build/conductor/tools.js +2 -2
- package/build/conductor-bundle-artifacts.js +8 -0
- package/build/credential-store.js +5 -4
- package/build/diagnostic-text.js +36 -0
- package/build/docs.generated.js +8 -3
- package/build/doctor.js +70 -10
- package/build/drive-epic-key.js +6 -5
- package/build/drive-epic.js +479 -131
- package/build/epic-coherence-input.js +2 -1
- package/build/epic-implementer-bin.js +30 -26
- package/build/epic-implementer-bundle-cli.js +2 -2
- package/build/epic-launch-diagnostic.js +31 -0
- package/build/epic-launch-profile.js +44 -14
- package/build/executor/cli.js +3 -2
- package/build/executor/completion-contract.js +48 -5
- package/build/executor/completion-supervision.js +9 -0
- package/build/executor/correction-dispatch.js +60 -0
- package/build/executor/env.js +25 -0
- package/build/executor/heartbeat.js +1 -1
- package/build/executor/http-client.js +35 -0
- package/build/executor/integration-job.js +6 -1
- package/build/executor/job-errors.js +38 -4
- package/build/executor/job-log-registry.js +340 -73
- package/build/executor/job-runner.js +485 -74
- package/build/executor/job-types.js +8 -13
- package/build/executor/observation.js +6 -1
- package/build/executor/preflight.js +136 -10
- package/build/executor/prompt-spec.js +113 -9
- package/build/executor/required-work-ledger.js +6 -1
- package/build/executor/resume-pre-spawn.js +2 -0
- package/build/executor/runner.js +31 -2
- package/build/executor/service-unit.js +7 -1
- package/build/executor/stale-artifacts.js +5 -4
- package/build/executor/types.js +1 -0
- package/build/executor/watch-cli.js +35 -8
- package/build/executor/worker-command.js +43 -43
- package/build/executor/worker-finalization.js +161 -43
- package/build/executor/worker-guard-hook.js +152 -12
- package/build/executor/worker-log.js +137 -70
- package/build/executor/worktree-gc.js +30 -6
- package/build/executor/worktree.js +82 -1
- package/build/index.js +482 -660
- package/build/init.js +107 -4
- package/build/install-bridge-conductor.js +8 -6
- package/build/install-bridge.js +287 -23
- package/build/install-doctor.js +172 -30
- package/build/install-reexec.js +69 -7
- package/build/macos-terminal-permission-guidance.js +16 -0
- package/build/model-thresholds-tool.js +185 -0
- package/build/phase-context-git-probe.js +68 -0
- package/build/phase-result-artifacts.js +173 -5
- package/build/pipelines.generated.js +19 -25
- package/build/plane/alembic-head.js +12 -3
- package/build/plane/base-worktree-guard.js +147 -0
- package/build/plane/cli.js +217 -17
- package/build/plane/code-snapshot.js +468 -0
- package/build/plane/defaults.js +48 -3
- package/build/plane/endpoint.js +41 -0
- package/build/plane/manifest.js +120 -1
- package/build/plane/member-roster.js +94 -19
- package/build/plane/preflight.js +30 -2
- package/build/plane/process-cwd.js +67 -0
- package/build/plane/restart.js +542 -0
- package/build/plane/shutdown.js +31 -0
- package/build/plane/status.js +145 -6
- package/build/plane/supervisor.js +588 -177
- package/build/plane/types.js +54 -2
- package/build/plane/worker-exit-code.js +2 -0
- package/build/printed-remedy-commands.js +37 -0
- package/build/project-root.js +99 -0
- package/build/readiness-check.js +1 -1
- package/build/readme.generated.js +1 -1
- package/build/review-generation.js +22 -0
- package/build/review-tickets.js +156 -13
- package/build/setup-epic.js +224 -127
- package/build/sfcc/config.js +9 -0
- package/build/sfcc/credentials.js +100 -38
- package/build/sfcc/hostname.js +67 -0
- package/build/sfcc/permissions.js +17 -13
- package/build/sfcc/register.js +1 -1
- package/build/sfcc/setup-status.js +2 -0
- package/build/sfcc/tool-wrapper.js +41 -43
- package/build/sfcc/tools-configured.js +96 -0
- package/build/sfcc/write-grants.js +17 -11
- package/build/sfcc/write-result.js +4 -3
- package/build/sfcc/writes-site-preference.js +20 -8
- package/build/start-tickets.js +332 -79
- package/build/tool-error-envelope.js +61 -0
- package/build/upgrade-cli.js +109 -24
- package/build/version.generated.js +3 -3
- package/build/visual-diff.js +22 -1
- package/build/windows-npm-entry.js +103 -0
- package/build/worker-guard-hook-bin.js +3 -5
- package/build/worker-guard-hook-main.js +47 -0
- package/build/worktree-core.js +136 -9
- package/docs/EPIC-IMPLEMENTER-INSTALL.md +849 -0
- package/docs/EPIC-IMPLEMENTER.md +662 -0
- package/docs/install/mcp-tool-integrations.md +25 -15
- package/docs/install/sfcc-integration.md +21 -8
- package/package.json +1 -1
- package/pipelines/implement-ticket.json +1 -1
- package/pipelines/plan-epic.json +0 -5
- package/pipelines/review-ticket.json +1 -1
- package/docs/CONDUCTOR.md +0 -605
- package/pipelines/idea-to-pr.json +0 -49
package/build/plane/types.js
CHANGED
|
@@ -52,8 +52,27 @@
|
|
|
52
52
|
* really a version gap. Reading v1 and v2 stays supported and a manifest without
|
|
53
53
|
* `lifecycle` is interpreted as a fully-up single-phase plane, which is exactly
|
|
54
54
|
* what an older build wrote.
|
|
55
|
+
*
|
|
56
|
+
* Bumped to 4 by BAPI-1362, which added the pinned code snapshot
|
|
57
|
+
* (`snapshotPath` / `snapshotSha`), a per-member `cwd`, the `restarting` member
|
|
58
|
+
* state, and the member `restartFailure` marker. Same reasoning as 3: an older
|
|
59
|
+
* binary rejects an unknown top-level key, so a v4 manifest read by a v3 build
|
|
60
|
+
* would read as a corrupt field rather than as a version gap.
|
|
61
|
+
*
|
|
62
|
+
* The version also carries a SAFETY meaning that no other bump has had: a
|
|
63
|
+
* manifest older than 4 was written by a runtime that has no `plane restart`
|
|
64
|
+
* handler, and the restart signal's default action terminates a process that
|
|
65
|
+
* does not handle it. `plane restart` therefore refuses a manifest below
|
|
66
|
+
* {@link PLANE_RESTART_MIN_SCHEMA_VERSION} before it signals anything.
|
|
55
67
|
*/
|
|
56
|
-
export const PLANE_MANIFEST_SCHEMA_VERSION =
|
|
68
|
+
export const PLANE_MANIFEST_SCHEMA_VERSION = 4;
|
|
69
|
+
/**
|
|
70
|
+
* The first manifest schema version whose runtime handles `plane restart`.
|
|
71
|
+
*
|
|
72
|
+
* A runtime that does not register the restart signal is killed by it, so this
|
|
73
|
+
* is the gate that keeps the CLI from signalling one (BAPI-1362).
|
|
74
|
+
*/
|
|
75
|
+
export const PLANE_RESTART_MIN_SCHEMA_VERSION = 4;
|
|
57
76
|
/**
|
|
58
77
|
* Every schema version this build can READ.
|
|
59
78
|
*
|
|
@@ -63,9 +82,35 @@ export const PLANE_MANIFEST_SCHEMA_VERSION = 3;
|
|
|
63
82
|
* legible, inflicted from the other side. Accepting 1 costs nothing: the two
|
|
64
83
|
* versions differ only in whether `observer` may appear among the members.
|
|
65
84
|
*/
|
|
66
|
-
export const PLANE_MANIFEST_SUPPORTED_SCHEMA_VERSIONS = [1, 2, 3];
|
|
85
|
+
export const PLANE_MANIFEST_SUPPORTED_SCHEMA_VERSIONS = [1, 2, 3, 4];
|
|
67
86
|
/** Runtime artifact directory, relative to the repository root. */
|
|
68
87
|
export const PLANE_RUNTIME_DIR = ".bridge/plane";
|
|
88
|
+
/**
|
|
89
|
+
* Directory of plane-owned detached code snapshots, relative to the repository
|
|
90
|
+
* root (BAPI-1362). One Git worktree per pinned commit, at
|
|
91
|
+
* `<PLANE_SNAPSHOTS_DIR>/<full-sha>`. Under {@link PLANE_RUNTIME_DIR}, which is
|
|
92
|
+
* already ignored by version control.
|
|
93
|
+
*/
|
|
94
|
+
export const PLANE_SNAPSHOTS_DIR = `${PLANE_RUNTIME_DIR}/snapshots`;
|
|
95
|
+
/** Filename of the pending restart request inside {@link PLANE_RUNTIME_DIR}. */
|
|
96
|
+
export const PLANE_RESTART_REQUEST_FILENAME = "restart-request.json";
|
|
97
|
+
/** Filename of the published restart result inside {@link PLANE_RUNTIME_DIR}. */
|
|
98
|
+
export const PLANE_RESTART_RESULT_FILENAME = "restart-result.json";
|
|
99
|
+
/**
|
|
100
|
+
* Signal the CLI sends the detached runtime to say "a restart request is waiting".
|
|
101
|
+
*
|
|
102
|
+
* The signal carries no data; the request itself is a file at a fixed path.
|
|
103
|
+
* `SIGUSR2`, because `SIGUSR1` is reserved by Node for its inspector and the
|
|
104
|
+
* termination signals already mean "wind the plane down". It is sent to the
|
|
105
|
+
* supervisor's own pid only, NEVER to the process group, which would reach every
|
|
106
|
+
* member.
|
|
107
|
+
*/
|
|
108
|
+
export const PLANE_RESTART_SIGNAL = "SIGUSR2";
|
|
109
|
+
/**
|
|
110
|
+
* The members `plane restart` may replace. Executor lanes are run-scoped and are
|
|
111
|
+
* recovered at the run level, so they are deliberately not restartable here.
|
|
112
|
+
*/
|
|
113
|
+
export const PLANE_RESTARTABLE_MEMBERS = ["server", "worker", "observer"];
|
|
69
114
|
/** Manifest filename inside {@link PLANE_RUNTIME_DIR}. */
|
|
70
115
|
export const PLANE_MANIFEST_FILENAME = "plane.json";
|
|
71
116
|
/**
|
|
@@ -188,6 +233,13 @@ export function planeCheckSkipped(check, label, detail) {
|
|
|
188
233
|
outcomes: [{ check, id: check, label, status: "skip", detail }],
|
|
189
234
|
};
|
|
190
235
|
}
|
|
236
|
+
/** Every value {@link PlaneRestartFailureReason} may take, for runtime guards. */
|
|
237
|
+
export const PLANE_RESTART_FAILURE_REASONS = [
|
|
238
|
+
"stop-incomplete",
|
|
239
|
+
"spawn",
|
|
240
|
+
"readiness",
|
|
241
|
+
"snapshot",
|
|
242
|
+
];
|
|
191
243
|
/**
|
|
192
244
|
* Every value {@link PlaneHeartbeatComponent} may take, for runtime guards.
|
|
193
245
|
*
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Complete, copy-ready CLI commands that operator-facing messages print as
|
|
3
|
+
* remedies (BAPI-1376).
|
|
4
|
+
*
|
|
5
|
+
* Every command starts with the non-interactive package launcher and names a
|
|
6
|
+
* subcommand `index.ts` dispatches. A command that carries a placeholder
|
|
7
|
+
* (`<check-name>`, `<id>`) must be printed with an instruction to replace it.
|
|
8
|
+
*
|
|
9
|
+
* Dispatch stays in `index.ts`; this module only names commands. The merge
|
|
10
|
+
* workflow command is deliberately NOT here: its single definition is the
|
|
11
|
+
* mirrored contract (`conductor/merge-execution-contract.ts`).
|
|
12
|
+
*/
|
|
13
|
+
import { MCP_PACKAGE_NAME } from "./mcp-identity.js";
|
|
14
|
+
/** The non-interactive launcher every printed command starts with. */
|
|
15
|
+
const LAUNCHER = `npx -y ${MCP_PACKAGE_NAME}`;
|
|
16
|
+
/** The top-level subcommand tokens `index.ts` dispatches that remedies name. */
|
|
17
|
+
export const PRINTED_REMEDY_DISPATCHED_SUBCOMMANDS = [
|
|
18
|
+
"install",
|
|
19
|
+
"install-bridge",
|
|
20
|
+
"doctor",
|
|
21
|
+
"connect-github",
|
|
22
|
+
];
|
|
23
|
+
/** The guided installer (interactive project setup). */
|
|
24
|
+
export const PRINTED_INSTALL_COMMAND = `${LAUNCHER} install`;
|
|
25
|
+
/** Conductor bootstrap. The parser requires at least one `--required-check`. */
|
|
26
|
+
export const PRINTED_CONDUCTOR_INSTALL_COMMAND = `${LAUNCHER} install conductor --required-check <check-name>`;
|
|
27
|
+
/** Conductor bootstrap that also provisions a repository-wide executor service. */
|
|
28
|
+
export const PRINTED_CONDUCTOR_EXECUTOR_INSTALL_COMMAND = `${LAUNCHER} install conductor --required-check <check-name> --executor-id <id> --repo-wide`;
|
|
29
|
+
/** Read-only readiness diagnostics. */
|
|
30
|
+
export const PRINTED_DOCTOR_COMMAND = `${LAUNCHER} doctor`;
|
|
31
|
+
/** Sessionless GitHub App connection. `--repo` is optional for this command. */
|
|
32
|
+
export const PRINTED_CONNECT_GITHUB_COMMAND = `${LAUNCHER} connect-github`;
|
|
33
|
+
/** Explains the `<check-name>` placeholder; print it beside a conductor command. */
|
|
34
|
+
export const PRINTED_CHECK_NAME_INSTRUCTION = "Replace <check-name> with the exact name of a CI check this repository requires; " +
|
|
35
|
+
"repeat --required-check for each additional check.";
|
|
36
|
+
/** Explains the `<id>` placeholder of the executor command. */
|
|
37
|
+
export const PRINTED_EXECUTOR_ID_INSTRUCTION = "Replace <id> with a name for the executor service.";
|
package/build/project-root.js
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* so this stays trivially testable and swappable.
|
|
17
17
|
*/
|
|
18
18
|
import path from "path";
|
|
19
|
+
import { renderDiagnosticValue } from "./diagnostic-text.js";
|
|
19
20
|
/**
|
|
20
21
|
* Whether `cwd` looks like a project root: presence of `.git`, checked through the
|
|
21
22
|
* injected `stat` probe. Any probe failure (absent, or an unexpected I/O error) is
|
|
@@ -32,3 +33,101 @@ export async function hasProjectRootMarker(cwd, stat) {
|
|
|
32
33
|
return false;
|
|
33
34
|
}
|
|
34
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Validate an explicit project root: it must exist, be a directory, and contain
|
|
38
|
+
* `.git` (a directory, or the `.git` FILE a worktree has) or `.bridge/config`.
|
|
39
|
+
* An absent path is `missing`; anything else that fails — a file, a folder with
|
|
40
|
+
* neither marker, or an inaccessible path — is `not-a-project`. Raw filesystem
|
|
41
|
+
* errors never leave this function.
|
|
42
|
+
*
|
|
43
|
+
* Deliberately a SIBLING of {@link hasProjectRootMarker}, which stays `.git`-only
|
|
44
|
+
* because `install` and `--init` use it and the README pins that wording. A
|
|
45
|
+
* marker proves only that the path looks like a project, not that it is THIS
|
|
46
|
+
* project; the stderr source line is how a wrong-but-valid root is noticed.
|
|
47
|
+
*/
|
|
48
|
+
export async function validateExplicitProjectRoot(root, stat) {
|
|
49
|
+
let info;
|
|
50
|
+
try {
|
|
51
|
+
info = await stat(root);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
const code = error?.code;
|
|
55
|
+
return { ok: false, reason: code === "ENOENT" || code === "ENOTDIR" ? "missing" : "not-a-project" };
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
if (!info.isDirectory())
|
|
59
|
+
return { ok: false, reason: "not-a-project" };
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return { ok: false, reason: "not-a-project" };
|
|
63
|
+
}
|
|
64
|
+
for (const marker of [path.join(root, ".git"), path.join(root, ".bridge", "config")]) {
|
|
65
|
+
try {
|
|
66
|
+
await stat(marker);
|
|
67
|
+
return { ok: true };
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
/* try the next marker */
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { ok: false, reason: "not-a-project" };
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Resolve the project root in the fixed order: a VALID `BAPI_PROJECT_ROOT`,
|
|
77
|
+
* then MCP `roots/list`, then `CLAUDE_PROJECT_DIR`, then `cwd`. Only the explicit
|
|
78
|
+
* value is validated — it is the one source written into (possibly committed)
|
|
79
|
+
* config files, so it is the one that can name another machine's path. The later
|
|
80
|
+
* sources come from the running host and keep today's behavior. An empty or
|
|
81
|
+
* whitespace `BAPI_PROJECT_ROOT` is treated as unset.
|
|
82
|
+
*
|
|
83
|
+
* Pure apart from the injected seams, so `index.ts` (which cannot be imported in
|
|
84
|
+
* tests) stays a thin wrapper over this.
|
|
85
|
+
*/
|
|
86
|
+
export async function resolveProjectRoot(options) {
|
|
87
|
+
let rejectedExplicit;
|
|
88
|
+
const explicit = (options.env.BAPI_PROJECT_ROOT ?? "").trim();
|
|
89
|
+
if (explicit.length > 0) {
|
|
90
|
+
const verdict = await validateExplicitProjectRoot(explicit, options.stat);
|
|
91
|
+
if (verdict.ok)
|
|
92
|
+
return { root: explicit, source: "BAPI_PROJECT_ROOT" };
|
|
93
|
+
rejectedExplicit = { path: explicit, reason: verdict.reason };
|
|
94
|
+
}
|
|
95
|
+
const withRejection = (root, source) => rejectedExplicit ? { root, source, rejectedExplicit } : { root, source };
|
|
96
|
+
let fromRoots = null;
|
|
97
|
+
try {
|
|
98
|
+
fromRoots = await options.listRoots();
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
fromRoots = null;
|
|
102
|
+
}
|
|
103
|
+
if (fromRoots && fromRoots.length > 0)
|
|
104
|
+
return withRejection(fromRoots, "roots/list");
|
|
105
|
+
const claudeDir = (options.env.CLAUDE_PROJECT_DIR ?? "").trim();
|
|
106
|
+
if (claudeDir.length > 0)
|
|
107
|
+
return withRejection(claudeDir, "CLAUDE_PROJECT_DIR");
|
|
108
|
+
return withRejection(options.cwd(), "cwd");
|
|
109
|
+
}
|
|
110
|
+
/** Resolve `BAPI_DOCS_DIR` (default `docs/tmp`) against the chosen project root. */
|
|
111
|
+
export function resolveDocsDirForRoot(root, env) {
|
|
112
|
+
return path.resolve(root, env.BAPI_DOCS_DIR ?? "docs/tmp");
|
|
113
|
+
}
|
|
114
|
+
/** Human wording for each closed refusal reason. */
|
|
115
|
+
export const PROJECT_ROOT_REFUSAL_TEXT = {
|
|
116
|
+
missing: "does not exist",
|
|
117
|
+
"not-a-project": "is not a project folder (no .git or .bridge/config)",
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* The one stderr line the server writes when it first resolves the root, e.g.
|
|
121
|
+
* `Bridge MCP: project root /home/b/app (from roots/list); BAPI_PROJECT_ROOT
|
|
122
|
+
* /Users/a/app ignored: does not exist`. Paths are rendered on one line with
|
|
123
|
+
* control characters escaped.
|
|
124
|
+
*/
|
|
125
|
+
export function formatProjectRootSourceLine(resolved) {
|
|
126
|
+
let line = `Bridge MCP: project root ${renderDiagnosticValue(resolved.root)} (from ${resolved.source})`;
|
|
127
|
+
if (resolved.rejectedExplicit) {
|
|
128
|
+
line +=
|
|
129
|
+
`; BAPI_PROJECT_ROOT ${renderDiagnosticValue(resolved.rejectedExplicit.path)} ignored: ` +
|
|
130
|
+
PROJECT_ROOT_REFUSAL_TEXT[resolved.rejectedExplicit.reason];
|
|
131
|
+
}
|
|
132
|
+
return line;
|
|
133
|
+
}
|
package/build/readiness-check.js
CHANGED
|
@@ -147,7 +147,7 @@ const POSIX_PATH_ROOTS = [
|
|
|
147
147
|
* Deliberately narrow: it catches the obvious leak (`/Users/...`, `/private/tmp/...`,
|
|
148
148
|
* `C:\\...`) without rejecting the relative, repository-conventional paths
|
|
149
149
|
* remediations legitimately name (`.github/workflows/claude-review.yml`,
|
|
150
|
-
* `docs/
|
|
150
|
+
* `docs/epic-implementer/operator-runbook.md`) or the approved setup
|
|
151
151
|
* URLs (`https://host/setup`) — note the Windows drive alternative requires a
|
|
152
152
|
* word boundary before the letter, so the `s:/` inside `https://` is not a hit.
|
|
153
153
|
*/
|