pullfrog 0.1.29 → 0.1.31

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.
Files changed (60) hide show
  1. package/dist/agents/claudePretoolGate.d.ts +5 -1
  2. package/dist/agents/opencodePlugin.d.ts +2 -2
  3. package/dist/agents/postRun.d.ts +8 -31
  4. package/dist/agents/shared.d.ts +6 -0
  5. package/dist/agents/subagentToolGates.d.ts +22 -40
  6. package/dist/cli.mjs +63989 -59666
  7. package/dist/external.d.ts +45 -2
  8. package/dist/index.js +62509 -58186
  9. package/dist/internal/index.d.ts +2 -2
  10. package/dist/internal.js +99 -33
  11. package/dist/mcp/checkSuite.d.ts +3 -1
  12. package/dist/mcp/checkout.d.ts +4 -2
  13. package/dist/mcp/comment.d.ts +12 -4
  14. package/dist/mcp/commitInfo.d.ts +3 -1
  15. package/dist/mcp/dependencies.d.ts +6 -2
  16. package/dist/mcp/git.d.ts +32 -6
  17. package/dist/mcp/issue.d.ts +26 -1
  18. package/dist/mcp/issueComments.d.ts +3 -1
  19. package/dist/mcp/issueEvents.d.ts +3 -1
  20. package/dist/mcp/issueInfo.d.ts +3 -1
  21. package/dist/mcp/labels.d.ts +16 -1
  22. package/dist/mcp/output.d.ts +6 -2
  23. package/dist/mcp/pr.d.ts +19 -2
  24. package/dist/mcp/prInfo.d.ts +3 -1
  25. package/dist/mcp/resolveRepoCtx.d.ts +34 -0
  26. package/dist/mcp/review.d.ts +9 -3
  27. package/dist/mcp/reviewComments.d.ts +9 -3
  28. package/dist/mcp/selectMode.d.ts +3 -1
  29. package/dist/mcp/server.d.ts +7 -1
  30. package/dist/mcp/shared.d.ts +18 -1
  31. package/dist/mcp/shell.d.ts +6 -2
  32. package/dist/mcp/upload.d.ts +3 -1
  33. package/dist/mcp/xrepo.d.ts +15 -0
  34. package/dist/models.d.ts +58 -5
  35. package/dist/modes.d.ts +1 -1
  36. package/dist/toolState.d.ts +66 -16
  37. package/dist/utils/apiCommit.d.ts +40 -0
  38. package/dist/utils/apiKeys.d.ts +19 -0
  39. package/dist/utils/buildPullfrogFooter.d.ts +27 -0
  40. package/dist/utils/claudeSubscription.d.ts +30 -0
  41. package/dist/utils/errorReport.d.ts +2 -2
  42. package/dist/utils/github.d.ts +28 -2
  43. package/dist/utils/instructions.d.ts +11 -0
  44. package/dist/utils/isTransientNetworkError.d.ts +10 -0
  45. package/dist/utils/learnings.d.ts +14 -0
  46. package/dist/utils/modelAccess.d.ts +64 -0
  47. package/dist/utils/openCodeModels.d.ts +2 -2
  48. package/dist/utils/payload.d.ts +16 -0
  49. package/dist/utils/proxy.d.ts +3 -5
  50. package/dist/utils/runContext.d.ts +4 -0
  51. package/dist/utils/runContextData.d.ts +10 -0
  52. package/dist/utils/runErrorRenderer.d.ts +2 -2
  53. package/dist/utils/setup.d.ts +18 -3
  54. package/dist/utils/token.d.ts +22 -3
  55. package/dist/yes/index.d.ts +32 -0
  56. package/dist/yes/standard-schema.d.ts +117 -0
  57. package/dist/yes.js +1244 -0
  58. package/package.json +19 -10
  59. package/dist/utils/byokFallback.d.ts +0 -44
  60. package/dist/utils/retry.d.ts +0 -13
@@ -1,5 +1,10 @@
1
1
  import { throttling } from "@octokit/plugin-throttling";
2
2
  import { Octokit } from "@octokit/rest";
3
+ /** GitHub Actions OIDC request credentials, stashed before env wipes */
4
+ export interface OidcCredentials {
5
+ requestUrl: string;
6
+ requestToken: string;
7
+ }
3
8
  export interface InstallationToken {
4
9
  token: string;
5
10
  expires_at: string;
@@ -35,9 +40,23 @@ type GitHubAppPermissions = {
35
40
  workflows?: WriteOnly;
36
41
  };
37
42
  type AcquireTokenOptions = {
38
- repos?: string[];
43
+ repos?: string[] | undefined;
39
44
  permissions?: GitHubAppPermissions;
45
+ /**
46
+ * stashed OIDC credentials for minting after restricted mode deletes
47
+ * ACTIONS_ID_TOKEN_REQUEST_* from process.env (mid-run token refresh)
48
+ */
49
+ oidc?: OidcCredentials | undefined;
40
50
  };
51
+ /**
52
+ * mint a GitHub Actions OIDC ID token from stashed credentials without
53
+ * touching process.env — `core.getIDToken` reads the env vars directly,
54
+ * which restricted mode has already deleted by the time a refresh runs.
55
+ * throws TokenExchangeError on HTTP errors and a "timed out" Error on
56
+ * timeout so `acquireNewToken`'s retry predicate treats 5xx/429/timeouts
57
+ * as transient.
58
+ */
59
+ export declare function fetchIdTokenFromStash(creds: OidcCredentials): Promise<string>;
41
60
  /**
42
61
  * ensure a GitHub token is available in the environment.
43
62
  *
@@ -51,6 +70,13 @@ type AcquireTokenOptions = {
51
70
  * main() directly and never calls this.
52
71
  */
53
72
  export declare function ensureGitHubToken(): Promise<void>;
73
+ /**
74
+ * retry predicate shared by token mints: 4xx is terminal user state (app not
75
+ * installed, permissions wrong) — retrying just triples our log noise and the
76
+ * user's CI bill (see #693). 5xx/429 and network failures are transient
77
+ * (vercel cold start, github outage, rate limit) and should ride the backoff.
78
+ */
79
+ export declare function isTransientTokenError(error: unknown): boolean;
54
80
  export declare function acquireNewToken(opts?: AcquireTokenOptions): Promise<string>;
55
81
  export interface RepoContext {
56
82
  owner: string;
@@ -74,5 +100,5 @@ export interface UsageSummary {
74
100
  };
75
101
  }
76
102
  export declare function writeGitHubUsageSummaryToFile(path: string): Promise<void>;
77
- export declare function createOctokit(token: string): OctokitWithPlugins;
103
+ export declare function createOctokit(token: string, refreshAuth?: (stale: string) => Promise<string>): OctokitWithPlugins;
78
104
  export {};
@@ -9,6 +9,9 @@ interface InstructionsContext {
9
9
  modes: Mode[];
10
10
  agentId: AgentId;
11
11
  outputSchema?: Record<string, unknown> | undefined;
12
+ /** commits are created via the GitHub API (commit_changes tool) so GitHub
13
+ * signs them — flips the Git instructions to the signed-commits flow. */
14
+ signedCommits: boolean;
12
15
  /** absolute path to the seeded learnings tmpfile, or null when the file
13
16
  * couldn't be seeded for some reason. main.ts always seeds, so in
14
17
  * practice this is always set; the null case keeps the type honest. */
@@ -21,6 +24,14 @@ interface InstructionsContext {
21
24
  * `describeSetupFailure`), rendered as a SETUP HOOK FAILED banner. empty
22
25
  * string when the hook succeeded, was skipped, or wasn't configured. */
23
26
  setupHookFailure: string;
27
+ /** operator-authored cross-repo brief (`Account.xrepoBrief`), rendered in
28
+ * the CROSS-REPO section on --xrepo runs. null/empty otherwise. */
29
+ xrepoBrief: string | null;
30
+ /** absolute path to the seeded cross-repo learnings tmpfile (--xrepo runs
31
+ * only), or null. */
32
+ xrepoLearningsFilePath: string | null;
33
+ /** server-parsed TOC for the cross-repo learnings body. */
34
+ xrepoLearningsHeadings: LearningsHeading[];
24
35
  }
25
36
  export interface ResolvedInstructions {
26
37
  full: string;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Predicate for transient network errors that should be retried (vs. fail fast
3
+ * on explicit HTTP status / validation errors that carry their own message).
4
+ *
5
+ * Matches errors from `fetch` (`fetch failed`), TCP-level interruption
6
+ * (`ECONNRESET`, `ETIMEDOUT`), and `AbortSignal.timeout` (`AbortError`).
7
+ * Callers may pass `extraPatterns` to whitelist additional transient
8
+ * substrings on `error.message` (e.g. provider-specific framings).
9
+ */
10
+ export declare function isTransientNetworkError(error: unknown, extraPatterns?: string[]): boolean;
@@ -29,7 +29,9 @@ export { MAX_LEARNINGS_LENGTH, truncateAtLineBoundary };
29
29
  * agent-targetable on long-lived repos; there is no fixed taxonomy.
30
30
  */
31
31
  export declare const LEARNINGS_FILE_NAME = "pullfrog-learnings.md";
32
+ export declare const XREPO_LEARNINGS_FILE_NAME = "pullfrog-xrepo-learnings.md";
32
33
  export declare function learningsFilePath(tmpdir: string): string;
34
+ export declare function xrepoLearningsFilePath(tmpdir: string): string;
33
35
  /** seed the rolling learnings tmpfile with the verbatim DB body (or empty
34
36
  * string for fresh repos). returns the absolute path. the parsed TOC is
35
37
  * carried separately via `RepoSettings.learningsHeadings` and rendered
@@ -39,6 +41,11 @@ export declare function seedLearningsFile(params: {
39
41
  tmpdir: string;
40
42
  current: string | null;
41
43
  }): Promise<string>;
44
+ /** seed the org-level cross-repo learnings tmpfile (--xrepo runs only). */
45
+ export declare function seedXrepoLearningsFile(params: {
46
+ tmpdir: string;
47
+ current: string | null;
48
+ }): Promise<string>;
42
49
  /** read the agent-edited learnings file. returns null when the file is
43
50
  * missing or unreadable (treated as "no change"). caps content at the
44
51
  * server's max length to avoid a 400 round-trip. */
@@ -60,3 +67,10 @@ export declare function readLearningsFile(path: string): Promise<string | null>;
60
67
  * normal end-of-run path and the SIGINT/SIGTERM handler.
61
68
  */
62
69
  export declare function persistLearnings(ctx: ToolContext): Promise<void>;
70
+ /**
71
+ * Read the agent-edited cross-repo learnings tmpfile and PATCH it to
72
+ * `Account.xrepoLearnings`. Org-level analogue of `persistLearnings` —
73
+ * same best-effort + unchanged-from-seed gating. Only seeded on --xrepo runs,
74
+ * so this is a no-op when `xrepoLearningsFilePath` is unset.
75
+ */
76
+ export declare function persistXrepoLearnings(ctx: ToolContext): Promise<void>;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Model-access gate for explicitly-requested per-run models (`--opus`,
3
+ * `--model=<slug>`). An explicit model the run can't serve hard-fails *before*
4
+ * the agent starts with one consistent, reason-tailored error.
5
+ *
6
+ * The provenance split lives upstream: `payload.modelExplicit` is true only for
7
+ * a flag in the triggerer's own @pullfrog prompt. A standing default (repo
8
+ * setting, a model flag in org/repo `baseInstructions`, or a trigger's fallback
9
+ * instructions) keeps `modelExplicit = false` and never reaches the error
10
+ * branches here — a missing key for a standing default surfaces through
11
+ * `validateAgentApiKey`'s missing-key error instead (#938).
12
+ *
13
+ * `decideModelAccess` is pure (no env / IO) so the branching is unit-testable;
14
+ * `buildModelAccessError` renders the user-facing markdown that `main.ts`
15
+ * throws and `runErrorRenderer.ts` re-surfaces on both run surfaces.
16
+ */
17
+ export type ModelAccessReason = "oss" | "byok_no_key" | "router";
18
+ export type ModelAccessDecision = {
19
+ kind: "ok";
20
+ }
21
+ /** route through the Router/OSS proxy, re-targeted to the requested model. */
22
+ | {
23
+ kind: "proxy";
24
+ target: string;
25
+ }
26
+ /** run BYOK with the requested model — clear the minted proxy target. */
27
+ | {
28
+ kind: "byok";
29
+ } | {
30
+ kind: "error";
31
+ reason: ModelAccessReason;
32
+ };
33
+ /**
34
+ * decide whether an (already-resolved) requested model can run, and how.
35
+ *
36
+ * - non-explicit / no model → `ok` (caller's missing-key validation applies).
37
+ * - proxy active + OSS → only the funded subsidy target routes; a different
38
+ * model needs the repo's own key (`byok`) else `error("oss")`.
39
+ * - proxy active + Router → honor any Router-servable model (`proxy`); fall to
40
+ * BYOK when locally authorized, else `error("router")`.
41
+ * - no proxy → the resolved model must be locally authorized, else
42
+ * `error("byok_no_key")`.
43
+ */
44
+ export declare function decideModelAccess(input: {
45
+ modelExplicit: boolean;
46
+ model: string | undefined;
47
+ oss: boolean;
48
+ proxyActive: boolean;
49
+ subsidyTarget: string | undefined;
50
+ resolvedModel: string | undefined;
51
+ authorized: Set<string>;
52
+ }): ModelAccessDecision;
53
+ /** marker on the throw message so `runErrorRenderer` can reclassify it. */
54
+ export declare const MODEL_ACCESS_MARKER = "requested model is not available";
55
+ /**
56
+ * render the model-access failure body (used for both the thrown error and the
57
+ * PR comment / job summary). one shape, reason-branched why → CTA.
58
+ */
59
+ export declare function buildModelAccessError(input: {
60
+ reason: ModelAccessReason;
61
+ model: string;
62
+ owner: string;
63
+ name: string;
64
+ }): string;
@@ -6,6 +6,6 @@ export declare function captureBaselineModels(cliPath: string): void;
6
6
  * `» BYOK auth enabled N model(s): …`. */
7
7
  export declare function captureAuthorizedModels(cliPath: string): void;
8
8
  /** Authorized set captured after Pullfrog-stored auth is applied. Throws if
9
- * called before `captureAuthorizedModels` — the call sites (fallback gate,
10
- * api-key validation, auto-select) all run strictly after capture. */
9
+ * called before `captureAuthorizedModels` — the call sites (api-key
10
+ * validation, auto-select) all run strictly after capture. */
11
11
  export declare function getAuthorizedModels(): Set<string>;
@@ -5,10 +5,18 @@ export declare const JsonPayload: import("arktype/internal/variants/object.ts").
5
5
  version: string;
6
6
  prompt: string;
7
7
  model?: string | undefined;
8
+ modelExplicit?: boolean | undefined;
8
9
  triggerer?: string | undefined;
10
+ baseInstructions?: string | undefined;
9
11
  eventInstructions?: string;
10
12
  previousRunsNote?: string;
11
13
  event?: object;
14
+ xrepo?: {
15
+ mode: "all" | "explicit";
16
+ read: string[];
17
+ write: string[];
18
+ unavailable?: string[];
19
+ } | undefined;
12
20
  timeout?: string | undefined;
13
21
  progressComment?: {
14
22
  id: string;
@@ -32,11 +40,19 @@ export declare function resolvePayload(resolvedPromptInput: ResolvedPromptInput,
32
40
  "~pullfrog": true;
33
41
  version: string;
34
42
  model: string | undefined;
43
+ modelExplicit: boolean;
35
44
  prompt: string;
36
45
  triggerer: string | undefined;
46
+ baseInstructions: string | undefined;
37
47
  eventInstructions: string | undefined;
38
48
  previousRunsNote: string | undefined;
39
49
  event: PayloadEvent;
50
+ xrepo: {
51
+ mode: "all" | "explicit";
52
+ read: string[];
53
+ write: string[];
54
+ unavailable?: string[];
55
+ } | undefined;
40
56
  timeout: string | undefined;
41
57
  cwd: string | undefined;
42
58
  progressComment: {
@@ -4,7 +4,8 @@
4
4
  * billing accounts) or OSS-grant paths.
5
5
  *
6
6
  * Authenticates one of two ways:
7
- * - production: GitHub Actions OIDC token via `core.getIDToken`
7
+ * - production: GitHub Actions OIDC token minted from the stashed
8
+ * credentials via `fetchIdTokenFromStash` (env-free)
8
9
  * - local dev (`API_URL` is localhost): `x-dev-repo` header bypass
9
10
  *
10
11
  * `runProxyResolution` is the entrypoint `main.ts` calls. It wraps
@@ -17,11 +18,8 @@
17
18
  * - 503 → `TransientError` (transient sync issue — retry next dispatch)
18
19
  */
19
20
  import type { ToolState } from "../toolState.ts";
21
+ import { type OidcCredentials } from "./github.ts";
20
22
  import type { ResolvedPayload } from "./payload.ts";
21
- export interface OidcCredentials {
22
- requestUrl: string;
23
- requestToken: string;
24
- }
25
23
  /**
26
24
  * Run `resolveProxyModel`; if it throws a Billing or Transient error, render
27
25
  * the user-facing summary, mirror it to the PR progress comment, and rethrow.
@@ -31,10 +31,14 @@ export interface RepoSettings {
31
31
  push: PushPermission;
32
32
  shell: ShellPermission;
33
33
  prApproveEnabled: boolean;
34
+ signedCommits: boolean;
34
35
  modeInstructions: Record<string, string>;
35
36
  learnings: string | null;
36
37
  learningsHeadings: LearningsHeading[];
37
38
  envAllowlist: string | null;
39
+ xrepoBrief: string | null;
40
+ xrepoLearnings: string | null;
41
+ xrepoLearningsHeadings: LearningsHeading[];
38
42
  }
39
43
  /**
40
44
  * Account-level billing plan. Orthogonal to repo-level OSS status. Mirrors
@@ -18,6 +18,16 @@ interface ResolveRunContextDataParams {
18
18
  octokit: OctokitWithPlugins;
19
19
  token: string;
20
20
  }
21
+ /**
22
+ * true when the action is pinned to a full commit SHA (vs the moving `@v0`
23
+ * tag or a branch). GitHub runs the action's `post:` hook (and reads
24
+ * `action.yml`) straight from the checked-out action ref, so a SHA pin freezes
25
+ * that checkout forever: the main agent still floats to the latest `^semver`
26
+ * via the npm bootstrap (this code is proof — it ran), but the post-run
27
+ * cleanup step keeps executing the pinned commit's source and never receives
28
+ * fixes. surfaced in the log and PR footers to nudge repos back to `@v0`.
29
+ */
30
+ export declare function isActionPinnedToSha(): boolean;
21
31
  /**
22
32
  * initialize run context data: parse context, fetch repo info and settings
23
33
  */
@@ -24,8 +24,8 @@
24
24
  * the underlying provider error often lands); `formatApiKeyErrorSummary`
25
25
  * renders provider + console-link copy.
26
26
  *
27
- * 4. ProviderModelNotFoundError — stale free-fallback model id no longer
28
- * in the OpenCode catalog; renders a nudge to add a BYOK key.
27
+ * 4. ProviderModelNotFoundError — configured model id no longer in the
28
+ * OpenCode catalog; renders a nudge to pick a different model.
29
29
  *
30
30
  * 5. Activity-timeout hang — `errorMessage` starts with
31
31
  * `"activity timeout"` or `"agent still pending"` AND none of the
@@ -1,5 +1,5 @@
1
1
  import type { ShellPermission } from "../external.ts";
2
- import type { ToolState } from "../toolState.ts";
2
+ import { type ToolState } from "../toolState.ts";
3
3
  import type { OctokitWithPlugins } from "./github.ts";
4
4
  export interface SetupOptions {
5
5
  tempDir: string;
@@ -61,15 +61,30 @@ export interface GitContext {
61
61
  postCheckoutScript: string | null;
62
62
  }
63
63
  export type SetupGitParams = GitContext;
64
+ /** GitContext plus an explicit working-tree directory (primary cwd or a
65
+ * secondary clone under ctx.tmpdir/xrepo/<name>). */
66
+ export interface ConfigureRepoGitParams extends GitContext {
67
+ dir: string;
68
+ }
64
69
  /**
65
- * setup git configuration and authentication for the repository.
70
+ * setup git configuration + authentication for the PRIMARY repo working tree
71
+ * (process.cwd()). thin wrapper over configureRepoGit. preserves the existing
72
+ * single-repo call shape in main.ts.
73
+ */
74
+ export declare function setupGit(params: SetupGitParams): Promise<void>;
75
+ /**
76
+ * setup git configuration and authentication for a repository working tree at
77
+ * `params.dir`. used for the primary repo (dir = cwd) and for secondary repos
78
+ * cloned on demand by checkout_repo (dir = ctx.tmpdir/xrepo/<name>).
66
79
  * - configures git identity (user.email, user.name)
67
80
  * - sets up authentication via gitToken (minimal contents:write)
81
+ * - records pushUrl + initialHead onto the repo's RepoToolState (must already
82
+ * be registered in toolState.repos)
68
83
  *
69
84
  * gitToken is a minimal-permission token (contents + workflows) used for git operations.
70
85
  * it is assumed to be potentially exfiltratable, so it has limited scope.
71
86
  */
72
- export declare function setupGit(params: SetupGitParams): Promise<void>;
87
+ export declare function configureRepoGit(params: ConfigureRepoGitParams): Promise<void>;
73
88
  /**
74
89
  * snapshot the current HEAD as either a branch name (when on a named branch)
75
90
  * or a literal SHA (when detached). used by setupGit to pin the run-entry
@@ -1,7 +1,12 @@
1
- import type { PushPermission } from "../external.ts";
2
- import { acquireNewToken } from "./github.ts";
1
+ import type { PushPermission, XrepoConfig } from "../external.ts";
2
+ import { acquireNewToken, type OidcCredentials } from "./github.ts";
3
3
  export { acquireNewToken as acquireInstallationToken };
4
4
  export { revokeGitHubInstallationToken as revokeInstallationToken };
5
+ /**
6
+ * get the refresh function for the MCP token, if re-acquisition is possible.
7
+ * pass to `createOctokit` so a mid-run 401 triggers a refresh + retry (#891).
8
+ */
9
+ export declare function getMcpTokenRefresh(): ((stale: string) => Promise<string>) | undefined;
5
10
  /**
6
11
  * get the job-scoped token from action input.
7
12
  * this token has permissions defined by the workflow's permissions block.
@@ -15,19 +20,33 @@ export declare function getJobToken(): string;
15
20
  export type TokenRef = {
16
21
  gitToken: string;
17
22
  mcpToken: string;
23
+ readToken?: string | undefined;
24
+ refreshGitToken?: ((stale: string) => Promise<string>) | undefined;
18
25
  [Symbol.asyncDispose]: () => Promise<void>;
19
26
  };
20
27
  type ResolveTokensParams = {
21
28
  push: PushPermission;
29
+ xrepo?: XrepoConfig | undefined;
30
+ /**
31
+ * OIDC credentials stashed by main.ts before the restricted-mode env wipe —
32
+ * the mid-run MCP token refresh mints from this snapshot (#891). null when
33
+ * OIDC isn't available (local dev, external token).
34
+ */
35
+ oidc: OidcCredentials | null;
22
36
  };
23
37
  /**
24
38
  * resolve tokens for the action run.
25
39
  *
26
- * creates two separate tokens:
40
+ * creates two separate tokens (three on cross-repo runs):
27
41
  * - gitToken: contents permission based on `push` setting (assumed exfiltratable)
28
42
  * - push: enabled → contents:write (can push)
29
43
  * - push: disabled → contents:read (read-only)
30
44
  * - mcpToken: full installation token - used for GitHub API calls in MCP tools (not exfiltratable)
45
+ * - readToken (xrepo only): contents:read over the read set, for cloning read-tier secondaries
46
+ *
47
+ * on cross-repo runs, gitToken + mcpToken are scoped to the WRITE set (always
48
+ * incl. the primary), so a writable secondary can take PRs; read-only
49
+ * secondaries route through readToken instead.
31
50
  *
32
51
  * security-conscious users can pass their own token via GH_TOKEN env var or inputs.token.
33
52
  */
@@ -0,0 +1,32 @@
1
+ import type { StandardSchemaV1 } from "./standard-schema.ts";
2
+ export type { StandardSchemaV1 } from "./standard-schema.ts";
3
+ export declare function range(n: number): number[];
4
+ export declare function range(start: number, end: number): number[];
5
+ export declare function range(n: number, fn: (i: number) => number): number[];
6
+ export declare function schedule(fn: (i: number) => number, count: number): number[];
7
+ type InferInput<S> = S extends StandardSchemaV1<infer I, any> ? I : never;
8
+ type InferOutput<S> = S extends StandardSchemaV1<any, infer O> ? O : never;
9
+ export interface OpOptions<TReturn = any> {
10
+ name?: string;
11
+ ttl?: number;
12
+ maxItems?: number;
13
+ retries?: number[];
14
+ cacheHit?: ((key: string) => void) | null;
15
+ cacheMiss?: ((key: string) => void) | null;
16
+ skipCache?: (result: TReturn) => boolean;
17
+ bail?: (error: unknown) => boolean;
18
+ }
19
+ export interface OpObjectOptions<TInputSchema extends StandardSchemaV1 | undefined = undefined, TOutputSchema extends StandardSchemaV1 | undefined = undefined, TRun extends (input: TInputSchema extends StandardSchemaV1 ? InferOutput<TInputSchema> : any, ctx?: any) => Promise<TOutputSchema extends StandardSchemaV1 ? InferInput<TOutputSchema> : any> = (input: TInputSchema extends StandardSchemaV1 ? InferOutput<TInputSchema> : any, ctx?: any) => Promise<TOutputSchema extends StandardSchemaV1 ? InferInput<TOutputSchema> : any>> extends OpOptions<TOutputSchema extends StandardSchemaV1 ? InferOutput<TOutputSchema> : Awaited<ReturnType<TRun>>> {
20
+ input?: TInputSchema;
21
+ output?: TOutputSchema;
22
+ run: TRun;
23
+ }
24
+ type AnyAsyncFn = (...args: any[]) => Promise<any>;
25
+ type Input<F extends AnyAsyncFn> = Parameters<F>[0];
26
+ export type OpFunction<F extends AnyAsyncFn> = F & {
27
+ clear: (key?: Input<F>) => void;
28
+ has: (key: Input<F>) => boolean;
29
+ invalidate: (predicate: (key: Input<F>) => boolean) => number;
30
+ };
31
+ export declare function op<F extends AnyAsyncFn>(fn: F, options?: OpOptions<Awaited<ReturnType<F>>>): OpFunction<F>;
32
+ export declare function op<TInputSchema extends StandardSchemaV1 | undefined = undefined, TOutputSchema extends StandardSchemaV1 | undefined = undefined, TRun extends (input: TInputSchema extends StandardSchemaV1 ? InferOutput<TInputSchema> : any, ctx?: any) => Promise<TOutputSchema extends StandardSchemaV1 ? InferInput<TOutputSchema> : any> = (input: TInputSchema extends StandardSchemaV1 ? InferOutput<TInputSchema> : any, ctx?: any) => Promise<TOutputSchema extends StandardSchemaV1 ? InferInput<TOutputSchema> : any>>(options: OpObjectOptions<TInputSchema, TOutputSchema, TRun>): OpFunction<(input: TInputSchema extends StandardSchemaV1 ? InferInput<TInputSchema> : Parameters<TRun>[0], ctx?: TRun extends (input: any, ctx: infer C, ...rest: any[]) => any ? C : never) => Promise<TOutputSchema extends StandardSchemaV1 ? InferOutput<TOutputSchema> : Awaited<ReturnType<TRun>>>>;
@@ -0,0 +1,117 @@
1
+ /** The Standard Typed interface. This is a base type extended by other specs. */
2
+ export interface StandardTypedV1<Input = unknown, Output = Input> {
3
+ /** The Standard properties. */
4
+ readonly "~standard": StandardTypedV1.Props<Input, Output>;
5
+ }
6
+ export declare namespace StandardTypedV1 {
7
+ /** The Standard Typed properties interface. */
8
+ interface Props<Input = unknown, Output = Input> {
9
+ /** The version number of the standard. */
10
+ readonly version: 1;
11
+ /** The vendor name of the schema library. */
12
+ readonly vendor: string;
13
+ /** Inferred types associated with the schema. */
14
+ readonly types?: Types<Input, Output> | undefined;
15
+ }
16
+ /** The Standard Typed types interface. */
17
+ interface Types<Input = unknown, Output = Input> {
18
+ /** The input type of the schema. */
19
+ readonly input: Input;
20
+ /** The output type of the schema. */
21
+ readonly output: Output;
22
+ }
23
+ /** Infers the input type of a Standard Typed. */
24
+ type InferInput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["input"];
25
+ /** Infers the output type of a Standard Typed. */
26
+ type InferOutput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["output"];
27
+ }
28
+ /** The Standard Schema interface. */
29
+ export interface StandardSchemaV1<Input = unknown, Output = Input> {
30
+ /** The Standard Schema properties. */
31
+ readonly "~standard": StandardSchemaV1.Props<Input, Output>;
32
+ }
33
+ export declare namespace StandardSchemaV1 {
34
+ /** The Standard Schema properties interface. */
35
+ interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> {
36
+ /** Validates unknown input values. */
37
+ readonly validate: (value: unknown, options?: StandardSchemaV1.Options | undefined) => Result<Output> | Promise<Result<Output>>;
38
+ }
39
+ /** The result interface of the validate function. */
40
+ type Result<Output> = SuccessResult<Output> | FailureResult;
41
+ /** The result interface if validation succeeds. */
42
+ interface SuccessResult<Output> {
43
+ /** The typed output value. */
44
+ readonly value: Output;
45
+ /** A falsy value for `issues` indicates success. */
46
+ readonly issues?: undefined;
47
+ }
48
+ interface Options {
49
+ /** Explicit support for additional vendor-specific parameters, if needed. */
50
+ readonly libraryOptions?: Record<string, unknown> | undefined;
51
+ }
52
+ /** The result interface if validation fails. */
53
+ interface FailureResult {
54
+ /** The issues of failed validation. */
55
+ readonly issues: ReadonlyArray<Issue>;
56
+ }
57
+ /** The issue interface of the failure output. */
58
+ interface Issue {
59
+ /** The error message of the issue. */
60
+ readonly message: string;
61
+ /** The path of the issue, if any. */
62
+ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
63
+ }
64
+ /** The path segment interface of the issue. */
65
+ interface PathSegment {
66
+ /** The key representing a path segment. */
67
+ readonly key: PropertyKey;
68
+ }
69
+ /** The Standard types interface. */
70
+ interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> {
71
+ }
72
+ /** Infers the input type of a Standard. */
73
+ type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;
74
+ /** Infers the output type of a Standard. */
75
+ type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
76
+ }
77
+ /** The Standard JSON Schema interface. */
78
+ export interface StandardJSONSchemaV1<Input = unknown, Output = Input> {
79
+ /** The Standard JSON Schema properties. */
80
+ readonly "~standard": StandardJSONSchemaV1.Props<Input, Output>;
81
+ }
82
+ export declare namespace StandardJSONSchemaV1 {
83
+ /** The Standard JSON Schema properties interface. */
84
+ interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> {
85
+ /** Methods for generating the input/output JSON Schema. */
86
+ readonly jsonSchema: StandardJSONSchemaV1.Converter;
87
+ }
88
+ /** The Standard JSON Schema converter interface. */
89
+ interface Converter {
90
+ /** Converts the input type to JSON Schema. May throw if conversion is not supported. */
91
+ readonly input: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>;
92
+ /** Converts the output type to JSON Schema. May throw if conversion is not supported. */
93
+ readonly output: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>;
94
+ }
95
+ /**
96
+ * The target version of the generated JSON Schema.
97
+ *
98
+ * It is *strongly recommended* that implementers support `"draft-2020-12"` and `"draft-07"`, as they are both in wide use. All other targets can be implemented on a best-effort basis. Libraries should throw if they don't support a specified target.
99
+ *
100
+ * The `"openapi-3.0"` target is intended as a standardized specifier for OpenAPI 3.0 which is a superset of JSON Schema `"draft-04"`.
101
+ */
102
+ type Target = "draft-2020-12" | "draft-07" | "openapi-3.0" | ({} & string);
103
+ /** The options for the input/output methods. */
104
+ interface Options {
105
+ /** Specifies the target version of the generated JSON Schema. Support for all versions is on a best-effort basis. If a given version is not supported, the library should throw. */
106
+ readonly target: Target;
107
+ /** Explicit support for additional vendor-specific parameters, if needed. */
108
+ readonly libraryOptions?: Record<string, unknown> | undefined;
109
+ }
110
+ /** The Standard types interface. */
111
+ interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> {
112
+ }
113
+ /** Infers the input type of a Standard. */
114
+ type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;
115
+ /** Infers the output type of a Standard. */
116
+ type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
117
+ }