@robosystems/core 0.8.6 → 0.8.8

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.
@@ -3,7 +3,7 @@ import type { ConsoleConfig, SampleQuery } from './types';
3
3
  /**
4
4
  * Graph-aware console configuration.
5
5
  *
6
- * The console's natural-language agent (the "cypher operator") and its example
6
+ * The console's natural-language agent (the Analyst Operator) and its example
7
7
  * queries only make sense against the schema of the *selected* graph. A shared
8
8
  * SEC repository, a RoboLedger accounting graph, a RoboInvestor portfolio
9
9
  * graph, and a generic custom graph each expose completely different nodes —
@@ -19,7 +19,7 @@ export interface GraphExampleSet {
19
19
  * builder swaps for the graph's display name when available. */
20
20
  description: string;
21
21
  /** Natural-language prompts shown in the USAGE section. Must be answerable by
22
- * the cypher operator against THIS graph's schema. */
22
+ * the Analyst Operator against THIS graph's schema. */
23
23
  naturalLanguageExamples: string[];
24
24
  /** `/query <cypher>` one-liners shown in the USAGE section. */
25
25
  directQueryExamples: string[];
package/index.d.ts CHANGED
@@ -14,7 +14,7 @@ export { buildGraphAwareConsoleConfig, ConsoleContent, EXAMPLE_SETS, getGraphExa
14
14
  export type { ConsoleBranding, ConsoleCommandContext, ConsoleConfig, ConsoleExtraCommand, ConsoleHeaderConfig, ConsoleMcpConfig, ConsoleWelcomeConfig, GraphExampleKind, GraphExampleSet, SampleQuery, } from './components/console';
15
15
  export { ActiveSubscriptions, BrowseRepositories, EntitySelector, EntitySelectorCore, GraphSelectorCore, PageLayout, RepositoryGuard, SearchBar, SearchContent, SearchHitCard, SearchPagination, SearchResultsMeta, useIsRepository, type ActiveSubscriptionsProps, type BrowseRepositoriesProps, type EntityGroup, type EntityLike, type EntityRecord, type EntitySelectorProps, type GraphSelectorProps, type GraphWithEntities, type SearchBarProps, type SearchConfig, type SearchFilterConfig, type SearchHitCardProps, type SearchPaginationProps, type SearchResultsMetaProps, type SelectableEntity, } from './components';
16
16
  export { composeFilters, excludeRepositories, excludeSubgraphs, GraphFilters, hasSchemaExtension, onlyRepositories, onlyUserGraphs, } from './components/graph-filters';
17
- export { ApiKeyDisplay, ApiKeysCard, ApiKeyTable, BrandSpinner, categorizeError, CategoryInput, ChatHeader, ChatInputArea, ChatMessage, ConfirmModal, CoreNavbar, CoreSidebar, CreateApiKeyModal, DeepResearchToggle, EmptyState, ErrorType, GeneralInformationCard, generateMessageId, getErrorMessage, LandingFooter, LoadingState, MarkdownProse, PageContainer, PageHeader, PasswordInformationCard, PasswordRequirements, SecureApiKeyField, SettingsCard, SettingsContainer, SettingsFormField, SettingsPageHeader, Spinner, StatCard, StatusAlert, SupportModal, TagInput, ThemeToggle, } from './ui-components';
17
+ export { ApiKeyDisplay, BrandSpinner, categorizeError, CategoryInput, ChatHeader, ChatInputArea, ChatMessage, ConfirmModal, CoreNavbar, CoreSidebar, CreateApiKeyModal, DeepResearchToggle, EmptyState, ErrorType, GeneralInformationCard, generateMessageId, getErrorMessage, LandingFooter, LoadingState, MarkdownProse, PageContainer, PageHeader, PasswordInformationCard, PasswordRequirements, SecureApiKeyField, SettingsCard, SettingsContainer, SettingsFormField, SettingsPageHeader, Spinner, StatCard, StatusAlert, SupportModal, TagInput, ThemeToggle, } from './ui-components';
18
18
  export type { CategoryInputProps, MarkdownProseProps, TagInputProps, } from './ui-components';
19
19
  export type { AgentType, FooterLink, LandingFooterProps, Message, PageHeaderProps, SidebarItemData, SupportMetadata, } from './ui-components';
20
20
  export * from './library';
package/index.js CHANGED
@@ -35,7 +35,7 @@ export { ActiveSubscriptions, BrowseRepositories, EntitySelector, EntitySelector
35
35
  // Export graph filters
36
36
  export { composeFilters, excludeRepositories, excludeSubgraphs, GraphFilters, hasSchemaExtension, onlyRepositories, onlyUserGraphs, } from './components/graph-filters';
37
37
  // Export app-components
38
- export { ApiKeyDisplay, ApiKeysCard, ApiKeyTable, BrandSpinner, categorizeError, CategoryInput, ChatHeader, ChatInputArea,
38
+ export { ApiKeyDisplay, BrandSpinner, categorizeError, CategoryInput, ChatHeader, ChatInputArea,
39
39
  // Chat components
40
40
  ChatMessage, ConfirmModal, CoreNavbar, CoreSidebar, CreateApiKeyModal, DeepResearchToggle, EmptyState, ErrorType, GeneralInformationCard, generateMessageId, getErrorMessage, LandingFooter, LoadingState, MarkdownProse, PageContainer, PageHeader, PasswordInformationCard, PasswordRequirements, SecureApiKeyField, SettingsCard, SettingsContainer, SettingsFormField, SettingsPageHeader, Spinner, StatCard, StatusAlert, SupportModal, TagInput, ThemeToggle, } from './ui-components';
41
41
  // Export library components, types, and helpers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robosystems/core",
3
- "version": "0.8.6",
3
+ "version": "0.8.8",
4
4
  "description": "Shared RoboSystems frontend core library (auth, contexts, task monitoring, UI components) for the RoboSystems Next.js apps",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -1,5 +1,3 @@
1
1
  export { ApiKeyDisplay } from './ApiKeyDisplay';
2
- export { ApiKeysCard } from './ApiKeysCard';
3
- export { ApiKeyTable } from './ApiKeyTable';
4
2
  export { CreateApiKeyModal } from './CreateApiKeyModal';
5
3
  export { SecureApiKeyField } from './SecureApiKeyField';
@@ -1,5 +1,3 @@
1
1
  export { ApiKeyDisplay } from './ApiKeyDisplay';
2
- export { ApiKeysCard } from './ApiKeysCard';
3
- export { ApiKeyTable } from './ApiKeyTable';
4
2
  export { CreateApiKeyModal } from './CreateApiKeyModal';
5
3
  export { SecureApiKeyField } from './SecureApiKeyField';
@@ -17,6 +17,12 @@ export interface LandingFooterProps {
17
17
  isOpen: boolean;
18
18
  onClose: () => void;
19
19
  }>;
20
+ /**
21
+ * Where the Company column's Blog link goes. Defaults to the platform blog on
22
+ * robosystems.ai; an app with its own blog lane (roboledger.ai/blog since
23
+ * 2026-09-02) passes its own path so the footer sends readers to that lane.
24
+ */
25
+ blogHref?: string;
20
26
  }
21
27
  /**
22
28
  * The shared marketing-site footer for all three apps. The brand column, social
@@ -25,4 +31,4 @@ export interface LandingFooterProps {
25
31
  * only the tagline and Product links vary and are passed in. Contact stays
26
32
  * per-app via the `contactModal` prop.
27
33
  */
28
- export declare function LandingFooter({ tagline, productLinks, contactModal: ContactModal, }: LandingFooterProps): import("react").JSX.Element;
34
+ export declare function LandingFooter({ tagline, productLinks, contactModal: ContactModal, blogHref, }: LandingFooterProps): import("react").JSX.Element;
@@ -15,20 +15,33 @@ const headingClass = 'mb-4 text-sm font-semibold tracking-wider text-gray-400 up
15
15
  * only the tagline and Product links vary and are passed in. Contact stays
16
16
  * per-app via the `contactModal` prop.
17
17
  */
18
- export function LandingFooter({ tagline, productLinks, contactModal: ContactModal, }) {
18
+ export function LandingFooter({ tagline, productLinks, contactModal: ContactModal, blogHref, }) {
19
19
  const [showContact, setShowContact] = useState(false);
20
20
  const current = getAppConfig(CURRENT_APP);
21
21
  const isRoboSystems = CURRENT_APP === 'robosystems';
22
- // RoboSystems serves Blog/Privacy/Terms itself; the other apps link out to it.
22
+ // RoboSystems serves the platform blog, Privacy and Terms itself; the other
23
+ // apps link out to it.
23
24
  const companyBase = isRoboSystems ? '' : getAppConfig('robosystems').url;
24
25
  const companyLinkProps = isRoboSystems
25
26
  ? {}
26
27
  : { target: '_blank', rel: 'noopener noreferrer' };
28
+ // Research lives on roboinvestor.ai (robosystems.ai redirects there since
29
+ // 2026-09-02), so it resolves against that app, not the platform site.
30
+ const isRoboInvestor = CURRENT_APP === 'roboinvestor';
31
+ const researchHref = isRoboInvestor
32
+ ? '/research'
33
+ : `${getAppConfig('roboinvestor').url}/research`;
34
+ const researchLinkProps = isRoboInvestor
35
+ ? {}
36
+ : { target: '_blank', rel: 'noopener noreferrer' };
37
+ const resolvedBlogHref = blogHref !== null && blogHref !== void 0 ? blogHref : `${companyBase}/blog`;
38
+ // A same-site path opens in the same tab; an external site opens in a new one.
39
+ const blogLinkProps = resolvedBlogHref.startsWith('/') ? {} : companyLinkProps;
27
40
  return (_jsxs("footer", { className: "border-t border-gray-800 bg-zinc-950", children: [_jsxs("div", { className: "mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8", children: [_jsxs("div", { className: "grid gap-4 md:grid-cols-5 lg:gap-6", children: [_jsxs("div", { className: "md:col-span-2", children: [_jsxs("div", { className: "mb-4 flex items-center gap-2", children: [_jsx(Image, { src: `/images/logos/${CURRENT_APP}.png`, alt: current.displayName, width: 32, height: 32, className: "rounded-lg" }), _jsx("span", { className: "font-heading text-xl font-semibold text-white", children: current.displayName })] }), _jsx("p", { className: "mb-4 max-w-md text-sm text-gray-400", children: tagline }), _jsxs("div", { className: "flex gap-4", children: [_jsx(Link, { href: "https://github.com/RoboFinSystems", target: "_blank", rel: "noopener noreferrer", "aria-label": "RoboSystems on GitHub", className: linkClass, children: _jsx("svg", { className: "h-6 w-6", fill: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { d: "M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" }) }) }), _jsx(Link, { href: "https://x.com/robofinsystems", target: "_blank", rel: "noopener noreferrer", "aria-label": "RoboSystems on X", className: linkClass, children: _jsx("svg", { className: "h-6 w-6", fill: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { d: "M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z" }) }) }), _jsx(Link, { href: "https://www.linkedin.com/company/robosystems", target: "_blank", rel: "noopener noreferrer", "aria-label": "RoboSystems on LinkedIn", className: linkClass, children: _jsx("svg", { className: "h-6 w-6", fill: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { d: "M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" }) }) }), _jsx(Link, { href: "https://www.youtube.com/@RoboSystems", target: "_blank", rel: "noopener noreferrer", "aria-label": "RoboSystems on YouTube", className: linkClass, children: _jsx("svg", { className: "h-6 w-6", fill: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { d: "M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z" }) }) })] })] }), _jsxs("div", { children: [_jsx("h3", { className: headingClass, children: "Product" }), _jsx("ul", { className: "space-y-2 text-sm", children: productLinks.map((link) => (_jsx("li", { children: _jsx(Link, { href: link.href, className: linkClass, children: link.label }) }, link.href))) })] }), _jsxs("div", { children: [_jsx("h3", { className: headingClass, children: "Applications" }), _jsx("ul", { className: "space-y-2 text-sm", children: APP_ORDER.map((app) => {
28
41
  const cfg = getAppConfig(app);
29
42
  const isCurrent = app === CURRENT_APP;
30
43
  return (_jsx("li", { children: _jsx(Link, Object.assign({ href: cfg.url }, (isCurrent
31
44
  ? {}
32
45
  : { target: '_blank', rel: 'noopener noreferrer' }), { className: linkClass, children: cfg.displayName })) }, app));
33
- }) })] }), _jsxs("div", { children: [_jsx("h3", { className: headingClass, children: "Company" }), _jsxs("ul", { className: "space-y-2 text-sm", children: [_jsx("li", { children: _jsx(Link, Object.assign({ href: `${companyBase}/research` }, companyLinkProps, { className: linkClass, children: "Research" })) }), _jsx("li", { children: _jsx(Link, { href: "https://holon.robosystems.ai", target: "_blank", rel: "noopener noreferrer", className: linkClass, children: "Holon Viewer" }) }), _jsx("li", { children: _jsx(Link, Object.assign({ href: `${companyBase}/blog` }, companyLinkProps, { className: linkClass, children: "Blog" })) }), _jsx("li", { children: _jsx(Link, Object.assign({ href: `${companyBase}/pages/privacy` }, companyLinkProps, { className: linkClass, children: "Privacy" })) }), _jsx("li", { children: _jsx(Link, Object.assign({ href: `${companyBase}/pages/terms` }, companyLinkProps, { className: linkClass, children: "Terms" })) }), _jsx("li", { children: _jsx(Link, { href: "https://trust.robosystems.ai", target: "_blank", rel: "noopener noreferrer", className: linkClass, children: "Trust Center" }) }), _jsx("li", { children: _jsx(Link, { href: "https://status.robosystems.ai", target: "_blank", rel: "noopener noreferrer", className: linkClass, children: "Status" }) }), ContactModal && (_jsx("li", { children: _jsx("button", { onClick: () => setShowContact(true), className: linkClass, children: "Contact" }) }))] })] })] }), _jsx("div", { className: "mt-8 border-t border-gray-800 pt-8 text-center text-sm text-gray-400", children: _jsxs("p", { children: ["\u00A9 ", new Date().getFullYear(), " RFS LLC. All rights reserved."] }) })] }), ContactModal && (_jsx(ContactModal, { isOpen: showContact, onClose: () => setShowContact(false) }))] }));
46
+ }) })] }), _jsxs("div", { children: [_jsx("h3", { className: headingClass, children: "Company" }), _jsxs("ul", { className: "space-y-2 text-sm", children: [_jsx("li", { children: _jsx(Link, Object.assign({ href: researchHref }, researchLinkProps, { className: linkClass, children: "Research" })) }), _jsx("li", { children: _jsx(Link, { href: "https://holon.robosystems.ai", target: "_blank", rel: "noopener noreferrer", className: linkClass, children: "Holon Viewer" }) }), _jsx("li", { children: _jsx(Link, Object.assign({ href: resolvedBlogHref }, blogLinkProps, { className: linkClass, children: "Blog" })) }), _jsx("li", { children: _jsx(Link, Object.assign({ href: `${companyBase}/pages/privacy` }, companyLinkProps, { className: linkClass, children: "Privacy" })) }), _jsx("li", { children: _jsx(Link, Object.assign({ href: `${companyBase}/pages/terms` }, companyLinkProps, { className: linkClass, children: "Terms" })) }), _jsx("li", { children: _jsx(Link, { href: "https://trust.robosystems.ai", target: "_blank", rel: "noopener noreferrer", className: linkClass, children: "Trust Center" }) }), _jsx("li", { children: _jsx(Link, { href: "https://status.robosystems.ai", target: "_blank", rel: "noopener noreferrer", className: linkClass, children: "Status" }) }), ContactModal && (_jsx("li", { children: _jsx("button", { onClick: () => setShowContact(true), className: linkClass, children: "Contact" }) }))] })] })] }), _jsx("div", { className: "mt-8 border-t border-gray-800 pt-8 text-center text-sm text-gray-400", children: _jsxs("p", { children: ["\u00A9 ", new Date().getFullYear(), " RFS LLC. All rights reserved."] }) })] }), ContactModal && (_jsx(ContactModal, { isOpen: showContact, onClose: () => setShowContact(false) }))] }));
34
47
  }
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- import type { ApiKey } from '../types';
3
- export interface ApiKeyTableProps {
4
- apiKeys: ApiKey[];
5
- onRevokeKey: (keyId: string) => void;
6
- theme?: any;
7
- formatDate?: (date: Date | string | null | undefined) => string;
8
- }
9
- export declare const ApiKeyTable: React.FC<ApiKeyTableProps>;
@@ -1,17 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Button, Dropdown, DropdownItem, Table, TableBody, TableCell, TableHead, TableHeadCell, TableRow, } from 'flowbite-react';
3
- import { HiCheckCircle, HiDotsVertical, HiExclamationCircle, HiKey, HiTrash, } from 'react-icons/hi';
4
- const defaultFormatDate = (date) => {
5
- if (!date)
6
- return 'Never';
7
- return new Date(date).toLocaleDateString('en-US', {
8
- year: 'numeric',
9
- month: 'short',
10
- day: 'numeric',
11
- });
12
- };
13
- export const ApiKeyTable = ({ apiKeys = [], onRevokeKey, theme, formatDate = defaultFormatDate, }) => {
14
- // Defensive check to ensure apiKeys is always an array
15
- const safeApiKeys = Array.isArray(apiKeys) ? apiKeys : [];
16
- return (_jsx("div", { className: "overflow-x-auto", children: _jsxs(Table, { className: "table-fixed", children: [_jsxs(TableHead, { children: [_jsx(TableHeadCell, { className: "w-[40%]", children: "Name" }), _jsx(TableHeadCell, { className: "w-[15%] whitespace-nowrap", children: "Created" }), _jsx(TableHeadCell, { className: "w-[15%] whitespace-nowrap", children: "Last Used" }), _jsx(TableHeadCell, { className: "w-[15%] whitespace-nowrap", children: "Status" }), _jsx(TableHeadCell, { className: "w-[15%] text-right", children: "Actions" })] }), _jsx(TableBody, { className: "divide-y", children: safeApiKeys.map((key) => (_jsxs(TableRow, { className: "dark:border-zinc-700", children: [_jsx(TableCell, { className: "font-medium text-zinc-900 dark:text-zinc-100", children: _jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(HiKey, { className: "h-5 w-5 shrink-0 text-zinc-600 dark:text-zinc-400" }), _jsx("span", { className: "truncate", title: key.name, children: key.name }), key.isSystem && (_jsx("span", { className: "bg-primary-100 text-primary-800 dark:bg-primary-900 dark:text-primary-300 shrink-0 rounded-full px-2.5 py-0.5 text-xs font-medium", children: "System" })), key.graphId && (_jsx("span", { className: "max-w-40 shrink-0 truncate rounded-full bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800 dark:bg-blue-900 dark:text-blue-300", title: `Scoped to graph ${key.graphId} — valid only for that graph and its subgraphs`, children: key.graphId }))] }) }), _jsx(TableCell, { className: "whitespace-nowrap text-zinc-600 dark:text-zinc-400", children: formatDate(key.createdAt) }), _jsx(TableCell, { className: "whitespace-nowrap text-zinc-600 dark:text-zinc-400", children: formatDate(key.lastUsedAt) }), _jsx(TableCell, { className: "whitespace-nowrap", children: key.isActive ? (_jsxs("div", { className: "inline-flex items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800 dark:bg-green-800 dark:text-green-100", children: [_jsx(HiCheckCircle, { className: "mr-1 h-3 w-3" }), "Active"] })) : (_jsxs("div", { className: "inline-flex items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-800 dark:bg-red-800 dark:text-red-100", children: [_jsx(HiExclamationCircle, { className: "mr-1 h-3 w-3" }), "Revoked"] })) }), _jsx(TableCell, { className: "text-right", children: _jsx("div", { className: "inline-flex justify-end", children: _jsx(Dropdown, { theme: theme === null || theme === void 0 ? void 0 : theme.dropdown, label: "", dismissOnClick: true, renderTrigger: () => (_jsx(Button, { theme: theme === null || theme === void 0 ? void 0 : theme.button, size: "sm", pill: true, className: "bg-zinc-100 text-zinc-900 hover:bg-zinc-200 dark:bg-zinc-700 dark:text-zinc-100 dark:hover:bg-zinc-600", children: _jsx(HiDotsVertical, { className: "h-4 w-4" }) })), children: _jsx(DropdownItem, { onClick: () => onRevokeKey(key.id), disabled: !key.isActive || key.isSystem, icon: HiTrash, className: "hover:bg-zinc-100 dark:hover:bg-zinc-700", children: "Revoke" }) }) }) })] }, key.id))) })] }) }));
17
- };
@@ -1,11 +0,0 @@
1
- import React from 'react';
2
- export interface ApiKeysCardProps {
3
- theme?: any;
4
- className?: string;
5
- /**
6
- * When set, the card links MCP users to the app's Connect page (the
7
- * ready-made connector-URL flow) — e.g. "/connect" in robosystems-app.
8
- */
9
- connectHref?: string;
10
- }
11
- export declare const ApiKeysCard: React.FC<ApiKeysCardProps>;
@@ -1,112 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import * as SDK from '@robosystems/client';
4
- import { Button } from 'flowbite-react';
5
- import { useContext, useEffect, useState } from 'react';
6
- import { HiKey, HiPlusCircle } from 'react-icons/hi';
7
- import { GraphContext } from '../../contexts';
8
- import { Spinner } from '../Spinner';
9
- import { SettingsCard } from '../forms/SettingsCard';
10
- import { StatusAlert } from '../forms/StatusAlert';
11
- import { ApiKeyTable } from './ApiKeyTable';
12
- import { CreateApiKeyModal } from './CreateApiKeyModal';
13
- export const ApiKeysCard = ({ theme, className = '', connectHref, }) => {
14
- var _a;
15
- // Read the graph context leniently: outside a GraphProvider the scope
16
- // selector simply doesn't render, preserving the card's old standalone
17
- // contract instead of throwing.
18
- const graphContext = useContext(GraphContext);
19
- const availableGraphs = (_a = graphContext === null || graphContext === void 0 ? void 0 : graphContext.state.graphs) !== null && _a !== void 0 ? _a : [];
20
- const [apiKeys, setApiKeys] = useState([]);
21
- const [isLoading, setIsLoading] = useState(false);
22
- const [isOpenCreateModal, setIsOpenCreateModal] = useState(false);
23
- const [error, setError] = useState(null);
24
- useEffect(() => {
25
- fetchApiKeys();
26
- }, []);
27
- const fetchApiKeys = async () => {
28
- var _a;
29
- setIsLoading(true);
30
- setError(null);
31
- try {
32
- // Always use SDK
33
- const response = await SDK.listUserApiKeys();
34
- const sdkKeys = ((_a = response.data) === null || _a === void 0 ? void 0 : _a.api_keys) || [];
35
- // Map SDK response to component format
36
- const keys = sdkKeys.map((key) => {
37
- var _a, _b;
38
- return ({
39
- id: key.id,
40
- name: key.name,
41
- graphId: key.graph_id,
42
- createdAt: key.created_at,
43
- lastUsedAt: key.last_used_at,
44
- expiresAt: key.expires_at,
45
- isActive: (_a = key.is_active) !== null && _a !== void 0 ? _a : true,
46
- isSystem: (_b = key.is_system) !== null && _b !== void 0 ? _b : false,
47
- });
48
- });
49
- setApiKeys(keys);
50
- }
51
- catch (_b) {
52
- setError('Failed to load API keys. Please try again.');
53
- }
54
- finally {
55
- setIsLoading(false);
56
- }
57
- };
58
- const handleCreateKey = async (data) => {
59
- var _a, _b;
60
- // Always use SDK to create key
61
- const response = await SDK.createUserApiKey({
62
- body: {
63
- name: data.name,
64
- description: `API key for ${data.name}`,
65
- graph_id: data.graphId,
66
- },
67
- });
68
- await fetchApiKeys(); // Refresh the list
69
- // Map SDK response to component format
70
- const responseData = response.data;
71
- const apiKeyInfo = responseData === null || responseData === void 0 ? void 0 : responseData.api_key;
72
- return {
73
- id: (apiKeyInfo === null || apiKeyInfo === void 0 ? void 0 : apiKeyInfo.id) || '',
74
- name: (apiKeyInfo === null || apiKeyInfo === void 0 ? void 0 : apiKeyInfo.name) || data.name,
75
- graphId: (_a = apiKeyInfo === null || apiKeyInfo === void 0 ? void 0 : apiKeyInfo.graph_id) !== null && _a !== void 0 ? _a : data.graphId,
76
- key: (responseData === null || responseData === void 0 ? void 0 : responseData.key) || '', // The actual API key value
77
- createdAt: (apiKeyInfo === null || apiKeyInfo === void 0 ? void 0 : apiKeyInfo.created_at) || new Date().toISOString(),
78
- lastUsedAt: (apiKeyInfo === null || apiKeyInfo === void 0 ? void 0 : apiKeyInfo.last_used_at) || null,
79
- expiresAt: null,
80
- isActive: (_b = apiKeyInfo === null || apiKeyInfo === void 0 ? void 0 : apiKeyInfo.is_active) !== null && _b !== void 0 ? _b : true,
81
- isSystem: false,
82
- };
83
- };
84
- const handleRevokeKey = async (keyId) => {
85
- try {
86
- // Always use SDK to revoke key
87
- await SDK.revokeUserApiKey({
88
- path: { api_key_id: keyId },
89
- });
90
- await fetchApiKeys(); // Refresh the list
91
- }
92
- catch (_a) {
93
- setError('Failed to revoke API key. Please try again.');
94
- }
95
- };
96
- const formatDate = (date) => {
97
- if (!date)
98
- return 'Never';
99
- return new Date(date).toLocaleDateString('en-US', {
100
- year: 'numeric',
101
- month: 'short',
102
- day: 'numeric',
103
- });
104
- };
105
- return (_jsxs(SettingsCard, { title: "API Keys", description: "Manage your API keys for programmatic access", icon: HiKey, theme: theme === null || theme === void 0 ? void 0 : theme.card, className: className, children: [_jsx("div", { className: "mb-4 flex items-center justify-end", children: _jsxs(Button, { theme: theme === null || theme === void 0 ? void 0 : theme.button, color: "blue", onClick: () => setIsOpenCreateModal(true), children: [_jsx(HiPlusCircle, { className: "mr-2 h-5 w-5" }), "Create API Key"] }) }), error && (_jsx(StatusAlert, { type: "error", message: error, theme: theme === null || theme === void 0 ? void 0 : theme.alert })), isLoading ? (_jsx("div", { className: "flex justify-center py-4", children: _jsx(Spinner, { size: "lg" }) })) : !Array.isArray(apiKeys) || apiKeys.length === 0 ? (_jsxs("div", { className: "rounded-lg border border-zinc-200 bg-zinc-50 p-8 text-center dark:border-zinc-700 dark:bg-zinc-800", children: [_jsx(HiKey, { className: "mx-auto mb-3 h-12 w-12 text-zinc-400" }), _jsx("h3", { className: "mb-2 text-lg font-semibold text-zinc-900 dark:text-zinc-100", children: "No API keys yet" }), _jsx("p", { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "Create an API key to access your graphs programmatically" })] })) : (_jsx(ApiKeyTable, { apiKeys: apiKeys, onRevokeKey: handleRevokeKey, theme: theme, formatDate: formatDate })), connectHref && (_jsxs("p", { className: "mt-4 text-sm text-zinc-500 dark:text-zinc-400", children: ["Connecting Claude or another MCP client? Generate a ready-made connector URL from the", ' ', _jsx("a", { href: connectHref, className: "text-primary-600 dark:text-primary-400 font-medium hover:underline", children: "Connect page" }), "."] })), _jsx(CreateApiKeyModal, { isOpen: isOpenCreateModal, onClose: () => setIsOpenCreateModal(false), onCreateKey: handleCreateKey, theme: theme, graphs: availableGraphs.map((g) => {
106
- var _a;
107
- return ({
108
- graphId: g.graphId,
109
- graphName: (_a = g.graphName) !== null && _a !== void 0 ? _a : g.graphId,
110
- });
111
- }) })] }));
112
- };