@bridge_gpt/mcp-server 0.2.69 → 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.
Files changed (151) hide show
  1. package/README.md +140 -292
  2. package/build/agent-launchers/claude-executor-adapter.js +17 -4
  3. package/build/agents.generated.js +4 -4
  4. package/build/artifact-diff.js +110 -0
  5. package/build/bin-entrypoint.js +36 -0
  6. package/build/bridge-permissions.js +23 -4
  7. package/build/claude-review-workflow-drift.js +3 -3
  8. package/build/codex-bridge-profile.js +1 -1
  9. package/build/commands.generated.js +6 -6
  10. package/build/conductor/bridge-api-client.js +598 -19
  11. package/build/conductor/bring-up-facts.js +9 -9
  12. package/build/conductor/doctor.js +466 -18
  13. package/build/conductor/epic-child-continuation.js +54 -3
  14. package/build/conductor/epic-implementer-cli.js +132 -34
  15. package/build/conductor/epic-runtime.js +2 -2
  16. package/build/conductor/epic-state.js +1 -1
  17. package/build/conductor/hook-runtime-qualification.js +1 -1
  18. package/build/conductor/install-doctor.js +4 -2
  19. package/build/conductor/launch-need-probes.js +337 -0
  20. package/build/conductor/local-merge.js +241 -56
  21. package/build/conductor/merge-credential.js +172 -0
  22. package/build/conductor/merge-execution-eligibility.js +1 -1
  23. package/build/conductor/merged-child-check.js +95 -0
  24. package/build/conductor/plan-trim.js +30 -0
  25. package/build/conductor/pr-ci-producer.js +1 -1
  26. package/build/conductor/readiness-cli.js +11 -6
  27. package/build/conductor/readiness-prerequisites.js +41 -0
  28. package/build/conductor/readiness-sections.js +345 -55
  29. package/build/conductor/readiness.js +99 -87
  30. package/build/conductor/recovery-cli.js +606 -21
  31. package/build/conductor/recovery-operations.js +306 -7
  32. package/build/conductor/repair-contract.js +47 -2
  33. package/build/conductor/repository-workflow-remedy.js +8 -6
  34. package/build/conductor/stored-merge-credential.js +76 -0
  35. package/build/conductor/stored-merge-token-probe.js +28 -0
  36. package/build/conductor/temporary-plan.js +50 -0
  37. package/build/conductor/wait-run-cli.js +759 -0
  38. package/build/conductor/worker-database-doctor-inspector.js +49 -0
  39. package/build/conductor-bin.js +2 -2
  40. package/build/conductor-claude-hook-bin.js +2 -2
  41. package/build/conductor-claude-hook-removed-stub-bin.js +2 -5
  42. package/build/conductor-removed-stub-bin.js +2 -5
  43. package/build/credential-store.js +356 -13
  44. package/build/docs.generated.js +26 -13
  45. package/build/doctor.js +94 -32
  46. package/build/drive-epic-help.js +212 -0
  47. package/build/drive-epic.js +1840 -373
  48. package/build/epic-ci-workflow-drift.js +77 -0
  49. package/build/epic-ci-workflow-install.js +183 -0
  50. package/build/epic-ci-workflow.js +157 -0
  51. package/build/epic-contract-context.js +326 -0
  52. package/build/epic-implementer-bin.js +57 -41
  53. package/build/epic-implementer-claude-hook-bin.js +2 -2
  54. package/build/escalation-reachability.js +134 -0
  55. package/build/executor/cleanup-report.js +99 -0
  56. package/build/executor/cli.js +12 -1
  57. package/build/executor/completion-contract.js +66 -11
  58. package/build/executor/completion-supervision.js +99 -0
  59. package/build/executor/delivery-outcome.js +179 -0
  60. package/build/executor/deps.js +3 -0
  61. package/build/executor/env.js +71 -0
  62. package/build/executor/failure-reason-codes.js +126 -0
  63. package/build/executor/heartbeat.js +38 -0
  64. package/build/executor/http-client.js +72 -0
  65. package/build/executor/integration-job.js +298 -5
  66. package/build/executor/job-errors.js +36 -6
  67. package/build/executor/job-runner.js +720 -36
  68. package/build/executor/likely-tests.js +36 -2
  69. package/build/executor/merge-job.js +145 -2
  70. package/build/executor/observation.js +73 -4
  71. package/build/executor/permissions.js +193 -97
  72. package/build/executor/preflight.js +14 -3
  73. package/build/executor/process-containment.js +28 -2
  74. package/build/executor/prompt-spec.js +50 -5
  75. package/build/executor/rebase-finalization.js +38 -3
  76. package/build/executor/reconcile-overlap-job.js +35 -7
  77. package/build/executor/required-work-ledger.js +236 -81
  78. package/build/executor/resume-pre-spawn.js +38 -1
  79. package/build/executor/runner.js +91 -3
  80. package/build/executor/test-clock.js +8 -0
  81. package/build/executor/types.js +37 -2
  82. package/build/executor/worker-cli-launcher.js +259 -0
  83. package/build/executor/worker-command.js +41 -4
  84. package/build/executor/worker-database-target.js +91 -0
  85. package/build/executor/worker-database.js +908 -0
  86. package/build/executor/worker-finalization.js +106 -0
  87. package/build/executor/worker-guard-hook.js +203 -0
  88. package/build/executor/worker-resources.js +47 -0
  89. package/build/executor/worker-verification-guidance.js +15 -2
  90. package/build/executor/worktree.js +303 -15
  91. package/build/executor-launch.js +11 -1
  92. package/build/generated-assets-doctor.js +9 -1
  93. package/build/generated-assets-health.js +13 -4
  94. package/build/generated-assets-legacy.js +39 -0
  95. package/build/generated-assets-paths.js +12 -1
  96. package/build/generated-assets-repair.js +4 -1
  97. package/build/generated-assets-test-support.js +12 -0
  98. package/build/github-remote.js +33 -0
  99. package/build/github-sign-in.js +62 -0
  100. package/build/index.js +1067 -536
  101. package/build/init.js +39 -1
  102. package/build/install-bridge-conductor-gate.js +78 -0
  103. package/build/install-bridge-conductor-setup.js +413 -0
  104. package/build/install-bridge-conductor.js +1226 -267
  105. package/build/install-bridge.js +376 -60
  106. package/build/mcp-install-state.js +8 -2
  107. package/build/merge-pull-request.js +6 -0
  108. package/build/merge-workflow-install.js +763 -345
  109. package/build/phase-result-artifacts.js +75 -20
  110. package/build/pipeline-orchestrator.js +247 -4
  111. package/build/pipelines.generated.js +35 -35
  112. package/build/plan-discovery.js +15 -2
  113. package/build/plan-execution-ledger.js +306 -17
  114. package/build/plan-phase-routing.js +48 -13
  115. package/build/plane/cli.js +105 -51
  116. package/build/plane/defaults.js +3 -0
  117. package/build/plane/plane-freshness.js +294 -0
  118. package/build/plane/schema-compatibility.js +137 -0
  119. package/build/plane/shutdown-deps.js +38 -0
  120. package/build/plane/shutdown.js +83 -8
  121. package/build/plane/terminal-run-cleanup.js +303 -0
  122. package/build/printed-remedy-commands.js +26 -4
  123. package/build/readiness-check.js +6 -2
  124. package/build/readiness-prerequisites.generated.js +532 -0
  125. package/build/readme.generated.js +1 -1
  126. package/build/setup-epic.js +400 -30
  127. package/build/shared-resources.generated.js +5 -0
  128. package/build/start-tickets.js +28 -15
  129. package/build/test-command-detection.js +247 -0
  130. package/build/test-command-validation.js +73 -0
  131. package/build/testing-config-client.js +150 -0
  132. package/build/ticket-delivery-artifacts.js +258 -0
  133. package/build/ticket-delivery-enrollment.js +306 -0
  134. package/build/ticket-delivery.js +205 -0
  135. package/build/ticket-review-summary.js +14 -0
  136. package/build/upgrade-cli.js +13 -0
  137. package/build/v2-readiness-requirements.js +552 -0
  138. package/build/version.generated.js +3 -3
  139. package/build/worker-guard-hook-bin.js +2 -2
  140. package/build/worktree-core.js +22 -7
  141. package/docs/BRIDGE-DIRECTORY-README.md +48 -0
  142. package/docs/EPIC-IMPLEMENTER-INSTALL.md +12 -867
  143. package/docs/EPIC-IMPLEMENTER.md +104 -63
  144. package/docs/epic-implementer/getting-started.md +131 -0
  145. package/docs/epic-implementer/self-hosting.md +133 -0
  146. package/package.json +3 -3
  147. package/pipelines/idea-to-ticket.json +1 -1
  148. package/pipelines/implement-ticket.json +8 -8
  149. package/pipelines/review-ticket.json +2 -2
  150. package/design-assets/favicon/favicon-32x32.png +0 -0
  151. package/design-assets/just-logo-rough-draft.png +0 -0
@@ -0,0 +1,205 @@
1
+ /**
2
+ * BAPI-1426 — the thin client for the server's ticket delivery authority.
3
+ *
4
+ * The Bridge API decides whether a managed ticket is ready to publish, merge, or
5
+ * complete. This module only carries requests to `/ticket-delivery/...` and hands
6
+ * the server's answer back. It holds no readiness policy: it never counts ledger
7
+ * records, never decides an outcome, and never turns a failed call into a green
8
+ * result.
9
+ *
10
+ * Every function returns a result object instead of throwing on an HTTP or
11
+ * network failure, so a caller can keep local work and retry later. Messages are
12
+ * sanitized and never carry the API key or any request header.
13
+ */
14
+ import { redactSecrets } from "./secret-redaction.js";
15
+ export const READINESS_BOUNDARIES = ["publish", "merge", "complete"];
16
+ const STATUS_CODES = {
17
+ 400: "BAD_REQUEST",
18
+ 401: "UNAUTHORIZED",
19
+ 403: "FORBIDDEN",
20
+ 404: "NOT_FOUND",
21
+ 409: "CONFLICT",
22
+ 422: "VALIDATION_ERROR",
23
+ 429: "RATE_LIMITED",
24
+ 500: "INTERNAL_ERROR",
25
+ 502: "BAD_GATEWAY",
26
+ 503: "SERVICE_UNAVAILABLE",
27
+ 504: "GATEWAY_TIMEOUT",
28
+ };
29
+ const MAX_MESSAGE_LENGTH = 500;
30
+ /** Strip credentials and bound the length of any text that leaves this module. */
31
+ export function sanitizeDeliveryMessage(raw, apiKey) {
32
+ let text = typeof raw === "string" ? raw : raw instanceof Error ? raw.message : String(raw);
33
+ if (apiKey && apiKey.length >= 4)
34
+ text = text.split(apiKey).join("[REDACTED]");
35
+ text = redactSecrets(text);
36
+ return text.length > MAX_MESSAGE_LENGTH ? `${text.slice(0, MAX_MESSAGE_LENGTH)}…` : text;
37
+ }
38
+ function deliveryUrl(baseUrl, path, query) {
39
+ const url = new URL(`${baseUrl.replace(/\/+$/, "")}/ticket-delivery${path}`);
40
+ for (const [key, value] of Object.entries(query ?? {}))
41
+ url.searchParams.set(key, value);
42
+ return url.toString();
43
+ }
44
+ async function request(deps, method, path, options = {}) {
45
+ const fetchImpl = deps.fetchImpl ?? fetch;
46
+ let headers = {};
47
+ try {
48
+ headers = await deps.headers();
49
+ }
50
+ catch (err) {
51
+ return {
52
+ ok: false,
53
+ status: 0,
54
+ error: "CREDENTIALS_UNAVAILABLE",
55
+ message: sanitizeDeliveryMessage(err),
56
+ };
57
+ }
58
+ const apiKey = headers["X-API-Key"];
59
+ let resp;
60
+ try {
61
+ resp = await fetchImpl(deliveryUrl(deps.baseUrl, path, options.query), {
62
+ method,
63
+ headers: options.body === undefined ? headers : { ...headers, "Content-Type": "application/json" },
64
+ ...(options.body === undefined ? {} : { body: JSON.stringify(options.body) }),
65
+ });
66
+ }
67
+ catch (err) {
68
+ return {
69
+ ok: false,
70
+ status: 0,
71
+ error: "NETWORK_ERROR",
72
+ message: sanitizeDeliveryMessage(err, apiKey),
73
+ };
74
+ }
75
+ let raw = "";
76
+ try {
77
+ raw = await resp.text();
78
+ }
79
+ catch (err) {
80
+ return {
81
+ ok: false,
82
+ status: resp.status,
83
+ error: "INVALID_RESPONSE",
84
+ message: sanitizeDeliveryMessage(err, apiKey),
85
+ };
86
+ }
87
+ if (resp.ok) {
88
+ try {
89
+ const body = JSON.parse(raw);
90
+ if (body === null || typeof body !== "object" || Array.isArray(body)) {
91
+ throw new Error("response body is not a JSON object");
92
+ }
93
+ return { ok: true, status: resp.status, body: body };
94
+ }
95
+ catch (err) {
96
+ return {
97
+ ok: false,
98
+ status: resp.status,
99
+ error: "INVALID_RESPONSE",
100
+ message: sanitizeDeliveryMessage(err, apiKey),
101
+ };
102
+ }
103
+ }
104
+ let error = STATUS_CODES[resp.status] ?? "UNKNOWN_ERROR";
105
+ let message = raw ? raw : `HTTP ${resp.status}`;
106
+ let detail;
107
+ try {
108
+ const parsed = JSON.parse(raw);
109
+ detail = parsed?.detail;
110
+ if (detail !== null && typeof detail === "object" && !Array.isArray(detail)) {
111
+ const d = detail;
112
+ if (typeof d.error === "string")
113
+ error = d.error;
114
+ message = typeof d.message === "string" ? d.message : JSON.stringify(d);
115
+ }
116
+ else if (typeof detail === "string") {
117
+ message = detail;
118
+ }
119
+ else if (detail !== undefined) {
120
+ message = JSON.stringify(detail);
121
+ }
122
+ }
123
+ catch {
124
+ // Not JSON: keep the raw text as the message.
125
+ }
126
+ return {
127
+ ok: false,
128
+ status: resp.status,
129
+ error,
130
+ message: sanitizeDeliveryMessage(message, apiKey),
131
+ ...(detail !== undefined ? { detail: JSON.parse(sanitizeDeliveryDetail(detail, apiKey)) } : {}),
132
+ };
133
+ }
134
+ function sanitizeDeliveryDetail(detail, apiKey) {
135
+ let text = JSON.stringify(detail);
136
+ if (apiKey && apiKey.length >= 4)
137
+ text = text.split(apiKey).join("[REDACTED]");
138
+ return redactSecrets(text);
139
+ }
140
+ // ---------------------------------------------------------------------------
141
+ // Operations
142
+ // ---------------------------------------------------------------------------
143
+ /** Bind a managed execution. Replaying the same registration key resumes it. */
144
+ export function registerExecution(deps, body) {
145
+ return request(deps, "POST", "/executions", { body });
146
+ }
147
+ /** Find the active attempt for a ticket and branch. A 404 means there is none. */
148
+ export function recoverExecution(deps, query) {
149
+ return request(deps, "GET", "/executions/recover", { query });
150
+ }
151
+ const RUN_RECOVERY_CODES = {
152
+ TICKET_DELIVERY_RUN_UNMANAGED: "unmanaged",
153
+ TICKET_DELIVERY_RUN_NO_RECOVERABLE_EXECUTION: "no_recoverable_execution",
154
+ TICKET_DELIVERY_RUN_AMBIGUOUS: "ambiguous",
155
+ TICKET_DELIVERY_RUN_LOOKUP_FAILED: "lookup_failed",
156
+ };
157
+ const RUN_RECOVERY_MESSAGES = {
158
+ unmanaged: "The server confirmed no managed execution exists for this run and ticket.",
159
+ no_recoverable_execution: "The ticket belongs to the run but has no active or completed execution to read.",
160
+ ambiguous: "More than one active execution exists for this run and ticket.",
161
+ lookup_failed: "The run-scoped lookup failed. This is not proof the ticket is unmanaged.",
162
+ };
163
+ /**
164
+ * Find a run child's execution by run id and ticket, with no branch. Only an
165
+ * allowlisted server code maps to `unmanaged`, `no_recoverable_execution` or
166
+ * `ambiguous`. Every other failure, including a bare 404 from an older server,
167
+ * a 5xx, an unreadable body and a transport error, is `lookup_failed`.
168
+ */
169
+ export async function recoverExecutionForRun(deps, query) {
170
+ const result = await request(deps, "GET", "/executions/recover", {
171
+ query,
172
+ });
173
+ if (result.ok)
174
+ return { ok: true, body: result.body };
175
+ const detail = result.detail;
176
+ const code = typeof detail?.error === "string" ? detail.error : undefined;
177
+ const mapped = code !== undefined ? RUN_RECOVERY_CODES[code] : undefined;
178
+ const outcome = mapped ?? "lookup_failed";
179
+ return { ok: false, outcome, status: result.status, message: RUN_RECOVERY_MESSAGES[outcome] };
180
+ }
181
+ /** Whether a branch is held by a managed ticket. Grants no submission authority. */
182
+ export function getBranchHold(deps, query) {
183
+ return request(deps, "GET", "/holds", { query });
184
+ }
185
+ /** Upload one durable evidence batch. `retryable: true` means nothing was stored. */
186
+ export function submitEvidence(deps, attemptId, body) {
187
+ return request(deps, "POST", `/executions/${encodeURIComponent(attemptId)}/evidence`, { body });
188
+ }
189
+ /** The server-accepted ledger, which is the only source of post-PR ownership. */
190
+ export function getAcceptedLedger(deps, attemptId, query) {
191
+ return request(deps, "GET", `/executions/${encodeURIComponent(attemptId)}/ledger`, { query });
192
+ }
193
+ /** The server's readiness decision at one boundary. */
194
+ export function getReadiness(deps, attemptId, query) {
195
+ const params = { repo_name: query.repo_name };
196
+ if (query.boundary)
197
+ params.boundary = query.boundary;
198
+ return request(deps, "GET", `/executions/${encodeURIComponent(attemptId)}/readiness`, {
199
+ query: params,
200
+ });
201
+ }
202
+ /** Ask the server to confirm delivery after merge. Only it can say `delivery_complete`. */
203
+ export function completeDelivery(deps, attemptId, body) {
204
+ return request(deps, "POST", `/executions/${encodeURIComponent(attemptId)}/complete`, { body });
205
+ }
@@ -0,0 +1,14 @@
1
+ export function ticketReviewSummary(projection, proposed) {
2
+ if (projection?.enabled === true && projection.provenance === 'enabled')
3
+ return 'on';
4
+ if (projection?.enabled === false && projection.provenance === 'recorded' &&
5
+ typeof projection.actor === 'string' && /^actor_[a-z0-9]{4,32}$/.test(projection.actor) &&
6
+ typeof projection.recorded_at === 'string' && /^\d{4}-\d{2}-\d{2}T.+(?:Z|\+00:00)$/.test(projection.recorded_at) && Number.isFinite(Date.parse(projection.recorded_at))) {
7
+ return `off (set by ${projection.actor} on ${projection.recorded_at.slice(0, 10)})`;
8
+ }
9
+ if (projection?.enabled === false)
10
+ return 'off (legacy choice not recorded)';
11
+ if (proposed?.spec_review_gate === false)
12
+ return 'off requested (admin key required; choice recorded at create)';
13
+ return 'on';
14
+ }
@@ -783,6 +783,19 @@ export async function runUpgradeCli(argv, injected) {
783
783
  stdout(line);
784
784
  }
785
785
  stdout("Refreshed scaffolded artifacts (commands, agents, pipelines).");
786
+ // BAPI-1470: `runInit` already printed the notice and any probe warnings in
787
+ // full. Summarize with counts only. A caller that omits the optional fields has
788
+ // told us nothing, so absent fields print nothing rather than "none found".
789
+ const legacyCopyCount = initResult.legacyProcedureCopies?.length ?? 0;
790
+ const legacyWarningCount = initResult.legacyProcedureProbeWarnings?.length ?? 0;
791
+ if (legacyCopyCount > 0 || legacyWarningCount > 0) {
792
+ const parts = [];
793
+ if (legacyCopyCount > 0)
794
+ parts.push(`${legacyCopyCount} old fallback ${legacyCopyCount === 1 ? "copy" : "copies"} found`);
795
+ if (legacyWarningCount > 0)
796
+ parts.push(`${legacyWarningCount} old ${legacyWarningCount === 1 ? "path" : "paths"} could not be checked`);
797
+ stdout(`Old procedure copies: ${parts.join(", ")} (details above).`);
798
+ }
786
799
  if (verificationFailures.length > 0) {
787
800
  stderr("\nBridge API upgrade did NOT converge:");
788
801
  for (const failure of verificationFailures)