@rool-dev/sdk 0.10.2-dev.47747e3 → 0.10.2-dev.550002

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.
Files changed (51) hide show
  1. package/README.md +36 -163
  2. package/dist/channel.d.ts +41 -129
  3. package/dist/channel.d.ts.map +1 -1
  4. package/dist/channel.js +233 -394
  5. package/dist/channel.js.map +1 -1
  6. package/dist/client.d.ts +3 -55
  7. package/dist/client.d.ts.map +1 -1
  8. package/dist/client.js +7 -93
  9. package/dist/client.js.map +1 -1
  10. package/dist/graphql.d.ts +4 -46
  11. package/dist/graphql.d.ts.map +1 -1
  12. package/dist/graphql.js +13 -223
  13. package/dist/graphql.js.map +1 -1
  14. package/dist/index.d.ts +3 -6
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -4
  17. package/dist/index.js.map +1 -1
  18. package/dist/path.d.ts +6 -0
  19. package/dist/path.d.ts.map +1 -0
  20. package/dist/path.js +47 -0
  21. package/dist/path.js.map +1 -0
  22. package/dist/rest.d.ts +9 -0
  23. package/dist/rest.d.ts.map +1 -1
  24. package/dist/rest.js +48 -1
  25. package/dist/rest.js.map +1 -1
  26. package/dist/space.d.ts +4 -14
  27. package/dist/space.d.ts.map +1 -1
  28. package/dist/space.js +30 -50
  29. package/dist/space.js.map +1 -1
  30. package/dist/subscription.d.ts.map +1 -1
  31. package/dist/subscription.js +18 -26
  32. package/dist/subscription.js.map +1 -1
  33. package/dist/types.d.ts +36 -212
  34. package/dist/types.d.ts.map +1 -1
  35. package/dist/webdav.d.ts +31 -21
  36. package/dist/webdav.d.ts.map +1 -1
  37. package/dist/webdav.js +70 -58
  38. package/dist/webdav.js.map +1 -1
  39. package/package.json +2 -1
  40. package/dist/apps.d.ts +0 -30
  41. package/dist/apps.d.ts.map +0 -1
  42. package/dist/apps.js +0 -81
  43. package/dist/apps.js.map +0 -1
  44. package/dist/locations.d.ts +0 -34
  45. package/dist/locations.d.ts.map +0 -1
  46. package/dist/locations.js +0 -90
  47. package/dist/locations.js.map +0 -1
  48. package/dist/machine.d.ts +0 -16
  49. package/dist/machine.d.ts.map +0 -1
  50. package/dist/machine.js +0 -51
  51. package/dist/machine.js.map +0 -1
package/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  The TypeScript SDK for Rool, a persistent and collaborative environment for organizing objects.
4
4
 
5
- > **Building a new Rool extension?** Start with [`@rool-dev/extension`](/extension/) — it handles hosting, dev server, and gives you a reactive Svelte channel out of the box. This SDK is for advanced use cases: integrating Rool into an existing application, building Node.js scripts, or working outside the extension sandbox.
6
-
7
5
  The SDK manages authentication, real-time synchronization, and per-space file storage. Core primitives:
8
6
 
9
7
  - **Spaces** — Containers for objects, schema, metadata, channels, and files
@@ -65,10 +63,9 @@ const { message, objects } = await channel.prompt(
65
63
  console.log(message); // AI explains what it did
66
64
  console.log(`Modified ${objects.length} objects`);
67
65
 
68
- // Query with natural language
69
- const { objects: innerPlanets } = await channel.findObjects({
70
- prompt: 'planets closer to the sun than Earth'
71
- });
66
+ // Read an object by location
67
+ const loadedEarth = await channel.getObject(earth.location);
68
+ console.log(loadedEarth?.body.name);
72
69
 
73
70
  // Clean up
74
71
  channel.close();
@@ -229,7 +226,7 @@ References are just data — no special API is needed to create or remove them.
229
226
  #### Location helpers
230
227
 
231
228
  ```typescript
232
- import { loc, parseLocation, normalizeLocation, generateBasename } from '@rool-dev/sdk';
229
+ import { loc, parseLocation, normalizeLocation } from '@rool-dev/sdk';
233
230
 
234
231
  loc('article', 'welcome'); // '/space/article/welcome.json'
235
232
  parseLocation('/space/article/welcome.json'); // { collection: 'article', basename: 'welcome' }
@@ -237,9 +234,6 @@ parseLocation('/space/article/welcome.json'); // { collection: 'article', basena
237
234
  // normalizeLocation accepts canonical or short form and returns canonical
238
235
  normalizeLocation('article/welcome'); // '/space/article/welcome.json'
239
236
  normalizeLocation('/space/article/welcome.json'); // unchanged
240
-
241
- // 6-char random basename — same generator the SDK uses by default
242
- generateBasename(); // e.g., 'X7kQ9p'
243
237
  ```
244
238
 
245
239
  SDK methods that accept a location (`getObject`, `updateObject`, `deleteObjects`, `moveObject`, etc.) accept either form and normalize internally. SDK return values always use the canonical full form.
@@ -320,24 +314,24 @@ await channel.createObject('article', {
320
314
 
321
315
  ### Real-time Sync
322
316
 
323
- Events fire for both local and remote changes. The `source` field indicates origin:
324
-
325
- - `local_user` — This client made the change
326
- - `remote_user` — Another user/client made the change
327
- - `remote_agent` — AI agent made the change
328
- - `system` — Resync after error
317
+ Object and file reactivity is WebDAV-based. Listen for space-level file change notifications, then reconcile with `webdav.syncCollection()` using your sync token. This covers both object files under `/space` and user files under `/rool-drive`.
329
318
 
330
319
  ```typescript
331
- // All UI updates happen in one place, regardless of change source
332
- channel.on('objectUpdated', ({ location, object, source }) => {
333
- renderObject(location, object);
334
- if (source === 'remote_agent') {
335
- doLayout(); // AI might have added content
336
- }
337
- });
320
+ let token: string | null = null;
338
321
 
339
- // Caller just makes the change - event handler does the UI work
340
- channel.updateObject(location, { prompt: 'expand this' });
322
+ async function syncFiles() {
323
+ const result = await space.webdav.syncCollection('/', {
324
+ token,
325
+ level: 'infinite',
326
+ props: ['displayname', 'getetag', 'getlastmodified', 'resourcetype'],
327
+ });
328
+ token = result.token;
329
+ updateFileTree(result.responses);
330
+ }
331
+
332
+ space.on('filesChanged', syncFiles);
333
+ space.on('filesReset', () => { token = null; syncFiles(); });
334
+ await syncFiles();
341
335
  ```
342
336
 
343
337
  ### Locations & Basenames
@@ -358,7 +352,7 @@ await channel.createObject('article',
358
352
 
359
353
  ```typescript
360
354
  // Fire-and-forget: create and reference without waiting
361
- const basename = RoolClient.generateBasename();
355
+ const basename = 'idea-seed';
362
356
  const location = loc('note', basename);
363
357
 
364
358
  channel.createObject('note', { text: '{{expand this idea}}' }, { basename });
@@ -574,7 +568,7 @@ await space.addUser(user.id, 'editor');
574
568
  | `owner` | Full control, can delete space and manage all users |
575
569
  | `admin` | All editor capabilities, plus can manage users (except other admins/owners) |
576
570
  | `editor` | Can create, modify, move, and delete objects |
577
- | `viewer` | Read-only access (can query with `prompt` and `findObjects`) |
571
+ | `viewer` | Read-only access (can query with `prompt` and read objects/files) |
578
572
 
579
573
  ### Space Collaboration Methods
580
574
 
@@ -621,18 +615,9 @@ When a user accesses a space via URL, they're granted the corresponding role (`v
621
615
 
622
616
  ### Real-time Collaboration
623
617
 
624
- When multiple users have a space open, changes sync in real-time. The `source` field in events tells you who made the change:
625
-
626
- ```typescript
627
- channel.on('objectUpdated', ({ location, object, source }) => {
628
- if (source === 'remote_user') {
629
- // Another user made this change
630
- showCollaboratorActivity(object);
631
- }
632
- });
633
- ```
618
+ When multiple users have a space open, object and file changes are announced by `space.on('filesChanged')` and reconciled through WebDAV `syncCollection()`. Channel/conversation state still emits channel events; filesystem state does not use channel object events.
634
619
 
635
- See [Real-time Sync](#real-time-sync) for more on event sources.
620
+ See [Real-time Sync](#real-time-sync) for a WebDAV sync-token example.
636
621
 
637
622
  ## RoolClient API
638
623
 
@@ -663,8 +648,6 @@ const client = new RoolClient({
663
648
  | `duplicateSpace(sourceSpaceId, name): Promise<RoolSpace>` | Duplicate an existing space. Returns a handle to the new space. |
664
649
  | `deleteSpace(id): Promise<void>` | Permanently delete a space (cannot be undone) |
665
650
  | `importArchive(name, archive): Promise<RoolSpace>` | Import from a zip archive, creating a new space |
666
- | `webdav(spaceId): RoolWebDAV` | Open a WebDAV client for a space's file storage |
667
- | `getSpaceStorageUsage(spaceId): Promise<SpaceFileStorageUsage>` | Get WebDAV quota usage for a space |
668
651
 
669
652
  ### Channel Management
670
653
 
@@ -673,7 +656,6 @@ Manage channels on the `RoolSpace` handle:
673
656
  | Method | Description |
674
657
  |--------|-------------|
675
658
  | `space.channels: ChannelInfo[]` | Live channel list (auto-updates via SSE) |
676
- | `space.getChannels(): ChannelInfo[]` | List channels (deprecated — use `space.channels` instead) |
677
659
  | `space.renameChannel(channelId, name): Promise<void>` | Rename a channel |
678
660
  | `space.deleteChannel(channelId): Promise<void>` | Delete a channel and its interaction history |
679
661
  | `channel.rename(name): Promise<void>` | Rename the current open channel |
@@ -717,39 +699,11 @@ client.on('userStorageChanged', ({ key, value, source }) => {
717
699
  });
718
700
  ```
719
701
 
720
- ### Extensions
721
-
722
- Manage and publish extensions. See [`@rool-dev/extension`](/extension/) for building extensions.
723
-
724
- There are two distinct domains: your **personal library** (extensions you've created or installed) and the **published extensions** (extensions discoverable by all users). Each has its own return type.
725
-
726
- #### Your Library (`ExtensionInfo`)
727
-
728
- Manage extensions you own. Each `ExtensionInfo` includes `published` (whether it's listed in the marketplace) and `marketplaceExtensionId` (non-null if you installed it from someone else's listing, null if you authored it).
729
-
730
- | Method | Description |
731
- |--------|-------------|
732
- | `uploadExtension(extensionId, options): Promise<ExtensionInfo>` | Upload or update an extension (`options.bundle`: zip with `index.html` and `manifest.json`) |
733
- | `listExtensions(): Promise<ExtensionInfo[]>` | List your extensions |
734
- | `getExtensionInfo(extensionId): Promise<ExtensionInfo \| null>` | Get info for a specific extension |
735
- | `deleteExtension(extensionId): Promise<void>` | Delete an extension permanently (removes files and DB row) |
736
-
737
- #### Marketplace (`PublishedExtensionInfo`)
738
-
739
- Discover and install extensions published by other users.
740
-
741
- | Method | Description |
742
- |--------|-------------|
743
- | `findExtensions(options?): Promise<PublishedExtensionInfo[]>` | Search the marketplace. Options: `query` (semantic search string), `limit` (default 20, max 100). Omit `query` to browse all. |
744
- | `publishToPublic(extensionId): Promise<void>` | Publish one of your extensions to the marketplace |
745
- | `unpublishFromPublic(extensionId): Promise<void>` | Remove from the marketplace (keeps the extension in your library) |
746
-
747
702
  ### Utilities
748
703
 
749
704
  | Method | Description |
750
705
  |--------|-------------|
751
- | `RoolClient.generateBasename(): string` | Generate a 6-char alphanumeric basename for new object identities. |
752
- | `RoolClient.generateId(): string` | Same as `generateBasename()`; retained for callers minting non-object IDs (interactions, conversations, channels). |
706
+ | `RoolClient.generateId(): string` | Generate a unique 6-character alphanumeric ID. |
753
707
  | `destroy(): void` | Clean up resources |
754
708
 
755
709
  ### Client Events
@@ -811,10 +765,8 @@ A space handle with a live SSE subscription. Extends `EventEmitter`. Manages use
811
765
  | `addUser(userId, role): Promise<void>` | Add user to space |
812
766
  | `removeUser(userId): Promise<void>` | Remove user from space |
813
767
  | `setLinkAccess(linkAccess): Promise<void>` | Set URL sharing level |
814
- | `getChannels(): ChannelInfo[]` | List channels (deprecated — use `channels` property instead) |
815
768
  | `renameChannel(channelId, name): Promise<void>` | Rename a channel |
816
769
  | `deleteChannel(channelId): Promise<void>` | Delete a channel |
817
- | `installExtension(extensionId, channelId): Promise<string>` | Install an extension into a channel of this space. If you own it, wires it directly. If it's a marketplace extension, copies and builds a new extension in your library. Returns the channel ID. |
818
770
  | `exportArchive(): Promise<Blob>` | Export space as zip archive |
819
771
  | `getStorageUsage(): Promise<SpaceFileStorageUsage>` | Get WebDAV quota usage for this space |
820
772
  | `fetchMachineResource(resource): Promise<Response>` | Fetch a resolved file `MachineResource` through this space |
@@ -824,7 +776,7 @@ A space handle with a live SSE subscription. Extends `EventEmitter`. Manages use
824
776
 
825
777
  ```typescript
826
778
  space.on('channelCreated', (channel: ChannelInfo) => void) // New channel added
827
- space.on('channelUpdated', (channel: ChannelInfo) => void) // Channel metadata changed (name, extension, manifest)
779
+ space.on('channelUpdated', (channel: ChannelInfo) => void) // Channel metadata changed
828
780
  space.on('channelDeleted', (channelId: string) => void) // Channel removed
829
781
  space.on('filesChanged', ({ source, timestamp }) => void) // WebDAV file storage changed; call webdav.syncCollection()
830
782
  space.on('connectionStateChanged', (state: 'connected' | 'disconnected' | 'reconnecting') => void)
@@ -845,9 +797,6 @@ A channel is a named context within a space. All object operations, AI prompts,
845
797
  | `userId: string` | Current user's ID |
846
798
  | `channelId: string` | Channel ID (read-only, fixed at open time) |
847
799
  | `isReadOnly: boolean` | True if viewer role |
848
- | `extensionUrl: string \| null` | URL of the installed extension, or null if this is a plain channel |
849
- | `extensionId: string \| null` | ID of the installed extension, or null if this is a plain channel |
850
- | `manifest: ExtensionManifest \| null` | Extension manifest snapshot (name, icon, collections, etc.), or null |
851
800
 
852
801
  ### Lifecycle
853
802
 
@@ -867,8 +816,6 @@ All methods that accept a location accept either the canonical form or the short
867
816
  |--------|-------------|
868
817
  | `getObject(location): Promise<RoolObject \| undefined>` | Get an object, or undefined if not found. |
869
818
  | `stat(location): RoolObjectStat \| undefined` | Get audit info for an object: when it was last modified, by whom, and where (channel/conversation/interaction). Sync read from local cache. |
870
- | `findObjects(options): Promise<{ objects, message }>` | Find objects using structured filters and/or natural language. Results sorted by modifiedAt (desc by default). |
871
- | `getObjectLocations(options?): string[]` | Get all object locations. Sorted by modifiedAt (desc by default). Options: `{ limit?, order? }`. |
872
819
  | `createObject(collection, body, options?): Promise<{ object, message }>` | Create a new object in `collection`. The SDK mints a random basename unless you pass `options.basename`. |
873
820
  | `updateObject(location, options): Promise<{ object, message }>` | Update an existing object's body. |
874
821
  | `moveObject(from, to, options?): Promise<{ object, message }>` | Rename or relocate an object. See [Moving and Renaming](#moving-and-renaming). |
@@ -961,59 +908,6 @@ await channel.moveObject(from, to, {
961
908
  | `ephemeral` | If true, the operation won't be recorded in interaction history. |
962
909
  | `parentInteractionId` | Conversation tree parent. Omit to auto-continue; pass `null` for a new root. |
963
910
 
964
- #### findObjects
965
-
966
- Find objects using structured filters and/or natural language.
967
-
968
- - **`where` only** — exact-match filtering, no AI, no credits.
969
- - **`collection` only** — filter by collection name, no AI, no credits.
970
- - **`prompt` only** — AI-powered semantic query over all objects.
971
- - **`where` + `prompt`** — `where` (and `locations`) narrow the data set first, then the AI queries within the constrained set.
972
-
973
- | Option | Description |
974
- |--------|-------------|
975
- | `where` | Exact-match body-field filter (e.g. `{ status: 'published' }`). Values must match literally — no operators or `{{placeholders}}`. When combined with `prompt`, constrains which objects the AI can see. |
976
- | `collection` | Filter by collection name. |
977
- | `prompt` | Natural language query. Triggers AI evaluation (uses credits). |
978
- | `limit` | Maximum number of results. |
979
- | `locations` | Scope to specific object locations. Constrains the candidate set in both structured and AI queries. |
980
- | `order` | Sort order by modifiedAt: `'asc'` or `'desc'` (default: `'desc'`). |
981
- | `ephemeral` | If true, the query won't be recorded in interaction history. Useful for responsive search. |
982
-
983
- **Examples:**
984
-
985
- ```typescript
986
- // Filter by collection (no AI, no credits)
987
- const { objects } = await channel.findObjects({
988
- collection: 'article'
989
- });
990
-
991
- // Exact field matching (no AI, no credits)
992
- const { objects } = await channel.findObjects({
993
- where: { status: 'published' }
994
- });
995
-
996
- // Combine collection and field filters
997
- const { objects } = await channel.findObjects({
998
- collection: 'article',
999
- where: { status: 'published' }
1000
- });
1001
-
1002
- // Pure natural language query (AI interprets)
1003
- const { objects, message } = await channel.findObjects({
1004
- prompt: 'articles about space exploration published this year'
1005
- });
1006
-
1007
- // Combined: collection + where narrow the data, prompt queries within it
1008
- const { objects } = await channel.findObjects({
1009
- collection: 'article',
1010
- prompt: 'that discuss climate solutions positively',
1011
- limit: 10
1012
- });
1013
- ```
1014
-
1015
- When `where` or `locations` are provided with a `prompt`, the AI only sees the filtered subset — not the full space. The returned `message` explains the query result.
1016
-
1017
911
  ### Undo/Redo
1018
912
 
1019
913
  | Method | Description |
@@ -1041,12 +935,13 @@ Store arbitrary data alongside the space without it being part of an object's bo
1041
935
 
1042
936
  Every space has authenticated file storage. WebDAV is the SDK surface for that storage: paths are relative to the space root and collection operations use WebDAV collection semantics. Human/AI file links use `rool-machine:/rool-drive/...`; resolve those links with `resolveMachineResource()` and fetch file resources with `space.fetchMachineResource(resource)`.
1043
937
 
1044
- Use `client.webdav(spaceId)` when you only have an ID, or `space.webdav` when you already have an open space.
938
+ Open a space, then use `space.webdav`.
1045
939
 
1046
940
  ```typescript
1047
941
  import { resolveMachineResource } from '@rool-dev/sdk';
1048
942
 
1049
- const webdav = client.webdav('space-id');
943
+ const space = await client.openSpace('space-id');
944
+ const webdav = space.webdav;
1050
945
 
1051
946
  await webdav.mkcol('docs');
1052
947
  await webdav.put('docs/readme.md', '# Hello', {
@@ -1091,8 +986,6 @@ Paths are space-relative (`docs/readme.md`, not `/docs/readme.md`). WebDAV metho
1091
986
 
1092
987
  | Method | Description |
1093
988
  |--------|-------------|
1094
- | `client.webdav(spaceId)` | Create a WebDAV client for a space |
1095
- | `client.getSpaceStorageUsage(spaceId)` | Get WebDAV quota usage for a space |
1096
989
  | `space.webdav` | WebDAV client for an open space |
1097
990
  | `space.getStorageUsage()` | Get WebDAV quota usage for an open space |
1098
991
  | `webdav.getStorageUsage()` | Get WebDAV quota usage through the WebDAV client |
@@ -1225,37 +1118,23 @@ The archive bundles `data.json` (objects, metadata, and channels) together with
1225
1118
 
1226
1119
  ### Channel Events
1227
1120
 
1228
- Semantic events describe what changed. Events fire for both local changes and remote changes.
1121
+ Channel events are for channel/conversation state. Object and file reactivity goes through `space.on('filesChanged' | 'filesReset')` plus WebDAV `syncCollection()`.
1229
1122
 
1230
1123
  ```typescript
1231
- // source indicates origin:
1232
- // - 'local_user': This client made the change
1233
- // - 'remote_user': Another user/client made the change
1234
- // - 'remote_agent': AI agent made the change
1235
- // - 'system': Resync after error
1236
-
1237
- // Object events — payload includes the full RoolObject
1238
- channel.on('objectCreated', ({ location, object, source }) => void)
1239
- channel.on('objectUpdated', ({ location, object, source }) => void)
1240
- channel.on('objectDeleted', ({ location, source }) => void)
1241
- channel.on('objectMoved', ({ from, to, object, source }) => void)
1242
-
1243
- // Space metadata
1244
- channel.on('metadataUpdated', ({ metadata, source }) => void)
1245
-
1246
- // Collection schema changed
1247
- channel.on('schemaUpdated', ({ schema, source }) => void)
1248
-
1249
- // Channel metadata updated (name, extensionUrl)
1124
+ // Channel metadata updated
1250
1125
  channel.on('channelUpdated', ({ channelId, source }) => void)
1251
1126
 
1252
1127
  // Conversation interaction history updated
1253
1128
  channel.on('conversationUpdated', ({ conversationId, channelId, source }) => void)
1254
1129
 
1130
+ // Space metadata / schema compatibility events
1131
+ channel.on('metadataUpdated', ({ metadata, source }) => void)
1132
+ channel.on('schemaUpdated', ({ schema, source }) => void)
1133
+
1255
1134
  // Full state replacement (undo/redo, resync after error)
1256
1135
  channel.on('reset', ({ source }) => void)
1257
1136
 
1258
- // Sync error occurred, channel resynced from server
1137
+ // Sync error occurred
1259
1138
  channel.on('syncError', (error: Error) => void)
1260
1139
  ```
1261
1140
 
@@ -1386,13 +1265,10 @@ interface Channel {
1386
1265
  createdAt: number; // Timestamp when channel was created
1387
1266
  createdBy: string; // User ID who created the channel
1388
1267
  createdByName?: string; // Display name at time of creation
1389
- extensionUrl?: string; // URL of installed extension (set by installExtension)
1390
- extensionId?: string; // ID of installed extension (user_extensions.extension_id)
1391
- manifest?: ExtensionManifest; // Extension manifest snapshot (set when extension is wired)
1392
1268
  conversations: Record<string, Conversation>; // Keyed by conversation ID
1393
1269
  }
1394
1270
 
1395
- // Channel summary info (returned by client.getChannels)
1271
+ // Channel summary info (used by space.channels)
1396
1272
  interface ChannelInfo {
1397
1273
  id: string;
1398
1274
  name: string | null;
@@ -1400,9 +1276,6 @@ interface ChannelInfo {
1400
1276
  createdBy: string;
1401
1277
  createdByName: string | null;
1402
1278
  interactionCount: number;
1403
- extensionUrl: string | null; // URL of installed extension, or null
1404
- extensionId: string | null; // ID of installed extension, or null
1405
- manifest: ExtensionManifest | null; // Extension manifest snapshot, or null
1406
1279
  }
1407
1280
  ```
1408
1281
 
package/dist/channel.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { EventEmitter } from './event-emitter.js';
2
2
  import type { GraphQLClient } from './graphql.js';
3
3
  import type { RestClient } from './rest.js';
4
- import type { RoolWebDAV } from './webdav.js';
4
+ import { type RoolWebDAV } from './webdav.js';
5
5
  import type { Logger } from './logger.js';
6
- import type { RoolObject, RoolObjectStat, ChannelEvents, RoolUserRole, PromptOptions, FindObjectsOptions, CreateObjectOptions, UpdateObjectOptions, MoveObjectOptions, ChannelEvent, Interaction, Channel, ConversationInfo, LinkAccess, SpaceSchema, CollectionDef, FieldDef, ExtensionManifest } from './types.js';
6
+ import type { RoolObject, GetObjectsResult, RoolObjectStat, ChannelEvents, RoolUserRole, PromptOptions, UpdateObjectOptions, MoveObjectOptions, ChannelEvent, Interaction, Channel, ConversationInfo, LinkAccess, SpaceSchema, CollectionDef, FieldDef, CollectionOptions } from './types.js';
7
7
  export declare function generateEntityId(): string;
8
8
  export interface ChannelConfig {
9
9
  id: string;
@@ -12,9 +12,7 @@ export interface ChannelConfig {
12
12
  linkAccess: LinkAccess;
13
13
  /** Current user's ID (for identifying own interactions) */
14
14
  userId: string;
15
- /** Object locations in the space (sorted by modifiedAt desc) */
16
- objectLocations: string[];
17
- /** Object stats keyed by location */
15
+ /** Object stats keyed by path */
18
16
  objectStats: Record<string, RoolObjectStat>;
19
17
  /** Collection schema */
20
18
  schema: SpaceSchema;
@@ -37,10 +35,10 @@ export interface ChannelConfig {
37
35
  * at open time and cannot be changed. To use a different channel,
38
36
  * open a second one.
39
37
  *
40
- * Objects are addressed by location (`/space/<collection>/<basename>.json`).
41
- * Only schema, metadata, the live object location list, and the channel's own
42
- * history are cached locally. Object bodies are fetched on demand. Changes
43
- * arrive via SSE semantic events and are emitted as SDK events.
38
+ * Objects are addressed by machine path (`/space/.../*.json`).
39
+ * Only schema, metadata, object stats, and the channel's own history are cached
40
+ * locally. Object bodies are fetched on demand. Object/file reactivity is
41
+ * exposed at the space level via WebDAV sync notifications.
44
42
  */
45
43
  export declare class RoolChannel extends EventEmitter<ChannelEvents> {
46
44
  private _id;
@@ -59,12 +57,8 @@ export declare class RoolChannel extends EventEmitter<ChannelEvents> {
59
57
  private _meta;
60
58
  private _schema;
61
59
  private _channel;
62
- private _objectLocations;
63
60
  private _objectStats;
64
61
  private _activeLeaves;
65
- private _pendingMutations;
66
- private _objectResolvers;
67
- private _objectBuffer;
68
62
  constructor(config: ChannelConfig);
69
63
  /**
70
64
  * Handle an event from the shared space subscription.
@@ -80,7 +74,6 @@ export declare class RoolChannel extends EventEmitter<ChannelEvents> {
80
74
  _applyResyncData(data: {
81
75
  meta: Record<string, unknown>;
82
76
  schema: SpaceSchema;
83
- objectLocations: string[];
84
77
  objectStats: Record<string, RoolObjectStat>;
85
78
  channel: Channel | undefined;
86
79
  }): void;
@@ -105,18 +98,6 @@ export declare class RoolChannel extends EventEmitter<ChannelEvents> {
105
98
  */
106
99
  get conversationId(): string;
107
100
  get isReadOnly(): boolean;
108
- /**
109
- * Get the extension URL if this channel was created via installExtension, or null.
110
- */
111
- get extensionUrl(): string | null;
112
- /**
113
- * Get the extension ID if this channel has an installed extension, or null.
114
- */
115
- get extensionId(): string | null;
116
- /**
117
- * Get the extension manifest if this channel has an installed extension, or null.
118
- */
119
- get manifest(): ExtensionManifest | null;
120
101
  /**
121
102
  * Get the active branch of the current conversation as a flat array (root → leaf).
122
103
  * Walks from the active leaf up through parentId pointers.
@@ -178,83 +159,35 @@ export declare class RoolChannel extends EventEmitter<ChannelEvents> {
178
159
  redo(): Promise<boolean>;
179
160
  /** Clear the space's checkpoint history. */
180
161
  clearHistory(): Promise<void>;
181
- /**
182
- * Get an object by location. Fetches from the server on each call.
183
- *
184
- * Accepts either the canonical form (`/space/<collection>/<basename>.json`)
185
- * or the short form (`<collection>/<basename>`).
186
- */
187
- getObject(location: string): Promise<RoolObject | undefined>;
188
- /**
189
- * Get an object's stat (audit information).
190
- * Returns the cached stat or undefined if not known.
191
- */
192
- stat(location: string): RoolObjectStat | undefined;
193
- /**
194
- * Find objects using structured filters and/or natural language.
195
- */
196
- findObjects(options: FindObjectsOptions): Promise<{
197
- objects: RoolObject[];
198
- message: string;
199
- }>;
200
- /** @internal */
201
- _findObjectsImpl(options: FindObjectsOptions, conversationId: string): Promise<{
202
- objects: RoolObject[];
203
- message: string;
204
- }>;
205
- /**
206
- * Get all object locations (sync, from local cache).
207
- * The list is loaded on open and kept current via SSE events.
208
- */
209
- getObjectLocations(options?: {
210
- limit?: number;
211
- order?: 'asc' | 'desc';
212
- }): string[];
213
- /**
214
- * Create a new object in the given collection.
215
- *
216
- * @param collection - The collection (must exist in the schema)
217
- * @param body - Object body fields. Use `{{placeholder}}` for AI-generated content.
218
- * Fields prefixed with `_` are hidden from AI.
219
- * @param options.basename - Specific basename to use. If omitted, the SDK generates a random one.
220
- * @param options.ephemeral - If true, the operation won't be recorded in interaction history.
221
- * @returns The created object and a status message.
222
- */
223
- createObject(collection: string, body: Record<string, unknown>, options?: CreateObjectOptions): Promise<{
162
+ private davHeaders;
163
+ private readObject;
164
+ /** Get an object JSON file by machine path. Fetches from the server on each call. */
165
+ getObject(path: string): Promise<RoolObject | undefined>;
166
+ /** Get object JSON files by machine path in bulk. Duplicate paths are fetched once. */
167
+ getObjects(paths: string[]): Promise<GetObjectsResult>;
168
+ /** Get an object's cached audit information. */
169
+ stat(path: string): RoolObjectStat | undefined;
170
+ /** Create or replace an object JSON file at an exact machine path. */
171
+ putObject(path: string, body: Record<string, unknown>): Promise<{
224
172
  object: RoolObject;
225
173
  message: string;
226
174
  }>;
227
175
  /** @internal */
228
- _createObjectImpl(collection: string, body: Record<string, unknown>, options: CreateObjectOptions | undefined, conversationId: string): Promise<{
176
+ _putObjectImpl(path: string, body: Record<string, unknown>, conversationId: string): Promise<{
229
177
  object: RoolObject;
230
178
  message: string;
231
179
  }>;
232
- /**
233
- * Update an existing object.
234
- *
235
- * @param location - The object's location (canonical or short form)
236
- * @param options.data - Fields to add or update. Pass `null` to delete a field. Use `{{placeholder}}` for AI-generated content.
237
- * @param options.prompt - AI prompt to drive the update.
238
- * @param options.ephemeral - If true, the operation won't be recorded in interaction history.
239
- */
240
- updateObject(location: string, options: UpdateObjectOptions): Promise<{
180
+ /** Patch an existing object. Null or undefined deletes a field. */
181
+ patchObject(path: string, options: UpdateObjectOptions): Promise<{
241
182
  object: RoolObject;
242
183
  message: string;
243
184
  }>;
244
185
  /** @internal */
245
- _updateObjectImpl(location: string, options: UpdateObjectOptions, conversationId: string): Promise<{
186
+ _patchObjectImpl(path: string, options: UpdateObjectOptions, conversationId: string): Promise<{
246
187
  object: RoolObject;
247
188
  message: string;
248
189
  }>;
249
- /**
250
- * Move (rename or relocate) an object to a new location.
251
- * Use this to rename, change collection, or atomically rewrite the body.
252
- *
253
- * @param from - Current location
254
- * @param to - New location
255
- * @param options.body - Replace the body atomically as part of the move.
256
- * @param options.ephemeral - If true, the operation won't be recorded in interaction history.
257
- */
190
+ /** Move an object JSON file to a new machine path, optionally replacing its body. */
258
191
  moveObject(from: string, to: string, options?: MoveObjectOptions): Promise<{
259
192
  object: RoolObject;
260
193
  message: string;
@@ -264,23 +197,22 @@ export declare class RoolChannel extends EventEmitter<ChannelEvents> {
264
197
  object: RoolObject;
265
198
  message: string;
266
199
  }>;
267
- /**
268
- * Delete objects by location.
269
- * Other objects that reference deleted objects will retain stale ref values.
270
- */
271
- deleteObjects(locations: string[]): Promise<void>;
200
+ /** Delete object JSON files by machine path. */
201
+ deleteObjects(paths: string[]): Promise<void>;
202
+ /** @deprecated Use deleteObjects instead. */
203
+ deletePaths(paths: string[]): Promise<void>;
272
204
  /** @internal */
273
- _deleteObjectsImpl(locations: string[], conversationId: string): Promise<void>;
205
+ _deleteObjectsImpl(paths: string[], conversationId: string): Promise<void>;
274
206
  /** Get the current schema for this space. */
275
207
  getSchema(): SpaceSchema;
276
208
  /** Create a new collection schema. */
277
- createCollection(name: string, fields: FieldDef[]): Promise<CollectionDef>;
209
+ createCollection(name: string, fields: FieldDef[] | CollectionDef, options?: CollectionOptions): Promise<CollectionDef>;
278
210
  /** @internal */
279
- _createCollectionImpl(name: string, fields: FieldDef[], conversationId: string): Promise<CollectionDef>;
211
+ _createCollectionImpl(name: string, fields: FieldDef[] | CollectionDef, options: CollectionOptions | undefined, conversationId: string): Promise<CollectionDef>;
280
212
  /** Alter an existing collection schema, replacing its field definitions. */
281
- alterCollection(name: string, fields: FieldDef[]): Promise<CollectionDef>;
213
+ alterCollection(name: string, fields: FieldDef[] | CollectionDef, options?: CollectionOptions): Promise<CollectionDef>;
282
214
  /** @internal */
283
- _alterCollectionImpl(name: string, fields: FieldDef[], conversationId: string): Promise<CollectionDef>;
215
+ _alterCollectionImpl(name: string, fields: FieldDef[] | CollectionDef, options: CollectionOptions | undefined, conversationId: string): Promise<CollectionDef>;
284
216
  /** Drop a collection schema. */
285
217
  dropCollection(name: string): Promise<void>;
286
218
  /** @internal */
@@ -334,28 +266,11 @@ export declare class RoolChannel extends EventEmitter<ChannelEvents> {
334
266
  }): Promise<Response>;
335
267
  private uploadAttachment;
336
268
  private ensureCollection;
337
- /**
338
- * Register a collector that resolves when the object arrives via SSE.
339
- * @internal
340
- */
341
- private _collectObject;
342
- /** @internal */
343
- private _cancelCollector;
344
- /** @internal */
345
- private _deliverObject;
346
269
  /**
347
270
  * Handle a channel event from the subscription.
348
271
  * @internal
349
272
  */
350
273
  private handleChannelEvent;
351
- /** @internal */
352
- private _handleObjectCreated;
353
- /** @internal */
354
- private _handleObjectUpdated;
355
- /** @internal */
356
- private _handleObjectDeleted;
357
- /** @internal */
358
- private _handleObjectMoved;
359
274
  }
360
275
  /**
361
276
  * A lightweight handle for a specific conversation within a channel.
@@ -382,18 +297,13 @@ export declare class ConversationHandle {
382
297
  setSystemInstruction(instruction: string | null): Promise<void>;
383
298
  /** Rename this conversation. */
384
299
  rename(name: string): Promise<void>;
385
- /** Find objects using structured filters and/or natural language. */
386
- findObjects(options: FindObjectsOptions): Promise<{
387
- objects: RoolObject[];
388
- message: string;
389
- }>;
390
- /** Create a new object. */
391
- createObject(collection: string, body: Record<string, unknown>, options?: CreateObjectOptions): Promise<{
300
+ /** Create or replace an object JSON file. */
301
+ putObject(path: string, body: Record<string, unknown>): Promise<{
392
302
  object: RoolObject;
393
303
  message: string;
394
304
  }>;
395
- /** Update an existing object. */
396
- updateObject(location: string, options: UpdateObjectOptions): Promise<{
305
+ /** Patch an existing object JSON file. */
306
+ patchObject(path: string, options: UpdateObjectOptions): Promise<{
397
307
  object: RoolObject;
398
308
  message: string;
399
309
  }>;
@@ -402,17 +312,19 @@ export declare class ConversationHandle {
402
312
  object: RoolObject;
403
313
  message: string;
404
314
  }>;
405
- /** Delete objects by location. */
406
- deleteObjects(locations: string[]): Promise<void>;
315
+ /** Delete object JSON files by path. */
316
+ deleteObjects(paths: string[]): Promise<void>;
317
+ /** @deprecated Use deleteObjects instead. */
318
+ deletePaths(paths: string[]): Promise<void>;
407
319
  /** Send a prompt to the AI agent, scoped to this conversation's history. */
408
320
  prompt(text: string, options?: PromptOptions): Promise<{
409
321
  message: string;
410
322
  objects: RoolObject[];
411
323
  }>;
412
324
  /** Create a new collection schema. */
413
- createCollection(name: string, fields: FieldDef[]): Promise<CollectionDef>;
325
+ createCollection(name: string, fields: FieldDef[] | CollectionDef, options?: CollectionOptions): Promise<CollectionDef>;
414
326
  /** Alter an existing collection schema. */
415
- alterCollection(name: string, fields: FieldDef[]): Promise<CollectionDef>;
327
+ alterCollection(name: string, fields: FieldDef[] | CollectionDef, options?: CollectionOptions): Promise<CollectionDef>;
416
328
  /** Drop a collection schema. */
417
329
  dropCollection(name: string): Promise<void>;
418
330
  setMetadata(key: string, value: unknown): void;