@spendctl/core 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/LICENSE +83 -0
  2. package/README.md +13 -2
  3. package/THIRD_PARTY_NOTICES +54 -0
  4. package/dist/approvals.d.ts +30 -0
  5. package/dist/approvals.d.ts.map +1 -0
  6. package/dist/approvals.js +114 -0
  7. package/dist/approvals.js.map +1 -0
  8. package/dist/config.d.ts +234 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +250 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/duration.d.ts +4 -0
  13. package/dist/duration.d.ts.map +1 -0
  14. package/dist/duration.js +32 -0
  15. package/dist/duration.js.map +1 -0
  16. package/dist/engine.d.ts +42 -0
  17. package/dist/engine.d.ts.map +1 -0
  18. package/dist/engine.js +164 -0
  19. package/dist/engine.js.map +1 -0
  20. package/dist/export.d.ts +38 -0
  21. package/dist/export.d.ts.map +1 -0
  22. package/dist/export.js +103 -0
  23. package/dist/export.js.map +1 -0
  24. package/dist/i18n/en.d.ts +4 -0
  25. package/dist/i18n/en.d.ts.map +1 -0
  26. package/dist/i18n/en.js +29 -0
  27. package/dist/i18n/en.js.map +1 -0
  28. package/dist/i18n/index.d.ts +5 -0
  29. package/dist/i18n/index.d.ts.map +1 -0
  30. package/dist/i18n/index.js +24 -0
  31. package/dist/i18n/index.js.map +1 -0
  32. package/dist/ids.d.ts +5 -0
  33. package/dist/ids.d.ts.map +1 -0
  34. package/dist/ids.js +18 -0
  35. package/dist/ids.js.map +1 -0
  36. package/dist/index.d.ts +13 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +13 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/ledger/ledger.d.ts +51 -0
  41. package/dist/ledger/ledger.d.ts.map +1 -0
  42. package/dist/ledger/ledger.js +331 -0
  43. package/dist/ledger/ledger.js.map +1 -0
  44. package/dist/ledger/sqlite.d.ts +18 -0
  45. package/dist/ledger/sqlite.d.ts.map +1 -0
  46. package/dist/ledger/sqlite.js +44 -0
  47. package/dist/ledger/sqlite.js.map +1 -0
  48. package/dist/match.d.ts +21 -0
  49. package/dist/match.d.ts.map +1 -0
  50. package/dist/match.js +52 -0
  51. package/dist/match.js.map +1 -0
  52. package/dist/money.d.ts +20 -0
  53. package/dist/money.d.ts.map +1 -0
  54. package/dist/money.js +69 -0
  55. package/dist/money.js.map +1 -0
  56. package/dist/trace.d.ts +15 -0
  57. package/dist/trace.d.ts.map +1 -0
  58. package/dist/trace.js +52 -0
  59. package/dist/trace.js.map +1 -0
  60. package/dist/types.d.ts +112 -0
  61. package/dist/types.d.ts.map +1 -0
  62. package/dist/types.js +2 -0
  63. package/dist/types.js.map +1 -0
  64. package/package.json +26 -3
package/LICENSE ADDED
@@ -0,0 +1,83 @@
1
+ spendctl Proprietary Software License
2
+
3
+ Copyright (c) 2026 Mirai Studio, Inc. (株式会社みらいスタジオ), Tokyo, Japan.
4
+ All rights reserved.
5
+
6
+ This software and its documentation (the "Software") are licensed, not sold.
7
+ By installing or running the Software you agree to these terms. If you do not
8
+ agree, do not install or run it.
9
+
10
+ 1. Grant. Subject to these terms and to the spendctl Terms of Service
11
+ (https://spendctl.dev/terms), Mirai Studio grants you a non-exclusive,
12
+ non-transferable, non-sublicensable, revocable licence to install and run
13
+ the Software, in the form distributed by Mirai Studio (for example through
14
+ the npm registry or a container image), on systems you control, solely to
15
+ use the spendctl service within the limits of your plan.
16
+
17
+ 2. Restrictions. Except as expressly permitted by Mirai Studio in writing or
18
+ by applicable law notwithstanding this restriction, you may not:
19
+ (a) copy, modify, translate, adapt or create derivative works of the
20
+ Software;
21
+ (b) distribute, publish, sublicense, sell, rent, lease, lend or otherwise
22
+ make the Software available to third parties;
23
+ (c) reverse engineer, decompile, disassemble or otherwise attempt to derive
24
+ the source code of the Software;
25
+ (d) remove, obscure or alter any proprietary notice in the Software;
26
+ (e) circumvent or disable licence keys, plan limits, usage metering or
27
+ security measures in the Software;
28
+ (f) use the Software to build or train a product that competes with
29
+ spendctl.
30
+
31
+ 3. Third-party components. The Software incorporates third-party components
32
+ under their own licences. Their notices are provided with the distributed
33
+ package (THIRD_PARTY_NOTICES). Nothing in this licence limits your rights
34
+ under those licences. The spendctl client SDKs are separately licensed
35
+ under the Apache License 2.0 (https://github.com/miraistudio/spendctl-sdk).
36
+
37
+ 4. Ownership. The Software is protected by copyright and other laws. Mirai
38
+ Studio and its licensors retain all right, title and interest in the
39
+ Software. No rights are granted except those expressly stated here.
40
+
41
+ 5. Your data and keys. The Software signs payments with a wallet you control
42
+ and keeps its ledger on systems you control. The Software may send
43
+ licence-validation and billing metadata to Mirai Studio as described in
44
+ the documentation; it does not send private keys, signed payment
45
+ authorizations, request bodies or response bodies to Mirai Studio.
46
+
47
+ 6. Feedback. If you send suggestions about the Software, Mirai Studio may use
48
+ them without obligation to you.
49
+
50
+ 7. Term and termination. This licence remains in effect until terminated. It
51
+ terminates automatically if you breach these terms or if your plan ends.
52
+ On termination you must stop using and delete the Software. Sections 2,
53
+ 4, 8, 9 and 10 survive termination.
54
+
55
+ 8. Disclaimer of warranty. THE SOFTWARE IS PROVIDED "AS IS" AND "AS AVAILABLE"
56
+ WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING WARRANTIES OF
57
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
58
+ NON-INFRINGEMENT. Spend policies are a safeguard, not a guarantee: Mirai
59
+ Studio does not warrant that the Software will prevent every unauthorised,
60
+ unintended or erroneous payment, that sellers or facilitators will behave
61
+ correctly, or that any blockchain or payment network will be available.
62
+ You remain responsible for the policies you configure and for the wallets
63
+ you connect.
64
+
65
+ 9. Limitation of liability. TO THE MAXIMUM EXTENT PERMITTED BY LAW, MIRAI
66
+ STUDIO SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
67
+ CONSEQUENTIAL OR PUNITIVE DAMAGES, OR FOR ANY LOSS OF FUNDS, PROFITS, DATA
68
+ OR GOODWILL, ARISING OUT OF OR RELATED TO THE SOFTWARE, EVEN IF ADVISED OF
69
+ THE POSSIBILITY. MIRAI STUDIO'S TOTAL LIABILITY UNDER THIS LICENCE SHALL
70
+ NOT EXCEED THE AMOUNT YOU PAID FOR THE SPENDCTL SERVICE IN THE TWELVE
71
+ MONTHS BEFORE THE CLAIM. Nothing here limits liability that cannot be
72
+ limited under applicable law.
73
+
74
+ 10. Governing law. This licence is governed by the laws of Japan. The Tokyo
75
+ District Court has exclusive jurisdiction in the first instance over any
76
+ dispute arising from it.
77
+
78
+ 11. Export and sanctions. You may not use the Software in violation of
79
+ applicable export-control or sanctions laws.
80
+
81
+ 12. Entire agreement. This licence and the Terms of Service are the entire
82
+ agreement about the Software. If any provision is unenforceable, the rest
83
+ remains in effect.
package/README.md CHANGED
@@ -1,3 +1,14 @@
1
- # Temporary Holding Version
1
+ # @spendctl/core
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Policy engine, budget ledger and approval broker behind [spendctl](https://spendctl.dev).
4
+
5
+ ```ts
6
+ import { parseConfigText, evaluate, Ledger } from "@spendctl/core";
7
+ ```
8
+
9
+ - `parseConfigText` / `loadConfig`: validate `spendctl.yaml` (zod) into a normalised policy.
10
+ - `evaluate`: pure decision function — allow / deny / approve with reasons an LLM can read.
11
+ - `Ledger`: SQLite ledger on `node:sqlite` or `bun:sqlite` (no native addon) with `BEGIN IMMEDIATE` budget reservations, CSV/JSON export.
12
+ - `ApprovalBroker`: persisted approvals with wait/decide/expire.
13
+
14
+ Proprietary — see LICENSE. Part of the spendctl sidecar; docs at https://spendctl.dev/docs/.
@@ -0,0 +1,54 @@
1
+ THIRD-PARTY NOTICES for @spendctl/core@0.1.0
2
+
3
+ @spendctl/core is proprietary software of Mirai Studio, Inc. It depends on the open-source packages listed below, which are distributed under their own licences. This file reproduces those licences and any NOTICE files, as the licences require. Generated 2026-10-25 from the production dependency tree.
4
+
5
+ ==============================================================================
6
+ 1. PACKAGES
7
+ ==============================================================================
8
+
9
+ yaml@2.9.1 — ISC — Eemeli Aro — https://eemeli.org/yaml/
10
+ zod@4.6.7 — MIT — Colin McDonnell — https://zod.dev
11
+
12
+ ==============================================================================
13
+ 2. LICENSE TEXTS
14
+ ==============================================================================
15
+
16
+ --- Applies to: yaml@2.9.1 ---
17
+
18
+ Copyright Eemeli Aro <eemeli@gmail.com>
19
+
20
+ Permission to use, copy, modify, and/or distribute this software for any purpose
21
+ with or without fee is hereby granted, provided that the above copyright notice
22
+ and this permission notice appear in all copies.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
25
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
26
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
27
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
28
+ OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
29
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
30
+ THIS SOFTWARE.
31
+
32
+ --- Applies to: zod@4.6.7 ---
33
+
34
+ MIT License
35
+
36
+ Copyright (c) 2025 Colin McDonnell
37
+
38
+ Permission is hereby granted, free of charge, to any person obtaining a copy
39
+ of this software and associated documentation files (the "Software"), to deal
40
+ in the Software without restriction, including without limitation the rights
41
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
42
+ copies of the Software, and to permit persons to whom the Software is
43
+ furnished to do so, subject to the following conditions:
44
+
45
+ The above copyright notice and this permission notice shall be included in all
46
+ copies or substantial portions of the Software.
47
+
48
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
51
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
54
+ SOFTWARE.
@@ -0,0 +1,30 @@
1
+ import type { Ledger } from "./ledger/ledger.js";
2
+ import type { Approval, ApprovalStatus, Attempt, Reason } from "./types.js";
3
+ export interface ApprovalBrokerOptions {
4
+ timeoutMs: number;
5
+ /** Called once when an approval is created (webhooks, logs). Errors are swallowed. */
6
+ notify?: (approval: Approval, attempt: Attempt) => Promise<void> | void;
7
+ }
8
+ /**
9
+ * Creates approval requests, lets a human decide them, and wakes up any
10
+ * request that is waiting. Decisions are persisted in the ledger first, so a
11
+ * restart never loses an approval.
12
+ */
13
+ export declare class ApprovalBroker {
14
+ private readonly ledger;
15
+ private readonly options;
16
+ private readonly waiters;
17
+ constructor(ledger: Ledger, options: ApprovalBrokerOptions);
18
+ create(attempt: Attempt, reasons: Reason[]): Approval;
19
+ /**
20
+ * Resolves when the approval is decided or expires (whichever comes first). With `timeoutMs` it
21
+ * also resolves — with the still-pending approval — once that long has passed, and with `signal`
22
+ * it resolves the same way as soon as the signal aborts (the requester went away).
23
+ */
24
+ wait(id: string, timeoutMs?: number, signal?: AbortSignal): Promise<Approval>;
25
+ decide(id: string, status: Exclude<ApprovalStatus, "pending">, by: string, note?: string): Approval | undefined;
26
+ pending(): Approval[];
27
+ /** Marks pending approvals past their deadline as expired. */
28
+ expireStale(now?: number): Approval[];
29
+ }
30
+ //# sourceMappingURL=approvals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAI5E,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACzE;AAED;;;;GAIG;AACH,qBAAa,cAAc;IAIvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAE1D,YACmB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,EAC7C;IAEJ,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,QAAQ,CAmBpD;IAED;;;;OAIG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAgD5E;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,cAAc,EAAE,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAO9G;IAED,OAAO,IAAI,QAAQ,EAAE,CAEpB;IAED,8DAA8D;IAC9D,WAAW,CAAC,GAAG,SAAa,GAAG,QAAQ,EAAE,CASxC;CACF"}
@@ -0,0 +1,114 @@
1
+ import { newId } from "./ids.js";
2
+ /**
3
+ * Creates approval requests, lets a human decide them, and wakes up any
4
+ * request that is waiting. Decisions are persisted in the ledger first, so a
5
+ * restart never loses an approval.
6
+ */
7
+ export class ApprovalBroker {
8
+ ledger;
9
+ options;
10
+ waiters = new Map();
11
+ constructor(ledger, options) {
12
+ this.ledger = ledger;
13
+ this.options = options;
14
+ }
15
+ create(attempt, reasons) {
16
+ const now = Date.now();
17
+ const approval = {
18
+ id: newId("apr"),
19
+ attemptId: attempt.id,
20
+ agent: attempt.agent,
21
+ createdAt: now,
22
+ expiresAt: now + this.options.timeoutMs,
23
+ status: "pending",
24
+ usdMicros: attempt.usdMicros,
25
+ host: attempt.host,
26
+ path: attempt.path,
27
+ reasons,
28
+ };
29
+ this.ledger.insertApproval(approval);
30
+ if (this.options.notify) {
31
+ Promise.resolve(this.options.notify(approval, attempt)).catch(() => undefined);
32
+ }
33
+ return approval;
34
+ }
35
+ /**
36
+ * Resolves when the approval is decided or expires (whichever comes first). With `timeoutMs` it
37
+ * also resolves — with the still-pending approval — once that long has passed, and with `signal`
38
+ * it resolves the same way as soon as the signal aborts (the requester went away).
39
+ */
40
+ wait(id, timeoutMs, signal) {
41
+ const current = this.ledger.getApproval(id);
42
+ if (!current)
43
+ return Promise.reject(new Error(`Unknown approval ${id}`));
44
+ if (current.status !== "pending" || signal?.aborted)
45
+ return Promise.resolve(current);
46
+ // Wall-clock deadline: the approval's own expiry, or the caller's shorter timeout.
47
+ const deadline = Math.min(current.expiresAt, timeoutMs === undefined ? Number.POSITIVE_INFINITY : Date.now() + timeoutMs);
48
+ return new Promise((resolve) => {
49
+ let timer;
50
+ const settle = (approval) => {
51
+ clearTimeout(timer);
52
+ signal?.removeEventListener("abort", onAbort);
53
+ this.waiters.get(id)?.delete(waiter);
54
+ resolve(approval);
55
+ };
56
+ const waiter = (approval) => settle(approval);
57
+ const onAbort = () => settle(this.ledger.getApproval(id) ?? current);
58
+ const onTimer = () => {
59
+ const latest = this.ledger.getApproval(id);
60
+ if (latest?.status !== "pending") {
61
+ settle(latest ?? current);
62
+ return;
63
+ }
64
+ // Node timers run on a monotonic clock that can be a few milliseconds behind Date.now(),
65
+ // so the timer may fire before the wall-clock deadline. Re-arm instead of returning a
66
+ // still-pending approval, which the caller would otherwise read as a denial.
67
+ const left = deadline - Date.now();
68
+ if (left > 0) {
69
+ timer = setTimeout(onTimer, left);
70
+ return;
71
+ }
72
+ if (Date.now() >= latest.expiresAt) {
73
+ settle(this.decide(id, "expired", "timeout") ?? latest);
74
+ }
75
+ else {
76
+ settle(latest); // the caller's own timeout elapsed; the approval is still open
77
+ }
78
+ };
79
+ timer = setTimeout(onTimer, Math.max(0, deadline - Date.now()));
80
+ signal?.addEventListener("abort", onAbort, { once: true });
81
+ let set = this.waiters.get(id);
82
+ if (!set) {
83
+ set = new Set();
84
+ this.waiters.set(id, set);
85
+ }
86
+ set.add(waiter);
87
+ });
88
+ }
89
+ decide(id, status, by, note) {
90
+ const approval = this.ledger.decideApproval(id, status, by, note);
91
+ if (approval && approval.status !== "pending") {
92
+ for (const waiter of [...(this.waiters.get(id) ?? [])])
93
+ waiter(approval);
94
+ this.waiters.delete(id);
95
+ }
96
+ return approval;
97
+ }
98
+ pending() {
99
+ return this.ledger.listApprovals("pending");
100
+ }
101
+ /** Marks pending approvals past their deadline as expired. */
102
+ expireStale(now = Date.now()) {
103
+ const expired = [];
104
+ for (const approval of this.pending()) {
105
+ if (approval.expiresAt <= now) {
106
+ const decided = this.decide(approval.id, "expired", "timeout");
107
+ if (decided)
108
+ expired.push(decided);
109
+ }
110
+ }
111
+ return expired;
112
+ }
113
+ }
114
+ //# sourceMappingURL=approvals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvals.js","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,234 @@
1
+ import { z } from "zod";
2
+ export declare const agentPolicySchema: z.ZodObject<{
3
+ description: z.ZodOptional<z.ZodString>;
4
+ mode: z.ZodOptional<z.ZodEnum<{
5
+ "dry-run": "dry-run";
6
+ enforce: "enforce";
7
+ }>>;
8
+ budget: z.ZodOptional<z.ZodObject<{
9
+ perRequest: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
10
+ hourly: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
11
+ daily: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
12
+ weekly: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
13
+ monthly: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
14
+ }, z.core.$strict>>;
15
+ onBudgetExceeded: z.ZodOptional<z.ZodEnum<{
16
+ approve: "approve";
17
+ deny: "deny";
18
+ }>>;
19
+ requireApprovalAbove: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
20
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
21
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
22
+ payTo: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
23
+ protocols: z.ZodOptional<z.ZodArray<z.ZodEnum<{
24
+ mpp: "mpp";
25
+ x402: "x402";
26
+ }>>>;
27
+ networks: z.ZodOptional<z.ZodArray<z.ZodString>>;
28
+ assets: z.ZodOptional<z.ZodArray<z.ZodString>>;
29
+ maxChainDepth: z.ZodOptional<z.ZodNumber>;
30
+ firstPaymentMax: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
31
+ priceJumpFactor: z.ZodOptional<z.ZodNumber>;
32
+ maxTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
33
+ }, z.core.$strict>;
34
+ export declare const configSchema: z.ZodObject<{
35
+ version: z.ZodLiteral<1>;
36
+ server: z.ZodDefault<z.ZodObject<{
37
+ host: z.ZodDefault<z.ZodString>;
38
+ port: z.ZodDefault<z.ZodNumber>;
39
+ connect: z.ZodDefault<z.ZodEnum<{
40
+ deny: "deny";
41
+ tunnel: "tunnel";
42
+ }>>;
43
+ upstreamTimeout: z.ZodDefault<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
44
+ }, z.core.$strict>>;
45
+ signer: z.ZodDefault<z.ZodDiscriminatedUnion<[z.ZodObject<{
46
+ type: z.ZodLiteral<"mock">;
47
+ }, z.core.$strict>, z.ZodObject<{
48
+ type: z.ZodLiteral<"cdp">;
49
+ accountName: z.ZodOptional<z.ZodString>;
50
+ }, z.core.$strict>, z.ZodObject<{
51
+ type: z.ZodLiteral<"private-key">;
52
+ env: z.ZodOptional<z.ZodString>;
53
+ }, z.core.$strict>], "type">>;
54
+ agentAuth: z.ZodDefault<z.ZodEnum<{
55
+ header: "header";
56
+ token: "token";
57
+ }>>;
58
+ defaultAgent: z.ZodOptional<z.ZodString>;
59
+ defaults: z.ZodDefault<z.ZodObject<{
60
+ description: z.ZodOptional<z.ZodString>;
61
+ mode: z.ZodOptional<z.ZodEnum<{
62
+ "dry-run": "dry-run";
63
+ enforce: "enforce";
64
+ }>>;
65
+ budget: z.ZodOptional<z.ZodObject<{
66
+ perRequest: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
67
+ hourly: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
68
+ daily: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
69
+ weekly: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
70
+ monthly: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
71
+ }, z.core.$strict>>;
72
+ onBudgetExceeded: z.ZodOptional<z.ZodEnum<{
73
+ approve: "approve";
74
+ deny: "deny";
75
+ }>>;
76
+ requireApprovalAbove: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
77
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
78
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
79
+ payTo: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
80
+ protocols: z.ZodOptional<z.ZodArray<z.ZodEnum<{
81
+ mpp: "mpp";
82
+ x402: "x402";
83
+ }>>>;
84
+ networks: z.ZodOptional<z.ZodArray<z.ZodString>>;
85
+ assets: z.ZodOptional<z.ZodArray<z.ZodString>>;
86
+ maxChainDepth: z.ZodOptional<z.ZodNumber>;
87
+ firstPaymentMax: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
88
+ priceJumpFactor: z.ZodOptional<z.ZodNumber>;
89
+ maxTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
90
+ }, z.core.$strict>>;
91
+ agents: z.ZodRecord<z.ZodString, z.ZodObject<{
92
+ description: z.ZodOptional<z.ZodString>;
93
+ mode: z.ZodOptional<z.ZodEnum<{
94
+ "dry-run": "dry-run";
95
+ enforce: "enforce";
96
+ }>>;
97
+ budget: z.ZodOptional<z.ZodObject<{
98
+ perRequest: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
99
+ hourly: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
100
+ daily: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
101
+ weekly: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
102
+ monthly: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
103
+ }, z.core.$strict>>;
104
+ onBudgetExceeded: z.ZodOptional<z.ZodEnum<{
105
+ approve: "approve";
106
+ deny: "deny";
107
+ }>>;
108
+ requireApprovalAbove: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
109
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
110
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
111
+ payTo: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
112
+ protocols: z.ZodOptional<z.ZodArray<z.ZodEnum<{
113
+ mpp: "mpp";
114
+ x402: "x402";
115
+ }>>>;
116
+ networks: z.ZodOptional<z.ZodArray<z.ZodString>>;
117
+ assets: z.ZodOptional<z.ZodArray<z.ZodString>>;
118
+ maxChainDepth: z.ZodOptional<z.ZodNumber>;
119
+ firstPaymentMax: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
120
+ priceJumpFactor: z.ZodOptional<z.ZodNumber>;
121
+ maxTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
122
+ }, z.core.$strict>>;
123
+ approvals: z.ZodDefault<z.ZodObject<{
124
+ timeout: z.ZodDefault<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
125
+ onTimeout: z.ZodDefault<z.ZodEnum<{
126
+ deny: "deny";
127
+ }>>;
128
+ hold: z.ZodDefault<z.ZodBoolean>;
129
+ holdMax: z.ZodDefault<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
130
+ webhooks: z.ZodDefault<z.ZodArray<z.ZodObject<{
131
+ url: z.ZodString;
132
+ format: z.ZodDefault<z.ZodEnum<{
133
+ discord: "discord";
134
+ json: "json";
135
+ slack: "slack";
136
+ }>>;
137
+ secretEnv: z.ZodOptional<z.ZodString>;
138
+ }, z.core.$strict>>>;
139
+ publicUrl: z.ZodOptional<z.ZodString>;
140
+ }, z.core.$strict>>;
141
+ circuitBreaker: z.ZodDefault<z.ZodObject<{
142
+ failures: z.ZodDefault<z.ZodNumber>;
143
+ cooldown: z.ZodDefault<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
144
+ }, z.core.$strict>>;
145
+ assets: z.ZodDefault<z.ZodArray<z.ZodObject<{
146
+ network: z.ZodString;
147
+ asset: z.ZodString;
148
+ symbol: z.ZodString;
149
+ decimals: z.ZodNumber;
150
+ usdPegged: z.ZodDefault<z.ZodBoolean>;
151
+ }, z.core.$strict>>>;
152
+ ledger: z.ZodDefault<z.ZodObject<{
153
+ path: z.ZodDefault<z.ZodString>;
154
+ }, z.core.$strict>>;
155
+ idempotencyWindow: z.ZodDefault<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
156
+ }, z.core.$strict>;
157
+ export type RawConfig = z.input<typeof configSchema>;
158
+ export type ParsedConfig = z.output<typeof configSchema>;
159
+ export type RawAgentPolicy = z.input<typeof agentPolicySchema>;
160
+ export interface Budget {
161
+ perRequest?: bigint;
162
+ hourly?: bigint;
163
+ daily?: bigint;
164
+ weekly?: bigint;
165
+ monthly?: bigint;
166
+ }
167
+ export interface AgentPolicy {
168
+ name: string;
169
+ description?: string;
170
+ mode: "enforce" | "dry-run";
171
+ budget: Budget;
172
+ onBudgetExceeded: "deny" | "approve";
173
+ requireApprovalAbove?: bigint;
174
+ allow?: string[];
175
+ deny: string[];
176
+ payTo: Record<string, string[]>;
177
+ protocols?: string[];
178
+ networks?: string[];
179
+ assets?: string[];
180
+ maxChainDepth?: number;
181
+ firstPaymentMax?: bigint;
182
+ priceJumpFactor?: number;
183
+ maxTimeoutSeconds: number;
184
+ }
185
+ export interface WebhookConfig {
186
+ url: string;
187
+ format: "json" | "slack" | "discord";
188
+ secretEnv?: string;
189
+ }
190
+ export type SignerConfig = ParsedConfig["signer"];
191
+ export interface AssetConfig {
192
+ network: string;
193
+ asset: string;
194
+ symbol: string;
195
+ decimals: number;
196
+ usdPegged: boolean;
197
+ }
198
+ export interface Config {
199
+ server: {
200
+ host: string;
201
+ port: number;
202
+ connect: "tunnel" | "deny";
203
+ upstreamTimeoutMs: number;
204
+ };
205
+ signer: SignerConfig;
206
+ agentAuth: "header" | "token";
207
+ defaultAgent?: string;
208
+ agents: Record<string, AgentPolicy>;
209
+ approvals: {
210
+ timeoutMs: number;
211
+ onTimeout: "deny";
212
+ hold: boolean;
213
+ holdMaxMs: number;
214
+ webhooks: WebhookConfig[];
215
+ publicUrl?: string;
216
+ };
217
+ circuitBreaker: {
218
+ failures: number;
219
+ cooldownMs: number;
220
+ };
221
+ assets: AssetConfig[];
222
+ ledger: {
223
+ path: string;
224
+ };
225
+ idempotencyWindowMs: number;
226
+ }
227
+ export declare class ConfigError extends Error {
228
+ constructor(message: string);
229
+ }
230
+ /** Validates and normalises a raw config object (e.g. parsed YAML). */
231
+ export declare function resolveConfig(raw: unknown): Config;
232
+ export declare function parseConfigText(text: string): Config;
233
+ export declare function loadConfig(path: string): Config;
234
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}