@ai-ecoverse/slicc-spectrum 2.0.2 → 2.1.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
@@ -10587,12 +10587,17 @@ var Cuts = class {
10587
10587
  };
10588
10588
  var Ends = class {
10589
10589
  #seen = /* @__PURE__ */ new Set();
10590
+ #looked = /* @__PURE__ */ new Set();
10590
10591
  #root;
10591
10592
  #changed;
10592
10593
  #observer = new IntersectionObserver((entries) => {
10593
10594
  let changed2 = false;
10594
10595
  for (const entry of entries) {
10595
10596
  const id = entry.target.dataset.end;
10597
+ if (!this.#looked.has(id)) {
10598
+ this.#looked.add(id);
10599
+ changed2 = true;
10600
+ }
10596
10601
  if (!entry.isIntersecting || this.#seen.has(id)) continue;
10597
10602
  this.#seen.add(id);
10598
10603
  changed2 = true;
@@ -10606,8 +10611,12 @@ var Ends = class {
10606
10611
  has(id) {
10607
10612
  return this.#seen.has(id);
10608
10613
  }
10614
+ hidden(id) {
10615
+ return this.#looked.has(id) && !this.#seen.has(id);
10616
+ }
10609
10617
  clear() {
10610
10618
  this.#seen.clear();
10619
+ this.#looked.clear();
10611
10620
  }
10612
10621
  observe() {
10613
10622
  for (const end of this.#root().querySelectorAll("[data-end]"))
@@ -37442,6 +37451,16 @@ var SliccChat = class _SliccChat extends ThemedElement {
37442
37451
  background: var(--swc-background-elevated-color);
37443
37452
  box-shadow: var(--swc-drop-shadow-elevated);
37444
37453
  }
37454
+ .older {
37455
+ display: flex;
37456
+ align-items: center;
37457
+ justify-content: center;
37458
+ gap: var(--swc-spacing-100);
37459
+ min-block-size: var(--swc-component-height-100);
37460
+ margin-block-end: var(--swc-spacing-200);
37461
+ font-size: var(--swc-font-size-100);
37462
+ color: var(--swc-neutral-subdued-content-color-default);
37463
+ }
37445
37464
  .empty {
37446
37465
  color: var(--swc-neutral-subdued-content-color-default);
37447
37466
  text-align: center;
@@ -37547,7 +37566,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
37547
37566
  #tick;
37548
37567
  #tail = "";
37549
37568
  #held = "";
37550
- #mark = 0;
37569
+ #mark = "";
37551
37570
  #all = false;
37552
37571
  #seen = "";
37553
37572
  #focused = (event2) => {
@@ -37596,7 +37615,75 @@ var SliccChat = class _SliccChat extends ThemedElement {
37596
37615
  const log = this.#log();
37597
37616
  if (!this.#stuck && log.scrollHeight <= log.clientHeight) this.#follow();
37598
37617
  else this.#pin(false);
37618
+ this.#check();
37599
37619
  });
37620
+ #paging = /* @__PURE__ */ new Set();
37621
+ #stopped = /* @__PURE__ */ new Map();
37622
+ #shown = { agent: "", head: "" };
37623
+ #anchor = null;
37624
+ #first(id) {
37625
+ return id && this.model?.agent.messages(id)[0]?.id || "";
37626
+ }
37627
+ #check() {
37628
+ const log = this.#log();
37629
+ if (log.scrollTop < log.clientHeight) void this.#earlier();
37630
+ }
37631
+ async #earlier() {
37632
+ const agent = this.model?.agent;
37633
+ const id = this.#id();
37634
+ const head = this.#first(id);
37635
+ if (!agent?.hasOlder?.(id) || this.#paging.has(id) || this.#stopped.get(id)?.head === head)
37636
+ return;
37637
+ this.#paging.add(id);
37638
+ this.requestUpdate();
37639
+ try {
37640
+ const found = await agent.older(id, head);
37641
+ const now = this.#first(id);
37642
+ if (!found.length || now === head) this.#stopped.set(id, { head: now, failed: false });
37643
+ } catch {
37644
+ this.#stopped.set(id, { head, failed: true });
37645
+ }
37646
+ this.#paging.delete(id);
37647
+ this.requestUpdate();
37648
+ await this.updateComplete;
37649
+ if (this.#id() === id) this.#check();
37650
+ }
37651
+ #retry(id) {
37652
+ this.#log().focus({ preventScroll: true });
37653
+ this.#stopped.delete(id);
37654
+ void this.#earlier();
37655
+ }
37656
+ #keep(agent) {
37657
+ const log = this.#log();
37658
+ const top = log.getBoundingClientRect().top;
37659
+ const card2 = [...log.querySelector("swc-conversation-thread")?.children ?? []].find(
37660
+ (child) => !child.matches(".day") && child.getBoundingClientRect().bottom > top
37661
+ );
37662
+ return {
37663
+ agent,
37664
+ card: card2,
37665
+ offset: card2 ? card2.getBoundingClientRect().top - top : 0,
37666
+ top: log.scrollTop,
37667
+ height: log.scrollHeight
37668
+ };
37669
+ }
37670
+ #restore() {
37671
+ const { agent, card: card2, offset: offset3, top, height } = this.#anchor;
37672
+ this.#anchor = null;
37673
+ if (agent !== this.#id()) return;
37674
+ const log = this.#log();
37675
+ log.scrollTop = card2?.isConnected ? log.scrollTop + card2.getBoundingClientRect().top - log.getBoundingClientRect().top - offset3 : top + log.scrollHeight - height;
37676
+ this.#last = log.scrollTop;
37677
+ this.#height = log.scrollHeight;
37678
+ }
37679
+ #olderRow(id, head) {
37680
+ const stop = this.#stopped.get(id);
37681
+ if (stop?.failed && stop.head === head)
37682
+ return b`<div class="older" role="alert" data-older="failed"><span>Couldn’t load earlier messages.</span><swc-action-button size="s" quiet data-action="retry-older" @click=${() => this.#retry(id)}>Retry</swc-action-button></div>`;
37683
+ const paging = this.#paging.has(id);
37684
+ if (!paging && (!this.model?.agent.hasOlder?.(id) || stop?.head === head)) return A;
37685
+ return b`<div class="older" role="status" data-older="loading" aria-busy=${paging ? "true" : "false"}>Loading earlier messages…</div>`;
37686
+ }
37600
37687
  #fitted;
37601
37688
  #fit = new ResizeObserver(([entry]) => {
37602
37689
  this.style.setProperty("--composer-height", `${entry.target.offsetHeight}px`);
@@ -37654,6 +37741,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
37654
37741
  this.#stuck = false;
37655
37742
  this.#last = log.scrollTop;
37656
37743
  this.#height = log.scrollHeight;
37744
+ this.#check();
37657
37745
  };
37658
37746
  #intent = {
37659
37747
  passive: true,
@@ -37716,6 +37804,17 @@ var SliccChat = class _SliccChat extends ThemedElement {
37716
37804
  clearInterval(this.#tick);
37717
37805
  this.#tick = void 0;
37718
37806
  }
37807
+ willUpdate(changed2) {
37808
+ super.willUpdate(changed2);
37809
+ const id = this.#id();
37810
+ const head = this.#first(id);
37811
+ const shown5 = this.#shown;
37812
+ if (this.hasUpdated && !this.#anchor && id === shown5.agent && shown5.head && head !== shown5.head) {
37813
+ this.#anchor = this.#keep(id);
37814
+ requestAnimationFrame(() => this.#restore());
37815
+ }
37816
+ this.#shown = { agent: id, head };
37817
+ }
37719
37818
  updated() {
37720
37819
  this.#attach();
37721
37820
  const timed = this.isConnected && this.#timed();
@@ -38008,12 +38107,25 @@ var SliccChat = class _SliccChat extends ThemedElement {
38008
38107
  this.#seen = id;
38009
38108
  this.#all = false;
38010
38109
  this.#details.clear();
38110
+ this.#stopped.delete(id);
38011
38111
  }
38012
38112
  #probe() {
38013
38113
  if (this.#handlers.surface || this.#probed === this.color) return;
38014
38114
  this.#probed = this.color;
38015
38115
  this.#handlers.surface = readSurface(this.renderRoot);
38016
38116
  }
38117
+ #thread(items, older, blank2) {
38118
+ if (items.length)
38119
+ return b`<swc-conversation-thread>${c(
38120
+ items,
38121
+ ([key]) => key,
38122
+ ([, item2]) => item2
38123
+ )}</swc-conversation-thread>`;
38124
+ if (this.model?.tabs?.state().role === "connecting")
38125
+ return b`<div class="empty" data-connecting>${connecting}</div>`;
38126
+ if (this.model?.agent.starting?.() || older) return A;
38127
+ return b`<div class="empty" data-empty>${blank2}</div>`;
38128
+ }
38017
38129
  render() {
38018
38130
  this.#handlers.color = this.color;
38019
38131
  this.#handlers.model = this.model ?? null;
@@ -38028,8 +38140,10 @@ var SliccChat = class _SliccChat extends ThemedElement {
38028
38140
  const messages = agent ? this.model?.agent.messages(agent.id) ?? [] : [];
38029
38141
  this.#tail = messages.at(-1)?.id ?? "";
38030
38142
  const { items, asks } = dock(agent ? this.#items(messages, agent) : [], messages, seat);
38031
- const count2 = items.filter(([key]) => !key.startsWith("day:")).length;
38032
- if (!this.behind) this.#mark = count2;
38143
+ const keys = items.flatMap(([key]) => key.startsWith("day:") ? [] : [key]);
38144
+ if (!this.behind) this.#mark = keys.at(-1) ?? "";
38145
+ const seen = keys.lastIndexOf(this.#mark);
38146
+ const older = agent ? this.#olderRow(agent.id, messages[0]?.id ?? "") : A;
38033
38147
  return b`
38034
38148
  <header ?data-compact=${this.compact}>
38035
38149
  ${agent ? this.#meta(agent, !messages.length) : this.#agentless()}
@@ -38051,14 +38165,11 @@ var SliccChat = class _SliccChat extends ThemedElement {
38051
38165
  @pointerdown=${this.#hold}
38052
38166
  >
38053
38167
  <div class="column" @keydown=${this.#keys}>
38054
- ${items.length ? b`<swc-conversation-thread>${c(
38055
- items,
38056
- ([key]) => key,
38057
- ([, item2]) => item2
38058
- )}</swc-conversation-thread>` : this.model?.tabs?.state().role === "connecting" ? b`<div class="empty" data-connecting>${connecting}</div>` : this.model?.agent.starting?.() ? A : b`<div class="empty" data-empty>${empty3(watch2, seat, agent?.name ?? "the agent")}</div>`}
38168
+ ${older}
38169
+ ${this.#thread(items, older !== A, empty3(watch2, seat, agent?.name ?? "the agent"))}
38059
38170
  </div>
38060
38171
  </div>
38061
- ${this.behind ? this.#latest(count2 - this.#mark) : A}
38172
+ ${this.behind ? this.#latest(seen < 0 ? 0 : keys.length - 1 - seen) : A}
38062
38173
  </div>
38063
38174
  ${this.dropping ? b`<swc-dropzone dragged size="l" aria-label="Attach files" dragged-message="" data-surface="drop">
38064
38175
  <swc-illustrated-message>
@@ -49879,8 +49990,10 @@ var SliccApprovals = class extends ModelElement {
49879
49990
  gone: { state: true }
49880
49991
  };
49881
49992
  arming = 500;
49882
- #armed = false;
49883
- #arming;
49993
+ #changed = 0;
49994
+ #pressed = 0;
49995
+ #layout = "";
49996
+ #moves = new ResizeObserver(() => this.#settle());
49884
49997
  #showing = null;
49885
49998
  #pending = /* @__PURE__ */ new Set();
49886
49999
  #done = /* @__PURE__ */ new Set();
@@ -49890,11 +50003,6 @@ var SliccApprovals = class extends ModelElement {
49890
50003
  #timer = null;
49891
50004
  #shown = "";
49892
50005
  #trigger = null;
49893
- #full = /* @__PURE__ */ new Set();
49894
- #cuts = new Cuts(
49895
- () => this.renderRoot,
49896
- () => this.requestUpdate()
49897
- );
49898
50006
  #ends = new Ends(
49899
50007
  () => this.renderRoot,
49900
50008
  () => this.requestUpdate()
@@ -49908,7 +50016,6 @@ var SliccApprovals = class extends ModelElement {
49908
50016
  }
49909
50017
  static styles = [
49910
50018
  dialogStyles,
49911
- clampCss,
49912
50019
  i`
49913
50020
  :host {
49914
50021
  display: contents;
@@ -49955,9 +50062,6 @@ var SliccApprovals = class extends ModelElement {
49955
50062
  inline-size: 0;
49956
50063
  block-size: 0;
49957
50064
  }
49958
- .full-command {
49959
- margin-block-start: var(--swc-spacing-100);
49960
- }
49961
50065
  .guest {
49962
50066
  margin-block-start: var(--swc-spacing-200);
49963
50067
  padding: var(--swc-spacing-200) var(--swc-spacing-300);
@@ -49990,16 +50094,39 @@ var SliccApprovals = class extends ModelElement {
49990
50094
  margin-block-start: var(--swc-spacing-300);
49991
50095
  font-variant-numeric: tabular-nums;
49992
50096
  }
50097
+ .more {
50098
+ min-block-size: 1lh;
50099
+ }
50100
+ .notes {
50101
+ display: flex;
50102
+ flex-direction: column;
50103
+ gap: var(--swc-spacing-100);
50104
+ box-sizing: border-box;
50105
+ block-size: min(9lh, 30dvh);
50106
+ margin-block-start: var(--swc-spacing-200);
50107
+ font-size: var(--swc-font-size-75);
50108
+ overflow-y: auto;
50109
+ overscroll-behavior: contain;
50110
+ }
50111
+ .notes .hint,
50112
+ .notes .verdict {
50113
+ margin: 0;
50114
+ }
50115
+ .judge {
50116
+ display: flex;
50117
+ flex: 1 0 auto;
50118
+ flex-direction: column;
50119
+ gap: var(--swc-spacing-100);
50120
+ }
49993
50121
  .judged {
49994
50122
  display: flex;
50123
+ flex: 1 0 auto;
49995
50124
  align-items: flex-start;
49996
50125
  gap: var(--swc-spacing-100);
49997
- margin-block-start: var(--swc-spacing-200);
49998
50126
  padding: var(--swc-spacing-200) var(--swc-spacing-300);
49999
50127
  border-radius: var(--swc-corner-radius-medium-default);
50000
50128
  background: var(--swc-neutral-subtle-background-color-default);
50001
50129
  color: var(--swc-neutral-content-color-default);
50002
- font-size: var(--swc-font-size-75);
50003
50130
  overflow-wrap: anywhere;
50004
50131
  }
50005
50132
  .judged[data-verdict='checking'],
@@ -50023,6 +50150,9 @@ var SliccApprovals = class extends ModelElement {
50023
50150
  .judged p {
50024
50151
  margin: 0;
50025
50152
  }
50153
+ [slot='button'][data-action='deny'] {
50154
+ margin-inline-end: auto;
50155
+ }
50026
50156
  .problem {
50027
50157
  display: flex;
50028
50158
  align-items: flex-start;
@@ -50045,7 +50175,6 @@ var SliccApprovals = class extends ModelElement {
50045
50175
  this.#done.clear();
50046
50176
  this.#closed.clear();
50047
50177
  this.#ended.clear();
50048
- this.#full.clear();
50049
50178
  this.#ends.clear();
50050
50179
  }
50051
50180
  if (!port) return [];
@@ -50067,9 +50196,9 @@ var SliccApprovals = class extends ModelElement {
50067
50196
  disconnectedCallback() {
50068
50197
  super.disconnectedCallback();
50069
50198
  this.#tick(false);
50070
- clearTimeout(this.#arming);
50071
50199
  this.#showing = null;
50072
- this.#cuts.disconnect();
50200
+ this.#layout = "";
50201
+ this.#moves.disconnect();
50073
50202
  this.#ends.disconnect();
50074
50203
  }
50075
50204
  #tick(on2) {
@@ -50081,7 +50210,7 @@ var SliccApprovals = class extends ModelElement {
50081
50210
  }
50082
50211
  async decide(approval, decision2) {
50083
50212
  const port = this.model?.approvals;
50084
- if (!port?.decide || this.busy || decision2 !== "deny" && (!this.#armed || !this.#whole(approval)))
50213
+ if (!port?.decide || this.busy || decision2 !== "deny" && (!this.#settled(performance.now()) || !this.#whole(approval)))
50085
50214
  return;
50086
50215
  const live = port.list().find(({ id }) => id === approval.id);
50087
50216
  if (decision2 === "always" && !(live && offersAlways(live))) return;
@@ -50117,17 +50246,46 @@ var SliccApprovals = class extends ModelElement {
50117
50246
  const next = list6[0] ?? null;
50118
50247
  if (next?.id === showing?.id) return;
50119
50248
  this.#showing = next;
50120
- clearTimeout(this.#arming);
50121
- this.#armed = false;
50122
- this.#arming = setTimeout(() => this.#armed = true, this.arming);
50249
+ this.#changed = performance.now();
50250
+ }
50251
+ #settled(at) {
50252
+ return at - this.#changed >= this.arming;
50253
+ }
50254
+ #settle() {
50255
+ const dialog = this.renderRoot.querySelector("dialog");
50256
+ const buttons = [...this.renderRoot.querySelectorAll("[slot=button]")];
50257
+ const layout = JSON.stringify([
50258
+ dialog?.dataset.approval,
50259
+ dialog?.dataset.gone,
50260
+ buttons.map((button) => {
50261
+ const { left, top, width, height } = button.getBoundingClientRect();
50262
+ return [
50263
+ button.dataset.action,
50264
+ button.textContent,
50265
+ button.hasAttribute("disabled"),
50266
+ button.hasAttribute("pending"),
50267
+ ...[left, top, width, height].map(Math.round)
50268
+ ];
50269
+ })
50270
+ ]);
50271
+ if (layout === this.#layout) return;
50272
+ this.#layout = layout;
50273
+ this.#changed = performance.now();
50274
+ }
50275
+ #click(event2, approval, decision2) {
50276
+ if (!this.#settled(event2.detail ? this.#pressed : performance.now())) return;
50277
+ void this.decide(approval, decision2);
50123
50278
  }
50124
50279
  updated(changed2) {
50125
50280
  super.updated(changed2);
50126
50281
  const all2 = this.model?.approvals?.list() ?? [];
50127
50282
  this.#tick(this.isConnected && all2.length > 0);
50128
- this.#cuts.measure();
50129
50283
  this.#ends.observe();
50130
50284
  const dialog = this.renderRoot.querySelector("dialog");
50285
+ if (dialog)
50286
+ for (const box of dialog.querySelectorAll("sp-alert-dialog, [slot=button]"))
50287
+ this.#moves.observe(box);
50288
+ this.#settle();
50131
50289
  const key = dialog ? `${dialog.dataset.approval}:${dialog.dataset.gone ?? ""}:${dialog.hasAttribute("data-rejected")}` : "";
50132
50290
  if (key === this.#shown) return;
50133
50291
  if (dialog && !this.#shown) this.#trigger = origin();
@@ -50138,8 +50296,8 @@ var SliccApprovals = class extends ModelElement {
50138
50296
  return;
50139
50297
  }
50140
50298
  if (!dialog.open) dialog.showModal();
50141
- this.#cuts.measure();
50142
50299
  this.#ends.observe();
50300
+ this.#settle();
50143
50301
  const first2 = dialog.querySelector("[data-action=deny], [data-action=close]");
50144
50302
  void first2.updateComplete.then(() => first2.focus());
50145
50303
  }
@@ -50165,38 +50323,30 @@ var SliccApprovals = class extends ModelElement {
50165
50323
  fill-style=${variant === "accent" ? A : "outline"}
50166
50324
  data-action=${decision2}
50167
50325
  ?pending=${this.busy === decision2}
50168
- ?disabled=${!!this.busy && this.busy !== decision2}
50169
- @click=${() => this.decide(approval, decision2)}
50326
+ ?disabled=${!!this.busy && this.busy !== decision2 || decision2 !== "deny" && !this.#whole(approval)}
50327
+ @click=${(event2) => this.#click(event2, approval, decision2)}
50170
50328
  >${label}</swc-button
50171
50329
  >`;
50172
50330
  }
50173
50331
  #dialog(approval, key, content3) {
50174
50332
  return i23(
50175
50333
  key,
50176
- b`<dialog role="alertdialog" aria-labelledby="title" aria-describedby="asking" data-approval=${approval.id} data-kind=${approval.kind} data-requester=${approval.requester.kind} data-gone=${this.gone?.reason ?? A} data-rejected=${!this.gone && this.failure?.id === approval.id ? "" : A} @cancel=${(event2) => this.#cancel(event2, approval)}>${content3}</dialog>`
50334
+ b`<dialog role="alertdialog" aria-labelledby="title" aria-describedby="asking" data-approval=${approval.id} data-kind=${approval.kind} data-requester=${approval.requester.kind} data-gone=${this.gone?.reason ?? A} data-rejected=${!this.gone && this.failure?.id === approval.id ? "" : A} @pointerdown=${() => this.#pressed = performance.now()} @cancel=${(event2) => this.#cancel(event2, approval)}>${content3}</dialog>`
50177
50335
  );
50178
50336
  }
50179
50337
  #whole(approval) {
50180
- const { id } = approval;
50181
50338
  if (truncated(approval)) return false;
50182
- return !approved(approval) || this.#cuts.get(id) === false || this.#full.has(id) && this.#ends.has(id);
50339
+ return !approved(approval) || this.#ends.has(approval.id);
50183
50340
  }
50184
50341
  #gate(approval) {
50185
50342
  if (truncated(approval)) return tooLong;
50186
- if (this.#whole(approval)) return "";
50187
- return this.#full.has(approval.id) ? toScroll : toShow;
50188
- }
50189
- #expand(id) {
50190
- if (!this.#full.delete(id)) this.#full.add(id);
50191
- this.requestUpdate();
50343
+ return this.#ends.hidden(approval.id) ? toScroll : "";
50192
50344
  }
50193
50345
  #command(approval, pending) {
50194
50346
  const { id } = approval;
50195
50347
  const text4 = approved(approval);
50196
50348
  if (!text4) return b`<p class="hint" data-id="no-details">This request has no details.</p>`;
50197
- const full = !pending || this.#full.has(id);
50198
- const toggle = pending && (full || this.#cuts.get(id)) ? fullCommand(full, () => this.#expand(id)) : A;
50199
- return b`<pre class="command" data-command=${approval.kind === "sudo" ? "" : A} data-summary=${approval.kind === "sudo" ? A : ""}><span class="lines" data-clamp=${full ? A : id}>${approval.kind === "sudo" ? commandText(text4) : text4}${pending ? b`<span class="end" data-end=${id}></span>` : A}</span></pre>${toggle}`;
50349
+ return b`<pre class="command" data-command=${approval.kind === "sudo" ? "" : A} data-summary=${approval.kind === "sudo" ? A : ""}><span class="lines">${approval.kind === "sudo" ? commandText(text4) : text4}${pending ? b`<span class="end" data-end=${id}></span>` : A}</span></pre>`;
50200
50350
  }
50201
50351
  #request(approval, pending = false) {
50202
50352
  if (approval.kind === "tray") return b`<p id="asking">${trayAsking(approval)}</p>`;
@@ -50211,18 +50361,17 @@ var SliccApprovals = class extends ModelElement {
50211
50361
  <div class="guest" data-guest-text>${approval.text}</div>
50212
50362
  ${files.length ? b`<ul class="files" data-attachments>${files.map((file) => b`<li>${file.name} · ${file.mimeType} · ${size3(file.size)}</li>`)}</ul>` : A}`;
50213
50363
  }
50214
- #verdict(approval) {
50364
+ #notes(approval, gate, always) {
50215
50365
  if (approval.kind === "tray") return A;
50216
50366
  const note = verdictNote(approval);
50217
- return b`<div class="judge" aria-live="polite">${judged(approval)}${note ? b`<p class="hint" data-verdict-note>${note}</p>` : A}</div>`;
50367
+ return b`<div class="notes" data-notes><div class="judge" aria-live="polite">${judged(approval)}${note ? b`<p class="hint" data-verdict-note>${note}</p>` : A}</div>${gate ? b`<p class="hint" data-allow-hint>${gate}</p>` : A}${always ? b`<p class="hint" data-always-hint>${hintOf(approval)}</p>` : A}</div>`;
50218
50368
  }
50219
50369
  #actions(approval, rejected, always) {
50220
50370
  if (rejected)
50221
50371
  return b`<swc-button slot="button" variant="secondary" fill-style="outline" data-action="close" @click=${() => this.#dismiss(approval)}>Close</swc-button>`;
50222
- const whole = this.#whole(approval);
50223
50372
  return b`${this.#button(approval, "deny", "Deny", "secondary")}
50224
- ${whole && always ? this.#button(approval, "always", inCwd(approval) ? "Always allow in this directory" : "Always allow", "secondary") : A}
50225
- ${whole ? this.#button(approval, "once", "Allow once", "accent") : A}`;
50373
+ ${always ? this.#button(approval, "always", inCwd(approval) ? "Always allow in this directory" : "Always allow", "secondary") : A}
50374
+ ${this.#button(approval, "once", "Allow once", "accent")}`;
50226
50375
  }
50227
50376
  render() {
50228
50377
  if (this.gone) {
@@ -50244,8 +50393,7 @@ var SliccApprovals = class extends ModelElement {
50244
50393
  if (!approval) return A;
50245
50394
  const failure3 = this.failure?.id === approval.id ? this.failure.message : "";
50246
50395
  const always = offersAlways(approval);
50247
- const gate = this.#gate(approval);
50248
- const hint2 = always && this.#whole(approval) ? hintOf(approval) : "";
50396
+ const gate = failure3 ? "" : this.#gate(approval);
50249
50397
  return this.#dialog(
50250
50398
  approval,
50251
50399
  approval.id,
@@ -50253,11 +50401,9 @@ var SliccApprovals = class extends ModelElement {
50253
50401
  <h2 id="title" slot="heading">${title(approval)}</h2>
50254
50402
  ${this.#request(approval, true)}
50255
50403
  ${approval.kind === "sudo" && approval.cwd ? b`<p class="cwd">In ${commandText(approval.cwd, false)}</p>` : A}
50256
- ${this.#verdict(approval)}
50257
- ${hint2 ? b`<p class="hint">${hint2}</p>` : A}
50258
- ${!failure3 && gate ? b`<p class="hint" data-allow-hint>${gate}</p>` : A}
50404
+ ${this.#notes(approval, gate, always)}
50259
50405
  ${failure3 ? b`<p class="problem" role="alert" data-error><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><span>${failure3}</span></p>` : b`<p class="timer" data-timer>Denied automatically in ${countdown(approval.expiresAt - this.now)}.</p>`}
50260
- ${rest.length ? b`<p class="more" data-more>${rest.length === 1 ? "1 more request is waiting." : `${rest.length} more requests are waiting.`}</p>` : A}
50406
+ <p class="more" data-more=${rest.length ? "" : A}>${rest.length === 1 ? "1 more request is waiting." : rest.length ? `${rest.length} more requests are waiting.` : ""}</p>
50261
50407
  ${this.#actions(approval, !!failure3, always)}
50262
50408
  </sp-alert-dialog>`
50263
50409
  );
@@ -51994,7 +52140,7 @@ var SliccDiffPanel = class extends ThemedElement {
51994
52140
  // src/app/lucide.ts
51995
52141
  var library = null;
51996
52142
  function load2() {
51997
- library ??= import("./chunk-EFJJ7K57.js");
52143
+ library ??= import("./chunk-NMHCUT6N.js");
51998
52144
  return library;
51999
52145
  }
52000
52146
  function pascal(name) {
@@ -70197,6 +70343,10 @@ var PositionCache = class {
70197
70343
  }
70198
70344
  };
70199
70345
  var SCHEDULED = -1;
70346
+ function isInCollapsedEdgeGroup(panel) {
70347
+ const api = panel.group.api;
70348
+ return api.location.type === "edge" && api.isCollapsed();
70349
+ }
70200
70350
  function createFocusableElement() {
70201
70351
  const element2 = document.createElement("div");
70202
70352
  element2.tabIndex = -1;
@@ -70270,6 +70420,7 @@ var OverlayRenderContainer = class extends CompositeDisposable {
70270
70420
  return false;
70271
70421
  }
70272
70422
  attach(options2) {
70423
+ var _panel$group$api$onDi, _panel$group$api$onDi2, _panel$group$api;
70273
70424
  const { panel, referenceContainer } = options2;
70274
70425
  if (!this.map[panel.api.id]) {
70275
70426
  const element2 = createFocusableElement();
@@ -70290,7 +70441,12 @@ var OverlayRenderContainer = class extends CompositeDisposable {
70290
70441
  mapEntry.generation = ++this._generation;
70291
70442
  this.cancelPendingUpdate(mapEntry);
70292
70443
  mapEntry.referenceContainer = referenceContainer;
70293
- mapEntry.retainPreviousGeometry = mapEntry.positioned;
70444
+ const collapsedEdge = isInCollapsedEdgeGroup(panel);
70445
+ mapEntry.retainPreviousGeometry = mapEntry.positioned && !collapsedEdge;
70446
+ if (collapsedEdge && !mapEntry.forceVisible) {
70447
+ mapEntry.element.style.visibility = "hidden";
70448
+ mapEntry.element.style.pointerEvents = "none";
70449
+ }
70294
70450
  }
70295
70451
  const generation = mapEntry.generation;
70296
70452
  const focusContainer = mapEntry.element;
@@ -70318,18 +70474,30 @@ var OverlayRenderContainer = class extends CompositeDisposable {
70318
70474
  if (this.isDisposed || (entry === null || entry === void 0 ? void 0 : entry.generation) !== generation) return;
70319
70475
  const forceVisible = (_entry$forceVisible = entry.forceVisible) !== null && _entry$forceVisible !== void 0 ? _entry$forceVisible : false;
70320
70476
  const clip = entry.clip;
70477
+ const collapsedEdge = isInCollapsedEdgeGroup(panel);
70478
+ const hidden = !forceVisible && (!panel.api.isVisible || collapsedEdge);
70321
70479
  const box = this.positionCache.getPosition(referenceContainer.element);
70322
70480
  const box2 = this.positionCache.getPosition(this.element);
70323
70481
  const left = box.left - box2.left;
70324
70482
  const top = box.top - box2.top;
70325
70483
  const width = box.width;
70326
70484
  const height = box.height;
70327
- if (entry.retainPreviousGeometry && (width === 0 || height === 0)) {
70328
- if (!panel.api.isVisible && !forceVisible) {
70485
+ if (width === 0 || height === 0) {
70486
+ if (collapsedEdge && !forceVisible) {
70487
+ entry.retainPreviousGeometry = false;
70329
70488
  focusContainer.style.visibility = "hidden";
70330
70489
  focusContainer.style.pointerEvents = "none";
70490
+ focusContainer.style.clipPath = "";
70491
+ focusContainer.style.zIndex = "";
70492
+ return;
70493
+ }
70494
+ if (entry.retainPreviousGeometry) {
70495
+ if (hidden) {
70496
+ focusContainer.style.visibility = "hidden";
70497
+ focusContainer.style.pointerEvents = "none";
70498
+ }
70499
+ return;
70331
70500
  }
70332
- return;
70333
70501
  }
70334
70502
  entry.retainPreviousGeometry = false;
70335
70503
  entry.positioned = true;
@@ -70337,7 +70505,7 @@ var OverlayRenderContainer = class extends CompositeDisposable {
70337
70505
  setPixels(focusContainer.style, "top", top);
70338
70506
  setPixels(focusContainer.style, "width", width);
70339
70507
  setPixels(focusContainer.style, "height", height);
70340
- if (panel.api.isVisible || forceVisible) {
70508
+ if (!hidden) {
70341
70509
  focusContainer.style.visibility = "";
70342
70510
  focusContainer.style.pointerEvents = "";
70343
70511
  } else {
@@ -70364,11 +70532,13 @@ var OverlayRenderContainer = class extends CompositeDisposable {
70364
70532
  if (scheduling.pendingUpdate === SCHEDULED) scheduling.pendingUpdate = handle;
70365
70533
  };
70366
70534
  const visibilityChanged = () => {
70367
- if (panel.api.isVisible) {
70368
- var _this$map$panel$api$i;
70535
+ var _this$map$panel$api$i;
70536
+ const collapsedEdge = !((_this$map$panel$api$i = this.map[panel.api.id]) === null || _this$map$panel$api$i === void 0 ? void 0 : _this$map$panel$api$i.forceVisible) && isInCollapsedEdgeGroup(panel);
70537
+ if (panel.api.isVisible && !collapsedEdge) {
70538
+ var _this$map$panel$api$i2;
70369
70539
  this.positionCache.invalidate();
70370
70540
  resize();
70371
- if ((_this$map$panel$api$i = this.map[panel.api.id]) === null || _this$map$panel$api$i === void 0 ? void 0 : _this$map$panel$api$i.retainPreviousGeometry) focusContainer.style.visibility = "";
70541
+ if ((_this$map$panel$api$i2 = this.map[panel.api.id]) === null || _this$map$panel$api$i2 === void 0 ? void 0 : _this$map$panel$api$i2.retainPreviousGeometry) focusContainer.style.visibility = "";
70372
70542
  focusContainer.style.pointerEvents = "";
70373
70543
  } else {
70374
70544
  focusContainer.style.visibility = "hidden";
@@ -70431,6 +70601,10 @@ var OverlayRenderContainer = class extends CompositeDisposable {
70431
70601
  if (!panel.api.isVisible) return;
70432
70602
  resize();
70433
70603
  }),
70604
+ (_panel$group$api$onDi = (_panel$group$api$onDi2 = (_panel$group$api = panel.group.api).onDidCollapsedChange) === null || _panel$group$api$onDi2 === void 0 ? void 0 : _panel$group$api$onDi2.call(_panel$group$api, () => {
70605
+ this.positionCache.invalidate();
70606
+ resize();
70607
+ })) !== null && _panel$group$api$onDi !== void 0 ? _panel$group$api$onDi : Disposable.NONE,
70434
70608
  referenceContainer.onDidDimensionsChange((size4) => {
70435
70609
  applySize(size4);
70436
70610
  }),
@@ -84578,7 +84752,7 @@ lit-html/static.js:
84578
84752
  dockview-core/dist/package/main.esm.mjs:
84579
84753
  (**
84580
84754
  * dockview-core
84581
- * @version 8.8.1
84755
+ * @version 8.8.2
84582
84756
  * @link https://github.com/dockview/dockview
84583
84757
  * @license MIT
84584
84758
  *)