Files
Arcrun/landing/app/mira/layout.tsx
T
uncle6me-web 922a57fe34 arcrun — AI workflow execution engine (clean history)
Self-hosted 開源:WASM 零件 + recipe + cypher-executor,跑在你自己的 Cloudflare。

此為重建的乾淨歷史起點(移除曾誤 commit 的 GCP SA 金鑰,舊歷史保留在
richblack/arcrun 與本地 backup 分支)。含:
- acr init --self-hosted installer(建 KV/R2 + codeload 拉預編譯 wasm + wrangler deploy + seed recipe)
- recipe push 把關(資料外流提醒 + 打通檢查)
- 19 個正當零件預編譯 wasm(claude_api/km_writer/kbdb_upsert_block 排除:違反 DECISIONS §1)
- CLI / cypher-executor / registry / 完整 SDD

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 15:52:38 +08:00

88 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
// Mira 子應用 layout
// SDD: polaris/mira/.agents/specs/mira-app/design.md §5.5
// 規範:白名單 user 進得去;非白名單 user 看到「即將開放」頁
// middleware 已做未登入跳 /loginredirect=/mira 檢查(不在這裡重做)
import { useEffect, useState } from 'react';
import SiteNav from '../components/SiteNav';
import { MATRIX_APPS } from '../components/apps';
const API_BASE = process.env.NEXT_PUBLIC_API_BASE ?? 'https://cypher.arcrun.dev';
type Me = { email: string; display_name: string; api_key: string };
const MIRA = MATRIX_APPS.find(a => a.id === 'mira');
const ALLOWED = new Set(MIRA?.allowlist_emails ?? []);
export default function MiraLayout({ children }: { children: React.ReactNode }) {
const [me, setMe] = useState<Me | null | undefined>(undefined);
useEffect(() => {
fetch(`${API_BASE}/me`, { credentials: 'include' })
.then(r => r.ok ? r.json() as Promise<Me> : null)
.then(u => setMe(u))
.catch(() => setMe(null));
}, []);
if (me === undefined) {
return (
<>
<SiteNav currentPath="/mira" />
<div className="flex-1 flex items-center justify-center text-[#666]">載入中…</div>
</>
);
}
if (me === null) {
// 理論上 middleware 已擋住,但保險
if (typeof window !== 'undefined') {
window.location.href = '/login?redirect=/mira';
}
return null;
}
if (!ALLOWED.has(me.email)) {
return (
<>
<SiteNav currentPath="/mira" />
<BetaBlocked email={me.email} />
</>
);
}
return (
<>
<SiteNav currentPath="/mira" />
{children}
</>
);
}
function BetaBlocked({ email }: { email: string }) {
return (
<main className="flex-1 flex items-center justify-center px-6">
<div className="max-w-md text-center space-y-4">
<div className="text-6xl mb-2">🌊</div>
<h1 className="text-3xl font-bold text-white">Mira 仍封測中</h1>
<p className="text-[#888] leading-relaxed">
Mira arcrun 的個人化 KM 河道,目前僅開放給少數測試用戶。
</p>
<p className="text-sm text-[#555]">
你登入的帳號是 <span className="font-mono text-[#888]">{email}</span>
不在白名單內。準備好對外開放時會公告。
</p>
<div className="pt-4">
<a
href="/dashboard"
className="inline-block bg-indigo-600 hover:bg-indigo-500 text-white px-5 py-2 rounded-md text-sm font-medium transition-colors"
>
Dashboard
</a>
</div>
</div>
</main>
);
}