@homie-rocks/studio 0.58.18 → 0.58.20
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 +20 -0
- package/lib/template-history.json +84 -0
- package/lib/worker-config.mjs +14 -1
- package/package.json +5 -1
- package/worker/build-id.mjs +1 -1
- package/worker/function-schedule.d.ts +14 -0
- package/worker/version.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,26 @@ 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.20] - 2026-10-26
|
|
21
|
+
|
|
22
|
+
**Plugin 0.58.14**
|
|
23
|
+
|
|
24
|
+
An upgrade keeps a studio's game routes when nothing has been built yet.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- `homie-studio upgrade` in a fresh checkout (no `site/dist`, as on a new machine or a hosting platform's clone) no longer rewrites `wrangler.jsonc` without the studio's game routes (`/<game>`, `/<game>/*` and the static-asset exclusions). Without build output the Worker config keeps the routes the last build wrote; the next build still sets them from the games it finds.
|
|
29
|
+
|
|
30
|
+
## [0.58.19] - 2026-10-21
|
|
31
|
+
|
|
32
|
+
**Plugin 0.58.13**
|
|
33
|
+
|
|
34
|
+
A platform that runs a studio's scheduled ticks can use the worker's own cron parser.
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
- `@homie-rocks/studio/worker/schedule` exports the worker's own cron parser (`parseSchedule`, `nextDue`, with its types), Cloudflare's five-field UTC dialect, so a platform that runs a dispatch Worker's scheduled ticks schedules them as the studio's Cron Triggers would fire.
|
|
39
|
+
|
|
20
40
|
## [0.58.18] - 2026-10-21
|
|
21
41
|
|
|
22
42
|
**Plugin 0.58.12**
|
|
@@ -4722,6 +4722,90 @@
|
|
|
4722
4722
|
}
|
|
4723
4723
|
}
|
|
4724
4724
|
}
|
|
4725
|
+
},
|
|
4726
|
+
"0.58.19": {
|
|
4727
|
+
"files": {
|
|
4728
|
+
"CLAUDE.md": "ddf2b2a0376202f6",
|
|
4729
|
+
"README.md": "684b3cca8001673c",
|
|
4730
|
+
"HANDOFF.md": "29337e2ace95b2e7",
|
|
4731
|
+
"games/README.md": "5ad32fe80c61f117",
|
|
4732
|
+
"music/README.md": "a3dc042dadd39df8",
|
|
4733
|
+
"videos/README.md": "16babc3437d5545b",
|
|
4734
|
+
"posts/README.md": "37841aae476bd540",
|
|
4735
|
+
"site/README.md": "1dbdf22c03a1e505",
|
|
4736
|
+
"site/src/worker.mjs": "6cc5c6131eaf6fd0"
|
|
4737
|
+
},
|
|
4738
|
+
"sections": {
|
|
4739
|
+
"AGENTS.md": {
|
|
4740
|
+
"(intro)": "af7f2f732505d379",
|
|
4741
|
+
"## Version-matched authoring guides": "f6261a0e5801b96b",
|
|
4742
|
+
"## Layout": "f3a280b8c96cd068",
|
|
4743
|
+
"## Apps: one screen, roles and parts": "c10aa0441ea89702",
|
|
4744
|
+
"## Commands (all through the pinned CLI in node_modules)": "c20d90de21cde0c7",
|
|
4745
|
+
"## The site": "0cb8dd9a6f8a0096",
|
|
4746
|
+
"## Making games": "bb715272fd1a615b",
|
|
4747
|
+
"## The Game Codex and progress": "0738ef719cef3a4c",
|
|
4748
|
+
"## Art direction and models": "a48fff7bf0a5f2fc",
|
|
4749
|
+
"## Running live games (the back office)": "51ebf2ab756f6e4d",
|
|
4750
|
+
"## Servers and AI seats": "1ccfd549d2369a60",
|
|
4751
|
+
"## Selling things (the shop)": "0df5a5fe1833c624",
|
|
4752
|
+
"## Continuing a build from the Claude app": "0d68081e924ca419",
|
|
4753
|
+
"## Rules": "b2234d80f6cbe71d",
|
|
4754
|
+
"## Telling Homie": "80b46fdd9e578db8",
|
|
4755
|
+
"## Beta": "9d02638207a26e73"
|
|
4756
|
+
}
|
|
4757
|
+
},
|
|
4758
|
+
"named": {
|
|
4759
|
+
"Homie Arcade": {
|
|
4760
|
+
"sections": {
|
|
4761
|
+
"AGENTS.md": {
|
|
4762
|
+
"## Commands (all through the pinned CLI in node_modules)": "8364e05cebefcba4"
|
|
4763
|
+
}
|
|
4764
|
+
}
|
|
4765
|
+
}
|
|
4766
|
+
}
|
|
4767
|
+
},
|
|
4768
|
+
"0.58.20": {
|
|
4769
|
+
"files": {
|
|
4770
|
+
"CLAUDE.md": "ddf2b2a0376202f6",
|
|
4771
|
+
"README.md": "684b3cca8001673c",
|
|
4772
|
+
"HANDOFF.md": "29337e2ace95b2e7",
|
|
4773
|
+
"games/README.md": "5ad32fe80c61f117",
|
|
4774
|
+
"music/README.md": "a3dc042dadd39df8",
|
|
4775
|
+
"videos/README.md": "16babc3437d5545b",
|
|
4776
|
+
"posts/README.md": "37841aae476bd540",
|
|
4777
|
+
"site/README.md": "1dbdf22c03a1e505",
|
|
4778
|
+
"site/src/worker.mjs": "6cc5c6131eaf6fd0"
|
|
4779
|
+
},
|
|
4780
|
+
"sections": {
|
|
4781
|
+
"AGENTS.md": {
|
|
4782
|
+
"(intro)": "af7f2f732505d379",
|
|
4783
|
+
"## Version-matched authoring guides": "f6261a0e5801b96b",
|
|
4784
|
+
"## Layout": "f3a280b8c96cd068",
|
|
4785
|
+
"## Apps: one screen, roles and parts": "c10aa0441ea89702",
|
|
4786
|
+
"## Commands (all through the pinned CLI in node_modules)": "c20d90de21cde0c7",
|
|
4787
|
+
"## The site": "0cb8dd9a6f8a0096",
|
|
4788
|
+
"## Making games": "bb715272fd1a615b",
|
|
4789
|
+
"## The Game Codex and progress": "0738ef719cef3a4c",
|
|
4790
|
+
"## Art direction and models": "a48fff7bf0a5f2fc",
|
|
4791
|
+
"## Running live games (the back office)": "51ebf2ab756f6e4d",
|
|
4792
|
+
"## Servers and AI seats": "1ccfd549d2369a60",
|
|
4793
|
+
"## Selling things (the shop)": "0df5a5fe1833c624",
|
|
4794
|
+
"## Continuing a build from the Claude app": "0d68081e924ca419",
|
|
4795
|
+
"## Rules": "b2234d80f6cbe71d",
|
|
4796
|
+
"## Telling Homie": "80b46fdd9e578db8",
|
|
4797
|
+
"## Beta": "9d02638207a26e73"
|
|
4798
|
+
}
|
|
4799
|
+
},
|
|
4800
|
+
"named": {
|
|
4801
|
+
"Homie Arcade": {
|
|
4802
|
+
"sections": {
|
|
4803
|
+
"AGENTS.md": {
|
|
4804
|
+
"## Commands (all through the pinned CLI in node_modules)": "8364e05cebefcba4"
|
|
4805
|
+
}
|
|
4806
|
+
}
|
|
4807
|
+
}
|
|
4808
|
+
}
|
|
4725
4809
|
}
|
|
4726
4810
|
}
|
|
4727
4811
|
}
|
package/lib/worker-config.mjs
CHANGED
|
@@ -49,6 +49,19 @@ export function updateWorkerConfig(root,generated) {
|
|
|
49
49
|
const text='// Generated by homie-studio. Edit studio.json or wrangler.custom.json, then build.\n'+JSON.stringify(next,null,2)+'\n';
|
|
50
50
|
if(!existsSync(file)||readFileSync(file,'utf8')!==text) {const temp=`${file}.${process.pid}.tmp`;writeFileSync(temp,text);renameSync(temp,file);}
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* The Worker routes for the studio's games: the last build's catalogue (site/dist/games.json). Without build output (a
|
|
54
|
+
* fresh checkout, or an upgrade run before any build) there is no catalogue, so the routes the last build wrote into the
|
|
55
|
+
* Worker config are kept, with the toolkit's own routes, instead of dropping every game's route until the next build.
|
|
56
|
+
*/
|
|
57
|
+
export function workerRoutesOf(root) {
|
|
58
|
+
const catalogue=join(root,'site/dist/games.json');
|
|
59
|
+
if(existsSync(catalogue))return staticWorkerRoutes(read(catalogue));
|
|
60
|
+
const before=read(configPath(root)).assets?.run_worker_first;
|
|
61
|
+
if(before===true)return true;
|
|
62
|
+
const base=staticWorkerRoutes(null);
|
|
63
|
+
return Array.isArray(before)?[...new Set([...base,...before])]:base;
|
|
64
|
+
}
|
|
52
65
|
export function refreshWorkerConfig(root,overrides={}) {
|
|
53
66
|
const studio=readStudio(root),cf=studio.cloudflare;
|
|
54
67
|
if(!cf?.worker)return;
|
|
@@ -57,5 +70,5 @@ export function refreshWorkerConfig(root,overrides={}) {
|
|
|
57
70
|
const tools=read(join(root,'site/src/tools/declarations.json'));
|
|
58
71
|
const ai=cf.ai??listExperiences(root).some(g=>g.decide===true || g.chat!==false && (g.chat?.mode??'text')==='text' && g.chat?.ai!==false);
|
|
59
72
|
const paid=paidReleases(root).length>0||existsSync(join(root,'shop.json'))||tools.paid===true;
|
|
60
|
-
updateWorkerConfig(root,wranglerConfig({analytics:studio.stats?.analytics===true,workerRoutes:
|
|
73
|
+
updateWorkerConfig(root,wranglerConfig({analytics:studio.stats?.analytics===true,workerRoutes:workerRoutesOf(root),worker:cf.worker,name:studio.name,d1:cf.d1,d1Id:cf.d1Id,r2:cf.r2,layout:layoutOf(root),ai,paidParts:paid,partsRateLimit:cf.purchaseRateLimit??null,routes:cf.routes??null,eventFeeds:studio.mcp?.events,triggers:{crons:[scheduleTrigger(functions,{eventFeeds:Object.keys(studio.mcp?.events??{}).length>0})].filter(Boolean)},...overrides}));
|
|
61
74
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@homie-rocks/studio",
|
|
3
|
-
"version": "0.58.
|
|
3
|
+
"version": "0.58.20",
|
|
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",
|
|
@@ -85,6 +85,10 @@
|
|
|
85
85
|
"default": "./apps/apps.ts"
|
|
86
86
|
},
|
|
87
87
|
"./worker/selling": "./worker/selling/index.mjs",
|
|
88
|
+
"./worker/schedule": {
|
|
89
|
+
"types": "./worker/function-schedule.d.ts",
|
|
90
|
+
"default": "./worker/function-schedule.mjs"
|
|
91
|
+
},
|
|
88
92
|
"./tools": {
|
|
89
93
|
"types": "./tools/tools.ts",
|
|
90
94
|
"default": "./tools/tools.ts"
|
package/worker/build-id.mjs
CHANGED
|
@@ -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.
|
|
2
|
+
export const STUDIO_BUILD = Object.freeze({"version":"0.58.20","sha256":"8e8f40665f1f6a370f288217983318a04937be8ad2d51e80d0f52feb4cc3782d"});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** A five-field Cloudflare cron expression in UTC (Sunday = 1), parsed. */
|
|
2
|
+
export interface Schedule {
|
|
3
|
+
parts: string[];
|
|
4
|
+
fields: {values: number[]; special: string[]}[];
|
|
5
|
+
dayMatches(date: Date): boolean;
|
|
6
|
+
/** Whether the expression is due at this time (its UTC minute). */
|
|
7
|
+
matches(time: number): boolean;
|
|
8
|
+
}
|
|
9
|
+
/** Parse a cron expression; throws on one Cloudflare would refuse. */
|
|
10
|
+
export function parseSchedule(expression: string): Schedule;
|
|
11
|
+
/** The first time after `after` the expression is due, or null when it never is. */
|
|
12
|
+
export function nextDue(expression: string | Schedule, after?: number): number | null;
|
|
13
|
+
export function scheduleTrigger(definitions: {schedule?: string}[], options?: {eventFeeds?: boolean}): string | null;
|
|
14
|
+
export function scheduleStatus(definitions: {name: string; schedule?: string}[], crons: string[], now?: number): {function: string; schedule: string; nextDue: string | null; status: string}[];
|
package/worker/version.mjs
CHANGED
|
@@ -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.
|
|
2
|
+
export const STUDIO_VERSION_TAG = '0.58.20';
|