@tempoxyz/patron 0.0.23 → 0.0.25

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-3OTLNDSS.js");
7
+ const { runHookProcess } = await import("./chunks/hook-process-ZPEWRFL2.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-3OTLNDSS.js");
11
+ const { runPayProcess } = await import("./chunks/hook-process-ZPEWRFL2.js");
12
12
  await runPayProcess().catch(() => void 0);
13
13
  process.exit(0);
14
14
  } else {
15
- const { run } = await import("./chunks/-JRJJV4LP.js");
15
+ const { run } = await import("./chunks/-ZZLSTHT6.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-75CD5P6X.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,
@@ -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
@@ -90,6 +92,13 @@ export const description = 'Patron: pays $0.001 to each site Amp reads with read
90
92
  const COMMAND = ${JSON.stringify(command)}
91
93
  const TOOLS = new Set(${JSON.stringify(AMP_WEB_TOOLS)})
92
94
 
95
+ /** Length of a tool's output; 0 for none or blank text. */
96
+ function size(output: unknown): number {
97
+ if (output === undefined || output === null) return 0
98
+ const text = typeof output === 'string' ? output : JSON.stringify(output)
99
+ return text.trim().length
100
+ }
101
+
93
102
  export default function (amp: PluginAPI) {
94
103
  amp.on('tool.result', (event) => {
95
104
  if (event.status !== 'done' || !TOOLS.has(event.tool)) return
@@ -102,7 +111,8 @@ export default function (amp: PluginAPI) {
102
111
  hook_event_name: 'tool.result',
103
112
  tool_input: event.input,
104
113
  tool_name: event.tool,
105
- tool_response: event.tool === 'web_search' ? event.output : undefined,
114
+ // read_web_page sends only the page's length, so an empty page pays nothing.
115
+ tool_response: event.tool === 'web_search' ? event.output : { bytes: size(event.output) },
106
116
  }),
107
117
  )
108
118
  child.unref()
@@ -690,10 +700,10 @@ async function linkRefillFailedAt(home) {
690
700
  var REFILL_LOCK_STALE_MS = 5 * 60 * 1e3;
691
701
  var defaultOpenWallet = async (settings, config, issuer, maxUnits) => {
692
702
  if (config.wallet === "link") {
693
- const { openLinkWallet } = await import("./wallet-R3UWBXVC.js");
703
+ const { openLinkWallet } = await import("./wallet-7M2LEO4J.js");
694
704
  return openLinkWallet(config, maxUnits);
695
705
  }
696
- const { openWallet } = await import("./wallet-R3UWBXVC.js");
706
+ const { openWallet } = await import("./wallet-7M2LEO4J.js");
697
707
  return openWallet(settings, config.wallet, issuer, maxUnits);
698
708
  };
699
709
  async function buyWithinBudget(settings, config, wanted, openWallet = defaultOpenWallet) {
@@ -1062,7 +1072,7 @@ async function tempoSignIn(deps, budgetUnits, issuer) {
1062
1072
  deps,
1063
1073
  deps.settings.privateKey ? "Using PATRON_PRIVATE_KEY" : "Signing in with Tempo Wallet"
1064
1074
  );
1065
- const { signIn } = await import("./wallet-R3UWBXVC.js");
1075
+ const { signIn } = await import("./wallet-7M2LEO4J.js");
1066
1076
  const account = await signIn(deps.settings, {
1067
1077
  budgetUnits,
1068
1078
  issuer,
@@ -1176,7 +1186,7 @@ async function changeBudget(deps, input) {
1176
1186
  } else budget = await askBudget(deps, config.monthlyBudgetUsd);
1177
1187
  if (config.wallet === "tempo" && budget > config.monthlyBudgetUsd) {
1178
1188
  step(deps, "Approve the new spending limit in Tempo Wallet");
1179
- const { authorizeBudget } = await import("./wallet-R3UWBXVC.js");
1189
+ const { authorizeBudget } = await import("./wallet-7M2LEO4J.js");
1180
1190
  const issuer = await loadIssuer(settings.home, settings.gatewayUrl, {
1181
1191
  fetch: deps.fetch
1182
1192
  });
@@ -1292,7 +1302,7 @@ async function setName(deps, name) {
1292
1302
  const issuer = await loadIssuer(settings.home, settings.gatewayUrl, {
1293
1303
  fetch: deps.fetch
1294
1304
  });
1295
- const open = deps.openWallet ?? (async (s, c, i, max) => (await import("./wallet-R3UWBXVC.js")).openWallet(s, c.wallet, i, max));
1305
+ const open = deps.openWallet ?? (async (s, c, i, max) => (await import("./wallet-7M2LEO4J.js")).openWallet(s, c.wallet, i, max));
1296
1306
  const wallet = await open(settings, config, issuer, 0n);
1297
1307
  await setProfile(settings.gatewayUrl, wallet, name, deps.fetch);
1298
1308
  await writeConfig(settings.home, { ...config, name });
@@ -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;
@@ -45,7 +46,14 @@ function payableDomain(url) {
45
46
  function succeeded(response) {
46
47
  if (!isRecord(response)) return true;
47
48
  const status = response.code ?? response.status ?? response.statusCode;
48
- return typeof status !== "number" || status >= 200 && status < 300;
49
+ if (typeof status === "number" && (status < 200 || status >= 300 || status === 204))
50
+ return false;
51
+ if (response.bytes === 0) return false;
52
+ for (const field of ["markdown", "content"]) {
53
+ const body = response[field];
54
+ if (typeof body === "string" && body.trim() === "") return false;
55
+ }
56
+ return true;
49
57
  }
50
58
  function turnEnd(payload) {
51
59
  if (!isRecord(payload)) return void 0;
@@ -105,6 +113,7 @@ function isRecord(value) {
105
113
 
106
114
  export {
107
115
  HOOK_TIMEOUT_MS,
116
+ PAY_TIMEOUT_MS,
108
117
  MAX_DOMAINS_PER_HOOK,
109
118
  hookDomains,
110
119
  payableDomain,
@@ -13,9 +13,11 @@ 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,
@@ -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
  };
@@ -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-5GS6AZ5L.js";
11
+ } from "./chunk-HVTTV2A5.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-75CD5P6X.js";
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-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-HVTTV2A5.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-OZRD6I6F.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.23",
3
+ "version": "0.0.25",
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-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
- };