@bridge_gpt/mcp-server 0.2.68 → 0.2.70
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 +226 -320
- package/build/agent-launchers/claude-executor-adapter.js +17 -4
- package/build/agents.generated.js +4 -4
- package/build/artifact-diff.js +110 -0
- package/build/bin-entrypoint.js +36 -0
- package/build/bridge-permissions.js +650 -98
- package/build/check-update-cli.js +74 -0
- package/build/claude-review-workflow-drift.js +3 -3
- package/build/claude-settings.js +84 -2
- package/build/cli-help.js +7 -1
- package/build/codex-bridge-profile.js +1 -1
- package/build/codex-home.js +9 -1
- package/build/codex-launcher-pin.js +598 -0
- package/build/commands.generated.js +8 -8
- package/build/conductor/bridge-api-client.js +598 -19
- package/build/conductor/bring-up-facts.js +9 -9
- package/build/conductor/doctor.js +466 -18
- package/build/conductor/epic-child-continuation.js +54 -3
- package/build/conductor/epic-implementer-cli.js +132 -34
- package/build/conductor/epic-runtime.js +2 -2
- package/build/conductor/epic-state.js +1 -1
- package/build/conductor/hook-runtime-qualification.js +1 -1
- package/build/conductor/install-doctor.js +4 -2
- package/build/conductor/launch-need-probes.js +337 -0
- package/build/conductor/local-merge.js +241 -56
- package/build/conductor/merge-credential.js +172 -0
- package/build/conductor/merge-execution-eligibility.js +1 -1
- package/build/conductor/merged-child-check.js +95 -0
- package/build/conductor/plan-trim.js +30 -0
- package/build/conductor/pr-ci-producer.js +1 -1
- package/build/conductor/readiness-cli.js +11 -6
- package/build/conductor/readiness-prerequisites.js +41 -0
- package/build/conductor/readiness-sections.js +345 -55
- package/build/conductor/readiness.js +99 -87
- package/build/conductor/recovery-cli.js +606 -21
- package/build/conductor/recovery-operations.js +306 -7
- package/build/conductor/repair-contract.js +47 -2
- package/build/conductor/repository-workflow-remedy.js +8 -6
- package/build/conductor/stored-merge-credential.js +76 -0
- package/build/conductor/stored-merge-token-probe.js +28 -0
- package/build/conductor/temporary-plan.js +50 -0
- package/build/conductor/wait-run-cli.js +759 -0
- package/build/conductor/worker-database-doctor-inspector.js +49 -0
- package/build/conductor-bin.js +2 -2
- package/build/conductor-claude-hook-bin.js +2 -2
- package/build/conductor-claude-hook-removed-stub-bin.js +2 -5
- package/build/conductor-removed-stub-bin.js +2 -5
- package/build/connect-github-api.js +33 -14
- package/build/credential-store.js +356 -13
- package/build/docs.generated.js +27 -14
- package/build/doctor.js +203 -38
- package/build/drive-epic-help.js +212 -0
- package/build/drive-epic.js +1840 -373
- package/build/epic-ci-workflow-drift.js +77 -0
- package/build/epic-ci-workflow-install.js +183 -0
- package/build/epic-ci-workflow.js +157 -0
- package/build/epic-contract-context.js +326 -0
- package/build/epic-implementer-bin.js +131 -120
- package/build/epic-implementer-claude-hook-bin.js +2 -2
- package/build/escalation-reachability.js +134 -0
- package/build/executor/cleanup-report.js +99 -0
- package/build/executor/cli.js +12 -1
- package/build/executor/completion-contract.js +68 -11
- package/build/executor/completion-supervision.js +99 -0
- package/build/executor/delivery-outcome.js +179 -0
- package/build/executor/deps.js +3 -0
- package/build/executor/env.js +71 -0
- package/build/executor/failure-reason-codes.js +126 -0
- package/build/executor/heartbeat.js +38 -0
- package/build/executor/http-client.js +115 -4
- package/build/executor/integration-job.js +298 -5
- package/build/executor/job-errors.js +36 -6
- package/build/executor/job-runner.js +720 -36
- package/build/executor/likely-tests.js +36 -2
- package/build/executor/merge-job.js +145 -2
- package/build/executor/observation.js +73 -4
- package/build/executor/permissions.js +193 -97
- package/build/executor/preflight.js +14 -3
- package/build/executor/process-containment.js +28 -2
- package/build/executor/prompt-spec.js +50 -5
- package/build/executor/rebase-finalization.js +38 -3
- package/build/executor/reconcile-overlap-job.js +35 -7
- package/build/executor/required-work-ledger.js +236 -81
- package/build/executor/resume-pre-spawn.js +38 -1
- package/build/executor/runner.js +91 -3
- package/build/executor/test-clock.js +8 -0
- package/build/executor/types.js +37 -2
- package/build/executor/worker-cli-launcher.js +259 -0
- package/build/executor/worker-command.js +41 -4
- package/build/executor/worker-database-target.js +91 -0
- package/build/executor/worker-database.js +908 -0
- package/build/executor/worker-finalization.js +106 -0
- package/build/executor/worker-guard-hook.js +203 -0
- package/build/executor/worker-resources.js +47 -0
- package/build/executor/worker-verification-guidance.js +15 -2
- package/build/executor/worktree.js +303 -15
- package/build/executor-launch.js +11 -1
- package/build/generated-assets-doctor.js +9 -1
- package/build/generated-assets-health.js +13 -4
- package/build/generated-assets-legacy.js +39 -0
- package/build/generated-assets-paths.js +12 -1
- package/build/generated-assets-repair.js +4 -1
- package/build/generated-assets-test-support.js +12 -0
- package/build/github-remote.js +33 -0
- package/build/github-sign-in.js +62 -0
- package/build/index.js +1214 -465
- package/build/init.js +39 -1
- package/build/install-bridge-conductor-gate.js +78 -0
- package/build/install-bridge-conductor-setup.js +413 -0
- package/build/install-bridge-conductor.js +1226 -267
- package/build/install-bridge.js +629 -350
- package/build/launcher-config-inspection.js +184 -19
- package/build/mcp-host-targets.js +4 -0
- package/build/mcp-identity.js +7 -0
- package/build/mcp-install-state.js +8 -2
- package/build/merge-pull-request.js +6 -0
- package/build/merge-workflow-install.js +763 -345
- package/build/phase-result-artifacts.js +75 -20
- package/build/pipeline-orchestrator.js +247 -4
- package/build/pipelines.generated.js +35 -35
- package/build/plan-discovery.js +15 -2
- package/build/plan-execution-ledger.js +306 -17
- package/build/plan-phase-routing.js +48 -13
- package/build/plane/cli.js +105 -51
- package/build/plane/defaults.js +3 -0
- package/build/plane/plane-freshness.js +294 -0
- package/build/plane/schema-compatibility.js +137 -0
- package/build/plane/shutdown-deps.js +38 -0
- package/build/plane/shutdown.js +83 -8
- package/build/plane/terminal-run-cleanup.js +303 -0
- package/build/printed-remedy-commands.js +26 -4
- package/build/readiness-check.js +6 -2
- package/build/readiness-prerequisites.generated.js +532 -0
- package/build/readme.generated.js +1 -1
- package/build/session-upgrade-notice.js +86 -0
- package/build/setup-epic.js +400 -30
- package/build/shared-resources.generated.js +5 -0
- package/build/start-tickets.js +43 -15
- package/build/test-command-detection.js +247 -0
- package/build/test-command-validation.js +73 -0
- package/build/testing-config-client.js +150 -0
- package/build/ticket-delivery-artifacts.js +258 -0
- package/build/ticket-delivery-enrollment.js +306 -0
- package/build/ticket-delivery.js +205 -0
- package/build/ticket-review-summary.js +14 -0
- package/build/tool-call-advisory.js +162 -0
- package/build/tool-surface-gating.js +28 -89
- package/build/update-check.js +97 -16
- package/build/update-status.js +61 -71
- package/build/upgrade-advice.js +15 -11
- package/build/upgrade-cli.js +360 -20
- package/build/v2-readiness-requirements.js +552 -0
- package/build/version.generated.js +3 -3
- package/build/worker-guard-hook-bin.js +2 -2
- package/build/worktree-core.js +22 -7
- package/docs/BRIDGE-DIRECTORY-README.md +48 -0
- package/docs/EPIC-IMPLEMENTER-INSTALL.md +12 -867
- package/docs/EPIC-IMPLEMENTER.md +104 -63
- package/docs/epic-implementer/getting-started.md +131 -0
- package/docs/epic-implementer/self-hosting.md +133 -0
- package/package.json +3 -3
- package/pipelines/idea-to-ticket.json +1 -1
- package/pipelines/implement-ticket.json +8 -8
- package/pipelines/review-ticket.json +2 -2
- package/design-assets/favicon/favicon-32x32.png +0 -0
- package/design-assets/just-logo-rough-draft.png +0 -0
|
@@ -22,20 +22,16 @@
|
|
|
22
22
|
* carries config bodies, `env` maps, credential values, or raw error text.
|
|
23
23
|
*/
|
|
24
24
|
import path from "path";
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
25
|
+
import { codexHome, isCodexHomeOverrideHonored } from "./codex-home.js";
|
|
26
|
+
import { inspectCodexLauncher } from "./codex-launcher-pin.js";
|
|
27
|
+
import { getProjectJsonTargets, hostAdapterForTarget, MCP_HOST_TARGETS, } from "./mcp-host-targets.js";
|
|
28
|
+
import { LEGACY_SERVER_NAMES, MCP_SERVER_NAME, MCP_PACKAGE_NAME, resolveRegistrationKey, WORKTREE_SHIM_TOKEN, } from "./mcp-identity.js";
|
|
27
29
|
/**
|
|
28
30
|
* The npm package every Bridge launcher spec names. Retained as a compatibility
|
|
29
31
|
* alias — `doctor.ts` still imports this name — assigned from the shared
|
|
30
32
|
* constant so there is no duplicate package-name literal.
|
|
31
33
|
*/
|
|
32
34
|
export const BRIDGE_PACKAGE_NAME = MCP_PACKAGE_NAME;
|
|
33
|
-
/**
|
|
34
|
-
* The subcommand token that marks a worktree shim registration. A shim points at
|
|
35
|
-
* a sibling worktree's server rather than a published package, so no pin applies
|
|
36
|
-
* and no rewrite is ever safe (BAPI-714 / worktree provisioning).
|
|
37
|
-
*/
|
|
38
|
-
const WORKTREE_SHIM_TOKEN = "mcp-invoke";
|
|
39
35
|
/**
|
|
40
36
|
* Every project-local MCP config Bridge registers into. Exported so `doctor`,
|
|
41
37
|
* `init`, and `upgrade` can no longer drift apart on which paths exist or which
|
|
@@ -155,6 +151,10 @@ const REASON_TEXT = {
|
|
|
155
151
|
"malformed-version": "the launcher pin is not a valid MAJOR.MINOR.PATCH release",
|
|
156
152
|
"pinned-ahead-of-target": "the launcher pin is newer than the target version and must not be downgraded",
|
|
157
153
|
"duplicate-registration": DUPLICATE_REGISTRATION_GUIDANCE,
|
|
154
|
+
// BAPI-1445: Codex's global TOML is read by a conservative scanner that refuses
|
|
155
|
+
// anything it cannot interpret with confidence. The wording is fixed so no file
|
|
156
|
+
// content, argument, or environment value can ever reach a diagnostic.
|
|
157
|
+
unlocatable: "the Codex Bridge launcher cannot be located safely; resolve its configuration manually, then re-run the upgrade",
|
|
158
158
|
};
|
|
159
159
|
/** Render a reason code as sanitized prose. */
|
|
160
160
|
export function describeLauncherReason(reason) {
|
|
@@ -351,31 +351,38 @@ async function inspectOne(target, options) {
|
|
|
351
351
|
reason: "no-package-token",
|
|
352
352
|
};
|
|
353
353
|
}
|
|
354
|
-
|
|
354
|
+
return {
|
|
355
355
|
...keyed,
|
|
356
356
|
filePresent: true,
|
|
357
357
|
bridgeEntryPresent: true,
|
|
358
358
|
shape: "standard",
|
|
359
359
|
spec: pin.spec,
|
|
360
|
+
...classifyStandardPin(pin, targetVersion),
|
|
360
361
|
};
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Classify a parsed Bridge package token against the target version.
|
|
365
|
+
*
|
|
366
|
+
* Shared by the project JSON inspection and the global Codex inspection so a pin
|
|
367
|
+
* means the same thing wherever it was written. Order matters and is part of the
|
|
368
|
+
* contract: unpinned forms normalize, a non-exact specifier is refused, a
|
|
369
|
+
* non-release target is refused, a pin ahead of the target is never downgraded,
|
|
370
|
+
* and only then is the exact pin compared.
|
|
371
|
+
*/
|
|
372
|
+
function classifyStandardPin(pin, targetVersion) {
|
|
361
373
|
// Bare and explicit `@latest` are the two forms an exact-pin policy normalizes
|
|
362
374
|
// rather than rejects — both mean "whatever npx resolves", which is exactly the
|
|
363
375
|
// non-determinism BAPI-429 pinned away from.
|
|
364
376
|
if (pin.specifier === null || pin.specifier === "latest") {
|
|
365
|
-
return {
|
|
377
|
+
return { action: "normalize-unpinned" };
|
|
366
378
|
}
|
|
367
379
|
if (!isExactVersion(pin.specifier)) {
|
|
368
|
-
return {
|
|
369
|
-
...common,
|
|
370
|
-
action: "unsupported",
|
|
371
|
-
reason: classifyNonExactSpecifier(pin.specifier),
|
|
372
|
-
};
|
|
380
|
+
return { action: "unsupported", reason: classifyNonExactSpecifier(pin.specifier) };
|
|
373
381
|
}
|
|
374
382
|
const comparison = compareExactVersions(pin.specifier, targetVersion);
|
|
375
383
|
if (comparison === null) {
|
|
376
384
|
// The TARGET is not an exact release. Refuse rather than guess.
|
|
377
385
|
return {
|
|
378
|
-
...common,
|
|
379
386
|
currentVersion: pin.specifier,
|
|
380
387
|
action: "unsupported",
|
|
381
388
|
reason: "malformed-version",
|
|
@@ -383,20 +390,18 @@ async function inspectOne(target, options) {
|
|
|
383
390
|
}
|
|
384
391
|
if (comparison > 0) {
|
|
385
392
|
return {
|
|
386
|
-
...common,
|
|
387
393
|
currentVersion: pin.specifier,
|
|
388
394
|
action: "ahead",
|
|
389
395
|
reason: "pinned-ahead-of-target",
|
|
390
396
|
};
|
|
391
397
|
}
|
|
392
398
|
return {
|
|
393
|
-
...common,
|
|
394
399
|
currentVersion: pin.specifier,
|
|
395
400
|
action: comparison === 0 ? "already-current" : "repin",
|
|
396
401
|
};
|
|
397
402
|
}
|
|
398
403
|
/** Classify why a non-exact specifier cannot be treated as a release pin. */
|
|
399
|
-
function classifyNonExactSpecifier(specifier) {
|
|
404
|
+
export function classifyNonExactSpecifier(specifier) {
|
|
400
405
|
if (/^[\^~]|^[<>=]/.test(specifier) || specifier.includes(" - ") || specifier.includes("||")) {
|
|
401
406
|
return "version-range";
|
|
402
407
|
}
|
|
@@ -410,3 +415,163 @@ function classifyNonExactSpecifier(specifier) {
|
|
|
410
415
|
function isPlainObject(value) {
|
|
411
416
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
412
417
|
}
|
|
418
|
+
/**
|
|
419
|
+
* Resolve Codex's global config location through {@link codexHome}.
|
|
420
|
+
*
|
|
421
|
+
* `$CODEX_HOME/config.toml` is shown only when an absolute override was actually
|
|
422
|
+
* honored — even if it happens to equal the default location — so a relative or
|
|
423
|
+
* blank override falls back to the default display exactly as `codexHome` falls
|
|
424
|
+
* back to the default path.
|
|
425
|
+
*/
|
|
426
|
+
export function resolveCodexConfigLocation(env, homedir) {
|
|
427
|
+
return {
|
|
428
|
+
filePath: path.join(codexHome(env, homedir), "config.toml"),
|
|
429
|
+
displayPath: isCodexHomeOverrideHonored(env)
|
|
430
|
+
? "$CODEX_HOME/config.toml"
|
|
431
|
+
: MCP_HOST_TARGETS.codex.displayPath,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Inspect Codex's global Bridge launcher, read-only, with exactly one read.
|
|
436
|
+
*
|
|
437
|
+
* Only `ENOENT` is absence. Any other read failure is a blocking
|
|
438
|
+
* `file-unreadable`, and the exception text is discarded: it can carry an
|
|
439
|
+
* absolute path. After the scan, the launcher is classified with the same shared
|
|
440
|
+
* pin rules as the project JSON targets.
|
|
441
|
+
*/
|
|
442
|
+
export async function inspectGlobalLauncherConfigs(options) {
|
|
443
|
+
const { targetVersion } = options;
|
|
444
|
+
const { filePath, displayPath } = resolveCodexConfigLocation(options.env, options.homedir);
|
|
445
|
+
const base = {
|
|
446
|
+
hostId: "codex",
|
|
447
|
+
scope: "global",
|
|
448
|
+
displayPath,
|
|
449
|
+
targetVersion,
|
|
450
|
+
spec: null,
|
|
451
|
+
currentVersion: null,
|
|
452
|
+
registrationKey: null,
|
|
453
|
+
legacyRegistration: false,
|
|
454
|
+
};
|
|
455
|
+
let raw;
|
|
456
|
+
try {
|
|
457
|
+
raw = await options.readFile(filePath);
|
|
458
|
+
}
|
|
459
|
+
catch (err) {
|
|
460
|
+
const code = err && typeof err === "object" ? err.code : undefined;
|
|
461
|
+
if (code === "ENOENT") {
|
|
462
|
+
return {
|
|
463
|
+
...base,
|
|
464
|
+
filePresent: false,
|
|
465
|
+
bridgeEntryPresent: false,
|
|
466
|
+
shape: "none",
|
|
467
|
+
action: "skip-inactive",
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
return {
|
|
471
|
+
...base,
|
|
472
|
+
filePresent: true,
|
|
473
|
+
bridgeEntryPresent: false,
|
|
474
|
+
shape: "none",
|
|
475
|
+
action: "invalid",
|
|
476
|
+
reason: "file-unreadable",
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
const found = inspectCodexLauncher(raw);
|
|
480
|
+
switch (found.kind) {
|
|
481
|
+
case "none":
|
|
482
|
+
// A readable file with no Bridge declaration: the user never configured
|
|
483
|
+
// Bridge in Codex, so it is not a participant.
|
|
484
|
+
return {
|
|
485
|
+
...base,
|
|
486
|
+
filePresent: true,
|
|
487
|
+
bridgeEntryPresent: false,
|
|
488
|
+
shape: "none",
|
|
489
|
+
action: "skip-inactive",
|
|
490
|
+
};
|
|
491
|
+
case "duplicate":
|
|
492
|
+
return {
|
|
493
|
+
...base,
|
|
494
|
+
filePresent: true,
|
|
495
|
+
bridgeEntryPresent: true,
|
|
496
|
+
shape: "custom",
|
|
497
|
+
action: "duplicate-registration",
|
|
498
|
+
reason: "duplicate-registration",
|
|
499
|
+
};
|
|
500
|
+
case "unlocatable":
|
|
501
|
+
return {
|
|
502
|
+
...base,
|
|
503
|
+
filePresent: true,
|
|
504
|
+
bridgeEntryPresent: true,
|
|
505
|
+
shape: "custom",
|
|
506
|
+
action: "invalid",
|
|
507
|
+
reason: "unlocatable",
|
|
508
|
+
};
|
|
509
|
+
case "worktree-shim":
|
|
510
|
+
return {
|
|
511
|
+
...base,
|
|
512
|
+
filePresent: true,
|
|
513
|
+
bridgeEntryPresent: true,
|
|
514
|
+
registrationKey: found.registrationName,
|
|
515
|
+
legacyRegistration: found.registrationName !== MCP_SERVER_NAME,
|
|
516
|
+
shape: "worktree-shim",
|
|
517
|
+
action: "skip-worktree-shim",
|
|
518
|
+
};
|
|
519
|
+
case "located": {
|
|
520
|
+
const keyed = {
|
|
521
|
+
...base,
|
|
522
|
+
filePresent: true,
|
|
523
|
+
bridgeEntryPresent: true,
|
|
524
|
+
registrationKey: found.registrationName,
|
|
525
|
+
legacyRegistration: found.registrationName !== MCP_SERVER_NAME,
|
|
526
|
+
};
|
|
527
|
+
// Same order as the JSON targets: shim first (the parser already routed
|
|
528
|
+
// shims above), then the package token, then the shared pin rules.
|
|
529
|
+
const pin = parseLauncherPin(found.args);
|
|
530
|
+
if (!pin) {
|
|
531
|
+
return { ...keyed, shape: "custom", action: "invalid", reason: "unlocatable" };
|
|
532
|
+
}
|
|
533
|
+
const classified = classifyStandardPin(pin, targetVersion);
|
|
534
|
+
return {
|
|
535
|
+
...keyed,
|
|
536
|
+
shape: "standard",
|
|
537
|
+
spec: pin.spec,
|
|
538
|
+
...classified,
|
|
539
|
+
action: classified.action,
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
// ---------------------------------------------------------------------------
|
|
545
|
+
// Effective Claude Code pin (BAPI-1446)
|
|
546
|
+
// ---------------------------------------------------------------------------
|
|
547
|
+
/**
|
|
548
|
+
* The exact release the project's Claude Code launcher is pinned to, or null.
|
|
549
|
+
*
|
|
550
|
+
* Install uses this to pin the SessionStart upgrade-notice hook to the same build
|
|
551
|
+
* the project's MCP config launches. It answers null — never a guess from the
|
|
552
|
+
* running process, and never `@latest` — when the config is absent, unreadable,
|
|
553
|
+
* a worktree shim, a custom launcher, ambiguous (both registration keys), or
|
|
554
|
+
* pinned to anything other than one exact `MAJOR.MINOR.PATCH`. Read-only.
|
|
555
|
+
*/
|
|
556
|
+
export async function discoverClaudeCodeEffectivePin(options) {
|
|
557
|
+
try {
|
|
558
|
+
const relPath = MCP_HOST_TARGETS["claude-code"].relPath;
|
|
559
|
+
const target = relPath ? launcherTargetFor(relPath) : undefined;
|
|
560
|
+
if (!target)
|
|
561
|
+
return null;
|
|
562
|
+
const [found] = await inspectLauncherConfigs({
|
|
563
|
+
cwd: options.cwd,
|
|
564
|
+
targetVersion: options.targetVersion,
|
|
565
|
+
readFile: options.readFile,
|
|
566
|
+
targets: [target],
|
|
567
|
+
});
|
|
568
|
+
if (!found || found.shape !== "standard" || !found.bridgeEntryPresent)
|
|
569
|
+
return null;
|
|
570
|
+
if (isPrerequisiteFailure(found))
|
|
571
|
+
return null;
|
|
572
|
+
return isExactVersion(found.currentVersion) ? found.currentVersion : null;
|
|
573
|
+
}
|
|
574
|
+
catch {
|
|
575
|
+
return null;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
@@ -77,6 +77,7 @@ export const MCP_HOST_TARGETS = {
|
|
|
77
77
|
launchAgent: "claude",
|
|
78
78
|
capabilities: { mcpConfiguration: true, customCommands: true, worktreeProvisioning: true, sessionSpawning: true },
|
|
79
79
|
writeStrategy: "vendor-first",
|
|
80
|
+
reloadHint: "run /mcp or restart Claude Code",
|
|
80
81
|
// Claude Code is always a candidate default.
|
|
81
82
|
detect: () => true,
|
|
82
83
|
},
|
|
@@ -90,6 +91,7 @@ export const MCP_HOST_TARGETS = {
|
|
|
90
91
|
launchAgent: "cursor-agent",
|
|
91
92
|
capabilities: { mcpConfiguration: true, customCommands: true, worktreeProvisioning: true, sessionSpawning: true },
|
|
92
93
|
writeStrategy: "direct",
|
|
94
|
+
reloadHint: "toggle bridge off and on in Cursor Settings → MCP, or reload the window",
|
|
93
95
|
detect: (ctx) => ctx.exists(joinPath(ctx.cwd, ".cursor")) ||
|
|
94
96
|
typeof ctx.env.CURSOR_TRACE_DIR === "string" &&
|
|
95
97
|
ctx.env.CURSOR_TRACE_DIR.length > 0,
|
|
@@ -103,6 +105,7 @@ export const MCP_HOST_TARGETS = {
|
|
|
103
105
|
hostKind: "vscode-json",
|
|
104
106
|
capabilities: { mcpConfiguration: true, customCommands: true, worktreeProvisioning: false, sessionSpawning: false },
|
|
105
107
|
writeStrategy: "direct",
|
|
108
|
+
reloadHint: "restart the bridge server (MCP: List Servers)",
|
|
106
109
|
detect: (ctx) => ctx.exists(joinPath(ctx.cwd, ".vscode")),
|
|
107
110
|
},
|
|
108
111
|
codex: {
|
|
@@ -119,6 +122,7 @@ export const MCP_HOST_TARGETS = {
|
|
|
119
122
|
// registration remains the ordinary interactive default.
|
|
120
123
|
capabilities: { mcpConfiguration: true, customCommands: true, worktreeProvisioning: true, sessionSpawning: true },
|
|
121
124
|
writeStrategy: "vendor-first",
|
|
125
|
+
reloadHint: "restart Codex",
|
|
122
126
|
detect: (ctx) => ctx.exists(joinPath(ctx.homedir, ".codex")),
|
|
123
127
|
},
|
|
124
128
|
windsurf: {
|
package/build/mcp-identity.js
CHANGED
|
@@ -18,6 +18,13 @@
|
|
|
18
18
|
export const MCP_SERVER_NAME = "bridge";
|
|
19
19
|
/** The current published npm package name for the MCP server. */
|
|
20
20
|
export const MCP_PACKAGE_NAME = "@bridge_gpt/mcp-server";
|
|
21
|
+
/**
|
|
22
|
+
* The subcommand token that marks a worktree shim registration. A shim points at
|
|
23
|
+
* a sibling worktree's server rather than a published package, so no pin applies
|
|
24
|
+
* and no rewrite is ever safe (BAPI-714 / worktree provisioning). Shared by the
|
|
25
|
+
* JSON launcher inspection and the pure Codex TOML parser (BAPI-1445).
|
|
26
|
+
*/
|
|
27
|
+
export const WORKTREE_SHIM_TOKEN = "mcp-invoke";
|
|
21
28
|
/** The README resource URI served by the MCP server. */
|
|
22
29
|
export const MCP_README_URI = `${MCP_SERVER_NAME}://readme`;
|
|
23
30
|
/**
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* unit-testable with in-memory fakes.
|
|
18
18
|
*/
|
|
19
19
|
import { validPackagedAssetInventory } from "./generated-assets-context.js";
|
|
20
|
+
import { currentDestinationForLegacyDoc } from "./generated-assets-legacy.js";
|
|
20
21
|
import { executorIdFromLaunchdFilename, executorIdFromSystemdFilename, } from "./executor/service-unit.js";
|
|
21
22
|
import { HOST_PLATFORM_ORDER, isHostPlatformId, } from "./mcp-host-targets.js";
|
|
22
23
|
/** Current on-disk schema version. */
|
|
@@ -503,12 +504,17 @@ export async function recordPackagedAssetInventory(cwd, inventory, deps) {
|
|
|
503
504
|
return { ok: false, error: "Existing installation state cannot be safely preserved." };
|
|
504
505
|
const state = prior.status === "valid" ? prior.state : undefined;
|
|
505
506
|
const records = new Map();
|
|
507
|
+
// BAPI-1470: a record whose id or destination is one of the six moved procedure
|
|
508
|
+
// paths is dropped from both sides, so future inventories name only current ones.
|
|
509
|
+
const isMovedRecord = (a) => currentDestinationForLegacyDoc(a.id) !== undefined || currentDestinationForLegacyDoc(a.destination) !== undefined;
|
|
506
510
|
if (state?.packagedAssets?.rootBinding === inventory.rootBinding) {
|
|
507
511
|
for (const a of state.packagedAssets.assets)
|
|
508
|
-
|
|
512
|
+
if (!isMovedRecord(a))
|
|
513
|
+
records.set(`${a.host}:${a.id}`, a);
|
|
509
514
|
}
|
|
510
515
|
for (const a of inventory.assets)
|
|
511
|
-
|
|
516
|
+
if (!isMovedRecord(a))
|
|
517
|
+
records.set(`${a.host}:${a.id}`, a);
|
|
512
518
|
return writeMcpInstallState(cwd, { selectedPlatforms: state?.selectedPlatforms ?? [],
|
|
513
519
|
projectConfigPaths: state?.projectConfigPaths ?? [], packagedAssets: { ...inventory, assets: [...records.values()] } }, deps);
|
|
514
520
|
}
|
|
@@ -689,6 +689,12 @@ const LOCAL_GH_HINTS = {
|
|
|
689
689
|
machine_merge_credential_invalid: `The configured ${LOCAL_MERGE_CREDENTIAL_ENV_KEYS.machine_token} was rejected by GitHub. Rotate it and relaunch this MCP server.`,
|
|
690
690
|
local_merge_credential_unpermitted: `The configured ${LOCAL_MERGE_CREDENTIAL_ENV_KEYS.local} authenticates but cannot write to this repository. Grant it merge permission.`,
|
|
691
691
|
machine_merge_credential_unpermitted: `The configured ${LOCAL_MERGE_CREDENTIAL_ENV_KEYS.machine_token} authenticates but cannot write to this repository. Grant the machine user merge permission.`,
|
|
692
|
+
// BAPI-1452: GitHub gave no usable answer about the credential's access. Not
|
|
693
|
+
// proof of a missing permission, but a merge still refuses without evidence.
|
|
694
|
+
local_merge_probe_unavailable: `Could not confirm that ${LOCAL_MERGE_CREDENTIAL_ENV_KEYS.local} can push to this repository and read its pull requests ` +
|
|
695
|
+
"(GitHub returned no usable answer). Retry shortly; if it persists, check the token's repository access and GitHub's status.",
|
|
696
|
+
machine_merge_probe_unavailable: `Could not confirm that ${LOCAL_MERGE_CREDENTIAL_ENV_KEYS.machine_token} can push to this repository and read its pull requests ` +
|
|
697
|
+
"(GitHub returned no usable answer). Retry shortly; if it persists, check the machine user's repository access and GitHub's status.",
|
|
692
698
|
};
|
|
693
699
|
/**
|
|
694
700
|
* Read the repository's LEGACY merge execution mode.
|