pullfrog 0.1.3 → 0.1.5

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
@@ -108238,8 +108238,7 @@ var providers = {
108238
108238
  "gpt-5-nano": {
108239
108239
  displayName: "GPT Nano",
108240
108240
  resolve: "opencode/gpt-5-nano",
108241
- envVars: [],
108242
- isFree: true
108241
+ openRouterResolve: "openrouter/openai/gpt-5-nano"
108243
108242
  },
108244
108243
  "mimo-v2-pro-free": {
108245
108244
  displayName: "MiMo V2 Pro",
@@ -108468,6 +108467,11 @@ async function apiFetch(options) {
108468
108467
  if (bypassSecret) {
108469
108468
  headers["x-vercel-protection-bypass"] = bypassSecret;
108470
108469
  }
108470
+ if (!options.body) {
108471
+ for (const key of Object.keys(headers)) {
108472
+ if (key.toLowerCase() === "content-type") delete headers[key];
108473
+ }
108474
+ }
108471
108475
  log.debug(`api fetch: ${options.method ?? "GET"} ${url4.pathname}`);
108472
108476
  const init = {
108473
108477
  method: options.method ?? "GET",
@@ -109156,8 +109160,11 @@ function sanitizeToolForGemini(tool2) {
109156
109160
  }
109157
109161
  function isGeminiRouted(ctx) {
109158
109162
  const effective = ctx.payload.proxyModel ?? ctx.resolvedModel ?? ctx.payload.model;
109159
- if (!effective) return false;
109160
- return effective.toLowerCase().includes("gemini");
109163
+ if (!effective) return true;
109164
+ const normalized = effective.toLowerCase();
109165
+ if (normalized.includes("gemini")) return true;
109166
+ if (!normalized.includes("/")) return true;
109167
+ return false;
109161
109168
  }
109162
109169
 
109163
109170
  // mcp/shared.ts
@@ -142589,7 +142596,7 @@ var import_semver = __toESM(require_semver2(), 1);
142589
142596
  // package.json
142590
142597
  var package_default = {
142591
142598
  name: "pullfrog",
142592
- version: "0.1.3",
142599
+ version: "0.1.5",
142593
142600
  type: "module",
142594
142601
  bin: {
142595
142602
  pullfrog: "dist/cli.mjs",
@@ -147478,8 +147485,7 @@ function stripProviderPrefix(specifier) {
147478
147485
  const slashIndex = specifier.indexOf("/");
147479
147486
  return slashIndex > 0 ? specifier.slice(slashIndex + 1) : specifier;
147480
147487
  }
147481
- function resolveEffort(model) {
147482
- if (model?.includes("opus")) return "max";
147488
+ function resolveEffort(_model) {
147483
147489
  return "high";
147484
147490
  }
147485
147491
  function tailLines(text, maxCodeUnits) {
@@ -152964,6 +152970,7 @@ function buildRuntimeContext(ctx) {
152964
152970
  "~pullfrog": _2,
152965
152971
  prompt: _p,
152966
152972
  eventInstructions: _ei,
152973
+ previousRunsNote: _prn,
152967
152974
  event: _e2,
152968
152975
  ...payloadRest
152969
152976
  } = ctx.payload;
@@ -153044,14 +153051,16 @@ In case of conflict between instructions, follow this precedence (highest to low
153044
153051
  2. User prompt
153045
153052
  3. Event-level instructions`;
153046
153053
  function buildTaskSection(ctx) {
153054
+ const previousRunsNote = ctx.payload.previousRunsNote?.trim() ?? "";
153047
153055
  if (ctx.userQuoted) {
153056
+ const parts = [ctx.userQuoted, previousRunsNote].filter(Boolean);
153048
153057
  return `************* YOUR TASK *************
153049
153058
 
153050
- ${ctx.userQuoted}`;
153059
+ ${parts.join("\n\n")}`;
153051
153060
  }
153052
153061
  const eventInstructions = ctx.payload.eventInstructions ?? "";
153053
- if (eventInstructions) {
153054
- const parts = [ctx.eventTitle, eventInstructions].filter(Boolean);
153062
+ if (eventInstructions || previousRunsNote) {
153063
+ const parts = [ctx.eventTitle, eventInstructions, previousRunsNote].filter(Boolean);
153055
153064
  return `************* YOUR TASK *************
153056
153065
 
153057
153066
  ${parts.join("\n\n")}`;
@@ -153366,6 +153375,7 @@ var JsonPayload = type({
153366
153375
  prompt: "string",
153367
153376
  "triggerer?": "string | undefined",
153368
153377
  "eventInstructions?": "string",
153378
+ "previousRunsNote?": "string",
153369
153379
  "event?": "object",
153370
153380
  "timeout?": "string | undefined",
153371
153381
  "progressComment?": type({
@@ -153451,6 +153461,7 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
153451
153461
  triggerer: jsonPayload?.triggerer ?? // it's not a common use case but GITHUB_ACTOR can be a user when the workflow is manually triggered by a user through GitHub Actions UI
153452
153462
  (!isPullfrog(process.env.GITHUB_ACTOR) ? process.env.GITHUB_ACTOR : void 0),
153453
153463
  eventInstructions: jsonPayload?.eventInstructions,
153464
+ previousRunsNote: jsonPayload?.previousRunsNote,
153454
153465
  event,
153455
153466
  timeout: inputs.timeout ?? jsonPayload?.timeout,
153456
153467
  cwd: resolveCwd(inputs.cwd),
@@ -153632,8 +153643,7 @@ async function fetchRunContext(params) {
153632
153643
  const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
153633
153644
  try {
153634
153645
  const headers = {
153635
- Authorization: `Bearer ${params.token}`,
153636
- "Content-Type": "application/json"
153646
+ Authorization: `Bearer ${params.token}`
153637
153647
  };
153638
153648
  if (params.oidcToken) {
153639
153649
  headers["X-GitHub-OIDC-Token"] = params.oidcToken;
@@ -154049,7 +154059,7 @@ function formatBillingErrorSummary(error49, owner) {
154049
154059
  return [
154050
154060
  "**Add a card to start using Pullfrog Router.**",
154051
154061
  "",
154052
- "Router proxies OpenRouter at raw cost \u2014 no platform markup, and your first $20 of usage is on us.",
154062
+ "Router proxies OpenRouter at raw cost \u2014 no platform markup. Add a card and we'll auto-reload your wallet so runs keep flowing.",
154053
154063
  "",
154054
154064
  `[Add a card \u2192](${billingConsoleUrl(owner, "model-access")})`
154055
154065
  ].join("\n");
@@ -154225,12 +154235,12 @@ async function persistLearnings(ctx) {
154225
154235
  });
154226
154236
  if (!response.ok) {
154227
154237
  const error49 = await response.text().catch(() => "(no body)");
154228
- log.debug(`learnings persist failed (${response.status}): ${error49}`);
154238
+ log.warning(`learnings persist failed (${response.status}): ${error49}`);
154229
154239
  return;
154230
154240
  }
154231
154241
  log.info("\xBB learnings updated");
154232
154242
  } catch (err) {
154233
- log.debug(`learnings persist failed: ${err instanceof Error ? err.message : String(err)}`);
154243
+ log.warning(`learnings persist failed: ${err instanceof Error ? err.message : String(err)}`);
154234
154244
  }
154235
154245
  }
154236
154246
  async function persistSummary(ctx) {
@@ -156513,7 +156523,7 @@ async function run2() {
156513
156523
  }
156514
156524
 
156515
156525
  // cli.ts
156516
- var VERSION10 = "0.1.3";
156526
+ var VERSION10 = "0.1.5";
156517
156527
  var bin = basename2(process.argv[1] || "");
156518
156528
  var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
156519
156529
  var rawArgs = process.argv.slice(2);
@@ -201,6 +201,13 @@ export interface WriteablePayload {
201
201
  triggerer?: string | undefined;
202
202
  /** event-level instructions for this trigger type (flag-expanded server-side) */
203
203
  eventInstructions?: string | undefined;
204
+ /**
205
+ * system-injected note about prior superseded runs (e.g. when the
206
+ * triggering @pullfrog comment is edited). rendered alongside the user's
207
+ * prompt rather than via eventInstructions so it survives user-prompt
208
+ * precedence.
209
+ */
210
+ previousRunsNote?: string | undefined;
204
211
  /** event data from webhook payload - discriminated union based on trigger field */
205
212
  event: PayloadEvent;
206
213
  /** timeout for agent run (e.g., "10m", "1h30m") - defaults to "1h" */
package/dist/index.js CHANGED
@@ -107955,8 +107955,7 @@ var providers = {
107955
107955
  "gpt-5-nano": {
107956
107956
  displayName: "GPT Nano",
107957
107957
  resolve: "opencode/gpt-5-nano",
107958
- envVars: [],
107959
- isFree: true
107958
+ openRouterResolve: "openrouter/openai/gpt-5-nano"
107960
107959
  },
107961
107960
  "mimo-v2-pro-free": {
107962
107961
  displayName: "MiMo V2 Pro",
@@ -108185,6 +108184,11 @@ async function apiFetch(options) {
108185
108184
  if (bypassSecret) {
108186
108185
  headers["x-vercel-protection-bypass"] = bypassSecret;
108187
108186
  }
108187
+ if (!options.body) {
108188
+ for (const key of Object.keys(headers)) {
108189
+ if (key.toLowerCase() === "content-type") delete headers[key];
108190
+ }
108191
+ }
108188
108192
  log.debug(`api fetch: ${options.method ?? "GET"} ${url4.pathname}`);
108189
108193
  const init = {
108190
108194
  method: options.method ?? "GET",
@@ -108873,8 +108877,11 @@ function sanitizeToolForGemini(tool2) {
108873
108877
  }
108874
108878
  function isGeminiRouted(ctx) {
108875
108879
  const effective = ctx.payload.proxyModel ?? ctx.resolvedModel ?? ctx.payload.model;
108876
- if (!effective) return false;
108877
- return effective.toLowerCase().includes("gemini");
108880
+ if (!effective) return true;
108881
+ const normalized = effective.toLowerCase();
108882
+ if (normalized.includes("gemini")) return true;
108883
+ if (!normalized.includes("/")) return true;
108884
+ return false;
108878
108885
  }
108879
108886
 
108880
108887
  // mcp/shared.ts
@@ -142306,7 +142313,7 @@ var import_semver = __toESM(require_semver2(), 1);
142306
142313
  // package.json
142307
142314
  var package_default = {
142308
142315
  name: "pullfrog",
142309
- version: "0.1.3",
142316
+ version: "0.1.5",
142310
142317
  type: "module",
142311
142318
  bin: {
142312
142319
  pullfrog: "dist/cli.mjs",
@@ -147195,8 +147202,7 @@ function stripProviderPrefix(specifier) {
147195
147202
  const slashIndex = specifier.indexOf("/");
147196
147203
  return slashIndex > 0 ? specifier.slice(slashIndex + 1) : specifier;
147197
147204
  }
147198
- function resolveEffort(model) {
147199
- if (model?.includes("opus")) return "max";
147205
+ function resolveEffort(_model) {
147200
147206
  return "high";
147201
147207
  }
147202
147208
  function tailLines(text, maxCodeUnits) {
@@ -152681,6 +152687,7 @@ function buildRuntimeContext(ctx) {
152681
152687
  "~pullfrog": _,
152682
152688
  prompt: _p,
152683
152689
  eventInstructions: _ei,
152690
+ previousRunsNote: _prn,
152684
152691
  event: _e,
152685
152692
  ...payloadRest
152686
152693
  } = ctx.payload;
@@ -152761,14 +152768,16 @@ In case of conflict between instructions, follow this precedence (highest to low
152761
152768
  2. User prompt
152762
152769
  3. Event-level instructions`;
152763
152770
  function buildTaskSection(ctx) {
152771
+ const previousRunsNote = ctx.payload.previousRunsNote?.trim() ?? "";
152764
152772
  if (ctx.userQuoted) {
152773
+ const parts = [ctx.userQuoted, previousRunsNote].filter(Boolean);
152765
152774
  return `************* YOUR TASK *************
152766
152775
 
152767
- ${ctx.userQuoted}`;
152776
+ ${parts.join("\n\n")}`;
152768
152777
  }
152769
152778
  const eventInstructions = ctx.payload.eventInstructions ?? "";
152770
- if (eventInstructions) {
152771
- const parts = [ctx.eventTitle, eventInstructions].filter(Boolean);
152779
+ if (eventInstructions || previousRunsNote) {
152780
+ const parts = [ctx.eventTitle, eventInstructions, previousRunsNote].filter(Boolean);
152772
152781
  return `************* YOUR TASK *************
152773
152782
 
152774
152783
  ${parts.join("\n\n")}`;
@@ -153083,6 +153092,7 @@ var JsonPayload = type({
153083
153092
  prompt: "string",
153084
153093
  "triggerer?": "string | undefined",
153085
153094
  "eventInstructions?": "string",
153095
+ "previousRunsNote?": "string",
153086
153096
  "event?": "object",
153087
153097
  "timeout?": "string | undefined",
153088
153098
  "progressComment?": type({
@@ -153168,6 +153178,7 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
153168
153178
  triggerer: jsonPayload?.triggerer ?? // it's not a common use case but GITHUB_ACTOR can be a user when the workflow is manually triggered by a user through GitHub Actions UI
153169
153179
  (!isPullfrog(process.env.GITHUB_ACTOR) ? process.env.GITHUB_ACTOR : void 0),
153170
153180
  eventInstructions: jsonPayload?.eventInstructions,
153181
+ previousRunsNote: jsonPayload?.previousRunsNote,
153171
153182
  event,
153172
153183
  timeout: inputs.timeout ?? jsonPayload?.timeout,
153173
153184
  cwd: resolveCwd(inputs.cwd),
@@ -153349,8 +153360,7 @@ async function fetchRunContext(params) {
153349
153360
  const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
153350
153361
  try {
153351
153362
  const headers = {
153352
- Authorization: `Bearer ${params.token}`,
153353
- "Content-Type": "application/json"
153363
+ Authorization: `Bearer ${params.token}`
153354
153364
  };
153355
153365
  if (params.oidcToken) {
153356
153366
  headers["X-GitHub-OIDC-Token"] = params.oidcToken;
@@ -153766,7 +153776,7 @@ function formatBillingErrorSummary(error49, owner) {
153766
153776
  return [
153767
153777
  "**Add a card to start using Pullfrog Router.**",
153768
153778
  "",
153769
- "Router proxies OpenRouter at raw cost \u2014 no platform markup, and your first $20 of usage is on us.",
153779
+ "Router proxies OpenRouter at raw cost \u2014 no platform markup. Add a card and we'll auto-reload your wallet so runs keep flowing.",
153770
153780
  "",
153771
153781
  `[Add a card \u2192](${billingConsoleUrl(owner, "model-access")})`
153772
153782
  ].join("\n");
@@ -153942,12 +153952,12 @@ async function persistLearnings(ctx) {
153942
153952
  });
153943
153953
  if (!response.ok) {
153944
153954
  const error49 = await response.text().catch(() => "(no body)");
153945
- log.debug(`learnings persist failed (${response.status}): ${error49}`);
153955
+ log.warning(`learnings persist failed (${response.status}): ${error49}`);
153946
153956
  return;
153947
153957
  }
153948
153958
  log.info("\xBB learnings updated");
153949
153959
  } catch (err) {
153950
- log.debug(`learnings persist failed: ${err instanceof Error ? err.message : String(err)}`);
153960
+ log.warning(`learnings persist failed: ${err instanceof Error ? err.message : String(err)}`);
153951
153961
  }
153952
153962
  }
153953
153963
  async function persistSummary(ctx) {
package/dist/internal.js CHANGED
@@ -224,8 +224,7 @@ var providers = {
224
224
  "gpt-5-nano": {
225
225
  displayName: "GPT Nano",
226
226
  resolve: "opencode/gpt-5-nano",
227
- envVars: [],
228
- isFree: true
227
+ openRouterResolve: "openrouter/openai/gpt-5-nano"
229
228
  },
230
229
  "mimo-v2-pro-free": {
231
230
  displayName: "MiMo V2 Pro",
@@ -9,9 +9,20 @@ export declare function sanitizeForGemini(schema: unknown): unknown;
9
9
  export declare function wrapSchemaForGemini(schema: StandardSchemaV1<any>): StandardSchemaV1<any>;
10
10
  export declare function sanitizeToolForGemini<T extends Tool<any, any>>(tool: T): T;
11
11
  /**
12
- * true when the effective upstream model is served by google's generative
13
- * language API directly (`google/*`), via opencode (`opencode/gemini-*`),
14
- * or via openrouter (`openrouter/google/gemini-*`). slug-substring match
15
- * works because every gemini route's model id contains "gemini".
12
+ * true when the effective upstream model is or might become — google
13
+ * generative language API traffic. matches:
14
+ * - direct `google/*`, opencode `opencode/gemini-*`, openrouter
15
+ * `openrouter/google/gemini-*` (slug substring "gemini" wins).
16
+ * - any unresolved specifier: `undefined`, `"auto"`, or a slug that
17
+ * didn't map through the alias registry (no `provider/` prefix).
18
+ * these flow through the agent's own auto-select, which may land
19
+ * on gemini *after* the MCP server has already registered tools —
20
+ * at which point sanitization is too late to apply. erring on the
21
+ * side of sanitizing is safe: cases 1 + 2 are universally
22
+ * compatible JSON-Schema normalizations (enum-only → typed string,
23
+ * collapsible const-unions → string enum); case 3 is gemini-
24
+ * specific but only fires on non-collapsible unions, which arktype
25
+ * does not emit for our current tool schemas. see issue #676 for
26
+ * the prod failure that motivated this widening.
16
27
  */
17
28
  export declare function isGeminiRouted(ctx: ToolContext): boolean;
@@ -7,6 +7,7 @@ export declare const JsonPayload: import("arktype/internal/variants/object.ts").
7
7
  model?: string | undefined;
8
8
  triggerer?: string | undefined;
9
9
  eventInstructions?: string;
10
+ previousRunsNote?: string;
10
11
  event?: object;
11
12
  timeout?: string | undefined;
12
13
  progressComment?: {
@@ -34,6 +35,7 @@ export declare function resolvePayload(resolvedPromptInput: ResolvedPromptInput,
34
35
  prompt: string;
35
36
  triggerer: string | undefined;
36
37
  eventInstructions: string | undefined;
38
+ previousRunsNote: string | undefined;
37
39
  event: PayloadEvent;
38
40
  timeout: string | undefined;
39
41
  cwd: string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pullfrog",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "pullfrog": "dist/cli.mjs",