@ai-ecoverse/slicc-spectrum 2.9.1 → 2.10.0

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.
package/dist/slicc-ui.js CHANGED
@@ -39964,7 +39964,7 @@ function watchTitles(model, update) {
39964
39964
  seen.set(id, title2);
39965
39965
  update();
39966
39966
  };
39967
- const stops = [
39967
+ const stops2 = [
39968
39968
  model.agent.on("messages", check3),
39969
39969
  model.agent.on("message", ({ agentId }) => check3(agentId)),
39970
39970
  model.agent.on("agents", (agents) => {
@@ -39974,7 +39974,7 @@ function watchTitles(model, update) {
39974
39974
  })
39975
39975
  ];
39976
39976
  return () => {
39977
- for (const stop of stops) stop();
39977
+ for (const stop of stops2) stop();
39978
39978
  };
39979
39979
  }
39980
39980
 
@@ -51980,8 +51980,11 @@ function extras(approval) {
51980
51980
  if (approval.kind === "capture") return [approval.detail, approval.requester];
51981
51981
  return [];
51982
51982
  }
51983
+ var stops = (approval) => approval.kind === "sudo" && approval.stoppable === true && approval.requester.kind === "agent" && !!approval.requester.agentId;
51984
+ var denies = (decision2) => decision2 === "deny" || decision2 === "stop";
51983
51985
  function answerable(approval, decision2) {
51984
51986
  if (decision2 === "deny") return true;
51987
+ if (decision2 === "stop") return stops(approval);
51985
51988
  if (approval.kind === "secret") return false;
51986
51989
  return approval.kind !== "click" || approval.here;
51987
51990
  }
@@ -52152,9 +52155,23 @@ var SliccApprovals = class extends ModelElement {
52152
52155
  .judged p {
52153
52156
  margin: 0;
52154
52157
  }
52155
- [slot='button'][data-action='deny'] {
52158
+ [slot='button'][data-action='deny'],
52159
+ [slot='button'][data-action='stop'] {
52156
52160
  margin-inline-end: auto;
52157
52161
  }
52162
+ [slot='button'][data-action='deny']:has(+ [data-action='stop']) {
52163
+ margin-inline-end: 0;
52164
+ }
52165
+ sp-alert-dialog {
52166
+ --mod-buttongroup-spacing: var(--swc-spacing-300);
52167
+ }
52168
+ .break {
52169
+ flex-basis: 100%;
52170
+ block-size: 0;
52171
+ }
52172
+ .break ~ [slot='button'] {
52173
+ margin-block-start: calc(-1 * var(--swc-spacing-300));
52174
+ }
52158
52175
  .prompt {
52159
52176
  margin-block-start: var(--swc-spacing-200);
52160
52177
  padding-inline-start: var(--swc-spacing-200);
@@ -52264,10 +52281,11 @@ var SliccApprovals = class extends ModelElement {
52264
52281
  async decide(approval, decision2) {
52265
52282
  const port = this.model?.approvals;
52266
52283
  const { id } = approval;
52267
- if (!port?.decide || this.busy || this.gone || this.#showing?.id !== id || this.#done.has(id) || this.#closed.has(id) || !answerable(approval, decision2) || decision2 !== "deny" && (!this.#arming.settled() || !this.#whole(approval)))
52284
+ if (!port?.decide || this.busy || this.gone || this.#showing?.id !== id || this.#done.has(id) || this.#closed.has(id) || !answerable(approval, decision2) || !denies(decision2) && (!this.#arming.settled() || !this.#whole(approval)))
52268
52285
  return;
52269
52286
  const live = port.list().find(({ id: id2 }) => id2 === approval.id);
52270
52287
  if (decision2 === "always" && !(live && offersAlways(live))) return;
52288
+ if (decision2 === "stop" && !(live && stops(live))) return;
52271
52289
  this.busy = decision2;
52272
52290
  this.failure = null;
52273
52291
  this.#pending.add(approval.id);
@@ -52407,7 +52425,7 @@ var SliccApprovals = class extends ModelElement {
52407
52425
  fill-style=${variant === "accent" ? A : "outline"}
52408
52426
  data-action=${decision2}
52409
52427
  ?pending=${this.busy === decision2}
52410
- ?disabled=${!!this.busy && this.busy !== decision2 || decision2 !== "deny" && !this.#whole(approval)}
52428
+ ?disabled=${!!this.busy && this.busy !== decision2 || !denies(decision2) && !this.#whole(approval)}
52411
52429
  @click=${(event2) => this.#click(event2, approval, decision2)}
52412
52430
  >${label}</swc-button
52413
52431
  >`;
@@ -52469,6 +52487,7 @@ var SliccApprovals = class extends ModelElement {
52469
52487
  return b`<swc-button slot="button" variant="secondary" fill-style="outline" data-action="close" @click=${() => this.#dismiss(approval)}>Close</swc-button>`;
52470
52488
  const click = approval.kind === "click";
52471
52489
  return b`${this.#button(approval, "deny", click ? "Cancel" : "Deny", "secondary")}
52490
+ ${stops(approval) ? b`${this.#button(approval, "stop", "Deny and stop", "secondary")}<span slot="button" class="break" aria-hidden="true"></span>` : A}
52472
52491
  ${always ? this.#button(approval, "always", inCwd(approval) ? "Always allow in this directory" : "Always allow", "secondary") : A}
52473
52492
  ${answerable(approval, "once") ? this.#button(approval, "once", click ? approval.action : "Allow once", "accent") : A}`;
52474
52493
  }
@@ -52732,6 +52751,38 @@ var verbs2 = {
52732
52751
  function describe(action) {
52733
52752
  return verbs2[action.kind](action);
52734
52753
  }
52754
+ function recentActions(all2, shown6) {
52755
+ return all2.slice(-shown6).reverse();
52756
+ }
52757
+ function sameAction(a20, b10) {
52758
+ return a20.status === "done" && b10.status === "done" && a20.kind === b10.kind && a20.agentId === b10.agentId && a20.target === b10.target && a20.value === b10.value && a20.length === b10.length;
52759
+ }
52760
+ function foldActions(actions2) {
52761
+ const out = [];
52762
+ for (const action of actions2) {
52763
+ const prev = out.at(-1);
52764
+ if (prev && sameAction(prev.action, action)) {
52765
+ prev.count += 1;
52766
+ continue;
52767
+ }
52768
+ out.push({ action, count: 1 });
52769
+ }
52770
+ return out;
52771
+ }
52772
+ function pickImage(frame, shot, watching) {
52773
+ if (watching && frame) return frame;
52774
+ if (frame && (!shot || frame.at >= shot.at)) return frame;
52775
+ return shot ?? null;
52776
+ }
52777
+ function frameSize(box, dpr = 1, prior) {
52778
+ if (!box?.width || !box.height) return null;
52779
+ const width = Math.max(1, Math.round(box.width * dpr));
52780
+ const height = Math.max(1, Math.round(box.height * dpr));
52781
+ const slack = Math.max(2, Math.round(2 * dpr));
52782
+ if (prior && Math.abs(prior.width - width) <= slack && Math.abs(prior.height - height) <= slack)
52783
+ return { width: prior.width, height: prior.height, key: `${prior.width}x${prior.height}` };
52784
+ return { width, height, key: `${width}x${height}` };
52785
+ }
52735
52786
  var icons = {
52736
52787
  open: b`<swc-icon-open-in size="s"></swc-icon-open-in>`,
52737
52788
  goto: b`<swc-icon-link size="s"></swc-icon-link>`,
@@ -52776,8 +52827,9 @@ var SliccBrowser = class extends ModelElement {
52776
52827
  #last = null;
52777
52828
  #shown = actionPage;
52778
52829
  #anchor = null;
52830
+ #display = /* @__PURE__ */ new Map();
52831
+ #loading = /* @__PURE__ */ new Map();
52779
52832
  #expanded = new ViewSet(this, "browser");
52780
- #recent = new ViewState(this, "browser:recent", () => false);
52781
52833
  #chosen = new ViewState(this, "browser:tab", () => void 0);
52782
52834
  #scroll = new ViewScroll(this, "browser:scroll", {
52783
52835
  scroller: () => this.renderRoot.querySelector(".cards")?.parentElement ?? null,
@@ -52956,24 +53008,31 @@ var SliccBrowser = class extends ModelElement {
52956
53008
  .focused {
52957
53009
  display: grid;
52958
53010
  grid-template-columns: minmax(0, 1fr);
52959
- gap: var(--swc-spacing-300);
52960
- padding: var(--swc-spacing-300);
53011
+ gap: var(--swc-spacing-200);
53012
+ height: 100%;
53013
+ min-height: 0;
53014
+ padding: var(--swc-spacing-200);
53015
+ box-sizing: border-box;
52961
53016
  }
52962
53017
  .focused.wide {
52963
53018
  grid-template-columns: minmax(180px, 240px) minmax(0, 1fr);
52964
- align-items: start;
53019
+ grid-template-rows: minmax(0, 1fr);
53020
+ align-items: stretch;
52965
53021
  }
52966
53022
  .detail {
52967
53023
  display: flex;
52968
53024
  flex-direction: column;
52969
- gap: var(--swc-spacing-200);
53025
+ gap: var(--swc-spacing-100);
52970
53026
  min-width: 0;
53027
+ min-height: 0;
53028
+ height: 100%;
52971
53029
  }
52972
53030
  .bar,
52973
53031
  .address {
52974
53032
  display: flex;
52975
53033
  align-items: center;
52976
53034
  gap: var(--swc-spacing-100);
53035
+ flex: none;
52977
53036
  min-width: 0;
52978
53037
  }
52979
53038
  .bar sp-picker {
@@ -52981,13 +53040,14 @@ var SliccBrowser = class extends ModelElement {
52981
53040
  min-width: 0;
52982
53041
  max-width: 100%;
52983
53042
  }
52984
- .url {
53043
+ .address .url {
52985
53044
  flex: 1;
52986
53045
  min-width: 0;
52987
53046
  font-family: var(--swc-code-font-family-stack);
52988
53047
  color: var(--swc-neutral-subdued-content-color-default);
52989
53048
  }
52990
53049
  .detail .driving {
53050
+ flex: none;
52991
53051
  flex-wrap: nowrap;
52992
53052
  min-block-size: var(--swc-component-height-75);
52993
53053
  }
@@ -52997,6 +53057,18 @@ var SliccBrowser = class extends ModelElement {
52997
53057
  .detail .driving swc-button {
52998
53058
  flex: none;
52999
53059
  }
53060
+ .detail figure {
53061
+ flex: 0 1 auto;
53062
+ width: 100%;
53063
+ max-height: min(50vh, 100%);
53064
+ }
53065
+ .detail .feed {
53066
+ display: flex;
53067
+ flex-direction: column;
53068
+ flex: 1 1 10rem;
53069
+ min-height: 8rem;
53070
+ min-width: 0;
53071
+ }
53000
53072
  .swc-Link {
53001
53073
  font-size: inherit;
53002
53074
  }
@@ -53004,6 +53076,9 @@ var SliccBrowser = class extends ModelElement {
53004
53076
  display: flex;
53005
53077
  flex-direction: column;
53006
53078
  gap: var(--swc-spacing-50);
53079
+ min-height: 0;
53080
+ overflow: auto;
53081
+ overscroll-behavior: contain;
53007
53082
  }
53008
53083
  .tabs button {
53009
53084
  display: grid;
@@ -53047,19 +53122,20 @@ var SliccBrowser = class extends ModelElement {
53047
53122
  flex-direction: column;
53048
53123
  gap: var(--swc-spacing-75);
53049
53124
  margin: 0;
53125
+ min-height: 0;
53050
53126
  }
53051
53127
  .frame {
53052
53128
  display: grid;
53053
53129
  place-items: center;
53130
+ box-sizing: border-box;
53054
53131
  aspect-ratio: 16 / 10;
53132
+ width: 100%;
53133
+ max-height: inherit;
53055
53134
  overflow: hidden;
53056
53135
  border: var(--swc-border-width-100) solid var(--swc-gray-200);
53057
53136
  border-radius: var(--swc-corner-radius-medium-default);
53058
53137
  background: var(--swc-card-background-well-color);
53059
53138
  }
53060
- .wide .frame {
53061
- max-height: 50vh;
53062
- }
53063
53139
  .frame img {
53064
53140
  width: 100%;
53065
53141
  height: 100%;
@@ -53068,6 +53144,7 @@ var SliccBrowser = class extends ModelElement {
53068
53144
  user-select: none;
53069
53145
  }
53070
53146
  figcaption {
53147
+ flex: none;
53071
53148
  min-block-size: var(--swc-component-height-50);
53072
53149
  display: flex;
53073
53150
  align-items: center;
@@ -53160,10 +53237,15 @@ var SliccBrowser = class extends ModelElement {
53160
53237
  white-space: normal;
53161
53238
  user-select: text;
53162
53239
  }
53240
+ .feed h3,
53241
+ .feed .more {
53242
+ flex: none;
53243
+ }
53163
53244
  .actions {
53164
53245
  display: flex;
53165
53246
  flex-direction: column;
53166
- max-height: 20rem;
53247
+ flex: 1;
53248
+ min-height: 0;
53167
53249
  overflow: auto;
53168
53250
  }
53169
53251
  .actions li {
@@ -53187,11 +53269,10 @@ var SliccBrowser = class extends ModelElement {
53187
53269
  min-width: 0;
53188
53270
  overflow-wrap: anywhere;
53189
53271
  }
53190
- .last .what > :not(.full),
53191
- .last .url-toggle > span {
53192
- overflow: hidden;
53193
- text-overflow: ellipsis;
53194
- white-space: nowrap;
53272
+ .count {
53273
+ margin-inline-start: var(--swc-spacing-100);
53274
+ color: var(--swc-neutral-subdued-content-color-default);
53275
+ font-weight: var(--swc-bold-font-weight);
53195
53276
  }
53196
53277
  .actions .failure {
53197
53278
  color: var(--swc-negative-content-color-default);
@@ -53253,6 +53334,8 @@ var SliccBrowser = class extends ModelElement {
53253
53334
  subscribe(model) {
53254
53335
  this.#shots.clear();
53255
53336
  this.#frames.clear();
53337
+ this.#display.clear();
53338
+ this.#loading.clear();
53256
53339
  this.#pulse.clear();
53257
53340
  this.#shown = actionPage;
53258
53341
  const tabs = model.browser.list();
@@ -53367,10 +53450,26 @@ var SliccBrowser = class extends ModelElement {
53367
53450
  this.#running = false;
53368
53451
  }
53369
53452
  #image(id) {
53370
- const frame = this.#frames.get(id);
53371
- const shot = this.#shots.get(id);
53372
- if (frame && (!shot || frame.at >= shot.at)) return frame;
53373
- return shot ?? null;
53453
+ return pickImage(this.#frames.get(id), this.#shots.get(id), this.#watching?.tabId === id);
53454
+ }
53455
+ #hold(id, src) {
53456
+ const shown6 = this.#display.get(id);
53457
+ if (shown6 === src) return src;
53458
+ if (!shown6) {
53459
+ this.#display.set(id, src);
53460
+ return src;
53461
+ }
53462
+ if (this.#loading.get(id) === src) return shown6;
53463
+ this.#loading.set(id, src);
53464
+ const probe = document.createElement("img");
53465
+ probe.onload = () => {
53466
+ if (this.#loading.get(id) !== src) return;
53467
+ this.#loading.delete(id);
53468
+ this.#display.set(id, src);
53469
+ this.requestUpdate();
53470
+ };
53471
+ probe.src = src;
53472
+ return shown6;
53374
53473
  }
53375
53474
  #show(id) {
53376
53475
  this.#chosen.value = id;
@@ -53400,29 +53499,39 @@ var SliccBrowser = class extends ModelElement {
53400
53499
  if (visible3 && tab && !this.#ticker)
53401
53500
  this.#ticker = setInterval(() => this.requestUpdate(), 1e3);
53402
53501
  if (!(visible3 && tab)) this.#still();
53403
- const list6 = this.renderRoot.querySelector(".actions:not(.last)");
53404
- const last = list6?.lastElementChild?.getAttribute("data-action-id") ?? null;
53405
- if (list6 && this.#anchor !== null) list6.scrollTop = list6.scrollHeight - this.#anchor;
53406
- else if (list6 && last !== this.#last) list6.scrollTop = list6.scrollHeight;
53502
+ const list6 = this.renderRoot.querySelector(".actions");
53503
+ const head = list6?.firstElementChild?.getAttribute("data-action-id") ?? null;
53504
+ if (list6 && this.#anchor !== null) list6.scrollTop = this.#anchor;
53505
+ else if (list6 && head !== this.#last) list6.scrollTop = 0;
53407
53506
  this.#anchor = null;
53408
- this.#last = last;
53507
+ this.#last = head;
53409
53508
  }
53410
53509
  #still() {
53411
53510
  if (this.#ticker) clearInterval(this.#ticker);
53412
53511
  this.#ticker = null;
53413
53512
  }
53414
53513
  #settle(id) {
53415
- const box = id ? this.renderRoot.querySelector(".frame")?.getBoundingClientRect() : void 0;
53416
- const size4 = box?.width ? { width: Math.round(box.width), height: Math.round(box.height) } : void 0;
53417
- const key = size4 ? `${size4.width}x${size4.height}` : "";
53418
- if (this.#watching?.tabId === id && this.#watching?.size === key) return;
53514
+ if (!id) {
53515
+ this.#watching?.stop();
53516
+ this.#watching = null;
53517
+ return;
53518
+ }
53519
+ const box = this.renderRoot.querySelector(".frame")?.getBoundingClientRect();
53520
+ const area = box ? { width: box.width, height: box.height } : null;
53521
+ const prior = this.#watching?.tabId === id ? this.#watching.pixels : null;
53522
+ const sized = frameSize(area, globalThis.devicePixelRatio || 1, prior);
53523
+ const key = sized?.key ?? (this.#watching?.tabId === id ? this.#watching.size : "");
53524
+ const pixels = sized ? { width: sized.width, height: sized.height } : this.#watching?.tabId === id ? this.#watching.pixels : { width: 0, height: 0 };
53525
+ if (this.#watching?.tabId === id && this.#watching.size === key) return;
53419
53526
  this.#watching?.stop();
53420
- this.#watching = null;
53421
- if (!id) return;
53422
53527
  this.#watching = {
53423
53528
  tabId: id,
53424
53529
  size: key,
53425
- stop: this.model.browser.watch?.(id, size4)
53530
+ pixels,
53531
+ stop: this.model.browser.watch?.(
53532
+ id,
53533
+ sized ? { width: sized.width, height: sized.height } : void 0
53534
+ )
53426
53535
  };
53427
53536
  }
53428
53537
  #open() {
@@ -53524,24 +53633,26 @@ var SliccBrowser = class extends ModelElement {
53524
53633
  #view(tab) {
53525
53634
  const image2 = this.#image(tab.id);
53526
53635
  const now = Date.now();
53527
- const view = !image2 ? "none" : this.#watching?.tabId === tab.id && this.#frames.get(tab.id) === image2 && now - image2.at < fresh ? "live" : "shot";
53636
+ const liveFrame = !!image2 && this.#watching?.tabId === tab.id && this.#frames.get(tab.id) === image2 && now - image2.at < fresh;
53637
+ const view = !image2 ? "none" : liveFrame ? "live" : "shot";
53638
+ const src = image2 ? this.#hold(tab.id, image2.src) : null;
53528
53639
  return b`<figure data-view=${view}>
53529
53640
  <div class="frame">
53530
- ${image2 ? b`<img src=${image2.src} alt=${`${tab.title}, as the agent sees it`} draggable="false" />` : b`<swc-progress-circle size="m" label="Loading preview"></swc-progress-circle>`}
53641
+ ${src ? b`<img src=${src} alt=${`${tab.title}, as the agent sees it`} draggable="false" />` : b`<swc-progress-circle size="m" label="Loading preview"></swc-progress-circle>`}
53531
53642
  </div>
53532
53643
  <figcaption>
53533
53644
  ${view === "live" ? b`<swc-status-light size="s" variant="positive">Live</swc-status-light>` : b`<span>${image2 ? since2(image2.at, now) : "No preview yet"}</span>`}
53534
- <span>View only</span>
53645
+ <span>Watching only</span>
53535
53646
  </figcaption>
53536
53647
  </figure>`;
53537
53648
  }
53538
53649
  #more(total) {
53539
- const list6 = this.renderRoot.querySelector(".actions:not(.last)");
53540
- this.#anchor = list6.scrollHeight - list6.scrollTop;
53650
+ const list6 = this.renderRoot.querySelector(".actions");
53651
+ this.#anchor = list6.scrollTop;
53541
53652
  this.#shown += actionPage;
53542
53653
  const done2 = this.#shown >= total;
53543
53654
  void this.updateComplete.then(() => {
53544
- if (done2) this.focusOn(".actions:not(.last)");
53655
+ if (done2) this.focusOn(".actions");
53545
53656
  });
53546
53657
  this.requestUpdate();
53547
53658
  }
@@ -53554,12 +53665,12 @@ var SliccBrowser = class extends ModelElement {
53554
53665
  const open = this.#expanded.has(action.id);
53555
53666
  return b`<button class="url-toggle" data-action="action-url" aria-expanded=${open ? "true" : "false"} aria-controls=${`url-${action.id}`} @click=${() => this.#toggle(action.id)}><span>${describe(action)}</span><swc-icon-chevron-down class="chevron" size="s" aria-hidden="true"></swc-icon-chevron-down></button>${open ? b`<span class="full" id=${`url-${action.id}`}>${url}</span>` : A}`;
53556
53667
  }
53557
- #row(action) {
53668
+ #row(action, count2 = 1) {
53558
53669
  const failed2 = action.status === "failed";
53559
53670
  const url = linked.has(action.kind) ? action.value : void 0;
53560
- return b`<li data-action-id=${action.id} data-kind=${action.kind} data-status=${action.status} title=${url ?? A}>
53671
+ return b`<li data-action-id=${action.id} data-kind=${action.kind} data-status=${action.status} ?data-group=${count2 > 1} title=${url ?? A}>
53561
53672
  <span>${action.status === "running" ? b`<swc-progress-circle size="s" indeterminate label="Running"></swc-progress-circle>` : failed2 ? b`<swc-icon-alert-triangle size="s" aria-label="Failed"></swc-icon-alert-triangle>` : icons[action.kind]}</span>
53562
- <span class="what">${this.#what(action)}${failed2 && action.error ? b`<span class="failure">${action.error}</span>` : A}</span>
53673
+ <span class="what">${this.#what(action)}${count2 > 1 ? b`<span class="count">×${count2}</span>` : A}${failed2 && action.error ? b`<span class="failure">${action.error}</span>` : A}</span>
53563
53674
  <span class="who">${agentName(this.model, action.agentId)} ${time(action.at)}</span>
53564
53675
  </li>`;
53565
53676
  }
@@ -53570,23 +53681,21 @@ var SliccBrowser = class extends ModelElement {
53570
53681
  (action) => action.tabId === tab.id || action.tabId === null && action.agentId !== null && action.agentId === tab.agentId
53571
53682
  );
53572
53683
  if (!all2.length)
53573
- return b`<h3>Recent actions</h3><p class="muted" data-actions="none">No actions yet.</p>`;
53574
- const actions2 = all2.slice(-this.#shown);
53684
+ return b`<div class="feed"><h3>Recent actions</h3><p class="muted" data-actions="none">No actions yet.</p></div>`;
53685
+ const actions2 = recentActions(all2, this.#shown);
53686
+ const folded = foldActions(actions2);
53575
53687
  const more = all2.length > actions2.length ? b`<div class="more"><span>Showing the latest ${actions2.length} of ${all2.length}</span><swc-button size="s" variant="secondary" fill-style="outline" data-action="more-actions" @click=${() => this.#more(all2.length)}>Show more</swc-button></div>` : A;
53576
- if (this.#width >= narrowWidth)
53577
- return b`<h3>Recent actions</h3>${more}<ol class="actions" aria-label="Recent actions" tabindex="0">${actions2.map((action) => this.#row(action))}</ol>`;
53578
- const last = actions2.at(-1);
53579
- return b`<details ?open=${this.#recent.value} @toggle=${(event2) => this.#recent.value = event2.currentTarget.open}>
53580
- <summary><swc-icon-chevron-right class="chevron" size="s" aria-hidden="true"></swc-icon-chevron-right>Recent actions (${all2.length})</summary>
53581
- ${more}
53582
- <ol class="actions" aria-label="Earlier actions" tabindex="0">${actions2.slice(0, -1).map((action) => this.#row(action))}</ol>
53583
- </details>
53584
- <ol class="actions last" aria-label="Last action">${this.#row(last)}</ol>`;
53688
+ return b`<div class="feed">
53689
+ <h3>Recent actions</h3>
53690
+ ${more}
53691
+ <ol class="actions" aria-label="Recent actions" tabindex="0">${folded.map((item2) => this.#row(item2.action, item2.count))}</ol>
53692
+ </div>`;
53585
53693
  }
53586
53694
  #detail(tabs, tab) {
53587
53695
  const narrow = this.#width < narrowWidth;
53588
53696
  const wide2 = this.#width >= wideWidth;
53589
53697
  const copy = this.#copied === "url" ? "Copied" : this.#copied === "failed" ? "Couldn\u2019t copy" : "Copy";
53698
+ const watching = tab.controlled ? tab.agentId ? `Watching ${agentName(this.model, tab.agentId)}` : "In use" : "No agent is using this tab";
53590
53699
  return b`<div class=${`focused${wide2 ? " wide" : ""}${narrow ? " narrow" : ""}`}>
53591
53700
  ${wide2 ? this.#list(tabs, tab) : A}
53592
53701
  <section class="detail" aria-label=${tab.title}>
@@ -53605,7 +53714,7 @@ var SliccBrowser = class extends ModelElement {
53605
53714
  <swc-action-button size="s" quiet data-action="open-tab" accessible-label="Show in the browser" @click=${() => this.model?.browser.activate(tab.id)}><swc-icon-open-in slot="icon"></swc-icon-open-in>${narrow ? A : "Open"}</swc-action-button>
53606
53715
  </div>
53607
53716
  <div class="driving" data-driving=${tab.controlled ? tab.agentId ? "agent" : "user" : "none"}>
53608
- <swc-status-light size="m" variant=${tab.controlled ? "info" : "neutral"}>${tab.controlled ? this.#who(tab) : "No agent is using this tab"}</swc-status-light>
53717
+ <swc-status-light size="m" variant=${tab.controlled ? "info" : "neutral"}>${watching}</swc-status-light>
53609
53718
  ${tab.controlled ? this.#stopButton(tab, '[data-action="all-tabs"]') : A}
53610
53719
  </div>
53611
53720
  ${this.#view(tab)}
@@ -53634,7 +53743,7 @@ var SliccBrowser = class extends ModelElement {
53634
53743
  const tabs = this.model?.browser.list() ?? [];
53635
53744
  if (!tabs.length && this.model?.network?.status().browser?.via === null) return this.#offline();
53636
53745
  const tab = tabs.find((candidate) => candidate.id === this.#focus);
53637
- return tab ? b`<div class="scroll">${this.#detail(tabs, tab)}</div>` : this.#overview(tabs);
53746
+ return tab ? this.#detail(tabs, tab) : this.#overview(tabs);
53638
53747
  }
53639
53748
  };
53640
53749