diff --git a/nix/web.nix b/nix/web.nix index 690acb7e370..0a2039a1012 100644 --- a/nix/web.nix +++ b/nix/web.nix @@ -4,7 +4,7 @@ let src = ../web; npmDeps = pkgs.fetchNpmDeps { inherit src; - hash = "sha256-FL2E8Vv8gyeClEa5b/pHn/ekWoHWTd4YwzV6zhLEos4="; + hash = "sha256-GxSmEpclOwmv94KmGMediPITxqXAsxqTEQOoDIbYkUw="; }; npm = hermesNpmLib.mkNpmPassthru { folder = "web"; attr = "web"; pname = "hermes-web"; }; diff --git a/plugins/kanban/dashboard/dist/index.js b/plugins/kanban/dashboard/dist/index.js index 7f2fd573e74..9a04b6a649e 100644 --- a/plugins/kanban/dashboard/dist/index.js +++ b/plugins/kanban/dashboard/dist/index.js @@ -24,6 +24,23 @@ const { useState, useEffect, useCallback, useMemo, useRef } = SDK.hooks; const { cn, timeAgo } = SDK.utils; + // Newer host dashboards expose a DS-styled Checkbox on the plugin SDK. + // Fall back to a native shim so older hosts that + // predate the design-system rollout still render. The shim normalises + // Radix's onCheckedChange(checked) signature to native onChange(event). + const Checkbox = SDK.components.Checkbox || function (props) { + const { checked, onCheckedChange, className, onClick, ...rest } = props; + return h("input", Object.assign({ + type: "checkbox", + checked: !!checked, + className: className, + onClick: onClick, + onChange: function (e) { + if (onCheckedChange) onCheckedChange(e.target.checked); + }, + }, rest)); + }; + // useI18n is a hook each component calls locally. Older host dashboards // may not expose it yet; fall back to a shim so the bundle still renders // English against an older host SDK. English fallback strings live @@ -1648,11 +1665,10 @@ h(Label, { className: "text-xs text-muted-foreground" }, "Orchestration mode"), h("label", { className: "flex items-center gap-2 text-xs h-8" }, - h("input", { - type: "checkbox", + h(Checkbox, { checked: !!settings.auto_decompose, - onChange: function (e) { - saveSettings({ auto_decompose: !!e.target.checked }); + onCheckedChange: function (checked) { + saveSettings({ auto_decompose: checked === true }); }, }), "Auto-decompose triage tasks", @@ -1908,10 +1924,9 @@ }), ), h("label", { className: "flex items-center gap-2 text-xs" }, - h("input", { - type: "checkbox", + h(Checkbox, { checked: switchTo, - onChange: function (e) { setSwitchTo(e.target.checked); }, + onCheckedChange: function (checked) { setSwitchTo(checked === true); }, }), tx(t, "switchAfterCreate", "Switch to this board after creating it"), ), @@ -1981,19 +1996,17 @@ ), h("label", { className: "flex items-center gap-2 text-xs", title: "Include archived tasks in the board view. Archived tasks are hidden by default." }, - h("input", { - type: "checkbox", + h(Checkbox, { checked: props.includeArchived, - onChange: function (e) { props.setIncludeArchived(e.target.checked); }, + onCheckedChange: function (checked) { props.setIncludeArchived(checked === true); }, }), tx(t, "showArchived", "Show archived"), ), h("label", { className: "flex items-center gap-2 text-xs", title: "Group the Running column by assigned profile" }, - h("input", { - type: "checkbox", + h(Checkbox, { checked: props.laneByProfile, - onChange: function (e) { props.setLaneByProfile(e.target.checked); }, + onCheckedChange: function (checked) { props.setLaneByProfile(checked === true); }, }), tx(t, "lanesByProfile", "Lanes by profile"), ), @@ -2122,10 +2135,9 @@ }, tx(t, "apply", "Apply")), ), h("label", { className: "hermes-kanban-bulk-reclaim-first", title: "Reclaim any active claims before reassigning" }, - h("input", { - type: "checkbox", + h(Checkbox, { checked: reclaimFirst, - onChange: function (e) { setReclaimFirst(e.target.checked); }, + onCheckedChange: function (checked) { setReclaimFirst(checked === true); }, }), "Reclaim first", ), @@ -2313,14 +2325,12 @@ }, h("div", { className: "hermes-kanban-column-header", title: colHelp || "" }, - h("input", { - type: "checkbox", + h(Checkbox, { className: "hermes-kanban-col-check", title: "Select all tasks in this column", "aria-label": `Select all tasks in ${colLabel || props.column.name}`, checked: props.column.tasks.length > 0 && props.column.tasks.every(function (t) { return props.selectedIds.has(t.id); }), - onChange: function (e) { - e.stopPropagation(); + onCheckedChange: function () { if (props.selectAllInColumn) props.selectAllInColumn(props.column.name); }, onClick: function (e) { e.stopPropagation(); }, @@ -2461,8 +2471,7 @@ if (props.toggleSelected) props.toggleSelected(t.id, false); } }; - const handleCheckbox = function (e) { - e.stopPropagation(); + const handleCheckedChange = function () { props.toggleSelected(t.id, true); }; @@ -2495,11 +2504,10 @@ title: tx(i18n, "selectForBulk", "Select for bulk actions"), onClick: function (e) { e.stopPropagation(); }, }, - h("input", { - type: "checkbox", + h(Checkbox, { className: "hermes-kanban-card-check", checked: props.selected, - onChange: handleCheckbox, + onCheckedChange: handleCheckedChange, onClick: function (e) { e.stopPropagation(); }, "aria-label": `Select task ${t.id}`, }), diff --git a/web/package-lock.json b/web/package-lock.json index 171ccf9e0bc..e8990b61ab1 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -8,7 +8,7 @@ "name": "web", "version": "0.0.0", "dependencies": { - "@nous-research/ui": "0.14.0", + "@nous-research/ui": "^0.14.2", "@observablehq/plot": "^0.6.17", "@react-three/fiber": "^9.6.0", "@tailwindcss/vite": "^4.2.1", @@ -1081,12 +1081,13 @@ } }, "node_modules/@nous-research/ui": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@nous-research/ui/-/ui-0.14.0.tgz", - "integrity": "sha512-tfpE6jGOxE5oVBab/dTSepOudy/+Xep3gJ6NCFriYJvdtQBGXcqsi4mCaVPiNNaS/ZFf4/10dnl/oJTb6DtLKg==", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@nous-research/ui/-/ui-0.14.2.tgz", + "integrity": "sha512-H3cMt2e0IpmcTNOmR6zVX+8ja48w4X4F/IFXhWCpaoVs8zKVRN12Ryb4RnX/ac8IrbUu6UsIds7ZtmXxPHcfdQ==", "license": "MIT", "dependencies": { "@nanostores/react": "^1.1.0", + "@radix-ui/react-checkbox": "^1.3.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "nanostores": "^1.3.0", @@ -1208,6 +1209,77 @@ } } }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", @@ -1670,6 +1742,21 @@ } } }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-rect": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", @@ -3648,6 +3735,12 @@ "node": ">=12" } }, + "node_modules/dayjs": { + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", + "license": "MIT" + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -4193,6 +4286,33 @@ "node": ">=0.10.0" } }, + "node_modules/framer-motion": { + "version": "12.39.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.39.0.tgz", + "integrity": "sha512-+vnLfzrv0MzjLzNl+nvNvR7jdg3q4cxxjz/YvzfifHl0TREtL00cs1RoMTxs+1PzLiEqZGV6gYsBY0oEAYZ24w==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.39.0", + "motion-utils": "^12.39.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -4564,6 +4684,15 @@ "json-buffer": "3.0.1" } }, + "node_modules/launder": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/launder/-/launder-1.7.1.tgz", + "integrity": "sha512-mU6WRz5EusL9ZZuiZ5SO4Y6C0P9PAUR9iwdb6bzj4KDihm28DiHFw+/yk9DBH4f+Pv1wuzQ4e2jV3oQ7mkIqvw==", + "license": "MIT", + "dependencies": { + "dayjs": "^1.11.7" + } + }, "node_modules/leva": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/leva/-/leva-0.10.1.tgz", @@ -4972,6 +5101,48 @@ "node": ">=0.10.0" } }, + "node_modules/motion": { + "version": "12.39.0", + "resolved": "https://registry.npmjs.org/motion/-/motion-12.39.0.tgz", + "integrity": "sha512-H4a+Ze+a9j+/NTla5ezfb/g9vmIOxC+viDj++NGDZyTZkdRKjiOz3kSv6TalRWM8ZmD2y/CfC6TkQc97ybyqSA==", + "license": "MIT", + "peer": true, + "dependencies": { + "framer-motion": "^12.39.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/motion-dom": { + "version": "12.39.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.39.0.tgz", + "integrity": "sha512-Xn7aAcGDhco/JZTXOub64UmaYn73C6J1Po7Fk+8EvkJsNGTqfhon6UJY53vJKXW5v5Zl8HrYsVxv6oPXeGoGLQ==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.39.0" + } + }, + "node_modules/motion-utils": { + "version": "12.39.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.39.0.tgz", + "integrity": "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -5938,90 +6109,6 @@ "optional": true } } - }, - "node_modules/dayjs": { - "version": "1.11.20", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", - "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", - "license": "MIT" - }, - "node_modules/framer-motion": { - "version": "12.38.0", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz", - "integrity": "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==", - "license": "MIT", - "dependencies": { - "motion-dom": "^12.38.0", - "motion-utils": "^12.36.0", - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/launder": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/launder/-/launder-1.7.1.tgz", - "integrity": "sha512-mU6WRz5EusL9ZZuiZ5SO4Y6C0P9PAUR9iwdb6bzj4KDihm28DiHFw+/yk9DBH4f+Pv1wuzQ4e2jV3oQ7mkIqvw==", - "license": "MIT", - "dependencies": { - "dayjs": "^1.11.7" - } - }, - "node_modules/motion": { - "version": "12.38.0", - "resolved": "https://registry.npmjs.org/motion/-/motion-12.38.0.tgz", - "integrity": "sha512-uYfXzeHlgThchzwz5Te47dlv5JOUC7OB4rjJ/7XTUgtBZD8CchMN8qEJ4ZVsUmTyYA44zjV0fBwsiktRuFnn+w==", - "license": "MIT", - "peer": true, - "dependencies": { - "framer-motion": "^12.38.0", - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/motion-dom": { - "version": "12.38.0", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.38.0.tgz", - "integrity": "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==", - "license": "MIT", - "dependencies": { - "motion-utils": "^12.36.0" - } - }, - "node_modules/motion-utils": { - "version": "12.36.0", - "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.36.0.tgz", - "integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==", - "license": "MIT" } } } diff --git a/web/package.json b/web/package.json index b8608499f8c..cdc95162234 100644 --- a/web/package.json +++ b/web/package.json @@ -10,7 +10,7 @@ "preview": "vite preview" }, "dependencies": { - "@nous-research/ui": "0.14.0", + "@nous-research/ui": "^0.14.2", "@observablehq/plot": "^0.6.17", "@react-three/fiber": "^9.6.0", "@tailwindcss/vite": "^4.2.1", diff --git a/web/src/components/ModelPickerDialog.tsx b/web/src/components/ModelPickerDialog.tsx index 22b2cb1bce8..d01a46b01a0 100644 --- a/web/src/components/ModelPickerDialog.tsx +++ b/web/src/components/ModelPickerDialog.tsx @@ -1,6 +1,8 @@ import { Button } from "@nous-research/ui/ui/components/button"; +import { Checkbox } from "@nous-research/ui/ui/components/checkbox"; import { ListItem } from "@nous-research/ui/ui/components/list-item"; import { Spinner } from "@nous-research/ui/ui/components/spinner"; +import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import type { GatewayClient } from "@/lib/gatewayClient"; import { Check, Search, X } from "lucide-react"; @@ -283,15 +285,22 @@ export function ModelPickerDialog(props: Props) { Saves to config.yaml — applies to new sessions. ) : ( - + + + )}