← Commit history

Publish 0.19.8

Colby Knox ·cbedb2b066 ·2mo ago ·parent c965dc8
4 files changed +15−7
package.json+1−1
@@ -2,7 +2,7 @@   "slug": "hero-studio",   "title": "Hero Studio",   "type": "app",-  "version": "0.19.7",+  "version": "0.19.8",   "description": "The hero-image lab with a human gate: `hero-studio pose <owner/slug>` opens the studio in front of the human, posed for their package, and blocks until they click Generate, producing the provenance-stamped 2000x1250 PNG the registry's hero gate requires. The image carries the title and artwork; the exported image also bakes the type pill (top right) and full wiki slug (bottom right); the page shows the hero bare, and only the homepage marquee overlays its own dynamic info. Adom-org pages get the house wordmark and palette automatically; every other owner brings their own accent and background colors, with placement fixed for all. The floating app window is the vitrine: it auto-loads a real screenshot from the package's wiki page (screenshots/, docs/), takes a manual import, or a full-hero import (the human-ratified re-stamp path for existing heroes). The pose gate opens in verification mode: per-item checklist (title, subtitle, vitrine, type match) and a Generate that unlocks only fully confirmed. Includes vitrine bleeds, brand tile themes, gradient angles, pixel-faithful wiki marquee and index-card previews, and a component-hero mode with a photo/raytrace/phong fallback ladder.",   "license": "MIT",   "tags": [
page.json+1−1
@@ -2,7 +2,7 @@   "slug": "hero-studio",   "title": "Hero Studio",   "type": "app",-  "version": "0.19.7",+  "version": "0.19.8",   "description": "The hero-image lab with a human gate: `hero-studio pose <owner/slug>` opens the studio in front of the human, posed for their package, and blocks until they click Generate, producing the provenance-stamped 2000x1250 PNG the registry's hero gate requires. The image carries the title and artwork; the exported image also bakes the type pill (top right) and full wiki slug (bottom right); the page shows the hero bare, and only the homepage marquee overlays its own dynamic info. Adom-org pages get the house wordmark and palette automatically; every other owner brings their own accent and background colors, with placement fixed for all. The floating app window is the vitrine: it auto-loads a real screenshot from the package's wiki page (screenshots/, docs/), takes a manual import, or a full-hero import (the human-ratified re-stamp path for existing heroes). The pose gate opens in verification mode: per-item checklist (title, subtitle, vitrine, type match) and a Generate that unlocks only fully confirmed. Includes vitrine bleeds, brand tile themes, gradient angles, pixel-faithful wiki marquee and index-card previews, and a component-hero mode with a photo/raytrace/phong fallback ladder.",   "license": "MIT",   "tags": [
public/js/wizard.js+1−1
@@ -397,7 +397,7 @@ function wizRenderReview(host) {    const checks = document.createElement('div');   checks.className = 'rv-col';-  const seasoned = (state.gatesDone || 0) >= 4;+  const seasoned = state.seasoned !== undefined ? !!state.seasoned : (state.gatesDone || 0) >= 4;   if (seasoned && !wizExpanded) {     const row = document.createElement('div');     row.className = 'rv-check ok';
server.js+12−4
@@ -328,14 +328,14 @@ async function fetchRemoteGates() {     const REG = process.env.ADOM_WIKI_REGISTRY || 'https://wiki.adom.inc';     const headers = {};     try { headers.Authorization = 'Bearer ' + fs.readFileSync('/var/run/adom/api-key', 'utf8').trim(); } catch {}-    const who = await fetch(REG + '/api/me', { headers }).then((r) => (r.ok ? r.json() : null)).catch(() => null);-    const handle = who && (who.name || who.handle || (who.user && (who.user.name || who.user.handle)));+    const who = await fetch(REG + '/auth/me', { headers }).then((r) => (r.ok ? r.json() : null)).catch(() => null);+    const handle = who && (who.username || who.name || who.handle || (who.user && (who.user.username || who.user.name || who.user.handle)));     if (!handle) return;     const r = await fetch(REG + '/api/users/' + handle + '/hero-gates', { headers });     if (!r.ok) return;     const d = await r.json();     if (typeof d.hero_gates === 'number') {-      remoteGates = { count: d.hero_gates, seasoned: !!d.seasoned, handle };+      remoteGates = { count: d.hero_gates, seasoned: !!d.seasoned, threshold: d.threshold || 4, handle };       logLine('info', 'account gate count: ' + d.hero_gates + ' (' + handle + ', seasoned=' + d.seasoned + ')');       stateRev += 1;     }@@ -345,6 +345,14 @@ fetchRemoteGates(); function readGates() {   return Math.max(readLocalGates(), remoteGates ? remoteGates.count : 0); }+// seasoned keys on the SERVER's boolean when the endpoint answered (their+// threshold propagates with no studio release); local >= 4 is the offline+// fallback and covers gates whose heroes have not landed yet+function isSeasoned() {+  const threshold = remoteGates ? remoteGates.threshold : 4;+  if (readLocalGates() >= threshold) return true;+  return remoteGates ? remoteGates.seasoned : false;+}  // Live wiki re-fetch for a page row, shared by /refresh-page, the dropdown, // and now raw POST /state page changes (#44: the fixture-row hole).@@ -403,7 +411,7 @@ function route(req, res, url, p) {     let body;     if (cached && cached.rev === stateRev) body = cached.body;     else {-      body = JSON.stringify(Object.assign({}, lean ? leanState() : state, { _toast: lastToast, _gen: lastGen, enums: ENUMS, version: PKG_VERSION, aiThread: AI_THREAD, gatesDone: readGates(), resolved: resolvedText() }));+      body = JSON.stringify(Object.assign({}, lean ? leanState() : state, { _toast: lastToast, _gen: lastGen, enums: ENUMS, version: PKG_VERSION, aiThread: AI_THREAD, gatesDone: readGates(), seasoned: isSeasoned(), resolved: resolvedText() }));       stateBodyCache[variant] = { rev: stateRev, body };     }     res.writeHead(200, { 'Content-Type': 'application/json', ETag: etag, 'Cache-Control': 'no-cache' });