@bridge_gpt/mcp-server 0.1.13 → 0.1.16
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 +58 -0
- package/build/agent-registry.js +68 -0
- package/build/commands.generated.js +4 -3
- package/build/doctor.js +172 -0
- package/build/index.js +818 -95
- package/build/pipeline-orchestrator.js +593 -0
- package/build/pipeline-utils.js +50 -12
- package/build/pipelines.generated.js +44 -29
- package/build/start-tickets-prereqs.js +346 -0
- package/build/start-tickets.js +1210 -0
- package/build/version.generated.js +1 -1
- package/package.json +7 -7
- package/pipelines/check-ci-ticket.json +8 -2
- package/pipelines/implement-ticket.json +8 -2
- package/pipelines/pr-ticket.json +1 -2
- package/build/decision-page-schema.test.js +0 -248
package/build/pipeline-utils.js
CHANGED
|
@@ -79,6 +79,28 @@ export function validatePipelineSchema(json) {
|
|
|
79
79
|
return { valid: errors.length === 0, errors };
|
|
80
80
|
}
|
|
81
81
|
// ---------------------------------------------------------------------------
|
|
82
|
+
// Instruction-File Content Helpers
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
/**
|
|
85
|
+
* True when markdown contains a terminal ``## Return`` H2 heading — i.e. the
|
|
86
|
+
* heading appears and no later H2 heading follows. Used by the build-time
|
|
87
|
+
* bundler and the custom-pipeline loader to enforce the
|
|
88
|
+
* ``agent_result``-contract for ``agent_task`` instruction files.
|
|
89
|
+
*/
|
|
90
|
+
export function hasTerminalReturnSection(markdown) {
|
|
91
|
+
if (typeof markdown !== "string" || markdown.length === 0)
|
|
92
|
+
return false;
|
|
93
|
+
const h2Pattern = /^##\s+(.+?)\s*$/gm;
|
|
94
|
+
let match;
|
|
95
|
+
let lastHeading = null;
|
|
96
|
+
while ((match = h2Pattern.exec(markdown)) !== null) {
|
|
97
|
+
lastHeading = match[1].trim();
|
|
98
|
+
}
|
|
99
|
+
if (lastHeading === null)
|
|
100
|
+
return false;
|
|
101
|
+
return /^return\b/i.test(lastHeading);
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
82
104
|
// Variable Handling
|
|
83
105
|
// ---------------------------------------------------------------------------
|
|
84
106
|
const variablePattern = () => /\{([a-zA-Z_][a-zA-Z0-9_]*)}/g;
|
|
@@ -123,7 +145,7 @@ function substituteInParams(params, variables) {
|
|
|
123
145
|
// ---------------------------------------------------------------------------
|
|
124
146
|
// Recipe Resolution
|
|
125
147
|
// ---------------------------------------------------------------------------
|
|
126
|
-
export function resolveRecipe(pipeline, instructions, variables, skipSteps) {
|
|
148
|
+
export function resolveRecipe(pipeline, instructions, variables, skipSteps, autoApprove) {
|
|
127
149
|
// Validate required variables are provided
|
|
128
150
|
const declared = pipeline.variables ?? [];
|
|
129
151
|
const missing = declared.filter((v) => !(v in variables));
|
|
@@ -140,13 +162,18 @@ export function resolveRecipe(pipeline, instructions, variables, skipSteps) {
|
|
|
140
162
|
const skipKey = step.type === "mcp_call" ? step.tool : step.description;
|
|
141
163
|
if (skip.has(skipKey))
|
|
142
164
|
continue;
|
|
165
|
+
const declaredApproval = step.requires_approval ?? false;
|
|
166
|
+
const effectiveApproval = declaredApproval && !autoApprove;
|
|
143
167
|
const base = {
|
|
144
168
|
step: stepIndex++,
|
|
145
169
|
type: step.type,
|
|
146
|
-
description: step.description,
|
|
170
|
+
description: substituteVariables(step.description, variables),
|
|
147
171
|
on_error: step.on_error ?? "halt",
|
|
148
|
-
requires_approval:
|
|
172
|
+
requires_approval: effectiveApproval,
|
|
149
173
|
};
|
|
174
|
+
if (declaredApproval !== effectiveApproval) {
|
|
175
|
+
base.requires_approval_declared = declaredApproval;
|
|
176
|
+
}
|
|
150
177
|
if (step.type === "mcp_call") {
|
|
151
178
|
base.tool = step.tool;
|
|
152
179
|
base.params = substituteInParams(step.params, variables);
|
|
@@ -168,17 +195,22 @@ export function resolveRecipe(pipeline, instructions, variables, skipSteps) {
|
|
|
168
195
|
}
|
|
169
196
|
resolvedSteps.push(base);
|
|
170
197
|
}
|
|
198
|
+
const baseInstructions = "IMPORTANT: Execute every step below in exact sequential order. " +
|
|
199
|
+
"For mcp_call steps, call the specified tool with the provided params. " +
|
|
200
|
+
"For agent_task steps, follow the instruction text using any tools it specifies. " +
|
|
201
|
+
"If requires_approval is true, pause before executing. For agent_task steps, the instruction file's own approval format is authoritative — follow it verbatim and do not substitute your own short confirmation prompt. For mcp_call steps with no instruction file, present the resolved params as bullet points and ask for approval. " +
|
|
202
|
+
'For on_error "halt", stop the pipeline immediately on failure. ' +
|
|
203
|
+
'For on_error "warn_and_continue", log a warning and proceed. ' +
|
|
204
|
+
"Do not skip steps, reorder them, or substitute your own tool calls.";
|
|
205
|
+
const autoApproveSuffix = autoApprove
|
|
206
|
+
? " Auto-approve mode is ACTIVE: every approval gate has been pre-approved by the user via the auto_approve flag — proceed without pausing for confirmation, applying the default branching, file-staging, and recommendation choices documented in each instruction file's auto-approve branch."
|
|
207
|
+
: "";
|
|
171
208
|
return {
|
|
172
209
|
pipeline: pipeline.name,
|
|
173
210
|
description: pipeline.description ?? "",
|
|
174
211
|
total_steps: resolvedSteps.length,
|
|
175
|
-
agent_instructions:
|
|
176
|
-
|
|
177
|
-
"For agent_task steps, follow the instruction text using any tools it specifies. " +
|
|
178
|
-
"If requires_approval is true, pause before executing. For agent_task steps, the instruction file's own approval format is authoritative — follow it verbatim and do not substitute your own short confirmation prompt. For mcp_call steps with no instruction file, present the resolved params as bullet points and ask for approval. " +
|
|
179
|
-
'For on_error "halt", stop the pipeline immediately on failure. ' +
|
|
180
|
-
'For on_error "warn_and_continue", log a warning and proceed. ' +
|
|
181
|
-
"Do not skip steps, reorder them, or substitute your own tool calls.",
|
|
212
|
+
agent_instructions: baseInstructions + autoApproveSuffix,
|
|
213
|
+
auto_approve: !!autoApprove,
|
|
182
214
|
steps: resolvedSteps,
|
|
183
215
|
};
|
|
184
216
|
}
|
|
@@ -237,15 +269,21 @@ export async function loadCustomPipelines(pipelinesDir, instructionsDir, bundled
|
|
|
237
269
|
}
|
|
238
270
|
const pipeline = parsed;
|
|
239
271
|
const key = file.replace(/\.json$/, "");
|
|
240
|
-
// Validate instruction_file references
|
|
272
|
+
// Validate instruction_file references and terminal ## Return contract.
|
|
241
273
|
let hasInvalidRef = false;
|
|
242
274
|
for (const step of pipeline.steps) {
|
|
243
275
|
if (step.type === "agent_task" && step.instruction_file) {
|
|
244
|
-
|
|
276
|
+
const content = mergedInstructions[step.instruction_file];
|
|
277
|
+
if (content === undefined) {
|
|
245
278
|
console.error(`Warning: skipping "${file}" — instruction_file "${step.instruction_file}" not found.`);
|
|
246
279
|
hasInvalidRef = true;
|
|
247
280
|
break;
|
|
248
281
|
}
|
|
282
|
+
if (!hasTerminalReturnSection(content)) {
|
|
283
|
+
console.error(`Warning: skipping "${file}" — instruction_file "${step.instruction_file}" is missing a terminal "## Return" section (required by BAPI-275 agent_result contract).`);
|
|
284
|
+
hasInvalidRef = true;
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
249
287
|
}
|
|
250
288
|
}
|
|
251
289
|
if (hasInvalidRef)
|