@bridge_gpt/mcp-server 0.2.16 → 0.2.19
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/CONDUCTOR.md +75 -0
- package/README.md +2 -2
- package/build/agent-capabilities/probe-context.js +13 -3
- package/build/agent-capabilities/probes.js +262 -11
- package/build/agent-capabilities/reporter.js +1 -0
- package/build/agents.generated.js +3 -3
- package/build/backend-warnings.js +44 -0
- package/build/claude-settings.js +129 -0
- package/build/commands.generated.js +7 -6
- package/build/conductor/bridge-api-client.js +198 -18
- package/build/conductor/claude-hook.js +22 -4
- package/build/conductor/cli.js +76 -25
- package/build/conductor/deny-enforcement-preflight.js +96 -0
- package/build/conductor/doctor.js +183 -2
- package/build/conductor/done-gate.js +5 -0
- package/build/conductor/epic-reconcile.js +71 -14
- package/build/conductor/epic-runtime.js +839 -67
- package/build/conductor/epic-state.js +524 -63
- package/build/conductor/errors.js +156 -3
- package/build/conductor/event-accessors.js +252 -0
- package/build/conductor/file-scope-guard.js +201 -0
- package/build/conductor/github-mergeability.js +85 -0
- package/build/conductor/local-merge.js +47 -1
- package/build/conductor/merge-identity.js +41 -0
- package/build/conductor/merge-ledger.js +19 -72
- package/build/conductor/plan.js +12 -2
- package/build/conductor/pr-ci-producer.js +17 -2
- package/build/conductor/pr-discovery.js +11 -1
- package/build/conductor/producer-ledger.js +1 -1
- package/build/conductor/store.js +161 -18
- package/build/conductor/supervisor-config.js +4 -39
- package/build/conductor/supervisor-escalation.js +10 -26
- package/build/conductor/supervisor-ledger.js +5 -12
- package/build/conductor/supervisor-merge.js +32 -5
- package/build/conductor/supervisor-message-relay.js +2 -5
- package/build/conductor/supervisor-notification.js +1 -1
- package/build/conductor/supervisor-runtime.js +12 -54
- package/build/conductor/supervisor-state.js +4 -18
- package/build/conductor/supervisor-types.js +2 -2
- package/build/conductor/taxonomy.js +12 -0
- package/build/conductor/tools.js +28 -6
- package/build/conductor/worker-ledger-cli.js +244 -0
- package/build/conductor-bin.js +1800 -5166
- package/build/conductor-claude-hook-bin.js +4 -2
- package/build/doctor.js +40 -0
- package/build/executor/cli.js +229 -0
- package/build/executor/credentials.js +65 -0
- package/build/executor/deps.js +117 -0
- package/build/executor/env.js +79 -0
- package/build/executor/heartbeat.js +59 -0
- package/build/executor/http-client.js +131 -0
- package/build/executor/index.js +10 -0
- package/build/executor/job-errors.js +55 -0
- package/build/executor/job-log-registry.js +110 -0
- package/build/executor/job-runner.js +688 -0
- package/build/executor/job-types.js +60 -0
- package/build/executor/merge-job.js +155 -0
- package/build/executor/observation.js +123 -0
- package/build/executor/permissions.js +79 -0
- package/build/executor/preflight.js +144 -0
- package/build/executor/process.js +81 -0
- package/build/executor/prompt-spec.js +235 -0
- package/build/executor/results.js +134 -0
- package/build/executor/resume-pre-spawn.js +179 -0
- package/build/executor/runner.js +98 -0
- package/build/executor/terminal-mutation.js +34 -0
- package/build/executor/test-clock.js +109 -0
- package/build/executor/types.js +18 -0
- package/build/executor/verdict-artifact.js +53 -0
- package/build/executor/viewer-tabs.js +78 -0
- package/build/executor/watch-cli.js +113 -0
- package/build/executor/worker-command.js +106 -0
- package/build/executor/worker-finalization.js +97 -0
- package/build/executor/worker-log.js +92 -0
- package/build/executor/worktree-gc.js +134 -0
- package/build/executor/worktree-inspection.js +86 -0
- package/build/executor/worktree.js +103 -0
- package/build/index.js +13950 -9669
- package/build/install-bridge.js +25 -8
- package/build/install-doctor.js +387 -0
- package/build/mcp-invoke.js +19 -3
- package/build/mcp-provisioning.js +31 -25
- package/build/mcp-registration-doctor.js +27 -7
- package/build/mcp-server-invocation.js +152 -0
- package/build/pipelines.generated.js +31 -6
- package/build/readme.generated.js +1 -1
- package/build/regression-check.js +53 -1
- package/build/review-tickets.js +175 -21
- package/build/sfcc/reads-site-preference.js +52 -19
- package/build/start-tickets-conductor.js +47 -99
- package/build/start-tickets-prereqs.js +185 -4
- package/build/start-tickets.js +218 -180
- package/build/version.generated.js +1 -1
- package/build/visual-diff-worker.js +313 -0
- package/build/visual-diff.js +632 -0
- package/build/worktree-core.js +202 -0
- package/package.json +10 -6
- package/pipelines/review-ticket.json +24 -2
- package/public/css/main.min.css +3311 -1
- package/public/css/main.min.css.map +1 -1
- package/public/js/main.min.js +7924 -1
- package/public/js/main.min.js.map +1 -1
- package/smoke-test/SMOKE-TEST.md +5 -2
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Shared helper for surfacing non-blocking backend warnings (BAPI-545) as
|
|
2
|
+
// user-visible MCP tool text. The Tier-4 ticket-text routes (PRD, FSD,
|
|
3
|
+
// clarifying questions, ticket critique, ticket review, create_doc) attach a
|
|
4
|
+
// disclosure to their JSON response body when no VCS connection exists but
|
|
5
|
+
// still succeed — this never changes tool success/failure status, it only
|
|
6
|
+
// appends non-blocking text.
|
|
7
|
+
// Extracts warning strings from a parsed backend JSON response. Accepts the
|
|
8
|
+
// real backend shape (a singular `warning: string | null` field, as used by
|
|
9
|
+
// the Tier-4 trigger endpoints' MessageResponse) and, defensively, a
|
|
10
|
+
// `warnings` array of strings or `{ message: string }` objects (in case a
|
|
11
|
+
// future backend response adopts the list shape instead). Invalid/empty
|
|
12
|
+
// values are ignored; never throws.
|
|
13
|
+
export function extractBackendWarnings(body) {
|
|
14
|
+
if (body === null || typeof body !== "object") {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
const record = body;
|
|
18
|
+
const warnings = [];
|
|
19
|
+
if (typeof record.warning === "string" && record.warning) {
|
|
20
|
+
warnings.push(record.warning);
|
|
21
|
+
}
|
|
22
|
+
if (Array.isArray(record.warnings)) {
|
|
23
|
+
for (const entry of record.warnings) {
|
|
24
|
+
if (typeof entry === "string" && entry) {
|
|
25
|
+
warnings.push(entry);
|
|
26
|
+
}
|
|
27
|
+
else if (entry !== null &&
|
|
28
|
+
typeof entry === "object" &&
|
|
29
|
+
typeof entry.message === "string" &&
|
|
30
|
+
entry.message) {
|
|
31
|
+
warnings.push(entry.message);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return warnings;
|
|
36
|
+
}
|
|
37
|
+
// Appends a non-blocking warning section to existing tool output text.
|
|
38
|
+
// Returns `text` unchanged (byte-for-byte) when `warnings` is empty.
|
|
39
|
+
export function appendBackendWarningsToText(text, warnings) {
|
|
40
|
+
if (!warnings.length) {
|
|
41
|
+
return text;
|
|
42
|
+
}
|
|
43
|
+
return `${text}\n\n**Warning:** ${warnings.join(" ")}`;
|
|
44
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic, conductor-independent `.claude/settings.local.json` merge machinery
|
|
3
|
+
* (BAPI-534).
|
|
4
|
+
*
|
|
5
|
+
* Extracted from `start-tickets-conductor.ts` so both the conductor hook
|
|
6
|
+
* provisioning and the Epic Conductor v2 executor deny-layer provisioning share
|
|
7
|
+
* ONE malformed-safe read/merge/write implementation. `start-tickets-conductor.ts`
|
|
8
|
+
* re-implements `mergeClaudeSettingsWithConductorHook` /
|
|
9
|
+
* `provisionConductorHookForWorktree` as thin wrappers over these helpers,
|
|
10
|
+
* preserving their exported signatures and pinned behavior.
|
|
11
|
+
*
|
|
12
|
+
* Discipline preserved verbatim from the original:
|
|
13
|
+
* - a missing settings file is treated as `{}`;
|
|
14
|
+
* - a malformed / non-object settings file is NEVER clobbered (returns a
|
|
15
|
+
* `malformed` result and does not write);
|
|
16
|
+
* - the merged object is written pretty-printed (2-space indent) with a single
|
|
17
|
+
* trailing newline;
|
|
18
|
+
* - error strings are generic and never echo file contents.
|
|
19
|
+
*/
|
|
20
|
+
import path from "node:path";
|
|
21
|
+
/** Broad matcher used for `PreToolUse` when no existing matcher is present. */
|
|
22
|
+
export const DEFAULT_PRE_TOOL_USE_MATCHER = "*";
|
|
23
|
+
function asHookEntries(value) {
|
|
24
|
+
return Array.isArray(value) ? value : [];
|
|
25
|
+
}
|
|
26
|
+
/** Does this event already register `command` as a command hook? */
|
|
27
|
+
function entriesContainCommand(entries, command) {
|
|
28
|
+
return entries.some((entry) => Array.isArray(entry?.hooks) &&
|
|
29
|
+
entry.hooks.some((h) => h && h.type === "command" && h.command === command));
|
|
30
|
+
}
|
|
31
|
+
/** Detect an existing PreToolUse matcher to mirror, if any. */
|
|
32
|
+
export function detectExistingPreToolUseMatcher(settings) {
|
|
33
|
+
const hooks = settings.hooks;
|
|
34
|
+
if (hooks === null || typeof hooks !== "object" || Array.isArray(hooks))
|
|
35
|
+
return undefined;
|
|
36
|
+
const entries = asHookEntries(hooks.PreToolUse);
|
|
37
|
+
for (const entry of entries) {
|
|
38
|
+
if (typeof entry?.matcher === "string")
|
|
39
|
+
return entry.matcher;
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Merge a command hook into an existing Claude settings object across `events`
|
|
45
|
+
* (plus `PreToolUse` when `enablePreToolUse` is true) WITHOUT removing any
|
|
46
|
+
* existing settings or hooks. Idempotent: re-applying the same command never
|
|
47
|
+
* duplicates an entry. `PreToolUse` mirrors any existing matcher style.
|
|
48
|
+
*/
|
|
49
|
+
export function mergeClaudeSettingsWithCommandHook(settings, command, events, options = {}) {
|
|
50
|
+
const existingHooks = settings.hooks !== null && typeof settings.hooks === "object" && !Array.isArray(settings.hooks)
|
|
51
|
+
? settings.hooks
|
|
52
|
+
: {};
|
|
53
|
+
const hooks = { ...existingHooks };
|
|
54
|
+
const allEvents = [...events];
|
|
55
|
+
if (options.enablePreToolUse && !allEvents.includes("PreToolUse")) {
|
|
56
|
+
allEvents.push("PreToolUse");
|
|
57
|
+
}
|
|
58
|
+
for (const event of allEvents) {
|
|
59
|
+
const entries = asHookEntries(hooks[event]);
|
|
60
|
+
if (entriesContainCommand(entries, command)) {
|
|
61
|
+
// Idempotent: already registered for this event.
|
|
62
|
+
hooks[event] = entries;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const newEntry = { hooks: [{ type: "command", command }] };
|
|
66
|
+
if (event === "PreToolUse") {
|
|
67
|
+
// Explicit matcher wins; else mirror any existing PreToolUse matcher; else
|
|
68
|
+
// fall back to the broad default.
|
|
69
|
+
newEntry.matcher =
|
|
70
|
+
options.preToolUseMatcher ??
|
|
71
|
+
detectExistingPreToolUseMatcher(settings) ??
|
|
72
|
+
DEFAULT_PRE_TOOL_USE_MATCHER;
|
|
73
|
+
}
|
|
74
|
+
hooks[event] = [...entries, newEntry];
|
|
75
|
+
}
|
|
76
|
+
return { ...settings, hooks };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Provision (merge into) ONE worktree's `.claude/settings.local.json`. Missing
|
|
80
|
+
* settings are treated as `{}`; malformed JSON is a safety stop (the file is
|
|
81
|
+
* never overwritten). `mergeSettings` receives the parsed existing object (or
|
|
82
|
+
* `{}`) and returns the object to write. Writes pretty-printed JSON with a
|
|
83
|
+
* trailing newline.
|
|
84
|
+
*/
|
|
85
|
+
export async function provisionClaudeSettingsForWorktree(worktreePath, mergeSettings, deps) {
|
|
86
|
+
const claudeDir = path.join(worktreePath, ".claude");
|
|
87
|
+
const settingsPath = path.join(claudeDir, "settings.local.json");
|
|
88
|
+
let existing = {};
|
|
89
|
+
let raw = null;
|
|
90
|
+
try {
|
|
91
|
+
raw = await deps.readFile(settingsPath);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Missing file -> treat as empty settings.
|
|
95
|
+
raw = null;
|
|
96
|
+
}
|
|
97
|
+
if (raw !== null) {
|
|
98
|
+
try {
|
|
99
|
+
const parsed = JSON.parse(raw);
|
|
100
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
101
|
+
return {
|
|
102
|
+
ok: false,
|
|
103
|
+
reason: "malformed",
|
|
104
|
+
error: "existing .claude/settings.local.json is not a JSON object",
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
existing = parsed;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Malformed JSON: fail rather than clobber the user's file. The error is
|
|
111
|
+
// generic — it never echoes the file contents.
|
|
112
|
+
return {
|
|
113
|
+
ok: false,
|
|
114
|
+
reason: "malformed",
|
|
115
|
+
error: "existing .claude/settings.local.json contains invalid JSON",
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const merged = mergeSettings(existing);
|
|
120
|
+
try {
|
|
121
|
+
await deps.mkdir(claudeDir, { recursive: true });
|
|
122
|
+
await deps.writeFile(settingsPath, `${JSON.stringify(merged, null, 2)}\n`);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// Best-effort: a write/mkdir failure must not block the actual work.
|
|
126
|
+
return { ok: false, reason: "io", error: "failed to write .claude/settings.local.json" };
|
|
127
|
+
}
|
|
128
|
+
return { ok: true };
|
|
129
|
+
}
|