@muhkoo/connect 0.3.0-alpha.0 → 0.6.0-alpha.1

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
@@ -936,6 +936,14 @@ declare class EncryptedSession {
936
936
  interface WSTransportOptions {
937
937
  /** WebSocket URL, e.g. `ws://localhost:8787/foo`. */
938
938
  url: string;
939
+ /**
940
+ * Optional async provider for a FRESH connection URL, called before each
941
+ * RECONNECT. Use it when the URL carries a single-use/expiring credential
942
+ * (e.g. a one-time WS upgrade ticket): on reconnect the baked-in ticket is
943
+ * already consumed/expired, so without this the reconnect is rejected and the
944
+ * transport burns through its attempts. The initial connect uses `url` as-is.
945
+ */
946
+ urlProvider?: () => string | Promise<string>;
939
947
  /**
940
948
  * Stable identifier for this connection (a channel / space / personal-space
941
949
  * id). Lifecycle + MESSAGE events are namespaced by it on the shared
@@ -991,6 +999,7 @@ declare class WSTransport extends EventCore {
991
999
  readonly off: (event: EventCoreEvents, handler: EventListener | CallableFunction) => void;
992
1000
  private scopedEvent;
993
1001
  private url;
1002
+ private urlProvider?;
994
1003
  private socket;
995
1004
  private _isConnected;
996
1005
  private _isConnecting;
@@ -1586,6 +1595,12 @@ interface WriteToShardsInput {
1586
1595
  * resumable uploads: the same id always maps to the same manifest slot.
1587
1596
  */
1588
1597
  fileId?: string;
1598
+ /**
1599
+ * Optional upload-progress callback, invoked after each chunk finishes
1600
+ * (`completed` of `total` chunks). Lets a UI show a progress bar. Called once
1601
+ * with `(0, total)` before the first chunk so a bar can render immediately.
1602
+ */
1603
+ onProgress?: (completed: number, total: number) => void;
1589
1604
  }
1590
1605
  declare class FileStorage {
1591
1606
  private readonly space;
@@ -2279,6 +2294,7 @@ declare class HttpClient {
2279
2294
  readonly fetch: typeof fetch;
2280
2295
  get<T = unknown>(path: string): Promise<T>;
2281
2296
  post<T = unknown>(path: string, body?: unknown): Promise<T>;
2297
+ patch<T = unknown>(path: string, body?: unknown): Promise<T>;
2282
2298
  del<T = unknown>(path: string, body?: unknown): Promise<T>;
2283
2299
  private request;
2284
2300
  }
@@ -2357,6 +2373,101 @@ declare class KvNamespace {
2357
2373
  private getCipher;
2358
2374
  }
2359
2375
 
2376
+ /**
2377
+ * `client.db` — the app's scalable database. A developer defines tables in the
2378
+ * Muhkoo portal (columns + indexes); each table is backed by its own Durable
2379
+ * Object SQLite instance and reachable through a sanitized REST gateway. This
2380
+ * namespace wraps that gateway:
2381
+ *
2382
+ * const todos = client.db.table('todos');
2383
+ * const { id } = await todos.insert({ title: 'Buy milk', done: false });
2384
+ * const one = await todos.get(id);
2385
+ * const { rows, nextCursor } = await todos.query({
2386
+ * where: [{ column: 'done', op: 'eq', value: false }],
2387
+ * orderBy: { column: 'rank', dir: 'asc' },
2388
+ * limit: 50,
2389
+ * });
2390
+ * await todos.update(id, { done: true });
2391
+ * await todos.delete(id);
2392
+ *
2393
+ * Authorization is the **app key** ({@link HttpClient} stamps it on every
2394
+ * request); the appId + environment are resolved server-side from the key, so a
2395
+ * key can only ever reach its own app's tables. The front end never touches the
2396
+ * database directly — this REST surface is the only gateway, and all input is
2397
+ * validated against the table's schema (parameterized statements, column +
2398
+ * operator allowlists). There is no raw-SQL passthrough.
2399
+ *
2400
+ * Schema is authored in the portal, not here (the SDK reads + writes rows, it
2401
+ * doesn't create tables). Pagination is keyset-based: pass the `nextCursor` from
2402
+ * a previous `query()` back as `cursor` to fetch the next page.
2403
+ */
2404
+
2405
+ interface DbNamespaceDeps {
2406
+ http: HttpClient;
2407
+ }
2408
+ /** Comparison operators allowed in a {@link DbQuery} `where` clause. */
2409
+ type DbFilterOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "like" | "likeStartsWith" | "likeContains";
2410
+ interface DbWhereCondition {
2411
+ column: string;
2412
+ op: DbFilterOp;
2413
+ /** Scalar for most ops; an array for `in`; a string for the `like` family. */
2414
+ value: unknown;
2415
+ }
2416
+ interface DbQuery {
2417
+ /** Columns to return; omit for all columns. */
2418
+ select?: string[];
2419
+ /** Conditions AND-combined. */
2420
+ where?: DbWhereCondition[];
2421
+ /** Sort by a column (defaults to the primary key, ascending). */
2422
+ orderBy?: {
2423
+ column: string;
2424
+ dir?: "asc" | "desc";
2425
+ };
2426
+ /** Page size, clamped server-side to 100. */
2427
+ limit?: number;
2428
+ /** Opaque keyset cursor from a previous query's `nextCursor`. */
2429
+ cursor?: string;
2430
+ }
2431
+ interface DbQueryResult<T = Record<string, unknown>> {
2432
+ rows: T[];
2433
+ /** Cursor for the next page, or `null` when the last page was returned. */
2434
+ nextCursor: string | null;
2435
+ }
2436
+ /** A handle to one table — the ergonomic surface for row operations. */
2437
+ declare class DbTable<T extends Record<string, unknown> = Record<string, unknown>> {
2438
+ private readonly http;
2439
+ private readonly name;
2440
+ constructor(http: HttpClient, name: string);
2441
+ private base;
2442
+ /** Insert a row. Returns the created row and its primary-key value. */
2443
+ insert(values: Partial<T>): Promise<{
2444
+ row: T;
2445
+ id: unknown;
2446
+ }>;
2447
+ /** Fetch a row by primary key, or `null` if it doesn't exist. */
2448
+ get(id: string | number): Promise<T | null>;
2449
+ /** Query rows with filters, ordering, and keyset pagination. */
2450
+ query(query?: DbQuery): Promise<DbQueryResult<T>>;
2451
+ /** Update a row by primary key. Returns the updated row. */
2452
+ update(id: string | number, values: Partial<T>): Promise<{
2453
+ row: T;
2454
+ }>;
2455
+ /** Delete a row by primary key. Returns the number of rows removed (0 or 1). */
2456
+ delete(id: string | number): Promise<number>;
2457
+ }
2458
+ declare class DbNamespace {
2459
+ private readonly deps;
2460
+ constructor(deps: DbNamespaceDeps);
2461
+ /**
2462
+ * A handle to a table defined in the portal. The optional type parameter
2463
+ * gives row operations a typed shape:
2464
+ *
2465
+ * interface Todo { _id: number; title: string; done: boolean }
2466
+ * const todos = client.db.table<Todo>('todos');
2467
+ */
2468
+ table<T extends Record<string, unknown> = Record<string, unknown>>(name: string): DbTable<T>;
2469
+ }
2470
+
2360
2471
  /**
2361
2472
  * `client.storage` — file storage. Hides the `FileStorage` / `ShardClient` /
2362
2473
  * `SharedSpaceClient` primitives behind the unified client.
@@ -2516,6 +2627,23 @@ interface RosterMember {
2516
2627
  /** Base64url-encoded JWK of the member's identity ECDSA public key. */
2517
2628
  identityEcdsaPub?: string;
2518
2629
  }
2630
+ /** A shareable invite link to a space. Redeeming it allowlists the holder so
2631
+ * the keeper admits them. */
2632
+ interface InviteLink {
2633
+ /** The capability token; embed in a URL to share. */
2634
+ token: string;
2635
+ /** Member id (username) that created the link. */
2636
+ createdBy?: string;
2637
+ createdAt?: number;
2638
+ /** Epoch ms when the link stops working; 0 = never. */
2639
+ expiresAt?: number;
2640
+ /** Max redemptions; 0 = unlimited. */
2641
+ maxUses?: number;
2642
+ /** Redemptions so far. */
2643
+ uses?: number;
2644
+ /** Access level granted to redeemers ("viewer" | "editor"). */
2645
+ role?: string;
2646
+ }
2519
2647
 
2520
2648
  /**
2521
2649
  * PacketCipher — the strategy `Network` uses to seal/open a packet's payload.
@@ -2929,7 +3057,9 @@ declare class Space {
2929
3057
  memberId: string;
2930
3058
  identityEcdhPub: string;
2931
3059
  }>): Promise<number>;
2932
- putFile(file: File | Blob | Uint8Array, metadata: SpaceFileMetadata): Promise<{
3060
+ putFile(file: File | Blob | Uint8Array, metadata: SpaceFileMetadata, opts?: {
3061
+ onProgress?: (completed: number, total: number) => void;
3062
+ }): Promise<{
2933
3063
  manifest: FileManifest;
2934
3064
  stat: FileStat;
2935
3065
  }>;
@@ -3135,6 +3265,40 @@ declare class SpaceNamespace {
3135
3265
  joinChannel(name: string, opts?: {
3136
3266
  timeoutMs?: number;
3137
3267
  }): Promise<Space>;
3268
+ /** Mint a shareable invite link for a space. `opts.expiresInSec` / `maxUses`
3269
+ * bound it (0/undefined = unlimited); `opts.role` ("viewer"|"editor") is the
3270
+ * access granted to redeemers (default viewer). Returns the link. */
3271
+ createInviteLink(spaceId: string, opts?: {
3272
+ expiresInSec?: number;
3273
+ maxUses?: number;
3274
+ role?: string;
3275
+ }): Promise<InviteLink>;
3276
+ /** Set a member's role on a space ("viewer" | "editor"). Owner-only. */
3277
+ setMemberRole(spaceId: string, username: string, role: string): Promise<void>;
3278
+ /** Roster with roles (owner/members only). */
3279
+ members(spaceId: string): Promise<Array<{
3280
+ memberId: string;
3281
+ role: string;
3282
+ }>>;
3283
+ /** List a space's active invite links (creator/members only). */
3284
+ listInviteLinks(spaceId: string): Promise<InviteLink[]>;
3285
+ /** Revoke an invite link by token. */
3286
+ revokeInviteLink(spaceId: string, token: string): Promise<void>;
3287
+ /**
3288
+ * Join a space using an invite link: redeem the token (the keeper admits
3289
+ * this member), then connect and resolve once the group key arrives.
3290
+ * Returns the open {@link Space}.
3291
+ */
3292
+ joinByInvite(spaceId: string, token: string, opts?: {
3293
+ timeoutMs?: number;
3294
+ }): Promise<Space>;
3295
+ /** The current member roster of a space (member id → identity public keys). */
3296
+ roster(spaceId: string): Promise<Array<{
3297
+ memberId: string;
3298
+ identityEcdhPub: string;
3299
+ identityEcdsaPub?: string;
3300
+ }>>;
3301
+ private keyringFor;
3138
3302
  private build;
3139
3303
  /** Ensure the member has an identity keypair; return its public ECDH + ECDSA keys. */
3140
3304
  private ensureIdentity;
@@ -3143,6 +3307,270 @@ declare class SpaceNamespace {
3143
3307
  private myId;
3144
3308
  }
3145
3309
 
3310
+ /**
3311
+ * `client.agents` — manage an app's **Programmable Agents** (server-side
3312
+ * "virtual users" backed by Workers AI).
3313
+ *
3314
+ * const { config } = await client.agents.create(appId, {
3315
+ * handle: '@assistant', displayName: 'Assistant',
3316
+ * systemPrompt: 'You are a helpful teammate in this Space.',
3317
+ * triggers: [{ type: 'mention' }],
3318
+ * });
3319
+ * await client.agents.enable(appId, config.agentId, spaceId); // per-Space opt-in
3320
+ *
3321
+ * These are MANAGEMENT calls — the agent itself runs on the accelerator. Only an
3322
+ * app's owner or an editor of its shared Space may create/update/enable an agent
3323
+ * (viewers can read). Authorization rides the user session token; non-owner
3324
+ * editors pass their management Space via `opts.space`.
3325
+ *
3326
+ * An agent is "prompts + persona": a system prompt, a model, named prompt
3327
+ * `skills`, and `triggers` that decide when it speaks — plus optional `tools`
3328
+ * that let it act on the app (query/write its database, call its functions,
3329
+ * resolve its channels) via a server-side function-calling loop. See
3330
+ * {@link AgentToolsConfig}. Pair with the `@MuhkooAgent`/`@MuhkooSpace`/
3331
+ * `@MuhkooDB`/`@MuhkooFunction` decorators + `ejectAgentPrompt`/`ejectAgentTools`
3332
+ * to generate `systemPrompt` and `tools` straight from your app's surface.
3333
+ */
3334
+
3335
+ type AgentTriggerType = "mention" | "keyword" | "regex" | "always";
3336
+ /** How much database access the agent's tool-use has. */
3337
+ type AgentDbToolMode = "off" | "read" | "write";
3338
+ /**
3339
+ * Tool-use config — lets the agent act on the app through a function-calling
3340
+ * loop. Opt-in and conservatively gated server-side: a fresh agent has tools
3341
+ * off, the DB is read-only and per-table allowlisted, functions are per-name
3342
+ * allowlisted, and channels are off. **Enabling tools requires a
3343
+ * function-calling `model` in the same create/update payload** (the server
3344
+ * rejects `enabled: true` otherwise). `ejectAgentTools` produces this shape.
3345
+ */
3346
+ interface AgentToolsConfig {
3347
+ enabled: boolean;
3348
+ db: {
3349
+ /** `off` = no DB tools; `read` = query/get; `write` = + insert/update/delete. */
3350
+ mode: AgentDbToolMode;
3351
+ /** Allowlisted table names the agent may touch. */
3352
+ tables: string[];
3353
+ };
3354
+ /** Allowlisted serverless-function names the agent may call. */
3355
+ functions: string[];
3356
+ /** Whether the agent may resolve the app's PUBLIC channels. */
3357
+ channels: boolean;
3358
+ /** Max tool-call rounds per reply (1..6). */
3359
+ maxIterations: number;
3360
+ }
3361
+ interface AgentTrigger {
3362
+ type: AgentTriggerType;
3363
+ /** Required for `keyword` (case-insensitive substring) and `regex`. */
3364
+ pattern?: string;
3365
+ /** Name of a {@link AgentSkill} to run on match. */
3366
+ skill?: string;
3367
+ }
3368
+ interface AgentSkill {
3369
+ name: string;
3370
+ prompt: string;
3371
+ }
3372
+ interface AgentConfig {
3373
+ agentId: string;
3374
+ /** @-mention target, e.g. "@assistant". */
3375
+ handle: string;
3376
+ displayName: string;
3377
+ model: string;
3378
+ systemPrompt: string;
3379
+ skills: AgentSkill[];
3380
+ triggers: AgentTrigger[];
3381
+ /** Space ids this agent is enabled on (per-Space opt-in). */
3382
+ enabledSpaces: string[];
3383
+ caps: {
3384
+ dailyTokenBudget: number;
3385
+ };
3386
+ /** Tool-use config (absent / `enabled: false` = prompt-only). */
3387
+ tools?: AgentToolsConfig;
3388
+ createdAt: number;
3389
+ updatedAt: number;
3390
+ }
3391
+ /** The editor-settable fields when creating an agent. */
3392
+ interface AgentCreateInput {
3393
+ handle: string;
3394
+ displayName: string;
3395
+ systemPrompt: string;
3396
+ model?: string;
3397
+ skills?: AgentSkill[];
3398
+ triggers?: AgentTrigger[];
3399
+ caps?: {
3400
+ dailyTokenBudget: number;
3401
+ };
3402
+ /** Grant tool-use. Requires `model` to be a function-calling model. */
3403
+ tools?: AgentToolsConfig;
3404
+ }
3405
+ type AgentUpdateInput = Partial<AgentCreateInput>;
3406
+ /** Create/get response — the config plus the agent's published identity keys. */
3407
+ interface AgentProvisioned {
3408
+ config: AgentConfig;
3409
+ /** The agent's Space member id (`__agent__:<agentId>`). */
3410
+ memberId: string;
3411
+ /** base64url-JWK identity ECDH public key (null until provisioned). */
3412
+ ecdhPub: string | null;
3413
+ /** base64url-JWK identity ECDSA public key — verifies the agent's messages. */
3414
+ ecdsaPub: string | null;
3415
+ }
3416
+ interface AgentsNamespaceDeps {
3417
+ http: HttpClient;
3418
+ }
3419
+ /** Common option: a management Space for delegated (non-owner) access. */
3420
+ interface AgentScopeOpts {
3421
+ space?: string;
3422
+ }
3423
+ declare class AgentsNamespace {
3424
+ private readonly deps;
3425
+ constructor(deps: AgentsNamespaceDeps);
3426
+ /** List the app's agents. */
3427
+ list(appId: string, opts?: AgentScopeOpts): Promise<AgentConfig[]>;
3428
+ /** Read one agent (config + identity keys). */
3429
+ get(appId: string, agentId: string, opts?: AgentScopeOpts): Promise<AgentProvisioned>;
3430
+ /** Create an agent (owner/editor only). */
3431
+ create(appId: string, input: AgentCreateInput, opts?: AgentScopeOpts): Promise<AgentProvisioned>;
3432
+ /** Update an agent's editor-settable fields (owner/editor only). */
3433
+ update(appId: string, agentId: string, patch: AgentUpdateInput, opts?: AgentScopeOpts): Promise<{
3434
+ config: AgentConfig;
3435
+ }>;
3436
+ /** Delete an agent (owner/editor only). */
3437
+ delete(appId: string, agentId: string, opts?: AgentScopeOpts): Promise<{
3438
+ deleted: boolean;
3439
+ }>;
3440
+ /** Enable the agent on a Space (per-Space opt-in). */
3441
+ enable(appId: string, agentId: string, spaceId: string, opts?: AgentScopeOpts): Promise<{
3442
+ config: AgentConfig;
3443
+ }>;
3444
+ /** Disable the agent on a Space. */
3445
+ disable(appId: string, agentId: string, spaceId: string, opts?: AgentScopeOpts): Promise<{
3446
+ config: AgentConfig;
3447
+ }>;
3448
+ private path;
3449
+ }
3450
+
3451
+ /**
3452
+ * `client.functions` — manage an app's **serverless functions** (developer-
3453
+ * authored code that runs on the accelerator).
3454
+ *
3455
+ * const { config } = await client.functions.deploy(appId, {
3456
+ * name: 'hello', displayName: 'Hello',
3457
+ * code: `export default { fetch: () => new Response('hi') }`,
3458
+ * triggers: { http: { enabled: true } },
3459
+ * });
3460
+ * // HTTP-reachable at hello--<slug>.fns.muhkoo.dev
3461
+ * await client.functions.enable(appId, config.functionId, spaceId); // Space-bound
3462
+ *
3463
+ * These are MANAGEMENT calls — the function itself runs on the accelerator
3464
+ * (uploaded just-in-time, decrypted only at invocation). Only an app's owner or
3465
+ * an editor of its shared Space may deploy/update/enable (viewers read).
3466
+ * Authorization rides the user session token; non-owner editors pass their
3467
+ * management Space via `opts.space`.
3468
+ *
3469
+ * v1 is "compute-only": a function is an untrusted single-module ES worker
3470
+ * (`export default { fetch }`) with NO platform bindings — it reaches the
3471
+ * platform as an external client (the end-user session is passed through). Two
3472
+ * triggers: `http` (its own subdomain) and `space` (invoked on Space messages,
3473
+ * like a Programmable Agent).
3474
+ */
3475
+
3476
+ type FunctionTriggerType = "keyword" | "regex" | "always";
3477
+ interface FunctionTrigger {
3478
+ type: FunctionTriggerType;
3479
+ /** Required for `keyword` (case-insensitive substring) and `regex`. */
3480
+ pattern?: string;
3481
+ }
3482
+ interface FunctionTriggers {
3483
+ /** HTTP-invocable at `<name>--<slug>.fns.<zone>`. */
3484
+ http?: {
3485
+ enabled: boolean;
3486
+ methods?: string[];
3487
+ };
3488
+ /** Invoked on matching Space messages (per-Space opt-in via enable). */
3489
+ space?: {
3490
+ match: FunctionTrigger[];
3491
+ };
3492
+ }
3493
+ interface FunctionCaps {
3494
+ /** Per-invocation CPU ceiling (ms). */
3495
+ cpuMs: number;
3496
+ /** Per-invocation subrequest ceiling. */
3497
+ subRequests: number;
3498
+ /** Hard daily invocation cap (0 = unlimited). */
3499
+ dailyInvocationBudget: number;
3500
+ }
3501
+ interface FunctionConfig {
3502
+ functionId: string;
3503
+ /** DNS-safe slug — the function's subdomain label + WfP script name part. */
3504
+ name: string;
3505
+ displayName: string;
3506
+ triggers: FunctionTriggers;
3507
+ /** Space ids this function is enabled on (per-Space opt-in for `space`). */
3508
+ enabledSpaces: string[];
3509
+ caps: FunctionCaps;
3510
+ scriptName: string;
3511
+ /** sha-256 of the last-deployed source. */
3512
+ codeHash?: string;
3513
+ /** When the source was last (re)deployed. */
3514
+ deployedAt?: number;
3515
+ createdAt: number;
3516
+ updatedAt: number;
3517
+ }
3518
+ /** The editor-settable fields when deploying a function. */
3519
+ interface FunctionDeployInput {
3520
+ name: string;
3521
+ displayName: string;
3522
+ /** Raw single-module ES worker source (`export default { fetch }`). */
3523
+ code: string;
3524
+ triggers?: FunctionTriggers;
3525
+ caps?: Partial<FunctionCaps>;
3526
+ }
3527
+ /** Update input — any subset, including new `code` to redeploy. */
3528
+ type FunctionUpdateInput = Partial<FunctionDeployInput>;
3529
+ interface FunctionsNamespaceDeps {
3530
+ http: HttpClient;
3531
+ }
3532
+ /** Common option: a management Space for delegated (non-owner) access. */
3533
+ interface FunctionScopeOpts {
3534
+ space?: string;
3535
+ }
3536
+ declare class FunctionsNamespace {
3537
+ private readonly deps;
3538
+ constructor(deps: FunctionsNamespaceDeps);
3539
+ /** List the app's functions. */
3540
+ list(appId: string, opts?: FunctionScopeOpts): Promise<FunctionConfig[]>;
3541
+ /** Read one function's config. */
3542
+ get(appId: string, functionId: string, opts?: FunctionScopeOpts): Promise<{
3543
+ config: FunctionConfig;
3544
+ }>;
3545
+ /** Read a function's decrypted source (owner/editor; for the editor UI). */
3546
+ code(appId: string, functionId: string, opts?: FunctionScopeOpts): Promise<{
3547
+ functionId: string;
3548
+ code: string;
3549
+ codeHash: string | null;
3550
+ }>;
3551
+ /** Deploy (create) a function (owner/editor only). */
3552
+ deploy(appId: string, input: FunctionDeployInput, opts?: FunctionScopeOpts): Promise<{
3553
+ config: FunctionConfig;
3554
+ }>;
3555
+ /** Update a function's editor-settable fields and/or redeploy its `code`. */
3556
+ update(appId: string, functionId: string, patch: FunctionUpdateInput, opts?: FunctionScopeOpts): Promise<{
3557
+ config: FunctionConfig;
3558
+ }>;
3559
+ /** Delete a function (owner/editor only). */
3560
+ delete(appId: string, functionId: string, opts?: FunctionScopeOpts): Promise<{
3561
+ deleted: boolean;
3562
+ }>;
3563
+ /** Enable the function on a Space (per-Space opt-in for the `space` trigger). */
3564
+ enable(appId: string, functionId: string, spaceId: string, opts?: FunctionScopeOpts): Promise<{
3565
+ config: FunctionConfig;
3566
+ }>;
3567
+ /** Disable the function on a Space. */
3568
+ disable(appId: string, functionId: string, spaceId: string, opts?: FunctionScopeOpts): Promise<{
3569
+ config: FunctionConfig;
3570
+ }>;
3571
+ private path;
3572
+ }
3573
+
3146
3574
  /** The hosted Muhkoo Accelerator — the default {@link ClientOptions.baseUrl}. */
3147
3575
  declare const DEFAULT_BASE_URL = "https://api.muhkoo.dev";
3148
3576
  interface ClientOptions {
@@ -3182,12 +3610,18 @@ declare class Client {
3182
3610
  readonly auth: AuthNamespace;
3183
3611
  /** Per-user key/value storage — `client.kv.set(...)`, etc. */
3184
3612
  readonly kv: KvNamespace;
3613
+ /** App scalable database — `client.db.table('todos').query(...)`, etc. */
3614
+ readonly db: DbNamespace;
3185
3615
  /** File storage — `client.storage.writeFile(...)`, etc. */
3186
3616
  readonly storage: StorageNamespace;
3187
3617
  /** Realtime messaging — `client.message.subscribe(...)`, etc. */
3188
3618
  readonly message: MessageNamespace;
3189
3619
  /** Fan-out group spaces — `client.space.createSpace(...)`, etc. */
3190
3620
  readonly space: SpaceNamespace;
3621
+ /** Programmable Agents — `client.agents.create(appId, …)`, etc. */
3622
+ readonly agents: AgentsNamespace;
3623
+ /** Serverless functions — `client.functions.deploy(appId, …)`, etc. */
3624
+ readonly functions: FunctionsNamespace;
3191
3625
  private readonly session;
3192
3626
  private readonly http;
3193
3627
  /** Subscribers notified when a session expires and can't be recovered. */
@@ -3220,6 +3654,134 @@ declare class Client {
3220
3654
  recoverSession(): Promise<boolean>;
3221
3655
  }
3222
3656
 
3657
+ /**
3658
+ * Muhkoo app decorators — declare your app's agent-facing surface in code, then
3659
+ * "eject" a system prompt you hand to a Programmable Agent.
3660
+ *
3661
+ * You annotate a plain class with `@MuhkooAgent` (the app's identity + how the
3662
+ * agent should behave) plus per-surface decorators — `@MuhkooSpace`,
3663
+ * `@MuhkooDB`, `@MuhkooFunction` — that describe what each channel, table, and
3664
+ * function is *for*. {@link ejectAgentPrompt} reads those annotations and
3665
+ * produces a `systemPrompt` string:
3666
+ *
3667
+ * ```ts
3668
+ * @MuhkooAgent({
3669
+ * name: "Chat Assistant",
3670
+ * purpose: "A helpful assistant inside a real-time team chat.",
3671
+ * guidance: ["Keep replies short.", "Only chime in when relevant."],
3672
+ * })
3673
+ * class ChatAssistant {
3674
+ * @MuhkooSpace({ description: "Main team discussion." }) general!: string;
3675
+ * @MuhkooDB({ access: "read", description: "Chat message history." }) messages!: unknown;
3676
+ * @MuhkooFunction({ description: "Open a support ticket." }) openTicket!: () => void;
3677
+ * }
3678
+ *
3679
+ * const systemPrompt = ejectAgentPrompt(ChatAssistant);
3680
+ * await client.agents.create({ handle: "assistant", displayName: "Assistant", systemPrompt });
3681
+ * ```
3682
+ *
3683
+ * The ejected prompt owns the **semantic** layer — what the app is, how to act,
3684
+ * and what each surface means. The Muhkoo runtime separately appends the
3685
+ * **authoritative** roster (exact columns, function parameters, and the closed
3686
+ * list of callable tools), so the prompt here never needs to restate schema and
3687
+ * can't drift from it. Decorators only describe; they never change runtime
3688
+ * behavior, so they're safe to apply to a throwaway descriptor class.
3689
+ *
3690
+ * Requires `experimentalDecorators` (already enabled in this package). Metadata
3691
+ * is captured in a per-class registry — no `reflect-metadata` dependency.
3692
+ */
3693
+
3694
+ /** Whether the agent may only read a table, or read and write it. */
3695
+ type MuhkooDBAccess = "read" | "write";
3696
+ /** App-level identity + behavioral guidance — the heart of the ejected prompt. */
3697
+ interface MuhkooAgentMeta {
3698
+ /** The agent persona's name (e.g. "Chat Assistant"). */
3699
+ name: string;
3700
+ /** What the app is and the agent's role in it. One or two sentences. */
3701
+ purpose: string;
3702
+ /** Short behavioral rules, rendered as a bulleted list. */
3703
+ guidance?: string[];
3704
+ /** Optional free-form instructions appended verbatim after the surface. */
3705
+ instructions?: string;
3706
+ }
3707
+ /** A channel/Space the agent can resolve and post into. */
3708
+ interface MuhkooSpaceMeta {
3709
+ /** Channel name. Defaults to the decorated member's name. */
3710
+ name?: string;
3711
+ description: string;
3712
+ }
3713
+ /** An app database table the agent can query (and optionally mutate). */
3714
+ interface MuhkooDBMeta {
3715
+ /** Table name. Defaults to the decorated member's name. */
3716
+ table?: string;
3717
+ /** Read-only by default. */
3718
+ access?: MuhkooDBAccess;
3719
+ description: string;
3720
+ }
3721
+ /** A serverless function the agent can invoke via `call_function`. */
3722
+ interface MuhkooFunctionMeta {
3723
+ /** Function name. Defaults to the decorated member's name. */
3724
+ name?: string;
3725
+ description: string;
3726
+ }
3727
+ interface SpaceEntry {
3728
+ name: string;
3729
+ description: string;
3730
+ }
3731
+ interface TableEntry {
3732
+ table: string;
3733
+ access: MuhkooDBAccess;
3734
+ description: string;
3735
+ }
3736
+ interface FunctionEntry {
3737
+ name: string;
3738
+ description: string;
3739
+ }
3740
+ /** The full annotated surface gathered from one decorated class. */
3741
+ interface MuhkooAppDescriptor {
3742
+ agent?: MuhkooAgentMeta;
3743
+ spaces: SpaceEntry[];
3744
+ tables: TableEntry[];
3745
+ functions: FunctionEntry[];
3746
+ }
3747
+ /**
3748
+ * Class decorator. Declares the app's agent identity, purpose, and behavioral
3749
+ * guidance. Apply it to the class whose members carry the surface decorators.
3750
+ */
3751
+ declare function MuhkooAgent(meta: MuhkooAgentMeta): ClassDecorator;
3752
+ /** Member decorator. Marks a channel/Space the agent can resolve and post to. */
3753
+ declare function MuhkooSpace(meta: MuhkooSpaceMeta): PropertyDecorator & MethodDecorator;
3754
+ /** Member decorator. Marks an app database table the agent can query/mutate. */
3755
+ declare function MuhkooDB(meta: MuhkooDBMeta): PropertyDecorator & MethodDecorator;
3756
+ /** Member decorator. Marks a serverless function the agent can call. */
3757
+ declare function MuhkooFunction(meta: MuhkooFunctionMeta): PropertyDecorator & MethodDecorator;
3758
+ /** Read back the raw descriptor a class accumulated (for tooling/tests). */
3759
+ declare function getMuhkooAppDescriptor(appClass: Function): MuhkooAppDescriptor | undefined;
3760
+ /**
3761
+ * Compose the agent system prompt from a `@MuhkooAgent`-decorated class. Throws
3762
+ * if the class isn't decorated. The result is the semantic layer only — the
3763
+ * runtime appends exact schema + the closed tool list at invocation time.
3764
+ */
3765
+ declare function ejectAgentPrompt(appClass: Function): string;
3766
+ /**
3767
+ * The tools-config shape the Muhkoo platform uses to gate an agent. Alias of
3768
+ * `client.agents`' {@link AgentToolsConfig} so {@link ejectAgentTools} output
3769
+ * drops straight into `client.agents.create({ tools })`.
3770
+ */
3771
+ type MuhkooAgentToolsConfig = AgentToolsConfig;
3772
+ /**
3773
+ * Derive a suggested tools allowlist from a decorated class — the db tables
3774
+ * (and whether any are writable), the callable functions, and whether channels
3775
+ * are in play. Pair with {@link ejectAgentPrompt} when configuring the agent.
3776
+ *
3777
+ * If any tables/functions are present the result has `enabled: true`; to
3778
+ * actually grant tools you must also pass a function-calling `model` in the same
3779
+ * `client.agents.create`/`update` call (the server enforces this).
3780
+ */
3781
+ declare function ejectAgentTools(appClass: Function, opts?: {
3782
+ maxIterations?: number;
3783
+ }): AgentToolsConfig;
3784
+
3223
3785
  /**
3224
3786
  * KeyringClient — HTTP implementation of {@link KeyringTransport} against the
3225
3787
  * accelerator's per-space keyring endpoints. All blobs are opaque to the
@@ -3255,8 +3817,30 @@ declare class KeyringClient implements KeyringTransport {
3255
3817
  epoch: number;
3256
3818
  }>;
3257
3819
  invite(username: string): Promise<void>;
3820
+ createInviteLink(opts?: {
3821
+ expiresInSec?: number;
3822
+ maxUses?: number;
3823
+ role?: string;
3824
+ }): Promise<InviteLink>;
3825
+ listInviteLinks(): Promise<InviteLink[]>;
3826
+ /** Set a member's role ("viewer" | "editor"). Owner-only on the server. */
3827
+ setMemberRole(username: string, role: string): Promise<void>;
3828
+ /** Roster with roles (owner/members only). */
3829
+ members(): Promise<Array<{
3830
+ memberId: string;
3831
+ role: string;
3832
+ }>>;
3833
+ revokeInviteLink(token: string): Promise<void>;
3834
+ /** Redeem a link: the server allowlists this member and asks the keeper to
3835
+ * wrap the group key for their identity. Caller must be authenticated. */
3836
+ redeemInvite(req: {
3837
+ token: string;
3838
+ identityEcdhPub: string;
3839
+ identityEcdsaPub?: string;
3840
+ desiredEpoch?: number;
3841
+ }): Promise<void>;
3258
3842
  fetchMetadata(): Promise<SpaceMetadata | null>;
3259
3843
  }
3260
3844
 
3261
- export { AES_GCM_IV_BYTES, AES_GCM_KEY_BYTES, AES_GCM_TAG_BYTES, AuthClient, AuthNamespace, AuthPublicInput, Authenticator, BroadcastChannel, BroadcastChannelEvents, ChannelExistsError, ChannelNotFoundError, ChunkCipher, Client, DEFAULT_BASE_URL, DoubleRatchet, DoubleRatchetCipher, DoubleRatchetManager, EncryptedSession, EventCore, EventCoreEvents, Field, Field as FieldElement, FileStorage, HashKnowledge, HttpClient, HttpError, KEEPER_MEMBER_ID, KeyStore, KeyringClient, KvNamespace, LocalStorageSessionStore, MemorySessionStore, Message, Message as MessageDefault, MessageNamespace, PBKDF2_DEFAULT_ITERATIONS, PREIMAGE_POK_VERIFICATION_KEY, Packet, PersonalSpaceClient, Poseidon, PreimagePoK, ReedSolomonCodec, Space as Room, SerializeMessage, SessionState, ShardClient, SharedSpaceClient, Space, SpaceKeyring, SpaceNamespace, SpacePacketCipher, StorageNamespace, WSTransport, ZkAuth, buildCommitment, compilePrograms, decodeFromHex, decorators, decryptAesGcm, defaultCircuitUrls, defaultSessionStore, deriveAesKeyFromPassphrase, deriveBitsHkdf, deriveIdentity, encodeToHex, encryptAesGcm, exportPublicKeyBase64, exportPublicKeyHex, generateAuthProof, getSubtle, initBn128Wasm, initRsWasm, initializeCircuits, manifestToStat, poseidonHash, quickVerify, randomBytes, shardHash, signMessage, toField, unwrapWithPassphrase, verify, verifyGroth16, verifyHashKnowledge, verifyPreimagePoK, wrapWithPassphrase };
3262
- export type { ACL, ACLEntry, AuthClientOptions, AuthKeyPair, AuthSuccess, AuthToken, AuthType, AuthUser, Bn128WasmInstance, BroadcastChannelEvent, BroadcastChannelOptions, ChannelLike, ChunkKeyMaterial, ChunkManifest, CipherFrame, CipherMessage, CipherMessageHeader, CircuitBufferConfig, CircuitUrls, ClientOptions, DehydratedKeypair, DehydratedKeys, DoubleRatchetCipherDeps, ECDHCurve, EncodeResult, EphemeralEvent, EpochKeyProvider, FileManifest, FileNamespaceDeps, FileStat, FileStorageOptions, Groth16Proof, HttpClientOptions, IncomingFrame, KeyExchangeFrame, KeyPair, Keypair, KeyringClientDeps, KeyringTransport, KvNamespaceDeps, LoginOptions, MessageBody, MessageDeletedEvent, MessageEvent, MessageHeaders, MessageNamespaceDeps, MessageOptions, MessageSubscription, MuhkooMessageEvent, OAuthProvider, PacketCipher, PacketHeaders, PacketOptions, Participant, Permission, PermissionCheckRequest, PermissionCheckResult, PersonalSpaceClientOptions, PublicKeyJWK, RatchetState, ReceiveResult, RegisterParams, Role, SpaceDeps as RoomDeps, SpaceFileMetadata as RoomFileMetadata, SealedHeaders, Session, SessionOptions, SessionStore, SetOptions, ShardClientOptions, SharedSpaceClientOptions, SnarkProof, SpaceChannelLike, SpaceDeps, SpaceFileMetadata, SpaceKeyCache, SpaceKeyringDeps, SpaceMessageEvent, SpaceNamespaceDeps, StorageChangeEvent, StoredSession, Subscription, UserIdentity, VerificationKey, WSMessage, WSMessageType, WSTransportOptions, WrappedPayload, WriteFileInput, WriteFileOptions, WriteToShardsInput, ZkAuthDeps, ZkAuthenticateRequest, ZkChallengeResponse, ZkCompiled, ZkIdentity, ZkRegisterRequest, ZkRegisterResponse };
3845
+ export { AES_GCM_IV_BYTES, AES_GCM_KEY_BYTES, AES_GCM_TAG_BYTES, AgentsNamespace, AuthClient, AuthNamespace, AuthPublicInput, Authenticator, BroadcastChannel, BroadcastChannelEvents, ChannelExistsError, ChannelNotFoundError, ChunkCipher, Client, DEFAULT_BASE_URL, DoubleRatchet, DoubleRatchetCipher, DoubleRatchetManager, EncryptedSession, EventCore, EventCoreEvents, Field, Field as FieldElement, FileStorage, FunctionsNamespace, HashKnowledge, HttpClient, HttpError, KEEPER_MEMBER_ID, KeyStore, KeyringClient, KvNamespace, LocalStorageSessionStore, MemorySessionStore, Message, Message as MessageDefault, MessageNamespace, MuhkooAgent, MuhkooDB, MuhkooFunction, MuhkooSpace, PBKDF2_DEFAULT_ITERATIONS, PREIMAGE_POK_VERIFICATION_KEY, Packet, PersonalSpaceClient, Poseidon, PreimagePoK, ReedSolomonCodec, Space as Room, SerializeMessage, SessionState, ShardClient, SharedSpaceClient, Space, SpaceKeyring, SpaceNamespace, SpacePacketCipher, StorageNamespace, WSTransport, ZkAuth, buildCommitment, compilePrograms, decodeFromHex, decorators, decryptAesGcm, defaultCircuitUrls, defaultSessionStore, deriveAesKeyFromPassphrase, deriveBitsHkdf, deriveIdentity, ejectAgentPrompt, ejectAgentTools, encodeToHex, encryptAesGcm, exportPublicKeyBase64, exportPublicKeyHex, generateAuthProof, getMuhkooAppDescriptor, getSubtle, initBn128Wasm, initRsWasm, initializeCircuits, manifestToStat, poseidonHash, quickVerify, randomBytes, shardHash, signMessage, toField, unwrapWithPassphrase, verify, verifyGroth16, verifyHashKnowledge, verifyPreimagePoK, wrapWithPassphrase };
3846
+ export type { ACL, ACLEntry, AgentConfig, AgentCreateInput, AgentDbToolMode, AgentProvisioned, AgentScopeOpts, AgentSkill, AgentToolsConfig, AgentTrigger, AgentTriggerType, AgentUpdateInput, AgentsNamespaceDeps, AuthClientOptions, AuthKeyPair, AuthSuccess, AuthToken, AuthType, AuthUser, Bn128WasmInstance, BroadcastChannelEvent, BroadcastChannelOptions, ChannelLike, ChunkKeyMaterial, ChunkManifest, CipherFrame, CipherMessage, CipherMessageHeader, CircuitBufferConfig, CircuitUrls, ClientOptions, DehydratedKeypair, DehydratedKeys, DoubleRatchetCipherDeps, ECDHCurve, EncodeResult, EphemeralEvent, EpochKeyProvider, FileManifest, FileNamespaceDeps, FileStat, FileStorageOptions, FunctionCaps, FunctionConfig, FunctionDeployInput, FunctionScopeOpts, FunctionTrigger, FunctionTriggerType, FunctionTriggers, FunctionUpdateInput, FunctionsNamespaceDeps, Groth16Proof, HttpClientOptions, IncomingFrame, KeyExchangeFrame, KeyPair, Keypair, KeyringClientDeps, KeyringTransport, KvNamespaceDeps, LoginOptions, MessageBody, MessageDeletedEvent, MessageEvent, MessageHeaders, MessageNamespaceDeps, MessageOptions, MessageSubscription, MuhkooAgentMeta, MuhkooAgentToolsConfig, MuhkooAppDescriptor, MuhkooDBAccess, MuhkooDBMeta, MuhkooFunctionMeta, MuhkooMessageEvent, MuhkooSpaceMeta, OAuthProvider, PacketCipher, PacketHeaders, PacketOptions, Participant, Permission, PermissionCheckRequest, PermissionCheckResult, PersonalSpaceClientOptions, PublicKeyJWK, RatchetState, ReceiveResult, RegisterParams, Role, SpaceDeps as RoomDeps, SpaceFileMetadata as RoomFileMetadata, SealedHeaders, Session, SessionOptions, SessionStore, SetOptions, ShardClientOptions, SharedSpaceClientOptions, SnarkProof, SpaceChannelLike, SpaceDeps, SpaceFileMetadata, SpaceKeyCache, SpaceKeyringDeps, SpaceMessageEvent, SpaceNamespaceDeps, StorageChangeEvent, StoredSession, Subscription, UserIdentity, VerificationKey, WSMessage, WSMessageType, WSTransportOptions, WrappedPayload, WriteFileInput, WriteFileOptions, WriteToShardsInput, ZkAuthDeps, ZkAuthenticateRequest, ZkChallengeResponse, ZkCompiled, ZkIdentity, ZkRegisterRequest, ZkRegisterResponse };