@ai-ecoverse/slicc-spectrum 1.103.2 → 1.104.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
@@ -21282,12 +21282,12 @@ function safeUrl(url, images = false, strict = false) {
21282
21282
  if (strict) return /^https:\/\//i.test(url);
21283
21283
  return /^https?:\/\//.test(url) || !images && /^mailto:/.test(url) || images && /^data:image\/(png|jpeg|gif|webp|svg\+xml)[;,]/.test(url);
21284
21284
  }
21285
- function link(url, title, label, strict) {
21286
- return safeUrl(url, false, strict) ? b`<a href=${url} title=${title ?? A} target="_blank" rel="noopener noreferrer">${label}</a>` : b`${label}`;
21285
+ function link(url, title2, label, strict) {
21286
+ return safeUrl(url, false, strict) ? b`<a href=${url} title=${title2 ?? A} target="_blank" rel="noopener noreferrer">${label}</a>` : b`${label}`;
21287
21287
  }
21288
- function image(url, title, alt, strict) {
21289
- if (strict) return link(url, title, alt || url, true);
21290
- return safeUrl(url, true) ? b`<img src=${url} alt=${alt} title=${title ?? A} />` : alt;
21288
+ function image(url, title2, alt, strict) {
21289
+ if (strict) return link(url, title2, alt || url, true);
21290
+ return safeUrl(url, true) ? b`<img src=${url} alt=${alt} title=${title2 ?? A} />` : alt;
21291
21291
  }
21292
21292
  function inline3(node2, context) {
21293
21293
  return node2.children.map((child) => phrasing(child, context));
@@ -21868,11 +21868,11 @@ function errorCard(item2, handlers) {
21868
21868
  const resolved = login?.state === "connected";
21869
21869
  const signing = login?.state === "signing-in" && login.window;
21870
21870
  const text5 = resolved ? signedIn : signing ? signInText(login.waited) : item2.text;
21871
- const title = resolved && login.provider ? `Signed in to ${login.provider} again.` : item2.title;
21871
+ const title2 = resolved && login.provider ? `Signed in to ${login.provider} again.` : item2.title;
21872
21872
  const failure2 = login?.state === "idle" ? login.error : void 0;
21873
21873
  return b`<div class="error-card" role=${resolved ? A : "alert"} aria-atomic=${resolved ? A : "false"} data-id=${id || A} data-login=${login?.state ?? A}>
21874
21874
  ${resolved ? b`<swc-icon-info-circle class="icon" size="s" aria-hidden="true"></swc-icon-info-circle>` : b`<swc-icon-alert-diamond class="icon" size="s" aria-hidden="true"></swc-icon-alert-diamond>`}
21875
- ${resolved ? A : b`<span class="sr">Error: </span>`}<span class="lead">${title}</span>
21875
+ ${resolved ? A : b`<span class="sr">Error: </span>`}<span class="lead">${title2}</span>
21876
21876
  ${text5 ? b`<span class="detail" role=${login ? "status" : A}>${text5}</span>` : A}
21877
21877
  ${fix ? b`<div class="fix" aria-live="off">${fixButton(fix, item2, handlers, login)}</div>` : A}
21878
21878
  ${signing ? signInDetails(item2.account, login.signIn, login.copied, (code3) => handlers.copySignIn?.(item2.account, id, code3), "s") : A}
@@ -22187,8 +22187,8 @@ function attachment(item2) {
22187
22187
  <span slot="subtitle" class="size">${detail}</span>
22188
22188
  </swc-user-message>`;
22189
22189
  }
22190
- function when(at, title = "") {
22191
- return b`<time class="when" datetime=${new Date(at).toISOString()} title=${title || A}>${time(at)}</time>`;
22190
+ function when(at, title2 = "") {
22191
+ return b`<time class="when" datetime=${new Date(at).toISOString()} title=${title2 || A}>${time(at)}</time>`;
22192
22192
  }
22193
22193
  function unseen(at) {
22194
22194
  return b`<time class="sr" datetime=${new Date(at).toISOString()}>${time(at)}</time>`;
@@ -22324,12 +22324,12 @@ var ended = /* @__PURE__ */ new Set([
22324
22324
  function system(message, handlers) {
22325
22325
  if (message.kind === "compaction") {
22326
22326
  const failed2 = message.state === "fallback" || message.state === "discarded";
22327
- const title = message.title ?? compactionTitles[message.state ?? "summarized"];
22327
+ const title2 = message.title ?? compactionTitles[message.state ?? "summarized"];
22328
22328
  return event(
22329
- title,
22329
+ title2,
22330
22330
  b`<div class="marker" role="status" data-id=${message.id} data-state=${message.state ?? "summarized"}>
22331
22331
  <span class="line"></span>
22332
- <span class="marker-text">${failed2 ? b`<swc-icon-alert-diamond class="fault" size="xs" aria-hidden="true"></swc-icon-alert-diamond>` : A}${title}${message.state === "summarizing" ? b`<swc-progress-circle size="s" label="Summarizing"></swc-progress-circle>` : A}${message.text ? b`<span class="sr">. ${message.text}</span>` : A}</span>
22332
+ <span class="marker-text">${failed2 ? b`<swc-icon-alert-diamond class="fault" size="xs" aria-hidden="true"></swc-icon-alert-diamond>` : A}${title2}${message.state === "summarizing" ? b`<swc-progress-circle size="s" label="Summarizing"></swc-progress-circle>` : A}${message.text ? b`<span class="sr">. ${message.text}</span>` : A}</span>
22333
22333
  <span class="line"></span>
22334
22334
  </div>`
22335
22335
  );
@@ -24000,7 +24000,7 @@ var SliccComposer = class extends ThemedElement {
24000
24000
  padding: var(--swc-spacing-50) var(--swc-spacing-50) var(--swc-spacing-50) var(--swc-spacing-200);
24001
24001
  border-radius: var(--swc-corner-radius-medium-default);
24002
24002
  background: var(--swc-neutral-subtle-background-color-default);
24003
- border: var(--swc-border-width-100) dashed var(--swc-gray-300);
24003
+ border: var(--swc-border-width-100) dashed var(--swc-neutral-visual-color);
24004
24004
  color: var(--swc-neutral-content-color-default);
24005
24005
  }
24006
24006
  .hold {
@@ -24858,7 +24858,7 @@ ${this.value}` : text5;
24858
24858
  <swc-button size="s" variant="accent" data-action="share-secret" ?pending=${this.sharing} @click=${(event2) => event2.currentTarget.closest("form")?.requestSubmit()}>Share</swc-button>
24859
24859
  </form>`;
24860
24860
  }
24861
- const title = {
24861
+ const title2 = {
24862
24862
  command: "Commands",
24863
24863
  argument: "Options",
24864
24864
  mention: "Mention",
@@ -24882,7 +24882,7 @@ ${this.value}` : text5;
24882
24882
  if (last && last.group === item2.group) last.entries.push([item2, index2]);
24883
24883
  else sections2.push({ group: item2.group, entries: [[item2, index2]] });
24884
24884
  });
24885
- return b`<div class="popup" role="listbox" aria-label=${title} data-kind=${popup2.kind}>
24885
+ return b`<div class="popup" role="listbox" aria-label=${title2} data-kind=${popup2.kind}>
24886
24886
  ${popup2.items.length ? sections2.map(
24887
24887
  ({ group, entries }) => group ? b`<div class="section" role="group" aria-label=${group} data-group=${group}>
24888
24888
  <div class="heading" aria-hidden="true">${group}</div>
@@ -25533,6 +25533,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
25533
25533
  globalThis.addEventListener("keydown", this.#escape, true);
25534
25534
  };
25535
25535
  #leaving;
25536
+ #probed = null;
25536
25537
  #leave = (event2) => {
25537
25538
  const to = event2.relatedTarget;
25538
25539
  if (to instanceof Node && this.contains(to)) return;
@@ -26038,6 +26039,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
26038
26039
  }
26039
26040
  connectedCallback() {
26040
26041
  super.connectedCallback();
26042
+ this.#probed = null;
26041
26043
  globalThis.addEventListener("pointerup", this.#release, true);
26042
26044
  globalThis.addEventListener("pointercancel", this.#release, true);
26043
26045
  if (this.hasUpdated) this.#observe();
@@ -26298,6 +26300,9 @@ var SliccChat = class _SliccChat extends ThemedElement {
26298
26300
  this.model.agent.clear(agent.id);
26299
26301
  this.renderRoot.querySelector("slicc-composer")?.focus();
26300
26302
  }
26303
+ #agentless() {
26304
+ return this.model?.agent.starting?.() ? b`<swc-status-light size="s" variant="neutral" data-starting>Starting…</swc-status-light>` : b`<span>No agent</span>`;
26305
+ }
26301
26306
  #meta(agent, empty5) {
26302
26307
  const model = this.model;
26303
26308
  const fill2 = Math.round(agent.contextFill * 100);
@@ -26343,10 +26348,15 @@ var SliccChat = class _SliccChat extends ThemedElement {
26343
26348
  this.#all = false;
26344
26349
  this.#details.clear();
26345
26350
  }
26351
+ #probe() {
26352
+ if (this.#handlers.surface || this.#probed === this.color) return;
26353
+ this.#probed = this.color;
26354
+ this.#handlers.surface = readSurface(this.renderRoot);
26355
+ }
26346
26356
  render() {
26347
26357
  this.#handlers.color = this.color;
26348
26358
  this.#handlers.model = this.model ?? null;
26349
- this.#handlers.surface ??= readSurface(this.renderRoot);
26359
+ this.#probe();
26350
26360
  const agent = this.#agent();
26351
26361
  this.#switched(agent);
26352
26362
  const watch2 = watchOnly(this.model);
@@ -26361,7 +26371,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
26361
26371
  if (!this.behind) this.#mark = count2;
26362
26372
  return b`
26363
26373
  <header ?data-compact=${this.compact}>
26364
- ${agent ? this.#meta(agent, !messages.length) : b`<span>No agent</span>`}
26374
+ ${agent ? this.#meta(agent, !messages.length) : this.#agentless()}
26365
26375
  </header>
26366
26376
  <slicc-notices .model=${this.model}></slicc-notices>
26367
26377
  ${this.#asks(asks)}
@@ -27620,8 +27630,8 @@ function agentTitle(model, agent) {
27620
27630
  function twinned(name, id, rows2) {
27621
27631
  return rows2.some((row) => row.id !== id && row.name === name);
27622
27632
  }
27623
- function withTitle(name, title) {
27624
- return `${name} (${short(title) || untitled.toLowerCase()})`;
27633
+ function withTitle(name, title2) {
27634
+ return `${name} (${short(title2) || untitled.toLowerCase()})`;
27625
27635
  }
27626
27636
  function coneLabel(model, agent) {
27627
27637
  const cones = model.agent.list().filter((other) => other.kind === "cone");
@@ -27633,9 +27643,9 @@ function watchTitles(model, update) {
27633
27643
  const check3 = (id) => {
27634
27644
  const agent = model.agent.list().find((candidate) => candidate.id === id);
27635
27645
  if (!agent) return;
27636
- const title = agentTitle(model, agent);
27637
- if (seen.get(id) === title) return;
27638
- seen.set(id, title);
27646
+ const title2 = agentTitle(model, agent);
27647
+ if (seen.get(id) === title2) return;
27648
+ seen.set(id, title2);
27639
27649
  update();
27640
27650
  };
27641
27651
  const stops = [
@@ -28510,6 +28520,11 @@ var SliccAgents = class extends ModelElement {
28510
28520
  min-block-size: 0;
28511
28521
  overflow-y: auto;
28512
28522
  }
28523
+ .note {
28524
+ margin: 0;
28525
+ padding: var(--swc-spacing-400);
28526
+ color: var(--swc-neutral-subdued-content-color-default);
28527
+ }
28513
28528
  .actions {
28514
28529
  display: flex;
28515
28530
  padding: var(--swc-spacing-75) var(--swc-spacing-100);
@@ -28736,6 +28751,7 @@ var SliccAgents = class extends ModelElement {
28736
28751
  this.#reveal(model);
28737
28752
  return [
28738
28753
  model.agent.on("agents", () => this.requestUpdate()),
28754
+ ...model.agent.starting ? [model.agent.on("starting", () => this.requestUpdate())] : [],
28739
28755
  model.agent.on("active", () => {
28740
28756
  this.#reveal(model);
28741
28757
  this.requestUpdate();
@@ -28930,7 +28946,7 @@ var SliccAgents = class extends ModelElement {
28930
28946
  const current = agent.id === anchor;
28931
28947
  const error = this.errors[agent.id];
28932
28948
  const model = this.model;
28933
- const title = agentTitle(model, agent);
28949
+ const title2 = agentTitle(model, agent);
28934
28950
  const scoops = this.#scoops(agent);
28935
28951
  const open = this.#expanded.has(agent.id);
28936
28952
  const unread = selected ? 0 : agent.unread;
@@ -28958,7 +28974,7 @@ var SliccAgents = class extends ModelElement {
28958
28974
  <span class="name">${agent.name}</span>
28959
28975
  </div>
28960
28976
  ${fillShown(agent.contextFill) ? b`<span class="fill" data-variant=${meterVariant2(agent.contextFill)}>${percent(agent.contextFill)}</span>` : A}
28961
- <span class="title"><span class="state">${statusLabel[agent.status]}</span> · ${title || untitled}</span>
28977
+ <span class="title"><span class="state">${statusLabel[agent.status]}</span> · ${title2 || untitled}</span>
28962
28978
  ${this.#ribbon(scoops)}
28963
28979
  ${this.#dropButton(agent, selected)}
28964
28980
  ${this.#deleteButton(agent, selected)}
@@ -28985,6 +29001,8 @@ var SliccAgents = class extends ModelElement {
28985
29001
  }
28986
29002
  render() {
28987
29003
  const list6 = this.model?.agent.list() ?? [];
29004
+ if (!list6.length && this.model?.agent.starting?.())
29005
+ return b`<div class="list"><p class="note" data-empty="starting">The agent shows up here once it starts.</p></div>`;
28988
29006
  const active = this.model?.agent.active() ?? "";
28989
29007
  const errors = Object.values(this.errors);
28990
29008
  const rows2 = ordered(list6).filter(
@@ -29496,13 +29514,13 @@ var SliccGuestInvite = class extends i2 {
29496
29514
  this.remove();
29497
29515
  if (this.trigger?.isConnected) this.trigger.focus();
29498
29516
  }
29499
- #gate(field, title, value) {
29517
+ #gate(field, title2, value) {
29500
29518
  const options2 = this.#options(field, this.#current);
29501
29519
  const chosen = options2.find((option2) => option2.value === value);
29502
29520
  const id = `guest-${field}`;
29503
29521
  return b`<div class="field">
29504
- <sp-field-label for=${id} size="m">${title}</sp-field-label>
29505
- <sp-picker id=${id} size="m" label=${title} data-action=${`guest-${field}`} .value=${l(value)} ?disabled=${this.pending} @change=${(event2) => {
29522
+ <sp-field-label for=${id} size="m">${title2}</sp-field-label>
29523
+ <sp-picker id=${id} size="m" label=${title2} data-action=${`guest-${field}`} .value=${l(value)} ?disabled=${this.pending} @change=${(event2) => {
29506
29524
  this[field] = this.#pick(event2);
29507
29525
  }}>
29508
29526
  ${options2.map((option2) => b`<sp-menu-item value=${option2.value}>${option2.label}<span slot="description">${option2.description}</span></sp-menu-item>`)}
@@ -30480,7 +30498,7 @@ function terminalsText(count2) {
30480
30498
  var again = "Unlinking it, or a new certificate on it, turns this off again.";
30481
30499
  function accessConfirm(device, key2) {
30482
30500
  const name = device.name;
30483
- const [title, body4] = {
30501
+ const [title2, body4] = {
30484
30502
  follow: [
30485
30503
  `Let ${name} follow this SLICC?`,
30486
30504
  "It sees the agent\u2019s conversations live. To let it send prompts or open terminals, turn on Control or Terminal for it afterwards."
@@ -30498,7 +30516,7 @@ function accessConfirm(device, key2) {
30498
30516
  "Terminal lets it open shells on this SLICC as root: it can run any command and read or change every file."
30499
30517
  ]
30500
30518
  }[key2];
30501
- return { title, body: `${body4} ${again}`, action: "Allow", variant: "confirmation" };
30519
+ return { title: title2, body: `${body4} ${again}`, action: "Allow", variant: "confirmation" };
30502
30520
  }
30503
30521
  function say(devices, one3, many) {
30504
30522
  if (!devices.length) return [];
@@ -32440,7 +32458,7 @@ function state(info) {
32440
32458
  function table2(rows2) {
32441
32459
  const lines = [["ID", "TITLE", "STATE"], ...rows2.map((row) => [row.id, row.title, state(row)])];
32442
32460
  const widths = [0, 1].map((column) => Math.max(...lines.map((line) => line[column].length)));
32443
- return lines.map(([id, title, shown4]) => `${id.padEnd(widths[0])} ${title.padEnd(widths[1])} ${shown4}`).join("\n");
32461
+ return lines.map(([id, title2, shown4]) => `${id.padEnd(widths[0])} ${title2.padEnd(widths[1])} ${shown4}`).join("\n");
32444
32462
  }
32445
32463
  var done = (result, note = "") => result.code === 0 ? { stdout: `${result.message}${note}
32446
32464
  `, stderr: "", code: 0 } : { stdout: "", stderr: `panel: ${result.message}
@@ -38039,9 +38057,22 @@ function guestAlwaysHint(approval) {
38039
38057
  function guestAsking(approval) {
38040
38058
  return approval.kind === "guest-message" ? `${approval.requester.name} wants to send this to ${approval.agentName ?? "this cone"}:` : `${approval.agentName ?? "This cone"} wants to run ${approval.tool} for ${approval.requester.name}:`;
38041
38059
  }
38060
+ function trayTitle(approval) {
38061
+ if (approval.op === "url") return "Share this seven\u2019s join URL?";
38062
+ if (approval.op === "rotate") return "Make a new join URL?";
38063
+ return approval.device ? `Unlink ${approval.device.name}?` : "Unlink a device?";
38064
+ }
38065
+ function trayAsking(approval) {
38066
+ const { name } = approval.requester;
38067
+ if (approval.op === "url")
38068
+ return `${name} wants this seven\u2019s join URL. Anyone with it can ask to link to this seven.`;
38069
+ if (approval.op === "rotate")
38070
+ return `${name} wants a new join URL. Linked devices move to it, and the old one stops working.`;
38071
+ return `${name} wants to unlink ${approval.device?.name ?? "a device"} from this seven.`;
38072
+ }
38042
38073
  function approved(approval) {
38043
38074
  if (approval.kind === "sudo") return sudo(approval);
38044
- if (approval.kind === "guest-message") return "";
38075
+ if (approval.kind === "guest-message" || approval.kind === "tray") return "";
38045
38076
  if (approval.summary.trim()) return approval.summary;
38046
38077
  return approval.args?.trim() ? `${approval.tool}
38047
38078
  ${approval.args}` : "";
@@ -38061,7 +38092,7 @@ function rulesOf(approval) {
38061
38092
  return approval.kind === "sudo" ? secretRules(approval.command, approval.cwd) : clear;
38062
38093
  }
38063
38094
  function waiting2(model, now) {
38064
- return [...model?.approvals?.list() ?? []].filter((approval) => approval.expiresAt > now).sort((a23, b13) => a23.createdAt - b13.createdAt);
38095
+ return [...model?.approvals?.list() ?? []].filter((approval) => approval.expiresAt > now && Object.hasOwn(titles, approval.kind)).sort((a23, b13) => a23.createdAt - b13.createdAt);
38065
38096
  }
38066
38097
  var titles = {
38067
38098
  sudo: {
@@ -38078,8 +38109,16 @@ var titles = {
38078
38109
  ask: "Allow a guest\u2019s tool call?",
38079
38110
  elsewhere: "Answered elsewhere",
38080
38111
  expired: "Guest tool call timed out"
38112
+ },
38113
+ tray: {
38114
+ ask: "",
38115
+ elsewhere: "Answered in another tab",
38116
+ expired: "Tray request timed out"
38081
38117
  }
38082
38118
  };
38119
+ function title(approval) {
38120
+ return approval.kind === "tray" ? trayTitle(approval) : titles[approval.kind].ask;
38121
+ }
38083
38122
  function gone(reason) {
38084
38123
  return reason === "expired" ? "expired" : "elsewhere";
38085
38124
  }
@@ -38271,7 +38310,7 @@ var SliccApprovals = class extends ModelElement {
38271
38310
  if (!port?.decide || this.busy || decision2 !== "deny" && (!this.#armed || !this.#whole(approval)))
38272
38311
  return;
38273
38312
  const verdict = rulesOf(approval);
38274
- const always = approval.kind === "sudo" || approval.always;
38313
+ const always = approval.kind === "sudo" || approval.kind !== "tray" && approval.always;
38275
38314
  if (decision2 === "always" && (!always || verdict.certain || verdict.maybe)) return;
38276
38315
  this.busy = decision2;
38277
38316
  this.failure = null;
@@ -38387,6 +38426,7 @@ var SliccApprovals = class extends ModelElement {
38387
38426
  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}>${text5}${pending ? b`<span class="end" data-end=${id}></span>` : A}</span></pre>${toggle}`;
38388
38427
  }
38389
38428
  #request(approval, pending = false) {
38429
+ if (approval.kind === "tray") return b`<p id="asking">${trayAsking(approval)}</p>`;
38390
38430
  if (approval.kind === "sudo")
38391
38431
  return b`<p id="asking">${asking(approval)}:</p>
38392
38432
  ${this.#command(approval, pending)}`;
@@ -38399,7 +38439,7 @@ var SliccApprovals = class extends ModelElement {
38399
38439
  ${files.length ? b`<ul class="files" data-attachments>${files.map((file) => b`<li>${file.name} · ${file.mimeType} · ${size3(file.size)}</li>`)}</ul>` : A}`;
38400
38440
  }
38401
38441
  #verdict(approval) {
38402
- const verdict = approval.kind === "sudo" ? void 0 : approval.verdict;
38442
+ const verdict = approval.kind === "sudo" || approval.kind === "tray" ? void 0 : approval.verdict;
38403
38443
  return verdict ? b`<p class="verdict" data-verdict=${verdict.decision}>${verdict.decision === "unsure" ? "The automatic check wasn\u2019t sure" : `The automatic check would ${verdict.decision} this`}: ${verdict.reason}</p>` : A;
38404
38444
  }
38405
38445
  #actions(approval, rejected, always) {
@@ -38431,14 +38471,14 @@ var SliccApprovals = class extends ModelElement {
38431
38471
  const failure2 = this.failure?.id === approval.id ? this.failure.message : "";
38432
38472
  const verdict = rulesOf(approval);
38433
38473
  const rules = verdict.certain ?? verdict.maybe;
38434
- const always = approval.always && !rules;
38474
+ const always = approval.kind !== "tray" && approval.always && !rules;
38435
38475
  const gate = this.#gate(approval);
38436
38476
  const hint2 = always && this.#whole(approval) ? hintOf(approval) : "";
38437
38477
  return this.#dialog(
38438
38478
  approval,
38439
38479
  approval.id,
38440
38480
  b`<sp-alert-dialog variant="warning" data-approval-kind=${approval.kind}>
38441
- <h2 id="title" slot="heading">${titles[approval.kind].ask}</h2>
38481
+ <h2 id="title" slot="heading">${title(approval)}</h2>
38442
38482
  ${this.#request(approval, true)}
38443
38483
  ${this.#verdict(approval)}
38444
38484
  ${approval.kind === "sudo" && approval.cwd ? b`<p class="cwd">In ${approval.cwd}</p>` : A}
@@ -39916,6 +39956,7 @@ var SliccChanges = class extends ModelElement {
39916
39956
  subscribe(model) {
39917
39957
  return [
39918
39958
  changesOf(model).on("changes", () => this.requestUpdate()),
39959
+ model.agent.on("agents", () => this.requestUpdate()),
39919
39960
  ...onWatch(model, () => this.requestUpdate())
39920
39961
  ];
39921
39962
  }
@@ -39944,8 +39985,8 @@ var SliccChanges = class extends ModelElement {
39944
39985
  return;
39945
39986
  }
39946
39987
  const count2 = changes2.length;
39947
- const title = `Revert ${count2} ${count2 === 1 ? "change" : "changes"}?`;
39948
- if (await confirm({ title, body: lost(changes2), action: "Revert all" }) && !watchOnly(this.model))
39988
+ const title2 = `Revert ${count2} ${count2 === 1 ? "change" : "changes"}?`;
39989
+ if (await confirm({ title: title2, body: lost(changes2), action: "Revert all" }) && !watchOnly(this.model))
39949
39990
  this.error = await revertPaths(
39950
39991
  port,
39951
39992
  changes2.map((change) => change.path)
@@ -40111,6 +40152,7 @@ var SliccDiffPanel = class extends ThemedElement {
40111
40152
  return [
40112
40153
  ...super.subscribe(model),
40113
40154
  changesOf(model).on("changes", () => this.requestUpdate()),
40155
+ model.agent.on("agents", () => this.requestUpdate()),
40114
40156
  ...onWatch(model, () => this.requestUpdate())
40115
40157
  ];
40116
40158
  }
@@ -40705,8 +40747,8 @@ var SliccMemory = class extends ModelElement {
40705
40747
  }
40706
40748
  async #forget(memory, trigger2) {
40707
40749
  const body4 = "Agents won\u2019t remember this anymore. You can\u2019t undo this.";
40708
- const title = `Forget \u201C${memory.title}\u201D?`;
40709
- if (await confirm({ title, body: body4, action: "Forget", variant: "destructive", trigger: trigger2 }))
40750
+ const title2 = `Forget \u201C${memory.title}\u201D?`;
40751
+ if (await confirm({ title: title2, body: body4, action: "Forget", variant: "destructive", trigger: trigger2 }))
40710
40752
  this.model?.memory.remove(memory.id);
40711
40753
  }
40712
40754
  #scopeOf(id) {
@@ -40985,6 +41027,15 @@ var SliccNotices = class extends ModelElement {
40985
41027
  </div>`;
40986
41028
  }
40987
41029
  #approval(approval) {
41030
+ if (approval.kind === "tray")
41031
+ return b`<div class="notice" role="status" data-approval-notice=${approval.id} data-approval-kind="tray" data-tone="warning">
41032
+ <swc-icon-alert-triangle></swc-icon-alert-triangle>
41033
+ <div class="text">
41034
+ <span class="title">Waiting for tray approval</span>
41035
+ <p>${trayAsking(approval)}</p>
41036
+ <p>It waits for the owner's approval. Denied automatically at ${deadline(approval.expiresAt)}.</p>
41037
+ </div>
41038
+ </div>`;
40988
41039
  if (approval.kind !== "sudo")
40989
41040
  return b`<div class="notice" role="status" data-approval-notice=${approval.id} data-approval-kind=${approval.kind} data-tone="warning">
40990
41041
  <swc-icon-alert-triangle></swc-icon-alert-triangle>
@@ -41126,11 +41177,24 @@ function endpointsLine(entry, named2 = (provider) => provider) {
41126
41177
  );
41127
41178
  return b`${parts3.map((part2, index2) => b`${index2 ? ". " : ""}${part2}`)}`;
41128
41179
  }
41180
+ var sessionProtocols = {
41181
+ http1: "HTTP/1.1",
41182
+ smtp: "SMTP",
41183
+ pg: "Postgres"
41184
+ };
41185
+ var sessionTrust = {
41186
+ roots: "trusted by public roots",
41187
+ anchored: "trusted by its pinned anchor"
41188
+ };
41189
+ var sessionProtocol = (protocol) => Object.hasOwn(sessionProtocols, protocol) ? sessionProtocols[protocol] : protocol;
41190
+ var sessionTrusted = (verifiedBy) => verifiedBy && Object.hasOwn(sessionTrust, verifiedBy) ? `${sessionTrust[verifiedBy]}, ` : "";
41129
41191
  function auditLine(entry, devices, named2) {
41130
41192
  switch (entry.type) {
41131
41193
  case "inject":
41132
41194
  case "forward":
41133
41195
  return b`Sent to ${entry.domain}: <code>${entry.method} ${entry.path}</code>, through ${exitLabel(entry.exit, devices)}`;
41196
+ case "session":
41197
+ return b`Sent over ${sessionProtocol(entry.protocol)} to ${entry.domain}:${entry.port}, ${sessionTrusted(entry.verifiedBy)}through ${exitLabel(entry.exit, devices)}`;
41134
41198
  case "mcp":
41135
41199
  return b`Sent to the MCP server ${entry.server} at ${entry.domain}: <code>${entry.method} ${entry.path}</code>, through ${exitLabel(entry.exit, devices)}`;
41136
41200
  case "materialize":
@@ -43310,8 +43374,8 @@ var SliccSettings = class extends ThemedElement {
43310
43374
  const signIn = vaulted && account.auth !== "api-key" && account.group === "mcp";
43311
43375
  const stored2 = key2 || signIn ? vault : void 0;
43312
43376
  const body4 = `Agents can\u2019t use ${account.provider} until you connect it again.${key2 ? " You can restore its key from Removed in Secrets for 30 days." : ""}`;
43313
- const title = `Disconnect ${account.provider}?`;
43314
- if (!await confirm({ title, body: body4, action: "Disconnect", variant: "confirmation" })) return;
43377
+ const title2 = `Disconnect ${account.provider}?`;
43378
+ if (!await confirm({ title: title2, body: body4, action: "Disconnect", variant: "confirmation" })) return;
43315
43379
  clearValues(this.renderRoot);
43316
43380
  if (this.model !== model) return;
43317
43381
  const server = serverOf(account);
@@ -43460,8 +43524,8 @@ var SliccSettings = class extends ThemedElement {
43460
43524
  async #remove(account) {
43461
43525
  const model = this.model;
43462
43526
  const body4 = removeBodies[account.auth ?? ""] ?? "Its key is deleted from the vault. Models from it stop working.";
43463
- const title = `Remove ${account.provider}?`;
43464
- if (!await confirm({ title, body: body4, action: "Remove" })) return;
43527
+ const title2 = `Remove ${account.provider}?`;
43528
+ if (!await confirm({ title: title2, body: body4, action: "Remove" })) return;
43465
43529
  if (this.model !== model) return;
43466
43530
  clearValues(this.renderRoot);
43467
43531
  if (this.entering === account.id) this.entering = null;
@@ -55653,14 +55717,14 @@ function getIgnoreCaseMatchChars(char) {
55653
55717
  const set = /* @__PURE__ */ new Set();
55654
55718
  const lower2 = char.toLowerCase();
55655
55719
  const upper2 = lower2.toUpperCase();
55656
- const title = LowerToTitleCaseMap.get(lower2);
55720
+ const title2 = LowerToTitleCaseMap.get(lower2);
55657
55721
  const altLower = LowerToAlternativeLowerCaseMap.get(lower2);
55658
55722
  const altUpper = LowerToAlternativeUpperCaseMap.get(lower2);
55659
55723
  if ([...upper2].length === 1) {
55660
55724
  set.add(upper2);
55661
55725
  }
55662
55726
  altUpper && set.add(altUpper);
55663
- title && set.add(title);
55727
+ title2 && set.add(title2);
55664
55728
  set.add(lower2);
55665
55729
  altLower && set.add(altLower);
55666
55730
  return [...set];
@@ -72416,14 +72480,14 @@ function committedWhere(position2, target) {
72416
72480
  return position2 === "center" ? `docked into ${target}` : `split ${position2} of ${target}`;
72417
72481
  }
72418
72482
  var DEFAULT_MESSAGES = {
72419
- panelOpened: (title) => `${title} opened`,
72420
- panelClosed: (title) => `${title} closed`,
72421
- groupMaximized: (title) => `${title} maximized`,
72422
- groupRestored: (title) => `${title} restored`,
72423
- groupFloated: (title) => `${title} floated`,
72424
- groupDocked: (title) => `${title} docked`,
72425
- groupPoppedOut: (title) => `${title} opened in a new window`,
72426
- closeTab: (title) => `Close ${title}`,
72483
+ panelOpened: (title2) => `${title2} opened`,
72484
+ panelClosed: (title2) => `${title2} closed`,
72485
+ groupMaximized: (title2) => `${title2} maximized`,
72486
+ groupRestored: (title2) => `${title2} restored`,
72487
+ groupFloated: (title2) => `${title2} floated`,
72488
+ groupDocked: (title2) => `${title2} docked`,
72489
+ groupPoppedOut: (title2) => `${title2} opened in a new window`,
72490
+ closeTab: (title2) => `Close ${title2}`,
72427
72491
  closeTabPlain: () => `Close`,
72428
72492
  movePickTarget: (source, target, current, total) => `Moving ${source}. Target ${target}, ${current} of ${total}. Enter to choose where, Escape to cancel.`,
72429
72493
  movePickEdge: (position2, target) => `${edgeWhere(position2, target)}. Arrows to change, Enter to confirm, Escape to go back.`,
@@ -79706,8 +79770,8 @@ var DockviewGroupPanelModel = class extends CompositeDisposable {
79706
79770
  /** Label the group region with its active panel's title (the WAI-ARIA region name). */
79707
79771
  updateAccessibleLabel() {
79708
79772
  var _this$_activePanel5;
79709
- const title = (_this$_activePanel5 = this._activePanel) === null || _this$_activePanel5 === void 0 ? void 0 : _this$_activePanel5.title;
79710
- if (title) this.container.setAttribute("aria-label", title);
79773
+ const title2 = (_this$_activePanel5 = this._activePanel) === null || _this$_activePanel5 === void 0 ? void 0 : _this$_activePanel5.title;
79774
+ if (title2) this.container.setAttribute("aria-label", title2);
79711
79775
  else this.container.removeAttribute("aria-label");
79712
79776
  }
79713
79777
  updateMru(panel) {
@@ -80308,8 +80372,8 @@ var DockviewPanelApiImpl = class extends GridviewPanelApiImpl {
80308
80372
  });
80309
80373
  });
80310
80374
  }
80311
- setTitle(title) {
80312
- this.panel.setTitle(title);
80375
+ setTitle(title2) {
80376
+ this.panel.setTitle(title2);
80313
80377
  }
80314
80378
  setPinned(pinned) {
80315
80379
  this.accessor.setPanelPinned(this.panel, pinned);
@@ -80446,11 +80510,11 @@ var DockviewPanel = class extends CompositeDisposable {
80446
80510
  pinned: this._pinned ? true : void 0
80447
80511
  };
80448
80512
  }
80449
- setTitle(title) {
80450
- if (title !== this.title) {
80451
- this._title = title;
80452
- this.view.setTitle(title);
80453
- this.api._onDidTitleChange.fire({ title });
80513
+ setTitle(title2) {
80514
+ if (title2 !== this.title) {
80515
+ this._title = title2;
80516
+ this.view.setTitle(title2);
80517
+ this.api._onDidTitleChange.fire({ title: title2 });
80454
80518
  }
80455
80519
  }
80456
80520
  /**
@@ -80591,8 +80655,8 @@ var DockviewPanelModel = class {
80591
80655
  this.content.init(params);
80592
80656
  this.tab.init(_objectSpread2(_objectSpread2({}, params), {}, { tabLocation: "header" }));
80593
80657
  }
80594
- setTitle(title) {
80595
- if (this._params) this._params.title = title;
80658
+ setTitle(title2) {
80659
+ if (this._params) this._params.title = title2;
80596
80660
  }
80597
80661
  layout(width, height) {
80598
80662
  var _this$content$layout, _this$content;
@@ -80639,7 +80703,7 @@ var DefaultDockviewDeserialzier = class {
80639
80703
  var _panelData$contentCom, _viewData$tab, _this$accessor$option;
80640
80704
  const panelId = panelData.id;
80641
80705
  const params = panelData.params;
80642
- const title = panelData.title;
80706
+ const title2 = panelData.title;
80643
80707
  const viewData = panelData.view;
80644
80708
  const contentComponent = viewData ? viewData.content.id : (_panelData$contentCom = panelData.contentComponent) !== null && _panelData$contentCom !== void 0 ? _panelData$contentCom : "unknown";
80645
80709
  const tabComponent = viewData ? (_viewData$tab = viewData.tab) === null || _viewData$tab === void 0 ? void 0 : _viewData$tab.id : panelData.tabComponent;
@@ -80652,7 +80716,7 @@ var DefaultDockviewDeserialzier = class {
80652
80716
  maximumHeight: panelData.maximumHeight
80653
80717
  });
80654
80718
  panel.init({
80655
- title: title !== null && title !== void 0 ? title : panelId,
80719
+ title: title2 !== null && title2 !== void 0 ? title2 : panelId,
80656
80720
  params: params !== null && params !== void 0 ? params : {}
80657
80721
  });
80658
80722
  if (panelData.pinned && ((_this$accessor$option = this.accessor.options.pinnedTabs) === null || _this$accessor$option === void 0 ? void 0 : _this$accessor$option.enabled)) panel.setPinned(true);
@@ -81339,8 +81403,8 @@ var FloatingGroupService = class {
81339
81403
  })());
81340
81404
  const updateDialogLabel = () => {
81341
81405
  var _group$activePanel;
81342
- const title = (_group$activePanel = group.activePanel) === null || _group$activePanel === void 0 ? void 0 : _group$activePanel.title;
81343
- if (title) overlay.element.setAttribute("aria-label", title);
81406
+ const title2 = (_group$activePanel = group.activePanel) === null || _group$activePanel === void 0 ? void 0 : _group$activePanel.title;
81407
+ if (title2) overlay.element.setAttribute("aria-label", title2);
81344
81408
  else overlay.element.removeAttribute("aria-label");
81345
81409
  };
81346
81410
  updateDialogLabel();
@@ -86541,7 +86605,7 @@ var SliccTab = class {
86541
86605
  this.#close.append(cross);
86542
86606
  this.element.append(this.#label, this.#close);
86543
86607
  }
86544
- init({ api, containerApi, title }) {
86608
+ init({ api, containerApi, title: title2 }) {
86545
86609
  const render2 = (text5) => {
86546
86610
  this.#label.textContent = text5;
86547
86611
  this.#close.setAttribute(
@@ -86549,7 +86613,7 @@ var SliccTab = class {
86549
86613
  text5 ? containerApi.messages.closeTab(text5) : containerApi.messages.closeTabPlain()
86550
86614
  );
86551
86615
  };
86552
- render2(title);
86616
+ render2(title2);
86553
86617
  const pointerdown = (event2) => event2.preventDefault();
86554
86618
  const click = (event2) => {
86555
86619
  if (event2.defaultPrevented) return;
@@ -86559,7 +86623,7 @@ var SliccTab = class {
86559
86623
  this.#close.addEventListener("pointerdown", pointerdown);
86560
86624
  this.#close.addEventListener("click", click);
86561
86625
  this.#disposables.push(
86562
- api.onDidTitleChange(({ title: title2 }) => render2(title2)),
86626
+ api.onDidTitleChange(({ title: title3 }) => render2(title3)),
86563
86627
  {
86564
86628
  dispose: () => {
86565
86629
  this.#close.removeEventListener("pointerdown", pointerdown);