bb-plugin-manifest 0.0.0-stage → 0.17.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 (85) hide show
  1. package/LICENSE +67 -0
  2. package/PLUGIN_OVERVIEW.md +28 -0
  3. package/README.md +124 -2
  4. package/app.tsx +90 -0
  5. package/components/ui/button.tsx +59 -0
  6. package/components/ui/card.tsx +83 -0
  7. package/components/ui/checkbox.tsx +29 -0
  8. package/components/ui/coarse-pointer-sizing.ts +66 -0
  9. package/components/ui/dialog.tsx +419 -0
  10. package/components/ui/hooks/use-compact-viewport.tsx +37 -0
  11. package/components/ui/hooks/use-media-query.ts +70 -0
  12. package/components/ui/hooks/use-pointer-coarse.ts +7 -0
  13. package/components/ui/icon.tsx +8 -0
  14. package/components/ui/input.tsx +30 -0
  15. package/components/ui/motion.ts +4 -0
  16. package/components/ui/overlay-trigger.ts +84 -0
  17. package/components/ui/responsive-overlay.tsx +895 -0
  18. package/dist/app.css +2 -0
  19. package/dist/app.js +3 -0
  20. package/dist/app.meta.json +11 -0
  21. package/dist/package.json +1 -0
  22. package/dist/server.js +85 -0
  23. package/dist/server.js.map +6 -0
  24. package/dist/server.meta.json +11 -0
  25. package/focus.ts +196 -0
  26. package/hooks/useBrowserDimmingModal.ts +5 -0
  27. package/icons/dashboard.svg +1 -0
  28. package/icons/id-card.svg +1 -0
  29. package/icons/procurement.svg +1 -0
  30. package/icons/suppliers.svg +1 -0
  31. package/lib/mcp-client.ts +156 -0
  32. package/lib/portal-scope.ts +15 -0
  33. package/lib/tools.ts +842 -0
  34. package/lib/utils.ts +17 -0
  35. package/package.json +95 -4
  36. package/server.ts +1152 -0
  37. package/skills/manifest-outreach/SKILL.md +394 -0
  38. package/ui/CardTab.tsx +629 -0
  39. package/ui/CompanyPeek.tsx +277 -0
  40. package/ui/ConnectSection.tsx +85 -0
  41. package/ui/FilterSelect.tsx +113 -0
  42. package/ui/OutreachPage.tsx +102 -0
  43. package/ui/RegistryList.tsx +270 -0
  44. package/ui/SuppliersList.tsx +167 -0
  45. package/ui/dashboard/Accessory.tsx +15 -0
  46. package/ui/dashboard/DashboardPage.tsx +197 -0
  47. package/ui/dashboard/FilterBar.tsx +153 -0
  48. package/ui/dashboard/Widgets.tsx +410 -0
  49. package/ui/dashboard/state.ts +248 -0
  50. package/ui/directives.tsx +308 -0
  51. package/ui/hooks.ts +215 -0
  52. package/ui/labels.ts +199 -0
  53. package/ui/mail/CompanyMail.tsx +230 -0
  54. package/ui/mail/LetterView.tsx +134 -0
  55. package/ui/mail/MailPage.tsx +517 -0
  56. package/ui/mail/MailingView.tsx +324 -0
  57. package/ui/mail/TemplateEditor.tsx +393 -0
  58. package/ui/mail/attachments.tsx +296 -0
  59. package/ui/mail/common.tsx +291 -0
  60. package/ui/mail/hubTabs.ts +35 -0
  61. package/ui/mail/send.tsx +593 -0
  62. package/ui/manifest/index.tsx +122 -0
  63. package/ui/manifest/manifest.css +185 -0
  64. package/ui/map/CoverageMap.tsx +346 -0
  65. package/ui/map/world.ts +7 -0
  66. package/ui/procurement/CatalogDetail.tsx +98 -0
  67. package/ui/procurement/ChoiceTable.tsx +246 -0
  68. package/ui/procurement/CompanyAssortment.tsx +196 -0
  69. package/ui/procurement/Countries.tsx +530 -0
  70. package/ui/procurement/Matching.tsx +429 -0
  71. package/ui/procurement/NeedSheet.tsx +494 -0
  72. package/ui/procurement/Review.tsx +346 -0
  73. package/ui/procurement/file.ts +17 -0
  74. package/ui/procurement/grid.tsx +111 -0
  75. package/ui/procurement/nav.ts +17 -0
  76. package/ui/procurement/paths.ts +27 -0
  77. package/ui/suppliers.css +34 -0
  78. package/ui/types.ts +307 -0
  79. package/ui/workspace/Chips.tsx +214 -0
  80. package/ui/workspace/InboundView.tsx +119 -0
  81. package/ui/workspace/ObjectPanel.tsx +304 -0
  82. package/ui/workspace/compose.tsx +88 -0
  83. package/ui/workspace/intent.ts +97 -0
  84. package/ui/workspace/nav.tsx +82 -0
  85. package/ui/workspace/state.ts +289 -0
package/LICENSE ADDED
@@ -0,0 +1,67 @@
1
+ Manifest Plugins for bb — Proprietary License
2
+
3
+ Copyright (c) 2026 Dmitry Petrakov. All rights reserved.
4
+
5
+ This repository and all files in it (the "Software") are proprietary. The Software is
6
+ not open source. Its source code is published only so that authorized users can
7
+ install it in bb from a public URL.
8
+
9
+ 1. Permitted use
10
+
11
+ You may download, install and run the Software only if you are:
12
+
13
+ a) a user authorized by the copyright holder, or
14
+ b) an employee or contractor of an organization that has a valid agreement with
15
+ the copyright holder for the Manifest service,
16
+
17
+ and only to access a Manifest instance provided under such an agreement, for as
18
+ long as the agreement is in force.
19
+
20
+ You may view the source code on GitHub to the extent allowed by the GitHub Terms
21
+ of Service.
22
+
23
+ 2. Restrictions
24
+
25
+ Except as expressly permitted above, you may not, without prior written permission
26
+ of the copyright holder:
27
+
28
+ a) copy, modify, adapt, translate or create derivative works of the Software;
29
+ b) distribute, publish, sublicense, sell, rent, lend or otherwise transfer the
30
+ Software or any part of it to any third party;
31
+ c) use the Software, in whole or in part, with any system other than Manifest, or
32
+ to build a competing product or service;
33
+ d) remove or alter this notice or any copyright notice in the Software.
34
+
35
+ 3. Ownership
36
+
37
+ The Software is licensed, not sold. The copyright holder retains all rights,
38
+ title and interest in the Software. No rights are granted by implication or
39
+ estoppel beyond those stated in section 1.
40
+
41
+ 4. Third-party components
42
+
43
+ Third-party packages used by the Software are licensed under their own terms,
44
+ as stated in their respective packages. This license does not apply to them.
45
+
46
+ 5. Termination
47
+
48
+ This license ends automatically when your authorization or your organization's
49
+ agreement ends, or if you breach any of its terms. On termination you must stop
50
+ using the Software and delete all copies in your possession.
51
+
52
+ 6. No warranty
53
+
54
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
56
+ FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT, EXCEPT AS EXPRESSLY AGREED IN A
57
+ SEPARATE WRITTEN AGREEMENT WITH THE COPYRIGHT HOLDER.
58
+
59
+ 7. Limitation of liability
60
+
61
+ TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
62
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
63
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
64
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
65
+
66
+ For licensing questions, contact the copyright holder through
67
+ https://github.com/dpetrakov.
@@ -0,0 +1,28 @@
1
+ Работайте с реестром потенциальных поставщиков Manifest прямо в BB: список слева,
2
+ карточка организации справа, чат с агентом по карточке в центре, а на отдельной
3
+ странице — дашборд аутрича с темами-чатами.
4
+
5
+ ## Что вы получаете
6
+
7
+ - Реестр поставщиков по регионам и странам с приоритетом работы, поиском и фильтрами.
8
+ - Карточку организации: реквизиты, каналы связи, контактные лица, статус, касания,
9
+ следующий шаг, ответственный и комментарии — в пределах ваших прав в Manifest.
10
+ - **Дашборд аутрича**: очередь «Сегодня» (ждут нашего ответа, просрочено, на сегодня,
11
+ готовы и не тронуты), воронка с оттоком по причинам, регионы, матрица застоя,
12
+ качество данных и лента «что изменилось с прошлого визита».
13
+ - **Темы** — несколько чатов с агентом на дашборде, у каждой свой фильтр. Агент
14
+ показывает выборку на дашборде, выводит живые списки организаций и готовит правки
15
+ пачками: применяете и откатываете вы кнопкой.
16
+ - Счётчик «ждут ответа + просрочено» на вкладке «Поставщики» и пункте дашборда.
17
+
18
+ ## Как это работает
19
+
20
+ Данные, расчёт метрик и права живут в Manifest. Плагин подключается к нему по адресу,
21
+ email и паролю для плагина; пароль один раз обменивается на токен. Каждое изменение
22
+ агента видно в истории с пометкой «агент BB». Отозвать доступ можно в Manifest.
23
+
24
+ ## Для агентов
25
+
26
+ В чате организации и в темах дашборда агенту доступны инструменты `outreach_*`;
27
+ навык `manifest-outreach` описывает их, директивы `::manifest-companies` и
28
+ `::manifest-batch` и правило: массовые правки применяет человек.
package/README.md CHANGED
@@ -1,3 +1,125 @@
1
- # Temporary Holding Version
1
+ # manifest — Manifest outreach workspace for bb
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A [bb](https://github.com/get-bb/bb) plugin that connects bb to **Manifest**, a private
4
+ operations service, and gives the team its supplier outreach workspace inside bb. The
5
+ plugin interface and the agent skill are in Russian.
6
+
7
+ - **Left: registry.** The plugin's own sidebar list «Потенциальные поставщики»
8
+ (“Potential suppliers”): search and filters by region, country (with search inside
9
+ the list), priority and status. A button in the sidebar footer, tinted in Manifest's
10
+ soft green, switches the sidebar between the suppliers and the previous list;
11
+ opening «Аутрич» (“Outreach”) switches it on by itself.
12
+ - **Right: card.** The «Карточка» (“Card”) tab: company details, countries, contact
13
+ channels, contact persons, status, priority, comments and change history. Editing
14
+ requires the `outreach.manage` permission in Manifest.
15
+ - **Middle: chat.** A bb thread bound to the company. The agent reads and edits it
16
+ with Manifest tools within the user's permissions; each change is recorded in the
17
+ history as «агент BB» (“bb agent”).
18
+
19
+ - **Dashboard (0.2.0).** The «Дашборд аутрича» page: today queue, funnel, regions,
20
+ stagnation matrix, data quality and recent changes, with several topic chats. The
21
+ topic agent filters the dashboard, shows live company lists and prepares bulk edits
22
+ that a person applies or reverts.
23
+
24
+ Manifest is the MCP server and the only source of data and permissions. The plugin
25
+ keeps just an access token (a secret setting on the bb backend); the password is used
26
+ once to sign in.
27
+
28
+ ## Install
29
+
30
+ Install the prebuilt package through the CLI connected to your bb server. An
31
+ agent can run this command on an enrolled machine: the CLI asks the bb server
32
+ to download and install the package on the server's computer.
33
+
34
+ ```sh
35
+ bb plugin install npm:bb-plugin-manifest@latest
36
+ ```
37
+
38
+ This route does not need Git or Xcode Command Line Tools. The first npm release
39
+ is 0.17.0. The existing Git source is also supported (and requires Git):
40
+
41
+ ```sh
42
+ bb plugin install https://github.com/dpetrakov/manifest-bb-plugins --plugin manifest
43
+ ```
44
+
45
+ Then open *Settings → Plugins → Manifest → «Подключение к Manifest»* (“Connection to
46
+ Manifest”) and enter the Manifest URL, your email and your plugin password. The
47
+ password is set in Manifest by an administrator («Пользователи и права» → «Плагин BB»)
48
+ or by yourself (click your name at the bottom of the Manifest menu).
49
+
50
+ ## Layout
51
+
52
+ | Path | What it is |
53
+ |---|---|
54
+ | `server.ts` | Backend: settings, sign-in and sign-out, RPC for the panels, agent tools, agent configuration per company thread. |
55
+ | `app.tsx` | UI slots: sidebar list and its footer button, navigation pages, «Карточка» tab, directives, settings section. |
56
+ | `lib/mcp-client.ts` | Minimal MCP client over HTTPS (`tools/call`, Bearer token, actor kind header). |
57
+ | `lib/tools.ts` | Agent tool schemas and the list of tools available to panels. |
58
+ | `ui/` | React components: registry list, filters, card, connection settings; `SuppliersList.tsx` and `suppliers.css` — the sidebar list, its switch and the footer button tone. |
59
+ | `ui/dashboard/` | The outreach dashboard: page, widgets, topic filter, attention counter. |
60
+ | `ui/directives.tsx` | Message directives `::manifest-companies` and `::manifest-batch`. |
61
+ | `skills/manifest-outreach/` | Agent skill: registry rules and tool usage. |
62
+ | `PLUGIN_OVERVIEW.md` | Description shown inside bb (in Russian). |
63
+ | `tests/` | vitest (backend on a fake plugin host, UI with `renderSlot`) and `node:test` (MCP client). |
64
+
65
+ ## Development
66
+
67
+ ```sh
68
+ npm ci
69
+ npm run check # tsc --noEmit + vitest + node:test
70
+ bb plugin build . # dist/
71
+
72
+ # Optional: check the contract against a running Manifest
73
+ MANIFEST_URL=https://manifest.example.com MANIFEST_EMAIL=you@example.com MANIFEST_PASSWORD=… \
74
+ node --experimental-strip-types --test tests/mcp-client.test.mjs
75
+ ```
76
+
77
+ The plugin is developed together with Manifest and published to
78
+ [manifest-bb-plugins](https://github.com/dpetrakov/manifest-bb-plugins) by a release
79
+ script. The Manifest contract is version 1 (`manifest_whoami.contract`); on a mismatch
80
+ the plugin asks to be updated instead of failing.
81
+
82
+ ### Publishing a prebuilt npm package
83
+
84
+ Keep the package name `bb-plugin-manifest` so the bb plugin id stays `manifest`.
85
+ The `files` allowlist includes the built bundles, their metadata, the plugin
86
+ sources, icons, skill, and proprietary license. Tests and local settings are
87
+ excluded. `npm pack` runs `prepack` to rebuild bundles for the package version.
88
+
89
+ ```sh
90
+ npm run check
91
+ npm pack --dry-run
92
+ npm pack --pack-destination /absolute/path/to/release
93
+ ```
94
+
95
+ Inspect the archive before publishing. It must contain `dist/server.js`,
96
+ `dist/server.meta.json`, `dist/app.js`, `dist/app.meta.json`, and `dist/app.css`;
97
+ both metadata files must match the package id and version. Log in with
98
+ `npm login --auth-type=web --registry=https://registry.npmjs.org/`, then publish
99
+ the reviewed archive:
100
+
101
+ ```sh
102
+ npm publish /absolute/path/to/release/bb-plugin-manifest-X.Y.Z.tgz --access public --registry=https://registry.npmjs.org/
103
+ ```
104
+
105
+ Complete any npm authentication prompt yourself. A successful `npm publish`
106
+ exit alone does not prove availability: the first release can temporarily show
107
+ only a `0.0.0-stage` placeholder. Check that the actual version is visible,
108
+ `latest` points to it, and `dist.integrity` matches the reviewed archive:
109
+
110
+ ```sh
111
+ npm view bb-plugin-manifest@X.Y.Z version dist.integrity
112
+ npm view bb-plugin-manifest dist-tags
113
+ ```
114
+
115
+ If a version is staged for maintainer approval, use the npm website or
116
+ `npm stage list` and `npm stage approve` (requires npm 11.15+ and 2FA). Do not
117
+ publish the same version again to work around a pending release. After checking
118
+ the registry, test a fresh npm install in a separate bb server.
119
+ Every subsequent release needs a new version. Users installed with `@latest` update with
120
+ `bb plugin update manifest`. An existing Git installation keeps tracking Git;
121
+ do not remove it just to switch sources, because removal deletes its settings.
122
+
123
+ ## License
124
+
125
+ Proprietary, not open source. See [LICENSE](https://github.com/dpetrakov/manifest-bb-plugins/blob/main/LICENSE).
package/app.tsx ADDED
@@ -0,0 +1,90 @@
1
+ // bb-plugin-manifest — frontend (EP-069..EP-071, docs/outreach/bb-plugin.md).
2
+ //
3
+ // Left: «Потенциальные поставщики» — the plugin's own sidebar thread list, switched
4
+ // on by a footer button (and by the «Аутрич» section); the button returns the
5
+ // previous list. No sidebar-tabs host since 0.5.0.
6
+ // W-18 (ADR-049): chats are native BB threads; the object of a thread (organisation,
7
+ // mailing, template, topic, inbound) is a tab of the thread's side panel. Plugin pages
8
+ // are pults: lists, an object on the whole screen, its chats and «Новый чат».
9
+ // «Дашборд аутрича» (W-15): metrics, queue and topic chats; directives render
10
+ // live company lists and batch cards inside the agent's messages.
11
+ import { definePluginApp } from "@get-bb/plugin-sdk/app";
12
+ import { ConnectSection } from "./ui/ConnectSection";
13
+ import { PANEL_ID, PANEL_PATH } from "./ui/hooks";
14
+ import { OutreachPage } from "./ui/OutreachPage";
15
+ import { FOOTER_LABEL, SuppliersList, SuppliersSwitch, requestSuppliersToggle } from "./ui/SuppliersList";
16
+ import "./ui/suppliers.css";
17
+ import "./ui/manifest/manifest.css";
18
+ import { DashboardPage } from "./ui/dashboard/DashboardPage";
19
+ import { AttentionAccessory } from "./ui/dashboard/Accessory";
20
+ import { DASHBOARD_ID, DASHBOARD_PATH } from "./ui/dashboard/state";
21
+ import { BatchDirective, CompaniesDirective } from "./ui/directives";
22
+ import { MailPage } from "./ui/mail/MailPage";
23
+ import { LetterChip, MailingChip } from "./ui/workspace/Chips";
24
+ import { MAIL_ID, MAIL_PATH } from "./ui/mail/common";
25
+ import { NeedsPage } from "./ui/procurement/NeedSheet";
26
+ import { NEEDS_ID, NEEDS_PATH } from "./ui/procurement/paths";
27
+ import { FocusHeader, ObjectPanel } from "./ui/workspace/ObjectPanel";
28
+ import { BESIDE_NEW_PANEL, BESIDE_PANEL, OBJECT_PANEL } from "./ui/workspace/state";
29
+ import { ComposeBanner, NEW_COMPANY_PANEL, NewCompanyPanel } from "./ui/workspace/compose";
30
+
31
+ export default definePluginApp((app) => {
32
+ app.slots.navPanel({
33
+ id: PANEL_ID,
34
+ title: "Аутрич",
35
+ icon: "Globe",
36
+ path: PANEL_PATH,
37
+ component: OutreachPage,
38
+ });
39
+ // W-15: дашборд аутрича с темами-чатами; карточка — по цели вкладки.
40
+ app.slots.navPanel({
41
+ id: DASHBOARD_ID,
42
+ title: "Дашборд аутрича",
43
+ icon: "manifest/dashboard",
44
+ path: DASHBOARD_PATH,
45
+ component: DashboardPage,
46
+ experimental_sidebarAccessory: AttentionAccessory,
47
+ });
48
+ // W-16: почта — шаблоны (с чатом по шаблону), юрлица и отправители, неразобранные входящие.
49
+ app.slots.navPanel({ id: MAIL_ID, title: "Почта аутрича", icon: "Mail", path: MAIL_PATH, component: MailPage });
50
+ // ADR-051 (W-19): what we need — the procurement sheet, as an object beside a chat.
51
+ app.slots.navPanel({ id: NEEDS_ID, title: "Закупочный лист", icon: "manifest/procurement", path: NEEDS_PATH, component: NeedsPage });
52
+ app.slots.messageDirective({ id: "manifest-companies", component: CompaniesDirective });
53
+ app.slots.messageDirective({ id: "manifest-batch", component: BatchDirective });
54
+ // W-17: письмо организации «как уйдёт» — черновик из Manifest, обновляется после правки агента.
55
+ app.slots.messageDirective({ id: "manifest-letter", component: LetterChip });
56
+ // W-17: рассылка — одно письмо, много получателей, письмо каждого «как уйдёт».
57
+ app.slots.messageDirective({ id: "manifest-mailing", component: MailingChip });
58
+ // Список поставщиков в сайдбаре и кнопка-переключатель в подвале (цвет — suppliers.css).
59
+ app.slots.experimental_threadList({
60
+ id: "suppliers",
61
+ title: "Потенциальные поставщики",
62
+ description: "Реестр Manifest вместо списка тредов; кнопка в подвале возвращает прежний список.",
63
+ component: SuppliersList,
64
+ });
65
+ app.slots.experimental_appOverlay({ id: "suppliers-switch", component: SuppliersSwitch });
66
+ app.experimental_sidebarFooter.register({
67
+ kind: "action",
68
+ id: "suppliers",
69
+ label: FOOTER_LABEL,
70
+ icon: "manifest/suppliers",
71
+ onActivate: requestSuppliersToggle,
72
+ });
73
+ // W-18 (ADR-049): объект треда — во вкладке боковой панели родного треда BB; кнопка в
74
+ // шапке треда показывает, что открыто, и сама открывает панель.
75
+ app.slots.threadPanelAction({ id: OBJECT_PANEL, title: "Manifest", icon: "manifest/id-card", layout: "flush", component: ObjectPanel });
76
+ app.slots.experimental_threadHeaderAction({ id: "focus", title: "Объект Manifest", component: FocusHeader });
77
+ // Организация без чата открывается экраном нового треда BB: карточка — в его боковой
78
+ // панели, над полем — баннер; первое сообщение создаёт тред, привязанный к организации.
79
+ app.slots.experimental_newThreadPanelAction({ id: NEW_COMPANY_PANEL, title: "Manifest", icon: "manifest/id-card", layout: "flush", component: NewCompanyPanel });
80
+ // A second object beside the main one (Cmd/Ctrl-click, «Рядом» in the list): its own tab.
81
+ app.slots.threadPanelAction({ id: BESIDE_PANEL, title: "Manifest · рядом", icon: "manifest/id-card", layout: "flush", component: ObjectPanel });
82
+ app.slots.experimental_newThreadPanelAction({ id: BESIDE_NEW_PANEL, title: "Manifest · рядом", icon: "manifest/id-card", layout: "flush", component: NewCompanyPanel });
83
+ app.composer.customize({ id: "company-intent", scopes: ["new-thread"], banners: [{ id: "company", chrome: "bare", component: ComposeBanner }] });
84
+ app.slots.settingsSection({
85
+ id: "connect",
86
+ title: "Подключение к Manifest",
87
+ description: "Вход по email и паролю для плагина; данные и права — в Manifest.",
88
+ component: ConnectSection,
89
+ });
90
+ });
@@ -0,0 +1,59 @@
1
+ import * as React from "react";
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+
5
+ import { cn } from "../../lib/utils";
6
+ import { CONTROL_HOVER_TRANSITION } from "./motion.js";
7
+
8
+ const buttonVariants = cva(
9
+ `inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ${CONTROL_HOVER_TRANSITION} focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_[data-icon-root]]:pointer-events-none [&_[data-icon-root]]:size-4 [&_[data-icon-root]]:shrink-0`,
10
+ {
11
+ variants: {
12
+ variant: {
13
+ default: "bg-foreground text-background hover:bg-foreground/90",
14
+ destructive:
15
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
16
+ outline:
17
+ "border border-input bg-transparent hover:bg-state-hover hover:text-foreground",
18
+ secondary:
19
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
20
+ ghost:
21
+ "hover:bg-state-hover hover:text-foreground aria-pressed:bg-state-active aria-pressed:text-foreground aria-pressed:hover:bg-state-active data-[state=open]:bg-state-active data-[state=open]:text-foreground data-[state=open]:hover:bg-state-active",
22
+ link: "text-primary underline-offset-4 hover:underline",
23
+ },
24
+ size: {
25
+ default: "h-9 px-4 py-2",
26
+ sm: "h-8 rounded-md px-3 text-xs",
27
+ lg: "h-10 rounded-md px-8",
28
+ icon: "h-9 w-9",
29
+ },
30
+ },
31
+ defaultVariants: {
32
+ variant: "default",
33
+ size: "default",
34
+ },
35
+ },
36
+ );
37
+
38
+ export interface ButtonProps
39
+ extends
40
+ Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "title">,
41
+ VariantProps<typeof buttonVariants> {
42
+ asChild?: boolean;
43
+ }
44
+
45
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
46
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
47
+ const Comp = asChild ? Slot : "button";
48
+ return (
49
+ <Comp
50
+ className={cn(buttonVariants({ variant, size, className }))}
51
+ ref={ref}
52
+ {...props}
53
+ />
54
+ );
55
+ },
56
+ );
57
+ Button.displayName = "Button";
58
+
59
+ export { Button, buttonVariants };
@@ -0,0 +1,83 @@
1
+ import * as React from "react";
2
+
3
+ import { cn } from "../../lib/utils";
4
+
5
+ const Card = React.forwardRef<
6
+ HTMLDivElement,
7
+ React.HTMLAttributes<HTMLDivElement>
8
+ >(({ className, ...props }, ref) => (
9
+ <div
10
+ ref={ref}
11
+ className={cn(
12
+ "rounded-lg border border-border bg-card text-card-foreground",
13
+ className,
14
+ )}
15
+ {...props}
16
+ />
17
+ ));
18
+ Card.displayName = "Card";
19
+
20
+ const CardHeader = React.forwardRef<
21
+ HTMLDivElement,
22
+ React.HTMLAttributes<HTMLDivElement>
23
+ >(({ className, ...props }, ref) => (
24
+ <div
25
+ ref={ref}
26
+ className={cn("flex flex-col space-y-1.5 p-6", className)}
27
+ {...props}
28
+ />
29
+ ));
30
+ CardHeader.displayName = "CardHeader";
31
+
32
+ const CardTitle = React.forwardRef<
33
+ HTMLDivElement,
34
+ React.HTMLAttributes<HTMLDivElement>
35
+ >(({ className, ...props }, ref) => (
36
+ <div
37
+ ref={ref}
38
+ className={cn("font-semibold leading-none tracking-tight", className)}
39
+ {...props}
40
+ />
41
+ ));
42
+ CardTitle.displayName = "CardTitle";
43
+
44
+ const CardDescription = React.forwardRef<
45
+ HTMLDivElement,
46
+ React.HTMLAttributes<HTMLDivElement>
47
+ >(({ className, ...props }, ref) => (
48
+ <div
49
+ ref={ref}
50
+ className={cn("text-sm text-muted-foreground", className)}
51
+ {...props}
52
+ />
53
+ ));
54
+ CardDescription.displayName = "CardDescription";
55
+
56
+ const CardContent = React.forwardRef<
57
+ HTMLDivElement,
58
+ React.HTMLAttributes<HTMLDivElement>
59
+ >(({ className, ...props }, ref) => (
60
+ <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
61
+ ));
62
+ CardContent.displayName = "CardContent";
63
+
64
+ const CardFooter = React.forwardRef<
65
+ HTMLDivElement,
66
+ React.HTMLAttributes<HTMLDivElement>
67
+ >(({ className, ...props }, ref) => (
68
+ <div
69
+ ref={ref}
70
+ className={cn("flex items-center p-6 pt-0", className)}
71
+ {...props}
72
+ />
73
+ ));
74
+ CardFooter.displayName = "CardFooter";
75
+
76
+ export {
77
+ Card,
78
+ CardHeader,
79
+ CardFooter,
80
+ CardTitle,
81
+ CardDescription,
82
+ CardContent,
83
+ };
@@ -0,0 +1,29 @@
1
+ import * as React from "react";
2
+ import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
3
+
4
+ import { cn } from "../../lib/utils";
5
+ import { CONTROL_HOVER_TRANSITION } from "./motion.js";
6
+ import { Icon } from "../../components/ui/icon.js";
7
+
8
+ const Checkbox = React.forwardRef<
9
+ React.ComponentRef<typeof CheckboxPrimitive.Root>,
10
+ React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
11
+ >(({ className, ...props }, ref) => (
12
+ <CheckboxPrimitive.Root
13
+ ref={ref}
14
+ className={cn(
15
+ `peer size-4 shrink-0 rounded-sm border border-input shadow-xs ${CONTROL_HOVER_TRANSITION} focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-foreground data-[state=checked]:bg-foreground data-[state=checked]:text-background`,
16
+ className,
17
+ )}
18
+ {...props}
19
+ >
20
+ <CheckboxPrimitive.Indicator
21
+ className={cn("flex items-center justify-center text-current")}
22
+ >
23
+ <Icon name="Check" className="size-3.5" />
24
+ </CheckboxPrimitive.Indicator>
25
+ </CheckboxPrimitive.Root>
26
+ ));
27
+ Checkbox.displayName = CheckboxPrimitive.Root.displayName;
28
+
29
+ export { Checkbox };
@@ -0,0 +1,66 @@
1
+ export const COARSE_POINTER_TEXT_BASE_CLASS =
2
+ "text-sm max-md:pointer-coarse:text-base";
3
+
4
+ export const COARSE_POINTER_TEXT_SM_CLASS =
5
+ "text-xs max-md:pointer-coarse:text-sm";
6
+
7
+ export const COARSE_POINTER_ICON_SIZE_CLASS =
8
+ "size-4 max-md:pointer-coarse:size-5";
9
+
10
+ export const COARSE_POINTER_ICON_SIZE_SHRINK_CLASS =
11
+ "size-4 shrink-0 max-md:pointer-coarse:size-5";
12
+
13
+ export const COARSE_POINTER_COMPACT_ICON_SIZE_CLASS =
14
+ "size-3.5 max-md:pointer-coarse:size-5";
15
+
16
+ export const COARSE_POINTER_COMPACT_ICON_SIZE_SHRINK_CLASS =
17
+ "size-3.5 shrink-0 max-md:pointer-coarse:size-5";
18
+
19
+ export const COARSE_POINTER_DOT_SIZE_CLASS =
20
+ "size-1.5 max-md:pointer-coarse:size-2";
21
+
22
+ export const COARSE_POINTER_GLYPH_BOX_CLASS =
23
+ "h-4 w-4 max-md:pointer-coarse:h-5 max-md:pointer-coarse:w-5";
24
+
25
+ export const COARSE_POINTER_CHECK_SLOT_CLASS =
26
+ "h-3.5 w-3.5 max-md:pointer-coarse:h-5 max-md:pointer-coarse:w-5";
27
+
28
+ const HEADER_ICON_BUTTON_BOX_CLASS =
29
+ "h-[28px] w-[28px] rounded-md p-0 max-md:pointer-coarse:h-[36px] max-md:pointer-coarse:w-[36px]";
30
+
31
+ export const COARSE_POINTER_HEADER_ICON_BUTTON_CLASS = `${HEADER_ICON_BUTTON_BOX_CLASS} [&_[data-icon-root]]:size-[16px] max-md:pointer-coarse:[&_[data-icon-root]]:size-[20px]`;
32
+
33
+ export const COARSE_POINTER_HEADER_REDUCED_GLYPH_ICON_BUTTON_CLASS = `${HEADER_ICON_BUTTON_BOX_CLASS} [&_[data-icon-root]]:size-[13px] max-md:pointer-coarse:[&_[data-icon-root]]:size-[16px]`;
34
+
35
+ export const COARSE_POINTER_COMPACT_ICON_BUTTON_CLASS =
36
+ "h-7 w-7 rounded-md p-0 [&_[data-icon-root]]:size-3.5 max-md:pointer-coarse:h-9 max-md:pointer-coarse:w-9 max-md:pointer-coarse:[&_[data-icon-root]]:size-5";
37
+
38
+ export const COARSE_POINTER_CHILD_ICON_BUTTON_CLASS =
39
+ "h-8 w-8 justify-center p-0 [&>[data-icon-root]]:size-4 max-md:pointer-coarse:h-9 max-md:pointer-coarse:w-9 max-md:pointer-coarse:[&>[data-icon-root]]:size-5";
40
+
41
+ export const COARSE_POINTER_TOOLBAR_ACTION_BUTTON_CLASS =
42
+ "h-7 rounded-md border-border bg-transparent px-2 text-xs font-medium text-foreground shadow-none hover:bg-state-hover hover:text-foreground max-md:pointer-coarse:h-9";
43
+
44
+ export const COARSE_POINTER_PROMPT_ACTION_BUTTON_CLASS =
45
+ "h-8 px-2 transition-all max-md:pointer-coarse:h-10 max-md:pointer-coarse:px-3";
46
+
47
+ export const COARSE_POINTER_PROMPT_ICON_ACTION_BUTTON_CLASS =
48
+ "size-auto h-8 px-2 transition-all max-md:pointer-coarse:h-10 max-md:pointer-coarse:px-3";
49
+
50
+ export const COARSE_POINTER_PROMPT_COMBO_BUTTON_CLASS =
51
+ "h-8 w-8 rounded-l-none border-l border-l-primary-foreground/20 px-0 transition-all hover:border-l-primary-foreground/30 max-md:pointer-coarse:h-10 max-md:pointer-coarse:w-10";
52
+
53
+ export const COARSE_POINTER_INPUT_HEIGHT_CLASS =
54
+ "h-9 max-md:pointer-coarse:h-10";
55
+
56
+ export const COARSE_POINTER_COMPACT_ROW_HEIGHT_CLASS =
57
+ "h-7 max-md:pointer-coarse:h-9";
58
+
59
+ export const COARSE_POINTER_ROW_HEIGHT_CLASS =
60
+ "h-[var(--bb-sidebar-row-height)] max-md:pointer-coarse:h-[var(--bb-sidebar-row-height-coarse)]";
61
+
62
+ export const COARSE_POINTER_PROVIDER_TAB_SIZE_CLASS =
63
+ "h-7 w-6 max-md:pointer-coarse:h-9 max-md:pointer-coarse:w-9";
64
+
65
+ export const COARSE_POINTER_ROW_ACTION_SIZE_CLASS =
66
+ "h-7 w-7 max-md:pointer-coarse:h-9 max-md:pointer-coarse:w-9";