pullfrog 0.1.95 → 0.1.97
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/README.md +1 -0
- package/dist/agents/opencodePlugin.d.ts +4 -2
- package/dist/cli.mjs +1415 -1279
- package/dist/external.d.ts +1 -1
- package/dist/index.js +1358 -1231
- package/dist/internal/index.d.ts +1 -1
- package/dist/internal.js +107 -42
- package/dist/mcp/checkout.d.ts +2 -0
- package/dist/mcp/comment.d.ts +3 -0
- package/dist/models.d.ts +5 -5
- package/dist/toolState.d.ts +6 -4
- package/dist/utils/apiKeys.d.ts +26 -0
- package/dist/utils/changeImpact.d.ts +1 -0
- package/dist/utils/codexHome.d.ts +4 -6
- package/dist/utils/gitAuth.d.ts +1 -0
- package/dist/utils/github.d.ts +1 -1
- package/dist/utils/oauthWriteback.d.ts +5 -0
- package/dist/utils/openCodeModels.d.ts +19 -2
- package/dist/utils/patchWorkflowRunFields.d.ts +8 -1
- package/dist/utils/providerErrors.d.ts +4 -1
- package/dist/utils/runContext.d.ts +8 -0
- package/dist/utils/runContextData.d.ts +2 -0
- package/dist/utils/runErrorRenderer.d.ts +25 -9
- package/dist/utils/runStatusCheck.d.ts +11 -0
- package/dist/utils/statusChecks.d.ts +2 -1
- package/dist/utils/subprocess.d.ts +2 -0
- package/package.json +2 -2
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HOME and XDG dirs for every opencode subprocess, all inside this run. the runner user's own
|
|
3
|
+
* are shared by every run on a self-hosted host, and so is opencode's SQLite db in them (#1475).
|
|
4
|
+
*/
|
|
5
|
+
export declare function openCodeHomeEnv(tmpdir: string): {
|
|
6
|
+
HOME: string;
|
|
7
|
+
XDG_CONFIG_HOME: string;
|
|
8
|
+
XDG_DATA_HOME: string;
|
|
9
|
+
XDG_CACHE_HOME: string;
|
|
10
|
+
XDG_STATE_HOME: string;
|
|
11
|
+
};
|
|
1
12
|
/**
|
|
2
13
|
* Why the last `opencode models` came back empty, in opencode's own words.
|
|
3
14
|
*
|
|
@@ -9,11 +20,17 @@
|
|
|
9
20
|
export declare function getModelsFailure(): string | undefined;
|
|
10
21
|
/** Snapshot the set of models OpenCode can serve from the current env, BEFORE
|
|
11
22
|
* Pullfrog-stored credentials are merged in. Call once early in `main.ts`. */
|
|
12
|
-
export declare function captureBaselineModels(
|
|
23
|
+
export declare function captureBaselineModels(params: {
|
|
24
|
+
cliPath: string;
|
|
25
|
+
tmpdir: string;
|
|
26
|
+
}): void;
|
|
13
27
|
/** Snapshot the set of models OpenCode can serve AFTER dbSecrets +
|
|
14
28
|
* Codex auth.json are in place. Logs the diff against the baseline as
|
|
15
29
|
* `» BYOK auth enabled N model(s): …`. */
|
|
16
|
-
export declare function captureAuthorizedModels(
|
|
30
|
+
export declare function captureAuthorizedModels(params: {
|
|
31
|
+
cliPath: string;
|
|
32
|
+
tmpdir: string;
|
|
33
|
+
}): void;
|
|
17
34
|
/** A model whose credential the pool just probed. Added directly: a second
|
|
18
35
|
* `opencode models` would run inside the checkout and load the repo's own
|
|
19
36
|
* `.opencode` plugins, which can outlast its timeout and empty the set. */
|
|
@@ -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
|
-
|
|
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
|
/**
|
|
@@ -7,7 +7,8 @@ export declare const PROVIDER_NO_ENDPOINTS_LABEL = "provider no routable endpoin
|
|
|
7
7
|
* `PROVIDER_BILLING_EXHAUSTED_LABEL`: that label routes to a body whose CTA is
|
|
8
8
|
* "Top up your provider balance", and a capped ChatGPT or Zen plan has no
|
|
9
9
|
* balance to top up — it resets on its own. This label carries the cause into
|
|
10
|
-
* the headline and lets the generic body stand
|
|
10
|
+
* the hang headline and lets the generic body stand; a turn it ends directly
|
|
11
|
+
* gets its own wait-or-raise copy in `renderRunError` (#1474).
|
|
11
12
|
*/
|
|
12
13
|
export declare const PROVIDER_USAGE_LIMIT_LABEL = "provider usage limit reached";
|
|
13
14
|
export declare function findAnthropicSpendCap(text: string): {
|
|
@@ -35,6 +36,8 @@ export declare function isRouterKeylimitExhaustedError(text: string): boolean;
|
|
|
35
36
|
* is the user's own provider account.
|
|
36
37
|
*/
|
|
37
38
|
export declare function isProviderBillingExhausted(text: string): boolean;
|
|
39
|
+
/** A capped subscription window or a configured usage limit — see `PROVIDER_USAGE_LIMIT_LABEL`. */
|
|
40
|
+
export declare function isProviderUsageLimit(text: string): boolean;
|
|
38
41
|
/**
|
|
39
42
|
* OpenRouter accepted the request and found nowhere to send it: the account's
|
|
40
43
|
* data policy or guardrail settings exclude every provider serving the picked
|
|
@@ -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
|
}
|
|
@@ -13,19 +13,28 @@
|
|
|
13
13
|
* "key budget exhausted" string mid-run. Both render via
|
|
14
14
|
* `formatBillingErrorSummary` so the user sees actionable copy.
|
|
15
15
|
*
|
|
16
|
+
* 1a. Pre-rendered bodies — a throw site that already built the markdown
|
|
17
|
+
* (`MODEL_ACCESS_MARKER`, `SECRETS_UNAVAILABLE_MARKER`,
|
|
18
|
+
* `ROUTER_UNFUNDED_MARKER`, `CREDENTIAL_REJECTED_MARKER`,
|
|
19
|
+
* `CREDENTIAL_POOL_REFUSED_MARKER`) passes through verbatim on both surfaces.
|
|
20
|
+
*
|
|
16
21
|
* 2. BYOK provider billing-exhausted (#835) — DeepSeek "Insufficient
|
|
17
22
|
* Balance", Anthropic "credit balance is too low", OpenCode Zen
|
|
18
23
|
* `CreditsError`, Gemini "spending cap". Checked before api-key auth
|
|
19
24
|
* because billing-exhausted responses often carry 401 status codes
|
|
20
25
|
* that `isApiKeyAuthError` would otherwise mis-classify.
|
|
21
26
|
*
|
|
27
|
+
* 2a. Provider usage limit (#1474) — a capped subscription window or a
|
|
28
|
+
* configured workspace limit; "wait or raise it", never "top up".
|
|
29
|
+
*
|
|
22
30
|
* 3. API-key auth error — `isApiKeyAuthError` sniffs the raw error string
|
|
23
31
|
* (or the activity-timeout hang body when present, since that's where
|
|
24
32
|
* the underlying provider error often lands); `formatApiKeyErrorSummary`
|
|
25
33
|
* renders provider + console-link copy.
|
|
26
34
|
*
|
|
27
|
-
* 4. ProviderModelNotFoundError — configured model id
|
|
28
|
-
*
|
|
35
|
+
* 4. ProviderModelNotFoundError — configured model id not in the OpenCode
|
|
36
|
+
* catalog (opencode ≥1.18 words it `Model not found: <id>`, #1470);
|
|
37
|
+
* renders a nudge to pick a different model.
|
|
29
38
|
*
|
|
30
39
|
* 4a. No-provider-available (#1077) — the model IS in the catalog but the
|
|
31
40
|
* provider declines to route it on this account's plan (OpenCode Zen's
|
|
@@ -60,17 +69,24 @@
|
|
|
60
69
|
* event counts and a benign stderr tail are operator-grade detail that
|
|
61
70
|
* only alarm the average user.
|
|
62
71
|
*
|
|
63
|
-
* 6.
|
|
72
|
+
* 6. Unclassified provider error (#1474) — `errorMessage` starts with
|
|
73
|
+
* `provider error: `. opencode prefixes every provider-side turn failure
|
|
74
|
+
* with the provider's text; claude-code (a zero-event exit) and codex (no
|
|
75
|
+
* turn error, no stderr) prefix only our classifier label. Either names
|
|
76
|
+
* something the user can act on, so both surfaces get a lead line plus the
|
|
77
|
+
* raw text in a fenced block.
|
|
78
|
+
*
|
|
79
|
+
* 7. Default — the job summary gets a plain-English lead sentence plus the
|
|
64
80
|
* raw error in a fenced code block under the `### ❌ Pullfrog failed`
|
|
65
81
|
* banner; the PR comment collapses to the same one-line logs link as
|
|
66
82
|
* the hang case, since the raw internal string helps nobody on the PR.
|
|
67
83
|
*
|
|
68
|
-
* Net: the actionable classifications (billing, API-key,
|
|
69
|
-
* no-provider-available, context-overflow, run time limit,
|
|
70
|
-
* render identical bodies on
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* branding + rerun links.
|
|
84
|
+
* Net: the actionable classifications (billing, usage limit, API-key,
|
|
85
|
+
* model-not-found, no-provider-available, context-overflow, run time limit,
|
|
86
|
+
* transient-upstream, unclassified provider error) render identical bodies on
|
|
87
|
+
* both surfaces; the non-actionable ones (unexplained hang, generic) keep the
|
|
88
|
+
* forensics in the Actions job summary and show a calm one-liner in the PR
|
|
89
|
+
* comment, whose footer already carries Pullfrog branding + rerun links.
|
|
74
90
|
*/
|
|
75
91
|
import type { AgentDiagnostic } from "./agentHangReport.ts";
|
|
76
92
|
export type RenderedRunError = {
|
|
@@ -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
|
/**
|
|
@@ -50,6 +51,7 @@ export interface SpawnOptions {
|
|
|
50
51
|
killGroup?: boolean;
|
|
51
52
|
retain?: RetainMode;
|
|
52
53
|
maxRetainedBytes?: number;
|
|
54
|
+
signal?: AbortSignal | undefined;
|
|
53
55
|
}
|
|
54
56
|
/**
|
|
55
57
|
* Bounded string accumulator that keeps the tail of appended chunks.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pullfrog",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.97",
|
|
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.
|
|
69
|
+
"yes": "0.2.3",
|
|
70
70
|
"zod": "4.3.6"
|
|
71
71
|
},
|
|
72
72
|
"repository": {
|