@soederpop/luca 0.0.2 → 0.0.4
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/AGENTS.md +98 -0
- package/CLAUDE.md +27 -0
- package/SPEC.md +304 -0
- package/bun.lock +110 -265
- package/docs/CLI.md +1 -1
- package/docs/apis/features/node/content-db.md +16 -0
- package/docs/apis/features/node/fs.md +24 -0
- package/docs/apis/features/node/ipc-socket.md +0 -1
- package/docs/apis/features/node/package-finder.md +1 -11
- package/docs/apis/features/node/proc.md +0 -41
- package/docs/apis/features/node/ui.md +0 -2
- package/package.json +12 -8
- package/src/agi/container.server.ts +16 -3
- package/src/agi/features/assistant.ts +3 -7
- package/src/agi/features/assistants-manager.ts +3 -7
- package/src/agi/features/claude-code.ts +3 -7
- package/src/agi/features/conversation-history.ts +3 -7
- package/src/agi/features/conversation.ts +4 -8
- package/src/agi/features/openai-codex.ts +3 -7
- package/src/agi/features/openapi.ts +4 -2
- package/src/agi/features/skills-library.ts +4 -8
- package/src/cli/cli.ts +22 -0
- package/src/client.ts +69 -26
- package/src/clients/civitai/index.ts +3 -7
- package/src/clients/comfyui/index.ts +5 -9
- package/src/clients/elevenlabs/index.ts +39 -19
- package/src/clients/openai/index.ts +3 -7
- package/src/clients/supabase/index.ts +4 -13
- package/src/commands/console.ts +0 -3
- package/src/commands/eval.ts +1 -1
- package/src/commands/index.ts +1 -0
- package/src/commands/introspect.ts +128 -0
- package/src/commands/prompt.ts +1 -4
- package/src/commands/run.ts +6 -13
- package/src/commands/sandbox-mcp.ts +1 -13
- package/src/feature.ts +45 -2
- package/src/introspection/generated.agi.ts +175 -101
- package/src/introspection/generated.node.ts +175 -101
- package/src/introspection/generated.web.ts +113 -29
- package/src/introspection/index.ts +1 -1
- package/src/introspection/scan.ts +3 -1
- package/src/node/features/container-link.ts +3 -2
- package/src/node/features/content-db.ts +10 -2
- package/src/node/features/disk-cache.ts +3 -4
- package/src/node/features/dns.ts +3 -2
- package/src/node/features/docker.ts +3 -2
- package/src/node/features/downloader.ts +3 -16
- package/src/node/features/esbuild.ts +3 -12
- package/src/node/features/file-manager.ts +3 -2
- package/src/node/features/fs.ts +12 -3
- package/src/node/features/git.ts +3 -2
- package/src/node/features/google-auth.ts +3 -2
- package/src/node/features/google-calendar.ts +3 -2
- package/src/node/features/google-docs.ts +3 -2
- package/src/node/features/google-drive.ts +3 -2
- package/src/node/features/google-sheets.ts +3 -2
- package/src/node/features/grep.ts +3 -2
- package/src/node/features/helpers.ts +13 -2
- package/src/node/features/ink.ts +3 -3
- package/src/node/features/ipc-socket.ts +3 -3
- package/src/node/features/json-tree.ts +3 -21
- package/src/node/features/launcher-app-command-listener.ts +3 -2
- package/src/node/features/networking.ts +3 -2
- package/src/node/features/nlp.ts +3 -2
- package/src/node/features/opener.ts +8 -7
- package/src/node/features/os.ts +3 -2
- package/src/node/features/package-finder.ts +3 -2
- package/src/node/features/port-exposer.ts +3 -4
- package/src/node/features/postgres.ts +3 -3
- package/src/node/features/proc.ts +37 -64
- package/src/node/features/process-manager.ts +3 -2
- package/src/node/features/python.ts +3 -3
- package/src/node/features/repl.ts +3 -2
- package/src/node/features/runpod.ts +3 -3
- package/src/node/features/secure-shell.ts +3 -2
- package/src/node/features/semantic-search.ts +4 -6
- package/src/node/features/sqlite.ts +3 -3
- package/src/node/features/telegram.ts +3 -2
- package/src/node/features/tts.ts +3 -2
- package/src/node/features/ui.ts +3 -3
- package/src/node/features/vault.ts +3 -14
- package/src/node/features/vm.ts +41 -3
- package/src/node/features/window-manager.ts +165 -22
- package/src/node/features/yaml-tree.ts +3 -4
- package/src/node/features/yaml.ts +3 -2
- package/src/registry.ts +1 -1
- package/src/scaffolds/generated.ts +1 -1
- package/src/server.ts +43 -0
- package/src/servers/express.ts +24 -8
- package/src/servers/mcp.ts +2 -6
- package/src/servers/socket.ts +22 -7
- package/src/web/clients/socket.ts +3 -5
- package/src/web/features/asset-loader.ts +20 -12
- package/src/web/features/container-link.ts +3 -6
- package/src/web/features/esbuild.ts +21 -7
- package/src/web/features/helpers.ts +4 -2
- package/src/web/features/network.ts +24 -7
- package/src/web/features/speech.ts +24 -7
- package/src/web/features/vault.ts +21 -3
- package/src/web/features/vm.ts +20 -13
- package/src/web/features/voice-recognition.ts +26 -9
- package/commands/update-introspection.ts +0 -67
- package/docs/ideas/class-registration-refactor-possibilities.md +0 -197
- package/docs/ideas/container-use-api.md +0 -9
- package/docs/ideas/easy-auth-for-express-servers-and-luca-serve.md +0 -0
- package/docs/ideas/feature-stacks.md +0 -22
- package/docs/ideas/luca-cli-self-sufficiency-demo.md +0 -23
- package/docs/ideas/mcp-design.md +0 -9
- package/docs/ideas/web-container-debugging-feature.md +0 -13
- package/scripts/animations/chrome-glitch.ts +0 -55
- package/scripts/animations/index.ts +0 -16
- package/scripts/animations/neon-pulse.ts +0 -64
- package/scripts/animations/types.ts +0 -6
package/src/server.ts
CHANGED
|
@@ -29,6 +29,9 @@ export class Server<T extends ServerState = ServerState, K extends ServerOptions
|
|
|
29
29
|
static override optionsSchema = ServerOptionsSchema
|
|
30
30
|
static override eventsSchema = ServerEventsSchema
|
|
31
31
|
|
|
32
|
+
/** Self-register a Server subclass from a static initialization block. */
|
|
33
|
+
static register: (SubClass: typeof Server, id?: string) => typeof Server
|
|
34
|
+
|
|
32
35
|
override get initialState() : T {
|
|
33
36
|
return ({
|
|
34
37
|
port: this.options.port || 3000,
|
|
@@ -133,3 +136,43 @@ export class ServersRegistry extends Registry<Server<any>> {
|
|
|
133
136
|
export const servers = new ServersRegistry()
|
|
134
137
|
|
|
135
138
|
export const helperCache = new Map()
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Self-register a Server subclass from a static initialization block.
|
|
142
|
+
* IMPORTANT: Place the static block AFTER all static override declarations
|
|
143
|
+
* so schemas, envVars, and other metadata are set before interceptRegistration fires.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* export class ExpressServer extends Server {
|
|
148
|
+
* static override stateSchema = ServerStateSchema
|
|
149
|
+
* static override optionsSchema = ExpressServerOptionsSchema
|
|
150
|
+
* static { Server.register(this, 'express') } // must come last
|
|
151
|
+
* }
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
Server.register = function registerServer(
|
|
155
|
+
SubClass: typeof Server,
|
|
156
|
+
id?: string,
|
|
157
|
+
) {
|
|
158
|
+
const registryId = id ?? SubClass.name[0]!.toLowerCase() + SubClass.name.slice(1)
|
|
159
|
+
|
|
160
|
+
// Auto-set shortcut if not explicitly overridden on this class
|
|
161
|
+
if (!Object.getOwnPropertyDescriptor(SubClass, 'shortcut')?.value ||
|
|
162
|
+
(SubClass as any).shortcut === 'unspecified') {
|
|
163
|
+
;(SubClass as any).shortcut = `servers.${registryId}` as const
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Register in the servers registry (interceptRegistration sees all statics above)
|
|
167
|
+
servers.register(registryId, SubClass as any)
|
|
168
|
+
|
|
169
|
+
// Generate default attach() if not explicitly overridden on this class
|
|
170
|
+
if (!Object.getOwnPropertyDescriptor(SubClass, 'attach')) {
|
|
171
|
+
;(SubClass as any).attach = (container: any) => {
|
|
172
|
+
servers.register(registryId, SubClass as any)
|
|
173
|
+
return container
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return SubClass
|
|
178
|
+
}
|
package/src/servers/express.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import type { NodeContainer } from '../node/container.js'
|
|
2
1
|
import express from 'express'
|
|
3
2
|
import type { Express } from 'express'
|
|
4
3
|
import cors from 'cors'
|
|
5
4
|
import { z } from 'zod'
|
|
6
5
|
import { ServerStateSchema, ServerOptionsSchema } from '../schemas/base.js'
|
|
7
|
-
import {
|
|
6
|
+
import { type StartOptions, Server, type ServerState } from '../server.js'
|
|
8
7
|
import { Endpoint, type EndpointModule } from '../endpoint.js'
|
|
9
8
|
|
|
10
9
|
declare module '../server' {
|
|
@@ -24,14 +23,33 @@ export type ExpressServerOptions = z.infer<typeof ExpressServerOptionsSchema>
|
|
|
24
23
|
|
|
25
24
|
const defaultCreate = (app: Express, server: Server) => app
|
|
26
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Express.js HTTP server with automatic endpoint mounting, CORS, and SPA history fallback.
|
|
28
|
+
*
|
|
29
|
+
* Wraps an Express application with convention-based endpoint discovery. Endpoints
|
|
30
|
+
* defined as modules are automatically mounted as routes. Supports static file serving,
|
|
31
|
+
* CORS configuration, and single-page app history fallback out of the box.
|
|
32
|
+
*
|
|
33
|
+
* @extends Server
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const server = container.server('express', { cors: true, static: './public' })
|
|
38
|
+
* await server.start({ port: 3000 })
|
|
39
|
+
*
|
|
40
|
+
* // Mount endpoints programmatically
|
|
41
|
+
* server.mount(myEndpoint)
|
|
42
|
+
*
|
|
43
|
+
* // Access the underlying Express app
|
|
44
|
+
* server.app.get('/health', (req, res) => res.json({ ok: true }))
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
27
47
|
export class ExpressServer<T extends ServerState = ServerState, K extends ExpressServerOptions = ExpressServerOptions> extends Server<T,K> {
|
|
28
48
|
static override shortcut = 'servers.express' as const
|
|
29
49
|
static override stateSchema = ServerStateSchema
|
|
30
50
|
static override optionsSchema = ExpressServerOptionsSchema
|
|
31
|
-
|
|
32
|
-
static
|
|
33
|
-
return container
|
|
34
|
-
}
|
|
51
|
+
|
|
52
|
+
static { Server.register(this, 'express') }
|
|
35
53
|
|
|
36
54
|
_app?: Express
|
|
37
55
|
_listener?: any
|
|
@@ -204,6 +222,4 @@ export class ExpressServer<T extends ServerState = ServerState, K extends Expres
|
|
|
204
222
|
}
|
|
205
223
|
}
|
|
206
224
|
|
|
207
|
-
servers.register('express', ExpressServer)
|
|
208
|
-
|
|
209
225
|
export default ExpressServer
|
package/src/servers/mcp.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { NodeContainer } from '../node/container.js'
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
import { MCPServerStateSchema, MCPServerOptionsSchema, MCPServerEventsSchema } from '../schemas/base.js'
|
|
4
|
-
import {
|
|
4
|
+
import { Server } from '../server.js'
|
|
5
5
|
import { Server as MCPProtocolServer } from '@modelcontextprotocol/sdk/server/index.js'
|
|
6
6
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
7
7
|
import {
|
|
@@ -297,9 +297,7 @@ export class MCPServer extends Server<MCPServerState, MCPServerOptions> {
|
|
|
297
297
|
static override optionsSchema = MCPServerOptionsSchema
|
|
298
298
|
static override eventsSchema = MCPServerEventsSchema
|
|
299
299
|
|
|
300
|
-
static
|
|
301
|
-
return container
|
|
302
|
-
}
|
|
300
|
+
static { Server.register(this, 'mcp') }
|
|
303
301
|
|
|
304
302
|
_mcpServer?: MCPProtocolServer
|
|
305
303
|
_tools: Map<string, RegisteredTool> = new Map()
|
|
@@ -800,6 +798,4 @@ export class MCPServer extends Server<MCPServerState, MCPServerOptions> {
|
|
|
800
798
|
}
|
|
801
799
|
}
|
|
802
800
|
|
|
803
|
-
servers.register('mcp', MCPServer)
|
|
804
|
-
|
|
805
801
|
export default MCPServer
|
package/src/servers/socket.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { NodeContainer } from '../node/container.js'
|
|
2
1
|
import { z } from 'zod'
|
|
3
2
|
import { ServerStateSchema, ServerOptionsSchema } from '../schemas/base.js'
|
|
4
|
-
import { type StartOptions,
|
|
3
|
+
import { type StartOptions, Server, type ServerState } from '../server.js';
|
|
5
4
|
import { WebSocketServer as BaseServer } from 'ws'
|
|
6
5
|
|
|
7
6
|
declare module '../server' {
|
|
@@ -15,14 +14,32 @@ export const SocketServerOptionsSchema = ServerOptionsSchema.extend({
|
|
|
15
14
|
})
|
|
16
15
|
export type SocketServerOptions = z.infer<typeof SocketServerOptionsSchema>
|
|
17
16
|
|
|
17
|
+
/**
|
|
18
|
+
* WebSocket server built on the `ws` library with optional JSON message framing.
|
|
19
|
+
*
|
|
20
|
+
* Manages WebSocket connections, tracks connected clients, and bridges
|
|
21
|
+
* messages to Luca's event bus. When `json` mode is enabled, messages
|
|
22
|
+
* are automatically parsed and stringified.
|
|
23
|
+
*
|
|
24
|
+
* @extends Server
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const ws = container.server('websocket', { json: true })
|
|
29
|
+
* await ws.start({ port: 8080 })
|
|
30
|
+
*
|
|
31
|
+
* ws.on('message', (client, data) => {
|
|
32
|
+
* console.log('Received:', data)
|
|
33
|
+
* ws.broadcast({ echo: data })
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
18
37
|
export class WebsocketServer<T extends ServerState = ServerState, K extends SocketServerOptions = SocketServerOptions> extends Server<T,K> {
|
|
19
38
|
static override shortcut = 'servers.websocket' as const
|
|
20
39
|
static override stateSchema = ServerStateSchema
|
|
21
40
|
static override optionsSchema = SocketServerOptionsSchema
|
|
22
41
|
|
|
23
|
-
static
|
|
24
|
-
return container
|
|
25
|
-
}
|
|
42
|
+
static { Server.register(this, 'websocket') }
|
|
26
43
|
|
|
27
44
|
_wss?: BaseServer
|
|
28
45
|
|
|
@@ -115,6 +132,4 @@ export class WebsocketServer<T extends ServerState = ServerState, K extends Sock
|
|
|
115
132
|
}
|
|
116
133
|
}
|
|
117
134
|
|
|
118
|
-
servers.register('websocket', WebsocketServer)
|
|
119
|
-
|
|
120
135
|
export default WebsocketServer
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Websocket from 'isomorphic-ws'
|
|
2
|
-
import {
|
|
2
|
+
import { Client, WebSocketClient, type WebSocketClientState, type WebSocketClientOptions } from '../../client'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Web-specific WebSocket client implementation using isomorphic-ws.
|
|
@@ -12,9 +12,7 @@ export class SocketClient<T extends WebSocketClientState = WebSocketClientState,
|
|
|
12
12
|
|
|
13
13
|
static override shortcut = 'clients.websocket' as const
|
|
14
14
|
|
|
15
|
-
static
|
|
16
|
-
clients.register('websocket', SocketClient)
|
|
17
|
-
}
|
|
15
|
+
static { Client.register(this, 'websocket') }
|
|
18
16
|
|
|
19
17
|
/**
|
|
20
18
|
* Send data over the WebSocket with an ID envelope.
|
|
@@ -79,4 +77,4 @@ export class SocketClient<T extends WebSocketClientState = WebSocketClientState,
|
|
|
79
77
|
}
|
|
80
78
|
}
|
|
81
79
|
|
|
82
|
-
export default
|
|
80
|
+
export default SocketClient
|
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
2
|
-
import { Feature
|
|
3
|
-
import { Container } from "../container.js";
|
|
2
|
+
import { Feature } from "../feature.js";
|
|
4
3
|
|
|
5
|
-
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Injects scripts and stylesheets into the page at runtime.
|
|
6
|
+
*
|
|
7
|
+
* Provides helpers for loading external libraries from unpkg.com,
|
|
8
|
+
* injecting arbitrary script/link tags, and managing load state.
|
|
9
|
+
* Used by other web features (e.g. Esbuild) to pull in dependencies on demand.
|
|
10
|
+
*
|
|
11
|
+
* @extends Feature
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const loader = container.feature('assetLoader')
|
|
16
|
+
* await loader.loadScript('https://unpkg.com/lodash')
|
|
17
|
+
* await AssetLoader.loadStylesheet('https://unpkg.com/normalize.css')
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
10
20
|
export class AssetLoader extends Feature {
|
|
11
|
-
static attach(container: Container & { assetLoader?: AssetLoader }) {
|
|
12
|
-
container.features.register("assetLoader", AssetLoader);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
21
|
static override stateSchema = FeatureStateSchema
|
|
16
22
|
static override optionsSchema = FeatureOptionsSchema
|
|
17
23
|
static override shortcut = "features.assetLoader" as const
|
|
18
24
|
|
|
25
|
+
static { Feature.register(this, 'assetLoader') }
|
|
26
|
+
|
|
19
27
|
static loadStylesheet(href: string) {
|
|
20
28
|
return new Promise((resolve, reject) => {
|
|
21
29
|
const link = document.createElement("link");
|
|
@@ -61,4 +69,4 @@ export class AssetLoader extends Feature {
|
|
|
61
69
|
}
|
|
62
70
|
}
|
|
63
71
|
|
|
64
|
-
export default
|
|
72
|
+
export default AssetLoader;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { FeatureStateSchema, FeatureOptionsSchema, FeatureEventsSchema } from '../../schemas/base.js'
|
|
3
|
-
import {
|
|
4
|
-
import type { Container } from '../../container.js'
|
|
3
|
+
import { Feature } from '../feature.js'
|
|
5
4
|
|
|
6
5
|
// --- Message Types ---
|
|
7
6
|
|
|
@@ -124,9 +123,7 @@ export class ContainerLink extends Feature<ContainerLinkState, ContainerLinkOpti
|
|
|
124
123
|
static override optionsSchema = ContainerLinkOptionsSchema
|
|
125
124
|
static override eventsSchema = ContainerLinkEventsSchema
|
|
126
125
|
|
|
127
|
-
static
|
|
128
|
-
container.features.register('containerLink', ContainerLink)
|
|
129
|
-
}
|
|
126
|
+
static { Feature.register(this as any, 'containerLink') }
|
|
130
127
|
|
|
131
128
|
private _ws?: WebSocket
|
|
132
129
|
private _reconnectTimer?: ReturnType<typeof setTimeout>
|
|
@@ -382,4 +379,4 @@ export class ContainerLink extends Feature<ContainerLinkState, ContainerLinkOpti
|
|
|
382
379
|
}
|
|
383
380
|
}
|
|
384
381
|
|
|
385
|
-
export default
|
|
382
|
+
export default ContainerLink
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
3
|
-
import { Feature, type FeatureState
|
|
4
|
-
import { Container } from "../container.js";
|
|
3
|
+
import { Feature, type FeatureState } from "../feature.js";
|
|
5
4
|
import type * as esbuild from 'esbuild-wasm';
|
|
6
5
|
|
|
7
6
|
export const EsbuildWebOptionsSchema = FeatureOptionsSchema.extend({
|
|
@@ -11,14 +10,29 @@ export const EsbuildWebOptionsSchema = FeatureOptionsSchema.extend({
|
|
|
11
10
|
|
|
12
11
|
export type EsbuildWebOptions = z.infer<typeof EsbuildWebOptionsSchema>
|
|
13
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Browser-side TypeScript/ESM compilation feature using esbuild-wasm.
|
|
15
|
+
*
|
|
16
|
+
* Loads esbuild's WebAssembly build via the AssetLoader, then provides
|
|
17
|
+
* `compile()` and `transform()` methods that work entirely in the browser.
|
|
18
|
+
* Useful for live playgrounds, in-browser REPLs, and client-side bundling.
|
|
19
|
+
*
|
|
20
|
+
* @extends Feature
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const esbuild = container.feature('esbuild')
|
|
25
|
+
* await esbuild.start()
|
|
26
|
+
* const result = await esbuild.compile('const x: number = 1')
|
|
27
|
+
* console.log(result.code)
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
14
30
|
export class Esbuild extends Feature<FeatureState, EsbuildWebOptions> {
|
|
15
|
-
static attach(container: Container & { assetLoader?: Esbuild}) {
|
|
16
|
-
container.features.register("esbuild", Esbuild);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
31
|
static override stateSchema = FeatureStateSchema
|
|
20
32
|
static override optionsSchema = EsbuildWebOptionsSchema
|
|
21
33
|
static override shortcut = "features.esbuild" as const
|
|
34
|
+
|
|
35
|
+
static { Feature.register(this as any, 'esbuild') }
|
|
22
36
|
|
|
23
37
|
/** Returns the assetLoader feature for loading external libraries from unpkg. */
|
|
24
38
|
get assetLoader() {
|
|
@@ -74,6 +88,6 @@ export class Esbuild extends Feature<FeatureState, EsbuildWebOptions> {
|
|
|
74
88
|
|
|
75
89
|
}
|
|
76
90
|
|
|
77
|
-
export default
|
|
91
|
+
export default Esbuild;
|
|
78
92
|
|
|
79
93
|
const compileCache = new Map()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { FeatureStateSchema, FeatureOptionsSchema, FeatureEventsSchema } from '../../schemas/base.js'
|
|
3
|
-
import { Feature
|
|
3
|
+
import { Feature } from '../feature.js'
|
|
4
4
|
import { Client } from '../../client.js'
|
|
5
5
|
import type { Registry } from '../../registry.js'
|
|
6
6
|
import type { AssetLoader } from './asset-loader.js'
|
|
@@ -79,6 +79,8 @@ export class Helpers extends Feature<HelpersState, HelpersOptions> {
|
|
|
79
79
|
static override optionsSchema = HelpersOptionsSchema
|
|
80
80
|
static override eventsSchema = HelpersEventsSchema
|
|
81
81
|
|
|
82
|
+
static { Feature.register(this as any, 'helpers') }
|
|
83
|
+
|
|
82
84
|
private _manifest: Manifest | null = null
|
|
83
85
|
|
|
84
86
|
private get registryMap(): Record<RegistryType, { registry: Registry<any> }> {
|
|
@@ -264,4 +266,4 @@ export class Helpers extends Feature<HelpersState, HelpersOptions> {
|
|
|
264
266
|
}
|
|
265
267
|
}
|
|
266
268
|
|
|
267
|
-
export default
|
|
269
|
+
export default Helpers
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
3
|
-
import {
|
|
4
|
-
import type {
|
|
3
|
+
import { Feature } from "../feature.js";
|
|
4
|
+
import type { ContainerContext } from "../container.js";
|
|
5
5
|
|
|
6
6
|
export const NetworkStateSchema = FeatureStateSchema.extend({
|
|
7
7
|
offline: z.boolean().describe('Whether the browser is currently offline'),
|
|
@@ -12,6 +12,25 @@ export const NetworkOptionsSchema = FeatureOptionsSchema.extend({})
|
|
|
12
12
|
export type NetworkState = z.infer<typeof NetworkStateSchema>
|
|
13
13
|
export type NetworkOptions = z.infer<typeof NetworkOptionsSchema>
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Tracks browser online/offline connectivity state.
|
|
17
|
+
*
|
|
18
|
+
* Listens for the browser's `online` and `offline` events and keeps the
|
|
19
|
+
* feature state in sync. Other features can observe the `offline` state
|
|
20
|
+
* value or listen for change events to react to connectivity changes.
|
|
21
|
+
*
|
|
22
|
+
* @extends Feature
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const network = container.feature('network')
|
|
27
|
+
* console.log(network.state.get('offline')) // false when online
|
|
28
|
+
*
|
|
29
|
+
* network.on('stateChanged', ({ offline }) => {
|
|
30
|
+
* console.log(offline ? 'Went offline' : 'Back online')
|
|
31
|
+
* })
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
15
34
|
export class Network<
|
|
16
35
|
T extends NetworkState = NetworkState,
|
|
17
36
|
K extends NetworkOptions = NetworkOptions
|
|
@@ -19,10 +38,8 @@ export class Network<
|
|
|
19
38
|
static override stateSchema = NetworkStateSchema
|
|
20
39
|
static override optionsSchema = NetworkOptionsSchema
|
|
21
40
|
static override shortcut = "features.network" as const
|
|
22
|
-
|
|
23
|
-
static
|
|
24
|
-
container.features.register("network", Network);
|
|
25
|
-
}
|
|
41
|
+
|
|
42
|
+
static { Feature.register(this as any, 'network') }
|
|
26
43
|
|
|
27
44
|
constructor(options: K, context: ContainerContext) {
|
|
28
45
|
super(options, context);
|
|
@@ -58,4 +75,4 @@ export class Network<
|
|
|
58
75
|
}
|
|
59
76
|
}
|
|
60
77
|
|
|
61
|
-
export default
|
|
78
|
+
export default Network
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
3
|
-
import { Feature
|
|
4
|
-
import {
|
|
3
|
+
import { Feature } from "../feature.js";
|
|
4
|
+
import { type ContainerContext } from "../container.js";
|
|
5
5
|
|
|
6
6
|
export const SpeechOptionsSchema = FeatureOptionsSchema.extend({
|
|
7
7
|
voice: z.string().optional().describe('The voice to use for the speech'),
|
|
@@ -23,18 +23,35 @@ type Voice = {
|
|
|
23
23
|
default: boolean;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Text-to-speech synthesis using the Web Speech API (SpeechSynthesis).
|
|
28
|
+
*
|
|
29
|
+
* Wraps the browser's built-in speech synthesis, providing voice selection,
|
|
30
|
+
* queue management, and state tracking. Voices are discovered on init and
|
|
31
|
+
* exposed via state for UI binding.
|
|
32
|
+
*
|
|
33
|
+
* @extends Feature
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const speech = container.feature('speech')
|
|
38
|
+
* speech.say('Hello from the browser!')
|
|
39
|
+
*
|
|
40
|
+
* // Choose a specific voice
|
|
41
|
+
* const speech = container.feature('speech', { voice: 'Google UK English Female' })
|
|
42
|
+
* speech.say('Cheerio!')
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
26
45
|
export class Speech<
|
|
27
46
|
T extends SpeechState = SpeechState,
|
|
28
47
|
K extends SpeechOptions = SpeechOptions
|
|
29
48
|
> extends Feature<T, K> {
|
|
30
49
|
|
|
31
|
-
static attach(container: Container & { speech?: Speech }) {
|
|
32
|
-
container.features.register("speech", Speech);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
50
|
static override stateSchema = SpeechStateSchema
|
|
36
51
|
static override optionsSchema = SpeechOptionsSchema
|
|
37
52
|
static override shortcut = "features.speech" as const
|
|
53
|
+
|
|
54
|
+
static { Feature.register(this as any, 'speech') }
|
|
38
55
|
|
|
39
56
|
constructor(options: K, context: ContainerContext) {
|
|
40
57
|
super(options,context)
|
|
@@ -84,4 +101,4 @@ export class Speech<
|
|
|
84
101
|
}
|
|
85
102
|
}
|
|
86
103
|
|
|
87
|
-
export default
|
|
104
|
+
export default Speech;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
4
|
-
import { Feature
|
|
5
|
-
import { WebContainer} from '../container.js'
|
|
4
|
+
import { Feature } from '../feature.js'
|
|
6
5
|
|
|
7
6
|
export const WebVaultStateSchema = FeatureStateSchema.extend({
|
|
8
7
|
secret: z.string().optional().describe('Base64-encoded AES-GCM encryption secret key'),
|
|
@@ -15,10 +14,29 @@ export const WebVaultOptionsSchema = FeatureOptionsSchema.extend({
|
|
|
15
14
|
export type WebVaultState = z.infer<typeof WebVaultStateSchema>
|
|
16
15
|
export type WebVaultOptions = z.infer<typeof WebVaultOptionsSchema>
|
|
17
16
|
|
|
17
|
+
/**
|
|
18
|
+
* AES-256-GCM encryption and decryption for the browser using the Web Crypto API.
|
|
19
|
+
*
|
|
20
|
+
* Generates or accepts a secret key and provides `encrypt()` / `decrypt()` methods
|
|
21
|
+
* that work entirely client-side. Keys are stored as base64-encoded state so they
|
|
22
|
+
* can persist across sessions when needed.
|
|
23
|
+
*
|
|
24
|
+
* @extends Feature
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const vault = container.feature('vault')
|
|
29
|
+
* const encrypted = await vault.encrypt('secret data')
|
|
30
|
+
* const decrypted = await vault.decrypt(encrypted)
|
|
31
|
+
* console.log(decrypted) // 'secret data'
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
18
34
|
export class WebVault extends Feature<WebVaultState, WebVaultOptions> {
|
|
19
35
|
static override stateSchema = WebVaultStateSchema
|
|
20
36
|
static override optionsSchema = WebVaultOptionsSchema
|
|
21
37
|
static override shortcut = "features.vault" as const
|
|
38
|
+
|
|
39
|
+
static { Feature.register(this, 'vault') }
|
|
22
40
|
|
|
23
41
|
async secret({ refresh = false, set = true } = {}) : Promise<ArrayBuffer> {
|
|
24
42
|
if (!this.state.get('secret') && this.options.secret) {
|
|
@@ -67,7 +85,7 @@ export class WebVault extends Feature<WebVaultState, WebVaultOptions> {
|
|
|
67
85
|
}
|
|
68
86
|
}
|
|
69
87
|
|
|
70
|
-
export default
|
|
88
|
+
export default WebVault
|
|
71
89
|
|
|
72
90
|
async function generateSecretKey(): Promise<ArrayBuffer> {
|
|
73
91
|
const key = await crypto.subtle.generateKey(
|
package/src/web/features/vm.ts
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
import { z } from 'zod'
|
|
4
4
|
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
5
5
|
import vm from '../shims/isomorphic-vm'
|
|
6
|
-
import { Feature
|
|
7
|
-
import { Container } from '../../container.js';
|
|
6
|
+
import { Feature } from "../feature.js";
|
|
8
7
|
|
|
9
8
|
export const VMStateSchema = FeatureStateSchema.extend({})
|
|
10
9
|
|
|
@@ -15,25 +14,33 @@ export const VMOptionsSchema = FeatureOptionsSchema.extend({
|
|
|
15
14
|
export type VMState = z.infer<typeof VMStateSchema>
|
|
16
15
|
export type VMOptions = z.infer<typeof VMOptionsSchema>
|
|
17
16
|
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Sandboxed JavaScript execution environment for the browser.
|
|
19
|
+
*
|
|
20
|
+
* Automatically injects the container's context object into the global scope,
|
|
21
|
+
* so evaluated code can use anything provided by the container. Useful for
|
|
22
|
+
* live code playgrounds, plugin systems, and dynamic script evaluation.
|
|
23
|
+
*
|
|
24
|
+
* @extends Feature
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const vm = container.feature('vm')
|
|
29
|
+
* const result = vm.run('1 + 2 + 3') // 6
|
|
30
|
+
* const greeting = vm.run('container.uuid') // accesses container globals
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
24
33
|
export class VM<
|
|
25
34
|
T extends VMState = VMState,
|
|
26
35
|
K extends VMOptions = VMOptions
|
|
27
36
|
> extends Feature<T, K> {
|
|
28
37
|
|
|
29
|
-
static attach(container: Container) {
|
|
30
|
-
container.features.register('vm', VM)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
38
|
static override stateSchema = VMStateSchema
|
|
34
39
|
static override optionsSchema = VMOptionsSchema
|
|
35
40
|
static override shortcut = "features.vm" as const
|
|
36
41
|
|
|
42
|
+
static { Feature.register(this, 'vm') }
|
|
43
|
+
|
|
37
44
|
createScript(code: string) {
|
|
38
45
|
return new vm.Script(code)
|
|
39
46
|
}
|
|
@@ -75,4 +82,4 @@ export class VM<
|
|
|
75
82
|
}
|
|
76
83
|
}
|
|
77
84
|
|
|
78
|
-
export default
|
|
85
|
+
export default VM;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
3
|
-
import { Feature
|
|
4
|
-
import { type
|
|
3
|
+
import { Feature } from "../../feature.js";
|
|
4
|
+
import { type ContainerContext } from '../container.js'
|
|
5
5
|
|
|
6
6
|
export const VoiceRecognitionOptionsSchema = FeatureOptionsSchema.extend({
|
|
7
7
|
language: z.string().optional().describe('BCP 47 language code for recognition (e.g. en-US)'),
|
|
@@ -17,20 +17,37 @@ export const VoiceRecognitionStateSchema = FeatureStateSchema.extend({
|
|
|
17
17
|
export type VoiceRecognitionOptions = z.infer<typeof VoiceRecognitionOptionsSchema>
|
|
18
18
|
export type VoiceRecognitionState = z.infer<typeof VoiceRecognitionStateSchema>
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Speech-to-text recognition using the Web Speech API (SpeechRecognition).
|
|
22
|
+
*
|
|
23
|
+
* Wraps the browser's built-in speech recognition, supporting continuous
|
|
24
|
+
* listening, interim results, and language selection. Recognized text is
|
|
25
|
+
* accumulated in state and emitted as events for real-time transcription UIs.
|
|
26
|
+
*
|
|
27
|
+
* @extends Feature
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const voice = container.feature('voice', { continuous: true, autoListen: true })
|
|
32
|
+
*
|
|
33
|
+
* voice.on('transcript', ({ text }) => {
|
|
34
|
+
* console.log('Heard:', text)
|
|
35
|
+
* })
|
|
36
|
+
*
|
|
37
|
+
* // Or start manually
|
|
38
|
+
* voice.start()
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
20
41
|
export class VoiceRecognition<T extends VoiceRecognitionState = VoiceRecognitionState, K extends VoiceRecognitionOptions = VoiceRecognitionOptions> extends Feature<T, K> {
|
|
21
42
|
// @ts-ignore-next-line
|
|
22
43
|
private recognition: SpeechRecognition | null = null;
|
|
23
44
|
|
|
24
|
-
static attach(container: Container<WebFeatures> & { voice?: VoiceRecognition }, options?: VoiceRecognitionOptions) {
|
|
25
|
-
container.features.register('voice', VoiceRecognition)
|
|
26
|
-
container.feature('voice', { enable: true })
|
|
27
|
-
return container
|
|
28
|
-
}
|
|
29
|
-
|
|
30
45
|
static override stateSchema = VoiceRecognitionStateSchema
|
|
31
46
|
static override optionsSchema = VoiceRecognitionOptionsSchema
|
|
32
47
|
static override shortcut = "features.voice" as const
|
|
33
48
|
|
|
49
|
+
static { Feature.register(this as any, 'voice') }
|
|
50
|
+
|
|
34
51
|
constructor(options: K, context: ContainerContext) {
|
|
35
52
|
super(options, context);
|
|
36
53
|
|
|
@@ -126,4 +143,4 @@ export class VoiceRecognition<T extends VoiceRecognitionState = VoiceRecognition
|
|
|
126
143
|
}
|
|
127
144
|
}
|
|
128
145
|
|
|
129
|
-
export default
|
|
146
|
+
export default VoiceRecognition;
|