@wenathlan/extension 1.1.62 → 1.1.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +5 -3
  2. package/dist/environments.d.ts +10 -0
  3. package/dist/environments.d.ts.map +1 -1
  4. package/dist/index.d.ts +4 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +956 -1
  7. package/dist/index.js.map +4 -4
  8. package/dist/memory.d.ts +126 -1
  9. package/dist/memory.d.ts.map +1 -1
  10. package/dist/planreview.d.ts +87 -0
  11. package/dist/planreview.d.ts.map +1 -0
  12. package/dist/policy.d.ts +101 -0
  13. package/dist/policy.d.ts.map +1 -1
  14. package/dist/protocol.d.ts +135 -0
  15. package/dist/protocol.d.ts.map +1 -1
  16. package/dist/sessioninterface.d.ts +213 -0
  17. package/dist/sessioninterface.d.ts.map +1 -0
  18. package/dist/surfaces.d.ts +59 -0
  19. package/dist/surfaces.d.ts.map +1 -0
  20. package/dist/types.d.ts +376 -3
  21. package/dist/types.d.ts.map +1 -1
  22. package/dist/version.d.ts +1 -1
  23. package/extension/dist/background.js +1394 -2
  24. package/extension/dist/background.js.map +4 -4
  25. package/extension/dist/dashboardpage.html +13 -0
  26. package/extension/dist/dashboardpage.js +129 -0
  27. package/extension/dist/dashboardpage.js.map +7 -0
  28. package/extension/dist/manifest.json +5 -2
  29. package/extension/dist/offscreen.js +5 -0
  30. package/extension/dist/offscreen.js.map +2 -2
  31. package/extension/dist/optionspage.html +14 -0
  32. package/extension/dist/optionspage.js +118 -0
  33. package/extension/dist/optionspage.js.map +7 -0
  34. package/extension/dist/pagebridge.js.map +1 -1
  35. package/extension/dist/popup.html +4 -1
  36. package/extension/dist/popup.js +193 -0
  37. package/extension/dist/popup.js.map +3 -3
  38. package/extension/dist/sidepanel.html +7 -2
  39. package/extension/dist/sidepanel.js +693 -219
  40. package/extension/dist/sidepanel.js.map +3 -3
  41. package/extension/dist/transparencypage.html +1 -0
  42. package/extension/dist/transparencypage.js +42 -0
  43. package/extension/dist/transparencypage.js.map +2 -2
  44. package/extension/manifest.json +5 -2
  45. package/package.json +1 -1
@@ -781,10 +781,10 @@ function renderreader(capture) {
781
781
  title.textContent = `${capture.article.title || "Untitled"}${capture.article.byline ? ` \xB7 ${capture.article.byline}` : ""} \xB7 ${capture.article.words} words \xB7 ${capture.article.blocks.length} blocks`;
782
782
  readerroot.append(title);
783
783
  for (const block of capture.article.blocks.slice(0, 40)) {
784
- const line = document.createElement("p");
785
- line.className = /^h\d$/.test(block.kind) ? "readerblock heading" : "readerblock";
786
- line.textContent = `${block.kind}: ${block.text.slice(0, 200)}`;
787
- readerroot.append(line);
784
+ const line2 = document.createElement("p");
785
+ line2.className = /^h\d$/.test(block.kind) ? "readerblock heading" : "readerblock";
786
+ line2.textContent = `${block.kind}: ${block.text.slice(0, 200)}`;
787
+ readerroot.append(line2);
788
788
  }
789
789
  }
790
790
  function renderdetections(plan, outcomes) {
@@ -978,9 +978,9 @@ function rendernavigation(context) {
978
978
  title.textContent = `${list.links.length} curated url${list.links.length === 1 ? "" : "s"}${list.reviewedat ? " \xB7 opened after review" : " \xB7 waiting for review"}`;
979
979
  card.append(title);
980
980
  for (const link of list.links.slice(0, 8)) {
981
- const line = document.createElement("p");
982
- line.textContent = `${link.verdict === "safe" ? "\u2713" : "\u2717"} ${link.url}${link.reasons.length > 0 ? ` \xB7 ${link.reasons.join("; ")}` : ""}`;
983
- card.append(line);
981
+ const line2 = document.createElement("p");
982
+ line2.textContent = `${link.verdict === "safe" ? "\u2713" : "\u2717"} ${link.url}${link.reasons.length > 0 ? ` \xB7 ${link.reasons.join("; ")}` : ""}`;
983
+ card.append(line2);
984
984
  }
985
985
  navigationroot.append(card);
986
986
  }
@@ -1471,13 +1471,13 @@ function renderdatasets(context) {
1471
1471
  const sorted = sortrows(datasetvalue.rows.slice(0, 5), column.key, cell.dataset.sorted === "asc" ? "desc" : "asc");
1472
1472
  cell.dataset.sorted = cell.dataset.sorted === "asc" ? "desc" : "asc";
1473
1473
  body2.replaceChildren(...sorted.map((row) => {
1474
- const line = document.createElement("tr");
1474
+ const line2 = document.createElement("tr");
1475
1475
  for (const columnspec of datasetvalue.columns.slice(0, 6)) {
1476
1476
  const value = document.createElement("td");
1477
1477
  value.textContent = row[columnspec.key] ?? "";
1478
- line.append(value);
1478
+ line2.append(value);
1479
1479
  }
1480
- return line;
1480
+ return line2;
1481
1481
  }));
1482
1482
  });
1483
1483
  headerrow.append(cell);
@@ -1485,13 +1485,13 @@ function renderdatasets(context) {
1485
1485
  grid.append(headerrow);
1486
1486
  const body = document.createElement("tbody");
1487
1487
  for (const row of datasetvalue.rows.slice(0, 5)) {
1488
- const line = document.createElement("tr");
1488
+ const line2 = document.createElement("tr");
1489
1489
  for (const column of datasetvalue.columns.slice(0, 6)) {
1490
1490
  const cell = document.createElement("td");
1491
1491
  cell.textContent = row[column.key] ?? "";
1492
- line.append(cell);
1492
+ line2.append(cell);
1493
1493
  }
1494
- body.append(line);
1494
+ body.append(line2);
1495
1495
  }
1496
1496
  grid.append(body);
1497
1497
  card.append(grid);
@@ -2618,10 +2618,10 @@ function renderconsolediff() {
2618
2618
  headline.textContent = `Run ${lastdiff.base} became run ${lastdiff.target}: ${lastdiff.added} added, ${lastdiff.removed} removed and ${lastdiff.repeated} repeated.`;
2619
2619
  const list = document.createElement("ul");
2620
2620
  list.className = "audit";
2621
- for (const line of lastdiff.lines.slice(0, 80)) {
2621
+ for (const line2 of lastdiff.lines.slice(0, 80)) {
2622
2622
  const item = document.createElement("li");
2623
- item.className = `diffrow ${line.kind}`;
2624
- item.textContent = `${line.kind}${line.count !== void 0 ? ` \xD7${line.count}` : ""}: ${line.text}`;
2623
+ item.className = `diffrow ${line2.kind}`;
2624
+ item.textContent = `${line2.kind}${line2.count !== void 0 ? ` \xD7${line2.count}` : ""}: ${line2.text}`;
2625
2625
  list.append(item);
2626
2626
  }
2627
2627
  consolediffroot.append(headline, list);
@@ -2794,9 +2794,9 @@ function renderemulation(context) {
2794
2794
  const row = document.createElement("div");
2795
2795
  row.className = "emulationrow";
2796
2796
  row.dataset.stacked = active.length > 1 ? "true" : "false";
2797
- const line = document.createElement("p");
2798
- line.textContent = `${layer.family} layer ${layer.name} on ${layer.originscope} applied ${new Date(layer.appliedat).toLocaleTimeString()} with the revert plan ${layer.revertplan.join(", ")}.`;
2799
- row.append(line, button("Revert now", () => request({ kind: "revertemulation" }).then(() => {
2797
+ const line2 = document.createElement("p");
2798
+ line2.textContent = `${layer.family} layer ${layer.name} on ${layer.originscope} applied ${new Date(layer.appliedat).toLocaleTimeString()} with the revert plan ${layer.revertplan.join(", ")}.`;
2799
+ row.append(line2, button("Revert now", () => request({ kind: "revertemulation" }).then(() => {
2800
2800
  status("Reverted every active emulation layer of the run on review panel demand.");
2801
2801
  return refresh();
2802
2802
  })));
@@ -2826,9 +2826,9 @@ function renderemulation(context) {
2826
2826
  continue;
2827
2827
  }
2828
2828
  for (const preset of family.presets) {
2829
- const line = document.createElement("p");
2830
- line.textContent = preset.label;
2831
- emulationroot.append(line);
2829
+ const line2 = document.createElement("p");
2830
+ line2.textContent = preset.label;
2831
+ emulationroot.append(line2);
2832
2832
  }
2833
2833
  }
2834
2834
  const editor = document.createElement("details");
@@ -2888,9 +2888,9 @@ function renderemulation(context) {
2888
2888
  head.textContent = "blackboxed patterns of the run";
2889
2889
  emulationroot.append(head);
2890
2890
  for (const entry of blackbox) {
2891
- const line = document.createElement("p");
2892
- line.textContent = `${entry.origin}: ${entry.rules.flatMap((rule) => rule.urlpatterns).join(", ")} (${entry.rules.map((rule) => rule.tracescope).join(", ")} scope)`;
2893
- emulationroot.append(line);
2891
+ const line2 = document.createElement("p");
2892
+ line2.textContent = `${entry.origin}: ${entry.rules.flatMap((rule) => rule.urlpatterns).join(", ")} (${entry.rules.map((rule) => rule.tracescope).join(", ")} scope)`;
2893
+ emulationroot.append(line2);
2894
2894
  }
2895
2895
  }
2896
2896
  const restored = emulation.permissions.filter((record) => record.restoredat === void 0);
@@ -2899,9 +2899,9 @@ function renderemulation(context) {
2899
2899
  head.textContent = "permission overrides pending restore";
2900
2900
  emulationroot.append(head);
2901
2901
  for (const record of restored) {
2902
- const line = document.createElement("p");
2903
- line.textContent = `${record.name} of ${record.origin} answered ${record.state} for run ${record.runid}; the prior ${record.priorstate} state restores at run end.`;
2904
- emulationroot.append(line);
2902
+ const line2 = document.createElement("p");
2903
+ line2.textContent = `${record.name} of ${record.origin} answered ${record.state} for run ${record.runid}; the prior ${record.priorstate} state restores at run end.`;
2904
+ emulationroot.append(line2);
2905
2905
  }
2906
2906
  }
2907
2907
  const retentionrow = document.createElement("p");
@@ -2945,6 +2945,7 @@ async function refresh() {
2945
2945
  renderagents(context);
2946
2946
  renderenvironments(context);
2947
2947
  rendersecurity(context);
2948
+ rendersessioninterface(context);
2948
2949
  renderconsolediff();
2949
2950
  renderaudit(context.audit);
2950
2951
  rendercapabilities(context.capabilities);
@@ -3253,10 +3254,10 @@ function rendersessions(context) {
3253
3254
  summary.textContent = `Latest session diff (${diff.changes.length} changes)`;
3254
3255
  diffview.append(summary);
3255
3256
  for (const change of diff.changes) {
3256
- const line = document.createElement("p");
3257
- line.textContent = `${change.class} ${change.subject}: ${change.detail}`;
3258
- line.dataset.class = change.class;
3259
- diffview.append(line);
3257
+ const line2 = document.createElement("p");
3258
+ line2.textContent = `${change.class} ${change.subject}: ${change.detail}`;
3259
+ line2.dataset.class = change.class;
3260
+ diffview.append(line2);
3260
3261
  }
3261
3262
  sessionsroot.append(diffview);
3262
3263
  }
@@ -3305,19 +3306,19 @@ function renderrestorereview(record) {
3305
3306
  title.textContent = `Restore review of ${record.name}: ${record.tabs.length} tabs, ${record.tabs.reduce((total, tab) => total + tab.forms.length, 0)} captured form fields, ${record.captures.length} linked captures.`;
3306
3307
  review.append(title);
3307
3308
  for (const tab of record.tabs) {
3308
- const line = document.createElement("p");
3309
- line.textContent = `Tab ${tab.index}: ${tab.title || tab.url} \xB7 ${tab.forms.length} form fields \xB7 scroll ${tab.scrollx},${tab.scrolly}`;
3310
- review.append(line);
3309
+ const line2 = document.createElement("p");
3310
+ line2.textContent = `Tab ${tab.index}: ${tab.title || tab.url} \xB7 ${tab.forms.length} form fields \xB7 scroll ${tab.scrollx},${tab.scrolly}`;
3311
+ review.append(line2);
3311
3312
  }
3312
3313
  for (const entry of record.storage) {
3313
- const line = document.createElement("p");
3314
- line.textContent = `Local storage of ${entry.origin}: ${entry.keys.length} keys captured.`;
3315
- review.append(line);
3314
+ const line2 = document.createElement("p");
3315
+ line2.textContent = `Local storage of ${entry.origin}: ${entry.keys.length} keys captured.`;
3316
+ review.append(line2);
3316
3317
  }
3317
3318
  for (const entry of record.cookies) {
3318
- const line = document.createElement("p");
3319
- line.textContent = `Cookies of ${entry.origin}: ${entry.names.length} names captured, values held back.`;
3320
- review.append(line);
3319
+ const line2 = document.createElement("p");
3320
+ line2.textContent = `Cookies of ${entry.origin}: ${entry.names.length} names captured, values held back.`;
3321
+ review.append(line2);
3321
3322
  }
3322
3323
  review.append(button("Approve restore", async () => {
3323
3324
  const result = await request({ kind: "approverestore", sessionid: record.id });
@@ -3350,11 +3351,11 @@ function rendercontroldecision(entry) {
3350
3351
  summary.textContent = `control flow \xB7 ${control?.kind ?? "decision"} \xB7 ${entry.summary}`;
3351
3352
  block.append(summary);
3352
3353
  if (control?.branch !== void 0) {
3353
- const line = document.createElement("p");
3354
- line.textContent = `Chose the path ${control.branch.path}: ${control.branch.reason}`;
3355
- line.dataset.class = "added";
3356
- line.dataset.branch = control.branch.path;
3357
- block.append(line);
3354
+ const line2 = document.createElement("p");
3355
+ line2.textContent = `Chose the path ${control.branch.path}: ${control.branch.reason}`;
3356
+ line2.dataset.class = "added";
3357
+ line2.dataset.branch = control.branch.path;
3358
+ block.append(line2);
3358
3359
  }
3359
3360
  if (control?.loops !== void 0 && control.loops.length > 0) {
3360
3361
  const group = document.createElement("details");
@@ -3363,28 +3364,28 @@ function rendercontroldecision(entry) {
3363
3364
  groupsummary.textContent = `Loop iterations (${control.loops.length})`;
3364
3365
  group.append(groupsummary);
3365
3366
  for (const counter of control.loops) {
3366
- const line = document.createElement("p");
3367
- line.textContent = `${counter.path} \xB7 ${counter.ok ? "completed" : "failed"}`;
3368
- line.dataset.class = counter.ok ? "added" : "changed";
3369
- group.append(line);
3367
+ const line2 = document.createElement("p");
3368
+ line2.textContent = `${counter.path} \xB7 ${counter.ok ? "completed" : "failed"}`;
3369
+ line2.dataset.class = counter.ok ? "added" : "changed";
3370
+ group.append(line2);
3370
3371
  }
3371
3372
  block.append(group);
3372
3373
  }
3373
3374
  if (control?.retries !== void 0 && control.retries.length > 0) {
3374
3375
  for (const attempt of control.retries) {
3375
- const line = document.createElement("p");
3376
- line.textContent = `Retry attempt ${attempt.attempt} after a ${attempt.delay} ms backoff countdown for the ${attempt.errorclass} error class.`;
3377
- line.dataset.class = "changed";
3378
- block.append(line);
3376
+ const line2 = document.createElement("p");
3377
+ line2.textContent = `Retry attempt ${attempt.attempt} after a ${attempt.delay} ms backoff countdown for the ${attempt.errorclass} error class.`;
3378
+ line2.dataset.class = "changed";
3379
+ block.append(line2);
3379
3380
  }
3380
3381
  }
3381
3382
  if (control?.timeouts !== void 0 && control.timeouts.length > 0) {
3382
3383
  for (const abort of control.timeouts) {
3383
- const line = document.createElement("p");
3384
- line.textContent = `Timeout abort: the ${abort.scope} exceeded its reviewed budget of ${abort.budget} milliseconds.`;
3385
- line.dataset.class = "changed";
3386
- line.dataset.timeout = "true";
3387
- block.append(line);
3384
+ const line2 = document.createElement("p");
3385
+ line2.textContent = `Timeout abort: the ${abort.scope} exceeded its reviewed budget of ${abort.budget} milliseconds.`;
3386
+ line2.dataset.class = "changed";
3387
+ line2.dataset.timeout = "true";
3388
+ block.append(line2);
3388
3389
  }
3389
3390
  }
3390
3391
  if (control?.branches !== void 0 && control.branches.length > 0) {
@@ -3402,16 +3403,16 @@ function rendercontroldecision(entry) {
3402
3403
  block.append(lanes);
3403
3404
  }
3404
3405
  if (control?.join !== void 0) {
3405
- const line = document.createElement("p");
3406
- line.textContent = `Join under the ${control.join.strategy} strategy merged ${control.join.merged.join(", ") || "no variable"}${control.join.conflicts.length > 0 ? ` with the conflicts ${control.join.conflicts.join(", ")}` : " with no conflict"}.`;
3407
- line.dataset.class = control.join.conflicts.length > 0 ? "changed" : "added";
3408
- block.append(line);
3406
+ const line2 = document.createElement("p");
3407
+ line2.textContent = `Join under the ${control.join.strategy} strategy merged ${control.join.merged.join(", ") || "no variable"}${control.join.conflicts.length > 0 ? ` with the conflicts ${control.join.conflicts.join(", ")}` : " with no conflict"}.`;
3408
+ line2.dataset.class = control.join.conflicts.length > 0 ? "changed" : "added";
3409
+ block.append(line2);
3409
3410
  }
3410
3411
  if (control?.catch !== void 0) {
3411
- const line = document.createElement("p");
3412
- line.textContent = `The catch handler ran after the ${control.catch.errorclass} failure${control.catch.rerun ? " and reran the fragile body" : ""}.`;
3413
- line.dataset.class = "changed";
3414
- block.append(line);
3412
+ const line2 = document.createElement("p");
3413
+ line2.textContent = `The catch handler ran after the ${control.catch.errorclass} failure${control.catch.rerun ? " and reran the fragile body" : ""}.`;
3414
+ line2.dataset.class = "changed";
3415
+ block.append(line2);
3415
3416
  }
3416
3417
  return block;
3417
3418
  }
@@ -3491,9 +3492,9 @@ function renderworkflows(context) {
3491
3492
  review.append(headline);
3492
3493
  const list = document.createElement("ol");
3493
3494
  for (const step of workflowview.review.steps) {
3494
- const line = document.createElement("li");
3495
- line.textContent = `${step.label} (${step.kind}${step.block !== void 0 ? ` \xB7 block ${step.block}` : ""}${step.target !== void 0 ? ` \xB7 ${step.target}` : ""}${step.expression !== void 0 ? ` \xB7 expression ${step.expression.operator} into ${step.expression.result}` : ""}${step.extract !== void 0 && step.extract.groups.length > 0 ? ` \xB7 extracts ${step.extract.groups.join(", ")}` : ""}${Array.isArray(step.bindings) && step.bindings.length > 0 ? ` \xB7 ${step.bindings.length} binding${step.bindings.length === 1 ? "" : "s"}` : ""}${controlreviewtext(step.control)}`;
3496
- list.append(line);
3495
+ const line2 = document.createElement("li");
3496
+ line2.textContent = `${step.label} (${step.kind}${step.block !== void 0 ? ` \xB7 block ${step.block}` : ""}${step.target !== void 0 ? ` \xB7 ${step.target}` : ""}${step.expression !== void 0 ? ` \xB7 expression ${step.expression.operator} into ${step.expression.result}` : ""}${step.extract !== void 0 && step.extract.groups.length > 0 ? ` \xB7 extracts ${step.extract.groups.join(", ")}` : ""}${Array.isArray(step.bindings) && step.bindings.length > 0 ? ` \xB7 ${step.bindings.length} binding${step.bindings.length === 1 ? "" : "s"}` : ""}${controlreviewtext(step.control)}`;
3497
+ list.append(line2);
3497
3498
  if (step.control !== void 0 && (step.control.kind === "loop" || step.control.kind === "repeatuntil")) {
3498
3499
  const boundrow = document.createElement("div");
3499
3500
  boundrow.className = "actions";
@@ -3554,12 +3555,12 @@ function renderworkflows(context) {
3554
3555
  if (record) {
3555
3556
  const steps = document.createElement("ol");
3556
3557
  for (const [index, step] of record.steps.entries()) {
3557
- const line = document.createElement("li");
3558
+ const line2 = document.createElement("li");
3558
3559
  const entry = state?.log.find((candidate) => candidate.stepid === step.id);
3559
3560
  const done = index < latest.cursor;
3560
- line.textContent = `${step.label} (${step.kind}${step.block !== void 0 ? ` \xB7 block ${step.block}` : ""})${done ? ` \xB7 done${entry?.checkpoint === true ? " \xB7 checkpointed" : ""}` : ""}${entry !== void 0 ? ` \xB7 ${entry.state}: ${entry.summary}` : ""}`;
3561
- line.dataset.class = entry?.state === "failed" || entry?.state === "refused" ? "changed" : done ? "added" : "unavailable";
3562
- if (step.block !== void 0 && index === latest.cursor) line.dataset.blockactive = "true";
3561
+ line2.textContent = `${step.label} (${step.kind}${step.block !== void 0 ? ` \xB7 block ${step.block}` : ""})${done ? ` \xB7 done${entry?.checkpoint === true ? " \xB7 checkpointed" : ""}` : ""}${entry !== void 0 ? ` \xB7 ${entry.state}: ${entry.summary}` : ""}`;
3562
+ line2.dataset.class = entry?.state === "failed" || entry?.state === "refused" ? "changed" : done ? "added" : "unavailable";
3563
+ if (step.block !== void 0 && index === latest.cursor) line2.dataset.blockactive = "true";
3563
3564
  const singlestep = document.createElement("div");
3564
3565
  singlestep.className = "actions";
3565
3566
  singlestep.append(button("Run single step", async () => {
@@ -3567,17 +3568,17 @@ function renderworkflows(context) {
3567
3568
  status(outcome.steps[0] ? `Single step ${outcome.steps[0].state}: ${outcome.steps[0].summary}` : "The single step returned no outcome.");
3568
3569
  await refresh();
3569
3570
  }));
3570
- line.append(singlestep);
3571
- steps.append(line);
3571
+ line2.append(singlestep);
3572
+ steps.append(line2);
3572
3573
  }
3573
3574
  timeline.append(steps);
3574
3575
  }
3575
3576
  const runlog = document.createElement("div");
3576
3577
  for (const entry of state?.log ?? []) {
3577
- const line = document.createElement("p");
3578
- line.textContent = `${entry.state} \xB7 ${entry.label} \xB7 ${entry.duration} ms${entry.produced !== void 0 && entry.produced.length > 0 ? ` \xB7 produced ${entry.produced.join(", ")}` : ""}${entry.consumed !== void 0 && entry.consumed.length > 0 ? ` \xB7 consumed ${entry.consumed.join(", ")}` : ""} \xB7 ${entry.summary}`;
3579
- line.dataset.class = entry.state === "failed" || entry.state === "refused" ? "changed" : "added";
3580
- runlog.append(line);
3578
+ const line2 = document.createElement("p");
3579
+ line2.textContent = `${entry.state} \xB7 ${entry.label} \xB7 ${entry.duration} ms${entry.produced !== void 0 && entry.produced.length > 0 ? ` \xB7 produced ${entry.produced.join(", ")}` : ""}${entry.consumed !== void 0 && entry.consumed.length > 0 ? ` \xB7 consumed ${entry.consumed.join(", ")}` : ""} \xB7 ${entry.summary}`;
3580
+ line2.dataset.class = entry.state === "failed" || entry.state === "refused" ? "changed" : "added";
3581
+ runlog.append(line2);
3581
3582
  if (entry.details !== void 0 && entry.details.control !== void 0) runlog.append(rendercontroldecision(entry));
3582
3583
  }
3583
3584
  timeline.append(runlog);
@@ -3590,9 +3591,9 @@ function renderworkflows(context) {
3590
3591
  scopesummary.textContent = `Variables per scope (${scopes.reduce((total, scope) => total + scope.variables.length, 0)} values)`;
3591
3592
  scopeview.append(scopesummary);
3592
3593
  for (const scope of scopes) {
3593
- const line = document.createElement("p");
3594
- line.textContent = `Scope ${scope.name}${scope.parent !== void 0 ? ` (child of ${scope.parent})` : ""}: ${scope.variables.length === 0 ? "no variable" : scope.variables.map((variable) => `${variable.name} = ${Array.isArray(variable.value) ? `[${variable.value.join(", ")}]` : String(variable.value)} (${variable.kind})`).join(" \xB7 ")}`;
3595
- scopeview.append(line);
3594
+ const line2 = document.createElement("p");
3595
+ line2.textContent = `Scope ${scope.name}${scope.parent !== void 0 ? ` (child of ${scope.parent})` : ""}: ${scope.variables.length === 0 ? "no variable" : scope.variables.map((variable) => `${variable.name} = ${Array.isArray(variable.value) ? `[${variable.value.join(", ")}]` : String(variable.value)} (${variable.kind})`).join(" \xB7 ")}`;
3596
+ scopeview.append(line2);
3596
3597
  }
3597
3598
  workflowsroot.append(scopeview);
3598
3599
  }
@@ -3604,9 +3605,9 @@ function renderworkflows(context) {
3604
3605
  provsummary.textContent = `Provenance (${provenance.length} entries)`;
3605
3606
  provenanceview.append(provsummary);
3606
3607
  for (const entry of provenance.slice(-12)) {
3607
- const line = document.createElement("p");
3608
- line.textContent = `${entry.kind} \xB7 ${entry.name} = ${Array.isArray(entry.value) ? `[${entry.value.join(", ")}]` : String(entry.value)}`;
3609
- provenanceview.append(line);
3608
+ const line2 = document.createElement("p");
3609
+ line2.textContent = `${entry.kind} \xB7 ${entry.name} = ${Array.isArray(entry.value) ? `[${entry.value.join(", ")}]` : String(entry.value)}`;
3610
+ provenanceview.append(line2);
3610
3611
  }
3611
3612
  workflowsroot.append(provenanceview);
3612
3613
  }
@@ -3911,9 +3912,9 @@ function renderworkfloweditor(context) {
3911
3912
  if (results.length > 0) {
3912
3913
  const list = document.createElement("ul");
3913
3914
  for (const result of results) {
3914
- const line = document.createElement("li");
3915
- line.textContent = `${result.label} (${result.kind}) matched ${result.matched.join(", ")}`;
3916
- list.append(line);
3915
+ const line2 = document.createElement("li");
3916
+ line2.textContent = `${result.label} (${result.kind}) matched ${result.matched.join(", ")}`;
3917
+ list.append(line2);
3917
3918
  }
3918
3919
  canvascard.append(list);
3919
3920
  }
@@ -3967,9 +3968,9 @@ function renderworkfloweditor(context) {
3967
3968
  bindingssummary.textContent = `Bindings and nested params (${model.edges.filter((edge) => edge.to === inspectedstep.id || edge.from === inspectedstep.id).length} edges)`;
3968
3969
  bindings.append(bindingssummary);
3969
3970
  for (const edge of model.edges.filter((candidate) => candidate.to === inspectedstep?.id)) {
3970
- const line = document.createElement("p");
3971
- line.textContent = `${edge.variable} (${edge.kind}) from ${edge.from}${edge.path !== void 0 ? ` path ${edge.path}` : ""}`;
3972
- line.append(" ", button("Remove binding", async () => {
3971
+ const line2 = document.createElement("p");
3972
+ line2.textContent = `${edge.variable} (${edge.kind}) from ${edge.from}${edge.path !== void 0 ? ` path ${edge.path}` : ""}`;
3973
+ line2.append(" ", button("Remove binding", async () => {
3973
3974
  if (editorview.model === void 0) return;
3974
3975
  try {
3975
3976
  editorview.model = removeedge(editorview.model, edge.from, edge.to, edge.variable);
@@ -3979,7 +3980,7 @@ function renderworkfloweditor(context) {
3979
3980
  }
3980
3981
  await refresh();
3981
3982
  }));
3982
- bindings.append(line);
3983
+ bindings.append(line2);
3983
3984
  }
3984
3985
  const source = document.createElement("select");
3985
3986
  for (const node of model.nodes) {
@@ -4147,9 +4148,9 @@ function renderworkfloweditor(context) {
4147
4148
  palettebody.append(head);
4148
4149
  const list = document.createElement("ul");
4149
4150
  for (const entry of kinds) {
4150
- const line = document.createElement("li");
4151
- line.textContent = `${entry.kind}${entry.optionschema.length > 0 ? ` \xB7 options: ${entry.optionschema.map((option) => `${option.name} ${option.kind}${option.required === true ? " (required)" : ""}`).join(", ")}` : ""}`;
4152
- list.append(line);
4151
+ const line2 = document.createElement("li");
4152
+ line2.textContent = `${entry.kind}${entry.optionschema.length > 0 ? ` \xB7 options: ${entry.optionschema.map((option) => `${option.name} ${option.kind}${option.required === true ? " (required)" : ""}`).join(", ")}` : ""}`;
4153
+ list.append(line2);
4153
4154
  }
4154
4155
  palettebody.append(list);
4155
4156
  }
@@ -4165,10 +4166,10 @@ function renderworkfloweditor(context) {
4165
4166
  versionsummary.textContent = `Version timeline (${editor.versions.filter((entry) => entry.workflowid === editorview.workflowid).length} versions of this workflow)`;
4166
4167
  versioncard.append(versionsummary);
4167
4168
  for (const version of editor.versions.filter((entry) => entry.workflowid === editorview.workflowid)) {
4168
- const line = document.createElement("p");
4169
- line.className = "diffrow";
4170
- line.textContent = `v${version.version} \xB7 ${new Date(version.createdat).toISOString()} \xB7 ${version.steps} steps \xB7 ${version.risk ?? "ungraded"}${version.rollback === true ? " \xB7 rollback" : ""} \xB7 ${version.note}`;
4171
- line.append(" ", button("Roll back here", async () => {
4169
+ const line2 = document.createElement("p");
4170
+ line2.className = "diffrow";
4171
+ line2.textContent = `v${version.version} \xB7 ${new Date(version.createdat).toISOString()} \xB7 ${version.steps} steps \xB7 ${version.risk ?? "ungraded"}${version.rollback === true ? " \xB7 rollback" : ""} \xB7 ${version.note}`;
4172
+ line2.append(" ", button("Roll back here", async () => {
4172
4173
  try {
4173
4174
  const rolled = await request({ kind: "rollbackversion", workflowid: editorview.workflowid, version: version.version });
4174
4175
  status(`Rolled back to v${version.version}; stored as v${rolled.version} and ${rolled.reviewstate} until the rollback review approves it.`);
@@ -4177,7 +4178,7 @@ function renderworkfloweditor(context) {
4177
4178
  }
4178
4179
  await refresh();
4179
4180
  }));
4180
- versioncard.append(line);
4181
+ versioncard.append(line2);
4181
4182
  }
4182
4183
  const diffrow = document.createElement("div");
4183
4184
  diffrow.className = "actions";
@@ -4208,25 +4209,25 @@ function renderworkfloweditor(context) {
4208
4209
  headline.textContent = `Version diff v${diff.from} \u2192 v${diff.to}`;
4209
4210
  card.append(headline);
4210
4211
  for (const added of diff.added) {
4211
- const line = document.createElement("p");
4212
- line.className = "diffrow";
4213
- line.dataset.class = "added";
4214
- line.textContent = `+ ${added.stepid} (${added.kind}) ${added.label}`;
4215
- card.append(line);
4212
+ const line2 = document.createElement("p");
4213
+ line2.className = "diffrow";
4214
+ line2.dataset.class = "added";
4215
+ line2.textContent = `+ ${added.stepid} (${added.kind}) ${added.label}`;
4216
+ card.append(line2);
4216
4217
  }
4217
4218
  for (const removed of diff.removed) {
4218
- const line = document.createElement("p");
4219
- line.className = "diffrow";
4220
- line.dataset.class = "removed";
4221
- line.textContent = `- ${removed.stepid} (${removed.kind}) ${removed.label}`;
4222
- card.append(line);
4219
+ const line2 = document.createElement("p");
4220
+ line2.className = "diffrow";
4221
+ line2.dataset.class = "removed";
4222
+ line2.textContent = `- ${removed.stepid} (${removed.kind}) ${removed.label}`;
4223
+ card.append(line2);
4223
4224
  }
4224
4225
  for (const changed of diff.changed) {
4225
- const line = document.createElement("p");
4226
- line.className = "diffrow";
4227
- line.dataset.class = "changed";
4228
- line.textContent = `~ ${changed.stepid} (${changed.kind}) ${changed.label}: ${changed.changes.join(", ")}`;
4229
- card.append(line);
4226
+ const line2 = document.createElement("p");
4227
+ line2.className = "diffrow";
4228
+ line2.dataset.class = "changed";
4229
+ line2.textContent = `~ ${changed.stepid} (${changed.kind}) ${changed.label}: ${changed.changes.join(", ")}`;
4230
+ card.append(line2);
4230
4231
  }
4231
4232
  card.append(button("Close diff", async () => {
4232
4233
  editorview.diff = void 0;
@@ -4258,10 +4259,10 @@ function renderworkfloweditor(context) {
4258
4259
  logcard.append(logsummary);
4259
4260
  const breakpoints = /* @__PURE__ */ new Set([...editor?.breakpoints ?? [], ...context.workflow.workflows.find((record) => record.id === editorview.workflowid)?.steps.flatMap((step) => step.breakpoint === true ? [step.id] : []) ?? []]);
4260
4261
  for (const entry of context.workflow.log) {
4261
- const line = document.createElement("p");
4262
- line.textContent = `${entry.state} \xB7 ${entry.label}${breakpoints.has(entry.stepid) ? " \xB7 breakpoint" : ""} \xB7 ${entry.duration} ms \xB7 ${entry.summary}`;
4263
- line.dataset.class = entry.state === "failed" || entry.state === "refused" ? "changed" : "added";
4264
- logcard.append(line);
4262
+ const line2 = document.createElement("p");
4263
+ line2.textContent = `${entry.state} \xB7 ${entry.label}${breakpoints.has(entry.stepid) ? " \xB7 breakpoint" : ""} \xB7 ${entry.duration} ms \xB7 ${entry.summary}`;
4264
+ line2.dataset.class = entry.state === "failed" || entry.state === "refused" ? "changed" : "added";
4265
+ logcard.append(line2);
4265
4266
  }
4266
4267
  if (context.workflow.log.length === 0) {
4267
4268
  const empty = document.createElement("p");
@@ -4269,9 +4270,9 @@ function renderworkfloweditor(context) {
4269
4270
  logcard.append(empty);
4270
4271
  }
4271
4272
  for (const scope of context.workflow.scopes) {
4272
- const line = document.createElement("p");
4273
- line.textContent = `Scope ${scope.name}: ${scope.variables.length === 0 ? "no variable" : scope.variables.map((variable) => `${variable.name} = ${Array.isArray(variable.value) ? `[${variable.value.join(", ")}]` : String(variable.value)} (${variable.kind})`).join(" \xB7 ")}`;
4274
- logcard.append(line);
4273
+ const line2 = document.createElement("p");
4274
+ line2.textContent = `Scope ${scope.name}: ${scope.variables.length === 0 ? "no variable" : scope.variables.map((variable) => `${variable.name} = ${Array.isArray(variable.value) ? `[${variable.value.join(", ")}]` : String(variable.value)} (${variable.kind})`).join(" \xB7 ")}`;
4275
+ logcard.append(line2);
4275
4276
  }
4276
4277
  workfloweditorroot.append(logcard);
4277
4278
  }
@@ -4318,13 +4319,13 @@ function renderworkfloweditor(context) {
4318
4319
  historycard.append(historyfilters);
4319
4320
  const historyentries = editorview.history ?? editor?.history ?? [];
4320
4321
  for (const entry of historyentries.slice(0, 40)) {
4321
- const line = document.createElement("div");
4322
- line.className = "historyrow";
4323
- line.dataset.outcome = entry.outcome;
4322
+ const line2 = document.createElement("div");
4323
+ line2.className = "historyrow";
4324
+ line2.dataset.outcome = entry.outcome;
4324
4325
  const detail = document.createElement("p");
4325
4326
  detail.textContent = `${entry.outcome} \xB7 ${entry.steps}/${entry.total} steps \xB7 ${entry.duration} ms \xB7 ${entry.cause}${entry.dryrun === true ? " \xB7 dry run" : ""} \xB7 ${new Date(entry.startedat).toISOString()}`;
4326
- line.append(detail);
4327
- historycard.append(line);
4327
+ line2.append(detail);
4328
+ historycard.append(line2);
4328
4329
  }
4329
4330
  workfloweditorroot.append(historycard);
4330
4331
  const filecard = document.createElement("details");
@@ -4371,9 +4372,9 @@ function renderworkfloweditor(context) {
4371
4372
  review.append(headline);
4372
4373
  const list = document.createElement("ol");
4373
4374
  for (const step of editorview.importreview.steps) {
4374
- const line = document.createElement("li");
4375
- line.textContent = `${step.label} (${step.kind}${step.block !== void 0 ? ` \xB7 block ${step.block}` : ""}${step.target !== void 0 ? ` \xB7 ${step.target}` : ""})`;
4376
- list.append(line);
4375
+ const line2 = document.createElement("li");
4376
+ line2.textContent = `${step.label} (${step.kind}${step.block !== void 0 ? ` \xB7 block ${step.block}` : ""}${step.target !== void 0 ? ` \xB7 ${step.target}` : ""})`;
4377
+ list.append(line2);
4377
4378
  }
4378
4379
  review.append(list);
4379
4380
  review.append(button("Approve import", async () => {
@@ -4398,9 +4399,9 @@ function renderworkfloweditor(context) {
4398
4399
  filecard.append(review);
4399
4400
  }
4400
4401
  for (const pending of editor?.imports ?? []) {
4401
- const line = document.createElement("p");
4402
- line.textContent = `Pending import ${pending.name} v${pending.version} (${pending.steps} steps, ${pending.risk})${pending.filename !== void 0 ? ` from ${pending.filename}` : ""}`;
4403
- line.append(" ", button("Review steps", async () => {
4402
+ const line2 = document.createElement("p");
4403
+ line2.textContent = `Pending import ${pending.name} v${pending.version} (${pending.steps} steps, ${pending.risk})${pending.filename !== void 0 ? ` from ${pending.filename}` : ""}`;
4404
+ line2.append(" ", button("Review steps", async () => {
4404
4405
  try {
4405
4406
  const steps = await request({ kind: "workflowreview", workflowid: pending.workflowid });
4406
4407
  editorview.importreview = { importid: pending.id, workflowid: pending.workflowid, name: pending.name, version: pending.version, risk: pending.risk, steps: steps.steps };
@@ -4410,7 +4411,7 @@ function renderworkfloweditor(context) {
4410
4411
  }
4411
4412
  await refresh();
4412
4413
  }));
4413
- filecard.append(line);
4414
+ filecard.append(line2);
4414
4415
  }
4415
4416
  const exportrow = document.createElement("div");
4416
4417
  exportrow.className = "actions";
@@ -4501,9 +4502,9 @@ function renderworkfloweditor(context) {
4501
4502
  }));
4502
4503
  watchdogcard.append(watchdogactions);
4503
4504
  for (const event of (editor?.watchdog.events ?? []).slice(0, 15)) {
4504
- const line = document.createElement("p");
4505
- line.textContent = `${event.verdict} \xB7 ${event.action} \xB7 ${new Date(event.at).toISOString()} \xB7 ${event.outcome}`;
4506
- watchdogcard.append(line);
4505
+ const line2 = document.createElement("p");
4506
+ line2.textContent = `${event.verdict} \xB7 ${event.action} \xB7 ${new Date(event.at).toISOString()} \xB7 ${event.outcome}`;
4507
+ watchdogcard.append(line2);
4507
4508
  }
4508
4509
  workfloweditorroot.append(watchdogcard);
4509
4510
  const overridecard = document.createElement("details");
@@ -4548,9 +4549,9 @@ function renderworkfloweditor(context) {
4548
4549
  await refresh();
4549
4550
  }));
4550
4551
  for (const override of editor?.overrides ?? []) {
4551
- const line = document.createElement("p");
4552
- line.textContent = `${override.pattern} of ${override.workflowid}: ${Object.entries(override.deltas).map(([knob, delta]) => `${knob} ${delta}`).join(", ") || "no delta"}`;
4553
- line.append(" ", button("Remove override", async () => {
4552
+ const line2 = document.createElement("p");
4553
+ line2.textContent = `${override.pattern} of ${override.workflowid}: ${Object.entries(override.deltas).map(([knob, delta]) => `${knob} ${delta}`).join(", ") || "no delta"}`;
4554
+ line2.append(" ", button("Remove override", async () => {
4554
4555
  try {
4555
4556
  await request({ kind: "removesiteoverride", id: override.id });
4556
4557
  status(`Removed the override ${override.pattern}.`);
@@ -4559,7 +4560,7 @@ function renderworkfloweditor(context) {
4559
4560
  }
4560
4561
  await refresh();
4561
4562
  }));
4562
- overridecard.append(line);
4563
+ overridecard.append(line2);
4563
4564
  }
4564
4565
  workfloweditorroot.append(overridecard);
4565
4566
  }
@@ -4661,9 +4662,9 @@ function rendertriggers(context) {
4661
4662
  summary.textContent = `Fire history (${triggerview.history.length} records)`;
4662
4663
  history.append(summary);
4663
4664
  for (const fire of triggerview.history.slice(0, 25)) {
4664
- const line = document.createElement("p");
4665
- line.textContent = `${new Date(fire.at).toISOString()} \xB7 ${fire.cause}${fire.url !== void 0 ? ` \xB7 ${fire.url}` : ""}${fire.title !== void 0 ? ` \xB7 ${fire.title}` : ""}`;
4666
- history.append(line);
4665
+ const line2 = document.createElement("p");
4666
+ line2.textContent = `${new Date(fire.at).toISOString()} \xB7 ${fire.cause}${fire.url !== void 0 ? ` \xB7 ${fire.url}` : ""}${fire.title !== void 0 ? ` \xB7 ${fire.title}` : ""}`;
4667
+ history.append(line2);
4667
4668
  }
4668
4669
  triggersroot.append(history);
4669
4670
  }
@@ -4674,9 +4675,9 @@ function rendertriggers(context) {
4674
4675
  headline.textContent = `Manual run step preview: ${triggerview.manual.preview.length} expanded step${triggerview.manual.preview.length === 1 ? "" : "s"}; approve or cancel before anything runs.`;
4675
4676
  preview.append(headline);
4676
4677
  for (const step of triggerview.manual.preview) {
4677
- const line = document.createElement("p");
4678
- line.textContent = `${step.stepid} \xB7 ${step.kind} \xB7 ${step.label}${step.block !== void 0 ? ` \xB7 block ${step.block}` : ""}${step.control !== void 0 ? ` \xB7 ${Object.entries(step.control).map(([key, value]) => `${key}: ${Array.isArray(value) ? value.join(", ") : String(value)}`).join(" \xB7 ")}` : ""}`;
4679
- preview.append(line);
4678
+ const line2 = document.createElement("p");
4679
+ line2.textContent = `${step.stepid} \xB7 ${step.kind} \xB7 ${step.label}${step.block !== void 0 ? ` \xB7 block ${step.block}` : ""}${step.control !== void 0 ? ` \xB7 ${Object.entries(step.control).map(([key, value]) => `${key}: ${Array.isArray(value) ? value.join(", ") : String(value)}`).join(" \xB7 ")}` : ""}`;
4680
+ preview.append(line2);
4680
4681
  }
4681
4682
  const actions = document.createElement("div");
4682
4683
  actions.className = "actions";
@@ -4869,15 +4870,15 @@ function renderagentprotocol(context) {
4869
4870
  remoteline.textContent = `Endpoint ${mcp.remote.endpoint} \xB7 tls ${mcp.remote.tls.mode}${mcp.remote.tls.certificaterequired ? " (certificate required)" : ""}${mcp.remote.tls.verified ? " and verified" : " and unverified"} \xB7 ${mcp.remote.paired} of ${mcp.remote.clients} client${mcp.remote.clients === 1 ? "" : "s"} paired \xB7 ${mcp.remote.tokenslive} live token${mcp.remote.tokenslive === 1 ? "" : "s"}.`;
4870
4871
  remotebox.append(remoteline);
4871
4872
  for (const channel of mcp.channels.slice(0, 10)) {
4872
- const line = document.createElement("p");
4873
+ const line2 = document.createElement("p");
4873
4874
  const beatage = Math.max(0, Math.round((Date.now() - channel.lastbeatat) / 1e3));
4874
- line.textContent = `Stream channel ${channel.id.slice(0, 12)} of ${channel.clientid} \xB7 ${channel.closedat === void 0 ? `heartbeat ${beatage}s ago` : `closed at ${new Date(channel.closedat).toISOString()}`}.`;
4875
- remotebox.append(line);
4875
+ line2.textContent = `Stream channel ${channel.id.slice(0, 12)} of ${channel.clientid} \xB7 ${channel.closedat === void 0 ? `heartbeat ${beatage}s ago` : `closed at ${new Date(channel.closedat).toISOString()}`}.`;
4876
+ remotebox.append(line2);
4876
4877
  }
4877
4878
  for (const shake of mcp.handshakes.slice(0, 5)) {
4878
- const line = document.createElement("p");
4879
- line.textContent = `Auth handshake ${shake.method} of ${shake.clientid} \xB7 ${shake.outcome}${shake.outcome === "refused" ? " (consentrefused error, no pairing state leaked)" : ""} \xB7 ${new Date(shake.at).toISOString()}.`;
4880
- remotebox.append(line);
4879
+ const line2 = document.createElement("p");
4880
+ line2.textContent = `Auth handshake ${shake.method} of ${shake.clientid} \xB7 ${shake.outcome}${shake.outcome === "refused" ? " (consentrefused error, no pairing state leaked)" : ""} \xB7 ${new Date(shake.at).toISOString()}.`;
4881
+ remotebox.append(line2);
4881
4882
  }
4882
4883
  const pairingline = document.createElement("p");
4883
4884
  pairingline.textContent = mcp.pairing.length > 0 ? `Pairing code ${mcp.pairing[0]?.code} for ${mcp.pairing[0]?.scopes.join(", ") || "no"} namespaces \xB7 expires at ${new Date(mcp.pairing[0]?.expiresat ?? Date.now()).toISOString()} \xB7 single use.` : "No pairing code pending; issue one while a session is live to pair a remote client.";
@@ -4931,9 +4932,9 @@ function renderagentprotocol(context) {
4931
4932
  allowlistsummary.textContent = `Client allowlist (${mcp.allowlist.length} entr${mcp.allowlist.length === 1 ? "y" : "ies"})`;
4932
4933
  allowlistbox.append(allowlistsummary);
4933
4934
  for (const entry of mcp.allowlist) {
4934
- const line = document.createElement("p");
4935
- line.textContent = `${entry.displayname} \xB7 ${entry.fingerprint.slice(0, 12)} \xB7 namespaces ${entry.namespaces.join(", ") || "none"} \xB7 granted ${new Date(entry.grantedat).toISOString()} \xB7 ${entry.history.length} grant change${entry.history.length === 1 ? "" : "s"}.`;
4936
- allowlistbox.append(line);
4935
+ const line2 = document.createElement("p");
4936
+ line2.textContent = `${entry.displayname} \xB7 ${entry.fingerprint.slice(0, 12)} \xB7 namespaces ${entry.namespaces.join(", ") || "none"} \xB7 granted ${new Date(entry.grantedat).toISOString()} \xB7 ${entry.history.length} grant change${entry.history.length === 1 ? "" : "s"}.`;
4937
+ allowlistbox.append(line2);
4937
4938
  const actions = document.createElement("div");
4938
4939
  actions.className = "actions";
4939
4940
  actions.append(button(`Rescope to browser+memory`, async () => {
@@ -4988,9 +4989,9 @@ function renderagentprotocol(context) {
4988
4989
  domainsummary.textContent = `${namespace} (${tools.length} tools)`;
4989
4990
  domain.append(domainsummary);
4990
4991
  for (const tool of tools) {
4991
- const line = document.createElement("p");
4992
- line.textContent = `${tool.name} v${tool.version} \xB7 ${tool.risk} \xB7 ${tool.description.split(".")[0] ?? tool.description}${tool.consentmeta !== void 0 ? ` \xB7 ${tool.consentmeta.riskclass} \xB7 approval gate ${tool.consentmeta.approvalrequired ? "required" : "off"} \xB7 ${tool.consentmeta.originscope} scope \xB7 review: ${tool.consentmeta.review}` : ""}`;
4993
- domain.append(line);
4992
+ const line2 = document.createElement("p");
4993
+ line2.textContent = `${tool.name} v${tool.version} \xB7 ${tool.risk} \xB7 ${tool.description.split(".")[0] ?? tool.description}${tool.consentmeta !== void 0 ? ` \xB7 ${tool.consentmeta.riskclass} \xB7 approval gate ${tool.consentmeta.approvalrequired ? "required" : "off"} \xB7 ${tool.consentmeta.originscope} scope \xB7 review: ${tool.consentmeta.review}` : ""}`;
4994
+ domain.append(line2);
4994
4995
  }
4995
4996
  catalogbox.append(domain);
4996
4997
  }
@@ -5001,9 +5002,9 @@ function renderagentprotocol(context) {
5001
5002
  runtimesummary.textContent = `Call runtime (${mcp.inflight?.length ?? 0} in flight, ${mcp.dryruntoggle === true ? "dry run armed" : "dry run off"}, ${mcp.mocks?.length ?? 0} mock${(mcp.mocks?.length ?? 0) === 1 ? "" : "s"})`;
5002
5003
  runtimebox.append(runtimesummary);
5003
5004
  for (const call of mcp.inflight ?? []) {
5004
- const line = document.createElement("p");
5005
- line.textContent = `In flight ${call.tool} of ${call.clientid} \xB7 call ${call.callid.slice(0, 12)} \xB7 ${call.chunks} chunk${call.chunks === 1 ? "" : "s"} \xB7 open ${Math.max(0, Math.round((Date.now() - call.startedat) / 1e3))}s${call.dryrun === true ? " \xB7 dry run" : ""}.`;
5006
- runtimebox.append(line);
5005
+ const line2 = document.createElement("p");
5006
+ line2.textContent = `In flight ${call.tool} of ${call.clientid} \xB7 call ${call.callid.slice(0, 12)} \xB7 ${call.chunks} chunk${call.chunks === 1 ? "" : "s"} \xB7 open ${Math.max(0, Math.round((Date.now() - call.startedat) / 1e3))}s${call.dryrun === true ? " \xB7 dry run" : ""}.`;
5007
+ runtimebox.append(line2);
5007
5008
  const actions = document.createElement("div");
5008
5009
  actions.className = "actions";
5009
5010
  actions.append(button("Cancel call", async () => {
@@ -5038,9 +5039,9 @@ function renderagentprotocol(context) {
5038
5039
  }));
5039
5040
  runtimebox.append(runtimeactions);
5040
5041
  for (const mock of mcp.mocks ?? []) {
5041
- const line = document.createElement("p");
5042
- line.textContent = `Tool mock ${mock.tool} \xB7 test context \xB7 created ${new Date(mock.createdat).toISOString()}.`;
5043
- runtimebox.append(line);
5042
+ const line2 = document.createElement("p");
5043
+ line2.textContent = `Tool mock ${mock.tool} \xB7 test context \xB7 created ${new Date(mock.createdat).toISOString()}.`;
5044
+ runtimebox.append(line2);
5044
5045
  const actions = document.createElement("div");
5045
5046
  actions.className = "actions";
5046
5047
  actions.append(button("Remove mock", async () => {
@@ -5057,11 +5058,11 @@ function renderagentprotocol(context) {
5057
5058
  limitssummary.textContent = `Rate limits (${mcp.limits?.length ?? 0} client${(mcp.limits?.length ?? 0) === 1 ? "" : "s"} limited)`;
5058
5059
  limitsbox.append(limitssummary);
5059
5060
  for (const limit of mcp.limits ?? []) {
5060
- const line = document.createElement("p");
5061
+ const line2 = document.createElement("p");
5061
5062
  const used = limit.budget !== void 0 ? Math.min(100, Math.round(limit.used / limit.budget * 100)) : 0;
5062
5063
  const bar = limit.budget !== void 0 ? " " + "\u2588".repeat(Math.round(used / 10)) + "\xB7".repeat(10 - Math.round(used / 10)) : "";
5063
- line.textContent = `${limit.clientid} \xB7 ${limit.used}${limit.budget !== void 0 ? ` of ${limit.budget}` : " of unbounded"} call${limit.used === 1 ? "" : "s"} in the ${limit.windowms}ms window${bar} \xB7 resets in ${Math.max(0, Math.round((limit.windowstartedat + limit.windowms - Date.now()) / 1e3))}s.`;
5064
- limitsbox.append(line);
5064
+ line2.textContent = `${limit.clientid} \xB7 ${limit.used}${limit.budget !== void 0 ? ` of ${limit.budget}` : " of unbounded"} call${limit.used === 1 ? "" : "s"} in the ${limit.windowms}ms window${bar} \xB7 resets in ${Math.max(0, Math.round((limit.windowstartedat + limit.windowms - Date.now()) / 1e3))}s.`;
5065
+ limitsbox.append(line2);
5065
5066
  const actions = document.createElement("div");
5066
5067
  actions.className = "actions";
5067
5068
  actions.append(button("Remove limit", async () => {
@@ -5101,14 +5102,14 @@ function renderagentprotocol(context) {
5101
5102
  streamsummary.textContent = `Streaming and progress (${mcp.chunks?.length ?? 0} chunk${(mcp.chunks?.length ?? 0) === 1 ? "" : "s"}, ${mcp.progressnotices?.length ?? 0} notice${(mcp.progressnotices?.length ?? 0) === 1 ? "" : "s"})`;
5102
5103
  streambox.append(streamsummary);
5103
5104
  for (const notice of (mcp.progressnotices ?? []).slice(0, 5)) {
5104
- const line = document.createElement("p");
5105
- line.textContent = `Progress ${notice.percent !== void 0 ? `${notice.percent}%` : ""} of the call ${notice.callid.slice(0, 12)} \xB7 ${notice.message}${notice.cancellable ? " \xB7 cancellable" : ""} \xB7 ${new Date(notice.at).toISOString()}.`;
5106
- streambox.append(line);
5105
+ const line2 = document.createElement("p");
5106
+ line2.textContent = `Progress ${notice.percent !== void 0 ? `${notice.percent}%` : ""} of the call ${notice.callid.slice(0, 12)} \xB7 ${notice.message}${notice.cancellable ? " \xB7 cancellable" : ""} \xB7 ${new Date(notice.at).toISOString()}.`;
5107
+ streambox.append(line2);
5107
5108
  }
5108
5109
  for (const chunk of (mcp.chunks ?? []).slice(0, 10)) {
5109
- const line = document.createElement("p");
5110
- line.textContent = `Chunk ${chunk.seq}${chunk.done ? " (done)" : ""} of the call ${chunk.callid.slice(0, 12)} \xB7 ${chunk.content.slice(0, 60)}${chunk.content.length > 60 ? "\u2026" : ""}`;
5111
- streambox.append(line);
5110
+ const line2 = document.createElement("p");
5111
+ line2.textContent = `Chunk ${chunk.seq}${chunk.done ? " (done)" : ""} of the call ${chunk.callid.slice(0, 12)} \xB7 ${chunk.content.slice(0, 60)}${chunk.content.length > 60 ? "\u2026" : ""}`;
5112
+ streambox.append(line2);
5112
5113
  }
5113
5114
  if ((mcp.chunks?.length ?? 0) === 0 && (mcp.progressnotices?.length ?? 0) === 0) {
5114
5115
  const empty = document.createElement("p");
@@ -5122,9 +5123,9 @@ function renderagentprotocol(context) {
5122
5123
  samplingsummary.textContent = `Sampling callbacks (${mcp.sampling?.length ?? 0})`;
5123
5124
  samplingbox.append(samplingsummary);
5124
5125
  for (const callback of mcp.sampling ?? []) {
5125
- const line = document.createElement("p");
5126
- line.textContent = `${callback.state} \xB7 client ${callback.clientid} \xB7 requested ${new Date(callback.requestedat).toISOString()}${callback.answeredat !== void 0 ? ` \xB7 answered ${new Date(callback.answeredat).toISOString()}` : ""}${callback.pagecontent !== void 0 ? " \xB7 page content granted" : " \xB7 page content stripped"}.`;
5127
- samplingbox.append(line);
5126
+ const line2 = document.createElement("p");
5127
+ line2.textContent = `${callback.state} \xB7 client ${callback.clientid} \xB7 requested ${new Date(callback.requestedat).toISOString()}${callback.answeredat !== void 0 ? ` \xB7 answered ${new Date(callback.answeredat).toISOString()}` : ""}${callback.pagecontent !== void 0 ? " \xB7 page content granted" : " \xB7 page content stripped"}.`;
5128
+ samplingbox.append(line2);
5128
5129
  const payload = document.createElement("p");
5129
5130
  payload.textContent = `Prompt: ${callback.prompt}${callback.system !== void 0 ? ` System: ${callback.system}` : ""}${callback.answer !== void 0 ? ` Answer: ${callback.answer}` : ""}`;
5130
5131
  samplingbox.append(payload);
@@ -5171,9 +5172,9 @@ function renderagentprotocol(context) {
5171
5172
  subssummary.textContent = `Subscriptions (${mcp.subscriptions?.length ?? 0} event, ${mcp.watches?.length ?? 0} resource)`;
5172
5173
  subsbox.append(subssummary);
5173
5174
  for (const subscription of mcp.subscriptions ?? []) {
5174
- const line = document.createElement("p");
5175
- line.textContent = `Client ${subscription.clientid} \xB7 kinds ${subscription.kinds.join(", ")}${subscription.origin !== void 0 ? ` \xB7 origin ${subscription.origin}` : ""}${subscription.tool !== void 0 ? ` \xB7 tool ${subscription.tool}` : ""} \xB7 subscribed ${new Date(subscription.createdat).toISOString()}${subscription.lastdeliveredat !== void 0 ? ` \xB7 last delivery ${new Date(subscription.lastdeliveredat).toISOString()}` : ""}.`;
5176
- subsbox.append(line);
5175
+ const line2 = document.createElement("p");
5176
+ line2.textContent = `Client ${subscription.clientid} \xB7 kinds ${subscription.kinds.join(", ")}${subscription.origin !== void 0 ? ` \xB7 origin ${subscription.origin}` : ""}${subscription.tool !== void 0 ? ` \xB7 tool ${subscription.tool}` : ""} \xB7 subscribed ${new Date(subscription.createdat).toISOString()}${subscription.lastdeliveredat !== void 0 ? ` \xB7 last delivery ${new Date(subscription.lastdeliveredat).toISOString()}` : ""}.`;
5177
+ subsbox.append(line2);
5177
5178
  const actions = document.createElement("div");
5178
5179
  actions.className = "actions";
5179
5180
  actions.append(button("Unsubscribe", async () => {
@@ -5184,9 +5185,9 @@ function renderagentprotocol(context) {
5184
5185
  subsbox.append(actions);
5185
5186
  }
5186
5187
  for (const watch of mcp.watches ?? []) {
5187
- const line = document.createElement("p");
5188
- line.textContent = `Client ${watch.clientid} watches the ${watch.resource} resource \xB7 since ${new Date(watch.createdat).toISOString()}${watch.lastdeliveredat !== void 0 ? ` \xB7 last delta ${new Date(watch.lastdeliveredat).toISOString()}` : ""}.`;
5189
- subsbox.append(line);
5188
+ const line2 = document.createElement("p");
5189
+ line2.textContent = `Client ${watch.clientid} watches the ${watch.resource} resource \xB7 since ${new Date(watch.createdat).toISOString()}${watch.lastdeliveredat !== void 0 ? ` \xB7 last delta ${new Date(watch.lastdeliveredat).toISOString()}` : ""}.`;
5190
+ subsbox.append(line2);
5190
5191
  const actions = document.createElement("div");
5191
5192
  actions.className = "actions";
5192
5193
  actions.append(button("Unwatch", async () => {
@@ -5208,10 +5209,10 @@ function renderagentprotocol(context) {
5208
5209
  batchsummary.textContent = `Batch calls (${mcp.batches?.length ?? 0})`;
5209
5210
  batchbox.append(batchsummary);
5210
5211
  for (const batch of mcp.batches ?? []) {
5211
- const line = document.createElement("p");
5212
+ const line2 = document.createElement("p");
5212
5213
  const done = batch.outcomes.length;
5213
- line.textContent = `${batch.state} \xB7 client ${batch.clientid} \xB7 ${done} of ${batch.calls.length} member${batch.calls.length === 1 ? "" : "s"} done \xB7 stop on error ${batch.stoponerror ? "on" : "off"} \xB7 created ${new Date(batch.createdat).toISOString()}.`;
5214
- batchbox.append(line);
5214
+ line2.textContent = `${batch.state} \xB7 client ${batch.clientid} \xB7 ${done} of ${batch.calls.length} member${batch.calls.length === 1 ? "" : "s"} done \xB7 stop on error ${batch.stoponerror ? "on" : "off"} \xB7 created ${new Date(batch.createdat).toISOString()}.`;
5215
+ batchbox.append(line2);
5215
5216
  for (const outcome of batch.outcomes.slice(0, 10)) {
5216
5217
  const item = document.createElement("p");
5217
5218
  item.textContent = ` ${outcome.ok ? "ran" : "failed"} \xB7 ${outcome.tool} (${outcome.callid}).`;
@@ -5230,9 +5231,9 @@ function renderagentprotocol(context) {
5230
5231
  callssummary.textContent = `Audited tool calls (${(mcp.calllog ?? mcp.calls).length} shown, every call logged)`;
5231
5232
  callsbox.append(callssummary);
5232
5233
  for (const call of (mcp.calllog ?? mcp.calls).slice(0, 25)) {
5233
- const line = document.createElement("p");
5234
- line.textContent = `${new Date(call.at).toISOString()} \xB7 ${call.clientid} \xB7 ${call.tool} \xB7 ${call.origin} \xB7 ${call.ok ? "ran behind the gates" : `refused${call.code !== void 0 ? ` (${call.code})` : ""}`}${call.dryrun === true ? " \xB7 dry run" : ""}${call.mocked === true ? " \xB7 mocked" : ""}${call.batchid !== void 0 ? " \xB7 batch member" : ""}${call.idempotencykey !== void 0 ? ` \xB7 key ${call.idempotencykey.slice(0, 10)}` : ""}${call.replayed === true ? " \xB7 idempotent replay" : ""}`;
5235
- callsbox.append(line);
5234
+ const line2 = document.createElement("p");
5235
+ line2.textContent = `${new Date(call.at).toISOString()} \xB7 ${call.clientid} \xB7 ${call.tool} \xB7 ${call.origin} \xB7 ${call.ok ? "ran behind the gates" : `refused${call.code !== void 0 ? ` (${call.code})` : ""}`}${call.dryrun === true ? " \xB7 dry run" : ""}${call.mocked === true ? " \xB7 mocked" : ""}${call.batchid !== void 0 ? " \xB7 batch member" : ""}${call.idempotencykey !== void 0 ? ` \xB7 key ${call.idempotencykey.slice(0, 10)}` : ""}${call.replayed === true ? " \xB7 idempotent replay" : ""}`;
5236
+ callsbox.append(line2);
5236
5237
  }
5237
5238
  if ((mcp.calllog ?? mcp.calls).length === 0) {
5238
5239
  const empty = document.createElement("p");
@@ -5627,13 +5628,13 @@ function rendersecurity(context) {
5627
5628
  allowbox.append(none);
5628
5629
  }
5629
5630
  for (const entry of view.allowlist) {
5630
- const line = document.createElement("p");
5631
- line.textContent = `${entry.origin} \xB7 profile workspace ${entry.profileid} \xB7 granted ${new Date(entry.grantedat).toLocaleString()}`;
5632
- line.append(" ", button("Remove", async () => {
5631
+ const line2 = document.createElement("p");
5632
+ line2.textContent = `${entry.origin} \xB7 profile workspace ${entry.profileid} \xB7 granted ${new Date(entry.grantedat).toLocaleString()}`;
5633
+ line2.append(" ", button("Remove", async () => {
5633
5634
  await request({ kind: "security", allowlist: { remove: { origin: entry.origin } } });
5634
5635
  await refresh();
5635
5636
  }));
5636
- allowbox.append(line);
5637
+ allowbox.append(line2);
5637
5638
  }
5638
5639
  const origininput = document.createElement("input");
5639
5640
  origininput.placeholder = "https://exact.example";
@@ -5662,9 +5663,9 @@ function rendersecurity(context) {
5662
5663
  profilebox.append(none);
5663
5664
  }
5664
5665
  for (const profile of view.profiles) {
5665
- const line = document.createElement("p");
5666
- line.textContent = `${profile.origin}: ${profile.grants.length} granted kind${profile.grants.length === 1 ? "" : "s"}${profile.denials.length > 0 ? `, ${profile.denials.length} denied kind${profile.denials.length === 1 ? "" : "s"}` : ""}.`;
5667
- profilebox.append(line);
5666
+ const line2 = document.createElement("p");
5667
+ line2.textContent = `${profile.origin}: ${profile.grants.length} granted kind${profile.grants.length === 1 ? "" : "s"}${profile.denials.length > 0 ? `, ${profile.denials.length} denied kind${profile.denials.length === 1 ? "" : "s"}` : ""}.`;
5668
+ profilebox.append(line2);
5668
5669
  }
5669
5670
  if (context.session?.origin !== void 0) {
5670
5671
  const kindinput = document.createElement("input");
@@ -5696,13 +5697,13 @@ function rendersecurity(context) {
5696
5697
  }
5697
5698
  for (const window2 of view.windows) {
5698
5699
  const remaining = window2.state === "active" ? Math.max(0, window2.expiresat - now) : 0;
5699
- const line = document.createElement("p");
5700
- line.textContent = `${window2.origin} \xB7 ${window2.state === "active" ? `active, ${Math.ceil(remaining / 1e3)}s of the ${window2.boundary} boundary left` : `closed at ${new Date(window2.closedat ?? window2.expiresat).toLocaleString()}`} \xB7 ${window2.kinds.length} kind${window2.kinds.length === 1 ? "" : "s"} covered.`;
5700
+ const line2 = document.createElement("p");
5701
+ line2.textContent = `${window2.origin} \xB7 ${window2.state === "active" ? `active, ${Math.ceil(remaining / 1e3)}s of the ${window2.boundary} boundary left` : `closed at ${new Date(window2.closedat ?? window2.expiresat).toLocaleString()}`} \xB7 ${window2.kinds.length} kind${window2.kinds.length === 1 ? "" : "s"} covered.`;
5701
5702
  if (window2.state === "active") {
5702
5703
  const durationinput2 = document.createElement("input");
5703
5704
  durationinput2.placeholder = "duration in ms";
5704
5705
  durationinput2.setAttribute("aria-label", "Renewal duration in milliseconds");
5705
- line.append(" ", durationinput2, " ", button("Renew", async () => {
5706
+ line2.append(" ", durationinput2, " ", button("Renew", async () => {
5706
5707
  const duration = Number(durationinput2.value.trim());
5707
5708
  const offer = Number.isFinite(duration) && duration > 0 ? duration : view.promptduration;
5708
5709
  if (offer === void 0) throw new Error("The renewal prompt needs its duration in milliseconds; no grant ever defaults to unlimited.");
@@ -5710,7 +5711,7 @@ function rendersecurity(context) {
5710
5711
  await refresh();
5711
5712
  }));
5712
5713
  }
5713
- windowbox.append(line);
5714
+ windowbox.append(line2);
5714
5715
  }
5715
5716
  const durationinput = document.createElement("input");
5716
5717
  durationinput.placeholder = "duration in ms";
@@ -5741,9 +5742,9 @@ function rendersecurity(context) {
5741
5742
  }
5742
5743
  for (const pending of prompts) {
5743
5744
  const classification = context.plan?.steps.find((step) => step.id === pending.stepid) !== void 0 ? sensitiveclassesof(context.plan.steps.find((step) => step.id === pending.stepid)) : { classes: [], bydefault: false };
5744
- const line = document.createElement("p");
5745
- line.textContent = `${pending.prompt}${classification.classes.length > 0 ? ` Class badge: ${classification.classes.join(", ")}.` : classification.bydefault ? " Class badge: sensitive by default." : ""}`;
5746
- promptbox.append(line);
5745
+ const line2 = document.createElement("p");
5746
+ line2.textContent = `${pending.prompt}${classification.classes.length > 0 ? ` Class badge: ${classification.classes.join(", ")}.` : classification.bydefault ? " Class badge: sensitive by default." : ""}`;
5747
+ promptbox.append(line2);
5747
5748
  }
5748
5749
  if (context.session?.origin !== void 0 && prompts.length > 0) {
5749
5750
  promptbox.append(button("Consent to every sensitive class", async () => {
@@ -5795,13 +5796,13 @@ function rendersecurity(context) {
5795
5796
  maskbox.append(none);
5796
5797
  }
5797
5798
  for (const rule of view.maskrules) {
5798
- const line = document.createElement("p");
5799
- line.textContent = `${rule.shapes.join(", ")}${rule.origin !== void 0 ? ` scoped to ${rule.origin}` : " global"} \xB7 values show as [redacted] fields in step details.`;
5800
- line.append(" ", button("Remove", async () => {
5799
+ const line2 = document.createElement("p");
5800
+ line2.textContent = `${rule.shapes.join(", ")}${rule.origin !== void 0 ? ` scoped to ${rule.origin}` : " global"} \xB7 values show as [redacted] fields in step details.`;
5801
+ line2.append(" ", button("Remove", async () => {
5801
5802
  await request({ kind: "security", mask: { remove: { id: rule.id } } });
5802
5803
  await refresh();
5803
5804
  }));
5804
- maskbox.append(line);
5805
+ maskbox.append(line2);
5805
5806
  }
5806
5807
  securityroot.append(maskbox);
5807
5808
  const gatebox = document.createElement("details");
@@ -5817,17 +5818,17 @@ function rendersecurity(context) {
5817
5818
  gatebox.append(none);
5818
5819
  }
5819
5820
  for (const gate of gates) {
5820
- const line = document.createElement("p");
5821
+ const line2 = document.createElement("p");
5821
5822
  const payload = Object.entries(gate.payload).map(([key, value]) => `${key} ${value}`).join(", ");
5822
- line.textContent = `${gate.kind} \xB7 step ${gate.stepid} on ${gate.origin} \xB7 ${payload} \xB7 ${gate.state}${gate.resolvedat !== void 0 ? ` at ${new Date(gate.resolvedat).toLocaleTimeString()} by ${gate.actor ?? "the user"}` : " \xB7 waiting for one distinct human action; no timeout resolves a gate"}.`;
5823
- if (gate.state === "open") line.append(" ", button("Approve", async () => {
5823
+ line2.textContent = `${gate.kind} \xB7 step ${gate.stepid} on ${gate.origin} \xB7 ${payload} \xB7 ${gate.state}${gate.resolvedat !== void 0 ? ` at ${new Date(gate.resolvedat).toLocaleTimeString()} by ${gate.actor ?? "the user"}` : " \xB7 waiting for one distinct human action; no timeout resolves a gate"}.`;
5824
+ if (gate.state === "open") line2.append(" ", button("Approve", async () => {
5824
5825
  await request({ kind: "security", gate: { resolve: { gateid: gate.gateid, decision: "resolved" } } });
5825
5826
  await refresh();
5826
5827
  }), " ", button("Refuse", async () => {
5827
5828
  await request({ kind: "security", gate: { resolve: { gateid: gate.gateid, decision: "refused" } } });
5828
5829
  await refresh();
5829
5830
  }));
5830
- gatebox.append(line);
5831
+ gatebox.append(line2);
5831
5832
  }
5832
5833
  securityroot.append(gatebox);
5833
5834
  const deferbox = document.createElement("details");
@@ -5867,16 +5868,16 @@ function rendersecurity(context) {
5867
5868
  chainbox.append(none);
5868
5869
  }
5869
5870
  for (const chain of view.chain) {
5870
- const line = document.createElement("p");
5871
- line.textContent = `${chain.runid}: ${chain.valid ? "chain verified" : `chain broken at entry ${chain.brokenat ?? "unknown"}`} \xB7 ${chain.entries} entries${chain.sealhash !== void 0 ? ` \xB7 seal hash ${chain.sealhash.slice(0, 12)}\u2026 at ${new Date(chain.sealedat ?? 0).toLocaleString()}` : " \xB7 unsealed"}.`;
5872
- line.append(" ", button("Read log", async () => {
5871
+ const line2 = document.createElement("p");
5872
+ line2.textContent = `${chain.runid}: ${chain.valid ? "chain verified" : `chain broken at entry ${chain.brokenat ?? "unknown"}`} \xB7 ${chain.entries} entries${chain.sealhash !== void 0 ? ` \xB7 seal hash ${chain.sealhash.slice(0, 12)}\u2026 at ${new Date(chain.sealedat ?? 0).toLocaleString()}` : " \xB7 unsealed"}.`;
5873
+ line2.append(" ", button("Read log", async () => {
5873
5874
  const read = await request({ kind: "security", read: { runid: chain.runid } });
5874
5875
  status(read.verification ?? `The log of ${chain.runid} read through the audit accessor.`);
5875
5876
  }), " ", button("Export audit file", async () => {
5876
5877
  const exported = await request({ kind: "security", export: { runid: chain.runid } });
5877
5878
  status(`The verified run log of ${chain.runid} was exported as an audit file with ${exported.export?.entries ?? 0} entries.`);
5878
5879
  }));
5879
- chainbox.append(line);
5880
+ chainbox.append(line2);
5880
5881
  }
5881
5882
  const chainnote = document.createElement("p");
5882
5883
  chainnote.className = "muted";
@@ -5953,9 +5954,9 @@ function renderenvironments(context) {
5953
5954
  groupbox.append(none);
5954
5955
  }
5955
5956
  for (const [environment, stepids] of grouped) {
5956
- const line = document.createElement("p");
5957
- line.textContent = `${environment}: ${stepids.length} step${stepids.length === 1 ? "" : "s"}${view.report.turnarounds.filter((entry) => stepids.includes(entry.stepid)).length > 0 ? ` \xB7 worker turnaround ${view.report.turnarounds.filter((entry) => stepids.includes(entry.stepid)).map((entry) => `${entry.stepid}: ${entry.milliseconds} ms`).join(", ")}` : ""}`;
5958
- groupbox.append(line);
5957
+ const line2 = document.createElement("p");
5958
+ line2.textContent = `${environment}: ${stepids.length} step${stepids.length === 1 ? "" : "s"}${view.report.turnarounds.filter((entry) => stepids.includes(entry.stepid)).length > 0 ? ` \xB7 worker turnaround ${view.report.turnarounds.filter((entry) => stepids.includes(entry.stepid)).map((entry) => `${entry.stepid}: ${entry.milliseconds} ms`).join(", ")}` : ""}`;
5959
+ groupbox.append(line2);
5959
5960
  }
5960
5961
  environmentsroot.append(groupbox);
5961
5962
  const grantbox = document.createElement("div");
@@ -7054,4 +7055,477 @@ function renderagents(context) {
7054
7055
  }
7055
7056
  });
7056
7057
  }
7058
+ var historystate = { hits: [], query: "" };
7059
+ function rendersessiongrid(view) {
7060
+ const root = document.querySelector("#sessiongrid");
7061
+ if (!root) return;
7062
+ root.replaceChildren();
7063
+ const empty = view.emptystates.find((state) => state.surface === "sessiongrid");
7064
+ if (view.grid.length === 0) {
7065
+ root.append(line(empty?.message ?? "No session exists yet; start the first run by describing an objective and reviewing the plan the agent proposes."));
7066
+ return;
7067
+ }
7068
+ for (const row of view.grid) {
7069
+ const item = document.createElement("div");
7070
+ item.className = "row";
7071
+ const summary = document.createElement("p");
7072
+ summary.textContent = `${row.state} run ${row.runid} \u2014 ${row.origins.join(", ")} \u2014 ${row.outcome} \u2014 ${row.completed}/${row.steps} steps \u2014 lock ${row.lock}${row.sealhash !== void 0 ? ` \u2014 sealed ${row.sealhash.slice(0, 12)}` : ""}`;
7073
+ item.append(summary);
7074
+ if (row.actions.includes("cancelrun")) item.append(button("Cancel run", async () => {
7075
+ await request({ kind: "sessions", cancel: { runid: row.runid, ...view.cancelrollback !== void 0 ? { rollback: view.cancelrollback } : {} } });
7076
+ status(`The run ${row.runid} cancelled with its queued rollback.`);
7077
+ await refresh();
7078
+ }));
7079
+ if (row.actions.includes("resume")) item.append(" ", button("Resume", async () => {
7080
+ await request({ kind: "sessions", grid: { resume: { runid: row.runid } } });
7081
+ status(`The session of the run ${row.runid} resumed.`);
7082
+ await refresh();
7083
+ }));
7084
+ if (row.actions.includes("reopen")) item.append(" ", button("Reopen sealed run", async () => {
7085
+ const result = await request({ kind: "sessions", grid: { reopen: { runid: row.runid } } });
7086
+ status(`The sealed run ${row.runid} reopened with ${result.entries} verified log entries.`);
7087
+ }));
7088
+ item.append(" ", button("Open in sidepanel", async () => {
7089
+ await request({ kind: "sessions", grid: { open: { runid: row.runid } } });
7090
+ }));
7091
+ root.append(item);
7092
+ }
7093
+ }
7094
+ function renderhistorysearch(view) {
7095
+ const root = document.querySelector("#historysearch");
7096
+ if (!root) return;
7097
+ root.replaceChildren();
7098
+ if (!view.historyindex) {
7099
+ root.append(line("The historysearch index building stays off in the options; turn it on to search sessions, notes and summaries."));
7100
+ return;
7101
+ }
7102
+ const input = document.createElement("input");
7103
+ input.placeholder = "Search sessions, notes and run summaries";
7104
+ input.value = historystate.query;
7105
+ input.addEventListener("keydown", (event) => {
7106
+ if (event.key !== "Enter") return;
7107
+ void (async () => {
7108
+ const answer = await request({ kind: "sessions", search: { query: { text: input.value } } });
7109
+ historystate.hits = answer.hits;
7110
+ historystate.query = input.value;
7111
+ renderhistorysearch(view);
7112
+ })();
7113
+ });
7114
+ root.append(input, " ", button("Search", async () => {
7115
+ const answer = await request({ kind: "sessions", search: { query: { text: input.value } } });
7116
+ historystate.hits = answer.hits;
7117
+ historystate.query = input.value;
7118
+ renderhistorysearch(view);
7119
+ }));
7120
+ if (historystate.hits.length === 0) {
7121
+ root.append(line(view.emptystates.find((state) => state.surface === "historysearch")?.message ?? "No history matches yet; start with a first query such as an origin, a note title or a kind the runs executed."));
7122
+ return;
7123
+ }
7124
+ for (const hit of historystate.hits) {
7125
+ const item = document.createElement("div");
7126
+ item.className = "row";
7127
+ const text = document.createElement("p");
7128
+ text.textContent = `${hit.source}: ${hit.title} \u2014 ${hit.excerpt}${hit.highlights.length > 0 ? ` [matched: ${hit.highlights.join(", ")}]` : ""}`;
7129
+ item.append(text);
7130
+ item.append(button("Open sealed run", async () => {
7131
+ await request({ kind: "sessions", grid: { open: { runid: hit.source === "summary" ? hit.id : hit.id } } });
7132
+ status(`The history hit ${hit.id} links to its sealed run view.`);
7133
+ }));
7134
+ root.append(item);
7135
+ }
7136
+ }
7137
+ function rendersitenotes(view) {
7138
+ const root = document.querySelector("#sitenotes");
7139
+ if (!root) return;
7140
+ root.replaceChildren();
7141
+ if (view.notes.length === 0) root.append(line(view.emptystates.find((state) => state.surface === "sitenotes")?.message ?? "No site note exists yet; write the first note with a title and a body and the note flow keeps it per origin with its author provenance."));
7142
+ for (const note of view.notes) {
7143
+ const item = document.createElement("div");
7144
+ item.className = "row";
7145
+ const text = document.createElement("p");
7146
+ text.textContent = `${note.origin}: ${note.title} \u2014 ${note.body}${note.sensitive ? " (sensitive: the body stays sealed at rest)" : ""} \u2014 by ${note.author} at ${new Date(note.updatedat).toLocaleString()}`;
7147
+ item.append(text);
7148
+ item.append(button("Edit note", async () => {
7149
+ const title2 = window.prompt("Note title", note.title);
7150
+ if (title2 === null) return;
7151
+ const body2 = window.prompt("Note body", note.body);
7152
+ if (body2 === null) return;
7153
+ await request({ kind: "sessions", note: { edit: { id: note.id, title: title2, body: body2 } } });
7154
+ status("The site note edit landed with its author provenance.");
7155
+ await refresh();
7156
+ }), " ", button("Remove note", async () => {
7157
+ await request({ kind: "sessions", note: { remove: { id: note.id } } });
7158
+ status("The site note removed.");
7159
+ await refresh();
7160
+ }));
7161
+ root.append(item);
7162
+ }
7163
+ const title = document.createElement("input");
7164
+ title.placeholder = "note title";
7165
+ const body = document.createElement("input");
7166
+ body.placeholder = "note body";
7167
+ const sensitive = document.createElement("input");
7168
+ sensitive.type = "checkbox";
7169
+ const senslabel = document.createElement("label");
7170
+ senslabel.append(sensitive, " sensitive (seals the body at rest)");
7171
+ root.append(document.createElement("hr"), title, " ", body, " ", senslabel, " ", button("Write note", async () => {
7172
+ await request({ kind: "sessions", note: { add: { title: title.value, body: body.value, consent: true, ...sensitive.checked ? { sensitive: true } : {} } } });
7173
+ status("The site note landed per origin behind the explicit consent of the write.");
7174
+ await refresh();
7175
+ }));
7176
+ }
7177
+ function renderscratchpad(view) {
7178
+ const root = document.querySelector("#scratchpad");
7179
+ if (!root) return;
7180
+ root.replaceChildren();
7181
+ if (view.scratchpad.length === 0) root.append(line(view.emptystates.find((state) => state.surface === "scratchpad")?.message ?? "The scratchpad holds no entry yet; the agent appends its per task notes here while the reviewed steps run, and every entry carries its step provenance."));
7182
+ for (const entry of view.scratchpad) {
7183
+ const item = document.createElement("p");
7184
+ item.textContent = `${new Date(entry.at).toLocaleTimeString()} ${entry.author}${entry.stepid !== void 0 ? ` beside ${entry.stepid}` : ""}: ${entry.text}`;
7185
+ root.append(item);
7186
+ }
7187
+ const text = document.createElement("input");
7188
+ text.placeholder = "append one scratchpad entry";
7189
+ root.append(document.createElement("hr"), text, " ", button("Append", async () => {
7190
+ await request({ kind: "sessions", scratch: { append: { text: text.value } } });
7191
+ status("The scratchpad entry appended; the pad stays append only.");
7192
+ await refresh();
7193
+ }));
7194
+ }
7195
+ function rendersessionmemory(view) {
7196
+ const root = document.querySelector("#sessionmemory");
7197
+ if (!root) return;
7198
+ root.replaceChildren();
7199
+ const summaryhead = document.createElement("h3");
7200
+ summaryhead.textContent = "Run summaries";
7201
+ root.append(summaryhead);
7202
+ if (view.summaries.length === 0) root.append(line("No run summary exists yet; the executor distills one at run completion as an offscreen worker task."));
7203
+ for (const summary of view.summaries) {
7204
+ root.append(line(`${summary.runid} \u2014 ${summary.origins.join(", ")} \u2014 ${summary.kinds.length} kind${summary.kinds.length === 1 ? "" : "s"} \u2014 ${summary.steps} step outcome${summary.steps === 1 ? "" : "s"} \u2014 distilled ${summary.provenance === "offscreenworker" ? "inside the offscreen worker pool" : "inline beside the page"} at ${new Date(summary.distilledat).toLocaleString()}`));
7205
+ }
7206
+ const recallhead = document.createElement("h3");
7207
+ recallhead.textContent = "Semantic recall";
7208
+ root.append(recallhead);
7209
+ if (view.recall.length === 0) root.append(line("No past extraction matches the current objective inside the run scope yet."));
7210
+ for (const match of view.recall) root.append(line(`${match.origin} run ${match.runid} step ${match.stepid} \u2014 score ${match.score.toFixed(3)} \u2014 ${match.reason}`));
7211
+ const recallquery = document.createElement("input");
7212
+ recallquery.placeholder = "recall past extractions while planning";
7213
+ root.append(recallquery, " ", button("Recall", async () => {
7214
+ const answer = await request({ kind: "sessions", recall: { query: { text: recallquery.value } } });
7215
+ status(answer.matches.length > 0 ? answer.matches.map((match) => `${match.entry.origin} ${match.entry.stepid} ${match.score.toFixed(3)}`).join(" \xB7 ") : "No past extraction matches the query inside the run scope.");
7216
+ }));
7217
+ const correctionshead = document.createElement("h3");
7218
+ correctionshead.textContent = "Correction memory";
7219
+ root.append(correctionshead);
7220
+ if (view.corrections.length === 0) root.append(line("No correction exists yet; plan review edits and rejections land here per origin and kind."));
7221
+ for (const correction of view.corrections) root.append(line(`${correction.source} ${correction.kind} step ${correction.stepid} of ${correction.origin}: ${correction.reason}`));
7222
+ const consenthead = document.createElement("h3");
7223
+ consenthead.textContent = "Consent memory";
7224
+ root.append(consenthead);
7225
+ if (view.consentmemory.length === 0) root.append(line("No consent decision exists yet; every grant, denial, expiry and revocation lands here per origin and stays advisory."));
7226
+ for (const entry of view.consentmemory) root.append(line(`${entry.origin} ${entry.decision} ${entry.kinds.join(", ")} \u2014 boundary ${entry.boundary} \u2014 ${new Date(entry.at).toLocaleString()}${entry.expiresat !== void 0 ? ` \u2014 expires ${new Date(entry.expiresat).toLocaleString()}` : ""}`));
7227
+ const errorshead = document.createElement("h3");
7228
+ errorshead.textContent = "Error surfaces";
7229
+ root.append(errorshead);
7230
+ if (view.errors.length === 0) root.append(line("No failed step recorded an error surface yet."));
7231
+ for (const surface of view.errors) {
7232
+ const item = document.createElement("div");
7233
+ item.className = "row";
7234
+ item.append(line(`${surface.cause} failure of step ${surface.stepid} of run ${surface.runid}: ${surface.message} \u2014 retry ${surface.retry.allowed ? "allowed" : "refused"}: ${surface.retry.reason}`));
7235
+ if (surface.retry.allowed) item.append(button("Retry reviewed step", async () => {
7236
+ const output = await request({ kind: "sessions", retry: { stepid: surface.stepid } });
7237
+ status(output.summary);
7238
+ await refresh();
7239
+ }));
7240
+ root.append(item);
7241
+ }
7242
+ }
7243
+ function rendersessioninterface(context) {
7244
+ const view = context.sessionview;
7245
+ if (!view) return;
7246
+ rendersessiongrid(view);
7247
+ renderhistorysearch(view);
7248
+ rendersitenotes(view);
7249
+ renderscratchpad(view);
7250
+ rendersessionmemory(view);
7251
+ }
7252
+ var tasksubmitbutton = document.querySelector("#tasksubmit");
7253
+ var plancardsroot = document.querySelector("#plancards");
7254
+ var stepstimelineroot = document.querySelector("#stepstimeline");
7255
+ var logstreamroot = document.querySelector("#logstream");
7256
+ var logstreampaused = false;
7257
+ var logstreamfilter = {};
7258
+ function applyworkspacetabs(active) {
7259
+ const plantitles = ["Current plan", "Clickable map", "Detected shapes", "Derived selectors", "Structured diagnostics"];
7260
+ const reviewtitles = ["Plan cards", "Steps timeline", "Log stream", "Local audit", "Session grid", "History search", "Site notes", "Scratchpad", "Session memory", "Security", "Console diff", "Datasets", "Consent banners", "Accessibility tree", "Reader view", "Snapshot diffs", "Agent protocol", "Models"];
7261
+ for (const section of Array.from(document.querySelectorAll("main > section"))) {
7262
+ const title = section.querySelector("h2")?.textContent?.trim() ?? "";
7263
+ const tab = plantitles.includes(title) ? "plan" : reviewtitles.includes(title) ? "review" : "run";
7264
+ section.hidden = tab !== active;
7265
+ }
7266
+ for (const tab of ["plan", "run", "review"]) {
7267
+ const element = document.querySelector(`#tab${tab}`);
7268
+ if (element) element.className = tab === active ? "" : "secondary";
7269
+ }
7270
+ }
7271
+ for (const tab of ["plan", "run", "review"]) {
7272
+ document.querySelector(`#tab${tab}`)?.addEventListener("click", () => applyworkspacetabs(tab));
7273
+ }
7274
+ applyworkspacetabs("plan");
7275
+ tasksubmitbutton?.addEventListener("click", () => {
7276
+ const text = objective?.value ?? "";
7277
+ if (text.trim() === "") {
7278
+ status("Describe the goal first; the proposal flow needs its natural language task.", true);
7279
+ return;
7280
+ }
7281
+ void (async () => {
7282
+ status("The taskinput goal routes through the proposal flow; the plan generates.");
7283
+ const result = await request({ kind: "surface", task: { submit: { text, surface: "sidepanel" } } });
7284
+ status(`The taskinput goal became the plan ${result.plan?.id ?? ""}; review its plancards below.`);
7285
+ await refresh();
7286
+ await rendersurfacereview();
7287
+ })().catch((error) => status(error instanceof Error ? error.message : String(error), true));
7288
+ });
7289
+ async function renderplancards() {
7290
+ if (!plancardsroot) return;
7291
+ try {
7292
+ const result = await request({ kind: "surface", review: { groups: true } });
7293
+ plancardsroot.replaceChildren();
7294
+ if (result.cards.length === 0) {
7295
+ plancardsroot.textContent = "No plan exists yet; submit a task goal and the proposed steps render their cards here.";
7296
+ return;
7297
+ }
7298
+ for (const group of result.groups) {
7299
+ const heading = document.createElement("h3");
7300
+ heading.textContent = `${group.risk} steps${group.expanded ? " (expanded)" : ""}`;
7301
+ plancardsroot.append(heading);
7302
+ for (const card of group.cards) {
7303
+ const item = document.createElement("div");
7304
+ item.className = "panel";
7305
+ const label = document.createElement("strong");
7306
+ label.textContent = `${card.stepid} \xB7 ${card.kind} \xB7 ${card.environment}`;
7307
+ const summary = document.createElement("p");
7308
+ summary.textContent = card.summary;
7309
+ const options2 = document.createElement("p");
7310
+ options2.className = "muted";
7311
+ options2.textContent = card.options === "" ? "No reviewed options." : `Options: ${card.options}`;
7312
+ item.append(label, summary, options2);
7313
+ for (const correction of card.corrections) item.append(Object.assign(document.createElement("p"), { className: "muted", textContent: `Correction memory (${correction.source}): ${correction.reason}` }));
7314
+ if (card.editable) {
7315
+ item.append(button("Approve step", () => resolveStep(card.stepid, "approve")));
7316
+ item.append(" ", button("Reject step", () => resolveStep(card.stepid, "reject")));
7317
+ item.append(" ", button("Edit step", () => editStep(card.stepid)));
7318
+ }
7319
+ if (card.risk === "sensitive") item.append(" ", button("Diff preview", () => diffPreview(card.stepid)));
7320
+ plancardsroot.append(item);
7321
+ }
7322
+ }
7323
+ } catch (error) {
7324
+ plancardsroot.textContent = error instanceof Error ? error.message : String(error);
7325
+ }
7326
+ }
7327
+ async function resolveStep(stepid, resolution) {
7328
+ const result = await request({ kind: "surface", approve: { resolve: { stepid, resolution, surface: "sidepanel" } } });
7329
+ status(`The step ${result.resolution.stepid} resolved with a ${result.resolution.resolution}; the resolution landed in the immutable log.`);
7330
+ await refresh();
7331
+ await rendersurfacereview();
7332
+ }
7333
+ async function editStep(stepid) {
7334
+ if (!plancardsroot) return;
7335
+ const editor = document.createElement("div");
7336
+ editor.className = "panel";
7337
+ const input = document.createElement("textarea");
7338
+ input.rows = 4;
7339
+ input.value = '{ "kind": "click", "summary": "Describe the corrected step." }';
7340
+ const save = button("Save edit", async () => {
7341
+ const result = await request({ kind: "surface", approve: { resolve: { stepid, resolution: "edit", edited: input.value, surface: "sidepanel" } } });
7342
+ status(`The step ${result.resolution.stepid} carries the edited shape and the correction memory recorded the change.`);
7343
+ editor.remove();
7344
+ await refresh();
7345
+ await rendersurfacereview();
7346
+ });
7347
+ editor.append(input, save);
7348
+ plancardsroot.append(editor);
7349
+ }
7350
+ async function diffPreview(stepid) {
7351
+ const before = {};
7352
+ try {
7353
+ const preview = await request({ kind: "preview", stepid });
7354
+ if (preview.resolvedtarget?.selector !== void 0) before.selector = preview.resolvedtarget.selector;
7355
+ if (preview.resolvedtarget?.text !== void 0) before.text = preview.resolvedtarget.text;
7356
+ if (preview.resolvedtarget?.mode !== void 0) before.mode = preview.resolvedtarget.mode;
7357
+ } catch {
7358
+ }
7359
+ const result = await request({ kind: "surface", diff: { preview: { stepid, before } } });
7360
+ const detail = result.preview.changes.map((change) => `${change.kind} ${change.field}${change.before !== void 0 ? ` from ${change.before}` : ""}${change.after !== void 0 ? ` to ${change.after}` : ""}`).join("; ");
7361
+ const masked = Object.entries(result.preview.maskverdicts).map(([field, verdict]) => `${field}: ${verdict}`).join("; ");
7362
+ status(`Diff preview of ${stepid} (${result.preview.provenance}): ${detail === "" ? "no field changes" : detail}${masked === "" ? "" : ` \u2014 masked: ${masked}`}`);
7363
+ }
7364
+ async function renderstepstimeline() {
7365
+ if (!stepstimelineroot) return;
7366
+ try {
7367
+ const result = await request({ kind: "surface", timeline: { nodes: true } });
7368
+ stepstimelineroot.replaceChildren();
7369
+ if (result.nodes.length === 0) {
7370
+ stepstimelineroot.textContent = "No plan runs yet; the timeline derives its nodes from progress records with no new state.";
7371
+ return;
7372
+ }
7373
+ const list = document.createElement("ol");
7374
+ list.className = "audit";
7375
+ for (const node of result.nodes) {
7376
+ const item = document.createElement("li");
7377
+ item.id = node.anchor.slice(1);
7378
+ const badge = node.active ? " \u25B6" : "";
7379
+ const duration = node.durationms !== void 0 ? ` \xB7 ${node.durationms}ms` : "";
7380
+ const environment = node.environment !== void 0 ? ` \xB7 ${node.environment}` : "";
7381
+ item.textContent = `${node.stepid} ${node.kind} \u2014 ${node.status}${duration}${environment}${badge}${node.resultsummary !== void 0 ? ` \u2014 ${node.resultsummary}` : ""}`;
7382
+ if (node.status === "waiting") item.append(" ", button("Diff preview at the gate wait", () => diffPreview(node.stepid)));
7383
+ if (node.active) item.scrollIntoView({ block: "nearest" });
7384
+ list.append(item);
7385
+ }
7386
+ stepstimelineroot.append(list);
7387
+ } catch (error) {
7388
+ stepstimelineroot.textContent = error instanceof Error ? error.message : String(error);
7389
+ }
7390
+ }
7391
+ async function renderlogstream() {
7392
+ if (!logstreamroot) return;
7393
+ try {
7394
+ const result = await request({ kind: "surface", logstream: { read: { filters: logstreamfilter } } });
7395
+ logstreamroot.replaceChildren();
7396
+ const controls = document.createElement("div");
7397
+ controls.className = "actions";
7398
+ const pause = button(logstreampaused ? "Resume stream" : "Pause stream", async () => {
7399
+ logstreampaused = !logstreampaused;
7400
+ await renderlogstream();
7401
+ });
7402
+ const levelselect = document.createElement("select");
7403
+ for (const level of ["", "error", "warn", "info", "log", "debug", "trace"]) {
7404
+ const option = document.createElement("option");
7405
+ option.value = level;
7406
+ option.textContent = level === "" ? "all levels" : level;
7407
+ levelselect.append(option);
7408
+ }
7409
+ levelselect.value = logstreamfilter.level ?? "";
7410
+ levelselect.addEventListener("change", () => {
7411
+ const level = levelselect.value;
7412
+ logstreamfilter = { ...logstreamfilter, ...level !== "" ? { level } : {} };
7413
+ void renderlogstream();
7414
+ });
7415
+ const copy = button("Copy verified excerpt", async () => {
7416
+ const excerpt = await request({ kind: "surface", logstream: { excerpt: {} } });
7417
+ await navigator.clipboard?.writeText(excerpt.excerpt).catch(() => {
7418
+ });
7419
+ status(excerpt.reason);
7420
+ });
7421
+ const chain = document.createElement("span");
7422
+ chain.className = "muted";
7423
+ chain.textContent = result.chain.valid ? `chain verified \xB7 ${result.total} events` : `chain broken: ${result.chain.reason}`;
7424
+ controls.append(pause, levelselect, copy, chain);
7425
+ const list = document.createElement("ol");
7426
+ list.className = "audit";
7427
+ for (const event of logstreampaused ? [] : result.events) {
7428
+ const item = document.createElement("li");
7429
+ item.textContent = `[${new Date(event.at).toLocaleTimeString()}] ${event.level} ${event.source}${event.stepid !== void 0 ? ` step ${event.stepid}` : ""} ${event.origin} \u2014 ${event.summary}${event.masked ? ` (${event.maskverdict})` : ""}`;
7430
+ list.append(item);
7431
+ }
7432
+ if (logstreampaused) list.append(Object.assign(document.createElement("li"), { textContent: "The live stream pauses while the run continues; the full history stays in memory." }));
7433
+ logstreamroot.append(controls, list);
7434
+ } catch (error) {
7435
+ logstreamroot.textContent = error instanceof Error ? error.message : String(error);
7436
+ }
7437
+ }
7438
+ async function rendersurfacereview() {
7439
+ await renderplancards();
7440
+ await renderstepstimeline();
7441
+ await renderlogstream();
7442
+ }
7443
+ void rendersurfacereview().catch(() => {
7444
+ });
7445
+ var surfacechannel = typeof BroadcastChannel === "function" ? new BroadcastChannel("devthinksurfaces") : void 0;
7446
+ surfacechannel?.addEventListener("message", (event) => {
7447
+ const frame = event.data;
7448
+ if (frame?.channel === "logstream") {
7449
+ if (!logstreampaused) void renderlogstream().catch(() => {
7450
+ });
7451
+ return;
7452
+ }
7453
+ void refresh().catch(() => {
7454
+ });
7455
+ void rendersurfacereview().catch(() => {
7456
+ });
7457
+ });
7458
+ var paletteinputnode = document.querySelector("#paletteinput");
7459
+ var palettematchespanel = document.querySelector("#palettematches");
7460
+ async function renderworkspacepalette() {
7461
+ if (!palettematchespanel) return;
7462
+ try {
7463
+ const result = await request({ kind: "surface", palette: { query: { text: paletteinputnode?.value ?? "" } } });
7464
+ palettematchespanel.replaceChildren();
7465
+ for (const match of result.matches.slice(0, 6)) {
7466
+ const item = document.createElement("button");
7467
+ item.type = "button";
7468
+ item.className = "secondary";
7469
+ item.textContent = `${match.entry.label} (${match.entry.action.surface})`;
7470
+ item.title = match.reason;
7471
+ item.addEventListener("click", () => {
7472
+ void runworkspacepalette(match.entry.action.command).catch((error) => status(error instanceof Error ? error.message : String(error), true));
7473
+ });
7474
+ palettematchespanel.append(item, " ");
7475
+ }
7476
+ if (result.matches.length === 0) palettematchespanel.textContent = "No command matches; the palette lists only the actions the current capability set allows.";
7477
+ } catch (error) {
7478
+ palettematchespanel.textContent = error instanceof Error ? error.message : String(error);
7479
+ }
7480
+ }
7481
+ async function runworkspacepalette(command) {
7482
+ await request({ kind: "surface", palette: { used: { command } } });
7483
+ if (command === "opendashboardpage" || command === "historysearch") {
7484
+ await chrome.tabs.create({ url: chrome.runtime.getURL("dashboardpage.html") });
7485
+ status("The dashboardpage opened in a new tab.");
7486
+ return;
7487
+ }
7488
+ if (command === "openoptionspage") {
7489
+ await chrome.tabs.create({ url: chrome.runtime.getURL("optionspage.html") });
7490
+ status("The optionspage opened in a new tab.");
7491
+ return;
7492
+ }
7493
+ if (command === "opentransparencypage") {
7494
+ await chrome.tabs.create({ url: chrome.runtime.getURL("transparencypage.html") });
7495
+ status("The transparencypage opened in a new tab.");
7496
+ return;
7497
+ }
7498
+ if (command === "replayonboarding") {
7499
+ await request({ kind: "surface", onboarding: { replay: true } });
7500
+ status("The onboarding walkthrough replays on the next popup open.");
7501
+ return;
7502
+ }
7503
+ if (command === "copyauditexcerpt") {
7504
+ const result = await request({ kind: "surface", logstream: { excerpt: {} } });
7505
+ await navigator.clipboard?.writeText(result.excerpt).catch(() => {
7506
+ });
7507
+ status("The verified range copied as an audit excerpt.");
7508
+ return;
7509
+ }
7510
+ const route = await request({ kind: "surface", bus: { action: { surface: "sidepanel", command } } });
7511
+ status(route.route.reason);
7512
+ await refresh();
7513
+ await rendersurfacereview();
7514
+ }
7515
+ paletteinputnode?.addEventListener("input", () => {
7516
+ void renderworkspacepalette();
7517
+ });
7518
+ document.querySelector("#paletteopen")?.addEventListener("click", () => {
7519
+ paletteinputnode?.focus();
7520
+ void renderworkspacepalette();
7521
+ });
7522
+ document.addEventListener("keydown", (event) => {
7523
+ if (event.ctrlKey && event.key === ".") {
7524
+ event.preventDefault();
7525
+ paletteinputnode?.focus();
7526
+ void renderworkspacepalette();
7527
+ }
7528
+ });
7529
+ void renderworkspacepalette().catch(() => {
7530
+ });
7057
7531
  //# sourceMappingURL=sidepanel.js.map