@ai-ecoverse/slicc-spectrum 1.45.0 → 1.46.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
@@ -11737,6 +11737,44 @@ function installProperties(document2, text2 = swc_default) {
11737
11737
  return style;
11738
11738
  }
11739
11739
 
11740
+ // src/app/tabs.ts
11741
+ var following = "SLICC runs in another tab. This tab shows it and sends your actions there.";
11742
+ var connecting = "Connecting to the tab running SLICC\u2026";
11743
+ var alone = "SLICC is open in another tab.";
11744
+ function tabsBanner(state2) {
11745
+ if (!state2 || state2.role === "alone") return null;
11746
+ if (state2.skew === "newer")
11747
+ return {
11748
+ kind: "skew",
11749
+ skew: "newer",
11750
+ text: "Another tab runs a newer SLICC. Reload this tab.",
11751
+ reload: true
11752
+ };
11753
+ if (state2.skew === "older")
11754
+ return {
11755
+ kind: "skew",
11756
+ skew: "older",
11757
+ text: "Another tab runs an older SLICC. Reload the other SLICC tab.",
11758
+ reload: false
11759
+ };
11760
+ if (state2.stalled)
11761
+ return {
11762
+ kind: "stalled",
11763
+ skew: null,
11764
+ text: "Chrome paused the tab running SLICC. Switch to it to continue.",
11765
+ reload: false
11766
+ };
11767
+ return null;
11768
+ }
11769
+ function tabsLight(state2) {
11770
+ if (!state2 || state2.role === "owner" || state2.role === "alone") return null;
11771
+ const banner = tabsBanner(state2);
11772
+ if (banner) return { variant: "notice", text: "Another tab", tooltip: banner.text };
11773
+ if (state2.role === "connecting")
11774
+ return { variant: "info", text: "Connecting", tooltip: connecting };
11775
+ return { variant: "neutral", text: "Another tab", tooltip: following };
11776
+ }
11777
+
11740
11778
  // src/app/terminals.ts
11741
11779
  function deepActive(root2) {
11742
11780
  const active = root2.activeElement;
@@ -19917,6 +19955,33 @@ var SliccApp = class extends ThemedElement {
19917
19955
  flex-direction: column;
19918
19956
  height: 100%;
19919
19957
  }
19958
+ .shell[data-alone] header > :not(.brand),
19959
+ .shell[data-alone] main,
19960
+ .shell[data-alone] .rail.bottom {
19961
+ display: none;
19962
+ }
19963
+ .alone {
19964
+ display: flex;
19965
+ flex: 1;
19966
+ align-items: center;
19967
+ justify-content: center;
19968
+ padding: var(--swc-spacing-400);
19969
+ text-align: center;
19970
+ font-size: var(--swc-font-size-300);
19971
+ color: var(--swc-neutral-subdued-content-color-default);
19972
+ }
19973
+ .alone p {
19974
+ margin: 0;
19975
+ }
19976
+ header .tabs {
19977
+ display: inline-flex;
19978
+ align-self: center;
19979
+ padding-inline: var(--swc-spacing-75);
19980
+ border-radius: var(--swc-corner-radius-small-default);
19981
+ }
19982
+ header .tabs:focus-visible {
19983
+ outline: var(--swc-focus-indicator-thickness) solid var(--swc-focus-indicator-color);
19984
+ }
19920
19985
  main {
19921
19986
  display: grid;
19922
19987
  grid-template-columns: auto minmax(0, 1fr) auto;
@@ -20097,7 +20162,8 @@ var SliccApp = class extends ThemedElement {
20097
20162
  model.browser.on("tabs", update),
20098
20163
  this.dips.on("change", update),
20099
20164
  ...model.updates ? [model.updates.on("items", update)] : [],
20100
- ...model.network ? [model.network.on("network", update)] : []
20165
+ ...model.network ? [model.network.on("network", update)] : [],
20166
+ ...model.tabs ? [model.tabs.on("tabs", update)] : []
20101
20167
  ];
20102
20168
  }
20103
20169
  connectedCallback() {
@@ -20481,6 +20547,15 @@ var SliccApp = class extends ThemedElement {
20481
20547
  </swc-action-button>
20482
20548
  <swc-tooltip for="updates" placement="bottom">${text2}</swc-tooltip>`;
20483
20549
  }
20550
+ #tabsIndicator() {
20551
+ const state2 = this.model?.tabs?.state();
20552
+ const light = tabsLight(state2);
20553
+ if (!state2 || !light) return A;
20554
+ return b`<span id="tabs" class="tabs" tabindex="0" role="img" data-tabs data-role=${state2.role} ?data-stalled=${state2.stalled} data-skew=${state2.skew ?? A} aria-label=${`${light.text}. ${light.tooltip}`}>
20555
+ <swc-status-light size="s" variant=${light.variant}>${this.screen === "phone" ? A : light.text}</swc-status-light>
20556
+ </span>
20557
+ <swc-tooltip for="tabs" placement="bottom">${light.tooltip}</swc-tooltip>`;
20558
+ }
20484
20559
  #networkIndicator() {
20485
20560
  const port = this.model?.network;
20486
20561
  if (!port || !this.#offers("network")) return A;
@@ -20499,8 +20574,9 @@ var SliccApp = class extends ThemedElement {
20499
20574
  const color = this.color;
20500
20575
  const cones = (this.model?.agent.list() ?? []).filter((agent) => agent.kind === "cone");
20501
20576
  const rails = this.#rails();
20577
+ const lonely = this.model?.tabs?.state().role === "alone";
20502
20578
  return b`<div class=${`swc-theme swc-theme--sizeM swc-theme--${color}`}><sp-theme system="spectrum-two" color=${color} scale="medium">
20503
- <div class="shell">
20579
+ <div class="shell" ?data-alone=${lonely}>
20504
20580
  <header>
20505
20581
  <span class="brand">slicc</span>
20506
20582
  ${this.#offers("chat") ? i17(
@@ -20514,6 +20590,7 @@ var SliccApp = class extends ThemedElement {
20514
20590
  ) : A}
20515
20591
  <span class="spacer"></span>
20516
20592
  <div class="status" role="status"><slot name="status"></slot></div>
20593
+ ${this.#tabsIndicator()}
20517
20594
  ${this.#updatesIndicator()}
20518
20595
  ${this.#networkIndicator()}
20519
20596
  ${this.#offers("chat") ? b`<slicc-tray .model=${this.model} ?compact=${this.screen === "phone"}></slicc-tray>` : A}
@@ -20539,6 +20616,7 @@ var SliccApp = class extends ThemedElement {
20539
20616
  ) : A}
20540
20617
  ${this.#headerButton("theme", color === "dark" ? "Switch to light theme" : "Switch to dark theme", b`<swc-icon-contrast slot="icon"></swc-icon-contrast>`, () => this.toggleColor())}
20541
20618
  </header>
20619
+ ${lonely ? b`<div class="alone" role="status" data-tabs="alone"><p>${alone}</p></div>` : A}
20542
20620
  <main>
20543
20621
  ${rails.left}
20544
20622
  <slicc-dock empty-text="All panels are closed. Open one from a rail or View." @layout-change=${this.#save}
@@ -22496,6 +22574,7 @@ var SliccChat = class extends ThemedElement {
22496
22574
  if (!this.agent) this.#refresh(true);
22497
22575
  }),
22498
22576
  model.agent.on("agents", () => this.requestUpdate()),
22577
+ ...model.tabs ? [model.tabs.on("tabs", () => this.requestUpdate())] : [],
22499
22578
  model.agent.on("messages", (agentId) => {
22500
22579
  if (agentId === this.#id()) this.#refresh(this.#sent(agentId));
22501
22580
  }),
@@ -22687,7 +22766,7 @@ var SliccChat = class extends ThemedElement {
22687
22766
  this.#items(messages, agent),
22688
22767
  ([key2]) => key2,
22689
22768
  ([, item2]) => item2
22690
- )}</swc-conversation-thread>` : b`<div class="empty">No messages yet. Ask ${agent?.name ?? "the agent"} something.</div>`}
22769
+ )}</swc-conversation-thread>` : this.model?.tabs?.state().role === "connecting" ? b`<div class="empty" data-connecting>${connecting}</div>` : b`<div class="empty">No messages yet. Ask ${agent?.name ?? "the agent"} something.</div>`}
22691
22770
  </div>
22692
22771
  </div>
22693
22772
  ${this.model && !agent?.frozen ? b`<slicc-composer .model=${this.model} .agent=${this.agent}></slicc-composer>` : A}
@@ -24988,8 +25067,10 @@ var SliccNotices = class extends ModelElement {
24988
25067
  this.pending = /* @__PURE__ */ new Map();
24989
25068
  this.failures = /* @__PURE__ */ new Map();
24990
25069
  }
24991
- if (!port) return [];
25070
+ const tabs = model.tabs ? [model.tabs.on("tabs", () => this.requestUpdate())] : [];
25071
+ if (!port) return tabs;
24992
25072
  return [
25073
+ ...tabs,
24993
25074
  port.on("notices", (notices) => {
24994
25075
  const ids = new Set(notices.map((notice) => notice.id));
24995
25076
  this.dismissed = new Set([...this.dismissed].filter((id) => ids.has(id)));
@@ -25039,11 +25120,24 @@ var SliccNotices = class extends ModelElement {
25039
25120
  <swc-close-button size="m" data-dismiss accessible-label=${`Dismiss: ${notice.title}`} @click=${() => this.dismiss(notice.id)}></swc-close-button>
25040
25121
  </div>`;
25041
25122
  }
25123
+ #tabs() {
25124
+ const tabs = this.model?.tabs;
25125
+ const banner = tabsBanner(tabs?.state());
25126
+ if (!tabs || !banner) return A;
25127
+ return b`<div class="notice" role="status" data-tabs-notice=${banner.kind} data-skew=${banner.skew ?? A} data-tone="warning">
25128
+ <swc-icon-alert-triangle></swc-icon-alert-triangle>
25129
+ <div class="text">
25130
+ <p>${banner.text}</p>
25131
+ ${banner.reload ? b`<div class="actions"><swc-button size="s" variant="secondary" fill-style="outline" data-action="reload" @click=${() => tabs.reload()}>Reload</swc-button></div>` : A}
25132
+ </div>
25133
+ </div>`;
25134
+ }
25042
25135
  render() {
25043
25136
  const port = this.model?.notices;
25044
25137
  const notices = (port?.list() ?? []).filter((notice) => !this.dismissed.has(notice.id));
25045
- if (!notices.length) return A;
25046
- return b`<div class="notices">${c(
25138
+ const tabs = this.#tabs();
25139
+ if (!notices.length && tabs === A) return A;
25140
+ return b`<div class="notices">${tabs}${c(
25047
25141
  notices,
25048
25142
  (notice) => notice.id,
25049
25143
  (notice) => this.#notice(notice)