@ai-ecoverse/slicc-spectrum 1.111.4 → 1.112.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
@@ -10617,8 +10617,8 @@ var Ends = class {
10617
10617
  this.#observer.disconnect();
10618
10618
  }
10619
10619
  };
10620
- function fullCommand(shown4, toggle) {
10621
- return b`<swc-action-button size="s" quiet class="full-command" data-action="full-command" data-shown=${shown4 ? "" : A} aria-expanded=${shown4 ? "true" : "false"} @click=${toggle}><swc-icon-chevron-down slot="icon" class="chevron" aria-hidden="true"></swc-icon-chevron-down>${shown4 ? "Hide the full command" : "Show the full command"}</swc-action-button>`;
10620
+ function fullCommand(shown5, toggle) {
10621
+ return b`<swc-action-button size="s" quiet class="full-command" data-action="full-command" data-shown=${shown5 ? "" : A} aria-expanded=${shown5 ? "true" : "false"} @click=${toggle}><swc-icon-chevron-down slot="icon" class="chevron" aria-hidden="true"></swc-icon-chevron-down>${shown5 ? "Hide the full command" : "Show the full command"}</swc-action-button>`;
10622
10622
  }
10623
10623
 
10624
10624
  // node_modules/@adobe/spectrum-wc/dist/components/ui-icons/ui-icons.types.js
@@ -33402,9 +33402,9 @@ function stopSigningIn(event2, handlers, account, id) {
33402
33402
  function fixButton(fix, item2, handlers, login) {
33403
33403
  const id = item2.id ?? "";
33404
33404
  const signing = login?.state === "signing-in";
33405
- const shown4 = login?.state === "connected" ? "retry" : fix;
33405
+ const shown5 = login?.state === "connected" ? "retry" : fix;
33406
33406
  const cancel = signing && login.cancel;
33407
- return b`${cancel ? b`<swc-button size="s" variant="secondary" fill-style="outline" data-action="cancel-login" @click=${(event2) => stopSigningIn(event2, handlers, item2.account, id)}>Cancel</swc-button>` : A}<swc-button size="s" variant="secondary" fill-style="outline" data-action=${shown4} ?pending=${signing} ?disabled=${handlers.readOnly} @click=${() => handlers.action(shown4, item2.id, item2.account)}>${signing ? "Signing in\u2026" : actionLabel(shown4, handlers, id)}</swc-button>`;
33407
+ return b`${cancel ? b`<swc-button size="s" variant="secondary" fill-style="outline" data-action="cancel-login" @click=${(event2) => stopSigningIn(event2, handlers, item2.account, id)}>Cancel</swc-button>` : A}<swc-button size="s" variant="secondary" fill-style="outline" data-action=${shown5} ?pending=${signing} ?disabled=${handlers.readOnly} @click=${() => handlers.action(shown5, item2.id, item2.account)}>${signing ? "Signing in\u2026" : actionLabel(shown5, handlers, id)}</swc-button>`;
33408
33408
  }
33409
33409
  function errorCard(item2, handlers) {
33410
33410
  const id = item2.id ?? "";
@@ -33439,7 +33439,7 @@ function day(at) {
33439
33439
  }
33440
33440
  var stampGap = 2 * 6e4;
33441
33441
  function stamps(messages) {
33442
- const shown4 = /* @__PURE__ */ new Set();
33442
+ const shown5 = /* @__PURE__ */ new Set();
33443
33443
  let last = -Infinity;
33444
33444
  let seen = "";
33445
33445
  for (const message of messages) {
@@ -33449,10 +33449,10 @@ function stamps(messages) {
33449
33449
  last = -Infinity;
33450
33450
  }
33451
33451
  if (message.role === "system" || message.createdAt - last < stampGap) continue;
33452
- shown4.add(message.id);
33452
+ shown5.add(message.id);
33453
33453
  last = message.createdAt;
33454
33454
  }
33455
- return shown4;
33455
+ return shown5;
33456
33456
  }
33457
33457
  function size3(bytes) {
33458
33458
  if (bytes < 1024) return `${bytes} B`;
@@ -33712,10 +33712,10 @@ function toolOnly(message, showThinking) {
33712
33712
  if (message.role === "tool") return [message.tool];
33713
33713
  if (message.role !== "assistant") return null;
33714
33714
  if (message.parts.some((entry) => entry.type === "question")) return null;
33715
- const shown4 = message.parts.filter((entry) => !silent(entry, showThinking));
33716
- if (shown4.some((entry) => entry.type !== "tool")) return null;
33717
- if (!shown4.length && message.status !== "streaming") return null;
33718
- return shown4.map((entry) => entry.tool);
33715
+ const shown5 = message.parts.filter((entry) => !silent(entry, showThinking));
33716
+ if (shown5.some((entry) => entry.type !== "tool")) return null;
33717
+ if (!shown5.length && message.status !== "streaming") return null;
33718
+ return shown5.map((entry) => entry.tool);
33719
33719
  }
33720
33720
  var attachmentIcons = {
33721
33721
  image: b`<swc-icon-file slot="thumbnail" aria-hidden="true"></swc-icon-file>`,
@@ -34006,9 +34006,9 @@ function decision(message, handlers) {
34006
34006
  const settled4 = expired || guest;
34007
34007
  const { actions: actions2, command: command3 } = decide(message, handlers, settled4);
34008
34008
  const detail = settled4 ? void 0 : handlers.detail;
34009
- const shown4 = !!detail?.has(message.id);
34010
- 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;
34011
- 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=${settled4 ? A : ""} data-expired=${expired ? "" : A} data-detail=${shown4 ? "" : A} @click=${reveal} @keydown=${reveal}>
34009
+ const shown5 = !!detail?.has(message.id);
34010
+ const more = detail ? b`<swc-action-button size="s" quiet class="detail" data-action="ask-detail" aria-expanded=${shown5 ? "true" : "false"} accessible-label=${shown5 ? "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;
34011
+ 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=${settled4 ? A : ""} data-expired=${expired ? "" : A} data-detail=${shown5 ? "" : A} @click=${reveal} @keydown=${reveal}>
34012
34012
  <div class="decision" data-kind="approval">
34013
34013
  <div class="decision-head"><span class="who">${message.title}</span>${timer}${more}</div>
34014
34014
  <p class="decision-text">${message.text}</p>
@@ -34040,8 +34040,8 @@ function lickContent(message, body2, handlers) {
34040
34040
  const scoop = message.channel === "scoop-notify";
34041
34041
  const report = message.report;
34042
34042
  if (!scoop && !report) return b`<pre class="output">${body2}</pre>`;
34043
- const shown4 = !body2 ? A : scoop ? b`<div class="text">${markdown(body2)}</div>` : b`<pre class="output">${body2}</pre>`;
34044
- 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>`;
34043
+ const shown5 = !body2 ? A : scoop ? b`<div class="text">${markdown(body2)}</div>` : b`<pre class="output">${body2}</pre>`;
34044
+ return b`<div class="report">${shown5}${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>`;
34045
34045
  }
34046
34046
  function lick(message, handlers, stamp = true) {
34047
34047
  if (pendingApproval(message)) return decision(message, handlers);
@@ -36695,7 +36695,7 @@ var ModelFilter = class {
36695
36695
  items(options3) {
36696
36696
  if (options3.length <= searchable)
36697
36697
  return b`${options3.map((option2) => this.#item(option2, false))}`;
36698
- const shown4 = options3.filter((option2) => matchesModel(option2, this.#query));
36698
+ const shown5 = options3.filter((option2) => matchesModel(option2, this.#query));
36699
36699
  return b`<sp-search
36700
36700
  size="s"
36701
36701
  data-action="filter-models"
@@ -36707,8 +36707,8 @@ var ModelFilter = class {
36707
36707
  @submit=${(event2) => event2.preventDefault()}
36708
36708
  @keydown=${this.#key}
36709
36709
  ></sp-search>
36710
- ${options3.map((option2) => this.#item(option2, !shown4.includes(option2)))}
36711
- ${shown4.length ? A : b`<sp-menu-item disabled data-empty>No matching models</sp-menu-item>`}`;
36710
+ ${options3.map((option2) => this.#item(option2, !shown5.includes(option2)))}
36711
+ ${shown5.length ? A : b`<sp-menu-item disabled data-empty>No matching models</sp-menu-item>`}`;
36712
36712
  }
36713
36713
  #item(option2, hidden) {
36714
36714
  return b`<sp-menu-item value=${option2.id} ?hidden=${hidden}>${option2.label}<span slot="description">${option2.provider}</span></sp-menu-item>`;
@@ -37884,7 +37884,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
37884
37884
  #items(messages, agent) {
37885
37885
  const out = [];
37886
37886
  let previous3 = "";
37887
- let shown4;
37887
+ let shown5;
37888
37888
  const model = this.model;
37889
37889
  const last = messages.at(-1);
37890
37890
  const suggestion = last?.role === "assistant" && !agent.frozen && !watchOnly(model) && !model.seat && !model.agent.busy(agent.id) ? model.agent.suggestion(agent.id) : null;
@@ -37910,8 +37910,8 @@ var SliccChat = class _SliccChat extends ThemedElement {
37910
37910
  previous3 = label;
37911
37911
  }
37912
37912
  const next = message.role === "assistant" ? message.model : void 0;
37913
- const changed2 = !!next && next !== shown4;
37914
- if (changed2) shown4 = next;
37913
+ const changed2 = !!next && next !== shown5;
37914
+ if (changed2) shown5 = next;
37915
37915
  out.push([
37916
37916
  message.id,
37917
37917
  this.#message(
@@ -39814,12 +39814,12 @@ var SliccTray = class extends ModelElement {
39814
39814
  const title2 = provider ? budgetTitle(provider, budget.window) : "";
39815
39815
  const label = `${title2 || "Budget"} ${budget.percent}%`;
39816
39816
  const line = budgetLine(status2, budget);
39817
- const shown4 = provider ? b`<span>${providerOf(provider)}<span class="window"> ${budget.window}</span> ${budget.percent}%</span>` : label;
39817
+ const shown5 = provider ? b`<span>${providerOf(provider)}<span class="window"> ${budget.window}</span> ${budget.percent}%</span>` : label;
39818
39818
  return b`${this.#item(
39819
39819
  "usage",
39820
39820
  "monitor",
39821
39821
  `${label}. ${line}`,
39822
- b`<swc-status-light size="s" variant=${budgetVariant(budget.percent)}>${shown4}</swc-status-light>`,
39822
+ b`<swc-status-light size="s" variant=${budgetVariant(budget.percent)}>${shown5}</swc-status-light>`,
39823
39823
  () => this.#open("monitor")
39824
39824
  )}
39825
39825
  <swc-tooltip for="usage" placement="bottom">${title2 ? `${title2}. ${line}` : line}</swc-tooltip>`;
@@ -40886,8 +40886,8 @@ var SliccAgents = class extends ModelElement {
40886
40886
  const rows2 = ordered(list6).filter(
40887
40887
  (agent) => agent.kind === "cone" || this.#expanded.has(agent.parentId)
40888
40888
  );
40889
- const shown4 = rows2.find((agent) => agent.id === active);
40890
- const anchor = shown4 ? active : list6.find((agent) => agent.id === active)?.parentId ?? "";
40889
+ const shown5 = rows2.find((agent) => agent.id === active);
40890
+ const anchor = shown5 ? active : list6.find((agent) => agent.id === active)?.parentId ?? "";
40891
40891
  return b`<div class="list"><ul role="tree" aria-label="Cones and scoops" @keydown=${this.#keydown} @focusin=${this.#focusin} @focusout=${this.#focusout}>
40892
40892
  ${c(
40893
40893
  rows2,
@@ -44164,13 +44164,13 @@ function resolve(panels, raw, reachable2, cone) {
44164
44164
  return found?.id ?? null;
44165
44165
  }
44166
44166
  function state(info) {
44167
- const shown4 = info.active ? "active" : info.visible ? "shown" : info.open ? "open" : "closed";
44168
- return info.busy ? `${shown4} \xB7 busy: ${info.busy}` : shown4;
44167
+ const shown5 = info.active ? "active" : info.visible ? "shown" : info.open ? "open" : "closed";
44168
+ return info.busy ? `${shown5} \xB7 busy: ${info.busy}` : shown5;
44169
44169
  }
44170
44170
  function table2(rows2) {
44171
44171
  const lines2 = [["ID", "TITLE", "STATE"], ...rows2.map((row) => [row.id, row.title, state(row)])];
44172
44172
  const widths = [0, 1].map((column) => Math.max(...lines2.map((line) => line[column].length)));
44173
- return lines2.map(([id, title2, shown4]) => `${id.padEnd(widths[0])} ${title2.padEnd(widths[1])} ${shown4}`).join("\n");
44173
+ return lines2.map(([id, title2, shown5]) => `${id.padEnd(widths[0])} ${title2.padEnd(widths[1])} ${shown5}`).join("\n");
44174
44174
  }
44175
44175
  var done = (result, note = "") => result.code === 0 ? { stdout: `${result.message}${note}
44176
44176
  `, stderr: "", code: 0 } : { stdout: "", stderr: `panel: ${result.message}
@@ -48468,17 +48468,17 @@ var SliccUpdates = class extends ModelElement {
48468
48468
  return A;
48469
48469
  }
48470
48470
  const before = this.#reached.get(key);
48471
- const shown4 = progress ? { value: Math.max(before?.value ?? 0, phased(progress)), label: count2 } : before;
48472
- if (!shown4) {
48471
+ const shown5 = progress ? { value: Math.max(before?.value ?? 0, phased(progress)), label: count2 } : before;
48472
+ if (!shown5) {
48473
48473
  return b`<swc-progress-bar size="s" indeterminate accessible-label=${accessible2}></swc-progress-bar>`;
48474
48474
  }
48475
- this.#reached.set(key, shown4);
48475
+ this.#reached.set(key, shown5);
48476
48476
  return b`<swc-progress-bar
48477
48477
  size="s"
48478
48478
  min-value="0"
48479
48479
  max-value="100"
48480
- value=${shown4.value}
48481
- value-label=${shown4.label}
48480
+ value=${shown5.value}
48481
+ value-label=${shown5.label}
48482
48482
  accessible-label=${accessible2}
48483
48483
  ></swc-progress-bar>`;
48484
48484
  }
@@ -48495,12 +48495,12 @@ var SliccUpdates = class extends ModelElement {
48495
48495
  }
48496
48496
  #actions(item2) {
48497
48497
  const developer = typeof this.model?.updates?.setDeveloper === "function";
48498
- const shown4 = item2.actions.filter(
48498
+ const shown5 = item2.actions.filter(
48499
48499
  (action) => !betaActions.has(action) || developer && (action !== "install-beta" || item2.npm?.state === "offered")
48500
48500
  );
48501
- if (!shown4.length) return A;
48501
+ if (!shown5.length) return A;
48502
48502
  const busy = this.pending.has(item2.id);
48503
- return b`<div class="actions">${shown4.map(
48503
+ return b`<div class="actions">${shown5.map(
48504
48504
  (action) => b`<swc-button
48505
48505
  size="m"
48506
48506
  variant="secondary"
@@ -48514,8 +48514,8 @@ var SliccUpdates = class extends ModelElement {
48514
48514
  #checked(at) {
48515
48515
  if (at === null) return b`<span>Not checked yet</span>`;
48516
48516
  const date = new Date(at);
48517
- const shown4 = date.toLocaleString("en-GB", { dateStyle: "medium", timeStyle: "short" });
48518
- return b`<span>Checked <time datetime=${date.toISOString()}>${shown4}</time></span>`;
48517
+ const shown5 = date.toLocaleString("en-GB", { dateStyle: "medium", timeStyle: "short" });
48518
+ return b`<span>Checked <time datetime=${date.toISOString()}>${shown5}</time></span>`;
48519
48519
  }
48520
48520
  #title({ release: release3, certified }, label) {
48521
48521
  return b`${secure(release3.url) ? b`<a class="swc-Link swc-Link--standalone" href=${release3.url} target="_blank" rel="noopener noreferrer" data-action="release-notes" aria-label=${`${label} ${release3.version} release notes`}>${release3.version}</a>` : release3.version}${certified ? b`<swc-badge size="s" variant="positive" subtle data-certified>Certified</swc-badge>` : A}`;
@@ -48567,10 +48567,10 @@ var SliccUpdates = class extends ModelElement {
48567
48567
  const label = item2.state === "failed" && item2.from !== null ? "Update failed" : state2;
48568
48568
  const error = this.failures.get(item2.id) ?? item2.error;
48569
48569
  const developer = typeof this.model?.updates?.setDeveloper === "function";
48570
- const shown4 = developer ? item2 : { ...item2, npm: null };
48571
- const meta = npmMeta(shown4);
48572
- const note = npmNote(shown4);
48573
- const ahead2 = shown4.npm?.state === "offered" ? shown4.npm.latest ?? null : null;
48570
+ const shown5 = developer ? item2 : { ...item2, npm: null };
48571
+ const meta = npmMeta(shown5);
48572
+ const note = npmNote(shown5);
48573
+ const ahead2 = shown5.npm?.state === "offered" ? shown5.npm.latest ?? null : null;
48574
48574
  return b`<swc-divider size="s"></swc-divider>
48575
48575
  <article data-id=${item2.id} data-state=${item2.state} data-npm=${item2.npm?.state ?? A} aria-label=${item2.label}>
48576
48576
  <div class="head">
@@ -48637,7 +48637,7 @@ var SliccUpdates = class extends ModelElement {
48637
48637
  const light = packageLight(item2);
48638
48638
  const busy = this.busy.get(item2.id);
48639
48639
  const actions2 = item2.registry ? item2.actions.filter((action) => action !== "retry") : item2.actions;
48640
- const shown4 = busy ? [busy] : act2 ? actions2 : [];
48640
+ const shown5 = busy ? [busy] : act2 ? actions2 : [];
48641
48641
  const error = this.problems.get(item2.id) ?? item2.error;
48642
48642
  const managed = managedText(item2);
48643
48643
  return b`<li data-id=${item2.id} data-state=${item2.state} data-registry=${item2.registry ?? A}>
@@ -48645,7 +48645,7 @@ var SliccUpdates = class extends ModelElement {
48645
48645
  <h3 title=${item2.package}>${item2.label}</h3>
48646
48646
  ${light ? b`<swc-status-light size="s" variant=${light[0]}>${light[1]}</swc-status-light>` : A}
48647
48647
  </div>
48648
- <div class="buttons">${shown4.map(
48648
+ <div class="buttons">${shown5.map(
48649
48649
  (action) => b`<swc-button
48650
48650
  size="s"
48651
48651
  variant="secondary"
@@ -49483,11 +49483,11 @@ var SliccApp = class extends ThemedElement {
49483
49483
  #rail(items, side) {
49484
49484
  const primary = side === "bottom" ? items.filter((item2) => phoneRail.includes(item2.id)) : items;
49485
49485
  const fit = primary.length < items.length ? Math.min(primary.length, railCapacity(this.#width, Infinity)) : railCapacity(this.#width, items.length);
49486
- const shown4 = side === "bottom" ? primary.slice(0, fit) : items;
49487
- const grouped = new Set(shown4.map((item2) => item2.cone).filter(Boolean)).size > 1;
49488
- return b`<nav class=${`rail ${side}`} aria-label=${`Panels, ${side}`} @dragover=${this.#railOver} @dragleave=${this.#railLeave} @drop=${this.#railDrop}>${shown4.map(
49489
- (item2, index2) => b`${grouped && index2 && shown4[index2 - 1].cone !== item2.cone ? b`<span class="cones" aria-hidden="true"></span>` : A}${this.#railButton(item2, side)}`
49490
- )}${this.#more(items.filter((item2) => !shown4.includes(item2)))}</nav>`;
49486
+ const shown5 = side === "bottom" ? primary.slice(0, fit) : items;
49487
+ const grouped = new Set(shown5.map((item2) => item2.cone).filter(Boolean)).size > 1;
49488
+ return b`<nav class=${`rail ${side}`} aria-label=${`Panels, ${side}`} @dragover=${this.#railOver} @dragleave=${this.#railLeave} @drop=${this.#railDrop}>${shown5.map(
49489
+ (item2, index2) => b`${grouped && index2 && shown5[index2 - 1].cone !== item2.cone ? b`<span class="cones" aria-hidden="true"></span>` : A}${this.#railButton(item2, side)}`
49490
+ )}${this.#more(items.filter((item2) => !shown5.includes(item2)))}</nav>`;
49491
49491
  }
49492
49492
  #rails() {
49493
49493
  const dock2 = this.renderRoot.querySelector("slicc-dock");
@@ -50336,15 +50336,65 @@ function truncated(approval) {
50336
50336
  function hintOf(approval) {
50337
50337
  return approval.kind === "sudo" ? commandText(alwaysHint(approval), false) : guestAlwaysHint(approval);
50338
50338
  }
50339
- var deniedSudo = (approval) => approval.kind === "sudo" && approval.verdict?.decision === "deny";
50340
50339
  var tooLong = "This request is too long to show in full, so it can\u2019t be allowed.";
50341
50340
  function guestWaiting(approval) {
50342
50341
  return approval.kind === "guest-message" ? `${approval.requester.name}'s message to ${approval.agentName ?? "this cone"} waits for the owner's approval.` : `${approval.agentName ?? "This cone"} wants to run ${approval.tool} for ${approval.requester.name}, which waits for the owner's approval.`;
50343
50342
  }
50344
- var onceOnly = ({ once }) => once ? b`<p class="hint" data-once-only=${once}>Always allow isn’t offered: xargs adds arguments from its input, and they could include a write flag.</p>` : A;
50343
+ var levels2 = {
50344
+ 1: { name: "routine", label: "Routine." },
50345
+ 2: { name: "permissions", label: "Changes permissions." },
50346
+ 3: { name: "harm", label: "Could harm the system." }
50347
+ };
50348
+ var fits = (aligned) => aligned === void 0 ? "" : aligned ? " It fits what you asked for." : " It isn\u2019t clear it serves what you asked for.";
50349
+ function leveled(approval) {
50350
+ const level = approval.verdict?.level;
50351
+ return level === 1 || level === 2 || level === 3 ? level : null;
50352
+ }
50345
50353
  var clear = { certain: null, maybe: null, once: null };
50346
- function rulesOf(approval) {
50347
- return approval.kind === "sudo" ? secretRules(approval.command, approval.cwd) : clear;
50354
+ function legacyRules(approval) {
50355
+ return approval.kind === "sudo" && leveled(approval) === null ? secretRules(approval.command, approval.cwd) : clear;
50356
+ }
50357
+ function legacyClean(approval) {
50358
+ if (approval.kind !== "sudo") return true;
50359
+ if (approval.verdict?.decision === "deny") return false;
50360
+ const { certain: certain2, maybe, once } = legacyRules(approval);
50361
+ return !certain2 && !maybe && !once;
50362
+ }
50363
+ function legacyNotice(approval) {
50364
+ const verdict = legacyRules(approval);
50365
+ const rules = verdict.certain ?? verdict.maybe;
50366
+ if (rules)
50367
+ return b`<div class="rules" data-secret-rules=${rules}><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><p>${verdict.certain ? b`<strong>This changes secret rules.</strong> It names <code>${commandText(rules, false)}</code>, where SLICC keeps which secrets programs may use and where they may be sent.` : b`<strong>This may change secret rules.</strong> SLICC can't tell where <code>${commandText(rules, false)}</code> leads, and it could reach the files where SLICC keeps which secrets programs may use and where they may be sent.`} Allow it only if you asked for this change.</p></div>`;
50368
+ return verdict.once && approval.kind === "sudo" && approval.always && approval.verdict?.decision !== "deny" ? b`<p class="hint" data-once-only=${verdict.once}>Always allow isn’t offered: xargs adds arguments from its input, and they could include a write flag.</p>` : A;
50369
+ }
50370
+ function offersAlways(approval) {
50371
+ return approval.kind !== "tray" && approval.always && (leveled(approval) !== null || legacyClean(approval));
50372
+ }
50373
+ function verdictNote(approval) {
50374
+ if (approval.kind !== "sudo" || offersAlways(approval)) return "";
50375
+ const level = leveled(approval);
50376
+ if (level === 2) return "Always allow isn\u2019t offered for permission changes.";
50377
+ if (!level && !approval.judging && !approval.verdict && approval.verdictError)
50378
+ return "Always allow appears only with a level 1 verdict.";
50379
+ return "";
50380
+ }
50381
+ var shown4 = (text4) => {
50382
+ const chars = Array.from(text4);
50383
+ return commandText(chars.length > 300 ? `${chars.slice(0, 299).join("")}\u2026` : text4, false);
50384
+ };
50385
+ function judged(approval) {
50386
+ const { verdict, judging, verdictError } = approval;
50387
+ const level = leveled(approval);
50388
+ if (verdict && level) {
50389
+ const { name, label } = levels2[level];
50390
+ return b`<div class="judged" data-verdict=${name} data-level=${level}>${level === 3 ? b`<swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle>` : A}<p><strong>${label}</strong>${verdict.reason ? b` ${shown4(verdict.reason)}` : ""}${fits(verdict.aligned)}</p></div>`;
50391
+ }
50392
+ if (judging) return b`<div class="judged" data-verdict="checking"><p>Checking…</p></div>`;
50393
+ if (verdict?.decision)
50394
+ return b`<p class="verdict" data-verdict=${verdict.decision}>${verdict.decision === "unsure" ? "The automatic check wasn\u2019t sure" : `The automatic check would ${verdict.decision} this`}: ${shown4(verdict.reason)}</p>`;
50395
+ if (verdictError)
50396
+ return b`<div class="judged" data-verdict="none"><p><strong>No verdict:</strong> ${shown4(verdictError)}</p></div>`;
50397
+ return A;
50348
50398
  }
50349
50399
  function waiting2(model, now) {
50350
50400
  return [...model?.approvals?.list() ?? []].filter((approval) => approval.expiresAt > now && Object.hasOwn(titles, approval.kind)).sort((a20, b10) => a20.createdAt - b10.createdAt);
@@ -50518,6 +50568,39 @@ var SliccApprovals = class extends ModelElement {
50518
50568
  font-family: var(--swc-code-font-family-stack);
50519
50569
  overflow-wrap: anywhere;
50520
50570
  }
50571
+ .judged {
50572
+ display: flex;
50573
+ align-items: flex-start;
50574
+ gap: var(--swc-spacing-100);
50575
+ margin-block-start: var(--swc-spacing-200);
50576
+ padding: var(--swc-spacing-200) var(--swc-spacing-300);
50577
+ border-radius: var(--swc-corner-radius-medium-default);
50578
+ background: var(--swc-neutral-subtle-background-color-default);
50579
+ color: var(--swc-neutral-content-color-default);
50580
+ font-size: var(--swc-font-size-75);
50581
+ overflow-wrap: anywhere;
50582
+ }
50583
+ .judged[data-verdict='checking'],
50584
+ .judged[data-verdict='none'] {
50585
+ color: var(--swc-neutral-subdued-content-color-default);
50586
+ }
50587
+ .judged[data-level='1'] {
50588
+ background: var(--swc-positive-subtle-background-color-default);
50589
+ }
50590
+ .judged[data-level='2'] {
50591
+ background: var(--swc-notice-subtle-background-color-default);
50592
+ }
50593
+ .judged[data-level='3'] {
50594
+ background: var(--swc-negative-subtle-background-color-default);
50595
+ --swc-icon-color: var(--swc-icon-color-negative);
50596
+ }
50597
+ .judged swc-icon-alert-triangle {
50598
+ flex: none;
50599
+ margin-block-start: 0.15em;
50600
+ }
50601
+ .judged p {
50602
+ margin: 0;
50603
+ }
50521
50604
  .problem {
50522
50605
  display: flex;
50523
50606
  align-items: flex-start;
@@ -50578,10 +50661,8 @@ var SliccApprovals = class extends ModelElement {
50578
50661
  const port = this.model?.approvals;
50579
50662
  if (!port?.decide || this.busy || decision2 !== "deny" && (!this.#armed || !this.#whole(approval)))
50580
50663
  return;
50581
- const verdict = rulesOf(approval);
50582
- const always = approval.kind === "sudo" || approval.kind !== "tray" && approval.always;
50583
- if (decision2 === "always" && (!always || deniedSudo(approval) || verdict.certain || verdict.maybe || verdict.once))
50584
- return;
50664
+ const live = port.list().find(({ id }) => id === approval.id);
50665
+ if (decision2 === "always" && !(live && offersAlways(live))) return;
50585
50666
  this.busy = decision2;
50586
50667
  this.failure = null;
50587
50668
  this.#pending.add(approval.id);
@@ -50709,8 +50790,9 @@ var SliccApprovals = class extends ModelElement {
50709
50790
  ${files.length ? b`<ul class="files" data-attachments>${files.map((file) => b`<li>${file.name} · ${file.mimeType} · ${size3(file.size)}</li>`)}</ul>` : A}`;
50710
50791
  }
50711
50792
  #verdict(approval) {
50712
- const verdict = approval.kind === "tray" ? void 0 : approval.verdict;
50713
- 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;
50793
+ if (approval.kind === "tray") return A;
50794
+ const note = verdictNote(approval);
50795
+ return b`<div class="judge" aria-live="polite">${judged(approval)}${note ? b`<p class="hint" data-verdict-note>${note}</p>` : A}</div>`;
50714
50796
  }
50715
50797
  #actions(approval, rejected, always) {
50716
50798
  if (rejected)
@@ -50718,10 +50800,7 @@ var SliccApprovals = class extends ModelElement {
50718
50800
  const whole = this.#whole(approval);
50719
50801
  return b`${this.#button(approval, "deny", "Deny", "secondary")}
50720
50802
  ${whole && always ? this.#button(approval, "always", inCwd(approval) ? "Always allow in this directory" : "Always allow", "secondary") : A}
50721
- ${whole ? this.#button(approval, "once", deniedSudo(approval) ? "Allow anyway (once)" : "Allow once", "accent") : A}`;
50722
- }
50723
- #offered(approval, rules) {
50724
- return approval.kind !== "tray" && approval.always && !deniedSudo(approval) && !rules;
50803
+ ${whole ? this.#button(approval, "once", "Allow once", "accent") : A}`;
50725
50804
  }
50726
50805
  render() {
50727
50806
  if (this.gone) {
@@ -50742,10 +50821,7 @@ var SliccApprovals = class extends ModelElement {
50742
50821
  const [approval, ...rest] = held2 ? [held2, ...list6.filter(({ id }) => id !== held2.id)] : list6;
50743
50822
  if (!approval) return A;
50744
50823
  const failure3 = this.failure?.id === approval.id ? this.failure.message : "";
50745
- const verdict = rulesOf(approval);
50746
- const rules = verdict.certain ?? verdict.maybe;
50747
- const offered = this.#offered(approval, rules);
50748
- const always = offered && !verdict.once;
50824
+ const always = offersAlways(approval);
50749
50825
  const gate = this.#gate(approval);
50750
50826
  const hint2 = always && this.#whole(approval) ? hintOf(approval) : "";
50751
50827
  return this.#dialog(
@@ -50756,8 +50832,7 @@ var SliccApprovals = class extends ModelElement {
50756
50832
  ${this.#request(approval, true)}
50757
50833
  ${approval.kind === "sudo" && approval.cwd ? b`<p class="cwd">In ${commandText(approval.cwd, false)}</p>` : A}
50758
50834
  ${this.#verdict(approval)}
50759
- ${rules ? b`<div class="rules" data-secret-rules=${rules}><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><p>${verdict.certain ? b`<strong>This changes secret rules.</strong> It names <code>${commandText(rules, false)}</code>, where SLICC keeps which secrets programs may use and where they may be sent.` : b`<strong>This may change secret rules.</strong> SLICC can't tell where <code>${commandText(rules, false)}</code> leads, and it could reach the files where SLICC keeps which secrets programs may use and where they may be sent.`} Allow it only if you asked for this change.</p></div>` : A}
50760
- ${offered ? onceOnly(verdict) : A}
50835
+ ${legacyNotice(approval)}
50761
50836
  ${hint2 ? b`<p class="hint">${hint2}</p>` : A}
50762
50837
  ${!failure3 && gate ? b`<p class="hint" data-allow-hint>${gate}</p>` : A}
50763
50838
  ${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>`}
@@ -52498,7 +52573,7 @@ var SliccDiffPanel = class extends ThemedElement {
52498
52573
  // src/app/lucide.ts
52499
52574
  var library = null;
52500
52575
  function load2() {
52501
- library ??= import("./chunk-2UI4FYPN.js");
52576
+ library ??= import("./chunk-GIS2QBSN.js");
52502
52577
  return library;
52503
52578
  }
52504
52579
  function pascal(name) {
@@ -53105,11 +53180,11 @@ var SliccMemory = class extends ModelElement {
53105
53180
  const scopes = this.#scopes;
53106
53181
  const scope = this.scope;
53107
53182
  const option2 = (item2) => b`<sp-menu-item value=${item2.id}>${item2.label}</sp-menu-item>`;
53108
- const shown4 = visible2(all2, scope, this.tag, this.query);
53183
+ const shown5 = visible2(all2, scope, this.tag, this.query);
53109
53184
  const total = inScope(all2, scope);
53110
53185
  const filtered = this.tag !== "all" || this.query.trim() !== "";
53111
53186
  const current = scopes.find((item2) => item2.id === scope) ?? null;
53112
- return b`<div class="bar"><span>${shown4.length} of ${total} memories</span><span class="spacer"></span>
53187
+ return b`<div class="bar"><span>${shown5.length} of ${total} memories</span><span class="spacer"></span>
53113
53188
  <swc-action-button size="s" quiet data-action="remember" @click=${() => this.editing = "new"}><swc-icon-add slot="icon"></swc-icon-add>Remember</swc-action-button>
53114
53189
  </div>
53115
53190
  <div class="tools">
@@ -53132,7 +53207,7 @@ var SliccMemory = class extends ModelElement {
53132
53207
  </div>
53133
53208
  <div class="list">
53134
53209
  ${this.editing === "new" ? b`<div class="row">${this.#form({ scope: scope === everyone ? "global" : scope })}</div>` : A}
53135
- ${shown4.length ? sections(shown4).map(
53210
+ ${shown5.length ? sections(shown5).map(
53136
53211
  ([section, items]) => b`<section><h3>${section}</h3><ul>${items.map((memory) => this.#row(memory, section))}</ul></section>`
53137
53212
  ) : b`<div class="note">${emptyNote(total, filtered, current)}</div>`}
53138
53213
  </div>`;
@@ -54207,8 +54282,8 @@ var SliccSecrets = class extends ThemedElement {
54207
54282
  const before = entries[entries.length - 1]?.seq;
54208
54283
  const page = await vault.audit(before);
54209
54284
  if (this.model?.vault !== vault || !this.isConnected) return;
54210
- const shown4 = merged(vault.list()?.audit ?? [], this.older);
54211
- if (shown4[shown4.length - 1]?.seq !== before) return;
54285
+ const shown5 = merged(vault.list()?.audit ?? [], this.older);
54286
+ if (shown5[shown5.length - 1]?.seq !== before) return;
54212
54287
  this.older = merged(this.older, page.audit);
54213
54288
  this.more = page.more;
54214
54289
  } catch (error) {
@@ -54437,7 +54512,7 @@ var SliccSecrets = class extends ThemedElement {
54437
54512
  </li>`;
54438
54513
  }
54439
54514
  #audit(vault, list6, entries, devices) {
54440
- const shown4 = this.reveals ? entries.filter((entry) => entry.type === "materialize") : entries;
54515
+ const shown5 = this.reveals ? entries.filter((entry) => entry.type === "materialize") : entries;
54441
54516
  const more = this.more ?? list6.auditMore;
54442
54517
  const back = returned(entries);
54443
54518
  return b`<div class="audit-head">
@@ -54446,7 +54521,7 @@ var SliccSecrets = class extends ThemedElement {
54446
54521
  this.reveals = event2.target.checked;
54447
54522
  }}>Only reveals to programs</sp-switch>
54448
54523
  </div>
54449
- ${shown4.length ? b`<ol class="audit" aria-labelledby="secrets-audit">${shown4.map((entry) => this.#entry(entry, devices, vault, entries, back))}</ol>` : b`<p class="muted" data-audit-empty>${this.reveals ? more ? "No reveals in the activity loaded so far." : "No program has been given a secret." : "Nothing has used a secret yet."}</p>`}
54524
+ ${shown5.length ? b`<ol class="audit" aria-labelledby="secrets-audit">${shown5.map((entry) => this.#entry(entry, devices, vault, entries, back))}</ol>` : b`<p class="muted" data-audit-empty>${this.reveals ? more ? "No reveals in the activity loaded so far." : "No program has been given a secret." : "Nothing has used a secret yet."}</p>`}
54450
54525
  ${more ? b`<div class="row"><swc-button size="s" variant="secondary" fill-style="outline" data-action="older" ?pending=${this.loading} @click=${() => this.showOlder(vault, entries)}>Show older</swc-button></div>` : A}`;
54451
54526
  }
54452
54527
  #feedback() {
@@ -57578,10 +57653,10 @@ var SliccValueRequest = class extends ThemedElement {
57578
57653
  if (!vault || !request2) return A;
57579
57654
  const locked = !!vault.status()?.locked;
57580
57655
  const rest = queue.length - 1;
57581
- const shown4 = this.problem?.id === request2.id ? this.problem : null;
57582
- const problem = shown4?.text ?? "";
57583
- const name = this.#aria("name", shown4);
57584
- const field3 = this.#aria("value", shown4);
57656
+ const shown5 = this.problem?.id === request2.id ? this.problem : null;
57657
+ const problem = shown5?.text ?? "";
57658
+ const name = this.#aria("name", shown5);
57659
+ const field3 = this.#aria("value", shown5);
57585
57660
  return i23(
57586
57661
  request2.id,
57587
57662
  b`<dialog role="alertdialog" aria-labelledby="title" aria-describedby="asked" data-request=${request2.id} @cancel=${(event2) => {
@@ -84505,8 +84580,8 @@ var SliccFileTree = class extends HTMLElement {
84505
84580
  const item2 = tree?.getItem(path2);
84506
84581
  return item2 && "isExpanded" in item2 ? item2.isExpanded() : null;
84507
84582
  };
84508
- const shown4 = (path2) => path2.split("/").slice(0, -2).every((_7, i26, parts3) => open(`${parts3.slice(0, i26 + 1).join("/")}/`) !== false);
84509
- return this.#paths.filter((path2) => path2.endsWith("/") && open(path2) === true && shown4(path2)).map((path2) => path2.slice(0, -1));
84583
+ const shown5 = (path2) => path2.split("/").slice(0, -2).every((_7, i26, parts3) => open(`${parts3.slice(0, i26 + 1).join("/")}/`) !== false);
84584
+ return this.#paths.filter((path2) => path2.endsWith("/") && open(path2) === true && shown5(path2)).map((path2) => path2.slice(0, -1));
84510
84585
  }
84511
84586
  get gitStatus() {
84512
84587
  return this.#status;