pullfrog 0.1.81 → 0.1.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -19991,10 +19991,10 @@ var require_core = __commonJS({
19991
19991
  (0, command_1.issueCommand)("set-env", { name }, convertedVal);
19992
19992
  }
19993
19993
  exports.exportVariable = exportVariable;
19994
- function setSecret7(secret) {
19994
+ function setSecret2(secret) {
19995
19995
  (0, command_1.issueCommand)("add-mask", {}, secret);
19996
19996
  }
19997
- exports.setSecret = setSecret7;
19997
+ exports.setSecret = setSecret2;
19998
19998
  function addPath(inputPath) {
19999
19999
  const filePath = process.env["GITHUB_PATH"] || "";
20000
20000
  if (filePath) {
@@ -20099,14 +20099,14 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``);
20099
20099
  });
20100
20100
  }
20101
20101
  exports.group = group2;
20102
- function saveState4(name, value2) {
20102
+ function saveState2(name, value2) {
20103
20103
  const filePath = process.env["GITHUB_STATE"] || "";
20104
20104
  if (filePath) {
20105
20105
  return (0, file_command_1.issueFileCommand)("STATE", (0, file_command_1.prepareKeyValueMessage)(name, value2));
20106
20106
  }
20107
20107
  (0, command_1.issueCommand)("save-state", { name }, (0, utils_1.toCommandValue)(value2));
20108
20108
  }
20109
- exports.saveState = saveState4;
20109
+ exports.saveState = saveState2;
20110
20110
  function getState3(name) {
20111
20111
  return process.env[`STATE_${name}`] || "";
20112
20112
  }
@@ -27894,11 +27894,11 @@ var require_mode = __commonJS({
27894
27894
  var require_isexe = __commonJS({
27895
27895
  "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module) {
27896
27896
  var fs5 = __require("fs");
27897
- var core13;
27897
+ var core9;
27898
27898
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
27899
- core13 = require_windows();
27899
+ core9 = require_windows();
27900
27900
  } else {
27901
- core13 = require_mode();
27901
+ core9 = require_mode();
27902
27902
  }
27903
27903
  module.exports = isexe;
27904
27904
  isexe.sync = sync;
@@ -27921,7 +27921,7 @@ var require_isexe = __commonJS({
27921
27921
  });
27922
27922
  });
27923
27923
  }
27924
- core13(path4, options || {}, function(er, is) {
27924
+ core9(path4, options || {}, function(er, is) {
27925
27925
  if (er) {
27926
27926
  if (er.code === "EACCES" || options && options.ignoreErrors) {
27927
27927
  er = null;
@@ -27933,7 +27933,7 @@ var require_isexe = __commonJS({
27933
27933
  }
27934
27934
  function sync(path4, options) {
27935
27935
  try {
27936
- return core13.sync(path4, options || {});
27936
+ return core9.sync(path4, options || {});
27937
27937
  } catch (er) {
27938
27938
  if (options && options.ignoreErrors || er.code === "EACCES") {
27939
27939
  return false;
@@ -81073,7 +81073,7 @@ var require_core3 = __commonJS({
81073
81073
  Object.defineProperty(exports, "__esModule", { value: true });
81074
81074
  var id_1 = require_id();
81075
81075
  var ref_1 = require_ref();
81076
- var core13 = [
81076
+ var core9 = [
81077
81077
  "$schema",
81078
81078
  "$id",
81079
81079
  "$defs",
@@ -81083,7 +81083,7 @@ var require_core3 = __commonJS({
81083
81083
  id_1.default,
81084
81084
  ref_1.default
81085
81085
  ];
81086
- exports.default = core13;
81086
+ exports.default = core9;
81087
81087
  }
81088
81088
  });
81089
81089
 
@@ -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.81",
123008
+ version: "0.1.83",
123009
123009
  cliContractVersion: "1",
123010
123010
  type: "module",
123011
123011
  bin: {
@@ -123022,6 +123022,7 @@ var package_default = {
123022
123022
  typecheck: "tsc --noEmit",
123023
123023
  build: "node esbuild.config.js && tsc -p tsconfig.exports.json",
123024
123024
  "check:entrypoints": "nub scripts/check-entrypoint-imports.ts",
123025
+ "check:secret-commands": "nub scripts/check-secret-commands.ts",
123025
123026
  docker: "nub docker.ts",
123026
123027
  play: "nub play.ts",
123027
123028
  runtest: "nub test/run.ts",
@@ -123032,7 +123033,7 @@ var package_default = {
123032
123033
  },
123033
123034
  devDependencies: {
123034
123035
  "@actions/core": "^1.11.1",
123035
- "@anthropic-ai/claude-code": "2.1.150",
123036
+ "@anthropic-ai/claude-code": "2.1.280",
123036
123037
  "@ark/fs": "0.56.0",
123037
123038
  "@ark/util": "0.56.0",
123038
123039
  "@clack/prompts": "^1.2.0",
@@ -124579,7 +124580,7 @@ without a terminal, only print its URL.`
124579
124580
  }
124580
124581
 
124581
124582
  // commands/gha.ts
124582
- var core12 = __toESM(require_core(), 1);
124583
+ var core8 = __toESM(require_core(), 1);
124583
124584
  var import_arg5 = __toESM(require_arg(), 1);
124584
124585
  import { dirname as dirname6 } from "node:path";
124585
124586
 
@@ -124995,19 +124996,19 @@ var providers = {
124995
124996
  // API is the source of truth (#959).
124996
124997
  "claude-fable": {
124997
124998
  displayName: "Claude Fable",
124998
- resolve: "anthropic/claude-fable-5",
124999
+ resolve: "anthropic/claude-fable-5-1",
124999
125000
  effort: ["low", "medium", "high", "xhigh", "max"],
125000
125001
  // rolling alias: models.dev's OpenRouter mirror lags brand-new pinned
125001
- // versions (claude-fable-5 isn't indexed yet), so track ~…-latest to
125002
+ // versions (claude-fable-5 was missing there when this was added), so track ~…-latest to
125002
125003
  // stay catalog-valid and auto-follow version bumps.
125003
125004
  openRouterResolve: "openrouter/~anthropic/claude-fable-latest",
125004
125005
  subagentModel: "claude-sonnet"
125005
125006
  },
125006
125007
  "claude-opus": {
125007
125008
  displayName: "Claude Opus",
125008
- resolve: "anthropic/claude-opus-5",
125009
+ resolve: "anthropic/claude-opus-5-5",
125009
125010
  effort: ["low", "medium", "high", "xhigh", "max"],
125010
- openRouterResolve: "openrouter/anthropic/claude-opus-5",
125011
+ openRouterResolve: "openrouter/anthropic/claude-opus-5.5",
125011
125012
  preferred: true,
125012
125013
  subagentModel: "claude-sonnet"
125013
125014
  },
@@ -125042,9 +125043,9 @@ var providers = {
125042
125043
  },
125043
125044
  "gpt-sol": {
125044
125045
  displayName: "GPT Sol",
125045
- resolve: "openai/gpt-5.6-sol",
125046
+ resolve: "openai/gpt-6-sol",
125046
125047
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
125047
- openRouterResolve: "openrouter/openai/gpt-5.6-sol",
125048
+ openRouterResolve: "openrouter/openai/gpt-6-sol",
125048
125049
  preferred: true,
125049
125050
  subagentModel: "gpt-terra"
125050
125051
  },
@@ -125054,9 +125055,9 @@ var providers = {
125054
125055
  "gpt-sol-pro": {
125055
125056
  displayName: "GPT Sol Pro",
125056
125057
  description: "Maximum reasoning effort",
125057
- resolve: "openai/gpt-5.6-sol",
125058
+ resolve: "openai/gpt-6-sol",
125058
125059
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
125059
- openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
125060
+ openRouterResolve: "openrouter/openai/gpt-6-sol-pro",
125060
125061
  subagentModel: "gpt-sol"
125061
125062
  },
125062
125063
  // gpt-5.6's balanced mid-tier. selectable on its own and doubles as Sol's
@@ -125069,9 +125070,9 @@ var providers = {
125069
125070
  },
125070
125071
  "gpt-luna": {
125071
125072
  displayName: "GPT Luna",
125072
- resolve: "openai/gpt-5.6-luna",
125073
+ resolve: "openai/gpt-6-luna",
125073
125074
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
125074
- openRouterResolve: "openrouter/openai/gpt-5.6-luna"
125075
+ openRouterResolve: "openrouter/openai/gpt-6-luna"
125075
125076
  },
125076
125077
  // legacy aliases — openai unified the codex line into the main GPT family
125077
125078
  // and is shutting down every "-codex" snapshot on 2026-07-23. transparently
@@ -125165,9 +125166,9 @@ var providers = {
125165
125166
  models: {
125166
125167
  grok: {
125167
125168
  displayName: "Grok",
125168
- resolve: "xai/grok-4.6",
125169
+ resolve: "xai/grok-4.7",
125169
125170
  effort: ["low", "medium", "high", "xhigh"],
125170
- openRouterResolve: "openrouter/x-ai/grok-4.6",
125171
+ openRouterResolve: "openrouter/x-ai/grok-4.7",
125171
125172
  preferred: true
125172
125173
  },
125173
125174
  // the Smart ladder's cheap rung: 1.25/2.5 against 4.6's 2/6, and a 0.2
@@ -125182,17 +125183,17 @@ var providers = {
125182
125183
  // 2026-05-15 (https://docs.x.ai/developers/migration/may-15-deprecation)
125183
125184
  // and now redirects every deprecated text-model slug to grok-4.3 at
125184
125185
  // standard pricing. fall back to the live `xai/grok` so the alias
125185
- // chain resolves to grok-4.6 for both direct-key and OpenRouter users.
125186
+ // chain resolves to grok-4.7 for both direct-key and OpenRouter users.
125186
125187
  "grok-fast": {
125187
125188
  displayName: "Grok Fast",
125188
125189
  resolve: "xai/grok-4-1-fast",
125189
- openRouterResolve: "openrouter/x-ai/grok-4.6",
125190
+ openRouterResolve: "openrouter/x-ai/grok-4.7",
125190
125191
  fallback: "xai/grok"
125191
125192
  },
125192
125193
  "grok-code-fast": {
125193
125194
  displayName: "Grok Code Fast",
125194
125195
  resolve: "xai/grok-code-fast-1",
125195
- openRouterResolve: "openrouter/x-ai/grok-4.6",
125196
+ openRouterResolve: "openrouter/x-ai/grok-4.7",
125196
125197
  fallback: "xai/grok"
125197
125198
  }
125198
125199
  }
@@ -125220,8 +125221,9 @@ var providers = {
125220
125221
  "deepseek-pro": {
125221
125222
  displayName: "DeepSeek Pro",
125222
125223
  resolve: "deepseek/deepseek-v4-pro",
125223
- effort: ["high", "max"],
125224
- openRouterEffort: ["low", "high", "max"],
125224
+ // models.dev gave the direct id V4.1-Flash's ladder on 2026-09-21, which
125225
+ // is what DeepSeek now serves under it — and the same as the Router pin's.
125226
+ effort: ["low", "high", "max"],
125225
125227
  openRouterResolve: "openrouter/deepseek/deepseek-v4-pro-0813",
125226
125228
  preferred: true
125227
125229
  },
@@ -125285,12 +125287,20 @@ var providers = {
125285
125287
  // the same models as `moonshotai` above, billed against a Kimi membership
125286
125288
  // instead of a Moonshot API balance — a separate endpoint, separate model
125287
125289
  // 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
- // `kimi-for-coding` (api `https://api.kimi.com/coding/v1`, npm
125290
- // `@ai-sdk/anthropic`) and opencode's env loop enables it from a bare
125290
+ // `envVars` entry. no provider injection is needed: models.dev carries the
125291
+ // provider (api `https://api.kimi.com/coding/v1`, npm
125292
+ // `@ai-sdk/openai-compatible`) and opencode's env loop enables it from a bare
125291
125293
  // `KIMI_API_KEY`, verified against our pinned opencode-ai@1.18.5 — all four
125292
125294
  // ids list in `opencode models` and a run reaches Kimi's own auth check.
125293
125295
  //
125296
+ // models.dev renamed that provider on 2026-09-18: `kimi-for-coding` became
125297
+ // `kimi-code-plan-cn` (api.kimi.com — where the console mints the key) and
125298
+ // `kimi-code-plan-global` (api.kimi.ai). opencode resolves providers from
125299
+ // its models.dev cache, so a `resolve` still spelling the old key names a
125300
+ // provider it does not know. the `resolve` targets track models.dev's key;
125301
+ // the provider KEY below is Pullfrog's slug and stays put. see
125302
+ // wiki/kimi-code.md.
125303
+ //
125294
125304
  // NO `openRouterResolve` ON PURPOSE. OpenRouter cannot serve a Kimi
125295
125305
  // membership, so a Router path here would silently bill the wallet for
125296
125306
  // Moonshot pay-as-you-go under a slug picked for the opposite reason. The
@@ -125300,9 +125310,11 @@ var providers = {
125300
125310
  // keyless Router pick to the default subsidy model with `noRouterPath`.
125301
125311
  "kimi-for-coding": provider({
125302
125312
  // "Kimi Code" is the product name on kimi.com/code and in the console the
125303
- // key is minted from. The provider KEY has to stay `kimi-for-coding` — it
125304
- // is models.dev's id, so it is what `enabled_providers` and every
125305
- // `resolve` prefix must spell.
125313
+ // key is minted from. the provider KEY stays `kimi-for-coding`: it is the
125314
+ // slug prefix every stored pick, `--model` flag and BYOK card spells, and
125315
+ // it is not what reaches opencode — `enabled_providers` is derived from
125316
+ // the `resolve` prefix (`action/agents/opencode.ts`), which is why the
125317
+ // two may differ here and nowhere else in this file.
125306
125318
  displayName: "Kimi Code",
125307
125319
  envVars: ["KIMI_API_KEY"],
125308
125320
  models: {
@@ -125313,7 +125325,7 @@ var providers = {
125313
125325
  "kimi-k3": {
125314
125326
  displayName: "Kimi K3",
125315
125327
  description: "1M context, but only on Allegretto and above \xB7 Moderato caps it at 256K",
125316
- resolve: "kimi-for-coding/k3",
125328
+ resolve: "kimi-code-plan-cn/k3",
125317
125329
  effort: ["low", "high", "max"],
125318
125330
  subagentModel: "kimi-k2"
125319
125331
  },
@@ -125328,7 +125340,7 @@ var providers = {
125328
125340
  "kimi-k3-256k": {
125329
125341
  displayName: "Kimi K3 256K",
125330
125342
  description: "Same model at 256K for ~half the quota \xB7 Moderato or above",
125331
- resolve: "kimi-for-coding/k3-256k",
125343
+ resolve: "kimi-code-plan-cn/k3-256k",
125332
125344
  effort: ["low", "high", "max"],
125333
125345
  preferred: true,
125334
125346
  subagentModel: "kimi-k2"
@@ -125336,7 +125348,7 @@ var providers = {
125336
125348
  "kimi-k2": {
125337
125349
  displayName: "Kimi K2",
125338
125350
  description: "Included in every Kimi membership tier",
125339
- resolve: "kimi-for-coding/kimi-for-coding",
125351
+ resolve: "kimi-code-plan-cn/kimi-for-coding",
125340
125352
  // models.dev published this ladder on 2026-09-14; the catalog gate
125341
125353
  // mirrors it, so main was red until the alias carried it too.
125342
125354
  effort: ["low", "high", "max"]
@@ -125344,7 +125356,7 @@ var providers = {
125344
125356
  "kimi-k2-highspeed": {
125345
125357
  displayName: "Kimi K2 HighSpeed",
125346
125358
  description: "~6x output speed for ~3x quota \xB7 needs Allegretto or above",
125347
- resolve: "kimi-for-coding/kimi-for-coding-highspeed"
125359
+ resolve: "kimi-code-plan-cn/kimi-for-coding-highspeed"
125348
125360
  }
125349
125361
  }
125350
125362
  }),
@@ -125409,24 +125421,15 @@ var providers = {
125409
125421
  },
125410
125422
  "claude-opus": {
125411
125423
  displayName: "Claude Opus",
125412
- resolve: "opencode/claude-opus-5",
125424
+ resolve: "opencode/claude-opus-5-5",
125413
125425
  effort: ["low", "medium", "high", "xhigh", "max"],
125414
- openRouterResolve: "openrouter/anthropic/claude-opus-5",
125415
- subagentModel: "claude-sonnet",
125416
- // TEMPORARY — clear this ONLY when opus completes a run through opencode,
125417
- // never when the endpoint merely answers. Zen LISTS claude-opus-5 in
125418
- // /zen/v1/models, so the catalog test passes; on 2026-08-25 the endpoint
125419
- // itself answered 503 `Upstream request failed: Endpoint is unavailable.`
125420
- // (measured 5/5; claude-sonnet-5, claude-opus-4-8, claude-haiku-4-5 and
125421
- // claude-fable-5 all 200 on the same key). opencode retries above the AI
125422
- // SDK emitting no part.updated, so a run just produces nothing until it is
125423
- // killed — metaideas/init logged six zero-output failures from 2026-08-23.
125424
- // The 503 has since cleared and the model is STILL unusable: re-measured
125425
- // 2026-08-26, direct POST /zen/v1/messages is 10/10 200 at 1.3-4.1s while
125426
- // `opencode run --model opencode/claude-opus-5` on the same trivial prompt
125427
- // emitted nothing for 240s in CI. A raw-endpoint 200 is not runtime
125428
- // availability. see wiki/opencode-silent-stall.md
125429
- fallback: "opencode/claude-sonnet"
125426
+ openRouterResolve: "openrouter/anthropic/claude-opus-5.5",
125427
+ subagentModel: "claude-sonnet"
125428
+ // fell back to Sonnet from 2026-08-25 to 2026-09-25: Zen listed
125429
+ // claude-opus-5 while `opencode run` on it emitted nothing for 240s. A
125430
+ // raw-endpoint 200 is not runtime availability — the fallback was cleared
125431
+ // only once `opencode run` completed on both claude-opus-5 and 5-5. see
125432
+ // wiki/opencode-silent-stall.md
125430
125433
  },
125431
125434
  "claude-sonnet": {
125432
125435
  displayName: "Claude Sonnet",
@@ -125441,9 +125444,9 @@ var providers = {
125441
125444
  },
125442
125445
  "gpt-sol": {
125443
125446
  displayName: "GPT Sol",
125444
- resolve: "opencode/gpt-5.6-sol",
125447
+ resolve: "opencode/gpt-6-sol",
125445
125448
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
125446
- openRouterResolve: "openrouter/openai/gpt-5.6-sol",
125449
+ openRouterResolve: "openrouter/openai/gpt-6-sol",
125447
125450
  subagentModel: "gpt-terra"
125448
125451
  },
125449
125452
  "gpt-astra": {
@@ -125457,9 +125460,9 @@ var providers = {
125457
125460
  "gpt-sol-pro": {
125458
125461
  displayName: "GPT Sol Pro",
125459
125462
  description: "Maximum reasoning effort",
125460
- resolve: "opencode/gpt-5.6-sol",
125463
+ resolve: "opencode/gpt-6-sol",
125461
125464
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
125462
- openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
125465
+ openRouterResolve: "openrouter/openai/gpt-6-sol-pro",
125463
125466
  subagentModel: "gpt-sol"
125464
125467
  },
125465
125468
  // gpt-5.6 balanced mid-tier — selectable + Sol's subagent. see openai above.
@@ -125471,9 +125474,9 @@ var providers = {
125471
125474
  },
125472
125475
  "gpt-luna": {
125473
125476
  displayName: "GPT Luna",
125474
- resolve: "opencode/gpt-5.6-luna",
125477
+ resolve: "opencode/gpt-6-luna",
125475
125478
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
125476
- openRouterResolve: "openrouter/openai/gpt-5.6-luna"
125479
+ openRouterResolve: "openrouter/openai/gpt-6-luna"
125477
125480
  },
125478
125481
  // legacy aliases — see openai provider above for context.
125479
125482
  "gpt-codex": {
@@ -125572,9 +125575,34 @@ var providers = {
125572
125575
  },
125573
125576
  grok: {
125574
125577
  displayName: "Grok",
125575
- resolve: "opencode/grok-4.6",
125578
+ resolve: "opencode/grok-4.7",
125576
125579
  effort: ["low", "medium", "high", "xhigh"],
125577
- openRouterResolve: "openrouter/x-ai/grok-4.6"
125580
+ openRouterResolve: "openrouter/x-ai/grok-4.7"
125581
+ },
125582
+ // Zen began listing Qwen's Max and Flash tiers in late 2026-09 (Max on
125583
+ // 09-25); until then `opencode-go` was the only Qwen route, so a Zen
125584
+ // subscriber without Go had none. Plus is still Go-only. Zen's Max entry
125585
+ // publishes a reasoning toggle but no effort rungs.
125586
+ "qwen-max": {
125587
+ displayName: "Qwen Max",
125588
+ resolve: "opencode/qwen3.8-max",
125589
+ openRouterEffort: ["minimal", "low", "medium", "high", "xhigh"],
125590
+ openRouterResolve: "openrouter/qwen/qwen3.8-max-0902",
125591
+ // unlisted until a published `pullfrog` carries this alias (the
125592
+ // merge-vs-publish rule in wiki/models-catalog.md). unhide in the release
125593
+ // that ships it.
125594
+ hidden: true
125595
+ },
125596
+ "qwen-flash": {
125597
+ displayName: "Qwen Flash",
125598
+ resolve: "opencode/qwen3.8-flash",
125599
+ effort: ["low", "medium", "xhigh"],
125600
+ openRouterEffort: [],
125601
+ openRouterResolve: "openrouter/qwen/qwen3.8-flash",
125602
+ // unlisted until a published `pullfrog` carries this alias (the
125603
+ // merge-vs-publish rule in wiki/models-catalog.md). unhide in the release
125604
+ // that ships it.
125605
+ hidden: true
125578
125606
  },
125579
125607
  "gpt-5-nano": {
125580
125608
  displayName: "GPT Nano",
@@ -125587,8 +125615,12 @@ var providers = {
125587
125615
  "muse-spark": {
125588
125616
  displayName: "Muse Spark",
125589
125617
  resolve: "opencode/muse-spark-1.3",
125590
- effort: ["minimal", "low", "medium", "high", "xhigh", "max"],
125591
- openRouterResolve: "openrouter/meta/muse-spark-1.3"
125618
+ // models.dev dropped `max` from Zen's ladder on 2026-09-19 while the
125619
+ // OpenRouter and direct `meta/` routes kept it; the catalog gate
125620
+ // mirrors what is published per route.
125621
+ effort: ["minimal", "low", "medium", "high", "xhigh"],
125622
+ openRouterResolve: "openrouter/meta/muse-spark-1.3",
125623
+ openRouterEffort: ["minimal", "low", "medium", "high", "xhigh", "max"]
125592
125624
  },
125593
125625
  // Zen's FREE contributor tier: the same model at $0 because Meta trains
125594
125626
  // on the prompts and completions. Zen served it to our key on 2026-09-12
@@ -125612,13 +125644,38 @@ var providers = {
125612
125644
  resolve: "opencode/union-alpha",
125613
125645
  // free to run, still gated on the provider's own OPENCODE_API_KEY —
125614
125646
  // see the big-pickle note above (#1077).
125615
- isFree: true
125647
+ isFree: true,
125648
+ // Zen dropped the id from `/v1/models` on 2026-09-18, two days after it
125649
+ // listed it, and answers a 500 for it. a stealth preview has no same-
125650
+ // family successor, so stored picks land on the other free stealth
125651
+ // model, as `minimax-m2.5-free` does.
125652
+ fallback: "opencode/big-pickle"
125653
+ },
125654
+ // Zen's FREE stealth preview (listed 2026-09-23), the third after
125655
+ // big-pickle and union-alpha. OpenRouter's listing: prompts and
125656
+ // completions may be retained by the provider, not trained on. unlike the
125657
+ // first two it publishes an effort ladder, so the gate mirrors one here.
125658
+ "space-bunny": {
125659
+ displayName: "Space Bunny",
125660
+ description: "Stealth preview; prompts may be retained",
125661
+ resolve: "opencode/space-bunny-free",
125662
+ effort: ["low", "medium", "high", "xhigh", "max"],
125663
+ // free to run, still gated on the provider's own OPENCODE_API_KEY —
125664
+ // see the big-pickle note above (#1077).
125665
+ isFree: true,
125666
+ // unlisted until a published `pullfrog` carries this alias: 0.1.82
125667
+ // predates it, so a run passes `opencode/space-bunny` through raw and
125668
+ // Zen answers a 500. unhide in the release that ships it.
125669
+ hidden: true
125616
125670
  },
125617
125671
  // Zen's live free MiMo, and the second free row in a menu that big-pickle
125618
125672
  // was alone in since `mimo-v2-pro-free` lost its model.
125619
125673
  mimo: {
125620
125674
  displayName: "MiMo",
125621
- resolve: "opencode/mimo-v2.5-free",
125675
+ // models.dev deprecated `mimo-v2.5-free` on 2026-09-22. V2.6-Flash is
125676
+ // the only other MiMo Zen serves, so the slug follows it across the
125677
+ // tier rather than leaving stored picks on a dying id.
125678
+ resolve: "opencode/mimo-v2.6-flash-free",
125622
125679
  // free to run, still gated on the provider's own OPENCODE_API_KEY —
125623
125680
  // see the big-pickle note above (#1077).
125624
125681
  isFree: true
@@ -125647,11 +125704,12 @@ var providers = {
125647
125704
  // OpenCode Go is a separate $10/mo subscription from Zen, served on its own
125648
125705
  // base URL (`https://opencode.ai/zen/go/v1`) but authenticated with the SAME
125649
125706
  // `OPENCODE_API_KEY`. it carries the open-weight coding models plus a couple
125650
- // of frontier ones, six of which are served ONLY here — Zen's `/v1/models`
125651
- // does not list qwen3.7/3.8-*, mimo-v2.5-pro, longcat-2.0 or hy3. (it listed
125707
+ // of frontier ones, four of which are served ONLY here — Zen's `/v1/models`
125708
+ // does not list qwen3.7-plus, mimo-v2.6-pro, longcat-2.0 or hy3. (it listed
125652
125709
  // no glm-5.3* either until 2026-09, which is why `opencode/glm` trailed on
125653
- // 5.2.) so for a Go subscriber this provider is not a duplicate route to Zen,
125654
- // it is the only route to a large part of what they pay for.
125710
+ // 5.2, and no qwen3.8-* until late 2026-09.) so for a Go subscriber this
125711
+ // provider is not a duplicate route to Zen, it is the only route to a large
125712
+ // part of what they pay for.
125655
125713
  // like `opencode` and `openrouter` this is a ROUTER, not a vendor: slugs and
125656
125714
  // display names mirror the upstream brand tier, and the picker groups them
125657
125715
  // under the upstream vendor.
@@ -125711,7 +125769,8 @@ var providers = {
125711
125769
  // picker row that fails for almost everyone is worse than none. DeepSeek
125712
125770
  // stays reachable ungated via `deepseek/*`, `opencode/*` and
125713
125771
  // `openrouter/*`; both remain runnable by full specifier once opted in.
125714
- // Alibaba — new vendor family for the catalog; Zen serves neither tier.
125772
+ // Alibaba — Zen serves Max and Flash too (see `opencode/qwen-max`); Plus
125773
+ // is Go-only.
125715
125774
  "qwen-max": {
125716
125775
  displayName: "Qwen Max",
125717
125776
  resolve: "opencode-go/qwen3.8-max",
@@ -125754,8 +125813,8 @@ var providers = {
125754
125813
  // Xiaomi — Go-only; Zen serves the free `mimo-v2-pro-free` promo instead.
125755
125814
  "mimo-pro": {
125756
125815
  displayName: "MiMo Pro",
125757
- resolve: "opencode-go/mimo-v2.5-pro",
125758
- openRouterResolve: "openrouter/xiaomi/mimo-v2.5-pro"
125816
+ resolve: "opencode-go/mimo-v2.6-pro",
125817
+ openRouterResolve: "openrouter/xiaomi/mimo-v2.6-pro"
125759
125818
  },
125760
125819
  // Meituan — Go-only.
125761
125820
  longcat: {
@@ -125781,15 +125840,15 @@ var providers = {
125781
125840
  // wiki/models-catalog.md on `opencode/kimi-k2`.
125782
125841
  grok: {
125783
125842
  displayName: "Grok",
125784
- resolve: "opencode-go/grok-4.6",
125843
+ resolve: "opencode-go/grok-4.7",
125785
125844
  effort: ["low", "medium", "high", "xhigh"],
125786
- openRouterResolve: "openrouter/x-ai/grok-4.6"
125845
+ openRouterResolve: "openrouter/x-ai/grok-4.7"
125787
125846
  },
125788
125847
  "gpt-luna": {
125789
125848
  displayName: "GPT Luna",
125790
- resolve: "opencode-go/gpt-5.6-luna",
125849
+ resolve: "opencode-go/gpt-6-luna",
125791
125850
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
125792
- openRouterResolve: "openrouter/openai/gpt-5.6-luna"
125851
+ openRouterResolve: "openrouter/openai/gpt-6-luna"
125793
125852
  }
125794
125853
  }
125795
125854
  }),
@@ -125891,15 +125950,15 @@ var providers = {
125891
125950
  resolve: "openrouter/~anthropic/claude-haiku-latest",
125892
125951
  openRouterResolve: "openrouter/~anthropic/claude-haiku-latest"
125893
125952
  },
125894
- // pinned to the explicit gpt-5.6 tiers (not the ~openai/gpt-latest rolling
125895
- // alias): after the Sol/Terra/Luna rename, ~gpt-mini-latest no longer maps
125953
+ // pinned to the explicit Sol/Terra/Luna tiers (not the ~openai/gpt-latest
125954
+ // rolling alias): after that rename, ~gpt-mini-latest no longer maps
125896
125955
  // to Luna, so rolling aliases would silently diverge `gpt`/`gpt-mini` from
125897
125956
  // the chosen tiers across funding paths.
125898
125957
  "gpt-sol": {
125899
125958
  displayName: "GPT Sol",
125900
- resolve: "openrouter/openai/gpt-5.6-sol",
125959
+ resolve: "openrouter/openai/gpt-6-sol",
125901
125960
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
125902
- openRouterResolve: "openrouter/openai/gpt-5.6-sol",
125961
+ openRouterResolve: "openrouter/openai/gpt-6-sol",
125903
125962
  subagentModel: "gpt-terra"
125904
125963
  },
125905
125964
  "gpt-astra": {
@@ -125913,9 +125972,9 @@ var providers = {
125913
125972
  "gpt-sol-pro": {
125914
125973
  displayName: "GPT Sol Pro",
125915
125974
  description: "Maximum reasoning effort",
125916
- resolve: "openrouter/openai/gpt-5.6-sol-pro",
125975
+ resolve: "openrouter/openai/gpt-6-sol-pro",
125917
125976
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
125918
- openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
125977
+ openRouterResolve: "openrouter/openai/gpt-6-sol-pro",
125919
125978
  subagentModel: "gpt-sol"
125920
125979
  },
125921
125980
  // gpt-5.6 balanced mid-tier — selectable + Sol's subagent. see openai above.
@@ -125927,9 +125986,9 @@ var providers = {
125927
125986
  },
125928
125987
  "gpt-luna": {
125929
125988
  displayName: "GPT Luna",
125930
- resolve: "openrouter/openai/gpt-5.6-luna",
125989
+ resolve: "openrouter/openai/gpt-6-luna",
125931
125990
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
125932
- openRouterResolve: "openrouter/openai/gpt-5.6-luna"
125991
+ openRouterResolve: "openrouter/openai/gpt-6-luna"
125933
125992
  },
125934
125993
  // legacy aliases — see openai provider for context.
125935
125994
  "gpt-codex": {
@@ -125993,9 +126052,9 @@ var providers = {
125993
126052
  },
125994
126053
  grok: {
125995
126054
  displayName: "Grok",
125996
- resolve: "openrouter/x-ai/grok-4.6",
126055
+ resolve: "openrouter/x-ai/grok-4.7",
125997
126056
  effort: ["low", "medium", "high", "xhigh"],
125998
- openRouterResolve: "openrouter/x-ai/grok-4.6"
126057
+ openRouterResolve: "openrouter/x-ai/grok-4.7"
125999
126058
  },
126000
126059
  // dated pin, not the bare id — see `deepseek/deepseek-pro` for why
126001
126060
  // OpenRouter's unversioned `deepseek-v4-pro` is the stale April preview.
@@ -126066,8 +126125,10 @@ var providers = {
126066
126125
  vercel: provider({
126067
126126
  // Vercel AI Gateway — one key serves every model it fronts. model IDs use
126068
126127
  // the models.dev `vercel` catalog's own naming (dotted versions, e.g.
126069
- // `anthropic/claude-opus-5`, `zai/glm-5.3`), and effort ladders mirror that
126070
- // catalog's entries, not the upstream vendor's. deliberately no
126128
+ // `anthropic/claude-opus-5.5`, `zai/glm-5.3`). effort ladders come from the
126129
+ // gateway's OWN `/v1/models`, not models.dev — the two disagree routinely
126130
+ // (on 2026-09-22 they disagreed on all ten entries that drifted), and the
126131
+ // drift test reads the gateway for that reason. deliberately no
126071
126132
  // `openRouterResolve`: a gateway pick is BYOK-only — silently rerouting it
126072
126133
  // over the Router proxy would bill the wallet for traffic the user pointed
126073
126134
  // at their own gateway.
@@ -126076,7 +126137,7 @@ var providers = {
126076
126137
  models: {
126077
126138
  "claude-opus": {
126078
126139
  displayName: "Claude Opus",
126079
- resolve: "vercel/anthropic/claude-opus-5",
126140
+ resolve: "vercel/anthropic/claude-opus-5.5",
126080
126141
  effort: ["low", "medium", "high", "xhigh", "max"],
126081
126142
  preferred: true,
126082
126143
  subagentModel: "claude-sonnet"
@@ -126084,7 +126145,7 @@ var providers = {
126084
126145
  "claude-sonnet": {
126085
126146
  displayName: "Claude Sonnet",
126086
126147
  resolve: "vercel/anthropic/claude-sonnet-5",
126087
- effort: ["low", "medium", "high", "xhigh"]
126148
+ effort: ["none", "low", "medium", "high", "xhigh", "max"]
126088
126149
  },
126089
126150
  "claude-haiku": {
126090
126151
  displayName: "Claude Haiku",
@@ -126092,7 +126153,7 @@ var providers = {
126092
126153
  },
126093
126154
  "gpt-sol": {
126094
126155
  displayName: "GPT Sol",
126095
- resolve: "vercel/openai/gpt-5.6-sol",
126156
+ resolve: "vercel/openai/gpt-6-sol",
126096
126157
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
126097
126158
  subagentModel: "gpt-terra"
126098
126159
  },
@@ -126105,35 +126166,35 @@ var providers = {
126105
126166
  "gpt-terra": {
126106
126167
  displayName: "GPT Terra",
126107
126168
  resolve: "vercel/openai/gpt-5.6-terra",
126108
- effort: ["none", "low", "medium", "high", "xhigh", "max"]
126169
+ effort: ["none", "minimal", "low", "medium", "high", "xhigh", "max"]
126109
126170
  },
126110
126171
  "gpt-luna": {
126111
126172
  displayName: "GPT Luna",
126112
- resolve: "vercel/openai/gpt-5.6-luna",
126173
+ resolve: "vercel/openai/gpt-6-luna",
126113
126174
  effort: ["none", "low", "medium", "high", "xhigh", "max"]
126114
126175
  },
126115
126176
  "gemini-pro": {
126116
126177
  displayName: "Gemini Pro",
126117
126178
  resolve: "vercel/google/gemini-3.1-pro-preview",
126118
- effort: ["low", "medium", "high"]
126179
+ effort: ["low", "high"]
126119
126180
  },
126120
126181
  "gemini-flash": {
126121
126182
  displayName: "Gemini Flash",
126122
126183
  resolve: "vercel/google/gemini-3.8-flash",
126123
- effort: ["low", "medium", "high"]
126184
+ effort: ["low", "high"]
126124
126185
  },
126125
126186
  "deepseek-pro": {
126126
126187
  displayName: "DeepSeek Pro",
126127
126188
  resolve: "vercel/deepseek/deepseek-v4-pro-0813",
126128
- effort: ["high", "xhigh"]
126189
+ effort: ["none", "high", "max"]
126129
126190
  },
126130
126191
  // the gateway's bare `deepseek-v4-flash` is the April preview — the same
126131
126192
  // fork trap as OpenRouter, with `deepseek-v4-flash-0731` beside it — so
126132
- // this entry sat on the preview until V4.1. the gateway publishes no
126133
- // effort ladder for the V4.1 id.
126193
+ // this entry sat on the preview until V4.1.
126134
126194
  "deepseek-flash": {
126135
126195
  displayName: "DeepSeek Flash",
126136
- resolve: "vercel/deepseek/deepseek-v4.1-flash"
126196
+ resolve: "vercel/deepseek/deepseek-v4.1-flash",
126197
+ effort: ["none", "high", "max"]
126137
126198
  },
126138
126199
  glm: {
126139
126200
  displayName: "GLM",
@@ -126143,12 +126204,12 @@ var providers = {
126143
126204
  "kimi-k3": {
126144
126205
  displayName: "Kimi K3",
126145
126206
  resolve: "vercel/moonshotai/kimi-k3",
126146
- effort: ["low", "high", "max"]
126207
+ effort: ["none", "low", "high", "max"]
126147
126208
  },
126148
- // the gateway publishes no effort ladder for this id.
126149
126209
  "muse-spark": {
126150
126210
  displayName: "Muse Spark",
126151
- resolve: "vercel/meta/muse-spark-1.3"
126211
+ resolve: "vercel/meta/muse-spark-1.3",
126212
+ effort: ["minimal", "low", "medium", "high", "xhigh"]
126152
126213
  }
126153
126214
  }
126154
126215
  })
@@ -127730,7 +127791,7 @@ process.stdin.on("end", () => {
127730
127791
  });
127731
127792
  `;
127732
127793
  }
127733
- function buildClaudePretoolGateSettings(scriptAbsolutePath, execToolDenyRules) {
127794
+ function buildClaudePretoolGateSettings(scriptAbsolutePath, denyRules) {
127734
127795
  return {
127735
127796
  hooks: {
127736
127797
  PreToolUse: [
@@ -127750,7 +127811,7 @@ function buildClaudePretoolGateSettings(scriptAbsolutePath, execToolDenyRules) {
127750
127811
  }
127751
127812
  ]
127752
127813
  },
127753
- permissions: { deny: execToolDenyRules }
127814
+ permissions: { deny: denyRules }
127754
127815
  };
127755
127816
  }
127756
127817
 
@@ -128613,12 +128674,22 @@ async function installClaudeCli() {
128613
128674
  installDependencies: true
128614
128675
  });
128615
128676
  }
128616
- var CLAUDE_EXEC_TOOLS = ["Bash", "Monitor", "REPL", "Workflow"];
128617
- var CLAUDE_EXEC_TOOL_DENY_RULES = [
128677
+ var CLAUDE_EXEC_TOOLS = ["Bash", "PowerShell", "Monitor", "REPL", "Workflow"];
128678
+ var CLAUDE_DENIED_TOOLS = [
128618
128679
  ...CLAUDE_EXEC_TOOLS,
128619
- ...CLAUDE_EXEC_TOOLS.map((t2) => `Agent(${t2})`)
128680
+ "DesignSync",
128681
+ "Artifact",
128682
+ "ShareOnboardingGuide",
128683
+ "SendMessage",
128684
+ "ListAgents",
128685
+ "PushNotification",
128686
+ "RemoteTrigger"
128620
128687
  ];
128621
- var CLAUDE_DISALLOWED_TOOLS = CLAUDE_EXEC_TOOL_DENY_RULES.join(",");
128688
+ var CLAUDE_DENY_RULES = [
128689
+ ...CLAUDE_DENIED_TOOLS,
128690
+ ...CLAUDE_DENIED_TOOLS.map((t2) => `Agent(${t2})`)
128691
+ ];
128692
+ var CLAUDE_DISALLOWED_TOOLS = CLAUDE_DENY_RULES.join(",");
128622
128693
  function writeMcpConfig(ctx) {
128623
128694
  const configDir = join5(ctx.tmpdir, ".claude");
128624
128695
  mkdirSync4(configDir, { recursive: true });
@@ -129051,14 +129122,11 @@ function buildClaudeSettings(params) {
129051
129122
  `Glob(${path4}/**)`,
129052
129123
  `Glob(/${path4}/**)`
129053
129124
  ]);
129054
- const gate = buildClaudePretoolGateSettings(
129055
- params.pretoolGateScriptPath,
129056
- CLAUDE_EXEC_TOOL_DENY_RULES
129057
- );
129125
+ const gate = buildClaudePretoolGateSettings(params.pretoolGateScriptPath, CLAUDE_DENY_RULES);
129058
129126
  const base = {
129059
129127
  permissions: {
129060
129128
  deny: [
129061
- // native exec tools — the authoritative, bypass-immune deny.
129129
+ // CLAUDE_DENIED_TOOLS — the authoritative, bypass-immune deny.
129062
129130
  // `--disallowedTools` (a cliArg-source deny) leaked under
129063
129131
  // `--dangerously-skip-permissions`; policySettings denies survive
129064
129132
  // bypassPermissions mode. covers top-level + Agent(...) subagent use.
@@ -129272,7 +129340,6 @@ var claude = agent({
129272
129340
  });
129273
129341
 
129274
129342
  // agents/codex.ts
129275
- var core3 = __toESM(require_core(), 1);
129276
129343
  import { existsSync as existsSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "node:fs";
129277
129344
  import { join as join7 } from "node:path";
129278
129345
  import { performance as performance6 } from "node:perf_hooks";
@@ -129634,6 +129701,18 @@ async function writeBackEntry(apiToken, entry) {
129634
129701
  }
129635
129702
  }
129636
129703
 
129704
+ // utils/secretCommands.ts
129705
+ var core3 = __toESM(require_core(), 1);
129706
+ function maskSecret(value2) {
129707
+ if (isGitHubActions) core3.setSecret(value2);
129708
+ }
129709
+ function saveSecretState(name, value2) {
129710
+ if (isGitHubActions) core3.saveState(name, value2);
129711
+ }
129712
+ function setSecretOutput(name, value2) {
129713
+ if (isGitHubActions) core3.setOutput(name, value2);
129714
+ }
129715
+
129637
129716
  // utils/secrets.ts
129638
129717
  var SENSITIVE_PATTERNS = [
129639
129718
  /_KEY$/i,
@@ -129982,8 +130061,8 @@ function toTodoWriteInput(item) {
129982
130061
  }
129983
130062
  var CODEX_MODEL_PRICING = {
129984
130063
  "gpt-6-astra": { input: 10, cacheRead: 1, cacheWrite: 12.5, output: 50 },
129985
- "gpt-5.6-sol": { input: 5, cacheRead: 0.5, cacheWrite: 6.25, output: 30 },
129986
- "gpt-5.6-luna": { input: 0.2, cacheRead: 0.02, cacheWrite: 0.25, output: 1.2 },
130064
+ "gpt-6-sol": { input: 2, cacheRead: 0.2, cacheWrite: 2.5, output: 10 },
130065
+ "gpt-6-luna": { input: 0.1, cacheRead: 0.01, cacheWrite: 0.125, output: 0.5 },
129987
130066
  "gpt-5.6-terra": { input: 2, cacheRead: 0.2, cacheWrite: 2.5, output: 12 }
129988
130067
  };
129989
130068
  function codexCostUsd(params) {
@@ -130221,7 +130300,7 @@ var codex = agent({
130221
130300
  gatewayUrl: codexHomeAuth ? void 0 : getProviderGatewayUrl("openai/")
130222
130301
  });
130223
130302
  if (codexHomeAuth) {
130224
- core3.saveState(
130303
+ saveSecretState(
130225
130304
  OAUTH_WRITEBACK_STATE,
130226
130305
  JSON.stringify({
130227
130306
  apiToken: ctx.apiToken,
@@ -130306,7 +130385,6 @@ var codex = agent({
130306
130385
  });
130307
130386
 
130308
130387
  // agents/opencode.ts
130309
- var core4 = __toESM(require_core(), 1);
130310
130388
  import { spawn as nodeSpawn2 } from "node:child_process";
130311
130389
  import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync7 } from "node:fs";
130312
130390
  import { join as join8 } from "node:path";
@@ -135878,6 +135956,11 @@ export default async function pullfrogSubagentGatePlugin() {
135878
135956
  // pick a different action.
135879
135957
  const sessionID = typeof input?.sessionID === "string" ? input.sessionID : "";
135880
135958
  const tool = typeof input?.tool === "string" ? input.tool : "";
135959
+ // above the sessionID check: the bash block must never depend on a
135960
+ // session id being present.
135961
+ if (tool === "bash") {
135962
+ throw new Error("the native bash tool is disabled in Pullfrog runs.");
135963
+ }
135881
135964
  if (!sessionID || !tool) return;
135882
135965
  if (orchestratorSessionID === undefined) orchestratorSessionID = sessionID;
135883
135966
  if (sessionID === orchestratorSessionID) return;
@@ -136090,7 +136173,11 @@ var installCli = () => installOpencodeCli({ binPath: "bin/opencode.exe" });
136090
136173
  function buildSecurityConfig(ctx, model) {
136091
136174
  const config4 = {
136092
136175
  permission: {
136093
- bash: "deny",
136176
+ // listed but never run: Zen's free tier 403s a tool list missing `bash`,
136177
+ // `glob`, `grep` or `read` (2026-09-17), so the gate plugin throws on
136178
+ // every bash call and "ask" (no responder in serve mode) fails closed.
136179
+ // never switch one of those four to "deny". see wiki/security.md.
136180
+ bash: "ask",
136094
136181
  edit: "allow",
136095
136182
  read: "allow",
136096
136183
  webfetch: "allow",
@@ -136739,7 +136826,7 @@ var opencode = agent({
136739
136826
  });
136740
136827
  }
136741
136828
  if (writebacks.length > 0) {
136742
- core4.saveState(
136829
+ saveSecretState(
136743
136830
  OAUTH_WRITEBACK_STATE,
136744
136831
  JSON.stringify({ apiToken: ctx.apiToken, entries: writebacks })
136745
136832
  );
@@ -147834,7 +147921,7 @@ var Hono2 = class extends Hono {
147834
147921
  }
147835
147922
  };
147836
147923
 
147837
- // node_modules/.pnpm/mcp-proxy@6.7.11/node_modules/mcp-proxy/dist/startStdioServer-C4sEMMHS.mjs
147924
+ // node_modules/.pnpm/mcp-proxy@6.7.12/node_modules/mcp-proxy/dist/startStdioServer-C9HzKfjR.mjs
147838
147925
  import { createRequire } from "node:module";
147839
147926
  import { randomUUID as randomUUID2, timingSafeEqual } from "node:crypto";
147840
147927
 
@@ -157607,7 +157694,7 @@ var require_core$2 = /* @__PURE__ */ __commonJSMin(((exports) => {
157607
157694
  Object.defineProperty(exports, "__esModule", { value: true });
157608
157695
  const id_1 = require_id2();
157609
157696
  const ref_1 = require_ref2();
157610
- const core13 = [
157697
+ const core9 = [
157611
157698
  "$schema",
157612
157699
  "$id",
157613
157700
  "$defs",
@@ -157617,7 +157704,7 @@ var require_core$2 = /* @__PURE__ */ __commonJSMin(((exports) => {
157617
157704
  id_1.default,
157618
157705
  ref_1.default
157619
157706
  ];
157620
- exports.default = core13;
157707
+ exports.default = core9;
157621
157708
  }));
157622
157709
  var require_limitNumber2 = /* @__PURE__ */ __commonJSMin(((exports) => {
157623
157710
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -159755,7 +159842,7 @@ var require_json_schema_2019_09 = /* @__PURE__ */ __commonJSMin(((exports) => {
159755
159842
  const metaSchema = require_schema$1();
159756
159843
  const applicator = require_applicator$1();
159757
159844
  const content = require_content$1();
159758
- const core13 = require_core$1();
159845
+ const core9 = require_core$1();
159759
159846
  const format2 = require_format3();
159760
159847
  const metadata = require_meta_data$1();
159761
159848
  const validation = require_validation$1();
@@ -159765,7 +159852,7 @@ var require_json_schema_2019_09 = /* @__PURE__ */ __commonJSMin(((exports) => {
159765
159852
  metaSchema,
159766
159853
  applicator,
159767
159854
  content,
159768
- core13,
159855
+ core9,
159769
159856
  with$data(this, format2),
159770
159857
  metadata,
159771
159858
  with$data(this, validation)
@@ -160205,7 +160292,7 @@ var require_json_schema_2020_12 = /* @__PURE__ */ __commonJSMin(((exports) => {
160205
160292
  const applicator = require_applicator2();
160206
160293
  const unevaluated = require_unevaluated();
160207
160294
  const content = require_content();
160208
- const core13 = require_core4();
160295
+ const core9 = require_core4();
160209
160296
  const format2 = require_format_annotation();
160210
160297
  const metadata = require_meta_data();
160211
160298
  const validation = require_validation2();
@@ -160216,7 +160303,7 @@ var require_json_schema_2020_12 = /* @__PURE__ */ __commonJSMin(((exports) => {
160216
160303
  applicator,
160217
160304
  unevaluated,
160218
160305
  content,
160219
- core13,
160306
+ core9,
160220
160307
  with$data(this, format2),
160221
160308
  metadata,
160222
160309
  with$data(this, validation)
@@ -163433,7 +163520,7 @@ function createMcpHandler(factory, options = {}) {
163433
163520
  };
163434
163521
  }
163435
163522
 
163436
- // node_modules/.pnpm/mcp-proxy@6.7.11/node_modules/mcp-proxy/dist/startStdioServer-C4sEMMHS.mjs
163523
+ // node_modules/.pnpm/mcp-proxy@6.7.12/node_modules/mcp-proxy/dist/startStdioServer-C9HzKfjR.mjs
163437
163524
  import http from "http";
163438
163525
  import { Http2ServerRequest } from "http2";
163439
163526
  import { Readable } from "stream";
@@ -171658,7 +171745,7 @@ var require_core$22 = /* @__PURE__ */ __commonJSMin2(((exports) => {
171658
171745
  Object.defineProperty(exports, "__esModule", { value: true });
171659
171746
  const id_1 = require_id3();
171660
171747
  const ref_1 = require_ref3();
171661
- const core13 = [
171748
+ const core9 = [
171662
171749
  "$schema",
171663
171750
  "$id",
171664
171751
  "$defs",
@@ -171668,7 +171755,7 @@ var require_core$22 = /* @__PURE__ */ __commonJSMin2(((exports) => {
171668
171755
  id_1.default,
171669
171756
  ref_1.default
171670
171757
  ];
171671
- exports.default = core13;
171758
+ exports.default = core9;
171672
171759
  }));
171673
171760
  var require_limitNumber3 = /* @__PURE__ */ __commonJSMin2(((exports) => {
171674
171761
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -173806,7 +173893,7 @@ var require_json_schema_2019_092 = /* @__PURE__ */ __commonJSMin2(((exports) =>
173806
173893
  const metaSchema = require_schema$12();
173807
173894
  const applicator = require_applicator$12();
173808
173895
  const content = require_content$12();
173809
- const core13 = require_core$12();
173896
+ const core9 = require_core$12();
173810
173897
  const format2 = require_format4();
173811
173898
  const metadata = require_meta_data$12();
173812
173899
  const validation = require_validation$12();
@@ -173816,7 +173903,7 @@ var require_json_schema_2019_092 = /* @__PURE__ */ __commonJSMin2(((exports) =>
173816
173903
  metaSchema,
173817
173904
  applicator,
173818
173905
  content,
173819
- core13,
173906
+ core9,
173820
173907
  with$data(this, format2),
173821
173908
  metadata,
173822
173909
  with$data(this, validation)
@@ -174256,7 +174343,7 @@ var require_json_schema_2020_122 = /* @__PURE__ */ __commonJSMin2(((exports) =>
174256
174343
  const applicator = require_applicator3();
174257
174344
  const unevaluated = require_unevaluated2();
174258
174345
  const content = require_content2();
174259
- const core13 = require_core5();
174346
+ const core9 = require_core5();
174260
174347
  const format2 = require_format_annotation2();
174261
174348
  const metadata = require_meta_data2();
174262
174349
  const validation = require_validation3();
@@ -174267,7 +174354,7 @@ var require_json_schema_2020_122 = /* @__PURE__ */ __commonJSMin2(((exports) =>
174267
174354
  applicator,
174268
174355
  unevaluated,
174269
174356
  content,
174270
- core13,
174357
+ core9,
174271
174358
  with$data(this, format2),
174272
174359
  metadata,
174273
174360
  with$data(this, validation)
@@ -174838,7 +174925,7 @@ var SseError = class extends Error {
174838
174925
  }
174839
174926
  };
174840
174927
 
174841
- // node_modules/.pnpm/mcp-proxy@6.7.11/node_modules/mcp-proxy/dist/startStdioServer-C4sEMMHS.mjs
174928
+ // node_modules/.pnpm/mcp-proxy@6.7.12/node_modules/mcp-proxy/dist/startStdioServer-C9HzKfjR.mjs
174842
174929
  var __create4 = Object.create;
174843
174930
  var __defProp$1 = Object.defineProperty;
174844
174931
  var __getOwnPropDesc4 = Object.getOwnPropertyDescriptor;
@@ -191851,6 +191938,10 @@ var applyCorsHeaders = (req, res, corsOptions) => {
191851
191938
  console.error("[mcp-proxy] error parsing origin", error109);
191852
191939
  }
191853
191940
  };
191941
+ var canServeModernRoute = (server) => {
191942
+ const target = server instanceof McpServer ? server.server : server;
191943
+ return Array.isArray(target._supportedProtocolVersions);
191944
+ };
191854
191945
  var createModernLeg = ({ createServer: createServer4, onClose, onConnect, onListenSubscriptions }) => {
191855
191946
  const requestContext = new AsyncLocalStorage2();
191856
191947
  const createInstance = async ({ authResult, body, req }) => {
@@ -191870,6 +191961,18 @@ var createModernLeg = ({ createServer: createServer4, onClose, onConnect, onList
191870
191961
  };
191871
191962
  target.onclose = teardown;
191872
191963
  try {
191964
+ if (!canServeModernRoute(server)) throw new Response(JSON.stringify({
191965
+ error: {
191966
+ code: -32e3,
191967
+ data: { reason: "server_missing_modern_protocol_support" },
191968
+ message: "Unsupported protocol version: the server instance cannot serve the 2026-07-28 protocol revision. It was built by the 1.x MCP SDK (e.g. fastmcp <=4.x pulling mcp-proxy through its `^6.4.6` range), which does not declare `_supportedProtocolVersions`. Upgrade the framework that builds it, or serve only 2025-era clients (`modern: false`)."
191969
+ },
191970
+ id: getRequestId(body),
191971
+ jsonrpc: "2.0"
191972
+ }), {
191973
+ headers: { "content-type": "application/json" },
191974
+ status: 400
191975
+ });
191873
191976
  if (onListenSubscriptions) {
191874
191977
  const listenUris = readListenSubscriptions(body);
191875
191978
  if (listenUris.length > 0) releaseSubscriptions = await onListenSubscriptions(listenUris);
@@ -204972,7 +205075,7 @@ this usually means your local branch has commits that were never pushed \u2014 s
204972
205075
  }
204973
205076
 
204974
205077
  // utils/github.ts
204975
- var core5 = __toESM(require_core(), 1);
205078
+ var core4 = __toESM(require_core(), 1);
204976
205079
  import { createSign } from "node:crypto";
204977
205080
  import { rename, writeFile } from "node:fs/promises";
204978
205081
  import { dirname as dirname3, join as join13 } from "node:path";
@@ -209221,9 +209324,7 @@ async function fetchIdTokenFromStash(creds) {
209221
209324
  if (!body.value) {
209222
209325
  throw new Error("ID token response has no value field");
209223
209326
  }
209224
- if (isGitHubActions) {
209225
- core5.setSecret(body.value);
209226
- }
209327
+ maskSecret(body.value);
209227
209328
  return body.value;
209228
209329
  }
209229
209330
  function translateIdTokenError(error109) {
@@ -209235,7 +209336,7 @@ function translateIdTokenError(error109) {
209235
209336
  var mintIdToken = op(
209236
209337
  async () => {
209237
209338
  try {
209238
- return await core5.getIDToken(OIDC_AUDIENCE);
209339
+ return await core4.getIDToken(OIDC_AUDIENCE);
209239
209340
  } catch (error109) {
209240
209341
  throw translateIdTokenError(error109);
209241
209342
  }
@@ -210573,6 +210674,15 @@ function buildImplementPlanLink(ctx, issueNumber, commentId) {
210573
210674
  const apiUrl = getApiUrl();
210574
210675
  return `[Implement plan \u2794](${apiUrl}/trigger/${ctx.repo.owner}/${ctx.repo.name}/${issueNumber}?action=implement&comment_id=${commentId})`;
210575
210676
  }
210677
+ function buildEnrichmentLinks(ctx) {
210678
+ const event = ctx.payload.event;
210679
+ if (event.trigger !== "issues_opened" || event.is_pr || ctx.payload.prompt || ctx.toolState.selectedMode === "Build") {
210680
+ return [];
210681
+ }
210682
+ return [
210683
+ `[Implement a fix \u2794](${getApiUrl()}/trigger/${ctx.repo.owner}/${ctx.repo.name}/${event.issue_number}?action=build)`
210684
+ ];
210685
+ }
210576
210686
  function addFooter(ctx, body) {
210577
210687
  if (/<br\s*\/?>[ \t]*\n(?!\s*\n)/i.test(body)) {
210578
210688
  throw new Error(
@@ -210609,13 +210719,14 @@ function CreateCommentTool(ctx) {
210609
210719
  if (issueNumber === ctx.payload.event.issue_number) {
210610
210720
  ctx.toolState.standaloneCommentId = result.data.id;
210611
210721
  }
210612
- if (commentType === "Plan") {
210613
- if (result.data.node_id) {
210722
+ const enrichmentLinks = issueNumber === ctx.payload.event.issue_number ? buildEnrichmentLinks(ctx) : [];
210723
+ if (commentType === "Plan" || enrichmentLinks.length > 0) {
210724
+ if (commentType === "Plan" && result.data.node_id) {
210614
210725
  await patchWorkflowRunFields(ctx, { planCommentNodeId: result.data.node_id });
210615
210726
  }
210616
- const customParts = [buildImplementPlanLink(ctx, issueNumber, result.data.id)];
210727
+ const customParts = commentType === "Plan" ? [buildImplementPlanLink(ctx, issueNumber, result.data.id)] : enrichmentLinks;
210617
210728
  const footer = buildCommentFooter(ctx, customParts);
210618
- const bodyWithPlanLink = `${stripExistingFooter(body)}${footer}`;
210729
+ const bodyWithPlanLink = `${stripExistingFooter(bodyWithFooter)}${footer}`;
210619
210730
  const updateResult = await ctx.octokit.rest.issues.updateComment({
210620
210731
  owner: ctx.repo.owner,
210621
210732
  repo: ctx.repo.name,
@@ -210687,6 +210798,7 @@ async function reportProgress(ctx, params) {
210687
210798
  }
210688
210799
  const issueNumber = ctx.payload.event.issue_number ?? primaryRepoState(ctx.toolState).issueNumber;
210689
210800
  const isPlanMode = ctx.toolState.selectedMode === "Plan";
210801
+ const enrichmentLinks = params.liveProgress ? [] : buildEnrichmentLinks(ctx);
210690
210802
  const apiCtx = { octokit: ctx.octokit, owner: ctx.repo.owner, repo: ctx.repo.name };
210691
210803
  if (target_plan_comment === true && ctx.toolState.existingPlanCommentId === void 0) {
210692
210804
  log2.warning("target_plan_comment requested but no existingPlanCommentId in tool state");
@@ -210694,7 +210806,7 @@ async function reportProgress(ctx, params) {
210694
210806
  if (target_plan_comment === true && ctx.toolState.existingPlanCommentId !== void 0) {
210695
210807
  const commentId = ctx.toolState.existingPlanCommentId;
210696
210808
  const customParts = issueNumber !== void 0 ? [buildImplementPlanLink(ctx, issueNumber, commentId)] : void 0;
210697
- const bodyWithoutFooter = stripExistingFooter(body);
210809
+ const bodyWithoutFooter = stripExistingFooter(fixDoubleEscapedString(body));
210698
210810
  const footer = buildCommentFooter(ctx, customParts);
210699
210811
  const bodyWithFooter = `${bodyWithoutFooter}${footer}`;
210700
210812
  const result = await updateProgressComment(
@@ -210715,8 +210827,8 @@ async function reportProgress(ctx, params) {
210715
210827
  }
210716
210828
  const existingComment = ctx.toolState.progressComment;
210717
210829
  if (existingComment) {
210718
- const customParts = isPlanMode && issueNumber !== void 0 ? [buildImplementPlanLink(ctx, issueNumber, existingComment.id)] : void 0;
210719
- const bodyWithoutFooter = stripExistingFooter(body);
210830
+ const customParts = isPlanMode && issueNumber !== void 0 ? [buildImplementPlanLink(ctx, issueNumber, existingComment.id)] : enrichmentLinks;
210831
+ const bodyWithoutFooter = stripExistingFooter(fixDoubleEscapedString(body));
210720
210832
  const footer = buildCommentFooter(ctx, customParts);
210721
210833
  const bodyWithFooter = `${bodyWithoutFooter}${footer}`;
210722
210834
  let result;
@@ -210768,13 +210880,13 @@ async function reportProgress(ctx, params) {
210768
210880
  );
210769
210881
  ctx.toolState.progressComment = created.comment;
210770
210882
  if (!params.liveProgress) ctx.toolState.wasUpdated = true;
210771
- if (isPlanMode) {
210772
- const customParts = [buildImplementPlanLink(ctx, issueNumber, created.comment.id)];
210773
- const bodyWithoutFooter = stripExistingFooter(body);
210883
+ if (isPlanMode || enrichmentLinks.length > 0) {
210884
+ const customParts = isPlanMode ? [buildImplementPlanLink(ctx, issueNumber, created.comment.id)] : enrichmentLinks;
210885
+ const bodyWithoutFooter = stripExistingFooter(initialBody);
210774
210886
  const footer = buildCommentFooter(ctx, customParts);
210775
210887
  const bodyWithPlanLink = `${bodyWithoutFooter}${footer}`;
210776
210888
  const updateResult = await updateProgressComment(apiCtx, created.comment, bodyWithPlanLink);
210777
- if (updateResult.node_id) {
210889
+ if (isPlanMode && updateResult.node_id) {
210778
210890
  await patchWorkflowRunFields(ctx, { planCommentNodeId: updateResult.node_id });
210779
210891
  }
210780
210892
  return {
@@ -214689,6 +214801,37 @@ function ResolveReviewThreadTool(ctx) {
214689
214801
  });
214690
214802
  }
214691
214803
 
214804
+ // mcp/searchIssues.ts
214805
+ var SearchIssues = type({
214806
+ terms: type.string.matching(/^[\p{L}\p{N}_./-]+$/u).atMostLength(40).array().atLeastLength(1).atMostLength(5).describe("1-5 keywords from the issue; no GitHub qualifiers or query operators")
214807
+ });
214808
+ function SearchIssuesTool(ctx) {
214809
+ return tool({
214810
+ name: "search_issues",
214811
+ description: "Find open or closed issues in this repository by keyword. Inspect promising matches with get_issue before deciding whether they are duplicates or related. Results are bounded, not an exhaustive duplicate check.",
214812
+ parameters: SearchIssues,
214813
+ execute: execute(async (params) => {
214814
+ const repoPath = `/repos/${ctx.repo.owner}/${ctx.repo.name}`.toLowerCase();
214815
+ const terms = params.terms.map((term) => `"${term}"`).join(" ");
214816
+ const response = await ctx.octokit.rest.search.issuesAndPullRequests({
214817
+ q: `repo:${ctx.repo.owner}/${ctx.repo.name} is:issue ${terms}`,
214818
+ per_page: 20
214819
+ });
214820
+ return {
214821
+ incomplete: response.data.incomplete_results || response.data.total_count > 20,
214822
+ issues: response.data.items.filter(
214823
+ (issue4) => new URL(issue4.repository_url).pathname.toLowerCase() === repoPath && !issue4.pull_request && issue4.number !== ctx.payload.event.issue_number
214824
+ ).map((issue4) => ({
214825
+ number: issue4.number,
214826
+ title: issue4.title,
214827
+ url: issue4.html_url,
214828
+ state: issue4.state
214829
+ }))
214830
+ };
214831
+ })
214832
+ });
214833
+ }
214834
+
214692
214835
  // mcp/selectMode.ts
214693
214836
  var SelectModeParams = type({
214694
214837
  mode: type.string.describe(
@@ -215103,6 +215246,9 @@ function buildCommonTools(ctx, outputSchema) {
215103
215246
  if (hasSimilarIssues({ repoIntelligence: ctx.repoIntelligence, event: ctx.payload.event })) {
215104
215247
  tools.push(SimilarIssuesTool(ctx));
215105
215248
  }
215249
+ if (ctx.payload.event.issue_number !== void 0 && !ctx.payload.event.is_pr) {
215250
+ tools.push(SearchIssuesTool(ctx));
215251
+ }
215106
215252
  const isStandalone = ctx.payload.event.trigger === "unknown";
215107
215253
  if (isStandalone || outputSchema) {
215108
215254
  tools.push(SetOutputTool(ctx, outputSchema));
@@ -216828,7 +216974,6 @@ function buildModelAccessError(input2) {
216828
216974
  }
216829
216975
 
216830
216976
  // utils/normalizeEnv.ts
216831
- var core6 = __toESM(require_core(), 1);
216832
216977
  function hasControlCharacter(value2) {
216833
216978
  return [...value2].some((ch) => {
216834
216979
  const code = ch.charCodeAt(0);
@@ -216854,7 +216999,7 @@ function sanitizeSecret(key, value2) {
216854
216999
  `\xBB stripped whitespace from ${key} (whitespace in secret values breaks GitHub Actions log masking)`
216855
217000
  );
216856
217001
  }
216857
- core6.setSecret(trimmed);
217002
+ maskSecret(trimmed);
216858
217003
  return trimmed;
216859
217004
  }
216860
217005
  function normalizeEnv() {
@@ -216898,7 +217043,6 @@ function normalizeEnv() {
216898
217043
  }
216899
217044
 
216900
217045
  // utils/overrides.ts
216901
- var core7 = __toESM(require_core(), 1);
216902
217046
  var DENIED_OVERRIDE_NAMES = /* @__PURE__ */ new Set([
216903
217047
  "GITHUB_TOKEN",
216904
217048
  "GH_TOKEN",
@@ -216944,7 +217088,7 @@ function applyOverrides(params) {
216944
217088
  denied.push(key);
216945
217089
  continue;
216946
217090
  }
216947
- if (value2.length > 0) core7.setSecret(value2);
217091
+ if (value2.length > 0) maskSecret(value2);
216948
217092
  params.env[key] = value2;
216949
217093
  applied.push(key);
216950
217094
  }
@@ -216953,7 +217097,7 @@ function applyOverrides(params) {
216953
217097
  }
216954
217098
 
216955
217099
  // utils/payload.ts
216956
- var core8 = __toESM(require_core(), 1);
217100
+ var core5 = __toESM(require_core(), 1);
216957
217101
  import { readFileSync as readFileSync9 } from "node:fs";
216958
217102
  import { isAbsolute as isAbsolute2, resolve as resolve2 } from "node:path";
216959
217103
 
@@ -217096,8 +217240,8 @@ function assertDispatchPayloadIntact(promptInput) {
217096
217240
  );
217097
217241
  }
217098
217242
  function resolvePromptInput() {
217099
- const promptInput = core8.getInput("prompt");
217100
- const promptFile = core8.getInput("prompt_file");
217243
+ const promptInput = core5.getInput("prompt");
217244
+ const promptFile = core5.getInput("prompt_file");
217101
217245
  if (promptInput && promptFile) {
217102
217246
  throw new Error("set exactly one of 'prompt' or 'prompt_file' inputs, not both.");
217103
217247
  }
@@ -217131,7 +217275,7 @@ function resolvePromptFile(input2) {
217131
217275
  }
217132
217276
  function warnIfDeprecatedStatusChecks(value2) {
217133
217277
  if (value2 !== void 0) {
217134
- core8.warning(
217278
+ core5.warning(
217135
217279
  "`status_checks` is deprecated. Both checks are now repository settings \u2014 open the Pullfrog console for this repo (Automations \u2192 Review PRs) and set them there, then remove `status_checks` from your workflow. It keeps working until you do."
217136
217280
  );
217137
217281
  }
@@ -217139,15 +217283,15 @@ function warnIfDeprecatedStatusChecks(value2) {
217139
217283
  }
217140
217284
  function resolveNonPromptInputs() {
217141
217285
  return Inputs.omit("prompt", "prompt_file").assert({
217142
- model: core8.getInput("model") || void 0,
217143
- effort: core8.getInput("effort") || void 0,
217144
- debug: core8.getInput("debug") || void 0,
217145
- timeout: core8.getInput("timeout") || void 0,
217146
- cwd: core8.getInput("cwd") || void 0,
217147
- push: core8.getInput("push") || void 0,
217148
- shell: core8.getInput("shell") || void 0,
217149
- status_checks: warnIfDeprecatedStatusChecks(core8.getInput("status_checks") || void 0),
217150
- progress_comments: core8.getInput("progress_comments") || void 0
217286
+ model: core5.getInput("model") || void 0,
217287
+ effort: core5.getInput("effort") || void 0,
217288
+ debug: core5.getInput("debug") || void 0,
217289
+ timeout: core5.getInput("timeout") || void 0,
217290
+ cwd: core5.getInput("cwd") || void 0,
217291
+ push: core5.getInput("push") || void 0,
217292
+ shell: core5.getInput("shell") || void 0,
217293
+ status_checks: warnIfDeprecatedStatusChecks(core5.getInput("status_checks") || void 0),
217294
+ progress_comments: core5.getInput("progress_comments") || void 0
217151
217295
  });
217152
217296
  }
217153
217297
  function resolvePayload(resolvedPromptInput, repoSettings) {
@@ -217218,7 +217362,7 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
217218
217362
  };
217219
217363
  }
217220
217364
  function resolveOutputSchema() {
217221
- const raw2 = core8.getInput("output_schema");
217365
+ const raw2 = core5.getInput("output_schema");
217222
217366
  if (!raw2) return void 0;
217223
217367
  let parsed2;
217224
217368
  try {
@@ -217233,11 +217377,8 @@ function resolveOutputSchema() {
217233
217377
  return parsed2;
217234
217378
  }
217235
217379
 
217236
- // utils/proxy.ts
217237
- var core10 = __toESM(require_core(), 1);
217238
-
217239
217380
  // utils/token.ts
217240
- var core9 = __toESM(require_core(), 1);
217381
+ var core6 = __toESM(require_core(), 1);
217241
217382
  import assert3 from "node:assert/strict";
217242
217383
  var mcpTokenValue;
217243
217384
  var refreshMcpTokenFn;
@@ -217245,7 +217386,7 @@ function getMcpTokenRefresh() {
217245
217386
  return refreshMcpTokenFn;
217246
217387
  }
217247
217388
  function getJobToken() {
217248
- const inputToken = core9.getInput("token");
217389
+ const inputToken = core6.getInput("token");
217249
217390
  if (inputToken) {
217250
217391
  return inputToken;
217251
217392
  }
@@ -217260,9 +217401,7 @@ async function resolveTokens(params) {
217260
217401
  const externalToken = process.env.GH_TOKEN;
217261
217402
  if (externalToken) {
217262
217403
  mcpTokenValue = externalToken;
217263
- if (isGitHubActions) {
217264
- core9.setSecret(externalToken);
217265
- }
217404
+ maskSecret(externalToken);
217266
217405
  log2.info("\xBB using external GH_TOKEN for both git and MCP");
217267
217406
  return {
217268
217407
  gitToken: externalToken,
@@ -217284,9 +217423,7 @@ async function resolveTokens(params) {
217284
217423
  xrepoGrant: params.xrepoGrant,
217285
217424
  permissions: gitPermissions
217286
217425
  });
217287
- if (isGitHubActions) {
217288
- core9.setSecret(gitToken);
217289
- }
217426
+ maskSecret(gitToken);
217290
217427
  log2.info(
217291
217428
  `\xBB acquired git token (${Object.entries(gitPermissions).map((e) => e.join(":")).join(", ")})`
217292
217429
  );
@@ -217305,9 +217442,7 @@ async function resolveTokens(params) {
217305
217442
  xrepoGrant: params.xrepoGrant,
217306
217443
  permissions: mcpPermissions
217307
217444
  });
217308
- if (isGitHubActions) {
217309
- core9.setSecret(mcpToken);
217310
- }
217445
+ maskSecret(mcpToken);
217311
217446
  log2.info(
217312
217447
  `\xBB acquired scoped MCP token (${Object.entries(mcpPermissions).map((e) => e.join(":")).join(", ")})`
217313
217448
  );
@@ -217315,7 +217450,7 @@ async function resolveTokens(params) {
217315
217450
  let ghToken;
217316
217451
  if (ghPermissions) {
217317
217452
  ghToken = await acquireNewToken({ permissions: ghPermissions });
217318
- if (isGitHubActions) core9.setSecret(ghToken);
217453
+ maskSecret(ghToken);
217319
217454
  log2.info(
217320
217455
  `\xBB acquired gh token mirroring ${params.authorPermission} (${formatPermissions(ghPermissions)})`
217321
217456
  );
@@ -217327,7 +217462,7 @@ async function resolveTokens(params) {
217327
217462
  xrepoGrant: params.xrepoGrant,
217328
217463
  permissions: { contents: "read" }
217329
217464
  });
217330
- if (isGitHubActions) core9.setSecret(readToken);
217465
+ maskSecret(readToken);
217331
217466
  log2.info(`\xBB acquired cross-repo read token (contents:read, ${params.xrepo.read.length} repos)`);
217332
217467
  }
217333
217468
  mcpTokenValue = mcpToken;
@@ -217346,9 +217481,7 @@ async function resolveTokens(params) {
217346
217481
  permissions: mcpPermissions,
217347
217482
  oidc: params.oidc ?? void 0
217348
217483
  }).then((fresh) => {
217349
- if (isGitHubActions) {
217350
- core9.setSecret(fresh);
217351
- }
217484
+ maskSecret(fresh);
217352
217485
  mcpTokenValue = fresh;
217353
217486
  currentMcpToken = fresh;
217354
217487
  log2.warning("\xBB GitHub rejected the MCP token; re-acquired a fresh scoped MCP token");
@@ -217369,7 +217502,7 @@ async function resolveTokens(params) {
217369
217502
  permissions: gitPermissions,
217370
217503
  oidc: params.oidc ?? void 0
217371
217504
  }).then((fresh) => {
217372
- if (isGitHubActions) core9.setSecret(fresh);
217505
+ maskSecret(fresh);
217373
217506
  void revokeGitHubInstallationToken(currentGitToken);
217374
217507
  currentGitToken = fresh;
217375
217508
  log2.warning("\xBB GitHub rejected the git token; re-acquired a fresh git token");
@@ -217387,7 +217520,7 @@ async function resolveTokens(params) {
217387
217520
  permissions: { contents: "read" },
217388
217521
  oidc: params.oidc ?? void 0
217389
217522
  }).then((fresh) => {
217390
- if (isGitHubActions) core9.setSecret(fresh);
217523
+ maskSecret(fresh);
217391
217524
  void revokeGitHubInstallationToken(read2);
217392
217525
  currentReadToken = fresh;
217393
217526
  log2.warning("\xBB GitHub rejected the read token; re-acquired a fresh read token");
@@ -217601,7 +217734,7 @@ async function resolveProxyModel(ctx) {
217601
217734
  });
217602
217735
  if (!key) return;
217603
217736
  process.env.OPENROUTER_API_KEY = key;
217604
- core10.setSecret(key);
217737
+ maskSecret(key);
217605
217738
  ctx.payload.proxyModel = ctx.proxyModel;
217606
217739
  ctx.toolState.model = ctx.proxyModel;
217607
217740
  const label = ctx.oss ? "oss" : "router";
@@ -217679,7 +217812,7 @@ async function resolveTrialFallback(ctx) {
217679
217812
  });
217680
217813
  if (!key) return false;
217681
217814
  process.env.OPENROUTER_API_KEY = key;
217682
- core10.setSecret(key);
217815
+ maskSecret(key);
217683
217816
  ctx.payload.proxyModel = DEFAULT_PROXY_MODEL;
217684
217817
  ctx.toolState.model = DEFAULT_PROXY_MODEL;
217685
217818
  ctx.toolState.modelClamped = {
@@ -217830,6 +217963,7 @@ var defaultSettings = {
217830
217963
  push: "restricted",
217831
217964
  shell: "restricted",
217832
217965
  prApproveEnabled: false,
217966
+ reviewDrafts: false,
217833
217967
  autoMergeEnabled: false,
217834
217968
  codexAgent: false,
217835
217969
  signedCommits: false,
@@ -218076,6 +218210,23 @@ function isContextOverflowError(message) {
218076
218210
  function isNoProviderAvailableError(message) {
218077
218211
  return /\bNo provider available\b/i.test(message);
218078
218212
  }
218213
+ function isZenFreeTierGateError(message) {
218214
+ return /free tier can only be used from within OpenCode/i.test(message);
218215
+ }
218216
+ function formatZenFreeTierGateSummary(input2) {
218217
+ const settingsUrl = `${getApiUrl()}/console/${input2.owner}/${input2.name}`;
218218
+ return [
218219
+ "**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.",
218220
+ "",
218221
+ '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.',
218222
+ "",
218223
+ `[Model settings \u2192](${settingsUrl}) \xB7 [Ask in Discord \u2192](https://discord.gg/8y96raFg8e)`,
218224
+ "",
218225
+ `\`\`\`
218226
+ ${input2.raw}
218227
+ \`\`\``
218228
+ ].join("\n");
218229
+ }
218079
218230
  function formatNoProviderAvailableSummary(input2) {
218080
218231
  const settingsUrl = `${getApiUrl()}/console/${input2.owner}/${input2.name}`;
218081
218232
  return [
@@ -218319,6 +218470,16 @@ ${body}`, comment: body };
218319
218470
  });
218320
218471
  return { summary: `### \u274C Pullfrog failed
218321
218472
 
218473
+ ${body}`, comment: body };
218474
+ }
218475
+ if (isZenFreeTierGateError(input2.errorMessage)) {
218476
+ const body = formatZenFreeTierGateSummary({
218477
+ owner: input2.repo.owner,
218478
+ name: input2.repo.name,
218479
+ raw: input2.errorMessage
218480
+ });
218481
+ return { summary: `### \u274C Pullfrog failed
218482
+
218322
218483
  ${body}`, comment: body };
218323
218484
  }
218324
218485
  if (isContextOverflowError(input2.errorMessage)) {
@@ -218356,7 +218517,7 @@ ${genericBody}`,
218356
218517
  }
218357
218518
 
218358
218519
  // utils/runLifecycle.ts
218359
- var core11 = __toESM(require_core(), 1);
218520
+ var core7 = __toESM(require_core(), 1);
218360
218521
 
218361
218522
  // utils/autoMerge.ts
218362
218523
  function hasBlockingHumanReview(reviews) {
@@ -218500,7 +218661,7 @@ async function dispatchFollowUpReReview(ctx, reviewedSha) {
218500
218661
  });
218501
218662
  if (pr.data.head.sha === reviewedSha) return;
218502
218663
  if (pr.data.state !== "open") return;
218503
- if (pr.data.draft) return;
218664
+ if (pr.data.draft && !ctx.reviewDrafts) return;
218504
218665
  log2.info(
218505
218666
  `safety net: pr HEAD moved from ${reviewedSha.slice(0, 7)} to ${pr.data.head.sha.slice(0, 7)} and agent did not review inline \u2014 dispatching follow-up re-review`
218506
218667
  );
@@ -218752,7 +218913,7 @@ async function finalizeSuccessRun(input2) {
218752
218913
  }
218753
218914
  if (input2.toolState.output) {
218754
218915
  log2.info(`::pullfrog-output::${Buffer.from(input2.toolState.output).toString("base64")}`);
218755
- core11.setOutput("result", input2.toolState.output);
218916
+ core7.setOutput("result", input2.toolState.output);
218756
218917
  }
218757
218918
  if (input2.result.success) {
218758
218919
  await approveAfterFix(input2.toolContext).catch((error109) => {
@@ -219333,6 +219494,7 @@ async function main() {
219333
219494
  postCheckoutScript: runContext.repoSettings.postCheckoutScript,
219334
219495
  prepushScript: runContext.repoSettings.prepushScript,
219335
219496
  prApproveEnabled: runContext.repoSettings.prApproveEnabled,
219497
+ reviewDrafts: runContext.repoSettings.reviewDrafts,
219336
219498
  autoMergeEnabled: runContext.repoSettings.autoMergeEnabled,
219337
219499
  signedCommits: runContext.repoSettings.signedCommits,
219338
219500
  repoIntelligence: runContext.repoSettings.repoIntelligence,
@@ -219643,27 +219805,27 @@ async function runMain() {
219643
219805
  }
219644
219806
  } catch (error109) {
219645
219807
  const errorMessage = error109 instanceof Error ? error109.message : "unknown error occurred";
219646
- core12.setFailed(`action failed: ${errorMessage}`);
219808
+ core8.setFailed(`action failed: ${errorMessage}`);
219647
219809
  }
219648
219810
  }
219649
219811
  async function tokenMain() {
219650
- const reposInput = core12.getInput("repos");
219812
+ const reposInput = core8.getInput("repos");
219651
219813
  const additionalRepos = reposInput ? reposInput.split(",").map((r2) => r2.trim()).filter(Boolean) : [];
219652
219814
  const token = await acquireNewToken({ repos: additionalRepos });
219653
- core12.setSecret(token);
219654
- core12.saveState(STATE_TOKEN, token);
219655
- core12.setOutput("token", token);
219815
+ maskSecret(token);
219816
+ saveSecretState(STATE_TOKEN, token);
219817
+ setSecretOutput("token", token);
219656
219818
  const scope2 = additionalRepos.length ? `current repo + ${additionalRepos.join(", ")}` : "current repo only";
219657
- core12.info(`\xBB installation token acquired (${scope2})`);
219819
+ core8.info(`\xBB installation token acquired (${scope2})`);
219658
219820
  }
219659
219821
  async function tokenPost() {
219660
- const token = core12.getState(STATE_TOKEN);
219822
+ const token = core8.getState(STATE_TOKEN);
219661
219823
  if (!token) {
219662
- core12.debug("no token found in state, skipping revocation");
219824
+ core8.debug("no token found in state, skipping revocation");
219663
219825
  return;
219664
219826
  }
219665
219827
  await revokeGitHubInstallationToken(token);
219666
- core12.info("\xBB installation token revoked");
219828
+ core8.info("\xBB installation token revoked");
219667
219829
  }
219668
219830
  function printGhaUsage(params) {
219669
219831
  params.stream(`usage: ${params.prog} gha [subcommand]
@@ -219770,7 +219932,7 @@ async function runCli5(params) {
219770
219932
  }
219771
219933
  async function run(args2) {
219772
219934
  if (args2.includes("--post") && !args2.includes("token")) {
219773
- await runOAuthWriteback().catch((error109) => core12.warning(`oauth post-hook: ${error109}`));
219935
+ await runOAuthWriteback().catch((error109) => core8.warning(`oauth post-hook: ${error109}`));
219774
219936
  return;
219775
219937
  }
219776
219938
  try {
@@ -219785,7 +219947,7 @@ async function run(args2) {
219785
219947
  }
219786
219948
  } catch (error109) {
219787
219949
  const message = error109 instanceof Error ? error109.message : String(error109);
219788
- core12.setFailed(message);
219950
+ core8.setFailed(message);
219789
219951
  }
219790
219952
  }
219791
219953
 
@@ -220172,7 +220334,7 @@ function resolveTarget2(repo) {
220172
220334
  return { owner: match3[1], repo: match3[2] };
220173
220335
  }
220174
220336
  function cliVersion() {
220175
- const parts = /^(\d+)\.(\d+)\.(\d+)$/.exec("0.1.81");
220337
+ const parts = /^(\d+)\.(\d+)\.(\d+)$/.exec("0.1.83");
220176
220338
  if (!parts) return "0.0.0";
220177
220339
  return `${Number(parts[1])}.${Number(parts[2])}.${Number(parts[3])}`;
220178
220340
  }
@@ -220339,7 +220501,7 @@ async function runCli8(input2) {
220339
220501
  }
220340
220502
 
220341
220503
  // cli.ts
220342
- var VERSION10 = "0.1.81";
220504
+ var VERSION10 = "0.1.83";
220343
220505
  var bin = basename2(process.argv[1] || "");
220344
220506
  var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
220345
220507
  var rawArgs = process.argv.slice(2);
@@ -220495,7 +220657,7 @@ ieee754/index.js:
220495
220657
  * MIT Licensed
220496
220658
  *)
220497
220659
 
220498
- mcp-proxy/dist/startStdioServer-C4sEMMHS.mjs:
220660
+ mcp-proxy/dist/startStdioServer-C9HzKfjR.mjs:
220499
220661
  (*!
220500
220662
  * content-type
220501
220663
  * Copyright(c) 2015 Douglas Christopher Wilson