diff --git a/apps/desktop/src/app/chat/composer/focus.ts b/apps/desktop/src/app/chat/composer/focus.ts new file mode 100644 index 000000000000..c728577465e4 --- /dev/null +++ b/apps/desktop/src/app/chat/composer/focus.ts @@ -0,0 +1,49 @@ +export type ComposerFocusTarget = 'main' | 'edit' + +interface ComposerFocusRequestDetail { + target: ComposerFocusTarget +} + +const COMPOSER_FOCUS_REQUEST_EVENT = 'hermes:composer-focus-request' + +let activeComposerTarget: ComposerFocusTarget = 'main' + +function resolveTarget(target: ComposerFocusTarget | 'active'): ComposerFocusTarget { + return target === 'active' ? activeComposerTarget : target +} + +export function markActiveComposer(target: ComposerFocusTarget) { + activeComposerTarget = target +} + +export function requestComposerFocus(target: ComposerFocusTarget | 'active' = 'active') { + if (typeof window === 'undefined') { + return + } + + const resolvedTarget = resolveTarget(target) + + const event = new CustomEvent(COMPOSER_FOCUS_REQUEST_EVENT, { + detail: { target: resolvedTarget } + }) + + window.dispatchEvent(event) +} + +export function onComposerFocusRequest(handler: (target: ComposerFocusTarget) => void) { + if (typeof window === 'undefined') { + return () => undefined + } + + const listener = (event: Event) => { + const detail = (event as CustomEvent).detail + + if (detail?.target === 'main' || detail?.target === 'edit') { + handler(detail.target) + } + } + + window.addEventListener(COMPOSER_FOCUS_REQUEST_EVENT, listener) + + return () => window.removeEventListener(COMPOSER_FOCUS_REQUEST_EVENT, listener) +} diff --git a/apps/desktop/src/app/skills/index.tsx b/apps/desktop/src/app/skills/index.tsx index be3a57c4aac0..9826bd52167e 100644 --- a/apps/desktop/src/app/skills/index.tsx +++ b/apps/desktop/src/app/skills/index.tsx @@ -5,9 +5,9 @@ import { PageLoader } from '@/components/page-loader' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Switch } from '@/components/ui/switch' +import { TextTab, TextTabMeta } from '@/components/ui/text-tab' import { getSkills, getToolsets, toggleSkill } from '@/hermes' -import { Brain, RefreshCw, Search, Wrench, X } from '@/lib/icons' -import type { LucideIcon } from '@/lib/icons' +import { RefreshCw, Search, X } from '@/lib/icons' import { cn } from '@/lib/utils' import { notify, notifyError } from '@/store/notifications' import type { SkillInfo, ToolsetInfo } from '@/types/hermes' @@ -185,14 +185,13 @@ export function SkillsView({
-
- setMode('skills')} text="Skills" /> - setMode('toolsets')} - text="Toolsets" - /> +
+ setMode('skills')}> + Skills + + setMode('toolsets')}> + Toolsets +
@@ -219,21 +218,18 @@ export function SkillsView({
{mode === 'skills' && categories.length > 0 && ( -
- setActiveCategory(null)} - /> +
+ setActiveCategory(null)}> + All {totalSkills} + {categories.map(category => ( - setActiveCategory(activeCategory === category.key ? null : category.key)} - /> + > + {prettyName(category.key)} {category.count} + ))}
)} @@ -330,64 +326,6 @@ export function SkillsView({ ) } -function ModeButton({ - active, - icon: Icon, - onClick, - text -}: { - active: boolean - icon: LucideIcon - onClick: () => void - text: string -}) { - return ( - - ) -} - -function CategoryButton({ - active, - count, - label, - onClick -}: { - active: boolean - count: number - label: string - onClick: () => void -}) { - return ( - - ) -} - function StatusPill({ active, children }: { active: boolean; children: string }) { return (