@robosystems/core 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +252 -0
  3. package/actions/entity-actions.d.ts +8 -0
  4. package/actions/entity-actions.js +16 -0
  5. package/actions/graph-actions.d.ts +3 -0
  6. package/actions/graph-actions.js +13 -0
  7. package/auth-components/AppSwitcher.d.ts +6 -0
  8. package/auth-components/AppSwitcher.js +28 -0
  9. package/auth-components/AuthGuard.d.ts +7 -0
  10. package/auth-components/AuthGuard.js +31 -0
  11. package/auth-components/AuthProvider.d.ts +9 -0
  12. package/auth-components/AuthProvider.js +565 -0
  13. package/auth-components/SessionWarningDialog.d.ts +1 -0
  14. package/auth-components/SessionWarningDialog.js +51 -0
  15. package/auth-components/SignInForm.d.ts +20 -0
  16. package/auth-components/SignInForm.js +139 -0
  17. package/auth-components/SignUpForm.d.ts +15 -0
  18. package/auth-components/SignUpForm.js +167 -0
  19. package/auth-components/TurnstileWidget.d.ts +99 -0
  20. package/auth-components/TurnstileWidget.js +224 -0
  21. package/auth-components/index.d.ts +6 -0
  22. package/auth-components/index.js +6 -0
  23. package/auth-core/cleanup.d.ts +44 -0
  24. package/auth-core/cleanup.js +157 -0
  25. package/auth-core/client.d.ts +121 -0
  26. package/auth-core/client.js +767 -0
  27. package/auth-core/config.d.ts +19 -0
  28. package/auth-core/config.js +56 -0
  29. package/auth-core/hooks.d.ts +19 -0
  30. package/auth-core/hooks.js +63 -0
  31. package/auth-core/index.d.ts +6 -0
  32. package/auth-core/index.js +6 -0
  33. package/auth-core/sso.d.ts +42 -0
  34. package/auth-core/sso.js +281 -0
  35. package/auth-core/token-storage.d.ts +58 -0
  36. package/auth-core/token-storage.js +177 -0
  37. package/auth-core/types.d.ts +145 -0
  38. package/auth-core/types.js +1 -0
  39. package/components/EntitySelector.d.ts +44 -0
  40. package/components/EntitySelector.js +64 -0
  41. package/components/EntitySelectorCore.d.ts +45 -0
  42. package/components/EntitySelectorCore.js +67 -0
  43. package/components/GraphSelectorCore.d.ts +21 -0
  44. package/components/GraphSelectorCore.js +39 -0
  45. package/components/PageLayout.d.ts +8 -0
  46. package/components/PageLayout.js +5 -0
  47. package/components/RepositoryGuard.d.ts +68 -0
  48. package/components/RepositoryGuard.js +91 -0
  49. package/components/console/ConsoleContent.d.ts +4 -0
  50. package/components/console/ConsoleContent.js +612 -0
  51. package/components/console/ConsoleMarkdown.d.ts +11 -0
  52. package/components/console/ConsoleMarkdown.js +49 -0
  53. package/components/console/ProgressiveText.d.ts +6 -0
  54. package/components/console/ProgressiveText.js +21 -0
  55. package/components/console/graphAwareConfig.d.ts +70 -0
  56. package/components/console/graphAwareConfig.js +411 -0
  57. package/components/console/index.d.ts +6 -0
  58. package/components/console/index.js +4 -0
  59. package/components/console/types.d.ts +84 -0
  60. package/components/console/types.js +1 -0
  61. package/components/graph-filters.d.ts +75 -0
  62. package/components/graph-filters.js +111 -0
  63. package/components/index.d.ts +10 -0
  64. package/components/index.js +9 -0
  65. package/components/repositories/ActiveSubscriptions.d.ts +26 -0
  66. package/components/repositories/ActiveSubscriptions.js +103 -0
  67. package/components/repositories/BrowseRepositories.d.ts +11 -0
  68. package/components/repositories/BrowseRepositories.js +184 -0
  69. package/components/repositories/index.d.ts +2 -0
  70. package/components/repositories/index.js +2 -0
  71. package/components/search/SearchContent.d.ts +4 -0
  72. package/components/search/SearchContent.js +168 -0
  73. package/components/search/index.d.ts +2 -0
  74. package/components/search/index.js +1 -0
  75. package/components/search/types.d.ts +15 -0
  76. package/components/search/types.js +1 -0
  77. package/contexts/entity-context.d.ts +28 -0
  78. package/contexts/entity-context.js +89 -0
  79. package/contexts/graph-context.d.ts +27 -0
  80. package/contexts/graph-context.js +128 -0
  81. package/contexts/index.d.ts +5 -0
  82. package/contexts/index.js +5 -0
  83. package/contexts/org-context.d.ts +25 -0
  84. package/contexts/org-context.js +64 -0
  85. package/contexts/service-offerings-context.d.ts +45 -0
  86. package/contexts/service-offerings-context.js +98 -0
  87. package/contexts/sidebar-context.d.ts +18 -0
  88. package/contexts/sidebar-context.js +44 -0
  89. package/hooks/index.d.ts +6 -0
  90. package/hooks/index.js +6 -0
  91. package/hooks/use-api-error.d.ts +3 -0
  92. package/hooks/use-api-error.js +24 -0
  93. package/hooks/use-media-query.d.ts +1 -0
  94. package/hooks/use-media-query.js +21 -0
  95. package/hooks/use-streaming-query.d.ts +22 -0
  96. package/hooks/use-streaming-query.js +142 -0
  97. package/hooks/use-toast.d.ts +37 -0
  98. package/hooks/use-toast.js +117 -0
  99. package/hooks/use-user-limits.d.ts +12 -0
  100. package/hooks/use-user-limits.js +73 -0
  101. package/hooks/use-user.d.ts +11 -0
  102. package/hooks/use-user.js +39 -0
  103. package/index.d.ts +29 -0
  104. package/index.js +77 -0
  105. package/lib/entity-cookie.d.ts +10 -0
  106. package/lib/entity-cookie.js +38 -0
  107. package/lib/graph-cookie.d.ts +11 -0
  108. package/lib/graph-cookie.js +62 -0
  109. package/lib/graph-tiers.d.ts +41 -0
  110. package/lib/graph-tiers.js +107 -0
  111. package/lib/index.d.ts +3 -0
  112. package/lib/index.js +3 -0
  113. package/lib/sidebar-cookie.d.ts +11 -0
  114. package/lib/sidebar-cookie.js +42 -0
  115. package/library/colors.d.ts +4 -0
  116. package/library/colors.js +41 -0
  117. package/library/components/ClassificationPicker.d.ts +8 -0
  118. package/library/components/ClassificationPicker.js +55 -0
  119. package/library/components/ElementBrowser.d.ts +11 -0
  120. package/library/components/ElementBrowser.js +106 -0
  121. package/library/components/ElementDetail.d.ts +7 -0
  122. package/library/components/ElementDetail.js +97 -0
  123. package/library/components/LibraryHierarchy.d.ts +13 -0
  124. package/library/components/LibraryHierarchy.js +380 -0
  125. package/library/components/TaxonomySidebar.d.ts +6 -0
  126. package/library/components/TaxonomySidebar.js +45 -0
  127. package/library/index.d.ts +8 -0
  128. package/library/index.js +7 -0
  129. package/package.json +37 -0
  130. package/research/CoverageCard.d.ts +12 -0
  131. package/research/CoverageCard.js +15 -0
  132. package/research/CoverageGrid.d.ts +6 -0
  133. package/research/CoverageGrid.js +9 -0
  134. package/research/CoverageHistory.d.ts +5 -0
  135. package/research/CoverageHistory.js +7 -0
  136. package/research/ResearchArticle.d.ts +15 -0
  137. package/research/ResearchArticle.js +26 -0
  138. package/research/catalog.d.ts +14 -0
  139. package/research/catalog.js +42 -0
  140. package/research/index.d.ts +6 -0
  141. package/research/index.js +9 -0
  142. package/research/types.d.ts +38 -0
  143. package/research/types.js +4 -0
  144. package/task-monitoring/hooks.d.ts +26 -0
  145. package/task-monitoring/hooks.js +126 -0
  146. package/task-monitoring/index.d.ts +5 -0
  147. package/task-monitoring/index.js +7 -0
  148. package/task-monitoring/operationErrors.d.ts +82 -0
  149. package/task-monitoring/operationErrors.js +251 -0
  150. package/task-monitoring/operationHooks.d.ts +117 -0
  151. package/task-monitoring/operationHooks.js +536 -0
  152. package/task-monitoring/operationMonitor.d.ts +78 -0
  153. package/task-monitoring/operationMonitor.js +200 -0
  154. package/task-monitoring/operationTypes.d.ts +236 -0
  155. package/task-monitoring/operationTypes.js +60 -0
  156. package/task-monitoring/taskMonitor.d.ts +14 -0
  157. package/task-monitoring/taskMonitor.js +132 -0
  158. package/task-monitoring/types.d.ts +31 -0
  159. package/task-monitoring/types.js +1 -0
  160. package/theme/flowbite-theme.d.ts +758 -0
  161. package/theme/flowbite-theme.js +765 -0
  162. package/theme/index.d.ts +1 -0
  163. package/theme/index.js +1 -0
  164. package/types/entity.d.ts +19 -0
  165. package/types/index.d.ts +2 -0
  166. package/types/index.js +1 -0
  167. package/types/user.d.ts +6 -0
  168. package/ui-components/ConfirmModal.d.ts +41 -0
  169. package/ui-components/ConfirmModal.js +19 -0
  170. package/ui-components/EmptyState.d.ts +22 -0
  171. package/ui-components/EmptyState.js +10 -0
  172. package/ui-components/LoadingState.d.ts +27 -0
  173. package/ui-components/LoadingState.js +12 -0
  174. package/ui-components/Logo.d.ts +28 -0
  175. package/ui-components/Logo.js +95 -0
  176. package/ui-components/Spinner.d.ts +37 -0
  177. package/ui-components/Spinner.js +48 -0
  178. package/ui-components/StatCard.d.ts +21 -0
  179. package/ui-components/StatCard.js +10 -0
  180. package/ui-components/api-keys/ApiKeyDisplay.d.ts +13 -0
  181. package/ui-components/api-keys/ApiKeyDisplay.js +7 -0
  182. package/ui-components/api-keys/ApiKeyTable.d.ts +9 -0
  183. package/ui-components/api-keys/ApiKeyTable.js +17 -0
  184. package/ui-components/api-keys/ApiKeysCard.d.ts +6 -0
  185. package/ui-components/api-keys/ApiKeysCard.js +97 -0
  186. package/ui-components/api-keys/CreateApiKeyModal.d.ts +11 -0
  187. package/ui-components/api-keys/CreateApiKeyModal.js +47 -0
  188. package/ui-components/api-keys/SecureApiKeyField.d.ts +13 -0
  189. package/ui-components/api-keys/SecureApiKeyField.js +64 -0
  190. package/ui-components/api-keys/index.d.ts +5 -0
  191. package/ui-components/api-keys/index.js +5 -0
  192. package/ui-components/chat/ChatHeader.d.ts +12 -0
  193. package/ui-components/chat/ChatHeader.js +5 -0
  194. package/ui-components/chat/ChatInputArea.d.ts +16 -0
  195. package/ui-components/chat/ChatInputArea.js +9 -0
  196. package/ui-components/chat/ChatMessage.d.ts +7 -0
  197. package/ui-components/chat/ChatMessage.js +24 -0
  198. package/ui-components/chat/DeepResearchToggle.d.ts +8 -0
  199. package/ui-components/chat/DeepResearchToggle.js +13 -0
  200. package/ui-components/chat/index.d.ts +9 -0
  201. package/ui-components/chat/index.js +8 -0
  202. package/ui-components/chat/types.d.ts +23 -0
  203. package/ui-components/chat/types.js +51 -0
  204. package/ui-components/forms/PasswordRequirements.d.ts +10 -0
  205. package/ui-components/forms/PasswordRequirements.js +15 -0
  206. package/ui-components/forms/SettingsCard.d.ts +11 -0
  207. package/ui-components/forms/SettingsCard.js +5 -0
  208. package/ui-components/forms/SettingsFormField.d.ts +18 -0
  209. package/ui-components/forms/SettingsFormField.js +17 -0
  210. package/ui-components/forms/StatusAlert.d.ts +8 -0
  211. package/ui-components/forms/StatusAlert.js +7 -0
  212. package/ui-components/forms/index.d.ts +4 -0
  213. package/ui-components/forms/index.js +4 -0
  214. package/ui-components/index.d.ts +13 -0
  215. package/ui-components/index.js +18 -0
  216. package/ui-components/layout/CoreNavbar.d.ts +14 -0
  217. package/ui-components/layout/CoreNavbar.js +53 -0
  218. package/ui-components/layout/CoreSidebar.d.ts +28 -0
  219. package/ui-components/layout/CoreSidebar.js +62 -0
  220. package/ui-components/layout/LandingFooter.d.ts +28 -0
  221. package/ui-components/layout/LandingFooter.js +34 -0
  222. package/ui-components/layout/PageContainer.d.ts +8 -0
  223. package/ui-components/layout/PageContainer.js +17 -0
  224. package/ui-components/layout/PageHeader.d.ts +23 -0
  225. package/ui-components/layout/PageHeader.js +12 -0
  226. package/ui-components/layout/SettingsContainer.d.ts +10 -0
  227. package/ui-components/layout/SettingsContainer.js +9 -0
  228. package/ui-components/layout/ThemeToggle.d.ts +4 -0
  229. package/ui-components/layout/ThemeToggle.js +6 -0
  230. package/ui-components/layout/index.d.ts +7 -0
  231. package/ui-components/layout/index.js +7 -0
  232. package/ui-components/settings/GeneralInformationCard.d.ts +12 -0
  233. package/ui-components/settings/GeneralInformationCard.js +72 -0
  234. package/ui-components/settings/PasswordInformationCard.d.ts +10 -0
  235. package/ui-components/settings/PasswordInformationCard.js +167 -0
  236. package/ui-components/settings/SettingsPageHeader.d.ts +7 -0
  237. package/ui-components/settings/SettingsPageHeader.js +6 -0
  238. package/ui-components/settings/index.d.ts +3 -0
  239. package/ui-components/settings/index.js +3 -0
  240. package/ui-components/support/SupportModal.d.ts +15 -0
  241. package/ui-components/support/SupportModal.js +74 -0
  242. package/ui-components/support/index.d.ts +2 -0
  243. package/ui-components/support/index.js +1 -0
  244. package/ui-components/types/index.d.ts +39 -0
  245. package/ui-components/types/index.js +1 -0
  246. package/utils/index.d.ts +31 -0
  247. package/utils/index.js +38 -0
  248. package/utils/turnstile-config.d.ts +11 -0
  249. package/utils/turnstile-config.js +19 -0
@@ -0,0 +1,49 @@
1
+ 'use client';
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ import ReactMarkdown from 'react-markdown';
15
+ import remarkGfm from 'remark-gfm';
16
+ /**
17
+ * Renders a natural-language console answer as GitHub-flavored markdown, themed
18
+ * for the dark terminal. The backend now returns enriched markdown (### headings,
19
+ * **bold**, and | pipe tables); without this it rendered as raw literal text.
20
+ *
21
+ * Styling stays inside the terminal's cyan/mono aesthetic — the surrounding
22
+ * container supplies `font-mono text-sm`, so tables and code inherit it.
23
+ */
24
+ export function ConsoleMarkdown({ content }) {
25
+ return (_jsx("div", { className: "leading-relaxed text-cyan-400", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: {
26
+ h1: ({ children }) => (_jsx("h1", { className: "mt-4 mb-2 text-base font-bold text-cyan-300 first:mt-0", children: children })),
27
+ h2: ({ children }) => (_jsx("h2", { className: "mt-4 mb-2 text-sm font-bold text-cyan-300 first:mt-0", children: children })),
28
+ h3: ({ children }) => (_jsx("h3", { className: "mt-3 mb-1.5 text-sm font-semibold text-cyan-300 first:mt-0", children: children })),
29
+ h4: ({ children }) => (_jsx("h4", { className: "mt-3 mb-1 text-xs font-semibold tracking-wide text-cyan-300 uppercase first:mt-0", children: children })),
30
+ p: ({ children }) => _jsx("p", { className: "my-2 first:mt-0", children: children }),
31
+ strong: ({ children }) => (_jsx("strong", { className: "font-semibold text-white", children: children })),
32
+ em: ({ children }) => (_jsx("em", { className: "text-cyan-200 italic", children: children })),
33
+ a: ({ href, children }) => (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", className: "text-cyan-300 underline hover:text-cyan-200", children: children })),
34
+ ul: ({ children }) => (_jsx("ul", { className: "my-2 list-disc space-y-1 pl-5", children: children })),
35
+ ol: ({ children }) => (_jsx("ol", { className: "my-2 list-decimal space-y-1 pl-5", children: children })),
36
+ li: ({ children }) => _jsx("li", { className: "pl-1", children: children }),
37
+ blockquote: ({ children }) => (_jsx("blockquote", { className: "my-2 border-l-2 border-cyan-700 pl-3 text-cyan-300/80 italic", children: children })),
38
+ hr: () => _jsx("hr", { className: "my-3 border-gray-800" }),
39
+ code: (_a) => {
40
+ var { className, children } = _a, props = __rest(_a, ["className", "children"]);
41
+ return /language-/.test(className || '') ? (_jsx("code", Object.assign({ className: className }, props, { children: children }))) : (_jsx("code", Object.assign({ className: "rounded bg-gray-800 px-1 py-0.5 text-cyan-200" }, props, { children: children })));
42
+ },
43
+ pre: ({ children }) => (_jsx("pre", { className: "my-2 overflow-x-auto rounded border border-gray-800 bg-gray-900/40 p-3 text-xs text-cyan-300", children: children })),
44
+ table: ({ children }) => (_jsx("div", { className: "my-3 overflow-x-auto rounded border border-gray-800", children: _jsx("table", { className: "w-full border-collapse text-xs", children: children }) })),
45
+ thead: ({ children }) => (_jsx("thead", { className: "border-b border-gray-800 bg-gray-900", children: children })),
46
+ th: ({ children }) => (_jsx("th", { className: "px-3 py-2 text-left font-semibold whitespace-nowrap text-cyan-400", children: children })),
47
+ td: ({ children }) => (_jsx("td", { className: "border-t border-gray-900 px-3 py-2 text-gray-300", children: children })),
48
+ }, children: content }) }));
49
+ }
@@ -0,0 +1,6 @@
1
+ export declare function ProgressiveText({ text, onComplete, speed, onUpdate, }: {
2
+ text: string;
3
+ onComplete?: () => void;
4
+ speed?: number;
5
+ onUpdate?: () => void;
6
+ }): import("react").JSX.Element;
@@ -0,0 +1,21 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useEffect, useState } from 'react';
4
+ export function ProgressiveText({ text, onComplete, speed = 1, onUpdate, }) {
5
+ const [displayedText, setDisplayedText] = useState('');
6
+ const [currentIndex, setCurrentIndex] = useState(0);
7
+ useEffect(() => {
8
+ if (currentIndex < text.length) {
9
+ const timeout = setTimeout(() => {
10
+ setDisplayedText(text.slice(0, currentIndex + 1));
11
+ setCurrentIndex(currentIndex + 1);
12
+ onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(); // Trigger scroll update
13
+ }, speed);
14
+ return () => clearTimeout(timeout);
15
+ }
16
+ else if (onComplete) {
17
+ onComplete();
18
+ }
19
+ }, [currentIndex, text, speed, onComplete, onUpdate]);
20
+ return _jsx("span", { children: displayedText });
21
+ }
@@ -0,0 +1,70 @@
1
+ import type { GraphInfo } from '@robosystems/client';
2
+ import type { ConsoleConfig, SampleQuery } from './types';
3
+ /**
4
+ * Graph-aware console configuration.
5
+ *
6
+ * The console's natural-language agent (the "cypher operator") and its example
7
+ * queries only make sense against the schema of the *selected* graph. A shared
8
+ * SEC repository, a RoboLedger accounting graph, a RoboInvestor portfolio
9
+ * graph, and a generic custom graph each expose completely different nodes —
10
+ * so the welcome examples, sample queries, and MCP prompts must switch with the
11
+ * graph. This module holds one example set per graph kind plus a builder that
12
+ * merges the right set with an app's branding.
13
+ */
14
+ export type GraphExampleKind = 'sec' | 'roboledger' | 'roboinvestor' | 'generic';
15
+ export interface GraphExampleSet {
16
+ /** Header subtitle describing what this graph is. */
17
+ subtitle: string;
18
+ /** Welcome-message description. May contain the token "your graph", which the
19
+ * builder swaps for the graph's display name when available. */
20
+ description: string;
21
+ /** Natural-language prompts shown in the USAGE section. Must be answerable by
22
+ * the cypher operator against THIS graph's schema. */
23
+ naturalLanguageExamples: string[];
24
+ /** `/query <cypher>` one-liners shown in the USAGE section. */
25
+ directQueryExamples: string[];
26
+ /** Full sample queries listed by the `/examples` command. */
27
+ sampleQueries: SampleQuery[];
28
+ /** Questions suggested after MCP setup (answered by the full MCP toolset). */
29
+ mcpExampleQuestions: string[];
30
+ }
31
+ export declare const EXAMPLE_SETS: Record<GraphExampleKind, GraphExampleSet>;
32
+ /**
33
+ * Classify the selected graph so the console can pick the right example set.
34
+ *
35
+ * @param preferredKind Tiebreak used only when a graph carries more than one
36
+ * entity extension (e.g. both roboledger and roboinvestor). Pass the app's
37
+ * own lens (a RoboLedger app passes 'roboledger') so a dual-extension graph
38
+ * shows the examples that fit the app the user is in.
39
+ */
40
+ export declare function getGraphExampleKind(graph: GraphInfo | undefined, preferredKind?: GraphExampleKind): GraphExampleKind;
41
+ /** App-specific branding merged with the graph-derived example set. */
42
+ export interface ConsoleBranding {
43
+ /** Page heading, e.g. "Console" or "RoboInvestor Console". */
44
+ title: string;
45
+ /** Console name in the welcome banner, e.g. "RoboSystems Console". */
46
+ consoleName: string;
47
+ gradientFrom: string;
48
+ gradientTo: string;
49
+ /** Final welcome line, e.g. "How can I help you today?". */
50
+ closingMessage: string;
51
+ mcp: {
52
+ serverName: string;
53
+ packageName: string;
54
+ contextIdFallback: string;
55
+ };
56
+ /** Defaults to "Example Cypher Queries:". */
57
+ examplesLabel?: string;
58
+ /** Defaults to "No graph selected. Please select a graph first.". */
59
+ noSelectionError?: string;
60
+ /** Tiebreak for graphs carrying multiple entity extensions — see
61
+ * {@link getGraphExampleKind}. */
62
+ preferredKind?: GraphExampleKind;
63
+ }
64
+ /** Merge an app's branding with the example set for the given graph. */
65
+ export declare function buildGraphAwareConsoleConfig(graph: GraphInfo | undefined, branding: ConsoleBranding): ConsoleConfig;
66
+ /**
67
+ * React hook: build a console config that tracks the currently selected graph,
68
+ * swapping example sets when the user changes graphs.
69
+ */
70
+ export declare function useGraphAwareConsoleConfig(branding: ConsoleBranding): ConsoleConfig;
@@ -0,0 +1,411 @@
1
+ 'use client';
2
+ import { useMemo } from 'react';
3
+ import { useIsRepository } from '../RepositoryGuard';
4
+ // ── SEC shared repository (base + roboledger reporting; XBRL facts) ──────────
5
+ // Data: XBRL financial facts + filing narrative text for 10,000+ public
6
+ // companies. No prices/macro. Gotchas baked into the queries: anchor on a
7
+ // ticker FIRST, use Element.canonical_concept (not a single qname),
8
+ // has_dimensions:false for consolidated totals, duration_type for
9
+ // income-statement periods vs period_type:'instant' for the balance sheet.
10
+ const SEC_EXAMPLE_SET = {
11
+ subtitle: 'AI financial analyst for 10,000+ public companies',
12
+ description: 'Ask in plain English and an AI analyst does the work — pulling full financial statements, comparing companies side by side, computing ratios and multi-year trends, and searching filing narratives like risk factors and MD&A. Every answer comes back with the data and the Cypher behind it. The graph holds XBRL filings from over 10,000 public companies.',
13
+ naturalLanguageExamples: [
14
+ 'Compare gross margin for NVIDIA, AMD, and Intel over the last three years',
15
+ 'Show Apple’s income statement for the last three fiscal years',
16
+ 'Break down Microsoft’s revenue by segment',
17
+ 'Calculate Tesla’s free cash flow and current ratio for the last two fiscal years',
18
+ 'What are the biggest risk factors in Apple’s latest 10-K?',
19
+ ],
20
+ directQueryExamples: [
21
+ "MATCH (e:Entity {ticker: 'NVDA'}) RETURN e.name, e.cik, e.sic_description, e.fiscal_year_end",
22
+ "MATCH (e:Entity) WHERE e.sic_description CONTAINS 'Semiconductor' RETURN e.ticker, e.name LIMIT 20",
23
+ "MATCH (e:Entity {ticker: 'AAPL'})-[:ENTITY_HAS_REPORT]->(r:Report) RETURN r.form, r.fiscal_year_focus, r.filing_date ORDER BY r.filing_date DESC LIMIT 10",
24
+ ],
25
+ sampleQueries: [
26
+ {
27
+ name: 'Companies by sector',
28
+ query: `MATCH (e:Entity)
29
+ WHERE e.sic_description IS NOT NULL
30
+ RETURN e.sic_description AS sector, count(e) AS company_count
31
+ ORDER BY company_count DESC
32
+ LIMIT 20`,
33
+ },
34
+ {
35
+ name: 'Recent SEC filings',
36
+ query: `MATCH (e:Entity)-[:ENTITY_HAS_REPORT]->(r:Report)
37
+ RETURN e.ticker, e.name, r.form, r.fiscal_year_focus, r.filing_date
38
+ ORDER BY r.filing_date DESC
39
+ LIMIT 25`,
40
+ },
41
+ {
42
+ name: 'NVIDIA annual revenue',
43
+ // canonical_concept normalizes across filers (us-gaap:Revenues vs
44
+ // RevenueFromContractWithCustomer…); has_dimensions:false = consolidated total.
45
+ query: `MATCH (e:Entity {ticker: 'NVDA'})<-[:FACT_HAS_ENTITY]-(f:Fact {has_dimensions: false})-[:FACT_HAS_ELEMENT]->(el:Element),
46
+ (f)-[:FACT_HAS_PERIOD]->(p:Period {duration_type: 'annual'})
47
+ WHERE el.canonical_concept = 'revenue' AND f.numeric_value IS NOT NULL
48
+ RETURN e.ticker, p.end_date, f.numeric_value AS revenue
49
+ ORDER BY p.end_date DESC
50
+ LIMIT 10`,
51
+ },
52
+ {
53
+ name: 'NVIDIA income statement',
54
+ // Pull a whole statement via Structure.canonical_type. Anchor on the
55
+ // Entity FIRST and reach Structure LAST, or the query scans every filing.
56
+ query: `MATCH (e:Entity {ticker: 'NVDA'})<-[:FACT_HAS_ENTITY]-(f:Fact {has_dimensions: false})-[:FACT_HAS_ELEMENT]->(el:Element),
57
+ (f)-[:FACT_HAS_PERIOD]->(p:Period {duration_type: 'annual'}),
58
+ (fs:FactSet)-[:FACT_SET_CONTAINS_FACT]->(f),
59
+ (s:Structure {canonical_type: 'income_statement'})-[:STRUCTURE_HAS_FACT_SET]->(fs)
60
+ WHERE f.numeric_value IS NOT NULL
61
+ RETURN DISTINCT el.qname, f.numeric_value AS value, p.end_date
62
+ ORDER BY p.end_date DESC
63
+ LIMIT 40`,
64
+ },
65
+ {
66
+ name: 'Apple balance sheet snapshot',
67
+ // Balance-sheet items are instantaneous — filter Period {period_type:'instant'}.
68
+ query: `MATCH (e:Entity {ticker: 'AAPL'})<-[:FACT_HAS_ENTITY]-(f:Fact {has_dimensions: false})-[:FACT_HAS_ELEMENT]->(el:Element),
69
+ (f)-[:FACT_HAS_PERIOD]->(p:Period {period_type: 'instant'})
70
+ WHERE el.canonical_concept IN ['total_assets', 'total_liabilities', 'stockholders_equity']
71
+ AND f.numeric_value IS NOT NULL
72
+ RETURN el.canonical_concept AS line_item, f.numeric_value AS value, p.end_date
73
+ ORDER BY p.end_date DESC, line_item
74
+ LIMIT 15`,
75
+ },
76
+ {
77
+ name: 'Compare net income across mega-cap tech',
78
+ query: `MATCH (e:Entity)<-[:FACT_HAS_ENTITY]-(f:Fact {has_dimensions: false})-[:FACT_HAS_ELEMENT]->(el:Element),
79
+ (f)-[:FACT_HAS_PERIOD]->(p:Period {duration_type: 'annual'})
80
+ WHERE e.ticker IN ['AAPL', 'MSFT', 'GOOGL', 'NVDA', 'META']
81
+ AND el.canonical_concept = 'net_income'
82
+ AND f.numeric_value IS NOT NULL
83
+ RETURN e.ticker, p.end_date, f.numeric_value AS net_income
84
+ ORDER BY p.end_date DESC, net_income DESC
85
+ LIMIT 25`,
86
+ },
87
+ {
88
+ name: 'NVIDIA gross margin trend',
89
+ // Pivot two concepts per period, then compute the ratio in Cypher.
90
+ query: `MATCH (e:Entity {ticker: 'NVDA'})<-[:FACT_HAS_ENTITY]-(f:Fact {has_dimensions: false})-[:FACT_HAS_ELEMENT]->(el:Element),
91
+ (f)-[:FACT_HAS_PERIOD]->(p:Period {duration_type: 'annual'})
92
+ WHERE el.canonical_concept IN ['revenue', 'gross_profit'] AND f.numeric_value IS NOT NULL
93
+ WITH p.end_date AS period,
94
+ max(CASE WHEN el.canonical_concept = 'revenue' THEN f.numeric_value END) AS revenue,
95
+ max(CASE WHEN el.canonical_concept = 'gross_profit' THEN f.numeric_value END) AS gross_profit
96
+ WHERE revenue IS NOT NULL AND gross_profit IS NOT NULL
97
+ RETURN period, gross_profit, revenue, gross_profit / revenue AS gross_margin
98
+ ORDER BY period DESC
99
+ LIMIT 10`,
100
+ },
101
+ {
102
+ name: 'NVIDIA revenue by segment (dimensional)',
103
+ // has_dimensions:true exposes the segment/geography breakdowns.
104
+ query: `MATCH (e:Entity {ticker: 'NVDA'})<-[:FACT_HAS_ENTITY]-(f:Fact {has_dimensions: true})-[:FACT_HAS_ELEMENT]->(el:Element),
105
+ (f)-[:FACT_HAS_DIMENSION]->(d:Dimension),
106
+ (f)-[:FACT_HAS_PERIOD]->(p:Period {duration_type: 'annual'})
107
+ WHERE el.canonical_concept = 'revenue' AND f.numeric_value IS NOT NULL
108
+ RETURN d.member AS segment, f.numeric_value AS value, p.end_date
109
+ ORDER BY p.end_date DESC, value DESC
110
+ LIMIT 20`,
111
+ },
112
+ ],
113
+ mcpExampleQuestions: [
114
+ 'Compare operating margin for NVIDIA, AMD, and Intel over five years',
115
+ 'Summarize the key risk factors in Apple’s latest 10-K',
116
+ 'Show Microsoft’s diluted EPS and free cash flow trend',
117
+ ],
118
+ };
119
+ // ── RoboLedger entity graph (double-entry ledger + reporting) ────────────────
120
+ // Data: the general-ledger spine Transaction -> Entry -> LineItem (each
121
+ // LineItem posts to an Element/account), plus the XBRL reports generated from
122
+ // it. The one rule to remember: count/sum only LIVE rows via the materialized
123
+ // `is_live` boolean (Entry/LineItem/Transaction), or cancelled/replaced rows
124
+ // double-count.
125
+ const ROBOLEDGER_EXAMPLE_SET = {
126
+ subtitle: 'AI analyst for your accounting ledger',
127
+ description: 'Ask in plain English and an AI analyst queries your ledger — transactions, journal entries, the trial balance, and the financial statements built from them. Every answer comes back with the data and the Cypher behind it.',
128
+ naturalLanguageExamples: [
129
+ 'Show me the trial balance',
130
+ 'What are my largest expenses by category?',
131
+ 'List the most recent journal entries',
132
+ 'How much did I spend last month?',
133
+ ],
134
+ directQueryExamples: [
135
+ 'MATCH (e:Entity)-[:ENTITY_HAS_TRANSACTION]->(t:Transaction) WHERE t.is_live RETURN t.date, t.number, t.description, t.amount ORDER BY t.date DESC LIMIT 15',
136
+ 'MATCH (en:Entry) WHERE en.is_live RETURN en.number, en.memo, en.posting_date, en.type ORDER BY en.posting_date DESC LIMIT 15',
137
+ 'MATCH (e:Entity) RETURN e.name, e.entity_type, e.industry',
138
+ ],
139
+ sampleQueries: [
140
+ {
141
+ name: 'Trial balance',
142
+ // Sum only live line items; each posts to an Element (account) via
143
+ // LINE_ITEM_RELATES_TO_ELEMENT.
144
+ query: `MATCH (en:Entry)-[:ENTRY_HAS_LINE_ITEM]->(li:LineItem)-[:LINE_ITEM_RELATES_TO_ELEMENT]->(el:Element)
145
+ WHERE li.is_live
146
+ RETURN el.qname AS account, el.name,
147
+ sum(li.debit_amount) AS total_debits,
148
+ sum(li.credit_amount) AS total_credits
149
+ ORDER BY total_debits DESC
150
+ LIMIT 25`,
151
+ },
152
+ {
153
+ name: 'Recent transactions',
154
+ query: `MATCH (e:Entity)-[:ENTITY_HAS_TRANSACTION]->(t:Transaction)
155
+ WHERE t.is_live
156
+ RETURN t.date, t.number, t.description, t.type, t.amount
157
+ ORDER BY t.date DESC
158
+ LIMIT 25`,
159
+ },
160
+ {
161
+ name: 'Recent journal entries',
162
+ query: `MATCH (t:Transaction)-[:TRANSACTION_HAS_ENTRY]->(en:Entry)
163
+ WHERE en.is_live
164
+ RETURN t.number AS txn, t.description, en.number AS entry, en.memo, en.posting_date, en.type
165
+ ORDER BY en.posting_date DESC
166
+ LIMIT 25`,
167
+ },
168
+ {
169
+ name: 'Expenses by category',
170
+ query: `MATCH (e:Entity)-[:ENTITY_HAS_TRANSACTION]->(t:Transaction)
171
+ WHERE t.is_live AND t.category IS NOT NULL
172
+ RETURN t.category, count(t) AS transactions, sum(t.amount) AS total
173
+ ORDER BY total DESC
174
+ LIMIT 20`,
175
+ },
176
+ {
177
+ name: 'Entry lines by account',
178
+ query: `MATCH (t:Transaction)-[:TRANSACTION_HAS_ENTRY]->(en:Entry)-[:ENTRY_HAS_LINE_ITEM]->(li:LineItem)-[:LINE_ITEM_RELATES_TO_ELEMENT]->(el:Element)
179
+ WHERE li.is_live
180
+ RETURN el.name AS account, count(li) AS line_items,
181
+ sum(li.debit_amount) AS debits, sum(li.credit_amount) AS credits
182
+ ORDER BY line_items DESC
183
+ LIMIT 15`,
184
+ },
185
+ {
186
+ name: 'Line items with dimensional breakdowns',
187
+ query: `MATCH (li:LineItem {has_dimensions: true})-[:LINE_ITEM_HAS_DIMENSION]->(d:Dimension)
188
+ WHERE li.is_live
189
+ RETURN d.axis, d.member, count(li) AS line_item_count
190
+ ORDER BY line_item_count DESC
191
+ LIMIT 15`,
192
+ },
193
+ {
194
+ name: 'Reports generated',
195
+ query: `MATCH (e:Entity)-[:ENTITY_HAS_REPORT]->(r:Report)
196
+ RETURN e.name, r.form, r.fiscal_year_focus, r.filing_date
197
+ ORDER BY r.filing_date DESC
198
+ LIMIT 20`,
199
+ },
200
+ ],
201
+ mcpExampleQuestions: [
202
+ 'Show me the trial balance for this entity',
203
+ 'What are my largest expenses this quarter?',
204
+ 'Summarize the most recent journal entries',
205
+ ],
206
+ };
207
+ // ── RoboInvestor entity graph (portfolios / positions / securities) ──────────
208
+ // Data: Entity -> Portfolio -> Position -> Security, and Entity -> Security
209
+ // (issuance). Position carries cost_basis and current_value, so gains and
210
+ // allocation are computed in Cypher. Trade/Benchmark/MarketData exist in the
211
+ // schema but aren't populated yet — keep examples off them.
212
+ const ROBOINVESTOR_EXAMPLE_SET = {
213
+ subtitle: 'AI analyst for your investment portfolios',
214
+ description: 'Ask in plain English and an AI analyst queries your portfolios, positions, and securities — holdings, cost basis vs. current value, allocation, and unrealized gains. Every answer comes back with the data and the Cypher behind it.',
215
+ naturalLanguageExamples: [
216
+ 'What is the current value of my portfolio?',
217
+ 'Show my largest positions by market value',
218
+ 'Which holdings have the biggest unrealized gains?',
219
+ 'Break down my holdings by security type',
220
+ ],
221
+ directQueryExamples: [
222
+ 'MATCH (p:Portfolio) RETURN p.name, p.strategy, p.base_currency',
223
+ 'MATCH (p:Portfolio)-[:PORTFOLIO_HAS_POSITION]->(pos:Position) RETURN p.name, count(pos) AS positions ORDER BY positions DESC',
224
+ 'MATCH (s:Security) RETURN s.ticker, s.name, s.security_type LIMIT 20',
225
+ ],
226
+ sampleQueries: [
227
+ {
228
+ name: 'Portfolio value',
229
+ query: `MATCH (p:Portfolio)-[:PORTFOLIO_HAS_POSITION]->(pos:Position)
230
+ RETURN p.name,
231
+ count(pos) AS positions,
232
+ sum(pos.cost_basis) AS total_cost,
233
+ sum(pos.current_value) AS total_value
234
+ ORDER BY total_value DESC`,
235
+ },
236
+ {
237
+ name: 'Holdings by current value',
238
+ query: `MATCH (p:Portfolio)-[:PORTFOLIO_HAS_POSITION]->(pos:Position)-[:POSITION_IN_SECURITY]->(s:Security)
239
+ RETURN p.name, s.ticker, s.name, pos.quantity, pos.cost_basis, pos.current_value
240
+ ORDER BY pos.current_value DESC
241
+ LIMIT 25`,
242
+ },
243
+ {
244
+ name: 'Unrealized gains',
245
+ query: `MATCH (p:Portfolio)-[:PORTFOLIO_HAS_POSITION]->(pos:Position)-[:POSITION_IN_SECURITY]->(s:Security)
246
+ WHERE pos.cost_basis IS NOT NULL AND pos.current_value IS NOT NULL
247
+ RETURN s.ticker, s.name, pos.cost_basis, pos.current_value,
248
+ pos.current_value - pos.cost_basis AS unrealized_gain
249
+ ORDER BY unrealized_gain DESC
250
+ LIMIT 20`,
251
+ },
252
+ {
253
+ name: 'Allocation by security type',
254
+ query: `MATCH (pos:Position)-[:POSITION_IN_SECURITY]->(s:Security)
255
+ RETURN s.security_type,
256
+ count(pos) AS positions,
257
+ sum(pos.current_value) AS total_value
258
+ ORDER BY total_value DESC`,
259
+ },
260
+ {
261
+ name: 'Securities issued by entity',
262
+ query: `MATCH (e:Entity)-[:ENTITY_ISSUES_SECURITY]->(s:Security)
263
+ RETURN e.name, s.ticker, s.name, s.security_type
264
+ ORDER BY s.ticker
265
+ LIMIT 25`,
266
+ },
267
+ ],
268
+ mcpExampleQuestions: [
269
+ 'What is the current value of my portfolio and its total cost basis?',
270
+ 'Show my largest positions by market value',
271
+ 'Which holdings have the biggest unrealized gains?',
272
+ ],
273
+ };
274
+ // ── Generic custom graph (no known schema extensions) ────────────────────────
275
+ // No SEC/ledger/portfolio assumptions — the operator gets only the live schema
276
+ // and read-only Cypher, so the examples are structure-discovery oriented.
277
+ const GENERIC_EXAMPLE_SET = {
278
+ subtitle: 'AI analyst for your graph database',
279
+ description: 'Ask in plain English and an AI analyst explores your graph — discovering the node types, relationships, and patterns in your data, and returning the results with the Cypher behind every answer.',
280
+ naturalLanguageExamples: [
281
+ 'What types of nodes are in the graph?',
282
+ 'How are the nodes connected?',
283
+ 'Show me a sample of the data',
284
+ 'Which nodes have the most connections?',
285
+ ],
286
+ directQueryExamples: [
287
+ 'MATCH (n) RETURN labels(n), count(n) ORDER BY count(n) DESC',
288
+ 'MATCH ()-[r]->() RETURN type(r), count(r) ORDER BY count(r) DESC',
289
+ 'MATCH (n) RETURN n LIMIT 10',
290
+ ],
291
+ sampleQueries: [
292
+ {
293
+ name: 'Node types',
294
+ query: `MATCH (n)
295
+ RETURN labels(n) AS label, count(n) AS count
296
+ ORDER BY count DESC`,
297
+ },
298
+ {
299
+ name: 'Relationship types',
300
+ query: `MATCH ()-[r]->()
301
+ RETURN type(r) AS relationship, count(r) AS count
302
+ ORDER BY count DESC`,
303
+ },
304
+ {
305
+ name: 'Sample nodes',
306
+ query: `MATCH (n)
307
+ RETURN n
308
+ LIMIT 25`,
309
+ },
310
+ {
311
+ name: 'Node connections',
312
+ query: `MATCH (a)-[r]->(b)
313
+ RETURN labels(a) AS from_type, type(r) AS relationship, labels(b) AS to_type, count(*) AS count
314
+ ORDER BY count DESC
315
+ LIMIT 15`,
316
+ },
317
+ ],
318
+ mcpExampleQuestions: [
319
+ 'What data is in my graph?',
320
+ 'Show me the most connected nodes',
321
+ 'Summarize the graph structure',
322
+ ],
323
+ };
324
+ export const EXAMPLE_SETS = {
325
+ sec: SEC_EXAMPLE_SET,
326
+ roboledger: ROBOLEDGER_EXAMPLE_SET,
327
+ roboinvestor: ROBOINVESTOR_EXAMPLE_SET,
328
+ generic: GENERIC_EXAMPLE_SET,
329
+ };
330
+ /**
331
+ * Classify the selected graph so the console can pick the right example set.
332
+ *
333
+ * @param preferredKind Tiebreak used only when a graph carries more than one
334
+ * entity extension (e.g. both roboledger and roboinvestor). Pass the app's
335
+ * own lens (a RoboLedger app passes 'roboledger') so a dual-extension graph
336
+ * shows the examples that fit the app the user is in.
337
+ */
338
+ export function getGraphExampleKind(graph, preferredKind) {
339
+ var _a;
340
+ if (!graph)
341
+ return preferredKind !== null && preferredKind !== void 0 ? preferredKind : 'generic';
342
+ if (graph.isRepository && graph.repositoryType === 'sec')
343
+ return 'sec';
344
+ const extensions = (_a = graph.schemaExtensions) !== null && _a !== void 0 ? _a : [];
345
+ const hasInvestor = extensions.includes('roboinvestor');
346
+ const hasLedger = extensions.includes('roboledger');
347
+ if (hasInvestor && hasLedger) {
348
+ return preferredKind === 'roboledger' || preferredKind === 'roboinvestor'
349
+ ? preferredKind
350
+ : 'roboinvestor';
351
+ }
352
+ if (hasInvestor)
353
+ return 'roboinvestor';
354
+ if (hasLedger)
355
+ return 'roboledger';
356
+ return 'generic';
357
+ }
358
+ /** Merge an app's branding with the example set for the given graph. */
359
+ export function buildGraphAwareConsoleConfig(graph, branding) {
360
+ var _a, _b, _c;
361
+ const kind = getGraphExampleKind(graph, branding.preferredKind);
362
+ const set = EXAMPLE_SETS[kind];
363
+ const isRepository = (_a = graph === null || graph === void 0 ? void 0 : graph.isRepository) !== null && _a !== void 0 ? _a : false;
364
+ const graphName = graph === null || graph === void 0 ? void 0 : graph.graphName;
365
+ // Personalize the description with the graph's name where the set opts in.
366
+ const description = graphName && set.description.includes('your graph')
367
+ ? set.description.replace('your graph', `"${graphName}"`)
368
+ : set.description;
369
+ return {
370
+ header: {
371
+ title: branding.title,
372
+ subtitle: set.subtitle,
373
+ gradientFrom: branding.gradientFrom,
374
+ gradientTo: branding.gradientTo,
375
+ },
376
+ welcome: {
377
+ consoleName: branding.consoleName,
378
+ description,
379
+ contextLabel: isRepository ? 'Repository' : 'Graph',
380
+ naturalLanguageExamples: set.naturalLanguageExamples,
381
+ directQueryExamples: set.directQueryExamples,
382
+ closingMessage: branding.closingMessage,
383
+ },
384
+ mcp: {
385
+ serverName: branding.mcp.serverName,
386
+ packageName: branding.mcp.packageName,
387
+ exampleQuestions: set.mcpExampleQuestions,
388
+ contextIdFallback: branding.mcp.contextIdFallback,
389
+ },
390
+ sampleQueries: set.sampleQueries,
391
+ examplesLabel: (_b = branding.examplesLabel) !== null && _b !== void 0 ? _b : 'Example Cypher Queries:',
392
+ noSelectionError: (_c = branding.noSelectionError) !== null && _c !== void 0 ? _c : 'No graph selected. Please select a graph first.',
393
+ };
394
+ }
395
+ /**
396
+ * React hook: build a console config that tracks the currently selected graph,
397
+ * swapping example sets when the user changes graphs.
398
+ */
399
+ export function useGraphAwareConsoleConfig(branding) {
400
+ const { currentGraph } = useIsRepository();
401
+ return useMemo(() => buildGraphAwareConsoleConfig(currentGraph, branding),
402
+ // eslint-disable-next-line react-hooks/exhaustive-deps
403
+ [
404
+ currentGraph === null || currentGraph === void 0 ? void 0 : currentGraph.graphId,
405
+ currentGraph === null || currentGraph === void 0 ? void 0 : currentGraph.isRepository,
406
+ currentGraph === null || currentGraph === void 0 ? void 0 : currentGraph.repositoryType,
407
+ currentGraph === null || currentGraph === void 0 ? void 0 : currentGraph.schemaExtensions,
408
+ currentGraph === null || currentGraph === void 0 ? void 0 : currentGraph.graphName,
409
+ branding,
410
+ ]);
411
+ }
@@ -0,0 +1,6 @@
1
+ export { ConsoleContent } from './ConsoleContent';
2
+ export { ConsoleMarkdown } from './ConsoleMarkdown';
3
+ export { EXAMPLE_SETS, buildGraphAwareConsoleConfig, getGraphExampleKind, useGraphAwareConsoleConfig, } from './graphAwareConfig';
4
+ export type { ConsoleBranding, GraphExampleKind, GraphExampleSet, } from './graphAwareConfig';
5
+ export { ProgressiveText } from './ProgressiveText';
6
+ export type { ConsoleCommandContext, ConsoleConfig, ConsoleExtraCommand, ConsoleHeaderConfig, ConsoleMcpConfig, ConsoleWelcomeConfig, SampleQuery, TerminalMessage, } from './types';
@@ -0,0 +1,4 @@
1
+ export { ConsoleContent } from './ConsoleContent';
2
+ export { ConsoleMarkdown } from './ConsoleMarkdown';
3
+ export { EXAMPLE_SETS, buildGraphAwareConsoleConfig, getGraphExampleKind, useGraphAwareConsoleConfig, } from './graphAwareConfig';
4
+ export { ProgressiveText } from './ProgressiveText';
@@ -0,0 +1,84 @@
1
+ export interface SampleQuery {
2
+ name: string;
3
+ query: string;
4
+ }
5
+ export interface ConsoleWelcomeConfig {
6
+ /** e.g. "RoboSystems Console", "RoboLedger Console" */
7
+ consoleName: string;
8
+ /** e.g. "Claude powered interactive graph database console" */
9
+ description: string;
10
+ /** Label for the context identifier: "Graph" | "Portfolio" */
11
+ contextLabel: string;
12
+ /** Example natural-language prompts shown in USAGE section */
13
+ naturalLanguageExamples: string[];
14
+ /** Example /query Cypher lines shown in USAGE section */
15
+ directQueryExamples: string[];
16
+ /** Final line of the welcome message, e.g. "How can I help you today?" */
17
+ closingMessage: string;
18
+ }
19
+ export interface ConsoleHeaderConfig {
20
+ /** Page heading, e.g. "Console" */
21
+ title: string;
22
+ /** Subtitle below heading */
23
+ subtitle: string;
24
+ /** Tailwind gradient-from class, e.g. "from-blue-500" */
25
+ gradientFrom: string;
26
+ /** Tailwind gradient-to class, e.g. "to-purple-600" */
27
+ gradientTo: string;
28
+ }
29
+ export interface ConsoleMcpConfig {
30
+ /** MCP server name in the JSON config, e.g. "robosystems" */
31
+ serverName: string;
32
+ /** npm package name, e.g. "@robosystems/mcp" */
33
+ packageName: string;
34
+ /** Example questions shown after MCP setup */
35
+ exampleQuestions: string[];
36
+ /** Fallback text for graph ID placeholder, e.g. "your_graph_id" */
37
+ contextIdFallback: string;
38
+ }
39
+ export interface ConsoleCommandContext {
40
+ addSystemMessage: (content: string, animate?: boolean) => void;
41
+ addErrorMessage: (content: string) => void;
42
+ graphId: string | null;
43
+ }
44
+ export interface ConsoleExtraCommand {
45
+ /** The slash command string, e.g. "/api-keys" */
46
+ command: string;
47
+ /** Handler called when the command is invoked */
48
+ handler: (context: ConsoleCommandContext) => void | Promise<void>;
49
+ }
50
+ export interface ConsoleConfig {
51
+ welcome: ConsoleWelcomeConfig;
52
+ header: ConsoleHeaderConfig;
53
+ mcp: ConsoleMcpConfig;
54
+ sampleQueries: SampleQuery[];
55
+ /** Label for the /examples output heading, e.g. "Example Cypher Queries:" */
56
+ examplesLabel: string;
57
+ /** Error message when no graph/portfolio is selected */
58
+ noSelectionError: string;
59
+ /** Extra slash commands beyond the built-in set */
60
+ extraCommands?: ConsoleExtraCommand[];
61
+ }
62
+ export interface TerminalMessage {
63
+ id: string;
64
+ type: 'system' | 'user' | 'result' | 'error';
65
+ content: string;
66
+ timestamp: Date;
67
+ /** Tabular result rows rendered below the message. */
68
+ data?: any;
69
+ /** Generated Cypher for a natural-language result, shown with a Run button. */
70
+ cypher?: string;
71
+ isAnimating?: boolean;
72
+ /**
73
+ * Render `content` as GitHub-flavored markdown (headings, bold, tables)
74
+ * rather than raw monospace text. Set for natural-language answers, which the
75
+ * backend now returns as enriched markdown.
76
+ */
77
+ markdown?: boolean;
78
+ /**
79
+ * Query stats (e.g. "Query completed in 123ms\nRows returned: 40") shown as a
80
+ * muted footer below a markdown answer, kept out of `content` so its line
81
+ * breaks survive markdown rendering.
82
+ */
83
+ footer?: string;
84
+ }
@@ -0,0 +1 @@
1
+ export {};