@tempoxyz/patron 0.0.12 → 0.0.14
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 +2 -2
- package/dist/chunks/{-KL2FSIN2.js → -CE2UCGLQ.js} +70 -31
- package/dist/chunks/{chunk-6TTNL3HT.js → chunk-A66D2RFJ.js} +3 -2
- package/dist/chunks/{chunk-EDGGHF4L.js → chunk-XUDTL3AP.js} +236 -5
- package/dist/chunks/{hook-process-2Y5LU62B.js → hook-process-RURAGR7W.js} +3 -5
- package/dist/chunks/{wallet-MEBNL43A.js → wallet-P26QSI4Y.js} +1 -1
- package/package.json +1 -1
- package/dist/chunks/chunk-E4XN5ZK6.js +0 -230
- package/dist/chunks/codex-UEAW7Y4U.js +0 -29
package/dist/bin.js
CHANGED
|
@@ -4,10 +4,10 @@ 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-RURAGR7W.js");
|
|
8
8
|
await runHookProcess().catch(() => void 0);
|
|
9
9
|
process.exit(0);
|
|
10
10
|
} else {
|
|
11
|
-
const { run } = await import("./chunks/-
|
|
11
|
+
const { run } = await import("./chunks/-CE2UCGLQ.js");
|
|
12
12
|
process.exitCode = await run(process.argv.slice(2));
|
|
13
13
|
}
|
|
@@ -13,34 +13,34 @@ import {
|
|
|
13
13
|
budgetTokens,
|
|
14
14
|
buyTokens,
|
|
15
15
|
clampTokensPerPage,
|
|
16
|
+
codexHome,
|
|
17
|
+
codexPaths,
|
|
16
18
|
formatUsd,
|
|
19
|
+
hasPatronHandler,
|
|
20
|
+
installCodex,
|
|
21
|
+
isObject,
|
|
22
|
+
isPatronHandler,
|
|
17
23
|
loadIssuer,
|
|
18
24
|
needsRefill,
|
|
19
25
|
normalizePayee,
|
|
20
26
|
parseUsd,
|
|
21
27
|
profileMessage,
|
|
22
28
|
purchasableTokens,
|
|
29
|
+
readJsonObject,
|
|
23
30
|
redeem,
|
|
31
|
+
removeCodex,
|
|
24
32
|
resolveSettings,
|
|
25
33
|
settingsFor,
|
|
26
34
|
startRefill,
|
|
27
35
|
tipTokens,
|
|
28
|
-
tokensToUnits
|
|
29
|
-
|
|
30
|
-
import {
|
|
31
|
-
codexHome,
|
|
32
|
-
codexPaths,
|
|
33
|
-
hasPatronHandler,
|
|
34
|
-
installCodex,
|
|
35
|
-
isObject,
|
|
36
|
-
isPatronHandler,
|
|
37
|
-
readJsonObject,
|
|
38
|
-
removeCodex,
|
|
36
|
+
tokensToUnits,
|
|
37
|
+
upgradeCodex,
|
|
39
38
|
withHooksKey,
|
|
40
39
|
withPatronGroup,
|
|
40
|
+
withPatronStatus,
|
|
41
41
|
withoutPatronHandlers,
|
|
42
42
|
writeJsonObject
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-XUDTL3AP.js";
|
|
44
44
|
import {
|
|
45
45
|
AGENT_IDS,
|
|
46
46
|
ensureHome,
|
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
withLock,
|
|
54
54
|
writeConfig,
|
|
55
55
|
writePrivateFile
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-A66D2RFJ.js";
|
|
57
57
|
|
|
58
58
|
// src/index.ts
|
|
59
59
|
import { readFileSync } from "node:fs";
|
|
@@ -116,6 +116,15 @@ async function installAmpPlugin(path, command) {
|
|
|
116
116
|
await writePrivateFile(path, source);
|
|
117
117
|
return "installed";
|
|
118
118
|
}
|
|
119
|
+
async function upgradeAmpPlugin(path) {
|
|
120
|
+
const current = await readText(path);
|
|
121
|
+
if (current === void 0 || !current.startsWith(AMP_PLUGIN_MARKER)) return false;
|
|
122
|
+
const literal = /^const COMMAND = (".*")$/m.exec(current)?.[1];
|
|
123
|
+
if (!literal) return false;
|
|
124
|
+
const command = JSON.parse(literal);
|
|
125
|
+
if (typeof command !== "string") return false;
|
|
126
|
+
return await installAmpPlugin(path, command) === "installed";
|
|
127
|
+
}
|
|
119
128
|
async function removeAmpPlugin(path) {
|
|
120
129
|
const current = await readText(path);
|
|
121
130
|
if (current === void 0 || !current.startsWith(AMP_PLUGIN_MARKER)) return "missing";
|
|
@@ -135,11 +144,30 @@ async function readText(path) {
|
|
|
135
144
|
var CLAUDE_MATCHER = "WebFetch|WebSearch";
|
|
136
145
|
var HOOK_TIMEOUT_SECONDS = 30;
|
|
137
146
|
var EVENT = "PostToolUse";
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
147
|
+
var CLAUDE_HOOK_STATUS = "Patron: pay the site this read";
|
|
148
|
+
function patronGroup(command) {
|
|
149
|
+
return {
|
|
150
|
+
hooks: [
|
|
151
|
+
{
|
|
152
|
+
async: true,
|
|
153
|
+
command,
|
|
154
|
+
statusMessage: CLAUDE_HOOK_STATUS,
|
|
155
|
+
timeout: HOOK_TIMEOUT_SECONDS,
|
|
156
|
+
type: "command"
|
|
157
|
+
}
|
|
158
|
+
],
|
|
141
159
|
matcher: CLAUDE_MATCHER
|
|
142
|
-
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function withPatronHook(settings, command) {
|
|
163
|
+
return withPatronGroup(settings, EVENT, patronGroup(command));
|
|
164
|
+
}
|
|
165
|
+
async function upgradeClaudeHook(path) {
|
|
166
|
+
const settings = await readJsonObject(path);
|
|
167
|
+
const next = withPatronStatus(settings, EVENT, CLAUDE_HOOK_STATUS);
|
|
168
|
+
if (!next) return false;
|
|
169
|
+
await writeJsonObject(path, next);
|
|
170
|
+
return true;
|
|
143
171
|
}
|
|
144
172
|
function withoutPatronHook(settings) {
|
|
145
173
|
return withoutPatronHandlers(settings, EVENT);
|
|
@@ -303,7 +331,8 @@ var ADAPTERS = {
|
|
|
303
331
|
install: async (command, { env, home }) => ({
|
|
304
332
|
state: await installAmpPlugin(ampPluginPath(env, home), command)
|
|
305
333
|
}),
|
|
306
|
-
remove: ({ env, home }) => removeAmpPlugin(ampPluginPath(env, home))
|
|
334
|
+
remove: ({ env, home }) => removeAmpPlugin(ampPluginPath(env, home)),
|
|
335
|
+
upgrade: ({ env, home }) => upgradeAmpPlugin(ampPluginPath(env, home))
|
|
307
336
|
},
|
|
308
337
|
"claude-code": {
|
|
309
338
|
files: (environment) => [claudeSettingsPath(environment)],
|
|
@@ -311,13 +340,15 @@ var ADAPTERS = {
|
|
|
311
340
|
install: async (command, environment) => ({
|
|
312
341
|
state: await installClaudeHook(claudeSettingsPath(environment), command)
|
|
313
342
|
}),
|
|
314
|
-
remove: (environment) => removeClaudeHook(claudeSettingsPath(environment))
|
|
343
|
+
remove: (environment) => removeClaudeHook(claudeSettingsPath(environment)),
|
|
344
|
+
upgrade: (environment) => upgradeClaudeHook(claudeSettingsPath(environment))
|
|
315
345
|
},
|
|
316
346
|
codex: {
|
|
317
347
|
files: ({ env, home }) => Object.values(codexPaths(env, home)),
|
|
318
348
|
detect: async ({ env, home }) => await exists(codexHome(env, home)) || await onPath(["codex"], env.PATH ?? ""),
|
|
319
349
|
install: (command, { env, home }) => installCodex(codexPaths(env, home), command),
|
|
320
|
-
remove: ({ env, home }) => removeCodex(codexPaths(env, home))
|
|
350
|
+
remove: ({ env, home }) => removeCodex(codexPaths(env, home)),
|
|
351
|
+
upgrade: ({ env, home }) => upgradeCodex(codexPaths(env, home))
|
|
321
352
|
},
|
|
322
353
|
cursor: {
|
|
323
354
|
files: ({ home }) => [cursorHooksPath(home)],
|
|
@@ -359,6 +390,14 @@ async function installAgents(agents, command, environment) {
|
|
|
359
390
|
})
|
|
360
391
|
);
|
|
361
392
|
}
|
|
393
|
+
async function upgradeAgents(agents, environment) {
|
|
394
|
+
const changed = await Promise.all(
|
|
395
|
+
agents.map(
|
|
396
|
+
async (agent) => await ADAPTERS[agent].upgrade?.(environment).catch(() => false) ? agent : void 0
|
|
397
|
+
)
|
|
398
|
+
);
|
|
399
|
+
return changed.filter((agent) => agent !== void 0);
|
|
400
|
+
}
|
|
362
401
|
async function removeAgents(environment) {
|
|
363
402
|
const store = originalsStore(environment);
|
|
364
403
|
return Promise.all(
|
|
@@ -575,7 +614,7 @@ ${styleText(title, "bold", color)}
|
|
|
575
614
|
// src/purchase.ts
|
|
576
615
|
var REFILL_LOCK_STALE_MS = 5 * 60 * 1e3;
|
|
577
616
|
var defaultOpenWallet = async (settings, config, issuer, maxUnits) => {
|
|
578
|
-
const { openWallet } = await import("./wallet-
|
|
617
|
+
const { openWallet } = await import("./wallet-P26QSI4Y.js");
|
|
579
618
|
return openWallet(settings, config.wallet, issuer, maxUnits);
|
|
580
619
|
};
|
|
581
620
|
async function buyWithinBudget(settings, config, wanted, openWallet = defaultOpenWallet) {
|
|
@@ -800,13 +839,13 @@ async function main(deps) {
|
|
|
800
839
|
await status(deps, deps.interactive);
|
|
801
840
|
}
|
|
802
841
|
async function syncAgents(deps, config) {
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
const
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
say(deps);
|
|
809
|
-
|
|
842
|
+
const upgraded = await upgradeAgents(config.agents, deps.agents);
|
|
843
|
+
if (upgraded.length > 0) {
|
|
844
|
+
const names = upgraded.map((agent) => AGENT_LABELS[agent]).join(", ");
|
|
845
|
+
say(deps, `Updated Patron for ${names}.`);
|
|
846
|
+
if (upgraded.includes("codex"))
|
|
847
|
+
say(deps, " Codex: trust the hook again in /hooks when it asks.");
|
|
848
|
+
say(deps);
|
|
810
849
|
}
|
|
811
850
|
const added = (await detectAgents(deps.agents)).filter(
|
|
812
851
|
(agent) => !config.agents.includes(agent)
|
|
@@ -842,7 +881,7 @@ async function setup(deps) {
|
|
|
842
881
|
deps,
|
|
843
882
|
settings.privateKey ? "Using PATRON_PRIVATE_KEY" : "Signing in with Tempo Wallet"
|
|
844
883
|
);
|
|
845
|
-
const { signIn } = await import("./wallet-
|
|
884
|
+
const { signIn } = await import("./wallet-P26QSI4Y.js");
|
|
846
885
|
const account = await signIn(settings, { budgetUnits, issuer, output: deps.stdout });
|
|
847
886
|
done(deps, `Signed in as ${account.address}`);
|
|
848
887
|
const config = {
|
|
@@ -956,7 +995,7 @@ async function changeBudget(deps, input) {
|
|
|
956
995
|
} else budget = await askBudget(deps, config.monthlyBudgetUsd);
|
|
957
996
|
if (config.wallet === "tempo" && budget > config.monthlyBudgetUsd) {
|
|
958
997
|
step(deps, "Approve the new spending limit in Tempo Wallet");
|
|
959
|
-
const { authorizeBudget } = await import("./wallet-
|
|
998
|
+
const { authorizeBudget } = await import("./wallet-P26QSI4Y.js");
|
|
960
999
|
const issuer = await loadIssuer(settings.home, settings.gatewayUrl, {
|
|
961
1000
|
fetch: deps.fetch
|
|
962
1001
|
});
|
|
@@ -1068,7 +1107,7 @@ async function setName(deps, name) {
|
|
|
1068
1107
|
const issuer = await loadIssuer(settings.home, settings.gatewayUrl, {
|
|
1069
1108
|
fetch: deps.fetch
|
|
1070
1109
|
});
|
|
1071
|
-
const open = deps.openWallet ?? (async (s, c, i, max) => (await import("./wallet-
|
|
1110
|
+
const open = deps.openWallet ?? (async (s, c, i, max) => (await import("./wallet-P26QSI4Y.js")).openWallet(s, c.wallet, i, max));
|
|
1072
1111
|
const wallet = await open(settings, config, issuer, 0n);
|
|
1073
1112
|
await setProfile(settings.gatewayUrl, wallet, name, deps.fetch);
|
|
1074
1113
|
await writeConfig(settings.home, { ...config, name });
|
|
@@ -41,7 +41,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
41
41
|
));
|
|
42
42
|
|
|
43
43
|
// src/state.ts
|
|
44
|
-
import { chmod, mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
44
|
+
import { chmod, mkdir, readFile, realpath, rename, writeFile } from "node:fs/promises";
|
|
45
45
|
import { join } from "node:path";
|
|
46
46
|
|
|
47
47
|
// src/lock.ts
|
|
@@ -120,7 +120,8 @@ async function readJson(path) {
|
|
|
120
120
|
throw error;
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
|
-
async function writePrivateFile(
|
|
123
|
+
async function writePrivateFile(link, contents) {
|
|
124
|
+
const path = await realpath(link).catch(() => link);
|
|
124
125
|
const temporary = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
125
126
|
await writeFile(temporary, contents, { mode: 384 });
|
|
126
127
|
await chmod(temporary, 384);
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
statePaths,
|
|
11
11
|
withLock,
|
|
12
12
|
writePrivateFile
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-A66D2RFJ.js";
|
|
14
14
|
|
|
15
15
|
// ../../node_modules/.pnpm/tldts@7.4.19/node_modules/tldts/dist/cjs/index.js
|
|
16
16
|
var require_cjs = __commonJS({
|
|
@@ -12270,7 +12270,7 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
12270
12270
|
}
|
|
12271
12271
|
return propValues;
|
|
12272
12272
|
});
|
|
12273
|
-
const
|
|
12273
|
+
const isObject3 = isObject;
|
|
12274
12274
|
const catchall = def.catchall;
|
|
12275
12275
|
let value;
|
|
12276
12276
|
const memo2 = globalConfig.memoizer;
|
|
@@ -12278,7 +12278,7 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
12278
12278
|
inst._zod.parse = (payload, ctx) => {
|
|
12279
12279
|
value ?? (value = _normalized.value);
|
|
12280
12280
|
const input2 = payload.value;
|
|
12281
|
-
if (!
|
|
12281
|
+
if (!isObject3(input2)) {
|
|
12282
12282
|
payload.issues.push({
|
|
12283
12283
|
expected: "object",
|
|
12284
12284
|
code: "invalid_type",
|
|
@@ -12414,7 +12414,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
12414
12414
|
return doc.compile();
|
|
12415
12415
|
};
|
|
12416
12416
|
let fastpass;
|
|
12417
|
-
const
|
|
12417
|
+
const isObject3 = isObject;
|
|
12418
12418
|
const jit = !globalConfig.jitless;
|
|
12419
12419
|
const allowsEval2 = allowsEval;
|
|
12420
12420
|
const fastEnabled = jit && allowsEval2.value;
|
|
@@ -12423,7 +12423,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
12423
12423
|
inst._zod.parse = (payload, ctx) => {
|
|
12424
12424
|
value ?? (value = _normalized.value);
|
|
12425
12425
|
const input2 = payload.value;
|
|
12426
|
-
if (!
|
|
12426
|
+
if (!isObject3(input2)) {
|
|
12427
12427
|
payload.issues.push({
|
|
12428
12428
|
expected: "object",
|
|
12429
12429
|
code: "invalid_type",
|
|
@@ -35691,6 +35691,223 @@ function startRefill(script = process.argv[1]) {
|
|
|
35691
35691
|
}
|
|
35692
35692
|
}
|
|
35693
35693
|
|
|
35694
|
+
// src/codex.ts
|
|
35695
|
+
import { mkdir as mkdir2, readFile as readFile3 } from "node:fs/promises";
|
|
35696
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
35697
|
+
|
|
35698
|
+
// src/hook-files.ts
|
|
35699
|
+
import { mkdir, readFile as readFile2 } from "node:fs/promises";
|
|
35700
|
+
import { dirname } from "node:path";
|
|
35701
|
+
function isObject2(value) {
|
|
35702
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
35703
|
+
}
|
|
35704
|
+
function isPatronHandler(handler) {
|
|
35705
|
+
if (!isObject2(handler) || typeof handler.command !== "string") return false;
|
|
35706
|
+
return /patron/i.test(handler.command) && /\shook\s*$/.test(handler.command);
|
|
35707
|
+
}
|
|
35708
|
+
function withoutPatronHandlers(settings, event) {
|
|
35709
|
+
const groups = isObject2(settings.hooks) ? settings.hooks[event] : void 0;
|
|
35710
|
+
if (!isObject2(settings.hooks) || !Array.isArray(groups)) return { ...settings };
|
|
35711
|
+
let changed = false;
|
|
35712
|
+
const kept = [];
|
|
35713
|
+
for (const group of groups) {
|
|
35714
|
+
if (!isObject2(group) || !Array.isArray(group.hooks)) {
|
|
35715
|
+
kept.push(group);
|
|
35716
|
+
continue;
|
|
35717
|
+
}
|
|
35718
|
+
const handlers = group.hooks.filter((handler) => !isPatronHandler(handler));
|
|
35719
|
+
if (handlers.length === group.hooks.length) kept.push(group);
|
|
35720
|
+
else {
|
|
35721
|
+
changed = true;
|
|
35722
|
+
if (handlers.length > 0) kept.push({ ...group, hooks: handlers });
|
|
35723
|
+
}
|
|
35724
|
+
}
|
|
35725
|
+
if (!changed) return { ...settings };
|
|
35726
|
+
return withHooksKey(settings, event, kept);
|
|
35727
|
+
}
|
|
35728
|
+
function withPatronGroup(settings, event, group) {
|
|
35729
|
+
const next = withoutPatronHandlers(settings, event);
|
|
35730
|
+
const hooks = isObject2(next.hooks) ? next.hooks : {};
|
|
35731
|
+
const groups = Array.isArray(hooks[event]) ? hooks[event] : [];
|
|
35732
|
+
return withHooksKey(next, event, [...groups, group]);
|
|
35733
|
+
}
|
|
35734
|
+
function hasPatronHandler(settings, event, options = {}) {
|
|
35735
|
+
const groups = isObject2(settings.hooks) ? settings.hooks[event] : void 0;
|
|
35736
|
+
if (!Array.isArray(groups)) return false;
|
|
35737
|
+
return groups.some(
|
|
35738
|
+
(group) => isObject2(group) && (options.matcher === void 0 || group.matcher === options.matcher) && Array.isArray(group.hooks) && group.hooks.some(
|
|
35739
|
+
(handler) => isPatronHandler(handler) && (options.command === void 0 || handler.command === options.command)
|
|
35740
|
+
)
|
|
35741
|
+
);
|
|
35742
|
+
}
|
|
35743
|
+
function withHooksKey(settings, event, entries) {
|
|
35744
|
+
const hooks = isObject2(settings.hooks) ? { ...settings.hooks } : {};
|
|
35745
|
+
if (entries.length > 0) hooks[event] = entries;
|
|
35746
|
+
else delete hooks[event];
|
|
35747
|
+
const next = { ...settings };
|
|
35748
|
+
if (Object.keys(hooks).length > 0) next.hooks = hooks;
|
|
35749
|
+
else delete next.hooks;
|
|
35750
|
+
return next;
|
|
35751
|
+
}
|
|
35752
|
+
async function readJsonObject(path) {
|
|
35753
|
+
let text;
|
|
35754
|
+
try {
|
|
35755
|
+
text = await readFile2(path, "utf8");
|
|
35756
|
+
} catch (error62) {
|
|
35757
|
+
if (error62.code === "ENOENT") return {};
|
|
35758
|
+
throw error62;
|
|
35759
|
+
}
|
|
35760
|
+
if (text.trim() === "") return {};
|
|
35761
|
+
let value;
|
|
35762
|
+
try {
|
|
35763
|
+
value = JSON.parse(text);
|
|
35764
|
+
} catch {
|
|
35765
|
+
throw new Error(`${path} is not valid JSON; fix it, then rerun patron.`);
|
|
35766
|
+
}
|
|
35767
|
+
if (!isObject2(value)) throw new Error(`${path} is not a JSON object; left unchanged.`);
|
|
35768
|
+
return value;
|
|
35769
|
+
}
|
|
35770
|
+
async function writeJsonObject(path, value) {
|
|
35771
|
+
await mkdir(dirname(path), { recursive: true });
|
|
35772
|
+
await writePrivateFile(path, `${JSON.stringify(value, null, 2)}
|
|
35773
|
+
`);
|
|
35774
|
+
}
|
|
35775
|
+
function withPatronStatus(settings, event, status) {
|
|
35776
|
+
const groups = isObject2(settings.hooks) ? settings.hooks[event] : void 0;
|
|
35777
|
+
if (!Array.isArray(groups)) return void 0;
|
|
35778
|
+
let changed = false;
|
|
35779
|
+
const next = groups.map((group) => {
|
|
35780
|
+
if (!isObject2(group) || !Array.isArray(group.hooks)) return group;
|
|
35781
|
+
return {
|
|
35782
|
+
...group,
|
|
35783
|
+
hooks: group.hooks.map((handler) => {
|
|
35784
|
+
if (!isPatronHandler(handler) || !isObject2(handler) || "statusMessage" in handler)
|
|
35785
|
+
return handler;
|
|
35786
|
+
changed = true;
|
|
35787
|
+
return { ...handler, statusMessage: status };
|
|
35788
|
+
})
|
|
35789
|
+
};
|
|
35790
|
+
});
|
|
35791
|
+
return changed ? withHooksKey(settings, event, next) : void 0;
|
|
35792
|
+
}
|
|
35793
|
+
|
|
35794
|
+
// src/codex.ts
|
|
35795
|
+
var CODEX_NOTIFY_MARKER = "# added by patron";
|
|
35796
|
+
var HOOK_TIMEOUT_SECONDS = 10;
|
|
35797
|
+
var EVENT = "Stop";
|
|
35798
|
+
function codexHome(env, home) {
|
|
35799
|
+
return env.CODEX_HOME || join2(home, ".codex");
|
|
35800
|
+
}
|
|
35801
|
+
function codexPaths(env, home) {
|
|
35802
|
+
const root = codexHome(env, home);
|
|
35803
|
+
return { config: join2(root, "config.toml"), hooks: join2(root, "hooks.json") };
|
|
35804
|
+
}
|
|
35805
|
+
function withCodexStopHook(settings, command) {
|
|
35806
|
+
return withPatronGroup(settings, EVENT, stopGroup(command));
|
|
35807
|
+
}
|
|
35808
|
+
var CODEX_HOOK_STATUS = "Patron: pay the sites this turn read";
|
|
35809
|
+
function stopGroup(command) {
|
|
35810
|
+
return {
|
|
35811
|
+
hooks: [
|
|
35812
|
+
{
|
|
35813
|
+
command,
|
|
35814
|
+
statusMessage: CODEX_HOOK_STATUS,
|
|
35815
|
+
timeout: HOOK_TIMEOUT_SECONDS,
|
|
35816
|
+
type: "command"
|
|
35817
|
+
}
|
|
35818
|
+
]
|
|
35819
|
+
};
|
|
35820
|
+
}
|
|
35821
|
+
function hasStopGroup(settings, command) {
|
|
35822
|
+
const groups = isObject2(settings.hooks) ? settings.hooks[EVENT] : void 0;
|
|
35823
|
+
const wanted = JSON.stringify(stopGroup(command));
|
|
35824
|
+
return Array.isArray(groups) && groups.some((group) => JSON.stringify(group) === wanted);
|
|
35825
|
+
}
|
|
35826
|
+
function codexNotifyLine(command) {
|
|
35827
|
+
const argv = ["sh", "-c", `${command} "$1"`, "patron"];
|
|
35828
|
+
return `notify = [${argv.map((arg) => JSON.stringify(arg)).join(", ")}] ${CODEX_NOTIFY_MARKER}`;
|
|
35829
|
+
}
|
|
35830
|
+
function withCodexNotify(toml, command) {
|
|
35831
|
+
const lines = toml === "" ? [] : toml.split("\n");
|
|
35832
|
+
const line = codexNotifyLine(command);
|
|
35833
|
+
const index = topLevelNotify(lines);
|
|
35834
|
+
if (index === -1)
|
|
35835
|
+
return {
|
|
35836
|
+
state: "installed",
|
|
35837
|
+
text: lines.length === 0 ? `${line}
|
|
35838
|
+
` : [line, ...lines].join("\n")
|
|
35839
|
+
};
|
|
35840
|
+
const current = lines[index] ?? "";
|
|
35841
|
+
if (!current.includes(CODEX_NOTIFY_MARKER)) return { state: "taken", text: toml };
|
|
35842
|
+
if (current.trimEnd() === line) return { state: "unchanged", text: toml };
|
|
35843
|
+
return {
|
|
35844
|
+
state: "installed",
|
|
35845
|
+
text: lines.map((value, at) => at === index ? line : value).join("\n")
|
|
35846
|
+
};
|
|
35847
|
+
}
|
|
35848
|
+
function withoutCodexNotify(toml) {
|
|
35849
|
+
const lines = toml.split("\n");
|
|
35850
|
+
const index = topLevelNotify(lines);
|
|
35851
|
+
if (index === -1 || !lines[index]?.includes(CODEX_NOTIFY_MARKER)) return void 0;
|
|
35852
|
+
return lines.filter((_, at) => at !== index).join("\n");
|
|
35853
|
+
}
|
|
35854
|
+
function topLevelNotify(lines) {
|
|
35855
|
+
for (const [index, line] of lines.entries()) {
|
|
35856
|
+
if (/^\s*\[/.test(line)) return -1;
|
|
35857
|
+
if (/^\s*notify\s*=/.test(line)) return index;
|
|
35858
|
+
}
|
|
35859
|
+
return -1;
|
|
35860
|
+
}
|
|
35861
|
+
async function installCodex(paths, command, platform = process.platform) {
|
|
35862
|
+
const settings = await readJsonObject(paths.hooks);
|
|
35863
|
+
const hookChanged = !hasStopGroup(settings, command);
|
|
35864
|
+
if (hookChanged)
|
|
35865
|
+
await writeJsonObject(paths.hooks, withCodexStopHook(settings, command));
|
|
35866
|
+
let notify = "taken";
|
|
35867
|
+
if (platform !== "win32") {
|
|
35868
|
+
const toml = await readText(paths.config);
|
|
35869
|
+
const edit = withCodexNotify(toml, command);
|
|
35870
|
+
notify = edit.state;
|
|
35871
|
+
if (edit.state === "installed") await writeText(paths.config, edit.text);
|
|
35872
|
+
}
|
|
35873
|
+
const state = hookChanged || notify === "installed" ? "installed" : "unchanged";
|
|
35874
|
+
return notify === "taken" ? { note: "open /hooks in Codex and trust it to start paying", state } : { note: "trust it in /hooks when Codex asks", state };
|
|
35875
|
+
}
|
|
35876
|
+
async function upgradeCodex(paths) {
|
|
35877
|
+
const settings = await readJsonObject(paths.hooks);
|
|
35878
|
+
const next = withPatronStatus(settings, EVENT, CODEX_HOOK_STATUS);
|
|
35879
|
+
if (!next) return false;
|
|
35880
|
+
await writeJsonObject(paths.hooks, next);
|
|
35881
|
+
return true;
|
|
35882
|
+
}
|
|
35883
|
+
async function removeCodex(paths) {
|
|
35884
|
+
let removed = false;
|
|
35885
|
+
const settings = await readJsonObject(paths.hooks);
|
|
35886
|
+
if (hasPatronHandler(settings, EVENT)) {
|
|
35887
|
+
await writeJsonObject(paths.hooks, withoutPatronHandlers(settings, EVENT));
|
|
35888
|
+
removed = true;
|
|
35889
|
+
}
|
|
35890
|
+
const toml = await readText(paths.config);
|
|
35891
|
+
const without = withoutCodexNotify(toml);
|
|
35892
|
+
if (without !== void 0) {
|
|
35893
|
+
await writeText(paths.config, without);
|
|
35894
|
+
removed = true;
|
|
35895
|
+
}
|
|
35896
|
+
return removed ? "removed" : "missing";
|
|
35897
|
+
}
|
|
35898
|
+
async function readText(path) {
|
|
35899
|
+
try {
|
|
35900
|
+
return await readFile3(path, "utf8");
|
|
35901
|
+
} catch (error62) {
|
|
35902
|
+
if (error62.code === "ENOENT") return "";
|
|
35903
|
+
throw error62;
|
|
35904
|
+
}
|
|
35905
|
+
}
|
|
35906
|
+
async function writeText(path, text) {
|
|
35907
|
+
await mkdir2(dirname2(path), { recursive: true });
|
|
35908
|
+
await writePrivateFile(path, text);
|
|
35909
|
+
}
|
|
35910
|
+
|
|
35694
35911
|
export {
|
|
35695
35912
|
TOKEN_PRICE_UNITS,
|
|
35696
35913
|
PACK_SIZE,
|
|
@@ -35714,6 +35931,20 @@ export {
|
|
|
35714
35931
|
needsRefill,
|
|
35715
35932
|
parseUsd,
|
|
35716
35933
|
tipTokens,
|
|
35934
|
+
isObject2 as isObject,
|
|
35935
|
+
isPatronHandler,
|
|
35936
|
+
withoutPatronHandlers,
|
|
35937
|
+
withPatronGroup,
|
|
35938
|
+
hasPatronHandler,
|
|
35939
|
+
withHooksKey,
|
|
35940
|
+
readJsonObject,
|
|
35941
|
+
writeJsonObject,
|
|
35942
|
+
withPatronStatus,
|
|
35943
|
+
codexHome,
|
|
35944
|
+
codexPaths,
|
|
35945
|
+
installCodex,
|
|
35946
|
+
upgradeCodex,
|
|
35947
|
+
removeCodex,
|
|
35717
35948
|
loadIssuer,
|
|
35718
35949
|
resolveSettings,
|
|
35719
35950
|
settingsFor,
|
|
@@ -3,6 +3,7 @@ const require = __patronCreateRequire(import.meta.url)
|
|
|
3
3
|
import {
|
|
4
4
|
FileTokenStore,
|
|
5
5
|
clampTokensPerPage,
|
|
6
|
+
codexHome,
|
|
6
7
|
loadIssuer,
|
|
7
8
|
needsRefill,
|
|
8
9
|
normalizePayee,
|
|
@@ -11,17 +12,14 @@ import {
|
|
|
11
12
|
settingsFor,
|
|
12
13
|
spend,
|
|
13
14
|
startRefill
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import {
|
|
16
|
-
codexHome
|
|
17
|
-
} from "./chunk-E4XN5ZK6.js";
|
|
15
|
+
} from "./chunk-XUDTL3AP.js";
|
|
18
16
|
import {
|
|
19
17
|
readConfig,
|
|
20
18
|
readUsage,
|
|
21
19
|
updateUsage,
|
|
22
20
|
withLock,
|
|
23
21
|
writePrivateFile
|
|
24
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-A66D2RFJ.js";
|
|
25
23
|
|
|
26
24
|
// src/hook.ts
|
|
27
25
|
import { homedir } from "node:os";
|
|
@@ -2,7 +2,7 @@ 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-A66D2RFJ.js";
|
|
6
6
|
|
|
7
7
|
// src/wallet.ts
|
|
8
8
|
import { Store } from "accounts";
|
package/package.json
CHANGED
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import { createRequire as __patronCreateRequire } from 'node:module'
|
|
2
|
-
const require = __patronCreateRequire(import.meta.url)
|
|
3
|
-
import {
|
|
4
|
-
writePrivateFile
|
|
5
|
-
} from "./chunk-6TTNL3HT.js";
|
|
6
|
-
|
|
7
|
-
// src/codex.ts
|
|
8
|
-
import { mkdir as mkdir2, readFile as readFile2 } from "node:fs/promises";
|
|
9
|
-
import { dirname as dirname2, join } from "node:path";
|
|
10
|
-
|
|
11
|
-
// src/hook-files.ts
|
|
12
|
-
import { mkdir, readFile } from "node:fs/promises";
|
|
13
|
-
import { dirname } from "node:path";
|
|
14
|
-
function isObject(value) {
|
|
15
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16
|
-
}
|
|
17
|
-
function isPatronHandler(handler) {
|
|
18
|
-
if (!isObject(handler) || typeof handler.command !== "string") return false;
|
|
19
|
-
return /patron/i.test(handler.command) && /\shook\s*$/.test(handler.command);
|
|
20
|
-
}
|
|
21
|
-
function withoutPatronHandlers(settings, event) {
|
|
22
|
-
const groups = isObject(settings.hooks) ? settings.hooks[event] : void 0;
|
|
23
|
-
if (!isObject(settings.hooks) || !Array.isArray(groups)) return { ...settings };
|
|
24
|
-
let changed = false;
|
|
25
|
-
const kept = [];
|
|
26
|
-
for (const group of groups) {
|
|
27
|
-
if (!isObject(group) || !Array.isArray(group.hooks)) {
|
|
28
|
-
kept.push(group);
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
const handlers = group.hooks.filter((handler) => !isPatronHandler(handler));
|
|
32
|
-
if (handlers.length === group.hooks.length) kept.push(group);
|
|
33
|
-
else {
|
|
34
|
-
changed = true;
|
|
35
|
-
if (handlers.length > 0) kept.push({ ...group, hooks: handlers });
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if (!changed) return { ...settings };
|
|
39
|
-
return withHooksKey(settings, event, kept);
|
|
40
|
-
}
|
|
41
|
-
function withPatronGroup(settings, event, group) {
|
|
42
|
-
const next = withoutPatronHandlers(settings, event);
|
|
43
|
-
const hooks = isObject(next.hooks) ? next.hooks : {};
|
|
44
|
-
const groups = Array.isArray(hooks[event]) ? hooks[event] : [];
|
|
45
|
-
return withHooksKey(next, event, [...groups, group]);
|
|
46
|
-
}
|
|
47
|
-
function hasPatronHandler(settings, event, options = {}) {
|
|
48
|
-
const groups = isObject(settings.hooks) ? settings.hooks[event] : void 0;
|
|
49
|
-
if (!Array.isArray(groups)) return false;
|
|
50
|
-
return groups.some(
|
|
51
|
-
(group) => isObject(group) && (options.matcher === void 0 || group.matcher === options.matcher) && Array.isArray(group.hooks) && group.hooks.some(
|
|
52
|
-
(handler) => isPatronHandler(handler) && (options.command === void 0 || handler.command === options.command)
|
|
53
|
-
)
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
function withHooksKey(settings, event, entries) {
|
|
57
|
-
const hooks = isObject(settings.hooks) ? { ...settings.hooks } : {};
|
|
58
|
-
if (entries.length > 0) hooks[event] = entries;
|
|
59
|
-
else delete hooks[event];
|
|
60
|
-
const next = { ...settings };
|
|
61
|
-
if (Object.keys(hooks).length > 0) next.hooks = hooks;
|
|
62
|
-
else delete next.hooks;
|
|
63
|
-
return next;
|
|
64
|
-
}
|
|
65
|
-
async function readJsonObject(path) {
|
|
66
|
-
let text;
|
|
67
|
-
try {
|
|
68
|
-
text = await readFile(path, "utf8");
|
|
69
|
-
} catch (error) {
|
|
70
|
-
if (error.code === "ENOENT") return {};
|
|
71
|
-
throw error;
|
|
72
|
-
}
|
|
73
|
-
if (text.trim() === "") return {};
|
|
74
|
-
let value;
|
|
75
|
-
try {
|
|
76
|
-
value = JSON.parse(text);
|
|
77
|
-
} catch {
|
|
78
|
-
throw new Error(`${path} is not valid JSON; fix it, then rerun patron.`);
|
|
79
|
-
}
|
|
80
|
-
if (!isObject(value)) throw new Error(`${path} is not a JSON object; left unchanged.`);
|
|
81
|
-
return value;
|
|
82
|
-
}
|
|
83
|
-
async function writeJsonObject(path, value) {
|
|
84
|
-
await mkdir(dirname(path), { recursive: true });
|
|
85
|
-
await writePrivateFile(path, `${JSON.stringify(value, null, 2)}
|
|
86
|
-
`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// src/codex.ts
|
|
90
|
-
var CODEX_NOTIFY_MARKER = "# added by patron";
|
|
91
|
-
var HOOK_TIMEOUT_SECONDS = 10;
|
|
92
|
-
var EVENT = "Stop";
|
|
93
|
-
function codexHome(env, home) {
|
|
94
|
-
return env.CODEX_HOME || join(home, ".codex");
|
|
95
|
-
}
|
|
96
|
-
function codexPaths(env, home) {
|
|
97
|
-
const root = codexHome(env, home);
|
|
98
|
-
return { config: join(root, "config.toml"), hooks: join(root, "hooks.json") };
|
|
99
|
-
}
|
|
100
|
-
function withCodexStopHook(settings, command) {
|
|
101
|
-
return withPatronGroup(settings, EVENT, stopGroup(command));
|
|
102
|
-
}
|
|
103
|
-
var CODEX_HOOK_STATUS = "Patron: pay the sites this turn read";
|
|
104
|
-
function stopGroup(command) {
|
|
105
|
-
return {
|
|
106
|
-
hooks: [
|
|
107
|
-
{
|
|
108
|
-
command,
|
|
109
|
-
statusMessage: CODEX_HOOK_STATUS,
|
|
110
|
-
timeout: HOOK_TIMEOUT_SECONDS,
|
|
111
|
-
type: "command"
|
|
112
|
-
}
|
|
113
|
-
]
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
function hasStopGroup(settings, command) {
|
|
117
|
-
const groups = isObject(settings.hooks) ? settings.hooks[EVENT] : void 0;
|
|
118
|
-
const wanted = JSON.stringify(stopGroup(command));
|
|
119
|
-
return Array.isArray(groups) && groups.some((group) => JSON.stringify(group) === wanted);
|
|
120
|
-
}
|
|
121
|
-
function codexNotifyLine(command) {
|
|
122
|
-
const argv = ["sh", "-c", `${command} "$1"`, "patron"];
|
|
123
|
-
return `notify = [${argv.map((arg) => JSON.stringify(arg)).join(", ")}] ${CODEX_NOTIFY_MARKER}`;
|
|
124
|
-
}
|
|
125
|
-
function withCodexNotify(toml, command) {
|
|
126
|
-
const lines = toml === "" ? [] : toml.split("\n");
|
|
127
|
-
const line = codexNotifyLine(command);
|
|
128
|
-
const index = topLevelNotify(lines);
|
|
129
|
-
if (index === -1)
|
|
130
|
-
return {
|
|
131
|
-
state: "installed",
|
|
132
|
-
text: lines.length === 0 ? `${line}
|
|
133
|
-
` : [line, ...lines].join("\n")
|
|
134
|
-
};
|
|
135
|
-
const current = lines[index] ?? "";
|
|
136
|
-
if (!current.includes(CODEX_NOTIFY_MARKER)) return { state: "taken", text: toml };
|
|
137
|
-
if (current.trimEnd() === line) return { state: "unchanged", text: toml };
|
|
138
|
-
return {
|
|
139
|
-
state: "installed",
|
|
140
|
-
text: lines.map((value, at) => at === index ? line : value).join("\n")
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
function withoutCodexNotify(toml) {
|
|
144
|
-
const lines = toml.split("\n");
|
|
145
|
-
const index = topLevelNotify(lines);
|
|
146
|
-
if (index === -1 || !lines[index]?.includes(CODEX_NOTIFY_MARKER)) return void 0;
|
|
147
|
-
return lines.filter((_, at) => at !== index).join("\n");
|
|
148
|
-
}
|
|
149
|
-
function topLevelNotify(lines) {
|
|
150
|
-
for (const [index, line] of lines.entries()) {
|
|
151
|
-
if (/^\s*\[/.test(line)) return -1;
|
|
152
|
-
if (/^\s*notify\s*=/.test(line)) return index;
|
|
153
|
-
}
|
|
154
|
-
return -1;
|
|
155
|
-
}
|
|
156
|
-
async function installCodex(paths, command, platform = process.platform) {
|
|
157
|
-
const settings = await readJsonObject(paths.hooks);
|
|
158
|
-
const hookChanged = !hasStopGroup(settings, command);
|
|
159
|
-
if (hookChanged)
|
|
160
|
-
await writeJsonObject(paths.hooks, withCodexStopHook(settings, command));
|
|
161
|
-
let notify = "taken";
|
|
162
|
-
if (platform !== "win32") {
|
|
163
|
-
const toml = await readText(paths.config);
|
|
164
|
-
const edit = withCodexNotify(toml, command);
|
|
165
|
-
notify = edit.state;
|
|
166
|
-
if (edit.state === "installed") await writeText(paths.config, edit.text);
|
|
167
|
-
}
|
|
168
|
-
const state = hookChanged || notify === "installed" ? "installed" : "unchanged";
|
|
169
|
-
return notify === "taken" ? { note: "open /hooks in Codex and trust it to start paying", state } : { note: "trust it in /hooks when Codex asks", state };
|
|
170
|
-
}
|
|
171
|
-
async function upgradeCodex(paths) {
|
|
172
|
-
const settings = await readJsonObject(paths.hooks);
|
|
173
|
-
const groups = isObject(settings.hooks) ? settings.hooks[EVENT] : void 0;
|
|
174
|
-
const handler = (Array.isArray(groups) ? groups : []).flatMap(
|
|
175
|
-
(group) => isObject(group) && Array.isArray(group.hooks) ? group.hooks : []
|
|
176
|
-
).find(isPatronHandler);
|
|
177
|
-
const command = typeof handler?.command === "string" ? handler.command : void 0;
|
|
178
|
-
if (!command || hasStopGroup(settings, command)) return false;
|
|
179
|
-
await writeJsonObject(paths.hooks, withCodexStopHook(settings, command));
|
|
180
|
-
return true;
|
|
181
|
-
}
|
|
182
|
-
async function removeCodex(paths) {
|
|
183
|
-
let removed = false;
|
|
184
|
-
const settings = await readJsonObject(paths.hooks);
|
|
185
|
-
if (hasPatronHandler(settings, EVENT)) {
|
|
186
|
-
await writeJsonObject(paths.hooks, withoutPatronHandlers(settings, EVENT));
|
|
187
|
-
removed = true;
|
|
188
|
-
}
|
|
189
|
-
const toml = await readText(paths.config);
|
|
190
|
-
const without = withoutCodexNotify(toml);
|
|
191
|
-
if (without !== void 0) {
|
|
192
|
-
await writeText(paths.config, without);
|
|
193
|
-
removed = true;
|
|
194
|
-
}
|
|
195
|
-
return removed ? "removed" : "missing";
|
|
196
|
-
}
|
|
197
|
-
async function readText(path) {
|
|
198
|
-
try {
|
|
199
|
-
return await readFile2(path, "utf8");
|
|
200
|
-
} catch (error) {
|
|
201
|
-
if (error.code === "ENOENT") return "";
|
|
202
|
-
throw error;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
async function writeText(path, text) {
|
|
206
|
-
await mkdir2(dirname2(path), { recursive: true });
|
|
207
|
-
await writePrivateFile(path, text);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
export {
|
|
211
|
-
isObject,
|
|
212
|
-
isPatronHandler,
|
|
213
|
-
withoutPatronHandlers,
|
|
214
|
-
withPatronGroup,
|
|
215
|
-
hasPatronHandler,
|
|
216
|
-
withHooksKey,
|
|
217
|
-
readJsonObject,
|
|
218
|
-
writeJsonObject,
|
|
219
|
-
CODEX_NOTIFY_MARKER,
|
|
220
|
-
codexHome,
|
|
221
|
-
codexPaths,
|
|
222
|
-
withCodexStopHook,
|
|
223
|
-
CODEX_HOOK_STATUS,
|
|
224
|
-
codexNotifyLine,
|
|
225
|
-
withCodexNotify,
|
|
226
|
-
withoutCodexNotify,
|
|
227
|
-
installCodex,
|
|
228
|
-
upgradeCodex,
|
|
229
|
-
removeCodex
|
|
230
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { createRequire as __patronCreateRequire } from 'node:module'
|
|
2
|
-
const require = __patronCreateRequire(import.meta.url)
|
|
3
|
-
import {
|
|
4
|
-
CODEX_HOOK_STATUS,
|
|
5
|
-
CODEX_NOTIFY_MARKER,
|
|
6
|
-
codexHome,
|
|
7
|
-
codexNotifyLine,
|
|
8
|
-
codexPaths,
|
|
9
|
-
installCodex,
|
|
10
|
-
removeCodex,
|
|
11
|
-
upgradeCodex,
|
|
12
|
-
withCodexNotify,
|
|
13
|
-
withCodexStopHook,
|
|
14
|
-
withoutCodexNotify
|
|
15
|
-
} from "./chunk-E4XN5ZK6.js";
|
|
16
|
-
import "./chunk-6TTNL3HT.js";
|
|
17
|
-
export {
|
|
18
|
-
CODEX_HOOK_STATUS,
|
|
19
|
-
CODEX_NOTIFY_MARKER,
|
|
20
|
-
codexHome,
|
|
21
|
-
codexNotifyLine,
|
|
22
|
-
codexPaths,
|
|
23
|
-
installCodex,
|
|
24
|
-
removeCodex,
|
|
25
|
-
upgradeCodex,
|
|
26
|
-
withCodexNotify,
|
|
27
|
-
withCodexStopHook,
|
|
28
|
-
withoutCodexNotify
|
|
29
|
-
};
|