@ai-ecoverse/slicc-spectrum 1.101.1 → 1.101.2

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
@@ -31013,8 +31013,8 @@ function question(item2, handlers) {
31013
31013
  ${body4}
31014
31014
  </div>`;
31015
31015
  }
31016
- function questionTurn(item2, handlers, pile) {
31017
- return b`<swc-conversation-turn type="system" class="message decision-turn" data-id=${item2.id} data-state=${item2.state} data-pending=${item2.state === "open" && handlers.seat === void 0 ? "" : A} accessible-label=${`Question: ${item2.question}`} style=${pileStyle(pile)} @click=${reveal} @keydown=${reveal}>${question(item2, handlers)}</swc-conversation-turn>`;
31016
+ function questionTurn(item2, handlers) {
31017
+ return b`<swc-conversation-turn type="system" class="message decision-turn" tabindex="-1" data-id=${item2.id} data-state=${item2.state} data-pending=${item2.state === "open" && handlers.seat === void 0 ? "" : A} accessible-label=${`Question: ${item2.question}`} @click=${reveal} @keydown=${reveal}>${question(item2, handlers)}</swc-conversation-turn>`;
31018
31018
  }
31019
31019
  var delegationVerbs = {
31020
31020
  feed: "fed",
@@ -31348,46 +31348,49 @@ function clock(ms) {
31348
31348
  }
31349
31349
  var still = () => globalThis.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
31350
31350
  function reveal(event2) {
31351
- if (event2.target.closest("swc-button, input, textarea")) return;
31351
+ if (event2.target.closest("swc-button, swc-action-button, input, textarea")) return;
31352
31352
  if (event2 instanceof KeyboardEvent && (event2.key !== "Enter" || event2.target !== event2.currentTarget))
31353
31353
  return;
31354
31354
  show(event2.currentTarget);
31355
31355
  }
31356
31356
  function show(turn) {
31357
- const log = turn.closest(".log");
31357
+ const place4 = [
31358
+ ...turn.getRootNode().querySelectorAll(".ask-place")
31359
+ ].find((candidate) => candidate.dataset.place === turn.dataset.id);
31360
+ const log = place4?.closest(".log");
31358
31361
  if (!log) return;
31359
- const origin2 = log.getBoundingClientRect().top;
31360
- const pile = turn.getBoundingClientRect().top - origin2;
31361
- turn.style.position = "static";
31362
- const flow4 = turn.getBoundingClientRect();
31363
- turn.style.position = "";
31364
- const natural = flow4.top - origin2;
31365
- const bottom = Math.max(16, log.clientHeight - flow4.height - 16);
31366
- if (Math.abs(pile - natural) > 1)
31367
- log.scrollTo({ top: log.scrollTop + natural - bottom, behavior: still() ? "auto" : "smooth" });
31368
- }
31369
- var flatPile = { stack: 0 };
31370
- function pileStyle(pile) {
31371
- return `--stack: ${pile.stack}`;
31362
+ const end = Number.parseFloat(getComputedStyle(log).scrollPaddingBlockEnd) || 0;
31363
+ const at = place4.getBoundingClientRect().top - log.getBoundingClientRect().top;
31364
+ log.scrollTo({
31365
+ top: log.scrollTop + at - log.clientHeight + end,
31366
+ behavior: still() ? "auto" : "smooth"
31367
+ });
31368
+ }
31369
+ function askTimer(at, now = Date.now()) {
31370
+ const left = at - now;
31371
+ return b`<span class="timer" data-timer aria-hidden="true">${left <= 0 ? "Timed out" : clock(left)}</span><span class="sr">${spokenLeft(left, at)}</span>`;
31372
31372
  }
31373
31373
  function spokenLeft(left, at) {
31374
31374
  if (left <= 0) return "Timed out";
31375
31375
  return left <= 6e4 ? "Less than a minute left" : `Expires at ${deadline(at)}`;
31376
31376
  }
31377
- function decision(message, handlers, pile) {
31377
+ function decision(message, handlers) {
31378
31378
  const at = message.expiresAt;
31379
- const left = at === void 0 ? null : at - Date.now();
31380
- const expired = left !== null && left <= 0;
31379
+ const now = Date.now();
31380
+ const expired = at !== void 0 && at <= now;
31381
31381
  const guest = handlers.seat !== void 0;
31382
- const timer = left === null || guest && !expired ? A : b`<span class="timer" data-timer aria-hidden="true">${expired ? "Timed out" : clock(left)}</span><span class="sr">${spokenLeft(left, at)}</span>`;
31382
+ const timer = at === void 0 || guest && !expired ? A : askTimer(at, now);
31383
31383
  const settled3 = expired || guest;
31384
31384
  const actions2 = expired ? A : guest ? hostAnswers : b`<div class="decide">
31385
31385
  <swc-button size="s" variant="secondary" fill-style="outline" data-action="deny" ?disabled=${handlers.readOnly} @click=${() => handlers.resolve(message.id, "dismissed")}>Deny</swc-button>
31386
31386
  <swc-button size="s" variant="accent" data-action="allow" ?disabled=${handlers.readOnly} @click=${() => handlers.resolve(message.id, "confirmed")}>Allow</swc-button>
31387
31387
  </div>`;
31388
- return b`<swc-conversation-turn type="system" class="message decision-turn" accessible-label=${`Permission request from ${message.title}`} data-id=${message.id} data-pending=${settled3 ? A : ""} data-expired=${expired ? "" : A} style=${pileStyle(pile)} @click=${reveal} @keydown=${reveal}>
31388
+ const detail = settled3 ? void 0 : handlers.detail;
31389
+ const shown4 = !!detail?.has(message.id);
31390
+ const more = detail ? b`<swc-action-button size="s" quiet class="detail" data-action="ask-detail" aria-expanded=${shown4 ? "true" : "false"} accessible-label=${shown4 ? "Hide details" : "Show details"} @click=${() => detail.toggle(message.id)}><swc-icon-chevron-right slot="icon" class="chevron"></swc-icon-chevron-right></swc-action-button>` : A;
31391
+ return b`<swc-conversation-turn type="system" class="message decision-turn" tabindex="-1" accessible-label=${`Permission request from ${message.title}`} data-id=${message.id} data-pending=${settled3 ? A : ""} data-expired=${expired ? "" : A} data-detail=${shown4 ? "" : A} @click=${reveal} @keydown=${reveal}>
31389
31392
  <div class="decision" data-kind="approval">
31390
- <div class="decision-head"><span class="who">${message.title}</span>${timer}</div>
31393
+ <div class="decision-head"><span class="who">${message.title}</span>${timer}${more}</div>
31391
31394
  <p class="decision-text">${message.text}</p>
31392
31395
  ${message.body ? b`<pre class="command">${message.body}</pre>` : A}
31393
31396
  ${actions2}
@@ -31420,8 +31423,8 @@ function lickContent(message, body4, handlers) {
31420
31423
  const shown4 = !body4 ? A : scoop ? b`<div class="text">${markdown(body4)}</div>` : b`<pre class="output">${body4}</pre>`;
31421
31424
  return b`<div class="report">${shown4}${report ? b`<swc-button size="s" variant="secondary" fill-style="outline" data-action="open-report" @click=${() => handlers.open(report)}>Open the report</swc-button>` : A}</div>`;
31422
31425
  }
31423
- function lick(message, handlers, stamp = true, pile = flatPile) {
31424
- if (pendingApproval(message)) return decision(message, handlers, pile);
31426
+ function lick(message, handlers, stamp = true) {
31427
+ if (pendingApproval(message)) return decision(message, handlers);
31425
31428
  const [line, failed2, icon, label] = scoopLine(message);
31426
31429
  const severity = message.severity ?? (failed2 ? "error" : void 0);
31427
31430
  const outcome = message.state === "confirmed" ? "Allowed" : message.state === "dismissed" ? "Denied" : "";
@@ -32227,15 +32230,6 @@ var messageCss = i`
32227
32230
  }
32228
32231
  swc-conversation-turn.decision-turn {
32229
32232
  container-type: inline-size;
32230
- transition:
32231
- top var(--swc-animation-duration-300) var(--swc-animation-ease-out),
32232
- transform var(--swc-animation-duration-300) var(--swc-animation-ease-out),
32233
- filter var(--swc-animation-duration-300) var(--swc-animation-ease-out);
32234
- }
32235
- @media (prefers-reduced-motion: reduce) {
32236
- swc-conversation-turn.decision-turn {
32237
- transition: none;
32238
- }
32239
32233
  }
32240
32234
  slicc-sprinkle[inline] {
32241
32235
  position: relative;
@@ -32243,19 +32237,8 @@ var messageCss = i`
32243
32237
  inline-size: calc(100cqw + var(--swc-spacing-300) * 2);
32244
32238
  transform: translateX(-50%);
32245
32239
  }
32246
- swc-conversation-turn.decision-turn[data-pending] {
32247
- position: sticky;
32248
- top: calc(var(--stack, 0) * (var(--swc-spacing-600) + var(--swc-spacing-75)));
32249
- z-index: calc(var(--stack, 0) + 1);
32250
- }
32251
- swc-conversation-turn.decision-turn[data-pinned] {
32252
- transform: scale(calc(1 - var(--depth, 0) * 0.03));
32253
- transform-origin: top center;
32254
- filter: blur(calc(var(--depth, 0) * 0.6px));
32255
- }
32256
32240
  .decision-turn[data-pending] .decision {
32257
32241
  border-color: var(--swc-gray-300);
32258
- box-shadow: var(--swc-drop-shadow-elevated);
32259
32242
  }
32260
32243
  .decision-turn[data-pending]:focus-visible {
32261
32244
  outline: none;
@@ -32285,6 +32268,12 @@ var messageCss = i`
32285
32268
  .decision-head .who {
32286
32269
  font-weight: var(--swc-bold-font-weight);
32287
32270
  }
32271
+ .decision-head .detail {
32272
+ display: none;
32273
+ }
32274
+ .decision-turn[data-detail] .detail .chevron {
32275
+ transform: rotate(90deg);
32276
+ }
32288
32277
  .timer {
32289
32278
  color: var(--swc-neutral-subdued-content-color-default);
32290
32279
  font-variant-numeric: tabular-nums;
@@ -34407,18 +34396,35 @@ var navigation = /* @__PURE__ */ new Set([
34407
34396
  ]);
34408
34397
  var upward = /* @__PURE__ */ new Set(["ArrowUp", "PageUp", "Home"]);
34409
34398
  var compactWidth = 560;
34410
- function pendingKeys(messages) {
34399
+ function pendingAsks(messages) {
34411
34400
  return messages.flatMap((message) => {
34412
- if (waiting(message)) return [message.id];
34401
+ if (waiting(message))
34402
+ return [[message.id, { id: message.id, at: message.expiresAt }]];
34413
34403
  if (message.role !== "assistant") return [];
34414
34404
  return message.parts.flatMap(
34415
- (part2) => part2.type === "question" && part2.question.state === "open" ? [`${message.id}:${part2.question.id}`] : []
34405
+ (part2) => part2.type === "question" && part2.question.state === "open" ? [[`${message.id}:${part2.question.id}`, { id: part2.question.id }]] : []
34416
34406
  );
34417
34407
  });
34418
34408
  }
34419
- function pendingPiles(messages) {
34420
- const keys = pendingKeys(messages);
34421
- return new Map(keys.map((key2, stack) => [key2, { stack }]));
34409
+ function into(card2, dock2) {
34410
+ const box = card2.getBoundingClientRect();
34411
+ const view = dock2.getBoundingClientRect();
34412
+ const start2 = view.top + (Number.parseFloat(getComputedStyle(dock2).scrollPaddingBlockStart) || 0);
34413
+ if (box.top < start2) dock2.scrollTop -= start2 - box.top;
34414
+ else if (box.bottom > view.bottom)
34415
+ dock2.scrollTop += Math.min(box.bottom - view.bottom, box.top - start2);
34416
+ }
34417
+ var place = (id) => b`<div class="ask-place" data-place=${id} aria-hidden="true"></div>`;
34418
+ function dock(entries, messages, seat) {
34419
+ const docked = new Map(seat ? [] : pendingAsks(messages));
34420
+ const asks = [];
34421
+ const items = entries.map(([key2, card2]) => {
34422
+ const ask = docked.get(key2);
34423
+ if (!ask) return [key2, card2];
34424
+ asks.push({ key: key2, id: ask.id, at: ask.at, card: card2 });
34425
+ return [key2, place(ask.id)];
34426
+ });
34427
+ return { items, asks };
34422
34428
  }
34423
34429
  var failed = (message) => message.role === "assistant" ? message.status === "error" : message.role === "system" && message.kind === "error";
34424
34430
  function empty3(watch, seat, name) {
@@ -34603,7 +34609,118 @@ var SliccChat = class _SliccChat extends ThemedElement {
34603
34609
  padding: var(--swc-spacing-400) var(--swc-spacing-300) calc(var(--composer-height, 0px) + var(--composer-fade) + 1lh);
34604
34610
  scroll-padding-block-end: calc(var(--composer-height, 0px) + var(--composer-fade) + var(--swc-spacing-200));
34605
34611
  font-size: var(--swc-font-size-200);
34606
- scroll-padding-block-start: var(--pile, 0px);
34612
+ }
34613
+ .ask-place {
34614
+ block-size: 0;
34615
+ margin-block-end: calc(-1 * var(--swc-spacing-400));
34616
+ }
34617
+ .asks {
34618
+ flex: 0 1 auto;
34619
+ min-block-size: 0;
34620
+ max-block-size: 50%;
34621
+ overflow-y: auto;
34622
+ container-type: inline-size;
34623
+ position: relative;
34624
+ z-index: 1;
34625
+ padding: var(--swc-spacing-200) var(--swc-spacing-300);
34626
+ border-block-end: var(--swc-border-width-100) solid var(--swc-gray-200);
34627
+ background: var(--swc-background-layer-2-color);
34628
+ box-shadow: 0 var(--swc-drop-shadow-elevated-y) var(--swc-drop-shadow-elevated-blur) var(--swc-drop-shadow-color-100);
34629
+ font-size: var(--swc-font-size-200);
34630
+ scrollbar-width: thin;
34631
+ scrollbar-color: transparent transparent;
34632
+ }
34633
+ .asks:hover,
34634
+ .asks:focus-within {
34635
+ scrollbar-color: var(--swc-gray-500) transparent;
34636
+ }
34637
+ .asks::after {
34638
+ content: '';
34639
+ position: sticky;
34640
+ bottom: calc(-1 * var(--swc-spacing-200));
34641
+ display: none;
34642
+ block-size: var(--swc-spacing-500);
34643
+ margin-block-start: calc(-1 * var(--swc-spacing-500));
34644
+ background: linear-gradient(to bottom, transparent, var(--swc-background-layer-2-color));
34645
+ pointer-events: none;
34646
+ }
34647
+ .asks[data-more]::after {
34648
+ display: block;
34649
+ }
34650
+ .asks:has(.waiting) {
34651
+ scroll-padding-block-start: calc(var(--swc-component-height-100) + var(--swc-spacing-100));
34652
+ }
34653
+ .asks + .stage {
34654
+ min-block-size: calc(var(--composer-height, 0px) + var(--composer-fade, 0px) + var(--swc-spacing-1000));
34655
+ }
34656
+ .asks[data-open] + .stage {
34657
+ min-block-size: calc(var(--composer-height, 0px) + var(--composer-fade, 0px));
34658
+ }
34659
+ .asks[data-open] .decision {
34660
+ gap: var(--swc-spacing-75);
34661
+ padding-block: var(--swc-spacing-100);
34662
+ }
34663
+ .asks[data-open] .decide {
34664
+ padding: 0;
34665
+ }
34666
+ .asks[data-open] .question.decision .options {
34667
+ margin-block-start: 0;
34668
+ }
34669
+ .asks[data-open] .decision-head {
34670
+ align-items: center;
34671
+ }
34672
+ .asks[data-open] .decision-head .who {
34673
+ margin-inline-end: auto;
34674
+ }
34675
+ .asks[data-open] .decision-head .detail {
34676
+ display: inline-flex;
34677
+ }
34678
+ .asks[data-open] .decision-turn:not([data-detail]) .command {
34679
+ overflow: hidden;
34680
+ white-space: nowrap;
34681
+ text-overflow: ellipsis;
34682
+ }
34683
+ .asks[data-open] .decision-turn:not([data-detail]) .decision-text {
34684
+ overflow: hidden;
34685
+ white-space: nowrap;
34686
+ text-overflow: ellipsis;
34687
+ }
34688
+ .waiting {
34689
+ position: sticky;
34690
+ top: calc(-1 * var(--swc-spacing-200));
34691
+ z-index: 1;
34692
+ display: flex;
34693
+ align-items: center;
34694
+ gap: var(--swc-spacing-100);
34695
+ margin-block: calc(-1 * var(--swc-spacing-200)) var(--swc-spacing-100);
34696
+ padding: var(--swc-spacing-200) var(--swc-spacing-700) 0;
34697
+ background: var(--swc-background-layer-2-color);
34698
+ font-size: var(--swc-font-size-100);
34699
+ color: var(--swc-neutral-subdued-content-color-default);
34700
+ }
34701
+ @container (inline-size < 480px) {
34702
+ .waiting {
34703
+ padding-inline: var(--swc-spacing-300);
34704
+ }
34705
+ }
34706
+ .ask-list {
34707
+ display: flex;
34708
+ flex-direction: column;
34709
+ gap: var(--swc-spacing-200);
34710
+ }
34711
+ .waiting .timer {
34712
+ margin-inline: auto var(--swc-spacing-300);
34713
+ }
34714
+ .waiting swc-icon-chevron-down {
34715
+ transition: transform var(--swc-animation-duration-100) var(--swc-animation-ease-out);
34716
+ }
34717
+ .asks[data-open] .waiting swc-icon-chevron-down {
34718
+ transform: rotate(180deg);
34719
+ }
34720
+ @media (prefers-reduced-motion: reduce) {
34721
+ .waiting swc-icon-chevron-down {
34722
+ transition: none;
34723
+ }
34607
34724
  }
34608
34725
  @container (min-width: 600px) {
34609
34726
  .column {
@@ -34656,8 +34773,16 @@ var SliccChat = class _SliccChat extends ThemedElement {
34656
34773
  `
34657
34774
  ];
34658
34775
  #licks = new ViewSet(this, "chat:licks");
34776
+ #details = /* @__PURE__ */ new Set();
34659
34777
  #handlers = {
34660
34778
  licks: this.#licks,
34779
+ detail: {
34780
+ has: (id) => this.#details.has(id),
34781
+ toggle: (id) => {
34782
+ if (!this.#details.delete(id)) this.#details.add(id);
34783
+ this.requestUpdate();
34784
+ }
34785
+ },
34661
34786
  color: "light",
34662
34787
  model: null,
34663
34788
  readOnly: false,
@@ -34725,15 +34850,29 @@ var SliccChat = class _SliccChat extends ThemedElement {
34725
34850
  #tail = "";
34726
34851
  #held = "";
34727
34852
  #mark = 0;
34853
+ #all = false;
34854
+ #seen = "";
34728
34855
  #focused = (event2) => {
34729
- const turn = event2.target.closest(".decision-turn[data-pending]");
34730
- this.#held = turn?.dataset.id ?? "";
34731
- if (turn && Number(turn.style.getPropertyValue("--depth")) > 0) show(turn);
34856
+ const target2 = event2.target;
34857
+ this.#held = target2.closest(".decision-turn[data-pending]")?.dataset.id ?? "";
34858
+ const card2 = target2.closest(".ask");
34859
+ if (card2) into(card2, card2.closest(".asks"));
34860
+ };
34861
+ #more = () => {
34862
+ const dock2 = this.renderRoot.querySelector(".asks");
34863
+ if (!dock2) return;
34864
+ const end = Number.parseFloat(getComputedStyle(dock2).paddingBlockEnd) || 0;
34865
+ dock2.toggleAttribute(
34866
+ "data-more",
34867
+ dock2.scrollHeight - dock2.scrollTop - dock2.clientHeight > end + 1
34868
+ );
34732
34869
  };
34733
34870
  #refocus() {
34734
- if (!this.#held || this.renderRoot.querySelector(":focus")) return;
34871
+ if (!this.#held || this.renderRoot.activeElement) return;
34735
34872
  this.#held = "";
34736
- const next = this.renderRoot.querySelector(".decision-turn[data-pending]");
34873
+ const next = [
34874
+ ...this.renderRoot.querySelectorAll(".asks .decision-turn[data-pending]")
34875
+ ].at(-1);
34737
34876
  if (next) next.focus();
34738
34877
  else this.renderRoot.querySelector("slicc-composer")?.focus();
34739
34878
  }
@@ -34744,6 +34883,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
34744
34883
  return seat ? mine(last, seat) : (last.origin ?? "user") === "user";
34745
34884
  }
34746
34885
  #resize = new ResizeObserver(() => {
34886
+ this.#more();
34747
34887
  const log = this.#log();
34748
34888
  if (!this.#stuck && log.scrollHeight <= log.clientHeight) this.#follow();
34749
34889
  else this.#pin();
@@ -34794,7 +34934,6 @@ var SliccChat = class _SliccChat extends ThemedElement {
34794
34934
  this.#stuck = false;
34795
34935
  this.#last = log.scrollTop;
34796
34936
  this.#height = log.scrollHeight;
34797
- this.#pile();
34798
34937
  };
34799
34938
  #intent = {
34800
34939
  passive: true,
@@ -34864,40 +35003,10 @@ var SliccChat = class _SliccChat extends ThemedElement {
34864
35003
  clearInterval(this.#tick);
34865
35004
  this.#tick = void 0;
34866
35005
  }
34867
- this.#pile();
34868
35006
  this.#refocus();
34869
- }
34870
- #pile() {
34871
- const turns = [
34872
- ...this.renderRoot.querySelectorAll(".decision-turn[data-pending]")
34873
- ];
34874
- const drawn = turns.map((turn) => turn.getBoundingClientRect().top);
34875
- for (const turn of turns) turn.style.position = "static";
34876
- const flow4 = turns.map((turn) => turn.getBoundingClientRect().top);
34877
- for (const turn of turns) turn.style.position = "";
34878
- const pinned = turns.flatMap(
34879
- (turn, index2) => drawn[index2] - flow4[index2] > 1 ? [{ turn, stack: Number.parseFloat(turn.style.getPropertyValue("--stack")) }] : []
34880
- );
34881
- for (const turn of turns) {
34882
- if (!pinned.some((entry) => entry.turn === turn)) {
34883
- turn.removeAttribute("data-pinned");
34884
- turn.style.removeProperty("--depth");
34885
- }
34886
- }
34887
- for (const { turn, stack } of pinned) {
34888
- turn.setAttribute("data-pinned", "");
34889
- turn.style.setProperty(
34890
- "--depth",
34891
- String(pinned.filter((other) => other.stack > stack).length)
34892
- );
34893
- }
34894
- const log = this.renderRoot.querySelector(".log");
34895
- const top = log?.getBoundingClientRect().top ?? 0;
34896
- const reach3 = Math.max(
34897
- 0,
34898
- ...pinned.map(({ turn }) => turn.getBoundingClientRect().bottom - top)
34899
- );
34900
- log?.style.setProperty("--pile", `${reach3}px`);
35007
+ const asks = [...this.renderRoot.querySelectorAll(".ask-list .decision-turn")];
35008
+ for (const turn of asks) turn.tabIndex = 0;
35009
+ this.#more();
34901
35010
  }
34902
35011
  #timed() {
34903
35012
  const model = this.model;
@@ -34907,6 +35016,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
34907
35016
  );
34908
35017
  }
34909
35018
  firstUpdated() {
35019
+ this.renderRoot.addEventListener("focusin", this.#focused);
34910
35020
  this.#observe();
34911
35021
  }
34912
35022
  focus() {
@@ -35013,7 +35123,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
35013
35123
  }
35014
35124
  this.#settings(account);
35015
35125
  }
35016
- #message(message, agent, suggestion, changed2, extra, owners, stamp, pile) {
35126
+ #message(message, agent, suggestion, changed2, extra, owners, stamp) {
35017
35127
  const model = this.model;
35018
35128
  const handlers = { ...this.#handlers, owners };
35019
35129
  switch (message.role) {
@@ -35037,7 +35147,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
35037
35147
  case "system":
35038
35148
  return system(message, this.#handlers);
35039
35149
  default:
35040
- return lick(message, this.#handlers, stamp, pile);
35150
+ return lick(message, this.#handlers, stamp);
35041
35151
  }
35042
35152
  }
35043
35153
  #items(messages, agent) {
@@ -35050,9 +35160,8 @@ var SliccChat = class _SliccChat extends ThemedElement {
35050
35160
  const showThinking = model.settings.get().showThinking;
35051
35161
  const extra = /* @__PURE__ */ new Map();
35052
35162
  const owners = /* @__PURE__ */ new Map();
35053
- const into = /* @__PURE__ */ new Map();
35163
+ const into2 = /* @__PURE__ */ new Map();
35054
35164
  const stamped = stamps(messages);
35055
- const piles = pendingPiles(messages);
35056
35165
  let anchor = null;
35057
35166
  for (const message of messages) {
35058
35167
  const calls = toolOnly(message, showThinking);
@@ -35063,14 +35172,14 @@ var SliccChat = class _SliccChat extends ThemedElement {
35063
35172
  at: message.createdAt,
35064
35173
  stamp: stamped.has(message.id)
35065
35174
  });
35066
- into.set(message.id, anchor.id);
35175
+ into2.set(message.id, anchor.id);
35067
35176
  continue;
35068
35177
  }
35069
35178
  anchor = toolTail(message, showThinking) ? message : null;
35070
35179
  }
35071
- const target2 = last && (into.get(last.id) ?? last.id);
35180
+ const target2 = last && (into2.get(last.id) ?? last.id);
35072
35181
  for (const message of messages) {
35073
- if (into.has(message.id)) continue;
35182
+ if (into2.has(message.id)) continue;
35074
35183
  const label = day(message.createdAt);
35075
35184
  if (label !== previous3) {
35076
35185
  out.push([
@@ -35093,23 +35202,41 @@ var SliccChat = class _SliccChat extends ThemedElement {
35093
35202
  changed2,
35094
35203
  extra.get(message.id) ?? [],
35095
35204
  owners,
35096
- stamped.has(message.id),
35097
- piles.get(message.id) ?? flatPile
35205
+ stamped.has(message.id)
35098
35206
  )
35099
35207
  ]);
35100
- out.push(...this.#questions(message, piles));
35208
+ out.push(...this.#questions(message));
35101
35209
  }
35102
35210
  return out;
35103
35211
  }
35104
- #questions(message, piles) {
35212
+ #questions(message) {
35105
35213
  if (message.role !== "assistant") return [];
35106
- return message.parts.flatMap((part2) => {
35107
- if (part2.type !== "question") return [];
35108
- const key2 = `${message.id}:${part2.question.id}`;
35109
- return [
35110
- [key2, questionTurn(part2.question, this.#handlers, piles.get(key2) ?? flatPile)]
35111
- ];
35112
- });
35214
+ return message.parts.flatMap(
35215
+ (part2) => part2.type === "question" ? [[`${message.id}:${part2.question.id}`, questionTurn(part2.question, this.#handlers)]] : []
35216
+ );
35217
+ }
35218
+ #asks(asks) {
35219
+ if (!asks.length) return A;
35220
+ const older = asks.slice(0, -1);
35221
+ const focused2 = this.renderRoot.activeElement?.closest(
35222
+ ".asks .decision-turn"
35223
+ )?.dataset.id;
35224
+ this.#all ||= older.some(({ id }) => id === focused2);
35225
+ this.#all &&= older.length > 0;
35226
+ const open = this.#all;
35227
+ const timed = open ? [] : older.flatMap(({ at }) => at === void 0 ? [] : [at]);
35228
+ const toggle = () => {
35229
+ this.#all = !open;
35230
+ this.requestUpdate();
35231
+ };
35232
+ return b`<section class="asks" aria-label="Waiting for you" ?data-open=${open} @scroll=${this.#more}><div class="column">
35233
+ ${older.length ? b`<div class="waiting"><swc-action-button size="s" quiet data-action="show-waiting" aria-expanded=${open ? "true" : "false"} @click=${toggle}><swc-icon-chevron-down slot="icon"></swc-icon-chevron-down>${asks.length} waiting</swc-action-button>${timed.length ? askTimer(Math.min(...timed)) : A}</div>` : A}
35234
+ <div class="ask-list" aria-live="polite">${c(
35235
+ asks,
35236
+ ({ key: key2 }) => key2,
35237
+ ({ card: card2 }, index2) => b`<div class="ask" ?hidden=${!open && index2 < older.length}>${card2}</div>`
35238
+ )}</div>
35239
+ </div></section>`;
35113
35240
  }
35114
35241
  #newChat(agent) {
35115
35242
  this.model.agent.clear(agent.id);
@@ -35153,10 +35280,18 @@ var SliccChat = class _SliccChat extends ThemedElement {
35153
35280
  const spoken = fresh2 > 0 ? `Jump to latest, ${fresh2} new ${fresh2 === 1 ? "message" : "messages"}` : "Jump to latest";
35154
35281
  return b`<div class="jump"><swc-action-button size="s" data-action="jump-latest" accessible-label=${spoken} @click=${this.#jump}><swc-icon-chevron-down slot="icon"></swc-icon-chevron-down>${label}</swc-action-button><span class="sr" role="status" aria-live="polite" data-jump-status>${fresh2 > 0 ? `${fresh2} new ${fresh2 === 1 ? "message" : "messages"} below` : ""}</span></div>`;
35155
35282
  }
35283
+ #switched(agent) {
35284
+ const id = agent?.id ?? "";
35285
+ if (id === this.#seen) return;
35286
+ this.#seen = id;
35287
+ this.#all = false;
35288
+ this.#details.clear();
35289
+ }
35156
35290
  render() {
35157
35291
  this.#handlers.color = this.color;
35158
35292
  this.#handlers.model = this.model ?? null;
35159
35293
  const agent = this.#agent();
35294
+ this.#switched(agent);
35160
35295
  const watch = watchOnly(this.model);
35161
35296
  const seat = this.model?.seat;
35162
35297
  this.#handlers.readOnly = !!agent?.frozen || !!watch || !!seat;
@@ -35164,7 +35299,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
35164
35299
  this.#handlers.seat = seat?.label;
35165
35300
  const messages = agent ? this.model?.agent.messages(agent.id) ?? [] : [];
35166
35301
  this.#tail = messages.at(-1)?.id ?? "";
35167
- const items = agent && messages.length > 0 ? this.#items(messages, agent) : [];
35302
+ const { items, asks } = dock(agent ? this.#items(messages, agent) : [], messages, seat);
35168
35303
  const count2 = items.filter(([key2]) => !key2.startsWith("day:")).length;
35169
35304
  if (!this.behind) this.#mark = count2;
35170
35305
  return b`
@@ -35172,6 +35307,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
35172
35307
  ${agent ? this.#meta(agent, !messages.length) : b`<span>No agent</span>`}
35173
35308
  </header>
35174
35309
  <slicc-notices .model=${this.model}></slicc-notices>
35310
+ ${this.#asks(asks)}
35175
35311
  <div class="stage">
35176
35312
  <div
35177
35313
  class="log"
@@ -35185,7 +35321,6 @@ var SliccChat = class _SliccChat extends ThemedElement {
35185
35321
  @touchmove=${this.#intent}
35186
35322
  @keydown=${this.#intent}
35187
35323
  @pointerdown=${this.#hold}
35188
- @focusin=${this.#focused}
35189
35324
  >
35190
35325
  <div class="column" @keydown=${this.#keys}>
35191
35326
  ${items.length ? b`<swc-conversation-thread>${c(
@@ -40862,8 +40997,8 @@ function sideOf(id) {
40862
40997
  return surface(terminalOf(id) === null ? id : "terminal")?.side ?? "center";
40863
40998
  }
40864
40999
  var home = (panel) => sideOf(panel.id);
40865
- function first(dock, side, sider, except) {
40866
- return dock.api.panels.find((panel) => panel.id !== except && sider(panel) === side)?.id;
41000
+ function first(dock2, side, sider, except) {
41001
+ return dock2.api.panels.find((panel) => panel.id !== except && sider(panel) === side)?.id;
40867
41002
  }
40868
41003
  var neighbours = {
40869
41004
  left: [
@@ -40879,25 +41014,25 @@ var neighbours = {
40879
41014
  ["left", "right"]
40880
41015
  ]
40881
41016
  };
40882
- function place(dock, side, screen, sider, except) {
41017
+ function place2(dock2, side, screen, sider, except) {
40883
41018
  const anchor = (id, direction) => id ? { position: { referencePanel: id, direction } } : null;
40884
- if (screen === "phone") return anchor(dock.api.panels[0]?.id, "within") ?? {};
40885
- const same = anchor(first(dock, side, sider, except), "within");
41019
+ if (screen === "phone") return anchor(dock2.api.panels[0]?.id, "within") ?? {};
41020
+ const same = anchor(first(dock2, side, sider, except), "within");
40886
41021
  if (same) return same;
40887
41022
  for (const [other, direction] of neighbours[side]) {
40888
- const found = anchor(first(dock, other, sider, except), direction);
41023
+ const found = anchor(first(dock2, other, sider, except), direction);
40889
41024
  if (found) return found;
40890
41025
  }
40891
41026
  return {};
40892
41027
  }
40893
- function placement(dock, side, screen) {
40894
- return place(dock, side, screen, home);
41028
+ function placement(dock2, side, screen) {
41029
+ return place2(dock2, side, screen, home);
40895
41030
  }
40896
41031
  function views(node2) {
40897
41032
  return node2.type === "leaf" ? node2.data.views : node2.data.flatMap(views);
40898
41033
  }
40899
- function destination(dock, id, side, screen) {
40900
- const { grid } = dock.api.toJSON();
41034
+ function destination(dock2, id, side, screen) {
41035
+ const { grid } = dock2.api.toJSON();
40901
41036
  const root2 = grid.root;
40902
41037
  const columns = String(grid.orientation) === "HORIZONTAL" && root2.type === "branch" ? root2.data.map(views) : [views(root2)];
40903
41038
  const holds = (test) => columns.findIndex((ids) => ids.some((other) => other !== id && test(other)));
@@ -40908,18 +41043,18 @@ function destination(dock, id, side, screen) {
40908
41043
  const at = columns.findIndex((ids) => ids.includes(panel.id));
40909
41044
  return at < middle ? "left" : at > middle ? "right" : "center";
40910
41045
  };
40911
- return place(dock, side, screen, current, id);
41046
+ return place2(dock2, side, screen, current, id);
40912
41047
  }
40913
- function openSurface(dock, item2, screen, focus = true) {
40914
- if (dock.has(item2.id)) return;
40915
- const place3 = placement(dock, item2.side, screen);
40916
- const fresh2 = place3.position?.direction !== "within";
40917
- dock.open({
41048
+ function openSurface(dock2, item2, screen, focus = true) {
41049
+ if (dock2.has(item2.id)) return;
41050
+ const place4 = placement(dock2, item2.side, screen);
41051
+ const fresh2 = place4.position?.direction !== "within";
41052
+ dock2.open({
40918
41053
  id: item2.id,
40919
41054
  component: item2.id,
40920
41055
  title: item2.title,
40921
41056
  inactive: !focus,
40922
- ...place3,
41057
+ ...place4,
40923
41058
  ...fresh2 && item2.width && screen !== "phone" ? { initialWidth: item2.width } : {}
40924
41059
  });
40925
41060
  }
@@ -40929,44 +41064,44 @@ function chatId(agentId) {
40929
41064
  function chatAgent(id) {
40930
41065
  return id?.startsWith("chat:") ? id.slice(5) : null;
40931
41066
  }
40932
- function chats(dock) {
40933
- return dock.api.panels.map((panel) => panel.id).filter((id) => chatAgent(id) !== null);
41067
+ function chats(dock2) {
41068
+ return dock2.api.panels.map((panel) => panel.id).filter((id) => chatAgent(id) !== null);
40934
41069
  }
40935
- function openChat(dock, agent, screen, focus = true, reveal2 = true) {
41070
+ function openChat(dock2, agent, screen, focus = true, reveal2 = true) {
40936
41071
  const id = chatId(agent.id);
40937
- if (!dock.has(id)) {
40938
- const sibling = chats(dock)[0];
40939
- const place3 = sibling ? { position: { referencePanel: sibling, direction: "within" } } : placement(dock, "center", screen);
40940
- dock.open({
41072
+ if (!dock2.has(id)) {
41073
+ const sibling = chats(dock2)[0];
41074
+ const place4 = sibling ? { position: { referencePanel: sibling, direction: "within" } } : placement(dock2, "center", screen);
41075
+ dock2.open({
40941
41076
  id,
40942
41077
  component: "chat",
40943
41078
  title: agent.name,
40944
41079
  params: { agent: agent.id },
40945
41080
  inactive: !focus,
40946
- ...place3
41081
+ ...place4
40947
41082
  });
40948
41083
  }
40949
- if (focus) dock.focusPanel(id);
40950
- else if (reveal2) dock.reveal(id);
41084
+ if (focus) dock2.focusPanel(id);
41085
+ else if (reveal2) dock2.reveal(id);
40951
41086
  return id;
40952
41087
  }
40953
- function openDocument(dock, kind, path2, screen, focus = true) {
41088
+ function openDocument(dock2, kind, path2, screen, focus = true) {
40954
41089
  const id = `${kind}:${path2}`;
40955
- if (!dock.has(id)) {
40956
- const sibling = dock.api.panels.find((panel) => /^(file|diff):/.test(panel.id));
40957
- const chat = chats(dock)[0];
40958
- const place3 = sibling ? { position: { referencePanel: sibling.id, direction: "within" } } : chat && screen !== "phone" ? { position: { referencePanel: chat, direction: "right" } } : placement(dock, "center", screen);
40959
- dock.open({
41090
+ if (!dock2.has(id)) {
41091
+ const sibling = dock2.api.panels.find((panel) => /^(file|diff):/.test(panel.id));
41092
+ const chat = chats(dock2)[0];
41093
+ const place4 = sibling ? { position: { referencePanel: sibling.id, direction: "within" } } : chat && screen !== "phone" ? { position: { referencePanel: chat, direction: "right" } } : placement(dock2, "center", screen);
41094
+ dock2.open({
40960
41095
  id,
40961
41096
  component: kind,
40962
41097
  title: documents[kind].title(path2),
40963
41098
  params: { path: path2 },
40964
41099
  inactive: !focus,
40965
- ...place3
41100
+ ...place4
40966
41101
  });
40967
41102
  }
40968
- if (focus) dock.focusPanel(id);
40969
- else dock.reveal(id);
41103
+ if (focus) dock2.focusPanel(id);
41104
+ else dock2.reveal(id);
40970
41105
  return id;
40971
41106
  }
40972
41107
  function terminalPanel(terminal) {
@@ -40975,48 +41110,48 @@ function terminalPanel(terminal) {
40975
41110
  function terminalOf(id) {
40976
41111
  return id?.startsWith("terminal:") ? id.slice(9) : null;
40977
41112
  }
40978
- function terminalPanels(dock) {
40979
- return dock.api.panels.map((panel) => panel.id).filter((id) => terminalOf(id) !== null);
41113
+ function terminalPanels(dock2) {
41114
+ return dock2.api.panels.map((panel) => panel.id).filter((id) => terminalOf(id) !== null);
40980
41115
  }
40981
41116
  function terminalTitle(info) {
40982
41117
  return `${info.title} \xB7 ${basename(info.cwd) || "/"}`;
40983
41118
  }
40984
- function openTerminal(dock, info, screen) {
41119
+ function openTerminal(dock2, info, screen) {
40985
41120
  const id = terminalPanel(info.id);
40986
- if (!dock.has(id)) {
40987
- const sibling = terminalPanels(dock).at(-1);
40988
- dock.open({
41121
+ if (!dock2.has(id)) {
41122
+ const sibling = terminalPanels(dock2).at(-1);
41123
+ dock2.open({
40989
41124
  id,
40990
41125
  component: "terminal",
40991
41126
  title: terminalTitle(info),
40992
41127
  params: { terminal: info.id },
40993
41128
  inactive: true,
40994
- ...sibling ? { position: { referencePanel: sibling, direction: "within" } } : placement(dock, "right", screen)
41129
+ ...sibling ? { position: { referencePanel: sibling, direction: "within" } } : placement(dock2, "right", screen)
40995
41130
  });
40996
41131
  }
40997
41132
  return id;
40998
41133
  }
40999
- function openChatSlot(dock, item2, screen, agent, agentless) {
41000
- if (agent) openChat(dock, agent, screen, false);
41001
- else if (agentless) openSurface(dock, item2, screen, false);
41134
+ function openChatSlot(dock2, item2, screen, agent, agentless) {
41135
+ if (agent) openChat(dock2, agent, screen, false);
41136
+ else if (agentless) openSurface(dock2, item2, screen, false);
41002
41137
  }
41003
- function defaultLayout(dock, screen, agent, items = surfaces2, terminals = [], agentless = false) {
41004
- dock.clear();
41138
+ function defaultLayout(dock2, screen, agent, items = surfaces2, terminals = [], agentless = false) {
41139
+ dock2.clear();
41005
41140
  const order = ["center", "left", "right"];
41006
41141
  for (const side of order) {
41007
41142
  for (const item2 of items) {
41008
41143
  if (item2.side !== side || !item2.open.includes(screen)) continue;
41009
- if (item2.id === "terminal") for (const info of terminals) openTerminal(dock, info, screen);
41010
- else if (item2.id === "chat") openChatSlot(dock, item2, screen, agent, agentless);
41011
- else openSurface(dock, item2, screen);
41144
+ if (item2.id === "terminal") for (const info of terminals) openTerminal(dock2, info, screen);
41145
+ else if (item2.id === "chat") openChatSlot(dock2, item2, screen, agent, agentless);
41146
+ else openSurface(dock2, item2, screen);
41012
41147
  }
41013
41148
  }
41014
- const chat = chats(dock)[0] ?? (dock.has("chat") ? "chat" : null);
41015
- if (chat) dock.api.getPanel(chat)?.api.setActive();
41149
+ const chat = chats(dock2)[0] ?? (dock2.has("chat") ? "chat" : null);
41150
+ if (chat) dock2.api.getPanel(chat)?.api.setActive();
41016
41151
  }
41017
- function shown2(dock, id) {
41018
- const ids = id === "chat" ? chats(dock) : id === "terminal" ? terminalPanels(dock) : [id];
41019
- return ids.some((panel) => dock.api.getPanel(panel)?.api.isVisible === true);
41152
+ function shown2(dock2, id) {
41153
+ const ids = id === "chat" ? chats(dock2) : id === "terminal" ? terminalPanels(dock2) : [id];
41154
+ return ids.some((panel) => dock2.api.getPanel(panel)?.api.isVisible === true);
41020
41155
  }
41021
41156
  function sprinkleSurface(sprinkle) {
41022
41157
  return {
@@ -41039,20 +41174,20 @@ var directions = {
41039
41174
  function dropPlacement(panel, position2) {
41040
41175
  return panel ? { position: { referencePanel: panel, direction: directions[position2] ?? "within" } } : null;
41041
41176
  }
41042
- function openSprinkle(dock, sprinkle, screen, place3 = null, focus = true) {
41177
+ function openSprinkle(dock2, sprinkle, screen, place4 = null, focus = true) {
41043
41178
  const id = `sprinkle:${sprinkle.id}`;
41044
- if (!dock.has(id)) {
41045
- dock.open({
41179
+ if (!dock2.has(id)) {
41180
+ dock2.open({
41046
41181
  id,
41047
41182
  component: "sprinkle",
41048
41183
  title: sprinkle.title,
41049
41184
  params: { sprinkle: sprinkle.id },
41050
41185
  inactive: !focus,
41051
- ...place3 ?? placement(dock, "right", screen)
41186
+ ...place4 ?? placement(dock2, "right", screen)
41052
41187
  });
41053
41188
  }
41054
- if (focus) dock.focusPanel(id);
41055
- else dock.reveal(id);
41189
+ if (focus) dock2.focusPanel(id);
41190
+ else dock2.reveal(id);
41056
41191
  return id;
41057
41192
  }
41058
41193
 
@@ -41096,10 +41231,10 @@ var Panels = class {
41096
41231
  return ago2 < userCloseWindow ? ago2 : null;
41097
41232
  }
41098
41233
  recentClose() {
41099
- const dock = this.#host.dock();
41234
+ const dock2 = this.#host.dock();
41100
41235
  for (const id of this.#closed.keys()) {
41101
41236
  const ago2 = this.closedAgo(id);
41102
- if (ago2 !== null && !dock.has(id)) return { id, ago: ago2 };
41237
+ if (ago2 !== null && !dock2.has(id)) return { id, ago: ago2 };
41103
41238
  }
41104
41239
  return null;
41105
41240
  }
@@ -41156,14 +41291,14 @@ var Panels = class {
41156
41291
  return rows2.map((row) => this.#state(row));
41157
41292
  }
41158
41293
  #state(row) {
41159
- const dock = this.#host.dock();
41160
- const panel = dock.api.getPanel(row.id);
41161
- const content3 = dock.content(row.id);
41294
+ const dock2 = this.#host.dock();
41295
+ const panel = dock2.api.getPanel(row.id);
41296
+ const content3 = dock2.content(row.id);
41162
41297
  return {
41163
41298
  ...row,
41164
41299
  open: panel !== void 0,
41165
41300
  visible: panel?.api.isVisible === true,
41166
- active: panel !== void 0 && dock.api.activePanel?.id === row.id,
41301
+ active: panel !== void 0 && dock2.api.activePanel?.id === row.id,
41167
41302
  busy: content3?.busyReason ?? null
41168
41303
  };
41169
41304
  }
@@ -41186,14 +41321,14 @@ var Panels = class {
41186
41321
  focus(id, options2 = {}) {
41187
41322
  return this.#show(id, true, options2);
41188
41323
  }
41189
- #show(id, focus, { place: place3, section }) {
41324
+ #show(id, focus, { place: place4, section }) {
41190
41325
  const info = this.find(id);
41191
41326
  if (!info) return unknown(id);
41192
- const bad = this.#reference(id, place3);
41327
+ const bad = this.#reference(id, place4);
41193
41328
  if (bad) return bad;
41194
41329
  this.quietly(() => this.#host.open(id, focus, section));
41195
- if (place3) {
41196
- const moved2 = this.move(id, place3);
41330
+ if (place4) {
41331
+ const moved2 = this.move(id, place4);
41197
41332
  if (moved2.code !== 0) return moved2;
41198
41333
  }
41199
41334
  return ok3(`${focus ? "focused" : info.open ? "showed" : "opened"} ${id}`);
@@ -41210,30 +41345,30 @@ var Panels = class {
41210
41345
  this.quietly(() => this.#host.dock().close(id));
41211
41346
  return ok3(`closed ${id}`);
41212
41347
  }
41213
- move(id, place3) {
41348
+ move(id, place4) {
41214
41349
  const info = this.find(id);
41215
41350
  if (!info) return unknown(id);
41216
- const bad = this.#reference(id, place3);
41351
+ const bad = this.#reference(id, place4);
41217
41352
  if (bad) return bad;
41218
- const dock = this.#host.dock();
41353
+ const dock2 = this.#host.dock();
41219
41354
  if (!info.open) this.quietly(() => this.#host.open(id, false));
41220
- if (!dock.has(id)) return unknown(id);
41355
+ if (!dock2.has(id)) return unknown(id);
41221
41356
  if (this.#host.screen() === "phone")
41222
41357
  return ok3(`phones show one panel at a time, so ${id} stays where it is`);
41223
41358
  const busy = info.open ? info.busy : this.find(id)?.busy ?? null;
41224
41359
  if (busy) return refused(`${id} is busy: ${busy}`);
41225
- const target2 = typeof place3 === "string" ? destination(dock, id, place3, this.#host.screen()) : { position: { referencePanel: place3.ref, direction: place3.direction } };
41226
- const reference2 = target2.position && dock.api.getPanel(target2.position.referencePanel);
41360
+ const target2 = typeof place4 === "string" ? destination(dock2, id, place4, this.#host.screen()) : { position: { referencePanel: place4.ref, direction: place4.direction } };
41361
+ const reference2 = target2.position && dock2.api.getPanel(target2.position.referencePanel);
41227
41362
  if (!reference2 || !target2.position) return ok3(`${id} is the only panel, so it stays`);
41228
41363
  const position2 = positions[target2.position.direction];
41229
- const panel = dock.api.getPanel(id);
41364
+ const panel = dock2.api.getPanel(id);
41230
41365
  this.quietly(() => panel?.api.moveTo({ group: reference2.group, position: position2 }));
41231
41366
  return ok3(`moved ${id}`);
41232
41367
  }
41233
- #reference(id, place3) {
41234
- if (typeof place3 !== "object") return null;
41235
- if (place3.ref === id) return { code: 2, message: `can't place ${id} beside itself` };
41236
- if (!this.#host.dock().has(place3.ref)) return { code: 1, message: `${place3.ref} isn't open` };
41368
+ #reference(id, place4) {
41369
+ if (typeof place4 !== "object") return null;
41370
+ if (place4.ref === id) return { code: 2, message: `can't place ${id} beside itself` };
41371
+ if (!this.#host.dock().has(place4.ref)) return { code: 1, message: `${place4.ref} isn't open` };
41237
41372
  return null;
41238
41373
  }
41239
41374
  reset() {
@@ -41288,16 +41423,16 @@ function scan(parsed, rest, positional) {
41288
41423
  parsed.place = side;
41289
41424
  return null;
41290
41425
  }
41291
- function check2({ verb, id, json, section, place: place3 }) {
41426
+ function check2({ verb, id, json, section, place: place4 }) {
41292
41427
  const ids = verb === "list" || verb === "reset" ? 0 : 1;
41293
41428
  if ((id === void 0 ? 0 : 1) !== ids)
41294
41429
  return ids ? `${verb} needs an id` : `${verb} takes no id`;
41295
41430
  if (json && verb !== "list") return "--json is for list";
41296
41431
  if (section !== void 0 && verb !== "open" && verb !== "focus")
41297
41432
  return "--section is for open and focus";
41298
- if (place3 && verb !== "open" && verb !== "focus" && verb !== "move")
41433
+ if (place4 && verb !== "open" && verb !== "focus" && verb !== "move")
41299
41434
  return `${verb} takes no place`;
41300
- if (verb === "move" && !place3) return "move needs a place";
41435
+ if (verb === "move" && !place4) return "move needs a place";
41301
41436
  return null;
41302
41437
  }
41303
41438
  function parse3(args2) {
@@ -41360,18 +41495,18 @@ function act(scope, parsed) {
41360
41495
  const raw2 = parsed.id;
41361
41496
  const id = resolve(panels, raw2, reachable2, cone);
41362
41497
  if (!id) return done(unknown(raw2));
41363
- let place3 = parsed.place;
41364
- if (typeof place3 === "object") {
41365
- const ref = resolve(panels, place3.ref, reachable2, cone);
41366
- if (!ref) return done(unknown(place3.ref));
41367
- place3 = { ...place3, ref };
41498
+ let place4 = parsed.place;
41499
+ if (typeof place4 === "object") {
41500
+ const ref = resolve(panels, place4.ref, reachable2, cone);
41501
+ if (!ref) return done(unknown(place4.ref));
41502
+ place4 = { ...place4, ref };
41368
41503
  }
41369
41504
  if (parsed.verb === "close") return done(panels.close(id));
41370
41505
  const ago2 = scope.agent && !panels.find(id)?.open ? panels.closedAgo(id) : null;
41371
41506
  if (ago2 !== null)
41372
41507
  return refusedOutput(`the user closed ${id} ${closedWhen(ago2)}; ask before opening it again`);
41373
- if (parsed.verb === "move") return done(panels.move(id, place3));
41374
- const options2 = { place: place3, section: parsed.section };
41508
+ if (parsed.verb === "move") return done(panels.move(id, place4));
41509
+ const options2 = { place: place4, section: parsed.section };
41375
41510
  if (parsed.verb === "open") return done(panels.open(id, options2));
41376
41511
  if (scope.agent && panels.typing())
41377
41512
  return done(
@@ -41837,18 +41972,18 @@ var TerminalPanels = class {
41837
41972
  #docks = /* @__PURE__ */ new WeakSet();
41838
41973
  #confirmed = /* @__PURE__ */ new Set();
41839
41974
  #asking = Promise.resolve();
41840
- attach(dock, port, screen) {
41841
- if (this.#docks.has(dock)) return;
41842
- this.#docks.add(dock);
41975
+ attach(dock2, port, screen) {
41976
+ if (this.#docks.has(dock2)) return;
41977
+ this.#docks.add(dock2);
41843
41978
  let kind = "";
41844
- dock.api.onWillMutateLayout((event2) => {
41979
+ dock2.api.onWillMutateLayout((event2) => {
41845
41980
  kind = event2.kind;
41846
41981
  });
41847
- dock.shadowRoot?.addEventListener(
41982
+ dock2.shadowRoot?.addEventListener(
41848
41983
  "click",
41849
41984
  (event2) => {
41850
41985
  const close = event2.composedPath().find((node2) => node2.classList?.contains("slicc-tab-close"));
41851
- const panel = dock.api.panels.find(
41986
+ const panel = dock2.api.panels.find(
41852
41987
  (candidate) => candidate.view.tab.element.contains(close ?? null)
41853
41988
  );
41854
41989
  const id = terminalOf(panel?.id ?? null);
@@ -41858,12 +41993,12 @@ var TerminalPanels = class {
41858
41993
  void this.#ask(info, close).then((yes) => {
41859
41994
  if (!yes) return;
41860
41995
  this.#confirmed.add(info.id);
41861
- dock.close(terminalPanel(info.id));
41996
+ dock2.close(terminalPanel(info.id));
41862
41997
  });
41863
41998
  },
41864
41999
  true
41865
42000
  );
41866
- dock.api.onDidRemovePanel((panel) => {
42001
+ dock2.api.onDidRemovePanel((panel) => {
41867
42002
  const id = terminalOf(panel.id);
41868
42003
  const terminals = port();
41869
42004
  if (kind !== "remove" || !id || !terminals) return;
@@ -41872,7 +42007,7 @@ var TerminalPanels = class {
41872
42007
  if (this.#confirmed.delete(id)) return terminals.close(id);
41873
42008
  void this.#ask(info, null).then((yes) => {
41874
42009
  if (yes) terminals.close(id);
41875
- else dock.focusPanel(openTerminal(dock, info, screen()));
42010
+ else dock2.focusPanel(openTerminal(dock2, info, screen()));
41876
42011
  });
41877
42012
  });
41878
42013
  }
@@ -41887,37 +42022,37 @@ var TerminalPanels = class {
41887
42022
  activated(id) {
41888
42023
  if (terminalOf(id) !== null) this.#recent = id;
41889
42024
  }
41890
- sync(dock, port, screen) {
42025
+ sync(dock2, port, screen) {
41891
42026
  const terminals = port.list();
41892
42027
  if (this.#port !== port) {
41893
42028
  this.#port = port;
41894
42029
  this.#known = new Set(terminals.map((terminal) => terminal.id));
41895
42030
  }
41896
42031
  const live = new Set(terminals.map((terminal) => terminal.id));
41897
- for (const panel of dock.api.panels.map((candidate) => candidate.id)) {
42032
+ for (const panel of dock2.api.panels.map((candidate) => candidate.id)) {
41898
42033
  const terminal = terminalOf(panel);
41899
42034
  if ((panel === "terminal" || terminal !== null) && !live.has(terminal ?? ""))
41900
- dock.close(panel);
42035
+ dock2.close(panel);
41901
42036
  }
41902
42037
  for (const info of terminals) {
41903
42038
  if (this.#known.has(info.id)) continue;
41904
42039
  this.#known.add(info.id);
41905
- openTerminal(dock, info, screen);
42040
+ openTerminal(dock2, info, screen);
41906
42041
  }
41907
42042
  }
41908
- show(dock, port, screen) {
41909
- const panels = terminalPanels(dock);
42043
+ show(dock2, port, screen) {
42044
+ const panels = terminalPanels(dock2);
41910
42045
  const recent = panels.find((id) => id === this.#recent) ?? panels.at(-1);
41911
42046
  const terminals = port.list();
41912
- if (recent) dock.focusPanel(recent);
41913
- else if (terminals.length === 0) this.create(dock, port, screen);
42047
+ if (recent) dock2.focusPanel(recent);
42048
+ else if (terminals.length === 0) this.create(dock2, port, screen);
41914
42049
  else {
41915
- for (const info of terminals) openTerminal(dock, info, screen);
41916
- dock.focusPanel(terminalPanel(terminals.at(-1).id));
42050
+ for (const info of terminals) openTerminal(dock2, info, screen);
42051
+ dock2.focusPanel(terminalPanel(terminals.at(-1).id));
41917
42052
  }
41918
42053
  }
41919
- create(dock, port, screen) {
41920
- dock.focusPanel(openTerminal(dock, port.open(), screen));
42054
+ create(dock2, port, screen) {
42055
+ dock2.focusPanel(openTerminal(dock2, port.open(), screen));
41921
42056
  }
41922
42057
  };
41923
42058
 
@@ -44768,9 +44903,9 @@ function placed(item2) {
44768
44903
  }
44769
44904
  var elsewhere = (item2) => (item2.installs ?? []).filter((install) => install.manager !== "panel");
44770
44905
  function installText(install, version2) {
44771
- const place3 = install.user ? `for ${install.user}` : `in ${install.where}`;
44906
+ const place4 = install.user ? `for ${install.user}` : `in ${install.where}`;
44772
44907
  const via = install.manager === "pnpm" ? ", via pnpm" : "";
44773
- return `${install.version === version2 ? "" : `${install.version} `}${place3}${via}`;
44908
+ return `${install.version === version2 ? "" : `${install.version} `}${place4}${via}`;
44774
44909
  }
44775
44910
  function managedText(item2) {
44776
44911
  const others = elsewhere(item2);
@@ -46074,42 +46209,42 @@ var SliccApp = class extends ThemedElement {
46074
46209
  };
46075
46210
  }
46076
46211
  #rebind(model) {
46077
- const dock = this.dock;
46078
- dock.factories = this.#factories(model);
46079
- for (const panel of dock.api.panels) {
46080
- const element3 = dock.content(panel.id);
46212
+ const dock2 = this.dock;
46213
+ dock2.factories = this.#factories(model);
46214
+ for (const panel of dock2.api.panels) {
46215
+ const element3 = dock2.content(panel.id);
46081
46216
  if (element3 && "model" in element3) element3.model = model;
46082
46217
  }
46083
- if (!model.network && !model.guests && dock.has("network")) dock.close("network");
46218
+ if (!model.network && !model.guests && dock2.has("network")) dock2.close("network");
46084
46219
  this.#prune();
46085
46220
  const agent = this.#active();
46086
- if (agent && this.#offers("chat")) openChat(dock, agent, this.screen, false, false);
46221
+ if (agent && this.#offers("chat")) openChat(dock2, agent, this.screen, false, false);
46087
46222
  }
46088
46223
  #followed(model) {
46089
46224
  if (!this.#started) return;
46090
- const dock = this.dock;
46091
- dock.factories = this.#factories(model);
46225
+ const dock2 = this.dock;
46226
+ dock2.factories = this.#factories(model);
46092
46227
  if (!terminalsAllowed(model))
46093
46228
  this.panels.quietly(() => {
46094
- for (const id of terminalPanels(dock)) dock.close(id);
46229
+ for (const id of terminalPanels(dock2)) dock2.close(id);
46095
46230
  });
46096
46231
  }
46097
46232
  #start(model) {
46098
- const dock = this.dock;
46233
+ const dock2 = this.dock;
46099
46234
  this.#saving = false;
46100
- dock.factories = this.#factories(model);
46101
- dock.accepts = [dipType];
46235
+ dock2.factories = this.#factories(model);
46236
+ dock2.accepts = [dipType];
46102
46237
  this.terminalPanels.attach(
46103
- dock,
46238
+ dock2,
46104
46239
  () => this.model?.terminals,
46105
46240
  () => this.screen
46106
46241
  );
46107
46242
  this.dips.load(this.storage);
46108
46243
  const saved = this.#saved();
46109
- const restored = this.#offered(saved, dock.factories) && dock.restore(saved);
46244
+ const restored = this.#offered(saved, dock2.factories) && dock2.restore(saved);
46110
46245
  if (!restored) {
46111
46246
  defaultLayout(
46112
- dock,
46247
+ dock2,
46113
46248
  this.screen,
46114
46249
  this.#active(),
46115
46250
  this.#available(),
@@ -46119,7 +46254,7 @@ var SliccApp = class extends ThemedElement {
46119
46254
  }
46120
46255
  this.#started = this.screen;
46121
46256
  this.#prune();
46122
- if (!(this.#active() || chats(dock).length || dock.has("chat")) && model.agent.starting?.())
46257
+ if (!(this.#active() || chats(dock2).length || dock2.has("chat")) && model.agent.starting?.())
46123
46258
  this.#open("chat", false);
46124
46259
  this.#saving = true;
46125
46260
  this.#save();
@@ -46148,18 +46283,18 @@ var SliccApp = class extends ThemedElement {
46148
46283
  return model?.agent.list().find((agent) => agent.id === model.agent.active()) ?? null;
46149
46284
  }
46150
46285
  #prune() {
46151
- const dock = this.renderRoot.querySelector("slicc-dock");
46152
- if (!dock || !this.#started) return;
46286
+ const dock2 = this.renderRoot.querySelector("slicc-dock");
46287
+ if (!dock2 || !this.#started) return;
46153
46288
  const known = new Set(this.model?.agent.list().map((agent2) => agent2.id));
46154
46289
  const agent = this.#active();
46155
- const held = !!agent && !!dock.content("chat")?.shadowRoot?.activeElement;
46290
+ const held = !!agent && !!dock2.content("chat")?.shadowRoot?.activeElement;
46156
46291
  this.panels.quietly(() => {
46157
- for (const id of chats(dock)) {
46158
- if (!known.has(chatAgent(id))) dock.close(id);
46292
+ for (const id of chats(dock2)) {
46293
+ if (!known.has(chatAgent(id))) dock2.close(id);
46159
46294
  }
46160
- if (agent && dock.has("chat")) {
46161
- if (this.#offers("chat") && !dock.has(chatId(agent.id)))
46162
- dock.open({
46295
+ if (agent && dock2.has("chat")) {
46296
+ if (this.#offers("chat") && !dock2.has(chatId(agent.id)))
46297
+ dock2.open({
46163
46298
  id: chatId(agent.id),
46164
46299
  component: "chat",
46165
46300
  title: agent.name,
@@ -46167,12 +46302,12 @@ var SliccApp = class extends ThemedElement {
46167
46302
  inactive: true,
46168
46303
  position: { referencePanel: "chat", direction: "within" }
46169
46304
  });
46170
- dock.close("chat");
46305
+ dock2.close("chat");
46171
46306
  }
46172
46307
  if (this.model && this.#offers("terminal"))
46173
- this.terminalPanels.sync(dock, this.model.terminals, this.screen);
46308
+ this.terminalPanels.sync(dock2, this.model.terminals, this.screen);
46174
46309
  });
46175
- if (agent && held && this.#offers("chat")) openChat(dock, agent, this.screen, true);
46310
+ if (agent && held && this.#offers("chat")) openChat(dock2, agent, this.screen, true);
46176
46311
  }
46177
46312
  #activated(event2) {
46178
46313
  const { id } = event2.detail;
@@ -46268,11 +46403,11 @@ var SliccApp = class extends ThemedElement {
46268
46403
  this.panels.closed(id);
46269
46404
  if (id.startsWith("sprinkle:")) this.dips.attach(id.slice("sprinkle:".length));
46270
46405
  };
46271
- #detach(id, place3, open) {
46406
+ #detach(id, place4, open) {
46272
46407
  const sprinkle = this.#sprinkle(id);
46273
46408
  if (!sprinkle) return;
46274
46409
  this.dips.detach(id);
46275
- if (open) openSprinkle(this.dock, sprinkle, this.screen, place3);
46410
+ if (open) openSprinkle(this.dock, sprinkle, this.screen, place4);
46276
46411
  }
46277
46412
  #dropped(event2) {
46278
46413
  const { type, data, panel, position: position2 } = event2.detail;
@@ -46326,9 +46461,9 @@ var SliccApp = class extends ThemedElement {
46326
46461
  )}${this.#more(items.filter((item2) => !shown4.includes(item2)))}</nav>`;
46327
46462
  }
46328
46463
  #rails() {
46329
- const dock = this.renderRoot.querySelector("slicc-dock");
46464
+ const dock2 = this.renderRoot.querySelector("slicc-dock");
46330
46465
  const sprinkles = this.#sprinkles().filter((sprinkle) => !sprinkle.inline || this.dips.has(sprinkle.id)).map(sprinkleSurface);
46331
- const all3 = dock && this.#started ? [...sprinkles, ...this.#available()] : [];
46466
+ const all3 = dock2 && this.#started ? [...sprinkles, ...this.#available()] : [];
46332
46467
  const phone = this.screen === "phone";
46333
46468
  return {
46334
46469
  left: this.#rail(phone ? [] : all3.filter((item2) => item2.side !== "right"), "left"),
@@ -46556,8 +46691,8 @@ function countdown(ms) {
46556
46691
  }
46557
46692
  function asking(approval) {
46558
46693
  const { kind, name, where: where2 } = approval.requester;
46559
- const place3 = where2 ? ` in ${where2}` : "";
46560
- return kind === "user" ? `You ran this with sudo${place3} (as ${name})` : `${name} wants to run this with sudo${place3}`;
46694
+ const place4 = where2 ? ` in ${where2}` : "";
46695
+ return kind === "user" ? `You ran this with sudo${place4} (as ${name})` : `${name} wants to run this with sudo${place4}`;
46561
46696
  }
46562
46697
  function sudo(approval) {
46563
46698
  const as = approval.target && approval.target !== "root" ? `-u ${approval.target} ` : "";
@@ -47275,7 +47410,7 @@ function host3(url) {
47275
47410
  return url;
47276
47411
  }
47277
47412
  }
47278
- function place2(url) {
47413
+ function place3(url) {
47279
47414
  try {
47280
47415
  const { host: host4, pathname } = new URL(url);
47281
47416
  return host4 ? `${host4}${pathname === "/" ? "" : pathname}` : url;
@@ -47303,8 +47438,8 @@ function typed2(action) {
47303
47438
  return `Typed${count2}${action.target ? ` into ${action.target}` : ""}`;
47304
47439
  }
47305
47440
  var verbs2 = {
47306
- open: (action) => `Opened ${place2(action.value ?? "")}`.trim(),
47307
- goto: (action) => `Went to ${place2(action.value ?? "")}`.trim(),
47441
+ open: (action) => `Opened ${place3(action.value ?? "")}`.trim(),
47442
+ goto: (action) => `Went to ${place3(action.value ?? "")}`.trim(),
47308
47443
  back: () => "Went back",
47309
47444
  reload: () => "Reloaded",
47310
47445
  close: () => "Closed tab",
@@ -48190,7 +48325,7 @@ var SliccBrowser = class extends ModelElement {
48190
48325
  ${wide2 ? A : this.#picker(tabs, tab)}
48191
48326
  </div>
48192
48327
  <div class="address">
48193
- <span class="url" title=${tab.url}>${narrow ? place2(tab.url) : tab.url}</span>
48328
+ <span class="url" title=${tab.url}>${narrow ? place3(tab.url) : tab.url}</span>
48194
48329
  <swc-action-button size="s" quiet data-action="copy-url" accessible-label=${copy === "Copy" ? "Copy URL" : copy} @click=${() => this.#copy(tab.url)}><swc-icon-copy slot="icon"></swc-icon-copy>${narrow ? A : copy}</swc-action-button>
48195
48330
  <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>
48196
48331
  </div>