@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/README.md CHANGED
@@ -1,12 +1,17 @@
1
1
  # @muhkoo/connect
2
2
 
3
3
  Client SDK for the Muhkoo Accelerator. The headline surface is a single
4
- **`Client`** that hangs everything off four namespaces —
5
- `client.auth` / `client.storage` / `client.message` / `client.space` — backed by
6
- end-to-end-encrypted messaging (fan-out group channels with history, plus
7
- Double Ratchet + ECDH P-384 for direct messages), ZK identity + personal/shared
8
- spaces, and a Cloudflare-Workers-compatible Groth16 verifier — all bundled from
9
- a single TypeScript source tree.
4
+ **`Client`** that hangs everything off its namespaces —
5
+ `client.auth` / `client.kv` / `client.db` / `client.storage` /
6
+ `client.message` / `client.space` / `client.agents` / `client.functions` —
7
+ backed by
8
+ end-to-end-encrypted messaging (fan-out group channels with history, plus Double
9
+ Ratchet + ECDH P-384 for direct messages), ZK identity + personal/shared spaces,
10
+ server-side Programmable Agents, developer-authored serverless functions, and an
11
+ edge-compatible Groth16 verifier — all bundled from a single
12
+ TypeScript source tree.
13
+
14
+ See [`CHANGELOG.md`](./CHANGELOG.md) for what's new.
10
15
 
11
16
  > Status: alpha. The library is consumed in tree by `../accelerator` and the
12
17
  > `../web` SPA.
@@ -14,10 +19,17 @@ a single TypeScript source tree.
14
19
  ## What's in the box
15
20
 
16
21
  - **`Client`** — the unified entry point. `new Client({ apiKey, baseUrl })`
17
- exposes `auth` (ZK register/login), `storage` (per-user encrypted KV +
18
- files), and `message` (pub/sub + E2E direct messages) over one shared
19
- session. This is the supported surface; everything below is a building block
20
- it composes.
22
+ exposes, over one shared session: `auth` (ZK register/login), `kv` (per-user
23
+ encrypted key/value), `db` (the app's scalable database), `storage` (encrypted
24
+ files), `message` (pub/sub + E2E direct messages), `space` (fan-out group
25
+ channels with history), `agents` (server-side Programmable Agents), and
26
+ `functions` (developer-authored serverless functions). This is the supported
27
+ surface; everything below is a building block it composes.
28
+
29
+ - **App-describing decorators** — `@MuhkooAgent` / `@MuhkooSpace` / `@MuhkooDB` /
30
+ `@MuhkooFunction` annotate a plain class with your app's agent-facing surface;
31
+ `ejectAgentPrompt()` / `ejectAgentTools()` turn that into a `systemPrompt` +
32
+ tool allowlist for a Programmable Agent. See the [agents reference](https://docs.muhkoo.dev/reference/agents/).
21
33
 
22
34
  - **`BroadcastChannel`** — multi-peer end-to-end-encrypted "room". Wires
23
35
  `WSTransport` (socket lifecycle, reconnect, offline queue) together with
@@ -163,6 +175,91 @@ blind (it only ever sees opaque, ECIES-wrapped key blobs). The space handle was
163
175
  once `Room`; that name is still exported as an alias, and `client.message.room()`
164
176
  returns the same handle.
165
177
 
178
+ **Shareable invite links + member roles.** A private Space (`createChannel(name,
179
+ { private: true })`) admits only allowlisted members. Instead of inviting
180
+ people one username at a time, mint a **capability link** anyone can redeem —
181
+ the keeper admits them on redemption. Members carry a **role** (`viewer` /
182
+ `editor`) the owner controls; apps use roles to gate delegated management (e.g.
183
+ who can edit an app's config).
184
+
185
+ ```typescript
186
+ // Owner: mint a shareable invite (optionally time-/use-bounded, with a role).
187
+ const { token } = await client.space.createInviteLink(space.id, { role: "viewer", maxUses: 10 });
188
+ const url = `https://yourapp.com/join?space=${space.id}&token=${token}`;
189
+ await client.space.listInviteLinks(space.id); // owner: active links
190
+ await client.space.revokeInviteLink(space.id, token);
191
+
192
+ // Recipient: redeem the link → admitted by the keeper, group key wrapped for them.
193
+ const joined = await client.space.joinByInvite(space.id, token);
194
+
195
+ // Owner: see members + roles, and promote/demote.
196
+ await client.space.members(space.id); // [{ memberId, role }]
197
+ await client.space.setMemberRole(space.id, "alice", "editor");
198
+ await client.space.roster(space.id); // member identity pubkeys
199
+ ```
200
+
201
+ **Programmable Agents (`client.agents`).** Server-side "virtual users" backed by
202
+ the edge AI runtime: an app editor gives an agent a persona (system prompt), a
203
+ model, and **triggers** (e.g. reply on @-mention), then enables it per-Space;
204
+ members chat with it inside that Space. Management is session-authed (owner or
205
+ Space editor) and **paid-tier-only**. Enabling an agent on a Space makes that
206
+ Space readable by the app's keeper (per-Space opt-in); every other Space stays
207
+ blind.
208
+
209
+ ```typescript
210
+ const { config } = await client.agents.create(appId, {
211
+ handle: "@assistant",
212
+ displayName: "Assistant",
213
+ model: "meta/llama-3.1-8b-instruct",
214
+ systemPrompt: "You are a concise, friendly teammate in this Space.",
215
+ triggers: [{ type: "mention" }],
216
+ });
217
+ await client.agents.enable(appId, config.agentId, space.id); // per-Space opt-in
218
+ // list / update / delete / disable also available.
219
+ ```
220
+
221
+ Give the agent **tools** (a function-calling loop over the app's database,
222
+ functions, and channels) by passing `tools` — requires a function-calling
223
+ `model`. Generate both the prompt and the tool allowlist from decorators:
224
+
225
+ ```typescript
226
+ import { MuhkooAgent, MuhkooSpace, MuhkooDB, ejectAgentPrompt, ejectAgentTools } from "@muhkoo/connect";
227
+
228
+ @MuhkooAgent({ name: "Assistant", purpose: "A helpful teammate in this chat." })
229
+ class ChatApp {
230
+ @MuhkooSpace({ description: "Main team discussion." }) general!: string;
231
+ @MuhkooDB({ access: "read", description: "Chat message history." }) messages!: unknown;
232
+ }
233
+
234
+ await client.agents.create(appId, {
235
+ handle: "@assistant",
236
+ displayName: "Assistant",
237
+ model: "openai/gpt-oss-120b", // a function-calling model
238
+ systemPrompt: ejectAgentPrompt(ChatApp),
239
+ tools: ejectAgentTools(ChatApp),
240
+ });
241
+ ```
242
+
243
+ **Serverless Functions (`client.functions`).** Deploy your own code that runs on
244
+ the accelerator. A function is an untrusted single-module ES worker
245
+ (`export default { fetch }`) with two triggers: **HTTP** (reachable at its own
246
+ `<name>--<slug>.fns.<zone>` subdomain) and **Space-bound** (invoked on Space
247
+ messages, like an agent). Source is encrypted at rest and uploaded just-in-time
248
+ on invocation. Management is session-authed (owner / Space editor) and
249
+ **paid-tier-only**.
250
+
251
+ ```typescript
252
+ const { config } = await client.functions.deploy(appId, {
253
+ name: "hello",
254
+ displayName: "Hello",
255
+ code: `export default { fetch: () => new Response("hi from Muhkoo!") }`,
256
+ triggers: { http: { enabled: true } },
257
+ });
258
+ // → reachable at https://hello--<app-slug>.fns.<zone>/
259
+ await client.functions.enable(appId, config.functionId, space.id); // Space-bound
260
+ // list / get / code / update / delete / disable also available.
261
+ ```
262
+
166
263
  Auth lifecycle:
167
264
 
168
265
  ```typescript