@xenosystem/blocks 0.6.0 → 0.7.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/dist/agent/host-source.d.ts +118 -0
- package/dist/agent/host-source.js +228 -0
- package/dist/agent/index.d.ts +568 -0
- package/dist/agent/index.js +1439 -0
- package/dist/auth/index.d.ts +399 -3
- package/dist/auth/index.js +620 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/types-C5T3uVwd.d.ts +425 -0
- package/package.json +9 -3
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { PanelModule, PanelManifest } from '@xenosystem/panel-sdk';
|
|
4
|
-
import { XenoAccountStatus, XenoAccountIdentity, XenoAccountActionKind } from '@xenosystem/panel-account';
|
|
5
|
-
export * from '@xenosystem/panel-account';
|
|
6
4
|
import { BlockDeclaration } from '@xenosystem/block-sdk';
|
|
7
5
|
|
|
8
6
|
interface CreateAuthGatePanelOptions {
|
|
@@ -22,6 +20,205 @@ declare const AUTH_GATE_PANEL_ID = "xeno.core.auth-gate";
|
|
|
22
20
|
*/
|
|
23
21
|
declare const authGateManifest: PanelManifest;
|
|
24
22
|
|
|
23
|
+
/**
|
|
24
|
+
* The `xeno.core.account` contract.
|
|
25
|
+
*
|
|
26
|
+
* ## 🔴 What this panel must NOT do, per `XENO AUTH - SPEC.md`
|
|
27
|
+
*
|
|
28
|
+
* A naive account panel violates the locked auth spec in four separate ways. Each is prevented
|
|
29
|
+
* structurally here, not by convention:
|
|
30
|
+
*
|
|
31
|
+
* | Locked rule | The naive mistake | How this contract prevents it |
|
|
32
|
+
* |---|---|---|
|
|
33
|
+
* | **L9** — refresh tokens live ONLY in the OS keystore; `~/.xeno/*` holds no secrets; **never** `localStorage` | Persisting a session or token through `serialize()`. The panel's ONE capability is `storage.local`, which is *exactly* the store L9 forbids for a token. | **No token type exists.** `XenoAccountIdentity` has no field a token could occupy, and `serialize()` returns view preferences only. What the panel never receives, it cannot persist. |
|
|
34
|
+
* | **L10** — the real gate is server-side; client entitlement checks are "legitimacy + friction", never a security boundary | Gating a feature locally on `plan.tier`. | `XenoEntitlement` is explicitly **display-only** and documented as such. The panel exposes no "may I?" predicate for anyone to mistake for a gate. |
|
|
35
|
+
* | **L12** — step-up re-auth for money/account (plan cancel, account delete, logout-everywhere, payout change) must be a **fresh interactive** auth the broker cannot satisfy silently | Emitting `signOut` or `cancelPlan` as an ordinary intent and rendering success. | Sensitive actions carry `stepUp: true` on the intent, and the panel **never renders a result** — it waits for the host to push new state. |
|
|
36
|
+
* | **L5** — Hub is the preferred broker, **never a hard dependency**; every product must authenticate with Hub uninstalled | Assuming a broker-supplied identity and rendering nothing without one. | `signedOut` is a first-class, fully-rendered state with its own action. The panel neither knows nor asks whether a broker exists. |
|
|
37
|
+
*
|
|
38
|
+
* The panel holds **no network capability** — the same posture as the rest of the family. Identity,
|
|
39
|
+
* plan, credits and ledger are **host-pushed state**.
|
|
40
|
+
*
|
|
41
|
+
* @module
|
|
42
|
+
*/
|
|
43
|
+
/** Who is signed in. **Carries no token, by construction.** */
|
|
44
|
+
interface XenoAccountIdentity {
|
|
45
|
+
/** The OIDC `sub`. An opaque identifier, not a secret. */
|
|
46
|
+
sub: string;
|
|
47
|
+
/** Display name. */
|
|
48
|
+
name?: string;
|
|
49
|
+
/** Email, for display. */
|
|
50
|
+
email?: string;
|
|
51
|
+
/** Avatar URL. */
|
|
52
|
+
avatarUrl?: string;
|
|
53
|
+
}
|
|
54
|
+
/** Plan tier. Display only — see L10 above. */
|
|
55
|
+
interface XenoAccountPlan {
|
|
56
|
+
/** Stable id (`'free'`, `'pro'`, `'team'`). */
|
|
57
|
+
id: string;
|
|
58
|
+
/** Display name. */
|
|
59
|
+
label: string;
|
|
60
|
+
/** Epoch ms the current period ends. */
|
|
61
|
+
renewsAt?: number;
|
|
62
|
+
/** The plan is set to lapse rather than renew. */
|
|
63
|
+
cancelAtPeriodEnd?: boolean;
|
|
64
|
+
/** Seats held, for a team plan. */
|
|
65
|
+
seats?: {
|
|
66
|
+
used: number;
|
|
67
|
+
total: number;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A credit balance.
|
|
72
|
+
*
|
|
73
|
+
* **`asOf` is mandatory.** A balance is a number that goes out of date the moment anything runs, and
|
|
74
|
+
* a stale one rendered as fresh is worse than no balance at all — a user acts on it. The view must
|
|
75
|
+
* show the age or show a loading state; there is no third option, which is why the field cannot be
|
|
76
|
+
* omitted.
|
|
77
|
+
*/
|
|
78
|
+
interface XenoAccountCredits {
|
|
79
|
+
/** Remaining credits. */
|
|
80
|
+
balance: number;
|
|
81
|
+
/** Epoch ms this balance was true. **Mandatory.** */
|
|
82
|
+
asOf: number;
|
|
83
|
+
/** Granted this period, when the host tracks it. */
|
|
84
|
+
included?: number;
|
|
85
|
+
/** Consumed this period. */
|
|
86
|
+
used?: number;
|
|
87
|
+
/** Epoch ms the allowance resets. */
|
|
88
|
+
resetsAt?: number;
|
|
89
|
+
/** Currency-style unit label (`'credits'`, `'tokens'`). */
|
|
90
|
+
unit?: string;
|
|
91
|
+
}
|
|
92
|
+
/** One ledger entry. */
|
|
93
|
+
interface XenoLedgerEntry {
|
|
94
|
+
/** Stable id. */
|
|
95
|
+
id: string;
|
|
96
|
+
/** Epoch ms. */
|
|
97
|
+
ts: number;
|
|
98
|
+
/** What happened, in the host's words. */
|
|
99
|
+
description: string;
|
|
100
|
+
/** Signed: negative is a spend, positive a grant or purchase. */
|
|
101
|
+
amount: number;
|
|
102
|
+
/** Which product or surface spent it. */
|
|
103
|
+
source?: string;
|
|
104
|
+
/** Balance immediately after, when the host knows it. */
|
|
105
|
+
balanceAfter?: number;
|
|
106
|
+
}
|
|
107
|
+
/** An append-oriented ledger update — the same discipline as runs and console. */
|
|
108
|
+
interface XenoLedgerDelta {
|
|
109
|
+
rev?: number;
|
|
110
|
+
append?: XenoLedgerEntry[];
|
|
111
|
+
replace?: XenoLedgerEntry[];
|
|
112
|
+
clear?: boolean;
|
|
113
|
+
/** More pages exist before the oldest held entry. */
|
|
114
|
+
hasMore?: boolean;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* An entitlement, for DISPLAY.
|
|
118
|
+
*
|
|
119
|
+
* **Not a gate.** L10: the only unbreakable enforcement is `api.xenostudio.ai` validating the token
|
|
120
|
+
* and debiting the ledger. Rendering a lock icon is friction and honesty; it is not security, and
|
|
121
|
+
* nothing here should be mistaken for a permission check.
|
|
122
|
+
*/
|
|
123
|
+
interface XenoEntitlement {
|
|
124
|
+
id: string;
|
|
125
|
+
label: string;
|
|
126
|
+
/** Whether the host says this plan includes it. */
|
|
127
|
+
included: boolean;
|
|
128
|
+
/** Host-authored explanation of what unlocks it. */
|
|
129
|
+
detail?: string;
|
|
130
|
+
}
|
|
131
|
+
/** Session lifecycle. */
|
|
132
|
+
type XenoAccountStatus = 'unknown' | 'signedOut' | 'signedIn'
|
|
133
|
+
/** A silent refresh is in flight. Balance and plan may be stale. */
|
|
134
|
+
| 'refreshing'
|
|
135
|
+
/** The session expired and interactive sign-in is required. */
|
|
136
|
+
| 'expired'
|
|
137
|
+
/** The host could not reach the origin. Cached state may still be shown, honestly. */
|
|
138
|
+
| 'offline';
|
|
139
|
+
/** Everything the host pushes. */
|
|
140
|
+
interface XenoAccountState {
|
|
141
|
+
status: XenoAccountStatus;
|
|
142
|
+
identity?: XenoAccountIdentity;
|
|
143
|
+
plan?: XenoAccountPlan;
|
|
144
|
+
credits?: XenoAccountCredits;
|
|
145
|
+
entitlements?: XenoEntitlement[];
|
|
146
|
+
/** Host-authored message for the current status, rendered verbatim. */
|
|
147
|
+
message?: string;
|
|
148
|
+
/**
|
|
149
|
+
* The active seat, when the host manages several.
|
|
150
|
+
*
|
|
151
|
+
* Per L6 there is no shared multi-reader credential; a seat switch is a host flow, not a token
|
|
152
|
+
* swap the panel performs.
|
|
153
|
+
*/
|
|
154
|
+
seatId?: string;
|
|
155
|
+
/** Seats the user may switch to. */
|
|
156
|
+
seats?: {
|
|
157
|
+
id: string;
|
|
158
|
+
label: string;
|
|
159
|
+
active: boolean;
|
|
160
|
+
}[];
|
|
161
|
+
}
|
|
162
|
+
/** Actions the panel asks for. **Every one is an intent; the host runs the flow.** */
|
|
163
|
+
type XenoAccountActionKind = 'signIn' | 'signOut' | 'purchase' | 'manageBilling' | 'switchSeat' | 'refresh';
|
|
164
|
+
/** An account intent. */
|
|
165
|
+
interface XenoAccountAction {
|
|
166
|
+
kind: XenoAccountActionKind;
|
|
167
|
+
/** For `switchSeat`. */
|
|
168
|
+
seatId?: string;
|
|
169
|
+
/** For `purchase` — a host-defined product/pack id. */
|
|
170
|
+
productId?: string;
|
|
171
|
+
/**
|
|
172
|
+
* **L12**: this action needs a FRESH interactive re-auth, which the broker must not satisfy
|
|
173
|
+
* silently. The panel flags it; the host enforces it.
|
|
174
|
+
*/
|
|
175
|
+
stepUp?: boolean;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Actions that require step-up re-auth per `XENO AUTH - SPEC.md` L12.
|
|
179
|
+
*
|
|
180
|
+
* Irreversible or money-adjacent operations. `manageBilling` is here because it is the door to plan
|
|
181
|
+
* cancellation and payout changes, both named in L12.
|
|
182
|
+
*/
|
|
183
|
+
declare const STEP_UP_ACTIONS: ReadonlySet<XenoAccountActionKind>;
|
|
184
|
+
/** The panel's serialized state. **No identity, no session, no balance — see L9.** */
|
|
185
|
+
interface AccountPanelState {
|
|
186
|
+
/** Whether the ledger section is expanded. A view preference and nothing more. */
|
|
187
|
+
ledgerExpanded: boolean;
|
|
188
|
+
}
|
|
189
|
+
/** What the controller exposes to its view. */
|
|
190
|
+
interface AccountViewState {
|
|
191
|
+
status: XenoAccountStatus;
|
|
192
|
+
identity: XenoAccountIdentity | null;
|
|
193
|
+
plan: XenoAccountPlan | null;
|
|
194
|
+
credits: XenoAccountCredits | null;
|
|
195
|
+
entitlements: XenoEntitlement[];
|
|
196
|
+
seats: NonNullable<XenoAccountState['seats']>;
|
|
197
|
+
message: string | null;
|
|
198
|
+
ledger: XenoLedgerEntry[];
|
|
199
|
+
ledgerHasMore: boolean;
|
|
200
|
+
ledgerExpanded: boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Age of the balance in ms, or `null` when there is none.
|
|
203
|
+
*
|
|
204
|
+
* The view MUST surface this (or a loading state) rather than rendering a number as though it
|
|
205
|
+
* were current.
|
|
206
|
+
*/
|
|
207
|
+
creditsAgeMs: number | null;
|
|
208
|
+
/** The balance is older than the staleness threshold. */
|
|
209
|
+
creditsStale: boolean;
|
|
210
|
+
}
|
|
211
|
+
/** Is a user signed in right now? */
|
|
212
|
+
declare function isSignedIn(status: XenoAccountStatus): boolean;
|
|
213
|
+
/** Does this action need a fresh interactive auth (L12)? */
|
|
214
|
+
declare function requiresStepUp(kind: XenoAccountActionKind): boolean;
|
|
215
|
+
/** Age of a balance in ms. */
|
|
216
|
+
declare function creditsAge(credits: XenoAccountCredits | undefined, now: number): number | null;
|
|
217
|
+
/** Format a signed ledger amount with an explicit sign. */
|
|
218
|
+
declare function formatAmount(amount: number, unit?: string): string;
|
|
219
|
+
/** Format a balance age compactly. */
|
|
220
|
+
declare function formatAge(ms: number): string;
|
|
221
|
+
|
|
25
222
|
/**
|
|
26
223
|
* `xeno.core.auth-gate` — the door in front of a XENO product.
|
|
27
224
|
*
|
|
@@ -219,4 +416,203 @@ interface MountedXenoAuthGate {
|
|
|
219
416
|
}
|
|
220
417
|
declare function mountXenoAuthGate(root: HTMLElement, options: MountXenoAuthGateOptions): MountedXenoAuthGate;
|
|
221
418
|
|
|
222
|
-
|
|
419
|
+
/**
|
|
420
|
+
* The Account controller.
|
|
421
|
+
*
|
|
422
|
+
* Everything it holds arrives from the host. **The panel never fetches**: it has no network
|
|
423
|
+
* capability, no origin, no token, and no knowledge of whether a broker exists. It renders what it
|
|
424
|
+
* was pushed, timestamps it honestly, and emits intents.
|
|
425
|
+
*
|
|
426
|
+
* @module
|
|
427
|
+
*/
|
|
428
|
+
|
|
429
|
+
/** The host seam. */
|
|
430
|
+
interface AccountHostBridge {
|
|
431
|
+
emit(portId: string, value: unknown): void;
|
|
432
|
+
now?: () => number;
|
|
433
|
+
}
|
|
434
|
+
/** Construction options. */
|
|
435
|
+
interface AccountControllerOptions {
|
|
436
|
+
host: AccountHostBridge;
|
|
437
|
+
/** ms after which a balance is called stale. Default 60 000. */
|
|
438
|
+
staleAfterMs?: number;
|
|
439
|
+
/** Ledger entries retained. Default 500. */
|
|
440
|
+
maxLedger?: number;
|
|
441
|
+
}
|
|
442
|
+
/** The Account panel controller. */
|
|
443
|
+
declare class AccountController {
|
|
444
|
+
private readonly host;
|
|
445
|
+
private readonly now;
|
|
446
|
+
private readonly staleAfterMs;
|
|
447
|
+
private readonly maxLedger;
|
|
448
|
+
private account;
|
|
449
|
+
private ledger;
|
|
450
|
+
private ledgerHasMore;
|
|
451
|
+
private ledgerRev;
|
|
452
|
+
private ledgerExpanded;
|
|
453
|
+
private readonly listeners;
|
|
454
|
+
private snapshot;
|
|
455
|
+
constructor(options: AccountControllerOptions);
|
|
456
|
+
subscribe: (listener: () => void) => (() => void);
|
|
457
|
+
getState: () => AccountViewState;
|
|
458
|
+
private notify;
|
|
459
|
+
/**
|
|
460
|
+
* Replace the account state.
|
|
461
|
+
*
|
|
462
|
+
* The host is authoritative. The panel does not merge cleverly, does not keep a "better" older
|
|
463
|
+
* value, and does not infer a status the host did not send — a panel that second-guesses its host
|
|
464
|
+
* is a second source of truth about who is signed in.
|
|
465
|
+
*
|
|
466
|
+
* @param next - The new state.
|
|
467
|
+
*/
|
|
468
|
+
setAccount(next: XenoAccountState): void;
|
|
469
|
+
/**
|
|
470
|
+
* A partial update, for hosts that push only what changed.
|
|
471
|
+
*
|
|
472
|
+
* `credits` is replaced wholesale rather than field-merged: a balance and its `asOf` are one fact,
|
|
473
|
+
* and merging a new number onto an old timestamp manufactures a lie.
|
|
474
|
+
*
|
|
475
|
+
* @param patch - Fields to overwrite.
|
|
476
|
+
*/
|
|
477
|
+
patchAccount(patch: Partial<XenoAccountState>): void;
|
|
478
|
+
/** Set the session status alone. */
|
|
479
|
+
setStatus(status: XenoAccountStatus, message?: string): void;
|
|
480
|
+
/**
|
|
481
|
+
* Apply a ledger delta.
|
|
482
|
+
*
|
|
483
|
+
* Append-oriented, with `rev` gating out-of-order deliveries — the same discipline as runs and
|
|
484
|
+
* console.
|
|
485
|
+
*
|
|
486
|
+
* @param delta - The update.
|
|
487
|
+
* @returns Whether it was applied.
|
|
488
|
+
*/
|
|
489
|
+
applyLedger(delta: XenoLedgerDelta): boolean;
|
|
490
|
+
/**
|
|
491
|
+
* Re-evaluate the balance's age.
|
|
492
|
+
*
|
|
493
|
+
* `getState` memoizes — it must, or `useSyncExternalStore` re-renders forever — which means the
|
|
494
|
+
* age would otherwise freeze at the moment of the last push, and a balance would sit on screen
|
|
495
|
+
* reading "as of 2s ago" for an hour. That is precisely the stale-as-fresh failure `asOf` exists
|
|
496
|
+
* to prevent, reintroduced by a caching bug.
|
|
497
|
+
*
|
|
498
|
+
* So time is an INPUT here, and the panel drives this on an interval. Notifying only when the
|
|
499
|
+
* rendered age actually changes keeps it off the re-render hot path: a one-second tick that
|
|
500
|
+
* re-renders once per second is honest; one that re-renders sixty times is waste.
|
|
501
|
+
*
|
|
502
|
+
* @returns Whether anything the view shows changed.
|
|
503
|
+
*/
|
|
504
|
+
tick(): boolean;
|
|
505
|
+
/** Expand or collapse the ledger. A view preference. */
|
|
506
|
+
setLedgerExpanded(expanded: boolean): void;
|
|
507
|
+
/**
|
|
508
|
+
* Ask the host to do something.
|
|
509
|
+
*
|
|
510
|
+
* **The panel never renders the result.** It does not flip to `signedOut` because the user
|
|
511
|
+
* clicked Sign out, and it does not add credits because the user clicked Purchase. It emits, and
|
|
512
|
+
* waits to be told — the same intents-only doctrine the rest of the family follows, and the only
|
|
513
|
+
* shape compatible with `XENO AUTH - SPEC.md` L12, where a sensitive action may be REFUSED at the
|
|
514
|
+
* step-up prompt after the click.
|
|
515
|
+
*
|
|
516
|
+
* @param kind - What to ask for.
|
|
517
|
+
* @param extra - `seatId` or `productId`.
|
|
518
|
+
* @returns The emitted action.
|
|
519
|
+
*/
|
|
520
|
+
request(kind: XenoAccountActionKind, extra?: Omit<XenoAccountAction, 'kind' | 'stepUp'>): XenoAccountAction;
|
|
521
|
+
/** Ask the host to re-read the balance. Cheap, idempotent, no step-up. */
|
|
522
|
+
refresh(): XenoAccountAction;
|
|
523
|
+
/**
|
|
524
|
+
* Serialize.
|
|
525
|
+
*
|
|
526
|
+
* **View preferences only.** No identity, no plan, no balance, no token.
|
|
527
|
+
*
|
|
528
|
+
* `XENO AUTH - SPEC.md` L9 forbids a refresh token in `localStorage` or `~/.xeno/*`, and this
|
|
529
|
+
* panel's one capability is `storage.local` — the very store L9 names. Persisting a balance would
|
|
530
|
+
* also reintroduce the stale-as-fresh problem `asOf` exists to solve: a number restored from disk
|
|
531
|
+
* has no honest timestamp.
|
|
532
|
+
*/
|
|
533
|
+
serialize(): {
|
|
534
|
+
ledgerExpanded: boolean;
|
|
535
|
+
};
|
|
536
|
+
/** Restore view preferences. */
|
|
537
|
+
deserialize(state: unknown): void;
|
|
538
|
+
/** Tear down. */
|
|
539
|
+
dispose(): void;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* The `PanelModule` — view wired inside the package (one React copy).
|
|
544
|
+
*
|
|
545
|
+
* @module
|
|
546
|
+
*/
|
|
547
|
+
|
|
548
|
+
/** Everything a renderer needs: the controller plus the resolved config. */
|
|
549
|
+
interface AccountRenderContext {
|
|
550
|
+
controller: AccountController;
|
|
551
|
+
config: {
|
|
552
|
+
showLedger: boolean;
|
|
553
|
+
showEntitlements: boolean;
|
|
554
|
+
emptyHint?: string;
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
/** Options for {@link createAccountPanel}. */
|
|
558
|
+
interface CreateAccountPanelOptions {
|
|
559
|
+
/** Override the view. Rarely needed — mounting inside the package keeps React singular. */
|
|
560
|
+
render?: (root: HTMLElement, context: AccountRenderContext) => () => void;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Build the Account panel module.
|
|
564
|
+
*
|
|
565
|
+
* @param options - Optional renderer override.
|
|
566
|
+
* @returns The module.
|
|
567
|
+
*/
|
|
568
|
+
declare function createAccountPanel(options?: CreateAccountPanelOptions): PanelModule;
|
|
569
|
+
/** The default Account panel module — view already wired. Register THIS. */
|
|
570
|
+
declare const accountPanel: PanelModule;
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* The `xeno.core.account` manifest.
|
|
574
|
+
*
|
|
575
|
+
* Capabilities: `storage.local` only — **no `net.fetch`**. That is not an oversight. Identity, plan,
|
|
576
|
+
* credits and ledger are host-pushed; a panel that could reach the origin itself would need a token,
|
|
577
|
+
* and a token is exactly what `XENO AUTH - SPEC.md` L9 says must never live where this panel can
|
|
578
|
+
* reach.
|
|
579
|
+
*
|
|
580
|
+
* @module
|
|
581
|
+
*/
|
|
582
|
+
|
|
583
|
+
/** The canonical manifest id. */
|
|
584
|
+
declare const ACCOUNT_PANEL_ID = "xeno.core.account";
|
|
585
|
+
/** The `xeno.core.account` manifest. */
|
|
586
|
+
declare const accountManifest: PanelManifest;
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* The Account panel view.
|
|
590
|
+
*
|
|
591
|
+
* Composes `@xenosystem/workbench/primitives`; the host must ensure `@xenosystem/workbench/primitives.css` is
|
|
592
|
+
* present.
|
|
593
|
+
*
|
|
594
|
+
* Three deliberate absences, each traceable to `XENO AUTH - SPEC.md`:
|
|
595
|
+
*
|
|
596
|
+
* - **No secret-reveal affordance.** `xeno-hub` has one (a masked API key with an eye toggle). It is
|
|
597
|
+
* deliberately not lifted: a shared panel that can render a secret is a shared panel that can leak
|
|
598
|
+
* one into a screenshot, a screen share, or a `serialize()`. L9 keeps secrets in the keystore, and
|
|
599
|
+
* the surest way to honour that is to have nothing to reveal.
|
|
600
|
+
* - **No optimistic success.** Clicking Sign out does not sign you out on screen. L12 says a
|
|
601
|
+
* sensitive action needs a fresh interactive re-auth that the user may cancel or fail; a view that
|
|
602
|
+
* had already cleared the name would be lying about state it does not own.
|
|
603
|
+
* - **No local gate.** Entitlements render as facts, never as enforcement (L10).
|
|
604
|
+
*
|
|
605
|
+
* @module
|
|
606
|
+
*/
|
|
607
|
+
|
|
608
|
+
/** Props for {@link AccountPanelView}. */
|
|
609
|
+
interface AccountPanelViewProps {
|
|
610
|
+
controller: AccountController;
|
|
611
|
+
showLedger?: boolean;
|
|
612
|
+
showEntitlements?: boolean;
|
|
613
|
+
emptyHint?: string;
|
|
614
|
+
}
|
|
615
|
+
/** The Account panel view. */
|
|
616
|
+
declare function AccountPanelView({ controller, showLedger, showEntitlements, emptyHint, }: AccountPanelViewProps): ReactNode;
|
|
617
|
+
|
|
618
|
+
export { ACCOUNT_PANEL_ID, AUTH_GATE_DECLARATION, AUTH_GATE_INITIAL, AUTH_GATE_PANEL_ID, AccountController, type AccountControllerOptions, type AccountHostBridge, type AccountPanelState, AccountPanelView, type AccountPanelViewProps, type AccountRenderContext, type AccountViewState, type AuthGateAction, AuthGateController, type AuthGateHostBridge, AuthGateView$1 as AuthGateView, type AuthGateView as AuthGateViewModel, type AuthGateViewProps, BEHAVIOURS, type CreateAccountPanelOptions, type CreateAuthGatePanelOptions, type MountXenoAuthGateOptions, type MountedXenoAuthGate, PHASE_INTENTS, STEP_UP_ACTIONS, type XenoAccountAction, type XenoAccountActionKind, type XenoAccountCredits, type XenoAccountIdentity, type XenoAccountPlan, type XenoAccountState, type XenoAccountStatus, type XenoAuthGateBridge, type XenoAuthGateIntent, type XenoAuthGateIntentKind, type XenoAuthGatePhase, type XenoAuthGateState, type XenoEntitlement, type XenoLedgerDelta, type XenoLedgerEntry, type XenoLicenceState, accountManifest, accountPanel, authGateManifest, authGatePanel, authGateView, createAccountPanel, createAuthGatePanel, creditsAge, deriveAuthGatePhase, formatAge, formatAmount, formatSince, hostContradiction, intentOffered, isSignedIn, mountXenoAuthGate, plateCopy, requiresStepUp };
|