pullfrog 0.1.80 → 0.1.82
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/opencodePlugin.d.ts +5 -0
- package/dist/cli.mjs +85 -19
- package/dist/index.js +83 -17
- package/dist/internal.js +46 -16
- package/dist/utils/runErrorRenderer.d.ts +5 -0
- package/package.json +1 -1
|
@@ -81,5 +81,10 @@ export declare const PULLFROG_OPENCODE_PLUGIN_SOURCE: string;
|
|
|
81
81
|
* session via `tool.execute.before`, complementing the runtime backstops from
|
|
82
82
|
* PR #796 (action/mcp/checkout.ts, action/mcp/git.ts). Deny-list source of
|
|
83
83
|
* truth: `action/agents/subagentToolGates.ts`.
|
|
84
|
+
*
|
|
85
|
+
* Also hard-blocks the native `bash` tool for EVERY session. bash stays in the
|
|
86
|
+
* tool list because Zen's free tier rejects a request without it (2026-09-17);
|
|
87
|
+
* `permission.bash: "ask"` is the fail-closed backstop should this plugin ever
|
|
88
|
+
* not load. see wiki/security.md.
|
|
84
89
|
*/
|
|
85
90
|
export declare function buildOpencodeSubagentGateSource(deniedTools: readonly string[]): string;
|
package/dist/cli.mjs
CHANGED
|
@@ -123005,7 +123005,7 @@ var import_picocolors = __toESM(require_picocolors(), 1);
|
|
|
123005
123005
|
// package.json
|
|
123006
123006
|
var package_default = {
|
|
123007
123007
|
name: "pullfrog",
|
|
123008
|
-
version: "0.1.
|
|
123008
|
+
version: "0.1.82",
|
|
123009
123009
|
cliContractVersion: "1",
|
|
123010
123010
|
type: "module",
|
|
123011
123011
|
bin: {
|
|
@@ -125285,12 +125285,20 @@ var providers = {
|
|
|
125285
125285
|
// the same models as `moonshotai` above, billed against a Kimi membership
|
|
125286
125286
|
// instead of a Moonshot API balance — a separate endpoint, separate model
|
|
125287
125287
|
// ids and a separate key, which is why it is a provider rather than a second
|
|
125288
|
-
// `envVars` entry. no provider injection is needed: models.dev carries
|
|
125289
|
-
//
|
|
125290
|
-
// `@ai-sdk/
|
|
125288
|
+
// `envVars` entry. no provider injection is needed: models.dev carries the
|
|
125289
|
+
// provider (api `https://api.kimi.com/coding/v1`, npm
|
|
125290
|
+
// `@ai-sdk/openai-compatible`) and opencode's env loop enables it from a bare
|
|
125291
125291
|
// `KIMI_API_KEY`, verified against our pinned opencode-ai@1.18.5 — all four
|
|
125292
125292
|
// ids list in `opencode models` and a run reaches Kimi's own auth check.
|
|
125293
125293
|
//
|
|
125294
|
+
// models.dev renamed that provider on 2026-09-18: `kimi-for-coding` became
|
|
125295
|
+
// `kimi-code-plan-cn` (api.kimi.com — where the console mints the key) and
|
|
125296
|
+
// `kimi-code-plan-global` (api.kimi.ai). opencode resolves providers from
|
|
125297
|
+
// its models.dev cache, so a `resolve` still spelling the old key names a
|
|
125298
|
+
// provider it does not know. the `resolve` targets track models.dev's key;
|
|
125299
|
+
// the provider KEY below is Pullfrog's slug and stays put. see
|
|
125300
|
+
// wiki/kimi-code.md.
|
|
125301
|
+
//
|
|
125294
125302
|
// NO `openRouterResolve` ON PURPOSE. OpenRouter cannot serve a Kimi
|
|
125295
125303
|
// membership, so a Router path here would silently bill the wallet for
|
|
125296
125304
|
// Moonshot pay-as-you-go under a slug picked for the opposite reason. The
|
|
@@ -125300,9 +125308,11 @@ var providers = {
|
|
|
125300
125308
|
// keyless Router pick to the default subsidy model with `noRouterPath`.
|
|
125301
125309
|
"kimi-for-coding": provider({
|
|
125302
125310
|
// "Kimi Code" is the product name on kimi.com/code and in the console the
|
|
125303
|
-
// key is minted from.
|
|
125304
|
-
//
|
|
125305
|
-
// `
|
|
125311
|
+
// key is minted from. the provider KEY stays `kimi-for-coding`: it is the
|
|
125312
|
+
// slug prefix every stored pick, `--model` flag and BYOK card spells, and
|
|
125313
|
+
// it is not what reaches opencode — `enabled_providers` is derived from
|
|
125314
|
+
// the `resolve` prefix (`action/agents/opencode.ts`), which is why the
|
|
125315
|
+
// two may differ here and nowhere else in this file.
|
|
125306
125316
|
displayName: "Kimi Code",
|
|
125307
125317
|
envVars: ["KIMI_API_KEY"],
|
|
125308
125318
|
models: {
|
|
@@ -125313,7 +125323,7 @@ var providers = {
|
|
|
125313
125323
|
"kimi-k3": {
|
|
125314
125324
|
displayName: "Kimi K3",
|
|
125315
125325
|
description: "1M context, but only on Allegretto and above \xB7 Moderato caps it at 256K",
|
|
125316
|
-
resolve: "kimi-
|
|
125326
|
+
resolve: "kimi-code-plan-cn/k3",
|
|
125317
125327
|
effort: ["low", "high", "max"],
|
|
125318
125328
|
subagentModel: "kimi-k2"
|
|
125319
125329
|
},
|
|
@@ -125328,7 +125338,7 @@ var providers = {
|
|
|
125328
125338
|
"kimi-k3-256k": {
|
|
125329
125339
|
displayName: "Kimi K3 256K",
|
|
125330
125340
|
description: "Same model at 256K for ~half the quota \xB7 Moderato or above",
|
|
125331
|
-
resolve: "kimi-
|
|
125341
|
+
resolve: "kimi-code-plan-cn/k3-256k",
|
|
125332
125342
|
effort: ["low", "high", "max"],
|
|
125333
125343
|
preferred: true,
|
|
125334
125344
|
subagentModel: "kimi-k2"
|
|
@@ -125336,7 +125346,7 @@ var providers = {
|
|
|
125336
125346
|
"kimi-k2": {
|
|
125337
125347
|
displayName: "Kimi K2",
|
|
125338
125348
|
description: "Included in every Kimi membership tier",
|
|
125339
|
-
resolve: "kimi-
|
|
125349
|
+
resolve: "kimi-code-plan-cn/kimi-for-coding",
|
|
125340
125350
|
// models.dev published this ladder on 2026-09-14; the catalog gate
|
|
125341
125351
|
// mirrors it, so main was red until the alias carried it too.
|
|
125342
125352
|
effort: ["low", "high", "max"]
|
|
@@ -125344,7 +125354,7 @@ var providers = {
|
|
|
125344
125354
|
"kimi-k2-highspeed": {
|
|
125345
125355
|
displayName: "Kimi K2 HighSpeed",
|
|
125346
125356
|
description: "~6x output speed for ~3x quota \xB7 needs Allegretto or above",
|
|
125347
|
-
resolve: "kimi-
|
|
125357
|
+
resolve: "kimi-code-plan-cn/kimi-for-coding-highspeed"
|
|
125348
125358
|
}
|
|
125349
125359
|
}
|
|
125350
125360
|
}),
|
|
@@ -125578,17 +125588,21 @@ var providers = {
|
|
|
125578
125588
|
},
|
|
125579
125589
|
"gpt-5-nano": {
|
|
125580
125590
|
displayName: "GPT Nano",
|
|
125581
|
-
resolve: "opencode/gpt-5-nano",
|
|
125582
|
-
effort: ["
|
|
125583
|
-
openRouterResolve: "openrouter/openai/gpt-5-nano"
|
|
125591
|
+
resolve: "opencode/gpt-5.4-nano",
|
|
125592
|
+
effort: ["none", "low", "medium", "high", "xhigh"],
|
|
125593
|
+
openRouterResolve: "openrouter/openai/gpt-5.4-nano"
|
|
125584
125594
|
},
|
|
125585
125595
|
// Zen's PAID Muse Spark, priced like Meta's own Standard tier. answered
|
|
125586
125596
|
// `OK` through the harness on 2026-09-12 once the workspace was funded.
|
|
125587
125597
|
"muse-spark": {
|
|
125588
125598
|
displayName: "Muse Spark",
|
|
125589
125599
|
resolve: "opencode/muse-spark-1.3",
|
|
125590
|
-
|
|
125591
|
-
|
|
125600
|
+
// models.dev dropped `max` from Zen's ladder on 2026-09-19 while the
|
|
125601
|
+
// OpenRouter and direct `meta/` routes kept it; the catalog gate
|
|
125602
|
+
// mirrors what is published per route.
|
|
125603
|
+
effort: ["minimal", "low", "medium", "high", "xhigh"],
|
|
125604
|
+
openRouterResolve: "openrouter/meta/muse-spark-1.3",
|
|
125605
|
+
openRouterEffort: ["minimal", "low", "medium", "high", "xhigh", "max"]
|
|
125592
125606
|
},
|
|
125593
125607
|
// Zen's FREE contributor tier: the same model at $0 because Meta trains
|
|
125594
125608
|
// on the prompts and completions. Zen served it to our key on 2026-09-12
|
|
@@ -125603,6 +125617,22 @@ var providers = {
|
|
|
125603
125617
|
// see the big-pickle note above (#1077).
|
|
125604
125618
|
isFree: true
|
|
125605
125619
|
},
|
|
125620
|
+
// Zen's FREE stealth preview (listed 2026-09-16), the big-pickle shape: an
|
|
125621
|
+
// anonymous vendor's model at $0 for a limited time. OpenRouter's listing:
|
|
125622
|
+
// prompts and completions may be retained, not trained on.
|
|
125623
|
+
"union-alpha": {
|
|
125624
|
+
displayName: "Union Alpha",
|
|
125625
|
+
description: "Stealth preview; prompts may be retained",
|
|
125626
|
+
resolve: "opencode/union-alpha",
|
|
125627
|
+
// free to run, still gated on the provider's own OPENCODE_API_KEY —
|
|
125628
|
+
// see the big-pickle note above (#1077).
|
|
125629
|
+
isFree: true,
|
|
125630
|
+
// Zen dropped the id from `/v1/models` on 2026-09-18, two days after it
|
|
125631
|
+
// listed it, and answers a 500 for it. a stealth preview has no same-
|
|
125632
|
+
// family successor, so stored picks land on the other free stealth
|
|
125633
|
+
// model, as `minimax-m2.5-free` does.
|
|
125634
|
+
fallback: "opencode/big-pickle"
|
|
125635
|
+
},
|
|
125606
125636
|
// Zen's live free MiMo, and the second free row in a menu that big-pickle
|
|
125607
125637
|
// was alone in since `mimo-v2-pro-free` lost its model.
|
|
125608
125638
|
mimo: {
|
|
@@ -135867,6 +135897,11 @@ export default async function pullfrogSubagentGatePlugin() {
|
|
|
135867
135897
|
// pick a different action.
|
|
135868
135898
|
const sessionID = typeof input?.sessionID === "string" ? input.sessionID : "";
|
|
135869
135899
|
const tool = typeof input?.tool === "string" ? input.tool : "";
|
|
135900
|
+
// above the sessionID check: the bash block must never depend on a
|
|
135901
|
+
// session id being present.
|
|
135902
|
+
if (tool === "bash") {
|
|
135903
|
+
throw new Error("the native bash tool is disabled in Pullfrog runs.");
|
|
135904
|
+
}
|
|
135870
135905
|
if (!sessionID || !tool) return;
|
|
135871
135906
|
if (orchestratorSessionID === undefined) orchestratorSessionID = sessionID;
|
|
135872
135907
|
if (sessionID === orchestratorSessionID) return;
|
|
@@ -136079,7 +136114,11 @@ var installCli = () => installOpencodeCli({ binPath: "bin/opencode.exe" });
|
|
|
136079
136114
|
function buildSecurityConfig(ctx, model) {
|
|
136080
136115
|
const config4 = {
|
|
136081
136116
|
permission: {
|
|
136082
|
-
|
|
136117
|
+
// listed but never run: Zen's free tier 403s a tool list missing `bash`,
|
|
136118
|
+
// `glob`, `grep` or `read` (2026-09-17), so the gate plugin throws on
|
|
136119
|
+
// every bash call and "ask" (no responder in serve mode) fails closed.
|
|
136120
|
+
// never switch one of those four to "deny". see wiki/security.md.
|
|
136121
|
+
bash: "ask",
|
|
136083
136122
|
edit: "allow",
|
|
136084
136123
|
read: "allow",
|
|
136085
136124
|
webfetch: "allow",
|
|
@@ -218065,6 +218104,23 @@ function isContextOverflowError(message) {
|
|
|
218065
218104
|
function isNoProviderAvailableError(message) {
|
|
218066
218105
|
return /\bNo provider available\b/i.test(message);
|
|
218067
218106
|
}
|
|
218107
|
+
function isZenFreeTierGateError(message) {
|
|
218108
|
+
return /free tier can only be used from within OpenCode/i.test(message);
|
|
218109
|
+
}
|
|
218110
|
+
function formatZenFreeTierGateSummary(input2) {
|
|
218111
|
+
const settingsUrl = `${getApiUrl()}/console/${input2.owner}/${input2.name}`;
|
|
218112
|
+
return [
|
|
218113
|
+
"**Zen's free tier refused a request this run made.** OpenCode Zen currently rejects free-model requests whose tool list is missing one of the built-in tools it expects ([upstream issue](https://github.com/anomalyco/opencode/issues/49587)). Pullfrog sends all of them, but opencode's mid-run context-compaction request carries no tools at all, and a repo-level `opencode.json` that denies `bash`, `glob`, `grep` or `read` strips that tool from every request.",
|
|
218114
|
+
"",
|
|
218115
|
+
'Pick a paid model for this repo, drop any `"deny"` on `bash`, `glob`, `grep` or `read` from the repo\'s `opencode.json` if it sets one, or split the PR so the run stays under the compaction threshold and re-trigger.',
|
|
218116
|
+
"",
|
|
218117
|
+
`[Model settings \u2192](${settingsUrl}) \xB7 [Ask in Discord \u2192](https://discord.gg/8y96raFg8e)`,
|
|
218118
|
+
"",
|
|
218119
|
+
`\`\`\`
|
|
218120
|
+
${input2.raw}
|
|
218121
|
+
\`\`\``
|
|
218122
|
+
].join("\n");
|
|
218123
|
+
}
|
|
218068
218124
|
function formatNoProviderAvailableSummary(input2) {
|
|
218069
218125
|
const settingsUrl = `${getApiUrl()}/console/${input2.owner}/${input2.name}`;
|
|
218070
218126
|
return [
|
|
@@ -218308,6 +218364,16 @@ ${body}`, comment: body };
|
|
|
218308
218364
|
});
|
|
218309
218365
|
return { summary: `### \u274C Pullfrog failed
|
|
218310
218366
|
|
|
218367
|
+
${body}`, comment: body };
|
|
218368
|
+
}
|
|
218369
|
+
if (isZenFreeTierGateError(input2.errorMessage)) {
|
|
218370
|
+
const body = formatZenFreeTierGateSummary({
|
|
218371
|
+
owner: input2.repo.owner,
|
|
218372
|
+
name: input2.repo.name,
|
|
218373
|
+
raw: input2.errorMessage
|
|
218374
|
+
});
|
|
218375
|
+
return { summary: `### \u274C Pullfrog failed
|
|
218376
|
+
|
|
218311
218377
|
${body}`, comment: body };
|
|
218312
218378
|
}
|
|
218313
218379
|
if (isContextOverflowError(input2.errorMessage)) {
|
|
@@ -220161,7 +220227,7 @@ function resolveTarget2(repo) {
|
|
|
220161
220227
|
return { owner: match3[1], repo: match3[2] };
|
|
220162
220228
|
}
|
|
220163
220229
|
function cliVersion() {
|
|
220164
|
-
const parts = /^(\d+)\.(\d+)\.(\d+)$/.exec("0.1.
|
|
220230
|
+
const parts = /^(\d+)\.(\d+)\.(\d+)$/.exec("0.1.82");
|
|
220165
220231
|
if (!parts) return "0.0.0";
|
|
220166
220232
|
return `${Number(parts[1])}.${Number(parts[2])}.${Number(parts[3])}`;
|
|
220167
220233
|
}
|
|
@@ -220328,7 +220394,7 @@ async function runCli8(input2) {
|
|
|
220328
220394
|
}
|
|
220329
220395
|
|
|
220330
220396
|
// cli.ts
|
|
220331
|
-
var VERSION10 = "0.1.
|
|
220397
|
+
var VERSION10 = "0.1.82";
|
|
220332
220398
|
var bin = basename2(process.argv[1] || "");
|
|
220333
220399
|
var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
|
|
220334
220400
|
var rawArgs = process.argv.slice(2);
|
package/dist/index.js
CHANGED
|
@@ -108061,12 +108061,20 @@ var providers = {
|
|
|
108061
108061
|
// the same models as `moonshotai` above, billed against a Kimi membership
|
|
108062
108062
|
// instead of a Moonshot API balance — a separate endpoint, separate model
|
|
108063
108063
|
// ids and a separate key, which is why it is a provider rather than a second
|
|
108064
|
-
// `envVars` entry. no provider injection is needed: models.dev carries
|
|
108065
|
-
//
|
|
108066
|
-
// `@ai-sdk/
|
|
108064
|
+
// `envVars` entry. no provider injection is needed: models.dev carries the
|
|
108065
|
+
// provider (api `https://api.kimi.com/coding/v1`, npm
|
|
108066
|
+
// `@ai-sdk/openai-compatible`) and opencode's env loop enables it from a bare
|
|
108067
108067
|
// `KIMI_API_KEY`, verified against our pinned opencode-ai@1.18.5 — all four
|
|
108068
108068
|
// ids list in `opencode models` and a run reaches Kimi's own auth check.
|
|
108069
108069
|
//
|
|
108070
|
+
// models.dev renamed that provider on 2026-09-18: `kimi-for-coding` became
|
|
108071
|
+
// `kimi-code-plan-cn` (api.kimi.com — where the console mints the key) and
|
|
108072
|
+
// `kimi-code-plan-global` (api.kimi.ai). opencode resolves providers from
|
|
108073
|
+
// its models.dev cache, so a `resolve` still spelling the old key names a
|
|
108074
|
+
// provider it does not know. the `resolve` targets track models.dev's key;
|
|
108075
|
+
// the provider KEY below is Pullfrog's slug and stays put. see
|
|
108076
|
+
// wiki/kimi-code.md.
|
|
108077
|
+
//
|
|
108070
108078
|
// NO `openRouterResolve` ON PURPOSE. OpenRouter cannot serve a Kimi
|
|
108071
108079
|
// membership, so a Router path here would silently bill the wallet for
|
|
108072
108080
|
// Moonshot pay-as-you-go under a slug picked for the opposite reason. The
|
|
@@ -108076,9 +108084,11 @@ var providers = {
|
|
|
108076
108084
|
// keyless Router pick to the default subsidy model with `noRouterPath`.
|
|
108077
108085
|
"kimi-for-coding": provider({
|
|
108078
108086
|
// "Kimi Code" is the product name on kimi.com/code and in the console the
|
|
108079
|
-
// key is minted from.
|
|
108080
|
-
//
|
|
108081
|
-
// `
|
|
108087
|
+
// key is minted from. the provider KEY stays `kimi-for-coding`: it is the
|
|
108088
|
+
// slug prefix every stored pick, `--model` flag and BYOK card spells, and
|
|
108089
|
+
// it is not what reaches opencode — `enabled_providers` is derived from
|
|
108090
|
+
// the `resolve` prefix (`action/agents/opencode.ts`), which is why the
|
|
108091
|
+
// two may differ here and nowhere else in this file.
|
|
108082
108092
|
displayName: "Kimi Code",
|
|
108083
108093
|
envVars: ["KIMI_API_KEY"],
|
|
108084
108094
|
models: {
|
|
@@ -108089,7 +108099,7 @@ var providers = {
|
|
|
108089
108099
|
"kimi-k3": {
|
|
108090
108100
|
displayName: "Kimi K3",
|
|
108091
108101
|
description: "1M context, but only on Allegretto and above \xB7 Moderato caps it at 256K",
|
|
108092
|
-
resolve: "kimi-
|
|
108102
|
+
resolve: "kimi-code-plan-cn/k3",
|
|
108093
108103
|
effort: ["low", "high", "max"],
|
|
108094
108104
|
subagentModel: "kimi-k2"
|
|
108095
108105
|
},
|
|
@@ -108104,7 +108114,7 @@ var providers = {
|
|
|
108104
108114
|
"kimi-k3-256k": {
|
|
108105
108115
|
displayName: "Kimi K3 256K",
|
|
108106
108116
|
description: "Same model at 256K for ~half the quota \xB7 Moderato or above",
|
|
108107
|
-
resolve: "kimi-
|
|
108117
|
+
resolve: "kimi-code-plan-cn/k3-256k",
|
|
108108
108118
|
effort: ["low", "high", "max"],
|
|
108109
108119
|
preferred: true,
|
|
108110
108120
|
subagentModel: "kimi-k2"
|
|
@@ -108112,7 +108122,7 @@ var providers = {
|
|
|
108112
108122
|
"kimi-k2": {
|
|
108113
108123
|
displayName: "Kimi K2",
|
|
108114
108124
|
description: "Included in every Kimi membership tier",
|
|
108115
|
-
resolve: "kimi-
|
|
108125
|
+
resolve: "kimi-code-plan-cn/kimi-for-coding",
|
|
108116
108126
|
// models.dev published this ladder on 2026-09-14; the catalog gate
|
|
108117
108127
|
// mirrors it, so main was red until the alias carried it too.
|
|
108118
108128
|
effort: ["low", "high", "max"]
|
|
@@ -108120,7 +108130,7 @@ var providers = {
|
|
|
108120
108130
|
"kimi-k2-highspeed": {
|
|
108121
108131
|
displayName: "Kimi K2 HighSpeed",
|
|
108122
108132
|
description: "~6x output speed for ~3x quota \xB7 needs Allegretto or above",
|
|
108123
|
-
resolve: "kimi-
|
|
108133
|
+
resolve: "kimi-code-plan-cn/kimi-for-coding-highspeed"
|
|
108124
108134
|
}
|
|
108125
108135
|
}
|
|
108126
108136
|
}),
|
|
@@ -108354,17 +108364,21 @@ var providers = {
|
|
|
108354
108364
|
},
|
|
108355
108365
|
"gpt-5-nano": {
|
|
108356
108366
|
displayName: "GPT Nano",
|
|
108357
|
-
resolve: "opencode/gpt-5-nano",
|
|
108358
|
-
effort: ["
|
|
108359
|
-
openRouterResolve: "openrouter/openai/gpt-5-nano"
|
|
108367
|
+
resolve: "opencode/gpt-5.4-nano",
|
|
108368
|
+
effort: ["none", "low", "medium", "high", "xhigh"],
|
|
108369
|
+
openRouterResolve: "openrouter/openai/gpt-5.4-nano"
|
|
108360
108370
|
},
|
|
108361
108371
|
// Zen's PAID Muse Spark, priced like Meta's own Standard tier. answered
|
|
108362
108372
|
// `OK` through the harness on 2026-09-12 once the workspace was funded.
|
|
108363
108373
|
"muse-spark": {
|
|
108364
108374
|
displayName: "Muse Spark",
|
|
108365
108375
|
resolve: "opencode/muse-spark-1.3",
|
|
108366
|
-
|
|
108367
|
-
|
|
108376
|
+
// models.dev dropped `max` from Zen's ladder on 2026-09-19 while the
|
|
108377
|
+
// OpenRouter and direct `meta/` routes kept it; the catalog gate
|
|
108378
|
+
// mirrors what is published per route.
|
|
108379
|
+
effort: ["minimal", "low", "medium", "high", "xhigh"],
|
|
108380
|
+
openRouterResolve: "openrouter/meta/muse-spark-1.3",
|
|
108381
|
+
openRouterEffort: ["minimal", "low", "medium", "high", "xhigh", "max"]
|
|
108368
108382
|
},
|
|
108369
108383
|
// Zen's FREE contributor tier: the same model at $0 because Meta trains
|
|
108370
108384
|
// on the prompts and completions. Zen served it to our key on 2026-09-12
|
|
@@ -108379,6 +108393,22 @@ var providers = {
|
|
|
108379
108393
|
// see the big-pickle note above (#1077).
|
|
108380
108394
|
isFree: true
|
|
108381
108395
|
},
|
|
108396
|
+
// Zen's FREE stealth preview (listed 2026-09-16), the big-pickle shape: an
|
|
108397
|
+
// anonymous vendor's model at $0 for a limited time. OpenRouter's listing:
|
|
108398
|
+
// prompts and completions may be retained, not trained on.
|
|
108399
|
+
"union-alpha": {
|
|
108400
|
+
displayName: "Union Alpha",
|
|
108401
|
+
description: "Stealth preview; prompts may be retained",
|
|
108402
|
+
resolve: "opencode/union-alpha",
|
|
108403
|
+
// free to run, still gated on the provider's own OPENCODE_API_KEY —
|
|
108404
|
+
// see the big-pickle note above (#1077).
|
|
108405
|
+
isFree: true,
|
|
108406
|
+
// Zen dropped the id from `/v1/models` on 2026-09-18, two days after it
|
|
108407
|
+
// listed it, and answers a 500 for it. a stealth preview has no same-
|
|
108408
|
+
// family successor, so stored picks land on the other free stealth
|
|
108409
|
+
// model, as `minimax-m2.5-free` does.
|
|
108410
|
+
fallback: "opencode/big-pickle"
|
|
108411
|
+
},
|
|
108382
108412
|
// Zen's live free MiMo, and the second free row in a menu that big-pickle
|
|
108383
108413
|
// was alone in since `mimo-v2-pro-free` lost its model.
|
|
108384
108414
|
mimo: {
|
|
@@ -109975,7 +110005,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
109975
110005
|
// package.json
|
|
109976
110006
|
var package_default = {
|
|
109977
110007
|
name: "pullfrog",
|
|
109978
|
-
version: "0.1.
|
|
110008
|
+
version: "0.1.82",
|
|
109979
110009
|
cliContractVersion: "1",
|
|
109980
110010
|
type: "module",
|
|
109981
110011
|
bin: {
|
|
@@ -118684,6 +118714,11 @@ export default async function pullfrogSubagentGatePlugin() {
|
|
|
118684
118714
|
// pick a different action.
|
|
118685
118715
|
const sessionID = typeof input?.sessionID === "string" ? input.sessionID : "";
|
|
118686
118716
|
const tool = typeof input?.tool === "string" ? input.tool : "";
|
|
118717
|
+
// above the sessionID check: the bash block must never depend on a
|
|
118718
|
+
// session id being present.
|
|
118719
|
+
if (tool === "bash") {
|
|
118720
|
+
throw new Error("the native bash tool is disabled in Pullfrog runs.");
|
|
118721
|
+
}
|
|
118687
118722
|
if (!sessionID || !tool) return;
|
|
118688
118723
|
if (orchestratorSessionID === undefined) orchestratorSessionID = sessionID;
|
|
118689
118724
|
if (sessionID === orchestratorSessionID) return;
|
|
@@ -118896,7 +118931,11 @@ var installCli = () => installOpencodeCli({ binPath: "bin/opencode.exe" });
|
|
|
118896
118931
|
function buildSecurityConfig(ctx, model) {
|
|
118897
118932
|
const config3 = {
|
|
118898
118933
|
permission: {
|
|
118899
|
-
|
|
118934
|
+
// listed but never run: Zen's free tier 403s a tool list missing `bash`,
|
|
118935
|
+
// `glob`, `grep` or `read` (2026-09-17), so the gate plugin throws on
|
|
118936
|
+
// every bash call and "ask" (no responder in serve mode) fails closed.
|
|
118937
|
+
// never switch one of those four to "deny". see wiki/security.md.
|
|
118938
|
+
bash: "ask",
|
|
118900
118939
|
edit: "allow",
|
|
118901
118940
|
read: "allow",
|
|
118902
118941
|
webfetch: "allow",
|
|
@@ -200882,6 +200921,23 @@ function isContextOverflowError(message) {
|
|
|
200882
200921
|
function isNoProviderAvailableError(message) {
|
|
200883
200922
|
return /\bNo provider available\b/i.test(message);
|
|
200884
200923
|
}
|
|
200924
|
+
function isZenFreeTierGateError(message) {
|
|
200925
|
+
return /free tier can only be used from within OpenCode/i.test(message);
|
|
200926
|
+
}
|
|
200927
|
+
function formatZenFreeTierGateSummary(input2) {
|
|
200928
|
+
const settingsUrl = `${getApiUrl()}/console/${input2.owner}/${input2.name}`;
|
|
200929
|
+
return [
|
|
200930
|
+
"**Zen's free tier refused a request this run made.** OpenCode Zen currently rejects free-model requests whose tool list is missing one of the built-in tools it expects ([upstream issue](https://github.com/anomalyco/opencode/issues/49587)). Pullfrog sends all of them, but opencode's mid-run context-compaction request carries no tools at all, and a repo-level `opencode.json` that denies `bash`, `glob`, `grep` or `read` strips that tool from every request.",
|
|
200931
|
+
"",
|
|
200932
|
+
'Pick a paid model for this repo, drop any `"deny"` on `bash`, `glob`, `grep` or `read` from the repo\'s `opencode.json` if it sets one, or split the PR so the run stays under the compaction threshold and re-trigger.',
|
|
200933
|
+
"",
|
|
200934
|
+
`[Model settings \u2192](${settingsUrl}) \xB7 [Ask in Discord \u2192](https://discord.gg/8y96raFg8e)`,
|
|
200935
|
+
"",
|
|
200936
|
+
`\`\`\`
|
|
200937
|
+
${input2.raw}
|
|
200938
|
+
\`\`\``
|
|
200939
|
+
].join("\n");
|
|
200940
|
+
}
|
|
200885
200941
|
function formatNoProviderAvailableSummary(input2) {
|
|
200886
200942
|
const settingsUrl = `${getApiUrl()}/console/${input2.owner}/${input2.name}`;
|
|
200887
200943
|
return [
|
|
@@ -201125,6 +201181,16 @@ ${body}`, comment: body };
|
|
|
201125
201181
|
});
|
|
201126
201182
|
return { summary: `### \u274C Pullfrog failed
|
|
201127
201183
|
|
|
201184
|
+
${body}`, comment: body };
|
|
201185
|
+
}
|
|
201186
|
+
if (isZenFreeTierGateError(input2.errorMessage)) {
|
|
201187
|
+
const body = formatZenFreeTierGateSummary({
|
|
201188
|
+
owner: input2.repo.owner,
|
|
201189
|
+
name: input2.repo.name,
|
|
201190
|
+
raw: input2.errorMessage
|
|
201191
|
+
});
|
|
201192
|
+
return { summary: `### \u274C Pullfrog failed
|
|
201193
|
+
|
|
201128
201194
|
${body}`, comment: body };
|
|
201129
201195
|
}
|
|
201130
201196
|
if (isContextOverflowError(input2.errorMessage)) {
|
package/dist/internal.js
CHANGED
|
@@ -8,7 +8,7 @@ var __export = (target, all) => {
|
|
|
8
8
|
// package.json
|
|
9
9
|
var package_default = {
|
|
10
10
|
name: "pullfrog",
|
|
11
|
-
version: "0.1.
|
|
11
|
+
version: "0.1.82",
|
|
12
12
|
cliContractVersion: "1",
|
|
13
13
|
type: "module",
|
|
14
14
|
bin: {
|
|
@@ -14629,12 +14629,20 @@ var providers = {
|
|
|
14629
14629
|
// the same models as `moonshotai` above, billed against a Kimi membership
|
|
14630
14630
|
// instead of a Moonshot API balance — a separate endpoint, separate model
|
|
14631
14631
|
// ids and a separate key, which is why it is a provider rather than a second
|
|
14632
|
-
// `envVars` entry. no provider injection is needed: models.dev carries
|
|
14633
|
-
//
|
|
14634
|
-
// `@ai-sdk/
|
|
14632
|
+
// `envVars` entry. no provider injection is needed: models.dev carries the
|
|
14633
|
+
// provider (api `https://api.kimi.com/coding/v1`, npm
|
|
14634
|
+
// `@ai-sdk/openai-compatible`) and opencode's env loop enables it from a bare
|
|
14635
14635
|
// `KIMI_API_KEY`, verified against our pinned opencode-ai@1.18.5 — all four
|
|
14636
14636
|
// ids list in `opencode models` and a run reaches Kimi's own auth check.
|
|
14637
14637
|
//
|
|
14638
|
+
// models.dev renamed that provider on 2026-09-18: `kimi-for-coding` became
|
|
14639
|
+
// `kimi-code-plan-cn` (api.kimi.com — where the console mints the key) and
|
|
14640
|
+
// `kimi-code-plan-global` (api.kimi.ai). opencode resolves providers from
|
|
14641
|
+
// its models.dev cache, so a `resolve` still spelling the old key names a
|
|
14642
|
+
// provider it does not know. the `resolve` targets track models.dev's key;
|
|
14643
|
+
// the provider KEY below is Pullfrog's slug and stays put. see
|
|
14644
|
+
// wiki/kimi-code.md.
|
|
14645
|
+
//
|
|
14638
14646
|
// NO `openRouterResolve` ON PURPOSE. OpenRouter cannot serve a Kimi
|
|
14639
14647
|
// membership, so a Router path here would silently bill the wallet for
|
|
14640
14648
|
// Moonshot pay-as-you-go under a slug picked for the opposite reason. The
|
|
@@ -14644,9 +14652,11 @@ var providers = {
|
|
|
14644
14652
|
// keyless Router pick to the default subsidy model with `noRouterPath`.
|
|
14645
14653
|
"kimi-for-coding": provider({
|
|
14646
14654
|
// "Kimi Code" is the product name on kimi.com/code and in the console the
|
|
14647
|
-
// key is minted from.
|
|
14648
|
-
//
|
|
14649
|
-
// `
|
|
14655
|
+
// key is minted from. the provider KEY stays `kimi-for-coding`: it is the
|
|
14656
|
+
// slug prefix every stored pick, `--model` flag and BYOK card spells, and
|
|
14657
|
+
// it is not what reaches opencode — `enabled_providers` is derived from
|
|
14658
|
+
// the `resolve` prefix (`action/agents/opencode.ts`), which is why the
|
|
14659
|
+
// two may differ here and nowhere else in this file.
|
|
14650
14660
|
displayName: "Kimi Code",
|
|
14651
14661
|
envVars: ["KIMI_API_KEY"],
|
|
14652
14662
|
models: {
|
|
@@ -14657,7 +14667,7 @@ var providers = {
|
|
|
14657
14667
|
"kimi-k3": {
|
|
14658
14668
|
displayName: "Kimi K3",
|
|
14659
14669
|
description: "1M context, but only on Allegretto and above \xB7 Moderato caps it at 256K",
|
|
14660
|
-
resolve: "kimi-
|
|
14670
|
+
resolve: "kimi-code-plan-cn/k3",
|
|
14661
14671
|
effort: ["low", "high", "max"],
|
|
14662
14672
|
subagentModel: "kimi-k2"
|
|
14663
14673
|
},
|
|
@@ -14672,7 +14682,7 @@ var providers = {
|
|
|
14672
14682
|
"kimi-k3-256k": {
|
|
14673
14683
|
displayName: "Kimi K3 256K",
|
|
14674
14684
|
description: "Same model at 256K for ~half the quota \xB7 Moderato or above",
|
|
14675
|
-
resolve: "kimi-
|
|
14685
|
+
resolve: "kimi-code-plan-cn/k3-256k",
|
|
14676
14686
|
effort: ["low", "high", "max"],
|
|
14677
14687
|
preferred: true,
|
|
14678
14688
|
subagentModel: "kimi-k2"
|
|
@@ -14680,7 +14690,7 @@ var providers = {
|
|
|
14680
14690
|
"kimi-k2": {
|
|
14681
14691
|
displayName: "Kimi K2",
|
|
14682
14692
|
description: "Included in every Kimi membership tier",
|
|
14683
|
-
resolve: "kimi-
|
|
14693
|
+
resolve: "kimi-code-plan-cn/kimi-for-coding",
|
|
14684
14694
|
// models.dev published this ladder on 2026-09-14; the catalog gate
|
|
14685
14695
|
// mirrors it, so main was red until the alias carried it too.
|
|
14686
14696
|
effort: ["low", "high", "max"]
|
|
@@ -14688,7 +14698,7 @@ var providers = {
|
|
|
14688
14698
|
"kimi-k2-highspeed": {
|
|
14689
14699
|
displayName: "Kimi K2 HighSpeed",
|
|
14690
14700
|
description: "~6x output speed for ~3x quota \xB7 needs Allegretto or above",
|
|
14691
|
-
resolve: "kimi-
|
|
14701
|
+
resolve: "kimi-code-plan-cn/kimi-for-coding-highspeed"
|
|
14692
14702
|
}
|
|
14693
14703
|
}
|
|
14694
14704
|
}),
|
|
@@ -14922,17 +14932,21 @@ var providers = {
|
|
|
14922
14932
|
},
|
|
14923
14933
|
"gpt-5-nano": {
|
|
14924
14934
|
displayName: "GPT Nano",
|
|
14925
|
-
resolve: "opencode/gpt-5-nano",
|
|
14926
|
-
effort: ["
|
|
14927
|
-
openRouterResolve: "openrouter/openai/gpt-5-nano"
|
|
14935
|
+
resolve: "opencode/gpt-5.4-nano",
|
|
14936
|
+
effort: ["none", "low", "medium", "high", "xhigh"],
|
|
14937
|
+
openRouterResolve: "openrouter/openai/gpt-5.4-nano"
|
|
14928
14938
|
},
|
|
14929
14939
|
// Zen's PAID Muse Spark, priced like Meta's own Standard tier. answered
|
|
14930
14940
|
// `OK` through the harness on 2026-09-12 once the workspace was funded.
|
|
14931
14941
|
"muse-spark": {
|
|
14932
14942
|
displayName: "Muse Spark",
|
|
14933
14943
|
resolve: "opencode/muse-spark-1.3",
|
|
14934
|
-
|
|
14935
|
-
|
|
14944
|
+
// models.dev dropped `max` from Zen's ladder on 2026-09-19 while the
|
|
14945
|
+
// OpenRouter and direct `meta/` routes kept it; the catalog gate
|
|
14946
|
+
// mirrors what is published per route.
|
|
14947
|
+
effort: ["minimal", "low", "medium", "high", "xhigh"],
|
|
14948
|
+
openRouterResolve: "openrouter/meta/muse-spark-1.3",
|
|
14949
|
+
openRouterEffort: ["minimal", "low", "medium", "high", "xhigh", "max"]
|
|
14936
14950
|
},
|
|
14937
14951
|
// Zen's FREE contributor tier: the same model at $0 because Meta trains
|
|
14938
14952
|
// on the prompts and completions. Zen served it to our key on 2026-09-12
|
|
@@ -14947,6 +14961,22 @@ var providers = {
|
|
|
14947
14961
|
// see the big-pickle note above (#1077).
|
|
14948
14962
|
isFree: true
|
|
14949
14963
|
},
|
|
14964
|
+
// Zen's FREE stealth preview (listed 2026-09-16), the big-pickle shape: an
|
|
14965
|
+
// anonymous vendor's model at $0 for a limited time. OpenRouter's listing:
|
|
14966
|
+
// prompts and completions may be retained, not trained on.
|
|
14967
|
+
"union-alpha": {
|
|
14968
|
+
displayName: "Union Alpha",
|
|
14969
|
+
description: "Stealth preview; prompts may be retained",
|
|
14970
|
+
resolve: "opencode/union-alpha",
|
|
14971
|
+
// free to run, still gated on the provider's own OPENCODE_API_KEY —
|
|
14972
|
+
// see the big-pickle note above (#1077).
|
|
14973
|
+
isFree: true,
|
|
14974
|
+
// Zen dropped the id from `/v1/models` on 2026-09-18, two days after it
|
|
14975
|
+
// listed it, and answers a 500 for it. a stealth preview has no same-
|
|
14976
|
+
// family successor, so stored picks land on the other free stealth
|
|
14977
|
+
// model, as `minimax-m2.5-free` does.
|
|
14978
|
+
fallback: "opencode/big-pickle"
|
|
14979
|
+
},
|
|
14950
14980
|
// Zen's live free MiMo, and the second free row in a menu that big-pickle
|
|
14951
14981
|
// was alone in since `mimo-v2-pro-free` lost its model.
|
|
14952
14982
|
mimo: {
|
|
@@ -31,6 +31,11 @@
|
|
|
31
31
|
* provider declines to route it on this account's plan (OpenCode Zen's
|
|
32
32
|
* own refusal string). Same "pick another model" CTA, different reason.
|
|
33
33
|
*
|
|
34
|
+
* 4a'. Zen free-tier gate (#1377) — Zen 403s a free-tier request whose tool
|
|
35
|
+
* list is missing a built-in it expects. The harness keeps `bash` listed,
|
|
36
|
+
* but opencode's auto-compaction request carries no tools, so a long
|
|
37
|
+
* free-Zen run can still die mid-flight on the raw upstream string.
|
|
38
|
+
*
|
|
34
39
|
* 4b. Context-window overflow (#1116) — terminal `Prompt is too long` /
|
|
35
40
|
* `maximum context length is N tokens`. Actionable, so it renders on
|
|
36
41
|
* both surfaces rather than collapsing to the one-line comment.
|