@ai-ecoverse/slicc-spectrum 1.92.0 → 1.94.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/README.md +12 -5
- package/dist/chunk-RYA3OPGE.js +1885 -0
- package/dist/chunk-RYA3OPGE.js.map +7 -0
- package/dist/slicc-dummy.js +133 -1621
- package/dist/slicc-dummy.js.map +4 -4
- package/dist/slicc-kernel-model.js +1 -1
- package/dist/slicc-ui.js +732 -64
- package/dist/slicc-ui.js.map +4 -4
- package/dist/types/app/approvals.d.ts +1 -1
- package/dist/types/app/chat.d.ts +2 -1
- package/dist/types/app/confirm.d.ts +4 -3
- package/dist/types/app/freezer-import.d.ts +1 -1
- package/dist/types/app/guests.d.ts +1 -1
- package/dist/types/app/secrets.d.ts +18 -2
- package/dist/types/app/settings.d.ts +25 -1
- package/dist/types/app/sign-in.d.ts +12 -0
- package/dist/types/app/value-request.d.ts +1 -1
- package/dist/types/dummy/index.d.ts +1 -1
- package/dist/types/dummy/providers.d.ts +4 -0
- package/dist/types/dummy/settings.d.ts +4 -2
- package/dist/types/dummy/vault.d.ts +6 -2
- package/dist/types/dummy.d.ts +2 -1
- package/dist/types/model/types.d.ts +52 -2
- package/package.json +1 -1
- package/dist/chunk-3CM23WFV.js +0 -122
- package/dist/chunk-3CM23WFV.js.map +0 -7
package/dist/slicc-ui.js
CHANGED
|
@@ -9349,7 +9349,7 @@ function themeOf(node) {
|
|
|
9349
9349
|
}
|
|
9350
9350
|
return document.querySelector("slicc-app")?.shadowRoot?.querySelector("sp-theme") ?? document.body;
|
|
9351
9351
|
}
|
|
9352
|
-
var
|
|
9352
|
+
var dialogFrame = i`
|
|
9353
9353
|
dialog {
|
|
9354
9354
|
box-sizing: border-box;
|
|
9355
9355
|
max-inline-size: calc(100vw - 2 * var(--swc-spacing-300));
|
|
@@ -9369,6 +9369,13 @@ var dialogStyles = i`
|
|
|
9369
9369
|
color-mix(in srgb, var(--swc-overlay-color) calc(var(--swc-overlay-opacity-dark) * 100%), transparent)
|
|
9370
9370
|
);
|
|
9371
9371
|
}
|
|
9372
|
+
@media (forced-colors: active) {
|
|
9373
|
+
dialog {
|
|
9374
|
+
outline: solid;
|
|
9375
|
+
}
|
|
9376
|
+
}
|
|
9377
|
+
`;
|
|
9378
|
+
var alertStyles = i`
|
|
9372
9379
|
sp-alert-dialog {
|
|
9373
9380
|
--mod-alert-dialog-min-width: min(
|
|
9374
9381
|
var(--swc-alert-dialog-minimum-width),
|
|
@@ -9390,9 +9397,6 @@ var dialogStyles = i`
|
|
|
9390
9397
|
}
|
|
9391
9398
|
}
|
|
9392
9399
|
@media (forced-colors: active) {
|
|
9393
|
-
dialog {
|
|
9394
|
-
outline: solid;
|
|
9395
|
-
}
|
|
9396
9400
|
sp-alert-dialog {
|
|
9397
9401
|
border: none;
|
|
9398
9402
|
}
|
|
@@ -9409,6 +9413,7 @@ var dialogStyles = i`
|
|
|
9409
9413
|
margin-block-end: var(--swc-spacing-75);
|
|
9410
9414
|
}
|
|
9411
9415
|
`;
|
|
9416
|
+
var dialogStyles = [dialogFrame, alertStyles];
|
|
9412
9417
|
var SliccConfirm = class extends i2 {
|
|
9413
9418
|
static properties = { heading: {}, body: {}, action: {}, variant: {}, cancel: {} };
|
|
9414
9419
|
trigger = null;
|
|
@@ -22649,6 +22654,34 @@ function markdown(text2) {
|
|
|
22649
22654
|
return b`${parse(text2).map(render)}`;
|
|
22650
22655
|
}
|
|
22651
22656
|
|
|
22657
|
+
// src/app/sign-in.ts
|
|
22658
|
+
var continuing = "Continue in the sign-in window that opened.";
|
|
22659
|
+
var closed = "Closed the sign-in window? Cancel, then Log in again.";
|
|
22660
|
+
var signInWait = { closedAfter: 2e4 };
|
|
22661
|
+
function signInText(waited) {
|
|
22662
|
+
return waited ? closed : continuing;
|
|
22663
|
+
}
|
|
22664
|
+
var SignInWaits = class {
|
|
22665
|
+
#since = /* @__PURE__ */ new Map();
|
|
22666
|
+
#update;
|
|
22667
|
+
constructor(update) {
|
|
22668
|
+
this.#update = update;
|
|
22669
|
+
}
|
|
22670
|
+
waited(key2) {
|
|
22671
|
+
const now = Date.now();
|
|
22672
|
+
const since3 = this.#since.get(key2);
|
|
22673
|
+
if (since3 === void 0) {
|
|
22674
|
+
this.#since.set(key2, now);
|
|
22675
|
+
setTimeout(this.#update, signInWait.closedAfter);
|
|
22676
|
+
return false;
|
|
22677
|
+
}
|
|
22678
|
+
return now - since3 >= signInWait.closedAfter;
|
|
22679
|
+
}
|
|
22680
|
+
done(key2) {
|
|
22681
|
+
this.#since.delete(key2);
|
|
22682
|
+
}
|
|
22683
|
+
};
|
|
22684
|
+
|
|
22652
22685
|
// src/app/messages.ts
|
|
22653
22686
|
var lickLabels = {
|
|
22654
22687
|
webhook: ["Webhook", "informative"],
|
|
@@ -22843,8 +22876,6 @@ function actionLabel(action, handlers, messageId) {
|
|
|
22843
22876
|
return count2 > 1 ? `Drop ${count2} failed turns` : actionLabels[action];
|
|
22844
22877
|
}
|
|
22845
22878
|
var signedIn = "Signed in. Retry to send it again.";
|
|
22846
|
-
var continuing = "Continue in the sign-in window that opened.";
|
|
22847
|
-
var closed = "Closed the sign-in window? Cancel, then Log in again.";
|
|
22848
22879
|
function stopSigningIn(event2, handlers, account, id) {
|
|
22849
22880
|
const main2 = event2.currentTarget.nextElementSibling;
|
|
22850
22881
|
main2.focus();
|
|
@@ -22863,7 +22894,7 @@ function errorCard(item2, handlers) {
|
|
|
22863
22894
|
const login = fix === "login" && item2.account && !handlers.readOnly ? handlers.login?.(item2.account, id) : void 0;
|
|
22864
22895
|
const resolved = login?.state === "connected";
|
|
22865
22896
|
const signing = login?.state === "signing-in" && login.window;
|
|
22866
|
-
const text2 = resolved ? signedIn : signing ? login.waited
|
|
22897
|
+
const text2 = resolved ? signedIn : signing ? signInText(login.waited) : item2.text;
|
|
22867
22898
|
const title = resolved && login.provider ? `Signed in to ${login.provider} again.` : item2.title;
|
|
22868
22899
|
const failure2 = login?.state === "idle" ? login.error : void 0;
|
|
22869
22900
|
return b`<div class="error-card" role=${resolved ? A : "alert"} aria-atomic=${resolved ? A : "false"} data-id=${id || A} data-login=${login?.state ?? A}>
|
|
@@ -24701,7 +24732,7 @@ document.addEventListener(
|
|
|
24701
24732
|
},
|
|
24702
24733
|
true
|
|
24703
24734
|
);
|
|
24704
|
-
var SliccChat = class
|
|
24735
|
+
var SliccChat = class extends ThemedElement {
|
|
24705
24736
|
static properties = {
|
|
24706
24737
|
...ThemedElement.properties,
|
|
24707
24738
|
agent: {},
|
|
@@ -25125,19 +25156,14 @@ var SliccChat = class _SliccChat extends ThemedElement {
|
|
|
25125
25156
|
if (!restored) return;
|
|
25126
25157
|
this.renderRoot.querySelector("slicc-composer")?.restore(latest ? { text: latest.text, attachments: latest.attachments } : restored);
|
|
25127
25158
|
}
|
|
25128
|
-
static closedAfter
|
|
25129
|
-
|
|
25130
|
-
#signing = /* @__PURE__ */ new Map();
|
|
25131
|
-
#waited(key2) {
|
|
25132
|
-
const now = Date.now();
|
|
25133
|
-
const since3 = this.#signing.get(key2);
|
|
25134
|
-
if (since3 === void 0) {
|
|
25135
|
-
this.#signing.set(key2, now);
|
|
25136
|
-
setTimeout(() => this.requestUpdate(), _SliccChat.closedAfter);
|
|
25137
|
-
return false;
|
|
25138
|
-
}
|
|
25139
|
-
return now - since3 >= _SliccChat.closedAfter;
|
|
25159
|
+
static get closedAfter() {
|
|
25160
|
+
return signInWait.closedAfter;
|
|
25140
25161
|
}
|
|
25162
|
+
static set closedAfter(after) {
|
|
25163
|
+
signInWait.closedAfter = after;
|
|
25164
|
+
}
|
|
25165
|
+
#logins = /* @__PURE__ */ new Map();
|
|
25166
|
+
#waits = new SignInWaits(() => this.requestUpdate());
|
|
25141
25167
|
#loginState(accountId, messageId) {
|
|
25142
25168
|
const settings = this.model.settings;
|
|
25143
25169
|
const account = settings.accounts().find((candidate) => candidate.id === accountId);
|
|
@@ -25146,8 +25172,8 @@ var SliccChat = class _SliccChat extends ThemedElement {
|
|
|
25146
25172
|
const window2 = account?.auth === "oauth";
|
|
25147
25173
|
const key2 = `${messageId}:${accountId}`;
|
|
25148
25174
|
if (account?.status === "signing-in" || local2?.pending)
|
|
25149
|
-
return { state: "signing-in", cancel, window: window2, waited: window2 && this.#waited(key2) };
|
|
25150
|
-
this.#
|
|
25175
|
+
return { state: "signing-in", cancel, window: window2, waited: window2 && this.#waits.waited(key2) };
|
|
25176
|
+
this.#waits.done(key2);
|
|
25151
25177
|
if (account?.status === "connected") return { state: "connected", provider: account.provider };
|
|
25152
25178
|
return { state: "idle", error: local2?.error };
|
|
25153
25179
|
}
|
|
@@ -25988,13 +26014,13 @@ var SliccFileView = class extends ThemedElement {
|
|
|
25988
26014
|
async save() {
|
|
25989
26015
|
const model = this.model;
|
|
25990
26016
|
if (!model || this.draft === null) return;
|
|
25991
|
-
const
|
|
26017
|
+
const draft2 = this.draft;
|
|
25992
26018
|
this.saving = true;
|
|
25993
26019
|
try {
|
|
25994
|
-
await model.files.write(this.path,
|
|
25995
|
-
this.text =
|
|
26020
|
+
await model.files.write(this.path, draft2);
|
|
26021
|
+
this.text = draft2;
|
|
25996
26022
|
this.missing = false;
|
|
25997
|
-
if (this.draft ===
|
|
26023
|
+
if (this.draft === draft2) this.draft = null;
|
|
25998
26024
|
} finally {
|
|
25999
26025
|
this.saving = false;
|
|
26000
26026
|
}
|
|
@@ -31336,8 +31362,8 @@ var Panels = class {
|
|
|
31336
31362
|
};
|
|
31337
31363
|
}
|
|
31338
31364
|
find(id) {
|
|
31339
|
-
const
|
|
31340
|
-
if (
|
|
31365
|
+
const listed2 = this.list().find((info) => info.id === id);
|
|
31366
|
+
if (listed2) return listed2;
|
|
31341
31367
|
const document2 = id.match(/^(file|diff):(.+)$/);
|
|
31342
31368
|
if (!document2) return void 0;
|
|
31343
31369
|
return this.#state({
|
|
@@ -40422,7 +40448,7 @@ var SliccComposer = class extends ThemedElement {
|
|
|
40422
40448
|
clearValues(this.renderRoot);
|
|
40423
40449
|
const held = [
|
|
40424
40450
|
this.attachments,
|
|
40425
|
-
...[...this.#drafts.values()].map((
|
|
40451
|
+
...[...this.#drafts.values()].map((draft2) => draft2.attachments)
|
|
40426
40452
|
];
|
|
40427
40453
|
if (held.flat().some((attachment2) => attachment2.url?.startsWith("blob:")))
|
|
40428
40454
|
this.#abandon = setTimeout(() => {
|
|
@@ -40478,10 +40504,10 @@ var SliccComposer = class extends ThemedElement {
|
|
|
40478
40504
|
#switch(id) {
|
|
40479
40505
|
if (this.#agent)
|
|
40480
40506
|
this.#drafts.set(this.#agent, { value: this.value, attachments: this.attachments });
|
|
40481
|
-
const
|
|
40507
|
+
const draft2 = this.#drafts.get(id);
|
|
40482
40508
|
this.#agent = id;
|
|
40483
|
-
this.value =
|
|
40484
|
-
this.attachments =
|
|
40509
|
+
this.value = draft2?.value ?? "";
|
|
40510
|
+
this.attachments = draft2?.attachments ?? [];
|
|
40485
40511
|
this.popup = null;
|
|
40486
40512
|
this.#history = -1;
|
|
40487
40513
|
}
|
|
@@ -40534,8 +40560,8 @@ var SliccComposer = class extends ThemedElement {
|
|
|
40534
40560
|
this.failure = null;
|
|
40535
40561
|
this.#history = -1;
|
|
40536
40562
|
model.agent.send(this.#agent, text2).catch((error) => {
|
|
40537
|
-
const
|
|
40538
|
-
this.value =
|
|
40563
|
+
const draft2 = this.value.trim();
|
|
40564
|
+
this.value = draft2 && draft2 !== text2 ? `${text2}
|
|
40539
40565
|
${this.value}` : text2;
|
|
40540
40566
|
this.failure = error instanceof Error ? error.message : String(error);
|
|
40541
40567
|
});
|
|
@@ -40860,8 +40886,8 @@ ${this.value}` : text2;
|
|
|
40860
40886
|
}
|
|
40861
40887
|
async #paste(event2) {
|
|
40862
40888
|
const data = event2.clipboardData;
|
|
40863
|
-
const
|
|
40864
|
-
const files =
|
|
40889
|
+
const listed2 = [...data?.files ?? []];
|
|
40890
|
+
const files = listed2.length ? listed2 : [...data?.items ?? []].flatMap((item2) => {
|
|
40865
40891
|
const file = item2.kind === "file" ? item2.getAsFile() : null;
|
|
40866
40892
|
return file ? [file] : [];
|
|
40867
40893
|
});
|
|
@@ -41839,7 +41865,28 @@ function changes(entry, devices) {
|
|
|
41839
41865
|
return entry.changes.map((change) => [change.kind, changeLine(change, devices)]);
|
|
41840
41866
|
return (entry.widened ?? []).map((change) => [change.kind, widening(change, devices)]);
|
|
41841
41867
|
}
|
|
41842
|
-
|
|
41868
|
+
var listed = (items, one2) => items.map((item2, index) => b`${index ? ", " : ""}${one2(item2)}`);
|
|
41869
|
+
function endpointsLine(entry, named2 = (provider) => provider) {
|
|
41870
|
+
const parts2 = [];
|
|
41871
|
+
if (entry.purged?.length)
|
|
41872
|
+
parts2.push(
|
|
41873
|
+
b`<span class="part" data-part="purged">Removed custom model URLs an agent set, automatically: ${listed(entry.purged, (item2) => b`${named2(item2.provider)} at <code>${item2.host ?? item2.url}</code>`)}. Only you can set a model URL now, in Settings › Accounts</span>`
|
|
41874
|
+
);
|
|
41875
|
+
if (entry.adopted?.length)
|
|
41876
|
+
parts2.push(
|
|
41877
|
+
b`<span class="part" data-part="adopted">Kept the MCP servers your tokens use, automatically: ${listed(entry.adopted, (item2) => b`${item2.server} at <code>${item2.host}</code>`)}</span>`
|
|
41878
|
+
);
|
|
41879
|
+
if (entry.pinned)
|
|
41880
|
+
parts2.push(
|
|
41881
|
+
b`<span class="part" data-part="pinned"><code>${entry.pinned.name ?? entry.pinned.server}</code> pinned to <code>${entry.pinned.host}</code> automatically, on first use</span>`
|
|
41882
|
+
);
|
|
41883
|
+
if (entry.unpinned)
|
|
41884
|
+
parts2.push(
|
|
41885
|
+
b`<span class="part" data-part="unpinned"><code>${entry.unpinned.name ?? entry.unpinned.server}</code> unpinned from <code>${entry.unpinned.host}</code>; the next use pins it again</span>`
|
|
41886
|
+
);
|
|
41887
|
+
return b`${parts2.map((part2, index) => b`${index ? ". " : ""}${part2}`)}`;
|
|
41888
|
+
}
|
|
41889
|
+
function auditLine(entry, devices, named2) {
|
|
41843
41890
|
switch (entry.type) {
|
|
41844
41891
|
case "inject":
|
|
41845
41892
|
case "forward":
|
|
@@ -41855,7 +41902,7 @@ function auditLine(entry, devices) {
|
|
|
41855
41902
|
case "restore":
|
|
41856
41903
|
return b`Restored`;
|
|
41857
41904
|
case "endpoints":
|
|
41858
|
-
return
|
|
41905
|
+
return endpointsLine(entry, named2);
|
|
41859
41906
|
case "refresh":
|
|
41860
41907
|
return entry.grant ? b`Refreshed automatically with the sign-in <code>${entry.grant}</code>` : b`Refreshed automatically`;
|
|
41861
41908
|
default:
|
|
@@ -41912,6 +41959,9 @@ var SliccSecrets = class extends ThemedElement {
|
|
|
41912
41959
|
failure: { state: true },
|
|
41913
41960
|
form: { state: true },
|
|
41914
41961
|
busy: { state: true },
|
|
41962
|
+
unpinning: { state: true },
|
|
41963
|
+
unpinned: { state: true },
|
|
41964
|
+
unpinFailure: { state: true },
|
|
41915
41965
|
problem: { state: true },
|
|
41916
41966
|
invalid: { state: true },
|
|
41917
41967
|
said: { state: true },
|
|
@@ -41934,6 +41984,9 @@ var SliccSecrets = class extends ThemedElement {
|
|
|
41934
41984
|
this.failure = null;
|
|
41935
41985
|
this.form = null;
|
|
41936
41986
|
this.busy = false;
|
|
41987
|
+
this.unpinning = null;
|
|
41988
|
+
this.unpinned = /* @__PURE__ */ new Set();
|
|
41989
|
+
this.unpinFailure = null;
|
|
41937
41990
|
this.problem = null;
|
|
41938
41991
|
this.invalid = null;
|
|
41939
41992
|
this.said = null;
|
|
@@ -42196,6 +42249,13 @@ var SliccSecrets = class extends ThemedElement {
|
|
|
42196
42249
|
.audit .hint {
|
|
42197
42250
|
display: block;
|
|
42198
42251
|
}
|
|
42252
|
+
.audit .unpin {
|
|
42253
|
+
display: flex;
|
|
42254
|
+
flex-wrap: wrap;
|
|
42255
|
+
align-items: center;
|
|
42256
|
+
gap: var(--swc-spacing-200);
|
|
42257
|
+
margin-top: var(--swc-spacing-100);
|
|
42258
|
+
}
|
|
42199
42259
|
.row {
|
|
42200
42260
|
display: flex;
|
|
42201
42261
|
flex-wrap: wrap;
|
|
@@ -42257,6 +42317,9 @@ var SliccSecrets = class extends ThemedElement {
|
|
|
42257
42317
|
this.failure = null;
|
|
42258
42318
|
this.form = null;
|
|
42259
42319
|
this.busy = false;
|
|
42320
|
+
this.unpinning = null;
|
|
42321
|
+
this.unpinned = /* @__PURE__ */ new Set();
|
|
42322
|
+
this.unpinFailure = null;
|
|
42260
42323
|
this.problem = null;
|
|
42261
42324
|
this.invalid = null;
|
|
42262
42325
|
this.said = null;
|
|
@@ -42741,12 +42804,42 @@ var SliccSecrets = class extends ThemedElement {
|
|
|
42741
42804
|
${refused2.map((item2) => b`<li data-refused-secret=${item2.secret}><span><code>${item2.secret}</code> to ${ruleLine(item2.rule)}</span><span class="muted">${item2.reason}</span></li>`)}
|
|
42742
42805
|
</ul>`;
|
|
42743
42806
|
}
|
|
42744
|
-
#
|
|
42807
|
+
#provider(id) {
|
|
42808
|
+
const settings = this.model?.settings;
|
|
42809
|
+
const option2 = settings?.providers?.().find((item2) => item2.id === id);
|
|
42810
|
+
const account = settings?.accounts().find((item2) => item2.id === id);
|
|
42811
|
+
return option2?.name ?? account?.provider ?? id;
|
|
42812
|
+
}
|
|
42813
|
+
#unpin(vault, entry, all2) {
|
|
42814
|
+
const name = entry.pinned?.name;
|
|
42815
|
+
if (!name || !vault.unpin) return A;
|
|
42816
|
+
const key2 = `unpin:${entry.seq}`;
|
|
42817
|
+
const undone = all2.some(
|
|
42818
|
+
(later) => later.type === "endpoints" && later.seq > entry.seq && later.unpinned?.name === name
|
|
42819
|
+
);
|
|
42820
|
+
if (undone || this.unpinned.has(key2)) return A;
|
|
42821
|
+
const busy = this.unpinning === key2;
|
|
42822
|
+
return b`<span class="unpin"><swc-button size="s" variant="secondary" fill-style="outline" data-action="unpin" ?pending=${busy} ?disabled=${!!vault.status()?.locked} @click=${() => this.#unpinNow(vault, name, key2)}>Unpin</swc-button>${this.unpinFailure?.key === key2 ? b`<span class="warning" role="alert" data-error="unpin">${this.unpinFailure.message}</span>` : A}</span>`;
|
|
42823
|
+
}
|
|
42824
|
+
async #unpinNow(vault, name, key2) {
|
|
42825
|
+
if (this.unpinning) return;
|
|
42826
|
+
this.unpinning = key2;
|
|
42827
|
+
this.unpinFailure = null;
|
|
42828
|
+
try {
|
|
42829
|
+
await vault.unpin?.([name]);
|
|
42830
|
+
if (this.#mine(vault)) this.unpinned = /* @__PURE__ */ new Set([...this.unpinned, key2]);
|
|
42831
|
+
} catch (error) {
|
|
42832
|
+
if (this.#mine(vault)) this.unpinFailure = { key: key2, message: failureText(error) };
|
|
42833
|
+
} finally {
|
|
42834
|
+
if (this.#mine(vault)) this.unpinning = null;
|
|
42835
|
+
}
|
|
42836
|
+
}
|
|
42837
|
+
#entry(entry, devices, vault, all2 = []) {
|
|
42745
42838
|
const date = new Date(entry.at);
|
|
42746
42839
|
const name = entry.type === "policy" || entry.type === "endpoints" ? null : entry.name;
|
|
42747
42840
|
return b`<li data-seq=${entry.seq} data-type=${entry.type}>
|
|
42748
42841
|
<time datetime=${date.toISOString()} title=${date.toLocaleString("en-GB", { dateStyle: "medium", timeStyle: "short" })}>${since(entry.at)}</time>
|
|
42749
|
-
<span class="what">${name ? b`<code>${name}</code> · ` : A}${auditLine(entry, devices)}${entry.type === "policy" || entry.type === "refresh" || entry.type === "endpoints" ? A : b` <span class="by">by ${who(entry)}</span>`}</span>
|
|
42842
|
+
<span class="what">${name ? b`<code>${name}</code> · ` : A}${auditLine(entry, devices, (provider) => this.#provider(provider))}${entry.type === "policy" || entry.type === "refresh" || entry.type === "endpoints" ? A : b` <span class="by">by ${who(entry)}</span>`}${entry.type === "endpoints" && vault ? this.#unpin(vault, entry, all2) : A}</span>
|
|
42750
42843
|
</li>`;
|
|
42751
42844
|
}
|
|
42752
42845
|
#audit(vault, list5, entries, devices) {
|
|
@@ -42758,7 +42851,7 @@ var SliccSecrets = class extends ThemedElement {
|
|
|
42758
42851
|
this.reveals = event2.target.checked;
|
|
42759
42852
|
}}>Only reveals to programs</sp-switch>
|
|
42760
42853
|
</div>
|
|
42761
|
-
${shown4.length ? b`<ol class="audit" aria-labelledby="secrets-audit">${shown4.map((entry) => this.#entry(entry, devices))}</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>`}
|
|
42854
|
+
${shown4.length ? b`<ol class="audit" aria-labelledby="secrets-audit">${shown4.map((entry) => this.#entry(entry, devices, vault, entries))}</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>`}
|
|
42762
42855
|
${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}`;
|
|
42763
42856
|
}
|
|
42764
42857
|
#feedback() {
|
|
@@ -42873,6 +42966,7 @@ function recordKind(account) {
|
|
|
42873
42966
|
return account.group === "mcp" ? "mcp" : "model";
|
|
42874
42967
|
}
|
|
42875
42968
|
function recordName(account) {
|
|
42969
|
+
if (account.vaultName) return account.vaultName;
|
|
42876
42970
|
if (account.group === "mcp") return `MCP_${upper(serverOf(account))}_TOKEN`;
|
|
42877
42971
|
return envNames[account.id] ?? `${upper(account.id)}_API_KEY`;
|
|
42878
42972
|
}
|
|
@@ -42887,6 +42981,48 @@ var accountStatus = {
|
|
|
42887
42981
|
"needs-sign-in": ["neutral", "Needs sign-in"],
|
|
42888
42982
|
"sign-in-expired": ["notice", "Sign-in expired"]
|
|
42889
42983
|
};
|
|
42984
|
+
var authHints = {
|
|
42985
|
+
"api-key": "API key",
|
|
42986
|
+
oauth: "Sign in",
|
|
42987
|
+
fields: "Endpoint and key",
|
|
42988
|
+
local: "On this device"
|
|
42989
|
+
};
|
|
42990
|
+
var listOrder = {
|
|
42991
|
+
connected: 0,
|
|
42992
|
+
expired: 1,
|
|
42993
|
+
"signing-in": 2,
|
|
42994
|
+
disconnected: 3
|
|
42995
|
+
};
|
|
42996
|
+
var corsNotice = {
|
|
42997
|
+
short: "Needs the SLICC extension or CLI",
|
|
42998
|
+
long: "Needs the SLICC extension or CLI, because the browser blocks direct requests to it."
|
|
42999
|
+
};
|
|
43000
|
+
var removeBodies = {
|
|
43001
|
+
oauth: "Its sign-in is deleted from the vault. Models from it stop working.",
|
|
43002
|
+
local: "Models from it stop working."
|
|
43003
|
+
};
|
|
43004
|
+
function draft(option2) {
|
|
43005
|
+
return {
|
|
43006
|
+
id: option2.id,
|
|
43007
|
+
provider: option2.name,
|
|
43008
|
+
identity: "",
|
|
43009
|
+
status: "disconnected",
|
|
43010
|
+
group: "providers",
|
|
43011
|
+
store: "vault",
|
|
43012
|
+
auth: option2.auth === "fields" ? "api-key" : option2.auth,
|
|
43013
|
+
fields: option2.fields,
|
|
43014
|
+
keyUrl: option2.keyUrl,
|
|
43015
|
+
needs: option2.needs,
|
|
43016
|
+
vaultName: option2.vaultName
|
|
43017
|
+
};
|
|
43018
|
+
}
|
|
43019
|
+
function matchProviders(options, query) {
|
|
43020
|
+
const words = query.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
43021
|
+
return options.filter((option2) => {
|
|
43022
|
+
const text2 = `${option2.name} ${option2.id} ${option2.description ?? ""}`.toLowerCase();
|
|
43023
|
+
return words.every((word) => text2.includes(word));
|
|
43024
|
+
});
|
|
43025
|
+
}
|
|
42890
43026
|
var popup = (account) => account.group === "mcp" && account.auth === "oauth";
|
|
42891
43027
|
var secretNames = { "api-key": "API key", token: "token" };
|
|
42892
43028
|
var rejectedNames = { "api-key": "API key rejected", token: "Token rejected" };
|
|
@@ -42906,8 +43042,15 @@ var SliccSettings = class extends ThemedElement {
|
|
|
42906
43042
|
entering: { state: true },
|
|
42907
43043
|
failure: { state: true },
|
|
42908
43044
|
problem: { state: true },
|
|
42909
|
-
blocked: { state: true }
|
|
43045
|
+
blocked: { state: true },
|
|
43046
|
+
picking: { state: true },
|
|
43047
|
+
adding: { state: true },
|
|
43048
|
+
query: { state: true },
|
|
43049
|
+
filled: { state: true }
|
|
42910
43050
|
};
|
|
43051
|
+
#waits = new SignInWaits(() => this.requestUpdate());
|
|
43052
|
+
#landing = null;
|
|
43053
|
+
#bases = /* @__PURE__ */ new Map();
|
|
42911
43054
|
#scroll = new ViewScroll(this, "settings:scroll", { scroller: () => this, rows: "[data-id]" });
|
|
42912
43055
|
constructor() {
|
|
42913
43056
|
super();
|
|
@@ -42916,9 +43059,16 @@ var SliccSettings = class extends ThemedElement {
|
|
|
42916
43059
|
this.failure = null;
|
|
42917
43060
|
this.problem = null;
|
|
42918
43061
|
this.blocked = false;
|
|
43062
|
+
this.picking = false;
|
|
43063
|
+
this.adding = null;
|
|
43064
|
+
this.query = "";
|
|
43065
|
+
this.filled = /* @__PURE__ */ new Set();
|
|
42919
43066
|
}
|
|
42920
43067
|
static styles = [
|
|
42921
43068
|
fieldStyles,
|
|
43069
|
+
dialogFrame,
|
|
43070
|
+
searchCss,
|
|
43071
|
+
r(link_default),
|
|
42922
43072
|
i`
|
|
42923
43073
|
:host {
|
|
42924
43074
|
display: block;
|
|
@@ -43030,6 +43180,144 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43030
43180
|
line-height: var(--swc-line-height-200);
|
|
43031
43181
|
--swc-icon-color: var(--swc-negative-content-color-default);
|
|
43032
43182
|
}
|
|
43183
|
+
.actions {
|
|
43184
|
+
display: flex;
|
|
43185
|
+
align-items: center;
|
|
43186
|
+
gap: var(--swc-spacing-75);
|
|
43187
|
+
}
|
|
43188
|
+
.notes {
|
|
43189
|
+
grid-column: 1 / -1;
|
|
43190
|
+
display: grid;
|
|
43191
|
+
gap: var(--swc-spacing-75);
|
|
43192
|
+
margin-block-start: calc(-1 * var(--swc-spacing-200));
|
|
43193
|
+
}
|
|
43194
|
+
.notice {
|
|
43195
|
+
display: flex;
|
|
43196
|
+
align-items: flex-start;
|
|
43197
|
+
gap: var(--swc-spacing-75);
|
|
43198
|
+
margin: 0;
|
|
43199
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
43200
|
+
font-size: var(--swc-font-size-75);
|
|
43201
|
+
line-height: var(--swc-line-height-200);
|
|
43202
|
+
--swc-icon-color: var(--swc-notice-visual-color);
|
|
43203
|
+
}
|
|
43204
|
+
.notice swc-icon-alert-triangle {
|
|
43205
|
+
flex: none;
|
|
43206
|
+
margin-block-start: var(--swc-spacing-50);
|
|
43207
|
+
}
|
|
43208
|
+
.add {
|
|
43209
|
+
margin-block-start: var(--swc-spacing-200);
|
|
43210
|
+
margin-inline-start: calc(-1 * var(--swc-spacing-100));
|
|
43211
|
+
}
|
|
43212
|
+
dialog.picker {
|
|
43213
|
+
inline-size: min(520px, calc(100vw - 2 * var(--swc-spacing-300)));
|
|
43214
|
+
}
|
|
43215
|
+
.picker .head {
|
|
43216
|
+
display: flex;
|
|
43217
|
+
align-items: center;
|
|
43218
|
+
justify-content: space-between;
|
|
43219
|
+
gap: var(--swc-spacing-200);
|
|
43220
|
+
padding: var(--swc-spacing-400) var(--swc-spacing-300) var(--swc-spacing-200) var(--swc-spacing-500);
|
|
43221
|
+
}
|
|
43222
|
+
.picker h2 {
|
|
43223
|
+
margin: 0;
|
|
43224
|
+
font-size: var(--swc-heading-size-s);
|
|
43225
|
+
overflow-wrap: anywhere;
|
|
43226
|
+
}
|
|
43227
|
+
.picker .find {
|
|
43228
|
+
display: flex;
|
|
43229
|
+
padding: var(--swc-spacing-100) var(--swc-spacing-500) var(--swc-spacing-200);
|
|
43230
|
+
}
|
|
43231
|
+
.picker .results {
|
|
43232
|
+
block-size: min(400px, calc(100dvh - 280px));
|
|
43233
|
+
overflow-y: auto;
|
|
43234
|
+
overscroll-behavior: contain;
|
|
43235
|
+
padding: var(--swc-spacing-75) var(--swc-spacing-400);
|
|
43236
|
+
border-block: var(--swc-border-width-100) solid var(--swc-gray-200);
|
|
43237
|
+
}
|
|
43238
|
+
.options {
|
|
43239
|
+
display: grid;
|
|
43240
|
+
gap: var(--swc-spacing-50);
|
|
43241
|
+
}
|
|
43242
|
+
.option {
|
|
43243
|
+
display: grid;
|
|
43244
|
+
grid-template-columns: minmax(0, 1fr) max-content;
|
|
43245
|
+
align-items: baseline;
|
|
43246
|
+
gap: var(--swc-spacing-50) var(--swc-spacing-300);
|
|
43247
|
+
padding: var(--swc-spacing-100) var(--swc-spacing-100);
|
|
43248
|
+
border-radius: var(--swc-corner-radius-medium-default);
|
|
43249
|
+
cursor: pointer;
|
|
43250
|
+
}
|
|
43251
|
+
.option:hover,
|
|
43252
|
+
.option:focus {
|
|
43253
|
+
background: var(--swc-gray-200);
|
|
43254
|
+
}
|
|
43255
|
+
.option:focus {
|
|
43256
|
+
outline: none;
|
|
43257
|
+
}
|
|
43258
|
+
.option:focus-visible {
|
|
43259
|
+
outline: var(--swc-focus-indicator-thickness) solid var(--swc-focus-indicator-color);
|
|
43260
|
+
outline-offset: calc(-1 * var(--swc-focus-indicator-thickness));
|
|
43261
|
+
}
|
|
43262
|
+
.option[aria-disabled='true'] {
|
|
43263
|
+
cursor: default;
|
|
43264
|
+
}
|
|
43265
|
+
.option[aria-disabled='true']:hover {
|
|
43266
|
+
background: none;
|
|
43267
|
+
}
|
|
43268
|
+
.option .name {
|
|
43269
|
+
font-weight: var(--swc-bold-font-weight);
|
|
43270
|
+
overflow-wrap: anywhere;
|
|
43271
|
+
}
|
|
43272
|
+
.option[aria-disabled='true'] .name {
|
|
43273
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
43274
|
+
}
|
|
43275
|
+
.option .tag {
|
|
43276
|
+
justify-self: end;
|
|
43277
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
43278
|
+
font-size: var(--swc-font-size-75);
|
|
43279
|
+
}
|
|
43280
|
+
.added {
|
|
43281
|
+
display: inline-flex;
|
|
43282
|
+
align-items: center;
|
|
43283
|
+
gap: var(--swc-spacing-50);
|
|
43284
|
+
}
|
|
43285
|
+
.option .description,
|
|
43286
|
+
.option .notice {
|
|
43287
|
+
grid-column: 1 / -1;
|
|
43288
|
+
}
|
|
43289
|
+
.option .description,
|
|
43290
|
+
.lead,
|
|
43291
|
+
.empty {
|
|
43292
|
+
margin: 0;
|
|
43293
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
43294
|
+
}
|
|
43295
|
+
.empty {
|
|
43296
|
+
padding: var(--swc-spacing-200) var(--swc-spacing-100);
|
|
43297
|
+
overflow-wrap: anywhere;
|
|
43298
|
+
}
|
|
43299
|
+
.picker .end {
|
|
43300
|
+
justify-content: flex-end;
|
|
43301
|
+
padding: var(--swc-spacing-300) var(--swc-spacing-500) var(--swc-spacing-400);
|
|
43302
|
+
}
|
|
43303
|
+
.step {
|
|
43304
|
+
display: grid;
|
|
43305
|
+
gap: var(--swc-spacing-200);
|
|
43306
|
+
padding: var(--swc-spacing-100) var(--swc-spacing-500) var(--swc-spacing-500);
|
|
43307
|
+
}
|
|
43308
|
+
.step .key.stacked {
|
|
43309
|
+
max-width: none;
|
|
43310
|
+
}
|
|
43311
|
+
.step sp-textfield {
|
|
43312
|
+
inline-size: 100%;
|
|
43313
|
+
}
|
|
43314
|
+
.step .buttons {
|
|
43315
|
+
margin-block-start: var(--swc-spacing-200);
|
|
43316
|
+
}
|
|
43317
|
+
.get-key {
|
|
43318
|
+
justify-self: start;
|
|
43319
|
+
font-size: var(--swc-font-size-75);
|
|
43320
|
+
}
|
|
43033
43321
|
@container (max-width: 480px) {
|
|
43034
43322
|
.page {
|
|
43035
43323
|
padding-inline: var(--swc-spacing-300);
|
|
@@ -43060,7 +43348,8 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43060
43348
|
.state {
|
|
43061
43349
|
grid-area: state;
|
|
43062
43350
|
}
|
|
43063
|
-
.account swc-button
|
|
43351
|
+
.account swc-button,
|
|
43352
|
+
.account .actions {
|
|
43064
43353
|
grid-area: action;
|
|
43065
43354
|
}
|
|
43066
43355
|
.key sp-textfield {
|
|
@@ -43080,6 +43369,7 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43080
43369
|
...super.subscribe(model),
|
|
43081
43370
|
model.settings.on("settings", settle2),
|
|
43082
43371
|
model.settings.on("accounts", settle2),
|
|
43372
|
+
model.settings.on("providers", update),
|
|
43083
43373
|
...model.vault ? [model.vault.on("status", update)] : []
|
|
43084
43374
|
];
|
|
43085
43375
|
}
|
|
@@ -43126,6 +43416,7 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43126
43416
|
try {
|
|
43127
43417
|
await (fields ? settings?.connect(id, secret, fields) : secret === void 0 ? settings?.connect(id) : settings?.connect(id, secret));
|
|
43128
43418
|
if (this.entering === id) this.entering = null;
|
|
43419
|
+
if (this.adding?.id === id && this.#added(id)?.status === "connected") this.#finish(id);
|
|
43129
43420
|
} catch (error) {
|
|
43130
43421
|
if (!this.#cancelled.has(id)) this.failure = { id, message: error.message };
|
|
43131
43422
|
} finally {
|
|
@@ -43161,7 +43452,82 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43161
43452
|
this.#busy(id, false);
|
|
43162
43453
|
return;
|
|
43163
43454
|
}
|
|
43164
|
-
await this
|
|
43455
|
+
await this.#connectBases(account, void 0, fields, vault);
|
|
43456
|
+
}
|
|
43457
|
+
#baseOf(value) {
|
|
43458
|
+
const trimmed = value?.trim() ?? "";
|
|
43459
|
+
try {
|
|
43460
|
+
return new URL(trimmed).protocol === "https:" ? trimmed : void 0;
|
|
43461
|
+
} catch {
|
|
43462
|
+
return void 0;
|
|
43463
|
+
}
|
|
43464
|
+
}
|
|
43465
|
+
#oldBase(account, field) {
|
|
43466
|
+
return this.#baseOf(field.value) ?? this.#bases.get(`${account.id} ${field.name}`);
|
|
43467
|
+
}
|
|
43468
|
+
#baseChanges(account, fields) {
|
|
43469
|
+
return (account.fields ?? []).filter((field) => field.customBase).map((field) => ({
|
|
43470
|
+
field: field.name,
|
|
43471
|
+
url: this.#baseOf(fields?.[field.name]),
|
|
43472
|
+
old: this.#oldBase(account, field)
|
|
43473
|
+
})).filter((change) => change.url !== change.old);
|
|
43474
|
+
}
|
|
43475
|
+
#modelChange(name, changes2, from, to) {
|
|
43476
|
+
const entries = (key2) => changes2.flatMap((change) => change[key2] ? [{ name, url: change[key2] }] : []);
|
|
43477
|
+
const remove2 = entries(from);
|
|
43478
|
+
const add = entries(to);
|
|
43479
|
+
if (!remove2.length && !add.length) return null;
|
|
43480
|
+
return {
|
|
43481
|
+
...remove2.length ? { remove: { model: remove2 } } : {},
|
|
43482
|
+
...add.length ? { add: { model: add } } : {}
|
|
43483
|
+
};
|
|
43484
|
+
}
|
|
43485
|
+
async #connectBases(account, secret, fields, vault = null) {
|
|
43486
|
+
const model = this.model;
|
|
43487
|
+
const live = vault?.endpoints ? vault : null;
|
|
43488
|
+
const { id } = account;
|
|
43489
|
+
const name = recordName(account);
|
|
43490
|
+
const changes2 = this.#baseChanges(account, fields);
|
|
43491
|
+
const forward = live ? this.#modelChange(name, changes2, "old", "url") : null;
|
|
43492
|
+
if (forward) {
|
|
43493
|
+
this.#busy(id, true);
|
|
43494
|
+
try {
|
|
43495
|
+
await live?.endpoints?.(forward);
|
|
43496
|
+
} catch (error) {
|
|
43497
|
+
this.#busy(id, false);
|
|
43498
|
+
const field = changes2.find((change) => change.url) ?? changes2[0];
|
|
43499
|
+
if (this.model === model) this.#refuse(id, field.field, failureText(error));
|
|
43500
|
+
return;
|
|
43501
|
+
}
|
|
43502
|
+
if (this.model !== model) {
|
|
43503
|
+
this.#busy(id, false);
|
|
43504
|
+
return;
|
|
43505
|
+
}
|
|
43506
|
+
}
|
|
43507
|
+
await this.connect(id, secret, fields);
|
|
43508
|
+
if (this.failure?.id === id) {
|
|
43509
|
+
this.#placeFailure(account, fields);
|
|
43510
|
+
const back = forward ? this.#modelChange(name, changes2, "url", "old") : null;
|
|
43511
|
+
if (back) await live?.endpoints?.(back).catch(() => {
|
|
43512
|
+
});
|
|
43513
|
+
return;
|
|
43514
|
+
}
|
|
43515
|
+
for (const change of changes2) {
|
|
43516
|
+
const key2 = `${id} ${change.field}`;
|
|
43517
|
+
if (change.url) this.#bases.set(key2, change.url);
|
|
43518
|
+
else this.#bases.delete(key2);
|
|
43519
|
+
}
|
|
43520
|
+
}
|
|
43521
|
+
#placeFailure(account, fields) {
|
|
43522
|
+
const message = this.failure.message;
|
|
43523
|
+
const field = (account.fields ?? []).find(
|
|
43524
|
+
(candidate) => candidate.customBase && !!fields?.[candidate.name] && [candidate.name, candidate.label, "https", "url", "port", "userinfo"].some(
|
|
43525
|
+
(word) => new RegExp(`\\b${word.replace(/[^a-z0-9 ]/gi, "\\$&")}\\b`, "i").test(message)
|
|
43526
|
+
)
|
|
43527
|
+
);
|
|
43528
|
+
if (!field) return;
|
|
43529
|
+
this.failure = null;
|
|
43530
|
+
this.#refuse(account.id, field.name, message);
|
|
43165
43531
|
}
|
|
43166
43532
|
#refuse(id, field, message) {
|
|
43167
43533
|
this.problem = { id, field, message };
|
|
@@ -43185,13 +43551,25 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43185
43551
|
}
|
|
43186
43552
|
return values;
|
|
43187
43553
|
}
|
|
43554
|
+
#added(id) {
|
|
43555
|
+
return this.model?.settings.accounts().find((account) => account.id === id);
|
|
43556
|
+
}
|
|
43557
|
+
#offered() {
|
|
43558
|
+
return this.model?.settings.providers?.() ?? null;
|
|
43559
|
+
}
|
|
43188
43560
|
#start(account) {
|
|
43189
43561
|
if (account.auth !== "api-key") {
|
|
43190
43562
|
void this.connect(account.id);
|
|
43191
43563
|
return;
|
|
43192
43564
|
}
|
|
43565
|
+
this.#enter(account);
|
|
43566
|
+
}
|
|
43567
|
+
#enter(account) {
|
|
43193
43568
|
this.failure = null;
|
|
43194
43569
|
this.problem = null;
|
|
43570
|
+
this.filled = new Set(
|
|
43571
|
+
(account.fields ?? []).filter((field) => field.options || field.value?.trim()).map((field) => field.name)
|
|
43572
|
+
);
|
|
43195
43573
|
this.entering = account.id;
|
|
43196
43574
|
void this.updateComplete.then(() => this.focusOn(".key sp-textfield", ".key input"));
|
|
43197
43575
|
}
|
|
@@ -43199,6 +43577,7 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43199
43577
|
event2.preventDefault();
|
|
43200
43578
|
const form = event2.currentTarget;
|
|
43201
43579
|
this.problem = null;
|
|
43580
|
+
this.filled = new Set([...this.filled].filter((name) => name !== "value"));
|
|
43202
43581
|
if (this.#vault(account)) {
|
|
43203
43582
|
const value = take(form.querySelector("input[data-field=value]"));
|
|
43204
43583
|
const fields2 = this.#fields(form, account);
|
|
@@ -43209,7 +43588,7 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43209
43588
|
const secret = field.value.trim();
|
|
43210
43589
|
field.value = "";
|
|
43211
43590
|
const fields = this.#fields(form, account);
|
|
43212
|
-
if (secret && fields !== null) void this
|
|
43591
|
+
if (secret && fields !== null) void this.#connectBases(account, secret, fields);
|
|
43213
43592
|
}
|
|
43214
43593
|
#submitOnEnter(event2) {
|
|
43215
43594
|
const target2 = event2.target;
|
|
@@ -43220,7 +43599,7 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43220
43599
|
#send(event2) {
|
|
43221
43600
|
event2.currentTarget.closest("form")?.requestSubmit();
|
|
43222
43601
|
}
|
|
43223
|
-
#
|
|
43602
|
+
#enterKey(event2) {
|
|
43224
43603
|
if (event2.key === "Enter") this.#send(event2);
|
|
43225
43604
|
}
|
|
43226
43605
|
#cancel() {
|
|
@@ -43248,9 +43627,15 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43248
43627
|
(field) => b`<label class="field">
|
|
43249
43628
|
<span>${field.label}</span>${this.#control(account, field)}
|
|
43250
43629
|
</label>
|
|
43630
|
+
${field.help ? b`<p class="hint" id=${`help-${field.name}`}>${field.help}</p>` : A}
|
|
43251
43631
|
${this.#problem(account, field.name)}`
|
|
43252
43632
|
);
|
|
43253
43633
|
}
|
|
43634
|
+
#describedBy(account, field) {
|
|
43635
|
+
const problem = this.#described(account, field.name);
|
|
43636
|
+
const ids = [problem === A ? "" : problem, field.help ? `help-${field.name}` : ""];
|
|
43637
|
+
return ids.filter(Boolean).join(" ") || A;
|
|
43638
|
+
}
|
|
43254
43639
|
#control(account, field) {
|
|
43255
43640
|
if (field.options) {
|
|
43256
43641
|
const chosen = field.value ?? field.options[0]?.value;
|
|
@@ -43259,7 +43644,7 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43259
43644
|
?disabled=${!field.options.length}
|
|
43260
43645
|
aria-required=${field.required ? "true" : A}
|
|
43261
43646
|
aria-invalid=${this.#invalid(account, field.name)}
|
|
43262
|
-
aria-describedby=${this.#
|
|
43647
|
+
aria-describedby=${this.#describedBy(account, field)}
|
|
43263
43648
|
>
|
|
43264
43649
|
${field.options.map((option2) => b`<option value=${option2.value} ?selected=${option2.value === chosen}>${option2.label}</option>`)}
|
|
43265
43650
|
</select>`;
|
|
@@ -43269,11 +43654,35 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43269
43654
|
autocomplete="off"
|
|
43270
43655
|
spellcheck="false"
|
|
43271
43656
|
data-account-field=${field.name}
|
|
43657
|
+
value=${field.value ?? A}
|
|
43658
|
+
placeholder=${field.placeholder ?? A}
|
|
43272
43659
|
aria-required=${field.required ? "true" : A}
|
|
43273
43660
|
aria-invalid=${this.#invalid(account, field.name)}
|
|
43274
|
-
aria-describedby=${this.#
|
|
43661
|
+
aria-describedby=${this.#describedBy(account, field)}
|
|
43275
43662
|
/>`;
|
|
43276
43663
|
}
|
|
43664
|
+
#getKey(account) {
|
|
43665
|
+
if (!account.keyUrl) return A;
|
|
43666
|
+
return b`<a class="swc-Link get-key" href=${account.keyUrl} target="_blank" rel="noopener noreferrer" data-action="get-key">Get a key</a>`;
|
|
43667
|
+
}
|
|
43668
|
+
#leave(account) {
|
|
43669
|
+
const adding = this.adding?.id === account.id;
|
|
43670
|
+
return b`<swc-button size="m" variant="secondary" data-action=${adding ? "back" : "cancel"} @click=${() => adding ? this.#back() : this.#cancel()}>${adding ? "Back" : "Cancel"}</swc-button>`;
|
|
43671
|
+
}
|
|
43672
|
+
#saveLabel(account) {
|
|
43673
|
+
return this.adding?.id === account.id ? "Connect" : "Save";
|
|
43674
|
+
}
|
|
43675
|
+
#ready(account) {
|
|
43676
|
+
if (!this.#offered()) return true;
|
|
43677
|
+
const required = (account.fields ?? []).filter((field) => field.required);
|
|
43678
|
+
return ["value", ...required.map((field) => field.name)].every((name) => this.filled.has(name));
|
|
43679
|
+
}
|
|
43680
|
+
#fill(event2) {
|
|
43681
|
+
const input = event2.target;
|
|
43682
|
+
const name = input.dataset.accountField ?? "value";
|
|
43683
|
+
const rest = [...this.filled].filter((candidate) => candidate !== name);
|
|
43684
|
+
this.filled = new Set(input.value.trim() ? [...rest, name] : rest);
|
|
43685
|
+
}
|
|
43277
43686
|
#unlock(vault) {
|
|
43278
43687
|
return b`<div class="locked" data-locked>
|
|
43279
43688
|
<span>Unlock the vault first</span>
|
|
@@ -43292,7 +43701,7 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43292
43701
|
const busy = this.pending.has(account.id);
|
|
43293
43702
|
const locked = !!vault.status()?.locked;
|
|
43294
43703
|
const name = secretNames[account.secret ?? "api-key"];
|
|
43295
|
-
return b`<form class="key stacked" data-id=${account.id} data-store="vault" @submit=${(event2) => this.#submit(event2, account)} @keydown=${(event2) => this.#submitOnEnter(event2)}>
|
|
43704
|
+
return b`<form class="key stacked" data-id=${account.id} data-store="vault" @submit=${(event2) => this.#submit(event2, account)} @keydown=${(event2) => this.#submitOnEnter(event2)} @input=${(event2) => this.#fill(event2)}>
|
|
43296
43705
|
<label class="field"><span>${account.provider} ${name}</span><input
|
|
43297
43706
|
type="password"
|
|
43298
43707
|
autocomplete="off"
|
|
@@ -43303,11 +43712,12 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43303
43712
|
aria-describedby=${this.#described(account, "value")}
|
|
43304
43713
|
/></label>
|
|
43305
43714
|
${this.#problem(account, "value")}
|
|
43306
|
-
${this.#extra(account)}
|
|
43307
43715
|
${locked ? this.#unlock(vault) : b`<p class="hint">Saved in the vault</p>`}
|
|
43716
|
+
${this.#getKey(account)}
|
|
43717
|
+
${this.#extra(account)}
|
|
43308
43718
|
<div class="buttons">
|
|
43309
|
-
<swc-button size="m" variant="accent" data-action="save" ?pending=${busy} ?disabled=${locked} @click=${(event2) => this.#send(event2)}
|
|
43310
|
-
|
|
43719
|
+
<swc-button size="m" variant="accent" data-action="save" ?pending=${busy} ?disabled=${locked || !busy && !this.#ready(account)} @click=${(event2) => this.#send(event2)}>${this.#saveLabel(account)}</swc-button>
|
|
43720
|
+
${this.#leave(account)}
|
|
43311
43721
|
</div>
|
|
43312
43722
|
</form>`;
|
|
43313
43723
|
}
|
|
@@ -43316,23 +43726,24 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43316
43726
|
const vault = this.#vault(account);
|
|
43317
43727
|
if (vault) return this.#kept(account, vault);
|
|
43318
43728
|
const busy = this.pending.has(account.id);
|
|
43319
|
-
const extra = account.fields?.length;
|
|
43320
|
-
return b`<form class=${extra ? "key stacked" : "key"} data-id=${account.id} @submit=${(event2) => this.#submit(event2, account)} @keydown=${(event2) => this.#submitOnEnter(event2)}>
|
|
43729
|
+
const extra = account.fields?.length || account.keyUrl;
|
|
43730
|
+
return b`<form class=${extra ? "key stacked" : "key"} data-id=${account.id} @submit=${(event2) => this.#submit(event2, account)} @keydown=${(event2) => this.#submitOnEnter(event2)} @input=${(event2) => this.#fill(event2)}>
|
|
43321
43731
|
<sp-textfield
|
|
43322
43732
|
size="m"
|
|
43323
43733
|
type="password"
|
|
43324
43734
|
autocomplete="off"
|
|
43325
43735
|
label=${`${account.provider} ${secretNames[account.secret ?? "api-key"]}`}
|
|
43326
43736
|
placeholder=${`Paste the ${secretNames[account.secret ?? "api-key"]}`}
|
|
43327
|
-
@keydown=${(event2) => this.#
|
|
43737
|
+
@keydown=${(event2) => this.#enterKey(event2)}
|
|
43328
43738
|
></sp-textfield>
|
|
43739
|
+
${this.#getKey(account)}
|
|
43329
43740
|
${extra ? this.#extra(account) : A}
|
|
43330
|
-
${extra ? b`<div class="buttons">${this.#buttons(busy)}</div>` : this.#buttons(busy)}
|
|
43741
|
+
${extra ? b`<div class="buttons">${this.#buttons(account, busy)}</div>` : this.#buttons(account, busy)}
|
|
43331
43742
|
</form>`;
|
|
43332
43743
|
}
|
|
43333
|
-
#buttons(busy) {
|
|
43334
|
-
return b`<swc-button size="m" variant="accent" data-action="save" ?pending=${busy} @click=${(event2) => this.#send(event2)}
|
|
43335
|
-
|
|
43744
|
+
#buttons(account, busy) {
|
|
43745
|
+
return b`<swc-button size="m" variant="accent" data-action="save" ?pending=${busy} ?disabled=${!busy && !this.#ready(account)} @click=${(event2) => this.#send(event2)}>${this.#saveLabel(account)}</swc-button>
|
|
43746
|
+
${this.#leave(account)}`;
|
|
43336
43747
|
}
|
|
43337
43748
|
#inVault(account) {
|
|
43338
43749
|
const vault = this.model?.vault;
|
|
@@ -43384,7 +43795,8 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43384
43795
|
get busyReason() {
|
|
43385
43796
|
const accounts = this.model?.settings.accounts() ?? [];
|
|
43386
43797
|
if (accounts.some((account) => this.#signingIn(account))) return "signing in";
|
|
43387
|
-
|
|
43798
|
+
if (this.entering !== null) return "a key is being entered";
|
|
43799
|
+
return this.picking ? "a provider is being added" : null;
|
|
43388
43800
|
}
|
|
43389
43801
|
#signingIn(account) {
|
|
43390
43802
|
return account.status === "signing-in" || account.auth !== "api-key" && account.status !== "connected" && this.pending.has(account.id);
|
|
@@ -43441,10 +43853,266 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43441
43853
|
<span class="provider">${account.provider}</span>
|
|
43442
43854
|
<span class="identity">${account.identity}${this.#inVault(account) ? b`<span class="kept" data-store="vault">${account.identity ? " \xB7 " : ""}${kept2(account)}</span>` : A}</span>
|
|
43443
43855
|
<swc-status-light class="state" variant=${variant}>${label}</swc-status-light>
|
|
43444
|
-
${this.#action(account)}
|
|
43856
|
+
${this.#removable(account) ? b`<div class="actions">${this.#action(account)}${this.#removeButton(account)}</div>` : this.#action(account)}
|
|
43445
43857
|
</div>
|
|
43446
|
-
${this.#
|
|
43447
|
-
${failure2}`;
|
|
43858
|
+
${this.#offered() ? this.#rowNotes(account) : A}
|
|
43859
|
+
${this.adding?.id === account.id ? A : b`${this.#key(account)}${failure2}`}`;
|
|
43860
|
+
}
|
|
43861
|
+
#removable(account) {
|
|
43862
|
+
return !!this.#offered() && !!this.model?.settings.remove && account.group !== "mcp";
|
|
43863
|
+
}
|
|
43864
|
+
#removeButton(account) {
|
|
43865
|
+
const id = `remove-${account.id}`;
|
|
43866
|
+
const label = `Remove ${account.provider}`;
|
|
43867
|
+
return b`<swc-action-button
|
|
43868
|
+
id=${id}
|
|
43869
|
+
size="m"
|
|
43870
|
+
quiet
|
|
43871
|
+
data-action="remove-account"
|
|
43872
|
+
accessible-label=${label}
|
|
43873
|
+
?disabled=${this.pending.has(account.id)}
|
|
43874
|
+
@click=${() => this.#remove(account)}
|
|
43875
|
+
><swc-icon-delete slot="icon"></swc-icon-delete></swc-action-button
|
|
43876
|
+
><swc-tooltip for=${id} placement="top">${label}</swc-tooltip>`;
|
|
43877
|
+
}
|
|
43878
|
+
async #remove(account) {
|
|
43879
|
+
const model = this.model;
|
|
43880
|
+
const body4 = removeBodies[account.auth ?? ""] ?? "Its key is deleted from the vault. Models from it stop working.";
|
|
43881
|
+
const title = `Remove ${account.provider}?`;
|
|
43882
|
+
if (!await confirm({ title, body: body4, action: "Remove" })) return;
|
|
43883
|
+
if (this.model !== model) return;
|
|
43884
|
+
clearValues(this.renderRoot);
|
|
43885
|
+
if (this.entering === account.id) this.entering = null;
|
|
43886
|
+
const vault = model.vault;
|
|
43887
|
+
const keyed = account.store === "vault" && account.auth === "api-key" && !!vault?.remove;
|
|
43888
|
+
if (keyed && !await this.#forget(account, vault)) return;
|
|
43889
|
+
if (this.model !== model) return;
|
|
43890
|
+
this.#busy(account.id, true);
|
|
43891
|
+
this.failure = null;
|
|
43892
|
+
try {
|
|
43893
|
+
await model.settings.remove?.(account.id);
|
|
43894
|
+
} catch (error) {
|
|
43895
|
+
if (this.model === model) this.failure = { id: account.id, message: failureText(error) };
|
|
43896
|
+
return;
|
|
43897
|
+
} finally {
|
|
43898
|
+
this.#busy(account.id, false);
|
|
43899
|
+
}
|
|
43900
|
+
this.focusOn("[data-action=add-provider]");
|
|
43901
|
+
for (const field of account.fields ?? []) this.#bases.delete(`${account.id} ${field.name}`);
|
|
43902
|
+
}
|
|
43903
|
+
#notice(needs, size4 = "long") {
|
|
43904
|
+
if (needs !== "cors-free-transport") return A;
|
|
43905
|
+
return b`<p class="notice" data-notice=${needs}><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><span>${corsNotice[size4]}</span></p>`;
|
|
43906
|
+
}
|
|
43907
|
+
#signingNote(account) {
|
|
43908
|
+
const key2 = `settings:${account.id}`;
|
|
43909
|
+
if (account.auth !== "oauth" || !this.#signingIn(account)) {
|
|
43910
|
+
this.#waits.done(key2);
|
|
43911
|
+
return A;
|
|
43912
|
+
}
|
|
43913
|
+
return b`<p class="hint" role="status" data-signing>${signInText(this.#waits.waited(key2))}</p>`;
|
|
43914
|
+
}
|
|
43915
|
+
#rowNotes(account) {
|
|
43916
|
+
const notice = this.#notice(account.needs);
|
|
43917
|
+
const signing = this.adding?.id === account.id ? A : this.#signingNote(account);
|
|
43918
|
+
if (notice === A && signing === A) return A;
|
|
43919
|
+
return b`<div class="notes">${notice}${signing}</div>`;
|
|
43920
|
+
}
|
|
43921
|
+
#openPicker() {
|
|
43922
|
+
this.query = "";
|
|
43923
|
+
this.adding = null;
|
|
43924
|
+
this.picking = true;
|
|
43925
|
+
}
|
|
43926
|
+
updated(changed) {
|
|
43927
|
+
super.updated(changed);
|
|
43928
|
+
const dialog = this.#dialog;
|
|
43929
|
+
if (!changed.has("picking") || !dialog || dialog.open) return;
|
|
43930
|
+
dialog.showModal();
|
|
43931
|
+
const field = this.renderRoot.querySelector("sp-search");
|
|
43932
|
+
void field.updateComplete.then(() => field.focus());
|
|
43933
|
+
}
|
|
43934
|
+
get #dialog() {
|
|
43935
|
+
return this.renderRoot.querySelector("dialog.picker");
|
|
43936
|
+
}
|
|
43937
|
+
#closePicker() {
|
|
43938
|
+
this.#dialog?.close();
|
|
43939
|
+
}
|
|
43940
|
+
#closed() {
|
|
43941
|
+
const id = this.adding?.id;
|
|
43942
|
+
if (id !== void 0 && this.entering === id) {
|
|
43943
|
+
clearValues(this.renderRoot);
|
|
43944
|
+
this.entering = null;
|
|
43945
|
+
this.problem = null;
|
|
43946
|
+
}
|
|
43947
|
+
if (id !== void 0 && this.failure?.id === id) this.failure = null;
|
|
43948
|
+
this.picking = false;
|
|
43949
|
+
this.adding = null;
|
|
43950
|
+
this.query = "";
|
|
43951
|
+
const landing = this.#landing;
|
|
43952
|
+
this.#landing = null;
|
|
43953
|
+
void this.updateComplete.then(() => {
|
|
43954
|
+
const root2 = this.renderRoot;
|
|
43955
|
+
const row = landing ? root2.querySelector(`.account[data-id="${CSS.escape(landing)}"] swc-button`) : null;
|
|
43956
|
+
(row ?? root2.querySelector("[data-action=add-provider]"))?.focus();
|
|
43957
|
+
});
|
|
43958
|
+
}
|
|
43959
|
+
#finish(id) {
|
|
43960
|
+
this.#landing = id;
|
|
43961
|
+
this.#closePicker();
|
|
43962
|
+
}
|
|
43963
|
+
#choose(option2) {
|
|
43964
|
+
if (this.#added(option2.id)) return;
|
|
43965
|
+
this.adding = option2;
|
|
43966
|
+
this.failure = null;
|
|
43967
|
+
if (option2.auth === "api-key" || option2.auth === "fields") {
|
|
43968
|
+
this.#enter(draft(option2));
|
|
43969
|
+
return;
|
|
43970
|
+
}
|
|
43971
|
+
void this.updateComplete.then(
|
|
43972
|
+
() => this.focusOn("[data-step] [data-action=sign-in]", "[data-step] [data-action=connect]")
|
|
43973
|
+
);
|
|
43974
|
+
}
|
|
43975
|
+
#back() {
|
|
43976
|
+
const id = this.adding.id;
|
|
43977
|
+
clearValues(this.renderRoot);
|
|
43978
|
+
if (this.entering === id) this.entering = null;
|
|
43979
|
+
if (this.failure?.id === id) this.failure = null;
|
|
43980
|
+
this.problem = null;
|
|
43981
|
+
this.adding = null;
|
|
43982
|
+
void this.updateComplete.then(
|
|
43983
|
+
() => this.renderRoot.querySelector(`.option[data-provider="${CSS.escape(id)}"]`)?.focus()
|
|
43984
|
+
);
|
|
43985
|
+
}
|
|
43986
|
+
#options() {
|
|
43987
|
+
return [...this.renderRoot.querySelectorAll(".option")];
|
|
43988
|
+
}
|
|
43989
|
+
#pickerKey(event2) {
|
|
43990
|
+
if (event2.key !== "Escape") return;
|
|
43991
|
+
event2.preventDefault();
|
|
43992
|
+
this.#closePicker();
|
|
43993
|
+
}
|
|
43994
|
+
#searchKey(event2) {
|
|
43995
|
+
if (event2.key === "ArrowDown") {
|
|
43996
|
+
event2.preventDefault();
|
|
43997
|
+
this.#options()[0]?.focus();
|
|
43998
|
+
return;
|
|
43999
|
+
}
|
|
44000
|
+
if (event2.key !== "Enter") return;
|
|
44001
|
+
event2.preventDefault();
|
|
44002
|
+
const first2 = matchProviders(this.#offered() ?? [], this.query).find(
|
|
44003
|
+
(option2) => !this.#added(option2.id)
|
|
44004
|
+
);
|
|
44005
|
+
if (first2) this.#choose(first2);
|
|
44006
|
+
}
|
|
44007
|
+
#optionKey(event2, option2) {
|
|
44008
|
+
const options = this.#options();
|
|
44009
|
+
const at = options.indexOf(event2.currentTarget);
|
|
44010
|
+
const moves = {
|
|
44011
|
+
ArrowDown: Math.min(at + 1, options.length - 1),
|
|
44012
|
+
ArrowUp: at - 1,
|
|
44013
|
+
Home: 0,
|
|
44014
|
+
End: options.length - 1
|
|
44015
|
+
};
|
|
44016
|
+
const typed3 = event2.key.length === 1 && !event2.ctrlKey && !event2.metaKey && !event2.altKey;
|
|
44017
|
+
if (event2.key in moves) {
|
|
44018
|
+
const to = moves[event2.key];
|
|
44019
|
+
if (to < 0) this.focusOn("sp-search");
|
|
44020
|
+
else options[to].focus();
|
|
44021
|
+
} else if (event2.key === "Enter" || event2.key === " ") this.#choose(option2);
|
|
44022
|
+
else if (typed3 || event2.key === "Backspace") {
|
|
44023
|
+
this.query = typed3 ? this.query + event2.key : this.query.slice(0, -1);
|
|
44024
|
+
this.focusOn("sp-search");
|
|
44025
|
+
} else return;
|
|
44026
|
+
event2.preventDefault();
|
|
44027
|
+
}
|
|
44028
|
+
#option(option2) {
|
|
44029
|
+
const added = !!this.#added(option2.id);
|
|
44030
|
+
return b`<div
|
|
44031
|
+
class="option"
|
|
44032
|
+
role="option"
|
|
44033
|
+
tabindex="-1"
|
|
44034
|
+
data-provider=${option2.id}
|
|
44035
|
+
data-auth=${option2.auth}
|
|
44036
|
+
aria-disabled=${added ? "true" : "false"}
|
|
44037
|
+
@click=${() => this.#choose(option2)}
|
|
44038
|
+
@keydown=${(event2) => this.#optionKey(event2, option2)}
|
|
44039
|
+
>
|
|
44040
|
+
<span class="name">${option2.name}</span>
|
|
44041
|
+
<span class="tag">${added ? b`<span class="added" data-added><swc-icon-checkmark size="s" aria-hidden="true"></swc-icon-checkmark>Added</span>` : authHints[option2.auth]}</span>
|
|
44042
|
+
${option2.description ? b`<span class="description">${option2.description}</span>` : A}
|
|
44043
|
+
${this.#notice(option2.needs, "short")}
|
|
44044
|
+
</div>`;
|
|
44045
|
+
}
|
|
44046
|
+
#pickStep(offered) {
|
|
44047
|
+
const matches2 = matchProviders(offered, this.query);
|
|
44048
|
+
return b`<div class="find">${search({
|
|
44049
|
+
label: "Search providers",
|
|
44050
|
+
value: this.query,
|
|
44051
|
+
input: (value) => {
|
|
44052
|
+
this.query = value;
|
|
44053
|
+
},
|
|
44054
|
+
keydown: (event2) => this.#searchKey(event2)
|
|
44055
|
+
})}</div>
|
|
44056
|
+
<div class="results">${matches2.length ? b`<div class="options" role="listbox" aria-label="Providers">${matches2.map((option2) => this.#option(option2))}</div>` : b`<p class="empty" role="status">No provider matches “${this.query.trim()}”.</p>`}</div>
|
|
44057
|
+
<div class="buttons end">
|
|
44058
|
+
<swc-button size="m" variant="secondary" data-action="close" @click=${() => this.#closePicker()}>Cancel</swc-button>
|
|
44059
|
+
</div>`;
|
|
44060
|
+
}
|
|
44061
|
+
#signInStep(account) {
|
|
44062
|
+
const signing = this.#signingIn(account);
|
|
44063
|
+
const cancel = signing && !!this.model?.settings.cancel;
|
|
44064
|
+
return b`<p class="hint">Sign in to ${account.provider} in a new window.</p>
|
|
44065
|
+
${signing ? this.#signingNote(account) : A}
|
|
44066
|
+
<div class="buttons">
|
|
44067
|
+
${cancel ? b`<swc-button size="m" variant="secondary" data-action="cancel-sign-in" @click=${() => this.#stopSigningIn(account)}>Cancel</swc-button>` : A}
|
|
44068
|
+
<swc-button size="m" variant="accent" data-action="sign-in" ?pending=${signing} @click=${() => this.connect(account.id)}>${signing ? "Signing in\u2026" : "Sign in"}</swc-button>
|
|
44069
|
+
${signing ? A : this.#leave(account)}
|
|
44070
|
+
</div>`;
|
|
44071
|
+
}
|
|
44072
|
+
#localStep(account) {
|
|
44073
|
+
return b`<p class="hint">SLICC connects to ${account.provider} on this device.</p>
|
|
44074
|
+
<div class="buttons">
|
|
44075
|
+
<swc-button size="m" variant="accent" data-action="connect" ?pending=${this.pending.has(account.id)} @click=${() => this.connect(account.id)}>Connect</swc-button>
|
|
44076
|
+
${this.#leave(account)}
|
|
44077
|
+
</div>`;
|
|
44078
|
+
}
|
|
44079
|
+
#connectStep(option2) {
|
|
44080
|
+
const account = this.#added(option2.id) ?? draft(option2);
|
|
44081
|
+
const step = option2.auth === "oauth" ? this.#signInStep(account) : option2.auth === "local" ? this.#localStep(account) : this.#key(account);
|
|
44082
|
+
return b`<div class="step" data-step=${option2.auth} data-provider=${option2.id}>
|
|
44083
|
+
${option2.description ? b`<p class="lead">${option2.description}</p>` : A}
|
|
44084
|
+
${this.#notice(option2.needs)}
|
|
44085
|
+
${step}
|
|
44086
|
+
${this.failure?.id === option2.id ? b`<div class="failure" role="alert"><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><span>${this.failure.message}</span></div>` : A}
|
|
44087
|
+
</div>`;
|
|
44088
|
+
}
|
|
44089
|
+
#picker(offered) {
|
|
44090
|
+
if (!this.picking) return A;
|
|
44091
|
+
const adding = this.adding;
|
|
44092
|
+
return b`<dialog class="picker" aria-labelledby="picker-title" data-picker=${adding ? "connect" : "pick"} @keydown=${(event2) => this.#pickerKey(event2)} @close=${() => this.#closed()}>
|
|
44093
|
+
<div class="head">
|
|
44094
|
+
<h2 id="picker-title">${adding ? `Add ${adding.name}` : "Add a provider"}</h2>
|
|
44095
|
+
<swc-close-button size="m" data-action="close" accessible-label="Close" @click=${() => this.#closePicker()}></swc-close-button>
|
|
44096
|
+
</div>
|
|
44097
|
+
${adding ? this.#connectStep(adding) : this.#pickStep(offered)}
|
|
44098
|
+
</dialog>`;
|
|
44099
|
+
}
|
|
44100
|
+
#providerList(accounts) {
|
|
44101
|
+
const offered = this.#offered();
|
|
44102
|
+
if (!offered)
|
|
44103
|
+
return b`<div class="accounts">${accounts.map((account) => this.#account(account))}</div>`;
|
|
44104
|
+
const sorted = [...accounts].sort((a23, b13) => listOrder[a23.status] - listOrder[b13.status]);
|
|
44105
|
+
return b`<div class="accounts" data-group="providers">${c(
|
|
44106
|
+
sorted,
|
|
44107
|
+
(account) => account.id,
|
|
44108
|
+
(account) => this.#account(account)
|
|
44109
|
+
)}</div>
|
|
44110
|
+
<div class="add">
|
|
44111
|
+
<swc-action-button size="m" quiet data-action="add-provider" @click=${() => this.#openPicker()}>
|
|
44112
|
+
<swc-icon-add slot="icon"></swc-icon-add>Add a provider
|
|
44113
|
+
</swc-action-button>
|
|
44114
|
+
</div>
|
|
44115
|
+
${this.#picker(offered)}`;
|
|
43448
44116
|
}
|
|
43449
44117
|
render() {
|
|
43450
44118
|
const settings = this.model?.settings;
|
|
@@ -43500,7 +44168,7 @@ var SliccSettings = class extends ThemedElement {
|
|
|
43500
44168
|
</div>
|
|
43501
44169
|
</div>
|
|
43502
44170
|
<h2 data-section="accounts">Accounts</h2>
|
|
43503
|
-
|
|
44171
|
+
${this.#providerList(providers)}
|
|
43504
44172
|
${servers.length ? b`<h2>MCP servers</h2>
|
|
43505
44173
|
<div class="accounts" data-group="mcp">${servers.map((account) => this.#account(account))}</div>` : A}
|
|
43506
44174
|
${this.model?.vault ? b`<slicc-secrets .model=${this.model}></slicc-secrets>` : A}
|