pullfrog 0.1.68 → 0.1.70
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/cli.mjs +93 -41
- package/dist/external.d.ts +9 -0
- package/dist/index.js +91 -39
- package/dist/internal.js +43 -13
- package/dist/mcp/reviewComments.d.ts +42 -0
- package/package.json +5 -5
package/dist/cli.mjs
CHANGED
|
@@ -110299,6 +110299,13 @@ var providers = {
|
|
|
110299
110299
|
// brand-tier names the slug convention asks for — the pre-5.6 `gpt` /
|
|
110300
110300
|
// `gpt-pro` / `gpt-mini` slugs are holdovers from the retired GPT / GPT Pro
|
|
110301
110301
|
// / GPT Mini tiering and are carried below as deprecated aliases.
|
|
110302
|
+
"gpt-astra": {
|
|
110303
|
+
displayName: "GPT Astra",
|
|
110304
|
+
resolve: "openai/gpt-6-astra",
|
|
110305
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
110306
|
+
openRouterResolve: "openrouter/openai/gpt-6-astra",
|
|
110307
|
+
subagentModel: "gpt-sol"
|
|
110308
|
+
},
|
|
110302
110309
|
"gpt-sol": {
|
|
110303
110310
|
displayName: "GPT Sol",
|
|
110304
110311
|
resolve: "openai/gpt-5.6-sol",
|
|
@@ -110660,6 +110667,13 @@ var providers = {
|
|
|
110660
110667
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
110661
110668
|
subagentModel: "gpt-terra"
|
|
110662
110669
|
},
|
|
110670
|
+
"gpt-astra": {
|
|
110671
|
+
displayName: "GPT Astra",
|
|
110672
|
+
resolve: "opencode/gpt-6-astra",
|
|
110673
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
110674
|
+
openRouterResolve: "openrouter/openai/gpt-6-astra",
|
|
110675
|
+
subagentModel: "gpt-sol"
|
|
110676
|
+
},
|
|
110663
110677
|
// see openai/gpt-sol-pro — Zen has no -pro id, so direct resolves to plain Sol.
|
|
110664
110678
|
"gpt-sol-pro": {
|
|
110665
110679
|
displayName: "GPT Sol Pro",
|
|
@@ -110773,10 +110787,9 @@ var providers = {
|
|
|
110773
110787
|
// was the catalog's only GLM route, and Grok had no Zen route at all.
|
|
110774
110788
|
glm: {
|
|
110775
110789
|
displayName: "GLM",
|
|
110776
|
-
resolve: "opencode/glm-5.
|
|
110777
|
-
effort: ["high", "max"],
|
|
110778
|
-
|
|
110779
|
-
openRouterResolve: "openrouter/z-ai/glm-5.2"
|
|
110790
|
+
resolve: "opencode/glm-5.3",
|
|
110791
|
+
effort: ["low", "high", "max"],
|
|
110792
|
+
openRouterResolve: "openrouter/z-ai/glm-5.3"
|
|
110780
110793
|
},
|
|
110781
110794
|
grok: {
|
|
110782
110795
|
displayName: "Grok",
|
|
@@ -110823,10 +110836,11 @@ var providers = {
|
|
|
110823
110836
|
// OpenCode Go is a separate $10/mo subscription from Zen, served on its own
|
|
110824
110837
|
// base URL (`https://opencode.ai/zen/go/v1`) but authenticated with the SAME
|
|
110825
110838
|
// `OPENCODE_API_KEY`. it carries the open-weight coding models plus a couple
|
|
110826
|
-
// of frontier ones,
|
|
110827
|
-
//
|
|
110828
|
-
//
|
|
110829
|
-
//
|
|
110839
|
+
// of frontier ones, six of which are served ONLY here — Zen's `/v1/models`
|
|
110840
|
+
// does not list qwen3.7/3.8-*, mimo-v2.5-pro, longcat-2.0 or hy3. (it listed
|
|
110841
|
+
// no glm-5.3* either until 2026-09, which is why `opencode/glm` trailed on
|
|
110842
|
+
// 5.2.) so for a Go subscriber this provider is not a duplicate route to Zen,
|
|
110843
|
+
// it is the only route to a large part of what they pay for.
|
|
110830
110844
|
// like `opencode` and `openrouter` this is a ROUTER, not a vendor: slugs and
|
|
110831
110845
|
// display names mirror the upstream brand tier, and the picker groups them
|
|
110832
110846
|
// under the upstream vendor.
|
|
@@ -110895,7 +110909,9 @@ var providers = {
|
|
|
110895
110909
|
// `high` the Go route does not.
|
|
110896
110910
|
effort: ["low", "medium", "xhigh"],
|
|
110897
110911
|
openRouterEffort: ["minimal", "low", "medium", "high", "xhigh"],
|
|
110898
|
-
|
|
110912
|
+
// OpenRouter retired the rolling `qwen3.8-max` for a dated snapshot, so
|
|
110913
|
+
// this side has to pin one; the Go route still carries the rolling id.
|
|
110914
|
+
openRouterResolve: "openrouter/qwen/qwen3.8-max-0902"
|
|
110899
110915
|
},
|
|
110900
110916
|
"qwen-plus": {
|
|
110901
110917
|
displayName: "Qwen Plus",
|
|
@@ -111075,6 +111091,13 @@ var providers = {
|
|
|
111075
111091
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
111076
111092
|
subagentModel: "gpt-terra"
|
|
111077
111093
|
},
|
|
111094
|
+
"gpt-astra": {
|
|
111095
|
+
displayName: "GPT Astra",
|
|
111096
|
+
resolve: "openrouter/openai/gpt-6-astra",
|
|
111097
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
111098
|
+
openRouterResolve: "openrouter/openai/gpt-6-astra",
|
|
111099
|
+
subagentModel: "gpt-sol"
|
|
111100
|
+
},
|
|
111078
111101
|
// see openai/gpt-sol-pro. openrouter serves sol-pro directly on both routes.
|
|
111079
111102
|
"gpt-sol-pro": {
|
|
111080
111103
|
displayName: "GPT Sol Pro",
|
|
@@ -111245,6 +111268,12 @@ var providers = {
|
|
|
111245
111268
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
111246
111269
|
subagentModel: "gpt-terra"
|
|
111247
111270
|
},
|
|
111271
|
+
"gpt-astra": {
|
|
111272
|
+
displayName: "GPT Astra",
|
|
111273
|
+
resolve: "vercel/openai/gpt-6-astra",
|
|
111274
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
111275
|
+
subagentModel: "gpt-sol"
|
|
111276
|
+
},
|
|
111248
111277
|
"gpt-terra": {
|
|
111249
111278
|
displayName: "GPT Terra",
|
|
111250
111279
|
resolve: "vercel/openai/gpt-5.6-terra",
|
|
@@ -112252,7 +112281,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
112252
112281
|
// package.json
|
|
112253
112282
|
var package_default = {
|
|
112254
112283
|
name: "pullfrog",
|
|
112255
|
-
version: "0.1.
|
|
112284
|
+
version: "0.1.70",
|
|
112256
112285
|
type: "module",
|
|
112257
112286
|
bin: {
|
|
112258
112287
|
pullfrog: "dist/cli.mjs",
|
|
@@ -112283,12 +112312,12 @@ var package_default = {
|
|
|
112283
112312
|
"@ark/util": "0.56.0",
|
|
112284
112313
|
"@clack/prompts": "^1.2.0",
|
|
112285
112314
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
112286
|
-
"@opencode-ai/sdk": "1.18.5",
|
|
112287
|
-
"@openai/codex": "0.147.0",
|
|
112288
|
-
"@openai/codex-sdk": "0.147.0",
|
|
112289
112315
|
"@octokit/plugin-throttling": "^11.0.3",
|
|
112290
112316
|
"@octokit/rest": "^22.0.0",
|
|
112291
112317
|
"@octokit/webhooks-types": "^7.6.1",
|
|
112318
|
+
"@openai/codex": "0.153.4",
|
|
112319
|
+
"@openai/codex-sdk": "0.153.4",
|
|
112320
|
+
"@opencode-ai/sdk": "1.18.29",
|
|
112292
112321
|
"@standard-schema/spec": "1.1.0",
|
|
112293
112322
|
"@toon-format/toon": "^1.0.0",
|
|
112294
112323
|
"@types/node": "^24.7.2",
|
|
@@ -112308,7 +112337,7 @@ var package_default = {
|
|
|
112308
112337
|
husky: "^9.0.0",
|
|
112309
112338
|
"lru-cache": "^11.0.0",
|
|
112310
112339
|
"object-hash": "^3.0.0",
|
|
112311
|
-
"opencode-ai": "1.18.
|
|
112340
|
+
"opencode-ai": "1.18.29",
|
|
112312
112341
|
"package-manager-detector": "^1.6.0",
|
|
112313
112342
|
picocolors: "^1.1.1",
|
|
112314
112343
|
semver: "^7.7.3",
|
|
@@ -113059,6 +113088,7 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
|
|
|
113059
113088
|
- record what was done (or why nothing was done)
|
|
113060
113089
|
|
|
113061
113090
|
5. Quality check:
|
|
113091
|
+
- re-call \`${t2("get_review_comments")}\` with \`fresh: true\` before committing: reviewers keep commenting while you work, and any thread it now returns that you have not addressed is in scope for this run.
|
|
113062
113092
|
- test changes, then review the diff before committing \u2014 verify only intended changes are present, no debug artifacts remain, no fix turned out to be bloat in context (revert any that did), and the changes are clean enough that a senior engineer would approve without hesitation
|
|
113063
113093
|
- ${commitStep}
|
|
113064
113094
|
|
|
@@ -113068,7 +113098,7 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
|
|
|
113068
113098
|
- **once the fix is live on the remote**, for each thread you acted on:
|
|
113069
113099
|
- reply ONCE via \`${t2("reply_to_review_comment")}\`. The \`comment_id\` parameter takes the root comment's numeric \`id=\` (from the first \`comment author=...\` tag in the \`${t2("get_review_comments")}\` output) \u2014 NOT the \`thread=\` value; that's a separate GraphQL ID used by resolve. The runtime dedupes identical bodies within a session.
|
|
113070
113100
|
- **immediately** call \`${t2("resolve_review_thread")}\` with that thread's \`thread=\` value as \`thread_id\`. Resolve every thread where you (a) made the requested code change in full \u2014 partial fixes leave the thread open \u2014 OR (b) replied with a substantive answer the user explicitly asked for. Do NOT resolve threads where you pushed back on the request and the disagreement is unresolved; leave those open for the human to mediate.
|
|
113071
|
-
- call \`${t2("report_progress")}\` with a brief summary
|
|
113101
|
+
- call \`${t2("report_progress")}\` with a brief summary. If your last \`${t2("get_review_comments")}\` turned up threads you did not address, name them there \u2014 a review arriving this late is suppressed as a duplicate and nothing else will pick it up.`
|
|
113072
113102
|
},
|
|
113073
113103
|
// Review and IncrementalReview route the minimum reviewfrog specialists
|
|
113074
113104
|
// needed to cover unresolved, disposition-changing hypotheses. Most runs
|
|
@@ -114908,6 +114938,7 @@ function toTodoWriteInput(item) {
|
|
|
114908
114938
|
};
|
|
114909
114939
|
}
|
|
114910
114940
|
var CODEX_MODEL_PRICING = {
|
|
114941
|
+
"gpt-6-astra": { input: 10, cacheRead: 1, cacheWrite: 12.5, output: 50 },
|
|
114911
114942
|
"gpt-5.6-sol": { input: 5, cacheRead: 0.5, cacheWrite: 6.25, output: 30 },
|
|
114912
114943
|
"gpt-5.6-luna": { input: 0.2, cacheRead: 0.02, cacheWrite: 0.25, output: 1.2 },
|
|
114913
114944
|
"gpt-5.6-terra": { input: 2, cacheRead: 0.2, cacheWrite: 2.5, output: 12 }
|
|
@@ -115234,7 +115265,7 @@ import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync7 } from "node:f
|
|
|
115234
115265
|
import { join as join8 } from "node:path";
|
|
115235
115266
|
import { performance as performance7 } from "node:perf_hooks";
|
|
115236
115267
|
|
|
115237
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
115268
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/core/serverSentEvents.gen.js
|
|
115238
115269
|
var createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url: url4, ...options }) => {
|
|
115239
115270
|
let lastEventId;
|
|
115240
115271
|
const sleep5 = sseSleepFn ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms)));
|
|
@@ -115353,7 +115384,7 @@ var createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransformer,
|
|
|
115353
115384
|
return { stream };
|
|
115354
115385
|
};
|
|
115355
115386
|
|
|
115356
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
115387
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/core/pathSerializer.gen.js
|
|
115357
115388
|
var separatorArrayExplode = (style) => {
|
|
115358
115389
|
switch (style) {
|
|
115359
115390
|
case "label":
|
|
@@ -115456,7 +115487,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value: value2
|
|
|
115456
115487
|
return style === "label" || style === "matrix" ? separator2 + joinedValues : joinedValues;
|
|
115457
115488
|
};
|
|
115458
115489
|
|
|
115459
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
115490
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/core/utils.gen.js
|
|
115460
115491
|
var PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
115461
115492
|
var defaultPathSerializer = ({ path: path4, url: _url3 }) => {
|
|
115462
115493
|
let url4 = _url3;
|
|
@@ -115539,7 +115570,7 @@ function getValidRequestBody(options) {
|
|
|
115539
115570
|
return void 0;
|
|
115540
115571
|
}
|
|
115541
115572
|
|
|
115542
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
115573
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/core/auth.gen.js
|
|
115543
115574
|
var getAuthToken = async (auth2, callback) => {
|
|
115544
115575
|
const token = typeof callback === "function" ? await callback(auth2) : callback;
|
|
115545
115576
|
if (!token) {
|
|
@@ -115554,12 +115585,12 @@ var getAuthToken = async (auth2, callback) => {
|
|
|
115554
115585
|
return token;
|
|
115555
115586
|
};
|
|
115556
115587
|
|
|
115557
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
115588
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/core/bodySerializer.gen.js
|
|
115558
115589
|
var jsonBodySerializer = {
|
|
115559
115590
|
bodySerializer: (body) => JSON.stringify(body, (_key, value2) => typeof value2 === "bigint" ? value2.toString() : value2)
|
|
115560
115591
|
};
|
|
115561
115592
|
|
|
115562
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
115593
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/client/utils.gen.js
|
|
115563
115594
|
var createQuerySerializer = ({ parameters = {}, ...args2 } = {}) => {
|
|
115564
115595
|
const querySerializer = (queryParams) => {
|
|
115565
115596
|
const search2 = [];
|
|
@@ -115769,7 +115800,7 @@ var createConfig = (override = {}) => ({
|
|
|
115769
115800
|
...override
|
|
115770
115801
|
});
|
|
115771
115802
|
|
|
115772
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
115803
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/client/client.gen.js
|
|
115773
115804
|
var createClient = (config3 = {}) => {
|
|
115774
115805
|
let _config = mergeConfigs(createConfig(), config3);
|
|
115775
115806
|
const getConfig = () => ({ ..._config });
|
|
@@ -115977,7 +116008,7 @@ var createClient = (config3 = {}) => {
|
|
|
115977
116008
|
};
|
|
115978
116009
|
};
|
|
115979
116010
|
|
|
115980
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
116011
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/core/params.gen.js
|
|
115981
116012
|
var extraPrefixesMap = {
|
|
115982
116013
|
$body_: "body",
|
|
115983
116014
|
$headers_: "headers",
|
|
@@ -116073,10 +116104,10 @@ var buildClientParams = (args2, fields) => {
|
|
|
116073
116104
|
return params;
|
|
116074
116105
|
};
|
|
116075
116106
|
|
|
116076
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
116107
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/client.gen.js
|
|
116077
116108
|
var client = createClient(createConfig({ baseUrl: "http://localhost:4096" }));
|
|
116078
116109
|
|
|
116079
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
116110
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/sdk.gen.js
|
|
116080
116111
|
var HeyApiClient = class {
|
|
116081
116112
|
client;
|
|
116082
116113
|
constructor(args2) {
|
|
@@ -116691,7 +116722,7 @@ var Global = class extends HeyApiClient {
|
|
|
116691
116722
|
/**
|
|
116692
116723
|
* Upgrade opencode
|
|
116693
116724
|
*
|
|
116694
|
-
* Upgrade opencode to the specified version
|
|
116725
|
+
* Upgrade opencode to the specified version.
|
|
116695
116726
|
*/
|
|
116696
116727
|
upgrade(parameters, options) {
|
|
116697
116728
|
const params = buildClientParams([parameters], [{ args: [{ in: "body", key: "target" }] }]);
|
|
@@ -120531,7 +120562,7 @@ var OpencodeClient = class _OpencodeClient extends HeyApiClient {
|
|
|
120531
120562
|
}
|
|
120532
120563
|
};
|
|
120533
120564
|
|
|
120534
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
120565
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/error-interceptor.js
|
|
120535
120566
|
function wrapClientError(error62, response, request2, opts) {
|
|
120536
120567
|
if (!opts?.throwOnError)
|
|
120537
120568
|
return error62;
|
|
@@ -120558,7 +120589,7 @@ function describe(request2, response) {
|
|
|
120558
120589
|
return `${method} ${url4}${status ? " \u2192 " + status : ""}${statusText ? " " + statusText : ""}`;
|
|
120559
120590
|
}
|
|
120560
120591
|
|
|
120561
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
120592
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/client.js
|
|
120562
120593
|
function pick(value2, fallback, encode5) {
|
|
120563
120594
|
if (!value2)
|
|
120564
120595
|
return;
|
|
@@ -120634,7 +120665,7 @@ function createOpencodeClient(config3) {
|
|
|
120634
120665
|
return new OpencodeClient({ client: client2 });
|
|
120635
120666
|
}
|
|
120636
120667
|
|
|
120637
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
120668
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/server.js
|
|
120638
120669
|
var import_cross_spawn = __toESM(require_cross_spawn(), 1);
|
|
120639
120670
|
|
|
120640
120671
|
// agents/opencode.ts
|
|
@@ -199174,7 +199205,10 @@ function extractFromFilePatches(hunks, startLine, endLine, side) {
|
|
|
199174
199205
|
}
|
|
199175
199206
|
var GetReviewComments = type({
|
|
199176
199207
|
pull_number: type.number.describe("The pull request number"),
|
|
199177
|
-
review_id: type.number.describe("The review ID to get comments for")
|
|
199208
|
+
review_id: type.number.describe("The review ID to get comments for"),
|
|
199209
|
+
"fresh?": type.boolean.describe(
|
|
199210
|
+
"Bypass the 60s thread cache. Use for the re-read before committing, so comments that landed while you worked are actually seen; leave unset otherwise."
|
|
199211
|
+
)
|
|
199178
199212
|
});
|
|
199179
199213
|
function hasThumbsUpFrom(comment, username) {
|
|
199180
199214
|
if (!comment.reactionGroups) return false;
|
|
@@ -199208,7 +199242,7 @@ function formatReviewThreads(threadBlocks, header) {
|
|
|
199208
199242
|
}
|
|
199209
199243
|
const lines = [];
|
|
199210
199244
|
lines.push(
|
|
199211
|
-
`#
|
|
199245
|
+
`# Open Threads (${threadBlocks.length}) on PR #${header.pullNumber} - dispatched by Review ${header.reviewId} from ${header.reviewer}`
|
|
199212
199246
|
);
|
|
199213
199247
|
lines.push("");
|
|
199214
199248
|
if (threadBlocks.length > 0) {
|
|
@@ -199349,11 +199383,27 @@ async function getReviewThreads(input2) {
|
|
|
199349
199383
|
if (!thread?.comments?.nodes) return false;
|
|
199350
199384
|
return thread.comments.nodes.some((c2) => c2?.pullRequestReview?.databaseId === input2.reviewId);
|
|
199351
199385
|
});
|
|
199352
|
-
if (
|
|
199353
|
-
|
|
199386
|
+
if (input2.approvedBy) {
|
|
199387
|
+
const username = input2.approvedBy;
|
|
199388
|
+
return threadsForReview.filter((thread) => threadHasThumbsUpFrom(thread, username));
|
|
199354
199389
|
}
|
|
199355
|
-
|
|
199356
|
-
return threadsForReview
|
|
199390
|
+
if (!input2.addressScope) return threadsForReview;
|
|
199391
|
+
return [...threadsForReview, ...concurrentThreads(allThreads, threadsForReview, input2)];
|
|
199392
|
+
}
|
|
199393
|
+
function concurrentThreads(allThreads, threadsForReview, input2) {
|
|
199394
|
+
const alreadyIncluded = new Set(threadsForReview.map((thread) => thread.id));
|
|
199395
|
+
return allThreads.filter((thread) => {
|
|
199396
|
+
if (!thread?.comments?.nodes || alreadyIncluded.has(thread.id)) return false;
|
|
199397
|
+
if (thread.isResolved) return false;
|
|
199398
|
+
const comments = thread.comments.nodes.filter((c2) => c2 !== null);
|
|
199399
|
+
if (comments.length === 0) return false;
|
|
199400
|
+
if (comments.some((c2) => isPullfrog(c2.author?.login))) return false;
|
|
199401
|
+
return input2.addressScope === "all" || comments.some((c2) => mentionsPullfrog(c2.body));
|
|
199402
|
+
});
|
|
199403
|
+
}
|
|
199404
|
+
function mentionsPullfrog(body) {
|
|
199405
|
+
if (!body) return false;
|
|
199406
|
+
return body.split(/\r?\n/).filter((line) => !line.trim().startsWith(">")).join("\n").toLowerCase().includes("@pullfrog");
|
|
199357
199407
|
}
|
|
199358
199408
|
function formatReviewData(input2) {
|
|
199359
199409
|
const rawReviewBody = input2.review.body;
|
|
@@ -199450,6 +199500,7 @@ function GetReviewCommentsTool(ctx) {
|
|
|
199450
199500
|
parameters: GetReviewComments,
|
|
199451
199501
|
execute: execute(async (params) => {
|
|
199452
199502
|
const approvedBy = ctx.payload.event.trigger === "fix_review" && ctx.payload.event.approved_only ? ctx.payload.triggerer : void 0;
|
|
199503
|
+
if (params.fresh) invalidateReviewThreadCache(ctx.repo);
|
|
199453
199504
|
const result = await getReviewData({
|
|
199454
199505
|
octokit: ctx.octokit,
|
|
199455
199506
|
owner: ctx.repo.owner,
|
|
@@ -199457,6 +199508,7 @@ function GetReviewCommentsTool(ctx) {
|
|
|
199457
199508
|
pullNumber: params.pull_number,
|
|
199458
199509
|
reviewId: params.review_id,
|
|
199459
199510
|
approvedBy,
|
|
199511
|
+
addressScope: ctx.payload.event.address_scope,
|
|
199460
199512
|
tmpdir: ctx.tmpdir,
|
|
199461
199513
|
githubToken: ctx.githubInstallationToken
|
|
199462
199514
|
});
|
|
@@ -199487,7 +199539,7 @@ function GetReviewCommentsTool(ctx) {
|
|
|
199487
199539
|
threadCount: threadBlocks.length,
|
|
199488
199540
|
commentsPath,
|
|
199489
199541
|
toc: formatted.toc,
|
|
199490
|
-
instructions: `the file at commentsPath contains ${threadBlocks.length} review threads with full conversation history. comments marked with * are from the target review (${params.review_id}). the TOC shows each thread's file:line and the line number where it appears in the file. to read a specific thread, use: grep -A 50 "^## <file:line>" ${commentsPath} (replace <file:line> with the path from the TOC, e.g. "^## action/utils/foo.ts:42"). address each thread in order, working through one file at a time.`
|
|
199542
|
+
instructions: `the file at commentsPath contains ${threadBlocks.length} review threads with full conversation history. comments marked with * are from the target review (${params.review_id}); any other thread is open feedback on this PR that is also yours to address, including comments that landed after this run started. the TOC shows each thread's file:line and the line number where it appears in the file. to read a specific thread, use: grep -A 50 "^## <file:line>" ${commentsPath} (replace <file:line> with the path from the TOC, e.g. "^## action/utils/foo.ts:42"). address each thread in order, working through one file at a time.`
|
|
199491
199543
|
};
|
|
199492
199544
|
})
|
|
199493
199545
|
});
|
|
@@ -200658,11 +200710,11 @@ function billingConsoleUrl(owner) {
|
|
|
200658
200710
|
function commercialPaywallBody(params) {
|
|
200659
200711
|
if (params.reason === "commercial") {
|
|
200660
200712
|
return [
|
|
200661
|
-
`**Pullfrog needs
|
|
200713
|
+
`**Pullfrog needs Pro on ${params.ownerLogin}, so this run didn't start.**`,
|
|
200662
200714
|
"",
|
|
200663
|
-
"
|
|
200715
|
+
"Pro is $30/month per organization and covers private repositories. Public repos and personal accounts keep running free.",
|
|
200664
200716
|
"",
|
|
200665
|
-
`[
|
|
200717
|
+
`[Upgrade to Pro \u2192](${params.url})`
|
|
200666
200718
|
].join("\n");
|
|
200667
200719
|
}
|
|
200668
200720
|
params.reason;
|
|
@@ -204932,7 +204984,7 @@ function resolveTarget(repo) {
|
|
|
204932
204984
|
return { owner: match3[1], repo: match3[2] };
|
|
204933
204985
|
}
|
|
204934
204986
|
function cliVersion() {
|
|
204935
|
-
const parts = /^(\d+)\.(\d+)\.(\d+)$/.exec("0.1.
|
|
204987
|
+
const parts = /^(\d+)\.(\d+)\.(\d+)$/.exec("0.1.70");
|
|
204936
204988
|
if (!parts) return "0.0.0";
|
|
204937
204989
|
return `${Number(parts[1])}.${Number(parts[2])}.${Number(parts[3])}`;
|
|
204938
204990
|
}
|
|
@@ -205099,7 +205151,7 @@ async function runCli5(input2) {
|
|
|
205099
205151
|
}
|
|
205100
205152
|
|
|
205101
205153
|
// cli.ts
|
|
205102
|
-
var VERSION10 = "0.1.
|
|
205154
|
+
var VERSION10 = "0.1.70";
|
|
205103
205155
|
var bin = basename2(process.argv[1] || "");
|
|
205104
205156
|
var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
|
|
205105
205157
|
var rawArgs = process.argv.slice(2);
|
package/dist/external.d.ts
CHANGED
|
@@ -137,6 +137,15 @@ interface PullRequestReviewSubmittedEvent extends BasePayloadEvent {
|
|
|
137
137
|
body: string | null;
|
|
138
138
|
review_state: string;
|
|
139
139
|
branch: string;
|
|
140
|
+
/**
|
|
141
|
+
* How far past the dispatching review this run may read: `all` on a
|
|
142
|
+
* Pullfrog-authored PR, `mentions` when only `@pullfrog`-mentioning threads
|
|
143
|
+
* are in scope. The server already computes this to decide whether to
|
|
144
|
+
* dispatch; forwarding it is what lets `get_review_comments` pick up the
|
|
145
|
+
* comments that land while the run is working. Optional so a payload from an
|
|
146
|
+
* older server build still parses against a newer action.
|
|
147
|
+
*/
|
|
148
|
+
address_scope?: "all" | "mentions" | undefined;
|
|
140
149
|
}
|
|
141
150
|
interface PullRequestReviewCommentCreatedEvent extends BasePayloadEvent {
|
|
142
151
|
trigger: "pull_request_review_comment_created";
|
package/dist/index.js
CHANGED
|
@@ -107809,6 +107809,13 @@ var providers = {
|
|
|
107809
107809
|
// brand-tier names the slug convention asks for — the pre-5.6 `gpt` /
|
|
107810
107810
|
// `gpt-pro` / `gpt-mini` slugs are holdovers from the retired GPT / GPT Pro
|
|
107811
107811
|
// / GPT Mini tiering and are carried below as deprecated aliases.
|
|
107812
|
+
"gpt-astra": {
|
|
107813
|
+
displayName: "GPT Astra",
|
|
107814
|
+
resolve: "openai/gpt-6-astra",
|
|
107815
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
107816
|
+
openRouterResolve: "openrouter/openai/gpt-6-astra",
|
|
107817
|
+
subagentModel: "gpt-sol"
|
|
107818
|
+
},
|
|
107812
107819
|
"gpt-sol": {
|
|
107813
107820
|
displayName: "GPT Sol",
|
|
107814
107821
|
resolve: "openai/gpt-5.6-sol",
|
|
@@ -108170,6 +108177,13 @@ var providers = {
|
|
|
108170
108177
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
108171
108178
|
subagentModel: "gpt-terra"
|
|
108172
108179
|
},
|
|
108180
|
+
"gpt-astra": {
|
|
108181
|
+
displayName: "GPT Astra",
|
|
108182
|
+
resolve: "opencode/gpt-6-astra",
|
|
108183
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
108184
|
+
openRouterResolve: "openrouter/openai/gpt-6-astra",
|
|
108185
|
+
subagentModel: "gpt-sol"
|
|
108186
|
+
},
|
|
108173
108187
|
// see openai/gpt-sol-pro — Zen has no -pro id, so direct resolves to plain Sol.
|
|
108174
108188
|
"gpt-sol-pro": {
|
|
108175
108189
|
displayName: "GPT Sol Pro",
|
|
@@ -108283,10 +108297,9 @@ var providers = {
|
|
|
108283
108297
|
// was the catalog's only GLM route, and Grok had no Zen route at all.
|
|
108284
108298
|
glm: {
|
|
108285
108299
|
displayName: "GLM",
|
|
108286
|
-
resolve: "opencode/glm-5.
|
|
108287
|
-
effort: ["high", "max"],
|
|
108288
|
-
|
|
108289
|
-
openRouterResolve: "openrouter/z-ai/glm-5.2"
|
|
108300
|
+
resolve: "opencode/glm-5.3",
|
|
108301
|
+
effort: ["low", "high", "max"],
|
|
108302
|
+
openRouterResolve: "openrouter/z-ai/glm-5.3"
|
|
108290
108303
|
},
|
|
108291
108304
|
grok: {
|
|
108292
108305
|
displayName: "Grok",
|
|
@@ -108333,10 +108346,11 @@ var providers = {
|
|
|
108333
108346
|
// OpenCode Go is a separate $10/mo subscription from Zen, served on its own
|
|
108334
108347
|
// base URL (`https://opencode.ai/zen/go/v1`) but authenticated with the SAME
|
|
108335
108348
|
// `OPENCODE_API_KEY`. it carries the open-weight coding models plus a couple
|
|
108336
|
-
// of frontier ones,
|
|
108337
|
-
//
|
|
108338
|
-
//
|
|
108339
|
-
//
|
|
108349
|
+
// of frontier ones, six of which are served ONLY here — Zen's `/v1/models`
|
|
108350
|
+
// does not list qwen3.7/3.8-*, mimo-v2.5-pro, longcat-2.0 or hy3. (it listed
|
|
108351
|
+
// no glm-5.3* either until 2026-09, which is why `opencode/glm` trailed on
|
|
108352
|
+
// 5.2.) so for a Go subscriber this provider is not a duplicate route to Zen,
|
|
108353
|
+
// it is the only route to a large part of what they pay for.
|
|
108340
108354
|
// like `opencode` and `openrouter` this is a ROUTER, not a vendor: slugs and
|
|
108341
108355
|
// display names mirror the upstream brand tier, and the picker groups them
|
|
108342
108356
|
// under the upstream vendor.
|
|
@@ -108405,7 +108419,9 @@ var providers = {
|
|
|
108405
108419
|
// `high` the Go route does not.
|
|
108406
108420
|
effort: ["low", "medium", "xhigh"],
|
|
108407
108421
|
openRouterEffort: ["minimal", "low", "medium", "high", "xhigh"],
|
|
108408
|
-
|
|
108422
|
+
// OpenRouter retired the rolling `qwen3.8-max` for a dated snapshot, so
|
|
108423
|
+
// this side has to pin one; the Go route still carries the rolling id.
|
|
108424
|
+
openRouterResolve: "openrouter/qwen/qwen3.8-max-0902"
|
|
108409
108425
|
},
|
|
108410
108426
|
"qwen-plus": {
|
|
108411
108427
|
displayName: "Qwen Plus",
|
|
@@ -108585,6 +108601,13 @@ var providers = {
|
|
|
108585
108601
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
108586
108602
|
subagentModel: "gpt-terra"
|
|
108587
108603
|
},
|
|
108604
|
+
"gpt-astra": {
|
|
108605
|
+
displayName: "GPT Astra",
|
|
108606
|
+
resolve: "openrouter/openai/gpt-6-astra",
|
|
108607
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
108608
|
+
openRouterResolve: "openrouter/openai/gpt-6-astra",
|
|
108609
|
+
subagentModel: "gpt-sol"
|
|
108610
|
+
},
|
|
108588
108611
|
// see openai/gpt-sol-pro. openrouter serves sol-pro directly on both routes.
|
|
108589
108612
|
"gpt-sol-pro": {
|
|
108590
108613
|
displayName: "GPT Sol Pro",
|
|
@@ -108755,6 +108778,12 @@ var providers = {
|
|
|
108755
108778
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
108756
108779
|
subagentModel: "gpt-terra"
|
|
108757
108780
|
},
|
|
108781
|
+
"gpt-astra": {
|
|
108782
|
+
displayName: "GPT Astra",
|
|
108783
|
+
resolve: "vercel/openai/gpt-6-astra",
|
|
108784
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
108785
|
+
subagentModel: "gpt-sol"
|
|
108786
|
+
},
|
|
108758
108787
|
"gpt-terra": {
|
|
108759
108788
|
displayName: "GPT Terra",
|
|
108760
108789
|
resolve: "vercel/openai/gpt-5.6-terra",
|
|
@@ -109762,7 +109791,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
109762
109791
|
// package.json
|
|
109763
109792
|
var package_default = {
|
|
109764
109793
|
name: "pullfrog",
|
|
109765
|
-
version: "0.1.
|
|
109794
|
+
version: "0.1.70",
|
|
109766
109795
|
type: "module",
|
|
109767
109796
|
bin: {
|
|
109768
109797
|
pullfrog: "dist/cli.mjs",
|
|
@@ -109793,12 +109822,12 @@ var package_default = {
|
|
|
109793
109822
|
"@ark/util": "0.56.0",
|
|
109794
109823
|
"@clack/prompts": "^1.2.0",
|
|
109795
109824
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
109796
|
-
"@opencode-ai/sdk": "1.18.5",
|
|
109797
|
-
"@openai/codex": "0.147.0",
|
|
109798
|
-
"@openai/codex-sdk": "0.147.0",
|
|
109799
109825
|
"@octokit/plugin-throttling": "^11.0.3",
|
|
109800
109826
|
"@octokit/rest": "^22.0.0",
|
|
109801
109827
|
"@octokit/webhooks-types": "^7.6.1",
|
|
109828
|
+
"@openai/codex": "0.153.4",
|
|
109829
|
+
"@openai/codex-sdk": "0.153.4",
|
|
109830
|
+
"@opencode-ai/sdk": "1.18.29",
|
|
109802
109831
|
"@standard-schema/spec": "1.1.0",
|
|
109803
109832
|
"@toon-format/toon": "^1.0.0",
|
|
109804
109833
|
"@types/node": "^24.7.2",
|
|
@@ -109818,7 +109847,7 @@ var package_default = {
|
|
|
109818
109847
|
husky: "^9.0.0",
|
|
109819
109848
|
"lru-cache": "^11.0.0",
|
|
109820
109849
|
"object-hash": "^3.0.0",
|
|
109821
|
-
"opencode-ai": "1.18.
|
|
109850
|
+
"opencode-ai": "1.18.29",
|
|
109822
109851
|
"package-manager-detector": "^1.6.0",
|
|
109823
109852
|
picocolors: "^1.1.1",
|
|
109824
109853
|
semver: "^7.7.3",
|
|
@@ -110569,6 +110598,7 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
|
|
|
110569
110598
|
- record what was done (or why nothing was done)
|
|
110570
110599
|
|
|
110571
110600
|
5. Quality check:
|
|
110601
|
+
- re-call \`${t("get_review_comments")}\` with \`fresh: true\` before committing: reviewers keep commenting while you work, and any thread it now returns that you have not addressed is in scope for this run.
|
|
110572
110602
|
- test changes, then review the diff before committing \u2014 verify only intended changes are present, no debug artifacts remain, no fix turned out to be bloat in context (revert any that did), and the changes are clean enough that a senior engineer would approve without hesitation
|
|
110573
110603
|
- ${commitStep}
|
|
110574
110604
|
|
|
@@ -110578,7 +110608,7 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
|
|
|
110578
110608
|
- **once the fix is live on the remote**, for each thread you acted on:
|
|
110579
110609
|
- reply ONCE via \`${t("reply_to_review_comment")}\`. The \`comment_id\` parameter takes the root comment's numeric \`id=\` (from the first \`comment author=...\` tag in the \`${t("get_review_comments")}\` output) \u2014 NOT the \`thread=\` value; that's a separate GraphQL ID used by resolve. The runtime dedupes identical bodies within a session.
|
|
110580
110610
|
- **immediately** call \`${t("resolve_review_thread")}\` with that thread's \`thread=\` value as \`thread_id\`. Resolve every thread where you (a) made the requested code change in full \u2014 partial fixes leave the thread open \u2014 OR (b) replied with a substantive answer the user explicitly asked for. Do NOT resolve threads where you pushed back on the request and the disagreement is unresolved; leave those open for the human to mediate.
|
|
110581
|
-
- call \`${t("report_progress")}\` with a brief summary
|
|
110611
|
+
- call \`${t("report_progress")}\` with a brief summary. If your last \`${t("get_review_comments")}\` turned up threads you did not address, name them there \u2014 a review arriving this late is suppressed as a duplicate and nothing else will pick it up.`
|
|
110582
110612
|
},
|
|
110583
110613
|
// Review and IncrementalReview route the minimum reviewfrog specialists
|
|
110584
110614
|
// needed to cover unresolved, disposition-changing hypotheses. Most runs
|
|
@@ -112491,6 +112521,7 @@ function toTodoWriteInput(item) {
|
|
|
112491
112521
|
};
|
|
112492
112522
|
}
|
|
112493
112523
|
var CODEX_MODEL_PRICING = {
|
|
112524
|
+
"gpt-6-astra": { input: 10, cacheRead: 1, cacheWrite: 12.5, output: 50 },
|
|
112494
112525
|
"gpt-5.6-sol": { input: 5, cacheRead: 0.5, cacheWrite: 6.25, output: 30 },
|
|
112495
112526
|
"gpt-5.6-luna": { input: 0.2, cacheRead: 0.02, cacheWrite: 0.25, output: 1.2 },
|
|
112496
112527
|
"gpt-5.6-terra": { input: 2, cacheRead: 0.2, cacheWrite: 2.5, output: 12 }
|
|
@@ -112817,7 +112848,7 @@ import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync6 } from "node:f
|
|
|
112817
112848
|
import { join as join7 } from "node:path";
|
|
112818
112849
|
import { performance as performance7 } from "node:perf_hooks";
|
|
112819
112850
|
|
|
112820
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
112851
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/core/serverSentEvents.gen.js
|
|
112821
112852
|
var createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url: url4, ...options }) => {
|
|
112822
112853
|
let lastEventId;
|
|
112823
112854
|
const sleep5 = sseSleepFn ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms)));
|
|
@@ -112936,7 +112967,7 @@ var createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransformer,
|
|
|
112936
112967
|
return { stream };
|
|
112937
112968
|
};
|
|
112938
112969
|
|
|
112939
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
112970
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/core/pathSerializer.gen.js
|
|
112940
112971
|
var separatorArrayExplode = (style) => {
|
|
112941
112972
|
switch (style) {
|
|
112942
112973
|
case "label":
|
|
@@ -113039,7 +113070,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value: value2
|
|
|
113039
113070
|
return style === "label" || style === "matrix" ? separator2 + joinedValues : joinedValues;
|
|
113040
113071
|
};
|
|
113041
113072
|
|
|
113042
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
113073
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/core/utils.gen.js
|
|
113043
113074
|
var PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
113044
113075
|
var defaultPathSerializer = ({ path: path4, url: _url3 }) => {
|
|
113045
113076
|
let url4 = _url3;
|
|
@@ -113122,7 +113153,7 @@ function getValidRequestBody(options) {
|
|
|
113122
113153
|
return void 0;
|
|
113123
113154
|
}
|
|
113124
113155
|
|
|
113125
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
113156
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/core/auth.gen.js
|
|
113126
113157
|
var getAuthToken = async (auth2, callback) => {
|
|
113127
113158
|
const token = typeof callback === "function" ? await callback(auth2) : callback;
|
|
113128
113159
|
if (!token) {
|
|
@@ -113137,12 +113168,12 @@ var getAuthToken = async (auth2, callback) => {
|
|
|
113137
113168
|
return token;
|
|
113138
113169
|
};
|
|
113139
113170
|
|
|
113140
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
113171
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/core/bodySerializer.gen.js
|
|
113141
113172
|
var jsonBodySerializer = {
|
|
113142
113173
|
bodySerializer: (body) => JSON.stringify(body, (_key, value2) => typeof value2 === "bigint" ? value2.toString() : value2)
|
|
113143
113174
|
};
|
|
113144
113175
|
|
|
113145
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
113176
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/client/utils.gen.js
|
|
113146
113177
|
var createQuerySerializer = ({ parameters = {}, ...args2 } = {}) => {
|
|
113147
113178
|
const querySerializer = (queryParams) => {
|
|
113148
113179
|
const search2 = [];
|
|
@@ -113352,7 +113383,7 @@ var createConfig = (override = {}) => ({
|
|
|
113352
113383
|
...override
|
|
113353
113384
|
});
|
|
113354
113385
|
|
|
113355
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
113386
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/client/client.gen.js
|
|
113356
113387
|
var createClient = (config3 = {}) => {
|
|
113357
113388
|
let _config = mergeConfigs(createConfig(), config3);
|
|
113358
113389
|
const getConfig = () => ({ ..._config });
|
|
@@ -113560,7 +113591,7 @@ var createClient = (config3 = {}) => {
|
|
|
113560
113591
|
};
|
|
113561
113592
|
};
|
|
113562
113593
|
|
|
113563
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
113594
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/core/params.gen.js
|
|
113564
113595
|
var extraPrefixesMap = {
|
|
113565
113596
|
$body_: "body",
|
|
113566
113597
|
$headers_: "headers",
|
|
@@ -113656,10 +113687,10 @@ var buildClientParams = (args2, fields) => {
|
|
|
113656
113687
|
return params;
|
|
113657
113688
|
};
|
|
113658
113689
|
|
|
113659
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
113690
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/client.gen.js
|
|
113660
113691
|
var client = createClient(createConfig({ baseUrl: "http://localhost:4096" }));
|
|
113661
113692
|
|
|
113662
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
113693
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/gen/sdk.gen.js
|
|
113663
113694
|
var HeyApiClient = class {
|
|
113664
113695
|
client;
|
|
113665
113696
|
constructor(args2) {
|
|
@@ -114274,7 +114305,7 @@ var Global = class extends HeyApiClient {
|
|
|
114274
114305
|
/**
|
|
114275
114306
|
* Upgrade opencode
|
|
114276
114307
|
*
|
|
114277
|
-
* Upgrade opencode to the specified version
|
|
114308
|
+
* Upgrade opencode to the specified version.
|
|
114278
114309
|
*/
|
|
114279
114310
|
upgrade(parameters, options) {
|
|
114280
114311
|
const params = buildClientParams([parameters], [{ args: [{ in: "body", key: "target" }] }]);
|
|
@@ -118114,7 +118145,7 @@ var OpencodeClient = class _OpencodeClient extends HeyApiClient {
|
|
|
118114
118145
|
}
|
|
118115
118146
|
};
|
|
118116
118147
|
|
|
118117
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
118148
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/error-interceptor.js
|
|
118118
118149
|
function wrapClientError(error62, response, request2, opts) {
|
|
118119
118150
|
if (!opts?.throwOnError)
|
|
118120
118151
|
return error62;
|
|
@@ -118141,7 +118172,7 @@ function describe(request2, response) {
|
|
|
118141
118172
|
return `${method} ${url4}${status ? " \u2192 " + status : ""}${statusText ? " " + statusText : ""}`;
|
|
118142
118173
|
}
|
|
118143
118174
|
|
|
118144
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
118175
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/client.js
|
|
118145
118176
|
function pick(value2, fallback, encode5) {
|
|
118146
118177
|
if (!value2)
|
|
118147
118178
|
return;
|
|
@@ -118217,7 +118248,7 @@ function createOpencodeClient(config3) {
|
|
|
118217
118248
|
return new OpencodeClient({ client: client2 });
|
|
118218
118249
|
}
|
|
118219
118250
|
|
|
118220
|
-
// node_modules/.pnpm/@opencode-ai+sdk@1.18.
|
|
118251
|
+
// node_modules/.pnpm/@opencode-ai+sdk@1.18.29/node_modules/@opencode-ai/sdk/dist/v2/server.js
|
|
118221
118252
|
var import_cross_spawn = __toESM(require_cross_spawn(), 1);
|
|
118222
118253
|
|
|
118223
118254
|
// agents/opencode.ts
|
|
@@ -196757,7 +196788,10 @@ function extractFromFilePatches(hunks, startLine, endLine, side) {
|
|
|
196757
196788
|
}
|
|
196758
196789
|
var GetReviewComments = type({
|
|
196759
196790
|
pull_number: type.number.describe("The pull request number"),
|
|
196760
|
-
review_id: type.number.describe("The review ID to get comments for")
|
|
196791
|
+
review_id: type.number.describe("The review ID to get comments for"),
|
|
196792
|
+
"fresh?": type.boolean.describe(
|
|
196793
|
+
"Bypass the 60s thread cache. Use for the re-read before committing, so comments that landed while you worked are actually seen; leave unset otherwise."
|
|
196794
|
+
)
|
|
196761
196795
|
});
|
|
196762
196796
|
function hasThumbsUpFrom(comment, username) {
|
|
196763
196797
|
if (!comment.reactionGroups) return false;
|
|
@@ -196791,7 +196825,7 @@ function formatReviewThreads(threadBlocks, header) {
|
|
|
196791
196825
|
}
|
|
196792
196826
|
const lines = [];
|
|
196793
196827
|
lines.push(
|
|
196794
|
-
`#
|
|
196828
|
+
`# Open Threads (${threadBlocks.length}) on PR #${header.pullNumber} - dispatched by Review ${header.reviewId} from ${header.reviewer}`
|
|
196795
196829
|
);
|
|
196796
196830
|
lines.push("");
|
|
196797
196831
|
if (threadBlocks.length > 0) {
|
|
@@ -196932,11 +196966,27 @@ async function getReviewThreads(input2) {
|
|
|
196932
196966
|
if (!thread?.comments?.nodes) return false;
|
|
196933
196967
|
return thread.comments.nodes.some((c) => c?.pullRequestReview?.databaseId === input2.reviewId);
|
|
196934
196968
|
});
|
|
196935
|
-
if (
|
|
196936
|
-
|
|
196969
|
+
if (input2.approvedBy) {
|
|
196970
|
+
const username = input2.approvedBy;
|
|
196971
|
+
return threadsForReview.filter((thread) => threadHasThumbsUpFrom(thread, username));
|
|
196937
196972
|
}
|
|
196938
|
-
|
|
196939
|
-
return threadsForReview
|
|
196973
|
+
if (!input2.addressScope) return threadsForReview;
|
|
196974
|
+
return [...threadsForReview, ...concurrentThreads(allThreads, threadsForReview, input2)];
|
|
196975
|
+
}
|
|
196976
|
+
function concurrentThreads(allThreads, threadsForReview, input2) {
|
|
196977
|
+
const alreadyIncluded = new Set(threadsForReview.map((thread) => thread.id));
|
|
196978
|
+
return allThreads.filter((thread) => {
|
|
196979
|
+
if (!thread?.comments?.nodes || alreadyIncluded.has(thread.id)) return false;
|
|
196980
|
+
if (thread.isResolved) return false;
|
|
196981
|
+
const comments = thread.comments.nodes.filter((c) => c !== null);
|
|
196982
|
+
if (comments.length === 0) return false;
|
|
196983
|
+
if (comments.some((c) => isPullfrog(c.author?.login))) return false;
|
|
196984
|
+
return input2.addressScope === "all" || comments.some((c) => mentionsPullfrog(c.body));
|
|
196985
|
+
});
|
|
196986
|
+
}
|
|
196987
|
+
function mentionsPullfrog(body) {
|
|
196988
|
+
if (!body) return false;
|
|
196989
|
+
return body.split(/\r?\n/).filter((line) => !line.trim().startsWith(">")).join("\n").toLowerCase().includes("@pullfrog");
|
|
196940
196990
|
}
|
|
196941
196991
|
function formatReviewData(input2) {
|
|
196942
196992
|
const rawReviewBody = input2.review.body;
|
|
@@ -197033,6 +197083,7 @@ function GetReviewCommentsTool(ctx) {
|
|
|
197033
197083
|
parameters: GetReviewComments,
|
|
197034
197084
|
execute: execute(async (params) => {
|
|
197035
197085
|
const approvedBy = ctx.payload.event.trigger === "fix_review" && ctx.payload.event.approved_only ? ctx.payload.triggerer : void 0;
|
|
197086
|
+
if (params.fresh) invalidateReviewThreadCache(ctx.repo);
|
|
197036
197087
|
const result = await getReviewData({
|
|
197037
197088
|
octokit: ctx.octokit,
|
|
197038
197089
|
owner: ctx.repo.owner,
|
|
@@ -197040,6 +197091,7 @@ function GetReviewCommentsTool(ctx) {
|
|
|
197040
197091
|
pullNumber: params.pull_number,
|
|
197041
197092
|
reviewId: params.review_id,
|
|
197042
197093
|
approvedBy,
|
|
197094
|
+
addressScope: ctx.payload.event.address_scope,
|
|
197043
197095
|
tmpdir: ctx.tmpdir,
|
|
197044
197096
|
githubToken: ctx.githubInstallationToken
|
|
197045
197097
|
});
|
|
@@ -197070,7 +197122,7 @@ function GetReviewCommentsTool(ctx) {
|
|
|
197070
197122
|
threadCount: threadBlocks.length,
|
|
197071
197123
|
commentsPath,
|
|
197072
197124
|
toc: formatted.toc,
|
|
197073
|
-
instructions: `the file at commentsPath contains ${threadBlocks.length} review threads with full conversation history. comments marked with * are from the target review (${params.review_id}). the TOC shows each thread's file:line and the line number where it appears in the file. to read a specific thread, use: grep -A 50 "^## <file:line>" ${commentsPath} (replace <file:line> with the path from the TOC, e.g. "^## action/utils/foo.ts:42"). address each thread in order, working through one file at a time.`
|
|
197125
|
+
instructions: `the file at commentsPath contains ${threadBlocks.length} review threads with full conversation history. comments marked with * are from the target review (${params.review_id}); any other thread is open feedback on this PR that is also yours to address, including comments that landed after this run started. the TOC shows each thread's file:line and the line number where it appears in the file. to read a specific thread, use: grep -A 50 "^## <file:line>" ${commentsPath} (replace <file:line> with the path from the TOC, e.g. "^## action/utils/foo.ts:42"). address each thread in order, working through one file at a time.`
|
|
197074
197126
|
};
|
|
197075
197127
|
})
|
|
197076
197128
|
});
|
|
@@ -198241,11 +198293,11 @@ function billingConsoleUrl(owner) {
|
|
|
198241
198293
|
function commercialPaywallBody(params) {
|
|
198242
198294
|
if (params.reason === "commercial") {
|
|
198243
198295
|
return [
|
|
198244
|
-
`**Pullfrog needs
|
|
198296
|
+
`**Pullfrog needs Pro on ${params.ownerLogin}, so this run didn't start.**`,
|
|
198245
198297
|
"",
|
|
198246
|
-
"
|
|
198298
|
+
"Pro is $30/month per organization and covers private repositories. Public repos and personal accounts keep running free.",
|
|
198247
198299
|
"",
|
|
198248
|
-
`[
|
|
198300
|
+
`[Upgrade to Pro \u2192](${params.url})`
|
|
198249
198301
|
].join("\n");
|
|
198250
198302
|
}
|
|
198251
198303
|
params.reason;
|
package/dist/internal.js
CHANGED
|
@@ -105,6 +105,13 @@ var providers = {
|
|
|
105
105
|
// brand-tier names the slug convention asks for — the pre-5.6 `gpt` /
|
|
106
106
|
// `gpt-pro` / `gpt-mini` slugs are holdovers from the retired GPT / GPT Pro
|
|
107
107
|
// / GPT Mini tiering and are carried below as deprecated aliases.
|
|
108
|
+
"gpt-astra": {
|
|
109
|
+
displayName: "GPT Astra",
|
|
110
|
+
resolve: "openai/gpt-6-astra",
|
|
111
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
112
|
+
openRouterResolve: "openrouter/openai/gpt-6-astra",
|
|
113
|
+
subagentModel: "gpt-sol"
|
|
114
|
+
},
|
|
108
115
|
"gpt-sol": {
|
|
109
116
|
displayName: "GPT Sol",
|
|
110
117
|
resolve: "openai/gpt-5.6-sol",
|
|
@@ -466,6 +473,13 @@ var providers = {
|
|
|
466
473
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
467
474
|
subagentModel: "gpt-terra"
|
|
468
475
|
},
|
|
476
|
+
"gpt-astra": {
|
|
477
|
+
displayName: "GPT Astra",
|
|
478
|
+
resolve: "opencode/gpt-6-astra",
|
|
479
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
480
|
+
openRouterResolve: "openrouter/openai/gpt-6-astra",
|
|
481
|
+
subagentModel: "gpt-sol"
|
|
482
|
+
},
|
|
469
483
|
// see openai/gpt-sol-pro — Zen has no -pro id, so direct resolves to plain Sol.
|
|
470
484
|
"gpt-sol-pro": {
|
|
471
485
|
displayName: "GPT Sol Pro",
|
|
@@ -579,10 +593,9 @@ var providers = {
|
|
|
579
593
|
// was the catalog's only GLM route, and Grok had no Zen route at all.
|
|
580
594
|
glm: {
|
|
581
595
|
displayName: "GLM",
|
|
582
|
-
resolve: "opencode/glm-5.
|
|
583
|
-
effort: ["high", "max"],
|
|
584
|
-
|
|
585
|
-
openRouterResolve: "openrouter/z-ai/glm-5.2"
|
|
596
|
+
resolve: "opencode/glm-5.3",
|
|
597
|
+
effort: ["low", "high", "max"],
|
|
598
|
+
openRouterResolve: "openrouter/z-ai/glm-5.3"
|
|
586
599
|
},
|
|
587
600
|
grok: {
|
|
588
601
|
displayName: "Grok",
|
|
@@ -629,10 +642,11 @@ var providers = {
|
|
|
629
642
|
// OpenCode Go is a separate $10/mo subscription from Zen, served on its own
|
|
630
643
|
// base URL (`https://opencode.ai/zen/go/v1`) but authenticated with the SAME
|
|
631
644
|
// `OPENCODE_API_KEY`. it carries the open-weight coding models plus a couple
|
|
632
|
-
// of frontier ones,
|
|
633
|
-
//
|
|
634
|
-
//
|
|
635
|
-
//
|
|
645
|
+
// of frontier ones, six of which are served ONLY here — Zen's `/v1/models`
|
|
646
|
+
// does not list qwen3.7/3.8-*, mimo-v2.5-pro, longcat-2.0 or hy3. (it listed
|
|
647
|
+
// no glm-5.3* either until 2026-09, which is why `opencode/glm` trailed on
|
|
648
|
+
// 5.2.) so for a Go subscriber this provider is not a duplicate route to Zen,
|
|
649
|
+
// it is the only route to a large part of what they pay for.
|
|
636
650
|
// like `opencode` and `openrouter` this is a ROUTER, not a vendor: slugs and
|
|
637
651
|
// display names mirror the upstream brand tier, and the picker groups them
|
|
638
652
|
// under the upstream vendor.
|
|
@@ -701,7 +715,9 @@ var providers = {
|
|
|
701
715
|
// `high` the Go route does not.
|
|
702
716
|
effort: ["low", "medium", "xhigh"],
|
|
703
717
|
openRouterEffort: ["minimal", "low", "medium", "high", "xhigh"],
|
|
704
|
-
|
|
718
|
+
// OpenRouter retired the rolling `qwen3.8-max` for a dated snapshot, so
|
|
719
|
+
// this side has to pin one; the Go route still carries the rolling id.
|
|
720
|
+
openRouterResolve: "openrouter/qwen/qwen3.8-max-0902"
|
|
705
721
|
},
|
|
706
722
|
"qwen-plus": {
|
|
707
723
|
displayName: "Qwen Plus",
|
|
@@ -881,6 +897,13 @@ var providers = {
|
|
|
881
897
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
882
898
|
subagentModel: "gpt-terra"
|
|
883
899
|
},
|
|
900
|
+
"gpt-astra": {
|
|
901
|
+
displayName: "GPT Astra",
|
|
902
|
+
resolve: "openrouter/openai/gpt-6-astra",
|
|
903
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
904
|
+
openRouterResolve: "openrouter/openai/gpt-6-astra",
|
|
905
|
+
subagentModel: "gpt-sol"
|
|
906
|
+
},
|
|
884
907
|
// see openai/gpt-sol-pro. openrouter serves sol-pro directly on both routes.
|
|
885
908
|
"gpt-sol-pro": {
|
|
886
909
|
displayName: "GPT Sol Pro",
|
|
@@ -1051,6 +1074,12 @@ var providers = {
|
|
|
1051
1074
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
1052
1075
|
subagentModel: "gpt-terra"
|
|
1053
1076
|
},
|
|
1077
|
+
"gpt-astra": {
|
|
1078
|
+
displayName: "GPT Astra",
|
|
1079
|
+
resolve: "vercel/openai/gpt-6-astra",
|
|
1080
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
1081
|
+
subagentModel: "gpt-sol"
|
|
1082
|
+
},
|
|
1054
1083
|
"gpt-terra": {
|
|
1055
1084
|
displayName: "GPT Terra",
|
|
1056
1085
|
resolve: "vercel/openai/gpt-5.6-terra",
|
|
@@ -1383,6 +1412,7 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
|
|
|
1383
1412
|
- record what was done (or why nothing was done)
|
|
1384
1413
|
|
|
1385
1414
|
5. Quality check:
|
|
1415
|
+
- re-call \`${t("get_review_comments")}\` with \`fresh: true\` before committing: reviewers keep commenting while you work, and any thread it now returns that you have not addressed is in scope for this run.
|
|
1386
1416
|
- test changes, then review the diff before committing \u2014 verify only intended changes are present, no debug artifacts remain, no fix turned out to be bloat in context (revert any that did), and the changes are clean enough that a senior engineer would approve without hesitation
|
|
1387
1417
|
- ${commitStep}
|
|
1388
1418
|
|
|
@@ -1392,7 +1422,7 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
|
|
|
1392
1422
|
- **once the fix is live on the remote**, for each thread you acted on:
|
|
1393
1423
|
- reply ONCE via \`${t("reply_to_review_comment")}\`. The \`comment_id\` parameter takes the root comment's numeric \`id=\` (from the first \`comment author=...\` tag in the \`${t("get_review_comments")}\` output) \u2014 NOT the \`thread=\` value; that's a separate GraphQL ID used by resolve. The runtime dedupes identical bodies within a session.
|
|
1394
1424
|
- **immediately** call \`${t("resolve_review_thread")}\` with that thread's \`thread=\` value as \`thread_id\`. Resolve every thread where you (a) made the requested code change in full \u2014 partial fixes leave the thread open \u2014 OR (b) replied with a substantive answer the user explicitly asked for. Do NOT resolve threads where you pushed back on the request and the disagreement is unresolved; leave those open for the human to mediate.
|
|
1395
|
-
- call \`${t("report_progress")}\` with a brief summary
|
|
1425
|
+
- call \`${t("report_progress")}\` with a brief summary. If your last \`${t("get_review_comments")}\` turned up threads you did not address, name them there \u2014 a review arriving this late is suppressed as a duplicate and nothing else will pick it up.`
|
|
1396
1426
|
},
|
|
1397
1427
|
// Review and IncrementalReview route the minimum reviewfrog specialists
|
|
1398
1428
|
// needed to cover unresolved, disposition-changing hypotheses. Most runs
|
|
@@ -1653,11 +1683,11 @@ var modes = computeModes("opencode");
|
|
|
1653
1683
|
function commercialPaywallBody(params) {
|
|
1654
1684
|
if (params.reason === "commercial") {
|
|
1655
1685
|
return [
|
|
1656
|
-
`**Pullfrog needs
|
|
1686
|
+
`**Pullfrog needs Pro on ${params.ownerLogin}, so this run didn't start.**`,
|
|
1657
1687
|
"",
|
|
1658
|
-
"
|
|
1688
|
+
"Pro is $30/month per organization and covers private repositories. Public repos and personal accounts keep running free.",
|
|
1659
1689
|
"",
|
|
1660
|
-
`[
|
|
1690
|
+
`[Upgrade to Pro \u2192](${params.url})`
|
|
1661
1691
|
].join("\n");
|
|
1662
1692
|
}
|
|
1663
1693
|
params.reason;
|
|
@@ -67,6 +67,7 @@ export declare function parseFilePatches(patch: string): ParsedHunk[];
|
|
|
67
67
|
export declare const GetReviewComments: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
68
68
|
pull_number: number;
|
|
69
69
|
review_id: number;
|
|
70
|
+
fresh?: boolean;
|
|
70
71
|
}, {}>;
|
|
71
72
|
/**
|
|
72
73
|
* formats thread blocks into markdown with TOC and line numbers.
|
|
@@ -94,6 +95,37 @@ export declare function buildThreadBlocks(threads: ReviewThread[], filePatchMap:
|
|
|
94
95
|
lineRange: string;
|
|
95
96
|
content: string[];
|
|
96
97
|
}[];
|
|
98
|
+
/**
|
|
99
|
+
* Open threads on the PR that this run should also address, beyond the review
|
|
100
|
+
* that dispatched it.
|
|
101
|
+
*
|
|
102
|
+
* A reviewer working through a PR emits one `pull_request_review_submitted` per
|
|
103
|
+
* submission, so a second review lands seconds after the first — and until this
|
|
104
|
+
* existed, the run already working on the PR could never see it: the filter
|
|
105
|
+
* above keeps only threads carrying a comment from the *dispatched* `reviewId`,
|
|
106
|
+
* so a new comment on a different line was invisible no matter how often the
|
|
107
|
+
* agent re-read. That is what made the in-flight cap in `handleWebhook.ts` a
|
|
108
|
+
* silent loss rather than the coalescing it was documented as (#1103).
|
|
109
|
+
*
|
|
110
|
+
* `fetchAllReviewThreads` already pulls every thread on the PR and caches it for
|
|
111
|
+
* 60s, so this costs no extra round trip and a re-read mid-run picks up whatever
|
|
112
|
+
* landed behind the run.
|
|
113
|
+
*
|
|
114
|
+
* Three exclusions, each load-bearing:
|
|
115
|
+
* - resolved threads are done, and re-opening that conversation is noise.
|
|
116
|
+
* - a thread Pullfrog has already spoken in was handled by an earlier run.
|
|
117
|
+
* That deliberately includes the pushbacks AddressReviews leaves open for a
|
|
118
|
+
* human to mediate — re-addressing one re-litigates a settled disagreement —
|
|
119
|
+
* and it is also what stops this mode replying to Pullfrog's own reviews.
|
|
120
|
+
* - under `mentions` a concurrent thread is in scope only if it actually asked
|
|
121
|
+
* for Pullfrog. Deliberately asymmetric with `threadsForReview`, which is
|
|
122
|
+
* returned whole and always was: the dispatching review is the one the
|
|
123
|
+
* server already adjudicated, and the agent needs its unmentioned threads as
|
|
124
|
+
* context for the comment that did mention it. Which of those to ACT on stays
|
|
125
|
+
* the mode prompt's job. A concurrent review has had no such adjudication, so
|
|
126
|
+
* the mention is the only thing that can authorize it.
|
|
127
|
+
*/
|
|
128
|
+
export declare function concurrentThreads(allThreads: (ReviewThread | null)[], threadsForReview: ReviewThread[], input: GetReviewDataInput): ReviewThread[];
|
|
97
129
|
interface GetReviewDataInput {
|
|
98
130
|
octokit: Octokit;
|
|
99
131
|
owner: string;
|
|
@@ -101,6 +133,14 @@ interface GetReviewDataInput {
|
|
|
101
133
|
pullNumber: number;
|
|
102
134
|
reviewId: number;
|
|
103
135
|
approvedBy?: string | undefined;
|
|
136
|
+
/**
|
|
137
|
+
* Widen the read past the dispatching review to the other open threads on the
|
|
138
|
+
* PR — `all` on a Pullfrog-authored PR, `mentions` when only `@pullfrog`-
|
|
139
|
+
* mentioning threads are in scope. Absent (console `fix_review`, and any
|
|
140
|
+
* payload from a server build that predates the field) keeps the read scoped
|
|
141
|
+
* to the dispatching review exactly as before.
|
|
142
|
+
*/
|
|
143
|
+
addressScope?: "all" | "mentions" | undefined;
|
|
104
144
|
tmpdir: string;
|
|
105
145
|
githubToken: string;
|
|
106
146
|
}
|
|
@@ -148,9 +188,11 @@ export declare function getReviewData(input: GetReviewDataInput): Promise<{
|
|
|
148
188
|
export declare function GetReviewCommentsTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
|
|
149
189
|
pull_number: number;
|
|
150
190
|
review_id: number;
|
|
191
|
+
fresh?: boolean;
|
|
151
192
|
}, {
|
|
152
193
|
pull_number: number;
|
|
153
194
|
review_id: number;
|
|
195
|
+
fresh?: boolean;
|
|
154
196
|
}>> & {
|
|
155
197
|
mutates?: boolean;
|
|
156
198
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pullfrog",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.70",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"pullfrog": "dist/cli.mjs",
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
"@ark/util": "0.56.0",
|
|
32
32
|
"@clack/prompts": "^1.2.0",
|
|
33
33
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
34
|
-
"@opencode-ai/sdk": "1.18.5",
|
|
35
|
-
"@openai/codex": "0.147.0",
|
|
36
|
-
"@openai/codex-sdk": "0.147.0",
|
|
37
34
|
"@octokit/plugin-throttling": "^11.0.3",
|
|
38
35
|
"@octokit/rest": "^22.0.0",
|
|
39
36
|
"@octokit/webhooks-types": "^7.6.1",
|
|
37
|
+
"@openai/codex": "0.153.4",
|
|
38
|
+
"@openai/codex-sdk": "0.153.4",
|
|
39
|
+
"@opencode-ai/sdk": "1.18.29",
|
|
40
40
|
"@standard-schema/spec": "1.1.0",
|
|
41
41
|
"@toon-format/toon": "^1.0.0",
|
|
42
42
|
"@types/node": "^24.7.2",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"husky": "^9.0.0",
|
|
57
57
|
"lru-cache": "^11.0.0",
|
|
58
58
|
"object-hash": "^3.0.0",
|
|
59
|
-
"opencode-ai": "1.18.
|
|
59
|
+
"opencode-ai": "1.18.29",
|
|
60
60
|
"package-manager-detector": "^1.6.0",
|
|
61
61
|
"picocolors": "^1.1.1",
|
|
62
62
|
"semver": "^7.7.3",
|