@homie-rocks/studio 0.51.0 → 0.51.2
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 +32 -0
- package/README.md +15 -4
- package/bin/homie-studio.mjs +7 -7
- package/guides/app/SKILL.md +14 -0
- package/guides/game/RULES.md +26 -0
- package/guides/office/SKILL.md +9 -0
- package/guides/studio-setup/SKILL.md +9 -1
- package/lib/app-preset-history.json +840 -0
- package/lib/build.mjs +4 -2
- package/lib/cloudflare.mjs +19 -10
- package/lib/dev.mjs +1 -1
- package/lib/directory.mjs +22 -5
- package/lib/giving-preset.mjs +9 -0
- package/lib/mcp-tools.mjs +1 -1
- package/lib/office.mjs +2 -1
- package/lib/scaffold.mjs +7 -4
- package/lib/shop.mjs +2 -1
- package/lib/template-history.json +90 -0
- package/lib/upgrade-app-presets.mjs +49 -0
- package/lib/upgrade.mjs +2 -1
- package/mcp/ui/build.js +3 -2
- package/package.json +1 -1
- package/rules/correction-path.ts +35 -0
- package/rules/map-index.ts +4 -4
- package/rules/view.ts +196 -28
- package/site/SITE.md +13 -0
- package/tools/TOOLS.md +9 -0
- package/worker/arrival.mjs +2 -1
- package/worker/build-id.mjs +1 -1
- package/worker/directory-choice.mjs +9 -0
- package/worker/index.mjs +18 -9
- package/worker/mcp.mjs +2 -2
- package/worker/pages.mjs +3 -2
- package/worker/records-page.mjs +1 -1
- package/worker/signin-target.mjs +8 -0
- package/worker/site.mjs +2 -0
- package/worker/stats-page.mjs +6 -3
- package/worker/version.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,38 @@ 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.51.2] - 2026-10-14
|
|
21
|
+
|
|
22
|
+
**Plugin 0.51.2** · Deploying and listing do what the studio chose, under one address.
|
|
23
|
+
|
|
24
|
+
Your studio follows your listing choice, shares one public address, and keeps its apps and tools working after deploy and upgrade.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- Your studio only joins the directory when you choose to list it. Existing claims remain honoured, and you can publish a listing after an unlisted deploy.
|
|
29
|
+
- Your custom domain is the shared address for pages and app links. Visitors arriving at the workers.dev address reach that domain, while app APIs, multiplayer connections and AI tools keep working.
|
|
30
|
+
- Deploy shows your app, game and wall links without guessing your bill. Local database tools keep working after deploy, interrupted setup can resume, and office sign-in takes you straight to the page you requested.
|
|
31
|
+
- Upgrades refresh untouched app presets and defaults while preserving your edits, including giving choices. App walls use the app's own join wording.
|
|
32
|
+
- Decorative app hero frames let visitors scroll the page; apps can share and download files while keeping their sandbox protection.
|
|
33
|
+
- Signed-in AI connectors can discover how to connect through `/mcp/auth`; public tools remain available through `/mcp`.
|
|
34
|
+
|
|
35
|
+
### Upgrade notes
|
|
36
|
+
|
|
37
|
+
- Ask Homie to upgrade your studio, install dependencies and rebuild. Existing directory claims remain honoured. To list a new studio, choose `homie.directory: true` or a directory URL before deploy.
|
|
38
|
+
- Use `/mcp/auth` for staff AI connectors and `/mcp` for public connectors.
|
|
39
|
+
|
|
40
|
+
## [0.51.1] - 2026-10-14
|
|
41
|
+
|
|
42
|
+
**Plugin 0.51.1** · A player's own runner never jumps across the screen.
|
|
43
|
+
|
|
44
|
+
Your platformer keeps a player's runner moving smoothly through network corrections and reconnects, with less work per frame on slower phones.
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- In server-rules platformers, a player's own box-shaped 2D runner now moves smoothly through network corrections, even after a delayed frame. It goes around blocking platforms without being pulled backwards against the player's held direction, and normal jumps keep their shape.
|
|
49
|
+
- After a dropped connection, the runner glides from its last visible position to where the server moved it. Real respawns and other deliberate placements still happen immediately; games can identify placements made during an outage with `respawned`.
|
|
50
|
+
- Rules games do less repeated movement, collision and drawing preparation each frame, helping play stay smooth on slower phones. These changes preserve the server's movement, hits and scoring.
|
|
51
|
+
|
|
20
52
|
## [0.51.0] - 2026-10-14
|
|
21
53
|
|
|
22
54
|
**Plugin 0.51.0** · Take the money through your own Stripe, keyless by default.
|
package/README.md
CHANGED
|
@@ -110,10 +110,21 @@ is put in a studio unless the person asks for one), and its Home has a
|
|
|
110
110
|
In the session that works in the repository, `homie-studio setup attach <hs_…> [--client claude|codex|grok]` then gives the studio
|
|
111
111
|
the name chosen in the chat and removes the band.
|
|
112
112
|
|
|
113
|
-
**
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
**Listing is the studio’s choice.** Set `homie.directory: true` for homie.rocks or a
|
|
114
|
+
chosen directory URL before deploying. Omitted, null or false makes no new claim;
|
|
115
|
+
existing stored claims remain honoured. An explicit `publish` also records the choice
|
|
116
|
+
and stores the directory claim without requiring a second deploy. The manifest and
|
|
117
|
+
publish use the custom domain when configured. Workers.dev browser pages redirect to
|
|
118
|
+
it; discovery and tool routes remain accessible on both addresses.
|
|
119
|
+
|
|
120
|
+
Deploy prints `/<id>/open` for apps, `/<id>/play` for games and `/<id>/tv` for walls.
|
|
121
|
+
It reports no unmeasured Cloudflare plan. Local tools retain their dev database binding
|
|
122
|
+
after the first deploy. Rerunning an interrupted `new` fills missing files without
|
|
123
|
+
overwriting the matching studio’s edits. Office links sign in directly and retain
|
|
124
|
+
`--to` destinations, including app and connection pages.
|
|
125
|
+
|
|
126
|
+
For signed-in staff AI connectors use `/mcp/auth`; it returns a 401 OAuth discovery
|
|
127
|
+
challenge without a token. `/mcp` continues to serve public tools anonymously.
|
|
117
128
|
|
|
118
129
|
## The site: the hub's shape, and a landing for every game
|
|
119
130
|
|
package/bin/homie-studio.mjs
CHANGED
|
@@ -507,25 +507,25 @@ function print(result) {
|
|
|
507
507
|
lines.push(JSON.stringify(result.result, null, 2));
|
|
508
508
|
break;
|
|
509
509
|
case 'deploy':
|
|
510
|
-
if (result.mcp) lines.push(`Connect your AI: ${result.mcp} (approve in your studio's browser page; no key)`);
|
|
510
|
+
if (result.mcp) lines.push(`Connect your AI: ${result.mcp}/auth (approve in your studio's browser page; no key)`);
|
|
511
511
|
if (result.ci) {
|
|
512
|
-
lines.push(`Live: ${result.url ?? '(Wrangler printed no address)'}${result.commit ? ` (commit ${result.commit.slice(0, 7)}${result.branch ? ` on ${result.branch}` : ''})` : ''}`, ...result.steps.map((x) => ` ${x.what}`), ...result.games.map((g) => ` ${g.id}: ${g.play}${g.hash ? ` [${deployWords(g)}]` : ''}`));
|
|
512
|
+
lines.push(`Live: ${result.url ?? '(Wrangler printed no address)'}${result.commit ? ` (commit ${result.commit.slice(0, 7)}${result.branch ? ` on ${result.branch}` : ''})` : ''}`, ...result.steps.map((x) => ` ${x.what}`), ...result.games.map((g) => ` ${g.id}: ${g.open ?? g.play}${g.hash ? ` [${deployWords(g)}]` : ''}${g.wall ? ` wall: ${g.wall}` : ''}`));
|
|
513
513
|
break;
|
|
514
514
|
}
|
|
515
515
|
lines.push(`Live: ${result.url}`, ...(result.workersDev && result.workersDev !== result.url ? [` also at ${result.workersDev}`] : []),
|
|
516
516
|
...(result.local ? [` (the workers.dev address names your Cloudflare account, so it is kept in ${result.local} on this computer, never in studio.json)`] : []),
|
|
517
517
|
// Which games this deploy changed since the last deploy from here, and each one's build hash
|
|
518
518
|
// (lib/deploy-state.mjs): the hash `build` printed and the one the live site's manifest answers with.
|
|
519
|
-
...result.games.map((g) => ` ${g.id}: ${g.play}${g.hash ? ` [${deployWords(g)}]` : ''}`), ...(result.removed?.length ? [` no longer on the site: ${result.removed.join(', ')}`] : []), ...(result.notes ?? []).map((n) => ` Note: ${n}`), ...(result.songs ?? []).map((m) => ` song ${m.slug}: ${m.page}`), ...(result.videos ?? []).map((m) => ` video ${m.slug}: ${m.page}`),
|
|
520
|
-
...(result.media?.moved ?? []).map((m) => ` moved to R2 (checked by SHA-256): ${m.path}, still at ${m.url}`), ...(result.media?.failed ?? []).map((m) => ` not moved to R2: ${m.path}: ${m.why}`), '', `Cloudflare: Worker ${result.worker}, D1 ${result.d1}, Durable Objects Table + Lobby${result.r2 ? `, R2 ${result.r2}` : ' (no storage: none needed; `homie-studio storage add` adds it for large media)'}
|
|
521
|
-
result.claim ? 'The site claimed itself in the directory: list the games with the Homie MCP tool studio_publish, or: npx --no-install homie-studio publish' : 'No directory claim
|
|
519
|
+
...result.games.map((g) => ` ${g.id}: ${g.open ?? g.play}${g.hash ? ` [${deployWords(g)}]` : ''}${g.wall ? ` wall: ${g.wall}` : ''}`), ...(result.removed?.length ? [` no longer on the site: ${result.removed.join(', ')}`] : []), ...(result.notes ?? []).map((n) => ` Note: ${n}`), ...(result.songs ?? []).map((m) => ` song ${m.slug}: ${m.page}`), ...(result.videos ?? []).map((m) => ` video ${m.slug}: ${m.page}`),
|
|
520
|
+
...(result.media?.moved ?? []).map((m) => ` moved to R2 (checked by SHA-256): ${m.path}, still at ${m.url}`), ...(result.media?.failed ?? []).map((m) => ` not moved to R2: ${m.path}: ${m.why}`), '', `Cloudflare: Worker ${result.worker}, D1 ${result.d1}, Durable Objects Table + Lobby${result.r2 ? `, R2 ${result.r2}` : ' (no storage: none needed; `homie-studio storage add` adds it for large media)'}.`,
|
|
521
|
+
result.claim ? 'The site claimed itself in the directory: list the games with the Homie MCP tool studio_publish, or: npx --no-install homie-studio publish' : 'No directory claim. Listing is the studio’s choice: set homie.directory to true or a directory URL before deploying to request one.',
|
|
522
522
|
...(result.standalone?.length ? ['', ...result.standalone] : []));
|
|
523
523
|
break;
|
|
524
524
|
case 'deploy plan':
|
|
525
525
|
lines.push(`What \`npm run deploy\` does for ${result.studio}, on the Cloudflare account the person approves:`, '',
|
|
526
526
|
...result.cloudflare.map((r) => ` ${r.kind}${r.name ? ` ${r.name}` : ''}: ${r.what} [${r.state}${r.plan ? `; ${r.plan}` : ''}]`), '',
|
|
527
|
-
`Cost: ${result.cost}
|
|
528
|
-
`The directory (${result.directory.site}) stores: ${result.directory.stores}
|
|
527
|
+
...(result.cost ? [`Cost: ${result.cost}`] : []), `Sign-in: ${result.login}`, `Address: ${result.address}`,
|
|
528
|
+
result.directory.choice, ...(result.directory.site ? [`The directory (${result.directory.site}) stores: ${result.directory.stores}`] : []), result.never,
|
|
529
529
|
...(result.zone?.warning ? ['', `Warning: ${result.zone.warning}`] : result.zone?.why ? ['', result.zone.why] : []),
|
|
530
530
|
...(result.parts && partsPlanLines(result.parts).length ? ['', ...partsPlanLines(result.parts)] : []),
|
|
531
531
|
...(result.standalone?.length ? ['', ...result.standalone] : []));
|
package/guides/app/SKILL.md
CHANGED
|
@@ -268,3 +268,17 @@ Use the Manage my gifts link for the buyer-owned Stripe portal in the shop.
|
|
|
268
268
|
For a records-only booking app, use `createShop({target: parent})` inside its
|
|
269
269
|
sandboxed view. The shell includes the authenticated shop bridge; do not add a
|
|
270
270
|
room simulation merely to make a payment button work.
|
|
271
|
+
|
|
272
|
+
## Frames and upgrades (0.51.1)
|
|
273
|
+
|
|
274
|
+
App frames permit Web Share and downloads, while keeping their opaque-origin
|
|
275
|
+
sandbox. Share still requires the guest’s click and browser support; offer a download
|
|
276
|
+
or copy link too. Both the iframe permissions and the served frame’s CSP matter.
|
|
277
|
+
Use `.hero-media` for a decorative iframe in a site hero: it lets scroll gestures
|
|
278
|
+
reach the page. An intentionally interactive hero frame opts in with `data-interactive`.
|
|
279
|
+
App shells allow normal touch scrolling and selection.
|
|
280
|
+
|
|
281
|
+
Upgrade compares copied app presets with recorded toolkit versions. Unchanged
|
|
282
|
+
preset files and default values take the new version; custom scene files, names and
|
|
283
|
+
edited labels remain the studio’s. An app wall uses its join label rather than game
|
|
284
|
+
instructions. Rebuild after upgrade and inspect both the wall and giving page.
|
package/guides/game/RULES.md
CHANGED
|
@@ -1443,3 +1443,29 @@ catch-up path. It resumes live prediction at once and carries the drawn pose int
|
|
|
1443
1443
|
the normal correction blend, so a counter-dash or jump does not wait for the
|
|
1444
1444
|
unseen impulse's history to finish. This changes drawing only; authority, input
|
|
1445
1445
|
timestamps, cooldowns and replay rules are unchanged.
|
|
1446
|
+
|
|
1447
|
+
Own box-bodied 2D presentation also sweeps from its last displayed position. Reconciliation
|
|
1448
|
+
cannot switch sides of a solid merely because the new predicted origin is on
|
|
1449
|
+
the other side. Travel is limited by elapsed time plus a body-sized blend. Horizontal travel uses the adjacent
|
|
1450
|
+
actual velocities; vertical travel uses the recorded substeps with interpolation headroom, so an apex or landing is not trimmed.
|
|
1451
|
+
A stationary correction spends only blend speed, not the declared terminal falling speed.
|
|
1452
|
+
A large falling-speed limit cannot accelerate a horizontal correction. If sliding cannot reach a correction, a bounded
|
|
1453
|
+
incremental route searches collision-tested edges around the obstruction. No
|
|
1454
|
+
route means holding the last valid position, never crossing a solid. Explicit
|
|
1455
|
+
placements and epoch changes reset presentation immediately. These positions
|
|
1456
|
+
never feed movement, hits, scoring, input timestamps, or authority.
|
|
1457
|
+
|
|
1458
|
+
A platformer can supply `openRoom({ correctionDirection: input => Number(input.r || 0) - Number(input.l || 0) })`
|
|
1459
|
+
for box-bodied 2D presentation. This is horizontal control intent (-1, 0, +1), not authority or a second movement loop.
|
|
1460
|
+
It prevents a visual correction from reversing held controls even when contact sets velocity to zero; neutral input
|
|
1461
|
+
allows convergence in either direction. Actual predicted braking against a newly reversed control remains allowed.
|
|
1462
|
+
|
|
1463
|
+
After a delayed render, box-bodied 2D presentation spends at most 1.4 body widths per drawn frame,
|
|
1464
|
+
then continues toward prediction. This affects drawing only; an explicit placement remains immediate.
|
|
1465
|
+
|
|
1466
|
+
When a player's connection comes back, the server hands the body back where it has it, with a new placement
|
|
1467
|
+
revision. Within three seconds of the link coming back online, box-bodied 2D presentation treats that revision as the
|
|
1468
|
+
same body and draws on from where it was shown, gliding and routing around solids as for any correction. A body that
|
|
1469
|
+
was really placed while the player was away (a respawn, a new round) should still be drawn at once: say so with
|
|
1470
|
+
`openRoom({ respawned: (before, after) => after.diedAt !== before.diedAt })`, where `before` and `after` are the own
|
|
1471
|
+
body as the server last had it before and after the outage.
|
package/guides/office/SKILL.md
CHANGED
|
@@ -147,3 +147,12 @@ Before Stripe is connected, both live and local shop/giving pages show items and
|
|
|
147
147
|
amounts with checkout disabled and clear not-taking-payment wording. A fresh studio
|
|
148
148
|
has an empty `/shop/` preview. `dev` watches authoring HTML/CSS/JS; check reports
|
|
149
149
|
accepted dialogs and precise waits, and reacquires frames during rebuilds.
|
|
150
|
+
|
|
151
|
+
## Direct sign-in links (0.51.1)
|
|
152
|
+
|
|
153
|
+
`office link --to /<app>/open` and `--to /_studio/office/connections` retain the
|
|
154
|
+
same-site destination, including its query string. Opening the link signs the browser
|
|
155
|
+
in and continues there. A plain link-preview GET spends nothing; the loaded page
|
|
156
|
+
submits the same-origin sign-in form. Keep the link private.
|
|
157
|
+
Local office and role commands reuse the running dev server’s D1 configuration even
|
|
158
|
+
after deploy records the production database id.
|
|
@@ -338,7 +338,7 @@ existing Cloudflare sign-in to create DNS and TLS. Never ask the person for a zo
|
|
|
338
338
|
or wildcard route already on that domain belongs to another site there, and the deploy's warning gives the
|
|
339
339
|
one line to add instead (the `publish` skill has the rest).
|
|
340
340
|
|
|
341
|
-
**The directory, only when asked.**
|
|
341
|
+
**The directory, only when asked.** A deploy never opts a studio in by itself: listing in the homie.rocks directory
|
|
342
342
|
is its own step, it is public, and it is the person's to ask for. When they asked to be listed (in their first
|
|
343
343
|
message or now), or say yes when you offer it once the site is live, call the Homie MCP tool `studio_publish`
|
|
344
344
|
with the live site address (without the connector, `npx --no-install homie-studio publish`). It lists the
|
|
@@ -417,3 +417,11 @@ there (checked by SHA-256, at the same addresses); `homie-studio media move --dr
|
|
|
417
417
|
Every studio serves its own MCP at `<site>/mcp`. Use the `tools` skill for studio-defined business actions, signed integrations and staff AI access. Reuse office and app-record built-ins first. After an authorized deploy, hand over the MCP address and `<site>/_studio/office/connections`: the person approves with the studio account they already have, with no key to copy. Staff connect their own account and retain only their app grants. Client connector setup is separate from the studio approval. Never deploy merely to set up a local tool test.
|
|
418
418
|
|
|
419
419
|
For a business or cause, use `studio_scaffold {name, kind:"business"}` or `homie-studio new <folder> --kind cause`. Continue directly with the app skill and the appropriate `app new --from` starter; no game demo or planning interview unless requested.
|
|
420
|
+
|
|
421
|
+
## Resuming setup (0.51.1)
|
|
422
|
+
|
|
423
|
+
If `homie-studio new` was interrupted, rerun it in the same folder with the same name
|
|
424
|
+
and slug. It fills missing generated files and retries installation, preserving files
|
|
425
|
+
already there. A different studio or unrelated nonempty folder is still refused.
|
|
426
|
+
New studios do not request a directory listing by default; set `homie.directory: true`
|
|
427
|
+
or a directory URL only when the person chooses listing.
|