pullfrog 0.1.11 → 0.1.12

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.
@@ -3,7 +3,7 @@
3
3
  * Re-exports shared types, values, and utilities needed by the Next.js app.
4
4
  */
5
5
  export type { AuthorPermission, ModelAlias, ModelProvider, Payload, PayloadEvent, ProviderConfig, PushPermission, ShellPermission, ToolPermission, WriteablePayload, } from "../external.ts";
6
- export { getModelEnvVars, getModelManagedCredentials, getModelProvider, getProviderDisplayName, modelAliases, parseModel, providers, pullfrogMcpName, resolveCliModel, resolveDisplayAlias, resolveModelSlug, resolveOpenRouterModel, } from "../external.ts";
6
+ export { DEFAULT_PROXY_MODEL, getModelEnvVars, getModelManagedCredentials, getModelProvider, getProviderDisplayName, modelAliases, parseModel, providers, pullfrogMcpName, resolveCliModel, resolveDisplayAlias, resolveModelSlug, resolveOpenRouterModel, } from "../external.ts";
7
7
  export type { Mode } from "../modes.ts";
8
8
  export { modes } from "../modes.ts";
9
9
  export type { BuildPullfrogFooterParams, WorkflowRunFooterInfo, } from "../utils/buildPullfrogFooter.ts";
package/dist/internal.js CHANGED
@@ -257,6 +257,11 @@ var providers = {
257
257
  resolve: "opencode/kimi-k2.6",
258
258
  openRouterResolve: "openrouter/moonshotai/kimi-k2.6"
259
259
  },
260
+ "minimax-m2.5": {
261
+ displayName: "MiniMax M2.5",
262
+ resolve: "opencode/minimax-m2.5",
263
+ openRouterResolve: "openrouter/minimax/minimax-m2.5"
264
+ },
260
265
  "gpt-5-nano": {
261
266
  displayName: "GPT Nano",
262
267
  resolve: "opencode/gpt-5-nano",
@@ -273,7 +278,9 @@ var providers = {
273
278
  displayName: "MiniMax M2.5",
274
279
  resolve: "opencode/minimax-m2.5-free",
275
280
  envVars: [],
276
- isFree: true
281
+ isFree: true,
282
+ fallback: "opencode/big-pickle",
283
+ hidden: true
277
284
  }
278
285
  }
279
286
  }),
@@ -411,6 +418,11 @@ var providers = {
411
418
  displayName: "Kimi K2",
412
419
  resolve: "openrouter/moonshotai/kimi-k2.6",
413
420
  openRouterResolve: "openrouter/moonshotai/kimi-k2.6"
421
+ },
422
+ "minimax-m2.5": {
423
+ displayName: "MiniMax M2.5",
424
+ resolve: "openrouter/minimax/minimax-m2.5",
425
+ openRouterResolve: "openrouter/minimax/minimax-m2.5"
414
426
  }
415
427
  }
416
428
  })
@@ -464,6 +476,11 @@ var modelAliases = Object.entries(providers).flatMap(
464
476
  hidden: def.hidden ?? false
465
477
  }))
466
478
  );
479
+ var defaultProxyAlias = modelAliases.find((a) => a.slug === "moonshotai/kimi-k2");
480
+ if (!defaultProxyAlias?.openRouterResolve) {
481
+ throw new Error("DEFAULT_PROXY_MODEL: moonshotai/kimi-k2 missing openRouterResolve");
482
+ }
483
+ var DEFAULT_PROXY_MODEL = defaultProxyAlias.openRouterResolve;
467
484
  function resolveModelSlug(slug) {
468
485
  return modelAliases.find((a) => a.slug === slug)?.resolve;
469
486
  }
@@ -687,7 +704,25 @@ function computeModes(agentId) {
687
704
 
688
705
  Otherwise delegate the \`${REVIEWER_AGENT_NAME}\` subagent to review your diff with fresh eyes against YOUR TASK. The subagent's baked-in system prompt enforces a non-mutative + non-recursive contract: read-only file/search/web tools and read-only MCP queries only; no writes, shell side effects, state-changing MCP calls, or nested subagent dispatch. Enforcement is prose-only \u2014 restate the constraint in your dispatch instructions and do not relax it.
689
706
 
690
- Provide the subagent with YOUR TASK, the output of \`git diff origin/<base-branch>\` (single-rev form, no \`HEAD\` \u2014 this compares the working tree against the remote base and captures committed + staged + unstaged work; \`main...HEAD\` and \`--cached\` both miss the uncommitted edits Build self-review runs on, since self-review happens BEFORE the commit), and a tight summary (not raw output) of any lint/typecheck/test failures you fixed during build \u2014 what broke, root cause, the fix \u2014 so it can check that fixes addressed root causes rather than suppressed symptoms; say "no build-phase failures" if the build path was clean. Instruct it to flag bugs, logic errors, missing edge cases, gaps between request and diff, and unintended changes.
707
+ Compose your \`${REVIEWER_AGENT_NAME}\` dispatch prompt using this template verbatim, substituting the \`<...>\` placeholders. The preamble aligns the orchestrator side of the dispatch contract with the reviewer's baked-in system prompt \u2014 both ends say the same thing about where the work lives and what to do on an empty diff.
708
+
709
+ \`\`\`
710
+ ## What you're reviewing
711
+ This is a PRE-COMMIT Build-mode self-review. The work to review lives in the working tree (uncommitted), NOT in committed history.
712
+
713
+ Branch: <branch> (off <base>)
714
+ Canonical diff command: git diff origin/<base>
715
+
716
+ If that command returns empty, treat it as "no changes \u2014 nothing to review" and stop per your system prompt. Do not search for the work elsewhere.
717
+
718
+ ## Your task
719
+ <YOUR TASK content>
720
+
721
+ ## Build-phase failures
722
+ <tight summary \u2014 what broke, root cause, the fix \u2014 or "no build-phase failures">
723
+ \`\`\`
724
+
725
+ Follow the template with the diff content (\`git diff origin/<base-branch>\`, single-rev form \u2014 \`main...HEAD\` and \`--cached\` both miss the uncommitted edits self-review runs on) and your task brief. Instruct the subagent to flag bugs, logic errors, missing edge cases, gaps between request and diff, and unintended changes.
691
726
 
692
727
  Delegation + research discipline (distilled from \`/anneal\` canonical \u2014 these are codified learnings from many review rounds, not theoretical best practices):
693
728
  - Do NOT summarize what you implemented \u2014 that biases the subagent toward validating the shape of your solution rather than questioning it.
@@ -1254,6 +1289,7 @@ function isValidTimeString(input) {
1254
1289
  return parseTimeString(input) !== null;
1255
1290
  }
1256
1291
  export {
1292
+ DEFAULT_PROXY_MODEL,
1257
1293
  LEAPING_INTO_ACTION_PREFIX,
1258
1294
  MAX_LEARNINGS_LENGTH,
1259
1295
  PULLFROG_DIVIDER,
@@ -48,7 +48,7 @@ export type CheckoutPrResult = {
48
48
  * this is the core diff formatting logic, extracted for testability.
49
49
  */
50
50
  export declare function fetchAndFormatPrDiff(ctx: ToolContext, pullNumber: number): Promise<FetchAndFormatPrDiffResult>;
51
- import type { GitContext } from "../utils/setup.ts";
51
+ import { type GitContext } from "../utils/setup.ts";
52
52
  export type PrData = {
53
53
  number: number;
54
54
  headSha: string;
package/dist/models.d.ts CHANGED
@@ -103,6 +103,7 @@ export declare function getModelEnvVars(slug: string): string[];
103
103
  * see `provider.managedCredentials` and wiki/codex-auth.md. */
104
104
  export declare function getModelManagedCredentials(slug: string): string[];
105
105
  export declare const modelAliases: ModelAlias[];
106
+ export declare const DEFAULT_PROXY_MODEL: string;
106
107
  /** resolve a model slug to its concrete models.dev specifier (e.g. "anthropic/claude-opus-4-6") */
107
108
  export declare function resolveModelSlug(slug: string): string | undefined;
108
109
  /**
@@ -57,6 +57,13 @@ export type CommentableLines = {
57
57
  export interface ToolState {
58
58
  pushUrl?: string;
59
59
  pushDest?: StoredPushDest;
60
+ initialHead?: {
61
+ kind: "branch";
62
+ name: string;
63
+ } | {
64
+ kind: "detached";
65
+ sha: string;
66
+ };
60
67
  issueNumber?: number;
61
68
  checkoutSha?: string;
62
69
  commentableLinesByFile?: Map<string, CommentableLines>;
@@ -2,15 +2,14 @@
2
2
  * Slug we fall back to when a BYOK-required model is configured but the
3
3
  * runner has no provider key in env. Picked because it's free
4
4
  * (`isFree: true`, `envVars: []` — see `action/models.ts`), stable, and
5
- * currently the strongest free OpenCode model in the catalog. If a
6
- * smarter free model is added later, update this single constant.
5
+ * currently served by OpenCode Zen without a key.
7
6
  *
8
7
  * The slug is intentionally hard-coded and not a config knob — the
9
8
  * fallback is a safety net, not a user-facing preference, and adding a
10
9
  * config surface here would just push the same "what to fall back to"
11
10
  * decision into another setting that goes stale the same way.
12
11
  */
13
- export declare const FREE_FALLBACK_SLUG = "opencode/minimax-m2.5-free";
12
+ export declare const FREE_FALLBACK_SLUG = "opencode/big-pickle";
14
13
  export type FallbackDecision = {
15
14
  fallback: false;
16
15
  } | {
@@ -13,11 +13,3 @@ export interface InstalledCodexAuth {
13
13
  * returns null when the env var is absent, malformed, or wrong auth mode —
14
14
  * caller treats null as "no codex auth, fall through to API key flow". */
15
15
  export declare function installCodexAuth(): InstalledCodexAuth | null;
16
- /** convert an on-disk OpenCode auth.json back to the Codex CLI shape so the
17
- * post-hook can write it to the Pullfrog secret store. returns null when the
18
- * file's `openai` entry is missing, has the wrong type, or hasn't actually
19
- * refreshed (refresh token unchanged from `originalRefresh`). */
20
- export declare function detectCodexRefresh(params: {
21
- authFileContent: string;
22
- originalRefresh: string;
23
- }): string | null;
@@ -24,7 +24,7 @@
24
24
  import type { AgentResult } from "../agents/shared.ts";
25
25
  import type { ToolContext } from "../mcp/server.ts";
26
26
  import type { ToolState } from "../toolState.ts";
27
- import type { RenderedRunError } from "./runErrorRenderer.ts";
27
+ import { type RenderedRunError } from "./runErrorRenderer.ts";
28
28
  /**
29
29
  * Best-effort cleanup shared by both run-end paths:
30
30
  * 1. post-review cleanup (dispatch follow-up re-review on submitted reviews)
@@ -40,9 +40,12 @@ export declare function persistRunArtifacts(toolContext: ToolContext): Promise<v
40
40
  *
41
41
  * 1. shared best-effort cleanup via `persistRunArtifacts`
42
42
  * 2. when the harness returned `success=false` (e.g. unsubmitted-review
43
- * gate exhausted retries, stop-hook persistently failing), surface
44
- * the error in the progress comment so the user sees it instead of a
45
- * deleted-comment void
43
+ * gate exhausted retries, stop-hook persistently failing), render via
44
+ * `renderRunError` and surface the error in BOTH the progress comment
45
+ * (rendered.comment) and the Actions job summary (rendered.summary,
46
+ * prepended below in step 4) — same classifier as the catch path so
47
+ * the user sees it instead of a deleted-comment void / empty summary
48
+ * tab
46
49
  * 3. when the run succeeded and the progress comment was never finalized
47
50
  * via `report_progress`, delete it (three sub-cases — orphan
48
51
  * "Leaping into action" comment, abandoned checklist, agent wrote
@@ -8,6 +8,32 @@ export interface SetupOptions {
8
8
  * Create a shared temp directory for the action
9
9
  */
10
10
  export declare function createTempDirectory(): string;
11
+ /**
12
+ * snapshot-and-delete the GHA runner's known credential leak surfaces inside
13
+ * `$RUNNER_TEMP` before the agent spawns. without this, a shell-capable agent
14
+ * can grep:
15
+ * - `_runner_file_commands/set_output_*` for `core.setOutput('token', ghs_…)`
16
+ * calls made by earlier composite-action steps (e.g.
17
+ * pullfrog/pullfrog/get-installation-token);
18
+ * - `<uuid>.sh` rendered step scripts whose `run: |` body embeds
19
+ * `${{ steps.token.outputs.token }}` literally (GHA expands BEFORE writing);
20
+ * - `git-credentials-*.config` written by `actions/checkout@v6` for the
21
+ * workflow GITHUB_TOKEN.
22
+ *
23
+ * the running bash process already has its own `.sh` open via fd, so the
24
+ * unlink is safe — `unlink` removes the dirent, the kernel keeps reading.
25
+ *
26
+ * preserves every `_runner_file_commands/` file path the runner pre-allocated
27
+ * for OUR step — `$GITHUB_OUTPUT`, `$GITHUB_ENV`, `$GITHUB_PATH`,
28
+ * `$GITHUB_STATE`, `$GITHUB_STEP_SUMMARY`. those are read by the runner
29
+ * AFTER we exit (or by our own `post:` hook), and wiping them would break
30
+ * pullfrog's `result` output, `post:` state handoff, and job summary.
31
+ *
32
+ * silent no-op when `$RUNNER_TEMP` is unset (local dev, `pnpm play`).
33
+ * per-file errors are tolerated — the runner may delete files between
34
+ * our readdir and our unlink.
35
+ */
36
+ export declare function wipeRunnerLeakSurface(): void;
11
37
  /**
12
38
  * Setup the test repository for running actions
13
39
  */
@@ -44,3 +70,21 @@ export type SetupGitParams = GitContext;
44
70
  * it is assumed to be potentially exfiltratable, so it has limited scope.
45
71
  */
46
72
  export declare function setupGit(params: SetupGitParams): Promise<void>;
73
+ /**
74
+ * snapshot the current HEAD as either a branch name (when on a named branch)
75
+ * or a literal SHA (when detached). used by setupGit to pin the run-entry
76
+ * position and by checkout_pr to compare the live HEAD against it.
77
+ *
78
+ * splitting the two cases is load-bearing: `git rev-parse --abbrev-ref HEAD`
79
+ * returns the sentinel string `"HEAD"` on detached entry — which is the
80
+ * default `actions/checkout` state for `pull_request` events. storing that
81
+ * raw string would make any future detached state (including a subagent's
82
+ * `git checkout --detach <sha>`) compare equal.
83
+ */
84
+ export declare function captureInitialHead(repoDir: string): {
85
+ kind: "branch";
86
+ name: string;
87
+ } | {
88
+ kind: "detached";
89
+ sha: string;
90
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pullfrog",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "pullfrog": "dist/cli.mjs",