pullfrog 0.1.49 → 0.1.51
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 +1 -1
- package/dist/cli.mjs +306 -238
- package/dist/external.d.ts +11 -1
- package/dist/index.js +305 -237
- package/dist/internal/index.d.ts +2 -1
- package/dist/internal.js +15 -2
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/similarIssues.d.ts +11 -0
- package/dist/models.d.ts +10 -0
- package/dist/utils/activity.d.ts +33 -0
- package/dist/utils/agentHangReport.d.ts +13 -0
- package/dist/utils/instructions.d.ts +3 -0
- package/dist/utils/isPullfrog.d.ts +4 -0
- package/dist/utils/payload.d.ts +0 -6
- package/dist/utils/runContext.d.ts +1 -0
- package/dist/utils/runStatusCheck.d.ts +9 -4
- package/dist/utils/statusChecks.d.ts +2 -2
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -102476,14 +102476,18 @@ function formatMcpToolRef(agentId, toolName) {
|
|
|
102476
102476
|
return agentId;
|
|
102477
102477
|
}
|
|
102478
102478
|
}
|
|
102479
|
+
function hasSimilarIssues(params) {
|
|
102480
|
+
return params.repoIntelligence && !!params.event.issue_number && !params.event.is_pr;
|
|
102481
|
+
}
|
|
102479
102482
|
|
|
102480
102483
|
// utils/activity.ts
|
|
102481
102484
|
import { performance as performance2 } from "node:perf_hooks";
|
|
102482
|
-
function
|
|
102485
|
+
function isDebugEnabled() {
|
|
102483
102486
|
return process.env.ACTIONS_STEP_DEBUG === "true" || process.env.RUNNER_DEBUG === "1" || process.env.LOG_LEVEL === "debug";
|
|
102484
102487
|
}
|
|
102485
102488
|
var DEFAULT_ACTIVITY_TIMEOUT_MS = 3e5;
|
|
102486
102489
|
var AGENT_ACTIVITY_TIMEOUT_MS = 9e5;
|
|
102490
|
+
var AGENT_FIRST_EVENT_TIMEOUT_MS = 12e4;
|
|
102487
102491
|
var DEFAULT_ACTIVITY_CHECK_INTERVAL_MS = 5e3;
|
|
102488
102492
|
var DEBUG_TS_PREFIX = /^(?:\[\d{4}-\d{2}-\d{2}T[^\]]+\]\s+)?/.source;
|
|
102489
102493
|
var ACTIVITY_NOISE_PATTERNS = [
|
|
@@ -102527,7 +102531,7 @@ function startProcessOutputMonitor(ctx) {
|
|
|
102527
102531
|
process.stdout.write = wrapWrite(originalStdoutWrite, markActivity);
|
|
102528
102532
|
process.stderr.write = wrapWrite(originalStderrWrite, markActivity);
|
|
102529
102533
|
const debugBypass = (msg) => {
|
|
102530
|
-
if (!
|
|
102534
|
+
if (!isDebugEnabled()) return;
|
|
102531
102535
|
originalStdoutWrite(`[${(/* @__PURE__ */ new Date()).toISOString()}] [DEBUG] ${msg}
|
|
102532
102536
|
`);
|
|
102533
102537
|
};
|
|
@@ -102736,7 +102740,6 @@ function prefixPlain(name) {
|
|
|
102736
102740
|
}
|
|
102737
102741
|
var isRunnerDebugEnabled = () => core.isDebug();
|
|
102738
102742
|
var isLocalDebugEnabled = () => process.env.LOG_LEVEL === "debug" || process.env.ACTIONS_STEP_DEBUG === "true";
|
|
102739
|
-
var isDebugEnabled = () => isLocalDebugEnabled() || isRunnerDebugEnabled();
|
|
102740
102743
|
function ts() {
|
|
102741
102744
|
return isDebugEnabled() ? `[${(/* @__PURE__ */ new Date()).toISOString()}] ` : "";
|
|
102742
102745
|
}
|
|
@@ -103177,7 +103180,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
103177
103180
|
// package.json
|
|
103178
103181
|
var package_default = {
|
|
103179
103182
|
name: "pullfrog",
|
|
103180
|
-
version: "0.1.
|
|
103183
|
+
version: "0.1.51",
|
|
103181
103184
|
type: "module",
|
|
103182
103185
|
bin: {
|
|
103183
103186
|
pullfrog: "dist/cli.mjs",
|
|
@@ -111048,7 +111051,7 @@ async function installOpencodeCli(params) {
|
|
|
111048
111051
|
installDependencies: true
|
|
111049
111052
|
});
|
|
111050
111053
|
}
|
|
111051
|
-
var AUTO_SELECT_WARNING = "select a model explicitly in the Pullfrog console (https://pullfrog.com/console) to avoid this.";
|
|
111054
|
+
var AUTO_SELECT_WARNING = "select a model explicitly in the Pullfrog console (https://pullfrog.com/console) to avoid this \u2014 if the picker is locked, this run had no Pullfrog Router funding: add a card or top up your credit.";
|
|
111052
111055
|
function autoSelectModel() {
|
|
111053
111056
|
const authorized2 = getAuthorizedModels();
|
|
111054
111057
|
if (authorized2.size > 0) {
|
|
@@ -111123,9 +111126,11 @@ function parseModel2(value2) {
|
|
|
111123
111126
|
return { providerID: value2.slice(0, slash), modelID: value2.slice(slash + 1) };
|
|
111124
111127
|
}
|
|
111125
111128
|
function bootOpencodeServer(params) {
|
|
111129
|
+
const logLevel = isDebugEnabled() ? "INFO" : "ERROR";
|
|
111130
|
+
if (logLevel !== "ERROR") log.info(`\xBB opencode log level: ${logLevel} (debug run)`);
|
|
111126
111131
|
const proc = nodeSpawn2(
|
|
111127
111132
|
params.cliPath,
|
|
111128
|
-
["serve", "--port", "0", "--hostname", "127.0.0.1", "--print-logs", "--log-level",
|
|
111133
|
+
["serve", "--port", "0", "--hostname", "127.0.0.1", "--print-logs", "--log-level", logLevel],
|
|
111129
111134
|
{
|
|
111130
111135
|
cwd: params.cwd,
|
|
111131
111136
|
env: params.env,
|
|
@@ -111260,9 +111265,18 @@ async function consumeEvents(ctx, signal) {
|
|
|
111260
111265
|
}
|
|
111261
111266
|
}
|
|
111262
111267
|
}
|
|
111268
|
+
function isModelOutput(ctx, part) {
|
|
111269
|
+
if (part.type !== "text") return true;
|
|
111270
|
+
if (ctx.promptMessageID === void 0) {
|
|
111271
|
+
ctx.promptMessageID = part.messageID;
|
|
111272
|
+
return false;
|
|
111273
|
+
}
|
|
111274
|
+
return part.messageID !== ctx.promptMessageID;
|
|
111275
|
+
}
|
|
111263
111276
|
async function dispatchEvent(ctx, event) {
|
|
111264
111277
|
if (event.type === "message.part.updated") {
|
|
111265
111278
|
ctx.lastEventAt = performance6.now();
|
|
111279
|
+
if (isModelOutput(ctx, event.properties.part)) ctx.sawModelOutput = true;
|
|
111266
111280
|
await onPartUpdated(ctx, event.properties.part);
|
|
111267
111281
|
return;
|
|
111268
111282
|
}
|
|
@@ -111406,6 +111420,8 @@ async function runPromptTurn(ctx, params) {
|
|
|
111406
111420
|
ctx.currentTurn = newTurn();
|
|
111407
111421
|
const turn = ctx.currentTurn;
|
|
111408
111422
|
const part = { type: "text", text: params.text };
|
|
111423
|
+
ctx.promptMessageID = void 0;
|
|
111424
|
+
ctx.sawModelOutput = false;
|
|
111409
111425
|
let assistant;
|
|
111410
111426
|
let returnedParts;
|
|
111411
111427
|
let networkError = null;
|
|
@@ -111579,11 +111595,14 @@ function startInnerActivityWatchdog(params) {
|
|
|
111579
111595
|
const id = setInterval(() => {
|
|
111580
111596
|
if (fired) return;
|
|
111581
111597
|
const idleMs = performance6.now() - params.ctx.lastEventAt;
|
|
111582
|
-
|
|
111598
|
+
const budgetMs = params.ctx.sawModelOutput ? params.timeoutMs : AGENT_FIRST_EVENT_TIMEOUT_MS;
|
|
111599
|
+
if (idleMs <= budgetMs) return;
|
|
111583
111600
|
fired = true;
|
|
111584
111601
|
const idleSec = Math.round(idleMs / 1e3);
|
|
111602
|
+
params.ctx.diagnostic.idleSec = idleSec;
|
|
111603
|
+
params.ctx.diagnostic.sawModelOutput = params.ctx.sawModelOutput;
|
|
111585
111604
|
log.info(
|
|
111586
|
-
`\xBB no opencode events for ${idleSec}s \u2014 aborting in-flight prompt and notifying harness`
|
|
111605
|
+
params.ctx.sawModelOutput ? `\xBB no opencode events for ${idleSec}s \u2014 aborting in-flight prompt and notifying harness` : `\xBB no opencode events for ${idleSec}s \u2014 the provider never returned a first token; aborting in-flight prompt and notifying harness`
|
|
111587
111606
|
);
|
|
111588
111607
|
params.abortController.abort();
|
|
111589
111608
|
try {
|
|
@@ -111708,6 +111727,8 @@ var opencode = agent({
|
|
|
111708
111727
|
currentTurn: null,
|
|
111709
111728
|
eventCount: 0,
|
|
111710
111729
|
lastEventAt: performance6.now(),
|
|
111730
|
+
sawModelOutput: false,
|
|
111731
|
+
promptMessageID: void 0,
|
|
111711
111732
|
taskDispatchByCallID: /* @__PURE__ */ new Map(),
|
|
111712
111733
|
loggedToolCallIDs: /* @__PURE__ */ new Set(),
|
|
111713
111734
|
recentStderr: server.recentStderr,
|
|
@@ -111715,6 +111736,8 @@ var opencode = agent({
|
|
|
111715
111736
|
label: "Pullfrog",
|
|
111716
111737
|
recentStderr: server.recentStderr,
|
|
111717
111738
|
lastProviderError: void 0,
|
|
111739
|
+
idleSec: void 0,
|
|
111740
|
+
sawModelOutput: false,
|
|
111718
111741
|
eventCount: 0
|
|
111719
111742
|
}
|
|
111720
111743
|
};
|
|
@@ -159948,6 +159971,12 @@ function fixDoubleEscapedString(str) {
|
|
|
159948
159971
|
return str;
|
|
159949
159972
|
}
|
|
159950
159973
|
|
|
159974
|
+
// utils/isPullfrog.ts
|
|
159975
|
+
function isPullfrog(actor) {
|
|
159976
|
+
actor = actor?.toLowerCase().replace("[bot]", "");
|
|
159977
|
+
return !!actor && (actor === "pullfrog" || actor === "pullfrogdev");
|
|
159978
|
+
}
|
|
159979
|
+
|
|
159951
159980
|
// utils/isTransientNetworkError.ts
|
|
159952
159981
|
function isTransientNetworkError(error49, extraPatterns = []) {
|
|
159953
159982
|
if (!(error49 instanceof Error)) return false;
|
|
@@ -160054,216 +160083,6 @@ function aggregateUsage(entries) {
|
|
|
160054
160083
|
return out;
|
|
160055
160084
|
}
|
|
160056
160085
|
|
|
160057
|
-
// utils/payload.ts
|
|
160058
|
-
var core4 = __toESM(require_core(), 1);
|
|
160059
|
-
import { readFileSync as readFileSync4 } from "node:fs";
|
|
160060
|
-
import { isAbsolute as isAbsolute2, resolve as resolve2 } from "node:path";
|
|
160061
|
-
|
|
160062
|
-
// utils/versioning.ts
|
|
160063
|
-
var import_semver2 = __toESM(require_semver2(), 1);
|
|
160064
|
-
var COMPATIBILITY_POLICY = "non-breaking";
|
|
160065
|
-
function validateCompatibility(payloadVersion, actionVersion) {
|
|
160066
|
-
const payloadSemVer = import_semver2.default.parse(payloadVersion);
|
|
160067
|
-
if (!payloadSemVer)
|
|
160068
|
-
throw new Error(`Payload version ${payloadVersion} is not a valid semantic version.`);
|
|
160069
|
-
const major = payloadSemVer.major;
|
|
160070
|
-
const minor = payloadSemVer.minor;
|
|
160071
|
-
const patch = payloadSemVer.patch;
|
|
160072
|
-
const compatibilityRange = COMPATIBILITY_POLICY === "same-features" ? `^${major}.${minor}.${major === 0 ? patch : 0}` : `^${major}.${major === 0 ? minor : 0}.${major === 0 ? "x" : 0}`;
|
|
160073
|
-
if (!import_semver2.default.satisfies(actionVersion, compatibilityRange)) {
|
|
160074
|
-
throw new Error(
|
|
160075
|
-
`Payload version ${payloadVersion} is incompatible with action version ${actionVersion}. Please update your workflow to use at least ${import_semver2.default.minVersion(compatibilityRange)} version of the action.`
|
|
160076
|
-
);
|
|
160077
|
-
}
|
|
160078
|
-
}
|
|
160079
|
-
|
|
160080
|
-
// utils/payload.ts
|
|
160081
|
-
var ShellPermissionInput = type.enumerated("disabled", "restricted", "enabled");
|
|
160082
|
-
var PushPermissionInput = type.enumerated("disabled", "restricted", "enabled");
|
|
160083
|
-
var StatusChecksInput = type.enumerated("disabled", "enabled");
|
|
160084
|
-
var ProgressCommentsInput = type.enumerated("disabled", "enabled");
|
|
160085
|
-
var JsonPayload = type({
|
|
160086
|
-
"~pullfrog": "true",
|
|
160087
|
-
version: "string",
|
|
160088
|
-
"model?": "string | undefined",
|
|
160089
|
-
"modelExplicit?": "boolean | undefined",
|
|
160090
|
-
"effort?": "number | string | undefined",
|
|
160091
|
-
prompt: "string",
|
|
160092
|
-
"triggerer?": "string | undefined",
|
|
160093
|
-
"baseInstructions?": "string | undefined",
|
|
160094
|
-
"eventInstructions?": "string",
|
|
160095
|
-
"previousRunsNote?": "string",
|
|
160096
|
-
"event?": "object",
|
|
160097
|
-
"xrepo?": type({
|
|
160098
|
-
mode: "'all' | 'explicit'",
|
|
160099
|
-
read: "string[]",
|
|
160100
|
-
write: "string[]",
|
|
160101
|
-
// optional so a payload from an older server build (pre-`unavailable`)
|
|
160102
|
-
// still parses against a newer action across a rolling deploy.
|
|
160103
|
-
"unavailable?": "string[]"
|
|
160104
|
-
}).or("undefined"),
|
|
160105
|
-
"timeout?": "string | undefined",
|
|
160106
|
-
"progressComment?": type({
|
|
160107
|
-
id: "string",
|
|
160108
|
-
type: "'issue' | 'review'"
|
|
160109
|
-
}).or("undefined"),
|
|
160110
|
-
// optional so a payload from an older server build (pre-`checkRun`) still parses
|
|
160111
|
-
// against a newer action across a rolling deploy.
|
|
160112
|
-
"checkRun?": type({ id: "string" }).or("undefined"),
|
|
160113
|
-
"generateSummary?": "boolean | undefined"
|
|
160114
|
-
});
|
|
160115
|
-
var COLLABORATOR_PERMISSIONS = ["admin", "maintain", "write"];
|
|
160116
|
-
function isCollaborator(event) {
|
|
160117
|
-
const perm = event.authorPermission;
|
|
160118
|
-
return perm !== void 0 && COLLABORATOR_PERMISSIONS.includes(perm);
|
|
160119
|
-
}
|
|
160120
|
-
var Inputs = type({
|
|
160121
|
-
"prompt?": type.string.or("undefined"),
|
|
160122
|
-
"prompt_file?": type.string.or("undefined"),
|
|
160123
|
-
"model?": type.string.or("undefined"),
|
|
160124
|
-
"effort?": type.string.or("undefined"),
|
|
160125
|
-
"timeout?": type.string.or("undefined"),
|
|
160126
|
-
"push?": PushPermissionInput.or("undefined"),
|
|
160127
|
-
"shell?": ShellPermissionInput.or("undefined"),
|
|
160128
|
-
"status_checks?": StatusChecksInput.or("undefined"),
|
|
160129
|
-
"progress_comments?": ProgressCommentsInput.or("undefined"),
|
|
160130
|
-
"cwd?": type.string.or("undefined"),
|
|
160131
|
-
"output_schema?": type.string.or("undefined")
|
|
160132
|
-
});
|
|
160133
|
-
function isPayloadEvent(value2) {
|
|
160134
|
-
return typeof value2 === "object" && value2 !== null && "trigger" in value2;
|
|
160135
|
-
}
|
|
160136
|
-
function resolveCwd(cwd) {
|
|
160137
|
-
const workspace = process.env.GITHUB_WORKSPACE;
|
|
160138
|
-
if (!cwd) return workspace;
|
|
160139
|
-
if (isAbsolute2(cwd)) return cwd;
|
|
160140
|
-
return workspace ? resolve2(workspace, cwd) : cwd;
|
|
160141
|
-
}
|
|
160142
|
-
function resolvePromptInput() {
|
|
160143
|
-
const promptInput = core4.getInput("prompt");
|
|
160144
|
-
const promptFile = core4.getInput("prompt_file");
|
|
160145
|
-
if (promptInput && promptFile) {
|
|
160146
|
-
throw new Error("set exactly one of 'prompt' or 'prompt_file' inputs, not both.");
|
|
160147
|
-
}
|
|
160148
|
-
if (promptFile) {
|
|
160149
|
-
return resolvePromptFile(promptFile);
|
|
160150
|
-
}
|
|
160151
|
-
if (!promptInput) {
|
|
160152
|
-
throw new Error("one of 'prompt' or 'prompt_file' inputs is required.");
|
|
160153
|
-
}
|
|
160154
|
-
let parsed2;
|
|
160155
|
-
try {
|
|
160156
|
-
parsed2 = JSON.parse(promptInput);
|
|
160157
|
-
} catch {
|
|
160158
|
-
return promptInput;
|
|
160159
|
-
}
|
|
160160
|
-
if (!parsed2 || typeof parsed2 !== "object" || !("~pullfrog" in parsed2)) {
|
|
160161
|
-
return promptInput;
|
|
160162
|
-
}
|
|
160163
|
-
const jsonPayload = JsonPayload.assert(parsed2);
|
|
160164
|
-
validateCompatibility(jsonPayload.version, package_default.version);
|
|
160165
|
-
return jsonPayload;
|
|
160166
|
-
}
|
|
160167
|
-
function resolvePromptFile(input) {
|
|
160168
|
-
const workspace = process.env.GITHUB_WORKSPACE;
|
|
160169
|
-
const path4 = isAbsolute2(input) ? input : workspace ? resolve2(workspace, input) : resolve2(input);
|
|
160170
|
-
const content = readFileSync4(path4, "utf-8");
|
|
160171
|
-
if (!content.trim()) {
|
|
160172
|
-
throw new Error(`prompt_file ${JSON.stringify(input)} is empty.`);
|
|
160173
|
-
}
|
|
160174
|
-
return content;
|
|
160175
|
-
}
|
|
160176
|
-
function resolveNonPromptInputs() {
|
|
160177
|
-
return Inputs.omit("prompt", "prompt_file").assert({
|
|
160178
|
-
model: core4.getInput("model") || void 0,
|
|
160179
|
-
effort: core4.getInput("effort") || void 0,
|
|
160180
|
-
timeout: core4.getInput("timeout") || void 0,
|
|
160181
|
-
cwd: core4.getInput("cwd") || void 0,
|
|
160182
|
-
push: core4.getInput("push") || void 0,
|
|
160183
|
-
shell: core4.getInput("shell") || void 0,
|
|
160184
|
-
status_checks: core4.getInput("status_checks") || void 0,
|
|
160185
|
-
progress_comments: core4.getInput("progress_comments") || void 0
|
|
160186
|
-
});
|
|
160187
|
-
}
|
|
160188
|
-
var isPullfrog = (actor) => {
|
|
160189
|
-
actor = actor?.replace("[bot]", "");
|
|
160190
|
-
return !!actor && (actor === "pullfrog" || actor === "pullfrogdev");
|
|
160191
|
-
};
|
|
160192
|
-
function resolvePayload(resolvedPromptInput, repoSettings) {
|
|
160193
|
-
const [prompt, jsonPayload] = typeof resolvedPromptInput !== "string" ? [resolvedPromptInput.prompt, resolvedPromptInput] : [resolvedPromptInput, void 0];
|
|
160194
|
-
const inputs = resolveNonPromptInputs();
|
|
160195
|
-
const rawEvent = jsonPayload?.event;
|
|
160196
|
-
const event = isPayloadEvent(rawEvent) ? rawEvent : { trigger: "unknown" };
|
|
160197
|
-
const model = jsonPayload?.model ?? inputs.model ?? repoSettings.model ?? void 0;
|
|
160198
|
-
const rawEffort = jsonPayload?.effort ?? inputs.effort ?? repoSettings.effort ?? void 0;
|
|
160199
|
-
const effort = rawEffort === void 0 ? void 0 : parseEffortPosition(String(rawEffort));
|
|
160200
|
-
const isNonCollaborator = !isCollaborator(event);
|
|
160201
|
-
const repoShell = repoSettings.shell ?? "restricted";
|
|
160202
|
-
const inputShell = inputs.shell;
|
|
160203
|
-
let resolvedShell = repoShell;
|
|
160204
|
-
if (inputShell === "disabled") {
|
|
160205
|
-
resolvedShell = "disabled";
|
|
160206
|
-
} else if (inputShell === "restricted" && resolvedShell === "enabled") {
|
|
160207
|
-
resolvedShell = "restricted";
|
|
160208
|
-
}
|
|
160209
|
-
if (isNonCollaborator && resolvedShell === "enabled") {
|
|
160210
|
-
resolvedShell = "restricted";
|
|
160211
|
-
}
|
|
160212
|
-
return {
|
|
160213
|
-
"~pullfrog": true,
|
|
160214
|
-
version: jsonPayload?.version ?? package_default.version,
|
|
160215
|
-
model,
|
|
160216
|
-
// explicit only when the model came from a per-run override flag (carried on
|
|
160217
|
-
// the JSON payload). a GHA `model` input or the repo default is not explicit.
|
|
160218
|
-
modelExplicit: jsonPayload?.modelExplicit ?? false,
|
|
160219
|
-
effort,
|
|
160220
|
-
prompt,
|
|
160221
|
-
triggerer: jsonPayload?.triggerer ?? // it's not a common use case but GITHUB_ACTOR can be a user when the workflow is manually triggered by a user through GitHub Actions UI
|
|
160222
|
-
(!isPullfrog(process.env.GITHUB_ACTOR) ? process.env.GITHUB_ACTOR : void 0),
|
|
160223
|
-
baseInstructions: jsonPayload?.baseInstructions,
|
|
160224
|
-
eventInstructions: jsonPayload?.eventInstructions,
|
|
160225
|
-
previousRunsNote: jsonPayload?.previousRunsNote,
|
|
160226
|
-
event,
|
|
160227
|
-
xrepo: jsonPayload?.xrepo,
|
|
160228
|
-
timeout: inputs.timeout ?? jsonPayload?.timeout,
|
|
160229
|
-
cwd: resolveCwd(inputs.cwd),
|
|
160230
|
-
progressComment: jsonPayload?.progressComment,
|
|
160231
|
-
checkRun: jsonPayload?.checkRun,
|
|
160232
|
-
generateSummary: jsonPayload?.generateSummary,
|
|
160233
|
-
// permissions: inputs > repoSettings > fallbacks
|
|
160234
|
-
push: inputs.push ?? repoSettings.push ?? "restricted",
|
|
160235
|
-
shell: resolvedShell,
|
|
160236
|
-
// the `pullfrog` run-lifecycle check. ON by default — the whole point is that a PR
|
|
160237
|
-
// shows whether Pullfrog is running without anyone having to opt in. the workflow
|
|
160238
|
-
// input is the source of truth when set (mirrors `push`); otherwise the repo
|
|
160239
|
-
// setting decides.
|
|
160240
|
-
runStatusCheck: inputs.status_checks === void 0 ? repoSettings.statusChecks : inputs.status_checks === "enabled",
|
|
160241
|
-
// the `pullfrog-approval` verdict check stays opt-in and workflow-only. it exists to
|
|
160242
|
-
// be *required* by branch protection, so it must never turn itself on.
|
|
160243
|
-
approvalCheck: inputs.status_checks === "enabled",
|
|
160244
|
-
// temporary progress chrome. the workflow input is the source of truth when
|
|
160245
|
-
// set (mirrors `push`); otherwise the repo setting decides. defaults to true.
|
|
160246
|
-
progressComments: inputs.progress_comments === void 0 ? repoSettings.progressComments : inputs.progress_comments === "enabled",
|
|
160247
|
-
// set by proxy logic in main.ts when routing through OpenRouter
|
|
160248
|
-
proxyModel: void 0
|
|
160249
|
-
};
|
|
160250
|
-
}
|
|
160251
|
-
function resolveOutputSchema() {
|
|
160252
|
-
const raw2 = core4.getInput("output_schema");
|
|
160253
|
-
if (!raw2) return void 0;
|
|
160254
|
-
let parsed2;
|
|
160255
|
-
try {
|
|
160256
|
-
parsed2 = JSON.parse(raw2);
|
|
160257
|
-
} catch {
|
|
160258
|
-
throw new Error(`invalid output_schema: not valid JSON`);
|
|
160259
|
-
}
|
|
160260
|
-
if (!parsed2 || typeof parsed2 !== "object" || Array.isArray(parsed2)) {
|
|
160261
|
-
throw new Error(`invalid output_schema: must be a JSON object`);
|
|
160262
|
-
}
|
|
160263
|
-
log.info("\xBB structured output schema provided \u2014 output will be required");
|
|
160264
|
-
return parsed2;
|
|
160265
|
-
}
|
|
160266
|
-
|
|
160267
160086
|
// mcp/comment.ts
|
|
160268
160087
|
function isNotFoundError(error49) {
|
|
160269
160088
|
return error49 instanceof Error && error49.message.includes("Not Found");
|
|
@@ -162574,7 +162393,7 @@ function isMetadataYarnClassic(metadataPath) {
|
|
|
162574
162393
|
}
|
|
162575
162394
|
|
|
162576
162395
|
// utils/packageManager.ts
|
|
162577
|
-
var
|
|
162396
|
+
var import_semver2 = __toESM(require_semver2(), 1);
|
|
162578
162397
|
import { existsSync as existsSync5 } from "node:fs";
|
|
162579
162398
|
import { mkdir, readFile as readFile2 } from "node:fs/promises";
|
|
162580
162399
|
import { delimiter, join as join17 } from "node:path";
|
|
@@ -162596,7 +162415,7 @@ function parsePackageManagerField(value2) {
|
|
|
162596
162415
|
return {
|
|
162597
162416
|
name,
|
|
162598
162417
|
version: version3,
|
|
162599
|
-
concrete:
|
|
162418
|
+
concrete: import_semver2.default.valid(version3) !== null,
|
|
162600
162419
|
source: "packageManager"
|
|
162601
162420
|
};
|
|
162602
162421
|
}
|
|
@@ -162610,7 +162429,7 @@ function parseDevEnginesField(field) {
|
|
|
162610
162429
|
return {
|
|
162611
162430
|
name: field.name,
|
|
162612
162431
|
version: version3,
|
|
162613
|
-
concrete:
|
|
162432
|
+
concrete: import_semver2.default.valid(version3) !== null,
|
|
162614
162433
|
source: "devEngines"
|
|
162615
162434
|
};
|
|
162616
162435
|
}
|
|
@@ -162644,7 +162463,7 @@ async function resolvePackageManagerSpec(cwd) {
|
|
|
162644
162463
|
}
|
|
162645
162464
|
return devSpec;
|
|
162646
162465
|
}
|
|
162647
|
-
if (pmSpec.concrete &&
|
|
162466
|
+
if (pmSpec.concrete && import_semver2.default.satisfies(pmSpec.version, devSpec.version)) {
|
|
162648
162467
|
return pmSpec;
|
|
162649
162468
|
}
|
|
162650
162469
|
if (pmSpec.concrete) {
|
|
@@ -162856,10 +162675,10 @@ ${errorMessage}`]
|
|
|
162856
162675
|
};
|
|
162857
162676
|
|
|
162858
162677
|
// prep/installPythonDependencies.ts
|
|
162859
|
-
import { existsSync as existsSync7, readFileSync as
|
|
162678
|
+
import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
|
|
162860
162679
|
import { join as join19 } from "node:path";
|
|
162861
162680
|
function declaresBuildSystem(path4) {
|
|
162862
|
-
return /^\s*\[\s*build-system\s*\]/m.test(
|
|
162681
|
+
return /^\s*\[\s*build-system\s*\]/m.test(readFileSync4(path4, "utf8"));
|
|
162863
162682
|
}
|
|
162864
162683
|
function configApplies(config3, cwd) {
|
|
162865
162684
|
const path4 = join19(cwd, config3.file);
|
|
@@ -164994,6 +164813,36 @@ function KillBackgroundTool(ctx) {
|
|
|
164994
164813
|
});
|
|
164995
164814
|
}
|
|
164996
164815
|
|
|
164816
|
+
// mcp/similarIssues.ts
|
|
164817
|
+
var SimilarIssues = type({
|
|
164818
|
+
issue_number: type.number.describe("The issue number to find older duplicate candidates for")
|
|
164819
|
+
});
|
|
164820
|
+
function SimilarIssuesTool(ctx) {
|
|
164821
|
+
return tool({
|
|
164822
|
+
name: "find_similar_issues",
|
|
164823
|
+
description: "Find high-recall older duplicate candidates for an issue. Similarity is only retrieval: inspect promising candidates with get_issue before deciding whether they are duplicates.",
|
|
164824
|
+
mutates: true,
|
|
164825
|
+
parameters: SimilarIssues,
|
|
164826
|
+
execute: execute(async (input) => {
|
|
164827
|
+
if (ctx.payload.event.is_pr || ctx.payload.event.issue_number !== input.issue_number) {
|
|
164828
|
+
throw new Error("find_similar_issues is limited to the issue that triggered this run");
|
|
164829
|
+
}
|
|
164830
|
+
const response = await apiFetch({
|
|
164831
|
+
path: `/api/repo/${ctx.repo.owner}/${ctx.repo.name}/issues/${input.issue_number}/similar`,
|
|
164832
|
+
headers: {
|
|
164833
|
+
authorization: `Bearer ${ctx.apiToken}`
|
|
164834
|
+
},
|
|
164835
|
+
signal: AbortSignal.timeout(13 * 6e4)
|
|
164836
|
+
});
|
|
164837
|
+
if (!response.ok) {
|
|
164838
|
+
const message = await response.text();
|
|
164839
|
+
throw new Error(`similar issue lookup returned ${response.status}: ${message}`);
|
|
164840
|
+
}
|
|
164841
|
+
return { result: await response.json() };
|
|
164842
|
+
})
|
|
164843
|
+
});
|
|
164844
|
+
}
|
|
164845
|
+
|
|
164997
164846
|
// mcp/upload.ts
|
|
164998
164847
|
import * as fs4 from "node:fs";
|
|
164999
164848
|
import * as path3 from "node:path";
|
|
@@ -165232,6 +165081,9 @@ function buildCommonTools(ctx, outputSchema) {
|
|
|
165232
165081
|
if (ctx.xrepo) {
|
|
165233
165082
|
tools.push(ListReposTool(ctx), CheckoutRepoTool(ctx));
|
|
165234
165083
|
}
|
|
165084
|
+
if (hasSimilarIssues({ repoIntelligence: ctx.repoIntelligence, event: ctx.payload.event })) {
|
|
165085
|
+
tools.push(SimilarIssuesTool(ctx));
|
|
165086
|
+
}
|
|
165235
165087
|
const isStandalone = ctx.payload.event.trigger === "unknown";
|
|
165236
165088
|
if (isStandalone || outputSchema) {
|
|
165237
165089
|
tools.push(SetOutputTool(ctx, outputSchema));
|
|
@@ -166175,6 +166027,11 @@ Rules:
|
|
|
166175
166027
|
### GitHub
|
|
166176
166028
|
|
|
166177
166029
|
Use MCP tools from ${pullfrogMcpName} for all GitHub operations. Never use the \`gh\` CLI \u2014 it is not authenticated and will fail. The MCP tools handle authentication and enforce permissions.
|
|
166030
|
+
${hasSimilarIssues({ repoIntelligence: ctx.repoIntelligence, event: ctx.payload.event }) ? `
|
|
166031
|
+
#### Duplicate detection (enabled for this repository)
|
|
166032
|
+
|
|
166033
|
+
Call \`${t2("find_similar_issues")}\` for #${ctx.payload.event.issue_number} before planning. If it duplicates an existing issue, link that instead of producing a plan; never close or label on similarity alone.
|
|
166034
|
+
` : ""}
|
|
166178
166035
|
|
|
166179
166036
|
${getShellInstructions(ctx.payload.shell, t2)}
|
|
166180
166037
|
|
|
@@ -166501,7 +166358,7 @@ function buildModelAccessError(input) {
|
|
|
166501
166358
|
}
|
|
166502
166359
|
|
|
166503
166360
|
// utils/normalizeEnv.ts
|
|
166504
|
-
var
|
|
166361
|
+
var core4 = __toESM(require_core(), 1);
|
|
166505
166362
|
function sanitizeSecret(key, value2) {
|
|
166506
166363
|
const trimmed = value2.trim();
|
|
166507
166364
|
if (trimmed.length === 0) {
|
|
@@ -166515,7 +166372,7 @@ function sanitizeSecret(key, value2) {
|
|
|
166515
166372
|
`\xBB stripped whitespace from ${key} (whitespace in secret values breaks GitHub Actions log masking)`
|
|
166516
166373
|
);
|
|
166517
166374
|
}
|
|
166518
|
-
|
|
166375
|
+
core4.setSecret(trimmed);
|
|
166519
166376
|
return trimmed;
|
|
166520
166377
|
}
|
|
166521
166378
|
function normalizeEnv() {
|
|
@@ -166559,7 +166416,7 @@ function normalizeEnv() {
|
|
|
166559
166416
|
}
|
|
166560
166417
|
|
|
166561
166418
|
// utils/overrides.ts
|
|
166562
|
-
var
|
|
166419
|
+
var core5 = __toESM(require_core(), 1);
|
|
166563
166420
|
var DENIED_OVERRIDE_NAMES = /* @__PURE__ */ new Set([
|
|
166564
166421
|
"GITHUB_TOKEN",
|
|
166565
166422
|
"GH_TOKEN",
|
|
@@ -166605,7 +166462,7 @@ function applyOverrides(params) {
|
|
|
166605
166462
|
denied.push(key);
|
|
166606
166463
|
continue;
|
|
166607
166464
|
}
|
|
166608
|
-
if (value2.length > 0)
|
|
166465
|
+
if (value2.length > 0) core5.setSecret(value2);
|
|
166609
166466
|
params.env[key] = value2;
|
|
166610
166467
|
applied.push(key);
|
|
166611
166468
|
}
|
|
@@ -166613,6 +166470,212 @@ function applyOverrides(params) {
|
|
|
166613
166470
|
return { applied, denied };
|
|
166614
166471
|
}
|
|
166615
166472
|
|
|
166473
|
+
// utils/payload.ts
|
|
166474
|
+
var core6 = __toESM(require_core(), 1);
|
|
166475
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
166476
|
+
import { isAbsolute as isAbsolute2, resolve as resolve2 } from "node:path";
|
|
166477
|
+
|
|
166478
|
+
// utils/versioning.ts
|
|
166479
|
+
var import_semver3 = __toESM(require_semver2(), 1);
|
|
166480
|
+
var COMPATIBILITY_POLICY = "non-breaking";
|
|
166481
|
+
function validateCompatibility(payloadVersion, actionVersion) {
|
|
166482
|
+
const payloadSemVer = import_semver3.default.parse(payloadVersion);
|
|
166483
|
+
if (!payloadSemVer)
|
|
166484
|
+
throw new Error(`Payload version ${payloadVersion} is not a valid semantic version.`);
|
|
166485
|
+
const major = payloadSemVer.major;
|
|
166486
|
+
const minor = payloadSemVer.minor;
|
|
166487
|
+
const patch = payloadSemVer.patch;
|
|
166488
|
+
const compatibilityRange = COMPATIBILITY_POLICY === "same-features" ? `^${major}.${minor}.${major === 0 ? patch : 0}` : `^${major}.${major === 0 ? minor : 0}.${major === 0 ? "x" : 0}`;
|
|
166489
|
+
if (!import_semver3.default.satisfies(actionVersion, compatibilityRange)) {
|
|
166490
|
+
throw new Error(
|
|
166491
|
+
`Payload version ${payloadVersion} is incompatible with action version ${actionVersion}. Please update your workflow to use at least ${import_semver3.default.minVersion(compatibilityRange)} version of the action.`
|
|
166492
|
+
);
|
|
166493
|
+
}
|
|
166494
|
+
}
|
|
166495
|
+
|
|
166496
|
+
// utils/payload.ts
|
|
166497
|
+
var ShellPermissionInput = type.enumerated("disabled", "restricted", "enabled");
|
|
166498
|
+
var PushPermissionInput = type.enumerated("disabled", "restricted", "enabled");
|
|
166499
|
+
var StatusChecksInput = type.enumerated("disabled", "enabled");
|
|
166500
|
+
var ProgressCommentsInput = type.enumerated("disabled", "enabled");
|
|
166501
|
+
var JsonPayload = type({
|
|
166502
|
+
"~pullfrog": "true",
|
|
166503
|
+
version: "string",
|
|
166504
|
+
"model?": "string | undefined",
|
|
166505
|
+
"modelExplicit?": "boolean | undefined",
|
|
166506
|
+
"effort?": "number | string | undefined",
|
|
166507
|
+
prompt: "string",
|
|
166508
|
+
"triggerer?": "string | undefined",
|
|
166509
|
+
"baseInstructions?": "string | undefined",
|
|
166510
|
+
"eventInstructions?": "string",
|
|
166511
|
+
"previousRunsNote?": "string",
|
|
166512
|
+
"event?": "object",
|
|
166513
|
+
"xrepo?": type({
|
|
166514
|
+
mode: "'all' | 'explicit'",
|
|
166515
|
+
read: "string[]",
|
|
166516
|
+
write: "string[]",
|
|
166517
|
+
// optional so a payload from an older server build (pre-`unavailable`)
|
|
166518
|
+
// still parses against a newer action across a rolling deploy.
|
|
166519
|
+
"unavailable?": "string[]"
|
|
166520
|
+
}).or("undefined"),
|
|
166521
|
+
"timeout?": "string | undefined",
|
|
166522
|
+
"progressComment?": type({
|
|
166523
|
+
id: "string",
|
|
166524
|
+
type: "'issue' | 'review'"
|
|
166525
|
+
}).or("undefined"),
|
|
166526
|
+
// optional so a payload from an older server build (pre-`checkRun`) still parses
|
|
166527
|
+
// against a newer action across a rolling deploy.
|
|
166528
|
+
"checkRun?": type({ id: "string" }).or("undefined"),
|
|
166529
|
+
"generateSummary?": "boolean | undefined"
|
|
166530
|
+
});
|
|
166531
|
+
var COLLABORATOR_PERMISSIONS = ["admin", "maintain", "write"];
|
|
166532
|
+
function isCollaborator(event) {
|
|
166533
|
+
const perm = event.authorPermission;
|
|
166534
|
+
return perm !== void 0 && COLLABORATOR_PERMISSIONS.includes(perm);
|
|
166535
|
+
}
|
|
166536
|
+
var Inputs = type({
|
|
166537
|
+
"prompt?": type.string.or("undefined"),
|
|
166538
|
+
"prompt_file?": type.string.or("undefined"),
|
|
166539
|
+
"model?": type.string.or("undefined"),
|
|
166540
|
+
"effort?": type.string.or("undefined"),
|
|
166541
|
+
"timeout?": type.string.or("undefined"),
|
|
166542
|
+
"push?": PushPermissionInput.or("undefined"),
|
|
166543
|
+
"shell?": ShellPermissionInput.or("undefined"),
|
|
166544
|
+
"status_checks?": StatusChecksInput.or("undefined"),
|
|
166545
|
+
"progress_comments?": ProgressCommentsInput.or("undefined"),
|
|
166546
|
+
"cwd?": type.string.or("undefined"),
|
|
166547
|
+
"output_schema?": type.string.or("undefined")
|
|
166548
|
+
});
|
|
166549
|
+
function isPayloadEvent(value2) {
|
|
166550
|
+
return typeof value2 === "object" && value2 !== null && "trigger" in value2;
|
|
166551
|
+
}
|
|
166552
|
+
function resolveCwd(cwd) {
|
|
166553
|
+
const workspace = process.env.GITHUB_WORKSPACE;
|
|
166554
|
+
if (!cwd) return workspace;
|
|
166555
|
+
if (isAbsolute2(cwd)) return cwd;
|
|
166556
|
+
return workspace ? resolve2(workspace, cwd) : cwd;
|
|
166557
|
+
}
|
|
166558
|
+
function resolvePromptInput() {
|
|
166559
|
+
const promptInput = core6.getInput("prompt");
|
|
166560
|
+
const promptFile = core6.getInput("prompt_file");
|
|
166561
|
+
if (promptInput && promptFile) {
|
|
166562
|
+
throw new Error("set exactly one of 'prompt' or 'prompt_file' inputs, not both.");
|
|
166563
|
+
}
|
|
166564
|
+
if (promptFile) {
|
|
166565
|
+
return resolvePromptFile(promptFile);
|
|
166566
|
+
}
|
|
166567
|
+
if (!promptInput) {
|
|
166568
|
+
throw new Error("one of 'prompt' or 'prompt_file' inputs is required.");
|
|
166569
|
+
}
|
|
166570
|
+
let parsed2;
|
|
166571
|
+
try {
|
|
166572
|
+
parsed2 = JSON.parse(promptInput);
|
|
166573
|
+
} catch {
|
|
166574
|
+
return promptInput;
|
|
166575
|
+
}
|
|
166576
|
+
if (!parsed2 || typeof parsed2 !== "object" || !("~pullfrog" in parsed2)) {
|
|
166577
|
+
return promptInput;
|
|
166578
|
+
}
|
|
166579
|
+
const jsonPayload = JsonPayload.assert(parsed2);
|
|
166580
|
+
validateCompatibility(jsonPayload.version, package_default.version);
|
|
166581
|
+
return jsonPayload;
|
|
166582
|
+
}
|
|
166583
|
+
function resolvePromptFile(input) {
|
|
166584
|
+
const workspace = process.env.GITHUB_WORKSPACE;
|
|
166585
|
+
const path4 = isAbsolute2(input) ? input : workspace ? resolve2(workspace, input) : resolve2(input);
|
|
166586
|
+
const content = readFileSync6(path4, "utf-8");
|
|
166587
|
+
if (!content.trim()) {
|
|
166588
|
+
throw new Error(`prompt_file ${JSON.stringify(input)} is empty.`);
|
|
166589
|
+
}
|
|
166590
|
+
return content;
|
|
166591
|
+
}
|
|
166592
|
+
function resolveNonPromptInputs() {
|
|
166593
|
+
return Inputs.omit("prompt", "prompt_file").assert({
|
|
166594
|
+
model: core6.getInput("model") || void 0,
|
|
166595
|
+
effort: core6.getInput("effort") || void 0,
|
|
166596
|
+
timeout: core6.getInput("timeout") || void 0,
|
|
166597
|
+
cwd: core6.getInput("cwd") || void 0,
|
|
166598
|
+
push: core6.getInput("push") || void 0,
|
|
166599
|
+
shell: core6.getInput("shell") || void 0,
|
|
166600
|
+
status_checks: core6.getInput("status_checks") || void 0,
|
|
166601
|
+
progress_comments: core6.getInput("progress_comments") || void 0
|
|
166602
|
+
});
|
|
166603
|
+
}
|
|
166604
|
+
function resolvePayload(resolvedPromptInput, repoSettings) {
|
|
166605
|
+
const [prompt, jsonPayload] = typeof resolvedPromptInput !== "string" ? [resolvedPromptInput.prompt, resolvedPromptInput] : [resolvedPromptInput, void 0];
|
|
166606
|
+
const inputs = resolveNonPromptInputs();
|
|
166607
|
+
const rawEvent = jsonPayload?.event;
|
|
166608
|
+
const event = isPayloadEvent(rawEvent) ? rawEvent : { trigger: "unknown" };
|
|
166609
|
+
const model = jsonPayload?.model ?? inputs.model ?? repoSettings.model ?? void 0;
|
|
166610
|
+
const rawEffort = jsonPayload?.effort ?? inputs.effort ?? repoSettings.effort ?? void 0;
|
|
166611
|
+
const effort = rawEffort === void 0 ? void 0 : parseEffortPosition(String(rawEffort));
|
|
166612
|
+
const isNonCollaborator = !isCollaborator(event);
|
|
166613
|
+
const repoShell = repoSettings.shell ?? "restricted";
|
|
166614
|
+
const inputShell = inputs.shell;
|
|
166615
|
+
let resolvedShell = repoShell;
|
|
166616
|
+
if (inputShell === "disabled") {
|
|
166617
|
+
resolvedShell = "disabled";
|
|
166618
|
+
} else if (inputShell === "restricted" && resolvedShell === "enabled") {
|
|
166619
|
+
resolvedShell = "restricted";
|
|
166620
|
+
}
|
|
166621
|
+
if (isNonCollaborator && resolvedShell === "enabled") {
|
|
166622
|
+
resolvedShell = "restricted";
|
|
166623
|
+
}
|
|
166624
|
+
return {
|
|
166625
|
+
"~pullfrog": true,
|
|
166626
|
+
version: jsonPayload?.version ?? package_default.version,
|
|
166627
|
+
model,
|
|
166628
|
+
// explicit only when the model came from a per-run override flag (carried on
|
|
166629
|
+
// the JSON payload). a GHA `model` input or the repo default is not explicit.
|
|
166630
|
+
modelExplicit: jsonPayload?.modelExplicit ?? false,
|
|
166631
|
+
effort,
|
|
166632
|
+
prompt,
|
|
166633
|
+
triggerer: jsonPayload?.triggerer ?? // it's not a common use case but GITHUB_ACTOR can be a user when the workflow is manually triggered by a user through GitHub Actions UI
|
|
166634
|
+
(!isPullfrog(process.env.GITHUB_ACTOR) ? process.env.GITHUB_ACTOR : void 0),
|
|
166635
|
+
baseInstructions: jsonPayload?.baseInstructions,
|
|
166636
|
+
eventInstructions: jsonPayload?.eventInstructions,
|
|
166637
|
+
previousRunsNote: jsonPayload?.previousRunsNote,
|
|
166638
|
+
event,
|
|
166639
|
+
xrepo: jsonPayload?.xrepo,
|
|
166640
|
+
timeout: inputs.timeout ?? jsonPayload?.timeout,
|
|
166641
|
+
cwd: resolveCwd(inputs.cwd),
|
|
166642
|
+
progressComment: jsonPayload?.progressComment,
|
|
166643
|
+
checkRun: jsonPayload?.checkRun,
|
|
166644
|
+
generateSummary: jsonPayload?.generateSummary,
|
|
166645
|
+
// permissions: inputs > repoSettings > fallbacks
|
|
166646
|
+
push: inputs.push ?? repoSettings.push ?? "restricted",
|
|
166647
|
+
shell: resolvedShell,
|
|
166648
|
+
// the `pullfrog` run-lifecycle check. ON by default — the whole point is that a PR
|
|
166649
|
+
// shows whether Pullfrog is running without anyone having to opt in. the workflow
|
|
166650
|
+
// input is the source of truth when set (mirrors `push`); otherwise the repo
|
|
166651
|
+
// setting decides.
|
|
166652
|
+
runStatusCheck: inputs.status_checks === void 0 ? repoSettings.statusChecks : inputs.status_checks === "enabled",
|
|
166653
|
+
// the `pullfrog-approval` verdict check stays opt-in and workflow-only. it exists to
|
|
166654
|
+
// be *required* by branch protection, so it must never turn itself on.
|
|
166655
|
+
approvalCheck: inputs.status_checks === "enabled",
|
|
166656
|
+
// temporary progress chrome. the workflow input is the source of truth when
|
|
166657
|
+
// set (mirrors `push`); otherwise the repo setting decides. defaults to true.
|
|
166658
|
+
progressComments: inputs.progress_comments === void 0 ? repoSettings.progressComments : inputs.progress_comments === "enabled",
|
|
166659
|
+
// set by proxy logic in main.ts when routing through OpenRouter
|
|
166660
|
+
proxyModel: void 0
|
|
166661
|
+
};
|
|
166662
|
+
}
|
|
166663
|
+
function resolveOutputSchema() {
|
|
166664
|
+
const raw2 = core6.getInput("output_schema");
|
|
166665
|
+
if (!raw2) return void 0;
|
|
166666
|
+
let parsed2;
|
|
166667
|
+
try {
|
|
166668
|
+
parsed2 = JSON.parse(raw2);
|
|
166669
|
+
} catch {
|
|
166670
|
+
throw new Error(`invalid output_schema: not valid JSON`);
|
|
166671
|
+
}
|
|
166672
|
+
if (!parsed2 || typeof parsed2 !== "object" || Array.isArray(parsed2)) {
|
|
166673
|
+
throw new Error(`invalid output_schema: must be a JSON object`);
|
|
166674
|
+
}
|
|
166675
|
+
log.info("\xBB structured output schema provided \u2014 output will be required");
|
|
166676
|
+
return parsed2;
|
|
166677
|
+
}
|
|
166678
|
+
|
|
166616
166679
|
// utils/proxy.ts
|
|
166617
166680
|
var core8 = __toESM(require_core(), 1);
|
|
166618
166681
|
|
|
@@ -167160,6 +167223,7 @@ var defaultSettings = {
|
|
|
167160
167223
|
prApproveEnabled: false,
|
|
167161
167224
|
autoMergeEnabled: false,
|
|
167162
167225
|
signedCommits: false,
|
|
167226
|
+
repoIntelligence: false,
|
|
167163
167227
|
progressComments: true,
|
|
167164
167228
|
statusChecks: true,
|
|
167165
167229
|
modeInstructions: {},
|
|
@@ -167299,7 +167363,8 @@ function formatAgentHangBody(input) {
|
|
|
167299
167363
|
const headline = `**${input.diagnostic.label} ${verb}**${cause}`;
|
|
167300
167364
|
const explanation = formatExplanation({
|
|
167301
167365
|
isHang: input.isHang,
|
|
167302
|
-
errorMessage: input.errorMessage
|
|
167366
|
+
errorMessage: input.errorMessage,
|
|
167367
|
+
idleSec: input.diagnostic.idleSec
|
|
167303
167368
|
});
|
|
167304
167369
|
const parts = [headline, "", `${explanation} ${formatEventsPart(input.diagnostic)}`];
|
|
167305
167370
|
const tail = renderStderrTail(input.diagnostic.recentStderr);
|
|
@@ -167320,7 +167385,7 @@ function formatAgentHangBody(input) {
|
|
|
167320
167385
|
}
|
|
167321
167386
|
function formatExplanation(input) {
|
|
167322
167387
|
if (!input.isHang) return `The agent exited unexpectedly: ${input.errorMessage}`;
|
|
167323
|
-
const idleSec = parseIdleSec(input.errorMessage);
|
|
167388
|
+
const idleSec = input.idleSec ?? parseIdleSec(input.errorMessage);
|
|
167324
167389
|
if (idleSec === void 0) {
|
|
167325
167390
|
return "The agent stopped emitting events and was killed by the activity-timeout watchdog.";
|
|
167326
167391
|
}
|
|
@@ -167331,11 +167396,13 @@ function parseIdleSec(message) {
|
|
|
167331
167396
|
return match3 ? Number(match3[1]) : void 0;
|
|
167332
167397
|
}
|
|
167333
167398
|
function formatEventsPart(diagnostic) {
|
|
167334
|
-
if (diagnostic.
|
|
167399
|
+
if (diagnostic.lastProviderError) {
|
|
167335
167400
|
return `${diagnostic.eventCount} events were processed before the failure.`;
|
|
167336
167401
|
}
|
|
167337
|
-
if (diagnostic.
|
|
167338
|
-
|
|
167402
|
+
if (!diagnostic.sawModelOutput) {
|
|
167403
|
+
return "The model produced no output at all before the stall \u2014 the request was sent but nothing came back. This is usually transient; re-running often succeeds.";
|
|
167404
|
+
}
|
|
167405
|
+
return `${diagnostic.eventCount} events were processed before the failure.`;
|
|
167339
167406
|
}
|
|
167340
167407
|
function renderStderrTail(lines) {
|
|
167341
167408
|
if (lines.length === 0) return "";
|
|
@@ -167691,8 +167758,8 @@ function getCurrentWorkflowFilename() {
|
|
|
167691
167758
|
}
|
|
167692
167759
|
|
|
167693
167760
|
// utils/runStatusCheck.ts
|
|
167694
|
-
var RUN_STATUS_CHECK_NAME = "
|
|
167695
|
-
var APPROVAL_CHECK_NAME = "
|
|
167761
|
+
var RUN_STATUS_CHECK_NAME = "pullfrog";
|
|
167762
|
+
var APPROVAL_CHECK_NAME = "pullfrog-approval";
|
|
167696
167763
|
function parseCheckRunId(raw2) {
|
|
167697
167764
|
if (!raw2?.id) return void 0;
|
|
167698
167765
|
const id = parseInt(raw2.id, 10);
|
|
@@ -168217,7 +168284,7 @@ async function main() {
|
|
|
168217
168284
|
_promise2 && await _promise2;
|
|
168218
168285
|
}
|
|
168219
168286
|
}
|
|
168220
|
-
createTempDirectory();
|
|
168287
|
+
const tmpdir4 = createTempDirectory();
|
|
168221
168288
|
const opencodeCliPath = await agents.opencode.install();
|
|
168222
168289
|
captureBaselineModels(opencodeCliPath);
|
|
168223
168290
|
if (runContext.dbSecrets) {
|
|
@@ -168271,7 +168338,6 @@ async function main() {
|
|
|
168271
168338
|
if (payload.cwd && process.cwd() !== payload.cwd) {
|
|
168272
168339
|
process.chdir(payload.cwd);
|
|
168273
168340
|
}
|
|
168274
|
-
const tmpdir4 = createTempDirectory();
|
|
168275
168341
|
const originalBody = payload.event.body;
|
|
168276
168342
|
const resolvedBody = await resolveBody({
|
|
168277
168343
|
event: payload.event,
|
|
@@ -168380,6 +168446,7 @@ async function main() {
|
|
|
168380
168446
|
prApproveEnabled: runContext.repoSettings.prApproveEnabled,
|
|
168381
168447
|
autoMergeEnabled: runContext.repoSettings.autoMergeEnabled,
|
|
168382
168448
|
signedCommits: runContext.repoSettings.signedCommits,
|
|
168449
|
+
repoIntelligence: runContext.repoSettings.repoIntelligence,
|
|
168383
168450
|
modeInstructions: runContext.repoSettings.modeInstructions,
|
|
168384
168451
|
toolState,
|
|
168385
168452
|
runId: runInfo.runId,
|
|
@@ -168454,6 +168521,7 @@ async function main() {
|
|
|
168454
168521
|
agentId,
|
|
168455
168522
|
outputSchema,
|
|
168456
168523
|
signedCommits: runContext.repoSettings.signedCommits,
|
|
168524
|
+
repoIntelligence: runContext.repoSettings.repoIntelligence,
|
|
168457
168525
|
learningsFilePath: toolState.learningsFilePath ?? null,
|
|
168458
168526
|
learningsHeadings: runContext.repoSettings.learningsHeadings,
|
|
168459
168527
|
setupHookFailure: describeSetupFailure(setupHook.failure),
|
|
@@ -169650,7 +169718,7 @@ async function runCli4(input) {
|
|
|
169650
169718
|
}
|
|
169651
169719
|
|
|
169652
169720
|
// cli.ts
|
|
169653
|
-
var VERSION10 = "0.1.
|
|
169721
|
+
var VERSION10 = "0.1.51";
|
|
169654
169722
|
var bin = basename2(process.argv[1] || "");
|
|
169655
169723
|
var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
|
|
169656
169724
|
var rawArgs = process.argv.slice(2);
|