@pillar-ai/sdk 0.1.8 → 0.1.14

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 (58) hide show
  1. package/README.md +118 -60
  2. package/dist/actions/index.d.ts +1 -1
  3. package/dist/actions/registry.d.ts +15 -27
  4. package/dist/actions/types.d.ts +20 -8
  5. package/dist/api/client.d.ts +91 -5
  6. package/dist/api/mcp-client.d.ts +105 -79
  7. package/dist/cli/sync.d.ts +0 -1
  8. package/dist/cli/sync.js +102 -14
  9. package/dist/components/DebugPanel/DebugPanel.d.ts +25 -0
  10. package/dist/components/DebugPanel/index.d.ts +2 -0
  11. package/dist/components/DevTools/index.d.ts +5 -0
  12. package/dist/components/DevTools/styles.d.ts +5 -0
  13. package/dist/components/Panel/Header.d.ts +1 -1
  14. package/dist/components/Panel/HistoryDropdown.d.ts +10 -0
  15. package/dist/components/Panel/Panel.d.ts +1 -0
  16. package/dist/components/Panel/TaskButton.d.ts +4 -14
  17. package/dist/components/Panel/styles.d.ts +1 -1
  18. package/dist/components/Plan/InlinePlanView.d.ts +1 -1
  19. package/dist/components/Plan/PlanDocument.d.ts +18 -0
  20. package/dist/components/Plan/PlanStepItem.d.ts +1 -1
  21. package/dist/components/Plan/PlanView.d.ts +1 -1
  22. package/dist/components/Plan/index.d.ts +1 -0
  23. package/dist/components/Progress/ProgressRow.d.ts +16 -0
  24. package/dist/components/Progress/ProgressStack.d.ts +15 -0
  25. package/dist/components/Progress/ReasoningDisclosure.d.ts +20 -0
  26. package/dist/components/Progress/index.d.ts +3 -0
  27. package/dist/components/Views/HomeView.d.ts +3 -0
  28. package/dist/components/Views/ResumePrompt.d.ts +22 -0
  29. package/dist/components/Views/index.d.ts +1 -0
  30. package/dist/components/index.d.ts +1 -0
  31. package/dist/components/shared/icons.d.ts +24 -0
  32. package/dist/components/shared/index.d.ts +1 -0
  33. package/dist/core/Pillar.d.ts +318 -80
  34. package/dist/core/config.d.ts +141 -3
  35. package/dist/core/events.d.ts +55 -70
  36. package/dist/core/plan-executor.d.ts +29 -0
  37. package/dist/core/plan.d.ts +6 -0
  38. package/dist/hooks/index.d.ts +5 -0
  39. package/dist/hooks/useDebouncedValue.d.ts +22 -0
  40. package/dist/hooks/useInlineCard.d.ts +35 -0
  41. package/dist/hooks/usePillarInstance.d.ts +30 -0
  42. package/dist/index.d.ts +14 -12
  43. package/dist/pillar.esm.js +1 -1
  44. package/dist/store/chat.d.ts +102 -4
  45. package/dist/store/index.d.ts +1 -0
  46. package/dist/store/session-persistence.d.ts +62 -0
  47. package/dist/store/suggestions.d.ts +58 -0
  48. package/dist/types/dom-scanner.d.ts +46 -0
  49. package/dist/types/index.d.ts +1 -0
  50. package/dist/types/user-context.d.ts +32 -1
  51. package/dist/utils/debug.d.ts +150 -0
  52. package/dist/utils/dom-scanner.d.ts +44 -0
  53. package/dist/utils/markdown-components.d.ts +53 -0
  54. package/dist/utils/preact-markdown.d.ts +17 -0
  55. package/dist/utils/route-observer.d.ts +67 -0
  56. package/package.json +1 -1
  57. package/src/actions/types.ts +21 -7
  58. package/dist/utils/markdown.d.ts +0 -9
@@ -20,23 +20,90 @@ export interface StoredChatMessage extends ChatMessage {
20
20
  actionStatus?: Record<string, ActionStatus>;
21
21
  userContext?: UserContextItem[];
22
22
  images?: ChatImage[];
23
+ progressEvents?: ProgressEvent[];
23
24
  }
24
25
  export declare const messages: import("@preact/signals-core").Signal<StoredChatMessage[]>;
25
26
  export declare const conversationId: import("@preact/signals-core").Signal<string | null>;
27
+ export declare const registeredActions: import("@preact/signals-core").Signal<Record<string, unknown>[]>;
28
+ export declare const historyInvalidationCounter: import("@preact/signals-core").Signal<number>;
26
29
  export declare const isLoading: import("@preact/signals-core").Signal<boolean>;
30
+ export interface InterruptedSession {
31
+ conversationId: string;
32
+ userMessage: string;
33
+ partialResponse: string;
34
+ summary: string;
35
+ elapsedMs: number;
36
+ }
37
+ export declare const interruptedSession: import("@preact/signals-core").Signal<InterruptedSession | null>;
27
38
  export interface ProgressStatus {
28
- kind: 'search' | 'search_complete' | 'generating' | 'thinking' | null;
39
+ kind: string | null;
29
40
  message?: string;
30
41
  }
31
42
  export declare const progressStatus: import("@preact/signals-core").Signal<ProgressStatus>;
43
+ /**
44
+ * Child item within a progress event (e.g., search source, plan step).
45
+ */
46
+ export interface ProgressChild {
47
+ id: string;
48
+ label: string;
49
+ url?: string;
50
+ }
51
+ /**
52
+ * Progress event for tracking AI response generation steps.
53
+ * Uses a generic design where the server controls display text via `label`.
54
+ *
55
+ * The new schema uses `id` and `status` fields. Legacy fields are kept
56
+ * for backwards compatibility with older backend versions.
57
+ */
58
+ export interface ProgressEvent {
59
+ kind: string;
60
+ id?: string;
61
+ label?: string;
62
+ status?: 'active' | 'done' | 'error';
63
+ text?: string;
64
+ children?: ProgressChild[];
65
+ metadata?: Record<string, unknown>;
66
+ progress_id?: string;
67
+ message?: string;
68
+ }
69
+ /**
70
+ * @deprecated Use `message.progressEvents` instead. Will be removed in v2.0.
71
+ *
72
+ * This global signal is kept for backwards compatibility with progressStatus.
73
+ */
74
+ export declare const progressEvents: import("@preact/signals-core").Signal<ProgressEvent[]>;
75
+ /**
76
+ * Add a progress event to the last assistant message.
77
+ * Events are stored directly on the message as they arrive.
78
+ *
79
+ * If the event has an id (or legacy progress_id) that matches an existing event,
80
+ * the existing event is updated:
81
+ * - Text is appended (delta mode for streaming)
82
+ * - Status transitions are handled (active → done/error)
83
+ * - Other fields are merged
84
+ *
85
+ * This prevents multiple rows from appearing for the same event.
86
+ */
87
+ export declare const addProgressEventToLastMessage: (event: ProgressEvent) => void;
32
88
  export declare const isExpanded: import("@preact/signals-core").Signal<boolean>;
89
+ /**
90
+ * @deprecated Sources are now stored per-message on `StoredChatMessage.sources`. Will be removed in v2.0.
91
+ *
92
+ * Kept for backwards compatibility with resetChat().
93
+ */
33
94
  export declare const currentSources: import("@preact/signals-core").Signal<ArticleSummary[]>;
95
+ /**
96
+ * @deprecated Actions are now stored per-message on `StoredChatMessage.actions`. Will be removed in v2.0.
97
+ *
98
+ * Kept for backwards compatibility with resetChat().
99
+ */
34
100
  export declare const currentActions: import("@preact/signals-core").Signal<TaskButtonData[]>;
35
101
  export declare const prefillText: import("@preact/signals-core").Signal<string>;
36
102
  export declare const pendingMessage: import("@preact/signals-core").Signal<string | null>;
103
+ export declare const submitPendingTrigger: import("@preact/signals-core").Signal<number>;
37
104
  export declare const focusInputTrigger: import("@preact/signals-core").Signal<number>;
38
- export declare const userContext: import("@preact/signals-core").Signal<import("../types").HighlightedTextContext[]>;
39
- export declare const pendingUserContext: import("@preact/signals-core").Signal<import("../types").HighlightedTextContext[]>;
105
+ export declare const userContext: import("@preact/signals-core").Signal<UserContextItem[]>;
106
+ export declare const pendingUserContext: import("@preact/signals-core").Signal<UserContextItem[]>;
40
107
  export type ImageUploadStatus = 'uploading' | 'ready' | 'error';
41
108
  export interface PendingImage {
42
109
  id: string;
@@ -62,7 +129,24 @@ export declare const setActionComplete: (actionName: string, success: boolean, e
62
129
  export declare const updateMessageContent: (messageIndex: number, content: string) => void;
63
130
  export declare const updateActionMessageContent: (actionName: string, content: string) => void;
64
131
  export declare const setConversationId: (id: string) => void;
132
+ /**
133
+ * @deprecated Use `setConversationId` instead. Will be removed in v2.0.
134
+ */
135
+ export declare const setThreadId: (id: string) => void;
65
136
  export declare const clearConversationId: () => void;
137
+ /**
138
+ * Set registered actions from backend response.
139
+ * These are actions discovered via search that can be called directly by the LLM.
140
+ */
141
+ export declare const setRegisteredActions: (actions: Record<string, unknown>[]) => void;
142
+ /**
143
+ * Get registered actions for sending with the next message.
144
+ */
145
+ export declare const getRegisteredActions: () => Record<string, unknown>[];
146
+ /**
147
+ * Clear registered actions (e.g., when starting a new conversation).
148
+ */
149
+ export declare const clearRegisteredActions: () => void;
66
150
  export declare const setMessageFeedback: (messageId: string, feedback: "up" | "down") => void;
67
151
  export declare const setSources: (sources: ArticleSummary[]) => void;
68
152
  export declare const setActions: (actions: TaskButtonData[]) => void;
@@ -70,16 +154,30 @@ export declare const clearActions: () => void;
70
154
  export declare const setLoading: (loading: boolean) => void;
71
155
  export declare const setProgressStatus: (status: ProgressStatus) => void;
72
156
  export declare const clearProgressStatus: () => void;
157
+ export declare const addProgressEvent: (event: ProgressEvent) => void;
158
+ export declare const clearProgressEvents: () => void;
159
+ export declare const setInterruptedSession: (session: InterruptedSession | null) => void;
160
+ export declare const clearInterruptedSession: () => void;
73
161
  export declare const expandChat: () => void;
74
162
  export declare const collapseChat: () => void;
75
163
  export declare const setPrefillText: (text: string) => void;
76
164
  export declare const clearPrefillText: () => void;
77
165
  export declare const setPendingMessage: (message: string) => void;
78
166
  export declare const clearPendingMessage: () => void;
167
+ export declare const triggerSubmitPending: () => void;
79
168
  export declare const triggerInputFocus: () => void;
80
- export declare const addUserContext: (item: Omit<UserContextItem, "id">) => void;
169
+ export declare const addUserContext: <T extends Omit<UserContextItem, "id">>(item: T) => void;
81
170
  export declare const removeUserContext: (id: string) => void;
82
171
  export declare const clearUserContext: () => void;
83
172
  export declare const setPendingUserContext: (items: UserContextItem[]) => void;
84
173
  export declare const clearPendingUserContext: () => void;
85
174
  export declare const resetChat: () => void;
175
+ /**
176
+ * Load a conversation from history.
177
+ * Populates the chat with messages from a previous conversation.
178
+ */
179
+ export declare const loadConversation: (id: string, historyMessages: Array<{
180
+ role: "user" | "assistant";
181
+ content: string;
182
+ id?: string;
183
+ }>) => void;
@@ -7,3 +7,4 @@ export * as routerStore from './router';
7
7
  export * as chatStore from './chat';
8
8
  export * as contextStore from './context';
9
9
  export * as workflowStore from './workflow';
10
+ export * as suggestionsStore from './suggestions';
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Session Persistence Module
3
+ *
4
+ * Handles localStorage persistence for active streaming sessions.
5
+ * Enables session recovery when the page is refreshed or the user
6
+ * navigates away and returns.
7
+ *
8
+ * This is a lightweight "recovery hint" - the server is the source of truth.
9
+ * We only store enough to know there might be a resumable session.
10
+ */
11
+ /**
12
+ * Stored session data with metadata.
13
+ * Minimal data - just enough to trigger a server check.
14
+ */
15
+ interface StoredSessionData {
16
+ version: number;
17
+ conversationId: string;
18
+ siteId: string;
19
+ streamingStartedAt: string;
20
+ }
21
+ /**
22
+ * Save an active session hint to localStorage.
23
+ *
24
+ * Called when streaming starts to enable recovery on disconnect.
25
+ *
26
+ * @param conversationId - The conversation UUID
27
+ * @param siteId - The site ID for scoping
28
+ */
29
+ export declare function saveActiveSession(conversationId: string, siteId: string): void;
30
+ /**
31
+ * Load a saved session hint from localStorage.
32
+ *
33
+ * @param siteId - The site ID for scoping
34
+ * @returns The saved session data or null if not found/invalid
35
+ */
36
+ export declare function loadActiveSession(siteId: string): StoredSessionData | null;
37
+ /**
38
+ * Clear any saved session from localStorage.
39
+ *
40
+ * Called when streaming completes, user discards, or on successful resume.
41
+ *
42
+ * @param siteId - The site ID for scoping
43
+ */
44
+ export declare function clearActiveSession(siteId: string): void;
45
+ /**
46
+ * Check if there's a saved session without loading it.
47
+ *
48
+ * @param siteId - The site ID for scoping
49
+ * @returns true if a session exists
50
+ */
51
+ export declare function hasActiveSession(siteId: string): boolean;
52
+ /**
53
+ * Get metadata about the saved session.
54
+ *
55
+ * @param siteId - The site ID for scoping
56
+ * @returns Session metadata or null
57
+ */
58
+ export declare function getActiveSessionMetadata(siteId: string): {
59
+ conversationId: string;
60
+ streamingStartedAt: string;
61
+ } | null;
62
+ export {};
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Suggestions Store
3
+ * Signal-based state for page-aware suggested questions
4
+ *
5
+ * The backend generates a pool of 15-20 diverse suggestions.
6
+ * This store sorts them client-side based on page relevance
7
+ * for instant page-aware suggestions without additional LLM calls.
8
+ */
9
+ import type { SuggestedQuestion } from '../api/client';
10
+ /** Base suggestion pool from backend (15-20 suggestions) */
11
+ export declare const suggestionPool: import("@preact/signals-core").Signal<SuggestedQuestion[]>;
12
+ /** Currently displayed suggestions (sorted by page relevance) */
13
+ export declare const suggestions: import("@preact/signals-core").Signal<SuggestedQuestion[]>;
14
+ /** Loading state (only for initial pool fetch) */
15
+ export declare const suggestionsLoading: import("@preact/signals-core").Signal<boolean>;
16
+ /** Error state */
17
+ export declare const suggestionsError: import("@preact/signals-core").Signal<string | null>;
18
+ /** Route when suggestions were last sorted */
19
+ export declare const lastSortedRoute: import("@preact/signals-core").Signal<string | null>;
20
+ /** Whether we have suggestions to display */
21
+ export declare const hasSuggestions: import("@preact/signals-core").ReadonlySignal<boolean>;
22
+ /** Whether we have a pool to sort from */
23
+ export declare const hasPool: import("@preact/signals-core").ReadonlySignal<boolean>;
24
+ /**
25
+ * Sort suggestions by relevance to the current page.
26
+ * Uses keyword matching between page context and suggestion text.
27
+ *
28
+ * @param pool - Full pool of suggestions from backend
29
+ * @param pathname - Current page pathname (e.g., '/dashboards/new')
30
+ * @param title - Current page title
31
+ * @param limit - Maximum number of suggestions to return
32
+ * @returns Sorted suggestions, most relevant first
33
+ */
34
+ export declare function sortByPageRelevance(pool: SuggestedQuestion[], pathname: string, title: string, limit?: number): SuggestedQuestion[];
35
+ /**
36
+ * Set the base suggestion pool (called once on init).
37
+ */
38
+ export declare function setSuggestionPool(pool: SuggestedQuestion[]): void;
39
+ /**
40
+ * Update displayed suggestions (sorted for current page).
41
+ */
42
+ export declare function setSuggestions(sorted: SuggestedQuestion[], route: string): void;
43
+ /**
44
+ * Set loading state.
45
+ */
46
+ export declare function setSuggestionsLoading(loading: boolean): void;
47
+ /**
48
+ * Set error state.
49
+ */
50
+ export declare function setSuggestionsError(error: string | null): void;
51
+ /**
52
+ * Sort pool for current page and update displayed suggestions.
53
+ */
54
+ export declare function sortForCurrentPage(pathname: string, title: string, limit?: number): SuggestedQuestion[];
55
+ /**
56
+ * Reset all suggestions state.
57
+ */
58
+ export declare function resetSuggestions(): void;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * DOM Scanner Types
3
+ * Types for scanning DOM and creating compact text representation for LLM context
4
+ */
5
+ /** Types of interactions possible with an element */
6
+ export type InteractionType = "click" | "input" | "select" | "toggle" | "submit" | "focus" | "hover" | string;
7
+ /** Options for controlling DOM scanning behavior */
8
+ export interface ScanOptions {
9
+ /** Maximum depth to traverse (default: 20) */
10
+ maxDepth?: number;
11
+ /** Include text content nodes (default: true) */
12
+ includeText?: boolean;
13
+ /** Include only visible elements (default: true) */
14
+ visibleOnly?: boolean;
15
+ /** Root element to scan from (default: document.body) */
16
+ root?: Element;
17
+ /** Selector for elements to exclude from scanning */
18
+ excludeSelector?: string;
19
+ /** Minimum text length to include (default: 1) */
20
+ minTextLength?: number;
21
+ /** Maximum text length before truncation (default: 500) */
22
+ maxTextLength?: number;
23
+ /** Include element positions/coordinates (default: false) */
24
+ includePositions?: boolean;
25
+ }
26
+ /** Default scan options */
27
+ export declare const DEFAULT_SCAN_OPTIONS: Required<Omit<ScanOptions, "root" | "excludeSelector">>;
28
+ /** Result of DOM scan with compact text representation for LLM context */
29
+ export interface CompactScanResult {
30
+ /** Compact text representation for LLM context */
31
+ content: string;
32
+ /** Number of interactable elements found */
33
+ interactableCount: number;
34
+ /** Timestamp when scan was performed */
35
+ timestamp: number;
36
+ /** URL of the page that was scanned */
37
+ url: string;
38
+ /** Title of the page */
39
+ title: string;
40
+ }
41
+ /** HTML tags that are inherently interactable */
42
+ export declare const INTERACTABLE_TAGS: Set<string>;
43
+ /** ARIA roles that indicate interactability */
44
+ export declare const INTERACTABLE_ROLES: Set<string>;
45
+ /** Tags to completely skip during scanning */
46
+ export declare const SKIP_TAGS: Set<string>;
@@ -2,3 +2,4 @@
2
2
  * Type exports for Pillar SDK
3
3
  */
4
4
  export * from './user-context';
5
+ export * from './dom-scanner';
@@ -18,12 +18,43 @@ export interface HighlightedTextContext extends BaseUserContext {
18
18
  /** The selected text content */
19
19
  text_content: string;
20
20
  }
21
+ /** Product context for context-aware chat */
22
+ export interface ProductContext extends BaseUserContext {
23
+ type: 'product_context';
24
+ [key: string]: unknown;
25
+ }
26
+ /** User profile context */
27
+ export interface UserProfileContext extends BaseUserContext {
28
+ type: 'user_profile';
29
+ [key: string]: unknown;
30
+ }
31
+ /** Generic context for arbitrary data */
32
+ export interface GenericContext extends BaseUserContext {
33
+ type: string;
34
+ [key: string]: unknown;
35
+ }
36
+ /** DOM snapshot context from page scanning */
37
+ export interface DOMSnapshotContext extends BaseUserContext {
38
+ type: 'dom_snapshot';
39
+ /** URL of the scanned page */
40
+ url: string;
41
+ /** Page title */
42
+ title: string;
43
+ /** Compact text representation of the page for LLM context */
44
+ content: string;
45
+ /** Number of interactable elements found */
46
+ interactableCount: number;
47
+ /** Timestamp when scan was performed */
48
+ timestamp: number;
49
+ }
21
50
  /** Union of all possible user context item types */
22
- export type UserContextItem = HighlightedTextContext;
51
+ export type UserContextItem = HighlightedTextContext | ProductContext | UserProfileContext | DOMSnapshotContext | GenericContext;
23
52
  /** Generate a unique ID for a context item */
24
53
  export declare function generateContextId(): string;
25
54
  /** Type guard for highlighted text context */
26
55
  export declare function isHighlightedTextContext(item: UserContextItem): item is HighlightedTextContext;
56
+ /** Type guard for DOM snapshot context */
57
+ export declare function isDOMSnapshotContext(item: UserContextItem): item is DOMSnapshotContext;
27
58
  /** Get display label for a context item */
28
59
  export declare function getContextDisplayLabel(item: UserContextItem): string;
29
60
  export {};
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Unified Debug Logger Utility
3
+ *
4
+ * Single source of truth for all SDK debugging:
5
+ * - debugLog.add() is the primary API for structured logging
6
+ * - debug.log/warn/error are convenience wrappers that route through debugLog
7
+ * - Server forwarding is handled via subscription pattern
8
+ * - DebugPanel subscribes for UI display
9
+ *
10
+ * Sources:
11
+ * - 'sdk': Core SDK events (init, ready, errors)
12
+ * - 'handler': Action handler execution
13
+ * - 'network': API requests/responses
14
+ * - 'server': Server-side events (via SSE)
15
+ */
16
+ import type { MCPClient } from '../api/mcp-client';
17
+ /** Debug entry sources */
18
+ export type DebugSource = 'sdk' | 'handler' | 'network' | 'server';
19
+ /** Debug entry severity levels */
20
+ export type DebugLevel = 'info' | 'warn' | 'error';
21
+ /**
22
+ * Unified debug entry for all logging.
23
+ * Used by DebugPanel, server forwarding, and console output.
24
+ */
25
+ export interface DebugEntry {
26
+ /** Unix timestamp in milliseconds */
27
+ timestamp: number;
28
+ /** Event name or message (e.g., 'sdk:init:start', 'network:request') */
29
+ event: string;
30
+ /** Structured data associated with the event */
31
+ data?: unknown;
32
+ /** Source of the log entry */
33
+ source: DebugSource;
34
+ /** Severity level */
35
+ level: DebugLevel;
36
+ /** Optional prefix for backward compatibility (e.g., '[Pillar]', '[PlanExecutor]') */
37
+ prefix?: string;
38
+ }
39
+ /**
40
+ * Log entry structure for server forwarding (backward compatible).
41
+ */
42
+ export interface LogEntry {
43
+ level: 'log' | 'warn' | 'error';
44
+ message: string;
45
+ data?: unknown;
46
+ timestamp: string;
47
+ }
48
+ /**
49
+ * Enable or disable runtime debug mode.
50
+ * Called by Pillar.init() when debug: true is passed.
51
+ */
52
+ export declare function setDebugMode(enabled: boolean): void;
53
+ /**
54
+ * Check if debug mode is enabled (either via environment or runtime flag).
55
+ */
56
+ export declare function isDebugEnabled(): boolean;
57
+ /**
58
+ * Central debug log store.
59
+ * All debug entries flow through here and are distributed to:
60
+ * - Console (in debug mode)
61
+ * - DebugPanel UI (via subscription)
62
+ * - Server (via ServerLogForwarder subscription)
63
+ */
64
+ declare class DebugLogStore {
65
+ private entries;
66
+ private maxEntries;
67
+ private listeners;
68
+ private serverForwarder;
69
+ private forwarderUnsubscribe;
70
+ /**
71
+ * Add a debug entry.
72
+ * This is the primary API for all logging.
73
+ */
74
+ add(entry: Omit<DebugEntry, 'timestamp'>): void;
75
+ private logToConsole;
76
+ /**
77
+ * Enable server forwarding of logs.
78
+ */
79
+ enableServerForwarding(client: MCPClient, options?: {
80
+ flushIntervalMs?: number;
81
+ }): void;
82
+ /**
83
+ * Disable server forwarding.
84
+ */
85
+ disableServerForwarding(): void;
86
+ /**
87
+ * Manually flush logs to server.
88
+ */
89
+ flush(): void;
90
+ /**
91
+ * Get all entries.
92
+ */
93
+ getEntries(): DebugEntry[];
94
+ /**
95
+ * Clear all entries.
96
+ */
97
+ clear(): void;
98
+ /**
99
+ * Subscribe to entry updates.
100
+ */
101
+ subscribe(listener: (entries: DebugEntry[]) => void): () => void;
102
+ /**
103
+ * Clean up all resources.
104
+ */
105
+ destroy(): void;
106
+ }
107
+ /**
108
+ * Global debug log store instance.
109
+ */
110
+ export declare const debugLog: DebugLogStore;
111
+ /**
112
+ * Debug logger convenience API.
113
+ *
114
+ * Routes all calls through debugLog for unified handling.
115
+ * Maintains backward compatibility with existing debug.log/warn/error calls.
116
+ */
117
+ export declare const debug: {
118
+ /**
119
+ * Configure server-side log forwarding.
120
+ * @deprecated Use debugLog.enableServerForwarding() instead
121
+ */
122
+ configure: (client: MCPClient, options?: {
123
+ forwardToServer?: boolean;
124
+ flushIntervalMs?: number;
125
+ }) => void;
126
+ /**
127
+ * Manually flush logs to server.
128
+ */
129
+ flush: () => void;
130
+ /**
131
+ * Log debug information.
132
+ * Only outputs in development mode or when debug is enabled.
133
+ */
134
+ log: (...args: unknown[]) => void;
135
+ /**
136
+ * Log warnings.
137
+ * Only outputs in development mode or when debug is enabled.
138
+ */
139
+ warn: (...args: unknown[]) => void;
140
+ /**
141
+ * Log errors.
142
+ * Always outputs regardless of environment.
143
+ */
144
+ error: (...args: unknown[]) => void;
145
+ /**
146
+ * Clean up resources.
147
+ */
148
+ destroy: () => void;
149
+ };
150
+ export {};
@@ -0,0 +1,44 @@
1
+ /**
2
+ * DOM Scanner Utilities
3
+ * Scans the DOM and outputs compact text representation for LLM context
4
+ */
5
+ import { type CompactScanResult, type InteractionType, type ScanOptions } from "../types/dom-scanner";
6
+ /**
7
+ * Clear all pillar refs from the DOM.
8
+ * Called before scanning to remove stale refs.
9
+ */
10
+ export declare function clearPillarRefs(): void;
11
+ /**
12
+ * Check if an element is interactable
13
+ */
14
+ export declare function isInteractable(el: Element): boolean;
15
+ /**
16
+ * Determine the interaction type for an element
17
+ */
18
+ export declare function getInteractionType(el: Element): InteractionType;
19
+ /**
20
+ * Build full selector from short ref ID.
21
+ * Converts "pr-abc" to '[data-pillar-ref="pr-abc"]'
22
+ *
23
+ * @param shortRef - Short ref ID (e.g., "pr-abc")
24
+ * @returns Full CSS selector for querySelector
25
+ */
26
+ export declare function buildSelectorFromRef(shortRef: string): string;
27
+ /**
28
+ * Optimized single-pass DOM scanner that outputs compact text directly.
29
+ * Skips the intermediate AST for better performance.
30
+ *
31
+ * @param options - Scan options
32
+ * @returns Compact scan result with text content ready for LLM
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const result = scanPageDirect();
37
+ * console.log(result.content);
38
+ * // === PAGE: My App | /dashboard ===
39
+ * // Welcome to your dashboard
40
+ * // CLICK: Create Report [[pr-a1]]
41
+ * // === 5 interactable elements ===
42
+ * ```
43
+ */
44
+ export declare function scanPageDirect(options?: ScanOptions): CompactScanResult;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Markdown Components
3
+ *
4
+ * Preact components that can be substituted for markdown elements.
5
+ * These enable interactive UI within markdown content.
6
+ */
7
+ import { ComponentChildren, VNode } from 'preact';
8
+ export interface CollapsibleSectionProps {
9
+ title: string;
10
+ defaultOpen?: boolean;
11
+ children: ComponentChildren;
12
+ }
13
+ export declare function CollapsibleSection({ title, defaultOpen, children, }: CollapsibleSectionProps): VNode;
14
+ export interface Source {
15
+ title: string;
16
+ url: string;
17
+ score?: number;
18
+ }
19
+ export interface SourceListProps {
20
+ sources: Source[];
21
+ }
22
+ export declare function SourceList({ sources }: SourceListProps): VNode;
23
+ export interface TaskItem {
24
+ id: string;
25
+ text: string;
26
+ completed: boolean;
27
+ }
28
+ export interface TaskListProps {
29
+ items: TaskItem[];
30
+ onToggle?: (id: string, completed: boolean) => void;
31
+ }
32
+ export declare function TaskList({ items, onToggle }: TaskListProps): VNode;
33
+ export interface CodeBlockProps {
34
+ language?: string;
35
+ children: string;
36
+ }
37
+ export declare function CodeBlock({ language, children }: CodeBlockProps): VNode;
38
+ export interface ActionButton {
39
+ name: string;
40
+ label: string;
41
+ data?: Record<string, unknown>;
42
+ }
43
+ export interface ActionButtonsProps {
44
+ actions: ActionButton[];
45
+ onAction?: (name: string, data?: Record<string, unknown>) => void;
46
+ }
47
+ export declare function ActionButtons({ actions, onAction }: ActionButtonsProps): VNode;
48
+ export interface ProgressIndicatorProps {
49
+ message: string;
50
+ isActive?: boolean;
51
+ }
52
+ export declare function ProgressIndicator({ message, isActive, }: ProgressIndicatorProps): VNode;
53
+ export declare const MARKDOWN_COMPONENT_STYLES = "\n/* Collapsible Section */\n._pillar-collapsible {\n margin: 2px 0;\n}\n\n._pillar-collapsible-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 0;\n background: transparent;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--pillar-text-secondary, #6b7280);\n font-family: inherit;\n width: 100%;\n text-align: left;\n transition: background-color 0.15s ease;\n}\n\n._pillar-collapsible-header:hover {\n background: var(--pillar-bg-hover, rgba(0, 0, 0, 0.05));\n}\n\n._pillar-collapsible-icon {\n font-size: 10px;\n color: var(--pillar-text-muted, #9ca3af);\n}\n\n._pillar-collapsible-title {\n flex: 1;\n}\n\n._pillar-collapsible-content-wrapper {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 0.2s ease;\n}\n\n._pillar-collapsible-content-wrapper--expanded {\n grid-template-rows: 1fr;\n}\n\n._pillar-collapsible-content {\n overflow: hidden;\n padding-left: 18px;\n font-size: 13px;\n color: var(--pillar-text-secondary, #6b7280);\n line-height: 1.4;\n}\n\n._pillar-collapsible-content-wrapper--expanded ._pillar-collapsible-content {\n padding-top: 2px;\n padding-bottom: 4px;\n}\n\n/* Source List */\n._pillar-source-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin: 4px 0;\n}\n\n._pillar-source-item {\n display: block;\n padding: 4px 8px;\n font-size: 12px;\n color: var(--pillar-primary, #2563eb);\n text-decoration: none;\n border-radius: 4px;\n transition: background-color 0.15s ease;\n}\n\n._pillar-source-item:hover {\n background: var(--pillar-bg-hover, rgba(0, 0, 0, 0.05));\n text-decoration: underline;\n}\n\n/* Task List */\n._pillar-task-list {\n list-style: none;\n padding: 0;\n margin: 8px 0;\n}\n\n._pillar-task-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n font-size: 13px;\n}\n\n._pillar-task-item--completed ._pillar-task-text {\n text-decoration: line-through;\n color: var(--pillar-text-placeholder, #9ca3af);\n}\n\n._pillar-task-checkbox {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n/* Code Block */\n._pillar-code-block {\n margin: 8px 0;\n border-radius: 8px;\n overflow: hidden;\n background: var(--pillar-bg-code, #1e1e1e);\n}\n\n._pillar-code-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n background: var(--pillar-bg-code-header, #2d2d2d);\n border-bottom: 1px solid var(--pillar-border-code, #404040);\n}\n\n._pillar-code-language {\n font-size: 11px;\n font-weight: 500;\n color: var(--pillar-text-code-header, #a0a0a0);\n text-transform: uppercase;\n}\n\n._pillar-code-copy {\n padding: 4px 8px;\n font-size: 11px;\n font-family: inherit;\n background: transparent;\n border: 1px solid var(--pillar-border-code, #404040);\n border-radius: 4px;\n color: var(--pillar-text-code-header, #a0a0a0);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n._pillar-code-copy:hover {\n background: var(--pillar-bg-code-hover, #404040);\n color: #fff;\n}\n\n._pillar-code-pre {\n margin: 0;\n padding: 12px;\n overflow-x: auto;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, monospace;\n font-size: 13px;\n line-height: 1.5;\n}\n\n._pillar-code-content {\n color: var(--pillar-text-code, #e0e0e0);\n}\n\n/* Action Buttons */\n._pillar-action-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n margin: 8px 0;\n}\n\n._pillar-action-button {\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n font-family: inherit;\n background: var(--pillar-primary, #2563eb);\n color: #fff;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n._pillar-action-button:hover {\n background: var(--pillar-primary-hover, #1d4ed8);\n}\n\n/* Progress Indicator */\n._pillar-progress-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 0;\n font-size: 13px;\n color: var(--pillar-text-secondary, #6b7280);\n}\n\n._pillar-progress-indicator--active ._pillar-loading-spinner {\n display: inline-block;\n}\n\n/* Streaming Thinking Content */\n._pillar-progress-row--streaming {\n margin: 2px 0;\n}\n\n._pillar-thinking-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 0;\n font-size: 13px;\n font-weight: 500;\n color: var(--pillar-text-secondary, #6b7280);\n}\n\n._pillar-thinking-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n}\n\n._pillar-spinner {\n width: 12px;\n height: 12px;\n border: 2px solid var(--pillar-border, #e5e7eb);\n border-top-color: var(--pillar-primary, #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._pillar-thinking-label {\n flex: 1;\n}\n\n._pillar-thinking-content {\n padding: 6px 10px;\n font-size: 13px;\n line-height: 1.4;\n color: var(--pillar-text-secondary, #6b7280);\n background: var(--pillar-bg-tertiary, #f9fafb);\n border-radius: 4px;\n margin-top: 2px;\n max-height: 150px;\n overflow-y: auto;\n}\n";
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Preact Markdown Renderer
3
+ *
4
+ * Converts markdown content to Preact vnodes using the marked lexer.
5
+ * Supports custom component substitution for special patterns.
6
+ */
7
+ import { VNode } from 'preact';
8
+ export interface PreactMarkdownProps {
9
+ content: string;
10
+ class?: string;
11
+ }
12
+ /**
13
+ * Render markdown content as Preact vnodes.
14
+ * Supports custom component markers in code blocks and HTML-like syntax.
15
+ */
16
+ export declare function PreactMarkdown({ content, class: className }: PreactMarkdownProps): VNode;
17
+ export declare const PREACT_MARKDOWN_STYLES = "\n/* Base markdown container */\n._pillar-markdown {\n font-size: 14px;\n line-height: 1.6;\n color: var(--pillar-text, #1a1a1a);\n}\n\n/* Headings */\n._pillar-md-heading {\n margin: 16px 0 8px 0;\n font-weight: 600;\n line-height: 1.3;\n}\n\n._pillar-md-h1 { font-size: 1.5em; }\n._pillar-md-h2 { font-size: 1.3em; }\n._pillar-md-h3 { font-size: 1.15em; }\n._pillar-md-h4 { font-size: 1em; }\n._pillar-md-h5 { font-size: 0.95em; }\n._pillar-md-h6 { font-size: 0.9em; }\n\n/* Paragraphs */\n._pillar-md-paragraph {\n margin: 8px 0;\n}\n\n/* Links */\n._pillar-md-link {\n color: var(--pillar-primary, #2563eb);\n text-decoration: none;\n}\n\n._pillar-md-link:hover {\n text-decoration: underline;\n}\n\n/* Inline code */\n._pillar-md-code-inline {\n padding: 2px 6px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, monospace;\n font-size: 0.9em;\n background: var(--pillar-bg-code-inline, #f3f4f6);\n border-radius: 4px;\n}\n\n/* Lists */\n._pillar-md-list {\n margin: 8px 0;\n padding-left: 24px;\n}\n\n._pillar-md-list-item {\n margin: 4px 0;\n}\n\n/* Task list items */\n._pillar-md-task-item {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n list-style: none;\n margin-left: -24px;\n}\n\n._pillar-md-task-checkbox {\n margin-top: 4px;\n}\n\n._pillar-md-task-text--checked {\n text-decoration: line-through;\n color: var(--pillar-text-placeholder, #9ca3af);\n}\n\n/* Blockquote */\n._pillar-md-blockquote {\n margin: 8px 0;\n padding: 8px 16px;\n border-left: 3px solid var(--pillar-border, #e5e7eb);\n color: var(--pillar-text-muted, #6b7280);\n background: var(--pillar-bg-secondary, #f9fafb);\n}\n\n/* Horizontal rule */\n._pillar-md-hr {\n margin: 16px 0;\n border: none;\n border-top: 1px solid var(--pillar-border, #e5e7eb);\n}\n\n/* Tables */\n._pillar-md-table-wrapper {\n overflow-x: auto;\n margin: 8px 0;\n}\n\n._pillar-md-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n._pillar-md-th,\n._pillar-md-td {\n padding: 8px 12px;\n border: 1px solid var(--pillar-border, #e5e7eb);\n text-align: left;\n}\n\n._pillar-md-th {\n background: var(--pillar-bg-secondary, #f9fafb);\n font-weight: 600;\n}\n\n/* Images */\n._pillar-md-image {\n max-width: 100%;\n height: auto;\n border-radius: 8px;\n margin: 8px 0;\n}\n";