From 992fa74b041400c1d606d9257bf8f6747608ccbc Mon Sep 17 00:00:00 2001 From: sjungwon03 Date: Fri, 31 Jul 2026 16:29:12 +0900 Subject: [PATCH] feat: publish OpenScene downloads for macOS, Windows, and Linux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v0.3.0 is the first release to ship packaged installers, so the site now offers them instead of only run-from-source. Asset filenames carry the version, which means `releases/latest/download/` cannot resolve them. `lib/releases.ts` holds one version constant that every link derives from, and `test/releases.test.ts` checks the filenames against the tag they point at so a partial version bump fails here rather than 404ing on GitHub. The release invalidated claims the site was making. Offering a download beside "there is no packaged installer" would contradict itself, so the hero caption, the installer FAQ, both documentation locales, and the boundaries table are corrected together. Signing status is stated rather than omitted: macOS builds are Developer ID signed and notarized, Windows and Linux builds are unsigned, and Windows SmartScreen warns on first run. The updater note now describes the prompt the application actually shows — it asks before updating — instead of claiming silent background updates, which nothing here verifies. Also renames the `product-surface--openvideo` class, the `openvideo-workspace-surface` test id, and two planning documents that kept the old product name after the rename landed. Closes #166 Co-Authored-By: Claude Opus 5 --- apps/openscene/app/globals.css | 6 +-- apps/openscene/app/page.tsx | 43 +++++++++++++++---- apps/openscene/lib/docs/content.en.ts | 24 +++++++---- apps/openscene/lib/docs/content.ko.ts | 24 +++++++---- apps/openscene/lib/releases.ts | 42 ++++++++++++++++++ apps/openscene/next-env.d.ts | 2 +- apps/openscene/test/home.test.tsx | 29 ++++++++++--- apps/openscene/test/releases.test.ts | 25 +++++++++++ apps/theorvane/public/products/openscene.svg | 2 +- apps/type-chain/app/globals.css | 4 +- apps/type-mcp/app/globals.css | 4 +- ...con-led-product-landings-implementation.md | 12 +++--- ...-07-30-icon-led-product-landings-design.md | 4 +- 13 files changed, 175 insertions(+), 46 deletions(-) create mode 100644 apps/openscene/lib/releases.ts create mode 100644 apps/openscene/test/releases.test.ts diff --git a/apps/openscene/app/globals.css b/apps/openscene/app/globals.css index 6a463d8..c2c397f 100644 --- a/apps/openscene/app/globals.css +++ b/apps/openscene/app/globals.css @@ -1,4 +1,4 @@ -:root{color-scheme:dark;--bg:#090b10;--surface:#111622;--ink:#f4f7fb;--muted:#a5afc0;--line:#293144;--accent:#78f7bc;--accent-ink:#072017;--violet:#a690ff}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:radial-gradient(circle at 82% 5%,#202943 0,transparent 30%),var(--bg);color:var(--ink);font-family:var(--font-sans)}a{color:inherit;text-underline-offset:4px}.shell{width:min(1120px,calc(100% - 2rem));margin:auto}.site-footer{margin-top:4rem;border-top:1px solid var(--line);padding:3rem 0 1.5rem}.footer-grid{display:grid;grid-template-columns:minmax(0,1fr) 1.4fr;gap:3rem}.footer-brand p{max-width:25rem;color:var(--muted);line-height:1.6}.footer-nav{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1.5rem}.footer-nav div{display:grid;align-content:start;gap:.6rem}.footer-nav strong{font:700 .72rem var(--font-mono);letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}.footer-nav a{min-height:32px;display:flex;align-items:center;width:max-content;max-width:100%}.footer-legal{display:flex;justify-content:space-between;gap:1rem;margin-top:3rem;padding-top:1.25rem;border-top:1px solid var(--line);color:var(--muted);font-size:.82rem}.skip-link{position:absolute;left:-999px}.skip-link:focus{left:1rem;top:1rem;background:var(--accent);color:var(--accent-ink);padding:.75rem;z-index:3}.wordmark{display:inline-flex;align-items:center;gap:.5rem;font:800 1.1rem var(--font-mono);letter-spacing:.08em;text-decoration:none}.wordmark__mark{display:block;width:24px;height:24px;border-radius:6px}.wordmark span{color:var(--accent)}header{display:flex;align-items:center;justify-content:space-between;padding:1.25rem 0;border-bottom:1px solid var(--line)}nav{display:flex;align-items:center;gap:1rem;font-size:.9rem}nav a{display:grid;min-height:44px;place-items:center}.hero{display:grid;grid-template-columns:1.15fr .85fr;gap:3rem;align-items:center;padding:clamp(5rem,12vw,9.5rem) 0}.eyebrow{margin:0;color:var(--accent);font:700 .72rem var(--font-mono);letter-spacing:.11em;text-transform:uppercase}h1{margin:1.1rem 0;font-size:clamp(3.5rem,7.6vw,7.4rem);letter-spacing:-.08em;line-height:.88}h1 em{font-family:Georgia,serif;font-weight:400;color:var(--violet)}.lede{max-width:40rem;color:var(--muted);font-size:1.15rem;line-height:1.65}.actions{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:2rem}.button{min-height:44px;padding:.78rem 1rem;border:1px solid var(--line);border-radius:99px;text-decoration:none;font-weight:700}.primary{border-color:var(--accent);background:var(--accent);color:var(--accent-ink)}.terminal{padding:1.4rem;border:1px solid var(--line);border-radius:1rem;background:linear-gradient(145deg,#171e2d,var(--surface));box-shadow:1rem 1rem 0 #161b29}.terminal p,.terminal span{font:700 .7rem var(--font-mono);letter-spacing:.1em}.terminal p{margin:0;color:var(--accent)}.terminal ol{display:grid;gap:.55rem;margin:1.5rem 0;padding:0;list-style:none;counter-reset:step}.terminal li{display:flex;gap:.7rem;align-items:baseline;min-width:0;overflow-x:auto}.terminal li::before{content:'$';color:var(--violet);font:700 .85rem var(--font-mono)}.terminal code{font:400 .84rem/1.5 var(--font-mono);color:var(--ink);white-space:pre}.terminal span{color:var(--muted);font-size:.65rem}.features{display:grid;grid-template-columns:repeat(3,1fr);border-block:1px solid var(--line)}.features article{min-height:15rem;padding:1.75rem;border-left:1px solid var(--line)}.features article:nth-child(3n+1){border-left:0}.features article:nth-child(n+4){border-top:1px solid var(--line)}.features b{color:var(--muted);font:700 .72rem var(--font-mono);letter-spacing:.1em}.features h2{margin:2rem 0 .65rem;font-size:1.4rem;letter-spacing:-.03em;line-height:1.25}.features h2 span{display:block;color:var(--accent);font:700 .72rem var(--font-mono);letter-spacing:.12em;text-transform:uppercase;margin-bottom:.5rem}.features p,.local>p:not(.eyebrow){color:var(--muted);line-height:1.65}.local{padding:8rem 0;max-width:760px;margin-left:max(1rem,calc((100% - 1120px)/2))}.local h2{margin:1rem 0;font-size:clamp(2.8rem,5vw,5.4rem);line-height:.95;letter-spacing:-.065em}.local a{display:inline-block;min-height:44px;padding-top:.8rem;color:var(--accent);font-weight:700}.agent{padding:6rem 0}.agent h2{margin:1rem 0;font-size:clamp(2.4rem,4.4vw,4.2rem);line-height:1;letter-spacing:-.055em}.tool-list{display:grid;gap:0;margin:2.5rem 0 2rem;padding:0;list-style:none;border-top:1px solid var(--line)}.tool-list li{display:flex;flex-wrap:wrap;gap:.4rem 1.5rem;align-items:baseline;justify-content:space-between;padding:.95rem 0;border-bottom:1px solid var(--line)}.tool-list span{font-size:1.02rem}.tool-list code{color:var(--accent);font:400 .8rem var(--font-mono);word-break:break-word}.note{max-width:52rem;color:var(--muted);line-height:1.7}.note strong{color:var(--ink)}.providers{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:3.5rem;align-items:start;padding:6rem 0;border-top:1px solid var(--line)}.providers h2{margin:1rem 0;font-size:clamp(2.2rem,3.8vw,3.4rem);line-height:1.02;letter-spacing:-.05em}.provider-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1.75rem;margin:0}.provider-grid dt{font:700 .72rem var(--font-mono);letter-spacing:.11em;text-transform:uppercase;color:var(--accent)}.provider-grid dd{margin:.6rem 0 0;color:var(--muted);line-height:1.6}.faq{padding:6rem 0;border-top:1px solid var(--line)}.faq h2{margin:0 0 2.5rem;font-size:clamp(2.2rem,3.8vw,3.4rem);letter-spacing:-.05em}.faq-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 3rem}.faq details{border-top:1px solid var(--line);padding:.4rem 0}.faq summary{min-height:44px;display:flex;align-items:center;gap:.75rem;cursor:pointer;font-size:1.05rem;font-weight:600;list-style:none}.faq summary::-webkit-details-marker{display:none}.faq summary::before{content:'+';color:var(--accent);font:700 1.1rem var(--font-mono)}.faq details[open] summary::before{content:'−'}.faq details p{margin:0 0 1rem 1.5rem;max-width:34rem;color:var(--muted);line-height:1.65}@media(max-width:760px){.footer-grid{grid-template-columns:1fr;gap:2rem}.footer-nav{grid-template-columns:repeat(2,minmax(0,1fr))}.footer-legal{align-items:flex-start;flex-direction:column;margin-top:2rem}}@media(max-width:760px){header{gap:1rem;flex-direction:column;align-items:flex-start}nav{gap:.65rem;flex-wrap:wrap;width:100%}.hero{grid-template-columns:1fr;padding:4.5rem 0}.actions{align-items:stretch;flex-direction:column}.button{text-align:center}.features{grid-template-columns:1fr 1fr}.features article:nth-child(3n+1){border-left:1px solid var(--line)}.features article:nth-child(odd){border-left:0}.features article:nth-child(n+3){border-top:1px solid var(--line)}.local{margin-inline:auto;padding:5rem 0}.providers{grid-template-columns:1fr;gap:2.5rem;padding:4.5rem 0}.provider-grid{grid-template-columns:1fr}.faq-grid{grid-template-columns:1fr}.agent{padding:4.5rem 0}.faq{padding:4.5rem 0}.tool-list li{flex-direction:column;gap:.35rem}}@media(max-width:480px){h1{font-size:clamp(2.4rem,10.5vw,3.5rem)}.terminal code{white-space:pre-wrap;word-break:break-all}.features{grid-template-columns:1fr}.features article,.features article:nth-child(3n+1){border-left:0;border-top:1px solid var(--line)}.features article:first-child{border-top:0}}@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}} +:root{color-scheme:dark;--bg:#090b10;--surface:#111622;--ink:#f4f7fb;--muted:#a5afc0;--line:#293144;--accent:#78f7bc;--accent-ink:#072017;--violet:#a690ff}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:radial-gradient(circle at 82% 5%,#202943 0,transparent 30%),var(--bg);color:var(--ink);font-family:var(--font-sans)}a{color:inherit;text-underline-offset:4px}.shell{width:min(1120px,calc(100% - 2rem));margin:auto}.site-footer{margin-top:4rem;border-top:1px solid var(--line);padding:3rem 0 1.5rem}.footer-grid{display:grid;grid-template-columns:minmax(0,1fr) 1.4fr;gap:3rem}.footer-brand p{max-width:25rem;color:var(--muted);line-height:1.6}.footer-nav{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1.5rem}.footer-nav div{display:grid;align-content:start;gap:.6rem}.footer-nav strong{font:700 .72rem var(--font-mono);letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}.footer-nav a{min-height:32px;display:flex;align-items:center;width:max-content;max-width:100%}.footer-legal{display:flex;justify-content:space-between;gap:1rem;margin-top:3rem;padding-top:1.25rem;border-top:1px solid var(--line);color:var(--muted);font-size:.82rem}.skip-link{position:absolute;left:-999px}.skip-link:focus{left:1rem;top:1rem;background:var(--accent);color:var(--accent-ink);padding:.75rem;z-index:3}.wordmark{display:inline-flex;align-items:center;gap:.5rem;font:800 1.1rem var(--font-mono);letter-spacing:.08em;text-decoration:none}.wordmark__mark{display:block;width:24px;height:24px;border-radius:6px}.wordmark span{color:var(--accent)}header{display:flex;align-items:center;justify-content:space-between;padding:1.25rem 0;border-bottom:1px solid var(--line)}nav{display:flex;align-items:center;gap:1rem;font-size:.9rem}nav a{display:grid;min-height:44px;place-items:center}.hero{display:grid;grid-template-columns:1.15fr .85fr;gap:3rem;align-items:center;padding:clamp(5rem,12vw,9.5rem) 0}.eyebrow{margin:0;color:var(--accent);font:700 .72rem var(--font-mono);letter-spacing:.11em;text-transform:uppercase}h1{margin:1.1rem 0;font-size:clamp(3.5rem,7.6vw,7.4rem);letter-spacing:-.08em;line-height:.88}h1 em{font-family:Georgia,serif;font-weight:400;color:var(--violet)}.lede{max-width:40rem;color:var(--muted);font-size:1.15rem;line-height:1.65}.actions{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:2rem}.button{min-height:44px;padding:.78rem 1rem;border:1px solid var(--line);border-radius:99px;text-decoration:none;font-weight:700}.primary{border-color:var(--accent);background:var(--accent);color:var(--accent-ink)}.terminal{padding:1.4rem;border:1px solid var(--line);border-radius:1rem;background:linear-gradient(145deg,#171e2d,var(--surface));box-shadow:1rem 1rem 0 #161b29}.terminal p,.terminal span{font:700 .7rem var(--font-mono);letter-spacing:.1em}.terminal p{margin:0;color:var(--accent)}.terminal ol{display:grid;gap:.55rem;margin:1.5rem 0;padding:0;list-style:none;counter-reset:step}.terminal li{display:flex;gap:.7rem;align-items:baseline;min-width:0;overflow-x:auto}.terminal li::before{content:'$';color:var(--violet);font:700 .85rem var(--font-mono)}.terminal code{font:400 .84rem/1.5 var(--font-mono);color:var(--ink);white-space:pre}.terminal span{color:var(--muted);font-size:.65rem}.features{display:grid;grid-template-columns:repeat(3,1fr);border-block:1px solid var(--line)}.features article{min-height:15rem;padding:1.75rem;border-left:1px solid var(--line)}.features article:nth-child(3n+1){border-left:0}.features article:nth-child(n+4){border-top:1px solid var(--line)}.features b{color:var(--muted);font:700 .72rem var(--font-mono);letter-spacing:.1em}.features h2{margin:2rem 0 .65rem;font-size:1.4rem;letter-spacing:-.03em;line-height:1.25}.features h2 span{display:block;color:var(--accent);font:700 .72rem var(--font-mono);letter-spacing:.12em;text-transform:uppercase;margin-bottom:.5rem}.features p,.local>p:not(.eyebrow){color:var(--muted);line-height:1.65}.local{padding:8rem 0;max-width:760px;margin-left:max(1rem,calc((100% - 1120px)/2))}.local h2{margin:1rem 0;font-size:clamp(2.8rem,5vw,5.4rem);line-height:.95;letter-spacing:-.065em}.local a{display:inline-block;min-height:44px;padding-top:.8rem;color:var(--accent);font-weight:700}.downloads{padding:6rem 0;border-top:1px solid var(--line)}.downloads h2{margin:1rem 0;font-size:clamp(2.2rem,3.8vw,3.4rem);line-height:1.02;letter-spacing:-.05em}.download-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.5rem;margin:2.5rem 0 2rem}.download-grid article{display:grid;align-content:start;padding:1.6rem;border:1px solid var(--line);border-radius:1rem;background:var(--surface)}.download-grid h3{margin:0;font:700 .72rem var(--font-mono);letter-spacing:.11em;text-transform:uppercase;color:var(--accent)}.download-grid ul{display:grid;gap:.6rem;margin:1.25rem 0;padding:0;list-style:none}.download-grid .button{display:flex;align-items:center;justify-content:center;text-align:center;font-size:.9rem}.download-grid article>p{margin:0;color:var(--muted);font-size:.82rem;line-height:1.55}.agent{padding:6rem 0}.agent h2{margin:1rem 0;font-size:clamp(2.4rem,4.4vw,4.2rem);line-height:1;letter-spacing:-.055em}.tool-list{display:grid;gap:0;margin:2.5rem 0 2rem;padding:0;list-style:none;border-top:1px solid var(--line)}.tool-list li{display:flex;flex-wrap:wrap;gap:.4rem 1.5rem;align-items:baseline;justify-content:space-between;padding:.95rem 0;border-bottom:1px solid var(--line)}.tool-list span{font-size:1.02rem}.tool-list code{color:var(--accent);font:400 .8rem var(--font-mono);word-break:break-word}.note{max-width:52rem;color:var(--muted);line-height:1.7}.note strong{color:var(--ink)}.providers{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:3.5rem;align-items:start;padding:6rem 0;border-top:1px solid var(--line)}.providers h2{margin:1rem 0;font-size:clamp(2.2rem,3.8vw,3.4rem);line-height:1.02;letter-spacing:-.05em}.provider-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1.75rem;margin:0}.provider-grid dt{font:700 .72rem var(--font-mono);letter-spacing:.11em;text-transform:uppercase;color:var(--accent)}.provider-grid dd{margin:.6rem 0 0;color:var(--muted);line-height:1.6}.faq{padding:6rem 0;border-top:1px solid var(--line)}.faq h2{margin:0 0 2.5rem;font-size:clamp(2.2rem,3.8vw,3.4rem);letter-spacing:-.05em}.faq-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 3rem}.faq details{border-top:1px solid var(--line);padding:.4rem 0}.faq summary{min-height:44px;display:flex;align-items:center;gap:.75rem;cursor:pointer;font-size:1.05rem;font-weight:600;list-style:none}.faq summary::-webkit-details-marker{display:none}.faq summary::before{content:'+';color:var(--accent);font:700 1.1rem var(--font-mono)}.faq details[open] summary::before{content:'−'}.faq details p{margin:0 0 1rem 1.5rem;max-width:34rem;color:var(--muted);line-height:1.65}@media(max-width:760px){.footer-grid{grid-template-columns:1fr;gap:2rem}.footer-nav{grid-template-columns:repeat(2,minmax(0,1fr))}.footer-legal{align-items:flex-start;flex-direction:column;margin-top:2rem}}@media(max-width:760px){header{gap:1rem;flex-direction:column;align-items:flex-start}nav{gap:.65rem;flex-wrap:wrap;width:100%}.hero{grid-template-columns:1fr;padding:4.5rem 0}.actions{align-items:stretch;flex-direction:column}.button{text-align:center}.features{grid-template-columns:1fr 1fr}.features article:nth-child(3n+1){border-left:1px solid var(--line)}.features article:nth-child(odd){border-left:0}.features article:nth-child(n+3){border-top:1px solid var(--line)}.local{margin-inline:auto;padding:5rem 0}.providers{grid-template-columns:1fr;gap:2.5rem;padding:4.5rem 0}.provider-grid{grid-template-columns:1fr}.faq-grid{grid-template-columns:1fr}.downloads{padding:4.5rem 0}.download-grid{grid-template-columns:1fr;margin:2rem 0 1.5rem}.agent{padding:4.5rem 0}.faq{padding:4.5rem 0}.tool-list li{flex-direction:column;gap:.35rem}}@media(max-width:480px){h1{font-size:clamp(2.4rem,10.5vw,3.5rem)}.terminal code{white-space:pre-wrap;word-break:break-all}.features{grid-template-columns:1fr}.features article,.features article:nth-child(3n+1){border-left:0;border-top:1px solid var(--line)}.features article:first-child{border-top:0}}@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}} /* Icon-led landing evidence */ .evidence-panel{display:grid;grid-template-columns:minmax(0,1fr) minmax(18rem,.8fr);gap:clamp(1.5rem,5vw,5rem);align-items:center;margin:clamp(3rem,8vw,7rem) auto;padding:clamp(1.5rem,4vw,3rem);border:1px solid var(--line);border-radius:1.25rem;background:linear-gradient(135deg,var(--accent-tint, color-mix(in srgb,var(--blue) 12%,#fff)),#fff)} .evidence-panel h2{margin:.35rem 0 .8rem;font-size:clamp(2.35rem,5vw,5rem);line-height:.9;letter-spacing:-.07em}.evidence-panel>div>p:last-child{max-width:34rem;line-height:1.65;color:var(--muted)} @@ -12,7 +12,7 @@ body:has(.product-surface) header nav{color:#b7c4dd} body:has(.product-surface) .site-footer{border-color:#ffffff27;background:#030812;color:#f5f7f6} .product-surface{--surface:#081226;--signal:#4c83f2;--surface-line:#ffffff27;--surface-muted:#b7c4dd;background:radial-gradient(circle at 86% 2%,color-mix(in srgb,var(--signal) 19%,transparent),transparent 32%),#030812;color:#f5f7f6;padding-bottom:1px} .product-surface--typechain{--surface:#082118;--signal:#0aa66e;--surface-muted:#bdd7c9;background:radial-gradient(circle at 86% 2%,color-mix(in srgb,var(--signal) 20%,transparent),transparent 32%),#03150f} -.product-surface--openvideo{--surface:#111622;--signal:#78f7bc;--surface-muted:#a5afc0;background:radial-gradient(circle at 83% 6%,#a690ff35,transparent 34%),#090b10} +.product-surface--openscene{--surface:#111622;--signal:#78f7bc;--surface-muted:#a5afc0;background:radial-gradient(circle at 83% 6%,#a690ff35,transparent 34%),#090b10} .product-surface .hero{min-height:clamp(38rem,68vw,48rem);padding-block:clamp(5rem,10vw,8rem);gap:clamp(2rem,7vw,6rem)} .product-surface .hero h1{font-size:clamp(3.6rem,7.8vw,7.5rem);line-height:.88;letter-spacing:-.08em;color:#f5f7f6} .product-surface .hero h1 em{color:var(--signal);font-family:Georgia,serif;font-weight:400} @@ -26,7 +26,7 @@ body:has(.product-surface) .site-footer{border-color:#ffffff27;background:#03081 .product-surface .architecture,.product-surface .start,.product-surface .agent,.product-surface .providers,.product-surface .local,.product-surface .faq{border-color:var(--surface-line)} .product-surface .integration{background:color-mix(in srgb,var(--surface) 82%,#000);border-block:1px solid var(--surface-line)}.product-surface .integration aside{background:color-mix(in srgb,var(--signal) 20%,var(--surface));border:1px solid var(--surface-line)} .product-surface .features article,.product-surface .tool-list li,.product-surface .provider-grid div,.product-surface .faq details{border-color:var(--surface-line)} -.product-surface .site-footer,.product-surface + .site-footer{background:#030812;color:#f5f7f6}.product-surface--typechain + .site-footer{background:#03150f}.product-surface--openvideo + .site-footer{background:#090b10} +.product-surface .site-footer,.product-surface + .site-footer{background:#030812;color:#f5f7f6}.product-surface--typechain + .site-footer{background:#03150f}.product-surface--openscene + .site-footer{background:#090b10} @media(max-width:700px){.product-surface .hero{min-height:auto;padding-block:4.5rem}.product-surface .hero h1{font-size:clamp(3.4rem,16vw,5.8rem)}.product-surface .capabilities{padding-block:1.5rem 2.5rem}} /* Preserve readable inherited text from the earlier light landing in the dark surface. */ diff --git a/apps/openscene/app/page.tsx b/apps/openscene/app/page.tsx index 1c4438c..ec3d40b 100644 --- a/apps/openscene/app/page.tsx +++ b/apps/openscene/app/page.tsx @@ -1,8 +1,9 @@ import { ExternalLink, SkipLink } from "@theorvane/ui"; +import { assetsFor, downloadUrl, releaseNotesUrl, releasesUrl, releaseTag, releaseVersion } from "../lib/releases"; + const siteUrl = "https://openscene.app/"; const repositoryUrl = "https://github.com/Theorvane/openscene"; -const releasesUrl = "https://github.com/Theorvane/openscene/releases"; const readmeUrl = "https://github.com/Theorvane/openscene#readme"; const theorvaneUrl = "https://theorvane.tech/"; const modelsDevUrl = "https://models.dev"; @@ -34,13 +35,21 @@ const faq = [ ["Which providers can I use?", "Anything in the generated models.dev catalog that speaks the OpenAI or Anthropic wire format, plus Google Gemini natively. For OpenAI you can use an API key or a ChatGPT sign-in."], ["Where does my footage go?", "Into the project folder you chose, and nowhere else. A provider only ever receives what you ask the agent to send it."], ["Do I need FFmpeg?", "Yes, for export. OpenScene drives the FFmpeg on your machine rather than bundling its own, and refuses to start an export it cannot complete."], - ["Is there an installer?", "Not yet. OpenScene runs from source today; there is no packaged build or auto-update, and this site will say so until there is."], + ["Is there an installer?", `Yes, from ${releaseVersion}. macOS, Windows, and Linux builds are published on every release, and running from source stays supported. The macOS builds are signed with a Developer ID certificate and notarized; the Windows and Linux builds are unsigned, so Windows SmartScreen warns on first run.`], + ["How do updates reach me?", "The application checks for a published release and asks before it updates. Nothing is downloaded or replaced without your answer, and a build you run from source updates when you pull and rebuild."], ] as const; +/** Platform order follows the desktop share the project sees, not alphabetical order. */ +const downloads = [ + { platform: "macos" as const, label: "macOS", note: "Signed and notarized" }, + { platform: "windows" as const, label: "Windows", note: "Unsigned — SmartScreen warns on first run" }, + { platform: "linux" as const, label: "Linux", note: "Unsigned, as AppImage and deb normally are" }, +]; + const schema = { "@context": "https://schema.org", "@graph": [ - { "@type": "SoftwareApplication", "@id": `${siteUrl}#application`, name: "OpenScene", url: siteUrl, applicationCategory: "VideoApplication", operatingSystem: "macOS, Windows, Linux", description: "A local-first desktop video editor with an AI agent that operates the timeline, plus voice and video generation and local FFmpeg export.", isAccessibleForFree: true, license: "https://opensource.org/licenses/MIT", codeRepository: repositoryUrl, softwareRequirements: "Node.js 22 or newer; FFmpeg on the host machine for export", offers: { "@type": "Offer", price: "0", priceCurrency: "USD" }, author: { "@id": "https://theorvane.tech/#organization" } }, + { "@type": "SoftwareApplication", "@id": `${siteUrl}#application`, name: "OpenScene", url: siteUrl, applicationCategory: "VideoApplication", operatingSystem: "macOS, Windows, Linux", description: "A local-first desktop video editor with an AI agent that operates the timeline, plus voice and video generation and local FFmpeg export.", isAccessibleForFree: true, license: "https://opensource.org/licenses/MIT", codeRepository: repositoryUrl, softwareVersion: releaseVersion, downloadUrl: `${siteUrl}#download`, softwareRequirements: "FFmpeg on the host machine for export; Node.js 22 or newer to run from source", offers: { "@type": "Offer", price: "0", priceCurrency: "USD" }, author: { "@id": "https://theorvane.tech/#organization" } }, { "@type": "WebSite", "@id": `${siteUrl}#website`, name: "OpenScene", url: siteUrl, inLanguage: "en", publisher: { "@id": "https://theorvane.tech/#organization" } }, { "@type": "FAQPage", "@id": `${siteUrl}#faq`, mainEntity: faq.map(([question, answer]) => ({ "@type": "Question", name: question, acceptedAnswer: { "@type": "Answer", text: answer } })) }, ], @@ -48,23 +57,41 @@ const schema = { export default function HomePage() { return <>