@muhkoo/connect 0.10.14-alpha.0 → 0.12.0-alpha.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/connect.d.ts CHANGED
@@ -1897,7 +1897,7 @@ interface AuthSuccess {
1897
1897
  /** A vault factor record (M1.0 + M2 gated types). Wrap/iv are base64 AES-GCM; absent for phrase. */
1898
1898
  interface VaultFactor {
1899
1899
  id: string;
1900
- type: "password" | "passkey" | "phrase-marker" | "email" | "google";
1900
+ type: "password" | "passkey" | "phrase-marker" | "email" | "google" | "device";
1901
1901
  wrap?: string;
1902
1902
  iv?: string;
1903
1903
  params?: Record<string, unknown>;
@@ -2009,7 +2009,9 @@ declare class AuthClient {
2009
2009
  /** Passkeys are per-origin: naming the caller's host returns THAT origin's
2010
2010
  * passkey instead of whichever was enrolled first (which WebAuthn would
2011
2011
  * refuse). Ignored for other factor types. */
2012
- rpId?: string): Promise<{
2012
+ rpId?: string,
2013
+ /** Device factors are selected by id — a user may have many machines. */
2014
+ factorId?: string): Promise<{
2013
2015
  factor: VaultFactor | null;
2014
2016
  }>;
2015
2017
  /**
@@ -2966,10 +2968,6 @@ interface ZkAuthDeps {
2966
2968
  circuits: CircuitUrls;
2967
2969
  session: SessionState;
2968
2970
  }
2969
- /**
2970
- * ZK identity auth. One instance per {@link Client}; reads/writes the shared
2971
- * {@link SessionState}.
2972
- */
2973
2971
  declare class ZkAuth {
2974
2972
  private readonly deps;
2975
2973
  constructor(deps: ZkAuthDeps);
@@ -3184,6 +3182,63 @@ declare class ZkAuth {
3184
3182
  * passwordless (passkey) login, both of which recover the same seed.
3185
3183
  */
3186
3184
  get seedBase64(): string | null;
3185
+ /**
3186
+ * Pair this machine, so it can unlock the account later without a password.
3187
+ *
3188
+ * Generates a random 32-byte key, wraps the master seed under it, and stores
3189
+ * only the CIPHERTEXT in the vault as a `device` factor. The key is returned
3190
+ * for the caller to persist locally and is never sent anywhere.
3191
+ *
3192
+ * The split is the point: the seed itself never lands on disk, and the
3193
+ * server holds a blob it cannot open. Revoking the factor
3194
+ * ({@link revokeDevice}) makes the local key inert immediately — which a
3195
+ * stored master seed can never be, because nothing can reach out and
3196
+ * un-store it.
3197
+ *
3198
+ * Returns the factor id and the key, both base64. Losing the key just means
3199
+ * re-pairing; leaking it is equivalent to leaking the seed for as long as
3200
+ * the factor exists, so store it with the tightest permissions available.
3201
+ */
3202
+ enrollDevice(label: string): Promise<{
3203
+ factorId: string;
3204
+ deviceKey: string;
3205
+ }>;
3206
+ /**
3207
+ * Unlock using a key stored by {@link enrollDevice}.
3208
+ *
3209
+ * Fetches the wrapped seed and opens it locally. Establishes the encryption
3210
+ * identity only — pair it with a session for calls that need one.
3211
+ *
3212
+ * Throws distinguishably: a REVOKED factor is gone from the vault and says
3213
+ * so, where a wrong key fails to decrypt. A machine that has had its access
3214
+ * withdrawn should be able to tell you that, not just "decryption failed".
3215
+ */
3216
+ unlockWithDevice(username: string, factorId: string, deviceKey: string): Promise<void>;
3217
+ /** Paired machines, newest first. Metadata only — never the ciphertext. */
3218
+ listDevices(): Promise<Array<{
3219
+ id: string;
3220
+ label?: string;
3221
+ createdAt?: number;
3222
+ }>>;
3223
+ /** Withdraw a machine's access. Its stored key stops working immediately. */
3224
+ revokeDevice(factorId: string): Promise<boolean>;
3225
+ /**
3226
+ * Restore an unlocked identity from a seed you already hold.
3227
+ *
3228
+ * The inverse of {@link seedBase64}, for hosts that persist the seed
3229
+ * themselves rather than re-deriving it from a password: a CLI holding it in
3230
+ * a 0600 file, a server-side tool, a test. Without this the seed is a
3231
+ * one-way export and anything outside a browser has to run a full ZK login —
3232
+ * circuits download and proof — on every single invocation.
3233
+ *
3234
+ * Establishes the ENCRYPTION identity only. It does not authenticate: pair
3235
+ * it with a session token (`sessionStore`) for calls that need one.
3236
+ *
3237
+ * Treat a persisted seed as the master credential it is. It is not scoped
3238
+ * and cannot be revoked server-side the way a session token can — rotating
3239
+ * it means moving the identity.
3240
+ */
3241
+ unlockWithSeed(seedBase64: string): void;
3187
3242
  /** Poseidon commitment for an identity — the value the server stores. */
3188
3243
  private commitmentFor;
3189
3244
  /**
@@ -3766,6 +3821,8 @@ interface StorageChangeEvent<T = unknown> {
3766
3821
  }
3767
3822
  declare class KvNamespace {
3768
3823
  private readonly deps;
3824
+ /** One personal-space socket, shared by every subscriber. */
3825
+ private feed;
3769
3826
  private cipher;
3770
3827
  private cipherIdentity;
3771
3828
  constructor(deps: KvNamespaceDeps);
@@ -3789,6 +3846,20 @@ declare class KvNamespace {
3789
3846
  * Requires a `WebSocket` global (browsers; Node 22+ or a `ws` shim).
3790
3847
  */
3791
3848
  on<T = unknown>(event: "change", handler: (e: StorageChangeEvent<T>) => void): () => void;
3849
+ /**
3850
+ * Subscribe to the personal space's raw change feed.
3851
+ *
3852
+ * Every key this user owns crosses this socket, not only `client.kv`
3853
+ * collections — the VFS keeps its directory records here too. Consumers get
3854
+ * the frame untouched: no decryption, no offline-cache merge, because the
3855
+ * value's meaning depends on which subsystem wrote it.
3856
+ *
3857
+ * The transport is SHARED and reference-counted. `WSTransport` namespaces
3858
+ * its events by `id`, so two transports with the same id would cross wires
3859
+ * on the shared event bus — and a second socket to the same Durable Object
3860
+ * would be pure waste besides.
3861
+ */
3862
+ onRaw(handler: (frame: unknown) => void): () => void;
3792
3863
  private dispatchChange;
3793
3864
  /** Decode a stored value: decrypt envelopes, pass plaintext through. */
3794
3865
  private decode;
@@ -4915,9 +4986,20 @@ declare class SpaceNamespace {
4915
4986
  * Create a new space: generate its keypair (public key = id), register
4916
4987
  * metadata, mint the initial group key, and connect. Returns the open Space.
4917
4988
  */
4989
+ /**
4990
+ * Create a space.
4991
+ *
4992
+ * `messaging: false` registers the space and stops there — no group-key
4993
+ * bootstrap and no WebSocket. Use it for a space that only ever holds
4994
+ * FILES: each chunk carries its own key inside its manifest, so the group
4995
+ * keyring buys nothing, and opening a socket makes the write path depend on
4996
+ * a live connection. That dependency is wrong for a CLI, and it is what made
4997
+ * the first VFS write hang forever instead of failing.
4998
+ */
4918
4999
  createSpace(opts?: {
4919
5000
  historyPolicy?: HistoryPolicy;
4920
5001
  private?: boolean;
5002
+ messaging?: boolean;
4921
5003
  }): Promise<Space>;
4922
5004
  /** Join an existing space by id (its public key). Resolves once a key arrives. */
4923
5005
  joinSpace(spaceId: string, opts?: {
@@ -5379,6 +5461,693 @@ declare class AccessTokensNamespace {
5379
5461
  private path;
5380
5462
  }
5381
5463
 
5464
+ /**
5465
+ * Wire types for the VFS metadata layer.
5466
+ *
5467
+ * ## What is stored where
5468
+ *
5469
+ * The filesystem is a graph of **directory records**, one per directory, each
5470
+ * held under a personal-space KV key and encrypted client-side. A record lists
5471
+ * only its immediate children — so listing a directory is one fetch, and you
5472
+ * only ever pay for the subtrees you actually open.
5473
+ *
5474
+ * File CONTENT is not here. Bytes are written with `client.storage.writeFile`
5475
+ * exactly as any other file — into a real Space, with a real gated manifest —
5476
+ * and the entry keeps the returned `FileManifest` as its handle.
5477
+ * `client.storage.readByManifest(manifest)` then reconstructs the bytes from
5478
+ * the content-addressed shard store with no space membership or directory
5479
+ * lookup needed, which is what makes a file shareable by handing over the
5480
+ * handle alone.
5481
+ *
5482
+ * This supersedes the flat personal mirror `writeFile` already maintains
5483
+ * (`{spaceId, manifest}` keyed by manifest id): the same metadata, in the same
5484
+ * personal space, arranged as a tree you can actually navigate.
5485
+ *
5486
+ * ## Why directories have stable random ids, not content hashes
5487
+ *
5488
+ * A git-style tree keys each directory by the hash of its contents, so writing
5489
+ * one file rewrites every ancestor up to the root. Here a directory's id is
5490
+ * random and permanent, so a file write touches exactly ONE record — its
5491
+ * parent — and renaming or moving a directory edits only the parent entry
5492
+ * while the whole subtree underneath stays byte-identical and untouched.
5493
+ *
5494
+ * ## Why a directory's key lives in its parent
5495
+ *
5496
+ * Only the root key is derived from the master seed. Every other directory has
5497
+ * a random key stored in its parent's entry, which chains capabilities
5498
+ * downward: handing someone `{id, key}` for `/apps/my-app` lets them walk that
5499
+ * subtree and nothing else, because no key can be derived upward. That is the
5500
+ * seam group-sharing hangs off later without re-encrypting the filesystem.
5501
+ */
5502
+
5503
+ /** Personal-space KV key holding a directory record. */
5504
+ declare const dirKey: (id: string) => string;
5505
+ /** Personal-space KV key holding one file's prior versions. */
5506
+ declare const historyKey: (id: string) => string;
5507
+ /** The root directory's id is fixed — it is the one node reached without a parent. */
5508
+ declare const ROOT_ID = "root";
5509
+ /** HKDF label for the seed-derived root key. Sits alongside `muhkoo-storage-v1`. */
5510
+ declare const VFS_ROOT_INFO = "muhkoo-vfs-v1";
5511
+ interface FileEntry {
5512
+ kind: "file";
5513
+ /**
5514
+ * Stable identity, independent of name and location. Renaming a file keeps
5515
+ * its id, so its version history follows it rather than being orphaned.
5516
+ */
5517
+ id: string;
5518
+ /** The handle: everything needed to read the current bytes back. */
5519
+ manifest: FileManifest;
5520
+ /** Plaintext byte length. */
5521
+ size: number;
5522
+ mtime: number;
5523
+ /**
5524
+ * Count of prior versions in the file's history record.
5525
+ *
5526
+ * Denormalised on purpose: the file tree wants to show "3 versions" while
5527
+ * listing a directory, and fetching every history record to answer that
5528
+ * would defeat the point of keeping history out of the directory record.
5529
+ */
5530
+ versions?: number;
5531
+ }
5532
+ interface DirEntry {
5533
+ kind: "dir";
5534
+ /** Record id — `dirKey(id)` locates it. Permanent for the directory's life. */
5535
+ id: string;
5536
+ /** Base64 AES-256 key for that record. See the capability note above. */
5537
+ key: string;
5538
+ mtime: number;
5539
+ }
5540
+ type Entry = FileEntry | DirEntry;
5541
+ /** One directory record, as stored (before encryption). */
5542
+ interface DirNode {
5543
+ v: 1;
5544
+ /** Child name → entry. Names are unique within a directory, per filesystem. */
5545
+ entries: Record<string, Entry>;
5546
+ mtime: number;
5547
+ }
5548
+ /** A file's prior versions, newest first. Fetched only when asked for. */
5549
+ interface HistoryRecord {
5550
+ v: 1;
5551
+ versions: Array<{
5552
+ manifest: FileManifest;
5553
+ size: number;
5554
+ mtime: number;
5555
+ }>;
5556
+ }
5557
+ /** What `stat` and `list` hand back — a path-addressed view of an entry. */
5558
+ interface VfsStat {
5559
+ path: string;
5560
+ name: string;
5561
+ kind: "file" | "dir";
5562
+ size: number;
5563
+ mtime: number;
5564
+ versions: number;
5565
+ }
5566
+ /** The encrypted envelope every record is stored in. */
5567
+ interface SealedRecord {
5568
+ v: 1;
5569
+ /** Base64 12-byte AES-GCM IV. */
5570
+ iv: string;
5571
+ /** Base64 ciphertext with the 16-byte tag appended. */
5572
+ ct: string;
5573
+ }
5574
+ /** The personal-space blob store the VFS persists through. */
5575
+ interface VfsStore {
5576
+ get(key: string): Promise<unknown | null>;
5577
+ put(key: string, value: unknown): Promise<void>;
5578
+ delete(key: string): Promise<void>;
5579
+ /** Every key in the store — the personal space is shared, so this is NOT VFS-only. */
5580
+ list(): Promise<string[]>;
5581
+ }
5582
+ /** Raised when the master seed is not held, so the root key cannot be derived. */
5583
+ declare class VfsLockedError extends Error {
5584
+ constructor();
5585
+ }
5586
+ /** Raised for a path that does not exist. */
5587
+ declare class VfsNotFoundError extends Error {
5588
+ constructor(path: string);
5589
+ }
5590
+ /** Raised when an operation would clobber or misuse an existing entry. */
5591
+ declare class VfsConflictError extends Error {
5592
+ constructor(message: string);
5593
+ }
5594
+
5595
+ /**
5596
+ * `client.vfs` — a real filesystem over Muhkoo primitives.
5597
+ *
5598
+ * Metadata is a graph of encrypted directory records in the user's personal
5599
+ * space; file content is chunked, encrypted and stored in the global
5600
+ * content-addressed shard store, referenced by manifest. See `types.ts` for
5601
+ * why directories carry stable random ids and why each key lives in its parent.
5602
+ *
5603
+ * ## Consistency
5604
+ *
5605
+ * Every mutation is a read-modify-write of exactly ONE directory record, so a
5606
+ * write cannot leave the tree half-updated: either the parent names the new
5607
+ * child or it does not. Two tabs writing different directories never conflict;
5608
+ * two tabs writing the SAME directory resolve last-writer-wins at the personal
5609
+ * space, which carries an HLC per key. Orphaned records (a directory whose
5610
+ * parent entry lost the race) are unreachable rather than corrupting — they
5611
+ * cost storage until a future sweep, which is the trade this shape makes in
5612
+ * exchange for single-record writes.
5613
+ */
5614
+
5615
+ /**
5616
+ * The slice of content storage the VFS needs.
5617
+ *
5618
+ * Narrow on purpose: the VFS knows how to name and arrange things, not how to
5619
+ * shard them. The adapter in `Client` resolves the content space and calls
5620
+ * `client.storage.writeFile` unchanged — the file still lands in a real Space
5621
+ * with a real gated manifest, and the VFS just keeps the handle somewhere
5622
+ * better than a flat mirror.
5623
+ */
5624
+ interface VfsContentStore {
5625
+ write(data: Uint8Array | Blob, meta: {
5626
+ name: string;
5627
+ type: string;
5628
+ }): Promise<{
5629
+ manifest: FileManifest;
5630
+ size: number;
5631
+ }>;
5632
+ read(manifest: FileManifest): Promise<Uint8Array>;
5633
+ /**
5634
+ * Drop a reference to a manifest's shards.
5635
+ *
5636
+ * Shards are content-addressed and reference-counted, so deleting a file is
5637
+ * not enough to reclaim the bytes — without this, every version ever
5638
+ * written stays on disk and billed forever. Best-effort: a failure here
5639
+ * leaks storage but must not block the delete.
5640
+ */
5641
+ release(manifest: FileManifest): Promise<void>;
5642
+ /**
5643
+ * Take an ADDITIONAL reference to shards that already exist.
5644
+ *
5645
+ * Needed when a manifest gains a second owner without new bytes being
5646
+ * written — copying a file. Without it the copy holds a handle to shards
5647
+ * with a refcount of one, and deleting the original frees the bytes out
5648
+ * from under it.
5649
+ */
5650
+ retain(manifest: FileManifest): Promise<void>;
5651
+ }
5652
+ interface VfsNamespaceDeps {
5653
+ store: VfsStore;
5654
+ /**
5655
+ * Subscribe to the personal space's raw change feed, if the runtime has one.
5656
+ * Optional so the VFS works headlessly (a CLI, a test) with no socket.
5657
+ */
5658
+ subscribe?: (handler: (frame: unknown) => void) => () => void;
5659
+ content: VfsContentStore;
5660
+ /** The in-memory master seed, or null when locked. Read per call — it can change. */
5661
+ seed: () => Uint8Array | null;
5662
+ /** Versions retained per file. */
5663
+ historyLimit?: number;
5664
+ }
5665
+ declare class VfsNamespace {
5666
+ private readonly deps;
5667
+ private rootKey;
5668
+ /**
5669
+ * Decrypted directory records, by id.
5670
+ *
5671
+ * The file tree re-lists constantly while typing, and every miss is a
5672
+ * network round trip plus a decrypt. Invalidated precisely on write rather
5673
+ * than by TTL — a stale directory listing shows files that are not there.
5674
+ */
5675
+ private cache;
5676
+ private readonly historyLimit;
5677
+ constructor(deps: VfsNamespaceDeps);
5678
+ /**
5679
+ * The working directory relative paths resolve against.
5680
+ *
5681
+ * Kept here rather than left to each caller so that a CLI, a script and the
5682
+ * SDK all agree on what "here" means — the alternative is every consumer
5683
+ * re-implementing `cd`, and disagreeing about `..`.
5684
+ */
5685
+ private _cwd;
5686
+ /** The current working directory. Always absolute. */
5687
+ get cwd(): string;
5688
+ /**
5689
+ * Change the working directory.
5690
+ *
5691
+ * Verifies the target is a real directory, so a typo fails here — where the
5692
+ * message can name the path — rather than turning every later relative path
5693
+ * into a confusing "does not exist".
5694
+ */
5695
+ cd(path: string): Promise<string>;
5696
+ /** Resolve a path against the working directory. Absolute paths pass through. */
5697
+ resolve(path: string): string;
5698
+ /** True when the master seed is held, so the root key can be derived. */
5699
+ get unlocked(): boolean;
5700
+ /**
5701
+ * Drop every cached record.
5702
+ *
5703
+ * Call after signing in as someone else — the cache is keyed by directory
5704
+ * id with no notion of whose filesystem it came from, and serving one
5705
+ * identity's directories to another would be the worst possible bug here.
5706
+ */
5707
+ clearCache(): void;
5708
+ /**
5709
+ * Call `handler` when this filesystem changes somewhere else — another tab,
5710
+ * another machine, the CLI.
5711
+ *
5712
+ * Deliberately a NOTIFICATION, not a diff: the frame names a record id, and
5713
+ * a record id is not a path (paths are resolved by walking, and the walk is
5714
+ * what the change may have invalidated). So the cache is dropped and the
5715
+ * caller re-reads whatever it is actually showing. Trying to translate a
5716
+ * record id back into a path would mean maintaining a reverse index that
5717
+ * could itself go stale.
5718
+ *
5719
+ * Returns an unsubscribe function. A runtime with no socket (a CLI) gets a
5720
+ * no-op rather than an error — watching is an optimisation, never required
5721
+ * for correctness.
5722
+ */
5723
+ watch(handler: () => void): () => void;
5724
+ exists(path: string): Promise<boolean>;
5725
+ stat(path: string): Promise<VfsStat>;
5726
+ /** Immediate children of a directory. One record fetch. */
5727
+ list(path?: string): Promise<VfsStat[]>;
5728
+ /**
5729
+ * Every file path under a prefix, depth-first.
5730
+ *
5731
+ * Deliberately separate from `list`: this walks the whole subtree, which is
5732
+ * one fetch per directory. Fine for a project, wrong as a default.
5733
+ */
5734
+ walk(path?: string): Promise<string[]>;
5735
+ readFile(path: string): Promise<Uint8Array>;
5736
+ readText(path: string): Promise<string>;
5737
+ /**
5738
+ * A file's manifest — the handle itself, without reading the bytes.
5739
+ *
5740
+ * Version control records manifests rather than content, so a commit costs
5741
+ * a hash and a reference, not a copy.
5742
+ */
5743
+ statManifest(path: string): Promise<{
5744
+ manifest: FileManifest;
5745
+ size: number;
5746
+ }>;
5747
+ /**
5748
+ * Read content by its manifest, wherever it came from.
5749
+ *
5750
+ * A merge needs the COMMON ANCESTOR's version of a file, which by definition
5751
+ * is not in the working tree any more. The manifest is the whole capability,
5752
+ * so no path lookup is involved.
5753
+ */
5754
+ readByManifest(manifest: FileManifest): Promise<Uint8Array>;
5755
+ /**
5756
+ * Pin content that something other than the working tree depends on.
5757
+ *
5758
+ * A commit references a manifest, so it is an OWNER of that content — without
5759
+ * a reference of its own, deleting the file from the working tree would free
5760
+ * shards the history still needs, and checking out an older commit would find
5761
+ * the content gone. (It did, in test.)
5762
+ */
5763
+ retainManifest(manifest: FileManifest): Promise<void>;
5764
+ /**
5765
+ * Point a path at content that already exists.
5766
+ *
5767
+ * This is how a checkout restores a file: the bytes are in the shard store
5768
+ * already, so nothing is uploaded or downloaded — only the directory record
5769
+ * changes. Takes a reference, because a second path now depends on those
5770
+ * shards.
5771
+ */
5772
+ writeManifest(path: string, manifest: FileManifest, size: number): Promise<VfsStat>;
5773
+ /**
5774
+ * Create a directory. `recursive` creates missing parents and tolerates an
5775
+ * existing target, matching `mkdir -p`.
5776
+ */
5777
+ mkdir(path: string, opts?: {
5778
+ recursive?: boolean;
5779
+ }): Promise<void>;
5780
+ /**
5781
+ * Write a file, creating parent directories as needed.
5782
+ *
5783
+ * The previous version is pushed onto the file's history record before the
5784
+ * directory entry is replaced, so an interrupted write can lose the new
5785
+ * version but never the old one.
5786
+ */
5787
+ writeFile(path: string, data: Uint8Array | string | Blob, opts?: {
5788
+ type?: string;
5789
+ }): Promise<VfsStat>;
5790
+ /**
5791
+ * Delete a file, or a directory when `recursive`.
5792
+ *
5793
+ * `keepContent` removes the entry WITHOUT releasing its shards. A checkout
5794
+ * needs that: the file is leaving the working tree, but commits still
5795
+ * reference the same manifest, and releasing would free content history
5796
+ * depends on.
5797
+ */
5798
+ delete(path: string, opts?: {
5799
+ recursive?: boolean;
5800
+ keepContent?: boolean;
5801
+ }): Promise<void>;
5802
+ /**
5803
+ * Move or rename. Works across directories, which is the same operation:
5804
+ * detach the entry from one parent and attach it to another.
5805
+ *
5806
+ * A directory move is O(1) regardless of how much is inside it — the
5807
+ * subtree records are not touched at all, because nothing in them records
5808
+ * its own path.
5809
+ */
5810
+ rename(from: string, to: string): Promise<void>;
5811
+ /**
5812
+ * Copy a file or a directory tree.
5813
+ *
5814
+ * Copying a FILE moves no bytes: content is immutable and content-addressed,
5815
+ * so the new entry simply points at the same manifest. A 200 MB asset
5816
+ * duplicates in one small metadata write, and the shard store already holds
5817
+ * exactly one copy of it.
5818
+ *
5819
+ * The copy gets a NEW file id, so it does not inherit or share history —
5820
+ * two paths sharing an id would mean saving one silently pushed a version
5821
+ * onto the other.
5822
+ */
5823
+ copy(from: string, to: string): Promise<VfsStat>;
5824
+ /**
5825
+ * Paths matching a glob, relative to the whole filesystem.
5826
+ *
5827
+ * Matching happens on the client over a walk of the tree, so the cost is one
5828
+ * record fetch per directory — cheap for a project, and worth knowing before
5829
+ * pointing it at the root of a large filesystem. Use `walk` when the prefix
5830
+ * already narrows it.
5831
+ */
5832
+ glob(pattern: string, opts?: {
5833
+ from?: string;
5834
+ }): Promise<string[]>;
5835
+ /**
5836
+ * Delete metadata records no longer reachable from the root.
5837
+ *
5838
+ * These accumulate because every write touches exactly one record: if two
5839
+ * tabs edit the same directory, last-writer-wins at the personal space can
5840
+ * leave a child whose parent entry lost the race. Unreachable is harmless —
5841
+ * it is invisible and undecryptable-by-nobody — but it costs storage, so
5842
+ * this reclaims it.
5843
+ *
5844
+ * Deliberately explicit, never automatic: a sweep racing another tab's
5845
+ * in-flight write could delete a record that is about to be referenced.
5846
+ * Run it when the filesystem is idle.
5847
+ */
5848
+ sweep(opts?: {
5849
+ force?: boolean;
5850
+ }): Promise<{
5851
+ removed: string[];
5852
+ }>;
5853
+ /** Prior versions of a file, newest first. One record fetch. */
5854
+ history(path: string): Promise<Array<{
5855
+ size: number;
5856
+ mtime: number;
5857
+ }>>;
5858
+ /**
5859
+ * Restore a prior version, where 0 is the most recent one.
5860
+ *
5861
+ * The current version is pushed onto history first, so restoring is itself
5862
+ * undoable rather than a one-way door.
5863
+ */
5864
+ restore(path: string, index?: number): Promise<VfsStat>;
5865
+ private expectFile;
5866
+ /** Resolve a path to its entry, or null. Root has no entry of its own. */
5867
+ private find;
5868
+ private root;
5869
+ /** Open a directory by path, creating nothing. Throws if it is missing. */
5870
+ private openDir;
5871
+ private openDirOrNull;
5872
+ private openDirById;
5873
+ /** Apply an edit to a directory record and persist it. */
5874
+ private mutate;
5875
+ private createDir;
5876
+ /** Recursively remove a subtree's records. Best-effort: unreachable ≠ fatal. */
5877
+ private purge;
5878
+ /**
5879
+ * Deep-copy an entry. Files reuse their manifest (no bytes move); each
5880
+ * directory gets a fresh id and key, so the copy is independent of the
5881
+ * original — writing into one must never appear in the other.
5882
+ */
5883
+ private cloneEntry;
5884
+ /**
5885
+ * Let go of a file's bytes: the current manifest and every retained
5886
+ * version, then the history record itself.
5887
+ */
5888
+ private releaseFile;
5889
+ private readHistory;
5890
+ /** Push `entry` onto its history record. Returns the new version count. */
5891
+ private pushHistory;
5892
+ }
5893
+
5894
+ /**
5895
+ * Object model for version control over the VFS. See `docs/VCS_DESIGN.md`.
5896
+ *
5897
+ * Two spaces, deliberately: the WORKING TREE (`/apps/<slug>`) uses mutable
5898
+ * random directory ids so a file write touches one record; the REPOSITORY
5899
+ * (here) is content-addressed so a commit means the same thing forever. Git
5900
+ * makes the same split, for the same reason.
5901
+ */
5902
+
5903
+ /** A file in a commit. The manifest IS the content — there are no blob objects. */
5904
+ interface TreeFile {
5905
+ kind: "file";
5906
+ manifest: FileManifest;
5907
+ size: number;
5908
+ }
5909
+ /** A subdirectory, by the hash of its own tree object. */
5910
+ interface TreeDir {
5911
+ kind: "tree";
5912
+ hash: string;
5913
+ }
5914
+ type TreeEntry = TreeFile | TreeDir;
5915
+ /**
5916
+ * One directory, frozen.
5917
+ *
5918
+ * Addressed by the hash of its canonical form, so an unchanged directory has
5919
+ * the same hash in every commit containing it — a deep project costs one new
5920
+ * tree per CHANGED directory, not one per commit.
5921
+ */
5922
+ interface Tree {
5923
+ v: 1;
5924
+ entries: Record<string, TreeEntry>;
5925
+ }
5926
+ interface Commit {
5927
+ v: 1;
5928
+ /** Hash of the root tree. */
5929
+ tree: string;
5930
+ /**
5931
+ * Ancestors. An ARRAY because a merge has two; the first commit has none.
5932
+ * Order matters: `parents[0]` is the branch being committed onto.
5933
+ */
5934
+ parents: string[];
5935
+ message: string;
5936
+ author: string;
5937
+ at: number;
5938
+ }
5939
+ /** Where a branch points, or a specific commit when detached. */
5940
+ type Head = {
5941
+ branch: string;
5942
+ } | {
5943
+ detached: string;
5944
+ };
5945
+ /** A single change between two trees. */
5946
+ interface Change {
5947
+ path: string;
5948
+ kind: "added" | "removed" | "modified";
5949
+ }
5950
+ /** A path the merge could not settle on its own. */
5951
+ interface Conflict {
5952
+ path: string;
5953
+ /** `binary` cannot be merged at all — the user picks a side. */
5954
+ reason: "content" | "binary" | "modify-delete";
5955
+ }
5956
+ interface MergeResult {
5957
+ /** "up-to-date" and "fast-forward" do no three-way work at all. */
5958
+ kind: "up-to-date" | "fast-forward" | "merged" | "conflicted";
5959
+ commit?: string;
5960
+ conflicts: Conflict[];
5961
+ }
5962
+ interface LogEntry {
5963
+ hash: string;
5964
+ message: string;
5965
+ author: string;
5966
+ at: number;
5967
+ parents: string[];
5968
+ }
5969
+ /** Storage keys. Namespaced per project so repositories cannot collide. */
5970
+ declare const objectKey: (slug: string, hash: string) => string;
5971
+ declare const refKey: (slug: string, name: string) => string;
5972
+ declare const headKey: (slug: string) => string;
5973
+ declare const refsIndexKey: (slug: string) => string;
5974
+ /** An in-progress merge: what to make the second parent when it is committed. */
5975
+ declare const mergeKey: (slug: string) => string;
5976
+ declare const DEFAULT_BRANCH = "main";
5977
+ declare class VcsError extends Error {
5978
+ constructor(message: string);
5979
+ }
5980
+
5981
+ /**
5982
+ * `client.vcs` — version control for a project in the VFS.
5983
+ *
5984
+ * Phase 1: objects, commit, log, checkout, diff. Branches and merge build on
5985
+ * this; see `docs/VCS_DESIGN.md` for the whole shape and for why the repository
5986
+ * is content-addressed while the working tree is not.
5987
+ */
5988
+
5989
+ interface VcsNamespaceDeps {
5990
+ vfs: VfsNamespace;
5991
+ store: VfsStore;
5992
+ /** The key repository objects are sealed with — the project's own. */
5993
+ key: () => Promise<Uint8Array>;
5994
+ /** Who to record as the author. */
5995
+ author: () => string;
5996
+ }
5997
+ declare class Repo {
5998
+ private readonly slug;
5999
+ private readonly deps;
6000
+ constructor(slug: string, deps: VcsNamespaceDeps);
6001
+ private get root();
6002
+ /** Store an object, returning its hash and whether it was new. */
6003
+ private put;
6004
+ private get;
6005
+ private head;
6006
+ private setHead;
6007
+ private readRef;
6008
+ private writeRef;
6009
+ /** Every branch name in this repository. */
6010
+ branches(): Promise<string[]>;
6011
+ /** The commit HEAD resolves to, or null in an empty repository. */
6012
+ current(): Promise<string | null>;
6013
+ /**
6014
+ * Freeze the working tree as a commit.
6015
+ *
6016
+ * Trees are written bottom-up so a directory's hash is known before its
6017
+ * parent references it. Nothing is written to the shard store: file entries
6018
+ * carry the manifest the VFS already holds.
6019
+ */
6020
+ commit(message: string, parents?: string[]): Promise<string>;
6021
+ /** Move whatever HEAD points at onto a new commit. */
6022
+ private advance;
6023
+ /** The other side of a merge that stopped for conflicts, if any. */
6024
+ pendingMerge(): Promise<{
6025
+ theirs: string;
6026
+ name: string;
6027
+ } | null>;
6028
+ /** Write a directory and everything under it, returning the tree's hash. */
6029
+ private writeTree;
6030
+ /** Commits reachable from HEAD, newest first. */
6031
+ log(limit?: number): Promise<LogEntry[]>;
6032
+ /**
6033
+ * What changed between two commits.
6034
+ *
6035
+ * Identical subtree hashes prune the walk: an untouched directory is one
6036
+ * comparison regardless of how much is inside it. That is the payoff for
6037
+ * content-addressing the trees.
6038
+ */
6039
+ diff(fromHash: string | null, toHash: string): Promise<Change[]>;
6040
+ private diffTrees;
6041
+ /**
6042
+ * Replace the working tree with a commit's.
6043
+ *
6044
+ * Moves no file content: entries carry manifests the shard store already
6045
+ * holds, so this rewrites directory records only.
6046
+ */
6047
+ /**
6048
+ * What has changed since the last commit.
6049
+ *
6050
+ * Compares the WORKING TREE against HEAD without writing any objects: the
6051
+ * common case is answering "anything to commit?", and a `status` that
6052
+ * quietly stored a tree object every time would litter the repository with
6053
+ * trees for states nobody chose to keep.
6054
+ */
6055
+ status(): Promise<Change[]>;
6056
+ /** The working tree as a path → entry map, mirroring `filesOf`. */
6057
+ private workingFiles;
6058
+ /**
6059
+ * Turn what a person typed into a commit hash.
6060
+ *
6061
+ * Accepts a branch name, `HEAD`, a full or abbreviated hash, and trailing
6062
+ * `^` / `~n` to walk back through parents — so `show abc123^` means "the
6063
+ * commit before that one" the way anyone who has used git expects.
6064
+ */
6065
+ resolve(rev: string): Promise<string>;
6066
+ /** A hash prefix a person typed → the one commit it names. */
6067
+ private expand;
6068
+ /**
6069
+ * Put one file back to the way it was in a commit.
6070
+ *
6071
+ * Scoped to a path on purpose — recovering one file you broke should not
6072
+ * mean rewinding everything else you have done since.
6073
+ */
6074
+ restore(path: string, rev?: string): Promise<void>;
6075
+ checkout(commitHash: string, opts?: {
6076
+ discardChanges?: boolean;
6077
+ }): Promise<void>;
6078
+ /** Make the working tree match a commit, leaving HEAD alone. */
6079
+ private materialise;
6080
+ /** Project-relative path → absolute VFS path. */
6081
+ private abs;
6082
+ private collect;
6083
+ /** Create a branch at a commit (HEAD by default). Does not switch to it. */
6084
+ branch(name: string, at?: string): Promise<string>;
6085
+ /**
6086
+ * Move onto a branch, bringing the working tree with it.
6087
+ *
6088
+ * Unlike {@link checkout}, this ATTACHES head: later commits advance the
6089
+ * branch. Checking out a bare commit deliberately does not, so that
6090
+ * committing from a historical state cannot silently rewrite a branch.
6091
+ */
6092
+ switchTo(name: string, opts?: {
6093
+ discardChanges?: boolean;
6094
+ }): Promise<void>;
6095
+ /**
6096
+ * Refuse to overwrite work that was never recorded.
6097
+ *
6098
+ * Moving between commits REPLACES the working tree, so uncommitted edits
6099
+ * are gone — and unlike an ordinary overwrite, the person did not ask for
6100
+ * anything to be written. Naming the files is the point: "you have changes"
6101
+ * with no list leaves them guessing what they are about to lose.
6102
+ */
6103
+ private guardWorkingTree;
6104
+ /** The branch HEAD is on, or null when detached. */
6105
+ currentBranch(): Promise<string | null>;
6106
+ /**
6107
+ * Merge another branch into the current one.
6108
+ *
6109
+ * Every part of this is client-side by necessity: the server holds
6110
+ * ciphertext and cannot compare versions, so base, ours and theirs are all
6111
+ * fetched and decrypted here.
6112
+ */
6113
+ merge(name: string, opts?: {
6114
+ discardChanges?: boolean;
6115
+ }): Promise<MergeResult>;
6116
+ /** Decide one path. Returns a conflict when it cannot be settled. */
6117
+ private settlePath;
6118
+ private take;
6119
+ /**
6120
+ * The most recent commit reachable from both.
6121
+ *
6122
+ * Walks our ancestry into a set, then theirs breadth-first until it hits it —
6123
+ * so the first match is the nearest, which is what a three-way merge needs.
6124
+ */
6125
+ mergeBase(a: string, b: string): Promise<string | null>;
6126
+ /** Every file in a commit, by path. */
6127
+ private filesOf;
6128
+ }
6129
+ /**
6130
+ * Version control over the VFS.
6131
+ *
6132
+ * One repository per project, addressed by slug — the same slug the VFS stores
6133
+ * that project's working tree under. `client.vcs.open("my-app")` is the whole
6134
+ * entry point.
6135
+ */
6136
+ declare class VcsNamespace {
6137
+ private readonly deps;
6138
+ private readonly repos;
6139
+ constructor(deps: VcsNamespaceOptions);
6140
+ /** The repository for one project. Cheap and cached; creates nothing. */
6141
+ open(slug: string): Repo;
6142
+ }
6143
+ interface VcsNamespaceOptions {
6144
+ vfs: VfsNamespace;
6145
+ store: VfsStore;
6146
+ /** The in-memory master seed, or null when locked. Read per call. */
6147
+ seed: () => Uint8Array | null;
6148
+ author: () => string;
6149
+ }
6150
+
5382
6151
  /** The hosted Muhkoo Accelerator — the default {@link ClientOptions.baseUrl}. */
5383
6152
  declare const DEFAULT_BASE_URL = "https://api.muhkoo.dev";
5384
6153
  /** The hosted auth SPA — the default {@link ClientOptions.authBaseUrl}. */
@@ -5476,6 +6245,10 @@ declare class Client {
5476
6245
  readonly db: DbNamespace;
5477
6246
  /** File storage — `client.storage.writeFile(...)`, etc. */
5478
6247
  readonly storage: StorageNamespace;
6248
+ /** Filesystem over the personal space: directories, versions, real paths. */
6249
+ readonly vfs: VfsNamespace;
6250
+ /** Version control over the VFS: commits, branches, merges — per project. */
6251
+ readonly vcs: VcsNamespace;
5479
6252
  /** Realtime messaging — `client.message.subscribe(...)`, etc. */
5480
6253
  readonly message: MessageNamespace;
5481
6254
  /** Fan-out group spaces — `client.space.createSpace(...)`, etc. */
@@ -5669,6 +6442,47 @@ declare function loadDeviceIdentity(): Promise<PersistedDeviceIdentity | null>;
5669
6442
  */
5670
6443
  declare function clearDeviceIdentity(): Promise<void>;
5671
6444
 
6445
+ /**
6446
+ * Three-way line merge.
6447
+ *
6448
+ * Given a common ancestor and two descendants, produce the combined text — or
6449
+ * report the regions where both sides changed the same lines differently.
6450
+ *
6451
+ * The server cannot do any of this: it holds ciphertext and cannot compare
6452
+ * versions, so merging is entirely a client concern and has to be exact here.
6453
+ */
6454
+ interface MergeRegionConflict {
6455
+ /** 1-based line where the conflict begins in the merged output. */
6456
+ line: number;
6457
+ ours: string[];
6458
+ theirs: string[];
6459
+ }
6460
+ interface Merge3Result {
6461
+ lines: string[];
6462
+ conflicts: MergeRegionConflict[];
6463
+ }
6464
+ /**
6465
+ * Merge `ours` and `theirs` over their common ancestor `base`.
6466
+ *
6467
+ * A region where only one side changed takes that side. A region where both
6468
+ * made the SAME change takes it once — two people fixing the same typo is not a
6469
+ * conflict. Only genuinely divergent edits conflict.
6470
+ */
6471
+ declare function merge3(base: string[], ours: string[], theirs: string[]): Merge3Result;
6472
+ /**
6473
+ * Merge to text, writing conflict markers where the sides diverged.
6474
+ *
6475
+ * Markers rather than a bespoke format: they are what every developer already
6476
+ * knows how to resolve, and resolving becomes ordinary editing.
6477
+ */
6478
+ declare function merge3Text(base: string, ours: string, theirs: string, labels?: {
6479
+ ours: string;
6480
+ theirs: string;
6481
+ }): {
6482
+ text: string;
6483
+ conflicted: boolean;
6484
+ };
6485
+
5672
6486
  /**
5673
6487
  * Passkey factor (M1.1) — WebAuthn with the **PRF extension**.
5674
6488
  *
@@ -6659,5 +7473,5 @@ declare class KeyringClient implements KeyringTransport {
6659
7473
  fetchMetadata(): Promise<SpaceMetadata | null>;
6660
7474
  }
6661
7475
 
6662
- export { ACCESS_TOKEN_SCOPES, AES_GCM_IV_BYTES, AES_GCM_KEY_BYTES, AES_GCM_TAG_BYTES, AccessTokensNamespace, AgentsNamespace, AuthClient, AuthNamespace, AuthPublicInput, Authenticator, BlockEngine, BroadcastChannel, BroadcastChannelEvents, ChannelExistsError, ChannelNotFoundError, ChunkCipher, Client, ConnectivityManager, DEFAULT_AUTH_BASE_URL, DEFAULT_BASE_URL, DEFAULT_FN_HOST_SUFFIX, DEVICE_IDENTITY_STORAGE_KEY, DEVICE_KEY_DB_NAME, DbCache, DevicePairingError, DeviceStoreUnavailableError, DoubleRatchet, DoubleRatchetCipher, DoubleRatchetManager, EncryptedSession, EventCore, EventCoreEvents, Field, Field as FieldElement, FileStorage, FunctionsNamespace, HLC, HashKnowledge, HostedAuth, HttpClient, HttpError, IndexedDbStore, KEEPER_MEMBER_ID, KeyStore, KeyringClient, KvCache, KvNamespace, LocalEngineHost, LocalStorageSessionStore, MemorySessionStore, Message, Message as MessageDefault, MessageNamespace, MuhkooAgent, MuhkooDB, MuhkooFunction, MuhkooSpace, NoopStore, OfflineLockedError, OfflineManager, OutboundQueue, P2P_SUBJECT, PAIRING_CODE_ALPHABET, PAIRING_CODE_LENGTH, PBKDF2_DEFAULT_ITERATIONS, PREIMAGE_POK_VERIFICATION_KEY, Packet, PasskeyOriginError, PeerExchange, PeerNetwork, PersonalSpaceClient, Poseidon, PreimagePoK, ReauthRequiredError, ReedSolomonCodec, Space as Room, SerializeMessage, SessionState, ShardCache, ShardClient, SharedSpaceClient, SnapshotNamespace, Space, SpaceCache, SpaceKeyring, SpaceNamespace, SpacePacketCipher, SpaceSignaler, StorageNamespace, SyncEngine, VaultUnavailableError, WSTransport, WebRtcTransport, WorkerEngineHost, ZERO_HLC, ZkAuth, buildCommitment, canonicalUserCode, clearDeviceIdentity, compareHlc, compilePrograms, configureDeviceStore, createPasskeyWithPrf, decodeFromHex, decorators, decryptAesGcm, defaultCircuitUrls, defaultRpId, defaultSessionStore, deleteBeatsWrite, deleteRegister, deriveAesKeyFromPassphrase, deriveBitsHkdf, deriveIdentity, deriveIdentityFromSeed, deriveMasterSeedFromPassword, deviceFingerprint, deviceIdentityIsEphemeral, deviceIdentityKey, ejectAgentPrompt, ejectAgentTools, emptyMap, emptyRegister, encodeToHex, encryptAesGcm, evaluatePasskeyPrf, exportPublicKeyBase64, exportPublicKeyHex, formatUserCode, generateAuthProof, generateDevicePairingKeypair, generatePkce, getMuhkooAppDescriptor, getSubtle, hasDeviceIdentity, initBn128Wasm, initRsWasm, initializeCircuits, isNewer, isOfflineCapable, isP2pCapable, isProvisional, loadDeviceIdentity, manifestToStat, materializeRow, mergeMap, mergeMessage, mergeRegister, messageKey, pack, padHandle, pairingVerificationCode, passkeyPrfCapable, passkeySupported, passkeyUsableFromOrigin, persistDeviceIdentity, poseidonHash, protocol, provisionalHandle, quickVerify, randomBytes, randomState, rpIdUsableForOrigin, sealSeed, sealSeedToDevice, shardHash, signMessage, stableStringify, toField, tombstoneRow, unpack, unsealSeed, unsealSeedFromDevice, unwrapWithPassphrase, verify, verifyGroth16, verifyHashKnowledge, verifyPreimagePoK, wrapWithPassphrase, writeBeatsTombstone, writeColumns, writeRegister };
6663
- export type { ACL, ACLEntry, AccessTokenInfo, AccessTokensNamespaceDeps, AgentConfig, AgentCreateInput, AgentDbToolMode, AgentProvisioned, AgentScopeOpts, AgentSkill, AgentToolsConfig, AgentTrigger, AgentTriggerType, AgentUpdateInput, AgentsNamespaceDeps, AttachedPeerNetwork, AuthClientOptions, AuthKeyPair, AuthSuccess, AuthToken, AuthType, AuthUser, BlockStore, Bn128WasmInstance, BroadcastChannelEvent, BroadcastChannelOptions, CachedSpaceMessage, ChannelLike, ChunkKeyMaterial, ChunkManifest, CipherFrame, CipherMessage, CipherMessageHeader, CircuitBufferConfig, CircuitUrls, ClientOptions, ConnectivityOptions, ConnectivityState, CreateAccessTokenInput, CreatedAccessToken, DbQueryPage, DehydratedKeypair, DehydratedKeys, DeviceBlobStore, DeviceKeyVault, DevicePairingErrorReason, DevicePairingKeypair, DevicePairingPoll, DevicePairingRequest, DevicePairingSession, DoubleRatchetCipherDeps, ECDHCurve, EncodeResult, EngineHandle, EngineHost, EphemeralEvent, EpochKeyProvider, FileManifest, FileNamespaceDeps, FileStat, FileStorageOptions, FunctionCaps, FunctionConfig, FunctionDeployInput, FunctionInvokeOptions, FunctionScopeOpts, FunctionTrigger, FunctionTriggerType, FunctionTriggers, FunctionUpdateInput, FunctionsNamespaceDeps, Groth16Proof, Hasher, HlcParts, HlcState, HostedAuthDeps, HttpClientOptions, IncomingFrame, KeyExchangeFrame, KeyPair, Keypair, KeyringClientDeps, KeyringTransport, KvEntry, KvNamespaceDeps, LoginOptions, LwwMap, LwwRegister, MessageBody, MessageDeletedEvent, MessageEntry, MessageEvent, MessageHeaders, MessageNamespaceDeps, MessageOp, MessageOptions, MessageSubscription, MuhkooAgentMeta, MuhkooAgentToolsConfig, MuhkooAppDescriptor, MuhkooDBAccess, MuhkooDBMeta, MuhkooFunctionMeta, MuhkooKeystoreBridge, MuhkooMessageEvent, MuhkooSpaceMeta, OAuthProvider, OfflineEntry, OfflineManagerDeps, OfflineStore, OutSink, PacketCipher, PacketHeaders, PacketOptions, PairedDevice, Participant, PasskeyEnrollment, PeerBlockSource, PeerExchangeOptions, PeerId, PeerNetworkOptions, PeerTransport, Permission, PermissionCheckRequest, PermissionCheckResult, PersistedDeviceIdentity, PersonalSpaceClientOptions, Pkce, PublicKeyJWK, QueueEntry, RatchetState, ReceiveResult, RegisterParams, Replayer, Role, SpaceDeps as RoomDeps, SpaceFileMetadata as RoomFileMetadata, Scope, SealedHandoff, SealedHeaders, Session, SessionOptions, SessionStore, SetOptions, ShardByteCache, ShardClientOptions, SharedSpaceClientOptions, SignalEnvelope, SignalKind, SignalingSpace, SnapshotNamespaceDeps, SnarkProof, SpaceChannelLike, SpaceCursor, SpaceDeps, SpaceFileMetadata, SpaceKeyCache, SpaceKeyringDeps, SpaceMessageEvent, SpaceNamespaceDeps, SpaceOfflineAdapter, StartDevicePairingOptions, StorageChangeEvent, StoreName, StoredSession, Subscription, UserIdentity, VaultFactor, VerificationKey, WSMessage, WSMessageType, WSTransportOptions, WaitForDevicePairingOptions, WebRtcTransportOptions, WrappedPayload, WriteFileInput, WriteFileOptions, WriteToShardsInput, ZkAuthDeps, ZkAuthenticateRequest, ZkChallengeResponse, ZkCompiled, ZkIdentity, ZkRegisterRequest, ZkRegisterResponse };
7476
+ export { ACCESS_TOKEN_SCOPES, AES_GCM_IV_BYTES, AES_GCM_KEY_BYTES, AES_GCM_TAG_BYTES, AccessTokensNamespace, AgentsNamespace, AuthClient, AuthNamespace, AuthPublicInput, Authenticator, BlockEngine, BroadcastChannel, BroadcastChannelEvents, ChannelExistsError, ChannelNotFoundError, ChunkCipher, Client, ConnectivityManager, DEFAULT_AUTH_BASE_URL, DEFAULT_BASE_URL, DEFAULT_BRANCH, DEFAULT_FN_HOST_SUFFIX, DEVICE_IDENTITY_STORAGE_KEY, DEVICE_KEY_DB_NAME, DbCache, DevicePairingError, DeviceStoreUnavailableError, DoubleRatchet, DoubleRatchetCipher, DoubleRatchetManager, EncryptedSession, EventCore, EventCoreEvents, Field, Field as FieldElement, FileStorage, FunctionsNamespace, HLC, HashKnowledge, HostedAuth, HttpClient, HttpError, IndexedDbStore, KEEPER_MEMBER_ID, KeyStore, KeyringClient, KvCache, KvNamespace, LocalEngineHost, LocalStorageSessionStore, MemorySessionStore, Message, Message as MessageDefault, MessageNamespace, MuhkooAgent, MuhkooDB, MuhkooFunction, MuhkooSpace, NoopStore, OfflineLockedError, OfflineManager, OutboundQueue, P2P_SUBJECT, PAIRING_CODE_ALPHABET, PAIRING_CODE_LENGTH, PBKDF2_DEFAULT_ITERATIONS, PREIMAGE_POK_VERIFICATION_KEY, Packet, PasskeyOriginError, PeerExchange, PeerNetwork, PersonalSpaceClient, Poseidon, PreimagePoK, ROOT_ID, ReauthRequiredError, ReedSolomonCodec, Repo, Space as Room, SerializeMessage, SessionState, ShardCache, ShardClient, SharedSpaceClient, SnapshotNamespace, Space, SpaceCache, SpaceKeyring, SpaceNamespace, SpacePacketCipher, SpaceSignaler, StorageNamespace, SyncEngine, VFS_ROOT_INFO, VaultUnavailableError, VcsError, VcsNamespace, VfsConflictError, VfsLockedError, VfsNamespace, VfsNotFoundError, WSTransport, WebRtcTransport, WorkerEngineHost, ZERO_HLC, ZkAuth, buildCommitment, canonicalUserCode, clearDeviceIdentity, compareHlc, compilePrograms, configureDeviceStore, createPasskeyWithPrf, decodeFromHex, decorators, decryptAesGcm, defaultCircuitUrls, defaultRpId, defaultSessionStore, deleteBeatsWrite, deleteRegister, deriveAesKeyFromPassphrase, deriveBitsHkdf, deriveIdentity, deriveIdentityFromSeed, deriveMasterSeedFromPassword, deviceFingerprint, deviceIdentityIsEphemeral, deviceIdentityKey, dirKey, ejectAgentPrompt, ejectAgentTools, emptyMap, emptyRegister, encodeToHex, encryptAesGcm, evaluatePasskeyPrf, exportPublicKeyBase64, exportPublicKeyHex, formatUserCode, generateAuthProof, generateDevicePairingKeypair, generatePkce, getMuhkooAppDescriptor, getSubtle, hasDeviceIdentity, headKey, historyKey, initBn128Wasm, initRsWasm, initializeCircuits, isNewer, isOfflineCapable, isP2pCapable, isProvisional, loadDeviceIdentity, manifestToStat, materializeRow, merge3, merge3Text, mergeKey, mergeMap, mergeMessage, mergeRegister, messageKey, objectKey, pack, padHandle, pairingVerificationCode, passkeyPrfCapable, passkeySupported, passkeyUsableFromOrigin, persistDeviceIdentity, poseidonHash, protocol, provisionalHandle, quickVerify, randomBytes, randomState, refKey, refsIndexKey, rpIdUsableForOrigin, sealSeed, sealSeedToDevice, shardHash, signMessage, stableStringify, toField, tombstoneRow, unpack, unsealSeed, unsealSeedFromDevice, unwrapWithPassphrase, verify, verifyGroth16, verifyHashKnowledge, verifyPreimagePoK, wrapWithPassphrase, writeBeatsTombstone, writeColumns, writeRegister };
7477
+ export type { ACL, ACLEntry, AccessTokenInfo, AccessTokensNamespaceDeps, AgentConfig, AgentCreateInput, AgentDbToolMode, AgentProvisioned, AgentScopeOpts, AgentSkill, AgentToolsConfig, AgentTrigger, AgentTriggerType, AgentUpdateInput, AgentsNamespaceDeps, AttachedPeerNetwork, AuthClientOptions, AuthKeyPair, AuthSuccess, AuthToken, AuthType, AuthUser, BlockStore, Bn128WasmInstance, BroadcastChannelEvent, BroadcastChannelOptions, CachedSpaceMessage, Change, ChannelLike, ChunkKeyMaterial, ChunkManifest, CipherFrame, CipherMessage, CipherMessageHeader, CircuitBufferConfig, CircuitUrls, ClientOptions, Commit, Conflict, ConnectivityOptions, ConnectivityState, CreateAccessTokenInput, CreatedAccessToken, DbQueryPage, DehydratedKeypair, DehydratedKeys, DeviceBlobStore, DeviceKeyVault, DevicePairingErrorReason, DevicePairingKeypair, DevicePairingPoll, DevicePairingRequest, DevicePairingSession, DirEntry, DirNode, DoubleRatchetCipherDeps, ECDHCurve, EncodeResult, EngineHandle, EngineHost, Entry, EphemeralEvent, EpochKeyProvider, FileEntry, FileManifest, FileNamespaceDeps, FileStat, FileStorageOptions, FunctionCaps, FunctionConfig, FunctionDeployInput, FunctionInvokeOptions, FunctionScopeOpts, FunctionTrigger, FunctionTriggerType, FunctionTriggers, FunctionUpdateInput, FunctionsNamespaceDeps, Groth16Proof, Hasher, Head, HistoryRecord, HlcParts, HlcState, HostedAuthDeps, HttpClientOptions, IncomingFrame, KeyExchangeFrame, KeyPair, Keypair, KeyringClientDeps, KeyringTransport, KvEntry, KvNamespaceDeps, LogEntry, LoginOptions, LwwMap, LwwRegister, Merge3Result, MergeRegionConflict, MergeResult, MessageBody, MessageDeletedEvent, MessageEntry, MessageEvent, MessageHeaders, MessageNamespaceDeps, MessageOp, MessageOptions, MessageSubscription, MuhkooAgentMeta, MuhkooAgentToolsConfig, MuhkooAppDescriptor, MuhkooDBAccess, MuhkooDBMeta, MuhkooFunctionMeta, MuhkooKeystoreBridge, MuhkooMessageEvent, MuhkooSpaceMeta, OAuthProvider, OfflineEntry, OfflineManagerDeps, OfflineStore, OutSink, PacketCipher, PacketHeaders, PacketOptions, PairedDevice, Participant, PasskeyEnrollment, PeerBlockSource, PeerExchangeOptions, PeerId, PeerNetworkOptions, PeerTransport, Permission, PermissionCheckRequest, PermissionCheckResult, PersistedDeviceIdentity, PersonalSpaceClientOptions, Pkce, PublicKeyJWK, QueueEntry, RatchetState, ReceiveResult, RegisterParams, Replayer, Role, SpaceDeps as RoomDeps, SpaceFileMetadata as RoomFileMetadata, Scope, SealedHandoff, SealedHeaders, SealedRecord, Session, SessionOptions, SessionStore, SetOptions, ShardByteCache, ShardClientOptions, SharedSpaceClientOptions, SignalEnvelope, SignalKind, SignalingSpace, SnapshotNamespaceDeps, SnarkProof, SpaceChannelLike, SpaceCursor, SpaceDeps, SpaceFileMetadata, SpaceKeyCache, SpaceKeyringDeps, SpaceMessageEvent, SpaceNamespaceDeps, SpaceOfflineAdapter, StartDevicePairingOptions, StorageChangeEvent, StoreName, StoredSession, Subscription, Tree, TreeDir, TreeEntry, TreeFile, UserIdentity, VaultFactor, VcsNamespaceDeps, VcsNamespaceOptions, VerificationKey, VfsContentStore, VfsNamespaceDeps, VfsStat, VfsStore, WSMessage, WSMessageType, WSTransportOptions, WaitForDevicePairingOptions, WebRtcTransportOptions, WrappedPayload, WriteFileInput, WriteFileOptions, WriteToShardsInput, ZkAuthDeps, ZkAuthenticateRequest, ZkChallengeResponse, ZkCompiled, ZkIdentity, ZkRegisterRequest, ZkRegisterResponse };