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.
Files changed (3) hide show
  1. package/luanette.mjs +5 -4
  2. package/mcp.mjs +3 -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] a playground share link
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
- export function shareLink(src, name, base = PLAYGROUND) {
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.4.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"],