@tempoxyz/patron 0.0.22 → 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 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-D5ENJPRB.js");
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-D5ENJPRB.js");
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/-PMO5HHO2.js");
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-QKBTYUXG.js";
32
+ } from "./chunk-NQ6RRPM6.js";
33
33
  import {
34
34
  startRefill
35
- } from "./chunk-HEQBEBKL.js";
35
+ } from "./chunk-TV5VLFTD.js";
36
36
  import {
37
37
  DEFAULT_MONTHLY_BUDGET_USD,
38
38
  MAX_TOKENS_PER_PAGE,
@@ -45,7 +45,7 @@ import {
45
45
  resolveSettings,
46
46
  settingsFor,
47
47
  tokensToUnits
48
- } from "./chunk-CF4LJZLC.js";
48
+ } from "./chunk-WZRGCKEK.js";
49
49
  import {
50
50
  AGENT_IDS,
51
51
  ensureHome,
@@ -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-UWIBR62N.js";
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-R3UWBXVC.js");
695
+ const { openLinkWallet } = await import("./wallet-7M2LEO4J.js");
694
696
  return openLinkWallet(config, maxUnits);
695
697
  }
696
- const { openWallet } = await import("./wallet-R3UWBXVC.js");
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-R3UWBXVC.js");
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-R3UWBXVC.js");
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-R3UWBXVC.js")).openWallet(s, c.wallet, i, max));
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 });
@@ -8,14 +8,16 @@ import {
8
8
  TOKEN_TYPE,
9
9
  fromBase64Url,
10
10
  toBase64Url
11
- } from "./chunk-CF4LJZLC.js";
11
+ } from "./chunk-WZRGCKEK.js";
12
12
  import {
13
13
  ensureHome,
14
14
  readJson,
15
15
  statePaths,
16
- withLock,
17
16
  writePrivateFile
18
- } from "./chunk-UWIBR62N.js";
17
+ } from "./chunk-SGQ525FB.js";
18
+ import {
19
+ withLock
20
+ } from "./chunk-O64T22EK.js";
19
21
  import {
20
22
  __commonJS,
21
23
  __export,
@@ -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 as rm2,
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}.${Date.now()}.tmp`;
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 rm2(temporary, { force: true }).catch(() => void 0);
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,
@@ -3,10 +3,11 @@ const require = __patronCreateRequire(import.meta.url)
3
3
  import {
4
4
  isExcludedByDefault,
5
5
  normalizePayee
6
- } from "./chunk-CF4LJZLC.js";
6
+ } from "./chunk-WZRGCKEK.js";
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 startPayment(payload, script = process.argv[1]) {
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: ["pipe", "ignore", "ignore"]
39
+ stdio: "ignore"
40
40
  });
41
41
  child.on("error", () => resolve(false));
42
- child.stdin.on("error", () => resolve(false));
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
- startPayment
54
+ startDrain
56
55
  };
@@ -849,9 +849,16 @@ function normalizeDomain(input) {
849
849
  if (!hostname || hostname === "localhost" || hostname.endsWith(".localhost"))
850
850
  return null;
851
851
  const parsed = (0, import_tldts.parse)(hostname, { allowPrivateDomains: true });
852
- if (parsed.isIp || !parsed.domain || !(parsed.isIcann || parsed.isPrivate)) return null;
852
+ if (parsed.isIp) return null;
853
+ if (isEnsGatewayName(hostname)) return hostname;
854
+ if (!parsed.domain || !(parsed.isIcann || parsed.isPrivate)) return null;
853
855
  return authorSite(hostname, parsed.domain) ?? parsed.domain;
854
856
  }
857
+ var ENS_GATEWAYS = /* @__PURE__ */ new Set(["eth.limo", "eth.link"]);
858
+ function isEnsGatewayName(hostname) {
859
+ const dot = hostname.indexOf(".");
860
+ return dot > 0 && ENS_GATEWAYS.has(hostname.slice(dot + 1));
861
+ }
855
862
  function authorSite(hostname, domain) {
856
863
  if (!AUTHOR_PLATFORMS.has(domain)) return null;
857
864
  const author = hostname.slice(0, -(domain.length + 1)).split(".").at(-1);
@@ -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-RJRJWNSQ.js";
11
+ } from "./chunk-SIIFXQ6S.js";
11
12
  import {
12
13
  FileTokenStore,
13
14
  codexHome,
@@ -15,18 +16,20 @@ import {
15
16
  needsRefill,
16
17
  redeem,
17
18
  refillSize
18
- } from "./chunk-QKBTYUXG.js";
19
+ } from "./chunk-NQ6RRPM6.js";
19
20
  import {
20
21
  clampTokensPerPage,
21
22
  settingsFor
22
- } from "./chunk-CF4LJZLC.js";
23
+ } from "./chunk-WZRGCKEK.js";
23
24
  import {
24
25
  readConfig,
25
26
  readUsage,
26
27
  updateUsage,
27
- withLock,
28
28
  writePrivateFile
29
- } from "./chunk-UWIBR62N.js";
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-UWIBR62N.js";
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@tempoxyz/patron",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
4
4
  "description": "Pay the websites your AI agents read, privately",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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-RJRJWNSQ.js";
10
- import {
11
- startPayment,
12
- startRefill
13
- } from "./chunk-HEQBEBKL.js";
14
- import {
15
- resolveSettings
16
- } from "./chunk-CF4LJZLC.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-QEFJTAKR.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-QEFJTAKR.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
- };