// /docs — documentation page

const DOC_NAV = [
  { h: "Getting started", items: [
    { id: "intro",        label: "Introduction" },
    { id: "install",      label: "Installation" },
    { id: "quickstart",   label: "Quickstart" },
    { id: "concepts",     label: "Core concepts" },
  ]},
  { h: "Scanners", items: [
    { id: "agentscan",    label: "AgentScan" },
    { id: "reposcan",     label: "RepoScan" },
    { id: "scoring",      label: "Trust scoring" },
    { id: "findings",     label: "Findings & severity" },
  ]},
  { h: "Registry & Hub", items: [
    { id: "registry",     label: "Registry" },
    { id: "providerhub",  label: "ProviderHub" },
    { id: "alerts",       label: "Alerts & webhooks" },
  ]},
  { h: "Reference", items: [
    { id: "api",          label: "REST API" },
    { id: "cli",          label: "CLI" },
    { id: "onchain",      label: "On-chain reports" },
  ]},
];

const DocsApp = () => {
  const [active, setActive] = React.useState("intro");
  React.useEffect(() => {
    const ids = DOC_NAV.flatMap(g => g.items.map(i => i.id));
    const obs = new IntersectionObserver(entries => {
      entries.forEach(e => {
        if (e.isIntersecting) setActive(e.target.id);
      });
    }, { rootMargin: "-30% 0px -60% 0px", threshold: 0 });
    ids.forEach(id => { const el = document.getElementById(id); if (el) obs.observe(el); });
    return () => obs.disconnect();
  }, []);

  return (
    <>
      <Nav active="Docs"/>
      <div className="wrap doc-shell">
        <aside className="doc-side">
          <div style={{display:"flex", alignItems:"center", gap:8, marginBottom:18}}>
            <Icon name="doc" size={14}/>
            <span className="serif" style={{fontSize: 16}}>Documentation</span>
          </div>
          {DOC_NAV.map(g => (
            <div key={g.h}>
              <div className="doc-side-h">{g.h}</div>
              {g.items.map(i => (
                <a key={i.id} href={`#${i.id}`}
                   className={active === i.id ? "active" : ""}>{i.label}</a>
              ))}
            </div>
          ))}
        </aside>

        <article className="doc-body">
          <span className="tag">v0.42 · 2026-05-13</span>
          <h1 className="serif" style={{marginTop:10}}>Lumiscan <span className="serif-i">documentation.</span></h1>
          <p>Everything you need to scan, register, and monitor autonomous agents on Solana.</p>

          <section id="intro" style={{scrollMarginTop:90}}>
            <h2>Introduction</h2>
            <p>Lumiscan is a security and trust layer for the Solana agent economy. It bundles four interlocking products:</p>
            <ul style={{color:"var(--text-dim)", lineHeight:1.75, paddingLeft:22}}>
              <li><b style={{color:"var(--green)"}}>AgentScan</b> — autonomous vulnerability prober for deployed agents.</li>
              <li><b style={{color:"var(--green)"}}>RepoScan</b> — static auditor for Solana programs and agent codebases.</li>
              <li><b style={{color:"#c79bff"}}>Registry</b> — live, queryable index of every audited agent.</li>
              <li><b style={{color:"#c79bff"}}>ProviderHub</b> — uptime and latency monitor for agent endpoints.</li>
            </ul>
            <p>All four share a single trust score, a single report format, and a single signed on-chain attestation. Build with any of them; integrate one and the rest come for free.</p>
          </section>

          <section id="install" style={{scrollMarginTop:90}}>
            <h2>Installation</h2>
            <p>Lumiscan ships as a Node/TypeScript SDK, a Rust crate, and a thin CLI. Pick whichever fits your stack:</p>
            <div className="code-block">
<span className="c"># npm / pnpm / bun</span>
<span className="k">pnpm add</span> @lumiscan/sdk

<span className="c"># cargo</span>
<span className="k">cargo add</span> lumiscan

<span className="c"># cli (homebrew)</span>
<span className="k">brew install</span> lumiscan/tap/lumi
            </div>
            <p>The CLI authenticates through a per-wallet keypair — no API key juggling. Run <span className="inline-code">lumi login</span> once and you're set.</p>
          </section>

          <section id="quickstart" style={{scrollMarginTop:90}}>
            <h2>Quickstart</h2>
            <p>Probe any deployed Solana agent in 30 seconds:</p>
            <div className="code-block">
<span className="k">import</span> {"{"} Lumiscan {"}"} <span className="k">from</span> <span className="s">"@lumiscan/sdk"</span>;

<span className="k">const</span> lumi = <span className="k">new</span> <span className="f">Lumiscan</span>({"{"} cluster: <span className="s">"mainnet-beta"</span> {"}"});

<span className="k">const</span> report = <span className="k">await</span> lumi.<span className="f">agentScan</span>({"{"}
  address: <span className="s">"sol1jit72b9k4...9xQ"</span>,
  depth:   <span className="s">"deep"</span>,        <span className="c">// shallow | standard | deep</span>
  battery: [<span className="s">"prompt"</span>, <span className="s">"signer"</span>, <span className="s">"tools"</span>],
{"}"});

console.<span className="f">log</span>(report.trustScore);   <span className="c">// → 72</span>
console.<span className="f">log</span>(report.findings);     <span className="c">// → [{"{"} severity, kind, location, ... {"}"}]</span>
console.<span className="f">log</span>(report.attestation);  <span className="c">// → on-chain pubkey of signed report</span>
            </div>
            <p>Every report is signed by a Lumiscan oracle keypair and posted to mainnet as a memo + PDA — third parties can verify a score without trusting your frontend.</p>
          </section>

          <section id="concepts" style={{scrollMarginTop:90}}>
            <h2>Core concepts</h2>
            <h3>Trust score</h3>
            <p>A 0–100 score combining four sub-scores: prompt safety, signer hygiene, tool surface, and treasury exposure. Anything &lt;60 is flagged.</p>
            <h3>Findings</h3>
            <p>Issues are graded <span className="tag">info</span> <span className="tag amber">warning</span> <span className="tag" style={{background:"rgba(255,93,93,0.16)",color:"#ff5d5d"}}>critical</span>. Critical findings block registry inclusion until resolved.</p>
            <h3>Attestation</h3>
            <p>Every report is anchored on-chain via a PDA derived from <span className="inline-code">(report_hash, oracle_pk)</span>. Wallets can verify a score in a single RPC call.</p>
          </section>

          <section id="agentscan" style={{scrollMarginTop:90}}>
            <h2>AgentScan</h2>
            <p>AgentScan spins up an isolated devnet wallet, mirrors the target agent's tool surface, and runs an adversarial battery of probes against it. The wallet is funded with a small SOL balance to allow the agent to make realistic decisions.</p>
            <h3>Probe batteries</h3>
            <p>Each scan runs ~94 tests across three batteries:</p>
            <div className="code-block">
prompt    <span className="c">// 64 tests: system override, role inversion, exfiltration,</span>
          <span className="c">//          context smuggle, confused deputy</span>
signer    <span className="c">// 18 tests: seed leak, sig reuse, nonce replay, key handling</span>
tools     <span className="c">// 12 tests: per-tool param fuzzing, rate-limit, slippage</span>
            </div>
          </section>

          <section id="reposcan" style={{scrollMarginTop:90}}>
            <h2>RepoScan</h2>
            <p>RepoScan ingests a GitHub URL or anchor program address, indexes the source, and compares it against 814k+ known Solana programs. It produces an <i>authenticity</i> score, a <i>similarity</i> percentage, and a list of provenance findings.</p>
            <div className="code-block">
<span className="k">await</span> lumi.<span className="f">repoScan</span>({"{"}
  url: <span className="s">"github.com/jito-foundation/agent-program"</span>,
  ref: <span className="s">"main"</span>,
{"}"});
            </div>
          </section>

          <section id="scoring" style={{scrollMarginTop:90}}>
            <h2>Trust scoring</h2>
            <p>The composite trust score is a weighted sum:</p>
            <div className="code-block">
score = 0.35 * prompt
      + 0.25 * signer
      + 0.20 * tools
      + 0.20 * treasury
            </div>
            <p>Weights are tunable per-integration. A DEX router may weight tools higher; a lending agent may weight treasury higher.</p>
          </section>

          <section id="findings" style={{scrollMarginTop:90}}>
            <h2>Findings & severity</h2>
            <p>Each finding has a stable <span className="inline-code">kind</span> identifier so you can suppress, snooze, or accept it across re-scans. The full taxonomy is published at <a href="#" style={{color:"var(--green)"}}>lumiscan.app/taxonomy</a>.</p>
          </section>

          <section id="registry" style={{scrollMarginTop:90}}>
            <h2>Registry</h2>
            <p>The Registry is a public, paginated index of every agent that has passed an AgentScan with score ≥ 60. Agents re-audit every 24 hours; expired audits are flagged.</p>
            <div className="code-block">
<span className="k">const</span> agents = <span className="k">await</span> lumi.registry.<span className="f">list</span>({"{"}
  minScore: <span className="n">80</span>,
  capability: <span className="s">"swap"</span>,
  sort: <span className="s">"score:desc"</span>,
{"}"});
            </div>
          </section>

          <section id="providerhub" style={{scrollMarginTop:90}}>
            <h2>ProviderHub</h2>
            <p>Register any HTTP or RPC endpoint your agent exposes. ProviderHub pings from 14 global regions, records latency percentiles, and fires webhooks on degradation.</p>
            <div className="code-block">
<span className="k">await</span> lumi.providerHub.<span className="f">register</span>({"{"}
  url:    <span className="s">"https://agent.driftprotocol.io/mcp"</span>,
  agent:  <span className="s">"drift-mm.agent"</span>,
  alerts: {"{"} email: <span className="s">"ops@drift.foo"</span>, sla: <span className="n">99.9</span> {"}"},
{"}"});
            </div>
          </section>

          <section id="alerts" style={{scrollMarginTop:90}}>
            <h2>Alerts & webhooks</h2>
            <p>Three delivery channels: email, webhook, and Discord. Webhooks ship a signed JSON payload with the offending probe, latency series, and a link to the report.</p>
            <h3>Webhook signature</h3>
            <p>Verify the <span className="inline-code">X-Lumiscan-Signature</span> header against your secret using ed25519.</p>
          </section>

          <section id="api" style={{scrollMarginTop:90}}>
            <h2>REST API</h2>
            <p>Base URL: <span className="inline-code">https://api.lumiscan.app/v1</span></p>
            <div className="code-block">
POST /agent-scan        <span className="c">// kick off a probe</span>
GET  /agent-scan/:id    <span className="c">// poll status / fetch report</span>
GET  /registry          <span className="c">// list agents</span>
GET  /registry/:address <span className="c">// fetch single agent</span>
POST /provider-hub      <span className="c">// register endpoint</span>
GET  /provider-hub/:id  <span className="c">// metrics</span>
            </div>
          </section>

          <section id="cli" style={{scrollMarginTop:90}}>
            <h2>CLI</h2>
            <div className="code-block">
lumi agent probe &lt;address&gt;       <span className="c"># run an AgentScan</span>
lumi repo  scan  &lt;url&gt;           <span className="c"># run a RepoScan</span>
lumi registry list --min 80     <span className="c"># browse registry</span>
lumi hub register &lt;url&gt;          <span className="c"># add an endpoint</span>
lumi hub watch                  <span className="c"># tail uptime live</span>
            </div>
          </section>

          <section id="onchain" style={{scrollMarginTop:90}}>
            <h2>On-chain reports</h2>
            <p>Every report PDA carries a 32-byte report hash, a 32-byte oracle pubkey, a score byte, and a unix timestamp. Wallets can verify a score with one <span className="inline-code">getAccountInfo</span> call — no Lumiscan server required.</p>
            <div className="code-block">
<span className="k">struct</span> <span className="f">LumiReport</span> {"{"}
    report_hash: [<span className="k">u8</span>; <span className="n">32</span>],
    oracle_pk:   <span className="f">Pubkey</span>,
    score:       <span className="k">u8</span>,
    issued_at:   <span className="k">i64</span>,
    expires_at:  <span className="k">i64</span>,
{"}"}
            </div>
            <p style={{marginTop: 48, padding:18, background:"var(--bg-elev)", border:"1px solid var(--border)", borderRadius:10, fontSize:13.5}}>
              ▸ Ready to build? See the <a href="sdk.html" style={{color:"var(--green)"}}>SDK reference</a> for typed bindings and end-to-end examples.
            </p>
          </section>
        </article>
      </div>
      <Footer/>
    </>
  );
};

ReactDOM.createRoot(document.getElementById("root")).render(<DocsApp/>);
