@agent-native/core 0.107.0 → 0.107.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.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +10 -0
- package/corpus/core/docs/content/integrations.mdx +27 -27
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +19 -0
- package/corpus/core/src/agent/run-store.ts +98 -2
- package/corpus/core/src/client/AssistantChat.tsx +13 -0
- package/corpus/core/src/client/CommandMenu.tsx +5 -0
- package/corpus/core/src/client/active-run-state.ts +34 -0
- package/corpus/core/src/client/agent-chat-adapter.ts +4 -0
- package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +41 -11
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +27 -9
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +45 -0
- package/corpus/core/src/client/sharing/ShareButton.tsx +30 -9
- package/corpus/core/src/client/use-agent-chat-home-handoff.ts +2 -2
- package/corpus/core/src/localization/default-messages.ts +4 -1
- package/corpus/core/src/secrets/register-framework-secrets.ts +28 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +29 -1
- package/corpus/core/src/vite/client.ts +24 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +29 -21
- package/corpus/templates/analytics/AGENTS.md +8 -0
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +1 -1
- package/corpus/templates/analytics/actions/update-dashboard.ts +6 -2
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +35 -7
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +1 -3
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +11 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/extension-slot.ts +11 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +27 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-dashboard-extension-boxes.md +6 -0
- package/corpus/templates/analytics/server/lib/agent-readable-resource-context.ts +8 -0
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/assets/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/brain/app/hooks/use-navigation-state.ts +6 -1
- package/corpus/templates/brain/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +1 -1
- package/corpus/templates/calendar/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/chat/app/hooks/use-navigation-state.ts +4 -1
- package/corpus/templates/chat/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
- package/corpus/templates/clips/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/content/actions/_content-space-access.ts +45 -2
- package/corpus/templates/content/actions/create-content-database.ts +41 -7
- package/corpus/templates/content/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/content/app/root.tsx +1 -10
- package/corpus/templates/content/changelog/2026-07-17-creating-a-database-now-completes-reliably-in-hosted-workspa.md +6 -0
- package/corpus/templates/content/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +4 -1
- package/corpus/templates/dispatch/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/forms/app/components/layout/Layout.tsx +2 -4
- package/corpus/templates/forms/app/components/ui/popover.tsx +25 -1
- package/corpus/templates/forms/app/hooks/use-navigation-state.ts +6 -1
- package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +13 -10
- package/corpus/templates/forms/app/root.tsx +6 -1
- package/corpus/templates/forms/changelog/2026-07-17-form-builder-popovers-stay-within-the-viewport.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-17-form-editor-loading-matches-current-sidebar-free-layout.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +1 -1
- package/corpus/templates/mail/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +14 -3
- package/corpus/templates/plan/app/hooks/use-navigation-state.ts +8 -1
- package/corpus/templates/plan/app/root.tsx +0 -2
- package/corpus/templates/plan/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +23 -23
- package/corpus/templates/slides/changelog/2026-07-17-duplicated-slides-now-stay-in-the-deck.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/tasks/app/components/layout/Layout.tsx +2 -13
- package/corpus/templates/tasks/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it.md +6 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +13 -1
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-store.d.ts +17 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +84 -2
- package/dist/agent/run-store.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +10 -1
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/CommandMenu.d.ts.map +1 -1
- package/dist/client/CommandMenu.js +4 -0
- package/dist/client/CommandMenu.js.map +1 -1
- package/dist/client/active-run-state.d.ts +7 -0
- package/dist/client/active-run-state.d.ts.map +1 -1
- package/dist/client/active-run-state.js +28 -0
- package/dist/client/active-run-state.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +4 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.js +27 -8
- package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +4 -2
- package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.d.ts +6 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.js +33 -0
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +15 -12
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/use-agent-chat-home-handoff.d.ts +1 -1
- package/dist/client/use-agent-chat-home-handoff.d.ts.map +1 -1
- package/dist/client/use-agent-chat-home-handoff.js +1 -1
- package/dist/client/use-agent-chat-home-handoff.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/localization/default-messages.d.ts +2 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +3 -1
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
- package/dist/secrets/register-framework-secrets.js +25 -0
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +23 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +4 -1
- package/dist/templates/chat/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +20 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/integrations.mdx +27 -27
- package/package.json +1 -1
- package/src/templates/chat/app/hooks/use-navigation-state.ts +4 -1
- package/src/templates/chat/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandMenu.d.ts","sourceRoot":"","sources":["../../src/client/CommandMenu.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,OAAO,KAAK,EAAE,EAQZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AA0Bf;;GAEG;AACH,wBAAgB,gBAAgB,SAE/B;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,CAAC,EAAE,MAAM,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"CommandMenu.d.ts","sourceRoot":"","sources":["../../src/client/CommandMenu.tsx"],"names":[],"mappings":"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"}
|
|
@@ -39,6 +39,10 @@ export function openAgentSettings(section) {
|
|
|
39
39
|
if (typeof window === "undefined")
|
|
40
40
|
return;
|
|
41
41
|
const normalizedSection = typeof section === "string" ? section : section?.section;
|
|
42
|
+
const secretHash = normalizedSection?.replace(/^#/, "");
|
|
43
|
+
if (secretHash?.toLowerCase().startsWith("secrets:")) {
|
|
44
|
+
window.location.hash = `#${secretHash}`;
|
|
45
|
+
}
|
|
42
46
|
openAgentSidebar();
|
|
43
47
|
// Voice mode unmounts the chat surface while its dock is collapsed, so its
|
|
44
48
|
// settings listener does not exist until opening the sidebar remounts it.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandMenu.js","sourceRoot":"","sources":["../../src/client/CommandMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * CommandMenu — reusable command palette with agent chat fallback.\n *\n * Features:\n * - Anchored to top of viewport (not centered)\n * - Falls back to agent chat when no command matches\n * - Opens agent sidebar automatically when sending prompts\n * - Customizable commands via children\n *\n * Usage:\n * <CommandMenu open={open} onOpenChange={setOpen}>\n * <CommandMenu.Group heading=\"Actions\">\n * <CommandMenu.Item onSelect={() => doThing()}>Do thing</CommandMenu.Item>\n * </CommandMenu.Group>\n * </CommandMenu>\n */\n\nimport {\n IconBook2,\n IconExternalLink,\n IconSearch,\n IconMessage,\n IconHistory,\n} from \"@tabler/icons-react\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\n\nimport { parseChangelog } from \"../changelog/parse.js\";\nimport { sendToAgentChat } from \"./agent-chat.js\";\nimport { ChangelogDialog, useChangelogSeen } from \"./changelog/Changelog.js\";\nimport { cn } from \"./utils.js\";\n\n// ─── Context ────────────────────────────────────────────────────────────────\n\ninterface CommandMenuContextValue {\n search: string;\n onOpenChange: (open: boolean) => void;\n containerRef: React.RefObject<HTMLDivElement | null>;\n setSelectedIndex: (index: number) => void;\n}\n\nconst CommandMenuContext = createContext<CommandMenuContextValue | null>(null);\n\nfunction useCommandMenuContext() {\n const ctx = useContext(CommandMenuContext);\n if (!ctx) throw new Error(\"CommandMenu.* must be used inside <CommandMenu>\");\n return ctx;\n}\n\n// ─── Hooks ──────────────────────────────────────────────────────────────────\n\n/**\n * Opens the agent sidebar (dispatches event that AgentSidebar listens for)\n */\nexport function openAgentSidebar() {\n window.dispatchEvent(new Event(\"agent-panel:open\"));\n}\n\nexport function openAgentSettings(\n section?: string | { section?: string | null },\n) {\n if (typeof window === \"undefined\") return;\n\n const normalizedSection =\n typeof section === \"string\" ? section : section?.section;\n\n openAgentSidebar();\n // Voice mode unmounts the chat surface while its dock is collapsed, so its\n // settings listener does not exist until opening the sidebar remounts it.\n // Deliver after the open-state render can commit instead of racing React's\n // concurrent remount. Non-visual runtimes fall back to the next task.\n const dispatchSettings = () => {\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:open-settings\", {\n detail: normalizedSection ? { section: normalizedSection } : undefined,\n }),\n );\n };\n if (typeof window.requestAnimationFrame === \"function\") {\n window.requestAnimationFrame(dispatchSettings);\n } else {\n window.setTimeout(dispatchSettings, 0);\n }\n}\n\nexport function focusAgentChat() {\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:set-mode\", {\n detail: { mode: \"chat\" },\n }),\n );\n openAgentSidebar();\n}\n\n/**\n * Sends a prompt to the agent and opens the sidebar\n */\nexport function submitToAgent(message: string) {\n focusAgentChat();\n sendToAgentChat({ message, submit: true });\n}\n\n// ─── Sub-components ─────────────────────────────────────────────────────────\n\ninterface CommandGroupProps {\n heading?: string;\n children: ReactNode;\n}\n\nfunction CommandGroup({ heading, children }: CommandGroupProps) {\n return (\n <div className=\"overflow-hidden p-1 text-foreground\">\n {heading && (\n <div className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n {heading}\n </div>\n )}\n {children}\n </div>\n );\n}\n\ninterface CommandItemProps {\n onSelect: () => void;\n children: ReactNode;\n keywords?: string[];\n className?: string;\n deferSelect?: boolean;\n}\n\nfunction CommandItem({\n onSelect,\n children,\n keywords: _keywords,\n className,\n deferSelect = true,\n}: CommandItemProps) {\n const { onOpenChange, containerRef, setSelectedIndex } =\n useCommandMenuContext();\n const itemRef = useRef<HTMLDivElement>(null);\n\n const handleSelect = () => {\n if (!deferSelect) {\n onSelect();\n onOpenChange(false);\n return;\n }\n\n onOpenChange(false);\n // Small delay to let dialog close animation start\n setTimeout(onSelect, 50);\n };\n\n const handleMouseEnter = () => {\n if (!containerRef.current || !itemRef.current) return;\n const items = containerRef.current.querySelectorAll('[role=\"option\"]');\n const index = Array.from(items).indexOf(itemRef.current);\n if (index >= 0) setSelectedIndex(index);\n };\n\n return (\n <div\n ref={itemRef}\n className={cn(\n \"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none\",\n className,\n )}\n onClick={handleSelect}\n onMouseEnter={handleMouseEnter}\n role=\"option\"\n >\n {children}\n </div>\n );\n}\n\ninterface CommandShortcutProps {\n children: ReactNode;\n className?: string;\n}\n\nfunction CommandShortcut({ children, className }: CommandShortcutProps) {\n return (\n <span\n className={cn(\n \"ms-auto text-xs tracking-widest text-muted-foreground\",\n className,\n )}\n >\n {children}\n </span>\n );\n}\n\nfunction CommandSeparator({ className }: { className?: string }) {\n return <div className={cn(\"-mx-1 my-1 h-px bg-border\", className)} />;\n}\n\nexport interface CommandMenuDoc {\n title: string;\n href: string;\n description?: string;\n keywords?: string[];\n}\n\ninterface CommandDocsGroupProps {\n docs: CommandMenuDoc[];\n heading?: string;\n}\n\nfunction commandDocSearchText(doc: CommandMenuDoc): string {\n return [doc.title, doc.description, ...(doc.keywords ?? [])]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n}\n\nfunction filterCommandDocs(docs: CommandMenuDoc[], search: string) {\n const searchLower = search.trim().toLowerCase();\n if (!searchLower) return docs;\n return docs.filter((doc) => commandDocSearchText(doc).includes(searchLower));\n}\n\nfunction openDocsHref(href: string) {\n if (/^https?:\\/\\//i.test(href)) {\n window.open(href, \"_blank\", \"noopener,noreferrer\");\n return;\n }\n window.location.assign(href);\n}\n\nfunction CommandDocsGroup({ docs, heading = \"Docs\" }: CommandDocsGroupProps) {\n if (docs.length === 0) return null;\n\n return (\n <CommandGroup heading={heading}>\n {docs.map((doc) => (\n <CommandItem\n key={doc.href}\n onSelect={() => openDocsHref(doc.href)}\n keywords={[doc.title, doc.description ?? \"\", ...(doc.keywords ?? [])]}\n deferSelect={false}\n className=\"items-start py-2\"\n >\n <IconBook2 className=\"mt-0.5 h-4 w-4 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium\">{doc.title}</span>\n {doc.description ? (\n <span className=\"mt-0.5 block line-clamp-2 text-xs leading-snug text-muted-foreground\">\n {doc.description}\n </span>\n ) : null}\n </span>\n <IconExternalLink className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n </CommandItem>\n ))}\n </CommandGroup>\n );\n}\n\n// ─── Main Component ─────────────────────────────────────────────────────────\n\nexport interface CommandMenuProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n children: ReactNode;\n /** Render app-specific dynamic results from the current search value. */\n renderResults?: (search: string) => ReactNode;\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Text shown when no results match (before showing agent fallback) */\n emptyText?: string;\n /** Whether to show the \"Ask AI\" fallback when no commands match. Default: true */\n showAgentFallback?: boolean;\n /** Custom class for the dialog content */\n className?: string;\n /**\n * Raw CHANGELOG.md contents. When provided, the menu shows a built-in\n * \"What's new\" entry that opens an in-app changelog dialog (with an unseen\n * dot for new releases). Pass your app's own file:\n * import changelog from \"../CHANGELOG.md?raw\";\n * <CommandMenu ... changelog={changelog} />\n */\n changelog?: string;\n /** Label for the built-in changelog entry. Default: \"What's new\". */\n changelogLabel?: string;\n /**\n * Stable key used to remember which release a user has already seen (for the\n * unseen dot). Defaults to the document title's host app; set explicitly when\n * multiple apps share an origin.\n */\n changelogKey?: string;\n}\n\nexport function CommandMenu({\n open,\n onOpenChange,\n children,\n renderResults,\n placeholder = \"Type a command or ask AI...\",\n emptyText: _emptyText = \"No commands found.\",\n showAgentFallback = true,\n className,\n changelog,\n changelogLabel = \"What's new\",\n changelogKey,\n}: CommandMenuProps) {\n const [search, setSearch] = useState(\"\");\n const [selectedIndex, setSelectedIndex] = useState(0);\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Built-in \"What's new\" changelog surface (only active when `changelog` is\n // passed). The dialog is rendered alongside the menu so it survives the menu\n // closing; the unseen dot persists per browser via localStorage.\n const [changelogOpen, setChangelogOpen] = useState(false);\n const hasChangelog =\n typeof changelog === \"string\" && changelog.trim().length > 0;\n const changelogEntries = useMemo(\n () => (hasChangelog ? parseChangelog(changelog as string) : []),\n [hasChangelog, changelog],\n );\n const latestChangelogId = changelogEntries[0]?.id;\n const { unseen: changelogUnseen, markSeen: markChangelogSeen } =\n useChangelogSeen(changelogKey ?? \"app\", latestChangelogId);\n\n const openChangelog = useCallback(() => {\n onOpenChange(false);\n markChangelogSeen();\n // Let the menu close before the dialog opens (avoids overlay flicker).\n setTimeout(() => setChangelogOpen(true), 50);\n }, [onOpenChange, markChangelogSeen]);\n\n // Focus input when opening; clear search while closed so reopen never renders\n // dynamic results for the previous query.\n useEffect(() => {\n if (!open) {\n setSearch(\"\");\n setSelectedIndex(0);\n return;\n }\n\n if (open) {\n setSearch(\"\");\n setSelectedIndex(0);\n // Wait for render then focus\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n }\n }, [open]);\n\n // Reset selection when search changes\n useEffect(() => {\n setSelectedIndex(0);\n }, [search]);\n\n // Keep selected item scrolled into view\n useEffect(() => {\n const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n if (items && items[selectedIndex]) {\n items[selectedIndex].scrollIntoView({ block: \"nearest\" });\n }\n }, [selectedIndex]);\n\n // Apply selected styling directly (can't rely on Tailwind scanning core package)\n useEffect(() => {\n const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n if (!items) return;\n items.forEach((item, i) => {\n const el = item as HTMLElement;\n if (i === selectedIndex) {\n el.style.backgroundColor = \"hsl(var(--accent))\";\n el.style.color = \"hsl(var(--accent-foreground))\";\n } else {\n el.style.backgroundColor = \"\";\n el.style.color = \"\";\n }\n });\n });\n\n // Close on escape\n useEffect(() => {\n if (!open) return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onOpenChange(false);\n }\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [open, onOpenChange]);\n\n // Close on click outside\n useEffect(() => {\n if (!open) return;\n const handleClick = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n onOpenChange(false);\n }\n };\n // Use capture to handle clicks before they bubble\n document.addEventListener(\"mousedown\", handleClick, true);\n return () => document.removeEventListener(\"mousedown\", handleClick, true);\n }, [open, onOpenChange]);\n\n const handleSubmitToAgent = useCallback(() => {\n onOpenChange(false);\n if (!search.trim()) {\n focusAgentChat();\n return;\n }\n submitToAgent(search.trim());\n }, [search, onOpenChange]);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n const itemCount = items?.length ?? 0;\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setSelectedIndex((prev) => (prev + 1) % itemCount || 0);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setSelectedIndex((prev) => (prev - 1 + itemCount) % itemCount || 0);\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n if (items && items[selectedIndex]) {\n (items[selectedIndex] as HTMLElement).click();\n }\n }\n };\n\n // The built-in \"What's new\" row matches changelog-ish search terms.\n const changelogRowMatches =\n !search ||\n [\n changelogLabel,\n \"changelog\",\n \"what's new\",\n \"whats new\",\n \"updates\",\n \"release notes\",\n \"changes\",\n ]\n .join(\" \")\n .toLowerCase()\n .includes(search.toLowerCase());\n const showChangelogRow = hasChangelog && changelogRowMatches;\n\n // Filter children based on search\n const filterChildren = (nodes: ReactNode): ReactNode => {\n return React.Children.map(nodes, (child) => {\n if (!React.isValidElement(child)) return child;\n const props = child.props as Record<string, unknown>;\n\n // If it's a CommandGroup, filter its children\n if (child.type === CommandGroup) {\n const groupChildren = filterChildren(props.children as ReactNode);\n const hasChildren = React.Children.count(groupChildren) > 0;\n if (!hasChildren) return null;\n return React.cloneElement(child, {\n ...props,\n children: groupChildren,\n } as Record<string, unknown>);\n }\n\n if (child.type === CommandDocsGroup) {\n const docs = Array.isArray(props.docs)\n ? (props.docs as CommandMenuDoc[])\n : [];\n const filteredDocs = filterCommandDocs(docs, search);\n if (filteredDocs.length === 0) return null;\n return React.cloneElement(child, {\n ...props,\n docs: filteredDocs,\n } as Record<string, unknown>);\n }\n\n // If it's a CommandItem, check if it matches search\n if (child.type === CommandItem) {\n if (!search) return child;\n const text = getTextContent(props.children as ReactNode).toLowerCase();\n const keywords = ((props.keywords as string[]) || [])\n .join(\" \")\n .toLowerCase();\n const searchLower = search.toLowerCase();\n if (text.includes(searchLower) || keywords.includes(searchLower)) {\n return child;\n }\n return null;\n }\n\n // If it's a separator, keep it (will be cleaned up later if needed)\n if (child.type === CommandSeparator) {\n return search ? null : child; // Hide separators when searching\n }\n\n return child;\n });\n };\n\n const filteredChildren = filterChildren(children);\n const hasResults = React.Children.toArray(filteredChildren).some(\n (child) =>\n React.isValidElement(child) &&\n (child.type === CommandGroup || child.type === CommandDocsGroup),\n );\n const dynamicResults = open ? renderResults?.(search) : null;\n const hasDynamicResults = Boolean(dynamicResults);\n\n return (\n <>\n {open && (\n <div className=\"fixed inset-0 z-50 bg-black/50\">\n <div\n ref={containerRef}\n className={cn(\n \"fixed left-1/2 top-[15vh] -translate-x-1/2 w-full max-w-lg\",\n \"rounded-lg border border-border bg-popover text-popover-foreground shadow-lg\",\n className,\n )}\n >\n <CommandMenuContext.Provider\n value={{ search, onOpenChange, containerRef, setSelectedIndex }}\n >\n {/* Search input */}\n <div className=\"flex items-center border-b px-3\">\n <IconSearch className=\"me-2 h-4 w-4 shrink-0 opacity-50\" />\n <input\n ref={inputRef}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n className=\"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\"\n />\n </div>\n\n {/* Command list */}\n <div className=\"max-h-[300px] overflow-y-auto overflow-x-hidden\">\n {dynamicResults}\n {hasResults && filteredChildren}\n\n {/* What's new — built-in changelog entry */}\n {showChangelogRow && (\n <>\n {hasResults && <CommandSeparator />}\n <div className=\"p-1\">\n <div\n className=\"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none\"\n onClick={openChangelog}\n onMouseEnter={(e) => {\n const items =\n containerRef.current?.querySelectorAll(\n '[role=\"option\"]',\n );\n if (!items) return;\n const index = Array.from(items).indexOf(\n e.currentTarget,\n );\n if (index >= 0) setSelectedIndex(index);\n }}\n role=\"option\"\n >\n <IconHistory className=\"h-4 w-4 text-muted-foreground\" />\n <span>{changelogLabel}</span>\n {changelogUnseen && (\n <span\n className=\"ms-auto h-2 w-2 rounded-full bg-primary\"\n aria-label=\"New updates available\"\n />\n )}\n </div>\n </div>\n </>\n )}\n\n {/* Ask AI — always visible at the bottom */}\n {showAgentFallback && (\n <>\n {(hasResults || showChangelogRow || hasDynamicResults) && (\n <CommandSeparator />\n )}\n <div className=\"p-1\">\n <div\n className=\"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none\"\n onClick={handleSubmitToAgent}\n onMouseEnter={(e) => {\n const items =\n containerRef.current?.querySelectorAll(\n '[role=\"option\"]',\n );\n if (!items) return;\n const index = Array.from(items).indexOf(\n e.currentTarget,\n );\n if (index >= 0) setSelectedIndex(index);\n }}\n role=\"option\"\n >\n <IconMessage className=\"h-4 w-4 text-muted-foreground\" />\n <span>\n {search.trim() ? (\n <>\n Ask AI:{\" \"}\n <span className=\"text-muted-foreground\">\n \"{search}\"\n </span>\n </>\n ) : (\n <span className=\"text-muted-foreground\">\n Ask AI anything...\n </span>\n )}\n </span>\n {search.trim() && (\n <span className=\"ms-auto text-xs text-muted-foreground\">\n ↵\n </span>\n )}\n </div>\n </div>\n </>\n )}\n </div>\n </CommandMenuContext.Provider>\n </div>\n </div>\n )}\n\n {hasChangelog && (\n <ChangelogDialog\n open={changelogOpen}\n onOpenChange={setChangelogOpen}\n markdown={changelog as string}\n title={changelogLabel}\n />\n )}\n </>\n );\n}\n\n// Helper to extract text content from React children\nfunction getTextContent(children: ReactNode): string {\n if (typeof children === \"string\") return children;\n if (typeof children === \"number\") return String(children);\n if (!children) return \"\";\n if (Array.isArray(children)) {\n return children.map(getTextContent).join(\" \");\n }\n if (\n React.isValidElement(children) &&\n (children.props as Record<string, unknown>).children\n ) {\n return getTextContent(\n (children.props as Record<string, unknown>).children as ReactNode,\n );\n }\n return \"\";\n}\n\n// Attach sub-components\nCommandMenu.Group = CommandGroup;\nCommandMenu.Item = CommandItem;\nCommandMenu.DocsGroup = CommandDocsGroup;\nCommandMenu.Shortcut = CommandShortcut;\nCommandMenu.Separator = CommandSeparator;\n\n// ─── Keyboard Hook ──────────────────────────────────────────────────────────\n\n/**\n * Hook to handle Cmd+K (or Ctrl+K) to open the command menu\n */\nexport function useCommandMenuShortcut(\n onOpen: () => void,\n options: { allowContentEditable?: boolean } = {},\n) {\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === \"k\") {\n // Don't trigger if user is typing in a native form control.\n const target = e.target instanceof HTMLElement ? e.target : null;\n const isContentEditable = target?.isContentEditable;\n if (\n target?.tagName === \"INPUT\" ||\n target?.tagName === \"TEXTAREA\" ||\n target?.tagName === \"SELECT\" ||\n (!options.allowContentEditable && isContentEditable)\n ) {\n return;\n }\n e.preventDefault();\n onOpen();\n }\n };\n const useCapture = Boolean(options.allowContentEditable);\n document.addEventListener(\"keydown\", handleKeyDown, useCapture);\n return () =>\n document.removeEventListener(\"keydown\", handleKeyDown, useCapture);\n }, [onOpen, options.allowContentEditable]);\n}\n\nexport type {\n CommandDocsGroupProps,\n CommandGroupProps,\n CommandItemProps,\n CommandShortcutProps,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"CommandMenu.js","sourceRoot":"","sources":["../../src/client/CommandMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * CommandMenu — reusable command palette with agent chat fallback.\n *\n * Features:\n * - Anchored to top of viewport (not centered)\n * - Falls back to agent chat when no command matches\n * - Opens agent sidebar automatically when sending prompts\n * - Customizable commands via children\n *\n * Usage:\n * <CommandMenu open={open} onOpenChange={setOpen}>\n * <CommandMenu.Group heading=\"Actions\">\n * <CommandMenu.Item onSelect={() => doThing()}>Do thing</CommandMenu.Item>\n * </CommandMenu.Group>\n * </CommandMenu>\n */\n\nimport {\n IconBook2,\n IconExternalLink,\n IconSearch,\n IconMessage,\n IconHistory,\n} from \"@tabler/icons-react\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\n\nimport { parseChangelog } from \"../changelog/parse.js\";\nimport { sendToAgentChat } from \"./agent-chat.js\";\nimport { ChangelogDialog, useChangelogSeen } from \"./changelog/Changelog.js\";\nimport { cn } from \"./utils.js\";\n\n// ─── Context ────────────────────────────────────────────────────────────────\n\ninterface CommandMenuContextValue {\n search: string;\n onOpenChange: (open: boolean) => void;\n containerRef: React.RefObject<HTMLDivElement | null>;\n setSelectedIndex: (index: number) => void;\n}\n\nconst CommandMenuContext = createContext<CommandMenuContextValue | null>(null);\n\nfunction useCommandMenuContext() {\n const ctx = useContext(CommandMenuContext);\n if (!ctx) throw new Error(\"CommandMenu.* must be used inside <CommandMenu>\");\n return ctx;\n}\n\n// ─── Hooks ──────────────────────────────────────────────────────────────────\n\n/**\n * Opens the agent sidebar (dispatches event that AgentSidebar listens for)\n */\nexport function openAgentSidebar() {\n window.dispatchEvent(new Event(\"agent-panel:open\"));\n}\n\nexport function openAgentSettings(\n section?: string | { section?: string | null },\n) {\n if (typeof window === \"undefined\") return;\n\n const normalizedSection =\n typeof section === \"string\" ? section : section?.section;\n\n const secretHash = normalizedSection?.replace(/^#/, \"\");\n if (secretHash?.toLowerCase().startsWith(\"secrets:\")) {\n window.location.hash = `#${secretHash}`;\n }\n\n openAgentSidebar();\n // Voice mode unmounts the chat surface while its dock is collapsed, so its\n // settings listener does not exist until opening the sidebar remounts it.\n // Deliver after the open-state render can commit instead of racing React's\n // concurrent remount. Non-visual runtimes fall back to the next task.\n const dispatchSettings = () => {\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:open-settings\", {\n detail: normalizedSection ? { section: normalizedSection } : undefined,\n }),\n );\n };\n if (typeof window.requestAnimationFrame === \"function\") {\n window.requestAnimationFrame(dispatchSettings);\n } else {\n window.setTimeout(dispatchSettings, 0);\n }\n}\n\nexport function focusAgentChat() {\n window.dispatchEvent(\n new CustomEvent(\"agent-panel:set-mode\", {\n detail: { mode: \"chat\" },\n }),\n );\n openAgentSidebar();\n}\n\n/**\n * Sends a prompt to the agent and opens the sidebar\n */\nexport function submitToAgent(message: string) {\n focusAgentChat();\n sendToAgentChat({ message, submit: true });\n}\n\n// ─── Sub-components ─────────────────────────────────────────────────────────\n\ninterface CommandGroupProps {\n heading?: string;\n children: ReactNode;\n}\n\nfunction CommandGroup({ heading, children }: CommandGroupProps) {\n return (\n <div className=\"overflow-hidden p-1 text-foreground\">\n {heading && (\n <div className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n {heading}\n </div>\n )}\n {children}\n </div>\n );\n}\n\ninterface CommandItemProps {\n onSelect: () => void;\n children: ReactNode;\n keywords?: string[];\n className?: string;\n deferSelect?: boolean;\n}\n\nfunction CommandItem({\n onSelect,\n children,\n keywords: _keywords,\n className,\n deferSelect = true,\n}: CommandItemProps) {\n const { onOpenChange, containerRef, setSelectedIndex } =\n useCommandMenuContext();\n const itemRef = useRef<HTMLDivElement>(null);\n\n const handleSelect = () => {\n if (!deferSelect) {\n onSelect();\n onOpenChange(false);\n return;\n }\n\n onOpenChange(false);\n // Small delay to let dialog close animation start\n setTimeout(onSelect, 50);\n };\n\n const handleMouseEnter = () => {\n if (!containerRef.current || !itemRef.current) return;\n const items = containerRef.current.querySelectorAll('[role=\"option\"]');\n const index = Array.from(items).indexOf(itemRef.current);\n if (index >= 0) setSelectedIndex(index);\n };\n\n return (\n <div\n ref={itemRef}\n className={cn(\n \"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none\",\n className,\n )}\n onClick={handleSelect}\n onMouseEnter={handleMouseEnter}\n role=\"option\"\n >\n {children}\n </div>\n );\n}\n\ninterface CommandShortcutProps {\n children: ReactNode;\n className?: string;\n}\n\nfunction CommandShortcut({ children, className }: CommandShortcutProps) {\n return (\n <span\n className={cn(\n \"ms-auto text-xs tracking-widest text-muted-foreground\",\n className,\n )}\n >\n {children}\n </span>\n );\n}\n\nfunction CommandSeparator({ className }: { className?: string }) {\n return <div className={cn(\"-mx-1 my-1 h-px bg-border\", className)} />;\n}\n\nexport interface CommandMenuDoc {\n title: string;\n href: string;\n description?: string;\n keywords?: string[];\n}\n\ninterface CommandDocsGroupProps {\n docs: CommandMenuDoc[];\n heading?: string;\n}\n\nfunction commandDocSearchText(doc: CommandMenuDoc): string {\n return [doc.title, doc.description, ...(doc.keywords ?? [])]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n}\n\nfunction filterCommandDocs(docs: CommandMenuDoc[], search: string) {\n const searchLower = search.trim().toLowerCase();\n if (!searchLower) return docs;\n return docs.filter((doc) => commandDocSearchText(doc).includes(searchLower));\n}\n\nfunction openDocsHref(href: string) {\n if (/^https?:\\/\\//i.test(href)) {\n window.open(href, \"_blank\", \"noopener,noreferrer\");\n return;\n }\n window.location.assign(href);\n}\n\nfunction CommandDocsGroup({ docs, heading = \"Docs\" }: CommandDocsGroupProps) {\n if (docs.length === 0) return null;\n\n return (\n <CommandGroup heading={heading}>\n {docs.map((doc) => (\n <CommandItem\n key={doc.href}\n onSelect={() => openDocsHref(doc.href)}\n keywords={[doc.title, doc.description ?? \"\", ...(doc.keywords ?? [])]}\n deferSelect={false}\n className=\"items-start py-2\"\n >\n <IconBook2 className=\"mt-0.5 h-4 w-4 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium\">{doc.title}</span>\n {doc.description ? (\n <span className=\"mt-0.5 block line-clamp-2 text-xs leading-snug text-muted-foreground\">\n {doc.description}\n </span>\n ) : null}\n </span>\n <IconExternalLink className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n </CommandItem>\n ))}\n </CommandGroup>\n );\n}\n\n// ─── Main Component ─────────────────────────────────────────────────────────\n\nexport interface CommandMenuProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n children: ReactNode;\n /** Render app-specific dynamic results from the current search value. */\n renderResults?: (search: string) => ReactNode;\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Text shown when no results match (before showing agent fallback) */\n emptyText?: string;\n /** Whether to show the \"Ask AI\" fallback when no commands match. Default: true */\n showAgentFallback?: boolean;\n /** Custom class for the dialog content */\n className?: string;\n /**\n * Raw CHANGELOG.md contents. When provided, the menu shows a built-in\n * \"What's new\" entry that opens an in-app changelog dialog (with an unseen\n * dot for new releases). Pass your app's own file:\n * import changelog from \"../CHANGELOG.md?raw\";\n * <CommandMenu ... changelog={changelog} />\n */\n changelog?: string;\n /** Label for the built-in changelog entry. Default: \"What's new\". */\n changelogLabel?: string;\n /**\n * Stable key used to remember which release a user has already seen (for the\n * unseen dot). Defaults to the document title's host app; set explicitly when\n * multiple apps share an origin.\n */\n changelogKey?: string;\n}\n\nexport function CommandMenu({\n open,\n onOpenChange,\n children,\n renderResults,\n placeholder = \"Type a command or ask AI...\",\n emptyText: _emptyText = \"No commands found.\",\n showAgentFallback = true,\n className,\n changelog,\n changelogLabel = \"What's new\",\n changelogKey,\n}: CommandMenuProps) {\n const [search, setSearch] = useState(\"\");\n const [selectedIndex, setSelectedIndex] = useState(0);\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Built-in \"What's new\" changelog surface (only active when `changelog` is\n // passed). The dialog is rendered alongside the menu so it survives the menu\n // closing; the unseen dot persists per browser via localStorage.\n const [changelogOpen, setChangelogOpen] = useState(false);\n const hasChangelog =\n typeof changelog === \"string\" && changelog.trim().length > 0;\n const changelogEntries = useMemo(\n () => (hasChangelog ? parseChangelog(changelog as string) : []),\n [hasChangelog, changelog],\n );\n const latestChangelogId = changelogEntries[0]?.id;\n const { unseen: changelogUnseen, markSeen: markChangelogSeen } =\n useChangelogSeen(changelogKey ?? \"app\", latestChangelogId);\n\n const openChangelog = useCallback(() => {\n onOpenChange(false);\n markChangelogSeen();\n // Let the menu close before the dialog opens (avoids overlay flicker).\n setTimeout(() => setChangelogOpen(true), 50);\n }, [onOpenChange, markChangelogSeen]);\n\n // Focus input when opening; clear search while closed so reopen never renders\n // dynamic results for the previous query.\n useEffect(() => {\n if (!open) {\n setSearch(\"\");\n setSelectedIndex(0);\n return;\n }\n\n if (open) {\n setSearch(\"\");\n setSelectedIndex(0);\n // Wait for render then focus\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n }\n }, [open]);\n\n // Reset selection when search changes\n useEffect(() => {\n setSelectedIndex(0);\n }, [search]);\n\n // Keep selected item scrolled into view\n useEffect(() => {\n const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n if (items && items[selectedIndex]) {\n items[selectedIndex].scrollIntoView({ block: \"nearest\" });\n }\n }, [selectedIndex]);\n\n // Apply selected styling directly (can't rely on Tailwind scanning core package)\n useEffect(() => {\n const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n if (!items) return;\n items.forEach((item, i) => {\n const el = item as HTMLElement;\n if (i === selectedIndex) {\n el.style.backgroundColor = \"hsl(var(--accent))\";\n el.style.color = \"hsl(var(--accent-foreground))\";\n } else {\n el.style.backgroundColor = \"\";\n el.style.color = \"\";\n }\n });\n });\n\n // Close on escape\n useEffect(() => {\n if (!open) return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onOpenChange(false);\n }\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [open, onOpenChange]);\n\n // Close on click outside\n useEffect(() => {\n if (!open) return;\n const handleClick = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n onOpenChange(false);\n }\n };\n // Use capture to handle clicks before they bubble\n document.addEventListener(\"mousedown\", handleClick, true);\n return () => document.removeEventListener(\"mousedown\", handleClick, true);\n }, [open, onOpenChange]);\n\n const handleSubmitToAgent = useCallback(() => {\n onOpenChange(false);\n if (!search.trim()) {\n focusAgentChat();\n return;\n }\n submitToAgent(search.trim());\n }, [search, onOpenChange]);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n const items = containerRef.current?.querySelectorAll('[role=\"option\"]');\n const itemCount = items?.length ?? 0;\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setSelectedIndex((prev) => (prev + 1) % itemCount || 0);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setSelectedIndex((prev) => (prev - 1 + itemCount) % itemCount || 0);\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n if (items && items[selectedIndex]) {\n (items[selectedIndex] as HTMLElement).click();\n }\n }\n };\n\n // The built-in \"What's new\" row matches changelog-ish search terms.\n const changelogRowMatches =\n !search ||\n [\n changelogLabel,\n \"changelog\",\n \"what's new\",\n \"whats new\",\n \"updates\",\n \"release notes\",\n \"changes\",\n ]\n .join(\" \")\n .toLowerCase()\n .includes(search.toLowerCase());\n const showChangelogRow = hasChangelog && changelogRowMatches;\n\n // Filter children based on search\n const filterChildren = (nodes: ReactNode): ReactNode => {\n return React.Children.map(nodes, (child) => {\n if (!React.isValidElement(child)) return child;\n const props = child.props as Record<string, unknown>;\n\n // If it's a CommandGroup, filter its children\n if (child.type === CommandGroup) {\n const groupChildren = filterChildren(props.children as ReactNode);\n const hasChildren = React.Children.count(groupChildren) > 0;\n if (!hasChildren) return null;\n return React.cloneElement(child, {\n ...props,\n children: groupChildren,\n } as Record<string, unknown>);\n }\n\n if (child.type === CommandDocsGroup) {\n const docs = Array.isArray(props.docs)\n ? (props.docs as CommandMenuDoc[])\n : [];\n const filteredDocs = filterCommandDocs(docs, search);\n if (filteredDocs.length === 0) return null;\n return React.cloneElement(child, {\n ...props,\n docs: filteredDocs,\n } as Record<string, unknown>);\n }\n\n // If it's a CommandItem, check if it matches search\n if (child.type === CommandItem) {\n if (!search) return child;\n const text = getTextContent(props.children as ReactNode).toLowerCase();\n const keywords = ((props.keywords as string[]) || [])\n .join(\" \")\n .toLowerCase();\n const searchLower = search.toLowerCase();\n if (text.includes(searchLower) || keywords.includes(searchLower)) {\n return child;\n }\n return null;\n }\n\n // If it's a separator, keep it (will be cleaned up later if needed)\n if (child.type === CommandSeparator) {\n return search ? null : child; // Hide separators when searching\n }\n\n return child;\n });\n };\n\n const filteredChildren = filterChildren(children);\n const hasResults = React.Children.toArray(filteredChildren).some(\n (child) =>\n React.isValidElement(child) &&\n (child.type === CommandGroup || child.type === CommandDocsGroup),\n );\n const dynamicResults = open ? renderResults?.(search) : null;\n const hasDynamicResults = Boolean(dynamicResults);\n\n return (\n <>\n {open && (\n <div className=\"fixed inset-0 z-50 bg-black/50\">\n <div\n ref={containerRef}\n className={cn(\n \"fixed left-1/2 top-[15vh] -translate-x-1/2 w-full max-w-lg\",\n \"rounded-lg border border-border bg-popover text-popover-foreground shadow-lg\",\n className,\n )}\n >\n <CommandMenuContext.Provider\n value={{ search, onOpenChange, containerRef, setSelectedIndex }}\n >\n {/* Search input */}\n <div className=\"flex items-center border-b px-3\">\n <IconSearch className=\"me-2 h-4 w-4 shrink-0 opacity-50\" />\n <input\n ref={inputRef}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n className=\"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\"\n />\n </div>\n\n {/* Command list */}\n <div className=\"max-h-[300px] overflow-y-auto overflow-x-hidden\">\n {dynamicResults}\n {hasResults && filteredChildren}\n\n {/* What's new — built-in changelog entry */}\n {showChangelogRow && (\n <>\n {hasResults && <CommandSeparator />}\n <div className=\"p-1\">\n <div\n className=\"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none\"\n onClick={openChangelog}\n onMouseEnter={(e) => {\n const items =\n containerRef.current?.querySelectorAll(\n '[role=\"option\"]',\n );\n if (!items) return;\n const index = Array.from(items).indexOf(\n e.currentTarget,\n );\n if (index >= 0) setSelectedIndex(index);\n }}\n role=\"option\"\n >\n <IconHistory className=\"h-4 w-4 text-muted-foreground\" />\n <span>{changelogLabel}</span>\n {changelogUnseen && (\n <span\n className=\"ms-auto h-2 w-2 rounded-full bg-primary\"\n aria-label=\"New updates available\"\n />\n )}\n </div>\n </div>\n </>\n )}\n\n {/* Ask AI — always visible at the bottom */}\n {showAgentFallback && (\n <>\n {(hasResults || showChangelogRow || hasDynamicResults) && (\n <CommandSeparator />\n )}\n <div className=\"p-1\">\n <div\n className=\"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none\"\n onClick={handleSubmitToAgent}\n onMouseEnter={(e) => {\n const items =\n containerRef.current?.querySelectorAll(\n '[role=\"option\"]',\n );\n if (!items) return;\n const index = Array.from(items).indexOf(\n e.currentTarget,\n );\n if (index >= 0) setSelectedIndex(index);\n }}\n role=\"option\"\n >\n <IconMessage className=\"h-4 w-4 text-muted-foreground\" />\n <span>\n {search.trim() ? (\n <>\n Ask AI:{\" \"}\n <span className=\"text-muted-foreground\">\n \"{search}\"\n </span>\n </>\n ) : (\n <span className=\"text-muted-foreground\">\n Ask AI anything...\n </span>\n )}\n </span>\n {search.trim() && (\n <span className=\"ms-auto text-xs text-muted-foreground\">\n ↵\n </span>\n )}\n </div>\n </div>\n </>\n )}\n </div>\n </CommandMenuContext.Provider>\n </div>\n </div>\n )}\n\n {hasChangelog && (\n <ChangelogDialog\n open={changelogOpen}\n onOpenChange={setChangelogOpen}\n markdown={changelog as string}\n title={changelogLabel}\n />\n )}\n </>\n );\n}\n\n// Helper to extract text content from React children\nfunction getTextContent(children: ReactNode): string {\n if (typeof children === \"string\") return children;\n if (typeof children === \"number\") return String(children);\n if (!children) return \"\";\n if (Array.isArray(children)) {\n return children.map(getTextContent).join(\" \");\n }\n if (\n React.isValidElement(children) &&\n (children.props as Record<string, unknown>).children\n ) {\n return getTextContent(\n (children.props as Record<string, unknown>).children as ReactNode,\n );\n }\n return \"\";\n}\n\n// Attach sub-components\nCommandMenu.Group = CommandGroup;\nCommandMenu.Item = CommandItem;\nCommandMenu.DocsGroup = CommandDocsGroup;\nCommandMenu.Shortcut = CommandShortcut;\nCommandMenu.Separator = CommandSeparator;\n\n// ─── Keyboard Hook ──────────────────────────────────────────────────────────\n\n/**\n * Hook to handle Cmd+K (or Ctrl+K) to open the command menu\n */\nexport function useCommandMenuShortcut(\n onOpen: () => void,\n options: { allowContentEditable?: boolean } = {},\n) {\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === \"k\") {\n // Don't trigger if user is typing in a native form control.\n const target = e.target instanceof HTMLElement ? e.target : null;\n const isContentEditable = target?.isContentEditable;\n if (\n target?.tagName === \"INPUT\" ||\n target?.tagName === \"TEXTAREA\" ||\n target?.tagName === \"SELECT\" ||\n (!options.allowContentEditable && isContentEditable)\n ) {\n return;\n }\n e.preventDefault();\n onOpen();\n }\n };\n const useCapture = Boolean(options.allowContentEditable);\n document.addEventListener(\"keydown\", handleKeyDown, useCapture);\n return () =>\n document.removeEventListener(\"keydown\", handleKeyDown, useCapture);\n }, [onOpen, options.allowContentEditable]);\n}\n\nexport type {\n CommandDocsGroupProps,\n CommandGroupProps,\n CommandItemProps,\n CommandShortcutProps,\n};\n"]}
|
|
@@ -5,6 +5,10 @@ export interface ActiveRunState {
|
|
|
5
5
|
lastSeq: number;
|
|
6
6
|
activityTool?: string | null;
|
|
7
7
|
}
|
|
8
|
+
export interface PendingTurnState {
|
|
9
|
+
threadId: string;
|
|
10
|
+
turnId: string;
|
|
11
|
+
}
|
|
8
12
|
export declare function setActiveRun(state: ActiveRunState): void;
|
|
9
13
|
export declare function getActiveRun(): ActiveRunState | null;
|
|
10
14
|
export declare function updateActiveRunSeq(seq: number): void;
|
|
@@ -12,6 +16,9 @@ export declare function updateActiveRunActivity(toolName: string | null | undefi
|
|
|
12
16
|
export declare function getActiveRunActivityTool(threadId: string, runId: string): string | null;
|
|
13
17
|
export declare function clearActiveRun(): void;
|
|
14
18
|
export declare function clearActiveRunIfMatches(threadId: string, runId: string): void;
|
|
19
|
+
export declare function setPendingTurn(state: PendingTurnState): void;
|
|
20
|
+
export declare function getPendingTurn(threadId: string): PendingTurnState | null;
|
|
21
|
+
export declare function clearPendingTurnIfMatches(threadId: string, turnId?: string): void;
|
|
15
22
|
/** Resume reconnect SSE after the last seen event (0 = replay from the start). */
|
|
16
23
|
export declare function resolveReconnectAfterSeq(threadId: string, runId: string): number;
|
|
17
24
|
//# sourceMappingURL=active-run-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"active-run-state.d.ts","sourceRoot":"","sources":["../../src/client/active-run-state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"active-run-state.d.ts","sourceRoot":"","sources":["../../src/client/active-run-state.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,sBAAsB,uCAAuC,CAAC;AAE3E,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAqBD,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAKxD;AAED,wBAAgB,YAAY,IAAI,cAAc,GAAG,IAAI,CAQpD;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAMpD;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAClC,IAAI,CAUN;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,IAAI,CAIf;AAED,wBAAgB,cAAc,IAAI,IAAI,CAKrC;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAI7E;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAI5D;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CASxE;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GACd,IAAI,CAMN;AAED,kFAAkF;AAClF,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,MAAM,CAUR"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const STORAGE_KEY = "agent-chat-active-run";
|
|
2
|
+
const PENDING_TURN_STORAGE_KEY = "agent-chat-pending-turn";
|
|
2
3
|
export const ACTIVE_RUN_STATE_EVENT = "agent-chat:active-run-state-change";
|
|
3
4
|
function notifyActiveRunStateChanged(state) {
|
|
4
5
|
if (typeof window === "undefined" ||
|
|
@@ -70,6 +71,33 @@ export function clearActiveRunIfMatches(threadId, runId) {
|
|
|
70
71
|
return;
|
|
71
72
|
clearActiveRun();
|
|
72
73
|
}
|
|
74
|
+
export function setPendingTurn(state) {
|
|
75
|
+
try {
|
|
76
|
+
sessionStorage.setItem(PENDING_TURN_STORAGE_KEY, JSON.stringify(state));
|
|
77
|
+
}
|
|
78
|
+
catch { }
|
|
79
|
+
}
|
|
80
|
+
export function getPendingTurn(threadId) {
|
|
81
|
+
try {
|
|
82
|
+
const raw = sessionStorage.getItem(PENDING_TURN_STORAGE_KEY);
|
|
83
|
+
if (!raw)
|
|
84
|
+
return null;
|
|
85
|
+
const state = JSON.parse(raw);
|
|
86
|
+
return state.threadId === threadId && state.turnId ? state : null;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export function clearPendingTurnIfMatches(threadId, turnId) {
|
|
93
|
+
const state = getPendingTurn(threadId);
|
|
94
|
+
if (!state || (turnId && state.turnId !== turnId))
|
|
95
|
+
return;
|
|
96
|
+
try {
|
|
97
|
+
sessionStorage.removeItem(PENDING_TURN_STORAGE_KEY);
|
|
98
|
+
}
|
|
99
|
+
catch { }
|
|
100
|
+
}
|
|
73
101
|
/** Resume reconnect SSE after the last seen event (0 = replay from the start). */
|
|
74
102
|
export function resolveReconnectAfterSeq(threadId, runId) {
|
|
75
103
|
const stored = getActiveRun();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"active-run-state.js","sourceRoot":"","sources":["../../src/client/active-run-state.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAC5C,MAAM,CAAC,MAAM,sBAAsB,GAAG,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"active-run-state.js","sourceRoot":"","sources":["../../src/client/active-run-state.ts"],"names":[],"mappings":"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","sourcesContent":["const STORAGE_KEY = \"agent-chat-active-run\";\nconst PENDING_TURN_STORAGE_KEY = \"agent-chat-pending-turn\";\nexport const ACTIVE_RUN_STATE_EVENT = \"agent-chat:active-run-state-change\";\n\nexport interface ActiveRunState {\n threadId: string;\n runId: string;\n lastSeq: number;\n activityTool?: string | null;\n}\n\nexport interface PendingTurnState {\n threadId: string;\n turnId: string;\n}\n\nfunction notifyActiveRunStateChanged(state: ActiveRunState | null): void {\n if (\n typeof window === \"undefined\" ||\n typeof window.dispatchEvent !== \"function\" ||\n typeof CustomEvent === \"undefined\"\n ) {\n return;\n }\n window.dispatchEvent(\n new CustomEvent(ACTIVE_RUN_STATE_EVENT, { detail: { state } }),\n );\n}\n\nfunction normalizeActivityTool(toolName: unknown): string | null {\n if (typeof toolName !== \"string\") return null;\n const tool = toolName.trim();\n return tool || null;\n}\n\nexport function setActiveRun(state: ActiveRunState): void {\n try {\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(state));\n } catch {}\n notifyActiveRunStateChanged(state);\n}\n\nexport function getActiveRun(): ActiveRunState | null {\n try {\n const raw = sessionStorage.getItem(STORAGE_KEY);\n if (!raw) return null;\n return JSON.parse(raw);\n } catch {\n return null;\n }\n}\n\nexport function updateActiveRunSeq(seq: number): void {\n const state = getActiveRun();\n if (state) {\n state.lastSeq = seq;\n setActiveRun(state);\n }\n}\n\nexport function updateActiveRunActivity(\n toolName: string | null | undefined,\n): void {\n const state = getActiveRun();\n if (!state) return;\n const activityTool = normalizeActivityTool(toolName);\n if (activityTool) {\n setActiveRun({ ...state, activityTool });\n return;\n }\n const { activityTool: _activityTool, ...nextState } = state;\n setActiveRun(nextState);\n}\n\nexport function getActiveRunActivityTool(\n threadId: string,\n runId: string,\n): string | null {\n const stored = getActiveRun();\n if (stored?.threadId !== threadId || stored.runId !== runId) return null;\n return normalizeActivityTool(stored.activityTool);\n}\n\nexport function clearActiveRun(): void {\n try {\n sessionStorage.removeItem(STORAGE_KEY);\n } catch {}\n notifyActiveRunStateChanged(null);\n}\n\nexport function clearActiveRunIfMatches(threadId: string, runId: string): void {\n const state = getActiveRun();\n if (state?.threadId !== threadId || state.runId !== runId) return;\n clearActiveRun();\n}\n\nexport function setPendingTurn(state: PendingTurnState): void {\n try {\n sessionStorage.setItem(PENDING_TURN_STORAGE_KEY, JSON.stringify(state));\n } catch {}\n}\n\nexport function getPendingTurn(threadId: string): PendingTurnState | null {\n try {\n const raw = sessionStorage.getItem(PENDING_TURN_STORAGE_KEY);\n if (!raw) return null;\n const state = JSON.parse(raw) as PendingTurnState;\n return state.threadId === threadId && state.turnId ? state : null;\n } catch {\n return null;\n }\n}\n\nexport function clearPendingTurnIfMatches(\n threadId: string,\n turnId?: string,\n): void {\n const state = getPendingTurn(threadId);\n if (!state || (turnId && state.turnId !== turnId)) return;\n try {\n sessionStorage.removeItem(PENDING_TURN_STORAGE_KEY);\n } catch {}\n}\n\n/** Resume reconnect SSE after the last seen event (0 = replay from the start). */\nexport function resolveReconnectAfterSeq(\n threadId: string,\n runId: string,\n): number {\n const stored = getActiveRun();\n if (\n stored?.threadId === threadId &&\n stored?.runId === runId &&\n Number.isFinite(stored.lastSeq)\n ) {\n return stored.lastSeq + 1;\n }\n return 0;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-chat-adapter.d.ts","sourceRoot":"","sources":["../../src/client/agent-chat-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,qBAAqB,CAAC;AAWhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-chat-adapter.d.ts","sourceRoot":"","sources":["../../src/client/agent-chat-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,qBAAqB,CAAC;AAWhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAqBrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,MAAM,oBAAoB;AAC9B;;;;GAIG;AACD,KAAK;AACP,0EAA0E;GACxE,WAAW;AACb,wEAAwE;GACtE,SAAS,CAAC;AAwId,eAAO,MAAM,iCAAiC,SAAU,CAAC;AAorCzD;;;;GAIG;AACH;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC3C,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC5C,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,eAAe,GAAG,SAAS,CAAA;KAAE,CAAC;IACrD,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAA;KAAE,CAAC;IAC3D,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC;AAyED,wBAAgB,sBAAsB,CACpC,OAAO,CAAC,EAAE,6BAA6B,GACtC,gBAAgB,CAkrElB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { actionPreparationContinuationNote } from "../agent/action-continuation-guidance.js";
|
|
2
2
|
import { LLM_MISSING_CREDENTIALS_ERROR_CODE, LLM_MISSING_CREDENTIALS_MESSAGE, } from "../agent/engine/credential-errors.js";
|
|
3
|
-
import { setActiveRun, updateActiveRunSeq, clearActiveRun, } from "./active-run-state.js";
|
|
3
|
+
import { clearPendingTurnIfMatches, setActiveRun, updateActiveRunSeq, clearActiveRun, setPendingTurn, } from "./active-run-state.js";
|
|
4
4
|
import { captureError } from "./analytics.js";
|
|
5
5
|
import { agentNativePath } from "./api-path.js";
|
|
6
6
|
import { unwrapAttachmentEnvelope } from "./composer/pasted-text.js";
|
|
@@ -1294,6 +1294,8 @@ export function createAgentChatAdapter(options) {
|
|
|
1294
1294
|
const content = [];
|
|
1295
1295
|
const toolCallCounter = { value: 0 };
|
|
1296
1296
|
const turnId = generateTurnId();
|
|
1297
|
+
if (threadId)
|
|
1298
|
+
setPendingTurn({ threadId, turnId });
|
|
1297
1299
|
let runId = null;
|
|
1298
1300
|
let lastSeq = -1;
|
|
1299
1301
|
const seenRunSeqs = new Map();
|
|
@@ -2706,6 +2708,7 @@ export function createAgentChatAdapter(options) {
|
|
|
2706
2708
|
attemptedRunIds.push(runId);
|
|
2707
2709
|
}
|
|
2708
2710
|
if (runId && threadId) {
|
|
2711
|
+
clearPendingTurnIfMatches(threadId, turnId);
|
|
2709
2712
|
setActiveRun({ threadId, runId, lastSeq: -1 });
|
|
2710
2713
|
}
|
|
2711
2714
|
for await (const result of readSSEStream(res.body, content, toolCallCounter, tabId, (seq) => {
|