@frockbot/plugin-flock 0.0.0 → 0.1.1

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.
Files changed (92) hide show
  1. package/README.md +8 -1
  2. package/assets/amber-glasses.webp +0 -0
  3. package/assets/background-bright-orange.webp +0 -0
  4. package/assets/background-canary-yellow.webp +0 -0
  5. package/assets/background-electric-blue.webp +0 -0
  6. package/assets/background-hot-pink.webp +0 -0
  7. package/assets/background-lime-green.webp +0 -0
  8. package/assets/background-vivid-purple.webp +0 -0
  9. package/assets/blue-sailor-cap.webp +0 -0
  10. package/assets/bronze-aviator-goggles.webp +0 -0
  11. package/assets/burgundy-beret.webp +0 -0
  12. package/assets/canary-party-hat.webp +0 -0
  13. package/assets/canary-rain-cap.webp +0 -0
  14. package/assets/canonical.webp +0 -0
  15. package/assets/chef-toque.webp +0 -0
  16. package/assets/cobalt-round-glasses.webp +0 -0
  17. package/assets/coral-bucket-hat.webp +0 -0
  18. package/assets/emerald-necktie.webp +0 -0
  19. package/assets/forest-ranger-fedora.webp +0 -0
  20. package/assets/gold-royal-crown.webp +0 -0
  21. package/assets/gold-sun-medallion.webp +0 -0
  22. package/assets/graduation-cap.webp +0 -0
  23. package/assets/green-square-glasses.webp +0 -0
  24. package/assets/layers.css +159 -0
  25. package/assets/leather-bell.webp +0 -0
  26. package/assets/lilac-flower-crown.webp +0 -0
  27. package/assets/manifest.json +769 -0
  28. package/assets/matte-black-top-hat.webp +0 -0
  29. package/assets/navy-wizard-hat.webp +0 -0
  30. package/assets/orange-hard-hat.webp +0 -0
  31. package/assets/plum-glasses.webp +0 -0
  32. package/assets/purple-scarf.webp +0 -0
  33. package/assets/purple-witch-hat.webp +0 -0
  34. package/assets/rainbow-propeller-cap.webp +0 -0
  35. package/assets/rainbow-visor.webp +0 -0
  36. package/assets/ranger-fedora-feather.webp +0 -0
  37. package/assets/red-polka-bowtie.webp +0 -0
  38. package/assets/retro-3d-glasses.webp +0 -0
  39. package/assets/rose-heart-sunglasses.webp +0 -0
  40. package/assets/royal-crown-rubies.webp +0 -0
  41. package/assets/sailor-cap-anchor.webp +0 -0
  42. package/assets/silver-space-helmet.webp +0 -0
  43. package/assets/straw-boater.webp +0 -0
  44. package/assets/teal-bowtie.webp +0 -0
  45. package/assets/teal-glasses.webp +0 -0
  46. package/assets/terracotta-beanie.webp +0 -0
  47. package/assets/tortoiseshell-readers.webp +0 -0
  48. package/assets/turquoise-bandana.webp +0 -0
  49. package/assets/violet-masquerade-mask.webp +0 -0
  50. package/assets/white-snow-goggles.webp +0 -0
  51. package/assets/white-tennis-visor.webp +0 -0
  52. package/assets/witch-hat-moon.webp +0 -0
  53. package/assets/yellow-star-glasses.webp +0 -0
  54. package/frockbot.json +38 -0
  55. package/package.json +47 -6
  56. package/src/agent.test.ts +401 -0
  57. package/src/agent.ts +571 -0
  58. package/src/assets.test.ts +31 -0
  59. package/src/backend.test.ts +205 -0
  60. package/src/backend.ts +283 -0
  61. package/src/bot.test.ts +190 -0
  62. package/src/bot.ts +255 -0
  63. package/src/client/BotAvatar.vue +20 -0
  64. package/src/client/FlockAvatar.vue +33 -0
  65. package/src/client/FlockAvatarEditor.vue +44 -0
  66. package/src/client/FlockCreateButton.vue +18 -0
  67. package/src/client/FlockIdentity.vue +31 -0
  68. package/src/client/FlockOverlay.vue +209 -0
  69. package/src/client/FlockSidebar.vue +254 -0
  70. package/src/client/SheepAvatar.vue +28 -0
  71. package/src/client/dialog-focus.test.ts +15 -0
  72. package/src/client/dialog-focus.ts +13 -0
  73. package/src/client/index.test.ts +502 -0
  74. package/src/client/index.ts +619 -0
  75. package/src/client/mobile-dialog-layout.test.ts +50 -0
  76. package/src/client/pending-create.test.ts +71 -0
  77. package/src/client/pending-create.ts +93 -0
  78. package/src/client/sidebar.test.ts +77 -0
  79. package/src/client/sidebar.ts +77 -0
  80. package/src/client/state.ts +53 -0
  81. package/src/client/styles.css +611 -0
  82. package/src/env.d.ts +9 -0
  83. package/src/index.ts +4 -0
  84. package/src/manifest.ts +3 -0
  85. package/src/package.test.ts +12 -0
  86. package/src/shared.test.ts +197 -0
  87. package/src/shared.ts +735 -0
  88. package/src/user.test.ts +455 -0
  89. package/src/user.ts +465 -0
  90. package/tsconfig.json +15 -0
  91. package/validate_readability.py +64 -0
  92. package/vite.config.ts +30 -0
@@ -0,0 +1,611 @@
1
+ .flock-avatar {
2
+ position: relative;
3
+ display: inline-block;
4
+ flex: 0 0 auto;
5
+ width: var(--frock-avatar-md);
6
+ height: var(--frock-avatar-md);
7
+ overflow: hidden;
8
+ border-radius: 12px;
9
+ background: var(--frock-surface-accent);
10
+ }
11
+
12
+ /* The message-thread size: one avatar token, matching a small control. */
13
+ .flock-avatar--mini {
14
+ width: var(--frock-avatar-sm);
15
+ height: var(--frock-avatar-sm);
16
+ border-radius: 9px;
17
+ }
18
+
19
+ .flock-avatar--large {
20
+ width: 188px;
21
+ height: 188px;
22
+ border-radius: 42px;
23
+ box-shadow: var(--frock-shadow-avatar);
24
+ }
25
+
26
+ /* Sidebar */
27
+
28
+ /* Bots their own settings keep out of the list, reachable behind one click. */
29
+ .flock-hidden-group {
30
+ display: flex;
31
+ flex-direction: column;
32
+ gap: 4px;
33
+ margin-top: 8px;
34
+ }
35
+
36
+ .flock-hidden-toggle {
37
+ align-self: flex-start;
38
+ }
39
+
40
+ .flock-list-actions {
41
+ display: flex;
42
+ min-height: 28px;
43
+ align-items: center;
44
+ justify-content: flex-end;
45
+ padding: 0 4px;
46
+ }
47
+
48
+ .flock-manage,
49
+ .flock-lifecycle {
50
+ border: 0;
51
+ border-radius: var(--frock-radius-control);
52
+ background: transparent;
53
+ color: var(--frock-text-muted);
54
+ padding: 2px 6px;
55
+ font: inherit;
56
+ font-size: var(--frock-text-xs);
57
+ cursor: pointer;
58
+ }
59
+
60
+ .flock-manage:hover,
61
+ .flock-lifecycle:hover {
62
+ background: var(--frock-fill-hover);
63
+ color: var(--frock-text);
64
+ }
65
+
66
+ .flock-groups,
67
+ .flock-group,
68
+ .flock-rows {
69
+ display: grid;
70
+ }
71
+
72
+ .flock-groups {
73
+ gap: 8px;
74
+ }
75
+
76
+ .flock-group {
77
+ gap: 2px;
78
+ }
79
+
80
+ .flock-group-heading {
81
+ margin: 0;
82
+ padding: 7px 10px 3px;
83
+ color: var(--frock-text-muted);
84
+ font-size: var(--frock-text-sm);
85
+ font-weight: 600;
86
+ line-height: var(--frock-leading-tight);
87
+ }
88
+
89
+ .flock-rows {
90
+ gap: 2px;
91
+ }
92
+
93
+ .flock-bot-row {
94
+ position: relative;
95
+ display: grid;
96
+ width: 100%;
97
+ grid-template-columns: minmax(0, 1fr) auto;
98
+ align-items: center;
99
+ gap: 10px;
100
+ padding: 8px 10px;
101
+ border: 0;
102
+ border-radius: 12px;
103
+ background: transparent;
104
+ color: inherit;
105
+ text-align: left;
106
+ cursor: pointer;
107
+ transition:
108
+ background-color var(--frock-motion-fast),
109
+ box-shadow var(--frock-motion-fast),
110
+ transform var(--frock-motion-fast);
111
+ }
112
+
113
+ .flock-bot-select {
114
+ display: grid;
115
+ grid-template-columns: var(--frock-avatar-md) minmax(0, 1fr) auto;
116
+ align-items: center;
117
+ gap: 10px;
118
+ min-width: 0;
119
+ padding: 0;
120
+ border: 0;
121
+ background: transparent;
122
+ color: inherit;
123
+ font: inherit;
124
+ text-align: left;
125
+ cursor: pointer;
126
+ }
127
+
128
+ .flock-bot-row.archived {
129
+ opacity: 0.72;
130
+ }
131
+
132
+ .flock-bot-row:hover {
133
+ background: var(--frock-fill-hover);
134
+ }
135
+
136
+ .flock-bot-row:active {
137
+ transform: scale(0.99);
138
+ }
139
+
140
+ .flock-bot-row.active,
141
+ .flock-bot-row.active:hover {
142
+ background: var(--frock-surface);
143
+ box-shadow: var(--frock-shadow-card);
144
+ }
145
+
146
+ .flock-bot-copy {
147
+ display: grid;
148
+ min-width: 0;
149
+ gap: 2px;
150
+ line-height: var(--frock-leading-tight);
151
+ }
152
+
153
+ .flock-bot-primary {
154
+ display: flex;
155
+ min-width: 0;
156
+ align-items: baseline;
157
+ gap: 8px;
158
+ }
159
+
160
+ .flock-bot-primary strong {
161
+ min-width: 0;
162
+ flex: 1 1 auto;
163
+ }
164
+
165
+ .flock-bot-primary time {
166
+ flex: 0 0 auto;
167
+ color: var(--frock-text-subtle);
168
+ font-size: var(--frock-text-xs);
169
+ font-weight: 400;
170
+ white-space: nowrap;
171
+ }
172
+
173
+ .flock-bot-copy strong,
174
+ .flock-bot-copy small {
175
+ display: block;
176
+ overflow: hidden;
177
+ text-overflow: ellipsis;
178
+ white-space: nowrap;
179
+ }
180
+
181
+ .flock-bot-row.unread .flock-bot-copy strong,
182
+ .flock-bot-row.unread .flock-bot-copy small,
183
+ .flock-bot-row.unread .flock-bot-primary time {
184
+ font-weight: 700;
185
+ }
186
+
187
+ .flock-create-button {
188
+ flex: 0 0 auto;
189
+ }
190
+
191
+ .flock-bot-copy strong {
192
+ color: var(--frock-text);
193
+ font-size: var(--frock-text-lg);
194
+ font-weight: 600;
195
+ }
196
+
197
+ .flock-bot-copy small {
198
+ color: var(--frock-text-muted);
199
+ font-size: var(--frock-text-sm);
200
+ }
201
+
202
+ .flock-bot-indicators {
203
+ display: inline-flex;
204
+ align-items: center;
205
+ gap: 8px;
206
+ }
207
+
208
+ .flock-bot-dot {
209
+ width: 8px;
210
+ height: 8px;
211
+ margin-right: 2px;
212
+ border-radius: 999px;
213
+ background: var(--frock-success-bright);
214
+ box-shadow: 0 0 0 3px var(--frock-success-surface);
215
+ }
216
+
217
+ .flock-row-enter-active,
218
+ .flock-row-leave-active {
219
+ transition:
220
+ opacity var(--frock-motion-fast),
221
+ transform var(--frock-motion-fast);
222
+ }
223
+
224
+ .flock-row-enter-from,
225
+ .flock-row-leave-to {
226
+ opacity: 0;
227
+ transform: translateY(-4px);
228
+ }
229
+
230
+ .flock-skeleton {
231
+ display: grid;
232
+ gap: 2px;
233
+ padding-top: 4px;
234
+ }
235
+
236
+ .flock-skeleton-label {
237
+ position: absolute;
238
+ width: 1px;
239
+ height: 1px;
240
+ overflow: hidden;
241
+ clip: rect(0 0 0 0);
242
+ white-space: nowrap;
243
+ }
244
+
245
+ .flock-skeleton-row {
246
+ display: grid;
247
+ grid-template-columns: var(--frock-avatar-md) minmax(0, 1fr);
248
+ align-items: center;
249
+ gap: 10px;
250
+ padding: 8px 10px;
251
+ }
252
+
253
+ .flock-skeleton-copy {
254
+ display: grid;
255
+ gap: 8px;
256
+ }
257
+
258
+ .flock-empty,
259
+ .flock-error {
260
+ margin: 0;
261
+ padding: 10px;
262
+ color: var(--frock-text-muted);
263
+ font-size: var(--frock-text-base);
264
+ line-height: var(--frock-leading-normal);
265
+ }
266
+
267
+ .flock-error {
268
+ color: var(--frock-danger-text);
269
+ }
270
+
271
+ /* Header identity */
272
+
273
+ .flock-identity-button {
274
+ display: grid;
275
+ width: var(--frock-control-md);
276
+ height: var(--frock-control-md);
277
+ padding: 0;
278
+ border: 0;
279
+ border-radius: 10px;
280
+ background: transparent;
281
+ cursor: pointer;
282
+ transition: transform var(--frock-motion-fast);
283
+ }
284
+
285
+ .flock-identity-button:hover {
286
+ transform: scale(1.06);
287
+ }
288
+
289
+ .flock-identity-button .flock-avatar {
290
+ width: var(--frock-control-md);
291
+ height: var(--frock-control-md);
292
+ border-radius: 10px;
293
+ }
294
+
295
+ /* Dialog */
296
+
297
+ .flock-backdrop {
298
+ position: fixed;
299
+ z-index: 1000;
300
+ inset: 0;
301
+ display: grid;
302
+ place-items: center;
303
+ padding: 24px;
304
+ background: var(--frock-overlay-tint);
305
+ backdrop-filter: blur(2px);
306
+ animation: frock-fade-in var(--frock-motion-fast) both;
307
+ }
308
+
309
+ .flock-dialog {
310
+ width: min(660px, 100%);
311
+ height: min(520px, calc(100vh - 48px));
312
+ display: grid;
313
+ grid-template-columns: 250px 1fr;
314
+ overflow: hidden;
315
+ border: 1px solid var(--frock-overlay-border);
316
+ border-radius: 24px;
317
+ background: var(--frock-surface);
318
+ color: var(--frock-text);
319
+ box-shadow: var(--frock-shadow-dialog);
320
+ animation: frock-scale-in var(--frock-motion-enter) both;
321
+ }
322
+
323
+ .flock-preview {
324
+ display: flex;
325
+ flex-direction: column;
326
+ align-items: center;
327
+ justify-content: center;
328
+ padding: 28px;
329
+ background: var(--frock-flock-preview);
330
+ }
331
+
332
+ .flock-preview h2 {
333
+ margin: 18px 0 0;
334
+ font-size: var(--frock-text-2xl);
335
+ letter-spacing: var(--frock-tracking-display);
336
+ }
337
+
338
+ .flock-preview p {
339
+ margin: 4px 0 0;
340
+ color: var(--frock-text-muted);
341
+ font-size: var(--frock-text-sm);
342
+ }
343
+
344
+ .flock-reroll {
345
+ margin-top: 14px;
346
+ padding: 8px 14px;
347
+ border: 1px solid var(--frock-accent-border);
348
+ border-radius: 999px;
349
+ background: var(--frock-surface);
350
+ color: var(--frock-action-primary-hover);
351
+ font-size: var(--frock-text-sm);
352
+ font-weight: 700;
353
+ cursor: pointer;
354
+ transition: background-color var(--frock-motion-fast);
355
+ }
356
+
357
+ .flock-reroll:hover {
358
+ background: var(--frock-surface-accent-soft);
359
+ }
360
+
361
+ .flock-form {
362
+ position: relative;
363
+ padding: 26px 30px;
364
+ }
365
+
366
+ .flock-eyebrow {
367
+ color: var(--frock-action-primary-hover);
368
+ font-size: var(--frock-text-xs);
369
+ font-weight: 800;
370
+ letter-spacing: var(--frock-tracking-eyebrow);
371
+ text-transform: uppercase;
372
+ }
373
+
374
+ .flock-form h1 {
375
+ margin: 6px 0 0;
376
+ font-family: var(--frock-font-display);
377
+ font-size: var(--frock-text-display);
378
+ font-weight: 400;
379
+ letter-spacing: var(--frock-tracking-display);
380
+ }
381
+
382
+ .flock-form > p {
383
+ margin: 6px 0 0;
384
+ color: var(--frock-text-muted);
385
+ font-size: var(--frock-text-base);
386
+ line-height: var(--frock-leading-normal);
387
+ }
388
+
389
+ .flock-name {
390
+ display: block;
391
+ margin-top: 18px;
392
+ font-size: var(--frock-text-sm);
393
+ font-weight: 700;
394
+ }
395
+
396
+ .flock-name input {
397
+ width: 100%;
398
+ height: 38px;
399
+ margin-top: 6px;
400
+ padding: 0 12px;
401
+ border: 1px solid var(--frock-border-strong);
402
+ border-radius: var(--frock-radius-control);
403
+ color: var(--frock-text);
404
+ background: var(--frock-surface-raised);
405
+ font: inherit;
406
+ font-size: var(--frock-text-md);
407
+ transition: border-color var(--frock-motion-fast);
408
+ }
409
+
410
+ .flock-name input:focus {
411
+ border-color: var(--frock-border-focus);
412
+ }
413
+
414
+ .flock-form fieldset {
415
+ margin: 16px 0 0;
416
+ padding: 0;
417
+ border: 0;
418
+ }
419
+
420
+ .flock-form legend {
421
+ margin-bottom: 8px;
422
+ padding: 0;
423
+ font-size: var(--frock-text-sm);
424
+ font-weight: 700;
425
+ }
426
+
427
+ .flock-select-grid {
428
+ display: grid;
429
+ grid-template-columns: 1fr 1fr;
430
+ gap: 8px;
431
+ }
432
+
433
+ .flock-select-grid label {
434
+ display: block;
435
+ padding: 8px 10px;
436
+ border: 1px solid var(--frock-border-strong);
437
+ border-radius: 12px;
438
+ color: var(--frock-text-muted);
439
+ background: var(--frock-surface-raised);
440
+ font-size: var(--frock-text-xs);
441
+ font-weight: 700;
442
+ letter-spacing: var(--frock-tracking-eyebrow);
443
+ text-transform: uppercase;
444
+ transition: border-color var(--frock-motion-fast);
445
+ }
446
+
447
+ .flock-select-grid label:focus-within {
448
+ border-color: var(--frock-border-focus);
449
+ }
450
+
451
+ .flock-select-grid select {
452
+ display: block;
453
+ width: 100%;
454
+ margin-top: 4px;
455
+ padding: 0;
456
+ border: 0;
457
+ background: transparent;
458
+ color: var(--frock-text);
459
+ font: inherit;
460
+ font-size: var(--frock-text-base);
461
+ font-weight: 600;
462
+ letter-spacing: normal;
463
+ text-transform: none;
464
+ }
465
+
466
+ .flock-note {
467
+ margin-top: 12px;
468
+ padding: 8px 10px;
469
+ border-radius: 9px;
470
+ background: var(--frock-accent-surface);
471
+ color: var(--frock-accent-text);
472
+ font-size: var(--frock-text-sm);
473
+ line-height: var(--frock-leading-normal);
474
+ }
475
+
476
+ .flock-actions {
477
+ position: absolute;
478
+ right: 30px;
479
+ bottom: 24px;
480
+ display: flex;
481
+ gap: 8px;
482
+ }
483
+
484
+ .flock-actions button {
485
+ height: var(--frock-control-lg);
486
+ padding: 0 16px;
487
+ border: 1px solid var(--frock-border);
488
+ border-radius: 999px;
489
+ background: var(--frock-surface);
490
+ font-size: var(--frock-text-base);
491
+ font-weight: 700;
492
+ cursor: pointer;
493
+ transition:
494
+ background-color var(--frock-motion-fast),
495
+ transform var(--frock-motion-fast);
496
+ }
497
+
498
+ .flock-actions button:hover {
499
+ background: var(--frock-surface-subtle);
500
+ }
501
+
502
+ .flock-actions button:active {
503
+ transform: scale(0.97);
504
+ }
505
+
506
+ .flock-actions .primary {
507
+ border-color: var(--frock-action-primary);
508
+ background: var(--frock-action-primary);
509
+ color: var(--frock-on-accent);
510
+ }
511
+
512
+ .flock-actions .primary:hover {
513
+ background: var(--frock-action-primary-hover);
514
+ }
515
+
516
+ .flock-actions .primary:active {
517
+ background: var(--frock-action-primary-pressed);
518
+ }
519
+
520
+ @media (max-width: 600px) {
521
+ .flock-backdrop {
522
+ padding: 10px;
523
+ }
524
+
525
+ .flock-dialog {
526
+ height: calc(100dvh - 20px);
527
+ grid-template-columns: 1fr;
528
+ grid-template-rows: 220px 1fr;
529
+ border-radius: 20px;
530
+ overflow: auto;
531
+ }
532
+
533
+ .flock-preview {
534
+ padding: 14px;
535
+ }
536
+
537
+ .flock-avatar--large {
538
+ width: 130px;
539
+ height: 130px;
540
+ border-radius: 30px;
541
+ }
542
+
543
+ .flock-preview h2 {
544
+ margin-top: 7px;
545
+ font-size: var(--frock-text-xl);
546
+ }
547
+
548
+ .flock-preview p {
549
+ display: none;
550
+ }
551
+
552
+ .flock-reroll {
553
+ margin-top: 7px;
554
+ }
555
+
556
+ .flock-form {
557
+ min-height: 470px;
558
+ padding: 20px;
559
+ }
560
+
561
+ .flock-form h1 {
562
+ font-size: var(--frock-text-2xl);
563
+ }
564
+
565
+ .flock-select-grid {
566
+ grid-template-columns: 1fr;
567
+ }
568
+
569
+ .flock-actions {
570
+ position: sticky;
571
+ right: auto;
572
+ bottom: 0;
573
+ justify-content: flex-end;
574
+ margin-top: 18px;
575
+ padding: 10px 0;
576
+ background: var(--frock-surface);
577
+ }
578
+ }
579
+
580
+ /*
581
+ * Unread. A row goes bold and carries a count; the Hidden group carries one
582
+ * aggregate badge, because a hidden Bot has no row to put one on.
583
+ */
584
+ .flock-bot-row.unread .flock-bot-copy strong {
585
+ color: var(--frock-text);
586
+ font-weight: 700;
587
+ }
588
+
589
+ .flock-bot-row.unread .flock-bot-copy small {
590
+ color: var(--frock-text);
591
+ }
592
+
593
+ .flock-unread-badge {
594
+ display: inline-flex;
595
+ min-width: 18px;
596
+ align-items: center;
597
+ justify-content: center;
598
+ border-radius: var(--frock-radius-control);
599
+ background: var(--frock-action-primary);
600
+ padding: 0 5px;
601
+ color: var(--frock-on-accent);
602
+ font-size: var(--frock-text-xs);
603
+ font-weight: 600;
604
+ line-height: 18px;
605
+ }
606
+
607
+ .flock-hidden-toggle {
608
+ display: inline-flex;
609
+ align-items: center;
610
+ gap: 6px;
611
+ }
package/src/env.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ declare module "*.vue" {
2
+ import type { DefineComponent } from "vue";
3
+ const component: DefineComponent<
4
+ Record<string, never>,
5
+ Record<string, never>,
6
+ unknown
7
+ >;
8
+ export default component;
9
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from "./shared.js";
2
+ export * from "./user.js";
3
+ export * from "./bot.js";
4
+ export * from "./backend.js";
@@ -0,0 +1,3 @@
1
+ import manifest from "../frockbot.json" with { type: "json" };
2
+
3
+ export default manifest;
@@ -0,0 +1,12 @@
1
+ import { expect, test } from "bun:test";
2
+ // Package conventions are verified through the production manifest surface.
3
+ import { verifyPluginPackage } from "@frockbot/plugin-testkit";
4
+ import manifest from "../frockbot.json" with { type: "json" };
5
+ import packageJson from "../package.json" with { type: "json" };
6
+
7
+ test("Flock satisfies built-in Package conventions", () => {
8
+ expect(verifyPluginPackage({ packageJson, manifest })).toMatchObject({
9
+ name: "@frockbot/plugin-flock",
10
+ contributionKinds: ["backend", "runtime", "client"],
11
+ });
12
+ });