pullfrog 0.1.51 → 0.1.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/agents/opencodeShared.d.ts +1 -1
- package/dist/cli.mjs +921 -526
- package/dist/external.d.ts +9 -1
- package/dist/index.js +919 -525
- package/dist/internal/index.d.ts +1 -1
- package/dist/internal.js +154 -57
- package/dist/mcp/shell.d.ts +4 -4
- package/dist/models.d.ts +29 -5
- package/dist/utils/apiKeys.d.ts +14 -9
- package/dist/utils/gitAuth.d.ts +13 -0
- package/dist/utils/modelAccess.d.ts +4 -2
- package/dist/utils/packageManager.d.ts +22 -0
- package/dist/utils/payload.d.ts +3 -0
- package/dist/utils/rangeDiff.d.ts +20 -1
- package/dist/utils/runContext.d.ts +1 -0
- package/dist/utils/runEffort.d.ts +15 -0
- package/dist/utils/runErrorRenderer.d.ts +15 -2
- package/dist/utils/secrets.d.ts +5 -0
- package/dist/utils/setup.d.ts +7 -0
- package/dist/utils/statusChecks.d.ts +1 -1
- package/dist/utils/worktree.d.ts +20 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3598,9 +3598,9 @@ var require_constants2 = __commonJS({
|
|
|
3598
3598
|
}
|
|
3599
3599
|
})();
|
|
3600
3600
|
var channel;
|
|
3601
|
-
var
|
|
3601
|
+
var structuredClone2 = globalThis.structuredClone ?? // https://github.com/nodejs/node/blob/b27ae24dcc4251bad726d9d84baf678d1f707fed/lib/internal/structured_clone.js
|
|
3602
3602
|
// structuredClone was added in v17.0.0, but fetch supports v16.8
|
|
3603
|
-
function
|
|
3603
|
+
function structuredClone3(value2, options = void 0) {
|
|
3604
3604
|
if (arguments.length === 0) {
|
|
3605
3605
|
throw new TypeError("missing argument");
|
|
3606
3606
|
}
|
|
@@ -3614,7 +3614,7 @@ var require_constants2 = __commonJS({
|
|
|
3614
3614
|
};
|
|
3615
3615
|
module.exports = {
|
|
3616
3616
|
DOMException: DOMException2,
|
|
3617
|
-
structuredClone,
|
|
3617
|
+
structuredClone: structuredClone2,
|
|
3618
3618
|
subresource,
|
|
3619
3619
|
forbiddenMethods,
|
|
3620
3620
|
requestBodyHeader,
|
|
@@ -5319,7 +5319,7 @@ var require_body = __commonJS({
|
|
|
5319
5319
|
var { FormData: FormData2 } = require_formdata();
|
|
5320
5320
|
var { kState } = require_symbols2();
|
|
5321
5321
|
var { webidl } = require_webidl();
|
|
5322
|
-
var { DOMException: DOMException2, structuredClone } = require_constants2();
|
|
5322
|
+
var { DOMException: DOMException2, structuredClone: structuredClone2 } = require_constants2();
|
|
5323
5323
|
var { Blob: Blob2, File: NativeFile } = __require("buffer");
|
|
5324
5324
|
var { kBodyUsed } = require_symbols();
|
|
5325
5325
|
var assert3 = __require("assert");
|
|
@@ -5483,7 +5483,7 @@ Content-Type: ${value2.type || "application/octet-stream"}\r
|
|
|
5483
5483
|
}
|
|
5484
5484
|
function cloneBody(body) {
|
|
5485
5485
|
const [out1, out2] = body.stream.tee();
|
|
5486
|
-
const out2Clone =
|
|
5486
|
+
const out2Clone = structuredClone2(out2, { transfer: [out2] });
|
|
5487
5487
|
const [, finalClone] = out2Clone.tee();
|
|
5488
5488
|
body.stream = out1;
|
|
5489
5489
|
return {
|
|
@@ -19793,10 +19793,10 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``);
|
|
|
19793
19793
|
(0, command_1.issueCommand)("error", (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message);
|
|
19794
19794
|
}
|
|
19795
19795
|
exports.error = error49;
|
|
19796
|
-
function
|
|
19796
|
+
function warning3(message, properties = {}) {
|
|
19797
19797
|
(0, command_1.issueCommand)("warning", (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message);
|
|
19798
19798
|
}
|
|
19799
|
-
exports.warning =
|
|
19799
|
+
exports.warning = warning3;
|
|
19800
19800
|
function notice(message, properties = {}) {
|
|
19801
19801
|
(0, command_1.issueCommand)("notice", (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message);
|
|
19802
19802
|
}
|
|
@@ -66407,7 +66407,7 @@ function initializeContext(params) {
|
|
|
66407
66407
|
external: params?.external ?? void 0
|
|
66408
66408
|
};
|
|
66409
66409
|
}
|
|
66410
|
-
function
|
|
66410
|
+
function process3(schema2, ctx, _params = { path: [], schemaPath: [] }) {
|
|
66411
66411
|
var _a2;
|
|
66412
66412
|
const def = schema2._zod.def;
|
|
66413
66413
|
const seen = ctx.seen.get(schema2);
|
|
@@ -66444,7 +66444,7 @@ function process2(schema2, ctx, _params = { path: [], schemaPath: [] }) {
|
|
|
66444
66444
|
if (parent) {
|
|
66445
66445
|
if (!result.ref)
|
|
66446
66446
|
result.ref = parent;
|
|
66447
|
-
|
|
66447
|
+
process3(parent, ctx, params);
|
|
66448
66448
|
ctx.seen.get(parent).isParent = true;
|
|
66449
66449
|
}
|
|
66450
66450
|
}
|
|
@@ -66729,14 +66729,14 @@ var init_to_json_schema = __esm({
|
|
|
66729
66729
|
init_registries();
|
|
66730
66730
|
createToJSONSchemaMethod = (schema2, processors = {}) => (params) => {
|
|
66731
66731
|
const ctx = initializeContext({ ...params, processors });
|
|
66732
|
-
|
|
66732
|
+
process3(schema2, ctx);
|
|
66733
66733
|
extractDefs(ctx, schema2);
|
|
66734
66734
|
return finalize(ctx, schema2);
|
|
66735
66735
|
};
|
|
66736
66736
|
createStandardJSONSchemaMethod = (schema2, io, processors = {}) => (params) => {
|
|
66737
66737
|
const { libraryOptions, target } = params ?? {};
|
|
66738
66738
|
const ctx = initializeContext({ ...libraryOptions ?? {}, target, io, processors });
|
|
66739
|
-
|
|
66739
|
+
process3(schema2, ctx);
|
|
66740
66740
|
extractDefs(ctx, schema2);
|
|
66741
66741
|
return finalize(ctx, schema2);
|
|
66742
66742
|
};
|
|
@@ -66751,7 +66751,7 @@ function toJSONSchema(input, params) {
|
|
|
66751
66751
|
const defs = {};
|
|
66752
66752
|
for (const entry of registry4._idmap.entries()) {
|
|
66753
66753
|
const [_, schema2] = entry;
|
|
66754
|
-
|
|
66754
|
+
process3(schema2, ctx2);
|
|
66755
66755
|
}
|
|
66756
66756
|
const schemas = {};
|
|
66757
66757
|
const external = {
|
|
@@ -66774,7 +66774,7 @@ function toJSONSchema(input, params) {
|
|
|
66774
66774
|
return { schemas };
|
|
66775
66775
|
}
|
|
66776
66776
|
const ctx = initializeContext({ ...params, processors: allProcessors });
|
|
66777
|
-
|
|
66777
|
+
process3(input, ctx);
|
|
66778
66778
|
extractDefs(ctx, input);
|
|
66779
66779
|
return finalize(ctx, input);
|
|
66780
66780
|
}
|
|
@@ -67034,7 +67034,7 @@ var init_json_schema_processors = __esm({
|
|
|
67034
67034
|
if (typeof maximum === "number")
|
|
67035
67035
|
json4.maxItems = maximum;
|
|
67036
67036
|
json4.type = "array";
|
|
67037
|
-
json4.items =
|
|
67037
|
+
json4.items = process3(def.element, ctx, { ...params, path: [...params.path, "items"] });
|
|
67038
67038
|
};
|
|
67039
67039
|
objectProcessor = (schema2, ctx, _json, params) => {
|
|
67040
67040
|
const json4 = _json;
|
|
@@ -67043,7 +67043,7 @@ var init_json_schema_processors = __esm({
|
|
|
67043
67043
|
json4.properties = {};
|
|
67044
67044
|
const shape = def.shape;
|
|
67045
67045
|
for (const key in shape) {
|
|
67046
|
-
json4.properties[key] =
|
|
67046
|
+
json4.properties[key] = process3(shape[key], ctx, {
|
|
67047
67047
|
...params,
|
|
67048
67048
|
path: [...params.path, "properties", key]
|
|
67049
67049
|
});
|
|
@@ -67066,7 +67066,7 @@ var init_json_schema_processors = __esm({
|
|
|
67066
67066
|
if (ctx.io === "output")
|
|
67067
67067
|
json4.additionalProperties = false;
|
|
67068
67068
|
} else if (def.catchall) {
|
|
67069
|
-
json4.additionalProperties =
|
|
67069
|
+
json4.additionalProperties = process3(def.catchall, ctx, {
|
|
67070
67070
|
...params,
|
|
67071
67071
|
path: [...params.path, "additionalProperties"]
|
|
67072
67072
|
});
|
|
@@ -67075,7 +67075,7 @@ var init_json_schema_processors = __esm({
|
|
|
67075
67075
|
unionProcessor = (schema2, ctx, json4, params) => {
|
|
67076
67076
|
const def = schema2._zod.def;
|
|
67077
67077
|
const isExclusive = def.inclusive === false;
|
|
67078
|
-
const options = def.options.map((x, i) =>
|
|
67078
|
+
const options = def.options.map((x, i) => process3(x, ctx, {
|
|
67079
67079
|
...params,
|
|
67080
67080
|
path: [...params.path, isExclusive ? "oneOf" : "anyOf", i]
|
|
67081
67081
|
}));
|
|
@@ -67087,11 +67087,11 @@ var init_json_schema_processors = __esm({
|
|
|
67087
67087
|
};
|
|
67088
67088
|
intersectionProcessor = (schema2, ctx, json4, params) => {
|
|
67089
67089
|
const def = schema2._zod.def;
|
|
67090
|
-
const a =
|
|
67090
|
+
const a = process3(def.left, ctx, {
|
|
67091
67091
|
...params,
|
|
67092
67092
|
path: [...params.path, "allOf", 0]
|
|
67093
67093
|
});
|
|
67094
|
-
const b =
|
|
67094
|
+
const b = process3(def.right, ctx, {
|
|
67095
67095
|
...params,
|
|
67096
67096
|
path: [...params.path, "allOf", 1]
|
|
67097
67097
|
});
|
|
@@ -67108,11 +67108,11 @@ var init_json_schema_processors = __esm({
|
|
|
67108
67108
|
json4.type = "array";
|
|
67109
67109
|
const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
|
|
67110
67110
|
const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
|
|
67111
|
-
const prefixItems = def.items.map((x, i) =>
|
|
67111
|
+
const prefixItems = def.items.map((x, i) => process3(x, ctx, {
|
|
67112
67112
|
...params,
|
|
67113
67113
|
path: [...params.path, prefixPath, i]
|
|
67114
67114
|
}));
|
|
67115
|
-
const rest = def.rest ?
|
|
67115
|
+
const rest = def.rest ? process3(def.rest, ctx, {
|
|
67116
67116
|
...params,
|
|
67117
67117
|
path: [...params.path, restPath, ...ctx.target === "openapi-3.0" ? [def.items.length] : []]
|
|
67118
67118
|
}) : null;
|
|
@@ -67152,7 +67152,7 @@ var init_json_schema_processors = __esm({
|
|
|
67152
67152
|
const keyBag = keyType._zod.bag;
|
|
67153
67153
|
const patterns = keyBag?.patterns;
|
|
67154
67154
|
if (def.mode === "loose" && patterns && patterns.size > 0) {
|
|
67155
|
-
const valueSchema =
|
|
67155
|
+
const valueSchema = process3(def.valueType, ctx, {
|
|
67156
67156
|
...params,
|
|
67157
67157
|
path: [...params.path, "patternProperties", "*"]
|
|
67158
67158
|
});
|
|
@@ -67162,12 +67162,12 @@ var init_json_schema_processors = __esm({
|
|
|
67162
67162
|
}
|
|
67163
67163
|
} else {
|
|
67164
67164
|
if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
|
|
67165
|
-
json4.propertyNames =
|
|
67165
|
+
json4.propertyNames = process3(def.keyType, ctx, {
|
|
67166
67166
|
...params,
|
|
67167
67167
|
path: [...params.path, "propertyNames"]
|
|
67168
67168
|
});
|
|
67169
67169
|
}
|
|
67170
|
-
json4.additionalProperties =
|
|
67170
|
+
json4.additionalProperties = process3(def.valueType, ctx, {
|
|
67171
67171
|
...params,
|
|
67172
67172
|
path: [...params.path, "additionalProperties"]
|
|
67173
67173
|
});
|
|
@@ -67182,7 +67182,7 @@ var init_json_schema_processors = __esm({
|
|
|
67182
67182
|
};
|
|
67183
67183
|
nullableProcessor = (schema2, ctx, json4, params) => {
|
|
67184
67184
|
const def = schema2._zod.def;
|
|
67185
|
-
const inner =
|
|
67185
|
+
const inner = process3(def.innerType, ctx, params);
|
|
67186
67186
|
const seen = ctx.seen.get(schema2);
|
|
67187
67187
|
if (ctx.target === "openapi-3.0") {
|
|
67188
67188
|
seen.ref = def.innerType;
|
|
@@ -67193,20 +67193,20 @@ var init_json_schema_processors = __esm({
|
|
|
67193
67193
|
};
|
|
67194
67194
|
nonoptionalProcessor = (schema2, ctx, _json, params) => {
|
|
67195
67195
|
const def = schema2._zod.def;
|
|
67196
|
-
|
|
67196
|
+
process3(def.innerType, ctx, params);
|
|
67197
67197
|
const seen = ctx.seen.get(schema2);
|
|
67198
67198
|
seen.ref = def.innerType;
|
|
67199
67199
|
};
|
|
67200
67200
|
defaultProcessor = (schema2, ctx, json4, params) => {
|
|
67201
67201
|
const def = schema2._zod.def;
|
|
67202
|
-
|
|
67202
|
+
process3(def.innerType, ctx, params);
|
|
67203
67203
|
const seen = ctx.seen.get(schema2);
|
|
67204
67204
|
seen.ref = def.innerType;
|
|
67205
67205
|
json4.default = JSON.parse(JSON.stringify(def.defaultValue));
|
|
67206
67206
|
};
|
|
67207
67207
|
prefaultProcessor = (schema2, ctx, json4, params) => {
|
|
67208
67208
|
const def = schema2._zod.def;
|
|
67209
|
-
|
|
67209
|
+
process3(def.innerType, ctx, params);
|
|
67210
67210
|
const seen = ctx.seen.get(schema2);
|
|
67211
67211
|
seen.ref = def.innerType;
|
|
67212
67212
|
if (ctx.io === "input")
|
|
@@ -67214,7 +67214,7 @@ var init_json_schema_processors = __esm({
|
|
|
67214
67214
|
};
|
|
67215
67215
|
catchProcessor = (schema2, ctx, json4, params) => {
|
|
67216
67216
|
const def = schema2._zod.def;
|
|
67217
|
-
|
|
67217
|
+
process3(def.innerType, ctx, params);
|
|
67218
67218
|
const seen = ctx.seen.get(schema2);
|
|
67219
67219
|
seen.ref = def.innerType;
|
|
67220
67220
|
let catchValue;
|
|
@@ -67228,32 +67228,32 @@ var init_json_schema_processors = __esm({
|
|
|
67228
67228
|
pipeProcessor = (schema2, ctx, _json, params) => {
|
|
67229
67229
|
const def = schema2._zod.def;
|
|
67230
67230
|
const innerType = ctx.io === "input" ? def.in._zod.def.type === "transform" ? def.out : def.in : def.out;
|
|
67231
|
-
|
|
67231
|
+
process3(innerType, ctx, params);
|
|
67232
67232
|
const seen = ctx.seen.get(schema2);
|
|
67233
67233
|
seen.ref = innerType;
|
|
67234
67234
|
};
|
|
67235
67235
|
readonlyProcessor = (schema2, ctx, json4, params) => {
|
|
67236
67236
|
const def = schema2._zod.def;
|
|
67237
|
-
|
|
67237
|
+
process3(def.innerType, ctx, params);
|
|
67238
67238
|
const seen = ctx.seen.get(schema2);
|
|
67239
67239
|
seen.ref = def.innerType;
|
|
67240
67240
|
json4.readOnly = true;
|
|
67241
67241
|
};
|
|
67242
67242
|
promiseProcessor = (schema2, ctx, _json, params) => {
|
|
67243
67243
|
const def = schema2._zod.def;
|
|
67244
|
-
|
|
67244
|
+
process3(def.innerType, ctx, params);
|
|
67245
67245
|
const seen = ctx.seen.get(schema2);
|
|
67246
67246
|
seen.ref = def.innerType;
|
|
67247
67247
|
};
|
|
67248
67248
|
optionalProcessor = (schema2, ctx, _json, params) => {
|
|
67249
67249
|
const def = schema2._zod.def;
|
|
67250
|
-
|
|
67250
|
+
process3(def.innerType, ctx, params);
|
|
67251
67251
|
const seen = ctx.seen.get(schema2);
|
|
67252
67252
|
seen.ref = def.innerType;
|
|
67253
67253
|
};
|
|
67254
67254
|
lazyProcessor = (schema2, ctx, _json, params) => {
|
|
67255
67255
|
const innerType = schema2._zod.innerType;
|
|
67256
|
-
|
|
67256
|
+
process3(innerType, ctx, params);
|
|
67257
67257
|
const seen = ctx.seen.get(schema2);
|
|
67258
67258
|
seen.ref = innerType;
|
|
67259
67259
|
};
|
|
@@ -67359,7 +67359,7 @@ var init_json_schema_generator = __esm({
|
|
|
67359
67359
|
* This must be called before emit().
|
|
67360
67360
|
*/
|
|
67361
67361
|
process(schema2, _params = { path: [], schemaPath: [] }) {
|
|
67362
|
-
return
|
|
67362
|
+
return process3(schema2, this.ctx, _params);
|
|
67363
67363
|
}
|
|
67364
67364
|
/**
|
|
67365
67365
|
* Emit the final JSON Schema after processing.
|
|
@@ -67652,7 +67652,7 @@ __export(core_exports2, {
|
|
|
67652
67652
|
parse: () => parse,
|
|
67653
67653
|
parseAsync: () => parseAsync,
|
|
67654
67654
|
prettifyError: () => prettifyError,
|
|
67655
|
-
process: () =>
|
|
67655
|
+
process: () => process3,
|
|
67656
67656
|
regexes: () => regexes_exports,
|
|
67657
67657
|
registry: () => registry2,
|
|
67658
67658
|
safeDecode: () => safeDecode,
|
|
@@ -99803,6 +99803,299 @@ import { existsSync as existsSync8, readdirSync as readdirSync2 } from "node:fs"
|
|
|
99803
99803
|
import { readFile as readFile5 } from "node:fs/promises";
|
|
99804
99804
|
import { join as join25 } from "node:path";
|
|
99805
99805
|
|
|
99806
|
+
// node_modules/.pnpm/package-manager-detector@1.6.0/node_modules/package-manager-detector/dist/commands.mjs
|
|
99807
|
+
function dashDashArg(agent2, agentCommand) {
|
|
99808
|
+
return (args2) => {
|
|
99809
|
+
if (args2.length > 1) {
|
|
99810
|
+
return [agent2, agentCommand, args2[0], "--", ...args2.slice(1)];
|
|
99811
|
+
} else {
|
|
99812
|
+
return [agent2, agentCommand, args2[0]];
|
|
99813
|
+
}
|
|
99814
|
+
};
|
|
99815
|
+
}
|
|
99816
|
+
function denoExecute() {
|
|
99817
|
+
return (args2) => {
|
|
99818
|
+
return ["deno", "run", `npm:${args2[0]}`, ...args2.slice(1)];
|
|
99819
|
+
};
|
|
99820
|
+
}
|
|
99821
|
+
var npm = {
|
|
99822
|
+
"agent": ["npm", 0],
|
|
99823
|
+
"run": dashDashArg("npm", "run"),
|
|
99824
|
+
"install": ["npm", "i", 0],
|
|
99825
|
+
"frozen": ["npm", "ci", 0],
|
|
99826
|
+
"global": ["npm", "i", "-g", 0],
|
|
99827
|
+
"add": ["npm", "i", 0],
|
|
99828
|
+
"upgrade": ["npm", "update", 0],
|
|
99829
|
+
"upgrade-interactive": null,
|
|
99830
|
+
"dedupe": ["npm", "dedupe", 0],
|
|
99831
|
+
"execute": ["npx", 0],
|
|
99832
|
+
"execute-local": ["npx", 0],
|
|
99833
|
+
"uninstall": ["npm", "uninstall", 0],
|
|
99834
|
+
"global_uninstall": ["npm", "uninstall", "-g", 0]
|
|
99835
|
+
};
|
|
99836
|
+
var yarn = {
|
|
99837
|
+
"agent": ["yarn", 0],
|
|
99838
|
+
"run": ["yarn", "run", 0],
|
|
99839
|
+
"install": ["yarn", "install", 0],
|
|
99840
|
+
"frozen": ["yarn", "install", "--frozen-lockfile", 0],
|
|
99841
|
+
"global": ["yarn", "global", "add", 0],
|
|
99842
|
+
"add": ["yarn", "add", 0],
|
|
99843
|
+
"upgrade": ["yarn", "upgrade", 0],
|
|
99844
|
+
"upgrade-interactive": ["yarn", "upgrade-interactive", 0],
|
|
99845
|
+
"dedupe": null,
|
|
99846
|
+
"execute": ["npx", 0],
|
|
99847
|
+
"execute-local": dashDashArg("yarn", "exec"),
|
|
99848
|
+
"uninstall": ["yarn", "remove", 0],
|
|
99849
|
+
"global_uninstall": ["yarn", "global", "remove", 0]
|
|
99850
|
+
};
|
|
99851
|
+
var yarnBerry = {
|
|
99852
|
+
...yarn,
|
|
99853
|
+
"frozen": ["yarn", "install", "--immutable", 0],
|
|
99854
|
+
"upgrade": ["yarn", "up", 0],
|
|
99855
|
+
"upgrade-interactive": ["yarn", "up", "-i", 0],
|
|
99856
|
+
"dedupe": ["yarn", "dedupe", 0],
|
|
99857
|
+
"execute": ["yarn", "dlx", 0],
|
|
99858
|
+
"execute-local": ["yarn", "exec", 0],
|
|
99859
|
+
// Yarn 2+ removed 'global', see https://github.com/yarnpkg/berry/issues/821
|
|
99860
|
+
"global": ["npm", "i", "-g", 0],
|
|
99861
|
+
"global_uninstall": ["npm", "uninstall", "-g", 0]
|
|
99862
|
+
};
|
|
99863
|
+
var pnpm = {
|
|
99864
|
+
"agent": ["pnpm", 0],
|
|
99865
|
+
"run": ["pnpm", "run", 0],
|
|
99866
|
+
"install": ["pnpm", "i", 0],
|
|
99867
|
+
"frozen": ["pnpm", "i", "--frozen-lockfile", 0],
|
|
99868
|
+
"global": ["pnpm", "add", "-g", 0],
|
|
99869
|
+
"add": ["pnpm", "add", 0],
|
|
99870
|
+
"upgrade": ["pnpm", "update", 0],
|
|
99871
|
+
"upgrade-interactive": ["pnpm", "update", "-i", 0],
|
|
99872
|
+
"dedupe": ["pnpm", "dedupe", 0],
|
|
99873
|
+
"execute": ["pnpm", "dlx", 0],
|
|
99874
|
+
"execute-local": ["pnpm", "exec", 0],
|
|
99875
|
+
"uninstall": ["pnpm", "remove", 0],
|
|
99876
|
+
"global_uninstall": ["pnpm", "remove", "--global", 0]
|
|
99877
|
+
};
|
|
99878
|
+
var bun = {
|
|
99879
|
+
"agent": ["bun", 0],
|
|
99880
|
+
"run": ["bun", "run", 0],
|
|
99881
|
+
"install": ["bun", "install", 0],
|
|
99882
|
+
"frozen": ["bun", "install", "--frozen-lockfile", 0],
|
|
99883
|
+
"global": ["bun", "add", "-g", 0],
|
|
99884
|
+
"add": ["bun", "add", 0],
|
|
99885
|
+
"upgrade": ["bun", "update", 0],
|
|
99886
|
+
"upgrade-interactive": ["bun", "update", "-i", 0],
|
|
99887
|
+
"dedupe": null,
|
|
99888
|
+
"execute": ["bun", "x", 0],
|
|
99889
|
+
"execute-local": ["bun", "x", 0],
|
|
99890
|
+
"uninstall": ["bun", "remove", 0],
|
|
99891
|
+
"global_uninstall": ["bun", "remove", "-g", 0]
|
|
99892
|
+
};
|
|
99893
|
+
var deno = {
|
|
99894
|
+
"agent": ["deno", 0],
|
|
99895
|
+
"run": ["deno", "task", 0],
|
|
99896
|
+
"install": ["deno", "install", 0],
|
|
99897
|
+
"frozen": ["deno", "install", "--frozen", 0],
|
|
99898
|
+
"global": ["deno", "install", "-g", 0],
|
|
99899
|
+
"add": ["deno", "add", 0],
|
|
99900
|
+
"upgrade": ["deno", "outdated", "--update", 0],
|
|
99901
|
+
"upgrade-interactive": ["deno", "outdated", "--update", 0],
|
|
99902
|
+
"dedupe": null,
|
|
99903
|
+
"execute": denoExecute(),
|
|
99904
|
+
"execute-local": ["deno", "task", "--eval", 0],
|
|
99905
|
+
"uninstall": ["deno", "remove", 0],
|
|
99906
|
+
"global_uninstall": ["deno", "uninstall", "-g", 0]
|
|
99907
|
+
};
|
|
99908
|
+
var COMMANDS = {
|
|
99909
|
+
"npm": npm,
|
|
99910
|
+
"yarn": yarn,
|
|
99911
|
+
"yarn@berry": yarnBerry,
|
|
99912
|
+
"pnpm": pnpm,
|
|
99913
|
+
// pnpm v6.x or below
|
|
99914
|
+
"pnpm@6": {
|
|
99915
|
+
...pnpm,
|
|
99916
|
+
run: dashDashArg("pnpm", "run")
|
|
99917
|
+
},
|
|
99918
|
+
"bun": bun,
|
|
99919
|
+
"deno": deno
|
|
99920
|
+
};
|
|
99921
|
+
function resolveCommand(agent2, command, args2) {
|
|
99922
|
+
const value2 = COMMANDS[agent2][command];
|
|
99923
|
+
return constructCommand(value2, args2);
|
|
99924
|
+
}
|
|
99925
|
+
function constructCommand(value2, args2) {
|
|
99926
|
+
if (value2 == null)
|
|
99927
|
+
return null;
|
|
99928
|
+
const list = typeof value2 === "function" ? value2(args2) : value2.flatMap((v) => {
|
|
99929
|
+
if (typeof v === "number")
|
|
99930
|
+
return args2;
|
|
99931
|
+
return [v];
|
|
99932
|
+
});
|
|
99933
|
+
return {
|
|
99934
|
+
command: list[0],
|
|
99935
|
+
args: list.slice(1)
|
|
99936
|
+
};
|
|
99937
|
+
}
|
|
99938
|
+
|
|
99939
|
+
// node_modules/.pnpm/package-manager-detector@1.6.0/node_modules/package-manager-detector/dist/constants.mjs
|
|
99940
|
+
var AGENTS = [
|
|
99941
|
+
"npm",
|
|
99942
|
+
"yarn",
|
|
99943
|
+
"yarn@berry",
|
|
99944
|
+
"pnpm",
|
|
99945
|
+
"pnpm@6",
|
|
99946
|
+
"bun",
|
|
99947
|
+
"deno"
|
|
99948
|
+
];
|
|
99949
|
+
var LOCKS = {
|
|
99950
|
+
"bun.lock": "bun",
|
|
99951
|
+
"bun.lockb": "bun",
|
|
99952
|
+
"deno.lock": "deno",
|
|
99953
|
+
"pnpm-lock.yaml": "pnpm",
|
|
99954
|
+
"pnpm-workspace.yaml": "pnpm",
|
|
99955
|
+
"yarn.lock": "yarn",
|
|
99956
|
+
"package-lock.json": "npm",
|
|
99957
|
+
"npm-shrinkwrap.json": "npm"
|
|
99958
|
+
};
|
|
99959
|
+
var INSTALL_METADATA = {
|
|
99960
|
+
"node_modules/.deno/": "deno",
|
|
99961
|
+
"node_modules/.pnpm/": "pnpm",
|
|
99962
|
+
"node_modules/.yarn-state.yml": "yarn",
|
|
99963
|
+
// yarn v2+ (node-modules)
|
|
99964
|
+
"node_modules/.yarn_integrity": "yarn",
|
|
99965
|
+
// yarn v1
|
|
99966
|
+
"node_modules/.package-lock.json": "npm",
|
|
99967
|
+
".pnp.cjs": "yarn",
|
|
99968
|
+
// yarn v3+ (pnp)
|
|
99969
|
+
".pnp.js": "yarn",
|
|
99970
|
+
// yarn v2 (pnp)
|
|
99971
|
+
"bun.lock": "bun",
|
|
99972
|
+
"bun.lockb": "bun"
|
|
99973
|
+
};
|
|
99974
|
+
|
|
99975
|
+
// node_modules/.pnpm/package-manager-detector@1.6.0/node_modules/package-manager-detector/dist/detect.mjs
|
|
99976
|
+
import fs from "node:fs/promises";
|
|
99977
|
+
import path from "node:path";
|
|
99978
|
+
import process2 from "node:process";
|
|
99979
|
+
async function pathExists(path22, type2) {
|
|
99980
|
+
try {
|
|
99981
|
+
const stat = await fs.stat(path22);
|
|
99982
|
+
return type2 === "file" ? stat.isFile() : stat.isDirectory();
|
|
99983
|
+
} catch {
|
|
99984
|
+
return false;
|
|
99985
|
+
}
|
|
99986
|
+
}
|
|
99987
|
+
function* lookup(cwd = process2.cwd()) {
|
|
99988
|
+
let directory = path.resolve(cwd);
|
|
99989
|
+
const { root } = path.parse(directory);
|
|
99990
|
+
while (directory && directory !== root) {
|
|
99991
|
+
yield directory;
|
|
99992
|
+
directory = path.dirname(directory);
|
|
99993
|
+
}
|
|
99994
|
+
}
|
|
99995
|
+
async function parsePackageJson(filepath, options) {
|
|
99996
|
+
if (!filepath || !await pathExists(filepath, "file"))
|
|
99997
|
+
return null;
|
|
99998
|
+
return await handlePackageManager(filepath, options);
|
|
99999
|
+
}
|
|
100000
|
+
async function detect(options = {}) {
|
|
100001
|
+
const {
|
|
100002
|
+
cwd,
|
|
100003
|
+
strategies = ["lockfile", "packageManager-field", "devEngines-field"]
|
|
100004
|
+
} = options;
|
|
100005
|
+
let stopDir;
|
|
100006
|
+
if (typeof options.stopDir === "string") {
|
|
100007
|
+
const resolved = path.resolve(options.stopDir);
|
|
100008
|
+
stopDir = (dir) => dir === resolved;
|
|
100009
|
+
} else {
|
|
100010
|
+
stopDir = options.stopDir;
|
|
100011
|
+
}
|
|
100012
|
+
for (const directory of lookup(cwd)) {
|
|
100013
|
+
for (const strategy of strategies) {
|
|
100014
|
+
switch (strategy) {
|
|
100015
|
+
case "lockfile": {
|
|
100016
|
+
for (const lock of Object.keys(LOCKS)) {
|
|
100017
|
+
if (await pathExists(path.join(directory, lock), "file")) {
|
|
100018
|
+
const name = LOCKS[lock];
|
|
100019
|
+
const result = await parsePackageJson(path.join(directory, "package.json"), options);
|
|
100020
|
+
if (result)
|
|
100021
|
+
return result;
|
|
100022
|
+
else
|
|
100023
|
+
return { name, agent: name };
|
|
100024
|
+
}
|
|
100025
|
+
}
|
|
100026
|
+
break;
|
|
100027
|
+
}
|
|
100028
|
+
case "packageManager-field":
|
|
100029
|
+
case "devEngines-field": {
|
|
100030
|
+
const result = await parsePackageJson(path.join(directory, "package.json"), options);
|
|
100031
|
+
if (result)
|
|
100032
|
+
return result;
|
|
100033
|
+
break;
|
|
100034
|
+
}
|
|
100035
|
+
case "install-metadata": {
|
|
100036
|
+
for (const metadata of Object.keys(INSTALL_METADATA)) {
|
|
100037
|
+
const fileOrDir = metadata.endsWith("/") ? "dir" : "file";
|
|
100038
|
+
if (await pathExists(path.join(directory, metadata), fileOrDir)) {
|
|
100039
|
+
const name = INSTALL_METADATA[metadata];
|
|
100040
|
+
const agent2 = name === "yarn" ? isMetadataYarnClassic(metadata) ? "yarn" : "yarn@berry" : name;
|
|
100041
|
+
return { name, agent: agent2 };
|
|
100042
|
+
}
|
|
100043
|
+
}
|
|
100044
|
+
break;
|
|
100045
|
+
}
|
|
100046
|
+
}
|
|
100047
|
+
}
|
|
100048
|
+
if (stopDir?.(directory))
|
|
100049
|
+
break;
|
|
100050
|
+
}
|
|
100051
|
+
return null;
|
|
100052
|
+
}
|
|
100053
|
+
function getNameAndVer(pkg) {
|
|
100054
|
+
const handelVer = (version3) => version3?.match(/\d+(\.\d+){0,2}/)?.[0] ?? version3;
|
|
100055
|
+
if (typeof pkg.packageManager === "string") {
|
|
100056
|
+
const [name, ver] = pkg.packageManager.replace(/^\^/, "").split("@");
|
|
100057
|
+
return { name, ver: handelVer(ver) };
|
|
100058
|
+
}
|
|
100059
|
+
if (typeof pkg.devEngines?.packageManager?.name === "string") {
|
|
100060
|
+
return {
|
|
100061
|
+
name: pkg.devEngines.packageManager.name,
|
|
100062
|
+
ver: handelVer(pkg.devEngines.packageManager.version)
|
|
100063
|
+
};
|
|
100064
|
+
}
|
|
100065
|
+
return void 0;
|
|
100066
|
+
}
|
|
100067
|
+
async function handlePackageManager(filepath, options) {
|
|
100068
|
+
try {
|
|
100069
|
+
const content = await fs.readFile(filepath, "utf8");
|
|
100070
|
+
const pkg = options.packageJsonParser ? await options.packageJsonParser(content, filepath) : JSON.parse(content);
|
|
100071
|
+
let agent2;
|
|
100072
|
+
const nameAndVer = getNameAndVer(pkg);
|
|
100073
|
+
if (nameAndVer) {
|
|
100074
|
+
const name = nameAndVer.name;
|
|
100075
|
+
const ver = nameAndVer.ver;
|
|
100076
|
+
let version3 = ver;
|
|
100077
|
+
if (name === "yarn" && ver && Number.parseInt(ver) > 1) {
|
|
100078
|
+
agent2 = "yarn@berry";
|
|
100079
|
+
version3 = "berry";
|
|
100080
|
+
return { name, agent: agent2, version: version3 };
|
|
100081
|
+
} else if (name === "pnpm" && ver && Number.parseInt(ver) < 7) {
|
|
100082
|
+
agent2 = "pnpm@6";
|
|
100083
|
+
return { name, agent: agent2, version: version3 };
|
|
100084
|
+
} else if (AGENTS.includes(name)) {
|
|
100085
|
+
agent2 = name;
|
|
100086
|
+
return { name, agent: agent2, version: version3 };
|
|
100087
|
+
} else {
|
|
100088
|
+
return options.onUnknown?.(pkg.packageManager) ?? null;
|
|
100089
|
+
}
|
|
100090
|
+
}
|
|
100091
|
+
} catch {
|
|
100092
|
+
}
|
|
100093
|
+
return null;
|
|
100094
|
+
}
|
|
100095
|
+
function isMetadataYarnClassic(metadataPath) {
|
|
100096
|
+
return metadataPath.endsWith(".yarn_integrity");
|
|
100097
|
+
}
|
|
100098
|
+
|
|
99806
100099
|
// agents/claude.ts
|
|
99807
100100
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
99808
100101
|
import { chmodSync as chmodSync2, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
@@ -99838,6 +100131,12 @@ function resolveRung(params) {
|
|
|
99838
100131
|
const clamped = Math.min(1, Math.max(0, params.position));
|
|
99839
100132
|
return rungs[Math.floor(clamped * (rungs.length - 1))];
|
|
99840
100133
|
}
|
|
100134
|
+
function rungPosition(params) {
|
|
100135
|
+
const rungs = offeredRungs(params.published);
|
|
100136
|
+
const index = rungs.indexOf(params.rung);
|
|
100137
|
+
if (index === -1) return void 0;
|
|
100138
|
+
return rungs.length > 1 ? index / (rungs.length - 1) : 0;
|
|
100139
|
+
}
|
|
99841
100140
|
|
|
99842
100141
|
// models.ts
|
|
99843
100142
|
function provider(config3) {
|
|
@@ -99891,7 +100190,11 @@ var providers = {
|
|
|
99891
100190
|
envVars: ["OPENAI_API_KEY"],
|
|
99892
100191
|
managedCredentials: ["CODEX_AUTH_JSON"],
|
|
99893
100192
|
models: {
|
|
99894
|
-
|
|
100193
|
+
// Sol/Terra/Luna are OpenAI's durable capability tiers, so they ARE the
|
|
100194
|
+
// brand-tier names the slug convention asks for — the pre-5.6 `gpt` /
|
|
100195
|
+
// `gpt-pro` / `gpt-mini` slugs are holdovers from the retired GPT / GPT Pro
|
|
100196
|
+
// / GPT Mini tiering and are carried below as deprecated aliases.
|
|
100197
|
+
"gpt-sol": {
|
|
99895
100198
|
displayName: "GPT Sol",
|
|
99896
100199
|
resolve: "openai/gpt-5.6-sol",
|
|
99897
100200
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
@@ -99902,24 +100205,23 @@ var providers = {
|
|
|
99902
100205
|
// Sol served at reasoning.mode=pro — same $/token as Sol, just more tokens
|
|
99903
100206
|
// burned; not a pricier premium tier. models.dev has no -pro id, so direct-key
|
|
99904
100207
|
// (BYOK) resolves to plain Sol; only the Router/OpenRouter path gets sol-pro.
|
|
99905
|
-
"gpt-pro": {
|
|
100208
|
+
"gpt-sol-pro": {
|
|
99906
100209
|
displayName: "GPT Sol Pro",
|
|
99907
100210
|
description: "Maximum reasoning effort",
|
|
99908
100211
|
resolve: "openai/gpt-5.6-sol",
|
|
99909
100212
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
99910
100213
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
99911
|
-
subagentModel: "gpt"
|
|
100214
|
+
subagentModel: "gpt-sol"
|
|
99912
100215
|
},
|
|
99913
|
-
// gpt-5.6's balanced mid-tier
|
|
99914
|
-
//
|
|
99915
|
-
// lens-fanout subagent — replaces the old hidden gpt-5.4 subagent target.
|
|
100216
|
+
// gpt-5.6's balanced mid-tier. selectable on its own and doubles as Sol's
|
|
100217
|
+
// cheaper lens-fanout subagent — replaces the old hidden gpt-5.4 target.
|
|
99916
100218
|
"gpt-terra": {
|
|
99917
100219
|
displayName: "GPT Terra",
|
|
99918
100220
|
resolve: "openai/gpt-5.6-terra",
|
|
99919
100221
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
99920
100222
|
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
99921
100223
|
},
|
|
99922
|
-
"gpt-
|
|
100224
|
+
"gpt-luna": {
|
|
99923
100225
|
displayName: "GPT Luna",
|
|
99924
100226
|
resolve: "openai/gpt-5.6-luna",
|
|
99925
100227
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
@@ -99934,20 +100236,40 @@ var providers = {
|
|
|
99934
100236
|
displayName: "GPT Codex",
|
|
99935
100237
|
resolve: "openai/gpt-5.3-codex",
|
|
99936
100238
|
openRouterResolve: "openrouter/openai/gpt-5.3-codex",
|
|
99937
|
-
fallback: "openai/gpt"
|
|
100239
|
+
fallback: "openai/gpt-sol"
|
|
99938
100240
|
},
|
|
99939
100241
|
"gpt-codex-mini": {
|
|
99940
100242
|
displayName: "GPT Codex Mini",
|
|
99941
100243
|
resolve: "openai/gpt-5.1-codex-mini",
|
|
99942
100244
|
openRouterResolve: "openrouter/openai/gpt-5.1-codex-mini",
|
|
99943
|
-
fallback: "openai/gpt-
|
|
100245
|
+
fallback: "openai/gpt-luna"
|
|
100246
|
+
},
|
|
100247
|
+
// pre-5.6 tier slugs. the tiers themselves were renamed Sol/Sol Pro/Luna,
|
|
100248
|
+
// so these fold forward rather than describing anything that still runs.
|
|
100249
|
+
gpt: {
|
|
100250
|
+
displayName: "GPT",
|
|
100251
|
+
resolve: "openai/gpt-5.6-sol",
|
|
100252
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
100253
|
+
fallback: "openai/gpt-sol"
|
|
100254
|
+
},
|
|
100255
|
+
"gpt-pro": {
|
|
100256
|
+
displayName: "GPT Pro",
|
|
100257
|
+
resolve: "openai/gpt-5.6-sol",
|
|
100258
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100259
|
+
fallback: "openai/gpt-sol-pro"
|
|
100260
|
+
},
|
|
100261
|
+
"gpt-mini": {
|
|
100262
|
+
displayName: "GPT Mini",
|
|
100263
|
+
resolve: "openai/gpt-5.6-luna",
|
|
100264
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-luna",
|
|
100265
|
+
fallback: "openai/gpt-luna"
|
|
99944
100266
|
},
|
|
99945
|
-
// dropped hidden subagent tier — folds stored pins forward to
|
|
100267
|
+
// dropped hidden subagent tier — folds stored pins forward to Sol.
|
|
99946
100268
|
"gpt-5.4": {
|
|
99947
100269
|
displayName: "GPT 5.4",
|
|
99948
100270
|
resolve: "openai/gpt-5.4",
|
|
99949
100271
|
openRouterResolve: "openrouter/openai/gpt-5.4",
|
|
99950
|
-
fallback: "openai/gpt"
|
|
100272
|
+
fallback: "openai/gpt-sol"
|
|
99951
100273
|
},
|
|
99952
100274
|
o3: {
|
|
99953
100275
|
displayName: "O3",
|
|
@@ -99975,9 +100297,9 @@ var providers = {
|
|
|
99975
100297
|
},
|
|
99976
100298
|
"gemini-flash": {
|
|
99977
100299
|
displayName: "Gemini Flash",
|
|
99978
|
-
resolve: "google/gemini-3.
|
|
100300
|
+
resolve: "google/gemini-3.6-flash",
|
|
99979
100301
|
effort: ["minimal", "low", "medium", "high"],
|
|
99980
|
-
openRouterResolve: "openrouter/google/gemini-3.
|
|
100302
|
+
openRouterResolve: "openrouter/google/gemini-3.6-flash"
|
|
99981
100303
|
}
|
|
99982
100304
|
}
|
|
99983
100305
|
}),
|
|
@@ -99987,26 +100309,26 @@ var providers = {
|
|
|
99987
100309
|
models: {
|
|
99988
100310
|
grok: {
|
|
99989
100311
|
displayName: "Grok",
|
|
99990
|
-
resolve: "xai/grok-4.
|
|
99991
|
-
effort: ["
|
|
99992
|
-
openRouterResolve: "openrouter/x-ai/grok-4.
|
|
100312
|
+
resolve: "xai/grok-4.5",
|
|
100313
|
+
effort: ["low", "medium", "high"],
|
|
100314
|
+
openRouterResolve: "openrouter/x-ai/grok-4.5",
|
|
99993
100315
|
preferred: true
|
|
99994
100316
|
},
|
|
99995
100317
|
// legacy aliases — xAI retired the entire fast/code-fast line on
|
|
99996
100318
|
// 2026-05-15 (https://docs.x.ai/developers/migration/may-15-deprecation)
|
|
99997
100319
|
// and now redirects every deprecated text-model slug to grok-4.3 at
|
|
99998
100320
|
// standard pricing. fall back to the live `xai/grok` so the alias
|
|
99999
|
-
// chain resolves to grok-4.
|
|
100321
|
+
// chain resolves to grok-4.5 for both direct-key and OpenRouter users.
|
|
100000
100322
|
"grok-fast": {
|
|
100001
100323
|
displayName: "Grok Fast",
|
|
100002
100324
|
resolve: "xai/grok-4-1-fast",
|
|
100003
|
-
openRouterResolve: "openrouter/x-ai/grok-4.
|
|
100325
|
+
openRouterResolve: "openrouter/x-ai/grok-4.5",
|
|
100004
100326
|
fallback: "xai/grok"
|
|
100005
100327
|
},
|
|
100006
100328
|
"grok-code-fast": {
|
|
100007
100329
|
displayName: "Grok Code Fast",
|
|
100008
100330
|
resolve: "xai/grok-code-fast-1",
|
|
100009
|
-
openRouterResolve: "openrouter/x-ai/grok-4.
|
|
100331
|
+
openRouterResolve: "openrouter/x-ai/grok-4.5",
|
|
100010
100332
|
fallback: "xai/grok"
|
|
100011
100333
|
}
|
|
100012
100334
|
}
|
|
@@ -100023,12 +100345,25 @@ var providers = {
|
|
|
100023
100345
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-pro",
|
|
100024
100346
|
preferred: true
|
|
100025
100347
|
},
|
|
100348
|
+
// DeepSeek upgrades the `deepseek-v4-flash` API model in place, so the
|
|
100349
|
+
// direct `resolve` needs no version. OpenRouter instead forked the 0731
|
|
100350
|
+
// release into its own id and left the April preview live under the
|
|
100351
|
+
// unversioned one at a HIGHER price ($0.14/$0.28 vs $0.09/$0.18) — so the
|
|
100352
|
+
// OpenRouter route can never use the bare id. it tracks the rolling
|
|
100353
|
+
// `~deepseek/*-latest` pointer (rule 4), which resolves to 0731 at the
|
|
100354
|
+
// same price today and follows the next in-place upgrade on its own,
|
|
100355
|
+
// rather than pinning a dated snapshot that goes stale every release.
|
|
100356
|
+
// 0731 gained a `low` rung and renamed the top to `max`, unlike Pro
|
|
100357
|
+
// (`high, max` direct / `high, xhigh` via OpenRouter). that ladder now
|
|
100358
|
+
// reads the same on BOTH routes — the in-place direct upgrade caught up
|
|
100359
|
+
// to the fork — so `low`, not `high`, is position 0 either way, which is
|
|
100360
|
+
// why the OSS effort floor in `main.ts` pins the `high` rung by name.
|
|
100026
100361
|
"deepseek-flash": {
|
|
100027
100362
|
displayName: "DeepSeek Flash",
|
|
100028
100363
|
resolve: "deepseek/deepseek-v4-flash",
|
|
100029
|
-
effort: ["high", "max"],
|
|
100030
|
-
openRouterEffort: ["high", "
|
|
100031
|
-
openRouterResolve: "openrouter
|
|
100364
|
+
effort: ["low", "high", "max"],
|
|
100365
|
+
openRouterEffort: ["low", "high", "max"],
|
|
100366
|
+
openRouterResolve: "openrouter/~deepseek/deepseek-v4-flash-latest"
|
|
100032
100367
|
},
|
|
100033
100368
|
// legacy aliases — deepseek retires these on 2026-07-24; transparently
|
|
100034
100369
|
// upgrade existing users to the v4 family via the fallback chain.
|
|
@@ -100097,30 +100432,30 @@ var providers = {
|
|
|
100097
100432
|
resolve: "opencode/claude-haiku-4-5",
|
|
100098
100433
|
openRouterResolve: "openrouter/anthropic/claude-haiku-4.5"
|
|
100099
100434
|
},
|
|
100100
|
-
gpt: {
|
|
100435
|
+
"gpt-sol": {
|
|
100101
100436
|
displayName: "GPT Sol",
|
|
100102
100437
|
resolve: "opencode/gpt-5.6-sol",
|
|
100103
100438
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100104
100439
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
100105
100440
|
subagentModel: "gpt-terra"
|
|
100106
100441
|
},
|
|
100107
|
-
// see openai/gpt-pro — Zen has no -pro id, so direct resolves to plain Sol.
|
|
100108
|
-
"gpt-pro": {
|
|
100442
|
+
// see openai/gpt-sol-pro — Zen has no -pro id, so direct resolves to plain Sol.
|
|
100443
|
+
"gpt-sol-pro": {
|
|
100109
100444
|
displayName: "GPT Sol Pro",
|
|
100110
100445
|
description: "Maximum reasoning effort",
|
|
100111
100446
|
resolve: "opencode/gpt-5.6-sol",
|
|
100112
100447
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100113
100448
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100114
|
-
subagentModel: "gpt"
|
|
100449
|
+
subagentModel: "gpt-sol"
|
|
100115
100450
|
},
|
|
100116
|
-
// gpt-5.6 balanced mid-tier — selectable +
|
|
100451
|
+
// gpt-5.6 balanced mid-tier — selectable + Sol's subagent. see openai above.
|
|
100117
100452
|
"gpt-terra": {
|
|
100118
100453
|
displayName: "GPT Terra",
|
|
100119
100454
|
resolve: "opencode/gpt-5.6-terra",
|
|
100120
100455
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100121
100456
|
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
100122
100457
|
},
|
|
100123
|
-
"gpt-
|
|
100458
|
+
"gpt-luna": {
|
|
100124
100459
|
displayName: "GPT Luna",
|
|
100125
100460
|
resolve: "opencode/gpt-5.6-luna",
|
|
100126
100461
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
@@ -100131,20 +100466,39 @@ var providers = {
|
|
|
100131
100466
|
displayName: "GPT Codex",
|
|
100132
100467
|
resolve: "opencode/gpt-5.3-codex",
|
|
100133
100468
|
openRouterResolve: "openrouter/openai/gpt-5.3-codex",
|
|
100134
|
-
fallback: "opencode/gpt"
|
|
100469
|
+
fallback: "opencode/gpt-sol"
|
|
100135
100470
|
},
|
|
100136
100471
|
"gpt-codex-mini": {
|
|
100137
100472
|
displayName: "GPT Codex Mini",
|
|
100138
100473
|
resolve: "opencode/gpt-5.1-codex-mini",
|
|
100139
100474
|
openRouterResolve: "openrouter/openai/gpt-5.1-codex-mini",
|
|
100140
|
-
fallback: "opencode/gpt-
|
|
100475
|
+
fallback: "opencode/gpt-luna"
|
|
100476
|
+
},
|
|
100477
|
+
// pre-5.6 tier slugs — see openai provider above.
|
|
100478
|
+
gpt: {
|
|
100479
|
+
displayName: "GPT",
|
|
100480
|
+
resolve: "opencode/gpt-5.6-sol",
|
|
100481
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
100482
|
+
fallback: "opencode/gpt-sol"
|
|
100483
|
+
},
|
|
100484
|
+
"gpt-pro": {
|
|
100485
|
+
displayName: "GPT Pro",
|
|
100486
|
+
resolve: "opencode/gpt-5.6-sol",
|
|
100487
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100488
|
+
fallback: "opencode/gpt-sol-pro"
|
|
100141
100489
|
},
|
|
100142
|
-
|
|
100490
|
+
"gpt-mini": {
|
|
100491
|
+
displayName: "GPT Mini",
|
|
100492
|
+
resolve: "opencode/gpt-5.6-luna",
|
|
100493
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-luna",
|
|
100494
|
+
fallback: "opencode/gpt-luna"
|
|
100495
|
+
},
|
|
100496
|
+
// dropped hidden subagent tier — folds stored pins forward to Sol.
|
|
100143
100497
|
"gpt-5.4": {
|
|
100144
100498
|
displayName: "GPT 5.4",
|
|
100145
100499
|
resolve: "opencode/gpt-5.4",
|
|
100146
100500
|
openRouterResolve: "openrouter/openai/gpt-5.4",
|
|
100147
|
-
fallback: "opencode/gpt"
|
|
100501
|
+
fallback: "opencode/gpt-sol"
|
|
100148
100502
|
},
|
|
100149
100503
|
"gemini-pro": {
|
|
100150
100504
|
displayName: "Gemini Pro",
|
|
@@ -100155,21 +100509,19 @@ var providers = {
|
|
|
100155
100509
|
},
|
|
100156
100510
|
"gemini-flash": {
|
|
100157
100511
|
displayName: "Gemini Flash",
|
|
100158
|
-
resolve: "opencode/gemini-3.
|
|
100512
|
+
resolve: "opencode/gemini-3.6-flash",
|
|
100159
100513
|
effort: ["minimal", "low", "medium", "high"],
|
|
100160
|
-
openRouterResolve: "openrouter/google/gemini-3.
|
|
100514
|
+
openRouterResolve: "openrouter/google/gemini-3.6-flash"
|
|
100161
100515
|
},
|
|
100162
100516
|
"kimi-k2": {
|
|
100163
100517
|
displayName: "Kimi K2",
|
|
100164
|
-
|
|
100165
|
-
// router/oss proxy runs) takes the newer k2.7-code.
|
|
100166
|
-
resolve: "opencode/kimi-k2.6",
|
|
100518
|
+
resolve: "opencode/kimi-k2.7-code",
|
|
100167
100519
|
openRouterResolve: "openrouter/moonshotai/kimi-k2.7-code"
|
|
100168
100520
|
},
|
|
100169
|
-
//
|
|
100521
|
+
// slug pins the m2 line for DB stability; resolve tracks the current m2.7.
|
|
100170
100522
|
"minimax-m2.5": {
|
|
100171
100523
|
displayName: "MiniMax M2",
|
|
100172
|
-
resolve: "opencode/minimax-m2.
|
|
100524
|
+
resolve: "opencode/minimax-m2.7",
|
|
100173
100525
|
openRouterResolve: "openrouter/minimax/minimax-m2.7"
|
|
100174
100526
|
},
|
|
100175
100527
|
"gpt-5-nano": {
|
|
@@ -100300,30 +100652,30 @@ var providers = {
|
|
|
100300
100652
|
// alias): after the Sol/Terra/Luna rename, ~gpt-mini-latest no longer maps
|
|
100301
100653
|
// to Luna, so rolling aliases would silently diverge `gpt`/`gpt-mini` from
|
|
100302
100654
|
// the chosen tiers across funding paths.
|
|
100303
|
-
gpt: {
|
|
100655
|
+
"gpt-sol": {
|
|
100304
100656
|
displayName: "GPT Sol",
|
|
100305
100657
|
resolve: "openrouter/openai/gpt-5.6-sol",
|
|
100306
100658
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100307
100659
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
100308
100660
|
subagentModel: "gpt-terra"
|
|
100309
100661
|
},
|
|
100310
|
-
// see openai/gpt-pro. openrouter serves sol-pro directly on both routes.
|
|
100311
|
-
"gpt-pro": {
|
|
100662
|
+
// see openai/gpt-sol-pro. openrouter serves sol-pro directly on both routes.
|
|
100663
|
+
"gpt-sol-pro": {
|
|
100312
100664
|
displayName: "GPT Sol Pro",
|
|
100313
100665
|
description: "Maximum reasoning effort",
|
|
100314
100666
|
resolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100315
100667
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100316
100668
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100317
|
-
subagentModel: "gpt"
|
|
100669
|
+
subagentModel: "gpt-sol"
|
|
100318
100670
|
},
|
|
100319
|
-
// gpt-5.6 balanced mid-tier — selectable +
|
|
100671
|
+
// gpt-5.6 balanced mid-tier — selectable + Sol's subagent. see openai above.
|
|
100320
100672
|
"gpt-terra": {
|
|
100321
100673
|
displayName: "GPT Terra",
|
|
100322
100674
|
resolve: "openrouter/openai/gpt-5.6-terra",
|
|
100323
100675
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100324
100676
|
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
100325
100677
|
},
|
|
100326
|
-
"gpt-
|
|
100678
|
+
"gpt-luna": {
|
|
100327
100679
|
displayName: "GPT Luna",
|
|
100328
100680
|
resolve: "openrouter/openai/gpt-5.6-luna",
|
|
100329
100681
|
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
@@ -100334,20 +100686,39 @@ var providers = {
|
|
|
100334
100686
|
displayName: "GPT Codex",
|
|
100335
100687
|
resolve: "openrouter/openai/gpt-5.3-codex",
|
|
100336
100688
|
openRouterResolve: "openrouter/openai/gpt-5.3-codex",
|
|
100337
|
-
fallback: "openrouter/gpt"
|
|
100689
|
+
fallback: "openrouter/gpt-sol"
|
|
100338
100690
|
},
|
|
100339
100691
|
"gpt-codex-mini": {
|
|
100340
100692
|
displayName: "GPT Codex Mini",
|
|
100341
100693
|
resolve: "openrouter/openai/gpt-5.1-codex-mini",
|
|
100342
100694
|
openRouterResolve: "openrouter/openai/gpt-5.1-codex-mini",
|
|
100343
|
-
fallback: "openrouter/gpt-
|
|
100695
|
+
fallback: "openrouter/gpt-luna"
|
|
100696
|
+
},
|
|
100697
|
+
// pre-5.6 tier slugs — see openai provider above.
|
|
100698
|
+
gpt: {
|
|
100699
|
+
displayName: "GPT",
|
|
100700
|
+
resolve: "openrouter/openai/gpt-5.6-sol",
|
|
100701
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
100702
|
+
fallback: "openrouter/gpt-sol"
|
|
100344
100703
|
},
|
|
100345
|
-
|
|
100704
|
+
"gpt-pro": {
|
|
100705
|
+
displayName: "GPT Pro",
|
|
100706
|
+
resolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100707
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100708
|
+
fallback: "openrouter/gpt-sol-pro"
|
|
100709
|
+
},
|
|
100710
|
+
"gpt-mini": {
|
|
100711
|
+
displayName: "GPT Mini",
|
|
100712
|
+
resolve: "openrouter/openai/gpt-5.6-luna",
|
|
100713
|
+
openRouterResolve: "openrouter/openai/gpt-5.6-luna",
|
|
100714
|
+
fallback: "openrouter/gpt-luna"
|
|
100715
|
+
},
|
|
100716
|
+
// dropped hidden subagent tier — folds stored pins forward to Sol.
|
|
100346
100717
|
"gpt-5.4": {
|
|
100347
100718
|
displayName: "GPT 5.4",
|
|
100348
100719
|
resolve: "openrouter/openai/gpt-5.4",
|
|
100349
100720
|
openRouterResolve: "openrouter/openai/gpt-5.4",
|
|
100350
|
-
fallback: "openrouter/gpt"
|
|
100721
|
+
fallback: "openrouter/gpt-sol"
|
|
100351
100722
|
},
|
|
100352
100723
|
"o4-mini": {
|
|
100353
100724
|
displayName: "O4 Mini",
|
|
@@ -100370,9 +100741,9 @@ var providers = {
|
|
|
100370
100741
|
},
|
|
100371
100742
|
grok: {
|
|
100372
100743
|
displayName: "Grok",
|
|
100373
|
-
resolve: "openrouter/x-ai/grok-4.
|
|
100374
|
-
effort: ["
|
|
100375
|
-
openRouterResolve: "openrouter/x-ai/grok-4.
|
|
100744
|
+
resolve: "openrouter/x-ai/grok-4.5",
|
|
100745
|
+
effort: ["low", "medium", "high"],
|
|
100746
|
+
openRouterResolve: "openrouter/x-ai/grok-4.5"
|
|
100376
100747
|
},
|
|
100377
100748
|
"deepseek-pro": {
|
|
100378
100749
|
displayName: "DeepSeek Pro",
|
|
@@ -100380,11 +100751,13 @@ var providers = {
|
|
|
100380
100751
|
effort: ["high", "xhigh"],
|
|
100381
100752
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-pro"
|
|
100382
100753
|
},
|
|
100754
|
+
// rolling pointer, not the bare id — see `deepseek/deepseek-flash` for why
|
|
100755
|
+
// OpenRouter's unversioned `deepseek-v4-flash` is the stale April preview.
|
|
100383
100756
|
"deepseek-flash": {
|
|
100384
100757
|
displayName: "DeepSeek Flash",
|
|
100385
|
-
resolve: "openrouter
|
|
100386
|
-
effort: ["high", "
|
|
100387
|
-
openRouterResolve: "openrouter
|
|
100758
|
+
resolve: "openrouter/~deepseek/deepseek-v4-flash-latest",
|
|
100759
|
+
effort: ["low", "high", "max"],
|
|
100760
|
+
openRouterResolve: "openrouter/~deepseek/deepseek-v4-flash-latest"
|
|
100388
100761
|
},
|
|
100389
100762
|
// legacy alias — deepseek retires this on 2026-07-24; transparently
|
|
100390
100763
|
// upgrade existing users to the v4 family via the fallback chain.
|
|
@@ -100465,7 +100838,7 @@ var modelAliases = Object.entries(providers).flatMap(
|
|
|
100465
100838
|
var AUTO_EFFICIENT = "auto/efficient";
|
|
100466
100839
|
var AUTO_INTELLIGENT = "auto/intelligent";
|
|
100467
100840
|
var AUTO_TIER_TARGET = {
|
|
100468
|
-
[AUTO_EFFICIENT]: "deepseek/deepseek-
|
|
100841
|
+
[AUTO_EFFICIENT]: "deepseek/deepseek-flash",
|
|
100469
100842
|
[AUTO_INTELLIGENT]: "anthropic/claude-opus"
|
|
100470
100843
|
};
|
|
100471
100844
|
function isAutoTier(slug2) {
|
|
@@ -100514,6 +100887,26 @@ if (!defaultProxyAlias?.openRouterResolve) {
|
|
|
100514
100887
|
}
|
|
100515
100888
|
var DEFAULT_PROXY_MODEL = defaultProxyAlias.openRouterResolve;
|
|
100516
100889
|
var defaultProxyDisplayName = defaultProxyAlias.displayName;
|
|
100890
|
+
var OSS_MODEL_ALLOWLIST = [
|
|
100891
|
+
"deepseek/deepseek-flash",
|
|
100892
|
+
"deepseek/deepseek-pro",
|
|
100893
|
+
"openai/gpt-luna",
|
|
100894
|
+
"openrouter/minimax-m2.5",
|
|
100895
|
+
"moonshotai/kimi-k2"
|
|
100896
|
+
];
|
|
100897
|
+
var OSS_RECOMMENDED_MODEL = AUTO_TIER_TARGET[AUTO_EFFICIENT];
|
|
100898
|
+
var ossAllowedTargets = new Set(
|
|
100899
|
+
OSS_MODEL_ALLOWLIST.map((slug2) => {
|
|
100900
|
+
const target = resolveOpenRouterModel(slug2);
|
|
100901
|
+
if (!target) throw new Error(`OSS_MODEL_ALLOWLIST: ${slug2} has no openRouterResolve`);
|
|
100902
|
+
return target;
|
|
100903
|
+
})
|
|
100904
|
+
);
|
|
100905
|
+
function isOssAllowedModel(slug2) {
|
|
100906
|
+
if (!slug2) return false;
|
|
100907
|
+
const target = resolveOpenRouterModel(slug2);
|
|
100908
|
+
return target !== void 0 && ossAllowedTargets.has(target);
|
|
100909
|
+
}
|
|
100517
100910
|
var BEDROCK_MODEL_ID_ENV = "BEDROCK_MODEL_ID";
|
|
100518
100911
|
var VERTEX_MODEL_ID_ENV = "VERTEX_MODEL_ID";
|
|
100519
100912
|
var OPENAI_COMPATIBLE_PROVIDER = "openai-compatible";
|
|
@@ -101119,7 +101512,21 @@ var PROVIDER_ERROR_PATTERNS = [
|
|
|
101119
101512
|
{ regex: /\bFreeUsageLimitError\b/, label: PROVIDER_BILLING_EXHAUSTED_LABEL },
|
|
101120
101513
|
{ regex: /Insufficient balance/i, label: PROVIDER_BILLING_EXHAUSTED_LABEL },
|
|
101121
101514
|
{ regex: /credit balance is too low/i, label: PROVIDER_BILLING_EXHAUSTED_LABEL },
|
|
101122
|
-
|
|
101515
|
+
// "spending cap" (Gemini) and "spending limit" (xAI, #1076) are the same
|
|
101516
|
+
// condition in two house styles — a configured ceiling was reached.
|
|
101517
|
+
{ regex: /spending (?:cap|limit)/i, label: PROVIDER_BILLING_EXHAUSTED_LABEL },
|
|
101518
|
+
// xAI exhausts credits and the monthly ceiling in one 403 whose status code
|
|
101519
|
+
// sits nowhere near a `status:` key, so no status pattern below fires (#1076).
|
|
101520
|
+
{ regex: /used all available credits/i, label: PROVIDER_BILLING_EXHAUSTED_LABEL },
|
|
101521
|
+
// the OpenRouter shapes `isRouterKeylimitExhaustedError` matches. on a Router
|
|
101522
|
+
// run those mean the PULLFROG wallet is empty and `renderRunError` returns a
|
|
101523
|
+
// `BillingError` before ever reaching this list; on a BYOK run the very same
|
|
101524
|
+
// wire text means the user's OWN OpenRouter wallet is empty, and this entry is
|
|
101525
|
+
// what gives them the right dashboard instead of ours. see #1135.
|
|
101526
|
+
{
|
|
101527
|
+
regex: /requires more credits|Key limit exceeded \(total limit\)/i,
|
|
101528
|
+
label: PROVIDER_BILLING_EXHAUSTED_LABEL
|
|
101529
|
+
},
|
|
101123
101530
|
// auth patterns must come BEFORE rate-limit patterns. OpenRouter 401 error
|
|
101124
101531
|
// payloads carry `x-ratelimit-*` response headers in the dump, and the
|
|
101125
101532
|
// free-form rate-limit regex below would otherwise win on word-boundary
|
|
@@ -101215,6 +101622,12 @@ function resolveRunAlias(ctx) {
|
|
|
101215
101622
|
if (!model) return void 0;
|
|
101216
101623
|
return modelAliases.find((a) => !a.fallback && a.resolve === model) ?? matchHostedAnthropicAlias(model);
|
|
101217
101624
|
}
|
|
101625
|
+
function ossEffortFloor(ctx) {
|
|
101626
|
+
const alias = resolveRunAlias(ctx);
|
|
101627
|
+
const published = alias?.openRouterEffort ?? alias?.effort;
|
|
101628
|
+
if (!published) return 0;
|
|
101629
|
+
return rungPosition({ rung: "high", published }) ?? 0;
|
|
101630
|
+
}
|
|
101218
101631
|
function resolveRunEffort(ctx) {
|
|
101219
101632
|
const configured = ctx.payload.effort !== void 0;
|
|
101220
101633
|
const position = ctx.payload.effort ?? DEFAULT_EFFORT_POSITION;
|
|
@@ -101245,7 +101658,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
101245
101658
|
// package.json
|
|
101246
101659
|
var package_default = {
|
|
101247
101660
|
name: "pullfrog",
|
|
101248
|
-
version: "0.1.
|
|
101661
|
+
version: "0.1.53",
|
|
101249
101662
|
type: "module",
|
|
101250
101663
|
bin: {
|
|
101251
101664
|
pullfrog: "dist/cli.mjs",
|
|
@@ -108902,6 +109315,41 @@ function bootstrapPullfrogDataDir() {
|
|
|
108902
109315
|
}
|
|
108903
109316
|
}
|
|
108904
109317
|
|
|
109318
|
+
// utils/worktree.ts
|
|
109319
|
+
async function dirtyTrackedPaths() {
|
|
109320
|
+
const result = await spawn({
|
|
109321
|
+
cmd: "git",
|
|
109322
|
+
args: ["diff", "--name-only", "HEAD"],
|
|
109323
|
+
env: process.env,
|
|
109324
|
+
activityTimeout: 0
|
|
109325
|
+
});
|
|
109326
|
+
if (result.exitCode !== 0) {
|
|
109327
|
+
throw new Error(
|
|
109328
|
+
`git diff --name-only HEAD failed (exit ${result.exitCode}): ${result.stderr.trim() || "(no stderr)"}`
|
|
109329
|
+
);
|
|
109330
|
+
}
|
|
109331
|
+
return new Set(result.stdout.split("\n").filter(Boolean));
|
|
109332
|
+
}
|
|
109333
|
+
async function restoreDirtiedSince(params) {
|
|
109334
|
+
const dirtied = [...await dirtyTrackedPaths()].filter((path4) => !params.before.has(path4));
|
|
109335
|
+
if (dirtied.length === 0) return;
|
|
109336
|
+
const result = await spawn({
|
|
109337
|
+
cmd: "git",
|
|
109338
|
+
args: ["restore", "--staged", "--worktree", "--", ...dirtied],
|
|
109339
|
+
env: process.env,
|
|
109340
|
+
activityTimeout: 0
|
|
109341
|
+
});
|
|
109342
|
+
if (result.exitCode !== 0) {
|
|
109343
|
+
log.warning(
|
|
109344
|
+
`\xBB failed to restore ${dirtied.length} tracked file(s) modified by ${params.actor}: ${result.stderr.trim() || "(no stderr)"}`
|
|
109345
|
+
);
|
|
109346
|
+
return;
|
|
109347
|
+
}
|
|
109348
|
+
log.info(
|
|
109349
|
+
`\xBB restored ${dirtied.length} tracked file(s) modified by ${params.actor}: ${dirtied.join(", ")}`
|
|
109350
|
+
);
|
|
109351
|
+
}
|
|
109352
|
+
|
|
108905
109353
|
// agents/opencodePlugin.ts
|
|
108906
109354
|
var PULLFROG_BUS_EVENT_TYPE = "pullfrog_bus_event";
|
|
108907
109355
|
var PULLFROG_OPENCODE_GATE_PLUGIN_FILENAME = "pullfrog-subagent-gate.ts";
|
|
@@ -109787,6 +110235,7 @@ var opencode = agent({
|
|
|
109787
110235
|
}
|
|
109788
110236
|
log.debug(`\xBB starting Pullfrog (OpenCode, in-process SDK): ${cliPath}`);
|
|
109789
110237
|
log.debug(`\xBB working directory: ${repoDir}`);
|
|
110238
|
+
const preBootDirty = await dirtyTrackedPaths();
|
|
109790
110239
|
const server = await bootOpencodeServer({ cliPath, env: env2, cwd: repoDir });
|
|
109791
110240
|
const dispatcher = new import_undici.Agent({ headersTimeout: 0, bodyTimeout: 0, connectTimeout: 0 });
|
|
109792
110241
|
const fetchWithoutTimeout = (input, init) => {
|
|
@@ -109807,6 +110256,7 @@ var opencode = agent({
|
|
|
109807
110256
|
fetch: fetchWithoutTimeout
|
|
109808
110257
|
});
|
|
109809
110258
|
const sessionResp = await client2.session.create({ title: "Pullfrog" });
|
|
110259
|
+
await restoreDirtiedSince({ before: preBootDirty, actor: "agent startup" });
|
|
109810
110260
|
if (sessionResp.error || !sessionResp.data) {
|
|
109811
110261
|
const msg = sessionResp.error ? formatPromptError(sessionResp.error) : "session.create returned no data";
|
|
109812
110262
|
return {
|
|
@@ -116535,7 +116985,7 @@ var Server = class extends Protocol {
|
|
|
116535
116985
|
};
|
|
116536
116986
|
|
|
116537
116987
|
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.27.1_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
116538
|
-
import
|
|
116988
|
+
import process4 from "node:process";
|
|
116539
116989
|
|
|
116540
116990
|
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.27.1_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
|
|
116541
116991
|
var ReadBuffer = class {
|
|
@@ -116567,7 +117017,7 @@ function serializeMessage(message) {
|
|
|
116567
117017
|
|
|
116568
117018
|
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.27.1_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
116569
117019
|
var StdioServerTransport = class {
|
|
116570
|
-
constructor(_stdin =
|
|
117020
|
+
constructor(_stdin = process4.stdin, _stdout = process4.stdout) {
|
|
116571
117021
|
this._stdin = _stdin;
|
|
116572
117022
|
this._stdout = _stdout;
|
|
116573
117023
|
this._readBuffer = new ReadBuffer();
|
|
@@ -120002,7 +120452,7 @@ var Hono2 = class extends Hono {
|
|
|
120002
120452
|
import { createRequire } from "node:module";
|
|
120003
120453
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
120004
120454
|
import { URL as URL$1 } from "node:url";
|
|
120005
|
-
import
|
|
120455
|
+
import fs2 from "fs";
|
|
120006
120456
|
import http from "http";
|
|
120007
120457
|
import https from "https";
|
|
120008
120458
|
var __create2 = Object.create;
|
|
@@ -134570,17 +135020,17 @@ var startHTTPServer = async ({ apiKey, authenticate, cors, createServer: createS
|
|
|
134570
135020
|
if (sslCa || sslCert || sslKey) {
|
|
134571
135021
|
const options = {};
|
|
134572
135022
|
if (sslCa) try {
|
|
134573
|
-
options.ca =
|
|
135023
|
+
options.ca = fs2.readFileSync(sslCa);
|
|
134574
135024
|
} catch (error$1) {
|
|
134575
135025
|
throw new Error(`Failed to read CA file '${sslCa}': ${error$1.message}`);
|
|
134576
135026
|
}
|
|
134577
135027
|
if (sslCert) try {
|
|
134578
|
-
options.cert =
|
|
135028
|
+
options.cert = fs2.readFileSync(sslCert);
|
|
134579
135029
|
} catch (error$1) {
|
|
134580
135030
|
throw new Error(`Failed to read certificate file '${sslCert}': ${error$1.message}`);
|
|
134581
135031
|
}
|
|
134582
135032
|
if (sslKey) try {
|
|
134583
|
-
options.key =
|
|
135033
|
+
options.key = fs2.readFileSync(sslKey);
|
|
134584
135034
|
} catch (error$1) {
|
|
134585
135035
|
throw new Error(`Failed to read key file '${sslKey}': ${error$1.message}`);
|
|
134586
135036
|
}
|
|
@@ -143007,6 +143457,24 @@ function isSafeEnvVar(key) {
|
|
|
143007
143457
|
if (SAFE_ENV_NAMES.has(key)) return true;
|
|
143008
143458
|
return SAFE_ENV_PREFIXES.some((p) => key.startsWith(p));
|
|
143009
143459
|
}
|
|
143460
|
+
var WORKFLOW_COMMAND_ENV_NAMES = [
|
|
143461
|
+
"GITHUB_ENV",
|
|
143462
|
+
"GITHUB_PATH",
|
|
143463
|
+
"GITHUB_OUTPUT",
|
|
143464
|
+
"GITHUB_STATE",
|
|
143465
|
+
"GITHUB_STEP_SUMMARY",
|
|
143466
|
+
// dropping the five paths above but keeping RUNNER_TEMP would be theatre:
|
|
143467
|
+
// the file-command files live in `$RUNNER_TEMP/_runner_file_commands/`, so the
|
|
143468
|
+
// directory is one `ls` away. nothing in the install path reads it (only our
|
|
143469
|
+
// own leak-surface wipe in `setup.ts`, which runs in the parent), and package
|
|
143470
|
+
// managers use TMPDIR.
|
|
143471
|
+
"RUNNER_TEMP"
|
|
143472
|
+
];
|
|
143473
|
+
function filterEnvForUntrustedCode() {
|
|
143474
|
+
const env2 = filterEnv();
|
|
143475
|
+
for (const name of WORKFLOW_COMMAND_ENV_NAMES) delete env2[name];
|
|
143476
|
+
return env2;
|
|
143477
|
+
}
|
|
143010
143478
|
function filterEnv() {
|
|
143011
143479
|
const filtered = {};
|
|
143012
143480
|
for (const [key, value2] of Object.entries(process.env)) {
|
|
@@ -151200,6 +151668,8 @@ import { join as join8 } from "node:path";
|
|
|
151200
151668
|
|
|
151201
151669
|
// utils/shell.ts
|
|
151202
151670
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
151671
|
+
var MAX_BUFFER_BYTES = 32 * 1024 * 1024;
|
|
151672
|
+
var MAX_ERROR_DETAIL_CHARS = 2e4;
|
|
151203
151673
|
function $(cmd, args2, options) {
|
|
151204
151674
|
const encoding = options?.encoding ?? "utf-8";
|
|
151205
151675
|
const env2 = resolveEnv(options?.env);
|
|
@@ -151207,7 +151677,8 @@ function $(cmd, args2, options) {
|
|
|
151207
151677
|
stdio: ["ignore", "pipe", "pipe"],
|
|
151208
151678
|
encoding,
|
|
151209
151679
|
cwd: options?.cwd,
|
|
151210
|
-
env: env2
|
|
151680
|
+
env: env2,
|
|
151681
|
+
maxBuffer: MAX_BUFFER_BYTES
|
|
151211
151682
|
});
|
|
151212
151683
|
const stdout = result.stdout ?? "";
|
|
151213
151684
|
const stderr = result.stderr ?? "";
|
|
@@ -151225,6 +151696,11 @@ function $(cmd, args2, options) {
|
|
|
151225
151696
|
}
|
|
151226
151697
|
}
|
|
151227
151698
|
if (result.status !== 0) {
|
|
151699
|
+
if (result.error && "code" in result.error && result.error.code === "ENOBUFS") {
|
|
151700
|
+
throw new Error(
|
|
151701
|
+
`Command produced more than ${MAX_BUFFER_BYTES / 1024 / 1024}MB of output and was terminated: ${cmd} ${args2.join(" ")}`
|
|
151702
|
+
);
|
|
151703
|
+
}
|
|
151228
151704
|
const errorResult = {
|
|
151229
151705
|
status: result.status ?? -1,
|
|
151230
151706
|
stdout,
|
|
@@ -151234,7 +151710,7 @@ function $(cmd, args2, options) {
|
|
|
151234
151710
|
options.onError(errorResult);
|
|
151235
151711
|
return stdout.trim();
|
|
151236
151712
|
}
|
|
151237
|
-
const detail = [stderr, stdout].map((s) => s.trim()).filter(Boolean).join("\n");
|
|
151713
|
+
const detail = [stderr, stdout].map((s) => s.trim()).filter(Boolean).join("\n").slice(0, MAX_ERROR_DETAIL_CHARS);
|
|
151238
151714
|
throw new Error(
|
|
151239
151715
|
`Command failed with exit code ${errorResult.status}: ${detail || "Unknown error"}`
|
|
151240
151716
|
);
|
|
@@ -151243,6 +151719,10 @@ function $(cmd, args2, options) {
|
|
|
151243
151719
|
}
|
|
151244
151720
|
|
|
151245
151721
|
// utils/gitAuth.ts
|
|
151722
|
+
var TRANSIENT_AUTH_PATTERNS = [
|
|
151723
|
+
/Invalid username or token/,
|
|
151724
|
+
/Authentication failed for 'https:\/\/github\.com\//
|
|
151725
|
+
];
|
|
151246
151726
|
var gitBinary;
|
|
151247
151727
|
function hashFile(path4) {
|
|
151248
151728
|
return createHash("sha256").update(readFileSync2(path4)).digest("hex");
|
|
@@ -151359,6 +151839,17 @@ async function $gitFetchWithDeepen(args2, options, label) {
|
|
|
151359
151839
|
return await $git("fetch", args2, options);
|
|
151360
151840
|
} catch (err) {
|
|
151361
151841
|
const msg = err instanceof Error ? err.message : String(err);
|
|
151842
|
+
if (TRANSIENT_AUTH_PATTERNS.some((p) => p.test(msg)) && options.refreshGitToken) {
|
|
151843
|
+
log.info(
|
|
151844
|
+
`\xBB ${label ?? "git fetch"} hit an auth error, re-minting the git token and retrying`
|
|
151845
|
+
);
|
|
151846
|
+
const fresh = await options.refreshGitToken(options.token);
|
|
151847
|
+
return await $gitFetchWithDeepen(
|
|
151848
|
+
args2,
|
|
151849
|
+
{ ...options, token: fresh, refreshGitToken: void 0 },
|
|
151850
|
+
label
|
|
151851
|
+
);
|
|
151852
|
+
}
|
|
151362
151853
|
const isShallowUnreachable = SHALLOW_UNREACHABLE_PATTERNS.some((p) => p.test(msg));
|
|
151363
151854
|
if (!isShallowUnreachable) throw err;
|
|
151364
151855
|
const isShallow = $("git", ["rev-parse", "--is-shallow-repository"], { log: false }).trim() === "true";
|
|
@@ -151478,10 +151969,12 @@ function computeIncrementalDiff(params) {
|
|
|
151478
151969
|
],
|
|
151479
151970
|
{ log: false }
|
|
151480
151971
|
);
|
|
151481
|
-
|
|
151972
|
+
const processed = postProcessRangeDiff(raw2);
|
|
151973
|
+
return processed === null ? { status: "empty" } : { status: "ok", diff: processed };
|
|
151482
151974
|
} catch (e) {
|
|
151483
|
-
|
|
151484
|
-
|
|
151975
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
151976
|
+
log.warning(`\xBB incremental diff unavailable: range-diff failed: ${reason}`);
|
|
151977
|
+
return { status: "unavailable", reason };
|
|
151485
151978
|
}
|
|
151486
151979
|
}
|
|
151487
151980
|
function isDiffPrefix(ch) {
|
|
@@ -152913,7 +153406,7 @@ throttling.VERSION = VERSION;
|
|
|
152913
153406
|
throttling.triggersNotification = triggersNotification;
|
|
152914
153407
|
|
|
152915
153408
|
// node_modules/.pnpm/universal-user-agent@7.0.3/node_modules/universal-user-agent/index.js
|
|
152916
|
-
function
|
|
153409
|
+
function getUserAgent2() {
|
|
152917
153410
|
if (typeof navigator === "object" && "userAgent" in navigator) {
|
|
152918
153411
|
return navigator.userAgent;
|
|
152919
153412
|
}
|
|
@@ -153031,7 +153524,7 @@ var before_after_hook_default = { Singular, Collection };
|
|
|
153031
153524
|
|
|
153032
153525
|
// node_modules/.pnpm/@octokit+endpoint@11.0.1/node_modules/@octokit/endpoint/dist-bundle/index.js
|
|
153033
153526
|
var VERSION2 = "0.0.0-development";
|
|
153034
|
-
var userAgent = `octokit-endpoint.js/${VERSION2} ${
|
|
153527
|
+
var userAgent = `octokit-endpoint.js/${VERSION2} ${getUserAgent2()}`;
|
|
153035
153528
|
var DEFAULTS = {
|
|
153036
153529
|
method: "GET",
|
|
153037
153530
|
baseUrl: "https://api.github.com",
|
|
@@ -153388,7 +153881,7 @@ var RequestError = class extends Error {
|
|
|
153388
153881
|
var VERSION3 = "10.0.5";
|
|
153389
153882
|
var defaults_default = {
|
|
153390
153883
|
headers: {
|
|
153391
|
-
"user-agent": `octokit-request.js/${VERSION3} ${
|
|
153884
|
+
"user-agent": `octokit-request.js/${VERSION3} ${getUserAgent2()}`
|
|
153392
153885
|
}
|
|
153393
153886
|
};
|
|
153394
153887
|
function isPlainObject4(value2) {
|
|
@@ -153653,7 +154146,7 @@ function withDefaults3(request2, newDefaults) {
|
|
|
153653
154146
|
}
|
|
153654
154147
|
var graphql2 = withDefaults3(request, {
|
|
153655
154148
|
headers: {
|
|
153656
|
-
"user-agent": `octokit-graphql.js/${VERSION4} ${
|
|
154149
|
+
"user-agent": `octokit-graphql.js/${VERSION4} ${getUserAgent2()}`
|
|
153657
154150
|
},
|
|
153658
154151
|
method: "POST",
|
|
153659
154152
|
url: "/graphql"
|
|
@@ -153733,7 +154226,7 @@ function createLogger(logger = {}) {
|
|
|
153733
154226
|
}
|
|
153734
154227
|
return logger;
|
|
153735
154228
|
}
|
|
153736
|
-
var userAgentTrail = `octokit-core.js/${VERSION5} ${
|
|
154229
|
+
var userAgentTrail = `octokit-core.js/${VERSION5} ${getUserAgent2()}`;
|
|
153737
154230
|
var Octokit = class {
|
|
153738
154231
|
static VERSION = VERSION5;
|
|
153739
154232
|
static defaults(defaults) {
|
|
@@ -156701,8 +157194,13 @@ function createOctokit(token, refreshAuth) {
|
|
|
156701
157194
|
var readOctokitByToken = /* @__PURE__ */ new Map();
|
|
156702
157195
|
function resolveRepoCtx(ctx, repo) {
|
|
156703
157196
|
const owner = ctx.repo.owner;
|
|
156704
|
-
const name = repo
|
|
156705
|
-
const state =
|
|
157197
|
+
const name = repo?.trim() || ctx.repo.name;
|
|
157198
|
+
const state = ctx.toolState.repos.get(repoKey(owner, name));
|
|
157199
|
+
if (!state) {
|
|
157200
|
+
throw new Error(
|
|
157201
|
+
ctx.xrepo ? `repo ${repoKey(owner, name)} is not a registered checkout \u2014 use checkout_repo first` : `repo ${repoKey(owner, name)} is not a registered checkout \u2014 this run is single-repo, so omit \`repo\` to target ${owner}/${ctx.repo.name}`
|
|
157202
|
+
);
|
|
157203
|
+
}
|
|
156706
157204
|
if (state.access !== "read") {
|
|
156707
157205
|
return {
|
|
156708
157206
|
owner,
|
|
@@ -157419,10 +157917,6 @@ var TRANSIENT_PATTERNS = [
|
|
|
157419
157917
|
/HTTP 429/,
|
|
157420
157918
|
/returned error: 429/i
|
|
157421
157919
|
];
|
|
157422
|
-
var TRANSIENT_AUTH_PATTERNS = [
|
|
157423
|
-
/Invalid username or token/,
|
|
157424
|
-
/Authentication failed for 'https:\/\/github\.com\//
|
|
157425
|
-
];
|
|
157426
157920
|
function classifyPushError(msg) {
|
|
157427
157921
|
if (CONCURRENT_PUSH_PATTERNS.some((p) => msg.includes(p))) return "concurrent-push";
|
|
157428
157922
|
if (TRANSIENT_AUTH_PATTERNS.some((p) => p.test(msg))) return "transient-auth";
|
|
@@ -157921,7 +158415,11 @@ function GitFetchTool(ctx) {
|
|
|
157921
158415
|
if (params.depth !== void 0) {
|
|
157922
158416
|
fetchArgs.push(`--depth=${params.depth}`);
|
|
157923
158417
|
}
|
|
157924
|
-
await $gitFetchWithDeepen(
|
|
158418
|
+
await $gitFetchWithDeepen(
|
|
158419
|
+
fetchArgs,
|
|
158420
|
+
{ token: rc.gitToken, cwd: rc.dir, refreshGitToken: rc.refreshGitToken },
|
|
158421
|
+
"git_fetch"
|
|
158422
|
+
);
|
|
157925
158423
|
return { success: true, ref: params.ref };
|
|
157926
158424
|
})
|
|
157927
158425
|
});
|
|
@@ -158010,7 +158508,7 @@ function formatModelLabel(params) {
|
|
|
158010
158508
|
const ossBase = `\`${displayName}\` (free via [Pullfrog for OSS](https://pullfrog.com/for-oss))`;
|
|
158011
158509
|
if (params.clamped?.reason !== "oss") return ossBase;
|
|
158012
158510
|
const configured = isAutoTier(params.clamped.from) ? "the intelligent tier" : `\`${resolveDisplayAlias(params.clamped.from)?.displayName ?? params.clamped.from}\``;
|
|
158013
|
-
return `${ossBase} (${configured} not used \u2014 the
|
|
158511
|
+
return `${ossBase} (${configured} not used \u2014 pick one of the [funded models](https://docs.pullfrog.com/models#pullfrog-for-oss) or add a [provider key](https://docs.pullfrog.com/keys) to run your own)`;
|
|
158014
158512
|
}
|
|
158015
158513
|
const base = alias?.isFree ? `\`${displayName}\` (free)` : `\`${displayName}\``;
|
|
158016
158514
|
if (params.fallbackFrom) {
|
|
@@ -159558,7 +160056,7 @@ async function ensureBeforeShaReachable(params) {
|
|
|
159558
160056
|
}), true);
|
|
159559
160057
|
await $gitFetchWithDeepen(
|
|
159560
160058
|
["--no-tags", ...params.isShallow ? ["--depth=1"] : [], "origin", tempBranch],
|
|
159561
|
-
{ token: params.gitToken },
|
|
160059
|
+
{ token: params.gitToken, refreshGitToken: params.refreshGitToken },
|
|
159562
160060
|
`before_sha temp branch ${tempBranch}`
|
|
159563
160061
|
);
|
|
159564
160062
|
log.debug(`\xBB fetched before_sha via temp branch ${tempBranch}`);
|
|
@@ -159574,6 +160072,14 @@ async function ensureBeforeShaReachable(params) {
|
|
|
159574
160072
|
return false;
|
|
159575
160073
|
}
|
|
159576
160074
|
}
|
|
160075
|
+
function hasLocalCommit(sha) {
|
|
160076
|
+
if (!sha) return false;
|
|
160077
|
+
try {
|
|
160078
|
+
return $("git", ["cat-file", "-t", sha], { log: false }).trim() === "commit";
|
|
160079
|
+
} catch {
|
|
160080
|
+
return false;
|
|
160081
|
+
}
|
|
160082
|
+
}
|
|
159577
160083
|
var STALE_LOCK_AGE_MS = 3e4;
|
|
159578
160084
|
var PULL_REF_RETRY_DELAYS_MS = [2e3, 5e3, 1e4];
|
|
159579
160085
|
var PULL_REF_MISSING_PATTERN = /couldn't find remote ref pull\/\d+\/head/i;
|
|
@@ -159624,7 +160130,7 @@ async function abortIfPullRequestMoved(args2) {
|
|
|
159624
160130
|
);
|
|
159625
160131
|
}
|
|
159626
160132
|
async function checkoutPrBranch(pr, params) {
|
|
159627
|
-
const { octokit, owner, name, gitToken, toolState, beforeSha } = params;
|
|
160133
|
+
const { octokit, owner, name, gitToken, refreshGitToken, toolState, beforeSha } = params;
|
|
159628
160134
|
rejectIfLeadingDash(pr.baseRef, "PR base ref");
|
|
159629
160135
|
rejectIfLeadingDash(pr.headRef, "PR head ref");
|
|
159630
160136
|
const repoState = requireRepoState(toolState, owner, name);
|
|
@@ -159638,7 +160144,7 @@ async function checkoutPrBranch(pr, params) {
|
|
|
159638
160144
|
log.debug(`\xBB fetching base branch (${pr.baseRef})...`);
|
|
159639
160145
|
await $gitFetchWithDeepen(
|
|
159640
160146
|
["--no-tags", "origin", pr.baseRef],
|
|
159641
|
-
{ token: gitToken },
|
|
160147
|
+
{ token: gitToken, refreshGitToken },
|
|
159642
160148
|
`base branch ${pr.baseRef}`
|
|
159643
160149
|
);
|
|
159644
160150
|
if (!alreadyOnBranch) {
|
|
@@ -159649,7 +160155,7 @@ async function checkoutPrBranch(pr, params) {
|
|
|
159649
160155
|
try {
|
|
159650
160156
|
await $gitFetchWithDeepen(
|
|
159651
160157
|
["--no-tags", "origin", `+pull/${pr.number}/head:${localBranch}`],
|
|
159652
|
-
{ token: gitToken },
|
|
160158
|
+
{ token: gitToken, refreshGitToken },
|
|
159653
160159
|
`PR #${pr.number}`
|
|
159654
160160
|
);
|
|
159655
160161
|
} catch (e) {
|
|
@@ -159676,6 +160182,7 @@ async function checkoutPrBranch(pr, params) {
|
|
|
159676
160182
|
owner,
|
|
159677
160183
|
repo: name,
|
|
159678
160184
|
gitToken,
|
|
160185
|
+
refreshGitToken,
|
|
159679
160186
|
isShallow
|
|
159680
160187
|
}) : false;
|
|
159681
160188
|
if (isShallow) {
|
|
@@ -159789,6 +160296,7 @@ function CheckoutPrTool(ctx) {
|
|
|
159789
160296
|
owner: ctx.repo.owner,
|
|
159790
160297
|
name: ctx.repo.name,
|
|
159791
160298
|
gitToken: ctx.gitToken,
|
|
160299
|
+
refreshGitToken: ctx.refreshGitToken,
|
|
159792
160300
|
toolState: ctx.toolState,
|
|
159793
160301
|
shell: ctx.payload.shell,
|
|
159794
160302
|
postCheckoutScript: ctx.postCheckoutScript,
|
|
@@ -159804,6 +160312,8 @@ function CheckoutPrTool(ctx) {
|
|
|
159804
160312
|
if (!checkoutSha) throw new Error("checkout completed without a resolved HEAD SHA");
|
|
159805
160313
|
const headShort = checkoutSha.slice(0, 7);
|
|
159806
160314
|
let incrementalDiffPath;
|
|
160315
|
+
let incrementalUnavailable = false;
|
|
160316
|
+
let incrementalUnavailableReason;
|
|
159807
160317
|
if (primary.beforeSha) {
|
|
159808
160318
|
const beforeShort = primary.beforeSha.slice(0, 7);
|
|
159809
160319
|
const incremental = computeIncrementalDiff({
|
|
@@ -159811,15 +160321,18 @@ function CheckoutPrTool(ctx) {
|
|
|
159811
160321
|
beforeSha: primary.beforeSha,
|
|
159812
160322
|
headSha: checkoutSha
|
|
159813
160323
|
});
|
|
159814
|
-
if (incremental) {
|
|
160324
|
+
if (incremental.status === "ok") {
|
|
159815
160325
|
incrementalDiffPath = join13(
|
|
159816
160326
|
tempDir,
|
|
159817
160327
|
`pr-${pull_number}-${beforeShort}-${headShort}-incremental.diff`
|
|
159818
160328
|
);
|
|
159819
|
-
writeFileSync8(incrementalDiffPath, incremental);
|
|
160329
|
+
writeFileSync8(incrementalDiffPath, incremental.diff);
|
|
159820
160330
|
log.info(
|
|
159821
|
-
`\xBB incremental diff computed (${incremental.length} bytes) \u2192 ${incrementalDiffPath}`
|
|
160331
|
+
`\xBB incremental diff computed (${incremental.diff.length} bytes) \u2192 ${incrementalDiffPath}`
|
|
159822
160332
|
);
|
|
160333
|
+
} else if (incremental.status === "unavailable") {
|
|
160334
|
+
incrementalUnavailable = true;
|
|
160335
|
+
incrementalUnavailableReason = incremental.reason;
|
|
159823
160336
|
}
|
|
159824
160337
|
}
|
|
159825
160338
|
const formatResult = await fetchAndFormatPrDiff(ctx, pull_number);
|
|
@@ -159886,7 +160399,13 @@ ${diffPreview}`);
|
|
|
159886
160399
|
primary.commentableLinesByFile = cached4;
|
|
159887
160400
|
primary.commentableLinesPullNumber = pull_number;
|
|
159888
160401
|
primary.commentableLinesCheckoutSha = checkoutSha;
|
|
159889
|
-
const incrementalInstructions = incrementalDiffPath ? `IMPORTANT: incrementalDiffPath contains ONLY the changes since the last reviewed version (computed via range-diff). you MUST read incrementalDiffPath FIRST to understand what changed, then use diffPath for full PR context. do NOT skip the incremental diff. ` :
|
|
160402
|
+
const incrementalInstructions = incrementalDiffPath ? `IMPORTANT: incrementalDiffPath contains ONLY the changes since the last reviewed version (computed via range-diff). you MUST read incrementalDiffPath FIRST to understand what changed, then use diffPath for full PR context. do NOT skip the incremental diff. ` : incrementalUnavailable ? (
|
|
160403
|
+
// say it FAILED rather than leaving the agent to infer "nothing changed"
|
|
160404
|
+
// from an absent field. only suggest diff-tree when the previous
|
|
160405
|
+
// revision is actually PRESENT locally — if the fetch never landed it,
|
|
160406
|
+
// diff-tree needs that object too and would fail identically. see #1139.
|
|
160407
|
+
`NOTE: an incremental diff was expected for this run but could not be computed` + (incrementalUnavailableReason ? ` (${incrementalUnavailableReason})` : "") + `. review the full diffPath instead. ` + (hasLocalCommit(primary.beforeSha) ? `if you need just the delta, \`git diff-tree -p ${primary.beforeSha} ${checkoutSha}\` works without a merge base. ` : `the previous revision was never fetched into this shallow checkout, so the full diff is the only option. `)
|
|
160408
|
+
) : "";
|
|
159890
160409
|
const impactInstructions = impactPath ? ` impactPath contains bounded, deterministic reference leads for semantic atoms changed by the PR. read the authoritative diff TOC and relevant raw diff lines FIRST; only then use impactPath as a supplemental, explicitly incomplete lead list. impactPath never establishes review coverage and an empty artifact is not evidence of no wider impact.` : "";
|
|
159891
160410
|
const COMMIT_LOG_MAX = 200;
|
|
159892
160411
|
const baseRange = `origin/${pr.baseRef}..HEAD`;
|
|
@@ -160206,299 +160725,6 @@ import { performance as performance8 } from "node:perf_hooks";
|
|
|
160206
160725
|
import { existsSync as existsSync6 } from "node:fs";
|
|
160207
160726
|
import { join as join17 } from "node:path";
|
|
160208
160727
|
|
|
160209
|
-
// node_modules/.pnpm/package-manager-detector@1.6.0/node_modules/package-manager-detector/dist/commands.mjs
|
|
160210
|
-
function dashDashArg(agent2, agentCommand) {
|
|
160211
|
-
return (args2) => {
|
|
160212
|
-
if (args2.length > 1) {
|
|
160213
|
-
return [agent2, agentCommand, args2[0], "--", ...args2.slice(1)];
|
|
160214
|
-
} else {
|
|
160215
|
-
return [agent2, agentCommand, args2[0]];
|
|
160216
|
-
}
|
|
160217
|
-
};
|
|
160218
|
-
}
|
|
160219
|
-
function denoExecute() {
|
|
160220
|
-
return (args2) => {
|
|
160221
|
-
return ["deno", "run", `npm:${args2[0]}`, ...args2.slice(1)];
|
|
160222
|
-
};
|
|
160223
|
-
}
|
|
160224
|
-
var npm = {
|
|
160225
|
-
"agent": ["npm", 0],
|
|
160226
|
-
"run": dashDashArg("npm", "run"),
|
|
160227
|
-
"install": ["npm", "i", 0],
|
|
160228
|
-
"frozen": ["npm", "ci", 0],
|
|
160229
|
-
"global": ["npm", "i", "-g", 0],
|
|
160230
|
-
"add": ["npm", "i", 0],
|
|
160231
|
-
"upgrade": ["npm", "update", 0],
|
|
160232
|
-
"upgrade-interactive": null,
|
|
160233
|
-
"dedupe": ["npm", "dedupe", 0],
|
|
160234
|
-
"execute": ["npx", 0],
|
|
160235
|
-
"execute-local": ["npx", 0],
|
|
160236
|
-
"uninstall": ["npm", "uninstall", 0],
|
|
160237
|
-
"global_uninstall": ["npm", "uninstall", "-g", 0]
|
|
160238
|
-
};
|
|
160239
|
-
var yarn = {
|
|
160240
|
-
"agent": ["yarn", 0],
|
|
160241
|
-
"run": ["yarn", "run", 0],
|
|
160242
|
-
"install": ["yarn", "install", 0],
|
|
160243
|
-
"frozen": ["yarn", "install", "--frozen-lockfile", 0],
|
|
160244
|
-
"global": ["yarn", "global", "add", 0],
|
|
160245
|
-
"add": ["yarn", "add", 0],
|
|
160246
|
-
"upgrade": ["yarn", "upgrade", 0],
|
|
160247
|
-
"upgrade-interactive": ["yarn", "upgrade-interactive", 0],
|
|
160248
|
-
"dedupe": null,
|
|
160249
|
-
"execute": ["npx", 0],
|
|
160250
|
-
"execute-local": dashDashArg("yarn", "exec"),
|
|
160251
|
-
"uninstall": ["yarn", "remove", 0],
|
|
160252
|
-
"global_uninstall": ["yarn", "global", "remove", 0]
|
|
160253
|
-
};
|
|
160254
|
-
var yarnBerry = {
|
|
160255
|
-
...yarn,
|
|
160256
|
-
"frozen": ["yarn", "install", "--immutable", 0],
|
|
160257
|
-
"upgrade": ["yarn", "up", 0],
|
|
160258
|
-
"upgrade-interactive": ["yarn", "up", "-i", 0],
|
|
160259
|
-
"dedupe": ["yarn", "dedupe", 0],
|
|
160260
|
-
"execute": ["yarn", "dlx", 0],
|
|
160261
|
-
"execute-local": ["yarn", "exec", 0],
|
|
160262
|
-
// Yarn 2+ removed 'global', see https://github.com/yarnpkg/berry/issues/821
|
|
160263
|
-
"global": ["npm", "i", "-g", 0],
|
|
160264
|
-
"global_uninstall": ["npm", "uninstall", "-g", 0]
|
|
160265
|
-
};
|
|
160266
|
-
var pnpm = {
|
|
160267
|
-
"agent": ["pnpm", 0],
|
|
160268
|
-
"run": ["pnpm", "run", 0],
|
|
160269
|
-
"install": ["pnpm", "i", 0],
|
|
160270
|
-
"frozen": ["pnpm", "i", "--frozen-lockfile", 0],
|
|
160271
|
-
"global": ["pnpm", "add", "-g", 0],
|
|
160272
|
-
"add": ["pnpm", "add", 0],
|
|
160273
|
-
"upgrade": ["pnpm", "update", 0],
|
|
160274
|
-
"upgrade-interactive": ["pnpm", "update", "-i", 0],
|
|
160275
|
-
"dedupe": ["pnpm", "dedupe", 0],
|
|
160276
|
-
"execute": ["pnpm", "dlx", 0],
|
|
160277
|
-
"execute-local": ["pnpm", "exec", 0],
|
|
160278
|
-
"uninstall": ["pnpm", "remove", 0],
|
|
160279
|
-
"global_uninstall": ["pnpm", "remove", "--global", 0]
|
|
160280
|
-
};
|
|
160281
|
-
var bun = {
|
|
160282
|
-
"agent": ["bun", 0],
|
|
160283
|
-
"run": ["bun", "run", 0],
|
|
160284
|
-
"install": ["bun", "install", 0],
|
|
160285
|
-
"frozen": ["bun", "install", "--frozen-lockfile", 0],
|
|
160286
|
-
"global": ["bun", "add", "-g", 0],
|
|
160287
|
-
"add": ["bun", "add", 0],
|
|
160288
|
-
"upgrade": ["bun", "update", 0],
|
|
160289
|
-
"upgrade-interactive": ["bun", "update", "-i", 0],
|
|
160290
|
-
"dedupe": null,
|
|
160291
|
-
"execute": ["bun", "x", 0],
|
|
160292
|
-
"execute-local": ["bun", "x", 0],
|
|
160293
|
-
"uninstall": ["bun", "remove", 0],
|
|
160294
|
-
"global_uninstall": ["bun", "remove", "-g", 0]
|
|
160295
|
-
};
|
|
160296
|
-
var deno = {
|
|
160297
|
-
"agent": ["deno", 0],
|
|
160298
|
-
"run": ["deno", "task", 0],
|
|
160299
|
-
"install": ["deno", "install", 0],
|
|
160300
|
-
"frozen": ["deno", "install", "--frozen", 0],
|
|
160301
|
-
"global": ["deno", "install", "-g", 0],
|
|
160302
|
-
"add": ["deno", "add", 0],
|
|
160303
|
-
"upgrade": ["deno", "outdated", "--update", 0],
|
|
160304
|
-
"upgrade-interactive": ["deno", "outdated", "--update", 0],
|
|
160305
|
-
"dedupe": null,
|
|
160306
|
-
"execute": denoExecute(),
|
|
160307
|
-
"execute-local": ["deno", "task", "--eval", 0],
|
|
160308
|
-
"uninstall": ["deno", "remove", 0],
|
|
160309
|
-
"global_uninstall": ["deno", "uninstall", "-g", 0]
|
|
160310
|
-
};
|
|
160311
|
-
var COMMANDS = {
|
|
160312
|
-
"npm": npm,
|
|
160313
|
-
"yarn": yarn,
|
|
160314
|
-
"yarn@berry": yarnBerry,
|
|
160315
|
-
"pnpm": pnpm,
|
|
160316
|
-
// pnpm v6.x or below
|
|
160317
|
-
"pnpm@6": {
|
|
160318
|
-
...pnpm,
|
|
160319
|
-
run: dashDashArg("pnpm", "run")
|
|
160320
|
-
},
|
|
160321
|
-
"bun": bun,
|
|
160322
|
-
"deno": deno
|
|
160323
|
-
};
|
|
160324
|
-
function resolveCommand(agent2, command, args2) {
|
|
160325
|
-
const value2 = COMMANDS[agent2][command];
|
|
160326
|
-
return constructCommand(value2, args2);
|
|
160327
|
-
}
|
|
160328
|
-
function constructCommand(value2, args2) {
|
|
160329
|
-
if (value2 == null)
|
|
160330
|
-
return null;
|
|
160331
|
-
const list = typeof value2 === "function" ? value2(args2) : value2.flatMap((v) => {
|
|
160332
|
-
if (typeof v === "number")
|
|
160333
|
-
return args2;
|
|
160334
|
-
return [v];
|
|
160335
|
-
});
|
|
160336
|
-
return {
|
|
160337
|
-
command: list[0],
|
|
160338
|
-
args: list.slice(1)
|
|
160339
|
-
};
|
|
160340
|
-
}
|
|
160341
|
-
|
|
160342
|
-
// node_modules/.pnpm/package-manager-detector@1.6.0/node_modules/package-manager-detector/dist/constants.mjs
|
|
160343
|
-
var AGENTS = [
|
|
160344
|
-
"npm",
|
|
160345
|
-
"yarn",
|
|
160346
|
-
"yarn@berry",
|
|
160347
|
-
"pnpm",
|
|
160348
|
-
"pnpm@6",
|
|
160349
|
-
"bun",
|
|
160350
|
-
"deno"
|
|
160351
|
-
];
|
|
160352
|
-
var LOCKS = {
|
|
160353
|
-
"bun.lock": "bun",
|
|
160354
|
-
"bun.lockb": "bun",
|
|
160355
|
-
"deno.lock": "deno",
|
|
160356
|
-
"pnpm-lock.yaml": "pnpm",
|
|
160357
|
-
"pnpm-workspace.yaml": "pnpm",
|
|
160358
|
-
"yarn.lock": "yarn",
|
|
160359
|
-
"package-lock.json": "npm",
|
|
160360
|
-
"npm-shrinkwrap.json": "npm"
|
|
160361
|
-
};
|
|
160362
|
-
var INSTALL_METADATA = {
|
|
160363
|
-
"node_modules/.deno/": "deno",
|
|
160364
|
-
"node_modules/.pnpm/": "pnpm",
|
|
160365
|
-
"node_modules/.yarn-state.yml": "yarn",
|
|
160366
|
-
// yarn v2+ (node-modules)
|
|
160367
|
-
"node_modules/.yarn_integrity": "yarn",
|
|
160368
|
-
// yarn v1
|
|
160369
|
-
"node_modules/.package-lock.json": "npm",
|
|
160370
|
-
".pnp.cjs": "yarn",
|
|
160371
|
-
// yarn v3+ (pnp)
|
|
160372
|
-
".pnp.js": "yarn",
|
|
160373
|
-
// yarn v2 (pnp)
|
|
160374
|
-
"bun.lock": "bun",
|
|
160375
|
-
"bun.lockb": "bun"
|
|
160376
|
-
};
|
|
160377
|
-
|
|
160378
|
-
// node_modules/.pnpm/package-manager-detector@1.6.0/node_modules/package-manager-detector/dist/detect.mjs
|
|
160379
|
-
import fs2 from "node:fs/promises";
|
|
160380
|
-
import path from "node:path";
|
|
160381
|
-
import process4 from "node:process";
|
|
160382
|
-
async function pathExists(path22, type2) {
|
|
160383
|
-
try {
|
|
160384
|
-
const stat = await fs2.stat(path22);
|
|
160385
|
-
return type2 === "file" ? stat.isFile() : stat.isDirectory();
|
|
160386
|
-
} catch {
|
|
160387
|
-
return false;
|
|
160388
|
-
}
|
|
160389
|
-
}
|
|
160390
|
-
function* lookup(cwd = process4.cwd()) {
|
|
160391
|
-
let directory = path.resolve(cwd);
|
|
160392
|
-
const { root } = path.parse(directory);
|
|
160393
|
-
while (directory && directory !== root) {
|
|
160394
|
-
yield directory;
|
|
160395
|
-
directory = path.dirname(directory);
|
|
160396
|
-
}
|
|
160397
|
-
}
|
|
160398
|
-
async function parsePackageJson(filepath, options) {
|
|
160399
|
-
if (!filepath || !await pathExists(filepath, "file"))
|
|
160400
|
-
return null;
|
|
160401
|
-
return await handlePackageManager(filepath, options);
|
|
160402
|
-
}
|
|
160403
|
-
async function detect(options = {}) {
|
|
160404
|
-
const {
|
|
160405
|
-
cwd,
|
|
160406
|
-
strategies = ["lockfile", "packageManager-field", "devEngines-field"]
|
|
160407
|
-
} = options;
|
|
160408
|
-
let stopDir;
|
|
160409
|
-
if (typeof options.stopDir === "string") {
|
|
160410
|
-
const resolved = path.resolve(options.stopDir);
|
|
160411
|
-
stopDir = (dir) => dir === resolved;
|
|
160412
|
-
} else {
|
|
160413
|
-
stopDir = options.stopDir;
|
|
160414
|
-
}
|
|
160415
|
-
for (const directory of lookup(cwd)) {
|
|
160416
|
-
for (const strategy of strategies) {
|
|
160417
|
-
switch (strategy) {
|
|
160418
|
-
case "lockfile": {
|
|
160419
|
-
for (const lock of Object.keys(LOCKS)) {
|
|
160420
|
-
if (await pathExists(path.join(directory, lock), "file")) {
|
|
160421
|
-
const name = LOCKS[lock];
|
|
160422
|
-
const result = await parsePackageJson(path.join(directory, "package.json"), options);
|
|
160423
|
-
if (result)
|
|
160424
|
-
return result;
|
|
160425
|
-
else
|
|
160426
|
-
return { name, agent: name };
|
|
160427
|
-
}
|
|
160428
|
-
}
|
|
160429
|
-
break;
|
|
160430
|
-
}
|
|
160431
|
-
case "packageManager-field":
|
|
160432
|
-
case "devEngines-field": {
|
|
160433
|
-
const result = await parsePackageJson(path.join(directory, "package.json"), options);
|
|
160434
|
-
if (result)
|
|
160435
|
-
return result;
|
|
160436
|
-
break;
|
|
160437
|
-
}
|
|
160438
|
-
case "install-metadata": {
|
|
160439
|
-
for (const metadata of Object.keys(INSTALL_METADATA)) {
|
|
160440
|
-
const fileOrDir = metadata.endsWith("/") ? "dir" : "file";
|
|
160441
|
-
if (await pathExists(path.join(directory, metadata), fileOrDir)) {
|
|
160442
|
-
const name = INSTALL_METADATA[metadata];
|
|
160443
|
-
const agent2 = name === "yarn" ? isMetadataYarnClassic(metadata) ? "yarn" : "yarn@berry" : name;
|
|
160444
|
-
return { name, agent: agent2 };
|
|
160445
|
-
}
|
|
160446
|
-
}
|
|
160447
|
-
break;
|
|
160448
|
-
}
|
|
160449
|
-
}
|
|
160450
|
-
}
|
|
160451
|
-
if (stopDir?.(directory))
|
|
160452
|
-
break;
|
|
160453
|
-
}
|
|
160454
|
-
return null;
|
|
160455
|
-
}
|
|
160456
|
-
function getNameAndVer(pkg) {
|
|
160457
|
-
const handelVer = (version3) => version3?.match(/\d+(\.\d+){0,2}/)?.[0] ?? version3;
|
|
160458
|
-
if (typeof pkg.packageManager === "string") {
|
|
160459
|
-
const [name, ver] = pkg.packageManager.replace(/^\^/, "").split("@");
|
|
160460
|
-
return { name, ver: handelVer(ver) };
|
|
160461
|
-
}
|
|
160462
|
-
if (typeof pkg.devEngines?.packageManager?.name === "string") {
|
|
160463
|
-
return {
|
|
160464
|
-
name: pkg.devEngines.packageManager.name,
|
|
160465
|
-
ver: handelVer(pkg.devEngines.packageManager.version)
|
|
160466
|
-
};
|
|
160467
|
-
}
|
|
160468
|
-
return void 0;
|
|
160469
|
-
}
|
|
160470
|
-
async function handlePackageManager(filepath, options) {
|
|
160471
|
-
try {
|
|
160472
|
-
const content = await fs2.readFile(filepath, "utf8");
|
|
160473
|
-
const pkg = options.packageJsonParser ? await options.packageJsonParser(content, filepath) : JSON.parse(content);
|
|
160474
|
-
let agent2;
|
|
160475
|
-
const nameAndVer = getNameAndVer(pkg);
|
|
160476
|
-
if (nameAndVer) {
|
|
160477
|
-
const name = nameAndVer.name;
|
|
160478
|
-
const ver = nameAndVer.ver;
|
|
160479
|
-
let version3 = ver;
|
|
160480
|
-
if (name === "yarn" && ver && Number.parseInt(ver) > 1) {
|
|
160481
|
-
agent2 = "yarn@berry";
|
|
160482
|
-
version3 = "berry";
|
|
160483
|
-
return { name, agent: agent2, version: version3 };
|
|
160484
|
-
} else if (name === "pnpm" && ver && Number.parseInt(ver) < 7) {
|
|
160485
|
-
agent2 = "pnpm@6";
|
|
160486
|
-
return { name, agent: agent2, version: version3 };
|
|
160487
|
-
} else if (AGENTS.includes(name)) {
|
|
160488
|
-
agent2 = name;
|
|
160489
|
-
return { name, agent: agent2, version: version3 };
|
|
160490
|
-
} else {
|
|
160491
|
-
return options.onUnknown?.(pkg.packageManager) ?? null;
|
|
160492
|
-
}
|
|
160493
|
-
}
|
|
160494
|
-
} catch {
|
|
160495
|
-
}
|
|
160496
|
-
return null;
|
|
160497
|
-
}
|
|
160498
|
-
function isMetadataYarnClassic(metadataPath) {
|
|
160499
|
-
return metadataPath.endsWith(".yarn_integrity");
|
|
160500
|
-
}
|
|
160501
|
-
|
|
160502
160728
|
// utils/packageManager.ts
|
|
160503
160729
|
var import_semver2 = __toESM(require_semver2(), 1);
|
|
160504
160730
|
import { existsSync as existsSync5 } from "node:fs";
|
|
@@ -160584,11 +160810,7 @@ async function runCorepack(args2) {
|
|
|
160584
160810
|
const result = await spawn({
|
|
160585
160811
|
cmd: "corepack",
|
|
160586
160812
|
args: args2,
|
|
160587
|
-
env: {
|
|
160588
|
-
PATH: process.env.PATH || "",
|
|
160589
|
-
HOME: process.env.HOME || "",
|
|
160590
|
-
COREPACK_ENABLE_DOWNLOAD_PROMPT: "0"
|
|
160591
|
-
},
|
|
160813
|
+
env: { ...filterEnvForUntrustedCode(), COREPACK_ENABLE_DOWNLOAD_PROMPT: "0" },
|
|
160592
160814
|
onStdout: (chunk) => process.stdout.write(chunk),
|
|
160593
160815
|
onStderr: (chunk) => process.stderr.write(chunk)
|
|
160594
160816
|
});
|
|
@@ -160598,7 +160820,7 @@ async function currentVersion(name) {
|
|
|
160598
160820
|
const result = await spawn({
|
|
160599
160821
|
cmd: name,
|
|
160600
160822
|
args: ["--version"],
|
|
160601
|
-
env:
|
|
160823
|
+
env: filterEnvForUntrustedCode()
|
|
160602
160824
|
});
|
|
160603
160825
|
if (result.exitCode !== 0) return null;
|
|
160604
160826
|
return result.stdout.trim();
|
|
@@ -160650,14 +160872,8 @@ async function ensurePackageManager(params) {
|
|
|
160650
160872
|
}
|
|
160651
160873
|
return true;
|
|
160652
160874
|
}
|
|
160653
|
-
|
|
160654
|
-
// prep/installNodeDependencies.ts
|
|
160655
160875
|
async function isCommandAvailable(command) {
|
|
160656
|
-
const result = await spawn({
|
|
160657
|
-
cmd: "which",
|
|
160658
|
-
args: [command],
|
|
160659
|
-
env: { PATH: process.env.PATH || "" }
|
|
160660
|
-
});
|
|
160876
|
+
const result = await spawn({ cmd: "which", args: [command], env: filterEnvForUntrustedCode() });
|
|
160661
160877
|
return result.exitCode === 0;
|
|
160662
160878
|
}
|
|
160663
160879
|
async function installFallback(name, installSpec) {
|
|
@@ -160668,19 +160884,41 @@ async function installFallback(name, installSpec) {
|
|
|
160668
160884
|
const result = await spawn({
|
|
160669
160885
|
cmd,
|
|
160670
160886
|
args: args2,
|
|
160671
|
-
env:
|
|
160887
|
+
env: filterEnvForUntrustedCode(),
|
|
160672
160888
|
onStderr: (chunk) => process.stderr.write(chunk)
|
|
160673
160889
|
});
|
|
160674
|
-
if (result.exitCode !== 0) {
|
|
160675
|
-
return result.stderr || `failed to install ${name}`;
|
|
160676
|
-
}
|
|
160890
|
+
if (result.exitCode !== 0) return result.stderr || `failed to install ${name}`;
|
|
160677
160891
|
if (name === "deno") {
|
|
160678
|
-
const denoPath =
|
|
160892
|
+
const denoPath = join16(process.env.HOME || "", ".deno", "bin");
|
|
160679
160893
|
process.env.PATH = `${denoPath}:${process.env.PATH}`;
|
|
160680
160894
|
}
|
|
160681
160895
|
log.info(`\xBB installed ${name}`);
|
|
160682
160896
|
return null;
|
|
160683
160897
|
}
|
|
160898
|
+
async function provisionPackageManager(params) {
|
|
160899
|
+
if (await isCommandAvailable(params.name)) {
|
|
160900
|
+
if (params.declared) {
|
|
160901
|
+
await ensurePackageManager({ spec: params.declared, binDir: params.binDir });
|
|
160902
|
+
}
|
|
160903
|
+
return null;
|
|
160904
|
+
}
|
|
160905
|
+
if (params.declared) {
|
|
160906
|
+
const activated = await ensurePackageManager({ spec: params.declared, binDir: params.binDir });
|
|
160907
|
+
if (activated) return null;
|
|
160908
|
+
}
|
|
160909
|
+
const spec = params.declared ? `${params.declared.name}@${params.declared.version}` : params.name;
|
|
160910
|
+
return installFallback(params.name, spec);
|
|
160911
|
+
}
|
|
160912
|
+
|
|
160913
|
+
// prep/installNodeDependencies.ts
|
|
160914
|
+
async function isCommandAvailable2(command) {
|
|
160915
|
+
const result = await spawn({
|
|
160916
|
+
cmd: "which",
|
|
160917
|
+
args: [command],
|
|
160918
|
+
env: filterEnvForUntrustedCode()
|
|
160919
|
+
});
|
|
160920
|
+
return result.exitCode === 0;
|
|
160921
|
+
}
|
|
160684
160922
|
var installNodeDependencies = {
|
|
160685
160923
|
name: "installNodeDependencies",
|
|
160686
160924
|
shouldRun: () => {
|
|
@@ -160701,8 +160939,8 @@ var installNodeDependencies = {
|
|
|
160701
160939
|
} else {
|
|
160702
160940
|
log.info(`\xBB no package manager declared, defaulting to npm`);
|
|
160703
160941
|
}
|
|
160704
|
-
if (
|
|
160705
|
-
if (
|
|
160942
|
+
if (options.ignoreScripts) {
|
|
160943
|
+
if (!await isCommandAvailable2(packageManager)) {
|
|
160706
160944
|
return {
|
|
160707
160945
|
language: "node",
|
|
160708
160946
|
packageManager,
|
|
@@ -160712,23 +160950,20 @@ var installNodeDependencies = {
|
|
|
160712
160950
|
]
|
|
160713
160951
|
};
|
|
160714
160952
|
}
|
|
160715
|
-
|
|
160716
|
-
|
|
160717
|
-
|
|
160718
|
-
|
|
160719
|
-
|
|
160720
|
-
|
|
160721
|
-
|
|
160722
|
-
|
|
160723
|
-
|
|
160724
|
-
|
|
160725
|
-
|
|
160726
|
-
|
|
160727
|
-
|
|
160728
|
-
}
|
|
160953
|
+
} else {
|
|
160954
|
+
const installError = await provisionPackageManager({
|
|
160955
|
+
name: packageManager,
|
|
160956
|
+
declared,
|
|
160957
|
+
binDir: options.binDir
|
|
160958
|
+
});
|
|
160959
|
+
if (installError) {
|
|
160960
|
+
return {
|
|
160961
|
+
language: "node",
|
|
160962
|
+
packageManager,
|
|
160963
|
+
dependenciesInstalled: false,
|
|
160964
|
+
issues: [installError]
|
|
160965
|
+
};
|
|
160729
160966
|
}
|
|
160730
|
-
} else if (declared) {
|
|
160731
|
-
await ensurePackageManager({ spec: declared, binDir: options.binDir });
|
|
160732
160967
|
}
|
|
160733
160968
|
if (!detected) {
|
|
160734
160969
|
log.info(
|
|
@@ -160754,7 +160989,7 @@ var installNodeDependencies = {
|
|
|
160754
160989
|
const result = await spawn({
|
|
160755
160990
|
cmd: resolved.command,
|
|
160756
160991
|
args: resolved.args,
|
|
160757
|
-
env:
|
|
160992
|
+
env: filterEnvForUntrustedCode()
|
|
160758
160993
|
});
|
|
160759
160994
|
const output = [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
|
|
160760
160995
|
if (output) {
|
|
@@ -160828,11 +161063,11 @@ var TOOL_INSTALL_COMMANDS = {
|
|
|
160828
161063
|
pipenv: ["pip", "install", "pipenv"],
|
|
160829
161064
|
poetry: ["pip", "install", "poetry"]
|
|
160830
161065
|
};
|
|
160831
|
-
async function
|
|
161066
|
+
async function isCommandAvailable3(command) {
|
|
160832
161067
|
const result = await spawn({
|
|
160833
161068
|
cmd: "which",
|
|
160834
161069
|
args: [command],
|
|
160835
|
-
env:
|
|
161070
|
+
env: filterEnvForUntrustedCode()
|
|
160836
161071
|
});
|
|
160837
161072
|
return result.exitCode === 0;
|
|
160838
161073
|
}
|
|
@@ -160846,7 +161081,7 @@ async function installTool(name) {
|
|
|
160846
161081
|
const result = await spawn({
|
|
160847
161082
|
cmd,
|
|
160848
161083
|
args: args2,
|
|
160849
|
-
env:
|
|
161084
|
+
env: filterEnvForUntrustedCode(),
|
|
160850
161085
|
onStderr: (chunk) => process.stderr.write(chunk)
|
|
160851
161086
|
});
|
|
160852
161087
|
if (result.exitCode !== 0) {
|
|
@@ -160858,7 +161093,7 @@ async function installTool(name) {
|
|
|
160858
161093
|
var installPythonDependencies = {
|
|
160859
161094
|
name: "installPythonDependencies",
|
|
160860
161095
|
shouldRun: async () => {
|
|
160861
|
-
const hasPython = await
|
|
161096
|
+
const hasPython = await isCommandAvailable3("python3") || await isCommandAvailable3("python");
|
|
160862
161097
|
if (!hasPython) {
|
|
160863
161098
|
return false;
|
|
160864
161099
|
}
|
|
@@ -160892,7 +161127,7 @@ var installPythonDependencies = {
|
|
|
160892
161127
|
]
|
|
160893
161128
|
};
|
|
160894
161129
|
}
|
|
160895
|
-
const isAvailable = await
|
|
161130
|
+
const isAvailable = await isCommandAvailable3(config3.tool);
|
|
160896
161131
|
if (!isAvailable) {
|
|
160897
161132
|
log.info(`\xBB ${config3.tool} not found, attempting to install...`);
|
|
160898
161133
|
const installError = await installTool(config3.tool);
|
|
@@ -160912,7 +161147,7 @@ var installPythonDependencies = {
|
|
|
160912
161147
|
const result = await spawn({
|
|
160913
161148
|
cmd,
|
|
160914
161149
|
args: args2,
|
|
160915
|
-
env:
|
|
161150
|
+
env: filterEnvForUntrustedCode()
|
|
160916
161151
|
});
|
|
160917
161152
|
const output = [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
|
|
160918
161153
|
if (output) {
|
|
@@ -160941,37 +161176,6 @@ var installPythonDependencies = {
|
|
|
160941
161176
|
|
|
160942
161177
|
// prep/index.ts
|
|
160943
161178
|
var prepSteps = [installNodeDependencies, installPythonDependencies];
|
|
160944
|
-
async function dirtyTrackedPaths() {
|
|
160945
|
-
const result = await spawn({
|
|
160946
|
-
cmd: "git",
|
|
160947
|
-
args: ["diff", "--name-only", "HEAD"],
|
|
160948
|
-
env: process.env,
|
|
160949
|
-
activityTimeout: 0
|
|
160950
|
-
});
|
|
160951
|
-
if (result.exitCode !== 0) {
|
|
160952
|
-
throw new Error(
|
|
160953
|
-
`git diff --name-only HEAD failed (exit ${result.exitCode}): ${result.stderr.trim() || "(no stderr)"}`
|
|
160954
|
-
);
|
|
160955
|
-
}
|
|
160956
|
-
return new Set(result.stdout.split("\n").filter(Boolean));
|
|
160957
|
-
}
|
|
160958
|
-
async function restorePrepDirtiedFiles(preDirty) {
|
|
160959
|
-
const dirtied = [...await dirtyTrackedPaths()].filter((path4) => !preDirty.has(path4));
|
|
160960
|
-
if (dirtied.length === 0) return;
|
|
160961
|
-
const result = await spawn({
|
|
160962
|
-
cmd: "git",
|
|
160963
|
-
args: ["restore", "--staged", "--worktree", "--", ...dirtied],
|
|
160964
|
-
env: process.env,
|
|
160965
|
-
activityTimeout: 0
|
|
160966
|
-
});
|
|
160967
|
-
if (result.exitCode !== 0) {
|
|
160968
|
-
log.warning(
|
|
160969
|
-
`\xBB failed to restore ${dirtied.length} tracked file(s) modified by prep: ${result.stderr.trim() || "(no stderr)"}`
|
|
160970
|
-
);
|
|
160971
|
-
return;
|
|
160972
|
-
}
|
|
160973
|
-
log.info(`\xBB restored ${dirtied.length} tracked file(s) modified by prep: ${dirtied.join(", ")}`);
|
|
160974
|
-
}
|
|
160975
161179
|
async function runPrepPhase(options) {
|
|
160976
161180
|
log.debug("\xBB starting prep phase...");
|
|
160977
161181
|
const startTime = performance8.now();
|
|
@@ -160994,7 +161198,7 @@ async function runPrepPhase(options) {
|
|
|
160994
161198
|
}
|
|
160995
161199
|
}
|
|
160996
161200
|
} finally {
|
|
160997
|
-
await
|
|
161201
|
+
await restoreDirtiedSince({ before: preDirty, actor: "prep" });
|
|
160998
161202
|
}
|
|
160999
161203
|
const totalDurationMs = performance8.now() - startTime;
|
|
161000
161204
|
log.debug(`\xBB prep phase completed (${Math.round(totalDurationMs)}ms)`);
|
|
@@ -162210,13 +162414,38 @@ function buildThreadBlocks(threads, filePatchMap, reviewId) {
|
|
|
162210
162414
|
}
|
|
162211
162415
|
return threadBlocks;
|
|
162212
162416
|
}
|
|
162417
|
+
var fetchAllReviewThreads = op(
|
|
162418
|
+
async (key, ctx) => {
|
|
162419
|
+
const response = await ctx.octokit.graphql(REVIEW_THREADS_QUERY, {
|
|
162420
|
+
owner: key.owner,
|
|
162421
|
+
name: key.name,
|
|
162422
|
+
prNumber: key.pullNumber
|
|
162423
|
+
});
|
|
162424
|
+
return response.repository?.pullRequest?.reviewThreads?.nodes ?? [];
|
|
162425
|
+
},
|
|
162426
|
+
{ ttl: 6e4, name: "reviewThreads" }
|
|
162427
|
+
);
|
|
162428
|
+
var fetchPrFiles = op(
|
|
162429
|
+
async (key, ctx) => ctx.octokit.paginate(ctx.octokit.rest.pulls.listFiles, {
|
|
162430
|
+
owner: key.owner,
|
|
162431
|
+
repo: key.name,
|
|
162432
|
+
pull_number: key.pullNumber,
|
|
162433
|
+
per_page: 100
|
|
162434
|
+
}),
|
|
162435
|
+
{ ttl: 6e4, name: "prFiles" }
|
|
162436
|
+
);
|
|
162437
|
+
function invalidateReviewThreadCache(repo) {
|
|
162438
|
+
fetchAllReviewThreads.invalidate(
|
|
162439
|
+
(cached4) => cached4.owner === repo.owner && cached4.name === repo.name
|
|
162440
|
+
);
|
|
162441
|
+
}
|
|
162213
162442
|
async function getReviewThreads(input) {
|
|
162214
|
-
const
|
|
162215
|
-
|
|
162216
|
-
|
|
162217
|
-
|
|
162218
|
-
|
|
162219
|
-
|
|
162443
|
+
const allThreads = structuredClone(
|
|
162444
|
+
await fetchAllReviewThreads(
|
|
162445
|
+
{ owner: input.owner, name: input.name, pullNumber: input.pullNumber },
|
|
162446
|
+
{ octokit: input.octokit }
|
|
162447
|
+
)
|
|
162448
|
+
);
|
|
162220
162449
|
if (allThreads.length >= 100) {
|
|
162221
162450
|
log.warning(
|
|
162222
162451
|
`PR ${input.owner}/${input.name}#${input.pullNumber}: reviewThreads returned 100 results (limit reached, some threads may be missing)`
|
|
@@ -162273,12 +162502,10 @@ async function getReviewData(input) {
|
|
|
162273
162502
|
}),
|
|
162274
162503
|
getReviewThreads(input)
|
|
162275
162504
|
]);
|
|
162276
|
-
const prFiles = threads.length > 0 ? await
|
|
162277
|
-
owner: input.owner,
|
|
162278
|
-
|
|
162279
|
-
|
|
162280
|
-
per_page: 100
|
|
162281
|
-
}) : [];
|
|
162505
|
+
const prFiles = threads.length > 0 ? await fetchPrFiles(
|
|
162506
|
+
{ owner: input.owner, name: input.name, pullNumber: input.pullNumber },
|
|
162507
|
+
{ octokit: input.octokit }
|
|
162508
|
+
) : [];
|
|
162282
162509
|
if (review.data.body) {
|
|
162283
162510
|
review.data.body = await resolveBodyAssets({
|
|
162284
162511
|
body: review.data.body,
|
|
@@ -162422,6 +162649,7 @@ function ResolveReviewThreadTool(ctx) {
|
|
|
162422
162649
|
});
|
|
162423
162650
|
const thread = response.resolveReviewThread.thread;
|
|
162424
162651
|
log.info(`\xBB resolved review thread ${thread.id}`);
|
|
162652
|
+
invalidateReviewThreadCache({ owner: ctx.repo.owner, name: ctx.repo.name });
|
|
162425
162653
|
return {
|
|
162426
162654
|
thread_id: thread.id,
|
|
162427
162655
|
is_resolved: thread.isResolved,
|
|
@@ -162596,7 +162824,10 @@ import { join as join20 } from "node:path";
|
|
|
162596
162824
|
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
162597
162825
|
var ShellParams = type({
|
|
162598
162826
|
command: "string",
|
|
162599
|
-
|
|
162827
|
+
// advisory and unread — no code path consumes it. kept in the schema only
|
|
162828
|
+
// because it nudges the model to state intent before running a command;
|
|
162829
|
+
// REQUIRING it cost a full rejected turn every time one was omitted. #1140.
|
|
162830
|
+
"description?": "string",
|
|
162600
162831
|
"timeout?": type.number.describe(
|
|
162601
162832
|
"Timeout in MILLISECONDS (not seconds). Default 30000 (30s), max 120000 (2m). e.g. timeout: 180000 for 3 minutes; timeout: 180 means 180ms and will kill the process almost immediately."
|
|
162602
162833
|
),
|
|
@@ -162604,6 +162835,7 @@ var ShellParams = type({
|
|
|
162604
162835
|
"background?": "boolean"
|
|
162605
162836
|
});
|
|
162606
162837
|
var detectedSandboxMethod;
|
|
162838
|
+
var usernsProbeError;
|
|
162607
162839
|
function detectSandboxMethod() {
|
|
162608
162840
|
if (detectedSandboxMethod !== void 0) {
|
|
162609
162841
|
return detectedSandboxMethod;
|
|
@@ -162637,6 +162869,35 @@ function detectSandboxMethod() {
|
|
|
162637
162869
|
}
|
|
162638
162870
|
} catch {
|
|
162639
162871
|
}
|
|
162872
|
+
try {
|
|
162873
|
+
const result = spawnSync6(
|
|
162874
|
+
"unshare",
|
|
162875
|
+
[
|
|
162876
|
+
"--user",
|
|
162877
|
+
"--map-root-user",
|
|
162878
|
+
"--pid",
|
|
162879
|
+
"--fork",
|
|
162880
|
+
"--mount",
|
|
162881
|
+
"setpriv",
|
|
162882
|
+
"--no-new-privs",
|
|
162883
|
+
"--bounding-set",
|
|
162884
|
+
"-all",
|
|
162885
|
+
"--inh-caps",
|
|
162886
|
+
"-all",
|
|
162887
|
+
"--ambient-caps",
|
|
162888
|
+
"-all",
|
|
162889
|
+
"true"
|
|
162890
|
+
],
|
|
162891
|
+
{ timeout: 5e3, stdio: ["ignore", "ignore", "pipe"] }
|
|
162892
|
+
);
|
|
162893
|
+
if (result.status === 0) {
|
|
162894
|
+
detectedSandboxMethod = "userns-unshare";
|
|
162895
|
+
log.debug("PID namespace isolation enabled (unprivileged userns unshare)");
|
|
162896
|
+
return "userns-unshare";
|
|
162897
|
+
}
|
|
162898
|
+
usernsProbeError = result.stderr?.toString().trim() || result.error?.message;
|
|
162899
|
+
} catch {
|
|
162900
|
+
}
|
|
162640
162901
|
detectedSandboxMethod = "none";
|
|
162641
162902
|
log.info("PID namespace isolation not available");
|
|
162642
162903
|
return "none";
|
|
@@ -162684,7 +162945,7 @@ function spawnShell(params) {
|
|
|
162684
162945
|
const ci = process.env.CI === "true";
|
|
162685
162946
|
if (ci && sandboxMethod === "none") {
|
|
162686
162947
|
throw new Error(
|
|
162687
|
-
"
|
|
162948
|
+
"PID-namespace isolation is required in CI but unavailable: unprivileged unshare, sudo unshare, and userns-nested unshare all failed. " + (usernsProbeError ? `userns probe said: ${usernsProbeError}. ` : "") + "on a containerized / Kubernetes self-hosted runner the cause is usually one of: the pod's seccomp profile blocks user-namespace creation (Pod Security Standards baseline/restricted); the pod runs as root without CAP_SETFCAP, which the kernel requires to map uid 0; or the node kernel disallows unprivileged user namespaces (Ubuntu >= 23.10, Bottlerocket, Talos). elsewhere, check that `unshare` and `setpriv` (util-linux >= 2.31, which is what added --ambient-caps) are on PATH. see https://docs.pullfrog.com/security#self-hosted-runners"
|
|
162688
162949
|
);
|
|
162689
162950
|
}
|
|
162690
162951
|
const repoRoot = resolveRepoRoot();
|
|
@@ -162703,6 +162964,23 @@ function spawnShell(params) {
|
|
|
162703
162964
|
spawnOpts
|
|
162704
162965
|
);
|
|
162705
162966
|
}
|
|
162967
|
+
if (sandboxMethod === "userns-unshare") {
|
|
162968
|
+
const escaped = params.command.replace(/'/g, "'\\''");
|
|
162969
|
+
return spawn3(
|
|
162970
|
+
"unshare",
|
|
162971
|
+
[
|
|
162972
|
+
"--user",
|
|
162973
|
+
"--map-root-user",
|
|
162974
|
+
"--pid",
|
|
162975
|
+
"--fork",
|
|
162976
|
+
"--mount",
|
|
162977
|
+
"bash",
|
|
162978
|
+
"-c",
|
|
162979
|
+
`${PROC_CLEANUP} ${SOCKET_CLEANUP} ${fsMounts} exec setpriv --no-new-privs --bounding-set -all --inh-caps -all --ambient-caps -all bash -c '${escaped}'`
|
|
162980
|
+
],
|
|
162981
|
+
spawnOpts
|
|
162982
|
+
);
|
|
162983
|
+
}
|
|
162706
162984
|
if (sandboxMethod === "sudo-unshare") {
|
|
162707
162985
|
const envArgs = [];
|
|
162708
162986
|
for (const [k, v] of Object.entries(params.env)) {
|
|
@@ -162866,6 +163144,8 @@ Do NOT use this tool for git commands \u2014 use the dedicated git tools instead
|
|
|
162866
163144
|
proc.on("exit", done);
|
|
162867
163145
|
proc.on("error", () => done(null));
|
|
162868
163146
|
});
|
|
163147
|
+
proc.stdout?.destroy();
|
|
163148
|
+
proc.stderr?.destroy();
|
|
162869
163149
|
let output = stderr ? stdout ? `${stdout}
|
|
162870
163150
|
${stderr}` : stderr : stdout;
|
|
162871
163151
|
if (timedOut)
|
|
@@ -163109,6 +163389,7 @@ function CheckoutRepoTool(ctx) {
|
|
|
163109
163389
|
owner,
|
|
163110
163390
|
name: repo,
|
|
163111
163391
|
gitToken: rc.gitToken,
|
|
163392
|
+
refreshGitToken: rc.refreshGitToken,
|
|
163112
163393
|
octokit: rc.octokit,
|
|
163113
163394
|
toolState: ctx.toolState,
|
|
163114
163395
|
shell: ctx.payload.shell,
|
|
@@ -163605,14 +163886,22 @@ function validateAgentApiKey(params) {
|
|
|
163605
163886
|
}
|
|
163606
163887
|
function isApiKeyAuthError(text) {
|
|
163607
163888
|
if (!text) return false;
|
|
163608
|
-
return text.includes(MISSING_KEY_MARKER) || /Invalid API key/i.test(text) || /\bUser not found\b/i.test(text) || /\bInvalid authentication\b/i.test(text) || /authentication_error/i.test(text) || /Invalid bearer token/i.test(text) || /api_error_status\s*=\s*401/i.test(text) || /API Error:\s*401/i.test(text) || /Failed to authenticate\. API Error:/i.test(text) || /Your api key:.*is invalid/i.test(text) || isClaudeSubscriptionDisabledError(text) || isOAuthCredentialExpiredError(text);
|
|
163889
|
+
return text.includes(MISSING_KEY_MARKER) || /Invalid API key/i.test(text) || /\bUser not found\b/i.test(text) || /\bInvalid authentication\b/i.test(text) || /authentication_error/i.test(text) || /Invalid bearer token/i.test(text) || /api_error_status\s*=\s*401/i.test(text) || /API Error:\s*401/i.test(text) || /Failed to authenticate\. API Error:/i.test(text) || /Your api key:.*is invalid/i.test(text) || isClaudeSubscriptionDisabledError(text) || isClaudeSessionLimitError(text) || isOAuthCredentialExpiredError(text);
|
|
163609
163890
|
}
|
|
163610
163891
|
function isOAuthCredentialExpiredError(text) {
|
|
163611
|
-
return /authentication token has (expired|been invalidated)
|
|
163892
|
+
return /(?:authentication|OAuth access) token has (?:expired|been (?:invalidated|revoked))/i.test(
|
|
163893
|
+
text
|
|
163894
|
+
) || // the provider no longer recognises the token at all (#1086) — same dead
|
|
163895
|
+
// credential, phrased as a lookup miss rather than a state transition.
|
|
163896
|
+
/Could not find the appropriate key in your authentication token/i.test(text) || /Token refresh failed/i.test(text);
|
|
163612
163897
|
}
|
|
163613
163898
|
function isClaudeSubscriptionDisabledError(text) {
|
|
163614
163899
|
return /disabled Claude subscription access/i.test(text);
|
|
163615
163900
|
}
|
|
163901
|
+
var CLAUDE_SESSION_LIMIT_PATTERN = /hit your (?:session|weekly|five-hour|Opus|Sonnet|Haiku)\s+limit(?:\s*·\s*resets\s+([^"\n]+))?/i;
|
|
163902
|
+
function isClaudeSessionLimitError(text) {
|
|
163903
|
+
return CLAUDE_SESSION_LIMIT_PATTERN.test(text);
|
|
163904
|
+
}
|
|
163616
163905
|
function formatApiKeyErrorSummary(params) {
|
|
163617
163906
|
if (params.raw.includes(MISSING_KEY_MARKER)) {
|
|
163618
163907
|
if (params.raw.startsWith(`**${MISSING_KEY_MARKER}**`)) return params.raw;
|
|
@@ -163620,6 +163909,15 @@ function formatApiKeyErrorSummary(params) {
|
|
|
163620
163909
|
}
|
|
163621
163910
|
const githubSecretsUrl = `https://github.com/${params.owner}/${params.name}/settings/secrets/actions`;
|
|
163622
163911
|
const settingsUrl = `${getApiUrl()}/console/${params.owner}/${params.name}`;
|
|
163912
|
+
if (isClaudeSessionLimitError(params.raw)) {
|
|
163913
|
+
const reset = CLAUDE_SESSION_LIMIT_PATTERN.exec(params.raw)?.[1]?.trim();
|
|
163914
|
+
const resets = reset ? ` It resets at **${reset}**.` : "";
|
|
163915
|
+
return [
|
|
163916
|
+
`**Your Claude subscription has hit its usage limit.**${resets} Re-trigger Pullfrog after the reset, or add an \`ANTHROPIC_API_KEY\` repo secret \u2014 Pullfrog routes around an exhausted subscription automatically when one is present.`,
|
|
163917
|
+
"",
|
|
163918
|
+
`[Add repo secret \u2192](${githubSecretsUrl}) \xB7 [Model settings \u2192](${settingsUrl}) \xB7 [Setup docs \u2192](https://docs.pullfrog.com/keys) \xB7 [Ask in Discord \u2192](https://discord.gg/8y96raFg8e)`
|
|
163919
|
+
].join("\n");
|
|
163920
|
+
}
|
|
163623
163921
|
if (isClaudeSubscriptionDisabledError(params.raw)) {
|
|
163624
163922
|
return [
|
|
163625
163923
|
`**Your organization has disabled Claude subscription access for Claude Code.** Ask your Claude organization's admin to re-enable it in the Claude Console, or set an \`ANTHROPIC_API_KEY\` for this repo instead, then re-trigger the run.`,
|
|
@@ -164429,7 +164727,9 @@ function decideModelAccess(input) {
|
|
|
164429
164727
|
if (input.proxyActive) {
|
|
164430
164728
|
const target = resolveOpenRouterModel(input.model);
|
|
164431
164729
|
if (input.oss) {
|
|
164432
|
-
if (target && target === input.subsidyTarget)
|
|
164730
|
+
if (target && (target === input.subsidyTarget || isOssAllowedModel(input.model))) {
|
|
164731
|
+
return { kind: "proxy", target };
|
|
164732
|
+
}
|
|
164433
164733
|
if (byokAuthorized) return { kind: "byok" };
|
|
164434
164734
|
return { kind: "error", reason: "oss" };
|
|
164435
164735
|
}
|
|
@@ -164441,6 +164741,11 @@ function decideModelAccess(input) {
|
|
|
164441
164741
|
return { kind: "error", reason: "byok_no_key" };
|
|
164442
164742
|
}
|
|
164443
164743
|
var MODEL_ACCESS_MARKER = "requested model is not available";
|
|
164744
|
+
function ossAllowedLabels() {
|
|
164745
|
+
return OSS_MODEL_ALLOWLIST.map(
|
|
164746
|
+
(slug2) => `\`${resolveDisplayAlias(slug2)?.displayName ?? slug2}\``
|
|
164747
|
+
).join(", ");
|
|
164748
|
+
}
|
|
164444
164749
|
function buildModelAccessError(input) {
|
|
164445
164750
|
const settingsUrl = `${getApiUrl()}/console/${input.owner}/${input.name}`;
|
|
164446
164751
|
const secretsUrl = `https://github.com/${input.owner}/${input.name}/settings/secrets/actions`;
|
|
@@ -164448,8 +164753,8 @@ function buildModelAccessError(input) {
|
|
|
164448
164753
|
const headline = `**The ${MODEL_ACCESS_MARKER}: \`${input.model}\`.**`;
|
|
164449
164754
|
const branch = {
|
|
164450
164755
|
oss: {
|
|
164451
|
-
why:
|
|
164452
|
-
cta: `[Add a provider key \u2192](${secretsUrl}) \xB7 [Setup docs \u2192](${docsUrl})`
|
|
164756
|
+
why: `This repo runs on Pullfrog's OSS subsidy, which funds a set of pre-approved models: ${ossAllowedLabels()}. Pick one of those, or add your own provider key to run a different one.`,
|
|
164757
|
+
cta: `[Configure model \u2192](${settingsUrl}) \xB7 [Add a provider key \u2192](${secretsUrl}) \xB7 [Setup docs \u2192](${docsUrl})`
|
|
164453
164758
|
},
|
|
164454
164759
|
byok_no_key: {
|
|
164455
164760
|
why: `No provider key for \`${input.model}\` is present in this run's environment. Add the matching provider key as a GitHub Actions secret, or pick a model you already have a key for.`,
|
|
@@ -164605,12 +164910,14 @@ var ShellPermissionInput = type.enumerated("disabled", "restricted", "enabled");
|
|
|
164605
164910
|
var PushPermissionInput = type.enumerated("disabled", "restricted", "enabled");
|
|
164606
164911
|
var StatusChecksInput = type.enumerated("disabled", "enabled");
|
|
164607
164912
|
var ProgressCommentsInput = type.enumerated("disabled", "enabled");
|
|
164913
|
+
var DebugInput = type.enumerated("disabled", "enabled");
|
|
164608
164914
|
var JsonPayload = type({
|
|
164609
164915
|
"~pullfrog": "true",
|
|
164610
164916
|
version: "string",
|
|
164611
164917
|
"model?": "string | undefined",
|
|
164612
164918
|
"modelExplicit?": "boolean | undefined",
|
|
164613
164919
|
"effort?": "number | string | undefined",
|
|
164920
|
+
"debug?": "boolean | undefined",
|
|
164614
164921
|
prompt: "string",
|
|
164615
164922
|
"triggerer?": "string | undefined",
|
|
164616
164923
|
"baseInstructions?": "string | undefined",
|
|
@@ -164645,6 +164952,7 @@ var Inputs = type({
|
|
|
164645
164952
|
"prompt_file?": type.string.or("undefined"),
|
|
164646
164953
|
"model?": type.string.or("undefined"),
|
|
164647
164954
|
"effort?": type.string.or("undefined"),
|
|
164955
|
+
"debug?": DebugInput.or("undefined"),
|
|
164648
164956
|
"timeout?": type.string.or("undefined"),
|
|
164649
164957
|
"push?": PushPermissionInput.or("undefined"),
|
|
164650
164958
|
"shell?": ShellPermissionInput.or("undefined"),
|
|
@@ -164696,15 +165004,24 @@ function resolvePromptFile(input) {
|
|
|
164696
165004
|
}
|
|
164697
165005
|
return content;
|
|
164698
165006
|
}
|
|
165007
|
+
function warnIfDeprecatedStatusChecks(value2) {
|
|
165008
|
+
if (value2 !== void 0) {
|
|
165009
|
+
core6.warning(
|
|
165010
|
+
"`status_checks` is deprecated. Both checks are now repository settings \u2014 open the Pullfrog console for this repo (Automations \u2192 Review PRs) and set them there, then remove `status_checks` from your workflow. It keeps working until you do."
|
|
165011
|
+
);
|
|
165012
|
+
}
|
|
165013
|
+
return value2;
|
|
165014
|
+
}
|
|
164699
165015
|
function resolveNonPromptInputs() {
|
|
164700
165016
|
return Inputs.omit("prompt", "prompt_file").assert({
|
|
164701
165017
|
model: core6.getInput("model") || void 0,
|
|
164702
165018
|
effort: core6.getInput("effort") || void 0,
|
|
165019
|
+
debug: core6.getInput("debug") || void 0,
|
|
164703
165020
|
timeout: core6.getInput("timeout") || void 0,
|
|
164704
165021
|
cwd: core6.getInput("cwd") || void 0,
|
|
164705
165022
|
push: core6.getInput("push") || void 0,
|
|
164706
165023
|
shell: core6.getInput("shell") || void 0,
|
|
164707
|
-
status_checks: core6.getInput("status_checks") || void 0,
|
|
165024
|
+
status_checks: warnIfDeprecatedStatusChecks(core6.getInput("status_checks") || void 0),
|
|
164708
165025
|
progress_comments: core6.getInput("progress_comments") || void 0
|
|
164709
165026
|
});
|
|
164710
165027
|
}
|
|
@@ -164716,6 +165033,8 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
|
|
|
164716
165033
|
const model = jsonPayload?.model ?? inputs.model ?? repoSettings.model ?? void 0;
|
|
164717
165034
|
const rawEffort = jsonPayload?.effort ?? inputs.effort ?? repoSettings.effort ?? void 0;
|
|
164718
165035
|
const effort = rawEffort === void 0 ? void 0 : parseEffortPosition(String(rawEffort));
|
|
165036
|
+
const debug3 = jsonPayload?.debug ?? inputs.debug === "enabled";
|
|
165037
|
+
if (debug3) process.env.LOG_LEVEL = "debug";
|
|
164719
165038
|
const isNonCollaborator = !isCollaborator(event);
|
|
164720
165039
|
const repoShell = repoSettings.shell ?? "restricted";
|
|
164721
165040
|
const inputShell = inputs.shell;
|
|
@@ -164736,6 +165055,7 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
|
|
|
164736
165055
|
// the JSON payload). a GHA `model` input or the repo default is not explicit.
|
|
164737
165056
|
modelExplicit: jsonPayload?.modelExplicit ?? false,
|
|
164738
165057
|
effort,
|
|
165058
|
+
debug: debug3 || void 0,
|
|
164739
165059
|
prompt,
|
|
164740
165060
|
triggerer: jsonPayload?.triggerer ?? // it's not a common use case but GITHUB_ACTOR can be a user when the workflow is manually triggered by a user through GitHub Actions UI
|
|
164741
165061
|
(!isPullfrog(process.env.GITHUB_ACTOR) ? process.env.GITHUB_ACTOR : void 0),
|
|
@@ -164757,9 +165077,11 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
|
|
|
164757
165077
|
// input is the source of truth when set (mirrors `push`); otherwise the repo
|
|
164758
165078
|
// setting decides.
|
|
164759
165079
|
runStatusCheck: inputs.status_checks === void 0 ? repoSettings.statusChecks : inputs.status_checks === "enabled",
|
|
164760
|
-
// the `pullfrog-approval` verdict check
|
|
164761
|
-
//
|
|
164762
|
-
|
|
165080
|
+
// the `pullfrog-approval` verdict check. `Repo.approvalCheck` is authoritative; the
|
|
165081
|
+
// `status_checks` input is DEPRECATED but still honoured, for the dormant installs the
|
|
165082
|
+
// backfill could not read (see `warnIfDeprecatedStatusChecks`). OR rather than override:
|
|
165083
|
+
// this can only ever turn the check ON, never off, so no existing user loses it.
|
|
165084
|
+
approvalCheck: repoSettings.approvalCheck || inputs.status_checks === "enabled",
|
|
164763
165085
|
// temporary progress chrome. the workflow input is the source of truth when
|
|
164764
165086
|
// set (mirrors `push`); otherwise the repo setting decides. defaults to true.
|
|
164765
165087
|
progressComments: inputs.progress_comments === void 0 ? repoSettings.progressComments : inputs.progress_comments === "enabled",
|
|
@@ -165131,7 +165453,7 @@ async function resolveProxyModel(ctx) {
|
|
|
165131
165453
|
if (ctx.oss) {
|
|
165132
165454
|
ctx.toolState.modelClamped = { from: ctx.payload.model, reason: "oss" };
|
|
165133
165455
|
log.info(
|
|
165134
|
-
`\xBB ${ctx.payload.model} overridden \u2014 Pullfrog for OSS
|
|
165456
|
+
`\xBB ${ctx.payload.model} overridden \u2014 it is not one of the models Pullfrog for OSS funds, so this run uses ${ctx.proxyModel}; pick a funded model in your Pullfrog settings, or add a provider key to run your own.`
|
|
165135
165457
|
);
|
|
165136
165458
|
} else if (isCardGatedModel(ctx.payload.model)) {
|
|
165137
165459
|
ctx.toolState.modelClamped = { from: ctx.payload.model, reason: "card" };
|
|
@@ -165333,6 +165655,7 @@ var defaultSettings = {
|
|
|
165333
165655
|
repoIntelligence: false,
|
|
165334
165656
|
progressComments: true,
|
|
165335
165657
|
statusChecks: true,
|
|
165658
|
+
approvalCheck: false,
|
|
165336
165659
|
modeInstructions: {},
|
|
165337
165660
|
learnings: null,
|
|
165338
165661
|
learningsHeadings: [],
|
|
@@ -165560,6 +165883,40 @@ function formatBillingExhaustedBody(diagnostic) {
|
|
|
165560
165883
|
function isProviderModelNotFoundError(message) {
|
|
165561
165884
|
return message.includes("ProviderModelNotFoundError");
|
|
165562
165885
|
}
|
|
165886
|
+
function isContextOverflowError(message) {
|
|
165887
|
+
return /Prompt is too long/i.test(message) || /Input exceeds context window/i.test(message) || /maximum context length is \d+ tokens/i.test(message) || /Session too large to compact/i.test(message);
|
|
165888
|
+
}
|
|
165889
|
+
function isNoProviderAvailableError(message) {
|
|
165890
|
+
return /\bNo provider available\b/i.test(message);
|
|
165891
|
+
}
|
|
165892
|
+
function formatNoProviderAvailableSummary(input) {
|
|
165893
|
+
const settingsUrl = `${getApiUrl()}/console/${input.owner}/${input.name}`;
|
|
165894
|
+
return [
|
|
165895
|
+
"**The provider refused to serve this model.** It's listed in the catalog, but the account this run used has no access to it \u2014 so the request was accepted and then declined.",
|
|
165896
|
+
"",
|
|
165897
|
+
"This often happens when Pullfrog auto-selects a model your account can't reach. Pin an explicit model for this repo, or add credentials for the provider that was picked.",
|
|
165898
|
+
"",
|
|
165899
|
+
`[Model settings \u2192](${settingsUrl}) \xB7 [Setup docs \u2192](https://docs.pullfrog.com/keys) \xB7 [Ask in Discord \u2192](https://discord.gg/8y96raFg8e)`,
|
|
165900
|
+
"",
|
|
165901
|
+
`\`\`\`
|
|
165902
|
+
${input.raw}
|
|
165903
|
+
\`\`\``
|
|
165904
|
+
].join("\n");
|
|
165905
|
+
}
|
|
165906
|
+
function formatContextOverflowSummary(input) {
|
|
165907
|
+
const settingsUrl = `${getApiUrl()}/console/${input.owner}/${input.name}`;
|
|
165908
|
+
return [
|
|
165909
|
+
"**This run exceeded the model's context window.** Pullfrog read more than the model could hold, so it stopped before finishing.",
|
|
165910
|
+
"",
|
|
165911
|
+
`Pick a model with a larger context window, or split this PR into smaller ones and re-trigger.`,
|
|
165912
|
+
"",
|
|
165913
|
+
`[Model settings \u2192](${settingsUrl}) \xB7 [Ask in Discord \u2192](https://discord.gg/8y96raFg8e)`,
|
|
165914
|
+
"",
|
|
165915
|
+
`\`\`\`
|
|
165916
|
+
${input.raw}
|
|
165917
|
+
\`\`\``
|
|
165918
|
+
].join("\n");
|
|
165919
|
+
}
|
|
165563
165920
|
function formatGenericFailure(errorMessage) {
|
|
165564
165921
|
return [
|
|
165565
165922
|
"Pullfrog ran into an unexpected error and couldn't finish this run. The underlying error is below \u2014 re-trigger Pullfrog to try again, and reach out to support if it keeps happening.",
|
|
@@ -165581,12 +165938,18 @@ var PROVIDER_BILLING_URLS = {
|
|
|
165581
165938
|
anthropic: "https://console.anthropic.com/settings/billing",
|
|
165582
165939
|
openai: "https://platform.openai.com/account/billing",
|
|
165583
165940
|
google: "https://aistudio.google.com/usage",
|
|
165584
|
-
opencode: "https://opencode.ai/zen"
|
|
165941
|
+
opencode: "https://opencode.ai/zen",
|
|
165942
|
+
xai: "https://console.x.ai/team/default/billing",
|
|
165943
|
+
openrouter: "https://openrouter.ai/settings/credits"
|
|
165585
165944
|
};
|
|
165586
165945
|
function detectProviderId(message) {
|
|
165587
165946
|
const harnessId = extractProviderId(message);
|
|
165588
165947
|
if (harnessId) return harnessId;
|
|
165589
165948
|
if (/credit balance is too low/i.test(message)) return "anthropic";
|
|
165949
|
+
if (/used all available credits/i.test(message)) return "xai";
|
|
165950
|
+
if (/requires more credits|Key limit exceeded \(total limit\)|openrouter\.ai/i.test(message)) {
|
|
165951
|
+
return "openrouter";
|
|
165952
|
+
}
|
|
165590
165953
|
return null;
|
|
165591
165954
|
}
|
|
165592
165955
|
function formatProviderBillingExhausted(input) {
|
|
@@ -165614,7 +165977,7 @@ ${input.raw}
|
|
|
165614
165977
|
\`\`\``;
|
|
165615
165978
|
}
|
|
165616
165979
|
function renderRunError(input) {
|
|
165617
|
-
const billingError = isRouterKeylimitExhaustedError(input.errorMessage) ? new BillingError(input.errorMessage, { code: "router_keylimit_exhausted" }) : null;
|
|
165980
|
+
const billingError = input.routerActive && isRouterKeylimitExhaustedError(input.errorMessage) ? new BillingError(input.errorMessage, { code: "router_keylimit_exhausted" }) : null;
|
|
165618
165981
|
if (billingError) {
|
|
165619
165982
|
const body = formatBillingErrorSummary(billingError, input.repo.owner);
|
|
165620
165983
|
return { summary: body, comment: body };
|
|
@@ -165654,6 +166017,26 @@ ${body}`, comment: body };
|
|
|
165654
166017
|
});
|
|
165655
166018
|
return { summary: body, comment: body };
|
|
165656
166019
|
}
|
|
166020
|
+
if (isNoProviderAvailableError(input.errorMessage)) {
|
|
166021
|
+
const body = formatNoProviderAvailableSummary({
|
|
166022
|
+
owner: input.repo.owner,
|
|
166023
|
+
name: input.repo.name,
|
|
166024
|
+
raw: input.errorMessage
|
|
166025
|
+
});
|
|
166026
|
+
return { summary: `### \u274C Pullfrog failed
|
|
166027
|
+
|
|
166028
|
+
${body}`, comment: body };
|
|
166029
|
+
}
|
|
166030
|
+
if (isContextOverflowError(input.errorMessage)) {
|
|
166031
|
+
const body = formatContextOverflowSummary({
|
|
166032
|
+
owner: input.repo.owner,
|
|
166033
|
+
name: input.repo.name,
|
|
166034
|
+
raw: input.errorMessage
|
|
166035
|
+
});
|
|
166036
|
+
return { summary: `### \u274C Pullfrog failed
|
|
166037
|
+
|
|
166038
|
+
${body}`, comment: body };
|
|
166039
|
+
}
|
|
165657
166040
|
if (hangBody) {
|
|
165658
166041
|
const isBillingExhausted = input.agentDiagnostic?.lastProviderError === "provider billing exhausted";
|
|
165659
166042
|
return {
|
|
@@ -166034,7 +166417,8 @@ async function finalizeSuccessRun(input) {
|
|
|
166034
166417
|
const rendered = !input.result.success ? renderRunError({
|
|
166035
166418
|
errorMessage: input.result.error || "agent run failed",
|
|
166036
166419
|
repo: input.repo,
|
|
166037
|
-
agentDiagnostic: input.toolState.agentDiagnostic
|
|
166420
|
+
agentDiagnostic: input.toolState.agentDiagnostic,
|
|
166421
|
+
routerActive: !!input.toolContext.payload.proxyModel
|
|
166038
166422
|
}) : null;
|
|
166039
166423
|
if (rendered) {
|
|
166040
166424
|
await reportErrorToComment({
|
|
@@ -166482,7 +166866,9 @@ async function main() {
|
|
|
166482
166866
|
}
|
|
166483
166867
|
if (access.kind === "proxy") payload.proxyModel = access.target;
|
|
166484
166868
|
if (access.kind === "byok") payload.proxyModel = void 0;
|
|
166485
|
-
if (runContext.oss && payload.proxyModel)
|
|
166869
|
+
if (runContext.oss && payload.proxyModel) {
|
|
166870
|
+
payload.effort = ossEffortFloor({ payload });
|
|
166871
|
+
}
|
|
166486
166872
|
const resolvedModel = payload.proxyModel ? void 0 : resolveModel({ slug: payload.model });
|
|
166487
166873
|
vertexCredentials = materializeVertexCredentials({ model: resolvedModel });
|
|
166488
166874
|
const agent2 = resolveAgent({ model: resolvedModel });
|
|
@@ -166509,8 +166895,15 @@ async function main() {
|
|
|
166509
166895
|
});
|
|
166510
166896
|
timer.checkpoint("git");
|
|
166511
166897
|
const pmSpec = await resolvePackageManagerSpec(process.cwd());
|
|
166512
|
-
|
|
166513
|
-
|
|
166898
|
+
const pmDetected = await detect({ cwd: process.cwd(), strategies: ["lockfile"] });
|
|
166899
|
+
const pmName = pmSpec?.name ?? pmDetected?.name ?? "npm";
|
|
166900
|
+
if (payload.shell !== "disabled") {
|
|
166901
|
+
const pmError = await provisionPackageManager({
|
|
166902
|
+
name: pmName,
|
|
166903
|
+
declared: pmSpec,
|
|
166904
|
+
binDir: packageManagerBinDir(tmpdir3)
|
|
166905
|
+
});
|
|
166906
|
+
if (pmError) log.warning(`\xBB could not provision ${pmName}: ${pmError}`);
|
|
166514
166907
|
}
|
|
166515
166908
|
timer.checkpoint("packageManager");
|
|
166516
166909
|
const setupHook = await executeLifecycleHook({
|
|
@@ -166790,7 +167183,8 @@ ${instructions.user}` : null,
|
|
|
166790
167183
|
const rendered = renderRunError({
|
|
166791
167184
|
errorMessage,
|
|
166792
167185
|
repo: runContext.repo,
|
|
166793
|
-
agentDiagnostic: toolState.agentDiagnostic
|
|
167186
|
+
agentDiagnostic: toolState.agentDiagnostic,
|
|
167187
|
+
routerActive: !!payload.proxyModel
|
|
166794
167188
|
});
|
|
166795
167189
|
await writeRunErrorOutputs({ rendered, toolState });
|
|
166796
167190
|
if (toolContext) {
|