@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.
@@ -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
- interface CoreWorkspaceAgentFrontProps<TSession extends WorkspaceAgentSession = WorkspaceAgentSession> extends Omit<WorkspaceAgentFrontProps<TSession>, 'workspaceId' | 'frontPluginHotReload' | 'hotReloadEnabled'> {
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
- declare function CoreWorkspaceAgentFront<TSession extends WorkspaceAgentSession = WorkspaceAgentSession>({ authPages, cspNonce, children, workspaceRoute, workspaceIdParam, workspaceHref, loadingFallback, bootPreloadPaths, topBarLeft, topBarRight, appTitle, bridgeEndpoint, hotReload, chatEntryMode, chatFirstPublicShell, ...workspaceProps }: CoreWorkspaceAgentFrontProps<TSession>): react_jsx_runtime.JSX.Element;
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
- export { type ChatFirstPublicShellOptions, CoreWorkspaceAgentFront, type CoreWorkspaceAgentFrontProps };
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 };