pullfrog 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/shared.d.ts +2 -0
- package/dist/cli.mjs +246 -86
- package/dist/index.js +245 -85
- package/dist/internal.js +19 -0
- package/dist/models.d.ts +20 -8
- package/dist/utils/vertex.d.ts +16 -0
- package/package.json +1 -1
package/dist/agents/shared.d.ts
CHANGED
|
@@ -90,6 +90,8 @@ export interface AgentRunContext {
|
|
|
90
90
|
resolvedModel?: string | undefined;
|
|
91
91
|
mcpServerUrl: string;
|
|
92
92
|
tmpdir: string;
|
|
93
|
+
/** harness-owned secret paths that agent filesystem tools must never read. */
|
|
94
|
+
secretDenyPaths?: string[] | undefined;
|
|
93
95
|
instructions: ResolvedInstructions;
|
|
94
96
|
todoTracker?: TodoTracker | undefined;
|
|
95
97
|
/**
|
package/dist/cli.mjs
CHANGED
|
@@ -97748,14 +97748,14 @@ var require_turndown_cjs = __commonJS({
|
|
|
97748
97748
|
} else if (node2.nodeType === 1) {
|
|
97749
97749
|
replacement = replacementForNode.call(self2, node2);
|
|
97750
97750
|
}
|
|
97751
|
-
return
|
|
97751
|
+
return join21(output, replacement);
|
|
97752
97752
|
}, "");
|
|
97753
97753
|
}
|
|
97754
97754
|
function postProcess(output) {
|
|
97755
97755
|
var self2 = this;
|
|
97756
97756
|
this.rules.forEach(function(rule) {
|
|
97757
97757
|
if (typeof rule.append === "function") {
|
|
97758
|
-
output =
|
|
97758
|
+
output = join21(output, rule.append(self2.options));
|
|
97759
97759
|
}
|
|
97760
97760
|
});
|
|
97761
97761
|
return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
|
|
@@ -97767,7 +97767,7 @@ var require_turndown_cjs = __commonJS({
|
|
|
97767
97767
|
if (whitespace.leading || whitespace.trailing) content = content.trim();
|
|
97768
97768
|
return whitespace.leading + rule.replacement(content, node2, this.options) + whitespace.trailing;
|
|
97769
97769
|
}
|
|
97770
|
-
function
|
|
97770
|
+
function join21(output, replacement) {
|
|
97771
97771
|
var s1 = trimTrailingNewlines(output);
|
|
97772
97772
|
var s2 = trimLeadingNewlines(replacement);
|
|
97773
97773
|
var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
|
|
@@ -100666,7 +100666,7 @@ import { dirname as dirname6 } from "node:path";
|
|
|
100666
100666
|
// main.ts
|
|
100667
100667
|
import { existsSync as existsSync7, readdirSync } from "node:fs";
|
|
100668
100668
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
100669
|
-
import { join as
|
|
100669
|
+
import { join as join20 } from "node:path";
|
|
100670
100670
|
|
|
100671
100671
|
// node_modules/.pnpm/@ark+util@0.56.0/node_modules/@ark/util/out/arrays.js
|
|
100672
100672
|
var liftArray = (data) => Array.isArray(data) ? data : [data];
|
|
@@ -109761,6 +109761,25 @@ var providers = {
|
|
|
109761
109761
|
}
|
|
109762
109762
|
}
|
|
109763
109763
|
}),
|
|
109764
|
+
vertex: provider({
|
|
109765
|
+
displayName: "Google Vertex AI",
|
|
109766
|
+
envVars: [
|
|
109767
|
+
"VERTEX_SERVICE_ACCOUNT_JSON",
|
|
109768
|
+
"GOOGLE_CLOUD_PROJECT",
|
|
109769
|
+
"VERTEX_LOCATION",
|
|
109770
|
+
"VERTEX_MODEL_ID"
|
|
109771
|
+
],
|
|
109772
|
+
models: {
|
|
109773
|
+
// single routing entry — the actual Vertex AI model ID is read from
|
|
109774
|
+
// VERTEX_MODEL_ID at run time. see ModelRouting docs for why we don't
|
|
109775
|
+
// catalog individual Vertex models.
|
|
109776
|
+
byok: {
|
|
109777
|
+
displayName: "Google Vertex AI",
|
|
109778
|
+
resolve: "vertex",
|
|
109779
|
+
routing: "vertex"
|
|
109780
|
+
}
|
|
109781
|
+
}
|
|
109782
|
+
}),
|
|
109764
109783
|
openrouter: provider({
|
|
109765
109784
|
displayName: "OpenRouter",
|
|
109766
109785
|
envVars: ["OPENROUTER_API_KEY"],
|
|
@@ -109924,9 +109943,13 @@ function resolveCliModel(slug2) {
|
|
|
109924
109943
|
return resolveDisplayAlias(slug2)?.resolve;
|
|
109925
109944
|
}
|
|
109926
109945
|
var BEDROCK_MODEL_ID_ENV = "BEDROCK_MODEL_ID";
|
|
109946
|
+
var VERTEX_MODEL_ID_ENV = "VERTEX_MODEL_ID";
|
|
109927
109947
|
function isBedrockAnthropicId(bedrockModelId) {
|
|
109928
109948
|
return bedrockModelId.toLowerCase().split(/[./:]/).includes("anthropic");
|
|
109929
109949
|
}
|
|
109950
|
+
function isVertexAnthropicId(vertexModelId) {
|
|
109951
|
+
return /^claude-/i.test(vertexModelId.trim());
|
|
109952
|
+
}
|
|
109930
109953
|
|
|
109931
109954
|
// utils/buildPullfrogFooter.ts
|
|
109932
109955
|
var PULLFROG_DIVIDER = "<!-- PULLFROG_DIVIDER_DO_NOT_REMOVE_PLZ -->";
|
|
@@ -144209,7 +144232,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
144209
144232
|
// package.json
|
|
144210
144233
|
var package_default = {
|
|
144211
144234
|
name: "pullfrog",
|
|
144212
|
-
version: "0.1.
|
|
144235
|
+
version: "0.1.11",
|
|
144213
144236
|
type: "module",
|
|
144214
144237
|
bin: {
|
|
144215
144238
|
pullfrog: "dist/cli.mjs",
|
|
@@ -148805,8 +148828,8 @@ function initToolState(params) {
|
|
|
148805
148828
|
|
|
148806
148829
|
// agents/claude.ts
|
|
148807
148830
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
148808
|
-
import { mkdirSync as
|
|
148809
|
-
import { join as
|
|
148831
|
+
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync9 } from "node:fs";
|
|
148832
|
+
import { join as join12 } from "node:path";
|
|
148810
148833
|
import { performance as performance6 } from "node:perf_hooks";
|
|
148811
148834
|
|
|
148812
148835
|
// utils/install.ts
|
|
@@ -149107,6 +149130,70 @@ var ThinkingTimer = class {
|
|
|
149107
149130
|
}
|
|
149108
149131
|
};
|
|
149109
149132
|
|
|
149133
|
+
// utils/vertex.ts
|
|
149134
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
149135
|
+
import { mkdirSync as mkdirSync4, rmSync as rmSync2, writeFileSync as writeFileSync8 } from "node:fs";
|
|
149136
|
+
import { homedir } from "node:os";
|
|
149137
|
+
import { join as join11 } from "node:path";
|
|
149138
|
+
var VERTEX_SERVICE_ACCOUNT_JSON_ENV = "VERTEX_SERVICE_ACCOUNT_JSON";
|
|
149139
|
+
var GOOGLE_APPLICATION_CREDENTIALS_ENV = "GOOGLE_APPLICATION_CREDENTIALS";
|
|
149140
|
+
var GOOGLE_CLOUD_PROJECT_ENV = "GOOGLE_CLOUD_PROJECT";
|
|
149141
|
+
var VERTEX_LOCATION_ENV = "VERTEX_LOCATION";
|
|
149142
|
+
function hasEnvVar(name) {
|
|
149143
|
+
const value2 = process.env[name];
|
|
149144
|
+
return typeof value2 === "string" && value2.length > 0;
|
|
149145
|
+
}
|
|
149146
|
+
function isVertexRoute(model) {
|
|
149147
|
+
const vertexId = process.env[VERTEX_MODEL_ID_ENV]?.trim();
|
|
149148
|
+
return model !== void 0 && vertexId !== void 0 && vertexId === model;
|
|
149149
|
+
}
|
|
149150
|
+
function readProjectIdFromVertexServiceAccountJson() {
|
|
149151
|
+
const blob = process.env[VERTEX_SERVICE_ACCOUNT_JSON_ENV];
|
|
149152
|
+
if (!blob) return void 0;
|
|
149153
|
+
try {
|
|
149154
|
+
const parsed2 = JSON.parse(blob);
|
|
149155
|
+
if (!parsed2 || typeof parsed2 !== "object" || !("project_id" in parsed2)) {
|
|
149156
|
+
return void 0;
|
|
149157
|
+
}
|
|
149158
|
+
const projectId = parsed2.project_id;
|
|
149159
|
+
return typeof projectId === "string" && projectId.length > 0 ? projectId : void 0;
|
|
149160
|
+
} catch {
|
|
149161
|
+
return void 0;
|
|
149162
|
+
}
|
|
149163
|
+
}
|
|
149164
|
+
function createSecretDir() {
|
|
149165
|
+
const base = process.env.PULLFROG_SECRET_HOME || process.env.HOME || homedir();
|
|
149166
|
+
const secretDir = join11(base, ".pullfrog", "secrets", randomUUID3());
|
|
149167
|
+
mkdirSync4(secretDir, { recursive: true, mode: 448 });
|
|
149168
|
+
return secretDir;
|
|
149169
|
+
}
|
|
149170
|
+
function materializeVertexCredentials(params) {
|
|
149171
|
+
if (!isVertexRoute(params.model)) return void 0;
|
|
149172
|
+
const blob = process.env[VERTEX_SERVICE_ACCOUNT_JSON_ENV];
|
|
149173
|
+
if (!blob) return void 0;
|
|
149174
|
+
const secretDir = createSecretDir();
|
|
149175
|
+
const credentialsPath = join11(secretDir, "vertex-sa.json");
|
|
149176
|
+
writeFileSync8(credentialsPath, blob, { mode: 384 });
|
|
149177
|
+
process.env[GOOGLE_APPLICATION_CREDENTIALS_ENV] = credentialsPath;
|
|
149178
|
+
const projectId = readProjectIdFromVertexServiceAccountJson();
|
|
149179
|
+
if (projectId && !hasEnvVar(GOOGLE_CLOUD_PROJECT_ENV)) {
|
|
149180
|
+
process.env[GOOGLE_CLOUD_PROJECT_ENV] = projectId;
|
|
149181
|
+
}
|
|
149182
|
+
return { credentialsPath, secretDir };
|
|
149183
|
+
}
|
|
149184
|
+
function cleanupVertexCredentials(credentials) {
|
|
149185
|
+
if (!credentials) return;
|
|
149186
|
+
rmSync2(credentials.secretDir, { recursive: true, force: true });
|
|
149187
|
+
}
|
|
149188
|
+
function applyClaudeVertexEnv(env2) {
|
|
149189
|
+
env2.CLAUDE_CODE_USE_VERTEX = "1";
|
|
149190
|
+
env2.ANTHROPIC_VERTEX_PROJECT_ID ??= env2[GOOGLE_CLOUD_PROJECT_ENV];
|
|
149191
|
+
env2.CLOUD_ML_REGION ??= env2[VERTEX_LOCATION_ENV];
|
|
149192
|
+
}
|
|
149193
|
+
function resolveVertexOpenCodeModel(model) {
|
|
149194
|
+
return isVertexRoute(model) && model ? `google-vertex/${model}` : void 0;
|
|
149195
|
+
}
|
|
149196
|
+
|
|
149110
149197
|
// agents/postRun.ts
|
|
149111
149198
|
import { readFile } from "node:fs/promises";
|
|
149112
149199
|
function getUnsubmittedReview(toolState) {
|
|
@@ -149410,10 +149497,10 @@ async function installClaudeCli() {
|
|
|
149410
149497
|
});
|
|
149411
149498
|
}
|
|
149412
149499
|
function writeMcpConfig(ctx) {
|
|
149413
|
-
const configDir =
|
|
149414
|
-
|
|
149415
|
-
const configPath =
|
|
149416
|
-
|
|
149500
|
+
const configDir = join12(ctx.tmpdir, ".claude");
|
|
149501
|
+
mkdirSync5(configDir, { recursive: true });
|
|
149502
|
+
const configPath = join12(configDir, "mcp.json");
|
|
149503
|
+
writeFileSync9(
|
|
149417
149504
|
configPath,
|
|
149418
149505
|
JSON.stringify({
|
|
149419
149506
|
mcpServers: {
|
|
@@ -149795,34 +149882,48 @@ ${stderrContext}`
|
|
|
149795
149882
|
var MANAGED_SETTINGS_DIR = "/etc/claude-code";
|
|
149796
149883
|
var MANAGED_SETTINGS_PATH = `${MANAGED_SETTINGS_DIR}/managed-settings.json`;
|
|
149797
149884
|
var CODEX_AUTH_DENY_PATH = "~/.local/share/opencode/auth.json";
|
|
149798
|
-
|
|
149799
|
-
|
|
149800
|
-
|
|
149801
|
-
|
|
149802
|
-
|
|
149803
|
-
|
|
149804
|
-
|
|
149805
|
-
|
|
149806
|
-
|
|
149807
|
-
|
|
149808
|
-
|
|
149809
|
-
|
|
149810
|
-
|
|
149811
|
-
|
|
149812
|
-
|
|
149813
|
-
|
|
149814
|
-
|
|
149815
|
-
|
|
149816
|
-
|
|
149817
|
-
|
|
149818
|
-
|
|
149819
|
-
|
|
149885
|
+
function buildManagedSettings(ctx) {
|
|
149886
|
+
const secretDenyPaths = ctx.secretDenyPaths ?? [];
|
|
149887
|
+
const toolDeny = secretDenyPaths.flatMap((path3) => [
|
|
149888
|
+
`Read(${path3}/**)`,
|
|
149889
|
+
`Read(/${path3}/**)`,
|
|
149890
|
+
`Grep(${path3}/**)`,
|
|
149891
|
+
`Grep(/${path3}/**)`,
|
|
149892
|
+
`Edit(${path3}/**)`,
|
|
149893
|
+
`Edit(/${path3}/**)`,
|
|
149894
|
+
`Glob(${path3}/**)`,
|
|
149895
|
+
`Glob(/${path3}/**)`
|
|
149896
|
+
]);
|
|
149897
|
+
return {
|
|
149898
|
+
allowManagedPermissionRulesOnly: true,
|
|
149899
|
+
allowManagedHooksOnly: true,
|
|
149900
|
+
permissions: {
|
|
149901
|
+
deny: [
|
|
149902
|
+
"Read(//proc/**)",
|
|
149903
|
+
"Read(//sys/**)",
|
|
149904
|
+
"Grep(//proc/**)",
|
|
149905
|
+
"Grep(//sys/**)",
|
|
149906
|
+
"Edit(//proc/**)",
|
|
149907
|
+
"Edit(//sys/**)",
|
|
149908
|
+
"Glob(//proc/**)",
|
|
149909
|
+
"Glob(//sys/**)",
|
|
149910
|
+
`Read(${CODEX_AUTH_DENY_PATH})`,
|
|
149911
|
+
`Grep(${CODEX_AUTH_DENY_PATH})`,
|
|
149912
|
+
`Edit(${CODEX_AUTH_DENY_PATH})`,
|
|
149913
|
+
`Glob(${CODEX_AUTH_DENY_PATH})`,
|
|
149914
|
+
...toolDeny
|
|
149915
|
+
]
|
|
149916
|
+
},
|
|
149917
|
+
sandbox: {
|
|
149918
|
+
filesystem: {
|
|
149919
|
+
denyRead: ["/proc", "/sys", CODEX_AUTH_DENY_PATH, ...secretDenyPaths]
|
|
149920
|
+
}
|
|
149820
149921
|
}
|
|
149821
|
-
}
|
|
149822
|
-
}
|
|
149823
|
-
function installManagedSettings() {
|
|
149922
|
+
};
|
|
149923
|
+
}
|
|
149924
|
+
function installManagedSettings(ctx) {
|
|
149824
149925
|
if (process.env.CI !== "true") return;
|
|
149825
|
-
const content = JSON.stringify(
|
|
149926
|
+
const content = JSON.stringify(buildManagedSettings(ctx), null, 2);
|
|
149826
149927
|
try {
|
|
149827
149928
|
execFileSync4("sudo", ["mkdir", "-p", MANAGED_SETTINGS_DIR]);
|
|
149828
149929
|
execFileSync4("sudo", ["tee", MANAGED_SETTINGS_PATH], {
|
|
@@ -149842,12 +149943,14 @@ var claude = agent({
|
|
|
149842
149943
|
const specifier = ctx.payload.proxyModel ?? ctx.resolvedModel;
|
|
149843
149944
|
const bedrockModelId = process.env[BEDROCK_MODEL_ID_ENV]?.trim();
|
|
149844
149945
|
const isBedrockRoute = specifier !== void 0 && bedrockModelId !== void 0 && bedrockModelId === specifier && isBedrockAnthropicId(specifier);
|
|
149845
|
-
const
|
|
149946
|
+
const vertexModelId = process.env[VERTEX_MODEL_ID_ENV]?.trim();
|
|
149947
|
+
const isVertexRoute2 = specifier !== void 0 && vertexModelId !== void 0 && vertexModelId === specifier && isVertexAnthropicId(specifier);
|
|
149948
|
+
const model = !specifier ? void 0 : isBedrockRoute ? specifier : isVertexRoute2 ? void 0 : stripProviderPrefix(specifier);
|
|
149846
149949
|
const homeEnv = {
|
|
149847
149950
|
HOME: ctx.tmpdir,
|
|
149848
|
-
XDG_CONFIG_HOME:
|
|
149951
|
+
XDG_CONFIG_HOME: join12(ctx.tmpdir, ".config")
|
|
149849
149952
|
};
|
|
149850
|
-
|
|
149953
|
+
mkdirSync5(join12(homeEnv.XDG_CONFIG_HOME, "claude"), { recursive: true });
|
|
149851
149954
|
const agentBrowserVersion = getDevDependencyVersion("agent-browser");
|
|
149852
149955
|
addSkill({
|
|
149853
149956
|
ref: `vercel-labs/agent-browser@v${agentBrowserVersion}`,
|
|
@@ -149858,7 +149961,7 @@ var claude = agent({
|
|
|
149858
149961
|
installBundledSkills({ home: homeEnv.HOME });
|
|
149859
149962
|
const mcpConfigPath = writeMcpConfig(ctx);
|
|
149860
149963
|
const effort = resolveEffort(model);
|
|
149861
|
-
installManagedSettings();
|
|
149964
|
+
installManagedSettings(ctx);
|
|
149862
149965
|
const baseArgs = [
|
|
149863
149966
|
cliPath,
|
|
149864
149967
|
"--output-format",
|
|
@@ -149886,6 +149989,10 @@ var claude = agent({
|
|
|
149886
149989
|
if (isBedrockRoute) {
|
|
149887
149990
|
env2.CLAUDE_CODE_USE_BEDROCK = "1";
|
|
149888
149991
|
}
|
|
149992
|
+
if (isVertexRoute2) {
|
|
149993
|
+
applyClaudeVertexEnv(env2);
|
|
149994
|
+
env2.ANTHROPIC_MODEL = specifier;
|
|
149995
|
+
}
|
|
149889
149996
|
if (env2.CLAUDE_CODE_OAUTH_TOKEN && !isBedrockRoute && env2.ANTHROPIC_API_KEY) {
|
|
149890
149997
|
log.debug(
|
|
149891
149998
|
"\xBB CLAUDE_CODE_OAUTH_TOKEN present \u2014 stripping ANTHROPIC_API_KEY from Claude Code env so the OAuth subscription is used"
|
|
@@ -149927,8 +150034,8 @@ var claude = agent({
|
|
|
149927
150034
|
|
|
149928
150035
|
// agents/opencode_v2.ts
|
|
149929
150036
|
var core2 = __toESM(require_core(), 1);
|
|
149930
|
-
import { mkdirSync as
|
|
149931
|
-
import { join as
|
|
150037
|
+
import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync11 } from "node:fs";
|
|
150038
|
+
import { join as join14 } from "node:path";
|
|
149932
150039
|
import { performance as performance7 } from "node:perf_hooks";
|
|
149933
150040
|
|
|
149934
150041
|
// utils/agentHangReport.ts
|
|
@@ -150027,9 +150134,9 @@ function formatBillingExhaustedBody(diagnostic) {
|
|
|
150027
150134
|
}
|
|
150028
150135
|
|
|
150029
150136
|
// utils/codexHome.ts
|
|
150030
|
-
import { mkdirSync as
|
|
150031
|
-
import { homedir } from "node:os";
|
|
150032
|
-
import { join as
|
|
150137
|
+
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync10 } from "node:fs";
|
|
150138
|
+
import { homedir as homedir2 } from "node:os";
|
|
150139
|
+
import { join as join13 } from "node:path";
|
|
150033
150140
|
var CODEX_AUTH_ENV = "CODEX_AUTH_JSON";
|
|
150034
150141
|
function installCodexAuth() {
|
|
150035
150142
|
const raw2 = process.env[CODEX_AUTH_ENV];
|
|
@@ -150039,9 +150146,9 @@ function installCodexAuth() {
|
|
|
150039
150146
|
log.warning(`\xBB ${CODEX_AUTH_ENV} present but malformed; ignoring`);
|
|
150040
150147
|
return null;
|
|
150041
150148
|
}
|
|
150042
|
-
const xdgDataHome =
|
|
150043
|
-
const opencodeDir =
|
|
150044
|
-
const authPath =
|
|
150149
|
+
const xdgDataHome = join13(homedir2(), ".local", "share");
|
|
150150
|
+
const opencodeDir = join13(xdgDataHome, "opencode");
|
|
150151
|
+
const authPath = join13(opencodeDir, "auth.json");
|
|
150045
150152
|
const opencodeAuth = {
|
|
150046
150153
|
openai: {
|
|
150047
150154
|
type: "oauth",
|
|
@@ -150054,8 +150161,8 @@ function installCodexAuth() {
|
|
|
150054
150161
|
...blob.tokens.account_id ? { accountId: blob.tokens.account_id } : {}
|
|
150055
150162
|
}
|
|
150056
150163
|
};
|
|
150057
|
-
|
|
150058
|
-
|
|
150164
|
+
mkdirSync6(opencodeDir, { recursive: true });
|
|
150165
|
+
writeFileSync10(authPath, `${JSON.stringify(opencodeAuth, null, 2)}
|
|
150059
150166
|
`, { mode: 384 });
|
|
150060
150167
|
log.info(`\xBB installed Codex auth at ${authPath}`);
|
|
150061
150168
|
return { authPath, xdgDataHome, originalRefresh: blob.tokens.refresh_token };
|
|
@@ -150711,16 +150818,17 @@ var opencode = agent({
|
|
|
150711
150818
|
const rawModel = ctx.payload.proxyModel ?? ctx.resolvedModel ?? autoSelectModel(cliPath);
|
|
150712
150819
|
const bedrockModelId = process.env[BEDROCK_MODEL_ID_ENV]?.trim();
|
|
150713
150820
|
const isBedrockRoute = rawModel !== void 0 && bedrockModelId !== void 0 && bedrockModelId === rawModel;
|
|
150714
|
-
const
|
|
150821
|
+
const vertexModel = resolveVertexOpenCodeModel(rawModel);
|
|
150822
|
+
const model = vertexModel ?? (isBedrockRoute ? `amazon-bedrock/${rawModel}` : rawModel);
|
|
150715
150823
|
const homeEnv = {
|
|
150716
150824
|
HOME: ctx.tmpdir,
|
|
150717
|
-
XDG_CONFIG_HOME:
|
|
150825
|
+
XDG_CONFIG_HOME: join14(ctx.tmpdir, ".config")
|
|
150718
150826
|
};
|
|
150719
|
-
|
|
150720
|
-
const opencodePluginDir =
|
|
150721
|
-
|
|
150722
|
-
|
|
150723
|
-
|
|
150827
|
+
mkdirSync7(join14(homeEnv.XDG_CONFIG_HOME, "opencode"), { recursive: true });
|
|
150828
|
+
const opencodePluginDir = join14(homeEnv.XDG_CONFIG_HOME, "opencode", "plugin");
|
|
150829
|
+
mkdirSync7(opencodePluginDir, { recursive: true });
|
|
150830
|
+
writeFileSync11(
|
|
150831
|
+
join14(opencodePluginDir, PULLFROG_OPENCODE_PLUGIN_FILENAME),
|
|
150724
150832
|
PULLFROG_OPENCODE_PLUGIN_SOURCE
|
|
150725
150833
|
);
|
|
150726
150834
|
const agentBrowserVersion = getDevDependencyVersion("agent-browser");
|
|
@@ -150790,15 +150898,18 @@ var opencode = agent({
|
|
|
150790
150898
|
var agents = { claude, opencode };
|
|
150791
150899
|
|
|
150792
150900
|
// utils/agent.ts
|
|
150793
|
-
function
|
|
150901
|
+
function hasEnvVar2(name) {
|
|
150794
150902
|
const val = process.env[name];
|
|
150795
150903
|
return typeof val === "string" && val.length > 0;
|
|
150796
150904
|
}
|
|
150797
150905
|
function hasClaudeCodeAuth() {
|
|
150798
|
-
return
|
|
150906
|
+
return hasEnvVar2("CLAUDE_CODE_OAUTH_TOKEN") || hasEnvVar2("ANTHROPIC_API_KEY");
|
|
150799
150907
|
}
|
|
150800
150908
|
function hasBedrockAuth() {
|
|
150801
|
-
return
|
|
150909
|
+
return hasEnvVar2("AWS_BEARER_TOKEN_BEDROCK") || hasEnvVar2("AWS_ACCESS_KEY_ID") && hasEnvVar2("AWS_SECRET_ACCESS_KEY");
|
|
150910
|
+
}
|
|
150911
|
+
function hasVertexAuth() {
|
|
150912
|
+
return hasEnvVar2(VERTEX_SERVICE_ACCOUNT_JSON_ENV);
|
|
150802
150913
|
}
|
|
150803
150914
|
function resolveSlug(slug2) {
|
|
150804
150915
|
const alias = resolveDisplayAlias(slug2);
|
|
@@ -150806,11 +150917,20 @@ function resolveSlug(slug2) {
|
|
|
150806
150917
|
const bedrockId = process.env[BEDROCK_MODEL_ID_ENV]?.trim();
|
|
150807
150918
|
if (!bedrockId) {
|
|
150808
150919
|
throw new Error(
|
|
150809
|
-
`${BEDROCK_MODEL_ID_ENV} env var is required when the model is set to "${slug2}". set it to an AWS Bedrock model ID
|
|
150920
|
+
`${BEDROCK_MODEL_ID_ENV} env var is required when the model is set to "${slug2}". set it to an AWS Bedrock model ID from the Bedrock console. see https://docs.pullfrog.com/bedrock for setup.`
|
|
150810
150921
|
);
|
|
150811
150922
|
}
|
|
150812
150923
|
return bedrockId;
|
|
150813
150924
|
}
|
|
150925
|
+
if (alias?.routing === "vertex") {
|
|
150926
|
+
const vertexId = process.env[VERTEX_MODEL_ID_ENV]?.trim();
|
|
150927
|
+
if (!vertexId) {
|
|
150928
|
+
throw new Error(
|
|
150929
|
+
`${VERTEX_MODEL_ID_ENV} env var is required when the model is set to "${slug2}". set it to a Google Vertex AI model ID from Model Garden. see https://docs.pullfrog.com/vertex for setup.`
|
|
150930
|
+
);
|
|
150931
|
+
}
|
|
150932
|
+
return vertexId;
|
|
150933
|
+
}
|
|
150814
150934
|
return resolveCliModel(slug2);
|
|
150815
150935
|
}
|
|
150816
150936
|
function resolveModel(ctx) {
|
|
@@ -150838,6 +150958,9 @@ function resolveAgent(ctx) {
|
|
|
150838
150958
|
if (ctx.model && hasBedrockAuth() && process.env[BEDROCK_MODEL_ID_ENV]?.trim() === ctx.model) {
|
|
150839
150959
|
return isBedrockAnthropicId(ctx.model) ? agents.claude : agents.opencode;
|
|
150840
150960
|
}
|
|
150961
|
+
if (ctx.model && hasVertexAuth() && process.env[VERTEX_MODEL_ID_ENV]?.trim() === ctx.model) {
|
|
150962
|
+
return isVertexAnthropicId(ctx.model) ? agents.claude : agents.opencode;
|
|
150963
|
+
}
|
|
150841
150964
|
if (ctx.model) {
|
|
150842
150965
|
try {
|
|
150843
150966
|
const provider2 = getModelProvider(ctx.model);
|
|
@@ -150878,26 +151001,51 @@ add the missing secret(s) to your GitHub repository at ${githubSecretsUrl}, then
|
|
|
150878
151001
|
|
|
150879
151002
|
for full setup instructions, see https://docs.pullfrog.com/bedrock`;
|
|
150880
151003
|
}
|
|
150881
|
-
function
|
|
151004
|
+
function buildVertexSetupError(params) {
|
|
151005
|
+
const githubSecretsUrl = `https://github.com/${params.owner}/${params.name}/settings/secrets/actions`;
|
|
151006
|
+
return `Google Vertex AI model selected but required configuration is missing: ${params.missing.join(", ")}.
|
|
151007
|
+
|
|
151008
|
+
add the missing secret(s) to your GitHub repository at ${githubSecretsUrl}, then reference them in your workflow's \`env:\` block:
|
|
151009
|
+
|
|
151010
|
+
${VERTEX_SERVICE_ACCOUNT_JSON_ENV}: \${{ secrets.${VERTEX_SERVICE_ACCOUNT_JSON_ENV} }}
|
|
151011
|
+
${GOOGLE_CLOUD_PROJECT_ENV}: my-project
|
|
151012
|
+
${VERTEX_LOCATION_ENV}: global
|
|
151013
|
+
${VERTEX_MODEL_ID_ENV}: <vertex-model-id>
|
|
151014
|
+
|
|
151015
|
+
for full setup instructions, see https://docs.pullfrog.com/vertex`;
|
|
151016
|
+
}
|
|
151017
|
+
function hasEnvVar3(name) {
|
|
150882
151018
|
const value2 = process.env[name];
|
|
150883
151019
|
return typeof value2 === "string" && value2.length > 0;
|
|
150884
151020
|
}
|
|
150885
151021
|
function hasProviderKey(model) {
|
|
150886
151022
|
const requiredVars = getModelEnvVars(model);
|
|
150887
151023
|
if (requiredVars.length === 0) return true;
|
|
150888
|
-
return requiredVars.some((v) =>
|
|
151024
|
+
return requiredVars.some((v) => hasEnvVar3(v));
|
|
150889
151025
|
}
|
|
150890
151026
|
function validateBedrockSetup(params) {
|
|
150891
|
-
const hasAuth =
|
|
151027
|
+
const hasAuth = hasEnvVar3("AWS_BEARER_TOKEN_BEDROCK") || hasEnvVar3("AWS_ACCESS_KEY_ID") && hasEnvVar3("AWS_SECRET_ACCESS_KEY");
|
|
150892
151028
|
const missing = [];
|
|
150893
151029
|
if (!hasAuth)
|
|
150894
151030
|
missing.push("AWS_BEARER_TOKEN_BEDROCK (or AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY)");
|
|
150895
|
-
if (!
|
|
150896
|
-
if (!
|
|
151031
|
+
if (!hasEnvVar3("AWS_REGION")) missing.push("AWS_REGION");
|
|
151032
|
+
if (!hasEnvVar3(BEDROCK_MODEL_ID_ENV)) missing.push(BEDROCK_MODEL_ID_ENV);
|
|
150897
151033
|
if (missing.length > 0) {
|
|
150898
151034
|
throw new Error(buildBedrockSetupError({ owner: params.owner, name: params.name, missing }));
|
|
150899
151035
|
}
|
|
150900
151036
|
}
|
|
151037
|
+
function validateVertexSetup(params) {
|
|
151038
|
+
const hasAuth = hasEnvVar3(VERTEX_SERVICE_ACCOUNT_JSON_ENV);
|
|
151039
|
+
const hasProject = hasEnvVar3(GOOGLE_CLOUD_PROJECT_ENV) || readProjectIdFromVertexServiceAccountJson() !== void 0;
|
|
151040
|
+
const missing = [];
|
|
151041
|
+
if (!hasAuth) missing.push(VERTEX_SERVICE_ACCOUNT_JSON_ENV);
|
|
151042
|
+
if (!hasProject) missing.push(GOOGLE_CLOUD_PROJECT_ENV);
|
|
151043
|
+
if (!hasEnvVar3(VERTEX_LOCATION_ENV)) missing.push(VERTEX_LOCATION_ENV);
|
|
151044
|
+
if (!hasEnvVar3(VERTEX_MODEL_ID_ENV)) missing.push(VERTEX_MODEL_ID_ENV);
|
|
151045
|
+
if (missing.length > 0) {
|
|
151046
|
+
throw new Error(buildVertexSetupError({ owner: params.owner, name: params.name, missing }));
|
|
151047
|
+
}
|
|
151048
|
+
}
|
|
150901
151049
|
function validateAgentApiKey(params) {
|
|
150902
151050
|
if (params.model) {
|
|
150903
151051
|
const alias = resolveDisplayAlias(params.model);
|
|
@@ -150905,16 +151053,24 @@ function validateAgentApiKey(params) {
|
|
|
150905
151053
|
validateBedrockSetup({ owner: params.owner, name: params.name });
|
|
150906
151054
|
return;
|
|
150907
151055
|
}
|
|
151056
|
+
if (alias?.routing === "vertex") {
|
|
151057
|
+
validateVertexSetup({ owner: params.owner, name: params.name });
|
|
151058
|
+
return;
|
|
151059
|
+
}
|
|
150908
151060
|
if (!params.model.includes("/")) {
|
|
151061
|
+
if (process.env[VERTEX_MODEL_ID_ENV]?.trim() === params.model) {
|
|
151062
|
+
validateVertexSetup({ owner: params.owner, name: params.name });
|
|
151063
|
+
return;
|
|
151064
|
+
}
|
|
150909
151065
|
validateBedrockSetup({ owner: params.owner, name: params.name });
|
|
150910
151066
|
return;
|
|
150911
151067
|
}
|
|
150912
151068
|
const requiredVars = getModelEnvVars(params.model);
|
|
150913
151069
|
if (requiredVars.length === 0) return;
|
|
150914
|
-
if (requiredVars.some((v) =>
|
|
151070
|
+
if (requiredVars.some((v) => hasEnvVar3(v))) return;
|
|
150915
151071
|
throw new Error(buildMissingApiKeyError({ owner: params.owner, name: params.name }));
|
|
150916
151072
|
}
|
|
150917
|
-
const hasAnyKey = [...knownApiKeys].some((k) =>
|
|
151073
|
+
const hasAnyKey = [...knownApiKeys].some((k) => hasEnvVar3(k));
|
|
150918
151074
|
if (!hasAnyKey) {
|
|
150919
151075
|
throw new Error(buildMissingApiKeyError({ owner: params.owner, name: params.name }));
|
|
150920
151076
|
}
|
|
@@ -151049,10 +151205,10 @@ function selectFallbackModelIfNeeded(input) {
|
|
|
151049
151205
|
}
|
|
151050
151206
|
|
|
151051
151207
|
// utils/gitAuthServer.ts
|
|
151052
|
-
import { randomUUID as
|
|
151053
|
-
import { writeFileSync as
|
|
151208
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
151209
|
+
import { writeFileSync as writeFileSync12 } from "node:fs";
|
|
151054
151210
|
import { createServer as createServer2 } from "node:http";
|
|
151055
|
-
import { join as
|
|
151211
|
+
import { join as join15 } from "node:path";
|
|
151056
151212
|
var CODE_TTL_MS = 5 * 60 * 1e3;
|
|
151057
151213
|
var TAMPER_WINDOW_MS = 6e4;
|
|
151058
151214
|
function revokeGitHubToken(token) {
|
|
@@ -151112,7 +151268,7 @@ async function startGitAuthServer(tmpdir4) {
|
|
|
151112
151268
|
const port = rawAddr.port;
|
|
151113
151269
|
log.debug(`git auth server listening on 127.0.0.1:${port}`);
|
|
151114
151270
|
function register4(token) {
|
|
151115
|
-
const code =
|
|
151271
|
+
const code = randomUUID4();
|
|
151116
151272
|
const timeout = setTimeout(() => {
|
|
151117
151273
|
codes.delete(code);
|
|
151118
151274
|
log.debug(`git auth code expired: ${code.slice(0, 8)}...`);
|
|
@@ -151122,9 +151278,9 @@ async function startGitAuthServer(tmpdir4) {
|
|
|
151122
151278
|
return code;
|
|
151123
151279
|
}
|
|
151124
151280
|
function writeAskpassScript(code) {
|
|
151125
|
-
const scriptId =
|
|
151281
|
+
const scriptId = randomUUID4();
|
|
151126
151282
|
const scriptName = `askpass-${scriptId}.js`;
|
|
151127
|
-
const scriptPath =
|
|
151283
|
+
const scriptPath = join15(tmpdir4, scriptName);
|
|
151128
151284
|
const content = [
|
|
151129
151285
|
`#!/usr/bin/env node`,
|
|
151130
151286
|
`var a=process.argv[2]||"";`,
|
|
@@ -151139,7 +151295,7 @@ async function startGitAuthServer(tmpdir4) {
|
|
|
151139
151295
|
`try{require("fs").unlinkSync("${scriptPath.replace(/\\/g, "\\\\")}")}catch(e){}`,
|
|
151140
151296
|
`})}).on("error",function(){process.exit(1)})}`
|
|
151141
151297
|
].join("\n");
|
|
151142
|
-
|
|
151298
|
+
writeFileSync12(scriptPath, content, { mode: 448 });
|
|
151143
151299
|
return scriptPath;
|
|
151144
151300
|
}
|
|
151145
151301
|
async function close() {
|
|
@@ -151163,7 +151319,7 @@ async function startGitAuthServer(tmpdir4) {
|
|
|
151163
151319
|
var core3 = __toESM(require_core(), 1);
|
|
151164
151320
|
import { createSign } from "node:crypto";
|
|
151165
151321
|
import { rename, writeFile } from "node:fs/promises";
|
|
151166
|
-
import { dirname as dirname3, join as
|
|
151322
|
+
import { dirname as dirname3, join as join16 } from "node:path";
|
|
151167
151323
|
|
|
151168
151324
|
// node_modules/.pnpm/@octokit+plugin-throttling@11.0.3_@octokit+core@7.0.5/node_modules/@octokit/plugin-throttling/dist-bundle/index.js
|
|
151169
151325
|
var import_light = __toESM(require_light(), 1);
|
|
@@ -155021,7 +155177,7 @@ function getGitHubUsageSummary() {
|
|
|
155021
155177
|
}
|
|
155022
155178
|
async function writeGitHubUsageSummaryToFile(path3) {
|
|
155023
155179
|
const summary2 = getGitHubUsageSummary();
|
|
155024
|
-
const tmpPath =
|
|
155180
|
+
const tmpPath = join16(dirname3(path3), `.usage-summary-${process.pid}.tmp`);
|
|
155025
155181
|
await writeFile(tmpPath, JSON.stringify(summary2));
|
|
155026
155182
|
await rename(tmpPath, path3);
|
|
155027
155183
|
}
|
|
@@ -155421,7 +155577,7 @@ function resolveInstructions(ctx) {
|
|
|
155421
155577
|
|
|
155422
155578
|
// utils/learnings.ts
|
|
155423
155579
|
import { mkdir, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
155424
|
-
import { dirname as dirname4, join as
|
|
155580
|
+
import { dirname as dirname4, join as join17 } from "node:path";
|
|
155425
155581
|
|
|
155426
155582
|
// utils/learningsTruncate.ts
|
|
155427
155583
|
var MAX_LEARNINGS_LENGTH = 1e5;
|
|
@@ -155438,7 +155594,7 @@ function truncateAtLineBoundary(body, cap) {
|
|
|
155438
155594
|
// utils/learnings.ts
|
|
155439
155595
|
var LEARNINGS_FILE_NAME = "pullfrog-learnings.md";
|
|
155440
155596
|
function learningsFilePath(tmpdir4) {
|
|
155441
|
-
return
|
|
155597
|
+
return join17(tmpdir4, LEARNINGS_FILE_NAME);
|
|
155442
155598
|
}
|
|
155443
155599
|
async function seedLearningsFile(params) {
|
|
155444
155600
|
const path3 = learningsFilePath(params.tmpdir);
|
|
@@ -156118,7 +156274,7 @@ async function runProxyResolution(ctx) {
|
|
|
156118
156274
|
|
|
156119
156275
|
// utils/prSummary.ts
|
|
156120
156276
|
import { mkdir as mkdir2, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
156121
|
-
import { dirname as dirname5, join as
|
|
156277
|
+
import { dirname as dirname5, join as join18 } from "node:path";
|
|
156122
156278
|
var SUMMARY_FILE_NAME = "pullfrog-summary.md";
|
|
156123
156279
|
var SUMMARY_SCAFFOLD = `# PR summary
|
|
156124
156280
|
|
|
@@ -156128,7 +156284,7 @@ var SUMMARY_SCAFFOLD = `# PR summary
|
|
|
156128
156284
|
var MIN_SNAPSHOT_LENGTH = 60;
|
|
156129
156285
|
var MAX_SNAPSHOT_LENGTH = 32768;
|
|
156130
156286
|
function summaryFilePath(tmpdir4) {
|
|
156131
|
-
return
|
|
156287
|
+
return join18(tmpdir4, SUMMARY_FILE_NAME);
|
|
156132
156288
|
}
|
|
156133
156289
|
async function seedSummaryFile(params) {
|
|
156134
156290
|
const path3 = summaryFilePath(params.tmpdir);
|
|
@@ -156552,9 +156708,9 @@ function logRunStartup(ctx) {
|
|
|
156552
156708
|
import { execFileSync as execFileSync6, execSync as execSync3 } from "node:child_process";
|
|
156553
156709
|
import { mkdtempSync as mkdtempSync2 } from "node:fs";
|
|
156554
156710
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
156555
|
-
import { join as
|
|
156711
|
+
import { join as join19 } from "node:path";
|
|
156556
156712
|
function createTempDirectory() {
|
|
156557
|
-
const sharedTempDir = mkdtempSync2(
|
|
156713
|
+
const sharedTempDir = mkdtempSync2(join19(tmpdir3(), "pullfrog-"));
|
|
156558
156714
|
process.env.PULLFROG_TEMP_DIR = sharedTempDir;
|
|
156559
156715
|
log.info(`\xBB created temp dir at ${sharedTempDir}`);
|
|
156560
156716
|
return sharedTempDir;
|
|
@@ -156886,6 +157042,7 @@ async function main() {
|
|
|
156886
157042
|
let toolContext;
|
|
156887
157043
|
let progressCallbackDisabled = false;
|
|
156888
157044
|
let todoTracker;
|
|
157045
|
+
let vertexCredentials;
|
|
156889
157046
|
try {
|
|
156890
157047
|
var _stack = [];
|
|
156891
157048
|
try {
|
|
@@ -156920,6 +157077,7 @@ async function main() {
|
|
|
156920
157077
|
);
|
|
156921
157078
|
toolState.modelFallback = { from: fallback.from };
|
|
156922
157079
|
}
|
|
157080
|
+
vertexCredentials = materializeVertexCredentials({ model: resolvedModel });
|
|
156923
157081
|
const agent2 = resolveAgent({ model: resolvedModel });
|
|
156924
157082
|
toolState.model = payload.proxyModel ?? resolvedModel ?? effectiveSlug;
|
|
156925
157083
|
validateAgentApiKey({
|
|
@@ -157031,7 +157189,7 @@ ${instructions.user}` : null,
|
|
|
157031
157189
|
log.info(instructions.full);
|
|
157032
157190
|
});
|
|
157033
157191
|
if (agentId === "opencode") {
|
|
157034
|
-
const pluginDir =
|
|
157192
|
+
const pluginDir = join20(process.cwd(), ".opencode", "plugin");
|
|
157035
157193
|
const hasPlugins = existsSync7(pluginDir) && readdirSync(pluginDir).some((f) => /\.[jt]sx?$/.test(f));
|
|
157036
157194
|
if (hasPlugins && toolState.dependencyInstallation?.promise) {
|
|
157037
157195
|
log.info(
|
|
@@ -157087,6 +157245,7 @@ ${instructions.user}` : null,
|
|
|
157087
157245
|
resolvedModel,
|
|
157088
157246
|
mcpServerUrl: mcpHttpServer.url,
|
|
157089
157247
|
tmpdir: tmpdir4,
|
|
157248
|
+
secretDenyPaths: vertexCredentials ? [vertexCredentials.secretDir] : [],
|
|
157090
157249
|
instructions,
|
|
157091
157250
|
todoTracker,
|
|
157092
157251
|
stopScript: runContext.repoSettings.stopScript,
|
|
@@ -157190,6 +157349,7 @@ ${instructions.user}` : null,
|
|
|
157190
157349
|
await patchWorkflowRunFields(toolContext, patch);
|
|
157191
157350
|
}
|
|
157192
157351
|
}
|
|
157352
|
+
cleanupVertexCredentials(vertexCredentials);
|
|
157193
157353
|
}
|
|
157194
157354
|
} catch (_3) {
|
|
157195
157355
|
var _error2 = _3, _hasError2 = true;
|
|
@@ -158078,7 +158238,7 @@ async function run2() {
|
|
|
158078
158238
|
}
|
|
158079
158239
|
|
|
158080
158240
|
// cli.ts
|
|
158081
|
-
var VERSION10 = "0.1.
|
|
158241
|
+
var VERSION10 = "0.1.11";
|
|
158082
158242
|
var bin = basename2(process.argv[1] || "");
|
|
158083
158243
|
var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
|
|
158084
158244
|
var rawArgs = process.argv.slice(2);
|