@rool-dev/extension 0.3.5
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 +458 -0
- package/dist/cli/build-pipeline.d.ts +18 -0
- package/dist/cli/build-pipeline.d.ts.map +1 -0
- package/dist/cli/build-pipeline.js +160 -0
- package/dist/cli/build.d.ts +9 -0
- package/dist/cli/build.d.ts.map +1 -0
- package/dist/cli/build.js +17 -0
- package/dist/cli/dev.d.ts +10 -0
- package/dist/cli/dev.d.ts.map +1 -0
- package/dist/cli/dev.js +257 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +34 -0
- package/dist/cli/init.d.ts +8 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +113 -0
- package/dist/cli/publish.d.ts +9 -0
- package/dist/cli/publish.d.ts.map +1 -0
- package/dist/cli/publish.js +65 -0
- package/dist/cli/vite-utils.d.ts +23 -0
- package/dist/cli/vite-utils.d.ts.map +1 -0
- package/dist/cli/vite-utils.js +105 -0
- package/dist/client.d.ts +139 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +360 -0
- package/dist/dev/AppGrid.svelte +246 -0
- package/dist/dev/AppGrid.svelte.d.ts +14 -0
- package/dist/dev/AppGrid.svelte.d.ts.map +1 -0
- package/dist/dev/DevHostController.d.ts +85 -0
- package/dist/dev/DevHostController.d.ts.map +1 -0
- package/dist/dev/DevHostController.js +429 -0
- package/dist/dev/HostShell.svelte +119 -0
- package/dist/dev/HostShell.svelte.d.ts +11 -0
- package/dist/dev/HostShell.svelte.d.ts.map +1 -0
- package/dist/dev/Sidebar.svelte +290 -0
- package/dist/dev/Sidebar.svelte.d.ts +22 -0
- package/dist/dev/Sidebar.svelte.d.ts.map +1 -0
- package/dist/dev/TabBar.svelte +83 -0
- package/dist/dev/TabBar.svelte.d.ts +14 -0
- package/dist/dev/TabBar.svelte.d.ts.map +1 -0
- package/dist/dev/app.css +1 -0
- package/dist/dev/host-shell.d.ts +8 -0
- package/dist/dev/host-shell.d.ts.map +1 -0
- package/dist/dev/host-shell.js +15282 -0
- package/dist/dev/host-shell.js.map +1 -0
- package/dist/dev/vite-env.d.ts +4 -0
- package/dist/host.d.ts +55 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +203 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/manifest.d.ts +40 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +11 -0
- package/dist/protocol.d.ts +48 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +14 -0
- package/dist/reactive.svelte.d.ts +150 -0
- package/dist/reactive.svelte.d.ts.map +1 -0
- package/dist/reactive.svelte.js +362 -0
- package/dist/types.d.ts +139 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/package.json +79 -0
package/dist/host.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rool-dev/extension/host — Host-side bridge for iframe-sandboxed extensions.
|
|
3
|
+
*
|
|
4
|
+
* The host creates a `BridgeHost` with a real `BridgeableChannel` and an iframe.
|
|
5
|
+
* It handles the handshake, proxies method calls, and forwards events.
|
|
6
|
+
*
|
|
7
|
+
* Used by both the console's ExtensionHost component and the local dev shell.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Minimal channel interface accepted by the bridge host.
|
|
11
|
+
* Works with both BridgeableChannel (SDK) and ReactiveChannel (@rool-dev/svelte).
|
|
12
|
+
*/
|
|
13
|
+
export interface BridgeableChannel {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
role: string;
|
|
17
|
+
linkAccess: string;
|
|
18
|
+
userId: string;
|
|
19
|
+
channelId: string;
|
|
20
|
+
getSchema(): Record<string, unknown>;
|
|
21
|
+
getAllMetadata(): Record<string, unknown>;
|
|
22
|
+
on(event: string, handler: (...args: unknown[]) => void): void;
|
|
23
|
+
off(event: string, handler: (...args: unknown[]) => void): void;
|
|
24
|
+
conversation(conversationId: string): unknown;
|
|
25
|
+
}
|
|
26
|
+
export interface BridgeHostOptions {
|
|
27
|
+
/** The real channel to proxy calls to */
|
|
28
|
+
channel: BridgeableChannel;
|
|
29
|
+
/** The iframe element hosting the extension */
|
|
30
|
+
iframe: HTMLIFrameElement;
|
|
31
|
+
}
|
|
32
|
+
export declare class BridgeHost {
|
|
33
|
+
private channel;
|
|
34
|
+
private iframe;
|
|
35
|
+
private eventCleanups;
|
|
36
|
+
private _destroyed;
|
|
37
|
+
constructor(options: BridgeHostOptions);
|
|
38
|
+
private _sendInit;
|
|
39
|
+
private _onMessage;
|
|
40
|
+
private _handleRequest;
|
|
41
|
+
private _postToApp;
|
|
42
|
+
destroy(): void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a bridge host that proxies a BridgeableChannel to an iframe.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const host = createBridgeHost({ channel, iframe });
|
|
50
|
+
* // ... later
|
|
51
|
+
* host.destroy();
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare function createBridgeHost(options: BridgeHostOptions): BridgeHost;
|
|
55
|
+
//# sourceMappingURL=host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH;;;GAGG;AAEH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAC/D,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAChE,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/C;AAqED,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,+CAA+C;IAC/C,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,EAAE,iBAAiB;IA0BtC,OAAO,CAAC,SAAS;IAmBjB,OAAO,CAAC,UAAU,CAchB;YAEY,cAAc;IAgD5B,OAAO,CAAC,UAAU;IASlB,OAAO,IAAI,IAAI;CAQhB;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAEvE"}
|
package/dist/host.js
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rool-dev/extension/host — Host-side bridge for iframe-sandboxed extensions.
|
|
3
|
+
*
|
|
4
|
+
* The host creates a `BridgeHost` with a real `BridgeableChannel` and an iframe.
|
|
5
|
+
* It handles the handshake, proxies method calls, and forwards events.
|
|
6
|
+
*
|
|
7
|
+
* Used by both the console's ExtensionHost component and the local dev shell.
|
|
8
|
+
*/
|
|
9
|
+
import { isBridgeMessage } from './protocol.js';
|
|
10
|
+
// Channel events to forward to the extension
|
|
11
|
+
const FORWARDED_EVENTS = [
|
|
12
|
+
'objectCreated',
|
|
13
|
+
'objectUpdated',
|
|
14
|
+
'objectDeleted',
|
|
15
|
+
'metadataUpdated',
|
|
16
|
+
'schemaUpdated',
|
|
17
|
+
'channelUpdated',
|
|
18
|
+
'conversationUpdated',
|
|
19
|
+
'reset',
|
|
20
|
+
'syncError',
|
|
21
|
+
];
|
|
22
|
+
// Channel methods the extension can call.
|
|
23
|
+
// Sync methods (getObjectIds, getSchema, etc.) are wrapped as async on the host side.
|
|
24
|
+
const ALLOWED_METHODS = new Set([
|
|
25
|
+
'getObject',
|
|
26
|
+
'stat',
|
|
27
|
+
'findObjects',
|
|
28
|
+
'getObjectIds',
|
|
29
|
+
'createObject',
|
|
30
|
+
'updateObject',
|
|
31
|
+
'deleteObjects',
|
|
32
|
+
'getSchema',
|
|
33
|
+
'createCollection',
|
|
34
|
+
'alterCollection',
|
|
35
|
+
'dropCollection',
|
|
36
|
+
'getInteractions',
|
|
37
|
+
'getConversations',
|
|
38
|
+
'getSystemInstruction',
|
|
39
|
+
'setSystemInstruction',
|
|
40
|
+
'deleteConversation',
|
|
41
|
+
'renameConversation',
|
|
42
|
+
'setMetadata',
|
|
43
|
+
'getMetadata',
|
|
44
|
+
'getAllMetadata',
|
|
45
|
+
'prompt',
|
|
46
|
+
'checkpoint',
|
|
47
|
+
'canUndo',
|
|
48
|
+
'canRedo',
|
|
49
|
+
'undo',
|
|
50
|
+
'redo',
|
|
51
|
+
'clearHistory',
|
|
52
|
+
]);
|
|
53
|
+
// Methods that can be dispatched to a ConversationHandle when conversationId is present
|
|
54
|
+
const CONVERSATION_METHODS = new Set([
|
|
55
|
+
'getInteractions',
|
|
56
|
+
'getSystemInstruction',
|
|
57
|
+
'setSystemInstruction',
|
|
58
|
+
'renameConversation',
|
|
59
|
+
'findObjects',
|
|
60
|
+
'createObject',
|
|
61
|
+
'updateObject',
|
|
62
|
+
'deleteObjects',
|
|
63
|
+
'prompt',
|
|
64
|
+
'createCollection',
|
|
65
|
+
'alterCollection',
|
|
66
|
+
'dropCollection',
|
|
67
|
+
'setMetadata',
|
|
68
|
+
]);
|
|
69
|
+
// Wire method names that differ on ConversationHandle
|
|
70
|
+
const CONVERSATION_METHOD_MAP = {
|
|
71
|
+
'renameConversation': 'rename',
|
|
72
|
+
};
|
|
73
|
+
export class BridgeHost {
|
|
74
|
+
channel;
|
|
75
|
+
iframe;
|
|
76
|
+
eventCleanups = [];
|
|
77
|
+
_destroyed = false;
|
|
78
|
+
constructor(options) {
|
|
79
|
+
this.channel = options.channel;
|
|
80
|
+
this.iframe = options.iframe;
|
|
81
|
+
window.addEventListener('message', this._onMessage);
|
|
82
|
+
// Forward channel events to the extension iframe
|
|
83
|
+
for (const eventName of FORWARDED_EVENTS) {
|
|
84
|
+
const handler = (data) => {
|
|
85
|
+
this._postToApp({
|
|
86
|
+
type: 'rool:event',
|
|
87
|
+
name: eventName,
|
|
88
|
+
data,
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
this.channel.on(eventName, handler);
|
|
92
|
+
this.eventCleanups.push(() => {
|
|
93
|
+
this.channel.off(eventName, handler);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Handshake
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
_sendInit() {
|
|
101
|
+
const init = {
|
|
102
|
+
type: 'rool:init',
|
|
103
|
+
channelId: this.channel.channelId,
|
|
104
|
+
spaceId: this.channel.id,
|
|
105
|
+
spaceName: this.channel.name,
|
|
106
|
+
role: this.channel.role,
|
|
107
|
+
linkAccess: this.channel.linkAccess,
|
|
108
|
+
userId: this.channel.userId,
|
|
109
|
+
schema: this.channel.getSchema(),
|
|
110
|
+
metadata: this.channel.getAllMetadata(),
|
|
111
|
+
};
|
|
112
|
+
this._postToApp(init);
|
|
113
|
+
}
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
// Message handling
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
_onMessage = async (event) => {
|
|
118
|
+
// Only accept messages from our iframe
|
|
119
|
+
if (event.source !== this.iframe.contentWindow)
|
|
120
|
+
return;
|
|
121
|
+
if (!isBridgeMessage(event.data))
|
|
122
|
+
return;
|
|
123
|
+
if (event.data.type === 'rool:ready') {
|
|
124
|
+
this._sendInit();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (event.data.type === 'rool:request') {
|
|
128
|
+
await this._handleRequest(event.data);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
async _handleRequest(req) {
|
|
133
|
+
const { id, method, args, conversationId } = req;
|
|
134
|
+
if (!ALLOWED_METHODS.has(method)) {
|
|
135
|
+
this._postToApp({
|
|
136
|
+
type: 'rool:response',
|
|
137
|
+
id,
|
|
138
|
+
error: `Method "${method}" is not available to extensions`,
|
|
139
|
+
});
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
// Determine the target: conversation handle or channel
|
|
144
|
+
let target = this.channel;
|
|
145
|
+
let methodName = method;
|
|
146
|
+
if (conversationId !== undefined && CONVERSATION_METHODS.has(method)) {
|
|
147
|
+
target = this.channel.conversation(conversationId);
|
|
148
|
+
methodName = CONVERSATION_METHOD_MAP[method] ?? method;
|
|
149
|
+
}
|
|
150
|
+
// Get the method from the target (cast for dynamic dispatch)
|
|
151
|
+
const fn = target[methodName];
|
|
152
|
+
let result;
|
|
153
|
+
if (typeof fn === 'function') {
|
|
154
|
+
result = fn.apply(target, args);
|
|
155
|
+
// Await if it returns a promise
|
|
156
|
+
if (result instanceof Promise) {
|
|
157
|
+
result = await result;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
// Property access (shouldn't happen with current ALLOWED_METHODS, but just in case)
|
|
162
|
+
result = fn;
|
|
163
|
+
}
|
|
164
|
+
this._postToApp({ type: 'rool:response', id, result });
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
168
|
+
this._postToApp({ type: 'rool:response', id, error: message });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// Helpers
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
_postToApp(message) {
|
|
175
|
+
if (this._destroyed)
|
|
176
|
+
return;
|
|
177
|
+
this.iframe.contentWindow?.postMessage(message, '*');
|
|
178
|
+
}
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// Cleanup
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
destroy() {
|
|
183
|
+
this._destroyed = true;
|
|
184
|
+
window.removeEventListener('message', this._onMessage);
|
|
185
|
+
for (const cleanup of this.eventCleanups) {
|
|
186
|
+
cleanup();
|
|
187
|
+
}
|
|
188
|
+
this.eventCleanups = [];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Create a bridge host that proxies a BridgeableChannel to an iframe.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* const host = createBridgeHost({ channel, iframe });
|
|
197
|
+
* // ... later
|
|
198
|
+
* host.destroy();
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
export function createBridgeHost(options) {
|
|
202
|
+
return new BridgeHost(options);
|
|
203
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rool-dev/extension — Svelte-first extension SDK for Rool.
|
|
3
|
+
*
|
|
4
|
+
* `initExtension()` connects to the host via the iframe bridge and returns
|
|
5
|
+
* a reactive channel with $state properties, matching the @rool-dev/svelte API.
|
|
6
|
+
*/
|
|
7
|
+
export { initExtension } from './reactive.svelte.js';
|
|
8
|
+
export type { ReactiveChannel, ReactiveConversationHandle, ReactiveObject, ReactiveWatch, WatchOptions } from './reactive.svelte.js';
|
|
9
|
+
export type { RoolObject, RoolObjectStat, SpaceSchema, CollectionDef, FieldDef, FieldType, Interaction, InteractionStatus, ConversationInfo, ToolCall, PromptOptions, PromptEffort, FindObjectsOptions, CreateObjectOptions, UpdateObjectOptions, ChangeSource, RoolUserRole, LinkAccess, ChannelEvents, } from './types.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,0BAA0B,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGrI,YAAY,EACV,UAAU,EACV,cAAc,EACd,WAAW,EACX,aAAa,EACb,QAAQ,EACR,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,aAAa,GACd,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rool-dev/extension — Svelte-first extension SDK for Rool.
|
|
3
|
+
*
|
|
4
|
+
* `initExtension()` connects to the host via the iframe bridge and returns
|
|
5
|
+
* a reactive channel with $state properties, matching the @rool-dev/svelte API.
|
|
6
|
+
*/
|
|
7
|
+
// Public API — reactive channel
|
|
8
|
+
export { initExtension } from './reactive.svelte.js';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared manifest types and environment config.
|
|
3
|
+
*
|
|
4
|
+
* Browser-safe — no Node.js imports. Used by CLI code, the dev host shell,
|
|
5
|
+
* and the publish command.
|
|
6
|
+
*/
|
|
7
|
+
export interface ManifestFieldDef {
|
|
8
|
+
name: string;
|
|
9
|
+
type: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export interface ManifestCollections {
|
|
12
|
+
write?: Record<string, ManifestFieldDef[]> | '*';
|
|
13
|
+
read?: Record<string, ManifestFieldDef[]> | '*';
|
|
14
|
+
}
|
|
15
|
+
export interface Manifest {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
public: boolean;
|
|
19
|
+
icon?: string;
|
|
20
|
+
collections: ManifestCollections;
|
|
21
|
+
description?: string;
|
|
22
|
+
systemInstruction?: string | null;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
export type ManifestResult = {
|
|
26
|
+
manifest: Manifest;
|
|
27
|
+
error: null;
|
|
28
|
+
} | {
|
|
29
|
+
manifest: null;
|
|
30
|
+
error: string;
|
|
31
|
+
};
|
|
32
|
+
export type Environment = 'local' | 'dev' | 'prod';
|
|
33
|
+
export interface EnvironmentConfig {
|
|
34
|
+
baseUrl: string;
|
|
35
|
+
authUrl: string;
|
|
36
|
+
label: string;
|
|
37
|
+
appsDomain: string;
|
|
38
|
+
}
|
|
39
|
+
export declare const ENV_URLS: Record<Environment, EnvironmentConfig>;
|
|
40
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,GAAG,GAAG,CAAC;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,GAAG,GAAG,CAAC;CACjD;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,mBAAmB,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GACnC;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAMtC,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAI3D,CAAC"}
|
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared manifest types and environment config.
|
|
3
|
+
*
|
|
4
|
+
* Browser-safe — no Node.js imports. Used by CLI code, the dev host shell,
|
|
5
|
+
* and the publish command.
|
|
6
|
+
*/
|
|
7
|
+
export const ENV_URLS = {
|
|
8
|
+
local: { baseUrl: 'http://localhost:1357', authUrl: 'https://api.dev.rool.dev/auth', label: 'localhost:1357', appsDomain: 'dev.rool.app' },
|
|
9
|
+
dev: { baseUrl: 'https://api.dev.rool.dev', authUrl: 'https://api.dev.rool.dev/auth', label: 'api.dev.rool.dev', appsDomain: 'dev.rool.app' },
|
|
10
|
+
prod: { baseUrl: 'https://api.rool.dev', authUrl: 'https://api.rool.dev/auth', label: 'api.rool.dev', appsDomain: 'rool.app' },
|
|
11
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge protocol types shared between extension (client) and host.
|
|
3
|
+
*
|
|
4
|
+
* All communication between the sandboxed iframe and the host happens
|
|
5
|
+
* via window.postMessage using these message shapes.
|
|
6
|
+
*/
|
|
7
|
+
/** Extension → Host: invoke a channel method */
|
|
8
|
+
export interface BridgeRequest {
|
|
9
|
+
type: 'rool:request';
|
|
10
|
+
id: string;
|
|
11
|
+
method: string;
|
|
12
|
+
args: unknown[];
|
|
13
|
+
/** When present, the host dispatches to channel.conversation(conversationId) */
|
|
14
|
+
conversationId?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Host → Extension: result of a channel method call */
|
|
17
|
+
export interface BridgeResponse {
|
|
18
|
+
type: 'rool:response';
|
|
19
|
+
id: string;
|
|
20
|
+
result?: unknown;
|
|
21
|
+
error?: string;
|
|
22
|
+
}
|
|
23
|
+
/** Host → Extension: channel event pushed in real-time */
|
|
24
|
+
export interface BridgeEvent {
|
|
25
|
+
type: 'rool:event';
|
|
26
|
+
name: string;
|
|
27
|
+
data: unknown;
|
|
28
|
+
}
|
|
29
|
+
/** Extension → Host: extension is loaded and ready for handshake */
|
|
30
|
+
export interface BridgeReady {
|
|
31
|
+
type: 'rool:ready';
|
|
32
|
+
}
|
|
33
|
+
/** Host → Extension: handshake response with channel metadata */
|
|
34
|
+
export interface BridgeInit {
|
|
35
|
+
type: 'rool:init';
|
|
36
|
+
channelId: string;
|
|
37
|
+
spaceId: string;
|
|
38
|
+
spaceName: string;
|
|
39
|
+
role: string;
|
|
40
|
+
linkAccess: string;
|
|
41
|
+
userId: string;
|
|
42
|
+
schema: Record<string, unknown>;
|
|
43
|
+
metadata: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
export type BridgeMessage = BridgeRequest | BridgeResponse | BridgeEvent | BridgeReady | BridgeInit;
|
|
46
|
+
/** Type guard for bridge messages */
|
|
47
|
+
export declare function isBridgeMessage(data: unknown): data is BridgeMessage;
|
|
48
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,gDAAgD;AAChD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,cAAc,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,eAAe,CAAC;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;CACf;AAED,oEAAoE;AACpE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,iEAAiE;AACjE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,MAAM,aAAa,GACrB,aAAa,GACb,cAAc,GACd,WAAW,GACX,WAAW,GACX,UAAU,CAAC;AAEf,qCAAqC;AACrC,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,aAAa,CAQpE"}
|
package/dist/protocol.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge protocol types shared between extension (client) and host.
|
|
3
|
+
*
|
|
4
|
+
* All communication between the sandboxed iframe and the host happens
|
|
5
|
+
* via window.postMessage using these message shapes.
|
|
6
|
+
*/
|
|
7
|
+
/** Type guard for bridge messages */
|
|
8
|
+
export function isBridgeMessage(data) {
|
|
9
|
+
return (typeof data === 'object' &&
|
|
10
|
+
data !== null &&
|
|
11
|
+
'type' in data &&
|
|
12
|
+
typeof data.type === 'string' &&
|
|
13
|
+
data.type.startsWith('rool:'));
|
|
14
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reactive Svelte wrapper around Channel (bridge client).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the @rool-dev/svelte ReactiveChannel API: same $state properties,
|
|
5
|
+
* same methods, same reactive primitives (object(), watch()).
|
|
6
|
+
* The underlying transport is the postMessage bridge, not the SDK.
|
|
7
|
+
*/
|
|
8
|
+
import { Channel } from './client.js';
|
|
9
|
+
import type { RoolObject, FieldDef, Interaction, ConversationInfo, PromptOptions, FindObjectsOptions, CreateObjectOptions, UpdateObjectOptions } from './types.js';
|
|
10
|
+
export interface WatchOptions {
|
|
11
|
+
where?: Record<string, unknown>;
|
|
12
|
+
collection?: string;
|
|
13
|
+
limit?: number;
|
|
14
|
+
order?: 'asc' | 'desc';
|
|
15
|
+
}
|
|
16
|
+
declare class ReactiveWatchImpl {
|
|
17
|
+
#private;
|
|
18
|
+
objects: RoolObject[];
|
|
19
|
+
loading: boolean;
|
|
20
|
+
constructor(channel: Channel, options: WatchOptions);
|
|
21
|
+
refresh(): Promise<void>;
|
|
22
|
+
close(): void;
|
|
23
|
+
}
|
|
24
|
+
export type ReactiveWatch = ReactiveWatchImpl;
|
|
25
|
+
declare class ReactiveObjectImpl {
|
|
26
|
+
#private;
|
|
27
|
+
data: RoolObject | undefined;
|
|
28
|
+
loading: boolean;
|
|
29
|
+
constructor(channel: Channel, objectId: string);
|
|
30
|
+
refresh(): Promise<void>;
|
|
31
|
+
close(): void;
|
|
32
|
+
}
|
|
33
|
+
export type ReactiveObject = ReactiveObjectImpl;
|
|
34
|
+
declare class ReactiveChannelImpl {
|
|
35
|
+
#private;
|
|
36
|
+
interactions: Interaction[];
|
|
37
|
+
objectIds: string[];
|
|
38
|
+
collections: string[];
|
|
39
|
+
conversations: ConversationInfo[];
|
|
40
|
+
constructor(channel: Channel);
|
|
41
|
+
get channelId(): string;
|
|
42
|
+
get spaceId(): string;
|
|
43
|
+
get spaceName(): string;
|
|
44
|
+
get role(): import("./types.js").RoolUserRole;
|
|
45
|
+
get linkAccess(): import("./types.js").LinkAccess;
|
|
46
|
+
get userId(): string;
|
|
47
|
+
get isReadOnly(): boolean;
|
|
48
|
+
getObject(objectId: string): Promise<RoolObject | undefined>;
|
|
49
|
+
stat(objectId: string): Promise<import("./types.js").RoolObjectStat | undefined>;
|
|
50
|
+
findObjects(options: FindObjectsOptions): Promise<{
|
|
51
|
+
objects: RoolObject[];
|
|
52
|
+
message: string;
|
|
53
|
+
}>;
|
|
54
|
+
getObjectIds(options?: {
|
|
55
|
+
limit?: number;
|
|
56
|
+
order?: 'asc' | 'desc';
|
|
57
|
+
}): Promise<string[]>;
|
|
58
|
+
createObject(options: CreateObjectOptions): Promise<{
|
|
59
|
+
object: RoolObject;
|
|
60
|
+
message: string;
|
|
61
|
+
}>;
|
|
62
|
+
updateObject(objectId: string, options: UpdateObjectOptions): Promise<{
|
|
63
|
+
object: RoolObject;
|
|
64
|
+
message: string;
|
|
65
|
+
}>;
|
|
66
|
+
deleteObjects(objectIds: string[]): Promise<void>;
|
|
67
|
+
prompt(text: string, options?: PromptOptions): Promise<{
|
|
68
|
+
message: string;
|
|
69
|
+
objects: RoolObject[];
|
|
70
|
+
}>;
|
|
71
|
+
checkpoint(label?: string): Promise<string>;
|
|
72
|
+
canUndo(): Promise<boolean>;
|
|
73
|
+
canRedo(): Promise<boolean>;
|
|
74
|
+
undo(): Promise<boolean>;
|
|
75
|
+
redo(): Promise<boolean>;
|
|
76
|
+
clearHistory(): Promise<void>;
|
|
77
|
+
setMetadata(key: string, value: unknown): Promise<void>;
|
|
78
|
+
getMetadata(key: string): unknown;
|
|
79
|
+
getAllMetadata(): Record<string, unknown>;
|
|
80
|
+
getInteractions(): Promise<Interaction[]>;
|
|
81
|
+
getSystemInstruction(): Promise<string | undefined>;
|
|
82
|
+
setSystemInstruction(instruction: string | null): Promise<void>;
|
|
83
|
+
getConversations(): Promise<ConversationInfo[]>;
|
|
84
|
+
deleteConversation(conversationId: string): Promise<void>;
|
|
85
|
+
renameConversation(name: string): Promise<void>;
|
|
86
|
+
getSchema(): import("./types.js").SpaceSchema;
|
|
87
|
+
createCollection(name: string, fields: FieldDef[]): Promise<import("./types.js").CollectionDef>;
|
|
88
|
+
alterCollection(name: string, fields: FieldDef[]): Promise<import("./types.js").CollectionDef>;
|
|
89
|
+
dropCollection(name: string): Promise<void>;
|
|
90
|
+
conversation(conversationId: string): ReactiveConversationHandle;
|
|
91
|
+
on(...args: Parameters<Channel['on']>): void;
|
|
92
|
+
off(...args: Parameters<Channel['off']>): void;
|
|
93
|
+
object(objectId: string): ReactiveObject;
|
|
94
|
+
watch(options: WatchOptions): ReactiveWatch;
|
|
95
|
+
destroy(): void;
|
|
96
|
+
}
|
|
97
|
+
export type ReactiveChannel = ReactiveChannelImpl;
|
|
98
|
+
/**
|
|
99
|
+
* A reactive conversation handle for the extension bridge.
|
|
100
|
+
* Wraps ConversationHandle with $state interactions that auto-update
|
|
101
|
+
* when the conversation changes via SSE events.
|
|
102
|
+
*
|
|
103
|
+
* Call `close()` when done to stop listening for updates.
|
|
104
|
+
*/
|
|
105
|
+
declare class ReactiveConversationHandleImpl {
|
|
106
|
+
#private;
|
|
107
|
+
interactions: Interaction[];
|
|
108
|
+
constructor(channel: Channel, conversationId: string);
|
|
109
|
+
get conversationId(): string;
|
|
110
|
+
getInteractions(): Promise<Interaction[]>;
|
|
111
|
+
getSystemInstruction(): Promise<string | undefined>;
|
|
112
|
+
setSystemInstruction(instruction: string | null): Promise<void>;
|
|
113
|
+
rename(name: string): Promise<void>;
|
|
114
|
+
findObjects(options: FindObjectsOptions): Promise<{
|
|
115
|
+
objects: RoolObject[];
|
|
116
|
+
message: string;
|
|
117
|
+
}>;
|
|
118
|
+
createObject(options: CreateObjectOptions): Promise<{
|
|
119
|
+
object: RoolObject;
|
|
120
|
+
message: string;
|
|
121
|
+
}>;
|
|
122
|
+
updateObject(objectId: string, options: UpdateObjectOptions): Promise<{
|
|
123
|
+
object: RoolObject;
|
|
124
|
+
message: string;
|
|
125
|
+
}>;
|
|
126
|
+
deleteObjects(objectIds: string[]): Promise<void>;
|
|
127
|
+
prompt(text: string, options?: PromptOptions): Promise<{
|
|
128
|
+
message: string;
|
|
129
|
+
objects: RoolObject[];
|
|
130
|
+
}>;
|
|
131
|
+
createCollection(name: string, fields: FieldDef[]): Promise<import("./types.js").CollectionDef>;
|
|
132
|
+
alterCollection(name: string, fields: FieldDef[]): Promise<import("./types.js").CollectionDef>;
|
|
133
|
+
dropCollection(name: string): Promise<void>;
|
|
134
|
+
setMetadata(key: string, value: unknown): Promise<void>;
|
|
135
|
+
/**
|
|
136
|
+
* Stop listening for updates and clean up.
|
|
137
|
+
*/
|
|
138
|
+
close(): void;
|
|
139
|
+
}
|
|
140
|
+
export type ReactiveConversationHandle = ReactiveConversationHandleImpl;
|
|
141
|
+
/**
|
|
142
|
+
* Initialize the extension and return a reactive channel.
|
|
143
|
+
*
|
|
144
|
+
* Sends `rool:ready` to the host, waits for the handshake, and returns
|
|
145
|
+
* a reactive channel with $state properties (interactions, objectIds)
|
|
146
|
+
* and reactive primitives (object(), watch()).
|
|
147
|
+
*/
|
|
148
|
+
export declare function initExtension(timeout?: number): Promise<ReactiveChannel>;
|
|
149
|
+
export {};
|
|
150
|
+
//# sourceMappingURL=reactive.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactive.svelte.d.ts","sourceRoot":"","sources":["../src/reactive.svelte.ts"],"names":[],"mappings":"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"}
|