@stage5/lumine 0.2.86 → 0.2.88
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/lib/sdk.js +13 -0
- package/package.json +1 -1
- package/sdk/BUILD_SDK_INDEX.md +88 -3
- package/sdk/LUMINE_ADMIN.md +4 -1
package/lib/sdk.js
CHANGED
|
@@ -22,6 +22,19 @@ export const SDK_CLI_METHODS = {
|
|
|
22
22
|
"aiCards.get": { path: "api/content/ai-card", scopes: ["content:read"] },
|
|
23
23
|
"grammarbles.listQuestions": { path: "api/content/grammarbles/questions", scopes: ["content:read"] },
|
|
24
24
|
"grammarbles.getMyQuestionHistory": { path: "api/content/grammarbles/history", scopes: ["content:read"] },
|
|
25
|
+
"minecraft.getWorlds": { path: "api/minecraft/worlds", scopes: ["content:read"] },
|
|
26
|
+
"minecraft.getOnlinePlayers": { path: "api/minecraft/players", scopes: ["content:read"] },
|
|
27
|
+
"minecraft.getZero": { path: "api/minecraft/zero", scopes: ["content:read"] },
|
|
28
|
+
"minecraft.getZeroBuilds": { path: "api/minecraft/zero/builds", scopes: ["content:read"] },
|
|
29
|
+
"minecraft.getPeople": { path: "api/minecraft/people", scopes: ["content:read"] },
|
|
30
|
+
"minecraft.setPlayerRole": { path: "api/minecraft/people/role", scopes: ["content:write"], write: true },
|
|
31
|
+
"minecraft.getChat": { path: "api/minecraft/chat", scopes: ["content:read"] },
|
|
32
|
+
"minecraft.getChatHistory": { path: "api/minecraft/chat/history", scopes: ["content:read"] },
|
|
33
|
+
"minecraft.sendChat": { path: "api/minecraft/chat/send", scopes: ["content:write"], write: true },
|
|
34
|
+
"minecraft.muteChatUser": { path: "api/minecraft/chat/mute", scopes: ["content:write"], write: true },
|
|
35
|
+
"minecraft.getMyLink": { path: "api/minecraft/link", scopes: ["content:read"] },
|
|
36
|
+
"minecraft.createLinkCode": { path: "api/minecraft/link/code", scopes: ["content:write"], write: true },
|
|
37
|
+
"minecraft.unlinkMinecraft": { path: "api/minecraft/link/unlink", scopes: ["content:write"], write: true },
|
|
25
38
|
"subjects.getMySubjects": { path: "api/content/my-subjects", scopes: ["content:read"] },
|
|
26
39
|
"subjects.search": { path: "api/content/subjects/search", scopes: ["content:read"] },
|
|
27
40
|
"subjects.getSubject": { path: "api/content/subject", scopes: ["content:read"] },
|
package/package.json
CHANGED
package/sdk/BUILD_SDK_INDEX.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Build SDK Index
|
|
2
2
|
|
|
3
|
-
Version: 1.
|
|
4
|
-
Updated: 2026-09-
|
|
5
|
-
Generated: 2026-09-
|
|
3
|
+
Version: 1.51.0
|
|
4
|
+
Updated: 2026-09-24
|
|
5
|
+
Generated: 2026-09-24T00:08:02.260Z
|
|
6
6
|
|
|
7
7
|
## Notes
|
|
8
8
|
- This SDK is injected into Build iframes via the Build preview/runtime.
|
|
@@ -761,6 +761,91 @@ const result = await Twinkle.characters.chat({ character: 'zero', thinkingMode:
|
|
|
761
761
|
- A quiet edition with no editorial events does not call an AI provider and does not consume AI Energy.
|
|
762
762
|
- A failed attempt may be queued again on the same day. A ready edition is immutable for ordinary viewers.
|
|
763
763
|
|
|
764
|
+
### Twinkle.minecraft
|
|
765
|
+
- async getWorlds() | scopes: content:read
|
|
766
|
+
- Returns: { worlds: [{ id, name, dimension, spawn: { x, z } | null, map: { tileUrlTemplate, minZoom, maxZoom, tilePixels, blocksPerTileAtMaxZoom, renderedAt } | null }], stale }
|
|
767
|
+
- List the server's worlds (world, world1, world2, world_nether, world_the_end) with squaremap tile info for drawing a top-down map.
|
|
768
|
+
- Tiles are 512x512 PNGs over HTTPS from www.twinklemc.site. At maxZoom one pixel is one block; blocksPerTile = blocksPerTileAtMaxZoom * 2 ** (maxZoom - z); tile x/y = floor(block x/z / blocksPerTile). Fill {z}, {x}, {y}. map.renderedAt tells how fresh the tiles are.
|
|
769
|
+
- Limited rollout: apps not enabled yet get 403 with code minecraft_sdk_not_enabled.
|
|
770
|
+
- stale: true means the Minecraft server was briefly unreachable and the data is a recent cached copy.
|
|
771
|
+
- Example: const { worlds } = await Twinkle.minecraft.getWorlds(); const w = worlds.find((x) => x.id === 'world'); const z = w.map.maxZoom; const blocksPerTile = w.map.blocksPerTileAtMaxZoom * 2 ** (w.map.maxZoom - z); const tx = Math.floor(blockX / blocksPerTile), ty = Math.floor(blockZ / blocksPerTile); const url = w.map.tileUrlTemplate.replace('{z}', z).replace('{x}', tx).replace('{y}', ty);
|
|
772
|
+
- async getOnlinePlayers() | scopes: content:read
|
|
773
|
+
- Returns: { players: [{ name, world, x, y, z, isZero }], count, stale }
|
|
774
|
+
- List players currently online with their world and block coordinates. Zero appears with isZero: true and is not counted in count.
|
|
775
|
+
- Cached for about 5 seconds; poll no faster than every 5 seconds.
|
|
776
|
+
- Names are Minecraft usernames, not Twinkle usernames.
|
|
777
|
+
- Example: const { players, count } = await Twinkle.minecraft.getOnlinePlayers();
|
|
778
|
+
- async getZero() | scopes: content:read
|
|
779
|
+
- Returns: { zero: { online, world, position: { x, y, z } | null, activity: 'idle'|'thinking'|'building'|'workshop', currentBuild: { id, title, status, placed, total, requester, world, bounds } | null, queue: [build], workshop: { world, min, max } | null, updatedAt }, stale }
|
|
780
|
+
- Where Zero is and what he is doing right now, including the build in progress and its progress.
|
|
781
|
+
- Cached for about 3 seconds.
|
|
782
|
+
- bounds are { min: [x, y, z], max: [x, y, z] } in world block coordinates.
|
|
783
|
+
- Example: const { zero } = await Twinkle.minecraft.getZero(); if (zero.currentBuild) console.log(zero.currentBuild.title, zero.currentBuild.placed + '/' + zero.currentBuild.total);
|
|
784
|
+
- async getZeroBuilds({ limit, kind } = {}) | scopes: content:read
|
|
785
|
+
- Returns: { builds: [{ id, kind: 'helper'|'workshop', title, status, placed, total, requester, world, bounds, createdAt }], stale }
|
|
786
|
+
- Zero's recent builds, newest first: builds for players (helper) and his own workshop projects (workshop).
|
|
787
|
+
- limit is 1-50 (default 10). kind filters to helper or workshop builds.
|
|
788
|
+
- Example: const { builds } = await Twinkle.minecraft.getZeroBuilds({ limit: 10, kind: 'workshop' });
|
|
789
|
+
- async getPeople() | scopes: content:read
|
|
790
|
+
- Returns: { canManage, people: [{ uuid, name, role: 'visitor'|'member'|'builder'|'moderator', groups, op, online, banned, protected, firstSeenAt, lastSeenAt, isZero, twinkle: { userId, username } | null }], roles }
|
|
791
|
+
- Everyone who has joined the server with their in-game role, for the server owner's role management screen.
|
|
792
|
+
- Only the server owner, in an app they own, gets the list; everyone else gets { canManage: false, people: [] } without an error, so hide the feature when canManage is false.
|
|
793
|
+
- Roles: visitor (play and chat), member (/tpa, /home, /back, may ask Zero to build), builder (member + /fly and creative/survival), moderator (builder + teleport others, CoreProtect rollback, /kick). op: true players are server operators and have every power regardless of role.
|
|
794
|
+
- protected: true players (the owner and Zero's account) can't be changed from the app. Sorted online first, then most recently seen.
|
|
795
|
+
- Not cached; call on screen open or after a change, not on a timer.
|
|
796
|
+
- twinkle is the Twinkle account linked to that player with /link, or null.
|
|
797
|
+
- Example: const { canManage, people } = await Twinkle.minecraft.getPeople(); if (!canManage) hidePeopleTab();
|
|
798
|
+
- async setPlayerRole({ uuid, role }) | scopes: content:write
|
|
799
|
+
- Returns: { player: { uuid, name, role, op } }
|
|
800
|
+
- Change a player's in-game role; it applies immediately, even while they are online.
|
|
801
|
+
- Server owner only, in an app they own; others get 403 with code minecraft_roles_forbidden.
|
|
802
|
+
- role is visitor, member, builder or moderator. 400 codes: minecraft_bad_uuid, minecraft_bad_role, minecraft_protected_player, minecraft_unknown_player. 503 minecraft_unavailable while the server restarts.
|
|
803
|
+
- Every change is logged on the server and emailed to the owner; the player is told in game.
|
|
804
|
+
- Example: await Twinkle.minecraft.setPlayerRole({ uuid: person.uuid, role: 'builder' });
|
|
805
|
+
- async getChat({ since } = {}) | scopes: content:read
|
|
806
|
+
- Returns: { events: [{ seq, at, kind: 'chat'|'zero'|'web'|'join'|'leave'|'death', name, text, userId, archived }], latestSeq, online, archiveReady, viewer: { canSend, muted, canModerate }, mutedUserIds }
|
|
807
|
+
- Live server chat after a sequence number: player chat, Zero, messages sent from the web, joins, leaves and deaths.
|
|
808
|
+
- Without since (or 0) it returns the newest 50 events, oldest first. Pass since = latestSeq from the previous response to get only new events. Poll every 2-3 seconds while the chat is visible; stop when hidden.
|
|
809
|
+
- kind: chat (a player), zero (Zero, the AI builder), web (someone chatting from the Twinkle app; userId is their Twinkle user id), join, leave, death. Private messages are never included.
|
|
810
|
+
- name is a Minecraft username for chat/join/leave/death, and a Twinkle username for web.
|
|
811
|
+
- viewer.canModerate is true only for the server owner; mutedUserIds is filled only for them.
|
|
812
|
+
- Example: let since = 0; async function poll() { const { events, latestSeq } = await Twinkle.minecraft.getChat({ since }); since = latestSeq; render(events); } setInterval(poll, 2500);
|
|
813
|
+
- async getChatHistory({ before, limit, query, includeArchived } = {}) | scopes: content:read
|
|
814
|
+
- Returns: { events: [{ seq, at, kind: 'chat'|'zero'|'web'|'join'|'leave'|'death', name, text, userId, archived }], hasMore, nextBefore: { at, seq } | null, includesArchived }
|
|
815
|
+
- Older server chat, newest first, for scrolling back or searching past days.
|
|
816
|
+
- before is the nextBefore cursor from the previous page; omit it to start from the newest. limit 1-100 (default 50). query searches message text and names (60 chars).
|
|
817
|
+
- Chat from before the web chat bridge existed (imported from server logs) is archived: only the server owner can include it with includeArchived: true; others never receive it.
|
|
818
|
+
- Example: const page = await Twinkle.minecraft.getChatHistory({ limit: 50 }); const older = await Twinkle.minecraft.getChatHistory({ before: page.nextBefore });
|
|
819
|
+
- async sendChat({ text }) | scopes: content:write
|
|
820
|
+
- Returns: { event: { seq, at, kind: 'chat'|'zero'|'web'|'join'|'leave'|'death', name, text, userId, archived } }
|
|
821
|
+
- Send a chat message from the app into the Minecraft server; players see it as [Web] <your Twinkle username>.
|
|
822
|
+
- Signed-in viewers only. text is trimmed to 200 characters. About one message per 2.5 seconds and 10 per minute per person: 429 with code minecraft_chat_rate_limited and retryAfterMs.
|
|
823
|
+
- 403 minecraft_chat_forbidden for accounts banned from chat; 400 minecraft_muted when the server owner muted them from web chat.
|
|
824
|
+
- Send only on a user action (Enter or Send); never automatically.
|
|
825
|
+
- Example: await Twinkle.minecraft.sendChat({ text: 'Hi from the website!' });
|
|
826
|
+
- async muteChatUser({ userId, muted }) | scopes: content:write
|
|
827
|
+
- Returns: { userId, muted }
|
|
828
|
+
- Server owner only: stop (or allow again) a Twinkle user sending web chat into the server.
|
|
829
|
+
- Server owner only, in an app they own; others get 403 with code minecraft_roles_forbidden. muted defaults to true.
|
|
830
|
+
- Example: await Twinkle.minecraft.muteChatUser({ userId: event.userId, muted: true });
|
|
831
|
+
- async getMyLink() | scopes: content:read
|
|
832
|
+
- Returns: { links: [{ uuid, name, linkedAt }], pending: { code, expiresAt } | null }
|
|
833
|
+
- The Minecraft accounts linked to the signed-in viewer's Twinkle account, and any unused link code.
|
|
834
|
+
- Always the caller's own account. A viewer may link several Minecraft accounts (e.g. Java and Bedrock); each Minecraft account belongs to one Twinkle user.
|
|
835
|
+
- Poll every few seconds only while showing a code and waiting for the player to type /link in game.
|
|
836
|
+
- Example: const { links } = await Twinkle.minecraft.getMyLink(); const myMinecraftName = links[0]?.name;
|
|
837
|
+
- async createLinkCode() | scopes: content:write
|
|
838
|
+
- Returns: { code, expiresAt, command }
|
|
839
|
+
- Get a one-time code the viewer types in game as /link CODE to connect that Minecraft account to their Twinkle account.
|
|
840
|
+
- Signed-in viewers only. Codes last 10 minutes, work once, and a new code replaces the old one. About 5 codes per 10 minutes: 429 minecraft_link_rate_limited.
|
|
841
|
+
- The player sees a confirmation in game; getMyLink() then lists the account.
|
|
842
|
+
- Example: const { command } = await Twinkle.minecraft.createLinkCode(); showText(`Type ${command} in Minecraft`);
|
|
843
|
+
- async unlinkMinecraft({ uuid }) | scopes: content:write
|
|
844
|
+
- Returns: { removed }
|
|
845
|
+
- Remove one of the viewer's own linked Minecraft accounts.
|
|
846
|
+
- Only the viewer's own links; removed is false when there was nothing to remove.
|
|
847
|
+
- Example: await Twinkle.minecraft.unlinkMinecraft({ uuid: link.uuid });
|
|
848
|
+
|
|
764
849
|
### Twinkle.leaderboards
|
|
765
850
|
- async get({ boardKey = 'default', limit, cursor } = {}) | scopes: none
|
|
766
851
|
- Returns: { entries: [{ rank, id, buildId, boardKey, viewerKind, userId, displayName, score, meta, achievedAt, createdAt, updatedAt }], scores, cursor, hasMore, personalBest: { id, buildId, boardKey, viewerKind, userId, displayName, score, meta, achievedAt, createdAt, updatedAt } | null }
|
package/sdk/LUMINE_ADMIN.md
CHANGED
|
@@ -3008,7 +3008,10 @@ disagreements and the `jev_reply_gate_audit`, `jev_chat_routing_audit` and
|
|
|
3008
3008
|
missing evidence. Report fallback rates and reasons instead. Auto rows served
|
|
3009
3009
|
without a comparison carry `baselineStatus: not_run`; its fallback LLM spend is
|
|
3010
3010
|
`lumine_model_fallback`. The eight comparison-only routing families below are
|
|
3011
|
-
unchanged.
|
|
3011
|
+
unchanged. Chat routing is also off since September 23
|
|
3012
|
+
(`JEV_CHAT_ROUTING_ENABLED`, default off; Jev served ~1% of chats and could not
|
|
3013
|
+
judge when a reply needs older history), so zero chat serving rows is expected.
|
|
3014
|
+
The rest of this section describes the pre-September-23 pilot.
|
|
3012
3015
|
|
|
3013
3016
|
Read `data.jevPilot` from `lumine admin brief --json` and carry it into
|
|
3014
3017
|
the full report for Mikey. The active `daily-run report --json` also includes
|