@tempoxyz/patron 0.0.23 → 0.0.24
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/bin.js +3 -3
- package/dist/chunks/{-JRJJV4LP.js → -CTLNBCDF.js} +12 -10
- package/dist/chunks/{chunk-75CD5P6X.js → chunk-NQ6RRPM6.js} +4 -2
- package/dist/chunks/chunk-O64T22EK.js +54 -0
- package/dist/chunks/{chunk-UWIBR62N.js → chunk-SGQ525FB.js} +7 -54
- package/dist/chunks/{chunk-5GS6AZ5L.js → chunk-SIIFXQ6S.js} +2 -0
- package/dist/chunks/{chunk-HEQBEBKL.js → chunk-TV5VLFTD.js} +4 -5
- package/dist/chunks/{hook-AHF4ELOX.js → hook-RJN6WCIT.js} +7 -5
- package/dist/chunks/hook-process-QIK6YAOS.js +243 -0
- package/dist/chunks/{wallet-R3UWBXVC.js → wallet-7M2LEO4J.js} +2 -1
- package/package.json +1 -1
- package/dist/chunks/hook-process-3OTLNDSS.js +0 -75
package/dist/bin.js
CHANGED
|
@@ -4,14 +4,14 @@ const require = __patronCreateRequire(import.meta.url)
|
|
|
4
4
|
|
|
5
5
|
// src/bin.ts
|
|
6
6
|
if (process.argv[2] === "hook") {
|
|
7
|
-
const { runHookProcess } = await import("./chunks/hook-process-
|
|
7
|
+
const { runHookProcess } = await import("./chunks/hook-process-QIK6YAOS.js");
|
|
8
8
|
await runHookProcess().catch(() => void 0);
|
|
9
9
|
process.exit(0);
|
|
10
10
|
} else if (process.argv[2] === "pay") {
|
|
11
|
-
const { runPayProcess } = await import("./chunks/hook-process-
|
|
11
|
+
const { runPayProcess } = await import("./chunks/hook-process-QIK6YAOS.js");
|
|
12
12
|
await runPayProcess().catch(() => void 0);
|
|
13
13
|
process.exit(0);
|
|
14
14
|
} else {
|
|
15
|
-
const { run } = await import("./chunks/-
|
|
15
|
+
const { run } = await import("./chunks/-CTLNBCDF.js");
|
|
16
16
|
process.exitCode = await run(process.argv.slice(2));
|
|
17
17
|
}
|
|
@@ -29,10 +29,10 @@ import {
|
|
|
29
29
|
withPatronStatus,
|
|
30
30
|
withoutPatronHandlers,
|
|
31
31
|
writeJsonObject
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-NQ6RRPM6.js";
|
|
33
33
|
import {
|
|
34
34
|
startRefill
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-TV5VLFTD.js";
|
|
36
36
|
import {
|
|
37
37
|
DEFAULT_MONTHLY_BUDGET_USD,
|
|
38
38
|
MAX_TOKENS_PER_PAGE,
|
|
@@ -53,12 +53,14 @@ import {
|
|
|
53
53
|
readJson,
|
|
54
54
|
readUsage,
|
|
55
55
|
statePaths,
|
|
56
|
-
tryLock,
|
|
57
56
|
updateUsage,
|
|
58
|
-
withLock,
|
|
59
57
|
writeConfig,
|
|
60
58
|
writePrivateFile
|
|
61
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-SGQ525FB.js";
|
|
60
|
+
import {
|
|
61
|
+
tryLock,
|
|
62
|
+
withLock
|
|
63
|
+
} from "./chunk-O64T22EK.js";
|
|
62
64
|
import "./chunk-GTMLTZRN.js";
|
|
63
65
|
|
|
64
66
|
// src/index.ts
|
|
@@ -690,10 +692,10 @@ async function linkRefillFailedAt(home) {
|
|
|
690
692
|
var REFILL_LOCK_STALE_MS = 5 * 60 * 1e3;
|
|
691
693
|
var defaultOpenWallet = async (settings, config, issuer, maxUnits) => {
|
|
692
694
|
if (config.wallet === "link") {
|
|
693
|
-
const { openLinkWallet } = await import("./wallet-
|
|
695
|
+
const { openLinkWallet } = await import("./wallet-7M2LEO4J.js");
|
|
694
696
|
return openLinkWallet(config, maxUnits);
|
|
695
697
|
}
|
|
696
|
-
const { openWallet } = await import("./wallet-
|
|
698
|
+
const { openWallet } = await import("./wallet-7M2LEO4J.js");
|
|
697
699
|
return openWallet(settings, config.wallet, issuer, maxUnits);
|
|
698
700
|
};
|
|
699
701
|
async function buyWithinBudget(settings, config, wanted, openWallet = defaultOpenWallet) {
|
|
@@ -1062,7 +1064,7 @@ async function tempoSignIn(deps, budgetUnits, issuer) {
|
|
|
1062
1064
|
deps,
|
|
1063
1065
|
deps.settings.privateKey ? "Using PATRON_PRIVATE_KEY" : "Signing in with Tempo Wallet"
|
|
1064
1066
|
);
|
|
1065
|
-
const { signIn } = await import("./wallet-
|
|
1067
|
+
const { signIn } = await import("./wallet-7M2LEO4J.js");
|
|
1066
1068
|
const account = await signIn(deps.settings, {
|
|
1067
1069
|
budgetUnits,
|
|
1068
1070
|
issuer,
|
|
@@ -1176,7 +1178,7 @@ async function changeBudget(deps, input) {
|
|
|
1176
1178
|
} else budget = await askBudget(deps, config.monthlyBudgetUsd);
|
|
1177
1179
|
if (config.wallet === "tempo" && budget > config.monthlyBudgetUsd) {
|
|
1178
1180
|
step(deps, "Approve the new spending limit in Tempo Wallet");
|
|
1179
|
-
const { authorizeBudget } = await import("./wallet-
|
|
1181
|
+
const { authorizeBudget } = await import("./wallet-7M2LEO4J.js");
|
|
1180
1182
|
const issuer = await loadIssuer(settings.home, settings.gatewayUrl, {
|
|
1181
1183
|
fetch: deps.fetch
|
|
1182
1184
|
});
|
|
@@ -1292,7 +1294,7 @@ async function setName(deps, name) {
|
|
|
1292
1294
|
const issuer = await loadIssuer(settings.home, settings.gatewayUrl, {
|
|
1293
1295
|
fetch: deps.fetch
|
|
1294
1296
|
});
|
|
1295
|
-
const open = deps.openWallet ?? (async (s, c, i, max) => (await import("./wallet-
|
|
1297
|
+
const open = deps.openWallet ?? (async (s, c, i, max) => (await import("./wallet-7M2LEO4J.js")).openWallet(s, c.wallet, i, max));
|
|
1296
1298
|
const wallet = await open(settings, config, issuer, 0n);
|
|
1297
1299
|
await setProfile(settings.gatewayUrl, wallet, name, deps.fetch);
|
|
1298
1300
|
await writeConfig(settings.home, { ...config, name });
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createRequire as __patronCreateRequire } from 'node:module'
|
|
2
|
+
const require = __patronCreateRequire(import.meta.url)
|
|
3
|
+
|
|
4
|
+
// src/lock.ts
|
|
5
|
+
import { open, rm, stat } from "node:fs/promises";
|
|
6
|
+
async function withLock(path, fn, options = {}) {
|
|
7
|
+
const deadline = Date.now() + (options.timeoutMs ?? 3e3);
|
|
8
|
+
const staleMs = options.staleMs ?? 1e4;
|
|
9
|
+
for (; ; ) {
|
|
10
|
+
try {
|
|
11
|
+
const handle = await open(path, "wx", 384);
|
|
12
|
+
await handle.close();
|
|
13
|
+
break;
|
|
14
|
+
} catch (error) {
|
|
15
|
+
if (error.code !== "EEXIST") throw error;
|
|
16
|
+
const age = await stat(path).then(
|
|
17
|
+
(stats) => Date.now() - stats.mtimeMs,
|
|
18
|
+
() => 0
|
|
19
|
+
);
|
|
20
|
+
if (age > staleMs) {
|
|
21
|
+
await rm(path, { force: true });
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (Date.now() > deadline) throw new Error(`Patron state is busy: ${path}`);
|
|
25
|
+
await new Promise((resolve) => setTimeout(resolve, 10 + Math.random() * 20));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
return await fn();
|
|
30
|
+
} finally {
|
|
31
|
+
await rm(path, { force: true });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async function tryLock(path, staleMs) {
|
|
35
|
+
try {
|
|
36
|
+
const handle = await open(path, "wx", 384);
|
|
37
|
+
await handle.close();
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (error.code !== "EEXIST") throw error;
|
|
40
|
+
const age = await stat(path).then(
|
|
41
|
+
(stats) => Date.now() - stats.mtimeMs,
|
|
42
|
+
() => 0
|
|
43
|
+
);
|
|
44
|
+
if (age <= staleMs) return void 0;
|
|
45
|
+
await rm(path, { force: true });
|
|
46
|
+
return tryLock(path, staleMs);
|
|
47
|
+
}
|
|
48
|
+
return () => rm(path, { force: true });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
withLock,
|
|
53
|
+
tryLock
|
|
54
|
+
};
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { createRequire as __patronCreateRequire } from 'node:module'
|
|
2
2
|
const require = __patronCreateRequire(import.meta.url)
|
|
3
|
+
import {
|
|
4
|
+
withLock
|
|
5
|
+
} from "./chunk-O64T22EK.js";
|
|
3
6
|
|
|
4
7
|
// src/state.ts
|
|
8
|
+
import { randomBytes } from "node:crypto";
|
|
5
9
|
import {
|
|
6
10
|
chmod,
|
|
7
11
|
lstat,
|
|
@@ -9,59 +13,10 @@ import {
|
|
|
9
13
|
readFile,
|
|
10
14
|
readlink,
|
|
11
15
|
rename,
|
|
12
|
-
rm
|
|
16
|
+
rm,
|
|
13
17
|
writeFile
|
|
14
18
|
} from "node:fs/promises";
|
|
15
19
|
import { dirname, join, resolve } from "node:path";
|
|
16
|
-
|
|
17
|
-
// src/lock.ts
|
|
18
|
-
import { open, rm, stat } from "node:fs/promises";
|
|
19
|
-
async function withLock(path, fn, options = {}) {
|
|
20
|
-
const deadline = Date.now() + (options.timeoutMs ?? 3e3);
|
|
21
|
-
const staleMs = options.staleMs ?? 1e4;
|
|
22
|
-
for (; ; ) {
|
|
23
|
-
try {
|
|
24
|
-
const handle = await open(path, "wx", 384);
|
|
25
|
-
await handle.close();
|
|
26
|
-
break;
|
|
27
|
-
} catch (error) {
|
|
28
|
-
if (error.code !== "EEXIST") throw error;
|
|
29
|
-
const age = await stat(path).then(
|
|
30
|
-
(stats) => Date.now() - stats.mtimeMs,
|
|
31
|
-
() => 0
|
|
32
|
-
);
|
|
33
|
-
if (age > staleMs) {
|
|
34
|
-
await rm(path, { force: true });
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
if (Date.now() > deadline) throw new Error(`Patron state is busy: ${path}`);
|
|
38
|
-
await new Promise((resolve2) => setTimeout(resolve2, 10 + Math.random() * 20));
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
try {
|
|
42
|
-
return await fn();
|
|
43
|
-
} finally {
|
|
44
|
-
await rm(path, { force: true });
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
async function tryLock(path, staleMs) {
|
|
48
|
-
try {
|
|
49
|
-
const handle = await open(path, "wx", 384);
|
|
50
|
-
await handle.close();
|
|
51
|
-
} catch (error) {
|
|
52
|
-
if (error.code !== "EEXIST") throw error;
|
|
53
|
-
const age = await stat(path).then(
|
|
54
|
-
(stats) => Date.now() - stats.mtimeMs,
|
|
55
|
-
() => 0
|
|
56
|
-
);
|
|
57
|
-
if (age <= staleMs) return void 0;
|
|
58
|
-
await rm(path, { force: true });
|
|
59
|
-
return tryLock(path, staleMs);
|
|
60
|
-
}
|
|
61
|
-
return () => rm(path, { force: true });
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// src/state.ts
|
|
65
20
|
var AGENT_IDS = ["claude-code", "codex", "cursor", "amp"];
|
|
66
21
|
function statePaths(home) {
|
|
67
22
|
return {
|
|
@@ -114,13 +69,13 @@ async function symlinkTarget(path, depth = 0) {
|
|
|
114
69
|
}
|
|
115
70
|
}
|
|
116
71
|
async function replaceFile(path, contents) {
|
|
117
|
-
const temporary = `${path}.${process.pid}.${
|
|
72
|
+
const temporary = `${path}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
|
|
118
73
|
try {
|
|
119
74
|
await writeFile(temporary, contents, { mode: 384 });
|
|
120
75
|
await chmod(temporary, 384);
|
|
121
76
|
await rename(temporary, path);
|
|
122
77
|
} catch (error) {
|
|
123
|
-
await
|
|
78
|
+
await rm(temporary, { force: true }).catch(() => void 0);
|
|
124
79
|
throw error;
|
|
125
80
|
}
|
|
126
81
|
}
|
|
@@ -195,8 +150,6 @@ async function updateUsage(home, update, now = /* @__PURE__ */ new Date()) {
|
|
|
195
150
|
}
|
|
196
151
|
|
|
197
152
|
export {
|
|
198
|
-
withLock,
|
|
199
|
-
tryLock,
|
|
200
153
|
AGENT_IDS,
|
|
201
154
|
statePaths,
|
|
202
155
|
ensureHome,
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
|
|
8
8
|
// src/hook-input.ts
|
|
9
9
|
var HOOK_TIMEOUT_MS = 2e3;
|
|
10
|
+
var PAY_TIMEOUT_MS = 2e4;
|
|
10
11
|
var MAX_DOMAINS_PER_HOOK = 10;
|
|
11
12
|
var MAX_DEPTH = 6;
|
|
12
13
|
var MAX_URLS = 50;
|
|
@@ -105,6 +106,7 @@ function isRecord(value) {
|
|
|
105
106
|
|
|
106
107
|
export {
|
|
107
108
|
HOOK_TIMEOUT_MS,
|
|
109
|
+
PAY_TIMEOUT_MS,
|
|
108
110
|
MAX_DOMAINS_PER_HOOK,
|
|
109
111
|
hookDomains,
|
|
110
112
|
payableDomain,
|
|
@@ -29,18 +29,17 @@ function refillCommand(script) {
|
|
|
29
29
|
];
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
function
|
|
32
|
+
function startDrain(script = process.argv[1]) {
|
|
33
33
|
return new Promise((resolve) => {
|
|
34
34
|
try {
|
|
35
35
|
if (!script) return resolve(false);
|
|
36
36
|
const child = spawn(process.execPath, [...process.execArgv, script, "pay"], {
|
|
37
37
|
detached: true,
|
|
38
38
|
env: process.env,
|
|
39
|
-
stdio:
|
|
39
|
+
stdio: "ignore"
|
|
40
40
|
});
|
|
41
41
|
child.on("error", () => resolve(false));
|
|
42
|
-
child.
|
|
43
|
-
child.stdin.end(payload, () => {
|
|
42
|
+
child.on("spawn", () => {
|
|
44
43
|
child.unref();
|
|
45
44
|
resolve(true);
|
|
46
45
|
});
|
|
@@ -52,5 +51,5 @@ function startPayment(payload, script = process.argv[1]) {
|
|
|
52
51
|
|
|
53
52
|
export {
|
|
54
53
|
startRefill,
|
|
55
|
-
|
|
54
|
+
startDrain
|
|
56
55
|
};
|
|
@@ -3,11 +3,12 @@ const require = __patronCreateRequire(import.meta.url)
|
|
|
3
3
|
import {
|
|
4
4
|
HOOK_TIMEOUT_MS,
|
|
5
5
|
MAX_DOMAINS_PER_HOOK,
|
|
6
|
+
PAY_TIMEOUT_MS,
|
|
6
7
|
hookDomains,
|
|
7
8
|
parseHookInput,
|
|
8
9
|
payableDomain,
|
|
9
10
|
turnEnd
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-SIIFXQ6S.js";
|
|
11
12
|
import {
|
|
12
13
|
FileTokenStore,
|
|
13
14
|
codexHome,
|
|
@@ -15,7 +16,7 @@ import {
|
|
|
15
16
|
needsRefill,
|
|
16
17
|
redeem,
|
|
17
18
|
refillSize
|
|
18
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-NQ6RRPM6.js";
|
|
19
20
|
import {
|
|
20
21
|
clampTokensPerPage,
|
|
21
22
|
settingsFor
|
|
@@ -24,9 +25,11 @@ import {
|
|
|
24
25
|
readConfig,
|
|
25
26
|
readUsage,
|
|
26
27
|
updateUsage,
|
|
27
|
-
withLock,
|
|
28
28
|
writePrivateFile
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-SGQ525FB.js";
|
|
30
|
+
import {
|
|
31
|
+
withLock
|
|
32
|
+
} from "./chunk-O64T22EK.js";
|
|
30
33
|
import "./chunk-GTMLTZRN.js";
|
|
31
34
|
|
|
32
35
|
// src/hook.ts
|
|
@@ -208,7 +211,6 @@ function isRecord(value) {
|
|
|
208
211
|
}
|
|
209
212
|
|
|
210
213
|
// src/hook.ts
|
|
211
|
-
var PAY_TIMEOUT_MS = 2e4;
|
|
212
214
|
var ABORT_MARGIN_MS = 500;
|
|
213
215
|
async function runHook(dependencies, timeoutMs = HOOK_TIMEOUT_MS) {
|
|
214
216
|
let timer;
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { createRequire as __patronCreateRequire } from 'node:module'
|
|
2
|
+
const require = __patronCreateRequire(import.meta.url)
|
|
3
|
+
import {
|
|
4
|
+
HOOK_TIMEOUT_MS,
|
|
5
|
+
PAY_TIMEOUT_MS,
|
|
6
|
+
hookDomains,
|
|
7
|
+
isCursorPayload,
|
|
8
|
+
parseHookInput,
|
|
9
|
+
turnEnd
|
|
10
|
+
} from "./chunk-SIIFXQ6S.js";
|
|
11
|
+
import {
|
|
12
|
+
startDrain,
|
|
13
|
+
startRefill
|
|
14
|
+
} from "./chunk-TV5VLFTD.js";
|
|
15
|
+
import {
|
|
16
|
+
resolveSettings
|
|
17
|
+
} from "./chunk-WZRGCKEK.js";
|
|
18
|
+
import {
|
|
19
|
+
tryLock
|
|
20
|
+
} from "./chunk-O64T22EK.js";
|
|
21
|
+
import "./chunk-GTMLTZRN.js";
|
|
22
|
+
|
|
23
|
+
// src/hook-process.ts
|
|
24
|
+
import { homedir } from "node:os";
|
|
25
|
+
import { join as join2 } from "node:path";
|
|
26
|
+
|
|
27
|
+
// src/pay-queue.ts
|
|
28
|
+
import { randomBytes } from "node:crypto";
|
|
29
|
+
import {
|
|
30
|
+
mkdir,
|
|
31
|
+
readdir,
|
|
32
|
+
readFile,
|
|
33
|
+
rename,
|
|
34
|
+
rm,
|
|
35
|
+
stat,
|
|
36
|
+
utimes,
|
|
37
|
+
writeFile
|
|
38
|
+
} from "node:fs/promises";
|
|
39
|
+
import { join } from "node:path";
|
|
40
|
+
function queuePaths(home) {
|
|
41
|
+
return {
|
|
42
|
+
dir: join(home, "pay-queue"),
|
|
43
|
+
lock: join(home, "pay.lock"),
|
|
44
|
+
start: join(home, "pay.start")
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
var MAX_QUEUED = 500;
|
|
48
|
+
var PAY_CONCURRENCY = 8;
|
|
49
|
+
var DRAIN_STALE_MS = 6e4;
|
|
50
|
+
var START_STALE_MS = 15e3;
|
|
51
|
+
async function enqueue(home, event) {
|
|
52
|
+
try {
|
|
53
|
+
const { dir } = queuePaths(home);
|
|
54
|
+
await mkdir(dir, { recursive: true, mode: 448 });
|
|
55
|
+
if ((await queued(dir)).length >= MAX_QUEUED) return void 0;
|
|
56
|
+
const name = `${String(Date.now()).padStart(15, "0")}-${randomBytes(6).toString("hex")}.json`;
|
|
57
|
+
const temporary = join(dir, `.${name}.tmp`);
|
|
58
|
+
await writeFile(temporary, JSON.stringify(event), { mode: 384 });
|
|
59
|
+
const path = join(dir, name);
|
|
60
|
+
await rename(temporary, path);
|
|
61
|
+
return path;
|
|
62
|
+
} catch {
|
|
63
|
+
return void 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function take(path) {
|
|
67
|
+
const taken = `${path}.${process.pid}.${randomBytes(4).toString("hex")}.taken`;
|
|
68
|
+
try {
|
|
69
|
+
await rename(path, taken);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (error.code !== "ENOENT")
|
|
72
|
+
await rm(path, { force: true }).catch(() => void 0);
|
|
73
|
+
return void 0;
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const event = JSON.parse(await readFile(taken, "utf8"));
|
|
77
|
+
return typeof event?.raw === "string" ? event : void 0;
|
|
78
|
+
} catch {
|
|
79
|
+
return void 0;
|
|
80
|
+
} finally {
|
|
81
|
+
await rm(taken, { force: true }).catch(() => void 0);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function drainerRunning(home, now = Date.now()) {
|
|
85
|
+
return stat(queuePaths(home).lock).then(
|
|
86
|
+
(stats) => now - stats.mtimeMs <= DRAIN_STALE_MS,
|
|
87
|
+
() => false
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
async function claimStart(home) {
|
|
91
|
+
return tryLock(queuePaths(home).start, START_STALE_MS).catch(() => void 0);
|
|
92
|
+
}
|
|
93
|
+
async function drainQueue(home, options) {
|
|
94
|
+
const { dir, lock, start } = queuePaths(home);
|
|
95
|
+
const deadline = options.deadline ?? Number.POSITIVE_INFINITY;
|
|
96
|
+
let processed = 0;
|
|
97
|
+
for (; ; ) {
|
|
98
|
+
const release = await tryLock(lock, DRAIN_STALE_MS).catch(() => void 0);
|
|
99
|
+
if (!release) return processed;
|
|
100
|
+
await rm(start, { force: true }).catch(() => void 0);
|
|
101
|
+
let pass = 0;
|
|
102
|
+
try {
|
|
103
|
+
pass = await drainHeld(dir, lock, options, deadline);
|
|
104
|
+
} finally {
|
|
105
|
+
await release();
|
|
106
|
+
}
|
|
107
|
+
processed += pass;
|
|
108
|
+
if (pass === 0 || Date.now() >= deadline || (await queued(dir)).length === 0)
|
|
109
|
+
return processed;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function drainHeld(dir, lock, options, deadline) {
|
|
113
|
+
let processed = 0;
|
|
114
|
+
let pending = [];
|
|
115
|
+
const seen = /* @__PURE__ */ new Set();
|
|
116
|
+
const next = async () => {
|
|
117
|
+
for (; ; ) {
|
|
118
|
+
if (pending.length === 0)
|
|
119
|
+
pending = (await queued(dir)).filter((name2) => !seen.has(name2));
|
|
120
|
+
const name = pending.shift();
|
|
121
|
+
if (!name) return void 0;
|
|
122
|
+
if (seen.has(name)) continue;
|
|
123
|
+
seen.add(name);
|
|
124
|
+
return name;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const worker = async () => {
|
|
128
|
+
for (; ; ) {
|
|
129
|
+
if (Date.now() >= deadline) return;
|
|
130
|
+
const name = await next();
|
|
131
|
+
if (!name) return;
|
|
132
|
+
const event = await take(join(dir, name));
|
|
133
|
+
if (!event) continue;
|
|
134
|
+
await options.pay(event).catch(() => void 0);
|
|
135
|
+
processed++;
|
|
136
|
+
const now = /* @__PURE__ */ new Date();
|
|
137
|
+
await utimes(lock, now, now).catch(() => void 0);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
const workers = Math.max(1, options.concurrency ?? PAY_CONCURRENCY);
|
|
141
|
+
await Promise.all(Array.from({ length: workers }, worker));
|
|
142
|
+
return processed;
|
|
143
|
+
}
|
|
144
|
+
async function queuedCount(home) {
|
|
145
|
+
return (await queued(queuePaths(home).dir)).length;
|
|
146
|
+
}
|
|
147
|
+
async function queued(dir) {
|
|
148
|
+
const names = await readdir(dir).catch(() => []);
|
|
149
|
+
return names.filter((name) => name.endsWith(".json") && !name.startsWith(".")).sort();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/hook-process.ts
|
|
153
|
+
var DRAIN_MAX_MS = 12e4;
|
|
154
|
+
var REFILL_RETRY_MS = 3e4;
|
|
155
|
+
var MAX_INPUT_BYTES = 8 * 1024 * 1024;
|
|
156
|
+
async function runHookProcess(argument = process.argv[3]) {
|
|
157
|
+
const started = Date.now();
|
|
158
|
+
setTimeout(() => process.exit(0), HOOK_TIMEOUT_MS + 500).unref();
|
|
159
|
+
const raw = argument ?? await readStdin(HOOK_TIMEOUT_MS / 2);
|
|
160
|
+
const payload = parseHookInput(raw);
|
|
161
|
+
if (isCursorPayload(payload)) process.stdout.write("{}\n");
|
|
162
|
+
if (!turnEnd(payload) && hookDomains(payload).length === 0) return;
|
|
163
|
+
const settings = resolveSettings();
|
|
164
|
+
const event = {
|
|
165
|
+
raw,
|
|
166
|
+
codexHome: process.env.CODEX_HOME || join2(homedir(), ".codex")
|
|
167
|
+
};
|
|
168
|
+
const path = await enqueue(settings.home, event);
|
|
169
|
+
if (path) {
|
|
170
|
+
if (await drainerRunning(settings.home)) return;
|
|
171
|
+
const claim = await claimStart(settings.home);
|
|
172
|
+
if (!claim) return;
|
|
173
|
+
if (await startDrain()) return;
|
|
174
|
+
await claim();
|
|
175
|
+
const own = await take(path);
|
|
176
|
+
if (!own) return;
|
|
177
|
+
}
|
|
178
|
+
await payEvent(
|
|
179
|
+
event,
|
|
180
|
+
settings,
|
|
181
|
+
() => startRefill(),
|
|
182
|
+
started + HOOK_TIMEOUT_MS - Date.now()
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
async function runPayProcess() {
|
|
186
|
+
setTimeout(() => process.exit(0), DRAIN_MAX_MS + PAY_TIMEOUT_MS + 5e3).unref();
|
|
187
|
+
const settings = resolveSettings();
|
|
188
|
+
const raw = await readStdin(HOOK_TIMEOUT_MS);
|
|
189
|
+
if (raw.trim()) await enqueue(settings.home, { raw });
|
|
190
|
+
let refilledAt = Number.NEGATIVE_INFINITY;
|
|
191
|
+
const refill = () => {
|
|
192
|
+
if (Date.now() - refilledAt < REFILL_RETRY_MS) return;
|
|
193
|
+
refilledAt = Date.now();
|
|
194
|
+
startRefill();
|
|
195
|
+
};
|
|
196
|
+
await drainQueue(settings.home, {
|
|
197
|
+
deadline: Date.now() + DRAIN_MAX_MS,
|
|
198
|
+
pay: (event) => payEvent(event, settings, refill, PAY_TIMEOUT_MS)
|
|
199
|
+
});
|
|
200
|
+
if (!await drainerRunning(settings.home) && await queuedCount(settings.home) > 0)
|
|
201
|
+
await startDrain();
|
|
202
|
+
}
|
|
203
|
+
async function payEvent(event, settings, refill, timeoutMs) {
|
|
204
|
+
if (timeoutMs <= 0) return;
|
|
205
|
+
const { runHook } = await import("./hook-RJN6WCIT.js");
|
|
206
|
+
await runHook(
|
|
207
|
+
{
|
|
208
|
+
readInput: async () => event.raw,
|
|
209
|
+
settings,
|
|
210
|
+
startRefill: refill,
|
|
211
|
+
...event.codexHome ? { agents: { env: { CODEX_HOME: event.codexHome }, home: homedir() } } : {}
|
|
212
|
+
},
|
|
213
|
+
timeoutMs
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
function readStdin(timeoutMs) {
|
|
217
|
+
return new Promise((resolve) => {
|
|
218
|
+
const chunks = [];
|
|
219
|
+
let size = 0;
|
|
220
|
+
const finish = () => {
|
|
221
|
+
clearTimeout(timer);
|
|
222
|
+
process.stdin.removeAllListeners();
|
|
223
|
+
process.stdin.pause();
|
|
224
|
+
resolve(Buffer.concat(chunks).toString("utf8"));
|
|
225
|
+
};
|
|
226
|
+
const timer = setTimeout(finish, timeoutMs);
|
|
227
|
+
process.stdin.on("data", (chunk) => {
|
|
228
|
+
size += chunk.length;
|
|
229
|
+
if (size > MAX_INPUT_BYTES) {
|
|
230
|
+
chunks.length = 0;
|
|
231
|
+
finish();
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
chunks.push(chunk);
|
|
235
|
+
});
|
|
236
|
+
process.stdin.on("end", finish);
|
|
237
|
+
process.stdin.on("error", finish);
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
export {
|
|
241
|
+
runHookProcess,
|
|
242
|
+
runPayProcess
|
|
243
|
+
};
|
|
@@ -2,7 +2,8 @@ import { createRequire as __patronCreateRequire } from 'node:module'
|
|
|
2
2
|
const require = __patronCreateRequire(import.meta.url)
|
|
3
3
|
import {
|
|
4
4
|
statePaths
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-SGQ525FB.js";
|
|
6
|
+
import "./chunk-O64T22EK.js";
|
|
6
7
|
import "./chunk-GTMLTZRN.js";
|
|
7
8
|
|
|
8
9
|
// src/wallet.ts
|
package/package.json
CHANGED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { createRequire as __patronCreateRequire } from 'node:module'
|
|
2
|
-
const require = __patronCreateRequire(import.meta.url)
|
|
3
|
-
import {
|
|
4
|
-
HOOK_TIMEOUT_MS,
|
|
5
|
-
hookDomains,
|
|
6
|
-
isCursorPayload,
|
|
7
|
-
parseHookInput,
|
|
8
|
-
turnEnd
|
|
9
|
-
} from "./chunk-5GS6AZ5L.js";
|
|
10
|
-
import {
|
|
11
|
-
startPayment,
|
|
12
|
-
startRefill
|
|
13
|
-
} from "./chunk-HEQBEBKL.js";
|
|
14
|
-
import {
|
|
15
|
-
resolveSettings
|
|
16
|
-
} from "./chunk-WZRGCKEK.js";
|
|
17
|
-
import "./chunk-GTMLTZRN.js";
|
|
18
|
-
|
|
19
|
-
// src/hook-process.ts
|
|
20
|
-
var MAX_INPUT_BYTES = 8 * 1024 * 1024;
|
|
21
|
-
async function runHookProcess(argument = process.argv[3]) {
|
|
22
|
-
setTimeout(() => process.exit(0), HOOK_TIMEOUT_MS + 500).unref();
|
|
23
|
-
const raw = argument ?? await readStdin(HOOK_TIMEOUT_MS / 2);
|
|
24
|
-
const payload = parseHookInput(raw);
|
|
25
|
-
if (isCursorPayload(payload)) process.stdout.write("{}\n");
|
|
26
|
-
if (!turnEnd(payload) && hookDomains(payload).length === 0) return;
|
|
27
|
-
if (await startPayment(raw)) return;
|
|
28
|
-
const { runHook } = await import("./hook-AHF4ELOX.js");
|
|
29
|
-
await runHook({
|
|
30
|
-
readInput: async () => raw,
|
|
31
|
-
settings: resolveSettings(),
|
|
32
|
-
startRefill: () => startRefill()
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
async function runPayProcess() {
|
|
36
|
-
const { PAY_TIMEOUT_MS, runHook } = await import("./hook-AHF4ELOX.js");
|
|
37
|
-
setTimeout(() => process.exit(0), PAY_TIMEOUT_MS + 1e3).unref();
|
|
38
|
-
const raw = await readStdin(HOOK_TIMEOUT_MS);
|
|
39
|
-
await runHook(
|
|
40
|
-
{
|
|
41
|
-
readInput: async () => raw,
|
|
42
|
-
settings: resolveSettings(),
|
|
43
|
-
startRefill: () => startRefill()
|
|
44
|
-
},
|
|
45
|
-
PAY_TIMEOUT_MS
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
function readStdin(timeoutMs) {
|
|
49
|
-
return new Promise((resolve) => {
|
|
50
|
-
const chunks = [];
|
|
51
|
-
let size = 0;
|
|
52
|
-
const finish = () => {
|
|
53
|
-
clearTimeout(timer);
|
|
54
|
-
process.stdin.removeAllListeners();
|
|
55
|
-
process.stdin.pause();
|
|
56
|
-
resolve(Buffer.concat(chunks).toString("utf8"));
|
|
57
|
-
};
|
|
58
|
-
const timer = setTimeout(finish, timeoutMs);
|
|
59
|
-
process.stdin.on("data", (chunk) => {
|
|
60
|
-
size += chunk.length;
|
|
61
|
-
if (size > MAX_INPUT_BYTES) {
|
|
62
|
-
chunks.length = 0;
|
|
63
|
-
finish();
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
chunks.push(chunk);
|
|
67
|
-
});
|
|
68
|
-
process.stdin.on("end", finish);
|
|
69
|
-
process.stdin.on("error", finish);
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
export {
|
|
73
|
-
runHookProcess,
|
|
74
|
-
runPayProcess
|
|
75
|
-
};
|