const KEY='commandlayer.buildPlan.v1';const itemsEl=document.getElementById('buildItems');const toast=document.getElementById('toast');const exportBox=document.getElementById('exportBox');function getPlan(){try{return JSON.parse(localStorage.getItem(KEY)||'[]')}catch{return[]}}function selectedIds(){const ids=getPlan().map(x=>x.id);return ids.length?ids:['trust-verification']}function setPlan(plan){localStorage.setItem(KEY,JSON.stringify(plan));renderPlan()}function showToast(msg){toast.textContent=msg;toast.classList.add('show');setTimeout(()=>toast.classList.remove('show'),1800)}function renderPlan(){const plan=getPlan();itemsEl.innerHTML='';if(!plan.length){itemsEl.innerHTML='<span class="build-empty">No capabilities selected yet.</span>';return}plan.forEach(item=>{const tag=document.createElement('span');tag.className='build-tag';tag.textContent=item.name;const btn=document.createElement('button');btn.type='button';btn.textContent='×';btn.setAttribute('aria-label','Remove '+item.name);btn.onclick=()=>setPlan(getPlan().filter(x=>x.id!==item.id));tag.appendChild(btn);itemsEl.appendChild(tag)})}function snippetFor(verb){return `const { output, receipt } = await cl.wrap("${verb}", async () => {\n return { ok: true };\n});`}function buildManifest(){const selected=getPlan();return {type:'commandlayer.capability_build_plan',version:'1.0.0',created_at:new Date().toISOString(),selected_capability_groups:selected,runtime:'https://runtime.commandlayer.org',verifier:'runtime /verify or configured verifier',proof_model:'metadata.proof'}}function agentCard(){return {type:'commandlayer.agent_card',version:'1.0.0',name:'runtime.commandlayer.eth',capabilities:selectedIds(),verifier:'/api/verify',generated_at:new Date().toISOString(),note:'Draft agent card generated locally from the selected capability build plan.'}}function ensRecords(){const caps=selectedIds().join(',');return [`cl.capabilities=${caps}`,'cl.verifier=https://www.commandlayer.org/api/verify','cl.sig.pub=ed25519:<public-key>','cl.sig.kid=vC4WbcNoq2znSCiQ','cl.sig.canonical=json.sorted_keys.v1','cl.receipt.signer=runtime.commandlayer.eth','agent-endpoint[mcp]=https://mcp.commandlayer.org/mcp'].join('\n')}function discoverySurface(){return {type:'commandlayer.discovery_surface_draft',version:'1.0.0',capabilities:selectedIds(),tools:['clas.trust-verification.verify','clas.trust-verification.sign','clas.trust-verification.attest','clas.trust-verification.authorize','clas.trust-verification.approve','clas.trust-verification.reject','clas.trust-verification.permit','clas.trust-verification.grant','clas.trust-verification.authenticate','clas.trust-verification.endorse'],bridge_note:'MCP is a bridge. Runtime signs. Verifier validates.',verification_endpoint:'/api/verify',generated_at:new Date().toISOString()}}function sdkConfig(){return `import { CommandLayer } from "@commandlayer/agent-sdk";\n\nconst cl = new CommandLayer({\n agent: "runtime.commandlayer.eth",\n privateKeyPem: process.env.CL_PRIVATE_KEY_PEM,\n keyId: "vC4WbcNoq2znSCiQ"\n});\n\nconst capabilities = ${JSON.stringify(getPlan().map(x=>x.id),null,2)};\n\nexport { cl, capabilities };`}function showExport(value){const text=typeof value==='string'?value:JSON.stringify(value||buildManifest(),null,2);exportBox.textContent=text;exportBox.classList.add('show');return text}async function copyOutput(label,value){await navigator.clipboard.writeText(showExport(value));showToast(label+' copied')}document.querySelectorAll('[data-add-plan]').forEach(btn=>btn.addEventListener('click',()=>{const card=btn.closest('.cap-card');const item={id:card.dataset.capId,name:card.dataset.capName,status:card.dataset.status||'planned',manifest:card.dataset.manifest||null,default_verb:card.dataset.snippet||null};const plan=getPlan();if(!plan.find(x=>x.id===item.id)){plan.push(item);setPlan(plan);showToast(item.name+' added to build plan')}else showToast(item.name+' is already in your build plan')}));document.querySelectorAll('[data-copy-snippet]').forEach(btn=>btn.addEventListener('click',async()=>{const verb=btn.closest('.cap-card').dataset.snippet||'verify';await navigator.clipboard.writeText(snippetFor(verb));showToast('SDK snippet copied for '+verb)}));document.getElementById('clearPlanBtn').onclick=()=>{setPlan([]);exportBox.classList.remove('show');showToast('Build plan cleared')};document.getElementById('exportManifestBtn').onclick=()=>{const json=showExport(buildManifest());const blob=new Blob([json],{type:'application/json'});const url=URL.createObjectURL(blob);const a=document.createElement('a');a.href=url;a.download='commandlayer-build-plan.json';a.click();URL.revokeObjectURL(url);showToast('Build plan manifest exported')};document.getElementById('copyManifestBtn').onclick=()=>copyOutput('Build plan JSON',buildManifest());document.getElementById('copySdkConfigBtn').onclick=()=>copyOutput('SDK config',sdkConfig());document.getElementById('copyAgentCardBtn').onclick=()=>copyOutput('Agent card',agentCard());document.getElementById('copyEnsBtn').onclick=()=>copyOutput('ENS records',ensRecords());document.getElementById('copyDiscoveryBtn').onclick=()=>copyOutput('MCP surface draft',discoverySurface());document.getElementById('addTrustBtn').onclick=()=>{const btn=document.querySelector('[data-cap-id="trust-verification"] [data-add-plan]');if(btn)btn.click()};renderPlan();
0 commit comments