@frockbot/plugin-flock 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.
@@ -52,7 +52,7 @@
52
52
  },
53
53
  {
54
54
  "id": "matte-black-top-hat",
55
- "label": "Matte-black top hat \u00b7 Qwen layer",
55
+ "label": "Matte-black top hat",
56
56
  "parent": "upper-neutral",
57
57
  "kind": "headwear"
58
58
  },
@@ -278,7 +278,7 @@
278
278
  },
279
279
  {
280
280
  "id": "purple-scarf",
281
- "label": "Purple silk scarf \u00b7 Qwen layer",
281
+ "label": "Purple silk scarf",
282
282
  "parent": "lower-neutral",
283
283
  "kind": "neckwear"
284
284
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frockbot/plugin-flock",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -27,16 +27,16 @@
27
27
  "typecheck": "vue-tsc --noEmit -p tsconfig.json"
28
28
  },
29
29
  "dependencies": {
30
- "@frockbot/client-core": "0.3.5",
31
- "@frockbot/client-ui": "0.3.5",
32
- "@frockbot/configuration-core": "0.3.5",
33
- "@frockbot/kernel-contracts": "0.3.5",
34
- "@frockbot/plugin-shell": "0.3.5",
30
+ "@frockbot/client-core": "0.3.7",
31
+ "@frockbot/client-ui": "0.3.7",
32
+ "@frockbot/configuration-core": "0.3.7",
33
+ "@frockbot/kernel-contracts": "0.3.7",
34
+ "@frockbot/plugin-shell": "0.3.7",
35
35
  "cordis": "4.0.0-rc.8",
36
36
  "vue": "3.5.41"
37
37
  },
38
38
  "devDependencies": {
39
- "@frockbot/plugin-testkit": "0.3.5",
39
+ "@frockbot/plugin-testkit": "0.3.7",
40
40
  "@types/bun": "1.4.0",
41
41
  "@vitejs/plugin-vue": "6.0.8",
42
42
  "css-tree": "2.3.1",
@@ -123,10 +123,7 @@ onBeforeUnmount(() => restoreFocus?.focus());
123
123
  : "Change the look"
124
124
  }}
125
125
  </h1>
126
- <p>
127
- Keep this look or tailor each layer. Your choice is saved with the
128
- Bot.
129
- </p>
126
+ <p>Keep this look, or change any layer.</p>
130
127
  <label v-if="flock.overlay === 'create'" class="flock-name"
131
128
  >Bot name<input
132
129
  v-model.trim="flock.draftName"
@@ -45,7 +45,7 @@ function botName(botId: string, fallback: string): string {
45
45
  return flock.value.profiles[botId]?.name ?? fallback;
46
46
  }
47
47
  function botSubtitle(botId: string): string {
48
- return flock.value.profiles[botId]?.title ?? botId;
48
+ return flock.value.profiles[botId]?.title ?? "No messages yet";
49
49
  }
50
50
  function previewText(botId: string): string {
51
51
  return flock.value.unread[botId]?.lastMessage?.text ?? botSubtitle(botId);
@@ -1,6 +1,6 @@
1
1
  import type { ClientPlugin } from "@frockbot/client-core";
2
2
  import type { FrockBotWebData } from "@frockbot/plugin-shell/shared";
3
- import { ref, type Ref } from "vue";
3
+ import { ref, watch, type Ref } from "vue";
4
4
  import {
5
5
  decodeBotLifecycleDirectoryViewV1,
6
6
  decodeBotIdentityDirectoryViewV1,
@@ -91,6 +91,8 @@ export const flockClientPlugin: ClientPlugin = (ctx) => {
91
91
  throw new Error("Flock hosted transport is unavailable");
92
92
  const request = ctx.transport.hostedRequest.bind(ctx.transport);
93
93
  let shell: Ref<FrockBotWebData> | undefined;
94
+ /** Stops the watcher that keeps a renamed Bot's sidebar row in step. */
95
+ let stopNameWatch: (() => void) | undefined;
94
96
  let authenticatedUserId: string | undefined;
95
97
  let loadGeneration = 0;
96
98
  let selectionGeneration = 0;
@@ -117,6 +119,24 @@ export const flockClientPlugin: ClientPlugin = (ctx) => {
117
119
  draftSheep: randomSheepRecipeV1(),
118
120
  bindShell(value) {
119
121
  shell = value;
122
+ // A rename is saved on the Bot's own settings, and the sidebar reads a
123
+ // directory it loaded once — so the row kept the old name until the page
124
+ // was reloaded. The row follows the settings the Shell is already
125
+ // holding rather than waiting for a second read of the directory.
126
+ stopNameWatch?.();
127
+ stopNameWatch = watch(
128
+ () => value.value.botSettings?.profile.name,
129
+ (name) => {
130
+ const botId = value.value.botSettings?.botId;
131
+ if (!botId || !name) return;
132
+ const profile = state.value.profiles[botId];
133
+ if (!profile || profile.name === name) return;
134
+ state.value.profiles = {
135
+ ...state.value.profiles,
136
+ [botId]: { ...profile, name },
137
+ };
138
+ },
139
+ );
120
140
  },
121
141
  async load() {
122
142
  const generation = ++loadGeneration;
@@ -158,9 +178,7 @@ export const flockClientPlugin: ClientPlugin = (ctx) => {
158
178
  if (receipt) {
159
179
  clearPendingCreate(userId);
160
180
  if (receipt.status === "rejected")
161
- throw new Error(
162
- receipt.failure ?? "Pending Bot creation was rejected",
163
- );
181
+ throw new Error(receipt.failure ?? "Couldn't create the Bot.");
164
182
  }
165
183
  state.value.directory = decodeDirectoryViewV1(
166
184
  await request("/api/bots"),
@@ -220,7 +238,11 @@ export const flockClientPlugin: ClientPlugin = (ctx) => {
220
238
  const selected = preferredBot?.botId ?? activeBots[0]?.botId;
221
239
  if (preferred && !preferredBot) replacePreferredBot(selected);
222
240
  if (selected && shell) await state.value.select(selected);
223
- else if (!selected) state.value.openCreate();
241
+ // Only a User with no Bots at all is asked to make one. Archiving your
242
+ // last Bot leaves you with an archived list to restore from, and a
243
+ // dialog opening over it puts its backdrop between you and Restore.
244
+ else if (!selected && state.value.directory.bots.length === 0)
245
+ state.value.openCreate();
224
246
  } catch (error) {
225
247
  state.value.error =
226
248
  error instanceof Error ? error.message : "Could not load your flock";
@@ -360,9 +382,9 @@ export const flockClientPlugin: ClientPlugin = (ctx) => {
360
382
  ),
361
383
  );
362
384
  if (receipt.status === "rejected")
363
- throw new Error(receipt.failure ?? "Bot archive was rejected");
385
+ throw new Error(receipt.failure ?? "Couldn't archive this Bot.");
364
386
  if (receipt.status === "pending") {
365
- state.value.error = "Bot archive is retrying in the backend.";
387
+ state.value.error = "Still archiving this will finish shortly.";
366
388
  return;
367
389
  }
368
390
  state.value.overlay = undefined;
@@ -388,9 +410,9 @@ export const flockClientPlugin: ClientPlugin = (ctx) => {
388
410
  ),
389
411
  );
390
412
  if (receipt.status === "rejected")
391
- throw new Error(receipt.failure ?? "Bot restore was rejected");
413
+ throw new Error(receipt.failure ?? "Couldn't restore this Bot.");
392
414
  if (receipt.status === "pending") {
393
- state.value.error = "Bot restore is retrying in the backend.";
415
+ state.value.error = "Still restoring this will finish shortly.";
394
416
  return;
395
417
  }
396
418
  await state.value.load();
@@ -419,18 +441,16 @@ export const flockClientPlugin: ClientPlugin = (ctx) => {
419
441
  clearPendingSheep(userId, botId);
420
442
  if (receipt.status === "rejected")
421
443
  reconciliationFailure =
422
- receipt.failure ?? "Pending sheep update was rejected";
444
+ receipt.failure ?? "Couldn't save the sheep.";
423
445
  } catch (error) {
424
446
  if (!isDefinitiveFlockFailure(error)) {
425
447
  state.value.error =
426
- "A previous sheep update could not be reconciled. Try again before editing.";
448
+ "Your last change to this sheep didn't save. Try again.";
427
449
  return;
428
450
  }
429
451
  clearPendingSheep(userId, botId);
430
452
  reconciliationFailure =
431
- error instanceof Error
432
- ? error.message
433
- : "Pending sheep update was rejected";
453
+ error instanceof Error ? error.message : "Couldn't save the sheep.";
434
454
  }
435
455
  try {
436
456
  identity = decodeSheepIdentityViewV1(
@@ -441,7 +461,7 @@ export const flockClientPlugin: ClientPlugin = (ctx) => {
441
461
  state.value.error =
442
462
  error instanceof Error
443
463
  ? error.message
444
- : "Could not reconcile the previous sheep update";
464
+ : "Couldn't finish saving your last change.";
445
465
  return;
446
466
  }
447
467
  }
@@ -479,7 +499,7 @@ export const flockClientPlugin: ClientPlugin = (ctx) => {
479
499
  );
480
500
  if (receipt.status === "rejected") {
481
501
  clearPendingCreate(userId);
482
- throw new Error(receipt.failure ?? "Bot creation was rejected");
502
+ throw new Error(receipt.failure ?? "Couldn't create the Bot.");
483
503
  }
484
504
  clearPendingCreate(userId);
485
505
  replacePreferredBot(command.botId);
@@ -521,7 +541,7 @@ export const flockClientPlugin: ClientPlugin = (ctx) => {
521
541
  );
522
542
  if (receipt.status === "rejected") {
523
543
  clearPendingSheep(userId, botId);
524
- throw new Error(receipt.failure ?? "Sheep update was rejected");
544
+ throw new Error(receipt.failure ?? "Couldn't save the sheep.");
525
545
  }
526
546
  clearPendingSheep(userId, botId);
527
547
  state.value.identities[botId] = decodeSheepIdentityViewV1(
@@ -608,6 +628,7 @@ export const flockClientPlugin: ClientPlugin = (ctx) => {
608
628
 
609
629
  return [
610
630
  () => clearInterval(poll),
631
+ () => stopNameWatch?.(),
611
632
  ctx.provide(flockWebDataKey, state),
612
633
  ctx.slot({
613
634
  slot: "frockbot.sidebar-bots",