@bridge_gpt/mcp-server 0.2.21 → 0.2.23
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 +86 -27
- package/README.md +80 -6
- package/build/base-ref.js +151 -0
- package/build/commands.generated.js +5 -3
- package/build/conductor/bridge-api-client.js +44 -3
- package/build/conductor/doctor.js +33 -22
- package/build/conductor/epic-runtime.js +101 -5
- package/build/conductor/pr-ci-producer.js +21 -2
- package/build/conductor/pr-discovery.js +12 -2
- package/build/conductor-bin.js +50 -20
- package/build/credential-store.js +564 -64
- package/build/executor/base-branch.js +50 -0
- package/build/executor/env.js +12 -1
- package/build/executor/job-errors.js +1 -0
- package/build/executor/job-runner.js +38 -7
- package/build/executor/test-clock.js +6 -1
- package/build/executor/worker-finalization.js +88 -1
- package/build/executor/worktree.js +21 -1
- package/build/index.js +1979 -423
- package/build/install-bridge.js +627 -69
- package/build/pipelines.generated.js +2 -2
- package/build/pr-base-contract.js +36 -0
- package/build/readme.generated.js +1 -1
- package/build/setup-epic.js +483 -0
- package/build/start-tickets.js +164 -75
- package/build/version.generated.js +1 -1
- package/build/worktree-core.js +62 -10
- package/package.json +3 -3
- package/public/js/main.min.js +9 -9
- package/public/js/main.min.js.map +1 -1
package/build/start-tickets.js
CHANGED
|
@@ -71,6 +71,7 @@ import { WORKTRUNK_BINARY_OVERRIDE_ENV, WINDOWS_TERMINAL_COMMAND, WINDOWS_POWERS
|
|
|
71
71
|
import { DEFAULT_AGENT_NAME, resolveAgentSpec, isAgentName, formatValidAgentNames, resolveModelAlias, isValidModelAlias, isModelTier, } from "./agent-registry.js";
|
|
72
72
|
import { createStartTicketsConductorContext, provisionConductorHooksForRows, emitStartTicketsRunStarted, injectConductorEnvIntoShellCommand, buildSupervisorTabCommand, isSupervisorLaunchEnabled, supervisorSpawnKey, } from "./start-tickets-conductor.js";
|
|
73
73
|
import { transitionEpicDispatch, resolveConductorBridgeApiAccess, } from "./conductor/bridge-api-client.js";
|
|
74
|
+
import { PR_BASE_BRANCH_ENV_VAR, buildPrBaseContractLaunchInstruction, } from "./pr-base-contract.js";
|
|
74
75
|
// Re-export the shared prereq surface (constants, platform helpers, command
|
|
75
76
|
// probes) so existing import sites that read them from "./start-tickets.js"
|
|
76
77
|
// keep working unchanged.
|
|
@@ -101,6 +102,8 @@ export function getStartTicketsUsage() {
|
|
|
101
102
|
"",
|
|
102
103
|
"Flags:",
|
|
103
104
|
" --agent claude|cursor-agent Agent command to launch in each worktree (default: claude)",
|
|
105
|
+
" --workflow implement|review-and-implement Slash command each spawned worktree runs (default: implement). review-and-implement runs /review-ticket then, after a per-ticket halt gate, /implement-ticket in the same session; --auto applies to the selected workflow.",
|
|
106
|
+
" --rounds 1|2 Review round count forwarded to the review phase; review-only, valid only with --workflow review-and-implement",
|
|
104
107
|
" --terminal terminal|iterm Override the macOS terminal app (default: auto-detect via $TERM_PROGRAM); honored on macOS only",
|
|
105
108
|
" --dry-run Print intended actions; creates no worktrees and opens no tabs, but DOES resolve model routing read-only (may compute+cache a ticket's difficulty) to preview the --model each tab would use",
|
|
106
109
|
" --branch KEY=BRANCH Use BRANCH instead of feature/KEY for that ticket (repeatable)",
|
|
@@ -151,6 +154,8 @@ export function parseStartTicketsArgs(argv) {
|
|
|
151
154
|
let agentName = DEFAULT_AGENT_NAME;
|
|
152
155
|
let baseBranch = "main";
|
|
153
156
|
let conductorEnabled = false;
|
|
157
|
+
let workflow = "implement";
|
|
158
|
+
let reviewRoundsRaw;
|
|
154
159
|
const branchEntries = [];
|
|
155
160
|
const keys = [];
|
|
156
161
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -183,6 +188,49 @@ export function parseStartTicketsArgs(argv) {
|
|
|
183
188
|
agentName = value;
|
|
184
189
|
continue;
|
|
185
190
|
}
|
|
191
|
+
if (arg === "--workflow" || arg.startsWith("--workflow=")) {
|
|
192
|
+
let value;
|
|
193
|
+
if (arg.startsWith("--workflow=")) {
|
|
194
|
+
value = arg.slice("--workflow=".length);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
value = takeValue();
|
|
198
|
+
if (value === undefined) {
|
|
199
|
+
return {
|
|
200
|
+
status: "error",
|
|
201
|
+
message: "--workflow requires a value (allowed values: implement, review-and-implement).",
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (value !== "implement" && value !== "review-and-implement") {
|
|
206
|
+
return {
|
|
207
|
+
status: "error",
|
|
208
|
+
message: `Invalid --workflow value: '${value}' (allowed values: implement, review-and-implement).`,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
workflow = value;
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (arg === "--rounds" || arg.startsWith("--rounds=")) {
|
|
215
|
+
let value;
|
|
216
|
+
if (arg.startsWith("--rounds=")) {
|
|
217
|
+
value = arg.slice("--rounds=".length);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
value = takeValue();
|
|
221
|
+
if (value === undefined) {
|
|
222
|
+
return { status: "error", message: "--rounds requires a value (allowed values: 1, 2)." };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (value !== "1" && value !== "2") {
|
|
226
|
+
return {
|
|
227
|
+
status: "error",
|
|
228
|
+
message: `Invalid --rounds value: '${value}' (allowed values: 1, 2).`,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
reviewRoundsRaw = value;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
186
234
|
if (arg === "--terminal" || arg.startsWith("--terminal=")) {
|
|
187
235
|
let value;
|
|
188
236
|
if (arg.startsWith("--terminal=")) {
|
|
@@ -337,29 +385,38 @@ export function parseStartTicketsArgs(argv) {
|
|
|
337
385
|
}
|
|
338
386
|
branchOverrides[overrideKey] = branchName;
|
|
339
387
|
}
|
|
388
|
+
// --- rounds validation: review-only, checked after the full argument scan
|
|
389
|
+
// so flag order (e.g. --rounds before --workflow) never affects validation.
|
|
390
|
+
let reviewRounds;
|
|
391
|
+
if (reviewRoundsRaw !== undefined) {
|
|
392
|
+
if (workflow !== "review-and-implement") {
|
|
393
|
+
return {
|
|
394
|
+
status: "error",
|
|
395
|
+
message: "--rounds is only valid with --workflow review-and-implement.",
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
reviewRounds = reviewRoundsRaw === "1" ? 1 : 2;
|
|
399
|
+
}
|
|
340
400
|
return {
|
|
341
401
|
status: "ok",
|
|
342
|
-
options: {
|
|
402
|
+
options: {
|
|
403
|
+
keys,
|
|
404
|
+
terminal,
|
|
405
|
+
dryRun,
|
|
406
|
+
autoApprove,
|
|
407
|
+
refreshMain,
|
|
408
|
+
maxParallel,
|
|
409
|
+
branchOverrides,
|
|
410
|
+
agentName,
|
|
411
|
+
baseBranch,
|
|
412
|
+
conductorEnabled,
|
|
413
|
+
workflow,
|
|
414
|
+
reviewRounds,
|
|
415
|
+
},
|
|
343
416
|
};
|
|
344
417
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
if (branch.trim().length === 0)
|
|
348
|
-
return "branch name must not be empty.";
|
|
349
|
-
if (branch.length > 255)
|
|
350
|
-
return "branch name must be 255 characters or fewer.";
|
|
351
|
-
if (branch.startsWith("-"))
|
|
352
|
-
return "branch name must not start with '-'.";
|
|
353
|
-
// Reject ASCII control characters (0x00-0x1F and 0x7F) without embedding
|
|
354
|
-
// raw control bytes in source.
|
|
355
|
-
for (let i = 0; i < branch.length; i++) {
|
|
356
|
-
const code = branch.charCodeAt(i);
|
|
357
|
-
if (code <= 0x1f || code === 0x7f) {
|
|
358
|
-
return "branch name must not contain control characters.";
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
return null;
|
|
362
|
-
}
|
|
418
|
+
// `validateBranchName` moved to `base-ref.ts` (BAPI-586); imported + re-exported
|
|
419
|
+
// above. See the import block near the worktree-core re-exports.
|
|
363
420
|
/**
|
|
364
421
|
* Determine which macOS terminal to drive. An explicit choice wins; otherwise
|
|
365
422
|
* auto-detect iTerm from `$TERM_PROGRAM` (case-insensitive), defaulting to
|
|
@@ -403,19 +460,27 @@ export function getDefaultSpawnTerminalTabForPlatform(platform) {
|
|
|
403
460
|
export function resolveStartTicketsPlatformConfig(deps, agent, autoApprove = false, conductorEnabled = false, repoName = null,
|
|
404
461
|
// BAPI-494: a conductor remediation re-dispatch. Appends the full-suite finalize
|
|
405
462
|
// instruction to the resume-mode worker's prompt.
|
|
406
|
-
resumeMode = false
|
|
463
|
+
resumeMode = false, workflow = "implement", reviewRounds,
|
|
464
|
+
// BAPI-586: the effective run base branch (incl. epic.base_branch override).
|
|
465
|
+
// Injected as BAPI_BASE_BRANCH for conductor workers so their PR targets it,
|
|
466
|
+
// and threaded (BAPI-593) into the spawned workflow command.
|
|
467
|
+
baseBranch) {
|
|
407
468
|
if (!isSupportedStartTicketsPlatform(deps.platform)) {
|
|
408
469
|
return { ok: false, error: unsupportedPlatformMessage(deps.platform) };
|
|
409
470
|
}
|
|
410
471
|
const platform = deps.platform;
|
|
472
|
+
// Only conductor dispatch uses the PR-base contract; interactive dispatch omits
|
|
473
|
+
// the BAPI_BASE_BRANCH assignment so its worker launch is unchanged.
|
|
474
|
+
const prBaseBranch = conductorEnabled ? baseBranch : null;
|
|
411
475
|
return {
|
|
412
476
|
ok: true,
|
|
413
477
|
config: {
|
|
414
478
|
platform,
|
|
415
479
|
worktrunkBinary: resolveWorktrunkBinary(platform, deps.env),
|
|
416
480
|
// Inject the resolved repo identity so the spawned worktree session never
|
|
417
|
-
// falls back to the basename-derived repo name (the 403 root cause)
|
|
418
|
-
|
|
481
|
+
// falls back to the basename-derived repo name (the 403 root cause), and
|
|
482
|
+
// (BAPI-586) the run base so the conductor worker opens its PR against it.
|
|
483
|
+
buildAgentShellCommand: (key, worktreePath, modelAlias) => prependBaseBranchEnvAssignment(prependRepoNameEnvAssignment(buildAgentShellCommand(agent, key, worktreePath, platform, autoApprove, modelAlias, conductorEnabled, resumeMode, workflow, reviewRounds, baseBranch), repoName, platform), prBaseBranch, platform),
|
|
419
484
|
spawnTerminalTab: deps.spawnTerminalTab,
|
|
420
485
|
},
|
|
421
486
|
};
|
|
@@ -445,6 +510,24 @@ export function prependRepoNameEnvAssignment(command, repoName, platform = "darw
|
|
|
445
510
|
}
|
|
446
511
|
return `export BAPI_REPO_NAME='${shSquoteInner(repoName)}' && ${command}`;
|
|
447
512
|
}
|
|
513
|
+
/**
|
|
514
|
+
* BAPI-586: prepend a `BAPI_BASE_BRANCH` environment assignment to a spawned
|
|
515
|
+
* conductor worker's shell command so the worker can open its PR against the run
|
|
516
|
+
* base via `gh pr create --base "$BAPI_BASE_BRANCH"` (paired with the PR-base
|
|
517
|
+
* launch instruction), instead of inferring the repo default branch. Platform
|
|
518
|
+
* correct — `$env:VAR = '…'; …` on PowerShell, `export VAR='…' && …` on POSIX —
|
|
519
|
+
* with the value quoted by the same escaper used for the rest of the command.
|
|
520
|
+
* Fail-open: a null/empty `baseBranch` returns the command unchanged (interactive
|
|
521
|
+
* dispatch does not use the PR-base contract).
|
|
522
|
+
*/
|
|
523
|
+
export function prependBaseBranchEnvAssignment(command, baseBranch, platform = "darwin") {
|
|
524
|
+
if (!baseBranch)
|
|
525
|
+
return command;
|
|
526
|
+
if (platform === "win32") {
|
|
527
|
+
return `$env:${PR_BASE_BRANCH_ENV_VAR} = ${powershellSquote(baseBranch)}; ${command}`;
|
|
528
|
+
}
|
|
529
|
+
return `export ${PR_BASE_BRANCH_ENV_VAR}='${shSquoteInner(baseBranch)}' && ${command}`;
|
|
530
|
+
}
|
|
448
531
|
/**
|
|
449
532
|
* Escape a string for inclusion inside a single-quoted shell context: each
|
|
450
533
|
* embedded single-quote becomes the sequence `'\''`. Returns only the inner
|
|
@@ -725,42 +808,10 @@ export async function refreshBaseBranch(deps, options) {
|
|
|
725
808
|
export async function refreshMainBranch(deps, options) {
|
|
726
809
|
return refreshBaseBranch(deps, { refreshMain: options.refreshMain, baseBranch: "main" });
|
|
727
810
|
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
* `git merge --ff-only`, no `git branch --force`). Used by review-grounding
|
|
733
|
-
* (BAPI-474), which must read a pinned base tree without touching the user's
|
|
734
|
-
* working tree, index, stash, or local branch refs.
|
|
735
|
-
*
|
|
736
|
-
* Validates `baseBranch` with {@link validateBranchName} first so an
|
|
737
|
-
* injection-shaped ref name is rejected before any git invocation. Every git
|
|
738
|
-
* call uses an argv array (never a shell string), consistent with
|
|
739
|
-
* {@link refreshBaseBranch}.
|
|
740
|
-
*/
|
|
741
|
-
export async function fetchAndResolveBaseSha(deps, baseBranch) {
|
|
742
|
-
const validationError = validateBranchName(baseBranch);
|
|
743
|
-
if (validationError) {
|
|
744
|
-
return { ok: false, error: `Invalid base branch '${baseBranch}': ${validationError}` };
|
|
745
|
-
}
|
|
746
|
-
const fetch = await deps.runCommand("git", ["fetch", "origin", baseBranch], {
|
|
747
|
-
cwd: deps.cwd,
|
|
748
|
-
});
|
|
749
|
-
if (!commandSucceeded(fetch)) {
|
|
750
|
-
return {
|
|
751
|
-
ok: false,
|
|
752
|
-
error: `git fetch origin ${baseBranch} failed. Check your network and 'git remote get-url origin', or pass --no-refresh-base to skip.`,
|
|
753
|
-
};
|
|
754
|
-
}
|
|
755
|
-
const resolve = await deps.runCommand("git", ["rev-parse", "--verify", `origin/${baseBranch}^{commit}`], { cwd: deps.cwd });
|
|
756
|
-
if (!commandSucceeded(resolve)) {
|
|
757
|
-
return {
|
|
758
|
-
ok: false,
|
|
759
|
-
error: `Failed to resolve origin/${baseBranch} to a commit SHA after fetch (git rev-parse --verify failed).`,
|
|
760
|
-
};
|
|
761
|
-
}
|
|
762
|
-
return { ok: true, base_sha: resolve.stdout.trim() };
|
|
763
|
-
}
|
|
811
|
+
// `fetchAndResolveBaseSha` + `FetchAndResolveBaseShaResult` moved to
|
|
812
|
+
// `base-ref.ts` (BAPI-586) and re-exported above. The shared helper now also
|
|
813
|
+
// serializes the fetch per repository via an async mutex so concurrent executor
|
|
814
|
+
// fresh jobs against one clone cannot collide on git lock files.
|
|
764
815
|
// ---------------------------------------------------------------------------
|
|
765
816
|
// Concurrency + worktree creation
|
|
766
817
|
// ---------------------------------------------------------------------------
|
|
@@ -798,6 +849,13 @@ export async function runWithConcurrency(items, limit, worker) {
|
|
|
798
849
|
// same function references.
|
|
799
850
|
import { resolveBranchForTicket, branchExists, buildWtSwitchArgs, pathApiForPlatform, extractWorktreePath, isExistingBranchSafeToReuse, createWorktreeForTicket, } from "./worktree-core.js";
|
|
800
851
|
export { resolveBranchForTicket, branchExists, buildWtSwitchArgs, pathApiForPlatform, extractWorktreePath, isExistingBranchSafeToReuse, createWorktreeForTicket, };
|
|
852
|
+
// BAPI-586: base-ref resolution now lives in the focused `base-ref.ts` module so
|
|
853
|
+
// the executor can depend on it without pulling in this large CLI module. We
|
|
854
|
+
// import the VALUES here (so internal uses keep working) and re-export the same
|
|
855
|
+
// references so existing importers of `./start-tickets.js` (index.ts,
|
|
856
|
+
// review-tickets.ts) and the pinned start-tickets tests are unaffected.
|
|
857
|
+
import { validateBranchName, fetchAndResolveBaseSha } from "./base-ref.js";
|
|
858
|
+
export { validateBranchName, fetchAndResolveBaseSha };
|
|
801
859
|
/**
|
|
802
860
|
* Create / switch worktrees for every ticket, throttled to `maxParallel`, using
|
|
803
861
|
* the resolved Worktrunk binary. Returns one row per ticket in original key
|
|
@@ -811,7 +869,17 @@ export { resolveBranchForTicket, branchExists, buildWtSwitchArgs, pathApiForPlat
|
|
|
811
869
|
* historical branch-name behavior unchanged.
|
|
812
870
|
*/
|
|
813
871
|
export async function createWorktrees(deps, options, worktrunkBinary, baseStartPoint = options.baseBranch) {
|
|
814
|
-
|
|
872
|
+
// BAPI-586: for guard-enabled Conductor fresh dispatch the caller has already
|
|
873
|
+
// resolved `baseStartPoint` to an immutable base SHA (`nonMutatingBase`). Align
|
|
874
|
+
// any safe pre-existing branch exactly to that SHA and verify the resulting
|
|
875
|
+
// head against it, so a dependent ticket starts at fresh `origin/<base>` rather
|
|
876
|
+
// than at a stale ancestor or a sibling seed. Interactive dispatch (a moving
|
|
877
|
+
// branch name, guard off) keeps the historical reuse-as-is behavior.
|
|
878
|
+
const exactBase = options.guardStaleWorktree === true && options.nonMutatingBase === true;
|
|
879
|
+
const behavior = exactBase
|
|
880
|
+
? { alignExistingBranchTo: baseStartPoint, verifyHeadMatches: baseStartPoint }
|
|
881
|
+
: {};
|
|
882
|
+
return runWithConcurrency(options.keys, options.maxParallel, (key) => createWorktreeForTicket(deps, key, options.branchOverrides, worktrunkBinary, baseStartPoint, options.guardStaleWorktree === true, behavior));
|
|
815
883
|
}
|
|
816
884
|
/**
|
|
817
885
|
* Resume-mode worktree resolution (BAPI-441). Instead of creating worktrees,
|
|
@@ -931,10 +999,26 @@ export function buildAgentPrompt(key, opts = {}) {
|
|
|
931
999
|
// `modelAlias` is accepted for signature consistency only — the model is
|
|
932
1000
|
// injected as a `--model` flag (see buildAgentInvocationArgv), never embedded
|
|
933
1001
|
// in the prompt text.
|
|
934
|
-
const
|
|
1002
|
+
const workflow = opts.workflow ?? "implement";
|
|
1003
|
+
const head = workflow === "review-and-implement" ? "/review-and-implement" : "/implement-ticket";
|
|
1004
|
+
let command = `${head} ${key}${opts.autoApprove ? " --auto" : ""}`;
|
|
1005
|
+
// Review-only arguments (`--rounds`, non-default `--base-branch`) must never
|
|
1006
|
+
// leak into the legacy `/implement-ticket` prompt.
|
|
1007
|
+
if (workflow === "review-and-implement") {
|
|
1008
|
+
if (opts.reviewRounds !== undefined) {
|
|
1009
|
+
command += ` --rounds=${opts.reviewRounds}`;
|
|
1010
|
+
}
|
|
1011
|
+
if (opts.baseBranch !== undefined && opts.baseBranch !== "main") {
|
|
1012
|
+
command += ` --base-branch='${shSquoteInner(opts.baseBranch)}'`;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
935
1015
|
const parts = [command];
|
|
936
|
-
if (opts.conductorEnabled)
|
|
1016
|
+
if (opts.conductorEnabled) {
|
|
937
1017
|
parts.push(buildConductorMessageRelayLaunchInstruction());
|
|
1018
|
+
// BAPI-586: conductor implementation workers must open their PR against the
|
|
1019
|
+
// run base (injected as BAPI_BASE_BRANCH), never the repo default branch.
|
|
1020
|
+
parts.push(buildPrBaseContractLaunchInstruction());
|
|
1021
|
+
}
|
|
938
1022
|
if (opts.resumeMode)
|
|
939
1023
|
parts.push(buildResumeModeRemediationFinalizeInstruction());
|
|
940
1024
|
return parts.join(" ");
|
|
@@ -976,13 +1060,13 @@ export function buildAgentInvocation(agent, prompt, quote, modelAlias) {
|
|
|
976
1060
|
}
|
|
977
1061
|
}
|
|
978
1062
|
/** POSIX agent shell command: `cd '<path>' && <agent> [--model '<alias>'] '<prompt>'`. */
|
|
979
|
-
export function buildPosixAgentShellCommand(agent, key, worktreePath, autoApprove = false, modelAlias, conductorEnabled = false, resumeMode = false) {
|
|
980
|
-
const invocation = buildAgentInvocation(agent, buildAgentPrompt(key, { autoApprove, conductorEnabled, resumeMode }), (p) => `'${shSquoteInner(p)}'`, modelAlias);
|
|
1063
|
+
export function buildPosixAgentShellCommand(agent, key, worktreePath, autoApprove = false, modelAlias, conductorEnabled = false, resumeMode = false, workflow = "implement", reviewRounds, baseBranch) {
|
|
1064
|
+
const invocation = buildAgentInvocation(agent, buildAgentPrompt(key, { autoApprove, conductorEnabled, resumeMode, workflow, reviewRounds, baseBranch }), (p) => `'${shSquoteInner(p)}'`, modelAlias);
|
|
981
1065
|
return `cd '${shSquoteInner(worktreePath)}' && ${invocation}`;
|
|
982
1066
|
}
|
|
983
1067
|
/** PowerShell agent shell command: `Set-Location -LiteralPath '<path>'; <agent> [--model '<alias>'] '<prompt>'`. */
|
|
984
|
-
export function buildPowerShellAgentShellCommand(agent, key, worktreePath, autoApprove = false, modelAlias, conductorEnabled = false, resumeMode = false) {
|
|
985
|
-
const invocation = buildAgentInvocation(agent, buildAgentPrompt(key, { autoApprove, conductorEnabled, resumeMode }), powershellSquote, modelAlias);
|
|
1068
|
+
export function buildPowerShellAgentShellCommand(agent, key, worktreePath, autoApprove = false, modelAlias, conductorEnabled = false, resumeMode = false, workflow = "implement", reviewRounds, baseBranch) {
|
|
1069
|
+
const invocation = buildAgentInvocation(agent, buildAgentPrompt(key, { autoApprove, conductorEnabled, resumeMode, workflow, reviewRounds, baseBranch }), powershellSquote, modelAlias);
|
|
986
1070
|
return `Set-Location -LiteralPath ${powershellSquote(worktreePath)}; ${invocation}`;
|
|
987
1071
|
}
|
|
988
1072
|
/**
|
|
@@ -993,10 +1077,10 @@ export function buildPowerShellAgentShellCommand(agent, key, worktreePath, autoA
|
|
|
993
1077
|
* injected as `--model` at the spawn boundary. `conductorEnabled` appends the
|
|
994
1078
|
* BAPI-397 message-relay instruction to the prompt (opt-in via `--conductor`).
|
|
995
1079
|
*/
|
|
996
|
-
export function buildAgentShellCommand(agent, key, worktreePath, platform = "darwin", autoApprove = false, modelAlias, conductorEnabled = false, resumeMode = false) {
|
|
1080
|
+
export function buildAgentShellCommand(agent, key, worktreePath, platform = "darwin", autoApprove = false, modelAlias, conductorEnabled = false, resumeMode = false, workflow = "implement", reviewRounds, baseBranch) {
|
|
997
1081
|
if (platform === "win32")
|
|
998
|
-
return buildPowerShellAgentShellCommand(agent, key, worktreePath, autoApprove, modelAlias, conductorEnabled, resumeMode);
|
|
999
|
-
return buildPosixAgentShellCommand(agent, key, worktreePath, autoApprove, modelAlias, conductorEnabled, resumeMode);
|
|
1082
|
+
return buildPowerShellAgentShellCommand(agent, key, worktreePath, autoApprove, modelAlias, conductorEnabled, resumeMode, workflow, reviewRounds, baseBranch);
|
|
1083
|
+
return buildPosixAgentShellCommand(agent, key, worktreePath, autoApprove, modelAlias, conductorEnabled, resumeMode, workflow, reviewRounds, baseBranch);
|
|
1000
1084
|
}
|
|
1001
1085
|
/**
|
|
1002
1086
|
* Build the shell command run inside a spawned tab/session for an ARBITRARY
|
|
@@ -1518,14 +1602,16 @@ export function buildDryRunResults(keys, overrides) {
|
|
|
1518
1602
|
* PowerShell on Windows, `wt` + POSIX on macOS/Linux, and a non-throwing `wt` +
|
|
1519
1603
|
* POSIX fallback for unsupported platforms.
|
|
1520
1604
|
*/
|
|
1521
|
-
export function getDryRunPlatformDetails(agent, platform = process.platform, env = process.env, autoApprove = false, conductorEnabled = false, repoName = null) {
|
|
1605
|
+
export function getDryRunPlatformDetails(agent, platform = process.platform, env = process.env, autoApprove = false, conductorEnabled = false, repoName = null, workflow = "implement", reviewRounds, baseBranch) {
|
|
1522
1606
|
return {
|
|
1523
1607
|
worktrunkBinary: resolveWorktrunkBinary(platform, env),
|
|
1524
1608
|
// The builder accepts an optional resolved modelAlias; the dry-run caller
|
|
1525
1609
|
// now passes the previewed tier's alias so `--model` shows in the preview.
|
|
1526
1610
|
// The resolved repo name (when known) is injected as a BAPI_REPO_NAME prefix
|
|
1527
|
-
// so the dry-run preview matches the real spawn command exactly.
|
|
1528
|
-
|
|
1611
|
+
// so the dry-run preview matches the real spawn command exactly. Reuses the
|
|
1612
|
+
// same buildAgentShellCommand/buildAgentPrompt path as a real spawn — dry-run
|
|
1613
|
+
// is never special-cased — so the previewed workflow prompt is exact.
|
|
1614
|
+
buildAgentShellCommand: (key, worktreePath, modelAlias) => prependRepoNameEnvAssignment(buildAgentShellCommand(agent, key, worktreePath, platform, autoApprove, modelAlias, conductorEnabled, false, workflow, reviewRounds, baseBranch), repoName, platform),
|
|
1529
1615
|
};
|
|
1530
1616
|
}
|
|
1531
1617
|
/**
|
|
@@ -1563,8 +1649,8 @@ export function buildDryRunMcpProvisioningLines(worktreePath, platform = process
|
|
|
1563
1649
|
* the secret-free MCP provisioning preview. Pure platform formatting only — no
|
|
1564
1650
|
* preflight, no routing failures.
|
|
1565
1651
|
*/
|
|
1566
|
-
export function buildDryRunDetailLines(agent, key, branch, platform = process.platform, env = process.env, baseBranch = "main", autoApprove = false, modelAlias = null, conductorEnabled = false, repoName = null, mcpServerInvocation) {
|
|
1567
|
-
const { worktrunkBinary, buildAgentShellCommand: build } = getDryRunPlatformDetails(agent, platform, env, autoApprove, conductorEnabled, repoName);
|
|
1652
|
+
export function buildDryRunDetailLines(agent, key, branch, platform = process.platform, env = process.env, baseBranch = "main", autoApprove = false, modelAlias = null, conductorEnabled = false, repoName = null, mcpServerInvocation, workflow = "implement", reviewRounds) {
|
|
1653
|
+
const { worktrunkBinary, buildAgentShellCommand: build } = getDryRunPlatformDetails(agent, platform, env, autoApprove, conductorEnabled, repoName, workflow, reviewRounds, baseBranch);
|
|
1568
1654
|
const wtArgs = buildWtSwitchArgs(branch, false, baseBranch);
|
|
1569
1655
|
const agentInvocation = build(key, "<worktree-path>", modelAlias);
|
|
1570
1656
|
return [
|
|
@@ -2504,7 +2590,10 @@ export async function orchestrateStartTickets(deps, options, overrides = {}) {
|
|
|
2504
2590
|
}
|
|
2505
2591
|
const platformConfig = resolveStartTicketsPlatformConfig(deps, agent, options.autoApprove, options.conductorEnabled ?? false, resolvedRepoName,
|
|
2506
2592
|
// BAPI-494: resume-mode dispatches get the full-suite remediation finalize prompt.
|
|
2507
|
-
options.resumeMode ?? false
|
|
2593
|
+
options.resumeMode ?? false, options.workflow, options.reviewRounds,
|
|
2594
|
+
// BAPI-586: the effective run base (already carries any epic.base_branch
|
|
2595
|
+
// override applied above) so conductor workers get BAPI_BASE_BRANCH.
|
|
2596
|
+
options.baseBranch);
|
|
2508
2597
|
if (!platformConfig.ok)
|
|
2509
2598
|
return { ok: false, error: platformConfig.error };
|
|
2510
2599
|
// BAPI-527: resolve the base start point new worktrees are cut from BEFORE any
|
|
@@ -2707,7 +2796,7 @@ export async function runStartTicketsCli(argv, overrides = {}) {
|
|
|
2707
2796
|
const branch = resolveBranchForTicket(key, options.branchOverrides);
|
|
2708
2797
|
const routedRow = routedByKey.get(key);
|
|
2709
2798
|
const modelAlias = routedRow?.modelAlias ?? null;
|
|
2710
|
-
for (const line of buildDryRunDetailLines(agent, key, branch, deps.platform, deps.env, options.baseBranch, options.autoApprove, modelAlias, options.conductorEnabled ?? false, dryRunRepoName, dryRunMcpInvocation)) {
|
|
2799
|
+
for (const line of buildDryRunDetailLines(agent, key, branch, deps.platform, deps.env, options.baseBranch, options.autoApprove, modelAlias, options.conductorEnabled ?? false, dryRunRepoName, dryRunMcpInvocation, options.workflow, options.reviewRounds)) {
|
|
2711
2800
|
log(line);
|
|
2712
2801
|
}
|
|
2713
2802
|
log(`DRY-RUN: model routing: ${formatModelRoutingLine(routedRow ?? { key, branch, status: "dry-run" }, agent)}`);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// AUTO-GENERATED — do not edit manually. Regenerate with: npm run build
|
|
2
|
-
export const VERSION = "0.2.
|
|
2
|
+
export const VERSION = "0.2.23";
|
package/build/worktree-core.js
CHANGED
|
@@ -145,6 +145,44 @@ export async function isExistingBranchSafeToReuse(deps, branch, baseStartPoint)
|
|
|
145
145
|
* job-type logic lives here — the caller decides the start point, the stale
|
|
146
146
|
* guard, and the freshen behavior.
|
|
147
147
|
*/
|
|
148
|
+
/**
|
|
149
|
+
* Hard-reset the branch checked out in `worktreePath` onto `ref`. Returns null on
|
|
150
|
+
* success or a bounded, secret-free `create-failed` error string on failure.
|
|
151
|
+
* Shared by the recovery freshen path and the BAPI-586 fresh-dispatch alignment.
|
|
152
|
+
*/
|
|
153
|
+
async function hardResetWorktree(deps, worktreePath, ref) {
|
|
154
|
+
const resetArgs = ["reset", "--hard", ref];
|
|
155
|
+
const reset = await deps.runCommand("git", resetArgs, { cwd: worktreePath });
|
|
156
|
+
if (!commandSucceeded(reset)) {
|
|
157
|
+
const reason = (reset.stderr || reset.stdout || "").trim();
|
|
158
|
+
return `git ${resetArgs.join(" ")} failed${reason ? `: ${reason}` : ""}`;
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* BAPI-586: resolve the worktree's `HEAD^{commit}` and the `expected` ref/commit
|
|
164
|
+
* and confirm they are equal. Returns null when they match, or a bounded,
|
|
165
|
+
* secret-free `create-failed` error string otherwise. Short-SHA fragments in the
|
|
166
|
+
* message are safe (they are public commit identifiers, not secrets).
|
|
167
|
+
*/
|
|
168
|
+
async function verifyWorktreeHead(deps, worktreePath, expected) {
|
|
169
|
+
const headRes = await deps.runCommand("git", ["rev-parse", "--verify", "HEAD^{commit}"], { cwd: worktreePath });
|
|
170
|
+
if (!commandSucceeded(headRes)) {
|
|
171
|
+
return "failed to resolve worktree HEAD after creation (git rev-parse HEAD^{commit} failed).";
|
|
172
|
+
}
|
|
173
|
+
const expectedRes = await deps.runCommand("git", ["rev-parse", "--verify", `${expected}^{commit}`], { cwd: worktreePath });
|
|
174
|
+
if (!commandSucceeded(expectedRes)) {
|
|
175
|
+
return "failed to resolve the expected base commit after creation (git rev-parse --verify failed).";
|
|
176
|
+
}
|
|
177
|
+
const head = headRes.stdout.trim();
|
|
178
|
+
const want = expectedRes.stdout.trim();
|
|
179
|
+
if (head !== want) {
|
|
180
|
+
return (`worktree head ${head.slice(0, 12)} does not match the pinned base ${want.slice(0, 12)}; ` +
|
|
181
|
+
`Worktrunk seeded the worktree from an unexpected start point. Refusing to hand a mis-seeded ` +
|
|
182
|
+
`worktree to a worker.`);
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
148
186
|
export async function createWorktreeForTicket(deps, key, branchOverrides, worktrunkBinary, baseStartPoint = "main", guardStaleWorktree = false, behavior = {}) {
|
|
149
187
|
const branch = resolveBranchForTicket(key, branchOverrides);
|
|
150
188
|
try {
|
|
@@ -181,16 +219,30 @@ export async function createWorktreeForTicket(deps, key, branchOverrides, worktr
|
|
|
181
219
|
// `origin/<branch>`), so this only applies when the local branch pre-existed.
|
|
182
220
|
// Run inside the switched worktree (the branch is checked out there).
|
|
183
221
|
if (exists && behavior.freshenFromOrigin) {
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
222
|
+
const resetError = await hardResetWorktree(deps, worktreePath, behavior.freshenFromOrigin);
|
|
223
|
+
if (resetError) {
|
|
224
|
+
return { key, branch, status: "create-failed", error: resetError };
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// BAPI-586 (fresh dispatch): a guard-approved pre-existing branch is an
|
|
228
|
+
// ancestor of base but may sit at an OLDER tip. Align it EXACTLY to the
|
|
229
|
+
// pinned base SHA so a fresh implementation starts at base, not at a stale
|
|
230
|
+
// ancestor. The stale-branch guard above already ran (and refused unsafe
|
|
231
|
+
// branches) before this destructive reset. Absent branches were created
|
|
232
|
+
// straight from `baseStartPoint`, so no alignment is needed there.
|
|
233
|
+
if (exists && behavior.alignExistingBranchTo) {
|
|
234
|
+
const resetError = await hardResetWorktree(deps, worktreePath, behavior.alignExistingBranchTo);
|
|
235
|
+
if (resetError) {
|
|
236
|
+
return { key, branch, status: "create-failed", error: resetError };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// BAPI-586 (fresh dispatch): verify the worktree actually starts at the
|
|
240
|
+
// pinned base. If Worktrunk seeded from an unexpected sibling despite
|
|
241
|
+
// `-b <sha>`, fail CLOSED before the worktree is handed to a worker.
|
|
242
|
+
if (behavior.verifyHeadMatches) {
|
|
243
|
+
const verifyError = await verifyWorktreeHead(deps, worktreePath, behavior.verifyHeadMatches);
|
|
244
|
+
if (verifyError) {
|
|
245
|
+
return { key, branch, status: "create-failed", error: verifyError };
|
|
194
246
|
}
|
|
195
247
|
}
|
|
196
248
|
return { key, branch, status: "created", path: worktreePath };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bridge_gpt/mcp-server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.23",
|
|
4
4
|
"description": "Bridge API MCP server — exposes Jira endpoints as MCP tools for Claude Code agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"check:version-generated": "node scripts/bundle-version.js && node scripts/check-version-generated.js",
|
|
28
28
|
"postbuild": "node scripts/prepend-shebang.cjs",
|
|
29
29
|
"start": "node build/index.js",
|
|
30
|
-
"test": "node --test --test-force-exit build/pipeline-utils.test.js build/backend-warnings.test.js build/update-check.test.js build/cli-upgrade.test.js build/decision-page-schema.test.js build/decision-page-template.test.js build/bundle-pipelines.test.js build/instructions-contract.test.js build/pipeline-orchestrator-persistence.test.js build/pipeline-orchestrator-execution.test.js build/pipeline-orchestrator-integration.test.js build/index-static.test.js build/config-fields.static.test.js build/index-resolvers.test.js build/index-project-root.test.js build/index-pipelines.test.js build/index.test.js build/bridge-config.test.js build/credential-store.test.js build/agent-config-credential-migration.test.js build/mcp-invoke.test.js build/mcp-provisioning.test.js build/mcp-server-invocation.test.js build/third-party-mcp-targets.test.js build/git-ignore-utils.test.js build/credential-materialization.test.js build/mcp-registration-doctor.test.js build/secret-safety.test.js build/start-tickets.test.js build/review-tickets.test.js build/start-tickets-base-branch.test.js build/agent-registry.test.js build/agent-registry.model-routing.test.js build/start-tickets.shell-model-routing.test.js build/start-tickets.bridge-api-model-routing.test.js build/start-tickets.tier-fetch-model-routing.test.js build/start-tickets.resolve-model-routing.test.js build/start-tickets.orchestrate-model-routing.test.js build/start-tickets.routing-diagnostics.test.js build/start-tickets-repo.test.js build/start-tickets-credential-invariants.static.test.js build/credentials-cli.test.js build/start-tickets-prereqs.test.js build/regression-check.test.js build/doctor.test.js build/install-doctor.test.js build/install-bridge.test.js build/init.test.js build/resolveUploadAttachment.test.js build/package-static.test.js build/chain-utils.test.js build/chain-orchestrator.test.js build/scheduler-backends/types.test.js build/scheduler-backends/escaping.test.js build/scheduler-backends/launchd.test.js build/scheduler-backends/task-scheduler.test.js build/scheduler-backends/systemd-user.test.js build/scheduler-backends/at-fallback.test.js build/scheduler-backends/index.test.js build/command-catalog.test.js build/scheduled-prompt.test.js build/agent-launchers/claude.test.js build/agent-launchers/cursor.test.js build/agent-launchers/index.test.js build/schedule-store.test.js build/schedule-run.test.js build/agent-capabilities/cli.test.js build/agent-capabilities/runner.test.js build/agent-capabilities/probes.test.js build/agent-capabilities/probe-context.test.js build/agent-capabilities/reporter.test.js build/conductor/taxonomy-and-errors.test.js build/conductor/github-mergeability.test.js build/conductor/merge-conflict-routing.test.js build/conductor/redaction-normalization.test.js build/conductor/claude-hook.test.js build/conductor/git-ci-types.test.js build/conductor/done-gate.test.js build/conductor/git-ci-taxonomy-payload.test.js build/conductor/bridge-api-client.test.js build/conductor/plan.test.js build/conductor/producer-ledger.test.js build/conductor/spec-review-producer.test.js build/conductor/git-producer.test.js build/conductor/git-hooks.test.js build/conductor/store-migration.test.js build/conductor/pr-discovery.test.js build/conductor/pr-ci-producer.test.js build/conductor/pr-review-producer.test.js build/conductor/doctor.test.js build/conductor/deny-enforcement-preflight.test.js build/conductor/errors.test.js build/conductor/store.test.js build/conductor/index-poll-ci-producer.test.js build/start-tickets-conductor.test.js build/start-tickets-conductor.spawn.test.js build/start-tickets-conductor-node-propagation.test.js build/start-tickets.non-mutating-base.test.js build/start-tickets-live-source-guard.test.js build/conductor/worker-ledger-cli.test.js build/conductor/supervisor-config.test.js build/conductor/supervisor-ledger.test.js build/conductor/supervisor-state-reducer.test.js build/conductor/supervisor-housekeeping-projection.test.js build/conductor/supervisor-escalation.test.js build/conductor/supervisor-retired-judgment.static.test.js build/conductor/supervisor-runtime.test.js build/conductor/supervisor-store-projection.test.js build/conductor/supervisor-cli.test.js build/conductor/supervisor-start-tickets.test.js build/conductor/supervisor-message-relay.test.js build/conductor/supervisor-state-message-events.test.js build/conductor/store-message-relay.test.js build/start-tickets-message-relay.test.js build/conductor/event-accessors.test.js build/conductor/merge-ledger.test.js build/conductor/deterministic-completion.static.test.js build/conductor/deterministic-completion.integration.test.js build/conductor/local-merge.test.js build/conductor/local-merge.static.test.js build/conductor/supervisor-merge.test.js build/conductor/bridge-api-merge-client.test.js build/conductor/bridge-api-epic-client.test.js build/conductor/supervisor-merge-runtime-state.test.js build/conductor/epic-state.test.js build/executor/claude-settings.test.js build/executor/cli.test.js build/executor/credentials.test.js build/executor/echo-acceptance.test.js build/executor/env.test.js build/executor/heartbeat.test.js build/executor/http-client.test.js build/executor/job-runner.test.js build/executor/job-runner.payload-timeout.test.js build/executor/worker-finalization.test.js build/executor/job-runner.static.test.js build/executor/prompt-spec.test.js build/executor/job-types.test.js build/executor/recovery-job.static.test.js build/executor/observation.test.js build/executor/permissions.test.js build/executor/preflight.test.js build/executor/process.test.js build/executor/results.test.js build/executor/runner.test.js build/executor/terminal-mutation.test.js build/executor/worker-command.test.js build/executor/worktree-core.test.js build/executor/worktree.test.js build/executor/job-errors.test.js build/executor/worktree-inspection.test.js build/executor/resume-pre-spawn.test.js build/executor/verdict-artifact.test.js build/executor/worker-log.test.js build/executor/job-log-registry.test.js build/executor/viewer-tabs.test.js build/executor/watch-cli.test.js build/executor/merge-job.test.js build/executor/job-runner.merge.test.js build/executor/worktree-gc.test.js build/executor/runner.job-behaviors.test.js build/conductor/cli-freeze.test.js build/conductor/epic-reconcile.test.js build/conductor/epic-runtime.test.js build/conductor/epic-tick-sequence.test.js build/conductor/epic-runtime-post-action.test.js build/conductor/file-scope-guard.test.js build/conductor/file-scope-guard.integration.test.js build/mcp-profile.test.js build/mcp-profile-registration.test.js build/tools-budget.test.js build/visual-diff-worker.test.js build/visual-diff.test.js build/estimate-epic.test.js build/integration/measure-tools.test.js build/sfcc/config.test.js build/sfcc/ocapi-shape.test.js build/sfcc/output.test.js build/sfcc/credentials.test.js build/sfcc/ocapi-write-faults.test.js build/sfcc/write-guard.test.js build/sfcc/write-grants.test.js build/sfcc/write-result.test.js build/sfcc/writes.test.js build/sfcc/writes-system-object-payloads.test.js build/sfcc/writes-payloads.test.js && node --experimental-test-module-mocks --test --test-force-exit build/index-heavy-read-truncation.test.js build/index-artifacts.test.js build/index.review-rounds.test.js build/index-brainstorm-filenames.test.js build/index-output-path.test.js build/index-generate-decision-page.test.js build/index-generate-decision-page.integration.test.js build/visual-diff.registration.test.js build/visual-diff.attachment-adapter.test.js build/attachment-download.test.js build/attachment-upload.test.js build/conductor/paths.test.js build/conductor/store-lifecycle.test.js build/conductor/store-queries.test.js build/conductor/tools.test.js build/conductor/cli.test.js build/conductor/security-regressions.test.js build/conductor/git-inspection.test.js build/conductor/tools-done-gate.test.js build/conductor/pr-ci-producer-emit-seam.test.js build/conductor/cli-git-hooks.test.js build/sfcc/client.test.js build/sfcc/tool-wrapper.test.js build/sfcc/setup-status.test.js build/sfcc/permissions.test.js build/sfcc/register.test.js build/sfcc/reads-system-object.test.js build/sfcc/reads-custom-object-def.test.js build/sfcc/reads-site-preference.test.js build/sfcc/writes-system-object.test.js build/sfcc/writes-custom-object-def.test.js build/sfcc/writes-site-preference.test.js",
|
|
31
|
-
"test:integration": "node --test build/integration/refresh-main.integration.test.js build/integration/start-tickets.integration.test.js build/integration/doctor.integration.test.js build/integration/agent-capabilities.integration.test.js build/integration/conductor-producer.integration.test.js build/integration/conductor-message-relay.integration.test.js build/integration/executor-http-runner.integration.test.js build/integration/executor-job-behaviors.integration.test.js build/integration/executor-recovery-jobs.integration.test.js build/integration/executor-spec-review-prompt.integration.test.js build/integration/resume-pre-spawn.git.integration.test.js build/integration/worker-finalization-origin.integration.test.js build/integration/post-remediation-merge-ci-wait.integration.test.js build/integration/executor-merge-supervision.integration.test.js build/integration/attachment-binary-roundtrip.integration.test.js",
|
|
30
|
+
"test": "node --test --test-force-exit build/pipeline-utils.test.js build/backend-warnings.test.js build/update-check.test.js build/cli-upgrade.test.js build/decision-page-schema.test.js build/decision-page-template.test.js build/bundle-pipelines.test.js build/instructions-contract.test.js build/pipeline-orchestrator-persistence.test.js build/pipeline-orchestrator-execution.test.js build/pipeline-orchestrator-integration.test.js build/index-static.test.js build/config-fields.static.test.js build/execute-plan-instructions.static.test.js build/index-resolvers.test.js build/index-project-root.test.js build/index-pipelines.test.js build/index.test.js build/bridge-config.test.js build/credential-store.test.js build/agent-config-credential-migration.test.js build/mcp-invoke.test.js build/mcp-provisioning.test.js build/mcp-server-invocation.test.js build/third-party-mcp-targets.test.js build/git-ignore-utils.test.js build/credential-materialization.test.js build/mcp-registration-doctor.test.js build/secret-safety.test.js build/base-ref.test.js build/pr-base-contract.test.js build/start-tickets.test.js build/review-tickets.test.js build/start-tickets-base-branch.test.js build/agent-registry.test.js build/agent-registry.model-routing.test.js build/start-tickets.shell-model-routing.test.js build/start-tickets.bridge-api-model-routing.test.js build/start-tickets.tier-fetch-model-routing.test.js build/start-tickets.resolve-model-routing.test.js build/start-tickets.orchestrate-model-routing.test.js build/start-tickets.routing-diagnostics.test.js build/start-tickets-repo.test.js build/start-tickets-credential-invariants.static.test.js build/credentials-cli.test.js build/start-tickets-prereqs.test.js build/regression-check.test.js build/doctor.test.js build/install-doctor.test.js build/install-bridge.test.js build/install-bridge-invite.test.js build/install-bridge-prompt.test.js build/init.test.js build/resolveUploadAttachment.test.js build/package-static.test.js build/chain-utils.test.js build/chain-orchestrator.test.js build/scheduler-backends/types.test.js build/scheduler-backends/escaping.test.js build/scheduler-backends/launchd.test.js build/scheduler-backends/task-scheduler.test.js build/scheduler-backends/systemd-user.test.js build/scheduler-backends/at-fallback.test.js build/scheduler-backends/index.test.js build/command-catalog.test.js build/scheduled-prompt.test.js build/agent-launchers/claude.test.js build/agent-launchers/cursor.test.js build/agent-launchers/index.test.js build/schedule-store.test.js build/schedule-run.test.js build/setup-epic.test.js build/agent-capabilities/cli.test.js build/agent-capabilities/runner.test.js build/agent-capabilities/probes.test.js build/agent-capabilities/probe-context.test.js build/agent-capabilities/reporter.test.js build/conductor/taxonomy-and-errors.test.js build/conductor/github-mergeability.test.js build/conductor/merge-conflict-routing.test.js build/conductor/redaction-normalization.test.js build/conductor/claude-hook.test.js build/conductor/git-ci-types.test.js build/conductor/done-gate.test.js build/conductor/git-ci-taxonomy-payload.test.js build/conductor/bridge-api-client.test.js build/conductor/plan.test.js build/conductor/producer-ledger.test.js build/conductor/spec-review-producer.test.js build/conductor/git-producer.test.js build/conductor/git-hooks.test.js build/conductor/store-migration.test.js build/conductor/pr-discovery.test.js build/conductor/pr-ci-producer.test.js build/conductor/pr-review-producer.test.js build/conductor/doctor.test.js build/conductor/deny-enforcement-preflight.test.js build/conductor/errors.test.js build/conductor/store.test.js build/conductor/index-poll-ci-producer.test.js build/start-tickets-conductor.test.js build/start-tickets-conductor.spawn.test.js build/start-tickets-conductor-node-propagation.test.js build/start-tickets.non-mutating-base.test.js build/start-tickets-live-source-guard.test.js build/conductor/worker-ledger-cli.test.js build/conductor/supervisor-config.test.js build/conductor/supervisor-ledger.test.js build/conductor/supervisor-state-reducer.test.js build/conductor/supervisor-housekeeping-projection.test.js build/conductor/supervisor-escalation.test.js build/conductor/supervisor-retired-judgment.static.test.js build/conductor/supervisor-runtime.test.js build/conductor/supervisor-store-projection.test.js build/conductor/supervisor-cli.test.js build/conductor/supervisor-start-tickets.test.js build/conductor/supervisor-message-relay.test.js build/conductor/supervisor-state-message-events.test.js build/conductor/store-message-relay.test.js build/start-tickets-message-relay.test.js build/conductor/event-accessors.test.js build/conductor/merge-ledger.test.js build/conductor/deterministic-completion.static.test.js build/conductor/deterministic-completion.integration.test.js build/conductor/local-merge.test.js build/conductor/local-merge.static.test.js build/conductor/supervisor-merge.test.js build/conductor/bridge-api-merge-client.test.js build/conductor/bridge-api-epic-client.test.js build/conductor/supervisor-merge-runtime-state.test.js build/conductor/epic-state.test.js build/executor/claude-settings.test.js build/executor/cli.test.js build/executor/credentials.test.js build/executor/echo-acceptance.test.js build/executor/env.test.js build/executor/base-branch.test.js build/executor/heartbeat.test.js build/executor/http-client.test.js build/executor/job-runner.test.js build/executor/job-runner.payload-timeout.test.js build/executor/worker-finalization.test.js build/executor/job-runner.static.test.js build/executor/prompt-spec.test.js build/executor/job-types.test.js build/executor/recovery-job.static.test.js build/executor/observation.test.js build/executor/permissions.test.js build/executor/preflight.test.js build/executor/process.test.js build/executor/results.test.js build/executor/runner.test.js build/executor/terminal-mutation.test.js build/executor/worker-command.test.js build/executor/worktree-core.test.js build/executor/worktree.test.js build/executor/job-errors.test.js build/executor/worktree-inspection.test.js build/executor/resume-pre-spawn.test.js build/executor/verdict-artifact.test.js build/executor/worker-log.test.js build/executor/job-log-registry.test.js build/executor/viewer-tabs.test.js build/executor/watch-cli.test.js build/executor/merge-job.test.js build/executor/job-runner.merge.test.js build/executor/worktree-gc.test.js build/executor/runner.job-behaviors.test.js build/conductor/cli-freeze.test.js build/conductor/epic-reconcile.test.js build/conductor/epic-runtime.test.js build/conductor/epic-tick-sequence.test.js build/conductor/epic-runtime-post-action.test.js build/conductor/file-scope-guard.test.js build/conductor/file-scope-guard.integration.test.js build/mcp-profile.test.js build/mcp-profile-registration.test.js build/tools-budget.test.js build/visual-diff-worker.test.js build/visual-diff.test.js build/estimate-epic.test.js build/integration/measure-tools.test.js build/sfcc/config.test.js build/sfcc/ocapi-shape.test.js build/sfcc/output.test.js build/sfcc/credentials.test.js build/sfcc/ocapi-write-faults.test.js build/sfcc/write-guard.test.js build/sfcc/write-grants.test.js build/sfcc/write-result.test.js build/sfcc/writes.test.js build/sfcc/writes-system-object-payloads.test.js build/sfcc/writes-payloads.test.js && node --experimental-test-module-mocks --test --test-force-exit build/index-heavy-read-truncation.test.js build/index-artifacts.test.js build/index.review-rounds.test.js build/index-brainstorm-filenames.test.js build/index-output-path.test.js build/index-generate-decision-page.test.js build/index-generate-decision-page.integration.test.js build/visual-diff.registration.test.js build/visual-diff.attachment-adapter.test.js build/attachment-download.test.js build/attachment-upload.test.js build/conductor/paths.test.js build/conductor/store-lifecycle.test.js build/conductor/store-queries.test.js build/conductor/tools.test.js build/conductor/cli.test.js build/conductor/security-regressions.test.js build/conductor/git-inspection.test.js build/conductor/tools-done-gate.test.js build/conductor/pr-ci-producer-emit-seam.test.js build/conductor/cli-git-hooks.test.js build/sfcc/client.test.js build/sfcc/tool-wrapper.test.js build/sfcc/setup-status.test.js build/sfcc/permissions.test.js build/sfcc/register.test.js build/sfcc/reads-system-object.test.js build/sfcc/reads-custom-object-def.test.js build/sfcc/reads-site-preference.test.js build/sfcc/writes-system-object.test.js build/sfcc/writes-custom-object-def.test.js build/sfcc/writes-site-preference.test.js",
|
|
31
|
+
"test:integration": "node --test build/integration/refresh-main.integration.test.js build/integration/start-tickets.integration.test.js build/integration/doctor.integration.test.js build/integration/agent-capabilities.integration.test.js build/integration/conductor-producer.integration.test.js build/integration/conductor-message-relay.integration.test.js build/integration/executor-http-runner.integration.test.js build/integration/executor-job-behaviors.integration.test.js build/integration/executor-recovery-jobs.integration.test.js build/integration/executor-spec-review-prompt.integration.test.js build/integration/resume-pre-spawn.git.integration.test.js build/integration/worker-finalization-origin.integration.test.js build/integration/post-remediation-merge-ci-wait.integration.test.js build/integration/executor-merge-supervision.integration.test.js build/integration/attachment-binary-roundtrip.integration.test.js build/integration/dependent-ticket-fresh-base.integration.test.js build/integration/execute-plan-instructions.integration.test.js",
|
|
32
32
|
"test:smoke": "node --test build/integration/packaged-cli-smoke.test.js",
|
|
33
33
|
"prepublishOnly": "node scripts/bundle-assets.js && npm run build && node scripts/verify-shebang.cjs"
|
|
34
34
|
},
|
package/public/js/main.min.js
CHANGED
|
@@ -5321,12 +5321,12 @@ function populateCiFollowupConfig(rawValue) {
|
|
|
5321
5321
|
// ladder below are kept byte-identical to the backend
|
|
5322
5322
|
// (api/library/review_ticket_policy.py) so a stored override round-trips exactly.
|
|
5323
5323
|
const REVIEW_POLICY_BUCKETS = Object.freeze([
|
|
5324
|
-
{ name: 'Very Easy', slug: 'very-easy', range: '1' },
|
|
5325
|
-
{ name: 'Easy', slug: 'easy', range: '
|
|
5326
|
-
{ name: 'Easy-Moderate', slug: 'easy-moderate', range: '
|
|
5327
|
-
{ name: 'Moderate', slug: 'moderate', range: '
|
|
5328
|
-
{ name: 'Moderate-Hard', slug: 'moderate-hard', range: '
|
|
5329
|
-
{ name: 'Hard', slug: 'hard', range: '
|
|
5324
|
+
{ name: 'Very Easy', slug: 'very-easy', range: '1-2' },
|
|
5325
|
+
{ name: 'Easy', slug: 'easy', range: '3-4' },
|
|
5326
|
+
{ name: 'Easy-Moderate', slug: 'easy-moderate', range: '5' },
|
|
5327
|
+
{ name: 'Moderate', slug: 'moderate', range: '6' },
|
|
5328
|
+
{ name: 'Moderate-Hard', slug: 'moderate-hard', range: '7' },
|
|
5329
|
+
{ name: 'Hard', slug: 'hard', range: '8-10' },
|
|
5330
5330
|
]);
|
|
5331
5331
|
|
|
5332
5332
|
// The two per-bucket automations and their coarse per-round tiers. `clarify` must
|
|
@@ -5345,9 +5345,9 @@ const REVIEW_POLICY_DEFAULT_NEW_TIER = 'basic';
|
|
|
5345
5345
|
const DEFAULT_REVIEW_POLICY_LADDER = Object.freeze({
|
|
5346
5346
|
'Very Easy': { clarify: ['basic'], critique: [] },
|
|
5347
5347
|
'Easy': { clarify: ['basic', 'basic'], critique: [] },
|
|
5348
|
-
'Easy-Moderate': { clarify: ['
|
|
5349
|
-
'Moderate': { clarify: ['premium', '
|
|
5350
|
-
'Moderate-Hard': { clarify: ['premium'], critique: ['premium'] },
|
|
5348
|
+
'Easy-Moderate': { clarify: ['basic', 'basic'], critique: ['basic'] },
|
|
5349
|
+
'Moderate': { clarify: ['premium', 'basic'], critique: ['premium'] },
|
|
5350
|
+
'Moderate-Hard': { clarify: ['premium', 'basic'], critique: ['premium', 'basic'] },
|
|
5351
5351
|
'Hard': { clarify: ['premium', 'premium'], critique: ['premium', 'premium'] },
|
|
5352
5352
|
});
|
|
5353
5353
|
|