constid=agentGrantField(grid,'Stable grant identifier');id.value=grant.id;id.maxLength=80;id.readOnly=agentGrantsPublishedIds.has(grant.id);id.disabled=!agentGrantsEditable;id.addEventListener('input',()=>{grant.id=id.value.trim();changedAgentGrants();});
constscopeBox=document.createElement('fieldset');constscopeLegend=document.createElement('legend');scopeLegend.textContent='Additional capability limit';scopeBox.append(scopeLegend);constscopeHelp=document.createElement('p');scopeHelp.className='muted';scopeHelp.textContent='History reads and navigation require separate capabilities. Window controls are limited to supported browser operations. All granted capabilities remain restricted by the central baseline, destination rules and DLP.';scopeBox.append(scopeHelp);constscopes=document.createElement('div');scopes.className='checks';scopeBox.append(scopes);box.append(scopeBox);
constactions=document.createElement('div');actions.className='row';constgeneration=document.createElement('span');generation.textContent=`Credential generation: ${grant.generation}`;constrotate=document.createElement('button');rotate.type='button';rotate.className='secondary';rotate.textContent='Invalidate previous credentials';rotate.disabled=!agentGrantsEditable||grant.generation>=Number.MAX_SAFE_INTEGER;rotate.addEventListener('click',()=>{grant.generation+=1;renderAgentGrants();changedAgentGrants();agentGrantStatus('Credential generation changed in draft. Publish after review, then pair this identity again locally.');});constrevoke=document.createElement('button');revoke.type='button';revoke.className='danger';revoke.textContent='Revoke grant';revoke.disabled=!agentGrantsEditable||!grant.enabled;revoke.addEventListener('click',()=>{grant.enabled=false;renderAgentGrants();changedAgentGrants();agentGrantStatus('Grant disabled in draft. Publish after review to apply revocation.');});actions.append(generation,rotate,revoke);
functionfillAgentGrants(p){agentGrantsDraft=structuredClone(p.agents.grants||[]);agentGrantsPublishedIds=newSet((publishedSnapshot?.agents?.grants||p.agents.grants||[]).map(g=>g.id));$('agent-identity-mode').value=p.agents.identityMode||'legacy';renderAgentGrants();agentGrantStatus('Agent identity changes require normal signed publication and review.');}
$('agent-grant-add').addEventListener('click',()=>{if(!agentGrantsEditable||agentGrantsDraft.length>=32)return;agentGrantsDraft.push({id:`agent-${crypto.randomUUID()}`,name:'New agent',enabled:false,expiresAt:newDate(Date.now()+86400000).toISOString(),scopes:[],allowedHosts:[],generation:1});renderAgentGrants();changedAgentGrants();agentGrantStatus('New grant starts disabled with no capabilities. Set expiry and permissions before enabling and publishing.');});