From 83953e5b3b495c8d741b0b000814e151689077b3 Mon Sep 17 00:00:00 2001 From: Jack Arturo Date: Tue, 15 Sep 2026 05:32:39 +0200 Subject: [PATCH 1/2] docs: link repository and public demo --- README.md | 21 ++++++++++++++++++--- src/town.html | 5 ++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 99b7e6e..82e82ac 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,10 @@ CottageCode is a local townmap for agent fleets. Walk up to a cottage, lift its Point it at any URL that returns cottages as JSON, or explore the built-in demo. Projects become towns (`HubTown`, `MemTown`, or `{Stem}Town` from a folder name). Townmap is the atlas view. **[Visit the public sample village](https://autojack.ai/cottagecode/)** — walk, -explore, and try a practice reply with fictional residents. No live task data is -connected. [Build or publish your own demo](docs/PUBLIC_DEMO.md). +explore, and try a practice reply with fictional residents. It is a static, +browser-only build: live feeds, task routes, and private local data are +disabled, and practice replies affect only that sample village in your browser. +[Build or publish your own demo](docs/PUBLIC_DEMO.md). Zero npm dependencies. Pixel canvas, native browser modules, and a small Node server. @@ -30,7 +32,14 @@ npm start Open [http://localhost:8787](http://localhost:8787). For the built-in demo town only: [http://localhost:8787/?demo=1](http://localhost:8787/?demo=1). -Run the checks with `npm test`. With the Browser Hand CLI and Chrome extension available, `npm run test:browser` exercises the playable journey against a temporary local fixture feed. +Run the Node suite with `npm test`. The optional real-Chrome journeys need the +Browser Hand CLI and its Chrome extension: + +```bash +npm run test:browser # walking, rooms, PR desk, activity, input, and recovery +npm run test:ambience # gramophone, light, and locally rendered postcards +npm run test:night # night palette, bedtime scenery, and visiting a host +``` ## 🚪 Visit a cottage @@ -60,6 +69,12 @@ leaving the tab pauses it. Open **Gramophone & light** to set the volume or preview morning, day, dusk, and night. Warm windows and fireflies follow the same clock. No geographic location is requested. [Soundtrack and credits](docs/MUSIC.md). +Dusk and night use a desaturated, Game Boy Color-inspired blue palette. From +18:30, residents gather their recorded child agents and chickens before bed; +nonworking hosts sleep while working hosts remain at the bench. This is visual +scenery only: it never changes task status or prevents you from visiting or +talking to a resident. + **Make a postcard** in any cottage's inspector previews a PNG of its seeded interior and resident. It starts with no work details. You can choose one recorded milestone, review the picture, and save it. The image is made locally diff --git a/src/town.html b/src/town.html index d5b655c..520b75c 100644 --- a/src/town.html +++ b/src/town.html @@ -21,6 +21,9 @@ header{display:flex;flex-wrap:wrap;align-items:baseline;gap:10px 16px} h1{font-family:"Silkscreen",monospace;font-size:22px;font-weight:700;margin:0;line-height:1.1} + .brand-link{color:inherit;text-decoration:none} + .brand-link:hover{text-decoration:underline} + .brand-link:focus-visible{outline:3px solid #ffd166;outline-offset:3px} .sub{color:var(--ink-dim);font-size:13px;margin:0} .tally{display:flex;flex-wrap:wrap;gap:6px;margin-left:auto} @@ -211,7 +214,7 @@
-

CottageCode

+

CottageCode

Every cottage is one agent. Smoke means it's working.

From f61ab334fe9b45e2927f7521c451b912f7e76175 Mon Sep 17 00:00:00 2001 From: Jack Arturo Date: Tue, 15 Sep 2026 05:42:48 +0200 Subject: [PATCH 2/2] fix(village): retain done marker after bedtime --- scripts/browser-night-smoke.mjs | 6 ++++-- src/town.mjs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/browser-night-smoke.mjs b/scripts/browser-night-smoke.mjs index 729d70d..4fd99a4 100644 --- a/scripts/browser-night-smoke.mjs +++ b/scripts/browser-night-smoke.mjs @@ -10,6 +10,7 @@ const pr={number:123,url:'https://github.com/example/cottage/pull/123',state:'op let agents=[ {id:'night-host',taskId:'night-task',name:'Night Owl',town:'HubTown',status:'working',pr}, {id:'night-sleeper',taskId:'quiet-task',name:'Sleepy',town:'HubTown',status:'idle',originalAsk:'A recorded request remains accessible after bedtime.',pr:{state:'none',source:'browser-fixture',checkedAt:stamp}}, + {id:'night-done',taskId:'complete-task',name:'Finished Finch',town:'HubTown',status:'done',pr}, {id:'night-kid',name:'Pip',parent:'night-host',town:'HubTown',status:'working',pr}, ]; const server=createFeedServer({snapshot:()=>({agents,source:'browser-fixture',checkedAt:Date.now()})}).listen(0,'127.0.0.1'); @@ -30,9 +31,9 @@ function pass(label){process.stdout.write('PASS '+label+'\n');} const samples=()=>evaluate(`(()=>{ const c=document.getElementById('town'),ctx=c.getContext('2d'),s=window.cottageState();let total=[0,0,0],n=0; for(let y=16;yp.id==='night-host'),q=s.plots.find(p=>p.id==='night-sleeper'); + const p=s.plots.find(p=>p.id==='night-host'),q=s.plots.find(p=>p.id==='night-sleeper'),r=s.plots.find(p=>p.id==='night-done'); const pixel=(x,y)=>Array.from(ctx.getImageData(x,y,1,1).data).slice(0,3); - return {mean:total.map(v=>v/n),working:pixel(p.x+13,p.y+43),sleeping:pixel(q.x+13,q.y+43),pr:pixel(p.x-9,p.y+54)}; + return {mean:total.map(v=>v/n),working:pixel(p.x+13,p.y+43),sleeping:pixel(q.x+13,q.y+43),done:pixel(r.x+47,r.y+22),pr:pixel(p.x-9,p.y+54)}; })()`); try{ await browser('open',['--url','http://127.0.0.1:'+server.address().port]); @@ -51,6 +52,7 @@ try{ assert.ok(luminance(dark.mean)dark.mean[1]&&dark.mean[1]>dark.mean[0]); assert.ok(dark.working[0]>dark.working[2]*1.5&&luminance(dark.working)>luminance(dark.sleeping)*2); + assert.deepEqual(dark.done,[121,194,95],'completed residents retain a green status marker after settling'); assert.deepEqual(dark.pr,daylight.pr,'PR readiness color must survive the palette'); pass('actual night pixels are darker and blue, working windows warm, PR colors unchanged, families tucked in'); await click('.cottage-directory > summary');await click('[data-cottage="night-sleeper"]');await click('[data-action="enter"]'); diff --git a/src/town.mjs b/src/town.mjs index 62c4efc..a9b5db9 100644 --- a/src/town.mjs +++ b/src/town.mjs @@ -1624,7 +1624,7 @@ function draw(){ for(const p of plots){ ctx.globalAlpha=(filter&&filter!==townKey(p.agent))||!observatory?.visible(p.agent)?0.3:1; observatory?.drawDispatch(ctx,p,t); - if(bedtimeFrames.get(p.agent.id)?.settled&&p.agent.status==='blocked')drawBubble(p.x+47,p.y+22,'blocked'); + if(bedtimeFrames.get(p.agent.id)?.settled&&['blocked','done'].includes(p.agent.status))drawBubble(p.x+47,p.y+22,p.agent.status); for(const kid of p.kids||[])if(['blocked','done'].includes(kid.agent.status)){ px(kid.x+6,kid.y-3,5,5,C.outline);px(kid.x+7,kid.y-2,3,3,kid.agent.status==='blocked'?C.alert:C.ok); }