@tokenfactory/acc-runner 0.25.1 → 0.27.0
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 +77 -4
- package/package.json +1 -1
- package/dist/anthropic-auth.d.ts +0 -53
- package/dist/anthropic-auth.d.ts.map +0 -1
- package/dist/anthropic-auth.js +0 -89
- package/dist/anthropic-auth.js.map +0 -1
- package/dist/bin-resolve.d.ts +0 -16
- package/dist/bin-resolve.d.ts.map +0 -1
- package/dist/bin-resolve.js +0 -35
- package/dist/bin-resolve.js.map +0 -1
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -128
- package/dist/cli.js.map +0 -1
- package/dist/config.d.ts +0 -121
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -396
- package/dist/config.js.map +0 -1
- package/dist/cost-pricing.d.ts +0 -130
- package/dist/cost-pricing.d.ts.map +0 -1
- package/dist/cost-pricing.js +0 -191
- package/dist/cost-pricing.js.map +0 -1
- package/dist/doctor.d.ts +0 -37
- package/dist/doctor.d.ts.map +0 -1
- package/dist/doctor.js +0 -658
- package/dist/doctor.js.map +0 -1
- package/dist/failure-classifier.d.ts +0 -112
- package/dist/failure-classifier.d.ts.map +0 -1
- package/dist/failure-classifier.js +0 -353
- package/dist/failure-classifier.js.map +0 -1
- package/dist/gh.d.ts +0 -22
- package/dist/gh.d.ts.map +0 -1
- package/dist/gh.js +0 -48
- package/dist/gh.js.map +0 -1
- package/dist/git.d.ts +0 -50
- package/dist/git.d.ts.map +0 -1
- package/dist/git.js +0 -127
- package/dist/git.js.map +0 -1
- package/dist/github-client.d.ts +0 -133
- package/dist/github-client.d.ts.map +0 -1
- package/dist/github-client.js +0 -234
- package/dist/github-client.js.map +0 -1
- package/dist/keychain.d.ts +0 -21
- package/dist/keychain.d.ts.map +0 -1
- package/dist/keychain.js +0 -45
- package/dist/keychain.js.map +0 -1
- package/dist/login.d.ts +0 -12
- package/dist/login.d.ts.map +0 -1
- package/dist/login.js +0 -133
- package/dist/login.js.map +0 -1
- package/dist/logout.d.ts +0 -2
- package/dist/logout.d.ts.map +0 -1
- package/dist/logout.js +0 -31
- package/dist/logout.js.map +0 -1
- package/dist/mcp-spawn.d.ts +0 -30
- package/dist/mcp-spawn.d.ts.map +0 -1
- package/dist/mcp-spawn.js +0 -145
- package/dist/mcp-spawn.js.map +0 -1
- package/dist/messaging.d.ts +0 -49
- package/dist/messaging.d.ts.map +0 -1
- package/dist/messaging.js +0 -36
- package/dist/messaging.js.map +0 -1
- package/dist/pkg-version.d.ts +0 -3
- package/dist/pkg-version.d.ts.map +0 -1
- package/dist/pkg-version.js +0 -20
- package/dist/pkg-version.js.map +0 -1
- package/dist/profiles/designer-prompt.d.ts +0 -18
- package/dist/profiles/designer-prompt.d.ts.map +0 -1
- package/dist/profiles/designer-prompt.js +0 -172
- package/dist/profiles/designer-prompt.js.map +0 -1
- package/dist/profiles/developer-prompt.d.ts +0 -24
- package/dist/profiles/developer-prompt.d.ts.map +0 -1
- package/dist/profiles/developer-prompt.js +0 -24
- package/dist/profiles/developer-prompt.js.map +0 -1
- package/dist/profiles/manager-prompt.d.ts +0 -34
- package/dist/profiles/manager-prompt.d.ts.map +0 -1
- package/dist/profiles/manager-prompt.js +0 -93
- package/dist/profiles/manager-prompt.js.map +0 -1
- package/dist/profiles/tester-prompt.d.ts +0 -28
- package/dist/profiles/tester-prompt.d.ts.map +0 -1
- package/dist/profiles/tester-prompt.js +0 -165
- package/dist/profiles/tester-prompt.js.map +0 -1
- package/dist/prompt.d.ts +0 -38
- package/dist/prompt.d.ts.map +0 -1
- package/dist/prompt.js +0 -78
- package/dist/prompt.js.map +0 -1
- package/dist/runtime/cache-dir.d.ts +0 -2
- package/dist/runtime/cache-dir.d.ts.map +0 -1
- package/dist/runtime/cache-dir.js +0 -15
- package/dist/runtime/cache-dir.js.map +0 -1
- package/dist/runtime/conflict-resolver.d.ts +0 -65
- package/dist/runtime/conflict-resolver.d.ts.map +0 -1
- package/dist/runtime/conflict-resolver.js +0 -477
- package/dist/runtime/conflict-resolver.js.map +0 -1
- package/dist/runtime/expand-args.d.ts +0 -28
- package/dist/runtime/expand-args.d.ts.map +0 -1
- package/dist/runtime/expand-args.js +0 -50
- package/dist/runtime/expand-args.js.map +0 -1
- package/dist/runtime/locks.d.ts +0 -21
- package/dist/runtime/locks.d.ts.map +0 -1
- package/dist/runtime/locks.js +0 -97
- package/dist/runtime/locks.js.map +0 -1
- package/dist/runtime/provision-mutex.d.ts +0 -37
- package/dist/runtime/provision-mutex.d.ts.map +0 -1
- package/dist/runtime/provision-mutex.js +0 -67
- package/dist/runtime/provision-mutex.js.map +0 -1
- package/dist/runtime/quarantine.d.ts +0 -26
- package/dist/runtime/quarantine.d.ts.map +0 -1
- package/dist/runtime/quarantine.js +0 -50
- package/dist/runtime/quarantine.js.map +0 -1
- package/dist/runtime/resolution-integrity.d.ts +0 -86
- package/dist/runtime/resolution-integrity.d.ts.map +0 -1
- package/dist/runtime/resolution-integrity.js +0 -248
- package/dist/runtime/resolution-integrity.js.map +0 -1
- package/dist/runtime/reviewer.d.ts +0 -81
- package/dist/runtime/reviewer.d.ts.map +0 -1
- package/dist/runtime/reviewer.js +0 -374
- package/dist/runtime/reviewer.js.map +0 -1
- package/dist/runtime/rework.d.ts +0 -48
- package/dist/runtime/rework.d.ts.map +0 -1
- package/dist/runtime/rework.js +0 -136
- package/dist/runtime/rework.js.map +0 -1
- package/dist/runtime/singleton.d.ts +0 -47
- package/dist/runtime/singleton.d.ts.map +0 -1
- package/dist/runtime/singleton.js +0 -200
- package/dist/runtime/singleton.js.map +0 -1
- package/dist/runtime/version-drift.d.ts +0 -31
- package/dist/runtime/version-drift.d.ts.map +0 -1
- package/dist/runtime/version-drift.js +0 -114
- package/dist/runtime/version-drift.js.map +0 -1
- package/dist/runtime/worktree.d.ts +0 -74
- package/dist/runtime/worktree.d.ts.map +0 -1
- package/dist/runtime/worktree.js +0 -206
- package/dist/runtime/worktree.js.map +0 -1
- package/dist/secrets/inject.d.ts +0 -70
- package/dist/secrets/inject.d.ts.map +0 -1
- package/dist/secrets/inject.js +0 -102
- package/dist/secrets/inject.js.map +0 -1
- package/dist/supabase.d.ts +0 -4
- package/dist/supabase.d.ts.map +0 -1
- package/dist/supabase.js +0 -36
- package/dist/supabase.js.map +0 -1
- package/dist/task-runner.d.ts +0 -313
- package/dist/task-runner.d.ts.map +0 -1
- package/dist/task-runner.js +0 -1766
- package/dist/task-runner.js.map +0 -1
- package/dist/token-provider.d.ts +0 -50
- package/dist/token-provider.d.ts.map +0 -1
- package/dist/token-provider.js +0 -177
- package/dist/token-provider.js.map +0 -1
- package/dist/types.d.ts +0 -120
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -16
- package/dist/types.js.map +0 -1
- package/dist/version-check.d.ts +0 -17
- package/dist/version-check.d.ts.map +0 -1
- package/dist/version-check.js +0 -56
- package/dist/version-check.js.map +0 -1
- package/dist/watch.d.ts +0 -295
- package/dist/watch.d.ts.map +0 -1
- package/dist/watch.js +0 -1532
- package/dist/watch.js.map +0 -1
package/dist/git.d.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
export declare const ACC_BRANCH_PATTERN: RegExp;
|
|
2
|
-
export declare function isAccBranch(name: string | null | undefined): boolean;
|
|
3
|
-
export interface GitRunner {
|
|
4
|
-
fetch(repoPath: string): Promise<void>;
|
|
5
|
-
checkout(repoPath: string, branch: string): Promise<void>;
|
|
6
|
-
push(repoPath: string, branch: string): Promise<void>;
|
|
7
|
-
/** True when the working tree has no uncommitted changes. */
|
|
8
|
-
isClean(repoPath: string): Promise<boolean>;
|
|
9
|
-
/**
|
|
10
|
-
* v0.53 T-53-4: the EARLIEST commit on `branch` that is not reachable
|
|
11
|
-
* from `baseRef` — i.e. the first commit the task produced on its branch
|
|
12
|
-
* — as `{ sha, ts }` where `ts` is the committer date (ISO-8601), or
|
|
13
|
-
* null when the branch has no commits ahead of the base. Powers the
|
|
14
|
-
* `task.first_commit` SLO signal (when coding actually started).
|
|
15
|
-
*
|
|
16
|
-
* Optional on the interface so existing GitRunner test stubs that omit
|
|
17
|
-
* it keep compiling; the default implementation below provides it and
|
|
18
|
-
* the task-runner guards the call with `?.`.
|
|
19
|
-
*/
|
|
20
|
-
firstCommit?(repoPath: string, baseRef: string, branch: string): Promise<{
|
|
21
|
-
sha: string;
|
|
22
|
-
ts: string;
|
|
23
|
-
} | null>;
|
|
24
|
-
}
|
|
25
|
-
export type PushErrorKind = "transient" | "terminal";
|
|
26
|
-
/**
|
|
27
|
-
* Classify a `git push` failure. Terminal = the operator has to fix
|
|
28
|
-
* something (credentials, permissions, branch protection). Transient =
|
|
29
|
-
* worth retrying (network drop, GitHub 5xx, TLS hiccup, RPC hangup).
|
|
30
|
-
*
|
|
31
|
-
* Heuristics walk stderr because git surfaces all of these as
|
|
32
|
-
* non-zero exits with explanatory text. We do not parse git's exit
|
|
33
|
-
* code — it's `1` for everything.
|
|
34
|
-
*/
|
|
35
|
-
export declare function classifyPushError(err: unknown): PushErrorKind;
|
|
36
|
-
export interface PushRetryOptions {
|
|
37
|
-
attempts?: number;
|
|
38
|
-
/** Milliseconds between attempt N and N+1. Defaults to 1s/2s/4s. */
|
|
39
|
-
backoffMs?: readonly number[];
|
|
40
|
-
/** Test seam — overrides setTimeout. */
|
|
41
|
-
sleep?: (ms: number) => Promise<void>;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Run `pushFn` with up to N attempts and exponential backoff between
|
|
45
|
-
* attempts. Terminal errors short-circuit immediately so callers don't
|
|
46
|
-
* wait through three rejected pushes when the GitHub token expired.
|
|
47
|
-
*/
|
|
48
|
-
export declare function pushWithRetry(pushFn: () => Promise<void>, options?: PushRetryOptions): Promise<void>;
|
|
49
|
-
export declare const git: GitRunner;
|
|
50
|
-
//# sourceMappingURL=git.d.ts.map
|
package/dist/git.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,kBAAkB,QAAsC,CAAC;AAEtE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEpE;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,6DAA6D;IAC7D,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C;;;;;;;;;;OAUG;IACH,WAAW,CAAC,CACV,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CAChD;AAMD,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,UAAU,CAAC;AAErD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,CA0B7D;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,wCAAwC;IACxC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAQD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC3B,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,eAAO,MAAM,GAAG,EAAE,SAkCjB,CAAC"}
|
package/dist/git.js
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thin git wrappers using execa. The CLI never edits the user's git
|
|
3
|
-
* config — it relies on whatever credentials they already have set up.
|
|
4
|
-
*
|
|
5
|
-
* Push uses an exponential-backoff retry (v0.5.0+): three attempts with
|
|
6
|
-
* 1s/2s/4s sleeps in between. Transient failures (network, 5xx from
|
|
7
|
-
* GitHub, hangups) retry; terminal failures (auth, permission) fail
|
|
8
|
-
* fast so an operator can fix credentials without waiting 7s.
|
|
9
|
-
*/
|
|
10
|
-
import { execa } from "execa";
|
|
11
|
-
import { buildEnv } from "./bin-resolve.js";
|
|
12
|
-
// Matches branches the runner should treat as ACC-owned, including the
|
|
13
|
-
// `chore/acc-…` and `feat/acc-…` conventional-commit forms that the CLI
|
|
14
|
-
// agent opens in some flows. The original `acc/…` form is preserved.
|
|
15
|
-
export const ACC_BRANCH_PATTERN = /^(?:acc\/|chore\/acc-|feat\/acc-)/;
|
|
16
|
-
export function isAccBranch(name) {
|
|
17
|
-
return typeof name === "string" && ACC_BRANCH_PATTERN.test(name);
|
|
18
|
-
}
|
|
19
|
-
async function run(repoPath, args) {
|
|
20
|
-
return execa("git", args, { cwd: repoPath, env: buildEnv() });
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Classify a `git push` failure. Terminal = the operator has to fix
|
|
24
|
-
* something (credentials, permissions, branch protection). Transient =
|
|
25
|
-
* worth retrying (network drop, GitHub 5xx, TLS hiccup, RPC hangup).
|
|
26
|
-
*
|
|
27
|
-
* Heuristics walk stderr because git surfaces all of these as
|
|
28
|
-
* non-zero exits with explanatory text. We do not parse git's exit
|
|
29
|
-
* code — it's `1` for everything.
|
|
30
|
-
*/
|
|
31
|
-
export function classifyPushError(err) {
|
|
32
|
-
const e = err;
|
|
33
|
-
const stderr = typeof e?.stderr === "string" ? e.stderr : "";
|
|
34
|
-
const message = typeof e?.message === "string" ? e.message : "";
|
|
35
|
-
const haystack = `${stderr}\n${message}`.toLowerCase();
|
|
36
|
-
// Terminal — auth / permission / branch protection. No amount of
|
|
37
|
-
// retrying fixes any of these.
|
|
38
|
-
const terminalPatterns = [
|
|
39
|
-
"authentication failed",
|
|
40
|
-
"permission denied",
|
|
41
|
-
"remote: permission",
|
|
42
|
-
"could not read username",
|
|
43
|
-
"could not read password",
|
|
44
|
-
"403 forbidden",
|
|
45
|
-
"401 unauthorized",
|
|
46
|
-
"protected branch",
|
|
47
|
-
"gh auth login",
|
|
48
|
-
"support for password authentication was removed",
|
|
49
|
-
];
|
|
50
|
-
if (terminalPatterns.some((p) => haystack.includes(p)))
|
|
51
|
-
return "terminal";
|
|
52
|
-
// Everything else (network errors, 5xx, RPC failures, generic hangups)
|
|
53
|
-
// is treated as transient so the retry loop gives the network a chance
|
|
54
|
-
// to recover.
|
|
55
|
-
return "transient";
|
|
56
|
-
}
|
|
57
|
-
const DEFAULT_BACKOFF_MS = [1_000, 2_000, 4_000];
|
|
58
|
-
function defaultSleep(ms) {
|
|
59
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Run `pushFn` with up to N attempts and exponential backoff between
|
|
63
|
-
* attempts. Terminal errors short-circuit immediately so callers don't
|
|
64
|
-
* wait through three rejected pushes when the GitHub token expired.
|
|
65
|
-
*/
|
|
66
|
-
export async function pushWithRetry(pushFn, options = {}) {
|
|
67
|
-
const attempts = options.attempts ?? 3;
|
|
68
|
-
const backoff = options.backoffMs ?? DEFAULT_BACKOFF_MS;
|
|
69
|
-
const sleep = options.sleep ?? defaultSleep;
|
|
70
|
-
let lastError = null;
|
|
71
|
-
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
72
|
-
try {
|
|
73
|
-
await pushFn();
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
catch (err) {
|
|
77
|
-
lastError = err;
|
|
78
|
-
const kind = classifyPushError(err);
|
|
79
|
-
if (kind === "terminal")
|
|
80
|
-
throw err;
|
|
81
|
-
if (attempt === attempts)
|
|
82
|
-
break;
|
|
83
|
-
const wait = backoff[attempt - 1] ?? backoff[backoff.length - 1] ?? 0;
|
|
84
|
-
if (wait > 0)
|
|
85
|
-
await sleep(wait);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
throw lastError;
|
|
89
|
-
}
|
|
90
|
-
export const git = {
|
|
91
|
-
async fetch(repoPath) {
|
|
92
|
-
await run(repoPath, ["fetch", "--prune", "--all"]);
|
|
93
|
-
},
|
|
94
|
-
async checkout(repoPath, branch) {
|
|
95
|
-
// First try `checkout -B`, which also creates the branch if missing.
|
|
96
|
-
await run(repoPath, ["checkout", "-B", branch]);
|
|
97
|
-
},
|
|
98
|
-
async push(repoPath, branch) {
|
|
99
|
-
await pushWithRetry(async () => {
|
|
100
|
-
await run(repoPath, ["push", "-u", "origin", branch]);
|
|
101
|
-
});
|
|
102
|
-
},
|
|
103
|
-
async isClean(repoPath) {
|
|
104
|
-
const { stdout } = await run(repoPath, ["status", "--porcelain"]);
|
|
105
|
-
return stdout.trim().length === 0;
|
|
106
|
-
},
|
|
107
|
-
async firstCommit(repoPath, baseRef, branch) {
|
|
108
|
-
// `--reverse` lists oldest→newest so the first line is the earliest
|
|
109
|
-
// commit on `branch` not reachable from `baseRef`. %H = full sha,
|
|
110
|
-
// %cI = committer date in strict ISO-8601. A tab separator survives
|
|
111
|
-
// both fields cleanly (commit dates never contain tabs).
|
|
112
|
-
const { stdout } = await run(repoPath, [
|
|
113
|
-
"log",
|
|
114
|
-
"--reverse",
|
|
115
|
-
"--format=%H%x09%cI",
|
|
116
|
-
`${baseRef}..${branch}`,
|
|
117
|
-
]);
|
|
118
|
-
const firstLine = stdout.split(/\r?\n/).find((l) => l.trim().length > 0);
|
|
119
|
-
if (!firstLine)
|
|
120
|
-
return null;
|
|
121
|
-
const [sha, ts] = firstLine.split("\t");
|
|
122
|
-
if (!sha)
|
|
123
|
-
return null;
|
|
124
|
-
return { sha: sha.trim(), ts: (ts ?? "").trim() };
|
|
125
|
-
},
|
|
126
|
-
};
|
|
127
|
-
//# sourceMappingURL=git.js.map
|
package/dist/git.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
|
package/dist/github-client.d.ts
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* v0.53 T-53-4 — runner-side, budget-aware GitHub REST client.
|
|
3
|
-
*
|
|
4
|
-
* A port of the api/ side's `api/_lib/github-client.ts` (T-52-4) into the
|
|
5
|
-
* runner package. The runner CANNOT import api/ code (separate build, no
|
|
6
|
-
* shared module graph), so the pattern is reproduced here. The three
|
|
7
|
-
* behaviours match the server client 1:1:
|
|
8
|
-
*
|
|
9
|
-
* 1. Quota tracking — x-ratelimit-remaining / x-ratelimit-reset per
|
|
10
|
-
* resource (core, search, graphql, …) from every response, surfaced
|
|
11
|
-
* via getQuotaSnapshot() for `acc-runner doctor`.
|
|
12
|
-
*
|
|
13
|
-
* 2. Secondary-limit backoff — a 429, or a 403 carrying retry-after /
|
|
14
|
-
* x-ratelimit-remaining: 0, is a rate-limit response, not an answer.
|
|
15
|
-
* The client sleeps once (retry-after if given, else an exponential
|
|
16
|
-
* base, both jittered, capped at MAX_BACKOFF_MS) and retries once. A
|
|
17
|
-
* second rate-limit response — or a retry-after beyond the cap —
|
|
18
|
-
* surfaces as a typed RateLimitedError.
|
|
19
|
-
*
|
|
20
|
-
* 3. Per-task-execution soft budget — runTask arms a budget at the top
|
|
21
|
-
* of a task (startTaskGithubBudget) and disarms it in its finally
|
|
22
|
-
* (endTaskGithubBudget). Once the budget is spent, every further
|
|
23
|
-
* githubFetch throws GithubBudgetExceededError WITHOUT hitting the
|
|
24
|
-
* network. The caller treats this as a CLEAN, RETRYABLE infra failure
|
|
25
|
-
* — NOT a code failure: it never reaches classifyClaudeExit, so the
|
|
26
|
-
* runner is never quarantined for exhausting its GitHub budget.
|
|
27
|
-
*
|
|
28
|
-
* ── Coverage note (READ THIS) ──────────────────────────────────────────
|
|
29
|
-
* As of v0.53 the runner makes ALL of its GitHub calls through the `gh`
|
|
30
|
-
* CLI (see gh.ts, runtime/conflict-resolver.ts, runtime/rework.ts,
|
|
31
|
-
* runtime/reviewer.ts). Those `gh`/`gh api` invocations are SEPARATE
|
|
32
|
-
* processes with their own rate-limit handling and are out of scope for
|
|
33
|
-
* this client — they remain UNCOVERED by the budget/backoff here. This
|
|
34
|
-
* module is the sanctioned wrapper for any future *direct* REST call the
|
|
35
|
-
* runner adds (`fetch` against api.github.com); routing such calls through
|
|
36
|
-
* githubFetch is what keeps them budget- and rate-limit-aware.
|
|
37
|
-
*
|
|
38
|
-
* Reference: api/_lib/github-client.ts, planning/ACC_WORKFLOW_GAP_ANALYSIS.md §G13.
|
|
39
|
-
*/
|
|
40
|
-
/** Soft per-task-execution call budget. */
|
|
41
|
-
export declare const DEFAULT_TASK_GITHUB_BUDGET = 50;
|
|
42
|
-
/**
|
|
43
|
-
* Longest single backoff sleep. A secondary-limit retry-after can be 60s+;
|
|
44
|
-
* sleeping that long inside a task run wastes wall-clock the operator is
|
|
45
|
-
* paying for, so anything above the cap skips the retry and throws
|
|
46
|
-
* RateLimitedError instead.
|
|
47
|
-
*/
|
|
48
|
-
export declare const MAX_BACKOFF_MS = 15000;
|
|
49
|
-
/** Base for the exponential backoff when GitHub sends no retry-after. */
|
|
50
|
-
export declare const BASE_BACKOFF_MS = 2000;
|
|
51
|
-
/**
|
|
52
|
-
* Typed rate-limit failure: GitHub said "back off" twice in a row (or
|
|
53
|
-
* asked for a longer wait than we can afford). A rate-limit storm is then
|
|
54
|
-
* diagnosable instead of looking like random github_http_403 noise. This
|
|
55
|
-
* is a RETRYABLE INFRA failure — see isRetryableGithubError.
|
|
56
|
-
*/
|
|
57
|
-
export declare class RateLimitedError extends Error {
|
|
58
|
-
readonly status: number;
|
|
59
|
-
readonly resource: string | null;
|
|
60
|
-
/** ISO timestamp the quota window resets at, when GitHub said. */
|
|
61
|
-
readonly reset_at: string | null;
|
|
62
|
-
readonly retry_after_s: number | null;
|
|
63
|
-
constructor(opts: {
|
|
64
|
-
status: number;
|
|
65
|
-
resource: string | null;
|
|
66
|
-
reset_at: string | null;
|
|
67
|
-
retry_after_s: number | null;
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Soft-budget exhaustion. NOT a code failure: the task simply did as much
|
|
72
|
-
* direct GitHub work as one task execution is allowed. The caller should
|
|
73
|
-
* surface it as a clean, RETRYABLE infra failure and NEVER feed it to the
|
|
74
|
-
* claude-exit classifier (which would quarantine the runner).
|
|
75
|
-
*/
|
|
76
|
-
export declare class GithubBudgetExceededError extends Error {
|
|
77
|
-
readonly used: number;
|
|
78
|
-
readonly budget: number;
|
|
79
|
-
constructor(used: number, budget: number);
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* v0.53 T-53-4: both client failure modes are retryable infra conditions,
|
|
83
|
-
* not task/code failures. The contract the runner relies on: an error for
|
|
84
|
-
* which this returns true must surface as `phase: "github"` / retryable and
|
|
85
|
-
* MUST NOT set `quarantine_cause` — i.e. it is classifier-neutral and never
|
|
86
|
-
* benches the runner.
|
|
87
|
-
*/
|
|
88
|
-
export declare function isRetryableGithubError(err: unknown): boolean;
|
|
89
|
-
interface ResourceQuota {
|
|
90
|
-
remaining: number | null;
|
|
91
|
-
/** ISO timestamp. */
|
|
92
|
-
reset_at: string | null;
|
|
93
|
-
}
|
|
94
|
-
export interface GithubQuotaSnapshot {
|
|
95
|
-
/** Lowest remaining across observed resources (the binding constraint). */
|
|
96
|
-
remaining: number | null;
|
|
97
|
-
/** Reset time of that lowest-remaining resource. */
|
|
98
|
-
reset_at: string | null;
|
|
99
|
-
/** Direct REST calls made since the last startTaskGithubBudget(). */
|
|
100
|
-
used_this_task: number;
|
|
101
|
-
/** Per-resource view (core, search, …) as reported by GitHub headers. */
|
|
102
|
-
resources: Record<string, ResourceQuota>;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Begin a budgeted task execution: resets the per-task counter and arms the
|
|
106
|
-
* soft budget. runTask calls this at the top of a task; the explicit reset
|
|
107
|
-
* also re-baselines a long-lived watch process between tasks.
|
|
108
|
-
*/
|
|
109
|
-
export declare function startTaskGithubBudget(budget?: number): void;
|
|
110
|
-
/**
|
|
111
|
-
* End a budgeted task execution: disarms the soft budget so any direct REST
|
|
112
|
-
* call made OUTSIDE a task run (e.g. doctor) is unbudgeted. Idempotent.
|
|
113
|
-
*/
|
|
114
|
-
export declare function endTaskGithubBudget(): void;
|
|
115
|
-
export declare function getQuotaSnapshot(): GithubQuotaSnapshot;
|
|
116
|
-
/** Test seam: wipe quota/budget state between unit tests. */
|
|
117
|
-
export declare function resetGithubClientStateForTests(): void;
|
|
118
|
-
/** Injection seams for unit tests; production callers never pass this. */
|
|
119
|
-
export interface GithubFetchDeps {
|
|
120
|
-
fetchImpl?: typeof fetch;
|
|
121
|
-
sleep?: (ms: number) => Promise<void>;
|
|
122
|
-
/** Returns [0, 1); defaults to Math.random. Drives backoff jitter. */
|
|
123
|
-
random?: () => number;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Authenticated GitHub REST fetch. The caller supplies whatever token is
|
|
127
|
-
* appropriate (the runner uses the operator's own gh/git credentials for
|
|
128
|
-
* CLI calls; a direct REST consumer would pass a token it already holds).
|
|
129
|
-
* An empty token sends an anonymous request rather than `Bearer <empty>`.
|
|
130
|
-
*/
|
|
131
|
-
export declare function githubFetch(url: string, token: string, init?: RequestInit, deps?: GithubFetchDeps): Promise<Response>;
|
|
132
|
-
export {};
|
|
133
|
-
//# sourceMappingURL=github-client.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"github-client.d.ts","sourceRoot":"","sources":["../src/github-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,2CAA2C;AAC3C,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,cAAc,QAAS,CAAC;AAErC,yEAAyE;AACzE,eAAO,MAAM,eAAe,OAAQ,CAAC;AAErC;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;gBAE1B,IAAI,EAAE;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;KAC9B;CAYF;AAED;;;;;GAKG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAMzC;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAE5D;AAED,UAAU,aAAa;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,qBAAqB;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,2EAA2E;IAC3E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC1C;AAOD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,GAAE,MAAmC,GAAG,IAAI,CAGvF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,gBAAgB,IAAI,mBAAmB,CAkBtD;AAED,6DAA6D;AAC7D,wBAAgB,8BAA8B,IAAI,IAAI,CAIrD;AA6CD,0EAA0E;AAC1E,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAMD;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,WAAgB,EACtB,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,QAAQ,CAAC,CAwCnB"}
|
package/dist/github-client.js
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* v0.53 T-53-4 — runner-side, budget-aware GitHub REST client.
|
|
3
|
-
*
|
|
4
|
-
* A port of the api/ side's `api/_lib/github-client.ts` (T-52-4) into the
|
|
5
|
-
* runner package. The runner CANNOT import api/ code (separate build, no
|
|
6
|
-
* shared module graph), so the pattern is reproduced here. The three
|
|
7
|
-
* behaviours match the server client 1:1:
|
|
8
|
-
*
|
|
9
|
-
* 1. Quota tracking — x-ratelimit-remaining / x-ratelimit-reset per
|
|
10
|
-
* resource (core, search, graphql, …) from every response, surfaced
|
|
11
|
-
* via getQuotaSnapshot() for `acc-runner doctor`.
|
|
12
|
-
*
|
|
13
|
-
* 2. Secondary-limit backoff — a 429, or a 403 carrying retry-after /
|
|
14
|
-
* x-ratelimit-remaining: 0, is a rate-limit response, not an answer.
|
|
15
|
-
* The client sleeps once (retry-after if given, else an exponential
|
|
16
|
-
* base, both jittered, capped at MAX_BACKOFF_MS) and retries once. A
|
|
17
|
-
* second rate-limit response — or a retry-after beyond the cap —
|
|
18
|
-
* surfaces as a typed RateLimitedError.
|
|
19
|
-
*
|
|
20
|
-
* 3. Per-task-execution soft budget — runTask arms a budget at the top
|
|
21
|
-
* of a task (startTaskGithubBudget) and disarms it in its finally
|
|
22
|
-
* (endTaskGithubBudget). Once the budget is spent, every further
|
|
23
|
-
* githubFetch throws GithubBudgetExceededError WITHOUT hitting the
|
|
24
|
-
* network. The caller treats this as a CLEAN, RETRYABLE infra failure
|
|
25
|
-
* — NOT a code failure: it never reaches classifyClaudeExit, so the
|
|
26
|
-
* runner is never quarantined for exhausting its GitHub budget.
|
|
27
|
-
*
|
|
28
|
-
* ── Coverage note (READ THIS) ──────────────────────────────────────────
|
|
29
|
-
* As of v0.53 the runner makes ALL of its GitHub calls through the `gh`
|
|
30
|
-
* CLI (see gh.ts, runtime/conflict-resolver.ts, runtime/rework.ts,
|
|
31
|
-
* runtime/reviewer.ts). Those `gh`/`gh api` invocations are SEPARATE
|
|
32
|
-
* processes with their own rate-limit handling and are out of scope for
|
|
33
|
-
* this client — they remain UNCOVERED by the budget/backoff here. This
|
|
34
|
-
* module is the sanctioned wrapper for any future *direct* REST call the
|
|
35
|
-
* runner adds (`fetch` against api.github.com); routing such calls through
|
|
36
|
-
* githubFetch is what keeps them budget- and rate-limit-aware.
|
|
37
|
-
*
|
|
38
|
-
* Reference: api/_lib/github-client.ts, planning/ACC_WORKFLOW_GAP_ANALYSIS.md §G13.
|
|
39
|
-
*/
|
|
40
|
-
/** Soft per-task-execution call budget. */
|
|
41
|
-
export const DEFAULT_TASK_GITHUB_BUDGET = 50;
|
|
42
|
-
/**
|
|
43
|
-
* Longest single backoff sleep. A secondary-limit retry-after can be 60s+;
|
|
44
|
-
* sleeping that long inside a task run wastes wall-clock the operator is
|
|
45
|
-
* paying for, so anything above the cap skips the retry and throws
|
|
46
|
-
* RateLimitedError instead.
|
|
47
|
-
*/
|
|
48
|
-
export const MAX_BACKOFF_MS = 15_000;
|
|
49
|
-
/** Base for the exponential backoff when GitHub sends no retry-after. */
|
|
50
|
-
export const BASE_BACKOFF_MS = 2_000;
|
|
51
|
-
/**
|
|
52
|
-
* Typed rate-limit failure: GitHub said "back off" twice in a row (or
|
|
53
|
-
* asked for a longer wait than we can afford). A rate-limit storm is then
|
|
54
|
-
* diagnosable instead of looking like random github_http_403 noise. This
|
|
55
|
-
* is a RETRYABLE INFRA failure — see isRetryableGithubError.
|
|
56
|
-
*/
|
|
57
|
-
export class RateLimitedError extends Error {
|
|
58
|
-
status;
|
|
59
|
-
resource;
|
|
60
|
-
/** ISO timestamp the quota window resets at, when GitHub said. */
|
|
61
|
-
reset_at;
|
|
62
|
-
retry_after_s;
|
|
63
|
-
constructor(opts) {
|
|
64
|
-
super(`github rate limited (${opts.status})` +
|
|
65
|
-
(opts.resource ? ` on ${opts.resource}` : "") +
|
|
66
|
-
(opts.reset_at ? `, resets ${opts.reset_at}` : ""));
|
|
67
|
-
this.name = "RateLimitedError";
|
|
68
|
-
this.status = opts.status;
|
|
69
|
-
this.resource = opts.resource;
|
|
70
|
-
this.reset_at = opts.reset_at;
|
|
71
|
-
this.retry_after_s = opts.retry_after_s;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Soft-budget exhaustion. NOT a code failure: the task simply did as much
|
|
76
|
-
* direct GitHub work as one task execution is allowed. The caller should
|
|
77
|
-
* surface it as a clean, RETRYABLE infra failure and NEVER feed it to the
|
|
78
|
-
* claude-exit classifier (which would quarantine the runner).
|
|
79
|
-
*/
|
|
80
|
-
export class GithubBudgetExceededError extends Error {
|
|
81
|
-
used;
|
|
82
|
-
budget;
|
|
83
|
-
constructor(used, budget) {
|
|
84
|
-
super(`github task budget exhausted (${used}/${budget} calls)`);
|
|
85
|
-
this.name = "GithubBudgetExceededError";
|
|
86
|
-
this.used = used;
|
|
87
|
-
this.budget = budget;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* v0.53 T-53-4: both client failure modes are retryable infra conditions,
|
|
92
|
-
* not task/code failures. The contract the runner relies on: an error for
|
|
93
|
-
* which this returns true must surface as `phase: "github"` / retryable and
|
|
94
|
-
* MUST NOT set `quarantine_cause` — i.e. it is classifier-neutral and never
|
|
95
|
-
* benches the runner.
|
|
96
|
-
*/
|
|
97
|
-
export function isRetryableGithubError(err) {
|
|
98
|
-
return err instanceof RateLimitedError || err instanceof GithubBudgetExceededError;
|
|
99
|
-
}
|
|
100
|
-
// ── Module state (per process) ───────────────────────────────────────────────
|
|
101
|
-
const quotaByResource = new Map();
|
|
102
|
-
let usedThisTask = 0;
|
|
103
|
-
let taskBudget = null;
|
|
104
|
-
/**
|
|
105
|
-
* Begin a budgeted task execution: resets the per-task counter and arms the
|
|
106
|
-
* soft budget. runTask calls this at the top of a task; the explicit reset
|
|
107
|
-
* also re-baselines a long-lived watch process between tasks.
|
|
108
|
-
*/
|
|
109
|
-
export function startTaskGithubBudget(budget = DEFAULT_TASK_GITHUB_BUDGET) {
|
|
110
|
-
usedThisTask = 0;
|
|
111
|
-
taskBudget = budget;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* End a budgeted task execution: disarms the soft budget so any direct REST
|
|
115
|
-
* call made OUTSIDE a task run (e.g. doctor) is unbudgeted. Idempotent.
|
|
116
|
-
*/
|
|
117
|
-
export function endTaskGithubBudget() {
|
|
118
|
-
taskBudget = null;
|
|
119
|
-
}
|
|
120
|
-
export function getQuotaSnapshot() {
|
|
121
|
-
let min = null;
|
|
122
|
-
const resources = {};
|
|
123
|
-
for (const [name, q] of quotaByResource) {
|
|
124
|
-
resources[name] = { ...q };
|
|
125
|
-
if (q.remaining !== null &&
|
|
126
|
-
(min === null || min.remaining === null || q.remaining < min.remaining)) {
|
|
127
|
-
min = q;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return {
|
|
131
|
-
remaining: min?.remaining ?? null,
|
|
132
|
-
reset_at: min?.reset_at ?? null,
|
|
133
|
-
used_this_task: usedThisTask,
|
|
134
|
-
resources,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
/** Test seam: wipe quota/budget state between unit tests. */
|
|
138
|
-
export function resetGithubClientStateForTests() {
|
|
139
|
-
quotaByResource.clear();
|
|
140
|
-
usedThisTask = 0;
|
|
141
|
-
taskBudget = null;
|
|
142
|
-
}
|
|
143
|
-
function recordRateLimitHeaders(res) {
|
|
144
|
-
const remainingRaw = res.headers.get("x-ratelimit-remaining");
|
|
145
|
-
const resetRaw = res.headers.get("x-ratelimit-reset");
|
|
146
|
-
if (remainingRaw === null && resetRaw === null)
|
|
147
|
-
return;
|
|
148
|
-
const resource = res.headers.get("x-ratelimit-resource") ?? "core";
|
|
149
|
-
const remaining = remainingRaw !== null && remainingRaw !== "" ? Number(remainingRaw) : NaN;
|
|
150
|
-
const resetEpochS = resetRaw !== null && resetRaw !== "" ? Number(resetRaw) : NaN;
|
|
151
|
-
quotaByResource.set(resource, {
|
|
152
|
-
remaining: Number.isFinite(remaining) ? remaining : null,
|
|
153
|
-
reset_at: Number.isFinite(resetEpochS)
|
|
154
|
-
? new Date(resetEpochS * 1000).toISOString()
|
|
155
|
-
: null,
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* A 429 is always "back off". A 403 is only a rate limit when it carries
|
|
160
|
-
* retry-after (secondary limit) or x-ratelimit-remaining: 0 (primary limit
|
|
161
|
-
* exhausted) — a plain 403 is a permissions error and passes through.
|
|
162
|
-
*/
|
|
163
|
-
function isRateLimitResponse(res) {
|
|
164
|
-
if (res.status === 429)
|
|
165
|
-
return true;
|
|
166
|
-
if (res.status !== 403)
|
|
167
|
-
return false;
|
|
168
|
-
if (res.headers.get("retry-after") !== null)
|
|
169
|
-
return true;
|
|
170
|
-
return res.headers.get("x-ratelimit-remaining") === "0";
|
|
171
|
-
}
|
|
172
|
-
function toRateLimitedError(res) {
|
|
173
|
-
const retryAfterRaw = res.headers.get("retry-after");
|
|
174
|
-
const retryAfter = retryAfterRaw !== null ? Number(retryAfterRaw) : NaN;
|
|
175
|
-
const resetRaw = res.headers.get("x-ratelimit-reset");
|
|
176
|
-
const resetEpochS = resetRaw !== null ? Number(resetRaw) : NaN;
|
|
177
|
-
return new RateLimitedError({
|
|
178
|
-
status: res.status,
|
|
179
|
-
resource: res.headers.get("x-ratelimit-resource"),
|
|
180
|
-
reset_at: Number.isFinite(resetEpochS)
|
|
181
|
-
? new Date(resetEpochS * 1000).toISOString()
|
|
182
|
-
: null,
|
|
183
|
-
retry_after_s: Number.isFinite(retryAfter) ? retryAfter : null,
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
function defaultSleep(ms) {
|
|
187
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Authenticated GitHub REST fetch. The caller supplies whatever token is
|
|
191
|
-
* appropriate (the runner uses the operator's own gh/git credentials for
|
|
192
|
-
* CLI calls; a direct REST consumer would pass a token it already holds).
|
|
193
|
-
* An empty token sends an anonymous request rather than `Bearer <empty>`.
|
|
194
|
-
*/
|
|
195
|
-
export async function githubFetch(url, token, init = {}, deps = {}) {
|
|
196
|
-
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
197
|
-
const sleep = deps.sleep ?? defaultSleep;
|
|
198
|
-
const random = deps.random ?? Math.random;
|
|
199
|
-
const headers = new Headers(init.headers);
|
|
200
|
-
if (token)
|
|
201
|
-
headers.set("Authorization", `Bearer ${token}`);
|
|
202
|
-
if (!headers.has("Accept")) {
|
|
203
|
-
headers.set("Accept", "application/vnd.github+json");
|
|
204
|
-
}
|
|
205
|
-
headers.set("X-GitHub-Api-Version", "2022-11-28");
|
|
206
|
-
headers.set("User-Agent", "acc-runner");
|
|
207
|
-
const doFetch = async () => {
|
|
208
|
-
if (taskBudget !== null && usedThisTask >= taskBudget) {
|
|
209
|
-
throw new GithubBudgetExceededError(usedThisTask, taskBudget);
|
|
210
|
-
}
|
|
211
|
-
usedThisTask++;
|
|
212
|
-
const res = await fetchImpl(url, { ...init, headers });
|
|
213
|
-
recordRateLimitHeaders(res);
|
|
214
|
-
return res;
|
|
215
|
-
};
|
|
216
|
-
const first = await doFetch();
|
|
217
|
-
if (!isRateLimitResponse(first))
|
|
218
|
-
return first;
|
|
219
|
-
// Rate limited: sleep jittered-exponential once, retry once.
|
|
220
|
-
const retryAfterRaw = first.headers.get("retry-after");
|
|
221
|
-
const retryAfterS = retryAfterRaw !== null ? Number(retryAfterRaw) : NaN;
|
|
222
|
-
const baseMs = Number.isFinite(retryAfterS) ? retryAfterS * 1000 : BASE_BACKOFF_MS;
|
|
223
|
-
if (baseMs > MAX_BACKOFF_MS) {
|
|
224
|
-
// GitHub asked for a longer pause than we want to burn mid-task —
|
|
225
|
-
// surface the typed error now instead of sleeping into the run.
|
|
226
|
-
throw toRateLimitedError(first);
|
|
227
|
-
}
|
|
228
|
-
await sleep(Math.round(baseMs * (1 + random() * 0.5)));
|
|
229
|
-
const second = await doFetch();
|
|
230
|
-
if (!isRateLimitResponse(second))
|
|
231
|
-
return second;
|
|
232
|
-
throw toRateLimitedError(second);
|
|
233
|
-
}
|
|
234
|
-
//# sourceMappingURL=github-client.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"github-client.js","sourceRoot":"","sources":["../src/github-client.ts"],"names":[],"mappings":"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"}
|
package/dist/keychain.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OS-keychain wrapper around `keytar`. The CLI never persists a JWT to
|
|
3
|
-
* disk in plaintext — keychain is the only writable surface.
|
|
4
|
-
*
|
|
5
|
-
* keytar is a native module; we lazy-import so commands that don't need
|
|
6
|
-
* credentials (`--version`, `--help`) still work on systems where the
|
|
7
|
-
* binding has not built (`linux` headless CI without libsecret, etc).
|
|
8
|
-
*/
|
|
9
|
-
import { type StoredSession } from "./types.js";
|
|
10
|
-
type KeytarLike = {
|
|
11
|
-
setPassword(service: string, account: string, password: string): Promise<void>;
|
|
12
|
-
getPassword(service: string, account: string): Promise<string | null>;
|
|
13
|
-
deletePassword(service: string, account: string): Promise<boolean>;
|
|
14
|
-
};
|
|
15
|
-
export declare function saveSession(session: StoredSession): Promise<void>;
|
|
16
|
-
export declare function loadSession(): Promise<StoredSession | null>;
|
|
17
|
-
export declare function clearSession(): Promise<boolean>;
|
|
18
|
-
/** Test-only seam used by the keychain test (overrides the lazy import). */
|
|
19
|
-
export declare function __setKeytar(impl: KeytarLike | null): void;
|
|
20
|
-
export {};
|
|
21
|
-
//# sourceMappingURL=keychain.d.ts.map
|
package/dist/keychain.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"keychain.d.ts","sourceRoot":"","sources":["../src/keychain.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAIzE,KAAK,UAAU,GAAG;IAChB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtE,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE,CAAC;AAYF,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvE;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAUjE;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAGrD;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAEzD"}
|
package/dist/keychain.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OS-keychain wrapper around `keytar`. The CLI never persists a JWT to
|
|
3
|
-
* disk in plaintext — keychain is the only writable surface.
|
|
4
|
-
*
|
|
5
|
-
* keytar is a native module; we lazy-import so commands that don't need
|
|
6
|
-
* credentials (`--version`, `--help`) still work on systems where the
|
|
7
|
-
* binding has not built (`linux` headless CI without libsecret, etc).
|
|
8
|
-
*/
|
|
9
|
-
import { RUNNER_KEYCHAIN_SERVICE } from "./types.js";
|
|
10
|
-
const ACCOUNT = "default";
|
|
11
|
-
let cached = null;
|
|
12
|
-
async function getKeytar() {
|
|
13
|
-
if (cached)
|
|
14
|
-
return cached;
|
|
15
|
-
// Dynamic import keeps native-binding failures out of the cold path.
|
|
16
|
-
const mod = (await import("keytar"));
|
|
17
|
-
cached = (mod.default ?? mod);
|
|
18
|
-
return cached;
|
|
19
|
-
}
|
|
20
|
-
export async function saveSession(session) {
|
|
21
|
-
const k = await getKeytar();
|
|
22
|
-
await k.setPassword(RUNNER_KEYCHAIN_SERVICE, ACCOUNT, JSON.stringify(session));
|
|
23
|
-
}
|
|
24
|
-
export async function loadSession() {
|
|
25
|
-
const k = await getKeytar();
|
|
26
|
-
const raw = await k.getPassword(RUNNER_KEYCHAIN_SERVICE, ACCOUNT);
|
|
27
|
-
if (!raw)
|
|
28
|
-
return null;
|
|
29
|
-
try {
|
|
30
|
-
return JSON.parse(raw);
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
// Corrupted entry — treat as "not logged in" rather than crashing.
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
export async function clearSession() {
|
|
38
|
-
const k = await getKeytar();
|
|
39
|
-
return k.deletePassword(RUNNER_KEYCHAIN_SERVICE, ACCOUNT);
|
|
40
|
-
}
|
|
41
|
-
/** Test-only seam used by the keychain test (overrides the lazy import). */
|
|
42
|
-
export function __setKeytar(impl) {
|
|
43
|
-
cached = impl;
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=keychain.js.map
|
package/dist/keychain.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"keychain.js","sourceRoot":"","sources":["../src/keychain.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,uBAAuB,EAAsB,MAAM,YAAY,CAAC;AAEzE,MAAM,OAAO,GAAG,SAAkB,CAAC;AAQnC,IAAI,MAAM,GAAsB,IAAI,CAAC;AAErC,KAAK,UAAU,SAAS;IACtB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,qEAAqE;IACrE,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAqD,CAAC;IACzF,MAAM,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAe,CAAC;IAC5C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAsB;IACtD,MAAM,CAAC,GAAG,MAAM,SAAS,EAAE,CAAC;IAC5B,MAAM,CAAC,CAAC,WAAW,CAAC,uBAAuB,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,CAAC,GAAG,MAAM,SAAS,EAAE,CAAC;IAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,WAAW,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;IAClE,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,mEAAmE;QACnE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,CAAC,GAAG,MAAM,SAAS,EAAE,CAAC;IAC5B,OAAO,CAAC,CAAC,cAAc,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;AAC5D,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,WAAW,CAAC,IAAuB;IACjD,MAAM,GAAG,IAAI,CAAC;AAChB,CAAC"}
|