Add protected launch status route
This commit is contained in:
parent
d5f800de65
commit
af07f720ff
12 changed files with 381 additions and 47 deletions
|
|
@ -128,6 +128,12 @@ The protected dashboard now also has a first-party launch-readiness panel for:
|
|||
- backend webhook-secret and billing-map configuration posture
|
||||
- public auth runtime posture, cookie-hardening posture, and local-vs-public runtime diagnostics
|
||||
|
||||
The next same-family protected-shell continuation then widened that signed-in
|
||||
launch-truth lane into a dedicated `/app/launch-status` route so rollout
|
||||
blockers, release action, packaged desktop proof, notices references, and
|
||||
signed-in next steps no longer collapse back to a single dashboard panel after
|
||||
auth succeeds.
|
||||
|
||||
The adjacent protected account route now also mirrors that same signed-in
|
||||
auth/session-authority truth instead of reducing the account lane to a thinner
|
||||
identity-and-billing shell than the main protected dashboard.
|
||||
|
|
@ -292,6 +298,10 @@ Current behavior:
|
|||
- the protected dashboard launch-readiness panel and the public
|
||||
preview-versus-launch callouts now also consume manifest-backed Windows
|
||||
download truth instead of relying only on static frontend config
|
||||
- the dedicated protected `/app/launch-status` route now consumes that same
|
||||
manifest-backed Windows download truth too, so signed-in rollout review
|
||||
stays aligned with both the public authority page and the protected release
|
||||
action surface
|
||||
- the same public launch-status lane now also checks live auth-health webhook
|
||||
and public-origin readiness posture before presenting the site as launch-ready
|
||||
- the runtime-readiness verifier now accepts server-backed release-manifest
|
||||
|
|
|
|||
|
|
@ -1053,6 +1053,10 @@ Current audit note:
|
|||
preview-versus-launch posture through a dedicated public `/launch-status`
|
||||
route, so rollout blockers, release references, support lanes, and packaged
|
||||
proof no longer have to be reconstructed from pricing plus scattered callouts
|
||||
- the adjacent protected-shell parity continuation then mirrored that same
|
||||
rollout truth after sign-in through a dedicated `/app/launch-status` route,
|
||||
so the signed-in browser lane no longer reduces launch authority back to a
|
||||
single dashboard panel once account context is present
|
||||
- this keeps the public manual professional without inventing browser
|
||||
simulator parity or widening the native XR branch
|
||||
- focused validation for that continuation stayed green under:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -7,14 +7,14 @@ First-party `hypertwist.app` surface for HyperTwist:
|
|||
- dedicated public `/launch-status` route for the canonical preview-versus-launch rollout checklist
|
||||
- public feature-atlas route for current capability and boundary truth
|
||||
- browser-facing operator/account dashboard
|
||||
- protected browser-access, account, and notices routes backed by live auth-health and release-manifest authority
|
||||
- protected launch-status, browser-access, account, and notices routes backed by live auth-health and release-manifest authority
|
||||
- shared SuperTokens auth posture reused from the FamiliarOS and ScriptoriumAI website lane
|
||||
- route-aware SuperTokens wrapping so public brochure routes do not pay for auth chrome unnecessarily while `/app`, `/login`, `/register`, `/auth/*`, and stored-session continuity still do
|
||||
- FamiliarOS-style first-party auth-shell backdrop for login/register/auth callback posture, including first-paint HTML fallback plus route-synced runtime ownership
|
||||
- desktop download posture and desktop-link handshake endpoints
|
||||
- server-backed release-manifest authority shared by public and protected download surfaces
|
||||
- Paddle-ready pricing/check-out wiring
|
||||
- dashboard-side launch-readiness surface for download, checkout, auth, and notice configuration
|
||||
- dashboard-side plus dedicated protected launch-status surfaces for download, checkout, auth, and notice configuration
|
||||
- public launch-status callouts across pricing, download, and notices surfaces
|
||||
- route-aware metadata, canonical, Open Graph, Twitter-card, and protected-route noindex posture for the live `hypertwist.app` surface
|
||||
- first-party `robots.txt` plus `sitemap.xml` for the public crawlable route set while keeping `/app`, `/login`, and `/register` out of crawler posture
|
||||
|
|
@ -84,6 +84,9 @@ manual:
|
|||
- the same launch-authority story is now also anchored at a dedicated public
|
||||
`/launch-status` route so preview-versus-launch truth, rollout blockers,
|
||||
packaged proof, and release references have one canonical authority surface
|
||||
- the protected operator shell now also mirrors that same launch-authority
|
||||
posture on a dedicated signed-in `/app/launch-status` route, so rollout
|
||||
truth no longer collapses back down to a single dashboard panel after sign-in
|
||||
- the protected app shell now also carries richer operator-facing browser
|
||||
boundary, account, entitlement, and notices guidance instead of treating
|
||||
those routes as thin placeholders beside the main dashboard
|
||||
|
|
@ -444,7 +447,7 @@ The focused frontend test coverage now also pins:
|
|||
- platform-preserving `/download -> /app/downloads?platform=...` continuation plus requested-target surfacing inside the protected release lane
|
||||
- support-topic fallback routing for pricing and launch-readiness actions when live checkout is not configured yet
|
||||
- protected-route loading/redirect behavior plus auth-aware marketing/app shell actions
|
||||
- real `AppRouteTree` smoke coverage for `/`, `/features`, `/pricing`, `/download`, `/login`, `/app`, and `/app/downloads`
|
||||
- real `AppRouteTree` smoke coverage for `/`, `/features`, `/pricing`, `/download`, `/login`, `/app`, `/app/launch-status`, and `/app/downloads`
|
||||
- top-level `App` bootstrap coverage for unknown-route redirect and SuperTokens wrapper on/off posture
|
||||
- login/register unhappy-path coverage for returned form errors, auth-runtime warning callouts, and OAuth-button visibility/invocation
|
||||
- dashboard launch-readiness plus desktop-link verify-url behavior
|
||||
|
|
|
|||
|
|
@ -202,6 +202,11 @@ describe('DashboardOverviewPage', () => {
|
|||
expect(screen.getByText('Signed-in help lanes')).toBeTruthy()
|
||||
expect(screen.getByText('Protected browser-versus-desktop reality')).toBeTruthy()
|
||||
expect(screen.getByText('Current input, XR, and settings truth')).toBeTruthy()
|
||||
expect(
|
||||
screen
|
||||
.getAllByRole('link', { name: 'Open protected launch status' })
|
||||
.some((link) => link.getAttribute('href') === '/app/launch-status'),
|
||||
).toBe(true)
|
||||
expect(screen.getByRole('link', { name: 'Open account' }).getAttribute('href')).toBe('/app/account')
|
||||
expect(screen.getAllByRole('link', { name: 'Open browser access' }).every((link) => link.getAttribute('href') === '/app/browser-access')).toBe(true)
|
||||
expect(screen.getAllByRole('link', { name: 'Open notices' }).length).toBeGreaterThan(0)
|
||||
|
|
|
|||
|
|
@ -348,6 +348,75 @@ describe('AppRouteTree', () => {
|
|||
expect(screen.getByText('Windows')).toBeTruthy()
|
||||
})
|
||||
|
||||
it('renders the protected launch-status route through the real route tree when authenticated', async () => {
|
||||
mockUsePlatformAuth.mockReturnValue({
|
||||
isAuthenticated: true,
|
||||
isLoading: false,
|
||||
login: vi.fn(),
|
||||
register: vi.fn(),
|
||||
logout: vi.fn(),
|
||||
toggleColorMode: vi.fn(),
|
||||
colorMode: 'dark',
|
||||
superTokensConfigured: true,
|
||||
user: {
|
||||
id: 'operator-1',
|
||||
name: 'Operator',
|
||||
email: 'operator@hypertwist.app',
|
||||
plan: 'operator',
|
||||
role: 'operator',
|
||||
canDownload: true,
|
||||
billing: {
|
||||
source: 'session',
|
||||
accessStatus: 'active',
|
||||
canDownload: true,
|
||||
lastEventType: 'transaction.completed',
|
||||
},
|
||||
},
|
||||
})
|
||||
mockGetReleaseManifest.mockResolvedValue({
|
||||
ok: true,
|
||||
manifest: {
|
||||
generated_at: '2026-06-22T12:00:00.000Z',
|
||||
support_email: 'hello@hypertwist.app',
|
||||
public_docs_url: 'https://docs.hypertwist.app',
|
||||
release_notes_url: 'https://notes.hypertwist.app',
|
||||
corresponding_source_url: 'https://hypertwist.app/open-source/source.zip',
|
||||
open_source_repo_url: 'https://github.com/hypertwist/hypertwist',
|
||||
viewer: {
|
||||
authenticated: true,
|
||||
canDownload: true,
|
||||
plan: 'operator',
|
||||
role: 'operator',
|
||||
accessStatus: 'active',
|
||||
},
|
||||
platforms: [
|
||||
{
|
||||
platform_key: 'windows',
|
||||
platform: 'Windows',
|
||||
subtitle: 'Primary shipping lane',
|
||||
details: 'Current packaged validation is strongest on the Windows Unreal lane.',
|
||||
configured: true,
|
||||
channel: 'candidate',
|
||||
version: '1.0.0',
|
||||
build_id: 'win64-1000',
|
||||
published_at: '2026-06-22T00:00:00.000Z',
|
||||
file_name: 'HyperTwist-Windows.zip',
|
||||
file_size_bytes: 1048576,
|
||||
checksum_sha256: 'abc123',
|
||||
download_url: 'https://downloads.hypertwist.app/windows.exe',
|
||||
download_available: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
renderRoute('/app/launch-status')
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Protected launch status')).toBeTruthy()
|
||||
})
|
||||
expect(screen.getByText('Launch references and notices')).toBeTruthy()
|
||||
})
|
||||
|
||||
it('renders the protected browser-access route through the real route tree when authenticated', async () => {
|
||||
mockUsePlatformAuth.mockReturnValue({
|
||||
isAuthenticated: true,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ vi.mock('../auth/auth-api', () => ({
|
|||
getReleaseManifest: (...args: unknown[]) => mockGetReleaseManifest(...args),
|
||||
}))
|
||||
|
||||
import { AccountPage, BrowserAccessPage, DownloadCenterPage, NoticesPage } from '../pages/app-pages'
|
||||
import { AccountPage, BrowserAccessPage, DownloadCenterPage, NoticesPage, ProtectedLaunchStatusPage } from '../pages/app-pages'
|
||||
|
||||
function renderPage(page: React.ReactNode, initialEntry: string) {
|
||||
const queryClient = new QueryClient({
|
||||
|
|
@ -209,6 +209,23 @@ describe('protected app pages', () => {
|
|||
expect(screen.getByRole('link', { name: 'Open support' }).getAttribute('href')).toBe('/support?topic=operator-access')
|
||||
})
|
||||
|
||||
it('surfaces a dedicated protected launch-status route with signed-in rollout authority', async () => {
|
||||
renderPage(<ProtectedLaunchStatusPage />, '/app/launch-status')
|
||||
|
||||
expect(await screen.findByText('Protected launch status')).toBeTruthy()
|
||||
expect(screen.getByText('Signed-in rollout authority')).toBeTruthy()
|
||||
expect(screen.getByText('Current release action')).toBeTruthy()
|
||||
expect(screen.getByText('Current packaged desktop proof')).toBeTruthy()
|
||||
expect(screen.getByText('Launch-readiness support lane')).toBeTruthy()
|
||||
expect(screen.getByText('Launch references and notices')).toBeTruthy()
|
||||
expect(screen.getByText('Protected browser-versus-desktop reality')).toBeTruthy()
|
||||
expect(screen.getByRole('link', { name: 'Open public launch status' }).getAttribute('href')).toBe('/launch-status')
|
||||
expect(screen.getByRole('link', { name: 'Open protected launch status' }).getAttribute('href')).toBe('/app/launch-status')
|
||||
expect(await screen.findByText(byExactTextContent('Public repository/notices URL: https://github.com/hypertwist/hypertwist', 'LI'))).toBeTruthy()
|
||||
expect(screen.getByRole('link', { name: 'Protected notices' }).getAttribute('href')).toBe('/app/notices')
|
||||
expect(screen.getByRole('link', { name: 'Public notices' }).getAttribute('href')).toBe('/open-source-notices')
|
||||
})
|
||||
|
||||
it('keeps the protected download center aligned with packaged proof, notices, and escalation guidance', async () => {
|
||||
renderPage(<DownloadCenterPage />, '/app/downloads?platform=windows')
|
||||
|
||||
|
|
|
|||
|
|
@ -250,6 +250,8 @@ describe('website route and shell behavior', () => {
|
|||
expect(screen.getByText('studio plan')).toBeTruthy()
|
||||
expect(screen.getByText('Overview content')).toBeTruthy()
|
||||
expect(screen.getByText('Desktop-first operator lane')).toBeTruthy()
|
||||
expect(screen.getByRole('link', { name: 'Launch Status' }).getAttribute('href')).toBe('/app/launch-status')
|
||||
expect(screen.getByRole('link', { name: 'Protected launch status' }).getAttribute('href')).toBe('/app/launch-status')
|
||||
expect(screen.getByRole('link', { name: 'Public download posture' }).getAttribute('href')).toBe('/download')
|
||||
expect(screen.getByRole('link', { name: 'Public notices' }).getAttribute('href')).toBe('/open-source-notices')
|
||||
expect(screen.getByRole('link', { name: 'Operator access support' }).getAttribute('href')).toBe('/support?topic=operator-access')
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Gauge, KeyRound, MonitorSmartphone, PackageOpen, ShieldCheck } from 'lucide-react'
|
||||
import { Gauge, KeyRound, Landmark, MonitorSmartphone, PackageOpen, ShieldCheck } from 'lucide-react'
|
||||
import { Link, NavLink, Outlet } from 'react-router-dom'
|
||||
import { usePlatformAuth } from '../../auth/platform-auth'
|
||||
import { brandConfig } from '../../site-config'
|
||||
|
|
@ -6,6 +6,7 @@ import { buildSupportPath } from '../../site-routes'
|
|||
|
||||
const appLinks = [
|
||||
{ to: '/app', label: 'Overview', icon: Gauge, end: true },
|
||||
{ to: '/app/launch-status', label: 'Launch Status', icon: Landmark },
|
||||
{ to: '/app/downloads', label: 'Downloads', icon: MonitorSmartphone },
|
||||
{ to: '/app/browser-access', label: 'Browser Access', icon: PackageOpen },
|
||||
{ to: '/app/account', label: 'Account', icon: KeyRound },
|
||||
|
|
@ -53,6 +54,7 @@ export function AppShell() {
|
|||
Use the native Unreal runtime for actual simulator execution.
|
||||
</p>
|
||||
<ul className="list top-gap">
|
||||
<li><Link to="/app/launch-status">Protected launch status</Link></li>
|
||||
<li><Link to="/download">Public download posture</Link></li>
|
||||
<li><Link to="/open-source-notices">Public notices</Link></li>
|
||||
<li><Link to={buildSupportPath('operator-access')}>Operator access support</Link></li>
|
||||
|
|
|
|||
|
|
@ -370,6 +370,11 @@ type ProtectedReleaseAction = {
|
|||
primary?: boolean
|
||||
}
|
||||
|
||||
type ProtectedLaunchReadinessAction = {
|
||||
label: string
|
||||
to: string
|
||||
}
|
||||
|
||||
type ProtectedReleaseActionSurface = {
|
||||
badge: string
|
||||
tone: 'success' | 'info'
|
||||
|
|
@ -383,6 +388,7 @@ function buildProtectedSupportTopicActions(topicKey: string): readonly Protected
|
|||
switch (topicKey) {
|
||||
case 'launch-readiness':
|
||||
return [
|
||||
{ label: 'Open protected launch status', to: '/app/launch-status' },
|
||||
{ label: 'Open downloads', to: buildProtectedDownloadPath('windows') },
|
||||
{ label: 'Open notices', to: '/app/notices' },
|
||||
{ label: 'Open pricing', to: '/pricing' },
|
||||
|
|
@ -431,6 +437,79 @@ function ProtectedActionLink({
|
|||
)
|
||||
}
|
||||
|
||||
function ProtectedLaunchReadinessPanel({
|
||||
title,
|
||||
kicker,
|
||||
description,
|
||||
launchStatus,
|
||||
releaseManifestQuery,
|
||||
actions = [],
|
||||
}: {
|
||||
title: string
|
||||
kicker: string
|
||||
description?: string
|
||||
launchStatus: ReturnType<typeof resolvePublicLaunchStatusSummary>
|
||||
releaseManifestQuery: {
|
||||
isLoading: boolean
|
||||
isError: boolean
|
||||
}
|
||||
actions?: readonly ProtectedLaunchReadinessAction[]
|
||||
}) {
|
||||
const launchReadinessIssues = launchStatus.missingLabels
|
||||
|
||||
return (
|
||||
<Panel title={title} kicker={kicker}>
|
||||
{description ? <p>{description}</p> : null}
|
||||
<p className={`status-pill${launchStatus.ready ? ' status-pill--success' : ''}`}>
|
||||
{launchStatus.ready ? 'Launch-ready posture' : 'Preview posture'}
|
||||
</p>
|
||||
<ul className="list">
|
||||
{launchStatus.checklist.map((item) => (
|
||||
<li key={item.id}>
|
||||
{item.label}: {item.configured
|
||||
? (item.id === 'public-auth-runtime' ? 'production-ready' : 'configured')
|
||||
: (item.id === 'public-auth-runtime' ? 'local-or-mixed' : 'missing')}
|
||||
</li>
|
||||
))}
|
||||
<li>Operator checkout target: {launchStatus.targets.operatorCheckoutTarget || 'support fallback active'}</li>
|
||||
<li>Studio checkout target: {launchStatus.targets.studioCheckoutTarget || 'support fallback active'}</li>
|
||||
</ul>
|
||||
{releaseManifestQuery.isLoading ? (
|
||||
<p>Refreshing release-manifest download readiness from the auth server.</p>
|
||||
) : null}
|
||||
{releaseManifestQuery.isError ? (
|
||||
<ProtectedReleaseAuthorityNotice
|
||||
badge="Dashboard release fallback"
|
||||
title="Live release-manifest lookup failed."
|
||||
summary="Download readiness is currently using local fallback metadata rather than current runtime release authority."
|
||||
stillWorks={[
|
||||
'Protected launch-readiness interpretation, packaged proof, and account posture remain visible.',
|
||||
'The protected browser shell can still separate auth, package, runtime, and rollout work while release authority recovers.',
|
||||
]}
|
||||
actionTo="/app/downloads"
|
||||
actionLabel="Open downloads"
|
||||
/>
|
||||
) : null}
|
||||
{launchReadinessIssues.length > 0 ? (
|
||||
<p className="form-error">
|
||||
Public launch is not fully configured yet: {launchReadinessIssues.join('; ')}.
|
||||
</p>
|
||||
) : (
|
||||
<p>Core public release configuration is present for the current bounded website lane.</p>
|
||||
)}
|
||||
{actions.length > 0 ? (
|
||||
<div className="button-row top-gap">
|
||||
{actions.map((action) => (
|
||||
<Link key={`${title}-${action.label}`} className="button button--ghost" to={action.to}>
|
||||
{action.label}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
</Panel>
|
||||
)
|
||||
}
|
||||
|
||||
function describeReleaseTarget(
|
||||
platform: ReleaseManifestView['platforms'][number] | null | undefined,
|
||||
) {
|
||||
|
|
@ -751,6 +830,79 @@ function ProtectedReleaseActionPanel({
|
|||
)
|
||||
}
|
||||
|
||||
function ProtectedSupportTopicPanel({
|
||||
title,
|
||||
kicker,
|
||||
description,
|
||||
topicKey,
|
||||
}: {
|
||||
title: string
|
||||
kicker: string
|
||||
description: string
|
||||
topicKey: string
|
||||
}) {
|
||||
const topic = protectedSupportTopicGuides.find((item) => item.topicKey === topicKey)
|
||||
if (!topic) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Panel title={title} kicker={kicker}>
|
||||
<p>{description}</p>
|
||||
<div className="card-grid top-gap">
|
||||
<article className="card card--compact">
|
||||
<p className="status-pill status-pill--info">{topic.title}</p>
|
||||
<p>{topic.description}</p>
|
||||
<ul className="list top-gap">
|
||||
{topic.steps.map((step) => (
|
||||
<li key={step}>{step}</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="button-row top-gap">
|
||||
{topic.actions.map((action) => (
|
||||
<Link key={`${topic.topicKey}-${action.label}`} className="button button--ghost" to={action.to}>
|
||||
{action.label}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</Panel>
|
||||
)
|
||||
}
|
||||
|
||||
function ProtectedReleaseReferencesPanel({
|
||||
title,
|
||||
kicker,
|
||||
description,
|
||||
releaseManifest,
|
||||
}: {
|
||||
title: string
|
||||
kicker: string
|
||||
description: string
|
||||
releaseManifest: ReleaseManifestView
|
||||
}) {
|
||||
const supportEmail = releaseManifest.support_email || 'hello@hypertwist.app'
|
||||
|
||||
return (
|
||||
<Panel title={title} kicker={kicker}>
|
||||
<p>{description}</p>
|
||||
<ul className="list top-gap">
|
||||
<li>Public docs URL: {releaseManifest.public_docs_url || 'configure before launch'}</li>
|
||||
<li>Release notes URL: {releaseManifest.release_notes_url || 'configure before launch'}</li>
|
||||
<li>Corresponding-source URL: {releaseManifest.corresponding_source_url || 'configure before launch'}</li>
|
||||
<li>Public repository/notices URL: {releaseManifest.open_source_repo_url || 'configure before launch'}</li>
|
||||
<li>Operator support contact: {supportEmail}</li>
|
||||
</ul>
|
||||
<ReleaseAuthorityLinks
|
||||
releaseManifest={releaseManifest}
|
||||
includeProtectedNoticesLink
|
||||
includePublicNoticesLink
|
||||
/>
|
||||
</Panel>
|
||||
)
|
||||
}
|
||||
|
||||
function PackagedValidationPanel({
|
||||
title,
|
||||
kicker,
|
||||
|
|
@ -1055,8 +1207,6 @@ export function DashboardOverviewPage() {
|
|||
return `${baseUrl}/api/auth/desktop-link/verify?token=${encodeURIComponent(token)}`
|
||||
}, [desktopLinkMutation.data?.token])
|
||||
|
||||
const launchReadinessIssues = launchStatus.missingLabels
|
||||
|
||||
return (
|
||||
<>
|
||||
<SiteMetadata
|
||||
|
|
@ -1144,45 +1294,17 @@ export function DashboardOverviewPage() {
|
|||
releaseAuthorityUnavailable={releaseManifestQuery.isError}
|
||||
/>
|
||||
|
||||
<Panel title="Launch readiness" kicker="Public release configuration">
|
||||
<p className={`status-pill${launchStatus.ready ? ' status-pill--success' : ''}`}>
|
||||
{launchStatus.ready ? 'Launch-ready posture' : 'Preview posture'}
|
||||
</p>
|
||||
<ul className="list">
|
||||
{launchStatus.checklist.map((item) => (
|
||||
<li key={item.id}>
|
||||
{item.label}: {item.configured
|
||||
? (item.id === 'public-auth-runtime' ? 'production-ready' : 'configured')
|
||||
: (item.id === 'public-auth-runtime' ? 'local-or-mixed' : 'missing')}
|
||||
</li>
|
||||
))}
|
||||
<li>Operator checkout target: {launchStatus.targets.operatorCheckoutTarget || 'support fallback active'}</li>
|
||||
<li>Studio checkout target: {launchStatus.targets.studioCheckoutTarget || 'support fallback active'}</li>
|
||||
</ul>
|
||||
{releaseManifestQuery.isLoading ? (
|
||||
<p>Refreshing release-manifest download readiness from the auth server.</p>
|
||||
) : null}
|
||||
{releaseManifestQuery.isError ? (
|
||||
<ProtectedReleaseAuthorityNotice
|
||||
badge="Dashboard release fallback"
|
||||
title="Live release-manifest lookup failed."
|
||||
summary="Download readiness is currently using local fallback metadata rather than current runtime release authority."
|
||||
stillWorks={[
|
||||
'Protected launch-readiness interpretation, packaged proof, and account posture remain visible.',
|
||||
'The operator dashboard can still separate auth, package, runtime, and rollout work while release authority recovers.',
|
||||
]}
|
||||
actionTo="/app/downloads"
|
||||
actionLabel="Open downloads"
|
||||
/>
|
||||
) : null}
|
||||
{launchReadinessIssues.length > 0 ? (
|
||||
<p className="form-error">
|
||||
Public launch is not fully configured yet: {launchReadinessIssues.join('; ')}.
|
||||
</p>
|
||||
) : (
|
||||
<p>Core public release configuration is present for the current bounded website lane.</p>
|
||||
)}
|
||||
</Panel>
|
||||
<ProtectedLaunchReadinessPanel
|
||||
title="Launch readiness"
|
||||
kicker="Public release configuration"
|
||||
launchStatus={launchStatus}
|
||||
releaseManifestQuery={releaseManifestQuery}
|
||||
actions={[
|
||||
{ label: 'Open protected launch status', to: '/app/launch-status' },
|
||||
{ label: 'Open downloads', to: buildProtectedDownloadPath('windows') },
|
||||
{ label: 'Open notices', to: '/app/notices' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<ProtectedOperatorQuickRoutesPanel
|
||||
title="Protected operator quick routes"
|
||||
|
|
@ -1237,6 +1359,92 @@ export function DashboardOverviewPage() {
|
|||
)
|
||||
}
|
||||
|
||||
export function ProtectedLaunchStatusPage() {
|
||||
const {
|
||||
user,
|
||||
superTokensConfigured,
|
||||
releaseManifest,
|
||||
releaseManifestQuery,
|
||||
} = useProtectedReleaseSurface('launch-status')
|
||||
const healthQuery = useProtectedAuthHealthQuery('launch-status')
|
||||
|
||||
const launchStatus = useMemo(() => (
|
||||
resolvePublicLaunchStatusSummary(
|
||||
healthQuery.data,
|
||||
releaseManifestQuery.data?.manifest,
|
||||
launchReadiness,
|
||||
)
|
||||
), [healthQuery.data, releaseManifestQuery.data?.manifest])
|
||||
|
||||
return (
|
||||
<>
|
||||
<SiteMetadata
|
||||
title="HyperTwist protected launch status"
|
||||
description="Review the signed-in HyperTwist launch-readiness posture, release action, package proof, and rollout references."
|
||||
canonicalPath="/app/launch-status"
|
||||
robots="noindex,nofollow"
|
||||
/>
|
||||
<div className="panel-grid">
|
||||
<ProtectedAuthSessionAuthorityPanel
|
||||
title="Auth and session authority"
|
||||
kicker="Launch dependency"
|
||||
user={user}
|
||||
superTokensConfigured={superTokensConfigured}
|
||||
healthQuery={healthQuery}
|
||||
/>
|
||||
|
||||
<ProtectedLaunchReadinessPanel
|
||||
title="Protected launch status"
|
||||
kicker="Signed-in rollout authority"
|
||||
description="This signed-in route keeps the live launch checklist, current targets, and rollout blockers in one operator-facing surface instead of leaving launch authority distributed across the dashboard and public pages."
|
||||
launchStatus={launchStatus}
|
||||
releaseManifestQuery={releaseManifestQuery}
|
||||
actions={[
|
||||
{ label: 'Open downloads', to: buildProtectedDownloadPath('windows') },
|
||||
{ label: 'Open notices', to: '/app/notices' },
|
||||
{ label: 'Open public launch status', to: '/launch-status' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<ProtectedReleaseActionPanel
|
||||
title="Current release action"
|
||||
kicker="Protected access guidance"
|
||||
releaseManifest={releaseManifest}
|
||||
releaseAuthorityUnavailable={releaseManifestQuery.isError}
|
||||
/>
|
||||
|
||||
<PackagedValidationPanel
|
||||
title={protectedPackagedDesktopProofTitle}
|
||||
kicker="Desktop proof"
|
||||
description="This protected launch route keeps rollout status anchored to the same Windows higher-dimensional package proof used by the public launch lane and the signed-in dashboard."
|
||||
emptyMessage="The current protected launch-status route could not find a Windows release target, so packaged desktop evidence is unavailable here right now."
|
||||
releaseManifest={releaseManifest}
|
||||
/>
|
||||
|
||||
<ProtectedSupportTopicPanel
|
||||
title="Launch-readiness support lane"
|
||||
kicker="Signed-in escalation"
|
||||
description="When rollout work turns from checklist review into action, this protected lane keeps the next signed-in destinations explicit."
|
||||
topicKey="launch-readiness"
|
||||
/>
|
||||
|
||||
<ProtectedReleaseReferencesPanel
|
||||
title="Launch references and notices"
|
||||
kicker="Distribution follow-through"
|
||||
description="Rollout posture is only trustworthy when docs, release notes, corresponding source, public notices, and protected notices remain reachable from the same signed-in launch surface."
|
||||
releaseManifest={releaseManifest}
|
||||
/>
|
||||
|
||||
<ProtectedBrowserDesktopRealityPanel
|
||||
title="Protected browser-versus-desktop reality"
|
||||
kicker="Signed-in product boundary"
|
||||
description="Launch authority belongs to the browser shell because checkout, notices, and release references are browser-owned, while the real simulator still remains native and the XR/controller branch remains explicitly bounded."
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export function DownloadCenterPage() {
|
||||
const { user, canDownload, releaseManifest, releaseManifestQuery } = useProtectedReleaseSurface('protected')
|
||||
const [searchParams] = useSearchParams()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { Suspense, lazy } from 'react'
|
|||
import { GeneralPageLoader } from '../components/ui/Skeletons'
|
||||
|
||||
const DashboardOverviewPage = lazy(() => import('../pages/app-pages').then((m) => ({ default: m.DashboardOverviewPage })))
|
||||
const ProtectedLaunchStatusPage = lazy(() => import('../pages/app-pages').then((m) => ({ default: m.ProtectedLaunchStatusPage })))
|
||||
const DownloadCenterPage = lazy(() => import('../pages/app-pages').then((m) => ({ default: m.DownloadCenterPage })))
|
||||
const BrowserAccessPage = lazy(() => import('../pages/app-pages').then((m) => ({ default: m.BrowserAccessPage })))
|
||||
const AccountPage = lazy(() => import('../pages/app-pages').then((m) => ({ default: m.AccountPage })))
|
||||
|
|
@ -24,6 +25,12 @@ const protectedAppLoaders = {
|
|||
description:
|
||||
'Resolving entitled desktop targets, current package proof, and rollout references before the signed-in download surface opens.',
|
||||
},
|
||||
launchStatus: {
|
||||
title: 'Loading launch status...',
|
||||
eyebrow: 'Protected rollout authority',
|
||||
description:
|
||||
'Restoring the signed-in launch checklist, release references, and packaged proof before protected rollout follow-through resumes.',
|
||||
},
|
||||
browserAccess: {
|
||||
title: 'Loading browser access...',
|
||||
eyebrow: 'Protected browser shell',
|
||||
|
|
@ -75,6 +82,7 @@ export function AppRouteTree() {
|
|||
<Route element={<ProtectedRoute />}>
|
||||
<Route path="/app" element={<AppShell />}>
|
||||
<Route index element={withAppLoader(protectedAppLoaders.dashboard, <DashboardOverviewPage />)} />
|
||||
<Route path="launch-status" element={withAppLoader(protectedAppLoaders.launchStatus, <ProtectedLaunchStatusPage />)} />
|
||||
<Route path="downloads" element={withAppLoader(protectedAppLoaders.downloads, <DownloadCenterPage />)} />
|
||||
<Route path="browser-access" element={withAppLoader(protectedAppLoaders.browserAccess, <BrowserAccessPage />)} />
|
||||
<Route path="account" element={withAppLoader(protectedAppLoaders.account, <AccountPage />)} />
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ export const productSurfaceMatrixRows = [
|
|||
description: 'This is the account-aware browser lane for entitlement, auth health, billing posture, protected notices, and desktop pairing.',
|
||||
owns: [
|
||||
'Live session, billing, entitlement, and release-manifest viewer posture.',
|
||||
'A dedicated signed-in launch-status route for rollout blockers, packaged proof, and protected next-step interpretation.',
|
||||
'Desktop-link token issuance and protected follow-through after sign-in.',
|
||||
'Operator-facing release, notice, and download-center context that should not sit on public pages.',
|
||||
],
|
||||
|
|
@ -865,6 +866,11 @@ export const resourceCollections = [
|
|||
] as const
|
||||
|
||||
export const changelogEntries = [
|
||||
{
|
||||
date: 'June 27, 2026',
|
||||
title: 'Protected launch status now has its own signed-in authority route',
|
||||
details: 'The browser operator shell now exposes a dedicated `/app/launch-status` route for signed-in launch-readiness truth, release action, packaged desktop proof, notices references, and protected rollout next steps instead of collapsing that lane down to one dashboard panel.',
|
||||
},
|
||||
{
|
||||
date: 'June 27, 2026',
|
||||
title: 'Launch status now has its own canonical public authority route',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue