@frockbot/plugin-settings 0.3.5 → 0.3.7
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/package.json +10 -10
- package/src/client/BotSettingsSurface.vue +7 -3
- package/src/client/ConnectionsSurface.vue +64 -17
- package/src/client/ModelsSurface.vue +2 -2
- package/src/client/PackageCatalogSurface.vue +13 -13
- package/src/client/PackageSettingsForm.vue +2 -4
- package/src/client/PackageSettingsSection.vue +1 -1
- package/src/client/PluginsSurface.vue +98 -22
- package/src/client/UserProfileTrigger.vue +1 -1
- package/src/client/UserSettingsSurface.vue +4 -4
- package/src/client/index.ts +2 -2
- package/src/client/package-surfaces.test.ts +1 -3
- package/src/client/package-surfaces.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frockbot/plugin-settings",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
"typecheck": "vue-tsc --noEmit -p tsconfig.json"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@frockbot/catalog-core": "0.3.
|
|
25
|
-
"@frockbot/client-core": "0.3.
|
|
26
|
-
"@frockbot/client-ui": "0.3.
|
|
27
|
-
"@frockbot/configuration-core": "0.3.
|
|
28
|
-
"@frockbot/connection-core": "0.3.
|
|
29
|
-
"@frockbot/kernel-composition": "0.3.
|
|
30
|
-
"@frockbot/kernel-contracts": "0.3.
|
|
31
|
-
"@frockbot/plugin-auth": "0.3.
|
|
32
|
-
"@frockbot/plugin-shell": "0.3.
|
|
24
|
+
"@frockbot/catalog-core": "0.3.7",
|
|
25
|
+
"@frockbot/client-core": "0.3.7",
|
|
26
|
+
"@frockbot/client-ui": "0.3.7",
|
|
27
|
+
"@frockbot/configuration-core": "0.3.7",
|
|
28
|
+
"@frockbot/connection-core": "0.3.7",
|
|
29
|
+
"@frockbot/kernel-composition": "0.3.7",
|
|
30
|
+
"@frockbot/kernel-contracts": "0.3.7",
|
|
31
|
+
"@frockbot/plugin-auth": "0.3.7",
|
|
32
|
+
"@frockbot/plugin-shell": "0.3.7",
|
|
33
33
|
"cordis": "4.0.0-rc.8",
|
|
34
34
|
"vue": "3.5.41"
|
|
35
35
|
},
|
|
@@ -266,9 +266,13 @@ async function save(): Promise<void> {
|
|
|
266
266
|
>
|
|
267
267
|
<div>
|
|
268
268
|
<strong>Identity</strong>
|
|
269
|
-
<p>{{ name || "This Bot" }}
|
|
269
|
+
<p>{{ name || "This Bot" }}</p>
|
|
270
270
|
</div>
|
|
271
|
-
<span>
|
|
271
|
+
<span>{{
|
|
272
|
+
web.botSettings?.profile.namedBy === "bot"
|
|
273
|
+
? "Named by this Bot"
|
|
274
|
+
: "Named by you"
|
|
275
|
+
}}</span>
|
|
272
276
|
</UiAnchor>
|
|
273
277
|
<UiAnchor
|
|
274
278
|
anchor="bot-info-members"
|
|
@@ -280,7 +284,7 @@ async function save(): Promise<void> {
|
|
|
280
284
|
<strong>Members</strong>
|
|
281
285
|
<p>This Bot uses what you enable for all of your Bots.</p>
|
|
282
286
|
</div>
|
|
283
|
-
<span>
|
|
287
|
+
<span>Plugins and connected accounts are shared</span>
|
|
284
288
|
</UiAnchor>
|
|
285
289
|
<k-slot name="frockbot.bot-settings-sections" />
|
|
286
290
|
</div>
|
|
@@ -28,6 +28,38 @@ const web = providedWeb;
|
|
|
28
28
|
// Connections are User-scoped, so the row's link names no Bot.
|
|
29
29
|
const connectionsLink = settingsLinkV1({ anchor: "user-connections" });
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* What the browser came back from an external grant with. Read at boot from the
|
|
33
|
+
* return URL; without this the User lands back in the app with no confirmation
|
|
34
|
+
* and a cancelled grant is silently discarded.
|
|
35
|
+
*/
|
|
36
|
+
const connectionReturn = computed(() => web.value.connectionReturn);
|
|
37
|
+
|
|
38
|
+
const connectionReturnMessage = computed(() => {
|
|
39
|
+
const result = connectionReturn.value;
|
|
40
|
+
if (!result) return "";
|
|
41
|
+
const name = connectorDisplayName(result.packageId);
|
|
42
|
+
if (result.status === "ready") return `${name} is connected.`;
|
|
43
|
+
if (result.status === "pending") {
|
|
44
|
+
return `${name} is finishing connecting. This page will show it when it is ready.`;
|
|
45
|
+
}
|
|
46
|
+
return result.reason
|
|
47
|
+
? `${name} did not connect: ${result.reason}`
|
|
48
|
+
: `${name} did not connect.`;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
/** The Package's display name when the catalog knows it, its id otherwise. */
|
|
52
|
+
function connectorDisplayName(packageId: string): string {
|
|
53
|
+
return (
|
|
54
|
+
web.value.pluginCatalog.find((item) => item.packageId === packageId)
|
|
55
|
+
?.displayName ?? packageId
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function dismissConnectionReturn(): void {
|
|
60
|
+
web.value.connectionReturn = undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
31
63
|
const connectors = computed(() =>
|
|
32
64
|
configurablePackages({
|
|
33
65
|
catalog: web.value.pluginCatalog,
|
|
@@ -254,7 +286,7 @@ async function addMcpServer(): Promise<void> {
|
|
|
254
286
|
} catch (error) {
|
|
255
287
|
mcpApiKey.value = "";
|
|
256
288
|
web.value.settingsError =
|
|
257
|
-
error instanceof Error ? error.message : "
|
|
289
|
+
error instanceof Error ? error.message : "Couldn't add that server.";
|
|
258
290
|
}
|
|
259
291
|
}
|
|
260
292
|
|
|
@@ -331,6 +363,18 @@ async function connect(
|
|
|
331
363
|
Connect an account or service once and every Bot you own can use it.
|
|
332
364
|
</p>
|
|
333
365
|
|
|
366
|
+
<p
|
|
367
|
+
v-if="connectionReturn"
|
|
368
|
+
class="connection-return"
|
|
369
|
+
:class="{
|
|
370
|
+
'connection-return--failed': connectionReturn.status === 'failed',
|
|
371
|
+
}"
|
|
372
|
+
role="status"
|
|
373
|
+
>
|
|
374
|
+
{{ connectionReturnMessage }}
|
|
375
|
+
<UiButton @click="dismissConnectionReturn">Dismiss</UiButton>
|
|
376
|
+
</p>
|
|
377
|
+
|
|
334
378
|
<section
|
|
335
379
|
v-if="pendingAuthorizations.length"
|
|
336
380
|
class="connect-cards"
|
|
@@ -343,11 +387,7 @@ async function connect(
|
|
|
343
387
|
>
|
|
344
388
|
<div class="connect-card-copy">
|
|
345
389
|
<strong>{{ connection.pendingAuthorization?.label }}</strong>
|
|
346
|
-
<span>
|
|
347
|
-
Needs your authorization. Only you can complete it — FrockBot
|
|
348
|
-
creates the sign-in link when you press Reconnect, and nothing is
|
|
349
|
-
stored waiting for it.
|
|
350
|
-
</span>
|
|
390
|
+
<span> Needs you to sign in again. </span>
|
|
351
391
|
</div>
|
|
352
392
|
<UiButton
|
|
353
393
|
variant="primary"
|
|
@@ -376,11 +416,7 @@ async function connect(
|
|
|
376
416
|
<span class="connector-copy">
|
|
377
417
|
<strong>{{ item.displayName }}</strong>
|
|
378
418
|
<small>
|
|
379
|
-
{{
|
|
380
|
-
item.connectionTypes
|
|
381
|
-
.map((connection) => connection.displayName)
|
|
382
|
-
.join(", ")
|
|
383
|
-
}}
|
|
419
|
+
{{ item.connectionTypes[0]?.displayName }}
|
|
384
420
|
</small>
|
|
385
421
|
</span>
|
|
386
422
|
<UiButton
|
|
@@ -548,12 +584,8 @@ async function connect(
|
|
|
548
584
|
/>
|
|
549
585
|
</label>
|
|
550
586
|
<p class="field-hint">
|
|
551
|
-
Leave both empty
|
|
552
|
-
|
|
553
|
-
server that issues a client secret is refused, because a secret
|
|
554
|
-
would have to live in this Connection's settings. You will be
|
|
555
|
-
sent to the server to sign in, and no token ever reaches this
|
|
556
|
-
page.
|
|
587
|
+
Leave both empty unless the server gave you specific values.
|
|
588
|
+
You'll sign in on the server's own site.
|
|
557
589
|
</p>
|
|
558
590
|
</template>
|
|
559
591
|
<div class="api-key-actions">
|
|
@@ -734,6 +766,21 @@ async function connect(
|
|
|
734
766
|
font-size: var(--frock-text-sm);
|
|
735
767
|
}
|
|
736
768
|
|
|
769
|
+
.connection-return {
|
|
770
|
+
display: flex;
|
|
771
|
+
align-items: center;
|
|
772
|
+
justify-content: space-between;
|
|
773
|
+
gap: 12px;
|
|
774
|
+
margin: 8px 0;
|
|
775
|
+
padding: 8px 12px;
|
|
776
|
+
border-radius: var(--frock-radius-card);
|
|
777
|
+
background: var(--frock-surface-accent);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
.connection-return--failed {
|
|
781
|
+
background: var(--frock-surface-danger, var(--frock-surface-accent));
|
|
782
|
+
}
|
|
783
|
+
|
|
737
784
|
.connections-empty {
|
|
738
785
|
display: flex;
|
|
739
786
|
flex-direction: column;
|
|
@@ -32,8 +32,8 @@ onMounted(() => void web.value.loadPluginCatalog());
|
|
|
32
32
|
class="models-anchor"
|
|
33
33
|
/>
|
|
34
34
|
<p class="models-empty">
|
|
35
|
-
FrockBot
|
|
36
|
-
|
|
35
|
+
FrockBot picks a model for you. Turn on Custom models in Plugins to choose
|
|
36
|
+
your own.
|
|
37
37
|
</p>
|
|
38
38
|
<p v-if="web.settingsError" class="settings-error" role="alert">
|
|
39
39
|
{{ web.settingsError }}
|
|
@@ -152,20 +152,17 @@ function isPackageInstalled(packageId: string): boolean {
|
|
|
152
152
|
<template>
|
|
153
153
|
<div class="package-catalog-surface">
|
|
154
154
|
<p class="catalog-intro">
|
|
155
|
-
Browse published
|
|
156
|
-
you own
|
|
155
|
+
Browse published plugins. Installing one makes it available to every Bot
|
|
156
|
+
you own, once it's turned on.
|
|
157
157
|
</p>
|
|
158
158
|
<label class="catalog-search">
|
|
159
159
|
<UiIcon name="search" />
|
|
160
160
|
<input
|
|
161
161
|
v-model="search"
|
|
162
|
-
placeholder="Search
|
|
163
|
-
aria-label="Search
|
|
162
|
+
placeholder="Search plugins"
|
|
163
|
+
aria-label="Search plugins"
|
|
164
164
|
/>
|
|
165
165
|
</label>
|
|
166
|
-
<p v-if="web.packageCatalogGeneration" class="catalog-generation">
|
|
167
|
-
Generation {{ web.packageCatalogGeneration }}
|
|
168
|
-
</p>
|
|
169
166
|
<div class="catalog-grid">
|
|
170
167
|
<article
|
|
171
168
|
v-for="entry in filteredCatalog"
|
|
@@ -211,7 +208,7 @@ function isPackageInstalled(packageId: string): boolean {
|
|
|
211
208
|
<p class="catalog-note">{{ openCatalogEntry.description }}</p>
|
|
212
209
|
<dl class="catalog-facts">
|
|
213
210
|
<div>
|
|
214
|
-
<dt>
|
|
211
|
+
<dt>Plugin</dt>
|
|
215
212
|
<dd>{{ openCatalogEntry.packageId }}</dd>
|
|
216
213
|
</div>
|
|
217
214
|
<div>
|
|
@@ -239,8 +236,8 @@ function isPackageInstalled(packageId: string): boolean {
|
|
|
239
236
|
>
|
|
240
237
|
<p>
|
|
241
238
|
Uninstalling {{ entry.displayName }} removes it from every
|
|
242
|
-
Bot.
|
|
243
|
-
|
|
239
|
+
Bot. Your connected accounts stay, so reinstalling picks up
|
|
240
|
+
where you left off.
|
|
244
241
|
</p>
|
|
245
242
|
<div class="catalog-actions">
|
|
246
243
|
<UiButton @click="uninstallingPackageId = undefined">
|
|
@@ -330,10 +327,13 @@ function isPackageInstalled(packageId: string): boolean {
|
|
|
330
327
|
v-if="web.packageCatalog.length === 0 && !web.settingsError"
|
|
331
328
|
class="catalog-empty"
|
|
332
329
|
>
|
|
333
|
-
|
|
330
|
+
No plugins are published yet.
|
|
334
331
|
</p>
|
|
335
|
-
<p
|
|
336
|
-
|
|
332
|
+
<p
|
|
333
|
+
v-else-if="filteredCatalog.length === 0 && !web.settingsError"
|
|
334
|
+
class="catalog-empty"
|
|
335
|
+
>
|
|
336
|
+
No plugin matches that search.
|
|
337
337
|
</p>
|
|
338
338
|
<p v-if="web.settingsError" class="settings-error" role="alert">
|
|
339
339
|
{{ web.settingsError }}
|
|
@@ -54,9 +54,7 @@ async function save(): Promise<void> {
|
|
|
54
54
|
await web.value.savePackageSettings(props.item.packageId, values);
|
|
55
55
|
} catch (error) {
|
|
56
56
|
web.value.settingsError =
|
|
57
|
-
error instanceof Error
|
|
58
|
-
? error.message
|
|
59
|
-
: "Could not save the Package settings";
|
|
57
|
+
error instanceof Error ? error.message : "Couldn't save those settings.";
|
|
60
58
|
}
|
|
61
59
|
}
|
|
62
60
|
</script>
|
|
@@ -73,7 +71,7 @@ async function save(): Promise<void> {
|
|
|
73
71
|
v-if="settingFieldKind(definition.schema) === 'enum'"
|
|
74
72
|
v-model="draft[definition.id]"
|
|
75
73
|
>
|
|
76
|
-
<option value="">
|
|
74
|
+
<option value="">Default</option>
|
|
77
75
|
<option
|
|
78
76
|
v-for="choice in definition.schema.enum ?? []"
|
|
79
77
|
:key="String(choice)"
|
|
@@ -60,11 +60,29 @@ onMounted(() => {
|
|
|
60
60
|
void web.value.loadPluginCatalog();
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
-
/**
|
|
63
|
+
/** Plain nouns for the manifest's capability kinds. */
|
|
64
|
+
const CAPABILITY_NOUNS: Record<string, string> = {
|
|
65
|
+
tool: "Tools",
|
|
66
|
+
model: "Models",
|
|
67
|
+
memory: "Memory",
|
|
68
|
+
notification: "Notifications",
|
|
69
|
+
computer: "Computer",
|
|
70
|
+
ui: "Pages",
|
|
71
|
+
storage: "Storage",
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
function capabilityNoun(kind: string): string {
|
|
75
|
+
return CAPABILITY_NOUNS[kind] ?? kind;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** What a plugin offers, in plain words. */
|
|
64
79
|
function capabilitySummary(item: PluginCatalogItem): string {
|
|
65
80
|
const kinds = [...new Set(item.capabilities.map((entry) => entry.kind))];
|
|
66
|
-
|
|
67
|
-
|
|
81
|
+
// A plugin can be worth turning on without contributing a capability of its
|
|
82
|
+
// own — Custom models is exactly that — so saying "no features" tells the
|
|
83
|
+
// User the one plugin they must enable does nothing.
|
|
84
|
+
if (kinds.length === 0) return "Adds settings";
|
|
85
|
+
return kinds.map(capabilityNoun).join(", ");
|
|
68
86
|
}
|
|
69
87
|
|
|
70
88
|
function installed(packageId: string): boolean {
|
|
@@ -111,13 +129,71 @@ function openPackageCatalog(): void {
|
|
|
111
129
|
surfaces.open("package-catalog");
|
|
112
130
|
}
|
|
113
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Refusals live on the row that was clicked, not in one panel-wide slot.
|
|
134
|
+
*
|
|
135
|
+
* The grid scrolls, so a message rendered above the list is off-screen for
|
|
136
|
+
* every row past the fold: the User sees the row unchanged and no explanation
|
|
137
|
+
* anywhere.
|
|
138
|
+
*/
|
|
139
|
+
const rowErrors = ref<Record<string, string>>({});
|
|
140
|
+
|
|
141
|
+
function rowError(packageId: string): string | undefined {
|
|
142
|
+
return rowErrors.value[packageId];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function setRowError(packageId: string, message: string): void {
|
|
146
|
+
rowErrors.value = { ...rowErrors.value, [packageId]: message };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function clearRowError(packageId: string): void {
|
|
150
|
+
const { [packageId]: _cleared, ...rest } = rowErrors.value;
|
|
151
|
+
rowErrors.value = rest;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Say what a Package is called, not what its id is.
|
|
156
|
+
*
|
|
157
|
+
* The backend refuses in terms of ids because that is what it holds; the
|
|
158
|
+
* surface knows the display names, so it substitutes them before the User
|
|
159
|
+
* reads the message.
|
|
160
|
+
*/
|
|
161
|
+
function inPlainNames(message: string): string {
|
|
162
|
+
const dependency = message.match(
|
|
163
|
+
/^Package "([^"]+)" requires Package "([^"]+)" to be installed and enabled/,
|
|
164
|
+
);
|
|
165
|
+
if (dependency) {
|
|
166
|
+
return `${displayName(dependency[1]!)} needs ${displayName(
|
|
167
|
+
dependency[2]!,
|
|
168
|
+
)} turned on first.`;
|
|
169
|
+
}
|
|
170
|
+
return message.replace(/"([a-z0-9][a-z0-9-]*)"/g, (quoted, packageId) =>
|
|
171
|
+
displayName(packageId) === packageId
|
|
172
|
+
? quoted
|
|
173
|
+
: `"${displayName(packageId)}"`,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function displayName(packageId: string): string {
|
|
178
|
+
return (
|
|
179
|
+
web.value.pluginCatalog.find(
|
|
180
|
+
(candidate) => candidate.packageId === packageId,
|
|
181
|
+
)?.displayName ?? packageId
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
114
185
|
async function install(item: PluginCatalogItem): Promise<void> {
|
|
115
186
|
busyPackageId.value = item.packageId;
|
|
187
|
+
clearRowError(item.packageId);
|
|
116
188
|
try {
|
|
117
189
|
await web.value.installPackage(item.packageId, item.version);
|
|
118
190
|
} catch (error) {
|
|
119
|
-
|
|
120
|
-
|
|
191
|
+
setRowError(
|
|
192
|
+
item.packageId,
|
|
193
|
+
inPlainNames(
|
|
194
|
+
error instanceof Error ? error.message : "Couldn't add that plugin.",
|
|
195
|
+
),
|
|
196
|
+
);
|
|
121
197
|
} finally {
|
|
122
198
|
busyPackageId.value = undefined;
|
|
123
199
|
}
|
|
@@ -125,13 +201,18 @@ async function install(item: PluginCatalogItem): Promise<void> {
|
|
|
125
201
|
|
|
126
202
|
async function setEnabled(packageId: string, next: boolean): Promise<void> {
|
|
127
203
|
busyPackageId.value = packageId;
|
|
204
|
+
clearRowError(packageId);
|
|
128
205
|
try {
|
|
129
206
|
await web.value.setPackageEnabled(packageId, next);
|
|
130
207
|
} catch (error) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
208
|
+
setRowError(
|
|
209
|
+
packageId,
|
|
210
|
+
inPlainNames(
|
|
211
|
+
error instanceof Error
|
|
212
|
+
? error.message
|
|
213
|
+
: "Couldn't turn that plugin on or off.",
|
|
214
|
+
),
|
|
215
|
+
);
|
|
135
216
|
} finally {
|
|
136
217
|
busyPackageId.value = undefined;
|
|
137
218
|
}
|
|
@@ -146,14 +227,6 @@ async function setEnabled(packageId: string, next: boolean): Promise<void> {
|
|
|
146
227
|
</span>
|
|
147
228
|
{{ installedPluginCount }} installed
|
|
148
229
|
</div>
|
|
149
|
-
<!--
|
|
150
|
-
A refused command is the answer to the click that caused it, so it is
|
|
151
|
-
shown above the list where the click happened, not below a long grid
|
|
152
|
-
where it scrolls out of view.
|
|
153
|
-
-->
|
|
154
|
-
<p v-if="web.settingsError" class="settings-error" role="alert">
|
|
155
|
-
{{ web.settingsError }}
|
|
156
|
-
</p>
|
|
157
230
|
<label class="plugin-search">
|
|
158
231
|
<UiIcon name="search" />
|
|
159
232
|
<input
|
|
@@ -164,17 +237,17 @@ async function setEnabled(packageId: string, next: boolean): Promise<void> {
|
|
|
164
237
|
</label>
|
|
165
238
|
<UiAnchor
|
|
166
239
|
anchor="user-packages"
|
|
167
|
-
label="
|
|
240
|
+
label="Plugins"
|
|
168
241
|
:href="packagesLink"
|
|
169
242
|
class="plugin-anchor"
|
|
170
243
|
>
|
|
171
244
|
<p class="plugin-intro">
|
|
172
|
-
Turn
|
|
245
|
+
Turn plugins on and off for your Bots. Set one up where it belongs:
|
|
173
246
|
model providers in Models, accounts in Connectors.
|
|
174
247
|
</p>
|
|
175
248
|
<div class="plugin-catalog-link">
|
|
176
249
|
<UiButton type="button" @click="openPackageCatalog">
|
|
177
|
-
Browse
|
|
250
|
+
Browse all plugins
|
|
178
251
|
</UiButton>
|
|
179
252
|
</div>
|
|
180
253
|
</UiAnchor>
|
|
@@ -227,6 +300,9 @@ async function setEnabled(packageId: string, next: boolean): Promise<void> {
|
|
|
227
300
|
</UiButton>
|
|
228
301
|
</span>
|
|
229
302
|
</div>
|
|
303
|
+
<p v-if="rowError(item.packageId)" class="plugin-failure" role="alert">
|
|
304
|
+
{{ rowError(item.packageId) }}
|
|
305
|
+
</p>
|
|
230
306
|
<p v-if="failure(item.packageId)" class="plugin-failure" role="alert">
|
|
231
307
|
{{ failure(item.packageId) }}
|
|
232
308
|
</p>
|
|
@@ -237,10 +313,10 @@ async function setEnabled(packageId: string, next: boolean): Promise<void> {
|
|
|
237
313
|
v-if="userPackages.length === 0 && !web.settingsError"
|
|
238
314
|
class="plugin-empty"
|
|
239
315
|
>
|
|
240
|
-
This
|
|
316
|
+
This deployment ships no plugins.
|
|
241
317
|
</p>
|
|
242
318
|
<p v-else-if="filteredCatalog.length === 0" class="plugin-empty">
|
|
243
|
-
No
|
|
319
|
+
No plugin matches that search.
|
|
244
320
|
</p>
|
|
245
321
|
</div>
|
|
246
322
|
</template>
|
|
@@ -120,7 +120,7 @@ onBeforeUnmount(() => window.removeEventListener("pointerdown", closeMenu));
|
|
|
120
120
|
{{ auth.signingOut.value ? "Signing out…" : "Sign out" }}
|
|
121
121
|
</button>
|
|
122
122
|
<p v-if="developmentIdentity" class="profile-menu-hint">
|
|
123
|
-
|
|
123
|
+
You're signed in as a local developer.
|
|
124
124
|
</p>
|
|
125
125
|
<p v-if="signOutError" class="profile-menu-error" role="alert">
|
|
126
126
|
{{ signOutError }}
|
|
@@ -70,7 +70,7 @@ async function save(): Promise<void> {
|
|
|
70
70
|
<span class="profile-face" aria-hidden="true" />
|
|
71
71
|
<div>
|
|
72
72
|
<strong>Your profile</strong>
|
|
73
|
-
<p>
|
|
73
|
+
<p>How your Bots refer to you.</p>
|
|
74
74
|
</div>
|
|
75
75
|
</div>
|
|
76
76
|
<UiField label="Name">
|
|
@@ -82,13 +82,13 @@ async function save(): Promise<void> {
|
|
|
82
82
|
</UiAnchor>
|
|
83
83
|
<UiAnchor
|
|
84
84
|
anchor="user-package-settings"
|
|
85
|
-
label="
|
|
85
|
+
label="Plugin settings"
|
|
86
86
|
:href="packageSettingsLink"
|
|
87
87
|
class="settings-row"
|
|
88
88
|
>
|
|
89
89
|
<p class="field-hint">
|
|
90
|
-
Settings
|
|
91
|
-
|
|
90
|
+
Settings for the plugins you've turned on. Model providers are set up in
|
|
91
|
+
Models, and accounts in Connectors.
|
|
92
92
|
</p>
|
|
93
93
|
<PackageSettingsSection />
|
|
94
94
|
<UiButton type="button" @click="surfaces.open('plugins')">
|
package/src/client/index.ts
CHANGED
|
@@ -45,12 +45,12 @@ export const settingsClientPlugin: ClientPlugin = (ctx) => {
|
|
|
45
45
|
}),
|
|
46
46
|
surfaces.register({
|
|
47
47
|
id: "package-catalog",
|
|
48
|
-
title: "
|
|
48
|
+
title: "All plugins",
|
|
49
49
|
component: PackageCatalogSurface,
|
|
50
50
|
}),
|
|
51
51
|
surfaces.register({
|
|
52
52
|
id: "user-settings",
|
|
53
|
-
title: "
|
|
53
|
+
title: "Settings",
|
|
54
54
|
component: UserSettingsSurface,
|
|
55
55
|
}),
|
|
56
56
|
ctx.slot({
|
|
@@ -165,9 +165,7 @@ describe("Package configuration homes", () => {
|
|
|
165
165
|
test("names the surface a Plugins row points at", () => {
|
|
166
166
|
expect(configurationHomeLabel("models")).toBe("Models");
|
|
167
167
|
expect(configurationHomeLabel("connections")).toBe("Connectors");
|
|
168
|
-
expect(configurationHomeLabel("user-settings")).toBe(
|
|
169
|
-
"Application settings",
|
|
170
|
-
);
|
|
168
|
+
expect(configurationHomeLabel("user-settings")).toBe("Settings");
|
|
171
169
|
expect(configurationHomeLabel("none")).toBeUndefined();
|
|
172
170
|
});
|
|
173
171
|
});
|
|
@@ -97,6 +97,6 @@ export function configurationHomeLabel(
|
|
|
97
97
|
): string | undefined {
|
|
98
98
|
if (home === "models") return "Models";
|
|
99
99
|
if (home === "connections") return "Connectors";
|
|
100
|
-
if (home === "user-settings") return "
|
|
100
|
+
if (home === "user-settings") return "Settings";
|
|
101
101
|
return undefined;
|
|
102
102
|
}
|