pullfrog 0.1.95 → 0.1.96

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.
@@ -6,7 +6,7 @@ export { CLI_CONTRACT_HEADER, CLI_CONTRACT_VERSION, CLI_UPGRADE_MESSAGE } from "
6
6
  export type { ConfigField, ConfigScope, ConfigValue } from "../configuration.ts";
7
7
  export { configEntrySchema, configFields, configResponseSchema, configValueSchema, } from "../configuration.ts";
8
8
  export type { AuthorPermission, AutoTier, EffortPosition, ModelAlias, ModelProvider, Payload, PayloadEvent, PayloadRouting, ProviderConfig, PushPermission, RouterSource, RouterTier, ShellPermission, ToolPermission, WriteablePayload, XrepoConfig, } from "../external.ts";
9
- export { AUTO_EFFICIENT, AUTO_INTELLIGENT, AUTO_ROUTER, autoLadder, autoRoutedSlug, DEFAULT_EFFORT_POSITION, DEFAULT_PROXY_MODEL, defaultAutoTier, EFFORT_ALIASES, getAutoSelectHintModel, getModelEffortLevels, getModelEnvVars, getModelManagedCredentials, getModelProvider, getProviderDisplayName, isAutoRouted, isAutoSlug, isAutoTier, isCardGatedModel, isEffortPosition, isOssAllowedModel, isRouterTier, ladderRungs, modelAliases, modelHasStoredAuth, modelIdLabel, OSS_MODEL_ALLOWLIST, OSS_RECOMMENDED_MODEL, offeredRungs, ossFundedModelNames, PROVIDER_GATEWAY_URL_ENV, parseEffortPosition, parseModel, pickUsesOpenRouter, providers, pullfrogMcpName, ROUTED_PROVIDERS, ROUTER_LADDER, ROUTER_TIERS, resolveAutoTier, resolveCliModel, resolveDisplayAlias, resolveModelRung, resolveModelSlug, resolveOpenRouterModel, resolveRoutedModel, resolveRung, routerProxyOptOut, rungLabel, rungPosition, SUBSIDY_RUNG, } from "../external.ts";
9
+ export { AUTO_EFFICIENT, AUTO_INTELLIGENT, AUTO_ROUTER, autoLadder, autoRoutedSlug, DEFAULT_EFFORT_POSITION, DEFAULT_PROXY_MODEL, defaultAutoTier, EFFORT_ALIASES, getAutoSelectHintModel, getModelEffortLevels, getModelEnvVars, getModelManagedCredentials, getModelProvider, getProviderDisplayName, isAutoRouted, isAutoSlug, isAutoTier, isCardGatedModel, isEffortPosition, isOssAllowedModel, isRouterTier, ladderRungs, modelAliases, modelHasStoredAuth, modelIdLabel, OSS_MODEL_ALLOWLIST, OSS_RECOMMENDED_MODEL, offeredRungs, ossFundedModelNames, PROVIDER_GATEWAY_URL_ENV, parseEffortPosition, parseModel, providers, pullfrogMcpName, ROUTED_PROVIDERS, ROUTER_LADDER, ROUTER_TIERS, resolveAutoTier, resolveCliModel, resolveDisplayAlias, resolveModelRung, resolveModelSlug, resolveOpenRouterModel, resolvePickModel, resolveRoutedModel, resolveRung, routerProxyOptOut, rungLabel, rungPosition, SUBSIDY_RUNG, } from "../external.ts";
10
10
  export type { Mode } from "../modes.ts";
11
11
  export { modes } from "../modes.ts";
12
12
  export { type CommercialRefusal, commercialPaywallBody } from "../utils/billingErrors.ts";
package/dist/internal.js CHANGED
@@ -8,7 +8,7 @@ var __export = (target, all) => {
8
8
  // package.json
9
9
  var package_default = {
10
10
  name: "pullfrog",
11
- version: "0.1.95",
11
+ version: "0.1.96",
12
12
  cliContractVersion: "1",
13
13
  type: "module",
14
14
  bin: {
@@ -74,7 +74,7 @@ var package_default = {
74
74
  undici: "^7.22.0",
75
75
  vitest: "^4.0.17",
76
76
  yaml: "^2.8.2",
77
- yes: "0.1.0",
77
+ yes: "0.2.3",
78
78
  zod: "4.3.6"
79
79
  },
80
80
  repository: {
@@ -15076,7 +15076,11 @@ var providers = {
15076
15076
  "glm-flash": {
15077
15077
  displayName: "GLM Flash",
15078
15078
  resolve: "opencode-go/glm-5.3-flash",
15079
- effort: ["low", "high", "max"],
15079
+ // the Go endpoint intermittently rejects reasoning_effort ("native reasoning
15080
+ // control reasoning_effort is not allowed") mid-run, despite models.dev
15081
+ // advertising a ladder — so this route sends none.
15082
+ effort: [],
15083
+ openRouterEffort: ["low", "high", "max"],
15080
15084
  openRouterResolve: "openrouter/z-ai/glm-5.3-flash"
15081
15085
  },
15082
15086
  // legacy alias — the slug pinned a version instead of a brand tier and
@@ -15532,7 +15536,7 @@ var providers = {
15532
15536
  "deepseek-pro": {
15533
15537
  displayName: "DeepSeek Pro",
15534
15538
  resolve: "vercel/deepseek/deepseek-v4-pro-0813",
15535
- effort: ["none", "high", "max"]
15539
+ effort: ["none", "low", "high", "max"]
15536
15540
  },
15537
15541
  // the gateway's bare `deepseek-v4-flash` is the April preview — the same
15538
15542
  // fork trap as OpenRouter, with `deepseek-v4-flash-0731` beside it — so
@@ -15540,7 +15544,7 @@ var providers = {
15540
15544
  "deepseek-flash": {
15541
15545
  displayName: "DeepSeek Flash",
15542
15546
  resolve: "vercel/deepseek/deepseek-v4.1-flash",
15543
- effort: ["none", "high", "max"]
15547
+ effort: ["none", "low", "high", "max"]
15544
15548
  },
15545
15549
  glm: {
15546
15550
  displayName: "GLM",
@@ -15611,8 +15615,8 @@ function routerProxyOptOut(ctx) {
15611
15615
  if (ctx.slug === null) return false;
15612
15616
  return resolveDisplayAlias(ctx.slug)?.isFree === true || modelHasStoredAuth({ model: ctx.slug, secretNames: ctx.secretNames });
15613
15617
  }
15614
- function pickUsesOpenRouter(params) {
15615
- return params.proxied && !routerProxyOptOut(params);
15618
+ function resolvePickModel(params) {
15619
+ return params.proxied && !routerProxyOptOut(params) ? resolveOpenRouterModel(params.slug) : resolveCliModel(params.slug);
15616
15620
  }
15617
15621
  var modelAliases = Object.entries(providers).flatMap(
15618
15622
  ([providerKey, config2]) => Object.entries(config2.models).map(([modelId, def]) => ({
@@ -15795,13 +15799,13 @@ for (const [name, ladder] of Object.entries({ ...PROVIDER_LADDERS, router: ROUTE
15795
15799
  if (terminal.size < 2) throw new Error(`${name} ladder runs every tier on ${[...terminal][0]}`);
15796
15800
  }
15797
15801
  var OSS_MODEL_ALLOWLIST = [
15798
- "deepseek/deepseek-flash",
15799
- "openai/gpt-luna",
15800
- "openrouter/minimax-m2.5",
15801
15802
  // opt-in: 0.86x the old default on the measured mix, and Meta trains on the
15802
15803
  // traffic — fine for public code on headless runs, the human decided
15803
15804
  // 2026-09-11. unmeasured on a real run; not the default until it is.
15804
- "meta/muse-spark-contributor"
15805
+ "meta/muse-spark-contributor",
15806
+ "deepseek/deepseek-flash",
15807
+ "openai/gpt-luna",
15808
+ "openrouter/minimax-m2.5"
15805
15809
  ];
15806
15810
  var OSS_RECOMMENDED_MODEL = AUTO_TIER_TARGET[AUTO_EFFICIENT];
15807
15811
  function ossFundedModelNames() {
@@ -16135,7 +16139,7 @@ ${PR_SUMMARY_FORMAT}`
16135
16139
 
16136
16140
  Follow these rules:
16137
16141
  - note: the first create_pull_request_review submission may error with a one-time diff-coverage nudge listing unread TOC regions. retry the same call to proceed \u2014 optionally after reading the listed ranges. the pre-flight will not block again this session.
16138
- - IF NO NEW ISSUES, NON-SUBSTANTIVE CHANGES ONLY (trivial formatting, import reordering, comment tweaks): do NOT submit a review. Instead call \`${t("report_progress")}\` with a 1-2 sentence note explaining no review was warranted (e.g. "No new issues. Changes since last review are formatting-only."). this leaves a visible signal that the run completed.
16142
+ - IF NO NEW ISSUES, NON-SUBSTANTIVE CHANGES ONLY (trivial formatting, import reordering, comment tweaks): do NOT submit a review. Instead call \`${t("report_progress")}\` with \`no_review_needed: true\` and a 1-2 sentence note explaining no review was warranted (e.g. "No new issues. Changes since last review are formatting-only."). this leaves a visible signal that the run completed.
16139
16143
  - ELSE IF NEW CRITICAL ISSUES (blocks merge \u2014 bugs, security, data loss, broken core flows): call \`${t("create_pull_request_review")}\` with \`approved: false\`, all comments, and the review body. body opens with \`> [!CAUTION]\\n> This PR introduces ...\`, followed by the PR summary using the default format below.
16140
16144
  - ELSE IF NEW MUST-ADDRESS NON-CRITICAL FINDINGS (real consequences if shipped \u2014 incorrect behavior, missing validation, regressions the author should fix before merge): call \`${t("create_pull_request_review")}\` with \`approved: false\`, all comments, and the review body. body opens with \`> [!IMPORTANT]\\n> ...\`, followed by the PR summary using the default format below. Do NOT use this tier for nits, style preferences, or "consider also" suggestions.
16141
16145
  - ELSE IF NEW MINOR SUGGESTIONS ONLY (low-stakes findings, or Nitpicks only): call \`${t("create_pull_request_review")}\` with \`approved: false\`, all comments, and the review body. body opens with \`> \u2139\uFE0F No critical issues \u2014 minor suggestions inline.\\n\\n\` (vary the wording after \u2139\uFE0F to fit the review), followed by the PR summary using the default format below.
@@ -17019,7 +17023,12 @@ function terminalOutput(params) {
17019
17023
  const review = params.reviewUrl ? `
17020
17024
 
17021
17025
  [View the review Pullfrog posted \u2192](${params.reviewUrl})` : "";
17022
- if (params.conclusion === "success") return { title: base.title, summary: base.summary + review };
17026
+ if (params.conclusion === "success") {
17027
+ const note = params.note ? `
17028
+
17029
+ ${params.note}` : "";
17030
+ return { title: base.title, summary: base.summary + review + note };
17031
+ }
17023
17032
  return {
17024
17033
  title: base.title,
17025
17034
  summary: base.summary + logsLine(params.detailsUrl) + review + disableCheckLine(params.owner, params.repo)
@@ -17061,7 +17070,8 @@ async function finalizeRunStatusCheck(params) {
17061
17070
  owner: params.owner,
17062
17071
  repo: params.repo,
17063
17072
  detailsUrl: params.detailsUrl,
17064
- reviewUrl: params.reviewUrl
17073
+ reviewUrl: params.reviewUrl,
17074
+ note: params.note
17065
17075
  })
17066
17076
  };
17067
17077
  if (params.detailsUrl) updateParams.details_url = params.detailsUrl;
@@ -17204,7 +17214,13 @@ var codexUsageSchema = external_exports.object({
17204
17214
  limit_reached: external_exports.boolean(),
17205
17215
  primary_window: codexWindowSchema,
17206
17216
  secondary_window: codexWindowSchema
17207
- }).optional()
17217
+ }).optional(),
17218
+ credits: external_exports.object({
17219
+ has_credits: external_exports.boolean().optional(),
17220
+ unlimited: external_exports.boolean().optional(),
17221
+ overage_limit_reached: external_exports.boolean().optional()
17222
+ }).nullish(),
17223
+ spend_control: external_exports.object({ reached: external_exports.boolean().optional() }).nullish()
17208
17224
  });
17209
17225
  var unknown2 = { status: "unknown" };
17210
17226
  var SubscriptionCredentialError = class extends Error {
@@ -17272,9 +17288,12 @@ async function probeSubscription(input) {
17272
17288
  const body = await response.json().catch(() => null);
17273
17289
  if (!codex) return unknown2;
17274
17290
  const parsed = codexUsageSchema.safeParse(body);
17275
- const limit = parsed.success ? parsed.data.rate_limit : void 0;
17276
- if (!limit) return unknown2;
17291
+ if (!parsed.success || !parsed.data.rate_limit) return unknown2;
17292
+ const limit = parsed.data.rate_limit;
17277
17293
  if (limit.allowed && !limit.limit_reached) return { status: "usable" };
17294
+ const credits = parsed.data.credits;
17295
+ if ((credits?.has_credits || credits?.unlimited) && !credits.overage_limit_reached && !parsed.data.spend_control?.reached)
17296
+ return { status: "usable" };
17278
17297
  const windows = [limit.primary_window, limit.secondary_window];
17279
17298
  const full = windows.filter((window) => (window?.used_percent ?? 0) >= 100);
17280
17299
  const resets = (full.length ? full : windows).flatMap(
@@ -17322,15 +17341,24 @@ async function probeInference(input) {
17322
17341
  const error48 = external_exports.object({ error: external_exports.object({ code: external_exports.string() }) }).safeParse(await response.json().catch(() => null));
17323
17342
  return error48.success && error48.data.error.code === "insufficient_quota" ? { status: "exhausted", detail: "refused with 429: insufficient quota", resetAt: void 0 } : unknown2;
17324
17343
  }
17344
+ if (response?.status === 401 || response?.status === 403)
17345
+ return {
17346
+ status: "rejected",
17347
+ detail: `rejected with ${response.status}${await providerReason(response)}`
17348
+ };
17325
17349
  await response?.body?.cancel();
17326
17350
  if (!response) return unknown2;
17327
17351
  if (response.ok) return { status: "usable" };
17328
- if (response.status === 401 || response.status === 403)
17329
- return { status: "rejected", detail: `rejected with ${response.status}` };
17330
17352
  if (response.status === 402)
17331
17353
  return { status: "exhausted", detail: "refused with 402", resetAt: void 0 };
17332
17354
  return unknown2;
17333
17355
  }
17356
+ async function providerReason(response) {
17357
+ const body = external_exports.object({ error: external_exports.union([external_exports.string(), external_exports.object({ message: external_exports.string() })]) }).safeParse(await response.json().catch(() => null));
17358
+ if (!body.success) return "";
17359
+ const error48 = body.data.error;
17360
+ return `: ${(typeof error48 === "string" ? error48 : error48.message).slice(0, 300)}`;
17361
+ }
17334
17362
 
17335
17363
  // utils/time.ts
17336
17364
  var TIMEOUT_DISABLED = "none";
@@ -17420,7 +17448,6 @@ export {
17420
17448
  parseModel,
17421
17449
  parseTimeString,
17422
17450
  parseXaiAuthBody,
17423
- pickUsesOpenRouter,
17424
17451
  probeSubscription,
17425
17452
  providers,
17426
17453
  pullfrogMcpName,
@@ -17432,6 +17459,7 @@ export {
17432
17459
  resolveModelRung,
17433
17460
  resolveModelSlug,
17434
17461
  resolveOpenRouterModel,
17462
+ resolvePickModel,
17435
17463
  resolveRoutedModel,
17436
17464
  resolveRung,
17437
17465
  routerProxyOptOut,
@@ -33,6 +33,7 @@ export declare function EditCommentTool(ctx: ToolContext): import("fastmcp").Too
33
33
  export declare const ReportProgress: import("arktype/internal/variants/object.ts").ObjectType<{
34
34
  body: string;
35
35
  target_plan_comment?: boolean;
36
+ no_review_needed?: boolean;
36
37
  }, {}>;
37
38
  /**
38
39
  * Report progress to a GitHub comment.
@@ -61,9 +62,11 @@ export declare function reportProgress(ctx: ToolContext, params: {
61
62
  export declare function ReportProgressTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
62
63
  body: string;
63
64
  target_plan_comment?: boolean;
65
+ no_review_needed?: boolean;
64
66
  }, {
65
67
  body: string;
66
68
  target_plan_comment?: boolean;
69
+ no_review_needed?: boolean;
67
70
  }>> & {
68
71
  mutates?: boolean;
69
72
  };
package/dist/models.d.ts CHANGED
@@ -189,7 +189,7 @@ export declare function modelHasStoredAuth(params: {
189
189
  * as-configured rather than clamping to the auto tier.
190
190
  *
191
191
  * one predicate for every reader — the console picker's `customLocked`, the
192
- * effort ladder's `resolveRunning` and `pickUsesOpenRouter`. they held two
192
+ * effort ladder's `resolveRunning` and `resolvePickModel`. they held two
193
193
  * copies and the free half was missing from both, which put the whole `opencode/*` free tier (`opencode/big-pickle`
194
194
  * is `preferred`, so the most-picked model there is) behind "add a payment
195
195
  * method to run it" on a card-less Router repo, against a server that ran it.
@@ -198,13 +198,13 @@ export declare function routerProxyOptOut(ctx: {
198
198
  slug: string | null;
199
199
  secretNames: string[];
200
200
  }): boolean;
201
- /** whether a pick runs as its OpenRouter target: a proxied account (Router, the OSS subsidy)
202
- * mints for every pick `routerProxyOptOut` does not exempt. */
203
- export declare function pickUsesOpenRouter(params: {
201
+ /** the specifier a pick runs as: its OpenRouter target on a proxied account (Router, the OSS
202
+ * subsidy), which mints for every pick `routerProxyOptOut` does not exempt, else its direct one. */
203
+ export declare function resolvePickModel(params: {
204
204
  slug: string;
205
205
  proxied: boolean;
206
206
  secretNames: string[];
207
- }): boolean;
207
+ }): string | undefined;
208
208
  export declare const modelAliases: ModelAlias[];
209
209
  /**
210
210
  * `repo.model` sentinels for the two managed auto tiers. stored verbatim in
@@ -106,6 +106,7 @@ export interface ToolState {
106
106
  sha: string | undefined;
107
107
  url?: string | undefined;
108
108
  };
109
+ noReviewNeededSha?: string | undefined;
109
110
  reviewReplies?: Map<number, {
110
111
  commentId: number;
111
112
  url: string | undefined;
@@ -147,10 +148,11 @@ export interface ToolState {
147
148
  todoTracker?: TodoTracker | undefined;
148
149
  agentDiagnostic?: AgentDiagnostic | undefined;
149
150
  /**
150
- * a `PATCH /api/workflow-run/:id` came back 404 — the reservation was never
151
- * claimed, which is permanent for the life of the run (the claim happens at
152
- * setup, strictly before any PATCH). latched so the remaining calls stop
153
- * firing: one CI run spent 28 doomed round trips on it. see #1153.
151
+ * a `PATCH /api/workflow-run/:id` came back 404 — Pullfrog neither claimed a
152
+ * reservation for the run nor recorded it as a custom run, which is permanent for
153
+ * the life of the run (both happen at setup, strictly before any PATCH). latched so
154
+ * the remaining calls stop firing: one CI run spent 28 doomed round trips on it.
155
+ * see #1153.
154
156
  */
155
157
  workflowRunUnclaimed?: boolean | undefined;
156
158
  }
@@ -75,7 +75,7 @@ export declare function fetchIdTokenFromStash(creds: OidcCredentials): Promise<s
75
75
  * own retry still re-mints. Mid-run refreshes take the stashed-credentials path
76
76
  * (`opts.oidc`) and deliberately bypass this.
77
77
  */
78
- export declare const mintIdToken: yes.OpFunction<() => Promise<string>>;
78
+ export declare const mintIdToken: (() => Promise<string>) & yes.CacheMethods<undefined, undefined>;
79
79
  /**
80
80
  * ensure a GitHub token is available in the environment.
81
81
  *
@@ -9,6 +9,9 @@ import type { ToolContext } from "../mcp/server.ts";
9
9
  * `Repo.model` slug), PATCHed once at end-of-run so per-model cost analytics
10
10
  * don't parse the audit-only `payload`.
11
11
  * Keep in sync with `STRING_FIELDS` in `app/api/workflow-run/[runId]/route.ts`.
12
+ * `succeeded` and the usage fields below are this start's own report: a custom
13
+ * workflow can start the action several times in one run, and the server keeps
14
+ * one row per start, keyed by `START_KEY`, and sums them onto the run.
12
15
  */
13
16
  declare const STRING_KEYS: readonly ["prNodeId", "issueNodeId", "reviewNodeId", "planCommentNodeId", "summarySnapshot", "model", "agent", "credential"];
14
17
  /**
@@ -18,7 +21,11 @@ declare const STRING_KEYS: readonly ["prNodeId", "issueNodeId", "reviewNodeId",
18
21
  * amounts. Keep in sync with `INT_FIELDS` + `DECIMAL_FIELDS` in the server route.
19
22
  */
20
23
  declare const NUMBER_KEYS: readonly ["inputTokens", "outputTokens", "cacheReadTokens", "cacheWriteTokens", "costUsd"];
21
- export type WorkflowRunPatch = Partial<Record<(typeof STRING_KEYS)[number], string>> & Partial<Record<(typeof NUMBER_KEYS)[number], number>>;
24
+ /** one-way flags, only ever sent as `true`. Keep in sync with `BOOLEAN_FIELDS` in the server route. */
25
+ declare const FLAG_KEYS: readonly ["reviewSkipped"];
26
+ export type WorkflowRunPatch = Partial<Record<(typeof STRING_KEYS)[number], string>> & Partial<Record<(typeof NUMBER_KEYS)[number], number>> & Partial<Record<(typeof FLAG_KEYS)[number], true>> & {
27
+ succeeded?: boolean;
28
+ };
22
29
  /** PATCH workflow-run fields (Pullfrog JWT, not GitHub). */
23
30
  export declare function patchWorkflowRunFields(ctx: ToolContext, fields: WorkflowRunPatch): Promise<void>;
24
31
  /**
@@ -3,6 +3,11 @@ import type { RouterTier } from "../models.ts";
3
3
  import type { CommercialRefusal } from "./billingErrors.ts";
4
4
  import type { RepoContext } from "./github.ts";
5
5
  import type { CredentialAccess } from "./subscriptionCredentials.ts";
6
+ /**
7
+ * One per process, which is one start of the action within its GitHub run. Sent to run-context
8
+ * first, so a custom run's start is recorded before it reports, and then on each workflow-run PATCH.
9
+ */
10
+ export declare const START_KEY: `${string}-${string}-${string}-${string}-${string}`;
6
11
  export interface Mode {
7
12
  id: string;
8
13
  name: string;
@@ -108,6 +113,9 @@ export declare function fetchRunContext(params: {
108
113
  /** `payload.type` — lets the server apply this repo's per-trigger model
109
114
  * override, which it cannot derive from owner/repo alone. */
110
115
  runType?: string | undefined;
116
+ /** a plain-text prompt, which no Pullfrog dispatch sends — so the server
117
+ * can record this run without waiting for a reservation to claim it. */
118
+ plainPrompt: boolean;
111
119
  /** `payload.routing.tier` — the model router's tier, which run-context
112
120
  * applies to the Router proxy mint the same way it applies `runType`. */
113
121
  routedTier?: RouterTier | undefined;
@@ -37,6 +37,8 @@ interface ResolveRunContextDataParams {
37
37
  * because run-context is fetched first and needs it to pick this trigger's
38
38
  * model override. */
39
39
  runType?: string | undefined;
40
+ /** the prompt is plain text, never a Pullfrog dispatch payload. */
41
+ plainPrompt: boolean;
40
42
  /** the model router's tier from the payload, forwarded so run-context applies it to the proxy mint. */
41
43
  routedTier?: RouterTier | undefined;
42
44
  }
@@ -32,6 +32,14 @@
32
32
  * See wiki/review-approval.md.
33
33
  */
34
34
  export declare const RUN_STATUS_CHECK_NAME = "pullfrog";
35
+ /**
36
+ * GitHub's own Actions app. It publishes a check run per job, named after the
37
+ * job — and the generated workflow's job is also called `pullfrog`, so the
38
+ * collision is structural rather than incidental. Renaming our check is not
39
+ * available: it was tried on 2026-08-02 and blocked merges on four customer
40
+ * repos (see above), so the reuse lookup filters instead. See #1196.
41
+ */
42
+ export declare const GITHUB_ACTIONS_APP_SLUG = "github-actions";
35
43
  /** the review-verdict check. opt-in, terminal-only, and deliberately separate from the above. */
36
44
  export declare const APPROVAL_CHECK_NAME = "pullfrog-approval";
37
45
  /**
@@ -147,6 +155,8 @@ export declare function finalizeRunStatusCheck(params: {
147
155
  conclusion: RunStatusCheckConclusion;
148
156
  detailsUrl: string | undefined;
149
157
  reviewUrl?: string | undefined;
158
+ /** the run's own final report, shown on success when nothing else carries it. */
159
+ note?: string | undefined;
150
160
  }): Promise<void>;
151
161
  /**
152
162
  * Post an already-terminal check-run in one call.
@@ -163,6 +173,7 @@ export declare function createTerminalRunStatusCheck(params: {
163
173
  conclusion: RunStatusCheckConclusion;
164
174
  detailsUrl: string | undefined;
165
175
  reviewUrl?: string | undefined;
176
+ note?: string | undefined;
166
177
  }): Promise<void>;
167
178
  /**
168
179
  * Whether this check still needs finalizing.
@@ -11,7 +11,8 @@ import type { ToolContext } from "../mcp/server.ts";
11
11
  * - `pullfrog-approval` stays opt-in (`Repo.approvalCheck`, default off) and terminal-only:
12
12
  * it asserts a review verdict, which only exists once a run produces one. anchored
13
13
  * to the exact reviewed sha so a mid-run push leaves the new head unapproved until
14
- * a follow-up re-review reports.
14
+ * a follow-up re-review reports. a re-review that submits no review carries the
15
+ * prior verdict forward instead (see `carriedApproval`).
15
16
  *
16
17
  * best-effort throughout: a check-post failure (transient 5xx, closed PR, revoked
17
18
  * permission) must never flip the run's own outcome. the `workflow_run.completed` webhook
@@ -12,6 +12,7 @@ export declare class SpawnTimeoutError extends Error {
12
12
  export type SignalHandler = (signal: NodeJS.Signals) => void;
13
13
  export declare function trackChild(options: TrackChildOptions): void;
14
14
  export declare function untrackChild(child: ChildProcess): void;
15
+ export declare function isTrackedChild(child: ChildProcess): boolean;
15
16
  export declare function setSignalHandler(handler: SignalHandler | null): void;
16
17
  export declare function killTrackedChildren(): void;
17
18
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pullfrog",
3
- "version": "0.1.95",
3
+ "version": "0.1.96",
4
4
  "cliContractVersion": "1",
5
5
  "type": "module",
6
6
  "bin": {
@@ -66,7 +66,7 @@
66
66
  "undici": "^7.22.0",
67
67
  "vitest": "^4.0.17",
68
68
  "yaml": "^2.8.2",
69
- "yes": "0.1.0",
69
+ "yes": "0.2.3",
70
70
  "zod": "4.3.6"
71
71
  },
72
72
  "repository": {