@hachej/boring-core 0.1.41 → 0.1.43
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/README.md +28 -279
- package/dist/PostgresMeteringStore-CzNv6xil.d.ts +224 -0
- package/dist/app/front/index.d.ts +212 -3
- package/dist/app/front/index.js +820 -44
- package/dist/app/server/index.d.ts +3 -3
- package/dist/app/server/index.js +13 -6
- package/dist/{authHook-DUqyxueY.d.ts → authHook-CzBsMwwM.d.ts} +2 -2
- package/dist/{chunk-C3YMOITB.js → chunk-I56OTSPB.js} +649 -6
- package/dist/{chunk-H5KU6R6Y.js → chunk-LIBHVT7V.js} +5 -1
- package/dist/{chunk-GZVKZD4P.js → chunk-UM5SHYIS.js} +11 -2
- package/dist/{chunk-WYTCJ5WL.js → chunk-VYXEXOCO.js} +69 -26
- package/dist/{connection-AL8KSENV.d.ts → connection-C5SiqoNc.d.ts} +1 -1
- package/dist/front/index.d.ts +15 -2
- package/dist/front/index.js +2 -2
- package/dist/server/db/index.d.ts +4 -4
- package/dist/server/db/index.js +6 -2
- package/dist/server/index.d.ts +594 -7
- package/dist/server/index.js +1467 -4
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/{types-CbMOXLBf.d.ts → types-CWtJ4kgd.d.ts} +3 -0
- package/drizzle/0011_usage_metering.sql +57 -0
- package/drizzle/0012_credit_purchases.sql +9 -0
- package/drizzle/0013_credit_purchase_lifecycle.sql +28 -0
- package/drizzle/0014_reservation_charge_on_expire.sql +7 -0
- package/drizzle/meta/_journal.json +28 -0
- package/package.json +4 -4
- package/dist/migrate-B4dwdtGP.d.ts +0 -8
|
@@ -10,16 +10,28 @@ interface ChatFirstPublicShellOptions {
|
|
|
10
10
|
eyebrow?: string;
|
|
11
11
|
title?: string;
|
|
12
12
|
description?: string;
|
|
13
|
+
footer?: ReactNode;
|
|
13
14
|
};
|
|
14
15
|
suggestions?: ChatSuggestion[];
|
|
16
|
+
/**
|
|
17
|
+
* Hand-drawn "Your agent" / "Your remote computer" annotations point at the
|
|
18
|
+
* composer and the workspace surface to teach the empty public shell. Apps
|
|
19
|
+
* that open a center panel on load (e.g. a landing page) should disable them,
|
|
20
|
+
* otherwise the fixed-position arrows overlay the open panel. Defaults to on.
|
|
21
|
+
*/
|
|
22
|
+
showTeachingArrows?: boolean;
|
|
15
23
|
}
|
|
16
24
|
|
|
17
25
|
type ChatEntryMode = 'auth-first' | 'chat-first';
|
|
18
|
-
|
|
26
|
+
type RoutedWorkspaceAgentProps<TSession extends WorkspaceAgentSession = WorkspaceAgentSession> = Omit<WorkspaceAgentFrontProps<TSession>, 'workspaceId' | 'frontPluginHotReload' | 'hotReloadEnabled'>;
|
|
27
|
+
interface CoreWorkspaceAgentFrontProps<TSession extends WorkspaceAgentSession = WorkspaceAgentSession> extends RoutedWorkspaceAgentProps<TSession> {
|
|
19
28
|
/** Core consumes plugins statically for now; app-level hot reload is explicitly unsupported. */
|
|
20
29
|
hotReload?: false;
|
|
21
30
|
chatEntryMode?: ChatEntryMode;
|
|
22
31
|
chatFirstPublicShell?: ChatFirstPublicShellOptions;
|
|
32
|
+
/** Extra workspace props used only by the unauthenticated chat-first public shell. */
|
|
33
|
+
chatFirstPublicWorkspaceProps?: Partial<RoutedWorkspaceAgentProps<TSession>>;
|
|
34
|
+
publicPaths?: string[];
|
|
23
35
|
authPages?: CoreFrontAuthPagesOverride;
|
|
24
36
|
cspNonce?: string;
|
|
25
37
|
children?: ReactNode;
|
|
@@ -29,6 +41,203 @@ interface CoreWorkspaceAgentFrontProps<TSession extends WorkspaceAgentSession =
|
|
|
29
41
|
loadingFallback?: ReactNode;
|
|
30
42
|
bootPreloadPaths?: string[];
|
|
31
43
|
}
|
|
32
|
-
|
|
44
|
+
/** Default top-bar right content. Exported so apps can compose extra widgets
|
|
45
|
+
* (e.g. a credit balance badge) alongside the user menu. */
|
|
46
|
+
declare function DefaultTopBarRight(): react_jsx_runtime.JSX.Element;
|
|
47
|
+
declare function CoreWorkspaceAgentFront<TSession extends WorkspaceAgentSession = WorkspaceAgentSession>({ authPages, cspNonce, children, workspaceRoute, workspaceIdParam, workspaceHref, loadingFallback, bootPreloadPaths, topBarLeft, topBarRight, appTitle, bridgeEndpoint, hotReload, chatEntryMode, chatFirstPublicShell, chatFirstPublicWorkspaceProps, publicPaths, ...workspaceProps }: CoreWorkspaceAgentFrontProps<TSession>): react_jsx_runtime.JSX.Element;
|
|
33
48
|
|
|
34
|
-
|
|
49
|
+
interface CreditBalanceBadgeProps {
|
|
50
|
+
/** Base URL for the credits API (default: same origin). */
|
|
51
|
+
apiBaseUrl?: string;
|
|
52
|
+
/** Fallback enable for the add-credits action. The server's `checkoutEnabled`
|
|
53
|
+
* (from /api/credits/balance) takes precedence when present. */
|
|
54
|
+
buyEnabled?: boolean;
|
|
55
|
+
/** Poll interval for the balance, ms (default 30s). */
|
|
56
|
+
pollMs?: number;
|
|
57
|
+
locale?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Top-bar credit balance: a DISCRETE remaining-balance figure plus a small "+" button.
|
|
61
|
+
* Clicking "+" opens a popover of fixed top-up amounts (Anthropic-style); picking one starts
|
|
62
|
+
* the server-created checkout and opens it. Polls `/api/credits/balance`; hides itself when
|
|
63
|
+
* credits are disabled or the user is unauthenticated.
|
|
64
|
+
*/
|
|
65
|
+
declare function CreditBalanceBadge({ apiBaseUrl, buyEnabled, pollMs, locale, }: CreditBalanceBadgeProps): react_jsx_runtime.JSX.Element | null;
|
|
66
|
+
|
|
67
|
+
interface CreditsSettingsPanelProps {
|
|
68
|
+
/** Base URL for the credits API (default: same origin). */
|
|
69
|
+
apiBaseUrl?: string;
|
|
70
|
+
locale?: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Account-settings "Billing & credits" panel: current balance (+ debt/low notices,
|
|
74
|
+
* staleness), a pack picker → checkout, and a lazy-loaded recent-activity list.
|
|
75
|
+
* Renders nothing when credits are disabled or the user is unauthenticated.
|
|
76
|
+
*/
|
|
77
|
+
declare function CreditsSettingsPanel({ apiBaseUrl, locale }: CreditsSettingsPanelProps): react_jsx_runtime.JSX.Element | null;
|
|
78
|
+
|
|
79
|
+
/** Front-end helpers for the credit balance badge + buy-credits flow. */
|
|
80
|
+
/** Display-ready credit pack (server-authored). The client never infers price from
|
|
81
|
+
* the id and never sees the provider's price/variant id. */
|
|
82
|
+
interface CreditPack {
|
|
83
|
+
id: string;
|
|
84
|
+
creditMicros: number;
|
|
85
|
+
/** Price in the currency's minor unit (e.g. cents). For a custom pack, the MINIMUM. */
|
|
86
|
+
priceMinor: number;
|
|
87
|
+
currency: string;
|
|
88
|
+
label: string;
|
|
89
|
+
isDefault: boolean;
|
|
90
|
+
/** Pay-what-you-want pack: the buyer enters the amount on the hosted checkout, so
|
|
91
|
+
* `creditMicros` is 0 here and `priceMinor` is the minimum. The picker shows an
|
|
92
|
+
* "enter amount" option instead of a fixed price. */
|
|
93
|
+
custom?: boolean;
|
|
94
|
+
}
|
|
95
|
+
interface CreditBalanceResponse {
|
|
96
|
+
enabled: boolean;
|
|
97
|
+
userId: string;
|
|
98
|
+
grantedMicros: number;
|
|
99
|
+
usedMicros: number;
|
|
100
|
+
remainingMicros: number;
|
|
101
|
+
activeReservedMicros: number;
|
|
102
|
+
availableMicros: number;
|
|
103
|
+
/** Amount owed when the ledger went negative (e.g. refund of spent credits). */
|
|
104
|
+
debtMicros: number;
|
|
105
|
+
/** Server truth: whether the Buy-credits checkout is wired (avoids client drift). */
|
|
106
|
+
checkoutEnabled?: boolean;
|
|
107
|
+
/** Display-ready packs (present only when checkout is wired). */
|
|
108
|
+
packs?: CreditPack[];
|
|
109
|
+
currency: 'credits';
|
|
110
|
+
}
|
|
111
|
+
type CreditLedgerKind = 'grant' | 'purchase' | 'usage' | 'refund' | 'fallback';
|
|
112
|
+
/** One credit-activity row (mirrors the server `CreditLedgerEntry`). `amountMicros`
|
|
113
|
+
* is signed: positive = added, negative = consumed/removed. */
|
|
114
|
+
interface CreditLedgerEntry {
|
|
115
|
+
id: string;
|
|
116
|
+
kind: CreditLedgerKind;
|
|
117
|
+
amountMicros: number;
|
|
118
|
+
createdAt: string;
|
|
119
|
+
description: string;
|
|
120
|
+
}
|
|
121
|
+
/** Format SIGNED credit micros as a euro string with an explicit +/− sign. */
|
|
122
|
+
declare function formatSignedCreditMicros(micros: number, locale?: string): string;
|
|
123
|
+
/** Format a minor-unit price (e.g. cents) in its currency for pack labels/buttons. */
|
|
124
|
+
declare function formatMinorPrice(priceMinor: number, currency: string, locale?: string): string;
|
|
125
|
+
/** Format credit micros as a euro string. 1 credit = €0.000001 ⇒ µ/1e6 euros. */
|
|
126
|
+
declare function formatCreditMicros(micros: number, locale?: string): string;
|
|
127
|
+
/** True when the remaining balance is at or below the low-balance threshold. */
|
|
128
|
+
declare function isLowBalance(micros: number, thresholdMicros?: number): boolean;
|
|
129
|
+
/** Stable server error code for an out-of-credits rejection (mirrors the agent's
|
|
130
|
+
* ErrorCode enum). Kept here so the credits feature owns the credit↔code mapping
|
|
131
|
+
* and the agent stays billing-agnostic. */
|
|
132
|
+
declare const PAYMENT_REQUIRED_ERROR_CODE = "PAYMENT_REQUIRED";
|
|
133
|
+
/** True when a run-rejected notice was an out-of-credits rejection. Hosts use this
|
|
134
|
+
* in renderNoticeAction to decide whether to show the Buy-credits CTA. */
|
|
135
|
+
declare function isPaymentRequiredNotice(notice: {
|
|
136
|
+
errorCode?: string;
|
|
137
|
+
}): boolean;
|
|
138
|
+
|
|
139
|
+
/** Window event other code can dispatch to force an immediate balance refetch —
|
|
140
|
+
* e.g. the chat dispatching `window.dispatchEvent(new Event(CREDITS_REFRESH_EVENT))`
|
|
141
|
+
* when a run finishes, so the balance updates without waiting for the poll. */
|
|
142
|
+
declare const CREDITS_REFRESH_EVENT = "credits:refresh";
|
|
143
|
+
interface UseCreditBalanceOptions {
|
|
144
|
+
/** Base URL for the credits API (default: same origin). */
|
|
145
|
+
apiBaseUrl?: string;
|
|
146
|
+
/** Poll interval for the balance, ms (default 30s). */
|
|
147
|
+
pollMs?: number;
|
|
148
|
+
/** Credit pack id to purchase (server maps it to a Lemon Squeezy variant). */
|
|
149
|
+
pack?: string;
|
|
150
|
+
}
|
|
151
|
+
interface UseCreditBalanceResult {
|
|
152
|
+
/** Latest balance, or null before the first successful load. */
|
|
153
|
+
balance: CreditBalanceResponse | null;
|
|
154
|
+
/** True when credits are disabled or the user is unauthenticated (UI should hide). */
|
|
155
|
+
hidden: boolean;
|
|
156
|
+
/** Set when a balance fetch failed (network/server) before a successful load; null
|
|
157
|
+
* otherwise. Lets a consumer show an error state rather than an endless spinner. */
|
|
158
|
+
error: string | null;
|
|
159
|
+
/** Refetch the balance now. */
|
|
160
|
+
refresh: () => Promise<void>;
|
|
161
|
+
/** Refetch now, then a short backoff burst (~15s) — credit writes settle
|
|
162
|
+
* asynchronously after a run/purchase, so a single refetch can read a stale value.
|
|
163
|
+
* Concurrent bursts are deduped (a new call restarts the window). */
|
|
164
|
+
refreshWithRetry: () => void;
|
|
165
|
+
/** Start a Lemon Squeezy checkout (server creates it, sets the buyer id from the
|
|
166
|
+
* session) and open it in a new tab. Resolves to an error message on failure.
|
|
167
|
+
* Pass a pack id to buy a specific pack. */
|
|
168
|
+
buy: (pack?: string) => Promise<string | null>;
|
|
169
|
+
/** True while a checkout request is in flight. */
|
|
170
|
+
buying: boolean;
|
|
171
|
+
/** Epoch ms of the last successful balance read (null before first load). */
|
|
172
|
+
lastUpdatedAt: number | null;
|
|
173
|
+
/** True while a refresh (incl. a retry burst) is in flight. */
|
|
174
|
+
updating: boolean;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Shared credit-balance state for the top-bar badge and the settings panel:
|
|
178
|
+
* polls `/api/credits/balance`, refetches on window focus and on the
|
|
179
|
+
* `credits:refresh` event, and exposes a server-side checkout action. The buyer
|
|
180
|
+
* id is set SERVER-side (POST /api/credits/checkout) so the client never supplies it.
|
|
181
|
+
*/
|
|
182
|
+
declare function useCreditBalance({ apiBaseUrl, pollMs, pack, }?: UseCreditBalanceOptions): UseCreditBalanceResult;
|
|
183
|
+
|
|
184
|
+
interface UseCreditHistoryResult {
|
|
185
|
+
entries: CreditLedgerEntry[] | null;
|
|
186
|
+
loading: boolean;
|
|
187
|
+
error: boolean;
|
|
188
|
+
/** Fetch (or refetch) the activity. Call lazily, e.g. when the section expands. */
|
|
189
|
+
load: () => Promise<void>;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Lazy loader for the account credit-activity list (`GET /api/credits/history`).
|
|
193
|
+
* Does NOT fetch on mount — call `load()` when the section is opened. `entries` is
|
|
194
|
+
* null until the first load; `[]` means "no activity yet".
|
|
195
|
+
*/
|
|
196
|
+
declare function useCreditHistory(apiBaseUrl?: string, limit?: number): UseCreditHistoryResult;
|
|
197
|
+
|
|
198
|
+
type CheckoutReturnStatus = 'idle' | 'checking' | 'confirmed' | 'processing' | 'cancelled';
|
|
199
|
+
interface UseCheckoutReturnHandlerOptions {
|
|
200
|
+
apiBaseUrl?: string;
|
|
201
|
+
/** Query param name the LS redirect uses (default 'checkout'). */
|
|
202
|
+
param?: string;
|
|
203
|
+
}
|
|
204
|
+
interface UseCheckoutReturnHandlerResult {
|
|
205
|
+
status: CheckoutReturnStatus;
|
|
206
|
+
dismiss: () => void;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Handle the return from a Lemon Squeezy hosted checkout. The URL marker (`?checkout=
|
|
210
|
+
* return|success|cancelled`) is NOT treated as proof of payment — on a return we poll
|
|
211
|
+
* the AUTHENTICATED balance and only show success once it actually increases (credits
|
|
212
|
+
* settle asynchronously via the webhook). The marker is stripped immediately so a reload
|
|
213
|
+
* can't replay it, and a `credits:refresh` event + BroadcastChannel signal refresh any
|
|
214
|
+
* other open app tab. Returns the status for a small banner to render.
|
|
215
|
+
*/
|
|
216
|
+
declare function useCheckoutReturnHandler({ apiBaseUrl, param }?: UseCheckoutReturnHandlerOptions): UseCheckoutReturnHandlerResult;
|
|
217
|
+
|
|
218
|
+
interface CheckoutReturnBannerProps {
|
|
219
|
+
apiBaseUrl?: string;
|
|
220
|
+
/** Query param the LS redirect uses (default 'checkout'). */
|
|
221
|
+
param?: string;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Renders the post-checkout return state (see useCheckoutReturnHandler). Mount it once
|
|
225
|
+
* near the app root. It NEVER claims success from the URL — only after the server
|
|
226
|
+
* balance actually increases. ARIA-live so the status is announced. Self-hides when idle.
|
|
227
|
+
*/
|
|
228
|
+
declare function CheckoutReturnBanner({ apiBaseUrl, param }: CheckoutReturnBannerProps): react_jsx_runtime.JSX.Element | null;
|
|
229
|
+
|
|
230
|
+
interface BuyCreditsNoticeActionProps {
|
|
231
|
+
/** Base URL for the credits API (default: same origin). */
|
|
232
|
+
apiBaseUrl?: string;
|
|
233
|
+
label?: string;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Inline "Buy credits" action for a PAYMENT_REQUIRED run-rejected notice. Self-contained:
|
|
237
|
+
* starts a server-created checkout (the buyer id is set server-side) on click. Renders
|
|
238
|
+
* nothing once the server reports checkout is disabled, so it can't dangle a dead button.
|
|
239
|
+
* Mount it from a host's renderNoticeAction (see isPaymentRequiredNotice).
|
|
240
|
+
*/
|
|
241
|
+
declare function BuyCreditsNoticeAction({ apiBaseUrl, label }: BuyCreditsNoticeActionProps): react_jsx_runtime.JSX.Element | null;
|
|
242
|
+
|
|
243
|
+
export { BuyCreditsNoticeAction, type BuyCreditsNoticeActionProps, CREDITS_REFRESH_EVENT, type ChatFirstPublicShellOptions, CheckoutReturnBanner, type CheckoutReturnBannerProps, type CheckoutReturnStatus, CoreWorkspaceAgentFront, type CoreWorkspaceAgentFrontProps, CreditBalanceBadge, type CreditBalanceBadgeProps, type CreditBalanceResponse, type CreditLedgerEntry, type CreditLedgerKind, type CreditPack, CreditsSettingsPanel, type CreditsSettingsPanelProps, DefaultTopBarRight, PAYMENT_REQUIRED_ERROR_CODE, type UseCheckoutReturnHandlerResult, type UseCreditBalanceOptions, type UseCreditBalanceResult, type UseCreditHistoryResult, formatCreditMicros, formatMinorPrice, formatSignedCreditMicros, isLowBalance, isPaymentRequiredNotice, useCheckoutReturnHandler, useCreditBalance, useCreditHistory };
|