@homie-rocks/studio 0.58.11 → 0.58.13

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/CHANGELOG.md CHANGED
@@ -17,6 +17,31 @@ To bring a studio up to date, tell Claude: "Upgrade my studio to the newest Homi
17
17
  `npx -y @homie-rocks/studio@latest upgrade`, which shows what's new since the version your studio pins (from this
18
18
  file) and what the upgrade would change, and changes nothing until you agree.
19
19
 
20
+ ## [0.58.13] - 2026-10-20
21
+
22
+ **Plugin 0.58.7**
23
+
24
+ A hosted workspace offers only the tools that work there, and a build put on the private preview no longer ends the check it is part of.
25
+
26
+ ### Changed
27
+
28
+ - In a hosted workspace (`HOMIE_PREVIEW_URL` named by the host), the local MCP server does not offer the tools that set up or sign in this computer, change the studio's own Cloudflare account or build for another platform (setup, scaffold and open, the GitHub, Cloudflare and Stripe sign-ins, the Stripe webhook, domains, the read-only switch, event webhooks, the Game Lab and standalone builds): the studio is already made and online with its host, whose sign-ins, domains and payments those are. Its instructions say so in place of the paragraphs about them.
29
+
30
+ ### Fixed
31
+
32
+ - `deploy --preview` inside a check or playtest no longer ends that run's progress feed as passed before the check and the pictures have run; its stage says the build is on the private preview, not live.
33
+
34
+ ## [0.58.12] - 2026-10-20
35
+
36
+ **Plugin 0.58.6**
37
+
38
+ Every browser the toolkit opens can be a cloud browser, and a studio worked on away from the person's screen previews on its own private preview.
39
+
40
+ ### Added
41
+
42
+ - Every command and skill that opens a browser (check, playtest, look, perf, shoot, lab check, port check, crowd load, 3D renders, art captures and video takes) can use a browser in the cloud (in 0.58.11 only check and the playtest script could): with `HOMIE_BROWSER_WS_ENDPOINT` set to a CDP WebSocket address (Cloudflare Browser Run, for example), they connect to it instead of starting Chrome on this computer. A platform target leaves queues and cron triggers to the platform.
43
+ - A host that runs the toolkit away from the person's screen (Homie Managed's studio workspace, a cloud dev box) can name the address of the studio's private preview in `HOMIE_PREVIEW_URL`. For a studio whose studio.json has a preview target (`cloudflare.preview`), the local MCP server's `preview_run` then puts the build there (`deploy --preview`) and gives that address, `check` and `playtest` put the current build there and open it, and `preview_stop` has nothing to stop. Without it, the site runs on this computer as before.
44
+
20
45
  ## [0.58.11] - 2026-10-19
21
46
 
22
47
  **Plugin 0.58.5**
@@ -26,7 +51,7 @@ Host a studio on Workers for Platforms with a private preview, check it with a b
26
51
  ### Added
27
52
 
28
53
  - A studio can deploy to a Workers for Platforms dispatch namespace: `cloudflare.dispatchNamespace`, `worker`, `d1Id` and `domain` in studio.json name the preprovisioned Worker, and `homie-studio deploy` sends the build there with Wrangler's own `--dispatch-namespace`. `cloudflare.preview` names a second Worker and database, and `homie-studio deploy --preview` sends the same build to it. A platform that hosts studios this way (Homie Managed) enforces the target at its API boundary.
29
- - Every command and skill that opens a browser (check, playtest, look, perf, shoot, lab check, port check, crowd load, 3D renders, art captures and video takes) can use a browser in the cloud: with `HOMIE_BROWSER_WS_ENDPOINT` set to a CDP WebSocket address (Cloudflare Browser Run, for example), they connect to it instead of starting Chrome on this computer. A platform target leaves queues and cron triggers to the platform.
54
+ - `homie-studio check` and the playtest script can use a browser in the cloud: with `HOMIE_BROWSER_WS_ENDPOINT` set to a CDP WebSocket address (Cloudflare Browser Run, for example), they connect to it instead of starting Chrome on this computer.
30
55
  - `homie-studio drain on|off|status` pauses new room admissions without deploying or closing existing sockets. A move waits for empty rooms and delivered records before freezing the source.
31
56
  - Managed media bindings preserve streamed media, range requests and large player saves.
32
57
  - A read-only switch for a studio: `homie-studio read-only on|off|status` (and the local MCP tool `studio_read_only`) freezes the live studio for a few minutes, for a move to another host or maintenance, without losing anything. It sets the Worker secret `STUDIO_READ_ONLY` with the studio's own Cloudflare sign-in, as a new Worker version. While on, changes answer 503 with `Retry-After` and `x-studio-read-only: 1`; pages, games, live rooms and the Stripe webhook keep working, D1 takes no other write, room records wait in each room, scheduled and queued work waits, and `/api/games` reports `readOnly`.
@@ -1273,11 +1273,12 @@ async function tracked(root, stage, run, command) {
1273
1273
  }
1274
1274
  if (!result?.ok) { feed.stage(stage, 'failed', result?.why ?? 'failed'); return result; }
1275
1275
  const note = stage === 'build' ? `Built ${(result.games ?? []).map((g) => `${g.id} (${Math.round(g.bytes / 1024)} KB)`).join(', ') || 'the site'}`
1276
- : stage === 'deploy' ? `Live: ${result.url ?? 'deployed'}`
1276
+ : stage === 'deploy' ? `${flags.has('preview') ? 'On the private preview' : 'Live'}: ${result.url ?? 'deployed'}`
1277
1277
  : result.command === 'port check' ? `${result.passed.length} passed${result.skipped.length ? `, ${result.skipped.length} skipped` : ''} in ${Math.round(result.totalMs / 1000)} s`
1278
1278
  : result.kind === 'app' ? `App ${result.game ?? ''}: wall and two phones, shared action and reconnect passed` : `Room ${result.room}: round ${result.round?.n} finished with ${result.round?.humans} people in ${Math.round(result.totalMs / 1000)} s`;
1279
1279
  feed.stage(stage, 'done', note);
1280
- if (stage === 'deploy') {
1280
+ // A build put on the private preview is not live: the run it is part of (a check, a playtest) carries on.
1281
+ if (stage === 'deploy' && !flags.has('preview')) {
1281
1282
  const doc = feed.doc;
1282
1283
  const game = (result.games ?? []).find((g) => g.id === doc.id) ?? (result.games ?? [])[0];
1283
1284
  if (game?.play) feed.preview({ url: game.play });
package/lib/mcp-tools.mjs CHANGED
@@ -32,6 +32,7 @@ import { newStudio, slugify } from './scaffold.mjs';
32
32
  import { repoFromUrl, studioRepo } from './repo.mjs';
33
33
  import { GAME_ID, PACKAGE_ROOT, findStudio, isRulesGame, listExperiences as listGames, readLocal, readStudio, siteUrl } from './studio.mjs';
34
34
  import { runningDev } from './dev.mjs';
35
+ import { dispatchTarget } from './dispatch-target.mjs';
35
36
  import { deployWords } from './deploy-state.mjs';
36
37
  import { partsForListing, publishBefore, publishesSoFar } from './directory.mjs';
37
38
  import { STUDIO_VERSION } from './version.mjs';
@@ -443,7 +444,7 @@ async function startRun(ctx, root, { kind, game, title, steps }) {
443
444
  const run = { kind, title, state: 'running', ...(await feedForRun(ctx, root, { id: game ?? null, title })), jobs: [] };
444
445
  ctx.runs.set(run.build, run);
445
446
  const next = (i) => {
446
- if (i >= steps.length) { run.state = 'passed'; endRun(root, run, 'passed', `${title}: done.`); if (kind !== 'deploy') ctx.note(root).checked = true; return; }
447
+ if (i >= steps.length) { run.state = 'passed'; endRun(root, run, 'passed', `${title}: done.`); if (kind === 'check' || kind === 'playtest') ctx.note(root).checked = true; return; }
447
448
  const step = steps[i];
448
449
  const job = cliJob(root, step.label, step.args, {
449
450
  onEnd: (j) => {
@@ -459,7 +460,38 @@ async function startRun(ctx, root, { kind, game, title, steps }) {
459
460
  return buildCard(ctx, root, feedFor(root, run.build));
460
461
  }
461
462
 
463
+ /**
464
+ * WHERE "HERE" IS, FOR A HOST AWAY FROM THE PERSON'S SCREEN. A platform that runs this toolkit for the person in a
465
+ * workspace of its own (Homie Managed's studio workspace, a cloud dev box) has no browser beside it that can open
466
+ * this computer's addresses. It names the address its studio's private preview is reachable at, HOMIE_PREVIEW_URL,
467
+ * and the studio's studio.json names that preview's Workers for Platforms target (cloudflare.preview). Then the
468
+ * studio's site "here" is that preview: preview_run puts the build there (deploy --preview), and check and playtest
469
+ * open it after doing the same. Without both, nothing changes: the site runs on this computer.
470
+ */
471
+ export function hostedPreview(root, env = process.env) {
472
+ const raw = String(env.HOMIE_PREVIEW_URL ?? '').trim();
473
+ if (!raw) return null;
474
+ let url;
475
+ try { url = new URL(raw); } catch { return null; }
476
+ if (url.protocol !== 'https:' || url.username || url.password || url.search || url.hash) return null;
477
+ try { if (!dispatchTarget(readStudio(root), { preview: true })) return null; } catch { return null; }
478
+ return url.href.replace(/\/+$/, '');
479
+ }
480
+
481
+ /**
482
+ * A hosted workspace (HOMIE_PREVIEW_URL named by the host): the studio is already made and online with the host,
483
+ * and its sign-ins, domains, payments and webhooks are the host's, so the tools that set up or sign in this
484
+ * computer, change the studio's own Cloudflare account, or build for another platform are not offered there.
485
+ */
486
+ export const HOSTED_OFF = Object.freeze(['setup_prepare', 'setup_status', 'studio_scaffold', 'studio_fold', 'studio_open', 'github_login', 'cloudflare_login', 'stripe_login', 'stripe_webhook', 'studio_domain', 'studio_read_only', 'studio_events_webhook', 'game_lab', 'game_standalone']);
487
+ export const hostedHere = (env = process.env) => Boolean(String(env.HOMIE_PREVIEW_URL ?? '').trim());
488
+
489
+ /** The step that puts the studio's current build on its hosted preview (a deploy --preview builds first). */
490
+ const PREVIEW_STEP = { label: 'the build on the private preview', args: ['deploy', '--preview'] };
491
+
462
492
  async function devUrl(ctx, root, port) {
493
+ const hosted = hostedPreview(root);
494
+ if (hosted) return hosted;
463
495
  const dev = devOf(root);
464
496
  if (dev) return dev.url;
465
497
  const r = await startDev(ctx, root, port);
@@ -1062,6 +1094,18 @@ export function toolDefs(ctx, avail = {}) {
1062
1094
  run: async (a) => {
1063
1095
  const root = ctx.root(a.studio);
1064
1096
  const need = needsInstall(ctx, root); if (need) return need;
1097
+ const hosted = hostedPreview(root);
1098
+ if (hosted) {
1099
+ const games = listGames(root);
1100
+ const g = a.game ? games.find((x) => x.id === a.game) : games[0];
1101
+ const card = await startRun(ctx, root, { kind: 'preview', game: g?.id ?? null, title: `${readStudio(root).name ?? 'The studio'}: private preview`, steps: [PREVIEW_STEP] });
1102
+ const lines = [
1103
+ `The studio's site runs on its private preview, not on this computer: the build is going there now (the card follows it). When it is done: ${hosted}/${games.length ? '' : ' (the home page: "First game coming soon")'}`,
1104
+ ...games.map((x) => ` ${x.name ?? x.id}: ${hosted}/${x.id}/play`),
1105
+ g ? `The person opens ${hosted}/${g.id}/play on two screens (a computer and a phone): two players, one room. Give them the address; do not open a browser for them.` : 'Give the person the address; do not open a browser for them.',
1106
+ ];
1107
+ return { ...card, content: [{ type: 'text', text: lines.join('\n') }, ...(card.content ?? [])] };
1108
+ }
1065
1109
  let url = devOf(root)?.url ?? null;
1066
1110
  let slow = false;
1067
1111
  if (!url) { const r = await startDev(ctx, root, a.port); if (r.error) return fail(r.error); url = r.url; slow = Boolean(r.slow); }
@@ -1081,6 +1125,8 @@ export function toolDefs(ctx, avail = {}) {
1081
1125
  annotations: { title: 'Stop the site here', ...RW },
1082
1126
  run: async (a) => {
1083
1127
  const root = ctx.root(a.studio);
1128
+ const hosted = hostedPreview(root);
1129
+ if (hosted) return ok(`Nothing runs on this computer to stop: the studio's private preview (${hosted}/) stays as it is until the next build is put there.`, { kind: 'preview', stopped: [], hosted });
1084
1130
  const r = await cli(ctx, root, 'dev --stop', ['dev', '--stop'], { wait: 20_000 });
1085
1131
  // What a server stopped another way left behind is cleaned up and said (lib/dev.mjs).
1086
1132
  const note = r.result?.why && (r.result?.stale || r.result?.stopped?.length) ? ` ${r.result.why[0].toUpperCase()}${r.result.why.slice(1)}.` : '';
@@ -1099,8 +1145,10 @@ export function toolDefs(ctx, avail = {}) {
1099
1145
  const game = a.game ?? (games.length === 1 ? games[0].id : null);
1100
1146
  if (!game) return fail(games.length ? `which game? ${games.map((g) => g.id).join(', ')}` : 'there is no game to check yet');
1101
1147
  const url = a.url ? String(a.url) : await devUrl(ctx, root);
1148
+ const hosted = !a.url && hostedPreview(root);
1102
1149
  return startRun(ctx, root, { kind: 'check', game, title: `${games.find((g) => g.id === game)?.name ?? game}: ${games.find((g) => g.id === game)?.kind === 'app' ? 'multi-screen' : 'two-browser'} check`, steps: [
1103
1150
  ...(games.some((g) => g.id === game && isRulesGame(g)) ? [{ label: 'rules build check', args: ['build', game] }] : []),
1151
+ ...(hosted ? [PREVIEW_STEP] : []),
1104
1152
  { label: 'two-browser check', args: ['check', game, '--url', url, '--shots', join('.checks', game)] },
1105
1153
  ] });
1106
1154
  },
@@ -1117,9 +1165,11 @@ export function toolDefs(ctx, avail = {}) {
1117
1165
  const game = a.game ?? (games.length === 1 ? games[0].id : null);
1118
1166
  if (!game) return fail(games.length ? `which game? ${games.map((g) => g.id).join(', ')}` : 'there is no game to playtest yet');
1119
1167
  const url = a.url ? String(a.url) : await devUrl(ctx, root);
1168
+ const hosted = !a.url && hostedPreview(root);
1120
1169
  const shots = join('.checks', `${game}-look`);
1121
1170
  return startRun(ctx, root, { kind: 'playtest', game, title: `${games.find((g) => g.id === game)?.name ?? game}: playtest`, steps: [
1122
1171
  ...(games.some((g) => g.id === game && isRulesGame(g)) ? [{ label: 'rules build check', args: ['build', game] }] : []),
1172
+ ...(hosted ? [PREVIEW_STEP] : []),
1123
1173
  { label: 'two-browser check', args: ['check', game, '--url', url, '--shots', join('.checks', game)] },
1124
1174
  { label: 'pictures on a computer and a phone', soft: true, args: ['look', `/${game}/`, `/${game}/${games.find((g) => g.id === game)?.kind === 'app' ? 'open' : 'play'}`, '--url', url, '--only', 'computer,phone', '--shots', shots],
1125
1175
  // The first screen of each page first (a whole page is a tall picture): what a person sees on arrival.
@@ -1551,7 +1601,7 @@ export function toolDefs(ctx, avail = {}) {
1551
1601
  // Every tool says whose it is: a Claude app may also have the Homie house app's own MCP server (its room and TV
1552
1602
  // tools), a different server with different tools.
1553
1603
  for (const t of tools) if (!t.description.startsWith('Homie Studio')) t.description = `Homie Studio: ${t.description}`;
1554
- return tools;
1604
+ return hostedHere() ? tools.filter((t) => !HOSTED_OFF.includes(t.name)) : tools;
1555
1605
  }
1556
1606
 
1557
1607
  /** Local processing availability only; provider connections belong to the AI host. */
package/lib/mcp.mjs CHANGED
@@ -23,7 +23,7 @@
23
23
  import { existsSync, readFileSync } from 'node:fs';
24
24
  import { join } from 'node:path';
25
25
  import { PACKAGE_ROOT } from './studio.mjs';
26
- import { DESKTOP_APPROVALS, StudioContext, UI, availability, inDesktopApp, toolDefs } from './mcp-tools.mjs';
26
+ import { DESKTOP_APPROVALS, StudioContext, UI, availability, hostedHere, inDesktopApp, toolDefs } from './mcp-tools.mjs';
27
27
  import { stopAllJobs, toolPath } from './jobs.mjs';
28
28
  import { shrinkPictureData } from './pictures.mjs';
29
29
  import { STUDIO_VERSION } from './version.mjs';
@@ -56,8 +56,20 @@ Telling Homie (homie_feedback): when the person is stuck, confused or frustrated
56
56
 
57
57
  Long work (npm install, check, playtest, deploy, renders) runs in the background: the tool answers at once with a card that follows it, and build_progress or studio_job reads where it is. studio_guide has Homie's full guide for each job (game, plan, port, playtest, publish, music, sound, art, video). Never put a key or password in a file or the chat. If Homie's homie.rocks connector is connected too, its tools of the same names say what to run; these run it.`;
58
58
 
59
+ /**
60
+ * In a hosted workspace (mcp-tools.mjs hostedHere), the paragraphs about this computer's setup, sign-ins, the
61
+ * person's own domain, payments setup, the Game Lab and standalone builds give way to one about the host.
62
+ */
63
+ export const HOSTED_INSTRUCTIONS = 'This toolkit runs in a workspace the studio\'s host made for it, away from the person\'s screen: the studio is already made and online with the host, and its sign-ins, domains, payments and webhooks are the host\'s, so the tools for those are not offered here. Build the requested thing and check it. preview_run puts the build on the studio\'s private preview and gives its link; check and playtest run there with a browser in the cloud. Only when going live was requested, studio_deploy puts it live (the host decides who may).';
64
+ const HOSTED_DROPS = [/^Run setup_status /, /^Show progress briefly/, /^For a shop, /, /^For a custom domain /, /^If studio_scaffold finds /, /^A studio made elsewhere /, /^To make one mechanic /, /^A game as an app of its own /];
65
+ export function hostedInstructions(text = INSTRUCTIONS) {
66
+ const paragraphs = text.split('\n');
67
+ const at = paragraphs.findIndex((p) => HOSTED_DROPS[0].test(p));
68
+ const kept = paragraphs.map((p, i) => (i === at ? HOSTED_INSTRUCTIONS : HOSTED_DROPS.some((d) => d.test(p)) ? null : p)).filter((p) => p !== null);
69
+ return kept.join('\n').replace(/\n{3,}/g, '\n\n');
70
+ }
59
71
  /** What the server tells the model as it connects: the checklist, and in the Claude desktop app what it asks the person. */
60
- export const instructionsFor = ({ desktop = false } = {}) => (desktop ? `${INSTRUCTIONS}\n\n${DESKTOP_APPROVALS}` : INSTRUCTIONS);
72
+ export const instructionsFor = ({ desktop = false, hosted = false } = {}) => { const base = hosted ? hostedInstructions() : INSTRUCTIONS; return desktop ? `${base}\n\n${DESKTOP_APPROVALS}` : base; };
61
73
 
62
74
  const CARD_FILES = { [UI.setup]: 'setup.js', [UI.build]: 'build.js', [UI.studio]: 'studio.js', [UI.codex]: 'codex.js', [UI.lab]: 'lab.js', [UI.style]: 'style.js', [UI.decision]: 'decision.js', [UI.cast]: 'cast.js', [UI.lineup]: 'lineup.js', [UI.rights]: 'rights.js', [UI.animation]: 'animation.js', [UI.feedback]: 'feedback.js' };
63
75
  const CARD_TITLES = { [UI.setup]: 'Studio setup', [UI.build]: 'Build progress', [UI.studio]: 'Studio', [UI.codex]: 'Game Codex', [UI.lab]: 'Game Lab', [UI.style]: 'Style board', [UI.decision]: 'Look decision', [UI.cast]: 'Cast', [UI.lineup]: 'Lineup', [UI.rights]: 'Rights', [UI.animation]: 'Clips', [UI.feedback]: 'Tell Homie' };
@@ -173,7 +185,7 @@ export async function serveMcp({ studios = null, skills = null, cwd = process.cw
173
185
  protocolVersion: PROTOCOLS.includes(asked) ? asked : PROTOCOLS[0],
174
186
  capabilities: { tools: { listChanged: true }, resources: { listChanged: false }, prompts: { listChanged: false } },
175
187
  serverInfo: { name: 'homie-studio', title: 'Homie Studio', version: STUDIO_VERSION },
176
- instructions: instructionsFor({ desktop: ctx.desktop }),
188
+ instructions: instructionsFor({ desktop: ctx.desktop, hosted: hostedHere() }),
177
189
  });
178
190
  }
179
191
  case 'ping': return reply({});
@@ -4554,6 +4554,48 @@
4554
4554
  }
4555
4555
  }
4556
4556
  }
4557
+ },
4558
+ "0.58.13": {
4559
+ "files": {
4560
+ "CLAUDE.md": "ddf2b2a0376202f6",
4561
+ "README.md": "684b3cca8001673c",
4562
+ "HANDOFF.md": "29337e2ace95b2e7",
4563
+ "games/README.md": "5ad32fe80c61f117",
4564
+ "music/README.md": "a3dc042dadd39df8",
4565
+ "videos/README.md": "16babc3437d5545b",
4566
+ "posts/README.md": "37841aae476bd540",
4567
+ "site/README.md": "1dbdf22c03a1e505",
4568
+ "site/src/worker.mjs": "6cc5c6131eaf6fd0"
4569
+ },
4570
+ "sections": {
4571
+ "AGENTS.md": {
4572
+ "(intro)": "af7f2f732505d379",
4573
+ "## Version-matched authoring guides": "f6261a0e5801b96b",
4574
+ "## Layout": "f3a280b8c96cd068",
4575
+ "## Apps: one screen, roles and parts": "c10aa0441ea89702",
4576
+ "## Commands (all through the pinned CLI in node_modules)": "c20d90de21cde0c7",
4577
+ "## The site": "0cb8dd9a6f8a0096",
4578
+ "## Making games": "bb715272fd1a615b",
4579
+ "## The Game Codex and progress": "0738ef719cef3a4c",
4580
+ "## Art direction and models": "a48fff7bf0a5f2fc",
4581
+ "## Running live games (the back office)": "51ebf2ab756f6e4d",
4582
+ "## Servers and AI seats": "1ccfd549d2369a60",
4583
+ "## Selling things (the shop)": "0df5a5fe1833c624",
4584
+ "## Continuing a build from the Claude app": "0d68081e924ca419",
4585
+ "## Rules": "b2234d80f6cbe71d",
4586
+ "## Telling Homie": "80b46fdd9e578db8",
4587
+ "## Beta": "9d02638207a26e73"
4588
+ }
4589
+ },
4590
+ "named": {
4591
+ "Homie Arcade": {
4592
+ "sections": {
4593
+ "AGENTS.md": {
4594
+ "## Commands (all through the pinned CLI in node_modules)": "8364e05cebefcba4"
4595
+ }
4596
+ }
4597
+ }
4598
+ }
4557
4599
  }
4558
4600
  }
4559
4601
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homie-rocks/studio",
3
- "version": "0.58.11",
3
+ "version": "0.58.13",
4
4
  "description": "A studio for games, music and video on its own Cloudflare: scaffold, multiplayer starters on the netplay contract, a port toolkit that makes existing single-player web games multiplayer, the site Worker with public rooms (Table/Lobby Durable Objects and D1, all on the free Workers plan, no payment method), a site with the hub's sections (Home, Games, Music, Videos, Rooms, Posts with feeds) in the studio's own look, an epic landing page for every game, big songs and videos in the studio's own R2 once it has storage (uploaded, checked by SHA-256, served at the same addresses), deploy, and the homie.rocks directory.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -1,2 +1,2 @@
1
1
  // Generated by lib/build-identity.mjs; identifies the bundled runtime sources.
2
- export const STUDIO_BUILD = Object.freeze({"version":"0.58.11","sha256":"4b6a276c704c1647234dfdbef1628bff5ade43b918653552b493965a2db72f9b"});
2
+ export const STUDIO_BUILD = Object.freeze({"version":"0.58.13","sha256":"9967c5676e36a715a20363398c63d98a28510e203e0b25523effa77a7cb8081f"});
@@ -1,2 +1,2 @@
1
1
  /** The @homie-rocks/studio version this Worker code is (package.json's; a test keeps them equal). Cache-busts /_homie/site.js. */
2
- export const STUDIO_VERSION_TAG = '0.58.11';
2
+ export const STUDIO_VERSION_TAG = '0.58.13';