app
Hero Studio
Public Made by Adomby adom
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. Every hero wears its P
← Commit history
0.21.4: app.js parses again (#59); test:syntax gate
2 files changed
+24
test/render-view.mjs+2@@ -87,6 +87,8 @@ try { await new Promise(r => setTimeout(r, 2000)); ok('render view makes no state-changing POST', posts.length === 0, posts.slice(0, 3).join(', ')); ok('render view still renders the hero', !!(await view.$('#hero')));+ const booted = await view.evaluate(() => typeof $ === 'function' && typeof render === 'function');+ ok('the page scripts parse and boot (app.js defines $ and render)', booted); ctl.abort(); ok('no slotSize ping-pong with a surface that measures differently', otherPosts <= 2, otherPosts + ' corrective posts from the other surface');
test/syntax.mjsadded+22@@ -0,0 +1,22 @@+#!/usr/bin/env node+// Syntax gate: node --check over every script the studio ships, page scripts+// included. A page script that fails to parse leaves the surface blank and the+// render view composing the generic mock (hero-studio#59), and nothing else+// in the suite loads public/js directly.+import { execFileSync } from 'child_process';+import fs from 'fs';+import path from 'path';+import { fileURLToPath } from 'url';+const ROOT = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');+const files = [+ ...fs.readdirSync(path.join(ROOT, 'public/js')).filter((f) => f.endsWith('.js')).map((f) => 'public/js/' + f),+ ...fs.readdirSync(ROOT).filter((f) => /\.(m|c)?js$/.test(f)),+ ...fs.readdirSync(path.join(ROOT, 'test')).filter((f) => /\.m?js$/.test(f)).map((f) => 'test/' + f),+];+let bad = 0;+for (const f of files) {+ try { execFileSync(process.execPath, ['--check', path.join(ROOT, f)], { stdio: 'pipe' }); console.log(' ok ' + f); }+ catch (e) { bad++; console.log(' FAIL ' + f + '\n' + String(e.stderr || e.message).split('\n').slice(0, 5).map((l) => ' ' + l).join('\n')); }+}+console.log('\n' + (files.length - bad) + ' passed, ' + bad + ' failed');+process.exit(bad ? 1 : 0);