pullfrog 0.1.33 → 0.1.35
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/dist/agents/opencodeShared.d.ts +1 -1
- package/dist/cli.mjs +541 -244
- package/dist/index.js +142 -97
- package/dist/internal/index.d.ts +0 -1
- package/dist/internal.js +82 -73
- package/dist/models.d.ts +7 -2
- package/dist/utils/autoMerge.d.ts +16 -25
- package/dist/utils/proxy.d.ts +1 -0
- package/package.json +1 -1
- package/dist/utils/checksGate.d.ts +0 -45
package/dist/index.js
CHANGED
|
@@ -99859,37 +99859,40 @@ var providers = {
|
|
|
99859
99859
|
managedCredentials: ["CODEX_AUTH_JSON"],
|
|
99860
99860
|
models: {
|
|
99861
99861
|
gpt: {
|
|
99862
|
-
displayName: "GPT",
|
|
99863
|
-
resolve: "openai/gpt-5.
|
|
99864
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
99862
|
+
displayName: "GPT Sol",
|
|
99863
|
+
resolve: "openai/gpt-5.6-sol",
|
|
99864
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
99865
99865
|
preferred: true,
|
|
99866
|
-
subagentModel: "gpt-
|
|
99866
|
+
subagentModel: "gpt-terra"
|
|
99867
99867
|
},
|
|
99868
|
+
// Sol served at reasoning.mode=pro — same $/token as Sol, just more tokens
|
|
99869
|
+
// burned; not a pricier premium tier. models.dev has no -pro id, so direct-key
|
|
99870
|
+
// (BYOK) resolves to plain Sol; only the Router/OpenRouter path gets sol-pro.
|
|
99868
99871
|
"gpt-pro": {
|
|
99869
|
-
displayName: "GPT Pro",
|
|
99870
|
-
|
|
99871
|
-
|
|
99872
|
+
displayName: "GPT Sol Pro",
|
|
99873
|
+
description: "Maximum reasoning effort",
|
|
99874
|
+
resolve: "openai/gpt-5.6-sol",
|
|
99875
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
99872
99876
|
subagentModel: "gpt"
|
|
99873
99877
|
},
|
|
99874
|
-
//
|
|
99875
|
-
//
|
|
99876
|
-
//
|
|
99877
|
-
"gpt-
|
|
99878
|
-
displayName: "GPT
|
|
99879
|
-
resolve: "openai/gpt-5.
|
|
99880
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
99881
|
-
hidden: true
|
|
99878
|
+
// gpt-5.6's balanced mid-tier (Sol/Terra/Luna are durable capability tiers,
|
|
99879
|
+
// not version bumps). selectable on its own and doubles as `gpt`'s cheaper
|
|
99880
|
+
// lens-fanout subagent — replaces the old hidden gpt-5.4 subagent target.
|
|
99881
|
+
"gpt-terra": {
|
|
99882
|
+
displayName: "GPT Terra",
|
|
99883
|
+
resolve: "openai/gpt-5.6-terra",
|
|
99884
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
99882
99885
|
},
|
|
99883
99886
|
"gpt-mini": {
|
|
99884
|
-
displayName: "GPT
|
|
99885
|
-
resolve: "openai/gpt-5.
|
|
99886
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
99887
|
+
displayName: "GPT Luna",
|
|
99888
|
+
resolve: "openai/gpt-5.6-luna",
|
|
99889
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
99887
99890
|
},
|
|
99888
99891
|
// legacy aliases — openai unified the codex line into the main GPT family
|
|
99889
99892
|
// and is shutting down every "-codex" snapshot on 2026-07-23. transparently
|
|
99890
99893
|
// upgrade existing users via the fallback chain. UI display sites resolve
|
|
99891
99894
|
// to the terminal alias's label (so dropdown trigger + PR footers show
|
|
99892
|
-
// "GPT" / "GPT
|
|
99895
|
+
// "GPT Sol" / "GPT Luna", not the historical name).
|
|
99893
99896
|
"gpt-codex": {
|
|
99894
99897
|
displayName: "GPT Codex",
|
|
99895
99898
|
resolve: "openai/gpt-5.3-codex",
|
|
@@ -99902,6 +99905,13 @@ var providers = {
|
|
|
99902
99905
|
openRouterResolve: "openrouter/openai/gpt-5.1-codex-mini",
|
|
99903
99906
|
fallback: "openai/gpt-mini"
|
|
99904
99907
|
},
|
|
99908
|
+
// dropped hidden subagent tier — folds stored pins forward to gpt (Sol).
|
|
99909
|
+
"gpt-5.4": {
|
|
99910
|
+
displayName: "GPT 5.4",
|
|
99911
|
+
resolve: "openai/gpt-5.4",
|
|
99912
|
+
openRouterResolve: "openrouter/openai/gpt-5.4",
|
|
99913
|
+
fallback: "openai/gpt"
|
|
99914
|
+
},
|
|
99905
99915
|
o3: {
|
|
99906
99916
|
displayName: "O3",
|
|
99907
99917
|
resolve: "openai/o3",
|
|
@@ -100031,28 +100041,29 @@ var providers = {
|
|
|
100031
100041
|
openRouterResolve: "openrouter/anthropic/claude-haiku-4.5"
|
|
100032
100042
|
},
|
|
100033
100043
|
gpt: {
|
|
100034
|
-
displayName: "GPT",
|
|
100035
|
-
resolve: "opencode/gpt-5.
|
|
100036
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
100037
|
-
subagentModel: "gpt-
|
|
100044
|
+
displayName: "GPT Sol",
|
|
100045
|
+
resolve: "opencode/gpt-5.6-sol",
|
|
100046
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
100047
|
+
subagentModel: "gpt-terra"
|
|
100038
100048
|
},
|
|
100049
|
+
// see openai/gpt-pro — Zen has no -pro id, so direct resolves to plain Sol.
|
|
100039
100050
|
"gpt-pro": {
|
|
100040
|
-
displayName: "GPT Pro",
|
|
100041
|
-
|
|
100042
|
-
|
|
100051
|
+
displayName: "GPT Sol Pro",
|
|
100052
|
+
description: "Maximum reasoning effort",
|
|
100053
|
+
resolve: "opencode/gpt-5.6-sol",
|
|
100054
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100043
100055
|
subagentModel: "gpt"
|
|
100044
100056
|
},
|
|
100045
|
-
//
|
|
100046
|
-
"gpt-
|
|
100047
|
-
displayName: "GPT
|
|
100048
|
-
resolve: "opencode/gpt-5.
|
|
100049
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
100050
|
-
hidden: true
|
|
100057
|
+
// gpt-5.6 balanced mid-tier — selectable + `gpt`'s subagent. see openai above.
|
|
100058
|
+
"gpt-terra": {
|
|
100059
|
+
displayName: "GPT Terra",
|
|
100060
|
+
resolve: "opencode/gpt-5.6-terra",
|
|
100061
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
100051
100062
|
},
|
|
100052
100063
|
"gpt-mini": {
|
|
100053
|
-
displayName: "GPT
|
|
100054
|
-
resolve: "opencode/gpt-5.
|
|
100055
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
100064
|
+
displayName: "GPT Luna",
|
|
100065
|
+
resolve: "opencode/gpt-5.6-luna",
|
|
100066
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
100056
100067
|
},
|
|
100057
100068
|
// legacy aliases — see openai provider above for context.
|
|
100058
100069
|
"gpt-codex": {
|
|
@@ -100067,6 +100078,13 @@ var providers = {
|
|
|
100067
100078
|
openRouterResolve: "openrouter/openai/gpt-5.1-codex-mini",
|
|
100068
100079
|
fallback: "opencode/gpt-mini"
|
|
100069
100080
|
},
|
|
100081
|
+
// dropped hidden subagent tier — folds stored pins forward to gpt (Sol).
|
|
100082
|
+
"gpt-5.4": {
|
|
100083
|
+
displayName: "GPT 5.4",
|
|
100084
|
+
resolve: "opencode/gpt-5.4",
|
|
100085
|
+
openRouterResolve: "openrouter/openai/gpt-5.4",
|
|
100086
|
+
fallback: "opencode/gpt"
|
|
100087
|
+
},
|
|
100070
100088
|
"gemini-pro": {
|
|
100071
100089
|
displayName: "Gemini Pro",
|
|
100072
100090
|
resolve: "opencode/gemini-3.1-pro",
|
|
@@ -100183,29 +100201,34 @@ var providers = {
|
|
|
100183
100201
|
resolve: "openrouter/~anthropic/claude-haiku-latest",
|
|
100184
100202
|
openRouterResolve: "openrouter/~anthropic/claude-haiku-latest"
|
|
100185
100203
|
},
|
|
100204
|
+
// pinned to the explicit gpt-5.6 tiers (not the ~openai/gpt-latest rolling
|
|
100205
|
+
// alias): after the Sol/Terra/Luna rename, ~gpt-mini-latest no longer maps
|
|
100206
|
+
// to Luna, so rolling aliases would silently diverge `gpt`/`gpt-mini` from
|
|
100207
|
+
// the chosen tiers across funding paths.
|
|
100186
100208
|
gpt: {
|
|
100187
|
-
displayName: "GPT",
|
|
100188
|
-
resolve: "openrouter
|
|
100189
|
-
openRouterResolve: "openrouter
|
|
100190
|
-
subagentModel: "gpt-
|
|
100209
|
+
displayName: "GPT Sol",
|
|
100210
|
+
resolve: "openrouter/openai/gpt-5.6-sol",
|
|
100211
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
100212
|
+
subagentModel: "gpt-terra"
|
|
100191
100213
|
},
|
|
100214
|
+
// see openai/gpt-pro. openrouter serves sol-pro directly on both routes.
|
|
100192
100215
|
"gpt-pro": {
|
|
100193
|
-
displayName: "GPT Pro",
|
|
100194
|
-
|
|
100195
|
-
|
|
100216
|
+
displayName: "GPT Sol Pro",
|
|
100217
|
+
description: "Maximum reasoning effort",
|
|
100218
|
+
resolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100219
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100196
100220
|
subagentModel: "gpt"
|
|
100197
100221
|
},
|
|
100198
|
-
//
|
|
100199
|
-
"gpt-
|
|
100200
|
-
displayName: "GPT
|
|
100201
|
-
resolve: "openrouter/openai/gpt-5.
|
|
100202
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
100203
|
-
hidden: true
|
|
100222
|
+
// gpt-5.6 balanced mid-tier — selectable + `gpt`'s subagent. see openai above.
|
|
100223
|
+
"gpt-terra": {
|
|
100224
|
+
displayName: "GPT Terra",
|
|
100225
|
+
resolve: "openrouter/openai/gpt-5.6-terra",
|
|
100226
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
100204
100227
|
},
|
|
100205
100228
|
"gpt-mini": {
|
|
100206
|
-
displayName: "GPT
|
|
100207
|
-
resolve: "openrouter
|
|
100208
|
-
openRouterResolve: "openrouter
|
|
100229
|
+
displayName: "GPT Luna",
|
|
100230
|
+
resolve: "openrouter/openai/gpt-5.6-luna",
|
|
100231
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
100209
100232
|
},
|
|
100210
100233
|
// legacy aliases — see openai provider for context.
|
|
100211
100234
|
"gpt-codex": {
|
|
@@ -100220,6 +100243,13 @@ var providers = {
|
|
|
100220
100243
|
openRouterResolve: "openrouter/openai/gpt-5.1-codex-mini",
|
|
100221
100244
|
fallback: "openrouter/gpt-mini"
|
|
100222
100245
|
},
|
|
100246
|
+
// dropped hidden subagent tier — folds stored pins forward to gpt (Sol).
|
|
100247
|
+
"gpt-5.4": {
|
|
100248
|
+
displayName: "GPT 5.4",
|
|
100249
|
+
resolve: "openrouter/openai/gpt-5.4",
|
|
100250
|
+
openRouterResolve: "openrouter/openai/gpt-5.4",
|
|
100251
|
+
fallback: "openrouter/gpt"
|
|
100252
|
+
},
|
|
100223
100253
|
"o4-mini": {
|
|
100224
100254
|
displayName: "O4 Mini",
|
|
100225
100255
|
resolve: "openrouter/openai/o4-mini",
|
|
@@ -100299,6 +100329,7 @@ var modelAliases = Object.entries(providers).flatMap(
|
|
|
100299
100329
|
slug: `${providerKey}/${modelId}`,
|
|
100300
100330
|
provider: providerKey,
|
|
100301
100331
|
displayName: def.displayName,
|
|
100332
|
+
description: def.description,
|
|
100302
100333
|
resolve: def.resolve,
|
|
100303
100334
|
openRouterResolve: def.openRouterResolve,
|
|
100304
100335
|
preferred: def.preferred ?? false,
|
|
@@ -101041,7 +101072,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
101041
101072
|
// package.json
|
|
101042
101073
|
var package_default = {
|
|
101043
101074
|
name: "pullfrog",
|
|
101044
|
-
version: "0.1.
|
|
101075
|
+
version: "0.1.35",
|
|
101045
101076
|
type: "module",
|
|
101046
101077
|
bin: {
|
|
101047
101078
|
pullfrog: "dist/cli.mjs",
|
|
@@ -163558,6 +163589,11 @@ async function mintProxyKey(ctx) {
|
|
|
163558
163589
|
body?.error ?? "billing service temporarily unavailable \u2014 retry shortly"
|
|
163559
163590
|
);
|
|
163560
163591
|
}
|
|
163592
|
+
if (response.status === 404) {
|
|
163593
|
+
throw new TransientError(
|
|
163594
|
+
"Pullfrog couldn't match this repository to its account \u2014 it may have just been renamed or transferred. The link refreshes automatically on the next run; if it keeps failing, reinstall the GitHub App on the repo's current owner."
|
|
163595
|
+
);
|
|
163596
|
+
}
|
|
163561
163597
|
if (!response.ok) {
|
|
163562
163598
|
log.warning(`proxy key mint failed (${response.status})`);
|
|
163563
163599
|
return null;
|
|
@@ -164122,28 +164158,7 @@ ${genericBody}`,
|
|
|
164122
164158
|
// utils/runLifecycle.ts
|
|
164123
164159
|
var core10 = __toESM(require_core(), 1);
|
|
164124
164160
|
|
|
164125
|
-
// utils/checksGate.ts
|
|
164126
|
-
var OK_CONCLUSIONS = /* @__PURE__ */ new Set(["success", "neutral", "skipped"]);
|
|
164127
|
-
var PULLFROG_CHECKS = /* @__PURE__ */ new Set(["pullfrog", "pullfrog-approval"]);
|
|
164128
|
-
function checkRunsGate(params) {
|
|
164129
|
-
for (const run of params.checkRuns) {
|
|
164130
|
-
if (PULLFROG_CHECKS.has(run.name.toLowerCase())) continue;
|
|
164131
|
-
if (run.status !== "completed")
|
|
164132
|
-
return { ok: false, reason: `check "${run.name}" ${run.status}` };
|
|
164133
|
-
if (!OK_CONCLUSIONS.has(run.conclusion ?? "")) {
|
|
164134
|
-
return { ok: false, reason: `check "${run.name}" concluded ${run.conclusion}` };
|
|
164135
|
-
}
|
|
164136
|
-
}
|
|
164137
|
-
return { ok: true, reason: "all checks passed" };
|
|
164138
|
-
}
|
|
164139
|
-
function hasVerifiedCheck(params) {
|
|
164140
|
-
return params.checkRuns.some(
|
|
164141
|
-
(r) => !PULLFROG_CHECKS.has(r.name.toLowerCase()) && r.status === "completed"
|
|
164142
|
-
);
|
|
164143
|
-
}
|
|
164144
|
-
|
|
164145
164161
|
// utils/autoMerge.ts
|
|
164146
|
-
var NON_MERGEABLE_STATES = /* @__PURE__ */ new Set(["dirty", "behind", "blocked"]);
|
|
164147
164162
|
function hasBlockingHumanReview(reviews) {
|
|
164148
164163
|
const latestByReviewer = /* @__PURE__ */ new Map();
|
|
164149
164164
|
for (const review of reviews) {
|
|
@@ -164160,6 +164175,20 @@ function hasBlockingHumanReview(reviews) {
|
|
|
164160
164175
|
}
|
|
164161
164176
|
return false;
|
|
164162
164177
|
}
|
|
164178
|
+
var ENABLE_AUTO_MERGE = (
|
|
164179
|
+
/* GraphQL */
|
|
164180
|
+
`
|
|
164181
|
+
mutation ($pullRequestId: ID!, $headSha: GitObjectID!) {
|
|
164182
|
+
enablePullRequestAutoMerge(input: {
|
|
164183
|
+
pullRequestId: $pullRequestId
|
|
164184
|
+
mergeMethod: SQUASH
|
|
164185
|
+
expectedHeadOid: $headSha
|
|
164186
|
+
}) { clientMutationId }
|
|
164187
|
+
}`
|
|
164188
|
+
);
|
|
164189
|
+
var isAlreadyMergeable = (error49) => error49 instanceof Error && /clean status/i.test(error49.message);
|
|
164190
|
+
var isHeadChanged = (error49) => error49 instanceof Error && /head has changed|expected head/i.test(error49.message);
|
|
164191
|
+
var isAutoMergeDisallowed = (error49) => error49 instanceof Error && /not allowed/i.test(error49.message);
|
|
164163
164192
|
async function autoMergeAfterApprove(ctx) {
|
|
164164
164193
|
if (!ctx.autoMergeEnabled) return;
|
|
164165
164194
|
if (!ctx.prApproveEnabled) return;
|
|
@@ -164170,6 +164199,12 @@ async function autoMergeAfterApprove(ctx) {
|
|
|
164170
164199
|
const skip = (reason) => log.info(
|
|
164171
164200
|
`autoMerge: pr=#${pullNumber} approvalSha=${approval.sha?.slice(0, 7)} \u2192 skipped: ${reason}`
|
|
164172
164201
|
);
|
|
164202
|
+
const comment = (body) => ctx.octokit.rest.issues.createComment({
|
|
164203
|
+
owner: ctx.repo.owner,
|
|
164204
|
+
repo: ctx.repo.name,
|
|
164205
|
+
issue_number: pullNumber,
|
|
164206
|
+
body: addFooter(ctx, body)
|
|
164207
|
+
}).catch((err) => log.debug(`autoMerge comment failed: ${err}`));
|
|
164173
164208
|
const pr = await ctx.octokit.rest.pulls.get({
|
|
164174
164209
|
owner: ctx.repo.owner,
|
|
164175
164210
|
repo: ctx.repo.name,
|
|
@@ -164177,6 +164212,7 @@ async function autoMergeAfterApprove(ctx) {
|
|
|
164177
164212
|
});
|
|
164178
164213
|
if (pr.data.state !== "open") return skip("pr not open");
|
|
164179
164214
|
if (pr.data.draft) return skip("pr is draft");
|
|
164215
|
+
if (pr.data.auto_merge) return skip("auto-merge already enabled");
|
|
164180
164216
|
const headSha = pr.data.head.sha;
|
|
164181
164217
|
if (approval.sha !== headSha) return skip(`approval sha != head ${headSha.slice(0, 7)}`);
|
|
164182
164218
|
const outstanding = await countOutstandingPullfrogThreads(ctx, pullNumber);
|
|
@@ -164188,40 +164224,49 @@ async function autoMergeAfterApprove(ctx) {
|
|
|
164188
164224
|
per_page: 100
|
|
164189
164225
|
});
|
|
164190
164226
|
if (hasBlockingHumanReview(reviews)) return skip("human changes requested");
|
|
164191
|
-
|
|
164192
|
-
|
|
164193
|
-
|
|
164227
|
+
try {
|
|
164228
|
+
await op(
|
|
164229
|
+
() => ctx.octokit.graphql(ENABLE_AUTO_MERGE, {
|
|
164230
|
+
pullRequestId: pr.data.node_id,
|
|
164231
|
+
headSha
|
|
164232
|
+
}),
|
|
164233
|
+
{
|
|
164234
|
+
name: "enablePullRequestAutoMerge",
|
|
164235
|
+
retries: [500, 2e3],
|
|
164236
|
+
bail: (error49) => !isTransientOctokitError(error49)
|
|
164237
|
+
}
|
|
164238
|
+
)();
|
|
164239
|
+
log.info(`autoMerge: pr=#${pullNumber} @ ${headSha.slice(0, 7)} \u2192 native auto-merge enabled`);
|
|
164240
|
+
await comment(
|
|
164241
|
+
"> \u2705 Approved \u2014 auto-merge enabled; GitHub will merge once required checks pass."
|
|
164242
|
+
);
|
|
164243
|
+
return;
|
|
164244
|
+
} catch (error49) {
|
|
164245
|
+
if (isHeadChanged(error49)) return skip("head moved during enable");
|
|
164246
|
+
if (isAutoMergeDisallowed(error49)) {
|
|
164247
|
+
await comment(
|
|
164248
|
+
"> \u26A0\uFE0F Approved, but auto-merge is off for this repo. Enable `Allow auto-merge` in Settings > General > Pull Requests."
|
|
164249
|
+
);
|
|
164250
|
+
return;
|
|
164251
|
+
}
|
|
164252
|
+
if (!isAlreadyMergeable(error49)) throw error49;
|
|
164194
164253
|
}
|
|
164195
|
-
const
|
|
164196
|
-
|
|
164197
|
-
repo: ctx.repo.name,
|
|
164198
|
-
ref: headSha,
|
|
164199
|
-
per_page: 100
|
|
164200
|
-
});
|
|
164201
|
-
const gate = checkRunsGate({ checkRuns });
|
|
164202
|
-
if (!gate.ok) return skip(`ci: ${gate.reason}`);
|
|
164203
|
-
if (!hasVerifiedCheck({ checkRuns })) return skip("no completed external check-run to verify");
|
|
164254
|
+
const base = await ctx.octokit.rest.repos.getBranch({ owner: ctx.repo.owner, repo: ctx.repo.name, branch: pr.data.base.ref }).catch(() => null);
|
|
164255
|
+
if (!base?.data.protected) return skip("base branch not protected \u2014 refusing CI-ungated merge");
|
|
164204
164256
|
const merge4 = await ctx.octokit.rest.pulls.merge({
|
|
164205
164257
|
owner: ctx.repo.owner,
|
|
164206
164258
|
repo: ctx.repo.name,
|
|
164207
164259
|
pull_number: pullNumber,
|
|
164208
164260
|
sha: headSha,
|
|
164209
164261
|
merge_method: "squash",
|
|
164210
|
-
commit_title: `${pr.data.title} (#${pullNumber})
|
|
164211
|
-
commit_message: "merged autonomously by Pullfrog after a clean approval."
|
|
164262
|
+
commit_title: `${pr.data.title} (#${pullNumber})`
|
|
164212
164263
|
});
|
|
164213
164264
|
log.info(
|
|
164214
|
-
`autoMerge: pr=#${pullNumber}
|
|
164265
|
+
`autoMerge: pr=#${pullNumber} @ ${headSha.slice(0, 7)} \u2192 merged directly ${merge4.data.sha?.slice(0, 7)}`
|
|
164266
|
+
);
|
|
164267
|
+
await comment(
|
|
164268
|
+
"> \u2705 Merged autonomously after Pullfrog approved this PR and resolved all of its own review threads."
|
|
164215
164269
|
);
|
|
164216
|
-
await ctx.octokit.rest.issues.createComment({
|
|
164217
|
-
owner: ctx.repo.owner,
|
|
164218
|
-
repo: ctx.repo.name,
|
|
164219
|
-
issue_number: pullNumber,
|
|
164220
|
-
body: addFooter(
|
|
164221
|
-
ctx,
|
|
164222
|
-
"> \u2705 Merged autonomously after Pullfrog approved this PR and resolved all of its own review threads."
|
|
164223
|
-
)
|
|
164224
|
-
}).catch((err) => log.debug(`autoMerge comment failed: ${err}`));
|
|
164225
164270
|
}
|
|
164226
164271
|
|
|
164227
164272
|
// utils/reviewCleanup.ts
|
package/dist/internal/index.d.ts
CHANGED
|
@@ -8,7 +8,6 @@ export type { Mode } from "../modes.ts";
|
|
|
8
8
|
export { modes } from "../modes.ts";
|
|
9
9
|
export type { BuildPullfrogFooterParams, WorkflowRunFooterInfo, } from "../utils/buildPullfrogFooter.ts";
|
|
10
10
|
export { buildPullfrogFooter, PULLFROG_DIVIDER, stripExistingFooter, } from "../utils/buildPullfrogFooter.ts";
|
|
11
|
-
export { checkRunsGate, hasVerifiedCheck } from "../utils/checksGate.ts";
|
|
12
11
|
export type { CodexAuthBody } from "../utils/codexOAuth.ts";
|
|
13
12
|
export { decodeJwtExpMs, OAuthInvalidGrantError, parseCodexAuthBody, refreshCodexAuthBody, stringifyCodexAuthBody, } from "../utils/codexOAuth.ts";
|
|
14
13
|
export type { ResourceUsage, UsageSummary } from "../utils/github.ts";
|
package/dist/internal.js
CHANGED
|
@@ -50,37 +50,40 @@ var providers = {
|
|
|
50
50
|
managedCredentials: ["CODEX_AUTH_JSON"],
|
|
51
51
|
models: {
|
|
52
52
|
gpt: {
|
|
53
|
-
displayName: "GPT",
|
|
54
|
-
resolve: "openai/gpt-5.
|
|
55
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
53
|
+
displayName: "GPT Sol",
|
|
54
|
+
resolve: "openai/gpt-5.6-sol",
|
|
55
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
56
56
|
preferred: true,
|
|
57
|
-
subagentModel: "gpt-
|
|
57
|
+
subagentModel: "gpt-terra"
|
|
58
58
|
},
|
|
59
|
+
// Sol served at reasoning.mode=pro — same $/token as Sol, just more tokens
|
|
60
|
+
// burned; not a pricier premium tier. models.dev has no -pro id, so direct-key
|
|
61
|
+
// (BYOK) resolves to plain Sol; only the Router/OpenRouter path gets sol-pro.
|
|
59
62
|
"gpt-pro": {
|
|
60
|
-
displayName: "GPT Pro",
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
displayName: "GPT Sol Pro",
|
|
64
|
+
description: "Maximum reasoning effort",
|
|
65
|
+
resolve: "openai/gpt-5.6-sol",
|
|
66
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
63
67
|
subagentModel: "gpt"
|
|
64
68
|
},
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
"gpt-
|
|
69
|
-
displayName: "GPT
|
|
70
|
-
resolve: "openai/gpt-5.
|
|
71
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
72
|
-
hidden: true
|
|
69
|
+
// gpt-5.6's balanced mid-tier (Sol/Terra/Luna are durable capability tiers,
|
|
70
|
+
// not version bumps). selectable on its own and doubles as `gpt`'s cheaper
|
|
71
|
+
// lens-fanout subagent — replaces the old hidden gpt-5.4 subagent target.
|
|
72
|
+
"gpt-terra": {
|
|
73
|
+
displayName: "GPT Terra",
|
|
74
|
+
resolve: "openai/gpt-5.6-terra",
|
|
75
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
73
76
|
},
|
|
74
77
|
"gpt-mini": {
|
|
75
|
-
displayName: "GPT
|
|
76
|
-
resolve: "openai/gpt-5.
|
|
77
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
78
|
+
displayName: "GPT Luna",
|
|
79
|
+
resolve: "openai/gpt-5.6-luna",
|
|
80
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
78
81
|
},
|
|
79
82
|
// legacy aliases — openai unified the codex line into the main GPT family
|
|
80
83
|
// and is shutting down every "-codex" snapshot on 2026-07-23. transparently
|
|
81
84
|
// upgrade existing users via the fallback chain. UI display sites resolve
|
|
82
85
|
// to the terminal alias's label (so dropdown trigger + PR footers show
|
|
83
|
-
// "GPT" / "GPT
|
|
86
|
+
// "GPT Sol" / "GPT Luna", not the historical name).
|
|
84
87
|
"gpt-codex": {
|
|
85
88
|
displayName: "GPT Codex",
|
|
86
89
|
resolve: "openai/gpt-5.3-codex",
|
|
@@ -93,6 +96,13 @@ var providers = {
|
|
|
93
96
|
openRouterResolve: "openrouter/openai/gpt-5.1-codex-mini",
|
|
94
97
|
fallback: "openai/gpt-mini"
|
|
95
98
|
},
|
|
99
|
+
// dropped hidden subagent tier — folds stored pins forward to gpt (Sol).
|
|
100
|
+
"gpt-5.4": {
|
|
101
|
+
displayName: "GPT 5.4",
|
|
102
|
+
resolve: "openai/gpt-5.4",
|
|
103
|
+
openRouterResolve: "openrouter/openai/gpt-5.4",
|
|
104
|
+
fallback: "openai/gpt"
|
|
105
|
+
},
|
|
96
106
|
o3: {
|
|
97
107
|
displayName: "O3",
|
|
98
108
|
resolve: "openai/o3",
|
|
@@ -222,28 +232,29 @@ var providers = {
|
|
|
222
232
|
openRouterResolve: "openrouter/anthropic/claude-haiku-4.5"
|
|
223
233
|
},
|
|
224
234
|
gpt: {
|
|
225
|
-
displayName: "GPT",
|
|
226
|
-
resolve: "opencode/gpt-5.
|
|
227
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
228
|
-
subagentModel: "gpt-
|
|
235
|
+
displayName: "GPT Sol",
|
|
236
|
+
resolve: "opencode/gpt-5.6-sol",
|
|
237
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
238
|
+
subagentModel: "gpt-terra"
|
|
229
239
|
},
|
|
240
|
+
// see openai/gpt-pro — Zen has no -pro id, so direct resolves to plain Sol.
|
|
230
241
|
"gpt-pro": {
|
|
231
|
-
displayName: "GPT Pro",
|
|
232
|
-
|
|
233
|
-
|
|
242
|
+
displayName: "GPT Sol Pro",
|
|
243
|
+
description: "Maximum reasoning effort",
|
|
244
|
+
resolve: "opencode/gpt-5.6-sol",
|
|
245
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
234
246
|
subagentModel: "gpt"
|
|
235
247
|
},
|
|
236
|
-
//
|
|
237
|
-
"gpt-
|
|
238
|
-
displayName: "GPT
|
|
239
|
-
resolve: "opencode/gpt-5.
|
|
240
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
241
|
-
hidden: true
|
|
248
|
+
// gpt-5.6 balanced mid-tier — selectable + `gpt`'s subagent. see openai above.
|
|
249
|
+
"gpt-terra": {
|
|
250
|
+
displayName: "GPT Terra",
|
|
251
|
+
resolve: "opencode/gpt-5.6-terra",
|
|
252
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
242
253
|
},
|
|
243
254
|
"gpt-mini": {
|
|
244
|
-
displayName: "GPT
|
|
245
|
-
resolve: "opencode/gpt-5.
|
|
246
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
255
|
+
displayName: "GPT Luna",
|
|
256
|
+
resolve: "opencode/gpt-5.6-luna",
|
|
257
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
247
258
|
},
|
|
248
259
|
// legacy aliases — see openai provider above for context.
|
|
249
260
|
"gpt-codex": {
|
|
@@ -258,6 +269,13 @@ var providers = {
|
|
|
258
269
|
openRouterResolve: "openrouter/openai/gpt-5.1-codex-mini",
|
|
259
270
|
fallback: "opencode/gpt-mini"
|
|
260
271
|
},
|
|
272
|
+
// dropped hidden subagent tier — folds stored pins forward to gpt (Sol).
|
|
273
|
+
"gpt-5.4": {
|
|
274
|
+
displayName: "GPT 5.4",
|
|
275
|
+
resolve: "opencode/gpt-5.4",
|
|
276
|
+
openRouterResolve: "openrouter/openai/gpt-5.4",
|
|
277
|
+
fallback: "opencode/gpt"
|
|
278
|
+
},
|
|
261
279
|
"gemini-pro": {
|
|
262
280
|
displayName: "Gemini Pro",
|
|
263
281
|
resolve: "opencode/gemini-3.1-pro",
|
|
@@ -374,29 +392,34 @@ var providers = {
|
|
|
374
392
|
resolve: "openrouter/~anthropic/claude-haiku-latest",
|
|
375
393
|
openRouterResolve: "openrouter/~anthropic/claude-haiku-latest"
|
|
376
394
|
},
|
|
395
|
+
// pinned to the explicit gpt-5.6 tiers (not the ~openai/gpt-latest rolling
|
|
396
|
+
// alias): after the Sol/Terra/Luna rename, ~gpt-mini-latest no longer maps
|
|
397
|
+
// to Luna, so rolling aliases would silently diverge `gpt`/`gpt-mini` from
|
|
398
|
+
// the chosen tiers across funding paths.
|
|
377
399
|
gpt: {
|
|
378
|
-
displayName: "GPT",
|
|
379
|
-
resolve: "openrouter
|
|
380
|
-
openRouterResolve: "openrouter
|
|
381
|
-
subagentModel: "gpt-
|
|
400
|
+
displayName: "GPT Sol",
|
|
401
|
+
resolve: "openrouter/openai/gpt-5.6-sol",
|
|
402
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
403
|
+
subagentModel: "gpt-terra"
|
|
382
404
|
},
|
|
405
|
+
// see openai/gpt-pro. openrouter serves sol-pro directly on both routes.
|
|
383
406
|
"gpt-pro": {
|
|
384
|
-
displayName: "GPT Pro",
|
|
385
|
-
|
|
386
|
-
|
|
407
|
+
displayName: "GPT Sol Pro",
|
|
408
|
+
description: "Maximum reasoning effort",
|
|
409
|
+
resolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
410
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
387
411
|
subagentModel: "gpt"
|
|
388
412
|
},
|
|
389
|
-
//
|
|
390
|
-
"gpt-
|
|
391
|
-
displayName: "GPT
|
|
392
|
-
resolve: "openrouter/openai/gpt-5.
|
|
393
|
-
openRouterResolve: "openrouter/openai/gpt-5.
|
|
394
|
-
hidden: true
|
|
413
|
+
// gpt-5.6 balanced mid-tier — selectable + `gpt`'s subagent. see openai above.
|
|
414
|
+
"gpt-terra": {
|
|
415
|
+
displayName: "GPT Terra",
|
|
416
|
+
resolve: "openrouter/openai/gpt-5.6-terra",
|
|
417
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
395
418
|
},
|
|
396
419
|
"gpt-mini": {
|
|
397
|
-
displayName: "GPT
|
|
398
|
-
resolve: "openrouter
|
|
399
|
-
openRouterResolve: "openrouter
|
|
420
|
+
displayName: "GPT Luna",
|
|
421
|
+
resolve: "openrouter/openai/gpt-5.6-luna",
|
|
422
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
400
423
|
},
|
|
401
424
|
// legacy aliases — see openai provider for context.
|
|
402
425
|
"gpt-codex": {
|
|
@@ -411,6 +434,13 @@ var providers = {
|
|
|
411
434
|
openRouterResolve: "openrouter/openai/gpt-5.1-codex-mini",
|
|
412
435
|
fallback: "openrouter/gpt-mini"
|
|
413
436
|
},
|
|
437
|
+
// dropped hidden subagent tier — folds stored pins forward to gpt (Sol).
|
|
438
|
+
"gpt-5.4": {
|
|
439
|
+
displayName: "GPT 5.4",
|
|
440
|
+
resolve: "openrouter/openai/gpt-5.4",
|
|
441
|
+
openRouterResolve: "openrouter/openai/gpt-5.4",
|
|
442
|
+
fallback: "openrouter/gpt"
|
|
443
|
+
},
|
|
414
444
|
"o4-mini": {
|
|
415
445
|
displayName: "O4 Mini",
|
|
416
446
|
resolve: "openrouter/openai/o4-mini",
|
|
@@ -499,6 +529,7 @@ var modelAliases = Object.entries(providers).flatMap(
|
|
|
499
529
|
slug: `${providerKey}/${modelId}`,
|
|
500
530
|
provider: providerKey,
|
|
501
531
|
displayName: def.displayName,
|
|
532
|
+
description: def.description,
|
|
502
533
|
resolve: def.resolve,
|
|
503
534
|
openRouterResolve: def.openRouterResolve,
|
|
504
535
|
preferred: def.preferred ?? false,
|
|
@@ -1245,26 +1276,6 @@ function stripExistingFooter(body) {
|
|
|
1245
1276
|
return body.substring(0, dividerIndex).trimEnd();
|
|
1246
1277
|
}
|
|
1247
1278
|
|
|
1248
|
-
// utils/checksGate.ts
|
|
1249
|
-
var OK_CONCLUSIONS = /* @__PURE__ */ new Set(["success", "neutral", "skipped"]);
|
|
1250
|
-
var PULLFROG_CHECKS = /* @__PURE__ */ new Set(["pullfrog", "pullfrog-approval"]);
|
|
1251
|
-
function checkRunsGate(params) {
|
|
1252
|
-
for (const run of params.checkRuns) {
|
|
1253
|
-
if (PULLFROG_CHECKS.has(run.name.toLowerCase())) continue;
|
|
1254
|
-
if (run.status !== "completed")
|
|
1255
|
-
return { ok: false, reason: `check "${run.name}" ${run.status}` };
|
|
1256
|
-
if (!OK_CONCLUSIONS.has(run.conclusion ?? "")) {
|
|
1257
|
-
return { ok: false, reason: `check "${run.name}" concluded ${run.conclusion}` };
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
return { ok: true, reason: "all checks passed" };
|
|
1261
|
-
}
|
|
1262
|
-
function hasVerifiedCheck(params) {
|
|
1263
|
-
return params.checkRuns.some(
|
|
1264
|
-
(r) => !PULLFROG_CHECKS.has(r.name.toLowerCase()) && r.status === "completed"
|
|
1265
|
-
);
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1268
1279
|
// utils/codexOAuth.ts
|
|
1269
1280
|
var CODEX_OAUTH_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
1270
1281
|
var CODEX_OAUTH_TOKEN_URL = "https://auth.openai.com/oauth/token";
|
|
@@ -1492,7 +1503,6 @@ export {
|
|
|
1492
1503
|
PULLFROG_DIVIDER,
|
|
1493
1504
|
TIMEOUT_DISABLED,
|
|
1494
1505
|
buildPullfrogFooter,
|
|
1495
|
-
checkRunsGate,
|
|
1496
1506
|
createLeapingProgressComment,
|
|
1497
1507
|
decodeJwtExpMs,
|
|
1498
1508
|
defaultAutoTier,
|
|
@@ -1503,7 +1513,6 @@ export {
|
|
|
1503
1513
|
getModelProvider,
|
|
1504
1514
|
getProgressComment,
|
|
1505
1515
|
getProviderDisplayName,
|
|
1506
|
-
hasVerifiedCheck,
|
|
1507
1516
|
isAutoTier,
|
|
1508
1517
|
isCardGatedModel,
|
|
1509
1518
|
isLeapingIntoActionCommentBody,
|
package/dist/models.d.ts
CHANGED
|
@@ -28,6 +28,9 @@ export interface ModelAlias {
|
|
|
28
28
|
provider: string;
|
|
29
29
|
/** human-readable name shown in dropdowns */
|
|
30
30
|
displayName: string;
|
|
31
|
+
/** optional one-line picker sub-label clarifying what the alias is (e.g.
|
|
32
|
+
* gpt-pro = "Maximum reasoning effort"). undefined for most aliases. */
|
|
33
|
+
description: string | undefined;
|
|
31
34
|
/** concrete models.dev specifier, e.g. "anthropic/claude-opus-4-6". sentinel for routing entries — never passed to a CLI directly. */
|
|
32
35
|
resolve: string;
|
|
33
36
|
/** full models.dev specifier for the OpenRouter equivalent (undefined for free models and routing entries) */
|
|
@@ -48,12 +51,14 @@ export interface ModelAlias {
|
|
|
48
51
|
* use as its lens-fanout subagent. e.g. claude-opus → "claude-sonnet". */
|
|
49
52
|
subagentModel: string | undefined;
|
|
50
53
|
/** hide from selectable lists (UI dropdowns, CLI pickers). does NOT affect
|
|
51
|
-
* resolution — for that use `fallback`. used
|
|
52
|
-
* (e.g.
|
|
54
|
+
* resolution — for that use `fallback`. used to keep a redundant alias out of
|
|
55
|
+
* pickers (e.g. the free `minimax-m2.5-free` duplicate). */
|
|
53
56
|
hidden: boolean;
|
|
54
57
|
}
|
|
55
58
|
interface ModelDef {
|
|
56
59
|
displayName: string;
|
|
60
|
+
/** optional one-line picker sub-label (e.g. "Maximum reasoning effort"). */
|
|
61
|
+
description?: string;
|
|
57
62
|
/** concrete models.dev specifier, e.g. "anthropic/claude-opus-4-6" */
|
|
58
63
|
resolve: string;
|
|
59
64
|
/** full models.dev specifier for the OpenRouter equivalent, e.g. "openrouter/anthropic/claude-opus-4.6" */
|