luanette 0.4.0 → 0.5.0
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/luanette.mjs +5 -4
- package/mcp.mjs +3 -3
- package/package.json +1 -1
package/luanette.mjs
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// luanette sound "C4 pulse 5, E4 slide, -, G4 saw 7 fadeout" [--speed N] [--loop A-B]
|
|
8
8
|
// luanette sound CART.lua N --wav OUT.wav a cart's sound, as a WAV
|
|
9
9
|
// luanette song CART.lua [--from N] --wav OUT.wav its song
|
|
10
|
-
// luanette link CART.lua [--name NAME]
|
|
10
|
+
// luanette link CART.lua [--name NAME] [--play] a playground share link (--play: opens in play mode)
|
|
11
11
|
// luanette new NAME [--template blank|platformer|shooter|puzzle]
|
|
12
12
|
// luanette mcp an MCP server over stdio (for agents)
|
|
13
13
|
//
|
|
@@ -375,9 +375,10 @@ export async function renderAudio(src, n, from = null, rate = 44100) {
|
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
// ---- links and new carts ---------------------------------------------------------------------------
|
|
378
|
-
|
|
378
|
+
// "&play" after it opens the cart in play mode: the screen alone, with buttons on a phone.
|
|
379
|
+
export function shareLink(src, name, base = PLAYGROUND, play = false) {
|
|
379
380
|
const data = zlib.deflateRawSync(Buffer.from(JSON.stringify({ name, src })), { level: 9 });
|
|
380
|
-
return base + "#cart=d" + data.toString("base64url");
|
|
381
|
+
return base + "#cart=d" + data.toString("base64url") + (play ? "&play" : "");
|
|
381
382
|
}
|
|
382
383
|
export function newCart(name, template = "blank") {
|
|
383
384
|
if (!/^[a-z0-9_-]{1,32}$/.test(name)) throw new Error("a cart's name is 1 to 32 of a-z, 0-9, _ and -");
|
|
@@ -436,7 +437,7 @@ async function main() {
|
|
|
436
437
|
print({ ok: true, wav: opt.wav || "song.wav", seconds: Number(r.seconds.toFixed(2)) });
|
|
437
438
|
} else if (cmd === "link") {
|
|
438
439
|
const { src, name } = readCart(pos[0]);
|
|
439
|
-
process.stdout.write(shareLink(src, opt.name || name, opt.base || PLAYGROUND) + "\n");
|
|
440
|
+
process.stdout.write(shareLink(src, opt.name || name, opt.base || PLAYGROUND, opt.play === true) + "\n");
|
|
440
441
|
} else if (cmd === "new") {
|
|
441
442
|
const name = pos[0], file = opt.out || `${name}.lua`;
|
|
442
443
|
if (fs.existsSync(file)) throw new Error(`${file} is there already`);
|
package/mcp.mjs
CHANGED
|
@@ -45,8 +45,8 @@ const TOOLS = [
|
|
|
45
45
|
inputSchema: { type: "object", required: ["notes"], properties: { notes: { type: "string" },
|
|
46
46
|
speed: { type: "integer", description: "Ticks of 1/120 s a note, 1-255 (8)" },
|
|
47
47
|
loop: { type: "array", items: { type: "integer" }, description: "[first, end]: loop those notes for good" } } } },
|
|
48
|
-
{ name: "share_link", description: "A link that opens the cart in the playground (https://geofresh.github.io/luanette/), to play it, edit it or send it to a board.",
|
|
49
|
-
inputSchema: { type: "object", properties: { ...CART, name: { type: "string" } } } },
|
|
48
|
+
{ name: "share_link", description: "A link that opens the cart in the playground (https://geofresh.github.io/luanette/), to play it, edit it or send it to a board. With play, it opens in play mode: the screen alone, with buttons on a phone.",
|
|
49
|
+
inputSchema: { type: "object", properties: { ...CART, name: { type: "string" }, play: { type: "boolean", description: "Open in play mode" } } } },
|
|
50
50
|
{ name: "api_help", description: "The cart API from docs/api.md: a call's signatures and what it does, or every call whose name or description has a word in it, or (with nothing) the list of names.",
|
|
51
51
|
inputSchema: { type: "object", properties: { name: { type: "string" }, search: { type: "string" } } } },
|
|
52
52
|
{ name: "new_cart", description: "A new cart's source from a template (blank, platformer, shooter, puzzle): full-screen, with sprites, sounds and log() to build on.",
|
|
@@ -112,7 +112,7 @@ const handlers = {
|
|
|
112
112
|
},
|
|
113
113
|
async share_link(a) {
|
|
114
114
|
const { src, name } = cartOf(a);
|
|
115
|
-
return { content: [text(L.shareLink(src, a.name || name))] };
|
|
115
|
+
return { content: [text(L.shareLink(src, a.name || name, undefined, a.play === true))] };
|
|
116
116
|
},
|
|
117
117
|
async api_help(a) {
|
|
118
118
|
if (a.name) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "luanette",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Check, run, hear and share carts for Luanette, a Lua game console for ESP32-S3 boards: the console's own engine in Node, nothing to build",
|
|
5
5
|
"bin": { "luanette": "luanette.mjs" },
|
|
6
6
|
"files": ["luanette.mjs", "pyrandom.mjs", "mcp.mjs", "engine/", "lib/", "templates/", "api.json", "README.md", "LICENSE"],
|