@bridge_gpt/mcp-server 0.2.57 → 0.2.59
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 +112 -113
- package/build/agent-registry.js +15 -0
- package/build/agent-utils.js +16 -8
- package/build/claude-user-config-doctor.js +1 -35
- package/build/codex-bridge-profile.js +5 -1
- package/build/codex-launch-scope.js +13 -2
- package/build/commands.generated.js +5 -6
- package/build/conductor/bridge-api-client.js +149 -0
- package/build/conductor/bring-up-facts.js +1 -1
- package/build/conductor/claude-hook.js +16 -16
- package/build/conductor/doctor.js +24 -19
- package/build/conductor/epic-implementer-cli.js +38 -5
- package/build/conductor/epic-reconcile.js +1 -1
- package/build/conductor/epic-runtime.js +10 -10
- package/build/conductor/errors.js +3 -3
- package/build/conductor/file-scope-guard.js +4 -4
- package/build/conductor/git-ci-types.js +1 -1
- package/build/conductor/git-inspection.js +2 -2
- package/build/conductor/install-doctor.js +6 -6
- package/build/conductor/merge-ledger.js +2 -2
- package/build/conductor/pr-ci-producer.js +6 -6
- package/build/conductor/pr-review-producer.js +2 -2
- package/build/conductor/producer-ledger.js +2 -0
- package/build/conductor/readiness-sections.js +7 -7
- package/build/conductor/readiness.js +2 -2
- package/build/conductor/recovery-cli.js +243 -12
- package/build/conductor/recovery-operations.js +56 -4
- package/build/conductor/repair-contract.js +38 -4
- package/build/conductor/spec-review-producer.js +6 -6
- package/build/conductor/store.js +10 -10
- package/build/conductor/supervisor-config.js +14 -14
- package/build/conductor/supervisor-ledger.js +2 -2
- package/build/conductor/supervisor-message-relay.js +2 -2
- package/build/conductor/worker-ledger-cli.js +19 -19
- package/build/conductor-bundle-artifacts.js +2 -2
- package/build/cursor-agent-progress.js +72 -0
- package/build/doctor.js +20 -296
- package/build/drive-epic.js +65 -71
- package/build/epic-implementer-bin.js +22 -17
- package/build/epic-implementer-claude-hook-bin.js +4 -2
- package/build/epic-implementer-env.js +155 -0
- package/build/epic-integration-pr.js +2 -2
- package/build/epic-shared/bridge-client.js +773 -0
- package/build/epic-shared/cut-protocol.js +392 -0
- package/build/executor/env.js +19 -8
- package/build/executor/heartbeat.js +1 -1
- package/build/executor/job-errors.js +3 -3
- package/build/executor/job-runner.js +1 -1
- package/build/executor/merge-job.js +35 -3
- package/build/executor/observation.js +1 -1
- package/build/executor/preflight.js +1 -1
- package/build/executor/prompt-spec.js +1 -1
- package/build/executor/reconcile-overlap-job.js +10 -130
- package/build/executor/reconcile-overlap-types.js +1 -1
- package/build/executor/runner.js +1 -1
- package/build/implement-epic/cli.js +1 -1
- package/build/index.js +187 -224
- package/build/init.js +20 -28
- package/build/install-bridge-conductor.js +7 -7
- package/build/install-bridge.js +203 -10
- package/build/install-doctor.js +1 -1
- package/build/mcp-host-entry-adapter.js +6 -0
- package/build/mcp-host-targets.js +2 -0
- package/build/mcp-invoke.js +5 -5
- package/build/mcp-profile.js +2 -2
- package/build/mcp-provisioning.js +2 -2
- package/build/mcp-server-invocation.js +3 -3
- package/build/merge-pull-request.js +15 -0
- package/build/model-routing-host.js +25 -0
- package/build/model-routing-preferences.js +99 -0
- package/build/pipelines.generated.js +11 -11
- package/build/plan-epic-implementer-eligibility.js +215 -0
- package/build/plan-execution-ledger.js +8 -0
- package/build/plane/member-roster.js +5 -5
- package/build/plane/supervisor.js +1 -1
- package/build/plane/types.js +5 -5
- package/build/readiness-check.js +1 -1
- package/build/readme.generated.js +1 -1
- package/build/review-tickets.js +4 -4
- package/build/setup-epic.js +8 -8
- package/build/start-tickets-conductor.js +32 -32
- package/build/start-tickets-prereqs.js +4 -9
- package/build/start-tickets.js +494 -98
- package/build/version.generated.js +3 -3
- package/docs/CONDUCTOR.md +69 -18
- package/docs/install/mcp-tool-integrations.md +2 -1
- package/package.json +2 -2
- package/pipelines/implement-ticket.json +2 -2
- package/pipelines/plan-epic.json +2 -2
- package/pipelines/review-ticket.json +1 -1
package/build/review-tickets.js
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Optionally supports a supervisor-driven epic-dispatch path: when an
|
|
14
14
|
* `EpicDispatchIdentity` is threaded through `ReviewTicketsOptions.epic`, each
|
|
15
|
-
* spawned tab receives an epic-identity env block (
|
|
16
|
-
*
|
|
15
|
+
* spawned tab receives an epic-identity env block (BAPI_EPIC_IMPLEMENTER_EPIC_KEY /
|
|
16
|
+
* BAPI_EPIC_IMPLEMENTER_EPIC_RUN_ID / BAPI_EPIC_IMPLEMENTER_PLAN_VERSION / BAPI_EPIC_IMPLEMENTER_RUN_ID)
|
|
17
17
|
* and dispatch is made idempotent via an injected `claimEpicDispatch` callback.
|
|
18
18
|
* This path is worktree-free and base-branch-free; the human CLI path leaves
|
|
19
19
|
* `epic` unset and retains byte-for-byte identical behavior.
|
|
@@ -518,7 +518,7 @@ export function buildReviewPlanRows(deps, options, agent, status, overrides = {}
|
|
|
518
518
|
if (options.epic) {
|
|
519
519
|
const mint = overrides.mintRunId ?? mintStartTicketsRunId;
|
|
520
520
|
runId = mint([key]);
|
|
521
|
-
const env = { ...buildEpicIdentityEnv(options.epic),
|
|
521
|
+
const env = { ...buildEpicIdentityEnv(options.epic), BAPI_EPIC_IMPLEMENTER_RUN_ID: runId };
|
|
522
522
|
command = injectConductorEnvIntoShellCommand(deps.platform, baseCommand, env);
|
|
523
523
|
}
|
|
524
524
|
return {
|
|
@@ -599,7 +599,7 @@ export async function orchestrateReviewTickets(deps, options, overrides = {}) {
|
|
|
599
599
|
if (options.epic) {
|
|
600
600
|
const mint = overrides.mintRunId ?? mintStartTicketsRunId;
|
|
601
601
|
runId = mint([key]);
|
|
602
|
-
const env = { ...buildEpicIdentityEnv(options.epic),
|
|
602
|
+
const env = { ...buildEpicIdentityEnv(options.epic), BAPI_EPIC_IMPLEMENTER_RUN_ID: runId };
|
|
603
603
|
shellCommand = injectConductorEnvIntoShellCommand(deps.platform, baseShellCommand, env);
|
|
604
604
|
if (options.epic.dispatch_key) {
|
|
605
605
|
if (!overrides.claimEpicDispatch) {
|
package/build/setup-epic.js
CHANGED
|
@@ -89,8 +89,8 @@ import { validateBranchName } from "./base-ref.js";
|
|
|
89
89
|
// typed clients the pilot already has are the v2 path's clients too, so neither
|
|
90
90
|
// conductor can drift on a field name or an endpoint shape. No MCP tool, no
|
|
91
91
|
// input-schema field, and no description changes.
|
|
92
|
-
import { getConfigFieldBaseBranch, getIndexScopeLifecycle, getParseStatus, } from "./
|
|
93
|
-
import { boundScopeLifecycleLabel, createExecFileRunCommand, ensureCommitResolvableLocally, normalizeCommitSha, performExactIndexScopeCut, pollIndexScopeLifecycle, readRemoteBranchHead, runGit, SCOPE_BOOTSTRAP_POLL_INTERVAL_MS, SCOPE_LIFECYCLE_LABELS, } from "./
|
|
92
|
+
import { getConfigFieldBaseBranch, getIndexScopeLifecycle, getParseStatus, } from "./epic-shared/bridge-client.js";
|
|
93
|
+
import { boundScopeLifecycleLabel, createExecFileRunCommand, ensureCommitResolvableLocally, normalizeCommitSha, performExactIndexScopeCut, pollIndexScopeLifecycle, readRemoteBranchHead, runGit, SCOPE_BOOTSTRAP_POLL_INTERVAL_MS, SCOPE_LIFECYCLE_LABELS, } from "./epic-shared/cut-protocol.js";
|
|
94
94
|
import { hashPlan } from "./conductor/plan.js";
|
|
95
95
|
import { BRING_UP_REFUSAL_MESSAGES, firstBringUpRefusal, } from "./conductor/bring-up-facts.js";
|
|
96
96
|
import { MCP_PACKAGE_NAME } from "./mcp-identity.js";
|
|
@@ -111,7 +111,7 @@ export const SETUP_EPIC_UNATTENDED_POSTURE = "unattended";
|
|
|
111
111
|
/**
|
|
112
112
|
* The server's stable error code for an unattended-posture refusal (BAPI-734).
|
|
113
113
|
*
|
|
114
|
-
* Mirrors `api.library.
|
|
114
|
+
* Mirrors `api.library.epic_implementer.unattended_posture.UNATTENDED_POSTURE_REFUSED_CODE`.
|
|
115
115
|
* Matched by EQUALITY on the structured `error_code`, never by searching the
|
|
116
116
|
* message text: the message is prose that may be rewritten, the code is the
|
|
117
117
|
* contract.
|
|
@@ -239,7 +239,7 @@ export function getSetupEpicUsage() {
|
|
|
239
239
|
" 10799; remediate / ci_fix 3599; rebase / smoke 2699;",
|
|
240
240
|
" merge 1799); the server rejects a higher value with a",
|
|
241
241
|
" 422 naming the offending field. Full table:",
|
|
242
|
-
" docs/claude/epic-
|
|
242
|
+
" docs/claude/epic-implementer-v2-operator-runbook.md §4.",
|
|
243
243
|
" --replace-policy Authorize replacing a LIVE run's stored policy with the",
|
|
244
244
|
" policy file, as a complete replacement. Without it, a",
|
|
245
245
|
" divergent policy on a reused run is refused with a",
|
|
@@ -1130,7 +1130,7 @@ export function resolveFeatureBranchSelection(opts, planNodeCount, policyDeclare
|
|
|
1130
1130
|
* refused every unattended run, its own named remedy included.
|
|
1131
1131
|
*
|
|
1132
1132
|
* The reason CODES are the server's bounded vocabulary, spelled exactly as
|
|
1133
|
-
* `api/library/
|
|
1133
|
+
* `api/library/epic_implementer/unattended_posture.py` spells them. The client adds
|
|
1134
1134
|
* remediation TEXT around them and invents no aliases — an alias would drift from
|
|
1135
1135
|
* the server's refusal the first time either side was edited, and an operator
|
|
1136
1136
|
* comparing a CLI message with an API response would have no way to tell they
|
|
@@ -1145,7 +1145,7 @@ export function resolveFeatureBranchSelection(opts, planNodeCount, policyDeclare
|
|
|
1145
1145
|
* Does this policy declare a notify webhook the server would probe?
|
|
1146
1146
|
*
|
|
1147
1147
|
* BAPI-1102. The shape check mirrors `_extract_webhook_url` in
|
|
1148
|
-
* `api/library/
|
|
1148
|
+
* `api/library/epic_implementer/webhook_verification.py` exactly as far as
|
|
1149
1149
|
* PRESENCE goes — a `notify` object carrying a non-blank string `webhook_url` —
|
|
1150
1150
|
* and stops there on purpose. Scheme, host, and reachability are the server's to
|
|
1151
1151
|
* judge at activation, where the probe actually happens; re-deciding them here
|
|
@@ -1492,7 +1492,7 @@ export const SETUP_EPIC_SCOPE_RECOVERY_COMMAND = "re-run this same setup-epic co
|
|
|
1492
1492
|
* The canonical one-line recovery for a scope collision (BAPI-1009).
|
|
1493
1493
|
*
|
|
1494
1494
|
* Repeated VERBATIM as the epic-run gate snapshot's shadow-hold recovery hint
|
|
1495
|
-
* (``api/library/
|
|
1495
|
+
* (``api/library/epic_implementer/gate_snapshot_service.py``), so an operator who
|
|
1496
1496
|
* reads the diagnosis on the status surface and an operator who reads it from
|
|
1497
1497
|
* the CLI are told to do the same thing in the same words.
|
|
1498
1498
|
*/
|
|
@@ -2256,7 +2256,7 @@ async function executeSetupEpic(argv, overrides, runIdSink) {
|
|
|
2256
2256
|
: ` - feature branch: ${effectiveFeatureBranch} (validated server-side at approval; no request made in dry-run)`);
|
|
2257
2257
|
if (needsCut && cutCommitSha !== null && scopeBaseBranch !== null) {
|
|
2258
2258
|
say(` - would open a draft pull request ${effectiveFeatureBranch} → ${scopeBaseBranch} ` +
|
|
2259
|
-
"for
|
|
2259
|
+
"for epic-implementer-ci / gate (BAPI-951; nothing opened in dry-run)");
|
|
2260
2260
|
}
|
|
2261
2261
|
}
|
|
2262
2262
|
if (opts.reviewPolicy !== undefined) {
|
|
@@ -62,20 +62,20 @@ export function mintStartTicketsWorkerId(ticketKey, agentName, fragment = random
|
|
|
62
62
|
*/
|
|
63
63
|
export function buildEpicIdentityEnv(epic) {
|
|
64
64
|
const env = {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
BAPI_EPIC_IMPLEMENTER_EPIC_KEY: epic.epic_key,
|
|
66
|
+
BAPI_EPIC_IMPLEMENTER_EPIC_RUN_ID: epic.epic_run_id,
|
|
67
|
+
BAPI_EPIC_IMPLEMENTER_PLAN_VERSION: String(epic.plan_version),
|
|
68
68
|
};
|
|
69
69
|
const declared = normalizeDeclaredTouchedFiles(epic.declared_touched_files);
|
|
70
70
|
if (declared.length > 0) {
|
|
71
|
-
env.
|
|
71
|
+
env.BAPI_EPIC_IMPLEMENTER_DECLARED_TOUCHED_FILES_JSON = JSON.stringify(declared);
|
|
72
72
|
}
|
|
73
73
|
return env;
|
|
74
74
|
}
|
|
75
75
|
// ---------------------------------------------------------------------------
|
|
76
76
|
// Conductor context
|
|
77
77
|
// ---------------------------------------------------------------------------
|
|
78
|
-
/** Default gate name when no `
|
|
78
|
+
/** Default gate name when no `BAPI_EPIC_IMPLEMENTER_GATE_NAME` override is present. */
|
|
79
79
|
export const DEFAULT_CONDUCTOR_GATE_NAME = "implement-ticket";
|
|
80
80
|
/**
|
|
81
81
|
* Resolve a packaged build artifact path relative to this compiled module.
|
|
@@ -110,11 +110,11 @@ export async function createStartTicketsConductorContext(options, agent, deps) {
|
|
|
110
110
|
// Repo resolution must never abort conductor setup; fall back to null.
|
|
111
111
|
repoName = null;
|
|
112
112
|
}
|
|
113
|
-
const gateName = nonEmpty(deps.env.
|
|
114
|
-
? deps.env.
|
|
113
|
+
const gateName = nonEmpty(deps.env.BAPI_EPIC_IMPLEMENTER_GATE_NAME)
|
|
114
|
+
? deps.env.BAPI_EPIC_IMPLEMENTER_GATE_NAME.trim()
|
|
115
115
|
: DEFAULT_CONDUCTOR_GATE_NAME;
|
|
116
|
-
const supervisorMode = nonEmpty(deps.env.
|
|
117
|
-
? deps.env.
|
|
116
|
+
const supervisorMode = nonEmpty(deps.env.BAPI_EPIC_IMPLEMENTER_SUPERVISOR_MODE)
|
|
117
|
+
? deps.env.BAPI_EPIC_IMPLEMENTER_SUPERVISOR_MODE.trim()
|
|
118
118
|
: options.autoApprove
|
|
119
119
|
? "auto"
|
|
120
120
|
: "interactive";
|
|
@@ -142,12 +142,12 @@ export async function createStartTicketsConductorContext(options, agent, deps) {
|
|
|
142
142
|
// ---------------------------------------------------------------------------
|
|
143
143
|
/** Conductor store-tuning env keys forwarded only when already set upstream. */
|
|
144
144
|
const CONDUCTOR_TUNING_ENV_KEYS = [
|
|
145
|
-
"
|
|
146
|
-
"
|
|
147
|
-
"
|
|
145
|
+
"BAPI_EPIC_IMPLEMENTER_BUSY_TIMEOUT_MS",
|
|
146
|
+
"BAPI_EPIC_IMPLEMENTER_RETENTION_DAYS",
|
|
147
|
+
"BAPI_EPIC_IMPLEMENTER_RETENTION_MAX_ROWS",
|
|
148
148
|
// BAPI-397: per-type relay cooldown — forwarded only when explicitly set so
|
|
149
149
|
// the supervisor's send config is honoured by the conductor store it writes to.
|
|
150
|
-
"
|
|
150
|
+
"BAPI_EPIC_IMPLEMENTER_MESSAGE_COOLDOWN_MS",
|
|
151
151
|
];
|
|
152
152
|
/** Truthy predicate for opt-in conductor boolean flags (`1` / `true`). */
|
|
153
153
|
export function isConductorFlagEnabled(value) {
|
|
@@ -164,30 +164,30 @@ export function isConductorFlagEnabled(value) {
|
|
|
164
164
|
* upstream.
|
|
165
165
|
*/
|
|
166
166
|
export function buildConductorWorkerEnv(context, worker, parentEnv) {
|
|
167
|
-
// Merge "
|
|
167
|
+
// Merge "epic_implementer" into the parent project's profile rather than overwriting it.
|
|
168
168
|
// This preserves groups like "sfcc" that the project already has, while adding
|
|
169
169
|
// the conductor-specific tools. Only validated group tokens from resolveProfiles
|
|
170
170
|
// are threaded — arbitrary parentEnv keys never leak through.
|
|
171
171
|
const parentActiveGroups = new Set(resolveProfiles(parentEnv.BRIDGE_MCP_PROFILE));
|
|
172
|
-
parentActiveGroups.add("
|
|
172
|
+
parentActiveGroups.add("epic_implementer");
|
|
173
173
|
const mergedProfile = Array.from(parentActiveGroups).join(",");
|
|
174
174
|
const env = {
|
|
175
|
-
|
|
175
|
+
BAPI_EPIC_IMPLEMENTER_ENABLED: "1",
|
|
176
176
|
BRIDGE_MCP_PROFILE: mergedProfile,
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
177
|
+
BAPI_EPIC_IMPLEMENTER_RUN_ID: context.runId,
|
|
178
|
+
BAPI_EPIC_IMPLEMENTER_WORKER_ID: worker.workerId,
|
|
179
|
+
BAPI_EPIC_IMPLEMENTER_TICKET_KEY: worker.ticketKey,
|
|
180
|
+
BAPI_EPIC_IMPLEMENTER_WORKTREE_PATH: worker.worktreePath,
|
|
181
|
+
BAPI_EPIC_IMPLEMENTER_GATE_NAME: context.gateName,
|
|
182
|
+
BAPI_EPIC_IMPLEMENTER_SUPERVISOR_MODE: context.supervisorMode,
|
|
183
|
+
BAPI_EPIC_IMPLEMENTER_CLI_FILE: context.cliFile,
|
|
184
184
|
// BAPI-527: the CLI file + Node runtime are a PAIR. The worker runs
|
|
185
185
|
// conductor-bin.js under this captured conductor Node for every worker-side
|
|
186
186
|
// ledger op, so the worker Node never loads better-sqlite3. Non-secret.
|
|
187
|
-
|
|
187
|
+
EPIC_IMPLEMENTER_NODE_PATH: context.conductorNodePath,
|
|
188
188
|
};
|
|
189
189
|
if (context.repoName) {
|
|
190
|
-
env.
|
|
190
|
+
env.BAPI_EPIC_IMPLEMENTER_REPO_NAME = context.repoName;
|
|
191
191
|
}
|
|
192
192
|
if (context.epic) {
|
|
193
193
|
const epicEnv = buildEpicIdentityEnv(context.epic);
|
|
@@ -195,8 +195,8 @@ export function buildConductorWorkerEnv(context, worker, parentEnv) {
|
|
|
195
195
|
env[k] = v;
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
|
-
if (isConductorFlagEnabled(parentEnv.
|
|
199
|
-
env.
|
|
198
|
+
if (isConductorFlagEnabled(parentEnv.BAPI_EPIC_IMPLEMENTER_ENABLE_PRE_TOOL_USE)) {
|
|
199
|
+
env.BAPI_EPIC_IMPLEMENTER_ENABLE_PRE_TOOL_USE = "1";
|
|
200
200
|
}
|
|
201
201
|
for (const key of CONDUCTOR_TUNING_ENV_KEYS) {
|
|
202
202
|
if (nonEmpty(parentEnv[key])) {
|
|
@@ -234,13 +234,13 @@ function shellQuotePath(value) {
|
|
|
234
234
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
235
235
|
}
|
|
236
236
|
/**
|
|
237
|
-
* Resolve the hook command string. Prefers `
|
|
237
|
+
* Resolve the hook command string. Prefers `BAPI_EPIC_IMPLEMENTER_HOOK_COMMAND`
|
|
238
238
|
* verbatim; otherwise runs the packaged hook bin via the current Node
|
|
239
239
|
* executable.
|
|
240
240
|
*/
|
|
241
241
|
export function resolveConductorHookCommand(env, hookBinPath, execPath = process.execPath) {
|
|
242
|
-
if (nonEmpty(env.
|
|
243
|
-
return env.
|
|
242
|
+
if (nonEmpty(env.BAPI_EPIC_IMPLEMENTER_HOOK_COMMAND)) {
|
|
243
|
+
return env.BAPI_EPIC_IMPLEMENTER_HOOK_COMMAND;
|
|
244
244
|
}
|
|
245
245
|
return `${shellQuotePath(execPath)} ${shellQuotePath(hookBinPath)}`;
|
|
246
246
|
}
|
|
@@ -279,7 +279,7 @@ export async function provisionConductorHookForWorktree(worktreePath, command, o
|
|
|
279
279
|
*/
|
|
280
280
|
export async function provisionConductorHooksForRows(rows, context, deps) {
|
|
281
281
|
const isClaude = context.agentName === "claude";
|
|
282
|
-
const enablePreToolUse = isConductorFlagEnabled(deps.env.
|
|
282
|
+
const enablePreToolUse = isConductorFlagEnabled(deps.env.BAPI_EPIC_IMPLEMENTER_ENABLE_PRE_TOOL_USE);
|
|
283
283
|
const command = resolveConductorHookCommand(deps.env, context.hookBinPath, deps.execPath);
|
|
284
284
|
const fragment = deps.workerFragment;
|
|
285
285
|
const out = [];
|
|
@@ -451,7 +451,7 @@ export function buildSupervisorTabCommand(context, platform, nodeExecPath = proc
|
|
|
451
451
|
/**
|
|
452
452
|
* Decide whether the supervisor peer tab should launch. Enabled by default for a
|
|
453
453
|
* normal packaged conductor context; disabled only when the resolved supervisor
|
|
454
|
-
* mode is `off` (i.e. `
|
|
454
|
+
* mode is `off` (i.e. `BAPI_EPIC_IMPLEMENTER_SUPERVISOR_MODE=off`).
|
|
455
455
|
*/
|
|
456
456
|
export function isSupervisorLaunchEnabled(context) {
|
|
457
457
|
return context.supervisorMode.trim().toLowerCase() !== "off";
|
|
@@ -52,7 +52,7 @@ export const START_TICKETS_DOCTOR_COMMAND = `npx -y ${MCP_PACKAGE_NAME} doctor`;
|
|
|
52
52
|
/**
|
|
53
53
|
* BAPI-527 live-source checkout guard (conductor durable execution).
|
|
54
54
|
*
|
|
55
|
-
* `
|
|
55
|
+
* `BAPI_EPIC_IMPLEMENTER_LIVE_SOURCE_PATH` — OPTIONAL operator-set path to the checkout
|
|
56
56
|
* an operator's live dev server (e.g. `uvicorn main:app --reload`) is running
|
|
57
57
|
* from. When set, unattended conductor/epic/non-mutating start-tickets dispatch
|
|
58
58
|
* refuses to run if the conductor base repo it would operate on resolves to the
|
|
@@ -62,14 +62,14 @@ export const START_TICKETS_DOCTOR_COMMAND = `npx -y ${MCP_PACKAGE_NAME} doctor`;
|
|
|
62
62
|
* discovery, so this local env contract is introduced here. Read only from the
|
|
63
63
|
* injected `deps.env` (never global `process.env`) so it stays mockable.
|
|
64
64
|
*
|
|
65
|
-
* `
|
|
65
|
+
* `BAPI_EPIC_IMPLEMENTER_ALLOW_LIVE_SOURCE_DISPATCH` — explicit escape hatch. When set
|
|
66
66
|
* to a truthy value (`1`/`true`/`yes`/`on`, case-insensitive) a detected
|
|
67
67
|
* collision is DOWNGRADED from fatal to a loud warning rather than silently
|
|
68
68
|
* ignored, so an operator who genuinely wants same-checkout dispatch can opt in
|
|
69
69
|
* with eyes open.
|
|
70
70
|
*/
|
|
71
|
-
export const CONDUCTOR_LIVE_SOURCE_PATH_ENV = "
|
|
72
|
-
export const CONDUCTOR_ALLOW_LIVE_SOURCE_DISPATCH_ENV = "
|
|
71
|
+
export const CONDUCTOR_LIVE_SOURCE_PATH_ENV = "BAPI_EPIC_IMPLEMENTER_LIVE_SOURCE_PATH";
|
|
72
|
+
export const CONDUCTOR_ALLOW_LIVE_SOURCE_DISPATCH_ENV = "BAPI_EPIC_IMPLEMENTER_ALLOW_LIVE_SOURCE_DISPATCH";
|
|
73
73
|
/** Stable descriptor id for the live-source checkout guard (used in messages + doctor). */
|
|
74
74
|
export const LIVE_SOURCE_GUARD_ID = "conductor-live-source";
|
|
75
75
|
/** True only for the three first-class supported platforms. */
|
|
@@ -566,11 +566,6 @@ const CLAUDE_MCP_SHADOWING_INSTALL_HINTS = {
|
|
|
566
566
|
* - a CONFIRMED foreign registration → `found: true` + advisory detail
|
|
567
567
|
* - unreadable / malformed config, or an unresolved main
|
|
568
568
|
* worktree path → `found: true` + detail
|
|
569
|
-
*
|
|
570
|
-
* Reporting stays deliberately independent of the retired
|
|
571
|
-
* `BAPI_CONDUCTOR_ALLOW_CLAUDE_MCP_SHADOWING` override: whether that variable is
|
|
572
|
-
* exported has never had any bearing on whether the collision exists, and now it
|
|
573
|
-
* has no bearing on anything at all.
|
|
574
569
|
*/
|
|
575
570
|
export function claudeMcpShadowingDescriptor() {
|
|
576
571
|
return {
|