pullfrog 0.1.84 → 0.1.85
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 +759 -396
- package/dist/configuration.d.ts +2 -2
- package/dist/external.d.ts +1 -1
- package/dist/index.js +50682 -50352
- package/dist/internal/index.d.ts +2 -0
- package/dist/internal.js +208 -37
- package/dist/utils/billingErrors.d.ts +1 -0
- package/dist/utils/codexHome.d.ts +1 -0
- package/dist/utils/credentialPool.d.ts +10 -0
- package/dist/utils/runContext.d.ts +2 -0
- package/dist/utils/runContextData.d.ts +2 -0
- package/dist/utils/setup.d.ts +8 -2
- package/dist/utils/subscriptionCredentials.d.ts +80 -0
- package/dist/utils/subscriptionProbe.d.ts +22 -0
- package/package.json +1 -1
package/dist/internal/index.d.ts
CHANGED
|
@@ -26,6 +26,8 @@ export { createLeapingProgressComment, deleteProgressCommentApi, getProgressComm
|
|
|
26
26
|
export { PROVIDER_DASHBOARDS, type ProviderDashboard } from "../utils/providerDashboards.ts";
|
|
27
27
|
export type { RunStatusCheckConclusion, RunStatusCheckOctokit, } from "../utils/runStatusCheck.ts";
|
|
28
28
|
export { APPROVAL_CHECK_NAME, createRunStatusCheck, finalizeRunStatusCheck, RUN_STATUS_CHECK_NAME, runStatusCheckNeedsFinalizing, } from "../utils/runStatusCheck.ts";
|
|
29
|
+
export * from "../utils/subscriptionCredentials.ts";
|
|
30
|
+
export { probeSubscription, SubscriptionCredentialError, subscriptionIdentity, } from "../utils/subscriptionProbe.ts";
|
|
29
31
|
export { isValidTimeString, parseTimeString, TIMEOUT_DISABLED, } from "../utils/time.ts";
|
|
30
32
|
export type { XaiAuthBody } from "../utils/xaiOAuth.ts";
|
|
31
33
|
export { parseXaiAuthBody, refreshXaiAuthBody, stringifyXaiAuthBody, } from "../utils/xaiOAuth.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.
|
|
11
|
+
version: "0.1.85",
|
|
12
12
|
cliContractVersion: "1",
|
|
13
13
|
type: "module",
|
|
14
14
|
bin: {
|
|
@@ -15000,6 +15000,17 @@ var providers = {
|
|
|
15000
15000
|
// see the big-pickle note above (#1077).
|
|
15001
15001
|
isFree: true
|
|
15002
15002
|
},
|
|
15003
|
+
// Zen's FREE Meituan preview (listed 2026-09-25). Zen's docs: zero
|
|
15004
|
+
// retention, no training. Go lists the same free id, but one key reaches
|
|
15005
|
+
// both, so the promo gets one row, here with the other free ones.
|
|
15006
|
+
"longcat-preview": {
|
|
15007
|
+
displayName: "LongCat Preview",
|
|
15008
|
+
description: "Meituan preview, free for a limited time",
|
|
15009
|
+
resolve: "opencode/longcat-2.5-preview-free",
|
|
15010
|
+
// free to run, still gated on the provider's own OPENCODE_API_KEY —
|
|
15011
|
+
// see the big-pickle note above (#1077).
|
|
15012
|
+
isFree: true
|
|
15013
|
+
},
|
|
15003
15014
|
// Zen's live free MiMo, and the second free row in a menu that big-pickle
|
|
15004
15015
|
// was alone in since `mimo-v2-pro-free` lost its model.
|
|
15005
15016
|
mimo: {
|
|
@@ -15633,7 +15644,7 @@ function isRouterTier(value) {
|
|
|
15633
15644
|
}
|
|
15634
15645
|
var PROVIDER_LADDERS = {
|
|
15635
15646
|
anthropic: {
|
|
15636
|
-
minimal: "anthropic/claude-
|
|
15647
|
+
minimal: "anthropic/claude-sonnet",
|
|
15637
15648
|
light: "anthropic/claude-sonnet",
|
|
15638
15649
|
standard: "anthropic/claude-opus",
|
|
15639
15650
|
deep: "anthropic/claude-opus"
|
|
@@ -16211,35 +16222,25 @@ var modes = computeModes("opencode");
|
|
|
16211
16222
|
|
|
16212
16223
|
// utils/billingErrors.ts
|
|
16213
16224
|
function commercialPaywallBody(params) {
|
|
16214
|
-
|
|
16225
|
+
let action;
|
|
16215
16226
|
switch (params.reason) {
|
|
16216
16227
|
case "commercial":
|
|
16217
|
-
|
|
16218
|
-
|
|
16219
|
-
"",
|
|
16220
|
-
pitch,
|
|
16221
|
-
"",
|
|
16222
|
-
`[Upgrade now \u2192](${params.url})`
|
|
16223
|
-
].join("\n");
|
|
16228
|
+
action = "upgrade";
|
|
16229
|
+
break;
|
|
16224
16230
|
case "subscription_ended":
|
|
16225
|
-
|
|
16226
|
-
|
|
16227
|
-
"",
|
|
16228
|
-
pitch,
|
|
16229
|
-
"",
|
|
16230
|
-
`[Resubscribe \u2192](${params.url})`
|
|
16231
|
-
].join("\n");
|
|
16231
|
+
action = "resubscribe";
|
|
16232
|
+
break;
|
|
16232
16233
|
case "subscription_unpaid":
|
|
16233
|
-
|
|
16234
|
-
|
|
16235
|
-
"",
|
|
16236
|
-
"Update the card on file to resume runs.",
|
|
16237
|
-
"",
|
|
16238
|
-
`[Update billing \u2192](${params.url})`
|
|
16239
|
-
].join("\n");
|
|
16234
|
+
action = "update billing";
|
|
16235
|
+
break;
|
|
16240
16236
|
default:
|
|
16241
16237
|
return params.reason;
|
|
16242
16238
|
}
|
|
16239
|
+
return [
|
|
16240
|
+
`**Pullfrog is ${params.freshReply ? "still paused" : "paused"} for ${params.ownerLogin}.**`,
|
|
16241
|
+
"",
|
|
16242
|
+
`An org owner can [${action}](${params.url}) to resume private-repo runs.`
|
|
16243
|
+
].join("\n");
|
|
16243
16244
|
}
|
|
16244
16245
|
|
|
16245
16246
|
// utils/buildPullfrogFooter.ts
|
|
@@ -16935,19 +16936,47 @@ async function runStatusCheckNeedsFinalizing(params) {
|
|
|
16935
16936
|
}
|
|
16936
16937
|
}
|
|
16937
16938
|
|
|
16938
|
-
// utils/
|
|
16939
|
-
var
|
|
16940
|
-
|
|
16941
|
-
|
|
16942
|
-
|
|
16943
|
-
|
|
16944
|
-
|
|
16945
|
-
|
|
16946
|
-
|
|
16947
|
-
|
|
16948
|
-
|
|
16949
|
-
|
|
16950
|
-
|
|
16939
|
+
// utils/subscriptionCredentials.ts
|
|
16940
|
+
var subscriptionNameSchema = external_exports.enum([
|
|
16941
|
+
"CLAUDE_CODE_OAUTH_TOKEN",
|
|
16942
|
+
"CODEX_AUTH_JSON",
|
|
16943
|
+
"GROK_AUTH_JSON"
|
|
16944
|
+
]);
|
|
16945
|
+
var subscriptionSchema = external_exports.object({
|
|
16946
|
+
id: external_exports.string(),
|
|
16947
|
+
credentialId: external_exports.string(),
|
|
16948
|
+
name: subscriptionNameSchema,
|
|
16949
|
+
label: external_exports.string(),
|
|
16950
|
+
owner: external_exports.string(),
|
|
16951
|
+
inherited: external_exports.boolean(),
|
|
16952
|
+
shared: external_exports.boolean(),
|
|
16953
|
+
registeredAt: external_exports.string()
|
|
16954
|
+
});
|
|
16955
|
+
var subscriptionListSchema = external_exports.object({
|
|
16956
|
+
subscriptions: external_exports.array(subscriptionSchema),
|
|
16957
|
+
writable: external_exports.boolean()
|
|
16958
|
+
});
|
|
16959
|
+
var subscriptionInputSchema = external_exports.object({
|
|
16960
|
+
name: subscriptionNameSchema,
|
|
16961
|
+
value: external_exports.string().trim().min(1).refine((value) => Buffer.byteLength(value, "utf8") <= 49152),
|
|
16962
|
+
replaceId: external_exports.string().optional()
|
|
16963
|
+
});
|
|
16964
|
+
var credentialCandidateSchema = external_exports.object({
|
|
16965
|
+
id: external_exports.string(),
|
|
16966
|
+
name: external_exports.string(),
|
|
16967
|
+
source: external_exports.enum(["repo", "account", "personal"])
|
|
16968
|
+
});
|
|
16969
|
+
var credentialAccessSchema = external_exports.object({
|
|
16970
|
+
token: external_exports.string(),
|
|
16971
|
+
candidates: external_exports.array(credentialCandidateSchema)
|
|
16972
|
+
});
|
|
16973
|
+
var selectedCredentialSchema = external_exports.object({
|
|
16974
|
+
name: external_exports.string(),
|
|
16975
|
+
value: external_exports.string(),
|
|
16976
|
+
receipt: external_exports.string()
|
|
16977
|
+
});
|
|
16978
|
+
function subscriptionLabel(input) {
|
|
16979
|
+
return input.email ?? `\u2022\u2022\u2022\u2022 ${input.suffix}`;
|
|
16951
16980
|
}
|
|
16952
16981
|
|
|
16953
16982
|
// utils/xaiOAuth.ts
|
|
@@ -17012,6 +17041,137 @@ function stringifyXaiAuthBody(body) {
|
|
|
17012
17041
|
return `${JSON.stringify(body, null, 2)}
|
|
17013
17042
|
`;
|
|
17014
17043
|
}
|
|
17044
|
+
|
|
17045
|
+
// utils/subscriptionProbe.ts
|
|
17046
|
+
var identitySchema = external_exports.object({
|
|
17047
|
+
email: external_exports.string().email().optional(),
|
|
17048
|
+
sub: external_exports.string().optional(),
|
|
17049
|
+
user_id: external_exports.string().optional(),
|
|
17050
|
+
account_id: external_exports.string().optional(),
|
|
17051
|
+
email_verified: external_exports.boolean().optional()
|
|
17052
|
+
});
|
|
17053
|
+
var codexUsageSchema = external_exports.object({
|
|
17054
|
+
rate_limit: external_exports.object({ allowed: external_exports.boolean(), limit_reached: external_exports.boolean() }).optional()
|
|
17055
|
+
});
|
|
17056
|
+
var SubscriptionCredentialError = class extends Error {
|
|
17057
|
+
};
|
|
17058
|
+
async function subscriptionIdentity(input) {
|
|
17059
|
+
const empty = { email: null, subject: null };
|
|
17060
|
+
if (input.name === "CLAUDE_CODE_OAUTH_TOKEN") return empty;
|
|
17061
|
+
const codex = input.name === "CODEX_AUTH_JSON" ? parseCodexAuthBody(input.value) : null;
|
|
17062
|
+
const grok = input.name === "GROK_AUTH_JSON" ? parseXaiAuthBody(input.value) : null;
|
|
17063
|
+
const token = codex?.tokens.access_token ?? grok?.tokens.access_token;
|
|
17064
|
+
if (!token) throw new SubscriptionCredentialError("invalid subscription credential");
|
|
17065
|
+
const response = await readSubscriptionEndpoint({
|
|
17066
|
+
url: codex ? "https://chatgpt.com/backend-api/wham/usage" : "https://auth.x.ai/oauth2/userinfo",
|
|
17067
|
+
token,
|
|
17068
|
+
accountId: codex?.tokens.account_id
|
|
17069
|
+
});
|
|
17070
|
+
if (response?.status === 401)
|
|
17071
|
+
throw new SubscriptionCredentialError("subscription credential was rejected");
|
|
17072
|
+
if (!response?.ok) return empty;
|
|
17073
|
+
const parsed = identitySchema.safeParse(await response.json().catch(() => null));
|
|
17074
|
+
if (!parsed.success) return empty;
|
|
17075
|
+
const subject = parsed.data.sub ?? parsed.data.user_id;
|
|
17076
|
+
return {
|
|
17077
|
+
email: parsed.data.email_verified === false ? null : parsed.data.email ?? null,
|
|
17078
|
+
subject: subject ? `${subject}:${parsed.data.account_id ?? ""}` : null
|
|
17079
|
+
};
|
|
17080
|
+
}
|
|
17081
|
+
async function readSubscriptionEndpoint(input) {
|
|
17082
|
+
const headers = new Headers({ authorization: `Bearer ${input.token}` });
|
|
17083
|
+
if (input.accountId) headers.set("ChatGPT-Account-Id", input.accountId);
|
|
17084
|
+
if (input.grokBilling) headers.set("x-xai-token-auth", "xai-grok-cli");
|
|
17085
|
+
return fetch(input.url, {
|
|
17086
|
+
headers,
|
|
17087
|
+
redirect: "error",
|
|
17088
|
+
signal: AbortSignal.timeout(1e4)
|
|
17089
|
+
}).catch(() => null);
|
|
17090
|
+
}
|
|
17091
|
+
async function probeSubscription(input) {
|
|
17092
|
+
if (input.name === "CLAUDE_CODE_OAUTH_TOKEN") {
|
|
17093
|
+
const result = await preflightClaudeSubscription({ token: input.value, model: input.model });
|
|
17094
|
+
return result.usable ? "usable" : "rejected";
|
|
17095
|
+
}
|
|
17096
|
+
const codex = input.name === "CODEX_AUTH_JSON" ? parseCodexAuthBody(input.value) : null;
|
|
17097
|
+
const grok = input.name === "GROK_AUTH_JSON" ? parseXaiAuthBody(input.value) : null;
|
|
17098
|
+
const auth = codex ?? grok;
|
|
17099
|
+
if (!auth || auth.refresh_rejected_at) return "rejected";
|
|
17100
|
+
if (grok && input.model)
|
|
17101
|
+
return probeInference({
|
|
17102
|
+
name: "XAI_API_KEY",
|
|
17103
|
+
value: grok.tokens.access_token,
|
|
17104
|
+
model: input.model
|
|
17105
|
+
});
|
|
17106
|
+
const response = await readSubscriptionEndpoint({
|
|
17107
|
+
url: codex ? "https://chatgpt.com/backend-api/wham/usage" : "https://cli-chat-proxy.grok.com/v1/billing?format=credits",
|
|
17108
|
+
token: auth.tokens.access_token,
|
|
17109
|
+
accountId: codex?.tokens.account_id,
|
|
17110
|
+
grokBilling: !!grok
|
|
17111
|
+
});
|
|
17112
|
+
if (response?.status === 401) return "rejected";
|
|
17113
|
+
if (!response?.ok) return "unknown";
|
|
17114
|
+
const body = await response.json().catch(() => null);
|
|
17115
|
+
if (codex) {
|
|
17116
|
+
const parsed = codexUsageSchema.safeParse(body);
|
|
17117
|
+
const limit = parsed.success ? parsed.data.rate_limit : void 0;
|
|
17118
|
+
if (!limit) return "unknown";
|
|
17119
|
+
return limit.allowed && !limit.limit_reached ? "usable" : "rejected";
|
|
17120
|
+
}
|
|
17121
|
+
return "unknown";
|
|
17122
|
+
}
|
|
17123
|
+
async function probeInference(input) {
|
|
17124
|
+
const anthropic = input.name === "ANTHROPIC_API_KEY";
|
|
17125
|
+
const openai = input.name === "OPENAI_API_KEY";
|
|
17126
|
+
if (!anthropic && !openai && input.name !== "XAI_API_KEY") {
|
|
17127
|
+
const result = await verifyCredential({ envVar: input.name, value: input.value });
|
|
17128
|
+
return result === "dead" ? "rejected" : result === "alive" ? "usable" : "unknown";
|
|
17129
|
+
}
|
|
17130
|
+
const headers = new Headers({ "content-type": "application/json" });
|
|
17131
|
+
if (anthropic) {
|
|
17132
|
+
headers.set("x-api-key", input.value);
|
|
17133
|
+
headers.set("anthropic-version", "2023-06-01");
|
|
17134
|
+
} else headers.set("authorization", `Bearer ${input.value}`);
|
|
17135
|
+
const response = await fetch(
|
|
17136
|
+
anthropic ? "https://api.anthropic.com/v1/messages" : openai ? "https://api.openai.com/v1/responses" : "https://api.x.ai/v1/chat/completions",
|
|
17137
|
+
{
|
|
17138
|
+
method: "POST",
|
|
17139
|
+
headers,
|
|
17140
|
+
body: JSON.stringify(
|
|
17141
|
+
openai ? { model: input.model, input: "Reply OK.", max_output_tokens: 16, store: false } : {
|
|
17142
|
+
model: input.model,
|
|
17143
|
+
messages: [{ role: "user", content: "Reply OK." }],
|
|
17144
|
+
max_tokens: 1
|
|
17145
|
+
}
|
|
17146
|
+
),
|
|
17147
|
+
redirect: "error",
|
|
17148
|
+
signal: AbortSignal.timeout(1e4)
|
|
17149
|
+
}
|
|
17150
|
+
).catch(() => null);
|
|
17151
|
+
if (response?.status === 400 && input.name === "XAI_API_KEY") {
|
|
17152
|
+
const error48 = external_exports.object({ error: external_exports.string() }).safeParse(await response.json().catch(() => null));
|
|
17153
|
+
return error48.success && error48.data.error.startsWith("Incorrect API key provided.") ? "rejected" : "unknown";
|
|
17154
|
+
}
|
|
17155
|
+
await response?.body?.cancel();
|
|
17156
|
+
if (!response) return "unknown";
|
|
17157
|
+
if (response.ok) return "usable";
|
|
17158
|
+
return [401, 402, 403, 429].includes(response.status) ? "rejected" : "unknown";
|
|
17159
|
+
}
|
|
17160
|
+
|
|
17161
|
+
// utils/time.ts
|
|
17162
|
+
var TIMEOUT_DISABLED = "none";
|
|
17163
|
+
var TIME_STRING_REGEX = /^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/;
|
|
17164
|
+
function parseTimeString(input) {
|
|
17165
|
+
const match = input.match(TIME_STRING_REGEX);
|
|
17166
|
+
if (!match || !match[1] && !match[2] && !match[3]) return null;
|
|
17167
|
+
const hours = parseInt(match[1] || "0", 10);
|
|
17168
|
+
const minutes = parseInt(match[2] || "0", 10);
|
|
17169
|
+
const seconds = parseInt(match[3] || "0", 10);
|
|
17170
|
+
return (hours * 3600 + minutes * 60 + seconds) * 1e3;
|
|
17171
|
+
}
|
|
17172
|
+
function isValidTimeString(input) {
|
|
17173
|
+
return parseTimeString(input) !== null;
|
|
17174
|
+
}
|
|
17015
17175
|
export {
|
|
17016
17176
|
APPROVAL_CHECK_NAME,
|
|
17017
17177
|
AUTO_EFFICIENT,
|
|
@@ -17036,6 +17196,7 @@ export {
|
|
|
17036
17196
|
ROUTER_TIERS,
|
|
17037
17197
|
RUN_STATUS_CHECK_NAME,
|
|
17038
17198
|
SUBSIDY_RUNG,
|
|
17199
|
+
SubscriptionCredentialError,
|
|
17039
17200
|
TIMEOUT_DISABLED,
|
|
17040
17201
|
autoLadder,
|
|
17041
17202
|
autoRoutedSlug,
|
|
@@ -17048,6 +17209,8 @@ export {
|
|
|
17048
17209
|
countOutstandingPullfrogThreads,
|
|
17049
17210
|
createLeapingProgressComment,
|
|
17050
17211
|
createRunStatusCheck,
|
|
17212
|
+
credentialAccessSchema,
|
|
17213
|
+
credentialCandidateSchema,
|
|
17051
17214
|
decodeJwtExpMs,
|
|
17052
17215
|
defaultAutoTier,
|
|
17053
17216
|
deleteProgressCommentApi,
|
|
@@ -17081,6 +17244,7 @@ export {
|
|
|
17081
17244
|
parseModel,
|
|
17082
17245
|
parseTimeString,
|
|
17083
17246
|
parseXaiAuthBody,
|
|
17247
|
+
probeSubscription,
|
|
17084
17248
|
providers,
|
|
17085
17249
|
pullfrogMcpName,
|
|
17086
17250
|
refreshCodexAuthBody,
|
|
@@ -17096,9 +17260,16 @@ export {
|
|
|
17096
17260
|
runStatusCheckNeedsFinalizing,
|
|
17097
17261
|
rungLabel,
|
|
17098
17262
|
rungPosition,
|
|
17263
|
+
selectedCredentialSchema,
|
|
17099
17264
|
stringifyCodexAuthBody,
|
|
17100
17265
|
stringifyXaiAuthBody,
|
|
17101
17266
|
stripExistingFooter,
|
|
17267
|
+
subscriptionIdentity,
|
|
17268
|
+
subscriptionInputSchema,
|
|
17269
|
+
subscriptionLabel,
|
|
17270
|
+
subscriptionListSchema,
|
|
17271
|
+
subscriptionNameSchema,
|
|
17272
|
+
subscriptionSchema,
|
|
17102
17273
|
truncateAtLineBoundary,
|
|
17103
17274
|
updateProgressComment,
|
|
17104
17275
|
verifyCredential
|
|
@@ -63,6 +63,7 @@ export declare function commercialPaywallBody(params: {
|
|
|
63
63
|
reason: CommercialRefusal;
|
|
64
64
|
ownerLogin: string;
|
|
65
65
|
url: string;
|
|
66
|
+
freshReply?: boolean | undefined;
|
|
66
67
|
}): string;
|
|
67
68
|
/**
|
|
68
69
|
* commercial-gate copy for action runs, linked to the account billing card.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare function clearInstalledSubscription(name: "CODEX_AUTH_JSON" | "GROK_AUTH_JSON"): void;
|
|
1
2
|
/** sandbox-hidden home for pullfrog-managed on-disk secrets in CI. bash via
|
|
2
3
|
* MCP shell tmpfs-overlays this path; opencode's internal auth module
|
|
3
4
|
* bypasses external_directory and reaches the real file. mirrors the
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RunContextData } from "./runContextData.ts";
|
|
2
|
+
/** load one subscription per provider for model discovery; keep the pool unflattened. */
|
|
3
|
+
export declare function initializeCredentialPool(ctx: RunContextData, model?: string): Promise<void>;
|
|
4
|
+
export declare function resolvePoolModel(input: {
|
|
5
|
+
codexAgent: boolean;
|
|
6
|
+
}): string | undefined;
|
|
7
|
+
export declare function selectConfiguredCredential(input: {
|
|
8
|
+
ctx: RunContextData;
|
|
9
|
+
model: string | undefined;
|
|
10
|
+
}): Promise<boolean>;
|
|
@@ -2,6 +2,7 @@ import type { PushPermission, ShellPermission } from "../external.ts";
|
|
|
2
2
|
import type { RouterTier } from "../models.ts";
|
|
3
3
|
import type { CommercialRefusal } from "./billingErrors.ts";
|
|
4
4
|
import type { RepoContext } from "./github.ts";
|
|
5
|
+
import type { CredentialAccess } from "./subscriptionCredentials.ts";
|
|
5
6
|
export interface Mode {
|
|
6
7
|
id: string;
|
|
7
8
|
name: string;
|
|
@@ -57,6 +58,7 @@ export interface RepoSettings {
|
|
|
57
58
|
*/
|
|
58
59
|
export type AccountPlan = "none" | "payg";
|
|
59
60
|
export interface RunContext {
|
|
61
|
+
credentialAccess?: CredentialAccess | undefined;
|
|
60
62
|
settings: RepoSettings;
|
|
61
63
|
apiToken: string;
|
|
62
64
|
oss: boolean;
|
|
@@ -3,7 +3,9 @@ import type { RouterTier } from "../models.ts";
|
|
|
3
3
|
import type { CommercialRefusal } from "./billingErrors.ts";
|
|
4
4
|
import { type OctokitWithPlugins } from "./github.ts";
|
|
5
5
|
import { type AccountPlan, type RepoSettings } from "./runContext.ts";
|
|
6
|
+
import type { CredentialAccess } from "./subscriptionCredentials.ts";
|
|
6
7
|
export interface RunContextData {
|
|
8
|
+
credentialAccess?: CredentialAccess | undefined;
|
|
7
9
|
repo: {
|
|
8
10
|
owner: string;
|
|
9
11
|
name: string;
|
package/dist/utils/setup.d.ts
CHANGED
|
@@ -5,9 +5,15 @@ export interface SetupOptions {
|
|
|
5
5
|
tempDir: string;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* Create a shared temp directory for the action
|
|
8
|
+
* Create a shared temp directory for the action, removed when the run's scope
|
|
9
|
+
* exits. a persistent self-hosted runner never wipes `/tmp`, so every run used
|
|
10
|
+
* to leave its tree (the OpenCode install alone is hundreds of MB) until the
|
|
11
|
+
* disk filled and every job on the runner died.
|
|
9
12
|
*/
|
|
10
|
-
export declare function createTempDirectory():
|
|
13
|
+
export declare function createTempDirectory(): {
|
|
14
|
+
path: string;
|
|
15
|
+
[Symbol.dispose]: () => void;
|
|
16
|
+
};
|
|
11
17
|
/**
|
|
12
18
|
* snapshot-and-delete the GHA runner's known credential leak surfaces inside
|
|
13
19
|
* `$RUNNER_TEMP` before the agent spawns. without this, a shell-capable agent
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const subscriptionNameSchema: z.ZodEnum<{
|
|
3
|
+
CLAUDE_CODE_OAUTH_TOKEN: "CLAUDE_CODE_OAUTH_TOKEN";
|
|
4
|
+
CODEX_AUTH_JSON: "CODEX_AUTH_JSON";
|
|
5
|
+
GROK_AUTH_JSON: "GROK_AUTH_JSON";
|
|
6
|
+
}>;
|
|
7
|
+
export type SubscriptionName = z.infer<typeof subscriptionNameSchema>;
|
|
8
|
+
export declare const subscriptionSchema: z.ZodObject<{
|
|
9
|
+
id: z.ZodString;
|
|
10
|
+
credentialId: z.ZodString;
|
|
11
|
+
name: z.ZodEnum<{
|
|
12
|
+
CLAUDE_CODE_OAUTH_TOKEN: "CLAUDE_CODE_OAUTH_TOKEN";
|
|
13
|
+
CODEX_AUTH_JSON: "CODEX_AUTH_JSON";
|
|
14
|
+
GROK_AUTH_JSON: "GROK_AUTH_JSON";
|
|
15
|
+
}>;
|
|
16
|
+
label: z.ZodString;
|
|
17
|
+
owner: z.ZodString;
|
|
18
|
+
inherited: z.ZodBoolean;
|
|
19
|
+
shared: z.ZodBoolean;
|
|
20
|
+
registeredAt: z.ZodString;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
export type Subscription = z.infer<typeof subscriptionSchema>;
|
|
23
|
+
export declare const subscriptionListSchema: z.ZodObject<{
|
|
24
|
+
subscriptions: z.ZodArray<z.ZodObject<{
|
|
25
|
+
id: z.ZodString;
|
|
26
|
+
credentialId: z.ZodString;
|
|
27
|
+
name: z.ZodEnum<{
|
|
28
|
+
CLAUDE_CODE_OAUTH_TOKEN: "CLAUDE_CODE_OAUTH_TOKEN";
|
|
29
|
+
CODEX_AUTH_JSON: "CODEX_AUTH_JSON";
|
|
30
|
+
GROK_AUTH_JSON: "GROK_AUTH_JSON";
|
|
31
|
+
}>;
|
|
32
|
+
label: z.ZodString;
|
|
33
|
+
owner: z.ZodString;
|
|
34
|
+
inherited: z.ZodBoolean;
|
|
35
|
+
shared: z.ZodBoolean;
|
|
36
|
+
registeredAt: z.ZodString;
|
|
37
|
+
}, z.core.$strip>>;
|
|
38
|
+
writable: z.ZodBoolean;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
export declare const subscriptionInputSchema: z.ZodObject<{
|
|
41
|
+
name: z.ZodEnum<{
|
|
42
|
+
CLAUDE_CODE_OAUTH_TOKEN: "CLAUDE_CODE_OAUTH_TOKEN";
|
|
43
|
+
CODEX_AUTH_JSON: "CODEX_AUTH_JSON";
|
|
44
|
+
GROK_AUTH_JSON: "GROK_AUTH_JSON";
|
|
45
|
+
}>;
|
|
46
|
+
value: z.ZodString;
|
|
47
|
+
replaceId: z.ZodOptional<z.ZodString>;
|
|
48
|
+
}, z.core.$strip>;
|
|
49
|
+
export declare const credentialCandidateSchema: z.ZodObject<{
|
|
50
|
+
id: z.ZodString;
|
|
51
|
+
name: z.ZodString;
|
|
52
|
+
source: z.ZodEnum<{
|
|
53
|
+
repo: "repo";
|
|
54
|
+
account: "account";
|
|
55
|
+
personal: "personal";
|
|
56
|
+
}>;
|
|
57
|
+
}, z.core.$strip>;
|
|
58
|
+
export type CredentialCandidate = z.infer<typeof credentialCandidateSchema>;
|
|
59
|
+
export declare const credentialAccessSchema: z.ZodObject<{
|
|
60
|
+
token: z.ZodString;
|
|
61
|
+
candidates: z.ZodArray<z.ZodObject<{
|
|
62
|
+
id: z.ZodString;
|
|
63
|
+
name: z.ZodString;
|
|
64
|
+
source: z.ZodEnum<{
|
|
65
|
+
repo: "repo";
|
|
66
|
+
account: "account";
|
|
67
|
+
personal: "personal";
|
|
68
|
+
}>;
|
|
69
|
+
}, z.core.$strip>>;
|
|
70
|
+
}, z.core.$strip>;
|
|
71
|
+
export type CredentialAccess = z.infer<typeof credentialAccessSchema>;
|
|
72
|
+
export declare const selectedCredentialSchema: z.ZodObject<{
|
|
73
|
+
name: z.ZodString;
|
|
74
|
+
value: z.ZodString;
|
|
75
|
+
receipt: z.ZodString;
|
|
76
|
+
}, z.core.$strip>;
|
|
77
|
+
export declare function subscriptionLabel(input: {
|
|
78
|
+
email: string | null;
|
|
79
|
+
suffix: string;
|
|
80
|
+
}): string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { SubscriptionName } from "./subscriptionCredentials.ts";
|
|
2
|
+
export declare class SubscriptionCredentialError extends Error {
|
|
3
|
+
}
|
|
4
|
+
export declare function subscriptionIdentity(input: {
|
|
5
|
+
name: SubscriptionName;
|
|
6
|
+
value: string;
|
|
7
|
+
}): Promise<{
|
|
8
|
+
email: string | null;
|
|
9
|
+
subject: string | null;
|
|
10
|
+
}>;
|
|
11
|
+
/** unknown quota is not a reason to skip a credential or change who pays. */
|
|
12
|
+
export declare function probeSubscription(input: {
|
|
13
|
+
name: SubscriptionName;
|
|
14
|
+
value: string;
|
|
15
|
+
model?: string | undefined;
|
|
16
|
+
}): Promise<"usable" | "rejected" | "unknown">;
|
|
17
|
+
/** probe the chosen model, not a models-list permission a restricted key may lack. */
|
|
18
|
+
export declare function probeInference(input: {
|
|
19
|
+
name: string;
|
|
20
|
+
value: string;
|
|
21
|
+
model: string;
|
|
22
|
+
}): Promise<"usable" | "rejected" | "unknown">;
|