From 145a8c1021b1faaa581e380407f51b6c3e6e3a12 Mon Sep 17 00:00:00 2001 From: a2a-cloud Date: Sat, 18 Jul 2026 09:22:32 +0000 Subject: [PATCH] a2a-source-edit: write frontend/src/App.jsx --- frontend/src/App.jsx | 268 ++++++++++++++++++++++++++----------------- 1 file changed, 160 insertions(+), 108 deletions(-) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 5b15a4a..8b04a9d 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,66 +1,60 @@ import { useEffect, useMemo, useState } from "react"; -import { - callSkill, - loadAgentConfig, - loadSession, - sampleArgs, - signInUrl, -} from "./a2a.js"; +import { callSkill, loadAgentConfig, loadSession, signInUrl } from "./a2a.js"; + +const DEFAULT_AUDIT_ID = "studio-launch-v1"; +const DEFAULT_URL = "https://example.com"; + +function statusText(result) { + if (!result) return "No report yet"; + if (!result.ok) return result.code || "Audit failed"; + const score = result.report?.summary?.score; + return typeof score === "number" ? `${score}/100 readiness` : "Report ready"; +} + +function CheckRow({ label, value }) { + return ( +
  • + {value ? "✓" : "!"} + {label} +
  • + ); +} export function App() { const [config, setConfig] = useState(null); const [session, setSession] = useState(null); - const [selectedSkillName, setSelectedSkillName] = useState(""); - const [argsText, setArgsText] = useState("{}"); + const [auditId, setAuditId] = useState(DEFAULT_AUDIT_ID); + const [url, setUrl] = useState(DEFAULT_URL); const [result, setResult] = useState(null); const [error, setError] = useState(null); const [running, setRunning] = useState(false); + const [loadingReport, setLoadingReport] = useState(false); useEffect(() => { loadAgentConfig() - .then((data) => { + .then(async (data) => { setConfig(data); - const firstSkill = data.skills?.[0]; - if (firstSkill) { - setSelectedSkillName(firstSkill.name); - setArgsText(JSON.stringify(sampleArgs(firstSkill), null, 2)); - } - return loadSession(data).catch(() => null); + const sessionData = await loadSession(data).catch(() => null); + setSession(sessionData); }) - .then((sessionData) => setSession(sessionData)) .catch((err) => setError(err.message || String(err))); }, []); - const selectedSkill = useMemo( - () => config?.skills?.find((skill) => skill.name === selectedSkillName), - [config, selectedSkillName], - ); + const needsSignIn = Boolean(config?.auth?.invokeRequiresSession && session && !session.authenticated); + const signInHref = useMemo(() => (config && needsSignIn ? signInUrl(config) : null), [config, needsSignIn]); + const report = result?.report; + const checks = report?.checks || {}; + const evidence = report?.evidence || {}; - const needsSignIn = Boolean( - config?.auth?.invokeRequiresSession && session && !session.authenticated, - ); - const signInHref = useMemo( - () => (config && needsSignIn ? signInUrl(config) : null), - [config, needsSignIn], - ); - - function selectSkill(skill) { - setSelectedSkillName(skill.name); - setArgsText(JSON.stringify(sampleArgs(skill), null, 2)); - setResult(null); - setError(null); - } - - async function runSkill(event) { + async function runAudit(event) { event.preventDefault(); - if (!config || !selectedSkill) return; + if (!config) return; setRunning(true); setError(null); - setResult(null); try { - const args = JSON.parse(argsText || "{}"); - const data = await callSkill(config, selectedSkill.name, args); + const data = await callSkill(config, "audit_url", { audit_id: auditId.trim(), url: url.trim() }); setResult(data); + if (!data.ok) setError(data.message || data.code || "Audit rejected."); } catch (err) { setError(err.message || String(err)); } finally { @@ -68,90 +62,148 @@ export function App() { } } + async function reopenAudit() { + if (!config) return; + setLoadingReport(true); + setError(null); + try { + const data = await callSkill(config, "get_audit", { audit_id: auditId.trim() }); + setResult(data); + if (!data.ok) setError(data.message || data.code || "No saved report found."); + } catch (err) { + setError(err.message || String(err)); + } finally { + setLoadingReport(false); + } + } + if (!config) { return (
    -

    {error || "Loading A2A agent contract..."}

    +

    {error || "Loading LaunchCheck..."}

    ); } return ( -
    - + -
    -
    -
    -

    Skill runner

    -

    {selectedSkill?.name || "No skills found"}

    -
    - - Docs - -
    +
    +

    Readiness checks

    + {report ? ( +
      + + + + + + + +
    + ) : ( +

    No checks yet.

    + )} +
    - {selectedSkill ? ( -
    -