All checks were successful
deploy / deploy (push) Successful in 7s
Live HL data → in-browser TA → 4-agent committee → LONG/SHORT/SKIP verdict. Terminal grid command bar + interactive agent-workflow graph. Paper-trading worker reuses the browser brain (dry-run + Telegram). Forgejo static deploy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
60 lines
3.4 KiB
JavaScript
60 lines
3.4 KiB
JavaScript
import sharp from 'sharp'
|
|
import toIco from 'to-ico'
|
|
import { readFileSync, writeFileSync } from 'node:fs'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { dirname, join } from 'node:path'
|
|
|
|
const root = join(dirname(fileURLToPath(import.meta.url)), '..')
|
|
const pub = join(root, 'public')
|
|
const svg = readFileSync(join(pub, 'favicon.svg'))
|
|
|
|
// favicon.ico (16/32/48)
|
|
const pngs = await Promise.all(
|
|
[16, 32, 48].map((s) => sharp(svg, { density: 384 }).resize(s, s).png().toBuffer()),
|
|
)
|
|
writeFileSync(join(pub, 'favicon.ico'), await toIco(pngs))
|
|
|
|
// apple touch + pwa icon
|
|
await sharp(svg, { density: 512 }).resize(180, 180).png().toFile(join(pub, 'apple-touch-icon.png'))
|
|
await sharp(svg, { density: 512 }).resize(512, 512).png().toFile(join(pub, 'icon-512.png'))
|
|
|
|
// social card (og:image) — Quant Agent (wireframe globe)
|
|
const globe = (cx, cy, r, sw) =>
|
|
`<g transform="translate(${cx} ${cy})" fill="none" stroke="#ffffff" stroke-width="${sw}" stroke-linecap="round">
|
|
<circle r="${r}"/>
|
|
<path d="M0 ${-r} C ${-r * 0.76} ${-r * 0.53} ${-r * 0.76} ${r * 0.53} 0 ${r}"/>
|
|
<path d="M0 ${-r} C ${r * 0.76} ${-r * 0.53} ${r * 0.76} ${r * 0.53} 0 ${r}"/>
|
|
<path d="M0 ${-r} C ${-r * 0.38} ${-r * 0.47} ${-r * 0.38} ${r * 0.47} 0 ${r}"/>
|
|
<path d="M0 ${-r} C ${r * 0.38} ${-r * 0.47} ${r * 0.38} ${r * 0.47} 0 ${r}"/>
|
|
<path d="M${-r} 0 H ${r}"/>
|
|
</g>
|
|
<g transform="translate(${cx} ${cy})" fill="#ffffff">
|
|
<ellipse cx="0" cy="${-r * 0.35}" rx="${r * 0.35}" ry="${r * 0.25}"/>
|
|
<ellipse cx="0" cy="${r * 0.35}" rx="${r * 0.35}" ry="${r * 0.25}"/>
|
|
</g>`
|
|
const og = `<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630" viewBox="0 0 1200 630">
|
|
<rect width="1200" height="630" fill="#0b0c0e"/>
|
|
<g stroke="#ffffff" stroke-opacity="0.04">
|
|
${Array.from({ length: 12 }, (_, i) => `<line x1="${i * 100}" y1="0" x2="${i * 100}" y2="630"/>`).join('')}
|
|
${Array.from({ length: 7 }, (_, i) => `<line x1="0" y1="${i * 100}" x2="1200" y2="${i * 100}"/>`).join('')}
|
|
</g>
|
|
<g opacity="0.95">${globe(955, 315, 210, 5)}</g>
|
|
<g stroke="#ffffff" stroke-opacity="0.3" fill="#ffffff" fill-opacity="0.85">
|
|
<line x1="760" y1="150" x2="900" y2="240"/><circle cx="760" cy="150" r="5"/>
|
|
<line x1="1150" y1="420" x2="1010" y2="360"/><circle cx="1150" cy="420" r="5"/>
|
|
<line x1="820" y1="520" x2="930" y2="450"/><circle cx="820" cy="520" r="5"/>
|
|
</g>
|
|
<g transform="translate(99 116)">${globe(0, 0, 19, 2.6)}</g>
|
|
<text x="128" y="124" font-family="Arial, sans-serif" font-size="28" font-weight="800" fill="#e8eaed">Quant Agent</text>
|
|
<text x="80" y="322" font-family="Arial, sans-serif" font-size="74" font-weight="800" fill="#e8eaed">Four agents argue.</text>
|
|
<text x="80" y="408" font-family="Arial, sans-serif" font-size="74" font-weight="800" fill="#ffb020">One verdict.</text>
|
|
<text x="80" y="478" font-family="Arial, sans-serif" font-size="28" fill="#828a94">A multi-agent quant terminal for Hyperliquid perps — live data, TA, LONG / SHORT / SKIP.</text>
|
|
<g transform="translate(80 528)">
|
|
<circle cx="8" cy="8" r="6" fill="#2bd974"/>
|
|
<text x="26" y="14" font-family="monospace" font-size="21" fill="#2bd974" letter-spacing="2">LIVE · HYPERLIQUID</text>
|
|
<text x="320" y="14" font-family="monospace" font-size="21" fill="#ffb020" letter-spacing="2">PAPER · DRY-RUN</text>
|
|
</g>
|
|
</svg>`
|
|
await sharp(Buffer.from(og)).png().toFile(join(pub, 'og.png'))
|
|
|
|
console.log('✓ icons + og generated')
|