@pillar-ai/sdk 0.1.24 → 0.1.26

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 (68) hide show
  1. package/dist/actions/definitions/analytics.d.ts +18 -0
  2. package/dist/actions/definitions/content.d.ts +40 -0
  3. package/dist/actions/definitions/index.d.ts +26 -0
  4. package/dist/actions/definitions/navigation.d.ts +65 -0
  5. package/dist/actions/definitions/settings.d.ts +162 -0
  6. package/dist/actions/definitions/sources.d.ts +44 -0
  7. package/dist/actions/definitions/support.d.ts +15 -0
  8. package/dist/actions/definitions/team.d.ts +120 -0
  9. package/dist/api/ag-ui-adapter.d.ts +76 -0
  10. package/dist/api/ag-ui-bridge.d.ts +49 -0
  11. package/dist/api/ag-ui-client.d.ts +102 -0
  12. package/dist/api/ag-ui-handler.d.ts +89 -0
  13. package/dist/api/client.d.ts +14 -0
  14. package/dist/button/FloatingButton.d.ts +44 -0
  15. package/dist/cli/sync.js +37 -5
  16. package/dist/components/Button/EdgeTrigger.d.ts +1 -0
  17. package/dist/components/Button/FloatingButton.d.ts +46 -0
  18. package/dist/components/DevTools/DOMScannerPreview.d.ts +21 -0
  19. package/dist/components/Progress/AGUIProgress.d.ts +15 -0
  20. package/dist/components/ToolDebugPanel/ToolDebugPanel.d.ts +21 -0
  21. package/dist/components/ToolDebugPanel/index.d.ts +1 -0
  22. package/dist/components/Tooltips/Tooltip.d.ts +46 -0
  23. package/dist/components/Tooltips/TooltipManager.d.ts +41 -0
  24. package/dist/components/Tooltips/index.d.ts +6 -0
  25. package/dist/components/Tooltips/styles.d.ts +5 -0
  26. package/dist/components/Views/ArticleChatView.d.ts +9 -0
  27. package/dist/components/Views/ArticleView.d.ts +10 -0
  28. package/dist/components/Views/CategoryView.d.ts +11 -0
  29. package/dist/components/Views/DeveloperView.d.ts +6 -0
  30. package/dist/components/Views/SearchView.d.ts +10 -0
  31. package/dist/components/shared/ArticleCard.d.ts +17 -0
  32. package/dist/components/shared/CategoryCard.d.ts +17 -0
  33. package/dist/content/extensions/AccordionNode.d.ts +10 -0
  34. package/dist/content/extensions/CalloutNode.d.ts +11 -0
  35. package/dist/content/extensions/index.d.ts +5 -0
  36. package/dist/content/index.d.ts +5 -0
  37. package/dist/content/renderer.d.ts +24 -0
  38. package/dist/core/Pillar.d.ts +45 -1
  39. package/dist/core/config.d.ts +1 -1
  40. package/dist/core/events.d.ts +10 -1
  41. package/dist/index.d.ts +1 -1
  42. package/dist/panel/Panel.d.ts +53 -0
  43. package/dist/panel/PanelUI.d.ts +43 -0
  44. package/dist/panel/components/ArticleCard.d.ts +10 -0
  45. package/dist/panel/components/CategoryCard.d.ts +10 -0
  46. package/dist/panel/components/ChatInput.d.ts +36 -0
  47. package/dist/panel/components/Header.d.ts +16 -0
  48. package/dist/panel/components/SearchInput.d.ts +11 -0
  49. package/dist/panel/styles.d.ts +5 -0
  50. package/dist/panel/views/ArticleView.d.ts +21 -0
  51. package/dist/panel/views/CategoryView.d.ts +20 -0
  52. package/dist/panel/views/ChatView.d.ts +30 -0
  53. package/dist/panel/views/HomeView.d.ts +18 -0
  54. package/dist/panel/views/SearchView.d.ts +22 -0
  55. package/dist/pillar.esm.js +1 -1
  56. package/dist/store/developer.d.ts +19 -0
  57. package/dist/store/panel.d.ts +3 -2
  58. package/dist/store/tooltips.d.ts +21 -0
  59. package/dist/tooltips/Tooltip.d.ts +63 -0
  60. package/dist/tooltips/TooltipManager.d.ts +42 -0
  61. package/dist/tooltips/styles.d.ts +5 -0
  62. package/dist/ui/config.d.ts +96 -0
  63. package/dist/ui/executor.d.ts +75 -0
  64. package/dist/ui/index.d.ts +11 -0
  65. package/dist/ui/scanner.d.ts +105 -0
  66. package/dist/ui/types.d.ts +293 -0
  67. package/dist/utils/markdown.d.ts +9 -0
  68. package/package.json +4 -1
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Content rendering utilities for the SDK
3
+ */
4
+ export { renderArticleContent, renderTipTapContent, isJSONContent, } from './renderer';
5
+ export type { CalloutType } from './extensions';
@@ -0,0 +1,24 @@
1
+ /**
2
+ * TipTap Content Renderer
3
+ * Converts TipTap JSON content to HTML for display in the SDK panel
4
+ */
5
+ import type { JSONContent } from '@tiptap/core';
6
+ /**
7
+ * Check if content is TipTap JSON format (has a 'type' property)
8
+ */
9
+ export declare function isJSONContent(content: unknown): content is JSONContent;
10
+ /**
11
+ * Render TipTap JSON content to HTML
12
+ *
13
+ * @param content - TipTap JSON content object
14
+ * @returns HTML string
15
+ */
16
+ export declare function renderTipTapContent(content: JSONContent): string;
17
+ /**
18
+ * Render article content to HTML
19
+ * Handles both TipTap JSON and legacy HTML string content
20
+ *
21
+ * @param content - TipTap JSON content or HTML string
22
+ * @returns HTML string
23
+ */
24
+ export declare function renderArticleContent(content: JSONContent | string | null | undefined): string;
@@ -2,7 +2,7 @@
2
2
  * Main Pillar SDK Class
3
3
  * Entry point for all SDK functionality
4
4
  */
5
- import { type ToolSchema } from "../tools";
5
+ import { type ToolSchema, type ToolType } from "../tools";
6
6
  import { type PillarConfig, type ResolvedConfig, type ThemeConfig } from "./config";
7
7
  import { type Context, type Suggestion, type UserProfile } from "./context";
8
8
  import { type CardRenderer, type PillarEvents, type TaskExecutePayload } from "./events";
@@ -20,7 +20,29 @@ export interface ChatContext {
20
20
  content: string;
21
21
  }>;
22
22
  }
23
+ /**
24
+ * Tool information for the debug panel.
25
+ */
26
+ export interface ToolInfo {
27
+ /** Tool name (unique identifier) */
28
+ name: string;
29
+ /** Human-readable description */
30
+ description: string;
31
+ /** Tool type (navigate, query, trigger_tool, etc.) */
32
+ type?: ToolType;
33
+ /** JSON Schema for input parameters */
34
+ inputSchema?: {
35
+ type: "object";
36
+ properties: Record<string, unknown>;
37
+ required?: string[];
38
+ };
39
+ /** Where this tool was registered from */
40
+ source: "defined" | "registered" | "registry";
41
+ /** Whether the tool has an execute handler */
42
+ hasHandler: boolean;
43
+ }
23
44
  export declare class Pillar {
45
+ static readonly version: string;
24
46
  private static instance;
25
47
  private _state;
26
48
  private _config;
@@ -112,6 +134,28 @@ export declare class Pillar {
112
134
  * Clear debug log entries.
113
135
  */
114
136
  clearDebugLog(): void;
137
+ /**
138
+ * Get all registered tools for debugging.
139
+ * Returns tools from all sources: defineTool(), registerTool(), and onTask() handlers.
140
+ *
141
+ * Only available when debug mode is enabled.
142
+ *
143
+ * @returns Array of tool information objects
144
+ */
145
+ getTools(): ToolInfo[];
146
+ /**
147
+ * Execute a tool by name for debugging purposes.
148
+ * Only available when debug mode is enabled.
149
+ *
150
+ * @param toolName - Name of the tool to execute
151
+ * @param input - Input parameters to pass to the tool
152
+ * @returns Promise resolving to the tool's result or error
153
+ */
154
+ executeToolForDebug(toolName: string, input: Record<string, unknown>): Promise<{
155
+ success: boolean;
156
+ result?: unknown;
157
+ error?: string;
158
+ }>;
115
159
  /**
116
160
  * Subscribe to SDK events
117
161
  */
@@ -17,7 +17,7 @@ export interface SidebarTabConfig {
17
17
  enabled: boolean;
18
18
  order: number;
19
19
  /** Preset icon for this tab */
20
- icon?: 'help' | 'support' | 'settings' | 'feedback' | 'chat' | 'calendar' | 'mail';
20
+ icon?: 'help' | 'support' | 'settings' | 'feedback' | 'chat' | 'calendar' | 'mail' | 'tools';
21
21
  }
22
22
  export declare const DEFAULT_SIDEBAR_TABS: SidebarTabConfig[];
23
23
  /**
@@ -27,7 +27,11 @@ export interface TaskExecutePayload {
27
27
  * Callbacks provided to custom card renderers.
28
28
  */
29
29
  export interface CardCallbacks {
30
- /** Called when user confirms the action. Pass modified data if needed. */
30
+ /**
31
+ * Called when user confirms the action. Pass modified data if needed.
32
+ * WARNING: Data passed here flows through the SDK pipeline (telemetry,
33
+ * agent context, logs). Never include secrets, tokens, or PII.
34
+ */
31
35
  onConfirm: (modifiedData?: Record<string, unknown>) => void;
32
36
  /** Called when user cancels the action */
33
37
  onCancel: () => void;
@@ -234,6 +238,11 @@ export interface PillarEvents {
234
238
  tabId: string;
235
239
  label: string;
236
240
  };
241
+ /** A tool was registered or unregistered. */
242
+ "tools:change": {
243
+ action: "add" | "remove";
244
+ name: string;
245
+ };
237
246
  /** @deprecated Use 'sidebar:click' instead. Will be removed in next major version. */
238
247
  "support:request": {
239
248
  tabId: string;
package/dist/index.d.ts CHANGED
@@ -19,7 +19,7 @@
19
19
  * });
20
20
  */
21
21
  export { EventEmitter, type CardCallbacks, type CardRenderer, type PillarEvents, type TaskExecutePayload, } from "./core/events";
22
- export { Pillar, type ChatContext, type PillarState } from "./core/Pillar";
22
+ export { Pillar, type ChatContext, type PillarState, type ToolInfo } from "./core/Pillar";
23
23
  export { DEFAULT_SIDEBAR_TABS, type DOMScanningConfig, type EdgeTriggerConfig, type InteractionHighlightConfig, type MobileTriggerConfig, type MobileTriggerIcon, type MobileTriggerPosition, type MobileTriggerSize, type PanelConfig, type PanelMode, type PanelPosition, type PillarConfig, type ResolvedConfig, type ResolvedDOMScanningConfig, type ResolvedInteractionHighlightConfig, type ResolvedMobileTriggerConfig, type ResolvedPanelConfig, type ResolvedSuggestionsConfig, type ResolvedThemeConfig, type SidebarTabConfig, type SuggestionsConfig, type TextSelectionConfig, type ThemeColors, type ThemeConfig, type ThemeMode, type UrlParamsConfig, } from "./core/config";
24
24
  export { type AssistantContext, type Context, type Suggestion, type UserProfile, } from "./core/context";
25
25
  export { clearRegistry, getToolCount, getToolDefinition, getToolNames, getClientInfo, getHandler, getManifest, hasTool, setClientInfo, type ToolDataSchema, type ToolDataSchemaProperty, type ToolDataType, type ToolDefinition, type ToolDefinitions, type ToolManifest, type ToolManifestEntry, type ToolNames, type ToolType, type ToolTypeDataMap, type ToolExecuteResult, type ToolSchema, type ClientInfo, type CopyTextData, type ExternalLinkData, type InlineUIData, type NavigateToolData, type TriggerToolData, type QueryToolData, type Platform, type SyncToolDefinition, type SyncToolDefinitions, type TypedOnTask, type TypedPillarMethods, type TypedTaskHandler, getActionCount, getActionDefinition, getActionNames, hasAction, type ActionDataSchema, type ActionDataSchemaProperty, type ActionDataType, type ActionDefinition, type ActionDefinitions, type ActionManifest, type ActionManifestEntry, type ActionNames, type ActionType, type ActionTypeDataMap, type ActionResult, type ActionSchema, type NavigateActionData, type TriggerActionData, type QueryActionData, type SyncActionDefinition, type SyncActionDefinitions, } from "./tools";
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Help Panel Container
3
+ * Shadow DOM container for the help panel
4
+ */
5
+ import type { EventEmitter } from '../core/events';
6
+ import type { ResolvedConfig } from '../core/config';
7
+ import type { APIClient } from '../api/client';
8
+ export declare class Panel {
9
+ private config;
10
+ private api;
11
+ private events;
12
+ private host;
13
+ private shadow;
14
+ private backdrop;
15
+ private panelElement;
16
+ private panelUI;
17
+ private _isOpen;
18
+ constructor(config: ResolvedConfig, api: APIClient, events: EventEmitter);
19
+ /**
20
+ * Whether the panel is currently open
21
+ */
22
+ get isOpen(): boolean;
23
+ /**
24
+ * Initialize the panel
25
+ */
26
+ init(): Promise<void>;
27
+ /**
28
+ * Open the panel
29
+ */
30
+ open(options?: {
31
+ view?: string;
32
+ article?: string;
33
+ search?: string;
34
+ }): void;
35
+ /**
36
+ * Close the panel
37
+ */
38
+ close(): void;
39
+ /**
40
+ * Navigate to a specific view
41
+ */
42
+ navigate(view: string, params?: Record<string, string>): void;
43
+ /**
44
+ * Destroy the panel
45
+ */
46
+ destroy(): void;
47
+ private createHost;
48
+ private createBackdrop;
49
+ private createPanel;
50
+ private bindEvents;
51
+ private handleKeyDown;
52
+ private setupFocusTrap;
53
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Panel UI Controller
3
+ * Manages panel navigation and view rendering with persistent chat input
4
+ */
5
+ import type { EventEmitter } from '../core/events';
6
+ import type { APIClient } from '../api/client';
7
+ export type ViewType = 'home' | 'article' | 'search' | 'category';
8
+ export interface PanelUIOptions {
9
+ api: APIClient;
10
+ events: EventEmitter;
11
+ onClose: () => void;
12
+ }
13
+ export declare class PanelUI {
14
+ private options;
15
+ private container;
16
+ private header;
17
+ private content;
18
+ private chatInput;
19
+ private homeView;
20
+ private articleView;
21
+ private searchView;
22
+ private categoryView;
23
+ private viewStack;
24
+ private currentView;
25
+ constructor(options: PanelUIOptions);
26
+ render(): HTMLElement;
27
+ /**
28
+ * Show the initial view when panel opens for the first time
29
+ * or when no view is currently displayed
30
+ */
31
+ showInitialView(): void;
32
+ navigate(view: ViewType, params?: Record<string, string>): void;
33
+ goBack(): void;
34
+ reset(): void;
35
+ private renderView;
36
+ private renderHomeView;
37
+ private renderArticleView;
38
+ private renderSearchView;
39
+ private renderCategoryView;
40
+ private updateHeader;
41
+ private destroyCurrentView;
42
+ destroy(): void;
43
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Article Card Component
3
+ */
4
+ import type { ArticleSummary } from '../../api/client';
5
+ export interface ArticleCardOptions {
6
+ article: ArticleSummary;
7
+ onClick: (article: ArticleSummary) => void;
8
+ }
9
+ export declare function createArticleCard(options: ArticleCardOptions): HTMLElement;
10
+ export declare function createArticleList(articles: ArticleSummary[], onClick: (article: ArticleSummary) => void): HTMLElement;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Category Card Component
3
+ */
4
+ import type { CategoryData } from '../../api/client';
5
+ export interface CategoryCardOptions {
6
+ category: CategoryData;
7
+ onClick: (category: CategoryData) => void;
8
+ }
9
+ export declare function createCategoryCard(options: CategoryCardOptions): HTMLElement;
10
+ export declare function createCategoryList(categories: CategoryData[], onClick: (category: CategoryData) => void): HTMLElement;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Chat Input Component
3
+ * Persistent chat input with message display area
4
+ */
5
+ import type { APIClient, ArticleSummary } from '../../api/client';
6
+ export interface ChatInputOptions {
7
+ api: APIClient;
8
+ onArticleClick: (article: ArticleSummary) => void;
9
+ }
10
+ export declare class ChatInput {
11
+ private options;
12
+ private element;
13
+ private messagesContainer;
14
+ private inputElement;
15
+ private sendButton;
16
+ private messages;
17
+ private isLoading;
18
+ private isExpanded;
19
+ constructor(options: ChatInputOptions);
20
+ render(): HTMLElement;
21
+ private createInputArea;
22
+ private handleSend;
23
+ private expand;
24
+ private addWelcomeMessage;
25
+ private addMessage;
26
+ private createAssistantMessageElement;
27
+ private createSourcesElement;
28
+ private formatMessageContent;
29
+ private setLoading;
30
+ private scrollToBottom;
31
+ /**
32
+ * Reset the chat state
33
+ */
34
+ reset(): void;
35
+ destroy(): void;
36
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Panel Header Component
3
+ * Displays title, back button, home button, and close button
4
+ */
5
+ export interface HeaderOptions {
6
+ title: string;
7
+ showBack?: boolean;
8
+ showHome?: boolean;
9
+ onBack?: () => void;
10
+ onHome?: () => void;
11
+ onClose?: () => void;
12
+ }
13
+ export declare function createHeader(options: HeaderOptions): HTMLElement;
14
+ export declare function updateHeaderTitle(header: HTMLElement, title: string): void;
15
+ export declare function setBackButtonVisible(header: HTMLElement, visible: boolean): void;
16
+ export declare function setHomeButtonVisible(header: HTMLElement, visible: boolean): void;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Search Input Component
3
+ */
4
+ export interface SearchInputOptions {
5
+ placeholder?: string;
6
+ onSearch: (query: string) => void;
7
+ debounceMs?: number;
8
+ }
9
+ export declare function createSearchInput(options: SearchInputOptions): HTMLElement;
10
+ export declare function setSearchValue(container: HTMLElement, value: string): void;
11
+ export declare function focusSearch(container: HTMLElement): void;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Panel CSS Styles
3
+ * Complete styling for the help panel (injected into Shadow DOM)
4
+ */
5
+ export declare const PANEL_STYLES = "\n/* Reset and base styles */\n*, *::before, *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\n:host {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: #1a1a1a;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* Panel Container */\n.pillar-panel {\n position: fixed;\n top: 0;\n bottom: 0;\n width: var(--pillar-panel-width, 380px);\n max-width: 100vw;\n background: #ffffff;\n box-shadow: -4px 0 20px rgba(0, 0, 0, 0.1);\n display: flex;\n flex-direction: column;\n z-index: 99999;\n transform: translateX(100%);\n transition: transform 0.3s ease;\n}\n\n.pillar-panel--right {\n right: 0;\n}\n\n.pillar-panel--left {\n left: 0;\n box-shadow: 4px 0 20px rgba(0, 0, 0, 0.1);\n transform: translateX(-100%);\n}\n\n.pillar-panel--open {\n transform: translateX(0);\n}\n\n/* Panel UI - Main layout */\n.pillar-panel-ui {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n/* Backdrop */\n.pillar-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.3);\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n z-index: 99998;\n}\n\n.pillar-backdrop--visible {\n opacity: 1;\n visibility: visible;\n}\n\n/* Header */\n.pillar-panel__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid #e5e7eb;\n flex-shrink: 0;\n}\n\n.pillar-panel__header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.pillar-panel__back-btn,\n.pillar-panel__home-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n color: #6b7280;\n background: none;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: color 0.15s ease, background 0.15s ease;\n}\n\n.pillar-panel__back-btn:hover,\n.pillar-panel__home-btn:hover {\n color: #1a1a1a;\n background: #f3f4f6;\n}\n\n.pillar-panel__back-btn svg,\n.pillar-panel__home-btn svg {\n width: 20px;\n height: 20px;\n}\n\n.pillar-panel__title {\n font-size: 16px;\n font-weight: 600;\n color: #1a1a1a;\n}\n\n.pillar-panel__close-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n color: #6b7280;\n background: none;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: color 0.15s ease, background 0.15s ease;\n}\n\n.pillar-panel__close-btn:hover {\n color: #1a1a1a;\n background: #f3f4f6;\n}\n\n.pillar-panel__close-btn svg {\n width: 20px;\n height: 20px;\n}\n\n/* Content area */\n.pillar-panel__content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n}\n\n/* Search Input */\n.pillar-search {\n position: relative;\n padding: 16px 20px;\n}\n\n.pillar-search__input {\n width: 100%;\n padding: 10px 12px 10px 40px;\n font-size: 14px;\n color: #1a1a1a;\n background: #f9fafb;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n outline: none;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.pillar-search__input:focus {\n border-color: #2563eb;\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n}\n\n.pillar-search__input::placeholder {\n color: #9ca3af;\n}\n\n.pillar-search__icon {\n position: absolute;\n left: 32px;\n top: 50%;\n transform: translateY(-50%);\n width: 18px;\n height: 18px;\n color: #9ca3af;\n pointer-events: none;\n}\n\n/* Category Card */\n.pillar-category-card {\n display: flex;\n align-items: flex-start;\n gap: 14px;\n padding: 16px 20px;\n border-bottom: 1px solid #f3f4f6;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.pillar-category-card:hover {\n background: #f9fafb;\n}\n\n.pillar-category-card__icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: #eff6ff;\n border-radius: 10px;\n color: #2563eb;\n flex-shrink: 0;\n}\n\n.pillar-category-card__icon svg {\n width: 20px;\n height: 20px;\n}\n\n.pillar-category-card__content {\n flex: 1;\n min-width: 0;\n}\n\n.pillar-category-card__title {\n font-size: 15px;\n font-weight: 500;\n color: #1a1a1a;\n margin-bottom: 2px;\n}\n\n.pillar-category-card__description {\n font-size: 13px;\n color: #6b7280;\n}\n\n.pillar-category-card__count {\n font-size: 12px;\n color: #9ca3af;\n margin-top: 4px;\n}\n\n/* Article Card */\n.pillar-article-card {\n display: block;\n padding: 16px 20px;\n border-bottom: 1px solid #f3f4f6;\n cursor: pointer;\n transition: background 0.15s ease;\n text-decoration: none;\n color: inherit;\n}\n\n.pillar-article-card:hover {\n background: #f9fafb;\n}\n\n.pillar-article-card__title {\n font-size: 15px;\n font-weight: 500;\n color: #1a1a1a;\n margin-bottom: 4px;\n}\n\n.pillar-article-card__excerpt {\n font-size: 13px;\n color: #6b7280;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.pillar-article-card__meta {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n font-size: 12px;\n color: #9ca3af;\n}\n\n/* Article Content */\n.pillar-article {\n padding: 20px;\n}\n\n.pillar-article__title {\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n margin-bottom: 16px;\n}\n\n.pillar-article__content {\n font-size: 15px;\n line-height: 1.7;\n color: #374151;\n}\n\n.pillar-article__content h1,\n.pillar-article__content h2,\n.pillar-article__content h3,\n.pillar-article__content h4 {\n color: #1a1a1a;\n margin: 24px 0 12px;\n font-weight: 600;\n}\n\n.pillar-article__content h2 {\n font-size: 18px;\n}\n\n.pillar-article__content h3 {\n font-size: 16px;\n}\n\n.pillar-article__content p {\n margin: 0 0 16px;\n}\n\n.pillar-article__content ul,\n.pillar-article__content ol {\n margin: 0 0 16px;\n padding-left: 24px;\n}\n\n.pillar-article__content li {\n margin-bottom: 8px;\n}\n\n.pillar-article__content a {\n color: #2563eb;\n text-decoration: none;\n}\n\n.pillar-article__content a:hover {\n text-decoration: underline;\n}\n\n.pillar-article__content code {\n padding: 2px 6px;\n font-size: 13px;\n background: #f3f4f6;\n border-radius: 4px;\n font-family: 'SF Mono', Consolas, monospace;\n}\n\n.pillar-article__content pre {\n padding: 16px;\n margin: 0 0 16px;\n background: #1a1a1a;\n border-radius: 8px;\n overflow-x: auto;\n}\n\n.pillar-article__content pre code {\n padding: 0;\n background: none;\n color: #e5e7eb;\n}\n\n.pillar-article__content img {\n max-width: 100%;\n height: auto;\n border-radius: 8px;\n margin: 16px 0;\n}\n\n/* ============================================================================\n Persistent Chat Input (bottom of panel)\n ============================================================================ */\n\n.pillar-chat-input-container {\n flex-shrink: 0;\n border-top: 1px solid #e5e7eb;\n background: #ffffff;\n display: flex;\n flex-direction: column;\n max-height: 50%;\n transition: max-height 0.3s ease;\n}\n\n.pillar-chat-input-container--expanded {\n max-height: 60%;\n}\n\n/* Messages area */\n.pillar-chat-input__messages {\n flex: 1;\n overflow-y: auto;\n padding: 0;\n max-height: 0;\n transition: max-height 0.3s ease, padding 0.3s ease;\n}\n\n.pillar-chat-input-container--expanded .pillar-chat-input__messages {\n max-height: 300px;\n padding: 16px 20px;\n}\n\n.pillar-chat-input__message {\n margin-bottom: 12px;\n}\n\n.pillar-chat-input__message--user {\n text-align: right;\n}\n\n.pillar-chat-input__message-content {\n display: inline-block;\n max-width: 85%;\n padding: 10px 14px;\n border-radius: 16px;\n font-size: 14px;\n line-height: 1.5;\n}\n\n.pillar-chat-input__message--user .pillar-chat-input__message-content {\n background: #2563eb;\n color: #ffffff;\n border-bottom-right-radius: 4px;\n}\n\n.pillar-chat-input__message--assistant .pillar-chat-input__message-content {\n background: #f3f4f6;\n color: #1a1a1a;\n border-bottom-left-radius: 4px;\n}\n\n.pillar-chat-input__sources {\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid #e5e7eb;\n}\n\n.pillar-chat-input__sources-title {\n font-size: 11px;\n font-weight: 500;\n color: #6b7280;\n margin-bottom: 6px;\n}\n\n.pillar-chat-input__source {\n display: block;\n padding: 6px 10px;\n margin-bottom: 4px;\n font-size: 12px;\n color: #2563eb;\n background: #eff6ff;\n border-radius: 6px;\n text-decoration: none;\n cursor: pointer;\n}\n\n.pillar-chat-input__source:hover {\n background: #dbeafe;\n}\n\n/* Input area */\n.pillar-chat-input__area {\n padding: 12px 16px;\n}\n\n.pillar-chat-input__wrapper {\n display: flex;\n gap: 8px;\n align-items: flex-end;\n}\n\n.pillar-chat-input__input {\n flex: 1;\n padding: 10px 14px;\n font-size: 14px;\n font-family: inherit;\n color: #1a1a1a;\n background: #f9fafb;\n border: 1px solid #e5e7eb;\n border-radius: 20px;\n outline: none;\n resize: none;\n min-height: 40px;\n max-height: 120px;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.pillar-chat-input__input:focus {\n border-color: #2563eb;\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n}\n\n.pillar-chat-input__input::placeholder {\n color: #9ca3af;\n}\n\n.pillar-chat-input__send-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n padding: 0;\n color: #ffffff;\n background: #2563eb;\n border: none;\n border-radius: 20px;\n cursor: pointer;\n flex-shrink: 0;\n transition: background 0.15s ease;\n}\n\n.pillar-chat-input__send-btn:hover:not(:disabled) {\n background: #1d4ed8;\n}\n\n.pillar-chat-input__send-btn:disabled {\n background: #9ca3af;\n cursor: not-allowed;\n}\n\n.pillar-chat-input__send-btn svg {\n width: 18px;\n height: 18px;\n}\n\n/* ============================================================================\n Legacy Chat View (for backwards compatibility)\n ============================================================================ */\n\n.pillar-chat {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.pillar-chat__messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n.pillar-chat__message {\n margin-bottom: 16px;\n}\n\n.pillar-chat__message--user {\n text-align: right;\n}\n\n.pillar-chat__message-content {\n display: inline-block;\n max-width: 85%;\n padding: 12px 16px;\n border-radius: 16px;\n font-size: 14px;\n line-height: 1.5;\n}\n\n.pillar-chat__message--user .pillar-chat__message-content {\n background: #2563eb;\n color: #ffffff;\n border-bottom-right-radius: 4px;\n}\n\n.pillar-chat__message--assistant .pillar-chat__message-content {\n background: #f3f4f6;\n color: #1a1a1a;\n border-bottom-left-radius: 4px;\n}\n\n.pillar-chat__sources {\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid #e5e7eb;\n}\n\n.pillar-chat__sources-title {\n font-size: 12px;\n font-weight: 500;\n color: #6b7280;\n margin-bottom: 8px;\n}\n\n.pillar-chat__source {\n display: block;\n padding: 8px 12px;\n margin-bottom: 4px;\n font-size: 13px;\n color: #2563eb;\n background: #eff6ff;\n border-radius: 6px;\n text-decoration: none;\n cursor: pointer;\n}\n\n.pillar-chat__source:hover {\n background: #dbeafe;\n}\n\n.pillar-chat__input-area {\n padding: 16px 20px;\n border-top: 1px solid #e5e7eb;\n background: #ffffff;\n}\n\n.pillar-chat__input-wrapper {\n display: flex;\n gap: 8px;\n}\n\n.pillar-chat__input {\n flex: 1;\n padding: 10px 14px;\n font-size: 14px;\n color: #1a1a1a;\n background: #f9fafb;\n border: 1px solid #e5e7eb;\n border-radius: 20px;\n outline: none;\n resize: none;\n min-height: 40px;\n max-height: 120px;\n}\n\n.pillar-chat__input:focus {\n border-color: #2563eb;\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n}\n\n.pillar-chat__send-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n padding: 0;\n color: #ffffff;\n background: #2563eb;\n border: none;\n border-radius: 20px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.pillar-chat__send-btn:hover:not(:disabled) {\n background: #1d4ed8;\n}\n\n.pillar-chat__send-btn:disabled {\n background: #9ca3af;\n cursor: not-allowed;\n}\n\n.pillar-chat__send-btn svg {\n width: 18px;\n height: 18px;\n}\n\n/* Loading states */\n.pillar-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: #6b7280;\n}\n\n.pillar-loading__spinner {\n width: 24px;\n height: 24px;\n border: 2px solid #e5e7eb;\n border-top-color: #2563eb;\n border-radius: 50%;\n animation: pillar-spin 0.8s linear infinite;\n}\n\n@keyframes pillar-spin {\n to { transform: rotate(360deg); }\n}\n\n/* Empty states */\n.pillar-empty {\n padding: 40px 20px;\n text-align: center;\n color: #6b7280;\n}\n\n.pillar-empty__icon {\n width: 48px;\n height: 48px;\n margin: 0 auto 16px;\n color: #d1d5db;\n}\n\n.pillar-empty__title {\n font-size: 16px;\n font-weight: 500;\n color: #1a1a1a;\n margin-bottom: 4px;\n}\n\n.pillar-empty__description {\n font-size: 14px;\n}\n\n/* Section titles */\n.pillar-section-title {\n padding: 12px 20px 8px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #6b7280;\n}\n\n/* Chat entry button (legacy - kept for backwards compatibility) */\n.pillar-chat-entry {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 16px 20px;\n padding: 14px 16px;\n background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);\n border: none;\n border-radius: 12px;\n cursor: pointer;\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n}\n\n.pillar-chat-entry:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);\n}\n\n.pillar-chat-entry__icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 10px;\n color: #ffffff;\n}\n\n.pillar-chat-entry__icon svg {\n width: 20px;\n height: 20px;\n}\n\n.pillar-chat-entry__content {\n flex: 1;\n text-align: left;\n}\n\n.pillar-chat-entry__title {\n font-size: 15px;\n font-weight: 600;\n color: #ffffff;\n margin-bottom: 2px;\n}\n\n.pillar-chat-entry__description {\n font-size: 13px;\n color: rgba(255, 255, 255, 0.8);\n}\n\n/* Scrollbar styling */\n.pillar-panel__content::-webkit-scrollbar,\n.pillar-chat__messages::-webkit-scrollbar,\n.pillar-chat-input__messages::-webkit-scrollbar {\n width: 6px;\n}\n\n.pillar-panel__content::-webkit-scrollbar-track,\n.pillar-chat__messages::-webkit-scrollbar-track,\n.pillar-chat-input__messages::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.pillar-panel__content::-webkit-scrollbar-thumb,\n.pillar-chat__messages::-webkit-scrollbar-thumb,\n.pillar-chat-input__messages::-webkit-scrollbar-thumb {\n background: #d1d5db;\n border-radius: 3px;\n}\n\n.pillar-panel__content::-webkit-scrollbar-thumb:hover,\n.pillar-chat__messages::-webkit-scrollbar-thumb:hover,\n.pillar-chat-input__messages::-webkit-scrollbar-thumb:hover {\n background: #9ca3af;\n}\n\n/* Home view */\n.pillar-home-view {\n padding-bottom: 16px;\n}\n";
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Article View
3
+ * Displays article content using TipTap for rendering
4
+ */
5
+ import type { APIClient, ArticleSummary } from '../../api/client';
6
+ export interface ArticleViewOptions {
7
+ api: APIClient;
8
+ onArticleClick: (article: ArticleSummary) => void;
9
+ }
10
+ export declare class ArticleView {
11
+ private options;
12
+ private element;
13
+ private currentSlug;
14
+ constructor(options: ArticleViewOptions);
15
+ render(slug: string): Promise<HTMLElement>;
16
+ private loadArticle;
17
+ private createArticleElement;
18
+ private createRelatedArticles;
19
+ getTitle(): string;
20
+ destroy(): void;
21
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Category View
3
+ * Displays articles within a category
4
+ */
5
+ import type { APIClient, CategoryData, ArticleSummary } from '../../api/client';
6
+ export interface CategoryViewOptions {
7
+ api: APIClient;
8
+ onArticleClick: (article: ArticleSummary) => void;
9
+ }
10
+ export declare class CategoryView {
11
+ private options;
12
+ private element;
13
+ private currentCategory;
14
+ constructor(options: CategoryViewOptions);
15
+ render(category: CategoryData): Promise<HTMLElement>;
16
+ private createCategoryHeader;
17
+ private loadArticles;
18
+ getTitle(): string;
19
+ destroy(): void;
20
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Chat View
3
+ * AI chat interface with streaming responses
4
+ */
5
+ import type { APIClient, ArticleSummary } from '../../api/client';
6
+ export interface ChatViewOptions {
7
+ api: APIClient;
8
+ onArticleClick: (article: ArticleSummary) => void;
9
+ }
10
+ export declare class ChatView {
11
+ private options;
12
+ private element;
13
+ private messagesContainer;
14
+ private inputElement;
15
+ private sendButton;
16
+ private messages;
17
+ private isLoading;
18
+ constructor(options: ChatViewOptions);
19
+ render(): HTMLElement;
20
+ private createInputArea;
21
+ private addWelcomeMessage;
22
+ private handleSend;
23
+ private addMessage;
24
+ private createAssistantMessageElement;
25
+ private createSourcesElement;
26
+ private formatMessageContent;
27
+ private setLoading;
28
+ private scrollToBottom;
29
+ destroy(): void;
30
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Home View
3
+ * Default panel view with categories list
4
+ */
5
+ import type { APIClient, CategoryData } from '../../api/client';
6
+ export interface HomeViewOptions {
7
+ api: APIClient;
8
+ onCategoryClick: (category: CategoryData) => void;
9
+ }
10
+ export declare class HomeView {
11
+ private options;
12
+ private element;
13
+ private categoriesLoaded;
14
+ constructor(options: HomeViewOptions);
15
+ render(): HTMLElement;
16
+ private loadCategories;
17
+ destroy(): void;
18
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Search View
3
+ * Search results display
4
+ */
5
+ import type { APIClient, ArticleSummary } from '../../api/client';
6
+ export interface SearchViewOptions {
7
+ api: APIClient;
8
+ onArticleClick: (article: ArticleSummary) => void;
9
+ initialQuery?: string;
10
+ }
11
+ export declare class SearchView {
12
+ private options;
13
+ private element;
14
+ private resultsContainer;
15
+ private currentQuery;
16
+ constructor(options: SearchViewOptions);
17
+ render(): HTMLElement;
18
+ private handleSearch;
19
+ private showEmptyState;
20
+ private showNoResults;
21
+ destroy(): void;
22
+ }