2026-11-08 17:26:51 +00:00
const COUNTED = { ask : "asks" , review : "reviews" , decision : "decisions" };
2026-11-07 18:14:21 +00:00
function ruleRequestBody ( item ) {
const rule = item . rule ;
const dry = item . dry_run ;
2026-11-08 17:26:51 +00:00
const pairs = [[ "Kind" , RULE_KINDS [ rule . kind ]], rule . kind === "ask" ? [ "Tool (glob)" , rule . tool ] : null , [ "Pattern (glob)" , rule . pattern ], rule . kind === "decision" ? null : [ "Directory (glob)" , rule . scope ], [ "Expires on" , absolute . format ( stampOf ( rule . expires ))]];
2026-11-07 18:14:21 +00:00
return h ( "div" , { class : "rule-request" },
item . detail ? h ( "p" , { class : "text" }, item . detail ) : null ,
meta ( pairs . filter ( Boolean )),
2026-11-08 17:26:51 +00:00
h ( "p" , { class : "muted dry-run-count" }, "Dry run: the rule would have granted " , h ( "strong" , {}, ` ${ dry . matched } of ${ dry . total } ` ), ` ${ COUNTED [ rule . kind ] } from the last ${ dry . days } days.` ),
2026-11-07 18:14:21 +00:00
h ( "p" , { class : "muted" }, RULE_HINTS [ rule . kind ]));
}
async function acceptRule ( item ) {
2026-11-08 17:26:51 +00:00
const label = `Rule: ${ short ( item . title ) } ` ;
2026-11-07 18:14:21 +00:00
ui . busy = true ;
const prepared = await sendJson ( `/api/rule-requests/ ${ encodeURIComponent ( item . id ) } /sign` , {});
const signed = prepared . ok && prepared . data ? await assertion ( prepared . data , label ) : null ;
if ( ! prepared . ok || ! prepared . data ) {
2026-11-08 17:26:51 +00:00
toast ( ` ${ label } : not possible` , fail ( prepared ), false );
2026-11-07 18:14:21 +00:00
}
const result = signed ? await sendJson ( `/api/rule-requests/ ${ encodeURIComponent ( item . id ) } /accept` , { rule : prepared . data . payload , assertion : signed }) : null ;
ui . busy = false ;
if ( result ) {
2026-11-08 17:26:51 +00:00
toast ( result . ok ? `Created: ${ short ( item . title ) } ` : ` ${ label } : not created` , result . ok ? [] : fail ( result ), result . ok );
2026-11-07 18:14:21 +00:00
}
await load ();
}