@web-applets/sdk 0.0.8 → 0.0.9
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 +98 -19
- package/dist/client.js +11 -4
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
@@ -1,18 +1,96 @@
|
|
1
1
|
# Web Applets
|
2
2
|
|
3
|
-
> An open
|
3
|
+
> An open spec & SDK for creating apps that agents can use.
|
4
4
|
|
5
|
-
🔗 [
|
5
|
+
🔗 [Applets Repo](https://github.com/unternet-co/community-applets) | 🔗 [Mailing List](https://groups.google.com/a/unternet.co/g/community) | 🔗 [Applets Chat Demo](https://github.com/unternet-co/applets-chat)
|
6
6
|
|
7
7
|
## What is it?
|
8
8
|
|
9
|
-
Web Applets is
|
9
|
+
Web Applets is an open specification for building software that both humans and AI can understand and use together. Instead of forcing AI to operate traditional point-and-click apps built for humans, Web Applets creates a new kind of software designed for human-AI collaboration. Think of them a bit like artifacts, but they do stuff!
|
10
10
|
|
11
|
-
|
11
|
+

|
12
12
|
|
13
|
-
|
13
|
+
Web Applets are modular pieces of web software that:
|
14
14
|
|
15
|
-
|
15
|
+
- **Can be used directly by humans with rich, graphical interfaces**
|
16
|
+
- **Can be understood and operated by AI through a clear protocol**
|
17
|
+
- **Run locally in your environment, not on distant servers**
|
18
|
+
- **Share context and state with their environment**
|
19
|
+
- **Can be freely combined and composed**
|
20
|
+
|
21
|
+
Think of any web software you use today - maps, documents, shopping, calendars - and imagine if instead of visiting these as separate websites, you could pull them into your own environment where both you and AI could use them together seamlessly.
|
22
|
+
|
23
|
+
## Key Features
|
24
|
+
|
25
|
+
- **Built on Web Standards:** Create applets using familiar web technologies (HTML, CSS, JavaScript)
|
26
|
+
- **AI-Native Protocol:** Applets expose their state and actions in a way AI can understand and use
|
27
|
+
- **Rich Interfaces:** Full support for complex graphical UIs, not just text
|
28
|
+
- **Local-First:** Runs in your environment, keeping your data under your control
|
29
|
+
- **Composable:** Applets can work together, sharing context and state
|
30
|
+
- **Open Standard:** Designed for interoperability, not platform lock-in
|
31
|
+
|
32
|
+
Web Applets aims to do for AI-enabled software what the web did for documents - create an open platform where anyone can build, share, and connect applications. We believe the future of software should be built on open collaboration, not tight integration with closed platforms.
|
33
|
+
|
34
|
+
## Example
|
35
|
+
|
36
|
+
This is a simple applet that prints "Hello, [your name]" when given the `set_name` action.
|
37
|
+
|
38
|
+
`index.html`:
|
39
|
+
|
40
|
+
```html
|
41
|
+
<!DOCTYPE html>
|
42
|
+
<html lang="en">
|
43
|
+
<script src="./main.js" type="module"></script>
|
44
|
+
<body>
|
45
|
+
Hello! <span id="name">whoever you are</span>.
|
46
|
+
</body>
|
47
|
+
</html>
|
48
|
+
```
|
49
|
+
|
50
|
+
`main.js`:
|
51
|
+
|
52
|
+
```js
|
53
|
+
import { appletContext } from '@web-applets/sdk';
|
54
|
+
|
55
|
+
// Get view element we want to manipulate
|
56
|
+
const nameElem = document.getElementById('name');
|
57
|
+
|
58
|
+
// Connect to the applet context
|
59
|
+
const applet = appletContext.connect();
|
60
|
+
|
61
|
+
// When the set_name action is called, change the state
|
62
|
+
applet.setActionHandler('set_name', ({ name }) => {
|
63
|
+
applet.setState({ name });
|
64
|
+
});
|
65
|
+
|
66
|
+
// Whenever we get a request to render the view, update the name
|
67
|
+
applet.onrender = () => {
|
68
|
+
nameElem.innerText = applet.state?.name;
|
69
|
+
};
|
70
|
+
```
|
71
|
+
|
72
|
+
`manifest.json`:
|
73
|
+
|
74
|
+
```json
|
75
|
+
{
|
76
|
+
"type": "applet",
|
77
|
+
"name": "Hello World",
|
78
|
+
"description": "Displays a greeting to the user.",
|
79
|
+
"entrypoint": "index.html",
|
80
|
+
"actions": [
|
81
|
+
{
|
82
|
+
"id": "set_name",
|
83
|
+
"description": "Sets the name of the user to be greeted",
|
84
|
+
"params": {
|
85
|
+
"name": {
|
86
|
+
"type": "string",
|
87
|
+
"description": "The name of the user"
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
]
|
92
|
+
}
|
93
|
+
```
|
16
94
|
|
17
95
|
## Getting started
|
18
96
|
|
@@ -135,29 +213,30 @@ applet.state = { name: 'Ada Lovelace' };
|
|
135
213
|
It may also be helpful to check available applets at a domain, or in your public folder. For that you can extract the applet headers from the App Manifest at the public root (`/manifest.json`), and see the available applets and a shorthand for the actions you can take in them. This is automatically created when you build your applets.
|
136
214
|
|
137
215
|
```js
|
138
|
-
const
|
216
|
+
const applets = await applets.list('/');
|
139
217
|
```
|
140
218
|
|
141
|
-
This
|
219
|
+
This applets object looks like:
|
142
220
|
|
143
221
|
```js
|
144
|
-
|
145
|
-
{
|
222
|
+
{
|
223
|
+
'/helloworld.applet': {
|
146
224
|
name: 'Hello World',
|
147
225
|
description: 'Displays a greeting to the user.',
|
148
226
|
url: '/applets/helloworld.applet',
|
149
|
-
actions:
|
150
|
-
{
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
227
|
+
actions: {
|
228
|
+
set_name: {
|
229
|
+
description: 'Sets the name of the user to be greeted',
|
230
|
+
params: {
|
231
|
+
name: {
|
232
|
+
type: 'string',
|
233
|
+
description: 'The name of the user'
|
234
|
+
}
|
156
235
|
},
|
157
|
-
|
236
|
+
},
|
158
237
|
},
|
159
238
|
// ...
|
160
|
-
|
239
|
+
};
|
161
240
|
```
|
162
241
|
|
163
242
|
You can use it to present a quick summary of available tools to your model, and then decide on an applet and action to use.
|
package/dist/client.js
CHANGED
@@ -40,14 +40,18 @@ const defaultOpts = {
|
|
40
40
|
};
|
41
41
|
export async function load(url, container, opts) {
|
42
42
|
const _opts = Object.assign(defaultOpts, opts ?? {});
|
43
|
+
url = parseUrl(url);
|
44
|
+
const manifest = await loadManifest(`${url}`);
|
43
45
|
if (!container) {
|
44
46
|
container = hiddenContainer;
|
45
47
|
_opts.headless = true;
|
46
48
|
}
|
47
|
-
if (
|
49
|
+
if (_opts.unsafe || manifest.unsafe) {
|
50
|
+
container.setAttribute('sandbox', 'allow-scripts allow-forms allow-same-origin');
|
51
|
+
}
|
52
|
+
else {
|
48
53
|
container.setAttribute('sandbox', 'allow-scripts allow-forms');
|
49
|
-
|
50
|
-
const manifest = await loadManifest(`${url}`);
|
54
|
+
}
|
51
55
|
const applet = new Applet();
|
52
56
|
applet.manifest = manifest;
|
53
57
|
applet.actions = manifest.actions;
|
@@ -102,7 +106,10 @@ export class Applet extends EventTarget {
|
|
102
106
|
// }
|
103
107
|
}
|
104
108
|
onstateupdated(event) { }
|
105
|
-
disconnect() {
|
109
|
+
disconnect() {
|
110
|
+
this.onstateupdated = () => { };
|
111
|
+
this.container.src = 'about:blank';
|
112
|
+
}
|
106
113
|
async dispatchAction(actionId, params) {
|
107
114
|
const requestMessage = new AppletMessage('action', {
|
108
115
|
actionId,
|
package/dist/types.d.ts
CHANGED