pullfrog 0.1.23 → 0.1.25
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/claudePretoolGate.d.ts +13 -1
- package/dist/cli.mjs +56 -18
- package/dist/index.js +55 -17
- package/dist/internal.js +3 -3
- package/dist/utils/byokFallback.d.ts +6 -0
- package/dist/utils/codexHome.d.ts +3 -2
- package/package.json +1 -1
|
@@ -54,8 +54,17 @@ export declare const CLAUDE_PRETOOL_GATE_SOURCE: string;
|
|
|
54
54
|
* literal JSON string per claude-code source `src/main.tsx` (`Path to a
|
|
55
55
|
* settings JSON file or a JSON string`), but we use a path so the script
|
|
56
56
|
* and its config sit side-by-side under `ctx.tmpdir`.
|
|
57
|
+
*
|
|
58
|
+
* `execToolDenyRules` are the native exec tools (Bash/Monitor/REPL/Workflow +
|
|
59
|
+
* their `Agent(...)` forms) to deny at a settings-source rule — the
|
|
60
|
+
* authoritative, bypass-immune layer. `--disallowedTools` alone (a `cliArg`
|
|
61
|
+
* deny) was observed to leak under `--dangerously-skip-permissions`, so the
|
|
62
|
+
* deny is carried here too. Both consumers use both returned fields: the flag
|
|
63
|
+
* `--settings` JSON (covers non-CI runs) writes the whole object, and
|
|
64
|
+
* `buildManagedSettings` (CI, /etc managed settings) spreads `hooks` and folds
|
|
65
|
+
* `permissions.deny` into its richer deny list.
|
|
57
66
|
*/
|
|
58
|
-
export declare function buildClaudePretoolGateSettings(scriptAbsolutePath: string): {
|
|
67
|
+
export declare function buildClaudePretoolGateSettings(scriptAbsolutePath: string, execToolDenyRules: string[]): {
|
|
59
68
|
hooks: {
|
|
60
69
|
PreToolUse: Array<{
|
|
61
70
|
matcher: string;
|
|
@@ -66,4 +75,7 @@ export declare function buildClaudePretoolGateSettings(scriptAbsolutePath: strin
|
|
|
66
75
|
}>;
|
|
67
76
|
}>;
|
|
68
77
|
};
|
|
78
|
+
permissions: {
|
|
79
|
+
deny: string[];
|
|
80
|
+
};
|
|
69
81
|
};
|
package/dist/cli.mjs
CHANGED
|
@@ -100992,7 +100992,7 @@ var providers = {
|
|
|
100992
100992
|
openRouterResolve: "openrouter/moonshotai/kimi-k2.6"
|
|
100993
100993
|
},
|
|
100994
100994
|
"minimax-m2.5": {
|
|
100995
|
-
displayName: "MiniMax M2
|
|
100995
|
+
displayName: "MiniMax M2",
|
|
100996
100996
|
resolve: "opencode/minimax-m2.5",
|
|
100997
100997
|
openRouterResolve: "openrouter/minimax/minimax-m2.5"
|
|
100998
100998
|
},
|
|
@@ -101009,7 +101009,7 @@ var providers = {
|
|
|
101009
101009
|
fallback: "opencode/big-pickle"
|
|
101010
101010
|
},
|
|
101011
101011
|
"minimax-m2.5-free": {
|
|
101012
|
-
displayName: "MiniMax M2
|
|
101012
|
+
displayName: "MiniMax M2",
|
|
101013
101013
|
resolve: "opencode/minimax-m2.5-free",
|
|
101014
101014
|
envVars: [],
|
|
101015
101015
|
isFree: true,
|
|
@@ -101166,7 +101166,7 @@ var providers = {
|
|
|
101166
101166
|
openRouterResolve: "openrouter/moonshotai/kimi-k2.6"
|
|
101167
101167
|
},
|
|
101168
101168
|
"minimax-m2.5": {
|
|
101169
|
-
displayName: "MiniMax M2
|
|
101169
|
+
displayName: "MiniMax M2",
|
|
101170
101170
|
resolve: "openrouter/minimax/minimax-m2.5",
|
|
101171
101171
|
openRouterResolve: "openrouter/minimax/minimax-m2.5"
|
|
101172
101172
|
}
|
|
@@ -101867,7 +101867,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
101867
101867
|
// package.json
|
|
101868
101868
|
var package_default = {
|
|
101869
101869
|
name: "pullfrog",
|
|
101870
|
-
version: "0.1.
|
|
101870
|
+
version: "0.1.25",
|
|
101871
101871
|
type: "module",
|
|
101872
101872
|
bin: {
|
|
101873
101873
|
pullfrog: "dist/cli.mjs",
|
|
@@ -102520,7 +102520,7 @@ process.stdin.on("end", () => {
|
|
|
102520
102520
|
process.exit(2);
|
|
102521
102521
|
});
|
|
102522
102522
|
`;
|
|
102523
|
-
function buildClaudePretoolGateSettings(scriptAbsolutePath) {
|
|
102523
|
+
function buildClaudePretoolGateSettings(scriptAbsolutePath, execToolDenyRules) {
|
|
102524
102524
|
return {
|
|
102525
102525
|
hooks: {
|
|
102526
102526
|
PreToolUse: [
|
|
@@ -102539,7 +102539,8 @@ function buildClaudePretoolGateSettings(scriptAbsolutePath) {
|
|
|
102539
102539
|
]
|
|
102540
102540
|
}
|
|
102541
102541
|
]
|
|
102542
|
-
}
|
|
102542
|
+
},
|
|
102543
|
+
permissions: { deny: execToolDenyRules }
|
|
102543
102544
|
};
|
|
102544
102545
|
}
|
|
102545
102546
|
|
|
@@ -103565,10 +103566,11 @@ async function installClaudeCli() {
|
|
|
103565
103566
|
});
|
|
103566
103567
|
}
|
|
103567
103568
|
var CLAUDE_EXEC_TOOLS = ["Bash", "Monitor", "REPL", "Workflow"];
|
|
103568
|
-
var
|
|
103569
|
+
var CLAUDE_EXEC_TOOL_DENY_RULES = [
|
|
103569
103570
|
...CLAUDE_EXEC_TOOLS,
|
|
103570
103571
|
...CLAUDE_EXEC_TOOLS.map((t2) => `Agent(${t2})`)
|
|
103571
|
-
]
|
|
103572
|
+
];
|
|
103573
|
+
var CLAUDE_DISALLOWED_TOOLS = CLAUDE_EXEC_TOOL_DENY_RULES.join(",");
|
|
103572
103574
|
function writeMcpConfig(ctx) {
|
|
103573
103575
|
const configDir = join5(ctx.tmpdir, ".claude");
|
|
103574
103576
|
mkdirSync4(configDir, { recursive: true });
|
|
@@ -103588,7 +103590,8 @@ function writePretoolGateAssets(ctx) {
|
|
|
103588
103590
|
writeFileSync4(scriptPath, CLAUDE_PRETOOL_GATE_SOURCE);
|
|
103589
103591
|
chmodSync2(scriptPath, 493);
|
|
103590
103592
|
const settingsPath = join5(ctx.tmpdir, "pullfrog-claude-settings.json");
|
|
103591
|
-
|
|
103593
|
+
const settings = buildClaudePretoolGateSettings(scriptPath, CLAUDE_EXEC_TOOL_DENY_RULES);
|
|
103594
|
+
writeFileSync4(settingsPath, JSON.stringify(settings));
|
|
103592
103595
|
return { scriptPath, settingsPath };
|
|
103593
103596
|
}
|
|
103594
103597
|
function buildAgentsJson() {
|
|
@@ -103990,11 +103993,20 @@ function buildManagedSettings(params) {
|
|
|
103990
103993
|
`Glob(${path4}/**)`,
|
|
103991
103994
|
`Glob(/${path4}/**)`
|
|
103992
103995
|
]);
|
|
103996
|
+
const gate = buildClaudePretoolGateSettings(
|
|
103997
|
+
params.pretoolGateScriptPath,
|
|
103998
|
+
CLAUDE_EXEC_TOOL_DENY_RULES
|
|
103999
|
+
);
|
|
103993
104000
|
const base = {
|
|
103994
104001
|
allowManagedPermissionRulesOnly: true,
|
|
103995
104002
|
allowManagedHooksOnly: true,
|
|
103996
104003
|
permissions: {
|
|
103997
104004
|
deny: [
|
|
104005
|
+
// native exec tools — the authoritative, bypass-immune deny.
|
|
104006
|
+
// `--disallowedTools` (a cliArg-source deny) leaked under
|
|
104007
|
+
// `--dangerously-skip-permissions`; policySettings denies survive
|
|
104008
|
+
// bypassPermissions mode. covers top-level + Agent(...) subagent use.
|
|
104009
|
+
...gate.permissions.deny,
|
|
103998
104010
|
"Read(//proc/**)",
|
|
103999
104011
|
"Read(//sys/**)",
|
|
104000
104012
|
"Grep(//proc/**)",
|
|
@@ -104020,7 +104032,7 @@ function buildManagedSettings(params) {
|
|
|
104020
104032
|
}
|
|
104021
104033
|
};
|
|
104022
104034
|
const hooks = {
|
|
104023
|
-
...
|
|
104035
|
+
...gate.hooks
|
|
104024
104036
|
};
|
|
104025
104037
|
if (params.stopHookPath) {
|
|
104026
104038
|
hooks.Stop = [
|
|
@@ -107629,6 +107641,7 @@ function installCodexAuth() {
|
|
|
107629
107641
|
mkdirSync5(opencodeDir, { recursive: true });
|
|
107630
107642
|
writeFileSync5(authPath, `${JSON.stringify(opencodeAuth, null, 2)}
|
|
107631
107643
|
`, { mode: 384 });
|
|
107644
|
+
process.env.XDG_DATA_HOME = xdgDataHome;
|
|
107632
107645
|
log.info(`\xBB installed Codex auth at ${authPath}`);
|
|
107633
107646
|
return {
|
|
107634
107647
|
authPath,
|
|
@@ -117953,6 +117966,9 @@ var addTools = (ctx, server, tools) => {
|
|
|
117953
117966
|
};
|
|
117954
117967
|
|
|
117955
117968
|
// mcp/comment.ts
|
|
117969
|
+
function isNotFoundError(error49) {
|
|
117970
|
+
return error49 instanceof Error && error49.message.includes("Not Found");
|
|
117971
|
+
}
|
|
117956
117972
|
function buildCommentFooter(ctx, customParts) {
|
|
117957
117973
|
const runId = ctx.runId;
|
|
117958
117974
|
return buildPullfrogFooter({
|
|
@@ -118109,7 +118125,30 @@ async function reportProgress(ctx, params) {
|
|
|
118109
118125
|
const bodyWithoutFooter = stripExistingFooter(body);
|
|
118110
118126
|
const footer = buildCommentFooter(ctx, customParts);
|
|
118111
118127
|
const bodyWithFooter = `${bodyWithoutFooter}${footer}`;
|
|
118112
|
-
|
|
118128
|
+
let result;
|
|
118129
|
+
try {
|
|
118130
|
+
result = await updateProgressComment(apiCtx, existingComment, bodyWithFooter);
|
|
118131
|
+
} catch (error49) {
|
|
118132
|
+
if (params.liveProgress || existingComment.type !== "review" || !isNotFoundError(error49) || issueNumber === void 0) {
|
|
118133
|
+
throw error49;
|
|
118134
|
+
}
|
|
118135
|
+
log.warning(
|
|
118136
|
+
`progress review comment ${existingComment.id} is gone (404); posting a top-level comment on #${issueNumber} instead`
|
|
118137
|
+
);
|
|
118138
|
+
const created2 = await createLeapingProgressComment(
|
|
118139
|
+
apiCtx,
|
|
118140
|
+
{ kind: "issue", issueNumber },
|
|
118141
|
+
bodyWithFooter
|
|
118142
|
+
);
|
|
118143
|
+
ctx.toolState.progressComment = created2.comment;
|
|
118144
|
+
if (!params.liveProgress) ctx.toolState.wasUpdated = true;
|
|
118145
|
+
return {
|
|
118146
|
+
commentId: created2.comment.id,
|
|
118147
|
+
url: created2.html_url,
|
|
118148
|
+
body: created2.body || "",
|
|
118149
|
+
action: "created"
|
|
118150
|
+
};
|
|
118151
|
+
}
|
|
118113
118152
|
if (!params.liveProgress) ctx.toolState.wasUpdated = true;
|
|
118114
118153
|
if (isPlanMode && result.node_id) {
|
|
118115
118154
|
await patchWorkflowRunFields(ctx, { planCommentNodeId: result.node_id });
|
|
@@ -118212,10 +118251,7 @@ async function deleteProgressComment(ctx) {
|
|
|
118212
118251
|
existing
|
|
118213
118252
|
);
|
|
118214
118253
|
} catch (error49) {
|
|
118215
|
-
if (error49
|
|
118216
|
-
} else {
|
|
118217
|
-
throw error49;
|
|
118218
|
-
}
|
|
118254
|
+
if (!isNotFoundError(error49)) throw error49;
|
|
118219
118255
|
}
|
|
118220
118256
|
ctx.toolState.progressComment = null;
|
|
118221
118257
|
return true;
|
|
@@ -151957,7 +151993,7 @@ function classifyPushError(msg) {
|
|
|
151957
151993
|
if (TRANSIENT_PATTERNS.some((p2) => p2.test(msg))) return "transient";
|
|
151958
151994
|
return "unknown";
|
|
151959
151995
|
}
|
|
151960
|
-
var TRANSIENT_RETRY_DELAYS_MS = [2e3,
|
|
151996
|
+
var TRANSIENT_RETRY_DELAYS_MS = [2e3, 4e3, 8e3, 16e3, 3e4];
|
|
151961
151997
|
async function pushWithRetry(args2, token) {
|
|
151962
151998
|
let lastErr;
|
|
151963
151999
|
for (let attempt = 0; attempt <= TRANSIENT_RETRY_DELAYS_MS.length; attempt++) {
|
|
@@ -155835,6 +155871,7 @@ function selectFallbackModelIfNeeded(input) {
|
|
|
155835
155871
|
if (!input.resolvedModel) return { fallback: false };
|
|
155836
155872
|
if (input.resolvedModel === FREE_FALLBACK_SLUG) return { fallback: false };
|
|
155837
155873
|
if (!input.resolvedModel.includes("/")) return { fallback: false };
|
|
155874
|
+
if (input.agentName === "claude") return { fallback: false };
|
|
155838
155875
|
if (input.authorized.has(input.resolvedModel)) return { fallback: false };
|
|
155839
155876
|
return {
|
|
155840
155877
|
fallback: true,
|
|
@@ -161815,7 +161852,8 @@ async function main() {
|
|
|
161815
161852
|
const fallback = selectFallbackModelIfNeeded({
|
|
161816
161853
|
resolvedModel: initialResolvedModel,
|
|
161817
161854
|
proxyModel: payload.proxyModel,
|
|
161818
|
-
authorized: authorized2
|
|
161855
|
+
authorized: authorized2,
|
|
161856
|
+
agentName: resolveAgent({ model: initialResolvedModel }).name
|
|
161819
161857
|
});
|
|
161820
161858
|
const effectiveSlug = fallback.fallback ? fallback.to : payload.model;
|
|
161821
161859
|
const resolvedModel = fallback.fallback ? fallback.to : initialResolvedModel;
|
|
@@ -163004,7 +163042,7 @@ async function run2() {
|
|
|
163004
163042
|
}
|
|
163005
163043
|
|
|
163006
163044
|
// cli.ts
|
|
163007
|
-
var VERSION10 = "0.1.
|
|
163045
|
+
var VERSION10 = "0.1.25";
|
|
163008
163046
|
var bin = basename2(process.argv[1] || "");
|
|
163009
163047
|
var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
|
|
163010
163048
|
var rawArgs = process.argv.slice(2);
|
package/dist/index.js
CHANGED
|
@@ -99192,7 +99192,7 @@ var providers = {
|
|
|
99192
99192
|
openRouterResolve: "openrouter/moonshotai/kimi-k2.6"
|
|
99193
99193
|
},
|
|
99194
99194
|
"minimax-m2.5": {
|
|
99195
|
-
displayName: "MiniMax M2
|
|
99195
|
+
displayName: "MiniMax M2",
|
|
99196
99196
|
resolve: "opencode/minimax-m2.5",
|
|
99197
99197
|
openRouterResolve: "openrouter/minimax/minimax-m2.5"
|
|
99198
99198
|
},
|
|
@@ -99209,7 +99209,7 @@ var providers = {
|
|
|
99209
99209
|
fallback: "opencode/big-pickle"
|
|
99210
99210
|
},
|
|
99211
99211
|
"minimax-m2.5-free": {
|
|
99212
|
-
displayName: "MiniMax M2
|
|
99212
|
+
displayName: "MiniMax M2",
|
|
99213
99213
|
resolve: "opencode/minimax-m2.5-free",
|
|
99214
99214
|
envVars: [],
|
|
99215
99215
|
isFree: true,
|
|
@@ -99366,7 +99366,7 @@ var providers = {
|
|
|
99366
99366
|
openRouterResolve: "openrouter/moonshotai/kimi-k2.6"
|
|
99367
99367
|
},
|
|
99368
99368
|
"minimax-m2.5": {
|
|
99369
|
-
displayName: "MiniMax M2
|
|
99369
|
+
displayName: "MiniMax M2",
|
|
99370
99370
|
resolve: "openrouter/minimax/minimax-m2.5",
|
|
99371
99371
|
openRouterResolve: "openrouter/minimax/minimax-m2.5"
|
|
99372
99372
|
}
|
|
@@ -100067,7 +100067,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
100067
100067
|
// package.json
|
|
100068
100068
|
var package_default = {
|
|
100069
100069
|
name: "pullfrog",
|
|
100070
|
-
version: "0.1.
|
|
100070
|
+
version: "0.1.25",
|
|
100071
100071
|
type: "module",
|
|
100072
100072
|
bin: {
|
|
100073
100073
|
pullfrog: "dist/cli.mjs",
|
|
@@ -100720,7 +100720,7 @@ process.stdin.on("end", () => {
|
|
|
100720
100720
|
process.exit(2);
|
|
100721
100721
|
});
|
|
100722
100722
|
`;
|
|
100723
|
-
function buildClaudePretoolGateSettings(scriptAbsolutePath) {
|
|
100723
|
+
function buildClaudePretoolGateSettings(scriptAbsolutePath, execToolDenyRules) {
|
|
100724
100724
|
return {
|
|
100725
100725
|
hooks: {
|
|
100726
100726
|
PreToolUse: [
|
|
@@ -100739,7 +100739,8 @@ function buildClaudePretoolGateSettings(scriptAbsolutePath) {
|
|
|
100739
100739
|
]
|
|
100740
100740
|
}
|
|
100741
100741
|
]
|
|
100742
|
-
}
|
|
100742
|
+
},
|
|
100743
|
+
permissions: { deny: execToolDenyRules }
|
|
100743
100744
|
};
|
|
100744
100745
|
}
|
|
100745
100746
|
|
|
@@ -101765,10 +101766,11 @@ async function installClaudeCli() {
|
|
|
101765
101766
|
});
|
|
101766
101767
|
}
|
|
101767
101768
|
var CLAUDE_EXEC_TOOLS = ["Bash", "Monitor", "REPL", "Workflow"];
|
|
101768
|
-
var
|
|
101769
|
+
var CLAUDE_EXEC_TOOL_DENY_RULES = [
|
|
101769
101770
|
...CLAUDE_EXEC_TOOLS,
|
|
101770
101771
|
...CLAUDE_EXEC_TOOLS.map((t) => `Agent(${t})`)
|
|
101771
|
-
]
|
|
101772
|
+
];
|
|
101773
|
+
var CLAUDE_DISALLOWED_TOOLS = CLAUDE_EXEC_TOOL_DENY_RULES.join(",");
|
|
101772
101774
|
function writeMcpConfig(ctx) {
|
|
101773
101775
|
const configDir = join4(ctx.tmpdir, ".claude");
|
|
101774
101776
|
mkdirSync4(configDir, { recursive: true });
|
|
@@ -101788,7 +101790,8 @@ function writePretoolGateAssets(ctx) {
|
|
|
101788
101790
|
writeFileSync3(scriptPath, CLAUDE_PRETOOL_GATE_SOURCE);
|
|
101789
101791
|
chmodSync2(scriptPath, 493);
|
|
101790
101792
|
const settingsPath = join4(ctx.tmpdir, "pullfrog-claude-settings.json");
|
|
101791
|
-
|
|
101793
|
+
const settings = buildClaudePretoolGateSettings(scriptPath, CLAUDE_EXEC_TOOL_DENY_RULES);
|
|
101794
|
+
writeFileSync3(settingsPath, JSON.stringify(settings));
|
|
101792
101795
|
return { scriptPath, settingsPath };
|
|
101793
101796
|
}
|
|
101794
101797
|
function buildAgentsJson() {
|
|
@@ -102190,11 +102193,20 @@ function buildManagedSettings(params) {
|
|
|
102190
102193
|
`Glob(${path4}/**)`,
|
|
102191
102194
|
`Glob(/${path4}/**)`
|
|
102192
102195
|
]);
|
|
102196
|
+
const gate = buildClaudePretoolGateSettings(
|
|
102197
|
+
params.pretoolGateScriptPath,
|
|
102198
|
+
CLAUDE_EXEC_TOOL_DENY_RULES
|
|
102199
|
+
);
|
|
102193
102200
|
const base = {
|
|
102194
102201
|
allowManagedPermissionRulesOnly: true,
|
|
102195
102202
|
allowManagedHooksOnly: true,
|
|
102196
102203
|
permissions: {
|
|
102197
102204
|
deny: [
|
|
102205
|
+
// native exec tools — the authoritative, bypass-immune deny.
|
|
102206
|
+
// `--disallowedTools` (a cliArg-source deny) leaked under
|
|
102207
|
+
// `--dangerously-skip-permissions`; policySettings denies survive
|
|
102208
|
+
// bypassPermissions mode. covers top-level + Agent(...) subagent use.
|
|
102209
|
+
...gate.permissions.deny,
|
|
102198
102210
|
"Read(//proc/**)",
|
|
102199
102211
|
"Read(//sys/**)",
|
|
102200
102212
|
"Grep(//proc/**)",
|
|
@@ -102220,7 +102232,7 @@ function buildManagedSettings(params) {
|
|
|
102220
102232
|
}
|
|
102221
102233
|
};
|
|
102222
102234
|
const hooks = {
|
|
102223
|
-
...
|
|
102235
|
+
...gate.hooks
|
|
102224
102236
|
};
|
|
102225
102237
|
if (params.stopHookPath) {
|
|
102226
102238
|
hooks.Stop = [
|
|
@@ -105871,6 +105883,7 @@ function installCodexAuth() {
|
|
|
105871
105883
|
mkdirSync5(opencodeDir, { recursive: true });
|
|
105872
105884
|
writeFileSync4(authPath, `${JSON.stringify(opencodeAuth, null, 2)}
|
|
105873
105885
|
`, { mode: 384 });
|
|
105886
|
+
process.env.XDG_DATA_HOME = xdgDataHome;
|
|
105874
105887
|
log.info(`\xBB installed Codex auth at ${authPath}`);
|
|
105875
105888
|
return {
|
|
105876
105889
|
authPath,
|
|
@@ -116195,6 +116208,9 @@ var addTools = (ctx, server, tools) => {
|
|
|
116195
116208
|
};
|
|
116196
116209
|
|
|
116197
116210
|
// mcp/comment.ts
|
|
116211
|
+
function isNotFoundError(error49) {
|
|
116212
|
+
return error49 instanceof Error && error49.message.includes("Not Found");
|
|
116213
|
+
}
|
|
116198
116214
|
function buildCommentFooter(ctx, customParts) {
|
|
116199
116215
|
const runId = ctx.runId;
|
|
116200
116216
|
return buildPullfrogFooter({
|
|
@@ -116351,7 +116367,30 @@ async function reportProgress(ctx, params) {
|
|
|
116351
116367
|
const bodyWithoutFooter = stripExistingFooter(body);
|
|
116352
116368
|
const footer = buildCommentFooter(ctx, customParts);
|
|
116353
116369
|
const bodyWithFooter = `${bodyWithoutFooter}${footer}`;
|
|
116354
|
-
|
|
116370
|
+
let result;
|
|
116371
|
+
try {
|
|
116372
|
+
result = await updateProgressComment(apiCtx, existingComment, bodyWithFooter);
|
|
116373
|
+
} catch (error49) {
|
|
116374
|
+
if (params.liveProgress || existingComment.type !== "review" || !isNotFoundError(error49) || issueNumber === void 0) {
|
|
116375
|
+
throw error49;
|
|
116376
|
+
}
|
|
116377
|
+
log.warning(
|
|
116378
|
+
`progress review comment ${existingComment.id} is gone (404); posting a top-level comment on #${issueNumber} instead`
|
|
116379
|
+
);
|
|
116380
|
+
const created2 = await createLeapingProgressComment(
|
|
116381
|
+
apiCtx,
|
|
116382
|
+
{ kind: "issue", issueNumber },
|
|
116383
|
+
bodyWithFooter
|
|
116384
|
+
);
|
|
116385
|
+
ctx.toolState.progressComment = created2.comment;
|
|
116386
|
+
if (!params.liveProgress) ctx.toolState.wasUpdated = true;
|
|
116387
|
+
return {
|
|
116388
|
+
commentId: created2.comment.id,
|
|
116389
|
+
url: created2.html_url,
|
|
116390
|
+
body: created2.body || "",
|
|
116391
|
+
action: "created"
|
|
116392
|
+
};
|
|
116393
|
+
}
|
|
116355
116394
|
if (!params.liveProgress) ctx.toolState.wasUpdated = true;
|
|
116356
116395
|
if (isPlanMode && result.node_id) {
|
|
116357
116396
|
await patchWorkflowRunFields(ctx, { planCommentNodeId: result.node_id });
|
|
@@ -116454,10 +116493,7 @@ async function deleteProgressComment(ctx) {
|
|
|
116454
116493
|
existing
|
|
116455
116494
|
);
|
|
116456
116495
|
} catch (error49) {
|
|
116457
|
-
if (error49
|
|
116458
|
-
} else {
|
|
116459
|
-
throw error49;
|
|
116460
|
-
}
|
|
116496
|
+
if (!isNotFoundError(error49)) throw error49;
|
|
116461
116497
|
}
|
|
116462
116498
|
ctx.toolState.progressComment = null;
|
|
116463
116499
|
return true;
|
|
@@ -150199,7 +150235,7 @@ function classifyPushError(msg) {
|
|
|
150199
150235
|
if (TRANSIENT_PATTERNS.some((p) => p.test(msg))) return "transient";
|
|
150200
150236
|
return "unknown";
|
|
150201
150237
|
}
|
|
150202
|
-
var TRANSIENT_RETRY_DELAYS_MS = [2e3,
|
|
150238
|
+
var TRANSIENT_RETRY_DELAYS_MS = [2e3, 4e3, 8e3, 16e3, 3e4];
|
|
150203
150239
|
async function pushWithRetry(args2, token) {
|
|
150204
150240
|
let lastErr;
|
|
150205
150241
|
for (let attempt = 0; attempt <= TRANSIENT_RETRY_DELAYS_MS.length; attempt++) {
|
|
@@ -154077,6 +154113,7 @@ function selectFallbackModelIfNeeded(input) {
|
|
|
154077
154113
|
if (!input.resolvedModel) return { fallback: false };
|
|
154078
154114
|
if (input.resolvedModel === FREE_FALLBACK_SLUG) return { fallback: false };
|
|
154079
154115
|
if (!input.resolvedModel.includes("/")) return { fallback: false };
|
|
154116
|
+
if (input.agentName === "claude") return { fallback: false };
|
|
154080
154117
|
if (input.authorized.has(input.resolvedModel)) return { fallback: false };
|
|
154081
154118
|
return {
|
|
154082
154119
|
fallback: true,
|
|
@@ -160057,7 +160094,8 @@ async function main() {
|
|
|
160057
160094
|
const fallback = selectFallbackModelIfNeeded({
|
|
160058
160095
|
resolvedModel: initialResolvedModel,
|
|
160059
160096
|
proxyModel: payload.proxyModel,
|
|
160060
|
-
authorized: authorized2
|
|
160097
|
+
authorized: authorized2,
|
|
160098
|
+
agentName: resolveAgent({ model: initialResolvedModel }).name
|
|
160061
160099
|
});
|
|
160062
160100
|
const effectiveSlug = fallback.fallback ? fallback.to : payload.model;
|
|
160063
160101
|
const resolvedModel = fallback.fallback ? fallback.to : initialResolvedModel;
|
package/dist/internal.js
CHANGED
|
@@ -258,7 +258,7 @@ var providers = {
|
|
|
258
258
|
openRouterResolve: "openrouter/moonshotai/kimi-k2.6"
|
|
259
259
|
},
|
|
260
260
|
"minimax-m2.5": {
|
|
261
|
-
displayName: "MiniMax M2
|
|
261
|
+
displayName: "MiniMax M2",
|
|
262
262
|
resolve: "opencode/minimax-m2.5",
|
|
263
263
|
openRouterResolve: "openrouter/minimax/minimax-m2.5"
|
|
264
264
|
},
|
|
@@ -275,7 +275,7 @@ var providers = {
|
|
|
275
275
|
fallback: "opencode/big-pickle"
|
|
276
276
|
},
|
|
277
277
|
"minimax-m2.5-free": {
|
|
278
|
-
displayName: "MiniMax M2
|
|
278
|
+
displayName: "MiniMax M2",
|
|
279
279
|
resolve: "opencode/minimax-m2.5-free",
|
|
280
280
|
envVars: [],
|
|
281
281
|
isFree: true,
|
|
@@ -432,7 +432,7 @@ var providers = {
|
|
|
432
432
|
openRouterResolve: "openrouter/moonshotai/kimi-k2.6"
|
|
433
433
|
},
|
|
434
434
|
"minimax-m2.5": {
|
|
435
|
-
displayName: "MiniMax M2
|
|
435
|
+
displayName: "MiniMax M2",
|
|
436
436
|
resolve: "openrouter/minimax/minimax-m2.5",
|
|
437
437
|
openRouterResolve: "openrouter/minimax/minimax-m2.5"
|
|
438
438
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AgentId } from "../external.ts";
|
|
1
2
|
/**
|
|
2
3
|
* Slug we fall back to when a BYOK-required model is configured but the
|
|
3
4
|
* runner has no provider key in env. Picked because it's free, stable, and
|
|
@@ -30,9 +31,14 @@ export type FallbackDecision = {
|
|
|
30
31
|
* - Resolved model is a raw Bedrock / Vertex ID (no `/`): the routing
|
|
31
32
|
* validators (`validateBedrockSetup` / `validateVertexSetup`) cover
|
|
32
33
|
* auth + region/location/model-id; `opencode models` does not.
|
|
34
|
+
* - The selected agent is `claude`: the Claude Code harness brings its own
|
|
35
|
+
* auth and `resolveAgent` only returns it when that auth is present.
|
|
36
|
+
* `opencode models` can't see `CLAUDE_CODE_OAUTH_TOKEN`, so without this
|
|
37
|
+
* an OAuth-subscription run on an Anthropic model would wrongly fall back.
|
|
33
38
|
*/
|
|
34
39
|
export declare function selectFallbackModelIfNeeded(input: {
|
|
35
40
|
resolvedModel: string | undefined;
|
|
36
41
|
proxyModel: string | undefined;
|
|
37
42
|
authorized: Set<string>;
|
|
43
|
+
agentName: AgentId;
|
|
38
44
|
}): FallbackDecision;
|
|
@@ -23,6 +23,7 @@ export interface InstalledCodexAuth {
|
|
|
23
23
|
* caller treats null as "no codex auth, fall through to API key flow".
|
|
24
24
|
*
|
|
25
25
|
* The env value is server-side guaranteed fresh by `maybeRotateCodexSecret`
|
|
26
|
-
* in the run-context endpoint. We
|
|
27
|
-
*
|
|
26
|
+
* in the run-context endpoint. We parse + write it here and set
|
|
27
|
+
* `process.env.XDG_DATA_HOME` so every opencode subprocess discovers the
|
|
28
|
+
* auth.json; no refresh, no DB interaction. */
|
|
28
29
|
export declare function installCodexAuth(): InstalledCodexAuth | null;
|