@zaflun/lumio-agent-skill 0.5.0 → 0.5.3
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/dist/bin/lumio-skills.js
CHANGED
|
@@ -14,8 +14,8 @@ Lumio Extensions are sandboxed React apps that run inside a 3-layer iframe sandb
|
|
|
14
14
|
\`\`\`
|
|
15
15
|
3-Layer Sandbox:
|
|
16
16
|
Host (lumio.vision / browser source)
|
|
17
|
-
\u2514\u2500\u2500 Supervisor iframe (supervisor.
|
|
18
|
-
\u2514\u2500\u2500 Extension Runtime iframe (ext.lumio.vision)
|
|
17
|
+
\u2514\u2500\u2500 Supervisor iframe (supervisor.ext.lumio.vision)
|
|
18
|
+
\u2514\u2500\u2500 Extension Runtime iframe (<label>.runtime.ext.lumio.vision)
|
|
19
19
|
\u2514\u2500\u2500 Web Worker (server function execution)
|
|
20
20
|
\`\`\`
|
|
21
21
|
|
|
@@ -30,7 +30,7 @@ Extension Project:
|
|
|
30
30
|
\`\`\`
|
|
31
31
|
|
|
32
32
|
**Runtime flow:**
|
|
33
|
-
1. Extension Runtime iframe loads
|
|
33
|
+
1. Extension Runtime iframe loads on the extension's own origin \`<label>.runtime.ext.lumio.vision\` (\`<label>\` = extension UUID as 32 lowercase hex)
|
|
34
34
|
2. \`Lumio.render(<Component />, { target: "layer" })\` must be called within 10 seconds
|
|
35
35
|
3. The custom React reconciler serializes the tree to \`LumioComponentNode[]\` via postMessage to the Supervisor
|
|
36
36
|
4. The Supervisor validates and forwards the node tree to the Host for rendering
|
|
@@ -76,6 +76,10 @@ All three surfaces share storage via \`useExtensionStorage()\` \u2014 changes in
|
|
|
76
76
|
},
|
|
77
77
|
"visibility": "public",
|
|
78
78
|
"pricing": { "type": "free" },
|
|
79
|
+
"sounds": [
|
|
80
|
+
{ "file": "alert.mp3", "name": "Alert" },
|
|
81
|
+
{ "file": "chime.wav", "name": "Chime", "default_volume": 0.8 }
|
|
82
|
+
],
|
|
79
83
|
"config_schema": [
|
|
80
84
|
{ "key": "title", "type": "string", "label": "Widget Title", "default_value": "My Widget", "required": true, "placeholder": "Enter title..." },
|
|
81
85
|
{ "key": "fontSize", "type": "number", "label": "Font Size", "default_value": 16, "required": false, "min": 8, "max": 200, "unit": "px" },
|
|
@@ -95,6 +99,8 @@ All three surfaces share storage via \`useExtensionStorage()\` \u2014 changes in
|
|
|
95
99
|
- \`"visibility": "unlisted"\` \u2014 accessible by direct link only
|
|
96
100
|
- Private invite: grant \`free_access\` to specific accounts via dashboard
|
|
97
101
|
|
|
102
|
+
**Bundled sounds:** Place audio files in \`dist/sounds/\` and declare them in the \`sounds\` array. Supported: MP3, WAV, OGG, WebM, M4A, AAC, FLAC. Default limits: 50 sounds per extension, 10 MB per file, 200 MB total storage (all admin-configurable). Developers can view limits at \`/account/developer/limits\` and request increases via a 4-step wizard. Requests are reviewed by admins in the admin app. Users cannot delete bundled sounds \u2014 uninstalling the extension removes them.
|
|
103
|
+
|
|
98
104
|
**Revenue split:** Configurable per developer (default 70/30 developer/Lumio).
|
|
99
105
|
|
|
100
106
|
**Feature gates:** The following Lumio plan features must be enabled for extension functionality:
|
|
@@ -196,26 +202,17 @@ export const fetchScores = action({
|
|
|
196
202
|
});
|
|
197
203
|
\`\`\`
|
|
198
204
|
|
|
199
|
-
**Extension Actions** via \`useLumioAction()\` (
|
|
205
|
+
**Extension Actions** via \`useLumioAction()\` (dispatched by the Lumio API; \`action\` is \`LumioActionType\`):
|
|
200
206
|
\`\`\`tsx
|
|
201
207
|
// Trigger platform actions (requires matching permission in lumio.config.json)
|
|
202
208
|
const { execute: sendChat } = useLumioAction("chat:send");
|
|
203
|
-
const { execute:
|
|
204
|
-
const { execute: unbanUser } = useLumioAction("chat:unban");
|
|
205
|
-
const { execute: timeoutUser } = useLumioAction("chat:timeout");
|
|
209
|
+
const { execute: deleteChat } = useLumioAction("chat:delete");
|
|
206
210
|
const { execute: setScene } = useLumioAction("obs:set_scene");
|
|
207
|
-
const { execute:
|
|
208
|
-
const { execute:
|
|
211
|
+
const { execute: setSourceVisible } = useLumioAction("obs:set_source_visible");
|
|
212
|
+
const { execute: startStream } = useLumioAction("obs:start_stream");
|
|
213
|
+
const { execute: stopStream } = useLumioAction("obs:stop_stream");
|
|
209
214
|
const { execute: emitEvent } = useLumioAction("events:emit");
|
|
210
215
|
const { execute: updateLayer } = useLumioAction("overlay:update_layer");
|
|
211
|
-
const { execute: spotifyPlay } = useLumioAction("spotify:play");
|
|
212
|
-
const { execute: spotifyPause } = useLumioAction("spotify:pause");
|
|
213
|
-
const { execute: spotifySkip } = useLumioAction("spotify:skip");
|
|
214
|
-
const { execute: spotifySeek } = useLumioAction("spotify:seek");
|
|
215
|
-
const { execute: spotifyVolume } = useLumioAction("spotify:volume");
|
|
216
|
-
const { execute: spotifyShuffle } = useLumioAction("spotify:shuffle");
|
|
217
|
-
const { execute: spotifyRepeat } = useLumioAction("spotify:repeat");
|
|
218
|
-
const { execute: spotifyQueueAdd } = useLumioAction("spotify:queue_add");
|
|
219
216
|
\`\`\`
|
|
220
217
|
|
|
221
218
|
See \`server-functions.md\` for schema definition, storage scoping, and advanced patterns.
|
|
@@ -375,22 +372,26 @@ return <Text content={storage.text} />;
|
|
|
375
372
|
|
|
376
373
|
### Live events
|
|
377
374
|
\`\`\`tsx
|
|
378
|
-
// eventType is LumioEventType \u2014 autocomplete shows all
|
|
375
|
+
// eventType is LumioEventType \u2014 autocomplete shows all 58 valid event strings
|
|
379
376
|
const event = useLumioEvent("twitch:follower");
|
|
380
377
|
// event updates automatically when a new follower event arrives
|
|
381
378
|
\`\`\`
|
|
382
379
|
|
|
383
|
-
**All
|
|
380
|
+
**All 58 event types** (\`LumioEventType\`):
|
|
381
|
+
|
|
382
|
+
Twitch (23): \`twitch:follower\`, \`twitch:subscribe\`, \`twitch:gift_sub\`, \`twitch:resub\`, \`twitch:cheer\`, \`twitch:raid\`, \`twitch:reward\`, \`twitch:hype_train\`, \`twitch:hype_train_end\`, \`twitch:poll\`, \`twitch:poll_end\`, \`twitch:prediction\`, \`twitch:prediction_lock\`, \`twitch:prediction_end\`, \`twitch:goal\`, \`twitch:goal_end\`, \`twitch:ad_break\`, \`twitch:ban\`, \`twitch:unban\`, \`twitch:stream_online\`, \`twitch:stream_offline\`, \`twitch:stream_update\`, \`twitch:chat\`
|
|
383
|
+
|
|
384
|
+
YouTube (10): \`youtube:subscribe\`, \`youtube:member\`, \`youtube:superchat\`, \`youtube:supersticker\`, \`youtube:gift_membership\`, \`youtube:gift_membership_received\`, \`youtube:poll\`, \`youtube:stream_online\`, \`youtube:stream_offline\`, \`youtube:chat\`
|
|
384
385
|
|
|
385
|
-
|
|
386
|
+
Kick (11): \`kick:follower\`, \`kick:subscribe\`, \`kick:resub\`, \`kick:gift\`, \`kick:kicks\`, \`kick:reward\`, \`kick:reward_status\`, \`kick:stream_online\`, \`kick:stream_offline\`, \`kick:stream_update\`, \`kick:chat\`
|
|
386
387
|
|
|
387
|
-
|
|
388
|
+
Spotify (12): \`spotify:track\`, \`spotify:play\`, \`spotify:pause\`, \`spotify:skip\`, \`spotify:volume\`, \`spotify:queue_add\`, \`spotify:device\`, \`spotify:playlist_add\`, \`spotify:playlist_remove\`, \`spotify:playlist_create\`, \`spotify:playlist_edit\`, \`spotify:playlist_delete\`
|
|
388
389
|
|
|
389
|
-
|
|
390
|
+
StreamElements (1): \`streamelements:tip\`
|
|
390
391
|
|
|
391
|
-
|
|
392
|
+
Cross-platform chat (1, fires for every platform): \`chat:message\`
|
|
392
393
|
|
|
393
|
-
|
|
394
|
+
Kick events carry canonical top-level fields (\`user_id\`, \`user_login\`, \`user_name\`, \`avatarUrl\`, \`is_anonymous\`) plus the original Kick payload. \`kick:kicks\` has \`kicks\` (amount, like Twitch \`bits\`) and \`message\`; \`kick:reward\` / \`kick:reward_status\` have \`status\`, \`user_input\` and \`reward { id, title, cost, prompt }\`; \`kick:resub\` has \`cumulative_months\`.
|
|
394
395
|
|
|
395
396
|
### Server queries
|
|
396
397
|
\`\`\`tsx
|
|
@@ -421,7 +422,7 @@ const anim = useAnimation("slide-in", { duration: 300 });
|
|
|
421
422
|
| \`EGRESS_BLOCKED\` | Fetch to undeclared host | Add host to \`egress.allowHosts\` in config |
|
|
422
423
|
| \`STORAGE_QUOTA\` | Exceeded storage limit | Reduce data or request limit increase |
|
|
423
424
|
| \`EDITOR_ONLY\` | Mutation called from layer/interactive | Remove \`editorOnly\` or restrict to editor |
|
|
424
|
-
| \`SUPERVISOR_BLOCKED\` | Supervisor rejected a postMessage | Check message origin matches ext.lumio.vision |
|
|
425
|
+
| \`SUPERVISOR_BLOCKED\` | Supervisor rejected a postMessage | Check message origin matches the extension's runtime origin (\`<label>.runtime.ext.lumio.vision\`) |
|
|
425
426
|
| \`WORKER_CREATION_FAILED\` | Web Worker could not be created | Verify server functions bundle is valid JS |
|
|
426
427
|
| \`STORAGE_DOM_EXCEPTION\` | localStorage/sessionStorage access | Use \`useExtensionStorage()\` instead (storage blocked) |
|
|
427
428
|
|
|
@@ -1063,46 +1064,41 @@ import { useLumioAction } from "@zaflun/lumio-sdk";
|
|
|
1063
1064
|
|
|
1064
1065
|
// Send a chat message on the connected platform
|
|
1065
1066
|
const { execute: sendChat, isLoading, error } = useLumioAction("chat:send");
|
|
1066
|
-
sendChat({
|
|
1067
|
+
sendChat({
|
|
1068
|
+
platform: "twitch",
|
|
1069
|
+
channel_id: "primary",
|
|
1070
|
+
message: "Hello from the extension!"
|
|
1071
|
+
});
|
|
1067
1072
|
|
|
1068
1073
|
// Switch OBS scene (requires OBS WebSocket integration)
|
|
1069
1074
|
const { execute: setScene } = useLumioAction("obs:set_scene");
|
|
1070
|
-
setScene({
|
|
1075
|
+
setScene({ scene_name: "Main Scene" });
|
|
1071
1076
|
|
|
1072
1077
|
// Emit a custom event into the Lumio event bus
|
|
1073
1078
|
const { execute: emitEvent } = useLumioAction("events:emit");
|
|
1074
|
-
emitEvent({
|
|
1079
|
+
emitEvent({ event_type: "extension:custom", data: { score: 42 } });
|
|
1075
1080
|
|
|
1076
1081
|
// Update a specific layer in the overlay
|
|
1077
1082
|
const { execute: updateLayer } = useLumioAction("overlay:update_layer");
|
|
1078
|
-
updateLayer({
|
|
1083
|
+
updateLayer({
|
|
1084
|
+
overlay_id: "overlay-uuid",
|
|
1085
|
+
layer_id: "layer-uuid",
|
|
1086
|
+
config: { visible: true }
|
|
1087
|
+
});
|
|
1079
1088
|
\`\`\`
|
|
1080
1089
|
|
|
1081
|
-
**Available actions (
|
|
1090
|
+
**Available dispatched actions (\`action\` is \`LumioActionType\`):**
|
|
1082
1091
|
|
|
1083
1092
|
| Action | Permission required | Description |
|
|
1084
1093
|
|--------|--------------------|----|
|
|
1085
1094
|
| \`chat:send\` | \`chat:send\` | Send chat message on connected platform |
|
|
1086
1095
|
| \`chat:delete\` | \`chat:delete\` | Delete a chat message |
|
|
1087
|
-
| \`
|
|
1088
|
-
| \`
|
|
1089
|
-
| \`
|
|
1090
|
-
| \`obs:
|
|
1091
|
-
| \`
|
|
1092
|
-
| \`
|
|
1093
|
-
| \`obs:stop_stream\` | \`obs:control\` | Stop OBS streaming |
|
|
1094
|
-
| \`obs:start_recording\` | \`obs:control\` | Start OBS recording |
|
|
1095
|
-
| \`obs:stop_recording\` | \`obs:control\` | Stop OBS recording |
|
|
1096
|
-
| \`events:emit\` | \`events:write\` | Emit event into Lumio event bus |
|
|
1097
|
-
| \`overlay:update_layer\` | \`overlays:edit\` | Update overlay layer properties |
|
|
1098
|
-
| \`spotify:play\` | \`spotify:control\` | Resume Spotify playback |
|
|
1099
|
-
| \`spotify:pause\` | \`spotify:control\` | Pause Spotify playback |
|
|
1100
|
-
| \`spotify:skip\` | \`spotify:control\` | Skip to next track |
|
|
1101
|
-
| \`spotify:seek\` | \`spotify:control\` | Seek to position in current track |
|
|
1102
|
-
| \`spotify:volume\` | \`spotify:control\` | Set Spotify volume |
|
|
1103
|
-
| \`spotify:shuffle\` | \`spotify:control\` | Toggle shuffle mode |
|
|
1104
|
-
| \`spotify:repeat\` | \`spotify:control\` | Set repeat mode |
|
|
1105
|
-
| \`spotify:queue_add\` | \`spotify:control\` | Add track to Spotify queue |
|
|
1096
|
+
| \`obs:set_scene\` | \`obs:set_scene\` | Switch OBS scene |
|
|
1097
|
+
| \`obs:set_source_visible\` | \`obs:set_source_visible\` | Show or hide an OBS source |
|
|
1098
|
+
| \`obs:start_stream\` | \`obs:start_stream\` | Start OBS streaming |
|
|
1099
|
+
| \`obs:stop_stream\` | \`obs:stop_stream\` | Stop OBS streaming |
|
|
1100
|
+
| \`events:emit\` | \`events:emit\` | Emit event into Lumio event bus |
|
|
1101
|
+
| \`overlay:update_layer\` | \`overlay:update_layer\` | Update overlay layer properties |
|
|
1106
1102
|
|
|
1107
1103
|
Actions are proxied through the Lumio API \u2014 the extension never accesses OAuth tokens or platform credentials directly.
|
|
1108
1104
|
|
|
@@ -1340,7 +1336,7 @@ The extension must declare the matching permission in \`lumio.config.json\`. For
|
|
|
1340
1336
|
| \`chat:delete\` | Delete chat messages | Enhanced |
|
|
1341
1337
|
| \`chat:ban\` | Ban, unban, and timeout users | Enhanced |
|
|
1342
1338
|
| \`events:read\` | Subscribe to platform events | Standard |
|
|
1343
|
-
| \`events:
|
|
1339
|
+
| \`events:emit\` | Emit custom events | Standard |
|
|
1344
1340
|
`;
|
|
1345
1341
|
|
|
1346
1342
|
// src/content/cli-workflows.ts
|
|
@@ -1503,19 +1499,29 @@ Features:
|
|
|
1503
1499
|
|
|
1504
1500
|
## lumio build
|
|
1505
1501
|
|
|
1506
|
-
Bundle the extension
|
|
1502
|
+
Bundle the extension and create source archive.
|
|
1507
1503
|
|
|
1508
1504
|
\`\`\`bash
|
|
1509
1505
|
lumio build
|
|
1510
1506
|
|
|
1511
|
-
# Output:
|
|
1512
|
-
#
|
|
1513
|
-
#
|
|
1514
|
-
#
|
|
1515
|
-
#
|
|
1516
|
-
#
|
|
1507
|
+
# Output for widgets:
|
|
1508
|
+
# Built: dist/editor.js
|
|
1509
|
+
# Built: dist/layer.js
|
|
1510
|
+
# Compiled: dist/styles.css (if Tailwind detected)
|
|
1511
|
+
# Archive: dist/source.tar.gz
|
|
1512
|
+
#
|
|
1513
|
+
# Output for bot modules (server: true):
|
|
1514
|
+
# Bot module \u2014 no UI targets to bundle.
|
|
1515
|
+
# Built: dist/server.js
|
|
1516
|
+
# Archive: dist/source.tar.gz
|
|
1517
1517
|
\`\`\`
|
|
1518
1518
|
|
|
1519
|
+
Build steps:
|
|
1520
|
+
1. UI targets (\`editor\`, \`layer\`, \`interactive\`, \`designer\`) \u2014 esbuild IIFE bundles
|
|
1521
|
+
2. Server handler (\`server: true\`) \u2014 compiles \`server/handler.ts\` to \`dist/server.js\` (ESM)
|
|
1522
|
+
3. CSS \u2014 Tailwind v4 auto-detected and compiled, or plain CSS copied
|
|
1523
|
+
4. Source archive \u2014 \`dist/source.tar.gz\`
|
|
1524
|
+
|
|
1519
1525
|
Warns if \`CHANGELOG.md\` is missing.
|
|
1520
1526
|
|
|
1521
1527
|
## lumio deploy
|
|
@@ -1539,6 +1545,11 @@ lumio deploy --breaking -v 2.0.0
|
|
|
1539
1545
|
lumio deploy --draft
|
|
1540
1546
|
\`\`\`
|
|
1541
1547
|
|
|
1548
|
+
Pre-flight checks before upload:
|
|
1549
|
+
- Sound files validated (format, existence in \`dist/sounds/\`, per-file size against limit)
|
|
1550
|
+
- Sound count, per-file size, and total storage checked against resolved limits from API
|
|
1551
|
+
- Manifest validated against schema
|
|
1552
|
+
|
|
1542
1553
|
After deploy:
|
|
1543
1554
|
1. Version status = \`draft\`
|
|
1544
1555
|
2. Submit for review via dashboard (\`/dashboard/extensions/{slug}/submit\`)
|
|
@@ -1707,7 +1718,7 @@ AuthContext::ExtensionToken {
|
|
|
1707
1718
|
### Token Lifecycle
|
|
1708
1719
|
|
|
1709
1720
|
1. User opens extension in dashboard/overlay \u2014 Lumio server generates \`lm_ext_*\` token
|
|
1710
|
-
2. Token
|
|
1721
|
+
2. Token handed to the extension inside the sandbox; the Extension Runtime iframe runs on the extension's own origin \`<label>.runtime.ext.lumio.vision\` (\`<label>\` = extension UUID as 32 lowercase hex). The extension \`slug\` includes the \`short_id\` prefix (e.g. \`k8f2x-my-extension\`); the store URL is \`/store/k8f2x-my-extension\`
|
|
1711
1722
|
3. SDK uses token for all API calls (server functions, storage, events)
|
|
1712
1723
|
4. Token auto-refreshes via postMessage every 12 minutes (before 15-min expiry) \u2014 the Supervisor mediates the refresh
|
|
1713
1724
|
5. On page reload, a new token is generated
|
|
@@ -1784,11 +1795,11 @@ Extensions run inside a 3-layer iframe sandbox. Understanding the layers is impo
|
|
|
1784
1795
|
|
|
1785
1796
|
\`\`\`
|
|
1786
1797
|
Host (lumio.vision / browser source)
|
|
1787
|
-
\u2514\u2500\u2500 Supervisor iframe (supervisor.
|
|
1798
|
+
\u2514\u2500\u2500 Supervisor iframe (supervisor.ext.lumio.vision)
|
|
1788
1799
|
Purpose: validates postMessage traffic, enforces egress allowlist,
|
|
1789
1800
|
mediates token refresh, proxies LumioComponentNode[] to host
|
|
1790
|
-
\u2514\u2500\u2500 Extension Runtime iframe (ext.lumio.vision)
|
|
1791
|
-
Purpose: runs extension code on
|
|
1801
|
+
\u2514\u2500\u2500 Extension Runtime iframe (<label>.runtime.ext.lumio.vision)
|
|
1802
|
+
Purpose: runs extension code on its own origin (one per extension)
|
|
1792
1803
|
Storage: localStorage/sessionStorage BLOCKED (cross-origin isolation)
|
|
1793
1804
|
\u2514\u2500\u2500 Web Worker
|
|
1794
1805
|
Purpose: V8 isolate for server function execution
|
|
@@ -1801,8 +1812,9 @@ Host (lumio.vision / browser source)
|
|
|
1801
1812
|
- Mediates \`lm_ext_*\` token refresh (12 min interval, before 15 min expiry)
|
|
1802
1813
|
- Forwards serialized \`LumioComponentNode[]\` to the Host renderer
|
|
1803
1814
|
|
|
1804
|
-
**Extension Runtime (ext.lumio.vision) origin isolation:**
|
|
1815
|
+
**Extension Runtime (<label>.runtime.ext.lumio.vision) origin isolation:**
|
|
1805
1816
|
- Runs on a separate origin from the Host \u2014 this prevents direct DOM access and localStorage sharing
|
|
1817
|
+
- Every extension gets its own origin (\`<label>\` = extension UUID as 32 lowercase hex), so two extensions never share browser state
|
|
1806
1818
|
- \`localStorage\` and \`sessionStorage\` throw \`DOMException: Access is denied\` \u2014 use \`useExtensionStorage()\` instead
|
|
1807
1819
|
- \`document.cookie\` is unavailable
|
|
1808
1820
|
- Cross-origin postMessage to the Host goes through the Supervisor
|
|
@@ -2074,7 +2086,7 @@ For beta testing before public launch:
|
|
|
2074
2086
|
| Large inline images | Use URL-based images via \`Image\` component |
|
|
2075
2087
|
| Missing \`Lumio.render()\` | Must be called within 10s of page load |
|
|
2076
2088
|
| Hardcoded strings | Use \`config_schema\` fields for user-customizable text |
|
|
2077
|
-
| Using localStorage directly | Use \`useExtensionStorage()\` (localStorage blocked
|
|
2089
|
+
| Using localStorage directly | Use \`useExtensionStorage()\` (localStorage blocked on the Extension Runtime origin) |
|
|
2078
2090
|
| Raw CSS \`@keyframes\` animations | Use \`useAnimation()\` + \`<Animated>\` SDK presets |
|
|
2079
2091
|
|
|
2080
2092
|
## Bot Module Security
|
|
@@ -2218,7 +2230,7 @@ var troubleshootingContent = `# Troubleshooting
|
|
|
2218
2230
|
| \`BUNDLE_TOO_LARGE\` | Bundle exceeds size limit | Built bundle exceeds \`max_bundle_size_mb\` | Reduce bundle size or request limit increase |
|
|
2219
2231
|
| \`SUPERVISOR_BLOCKED\` | Supervisor rejected postMessage | Message origin or schema invalid | Ensure you are in the correct iframe layer; do not post to Host directly |
|
|
2220
2232
|
| \`WORKER_CREATION_FAILED\` | Web Worker could not start | Server functions bundle is invalid or too large | Check for syntax errors in server functions; run \`lumio build\` locally |
|
|
2221
|
-
| \`STORAGE_DOM_EXCEPTION\` | localStorage/sessionStorage access attempt | Extension Runtime (ext.lumio.vision) blocks storage APIs | Replace \`localStorage.setItem\` with \`useExtensionStorage()\` |
|
|
2233
|
+
| \`STORAGE_DOM_EXCEPTION\` | localStorage/sessionStorage access attempt | Extension Runtime (<label>.runtime.ext.lumio.vision) blocks storage APIs | Replace \`localStorage.setItem\` with \`useExtensionStorage()\` |
|
|
2222
2234
|
| \`SLUG_FORMAT_INVALID\` | Slug does not match short-ID format | Manually edited slug in \`lumio.config.json\` | Use auto-generated slug (\`k8f2x-my-extension\` format) or run \`lumio init\` |
|
|
2223
2235
|
|
|
2224
2236
|
## Common Issues
|
|
@@ -2256,7 +2268,7 @@ The SDK auto-refreshes \`lm_ext_*\` tokens via postMessage. The Supervisor media
|
|
|
2256
2268
|
### Supervisor blocked messages (\`SUPERVISOR_BLOCKED\`)
|
|
2257
2269
|
The Supervisor validates all postMessage traffic between Extension Runtime and Host. If you see this error:
|
|
2258
2270
|
1. Do not post messages directly from extension code to \`window.parent.parent\` (Host) \u2014 always use SDK hooks
|
|
2259
|
-
2. Verify the extension iframe is loaded inside \`supervisor.
|
|
2271
|
+
2. Verify the extension iframe is loaded inside \`supervisor.ext.lumio.vision\`, not directly in the Host
|
|
2260
2272
|
3. Check that the message schema matches the \`@zaflun/lumio-protocol\` wire format (SDK handles this automatically)
|
|
2261
2273
|
|
|
2262
2274
|
### Worker creation failures (\`WORKER_CREATION_FAILED\`)
|
|
@@ -2266,7 +2278,7 @@ The V8 isolate Web Worker for server functions failed to start:
|
|
|
2266
2278
|
3. Check \`lumio logs\` for the underlying JS error from the Worker initializer
|
|
2267
2279
|
|
|
2268
2280
|
### Storage DOMException errors (\`STORAGE_DOM_EXCEPTION\`)
|
|
2269
|
-
\`localStorage\` and \`sessionStorage\` are blocked on the Extension Runtime origin (
|
|
2281
|
+
\`localStorage\` and \`sessionStorage\` are blocked on the Extension Runtime origin (\`<label>.runtime.ext.lumio.vision\`):
|
|
2270
2282
|
1. Replace all \`localStorage.setItem\` / \`localStorage.getItem\` calls with \`useExtensionStorage()\`
|
|
2271
2283
|
2. Replace all \`sessionStorage\` usage with \`useVisionState()\` for transient values
|
|
2272
2284
|
3. For server-side persistence, use \`ctx.db\` in server functions
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zaflun/lumio-agent-skill",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "AI agent skill files for building Lumio Extensions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
},
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@types/node": "^
|
|
30
|
+
"@types/node": "^26.1.2",
|
|
31
31
|
"tsup": "^8.4.0",
|
|
32
|
-
"typescript": "^
|
|
33
|
-
"vitest": "^
|
|
32
|
+
"typescript": "^6.0.3",
|
|
33
|
+
"vitest": "^4.1.10"
|
|
34
34
|
},
|
|
35
35
|
"repository": {
|
|
36
36
|
"type": "git",
|