pullfrog 0.1.7 → 0.1.9

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.
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Mint an OpenRouter proxy key via `/api/proxy-token` and inject it as
3
+ * `OPENROUTER_API_KEY` for runs that route through Pullfrog Router (managed
4
+ * billing accounts) or OSS-grant paths.
5
+ *
6
+ * Authenticates one of two ways:
7
+ * - production: GitHub Actions OIDC token via `core.getIDToken`
8
+ * - local dev (`API_URL` is localhost): `x-dev-repo` header bypass
9
+ *
10
+ * `runProxyResolution` is the entrypoint `main.ts` calls. It wraps
11
+ * `resolveProxyModel` and renders the user-facing copy itself (job summary
12
+ * + PR progress comment) before rethrowing the structured error — handled
13
+ * here, not in the outer `main()` catch, because `toolContext` doesn't
14
+ * exist yet at this point in the pipeline.
15
+ *
16
+ * - 402 → `BillingError` (card declined, balance empty, 3DS, etc.)
17
+ * - 503 → `TransientError` (transient sync issue — retry next dispatch)
18
+ */
19
+ import type { ToolState } from "../toolState.ts";
20
+ import type { ResolvedPayload } from "./payload.ts";
21
+ export interface OidcCredentials {
22
+ requestUrl: string;
23
+ requestToken: string;
24
+ }
25
+ /**
26
+ * Run `resolveProxyModel`; if it throws a Billing or Transient error, render
27
+ * the user-facing summary, mirror it to the PR progress comment, and rethrow.
28
+ *
29
+ * The rethrow is intentional: these errors are terminal for the run, and
30
+ * letting them surface lets `runMain` exit non-zero so GH Actions applies
31
+ * the workflow's retry policy. We catch them *here* (before the main try)
32
+ * because the outer catch needs `toolContext` (which isn't built yet) for
33
+ * its general-purpose rendering path — a BillingError landing in the outer
34
+ * catch would get rendered with `core.setFailed` only, losing the
35
+ * actionable copy + the PR-comment mirror.
36
+ */
37
+ export declare function runProxyResolution(ctx: {
38
+ payload: ResolvedPayload;
39
+ oss: boolean;
40
+ proxyModel?: string | undefined;
41
+ oidcCredentials: OidcCredentials | null;
42
+ repo: {
43
+ owner: string;
44
+ name: string;
45
+ };
46
+ toolState: ToolState;
47
+ }): Promise<void>;
@@ -42,15 +42,6 @@ export interface RepoSettings {
42
42
  * `"payg"` = card on file / pay-as-you-go.
43
43
  */
44
44
  export type AccountPlan = "none" | "payg";
45
- /**
46
- * "Is Pullfrog absorbing marginal infra cost for this repo?" — composite
47
- * predicate over the two orthogonal dimensions (repo-level OSS, account-level
48
- * plan). Mirrors `isInfraCovered` in the server's `utils/billing.ts`.
49
- */
50
- export declare function isInfraCovered(params: {
51
- isOss: boolean;
52
- plan: AccountPlan;
53
- }): boolean;
54
45
  export interface RunContext {
55
46
  settings: RepoSettings;
56
47
  apiToken: string;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Classify + render the error thrown out of the main run try-block into a
3
+ * pair of user-facing markdown bodies — one for the GitHub Actions job
4
+ * summary tab, one for the PR progress comment.
5
+ *
6
+ * Four classifications, in priority order:
7
+ *
8
+ * 1. `BillingError` — either the proxy-token mint already threw one (402
9
+ * handled inline) or the agent runtime surfaced an OpenRouter
10
+ * "key budget exhausted" string mid-run. Both render via
11
+ * `formatBillingErrorSummary` so the user sees actionable copy.
12
+ *
13
+ * 2. Activity-timeout hang — `errorMessage` starts with
14
+ * `"activity timeout"` or `"agent still pending"`. The harness keeps
15
+ * structured diagnostic state on `toolState.agentDiagnostic`;
16
+ * `formatAgentHangBody` renders that as a markdown block.
17
+ *
18
+ * 3. API-key auth error — `isApiKeyAuthError` sniffs the raw error string;
19
+ * `formatApiKeyErrorSummary` renders provider + console-link copy.
20
+ *
21
+ * 4. Default — a generic `❌ Pullfrog failed` block with the raw error
22
+ * message in a fenced code block. Same body for both surfaces.
23
+ *
24
+ * The hang body and the API-key body diverge between the two surfaces only
25
+ * in that the job summary wraps them in the `### ❌ Pullfrog failed` H3
26
+ * banner; the PR comment uses the bare body since it already has Pullfrog
27
+ * branding in its footer.
28
+ */
29
+ import type { AgentDiagnostic } from "./agentHangReport.ts";
30
+ export type RenderedRunError = {
31
+ summary: string;
32
+ comment: string;
33
+ };
34
+ export declare function renderRunError(input: {
35
+ errorMessage: string;
36
+ repo: {
37
+ owner: string;
38
+ name: string;
39
+ };
40
+ agentDiagnostic: AgentDiagnostic | undefined;
41
+ }): RenderedRunError;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * End-of-run cleanup phases extracted out of `main.ts`. Three shapes:
3
+ *
4
+ * - `persistRunArtifacts`: best-effort post-review cleanup + summary +
5
+ * learnings persistence. Shared by both the success path and the
6
+ * error-catch path; idempotent (each step has its own guard against
7
+ * double-execution).
8
+ *
9
+ * - `finalizeSuccessRun`: success-only — calls `persistRunArtifacts`
10
+ * first, then surfaces harness-side failures in the progress comment,
11
+ * deletes stranded progress comments, writes the GitHub Actions job
12
+ * summary, and emits the structured output marker.
13
+ *
14
+ * - `writeRunErrorOutputs`: error-only — writes the rendered error
15
+ * summary to the Actions summary tab and mirrors it to the PR
16
+ * progress comment. The catch path calls this and then
17
+ * `persistRunArtifacts` separately so the rendered error lands before
18
+ * the persistence calls, in case the latter throw.
19
+ *
20
+ * All three swallow their own non-fatal errors (`log.debug` or empty
21
+ * `catch {}`) so a cleanup failure can't flip an already-decided run
22
+ * outcome.
23
+ */
24
+ import type { AgentResult } from "../agents/shared.ts";
25
+ import type { ToolContext } from "../mcp/server.ts";
26
+ import type { ToolState } from "../toolState.ts";
27
+ import type { RenderedRunError } from "./runErrorRenderer.ts";
28
+ /**
29
+ * Best-effort cleanup shared by both run-end paths:
30
+ * 1. post-review cleanup (dispatch follow-up re-review on submitted reviews)
31
+ * 2. persist the agent-edited PR summary tmpfile
32
+ * 3. persist the agent-edited repo-level learnings tmpfile
33
+ *
34
+ * Each step is idempotent and swallows its own errors. Safe to call from
35
+ * both `main()`'s success path and its catch path.
36
+ */
37
+ export declare function persistRunArtifacts(toolContext: ToolContext): Promise<void>;
38
+ /**
39
+ * Run the success-path cleanup waterfall:
40
+ *
41
+ * 1. shared best-effort cleanup via `persistRunArtifacts`
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
46
+ * 3. when the run succeeded and the progress comment was never finalized
47
+ * via `report_progress`, delete it (three sub-cases — orphan
48
+ * "Leaping into action" comment, abandoned checklist, agent wrote
49
+ * a substantive artifact via another MCP write tool but skipped
50
+ * report_progress)
51
+ * 4. write the GitHub Actions step summary (best-effort — a write
52
+ * failure must not throw past this point because we'd hit the outer
53
+ * catch and clobber any progress comment we just wrote)
54
+ * 5. emit the structured output marker for tests + workflow consumers
55
+ */
56
+ export declare function finalizeSuccessRun(input: {
57
+ toolContext: ToolContext;
58
+ toolState: ToolState;
59
+ result: AgentResult;
60
+ repo: {
61
+ owner: string;
62
+ name: string;
63
+ };
64
+ }): Promise<void>;
65
+ /**
66
+ * Write the rendered error to the GitHub Actions job summary tab + mirror
67
+ * to the PR progress comment when one exists. Catch path only.
68
+ *
69
+ * `lastProgressBody` and the usage table are appended to the summary so the
70
+ * partial work the agent did before failing isn't lost.
71
+ */
72
+ export declare function writeRunErrorOutputs(input: {
73
+ rendered: RenderedRunError;
74
+ toolState: ToolState;
75
+ }): Promise<void>;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Startup log formatting for the resolver pipeline. Computes the
3
+ * "model / agent / push / shell / timeout" block that main.ts prints
4
+ * after resolving the agent + model + payload.
5
+ */
6
+ import type { ResolvedPayload } from "./payload.ts";
7
+ /**
8
+ * Emit the startup block ("» model / agent / push / shell / timeout") after
9
+ * the agent and model are resolved. Single side-effect; no return.
10
+ */
11
+ export declare function logRunStartup(ctx: {
12
+ payload: ResolvedPayload;
13
+ resolvedModel: string | undefined;
14
+ agentName: string;
15
+ }): void;
@@ -43,6 +43,7 @@ export interface SpawnOptions {
43
43
  timeout?: number;
44
44
  activityTimeout?: number;
45
45
  onActivityTimeout?: (() => void) | undefined;
46
+ isPausedExternally?: () => boolean;
46
47
  cwd?: string;
47
48
  stdio?: ("pipe" | "ignore" | "inherit")[];
48
49
  onStdout?: (chunk: string) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pullfrog",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "pullfrog": "dist/cli.mjs",
@@ -16,6 +16,7 @@
16
16
  "typecheck": "tsc --noEmit",
17
17
  "build": "node esbuild.config.js && tsc -p tsconfig.exports.json",
18
18
  "check:entrypoints": "node scripts/check-entrypoint-imports.ts",
19
+ "docker": "node docker.ts",
19
20
  "play": "node play.ts",
20
21
  "runtest": "node test/run.ts",
21
22
  "scratch": "node scratch.ts",
@@ -49,7 +50,7 @@
49
50
  "fastmcp": "^3.34.0",
50
51
  "file-type": "^21.3.0",
51
52
  "husky": "^9.0.0",
52
- "opencode-ai": "1.1.56",
53
+ "opencode-ai": "1.15.1",
53
54
  "package-manager-detector": "^1.6.0",
54
55
  "picocolors": "^1.1.1",
55
56
  "semver": "^7.7.3",
File without changes