@claudexor/budget 3.0.3 → 3.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.
- package/LICENSE +1 -1
- package/dist/router.d.ts +35 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +165 -19
- package/dist/router.js.map +1 -1
- package/package.json +3 -3
package/LICENSE
CHANGED
package/dist/router.d.ts
CHANGED
|
@@ -1,11 +1,36 @@
|
|
|
1
|
-
import type { BillingKnowledge, CredentialRoute, EffortHint, Intent, PaidFallback, QualityTierSet, RoutingGoal } from "@claudexor/schema";
|
|
1
|
+
import type { AuthVerification, BillingKnowledge, CredentialRoute, EffortHint, Intent, PaidFallback, QualityTierSet, RouteRankingRationale, RoutingGoal } from "@claudexor/schema";
|
|
2
2
|
import type { BudgetLedger } from "./ledger.js";
|
|
3
|
+
/**
|
|
4
|
+
* The typed auth-route evidence a route ran (or would run) under — the doctor's
|
|
5
|
+
* `auth_sources` verification for the credential source plus the concrete
|
|
6
|
+
* `credential_route` receipt. This is the ONLY sanctioned source of billing
|
|
7
|
+
* knowledge (INV-060 / schema `auth.ts`: a credential transport alone never
|
|
8
|
+
* proves entitlement or zero cost, but a VERIFIED native/subscription route is
|
|
9
|
+
* a subscription-entitlement fact). No per-vendor price table is inferred.
|
|
10
|
+
*/
|
|
11
|
+
export interface RouteAuthEvidence {
|
|
12
|
+
route: CredentialRoute | null;
|
|
13
|
+
verification: AuthVerification;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Billing knowledge derived STRICTLY from the typed auth route (QA-034). A
|
|
17
|
+
* verified vendor-native route proves `subscription_entitlement`; a managed
|
|
18
|
+
* API-key route is `metered` and is NEVER presumed free; every other route
|
|
19
|
+
* (unverified native, credential-free local, unknown) stays `unknown`. This is
|
|
20
|
+
* the missing production producer the schema/router already knew how to consume.
|
|
21
|
+
*/
|
|
22
|
+
export declare function billingKnowledgeForAuthRoute(evidence: RouteAuthEvidence): BillingKnowledge;
|
|
3
23
|
export interface RouterCandidate {
|
|
4
24
|
harnessId: string;
|
|
5
25
|
available: boolean;
|
|
6
26
|
model?: string;
|
|
7
27
|
effort?: EffortHint;
|
|
8
28
|
billingKnowledge?: BillingKnowledge;
|
|
29
|
+
/** Typed auth-route evidence. When present it is AUTHORITATIVE for billing
|
|
30
|
+
* knowledge (derived via billingKnowledgeForAuthRoute), so a verified native
|
|
31
|
+
* route survives paid_fallback:never and ranks with a real economy tuple.
|
|
32
|
+
* Falls back to the explicit billingKnowledge (else unknown) when absent. */
|
|
33
|
+
authRoute?: RouteAuthEvidence;
|
|
9
34
|
incrementalCostUsd?: number | null;
|
|
10
35
|
credentialRoute?: CredentialRoute;
|
|
11
36
|
/** Effective credential subject for quota filtering (release wave round-16
|
|
@@ -27,4 +52,13 @@ export declare class RoutingPreflightError extends Error {
|
|
|
27
52
|
/** Order candidates transparently; lower tuple values win. Unknown quota remains eligible. */
|
|
28
53
|
export declare function rankHarnesses(candidates: RouterCandidate[], ctx: RouteContext): RouterCandidate[];
|
|
29
54
|
export declare function selectHarness(candidates: RouterCandidate[], ctx: RouteContext): RouterCandidate | null;
|
|
55
|
+
/**
|
|
56
|
+
* Explain a ranking as a typed record (QA-034): the per-candidate billing/cost
|
|
57
|
+
* tuple, the eligible/dropped split, and the DECISIVE reason. Kept axis-aligned
|
|
58
|
+
* with rankHarnesses so the recorded rationale can never disagree with the
|
|
59
|
+
* order actually taken. Prose-free; a surface projects it, never reconstructs it.
|
|
60
|
+
* The shape is the schema-owned RouteRankingRationale (snake_case) so it can be
|
|
61
|
+
* persisted verbatim as RunTelemetry.routing_rationale.
|
|
62
|
+
*/
|
|
63
|
+
export declare function explainRanking(candidates: RouterCandidate[], ctx: RouteContext): RouteRankingRationale;
|
|
30
64
|
//# sourceMappingURL=router.d.ts.map
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,MAAM,EACN,YAAY,EACZ,cAAc,
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,MAAM,EACN,YAAY,EACZ,cAAc,EAEd,qBAAqB,EAErB,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,gBAAgB,CAAC;CAChC;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,iBAAiB,GAAG,gBAAgB,CAM1F;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;iFAG6E;IAC7E,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;;qEAGiE;IACjE,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,cAAc,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,+BAA+B;CAC7C;AA6FD,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,YAAY,GAAG,eAAe,EAAE,CAuBjG;AAED,wBAAgB,aAAa,CAC3B,UAAU,EAAE,eAAe,EAAE,EAC7B,GAAG,EAAE,YAAY,GAChB,eAAe,GAAG,IAAI,CAExB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,eAAe,EAAE,EAC7B,GAAG,EAAE,YAAY,GAChB,qBAAqB,CAavB"}
|
package/dist/router.js
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Billing knowledge derived STRICTLY from the typed auth route (QA-034). A
|
|
3
|
+
* verified vendor-native route proves `subscription_entitlement`; a managed
|
|
4
|
+
* API-key route is `metered` and is NEVER presumed free; every other route
|
|
5
|
+
* (unverified native, credential-free local, unknown) stays `unknown`. This is
|
|
6
|
+
* the missing production producer the schema/router already knew how to consume.
|
|
7
|
+
*/
|
|
8
|
+
export function billingKnowledgeForAuthRoute(evidence) {
|
|
9
|
+
if (evidence.route === "managed_api_key")
|
|
10
|
+
return "metered";
|
|
11
|
+
if (evidence.route === "vendor_native" && evidence.verification === "passed") {
|
|
12
|
+
return "subscription_entitlement";
|
|
13
|
+
}
|
|
14
|
+
return "unknown";
|
|
15
|
+
}
|
|
1
16
|
export class RoutingPreflightError extends Error {
|
|
2
17
|
code = "routing_preflight_refused";
|
|
3
18
|
}
|
|
@@ -8,8 +23,15 @@ function tierIndex(candidate, ctx) {
|
|
|
8
23
|
route.effort === candidate.effort));
|
|
9
24
|
return index < 0 ? null : index;
|
|
10
25
|
}
|
|
26
|
+
/** Effective billing knowledge: the typed auth route is authoritative when
|
|
27
|
+
* present (QA-034), else the explicitly supplied value, else unknown. */
|
|
28
|
+
function effectiveBilling(candidate) {
|
|
29
|
+
if (candidate.authRoute)
|
|
30
|
+
return billingKnowledgeForAuthRoute(candidate.authRoute);
|
|
31
|
+
return candidate.billingKnowledge ?? "unknown";
|
|
32
|
+
}
|
|
11
33
|
function isIncrementalPaid(candidate) {
|
|
12
|
-
return !["proven_zero", "subscription_entitlement"].includes(candidate
|
|
34
|
+
return !["proven_zero", "subscription_entitlement"].includes(effectiveBilling(candidate));
|
|
13
35
|
}
|
|
14
36
|
function eligible(candidates, ctx) {
|
|
15
37
|
const ready = candidates.filter((candidate) => candidate.available &&
|
|
@@ -21,36 +43,160 @@ function eligible(candidates, ctx) {
|
|
|
21
43
|
return free;
|
|
22
44
|
return ready;
|
|
23
45
|
}
|
|
46
|
+
/** User-declared tier index the comparators order by (missing => MAX). Shared
|
|
47
|
+
* by the sort and the traced comparator so a "tier" claim is never re-derived. */
|
|
48
|
+
function tierValueOf(candidate, ctx) {
|
|
49
|
+
return tierIndex(candidate, ctx) ?? Number.MAX_SAFE_INTEGER;
|
|
50
|
+
}
|
|
51
|
+
/** Binding pace slack the `auto` comparator orders by; null = none observed. */
|
|
52
|
+
function autoSlack(candidate, ctx) {
|
|
53
|
+
return ctx.ledger.bindingPaceSlack(candidate.harnessId, candidate.credentialRoute, candidate.credentialSubjectId);
|
|
54
|
+
}
|
|
55
|
+
/** null slack collapses to this so a slack-carrying candidate always outranks a
|
|
56
|
+
* slack-less one, exactly as the comparator subtraction does. */
|
|
57
|
+
const AUTO_SLACK_ABSENT = Number.NEGATIVE_INFINITY;
|
|
58
|
+
/**
|
|
59
|
+
* The SINGLE traced comparator for `auto` (round-4 #3 — this rationale has been
|
|
60
|
+
* wrong three times). It returns both the pair ORDER and the AXIS that produced
|
|
61
|
+
* it, and is the only place the auto ordering is defined. `rankHarnesses` sorts
|
|
62
|
+
* by `.order`; `rankingReason` reads `.axis`. Deriving the recorded reason from
|
|
63
|
+
* the very comparator that ordered the pool makes it structurally impossible for
|
|
64
|
+
* the rationale to claim a factor the sort did not use (the axis-registry
|
|
65
|
+
* pattern used in arbitration, specialized to auto's conditional slack axis).
|
|
66
|
+
*
|
|
67
|
+
* The slack axis is in force whenever EITHER candidate has a non-null slack; the
|
|
68
|
+
* subtraction of the (null => -Infinity) effective values is what decides — so
|
|
69
|
+
* two EQUAL non-null slacks yield order 0 and a null axis (declared order, and
|
|
70
|
+
* the sort does NOT fall through to tiers). Only when BOTH slacks are absent
|
|
71
|
+
* does the comparator compare tier indices.
|
|
72
|
+
*/
|
|
73
|
+
function compareAutoTraced(a, b, ctx) {
|
|
74
|
+
const aSlack = autoSlack(a, ctx);
|
|
75
|
+
const bSlack = autoSlack(b, ctx);
|
|
76
|
+
if (aSlack !== null || bSlack !== null) {
|
|
77
|
+
const order = (bSlack ?? AUTO_SLACK_ABSENT) - (aSlack ?? AUTO_SLACK_ABSENT);
|
|
78
|
+
return { order, axis: order !== 0 ? "expiring_quota_slack" : null };
|
|
79
|
+
}
|
|
80
|
+
const order = tierValueOf(a, ctx) - tierValueOf(b, ctx);
|
|
81
|
+
return { order, axis: order !== 0 ? "quality_tier" : null };
|
|
82
|
+
}
|
|
24
83
|
/** Order candidates transparently; lower tuple values win. Unknown quota remains eligible. */
|
|
25
84
|
export function rankHarnesses(candidates, ctx) {
|
|
26
85
|
const routes = eligible(candidates, ctx);
|
|
27
86
|
if (ctx.goal === "quality" && routes.every((candidate) => tierIndex(candidate, ctx) === null)) {
|
|
28
87
|
throw new RoutingPreflightError(`quality routing requires a comparable user-declared tier for intent '${ctx.intent}'`);
|
|
29
88
|
}
|
|
89
|
+
if (ctx.goal === "auto") {
|
|
90
|
+
return routes.toSorted((a, b) => compareAutoTraced(a, b, ctx).order);
|
|
91
|
+
}
|
|
30
92
|
return routes.toSorted((a, b) => {
|
|
31
|
-
const aTier =
|
|
32
|
-
const bTier =
|
|
93
|
+
const aTier = tierValueOf(a, ctx);
|
|
94
|
+
const bTier = tierValueOf(b, ctx);
|
|
33
95
|
if (ctx.goal === "quality")
|
|
34
96
|
return aTier - bTier;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
const aSlack = ctx.ledger.bindingPaceSlack(a.harnessId, a.credentialRoute, a.credentialSubjectId);
|
|
46
|
-
const bSlack = ctx.ledger.bindingPaceSlack(b.harnessId, b.credentialRoute, b.credentialSubjectId);
|
|
47
|
-
if (aSlack !== null || bSlack !== null) {
|
|
48
|
-
return (bSlack ?? Number.NEGATIVE_INFINITY) - (aSlack ?? Number.NEGATIVE_INFINITY);
|
|
49
|
-
}
|
|
50
|
-
return aTier - bTier;
|
|
97
|
+
// economy
|
|
98
|
+
const aPaid = isIncrementalPaid(a) ? 1 : 0;
|
|
99
|
+
const bPaid = isIncrementalPaid(b) ? 1 : 0;
|
|
100
|
+
const paidOrder = aPaid - bPaid;
|
|
101
|
+
if (paidOrder !== 0)
|
|
102
|
+
return paidOrder;
|
|
103
|
+
const aCost = a.incrementalCostUsd ?? Number.POSITIVE_INFINITY;
|
|
104
|
+
const bCost = b.incrementalCostUsd ?? Number.POSITIVE_INFINITY;
|
|
105
|
+
return aCost - bCost || aTier - bTier;
|
|
51
106
|
});
|
|
52
107
|
}
|
|
53
108
|
export function selectHarness(candidates, ctx) {
|
|
54
109
|
return rankHarnesses(candidates, ctx)[0] ?? null;
|
|
55
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Explain a ranking as a typed record (QA-034): the per-candidate billing/cost
|
|
113
|
+
* tuple, the eligible/dropped split, and the DECISIVE reason. Kept axis-aligned
|
|
114
|
+
* with rankHarnesses so the recorded rationale can never disagree with the
|
|
115
|
+
* order actually taken. Prose-free; a surface projects it, never reconstructs it.
|
|
116
|
+
* The shape is the schema-owned RouteRankingRationale (snake_case) so it can be
|
|
117
|
+
* persisted verbatim as RunTelemetry.routing_rationale.
|
|
118
|
+
*/
|
|
119
|
+
export function explainRanking(candidates, ctx) {
|
|
120
|
+
const rankedCandidates = rankHarnesses(candidates, ctx);
|
|
121
|
+
const order = rankedCandidates.map((c) => c.harnessId);
|
|
122
|
+
const eligibleIds = new Set(order);
|
|
123
|
+
const entries = candidates.map((c) => ({
|
|
124
|
+
harness_id: c.harnessId,
|
|
125
|
+
billing_knowledge: effectiveBilling(c),
|
|
126
|
+
incremental_cost_usd: c.incrementalCostUsd ?? null,
|
|
127
|
+
eligible: eligibleIds.has(c.harnessId),
|
|
128
|
+
}));
|
|
129
|
+
const dropped = candidates.filter((c) => !eligibleIds.has(c.harnessId)).map((c) => c.harnessId);
|
|
130
|
+
const reason = rankingReason(ctx, rankedCandidates, candidates);
|
|
131
|
+
return { goal: ctx.goal, paid_fallback: ctx.paidFallback, order, dropped, reason, entries };
|
|
132
|
+
}
|
|
133
|
+
/** Do the ranked candidates carry two distinct user-declared tier indices? Only
|
|
134
|
+
* then did the tier comparator (the auto/economy tie-break) actually decide the
|
|
135
|
+
* order; a single candidate or a uniform tier index leaves the declared order. */
|
|
136
|
+
function tiersDistinguish(ranked, ctx) {
|
|
137
|
+
const indices = ranked.map((c) => tierIndex(c, ctx) ?? Number.MAX_SAFE_INTEGER);
|
|
138
|
+
return indices.some((value) => value !== indices[0]);
|
|
139
|
+
}
|
|
140
|
+
/** Do the ranked candidates carry two distinct incremental costs (with the SAME
|
|
141
|
+
* missing-cost fallback the economy sort uses)? Only then did the cost
|
|
142
|
+
* comparator — not the paid/free split above it or the tier tie-break below —
|
|
143
|
+
* actually decide the order. */
|
|
144
|
+
function costsDistinguish(ranked) {
|
|
145
|
+
const costs = ranked.map((c) => c.incrementalCostUsd ?? Number.POSITIVE_INFINITY);
|
|
146
|
+
return costs.some((value) => value !== costs[0]);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* The DECISIVE comparator axis. For `auto` the reason is read directly off the
|
|
150
|
+
* SAME traced comparator that ordered the pool (`compareAutoTraced`) — never
|
|
151
|
+
* re-derived from a separately-recomputed condition (round-4 #3, the third
|
|
152
|
+
* recurrence of a rationale that disagreed with `rankHarnesses`): the reason is
|
|
153
|
+
* whichever axis actually separated an adjacent ranked pair, and `declared_order`
|
|
154
|
+
* when the comparator broke no pair (e.g. equal non-null slacks — which do NOT
|
|
155
|
+
* fall through to tiers).
|
|
156
|
+
*/
|
|
157
|
+
function rankingReason(ctx, ranked, candidates) {
|
|
158
|
+
if (ctx.goal === "quality")
|
|
159
|
+
return "quality_tier";
|
|
160
|
+
if (ctx.goal === "auto") {
|
|
161
|
+
// Walk the ranked order through the very comparator that produced it. Since
|
|
162
|
+
// the pool is sorted, any two distinct axis values leave a differing
|
|
163
|
+
// adjacent pair, so this sees every axis the sort actually used.
|
|
164
|
+
const axes = new Set();
|
|
165
|
+
for (let i = 0; i + 1 < ranked.length; i++) {
|
|
166
|
+
const traced = compareAutoTraced(ranked[i], ranked[i + 1], ctx);
|
|
167
|
+
if (traced.axis)
|
|
168
|
+
axes.add(traced.axis);
|
|
169
|
+
}
|
|
170
|
+
if (axes.has("expiring_quota_slack"))
|
|
171
|
+
return "expiring_quota_slack";
|
|
172
|
+
if (axes.has("quality_tier"))
|
|
173
|
+
return "quality_tier";
|
|
174
|
+
return "declared_order";
|
|
175
|
+
}
|
|
176
|
+
// economy: mirror the economy sort tuple EXACTLY — (isIncrementalPaid,
|
|
177
|
+
// incrementalCostUsd, tierIndex) — and report the FIRST axis that actually
|
|
178
|
+
// SEPARATED the pool. Reporting entitlement whenever ANY route is entitled was
|
|
179
|
+
// wrong when they are ALL entitled and cost/tier did the deciding (the same
|
|
180
|
+
// correction made for `auto` in 1d6a2a50).
|
|
181
|
+
const someEntitled = ranked.some((c) => !isIncrementalPaid(c));
|
|
182
|
+
// Entitlement decided when the pool actually WEIGHED an entitled route against
|
|
183
|
+
// a paid one — whether the paid route was ranked BELOW (sort axis 1) or DROPPED
|
|
184
|
+
// by paid_fallback (both are the entitled-preferred-over-paid outcome). When
|
|
185
|
+
// every route CONSIDERED is entitled, entitlement did not decide — cost/tier
|
|
186
|
+
// did (the round-3 correction; matches the pool-wide `auto` mirror in
|
|
187
|
+
// 1d6a2a50). The full candidate set (not just the eligible pool) is consulted
|
|
188
|
+
// so a paid route dropped by paid_fallback:never still attributes the outcome.
|
|
189
|
+
const anyPaidConsidered = candidates.some((c) => isIncrementalPaid(c));
|
|
190
|
+
if (someEntitled && anyPaidConsidered)
|
|
191
|
+
return "subscription_entitlement_first";
|
|
192
|
+
if (costsDistinguish(ranked))
|
|
193
|
+
return "lowest_incremental_cash";
|
|
194
|
+
if (tiersDistinguish(ranked, ctx))
|
|
195
|
+
return "quality_tier";
|
|
196
|
+
// Nothing separated the pool: distinguish "we could not compare cash at all"
|
|
197
|
+
// from a genuine declared-order tie.
|
|
198
|
+
if (ranked.length > 0 && ranked.some((c) => c.incrementalCostUsd == null))
|
|
199
|
+
return "all_incremental_cash_unknown";
|
|
200
|
+
return "declared_order";
|
|
201
|
+
}
|
|
56
202
|
//# sourceMappingURL=router.js.map
|
package/dist/router.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claudexor/budget",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Budget governor: pre-call leases, circuit breaker, evidence-based routing goals, and multi-window quota pacing.",
|
|
6
6
|
"type": "module",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@claudexor/
|
|
20
|
-
"@claudexor/
|
|
19
|
+
"@claudexor/util": "3.1.0",
|
|
20
|
+
"@claudexor/schema": "3.1.0"
|
|
21
21
|
},
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|