@pillar-ai/react 0.1.12 → 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.
- package/dist/HelpButton.d.ts +62 -0
- package/dist/hooks/usePillarAction.d.ts +71 -0
- package/dist/hooks/usePillarRender.d.ts +101 -0
- package/dist/hooks/usePillarTasks.d.ts +59 -0
- package/dist/hooks/usePillarTool.d.ts +10 -7
- package/dist/index.esm.js +5 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HelpButton Component
|
|
3
|
+
* Pre-styled button to open the help panel
|
|
4
|
+
*
|
|
5
|
+
* Styling follows the dual-class pattern:
|
|
6
|
+
* - Internal class (_pillar-help-btn): Contains default styles
|
|
7
|
+
* - Public class (pillar-help-btn): Empty by default, for user overrides
|
|
8
|
+
*
|
|
9
|
+
* Supports CSS variable customization:
|
|
10
|
+
* - --pillar-btn-primary-bg
|
|
11
|
+
* - --pillar-btn-primary-color
|
|
12
|
+
* - --pillar-btn-secondary-bg
|
|
13
|
+
* - --pillar-btn-secondary-color
|
|
14
|
+
* - --pillar-btn-ghost-color
|
|
15
|
+
* - --pillar-btn-radius
|
|
16
|
+
* - --pillar-btn-font-family
|
|
17
|
+
*/
|
|
18
|
+
import { type ButtonHTMLAttributes, type ReactNode } from 'react';
|
|
19
|
+
export interface HelpButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {
|
|
20
|
+
/** Button content - defaults to "Help" */
|
|
21
|
+
children?: ReactNode;
|
|
22
|
+
/** What to open when clicked */
|
|
23
|
+
action?: 'toggle' | 'open' | 'chat' | 'search';
|
|
24
|
+
/** Initial search query (when action is 'search') */
|
|
25
|
+
searchQuery?: string;
|
|
26
|
+
/** Article slug to open (when action is 'open') */
|
|
27
|
+
articleSlug?: string;
|
|
28
|
+
/** Custom click handler (overrides action) */
|
|
29
|
+
onClick?: () => void;
|
|
30
|
+
/** Visual variant */
|
|
31
|
+
variant?: 'primary' | 'secondary' | 'ghost';
|
|
32
|
+
/** Button size */
|
|
33
|
+
size?: 'sm' | 'md' | 'lg';
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Pre-styled help button that integrates with Pillar
|
|
37
|
+
*
|
|
38
|
+
* Uses CSS classes for styling with CSS variable support:
|
|
39
|
+
* - Internal classes (_pillar-help-btn-*): Default styles
|
|
40
|
+
* - Public classes (pillar-help-btn-*): For user overrides
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* // Basic usage
|
|
45
|
+
* <HelpButton>Get Help</HelpButton>
|
|
46
|
+
*
|
|
47
|
+
* // Open chat directly
|
|
48
|
+
* <HelpButton action="chat">Ask AI</HelpButton>
|
|
49
|
+
*
|
|
50
|
+
* // Search with query
|
|
51
|
+
* <HelpButton action="search" searchQuery="getting started">
|
|
52
|
+
* Search Help
|
|
53
|
+
* </HelpButton>
|
|
54
|
+
*
|
|
55
|
+
* // Customize via CSS variables
|
|
56
|
+
* // :root { --pillar-btn-primary-bg: #8b5cf6; }
|
|
57
|
+
*
|
|
58
|
+
* // Or via public class overrides
|
|
59
|
+
* // .pillar-help-btn--primary { background: #8b5cf6; }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function HelpButton({ children, action, searchQuery, articleSlug, onClick: customOnClick, variant, size, style, disabled, className, ...props }: HelpButtonProps): JSX.Element;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* usePillarAction Hook
|
|
3
|
+
*
|
|
4
|
+
* Register one or more actions with co-located metadata and handlers.
|
|
5
|
+
* Actions are registered on mount and unregistered on unmount.
|
|
6
|
+
*
|
|
7
|
+
* @example Single action
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { usePillarAction } from '@pillar-ai/react';
|
|
10
|
+
*
|
|
11
|
+
* function CartButton() {
|
|
12
|
+
* usePillarAction({
|
|
13
|
+
* name: 'add_to_cart',
|
|
14
|
+
* description: 'Add a product to the shopping cart',
|
|
15
|
+
* inputSchema: {
|
|
16
|
+
* type: 'object',
|
|
17
|
+
* properties: {
|
|
18
|
+
* productId: { type: 'string', description: 'Product ID' },
|
|
19
|
+
* quantity: { type: 'number', description: 'Quantity to add' },
|
|
20
|
+
* },
|
|
21
|
+
* required: ['productId', 'quantity'],
|
|
22
|
+
* },
|
|
23
|
+
* execute: async ({ productId, quantity }) => {
|
|
24
|
+
* await cartApi.add(productId, quantity);
|
|
25
|
+
* return { content: [{ type: 'text', text: 'Added to cart' }] };
|
|
26
|
+
* },
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* return <button>Cart</button>;
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @example Multiple actions
|
|
34
|
+
* ```tsx
|
|
35
|
+
* import { usePillarAction } from '@pillar-ai/react';
|
|
36
|
+
*
|
|
37
|
+
* function BillingPage() {
|
|
38
|
+
* usePillarAction([
|
|
39
|
+
* {
|
|
40
|
+
* name: 'get_current_plan',
|
|
41
|
+
* description: 'Get the current billing plan',
|
|
42
|
+
* execute: async () => ({ plan: 'pro', price: 29 }),
|
|
43
|
+
* },
|
|
44
|
+
* {
|
|
45
|
+
* name: 'upgrade_plan',
|
|
46
|
+
* description: 'Upgrade to a higher plan',
|
|
47
|
+
* inputSchema: {
|
|
48
|
+
* type: 'object',
|
|
49
|
+
* properties: { planId: { type: 'string' } },
|
|
50
|
+
* required: ['planId'],
|
|
51
|
+
* },
|
|
52
|
+
* execute: async ({ planId }) => {
|
|
53
|
+
* await billingApi.upgrade(planId);
|
|
54
|
+
* return { content: [{ type: 'text', text: 'Upgraded!' }] };
|
|
55
|
+
* },
|
|
56
|
+
* },
|
|
57
|
+
* ]);
|
|
58
|
+
*
|
|
59
|
+
* return <div>Billing Content</div>;
|
|
60
|
+
* }
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
import type { ActionSchema } from '@pillar-ai/sdk';
|
|
64
|
+
/**
|
|
65
|
+
* Register a single Pillar action with co-located metadata and handler.
|
|
66
|
+
*/
|
|
67
|
+
export declare function usePillarAction<TInput = Record<string, unknown>>(schema: ActionSchema<TInput>): void;
|
|
68
|
+
/**
|
|
69
|
+
* Register multiple Pillar actions with co-located metadata and handlers.
|
|
70
|
+
*/
|
|
71
|
+
export declare function usePillarAction(schemas: ActionSchema[]): void;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* usePillarRender Hook
|
|
3
|
+
*
|
|
4
|
+
* Register a React component to render inline in the chat when the agent
|
|
5
|
+
* calls an `inline_ui` tool. The component receives data from the agent
|
|
6
|
+
* and can submit results back.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* import { usePillarRender, type PillarRenderProps } from '@pillar-ai/react';
|
|
11
|
+
*
|
|
12
|
+
* function InviteCard({ data, submit, cancel }: PillarRenderProps<{ emails: string[] }>) {
|
|
13
|
+
* const [emails, setEmails] = useState(data.emails || []);
|
|
14
|
+
* return (
|
|
15
|
+
* <div>
|
|
16
|
+
* <input
|
|
17
|
+
* value={emails.join(',')}
|
|
18
|
+
* onChange={(e) => setEmails(e.target.value.split(','))}
|
|
19
|
+
* />
|
|
20
|
+
* <button onClick={() => submit({ invited: emails })}>Send</button>
|
|
21
|
+
* <button onClick={cancel}>Cancel</button>
|
|
22
|
+
* </div>
|
|
23
|
+
* );
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* function TeamPage() {
|
|
27
|
+
* usePillarRender({
|
|
28
|
+
* name: 'invite_members',
|
|
29
|
+
* description: 'Show invite UI when user wants to add team members',
|
|
30
|
+
* inputSchema: {
|
|
31
|
+
* type: 'object',
|
|
32
|
+
* properties: { emails: { type: 'array', items: { type: 'string' } } },
|
|
33
|
+
* },
|
|
34
|
+
* render: InviteCard,
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* return <div>Team content...</div>;
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
import { type ComponentType } from 'react';
|
|
42
|
+
/**
|
|
43
|
+
* Props passed to the render component.
|
|
44
|
+
*
|
|
45
|
+
* @template TData - Type of the data extracted by the agent
|
|
46
|
+
*/
|
|
47
|
+
export interface PillarRenderProps<TData extends Record<string, unknown> = Record<string, unknown>> {
|
|
48
|
+
/** Data extracted by the agent from the conversation */
|
|
49
|
+
data: TData;
|
|
50
|
+
/** Submit result back to the agent. Call this when the user confirms/completes the action. */
|
|
51
|
+
submit: (result: unknown) => void;
|
|
52
|
+
/** Cancel/dismiss the UI. Call this when the user cancels the action. */
|
|
53
|
+
cancel: () => void;
|
|
54
|
+
/** Report loading/success/error states for visual feedback */
|
|
55
|
+
setStatus: (status: 'loading' | 'success' | 'error', message?: string) => void;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Schema for registering a render component.
|
|
59
|
+
*
|
|
60
|
+
* @template TData - Type of the data extracted by the agent
|
|
61
|
+
*/
|
|
62
|
+
export interface PillarRenderSchema<TData extends Record<string, unknown> = Record<string, unknown>> {
|
|
63
|
+
/**
|
|
64
|
+
* Unique name for this render context (e.g., 'invite_members').
|
|
65
|
+
* This becomes the card_type that the agent references.
|
|
66
|
+
*/
|
|
67
|
+
name: string;
|
|
68
|
+
/**
|
|
69
|
+
* Human-readable description for AI matching.
|
|
70
|
+
* Describes when the agent should use this UI.
|
|
71
|
+
*/
|
|
72
|
+
description: string;
|
|
73
|
+
/**
|
|
74
|
+
* Example user queries that should trigger this render context.
|
|
75
|
+
* Used for semantic matching alongside the description.
|
|
76
|
+
*/
|
|
77
|
+
examples?: string[];
|
|
78
|
+
/**
|
|
79
|
+
* JSON Schema for data extraction from user query.
|
|
80
|
+
* The agent will extract structured data from the conversation
|
|
81
|
+
* to populate the `data` prop passed to your component.
|
|
82
|
+
*/
|
|
83
|
+
inputSchema?: {
|
|
84
|
+
type: 'object';
|
|
85
|
+
properties: Record<string, unknown>;
|
|
86
|
+
required?: string[];
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* React component to render inline in the chat panel.
|
|
90
|
+
* Receives PillarRenderProps with data from the agent and callbacks.
|
|
91
|
+
*/
|
|
92
|
+
render: ComponentType<PillarRenderProps<TData>>;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Register a single render context.
|
|
96
|
+
*/
|
|
97
|
+
export declare function usePillarRender<TData extends Record<string, unknown> = Record<string, unknown>>(schema: PillarRenderSchema<TData>): void;
|
|
98
|
+
/**
|
|
99
|
+
* Register multiple render contexts.
|
|
100
|
+
*/
|
|
101
|
+
export declare function usePillarRender(schemas: PillarRenderSchema[]): void;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* usePillarTasks Hook
|
|
3
|
+
* Declarative bulk registration of task handlers with automatic cleanup.
|
|
4
|
+
*
|
|
5
|
+
* Replaces the manual useEffect + unsubscribers[] pattern with a single
|
|
6
|
+
* hook call that accepts a map of task name → handler.
|
|
7
|
+
*
|
|
8
|
+
* Uses a ref internally so handlers are always up-to-date without
|
|
9
|
+
* re-registering on every render. Re-registration only happens when
|
|
10
|
+
* the Pillar instance changes.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* import type { Actions } from '@/lib/pillar/actions';
|
|
15
|
+
*
|
|
16
|
+
* function MyTaskHandlers() {
|
|
17
|
+
* const router = useRouter();
|
|
18
|
+
*
|
|
19
|
+
* usePillarTasks<Actions>({
|
|
20
|
+
* open_settings: (data) => router.push('/settings'),
|
|
21
|
+
* open_knowledge: (data) => router.push('/knowledge'),
|
|
22
|
+
* update_brand_name: async (data) => {
|
|
23
|
+
* await api.updateBrandName(data.name);
|
|
24
|
+
* return { success: true };
|
|
25
|
+
* },
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* return null;
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
import type { SyncActionDefinitions, ActionDefinitions, ActionDataType, ActionNames } from '@pillar-ai/sdk';
|
|
33
|
+
/**
|
|
34
|
+
* Type-safe map of action names to handler functions.
|
|
35
|
+
*
|
|
36
|
+
* Known action names (from TActions) get typed `data` parameters with
|
|
37
|
+
* autocomplete. Arbitrary string keys are also accepted for ad-hoc tasks
|
|
38
|
+
* (e.g. "escalate", "navigate") that aren't in the actions definition.
|
|
39
|
+
*
|
|
40
|
+
* Uses an intersection of a mapped type (for typed keys) with a loose
|
|
41
|
+
* index signature (for ad-hoc keys). The index signature uses
|
|
42
|
+
* `(...args: any[]) => any` to avoid contravariance conflicts with
|
|
43
|
+
* typed handlers.
|
|
44
|
+
*/
|
|
45
|
+
export type TaskHandlerMap<TActions extends SyncActionDefinitions | ActionDefinitions> = {
|
|
46
|
+
[K in ActionNames<TActions>]?: (data: ActionDataType<TActions, K>) => void | unknown | Promise<void | unknown>;
|
|
47
|
+
} & {
|
|
48
|
+
[key: string]: ((...args: any[]) => any) | undefined;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Declaratively register multiple task handlers at once.
|
|
52
|
+
*
|
|
53
|
+
* Handlers are stored in a ref so they always reflect the latest
|
|
54
|
+
* closures without causing re-registration. The effect only re-runs
|
|
55
|
+
* when the Pillar SDK instance itself changes.
|
|
56
|
+
*
|
|
57
|
+
* @param tasks - Map of task name → handler function
|
|
58
|
+
*/
|
|
59
|
+
export declare function usePillarTasks<TActions extends SyncActionDefinitions | ActionDefinitions = SyncActionDefinitions>(tasks: TaskHandlerMap<TActions>): void;
|
|
@@ -60,14 +60,17 @@
|
|
|
60
60
|
* }
|
|
61
61
|
* ```
|
|
62
62
|
*/
|
|
63
|
-
import type { ToolSchema } from
|
|
63
|
+
import type { ToolSchema } from "@pillar-ai/sdk";
|
|
64
64
|
/**
|
|
65
|
-
* Register
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
*
|
|
65
|
+
* Register one or more Pillar tools with co-located metadata and handlers.
|
|
66
|
+
*
|
|
67
|
+
* The tools are registered when the component mounts and automatically
|
|
68
|
+
* unregistered when it unmounts. The `execute` functions always capture
|
|
69
|
+
* the latest React state and props via refs, so you don't need to worry
|
|
70
|
+
* about stale closures.
|
|
71
|
+
*
|
|
72
|
+
* @param schemaOrSchemas - Single tool schema or array of tool schemas
|
|
70
73
|
*/
|
|
71
|
-
export declare function usePillarTool(
|
|
74
|
+
export declare function usePillarTool(schemaOrSchemas: ToolSchema<any> | ToolSchema<any>[]): void;
|
|
72
75
|
/** @deprecated Use usePillarTool instead */
|
|
73
76
|
export declare const usePillarAction: typeof usePillarTool;
|
package/dist/index.esm.js
CHANGED
|
@@ -454,15 +454,17 @@ function usePillar() {
|
|
|
454
454
|
*
|
|
455
455
|
* @param schemaOrSchemas - Single tool schema or array of tool schemas
|
|
456
456
|
*/
|
|
457
|
-
function usePillarTool(
|
|
457
|
+
function usePillarTool(
|
|
458
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
459
|
+
schemaOrSchemas) {
|
|
458
460
|
const { pillar } = usePillarContext();
|
|
459
461
|
// Normalize to array for consistent handling
|
|
460
|
-
const schemas = useMemo(() =>
|
|
462
|
+
const schemas = useMemo(() => Array.isArray(schemaOrSchemas) ? schemaOrSchemas : [schemaOrSchemas], [schemaOrSchemas]);
|
|
461
463
|
// Keep refs to latest schemas so handlers capture current state/props
|
|
462
464
|
const schemasRef = useRef(schemas);
|
|
463
465
|
schemasRef.current = schemas;
|
|
464
466
|
// Stable dependency key for the effect (tool names joined)
|
|
465
|
-
const toolNamesKey = useMemo(() => schemas.map((s) => s.name).join(
|
|
467
|
+
const toolNamesKey = useMemo(() => schemas.map((s) => s.name).join(","), [schemas]);
|
|
466
468
|
useEffect(() => {
|
|
467
469
|
if (!pillar)
|
|
468
470
|
return;
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../src/PillarProvider.tsx","../src/PillarPanel.tsx","../src/hooks/useHelpPanel.ts","../src/hooks/usePillar.ts","../src/hooks/usePillarTool.ts"],"sourcesContent":["/**\n * PillarProvider\n * Context provider that initializes and manages the Pillar SDK\n */\n\nimport {\n Pillar,\n scanPageDirect,\n type CardCallbacks,\n type CompactScanResult,\n type PillarConfig,\n type PillarEvents,\n type PillarState,\n type ScanOptions,\n type TaskExecutePayload,\n type ThemeConfig,\n} from \"@pillar-ai/sdk\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentType,\n type ReactNode,\n} from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\n\n// ============================================================================\n// Card Types\n// ============================================================================\n\n/**\n * Props passed to custom card components.\n */\nexport interface CardComponentProps<T = Record<string, unknown>> {\n /** Data extracted by the AI for this action */\n data: T;\n /** Called when user confirms the action */\n onConfirm: (modifiedData?: Record<string, unknown>) => void;\n /** Called when user cancels the action */\n onCancel: () => void;\n /** Called to report state changes (loading, success, error) */\n onStateChange?: (\n state: \"loading\" | \"success\" | \"error\",\n message?: string\n ) => void;\n}\n\n/**\n * A React component that can be used as a custom card renderer.\n */\nexport type CardComponent<T = Record<string, unknown>> = ComponentType<\n CardComponentProps<T>\n>;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PillarContextValue {\n /** The Pillar SDK instance */\n pillar: Pillar | null;\n\n /** Current SDK state */\n state: PillarState;\n\n /** Whether the SDK is ready */\n isReady: boolean;\n\n /** Whether the panel is currently open */\n isPanelOpen: boolean;\n\n /** Open the help panel */\n open: (options?: {\n view?: string;\n article?: string;\n search?: string;\n focusInput?: boolean;\n }) => void;\n\n /** Close the help panel */\n close: () => void;\n\n /** Toggle the help panel */\n toggle: () => void;\n\n /** Open a specific article */\n openArticle: (slug: string) => void;\n\n /** Open a specific category */\n openCategory: (slug: string) => Promise<void>;\n\n /** Perform a search */\n search: (query: string) => void;\n\n /** Navigate to a specific view */\n navigate: (view: string, params?: Record<string, string>) => void;\n\n /** Update the panel theme at runtime */\n setTheme: (theme: Partial<ThemeConfig>) => void;\n\n /** Enable or disable the text selection \"Ask AI\" popover */\n setTextSelectionEnabled: (enabled: boolean) => void;\n\n /**\n * Enable or disable DOM scanning.\n * @deprecated DOM scanning is currently disabled and this method has no effect.\n */\n setDOMScanningEnabled: (enabled: boolean) => void;\n\n /**\n * Whether DOM scanning is enabled.\n * @deprecated Always returns false - DOM scanning is disabled.\n */\n isDOMScanningEnabled: boolean;\n\n /** Manually scan the page and get the compact result */\n scanPage: (options?: ScanOptions) => CompactScanResult | null;\n\n /** Subscribe to SDK events */\n on: <K extends keyof PillarEvents>(\n event: K,\n callback: (data: PillarEvents[K]) => void\n ) => () => void;\n}\n\nexport interface PillarProviderProps {\n /**\n * Your product key from the Pillar app.\n * Get it at app.trypillar.com\n */\n productKey?: string;\n\n /**\n * @deprecated Use `productKey` instead. Will be removed in v1.0.\n */\n helpCenter?: string;\n\n /**\n * Additional SDK configuration\n *\n * Notable options:\n * - `panel.useShadowDOM`: Whether to isolate styles in Shadow DOM (default: false).\n * Set to false to let custom cards inherit your app's CSS (Tailwind, etc.)\n */\n config?: Omit<PillarConfig, \"productKey\" | \"helpCenter\">;\n\n /**\n * Handler called when a task action is triggered from the chat.\n * Use this to handle AI-suggested actions like opening modals, navigating, etc.\n *\n * @example\n * ```tsx\n * <PillarProvider\n * productKey=\"my-product-key\"\n * onTask={(task) => {\n * switch (task.name) {\n * case 'invite_team_member':\n * openInviteModal(task.data);\n * break;\n * case 'open_settings':\n * router.push('/settings');\n * break;\n * }\n * }}\n * >\n * ```\n */\n onTask?: (task: TaskExecutePayload) => void;\n\n /**\n * Custom card components to render for inline_ui type actions.\n * Map card type names to React components that will render the inline UI.\n *\n * @example\n * ```tsx\n * import { InviteMembersCard } from './cards/InviteMembersCard';\n *\n * <PillarProvider\n * productKey=\"my-product-key\"\n * cards={{\n * invite_members: InviteMembersCard,\n * confirm_delete: ConfirmDeleteCard,\n * }}\n * >\n * ```\n */\n cards?: Record<string, CardComponent>;\n\n /**\n * Enable DOM scanning to send page context with messages.\n * @deprecated DOM scanning is currently disabled. This prop has no effect.\n */\n domScanning?: boolean;\n\n /**\n * Enable DOM scanning dev mode to preview the scanned page before sending.\n * Shows a modal with the AST tree visualization before each message is sent.\n * Useful for debugging what context will be sent to the LLM.\n /** Children components */\n children: ReactNode;\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst PillarContext = createContext<PillarContextValue | null>(null);\n\n// ============================================================================\n// Provider Component\n// ============================================================================\n\nexport function PillarProvider({\n productKey,\n helpCenter,\n config,\n onTask,\n cards,\n domScanning: _domScanning, // Deprecated - DOM scanning is disabled\n children,\n}: PillarProviderProps): React.ReactElement {\n const [pillar, setPillar] = useState<Pillar | null>(null);\n const [state, setState] = useState<PillarState>(\"uninitialized\");\n const [isPanelOpen, setIsPanelOpen] = useState(false);\n // DOM scanning is disabled - always false\n const isDOMScanningEnabled = false;\n\n // Support both productKey (new) and helpCenter (deprecated)\n const resolvedKey = productKey ?? helpCenter;\n\n // Keep a ref to the latest onTask callback to avoid re-subscribing\n const onTaskRef = useRef(onTask);\n onTaskRef.current = onTask;\n\n // Warn about deprecated helpCenter usage\n useEffect(() => {\n if (helpCenter && !productKey) {\n console.warn(\n '[Pillar React] \"helpCenter\" prop is deprecated. Use \"productKey\" instead.'\n );\n }\n }, []);\n\n // Keep a ref to cards to access latest versions\n const cardsRef = useRef(cards);\n cardsRef.current = cards;\n\n // Initialize SDK\n useEffect(() => {\n let mounted = true;\n\n const initPillar = async () => {\n try {\n // Pillar is a singleton - check if already initialized\n const existingInstance = Pillar.getInstance();\n if (existingInstance) {\n // Reuse existing instance (preserves chat history, panel state, etc.)\n if (mounted) {\n setPillar(existingInstance);\n setState(existingInstance.state);\n\n // Re-subscribe to events\n existingInstance.on(\"panel:open\", () => {\n setIsPanelOpen(true);\n });\n\n existingInstance.on(\"panel:close\", () => {\n setIsPanelOpen(false);\n });\n }\n return;\n }\n\n // Initialize new instance\n // Note: DOM scanning is disabled, config.domScanning is ignored\n const instance = await Pillar.init({\n productKey: resolvedKey,\n ...config,\n });\n\n if (mounted) {\n setPillar(instance);\n setState(instance.state);\n\n // Listen for panel open/close\n instance.on(\"panel:open\", () => {\n setIsPanelOpen(true);\n });\n\n instance.on(\"panel:close\", () => {\n setIsPanelOpen(false);\n });\n }\n } catch (error) {\n console.error(\"[Pillar React] Failed to initialize:\", error);\n if (mounted) {\n setState(\"error\");\n }\n }\n };\n\n initPillar();\n\n // Cleanup - DON'T destroy the singleton on unmount\n // This preserves conversation history and panel state across navigation\n // Pillar.destroy() should only be called explicitly when the app unmounts completely\n return () => {\n mounted = false;\n // Note: We intentionally don't call Pillar.destroy() here\n // The singleton persists to maintain state across route changes\n };\n }, [resolvedKey]); // Re-initialize if productKey changes\n\n // Update state when SDK state changes\n useEffect(() => {\n if (pillar) {\n const unsubscribe = pillar.on(\"ready\", () => {\n setState(\"ready\");\n });\n\n const unsubscribeError = pillar.on(\"error\", () => {\n setState(\"error\");\n });\n\n return () => {\n unsubscribe();\n unsubscribeError();\n };\n }\n }, [pillar]);\n\n // Register task handler\n useEffect(() => {\n if (pillar) {\n const unsubscribe = pillar.on(\"task:execute\", (task) => {\n onTaskRef.current?.(task);\n });\n\n return unsubscribe;\n }\n }, [pillar]);\n\n // DOM scanning is disabled - no sync needed\n\n // Register custom card renderers\n useEffect(() => {\n if (!pillar || !cards) return;\n\n const unsubscribers: Array<() => void> = [];\n const roots: Map<HTMLElement, Root> = new Map();\n\n // Register each card component as a vanilla renderer\n Object.entries(cards).forEach(([cardType, Component]) => {\n const unsubscribe = pillar.registerCard(\n cardType,\n (container, data, callbacks: CardCallbacks) => {\n // Create a React root for this container\n const root = createRoot(container);\n roots.set(container, root);\n\n // Render the React component\n root.render(\n <Component\n data={data}\n onConfirm={callbacks.onConfirm}\n onCancel={callbacks.onCancel}\n onStateChange={callbacks.onStateChange}\n />\n );\n\n // Return cleanup function\n return () => {\n const existingRoot = roots.get(container);\n if (existingRoot) {\n existingRoot.unmount();\n roots.delete(container);\n }\n };\n }\n );\n\n unsubscribers.push(unsubscribe);\n });\n\n return () => {\n // Cleanup all registrations\n unsubscribers.forEach((unsub) => unsub());\n // Unmount all React roots\n roots.forEach((root) => root.unmount());\n roots.clear();\n };\n }, [pillar, cards]);\n\n // Actions\n const open = useCallback(\n (options?: {\n view?: string;\n article?: string;\n search?: string;\n focusInput?: boolean;\n }) => {\n pillar?.open(options);\n },\n [pillar]\n );\n\n const close = useCallback(() => {\n pillar?.close();\n }, [pillar]);\n\n const toggle = useCallback(() => {\n pillar?.toggle();\n }, [pillar]);\n\n const openArticle = useCallback(\n (slug: string) => {\n pillar?.open({ article: slug });\n },\n [pillar]\n );\n\n const openCategory = useCallback(\n async (slug: string) => {\n pillar?.navigate(\"category\", { slug });\n },\n [pillar]\n );\n\n const search = useCallback(\n (query: string) => {\n pillar?.open({ search: query });\n },\n [pillar]\n );\n\n const navigate = useCallback(\n (view: string, params?: Record<string, string>) => {\n pillar?.navigate(view, params);\n },\n [pillar]\n );\n\n const setTheme = useCallback(\n (theme: Partial<ThemeConfig>) => {\n pillar?.setTheme(theme);\n },\n [pillar]\n );\n\n const setTextSelectionEnabled = useCallback(\n (enabled: boolean) => {\n pillar?.setTextSelectionEnabled(enabled);\n },\n [pillar]\n );\n\n // DOM scanning is disabled - this is a no-op\n const setDOMScanningEnabled = useCallback(\n (_enabled: boolean) => {\n // DOM scanning is disabled - this method has no effect\n },\n []\n );\n\n const scanPage = useCallback(\n (options?: ScanOptions): CompactScanResult | null => {\n if (!pillar) return null;\n return scanPageDirect(options);\n },\n [pillar]\n );\n\n const on = useCallback(\n <K extends keyof PillarEvents>(\n event: K,\n callback: (data: PillarEvents[K]) => void\n ) => {\n return pillar?.on(event, callback) ?? (() => {});\n },\n [pillar]\n );\n\n // Context value\n const value = useMemo<PillarContextValue>(\n () => ({\n pillar,\n state,\n isReady: state === \"ready\",\n isPanelOpen,\n open,\n close,\n toggle,\n openArticle,\n openCategory,\n search,\n navigate,\n setTheme,\n setTextSelectionEnabled,\n setDOMScanningEnabled,\n isDOMScanningEnabled,\n scanPage,\n on,\n }),\n [\n pillar,\n state,\n isPanelOpen,\n open,\n close,\n toggle,\n openArticle,\n openCategory,\n search,\n navigate,\n setTheme,\n setTextSelectionEnabled,\n setDOMScanningEnabled,\n isDOMScanningEnabled,\n scanPage,\n on,\n ]\n );\n\n return (\n <PillarContext.Provider value={value}>{children}</PillarContext.Provider>\n );\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function usePillarContext(): PillarContextValue {\n const context = useContext(PillarContext);\n\n if (!context) {\n throw new Error(\"usePillarContext must be used within a PillarProvider\");\n }\n\n return context;\n}\n","/**\n * PillarPanel Component\n * Renders the Pillar help panel at a custom location in the DOM\n */\n\nimport React, { useRef, useEffect, type CSSProperties, type HTMLAttributes } from 'react';\nimport { usePillarContext } from './PillarProvider';\n\nexport interface PillarPanelProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name for the container */\n className?: string;\n \n /** Custom inline styles for the container */\n style?: CSSProperties;\n}\n\n/**\n * Renders the Pillar help panel at a custom location in the DOM.\n * Use this when you want to control where the panel is rendered instead of\n * having it automatically appended to document.body.\n * \n * **Important**: When using this component, set `panel.container: 'manual'` in your\n * PillarProvider config to prevent automatic mounting.\n * \n * @example\n * ```tsx\n * <PillarProvider \n * productKey=\"my-product-key\"\n * config={{ panel: { container: 'manual' } }}\n * >\n * <div className=\"my-layout\">\n * <Sidebar />\n * <PillarPanel className=\"help-panel-container\" />\n * <MainContent />\n * </div>\n * </PillarProvider>\n * ```\n */\nexport function PillarPanel({ \n className, \n style,\n ...props \n}: PillarPanelProps): React.ReactElement {\n const containerRef = useRef<HTMLDivElement>(null);\n const { pillar, isReady } = usePillarContext();\n const hasMounted = useRef(false);\n\n useEffect(() => {\n // Only mount once when SDK is ready and we have a container\n if (!isReady || !pillar || !containerRef.current || hasMounted.current) {\n return;\n }\n\n // Mount the panel into our container\n pillar.mountPanelTo(containerRef.current);\n hasMounted.current = true;\n\n // Cleanup is handled by Pillar.destroy() in the provider\n }, [isReady, pillar]);\n\n return (\n <div \n ref={containerRef} \n className={className}\n style={style}\n data-pillar-panel-container=\"\"\n {...props}\n />\n );\n}\n\n","/**\n * useHelpPanel Hook\n * Panel-specific controls and state\n */\n\nimport { useCallback } from 'react';\nimport { usePillarContext } from '../PillarProvider';\n\nexport interface UseHelpPanelResult {\n /** Whether the panel is currently open */\n isOpen: boolean;\n \n /** Open the panel */\n open: (options?: { view?: string; article?: string; search?: string }) => void;\n \n /** Close the panel */\n close: () => void;\n \n /** Toggle the panel */\n toggle: () => void;\n \n /** Open a specific article in the panel */\n openArticle: (slug: string) => void;\n \n /** Open a specific category in the panel */\n openCategory: (slug: string) => Promise<void>;\n \n /** Open search with a query */\n openSearch: (query?: string) => void;\n \n /** Open the AI chat */\n openChat: () => void;\n}\n\n/**\n * Hook for panel-specific controls\n * \n * @example\n * ```tsx\n * function HelpButton() {\n * const { isOpen, toggle, openChat } = useHelpPanel();\n * \n * return (\n * <div>\n * <button onClick={toggle}>\n * {isOpen ? 'Close' : 'Help'}\n * </button>\n * <button onClick={openChat}>\n * Ask AI\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useHelpPanel(): UseHelpPanelResult {\n const { isPanelOpen, open, close, toggle, openArticle, openCategory, search, navigate } = usePillarContext();\n\n const openSearch = useCallback(\n (query?: string) => {\n if (query) {\n search(query);\n } else {\n open({ view: 'search' });\n }\n },\n [search, open]\n );\n\n const openChat = useCallback(() => {\n navigate('chat');\n }, [navigate]);\n\n return {\n isOpen: isPanelOpen,\n open,\n close,\n toggle,\n openArticle,\n openCategory,\n openSearch,\n openChat,\n };\n}\n\n","/**\n * usePillar Hook\n * Access Pillar SDK instance and state with optional type-safe onTask\n */\n\nimport type {\n SyncActionDefinitions,\n ActionDefinitions,\n ActionDataType,\n ActionNames,\n} from '@pillar-ai/sdk';\nimport { useCallback } from 'react';\nimport { usePillarContext, type PillarContextValue } from '../PillarProvider';\n\nexport type UsePillarResult = PillarContextValue;\n\n/**\n * Extended result with type-safe onTask method.\n *\n * @template TActions - The action definitions for type inference\n */\nexport interface TypedUsePillarResult<\n TActions extends SyncActionDefinitions | ActionDefinitions,\n> extends Omit<PillarContextValue, 'pillar'> {\n pillar: PillarContextValue['pillar'];\n /**\n * Type-safe task handler registration.\n *\n * @param taskName - The action name (autocompleted from your actions)\n * @param handler - Handler function with typed data parameter\n * @returns Unsubscribe function\n */\n onTask: <TName extends ActionNames<TActions>>(\n taskName: TName,\n handler: (data: ActionDataType<TActions, TName>) => void\n ) => () => void;\n}\n\n/**\n * Hook to access the Pillar SDK instance and state\n *\n * @example Basic usage (untyped)\n * ```tsx\n * function MyComponent() {\n * const { isReady, open, close, isPanelOpen } = usePillar();\n *\n * if (!isReady) return <div>Loading...</div>;\n *\n * return (\n * <button onClick={() => open()}>\n * {isPanelOpen ? 'Close Help' : 'Get Help'}\n * </button>\n * );\n * }\n * ```\n *\n * @example Type-safe onTask with action definitions\n * ```tsx\n * import { actions } from '@/lib/pillar/actions';\n *\n * function MyComponent() {\n * const { pillar, onTask } = usePillar<typeof actions>();\n *\n * useEffect(() => {\n * // TypeScript knows data has { type, url, name }\n * const unsub = onTask('add_new_source', (data) => {\n * console.log(data.url); // ✓ Typed!\n * });\n * return unsub;\n * }, [onTask]);\n * }\n * ```\n */\nexport function usePillar<\n TActions extends SyncActionDefinitions | ActionDefinitions = SyncActionDefinitions,\n>(): TypedUsePillarResult<TActions> {\n const context = usePillarContext();\n\n // Create a type-safe wrapper around pillar.onTask\n const onTask = useCallback(\n <TName extends ActionNames<TActions>>(\n taskName: TName,\n handler: (data: ActionDataType<TActions, TName>) => void\n ): (() => void) => {\n if (!context.pillar) {\n // Return no-op if pillar not ready\n return () => {};\n }\n // Cast handler to match the SDK's expected type\n // The runtime behavior is the same, this is just for type narrowing\n return context.pillar.onTask(\n taskName as string,\n handler as (data: Record<string, unknown>) => void\n );\n },\n [context.pillar]\n );\n\n return {\n ...context,\n onTask,\n };\n}\n\n","/**\n * usePillarTool Hook\n *\n * Register one or more tools with co-located metadata and handlers.\n * Tools are registered on mount and unregistered on unmount.\n *\n * @example Single tool\n * ```tsx\n * import { usePillarTool } from '@pillar-ai/react';\n *\n * function CartButton() {\n * usePillarTool({\n * name: 'add_to_cart',\n * description: 'Add a product to the shopping cart',\n * inputSchema: {\n * type: 'object',\n * properties: {\n * productId: { type: 'string', description: 'Product ID' },\n * quantity: { type: 'number', description: 'Quantity to add' },\n * },\n * required: ['productId', 'quantity'],\n * },\n * execute: async ({ productId, quantity }) => {\n * await cartApi.add(productId, quantity);\n * return { content: [{ type: 'text', text: 'Added to cart' }] };\n * },\n * });\n *\n * return <button>Cart</button>;\n * }\n * ```\n *\n * @example Multiple tools\n * ```tsx\n * import { usePillarTool } from '@pillar-ai/react';\n *\n * function BillingPage() {\n * usePillarTool([\n * {\n * name: 'get_current_plan',\n * description: 'Get the current billing plan',\n * execute: async () => ({ plan: 'pro', price: 29 }),\n * },\n * {\n * name: 'upgrade_plan',\n * description: 'Upgrade to a higher plan',\n * inputSchema: {\n * type: 'object',\n * properties: { planId: { type: 'string' } },\n * required: ['planId'],\n * },\n * execute: async ({ planId }) => {\n * await billingApi.upgrade(planId);\n * return { content: [{ type: 'text', text: 'Upgraded!' }] };\n * },\n * },\n * ]);\n *\n * return <div>Billing Content</div>;\n * }\n * ```\n */\n\nimport { useEffect, useRef, useMemo } from 'react';\nimport type { ToolSchema } from '@pillar-ai/sdk';\nimport { usePillarContext } from '../PillarProvider';\n\n/**\n * Register a single Pillar tool with co-located metadata and handler.\n */\nexport function usePillarTool<TInput = Record<string, unknown>>(\n schema: ToolSchema<TInput>\n): void;\n\n/**\n * Register multiple Pillar tools with co-located metadata and handlers.\n */\nexport function usePillarTool(schemas: ToolSchema[]): void;\n\n/**\n * Register one or more Pillar tools with co-located metadata and handlers.\n *\n * The tools are registered when the component mounts and automatically\n * unregistered when it unmounts. The `execute` functions always capture\n * the latest React state and props via refs, so you don't need to worry\n * about stale closures.\n *\n * @param schemaOrSchemas - Single tool schema or array of tool schemas\n */\nexport function usePillarTool<TInput = Record<string, unknown>>(\n schemaOrSchemas: ToolSchema<TInput> | ToolSchema[]\n): void {\n const { pillar } = usePillarContext();\n\n // Normalize to array for consistent handling\n const schemas = useMemo(\n () => (Array.isArray(schemaOrSchemas) ? schemaOrSchemas : [schemaOrSchemas]),\n [schemaOrSchemas]\n );\n\n // Keep refs to latest schemas so handlers capture current state/props\n const schemasRef = useRef(schemas);\n schemasRef.current = schemas;\n\n // Stable dependency key for the effect (tool names joined)\n const toolNamesKey = useMemo(\n () => schemas.map((s) => s.name).join(','),\n [schemas]\n );\n\n useEffect(() => {\n if (!pillar) return;\n\n // Register all tools and collect unsubscribe functions\n const unsubscribes = schemasRef.current.map((schema, index) => {\n return pillar.defineTool({\n ...schema,\n // Wrap execute to always use the latest ref version\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n execute: (input: any) => schemasRef.current[index].execute(input),\n } as ToolSchema);\n });\n\n // Cleanup: unregister all tools\n return () => {\n unsubscribes.forEach((unsub) => unsub());\n };\n }, [pillar, toolNamesKey]);\n}\n\n/** @deprecated Use usePillarTool instead */\nexport const usePillarAction = usePillarTool;\n"],"names":["_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/PillarProvider.tsx","../src/PillarPanel.tsx","../src/hooks/useHelpPanel.ts","../src/hooks/usePillar.ts","../src/hooks/usePillarTool.ts"],"sourcesContent":["/**\n * PillarProvider\n * Context provider that initializes and manages the Pillar SDK\n */\n\nimport {\n Pillar,\n scanPageDirect,\n type CardCallbacks,\n type CompactScanResult,\n type PillarConfig,\n type PillarEvents,\n type PillarState,\n type ScanOptions,\n type TaskExecutePayload,\n type ThemeConfig,\n} from \"@pillar-ai/sdk\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentType,\n type ReactNode,\n} from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\n\n// ============================================================================\n// Card Types\n// ============================================================================\n\n/**\n * Props passed to custom card components.\n */\nexport interface CardComponentProps<T = Record<string, unknown>> {\n /** Data extracted by the AI for this action */\n data: T;\n /** Called when user confirms the action */\n onConfirm: (modifiedData?: Record<string, unknown>) => void;\n /** Called when user cancels the action */\n onCancel: () => void;\n /** Called to report state changes (loading, success, error) */\n onStateChange?: (\n state: \"loading\" | \"success\" | \"error\",\n message?: string\n ) => void;\n}\n\n/**\n * A React component that can be used as a custom card renderer.\n */\nexport type CardComponent<T = Record<string, unknown>> = ComponentType<\n CardComponentProps<T>\n>;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PillarContextValue {\n /** The Pillar SDK instance */\n pillar: Pillar | null;\n\n /** Current SDK state */\n state: PillarState;\n\n /** Whether the SDK is ready */\n isReady: boolean;\n\n /** Whether the panel is currently open */\n isPanelOpen: boolean;\n\n /** Open the help panel */\n open: (options?: {\n view?: string;\n article?: string;\n search?: string;\n focusInput?: boolean;\n }) => void;\n\n /** Close the help panel */\n close: () => void;\n\n /** Toggle the help panel */\n toggle: () => void;\n\n /** Open a specific article */\n openArticle: (slug: string) => void;\n\n /** Open a specific category */\n openCategory: (slug: string) => Promise<void>;\n\n /** Perform a search */\n search: (query: string) => void;\n\n /** Navigate to a specific view */\n navigate: (view: string, params?: Record<string, string>) => void;\n\n /** Update the panel theme at runtime */\n setTheme: (theme: Partial<ThemeConfig>) => void;\n\n /** Enable or disable the text selection \"Ask AI\" popover */\n setTextSelectionEnabled: (enabled: boolean) => void;\n\n /**\n * Enable or disable DOM scanning.\n * @deprecated DOM scanning is currently disabled and this method has no effect.\n */\n setDOMScanningEnabled: (enabled: boolean) => void;\n\n /**\n * Whether DOM scanning is enabled.\n * @deprecated Always returns false - DOM scanning is disabled.\n */\n isDOMScanningEnabled: boolean;\n\n /** Manually scan the page and get the compact result */\n scanPage: (options?: ScanOptions) => CompactScanResult | null;\n\n /** Subscribe to SDK events */\n on: <K extends keyof PillarEvents>(\n event: K,\n callback: (data: PillarEvents[K]) => void\n ) => () => void;\n}\n\nexport interface PillarProviderProps {\n /**\n * Your product key from the Pillar app.\n * Get it at app.trypillar.com\n */\n productKey?: string;\n\n /**\n * @deprecated Use `productKey` instead. Will be removed in v1.0.\n */\n helpCenter?: string;\n\n /**\n * Additional SDK configuration\n *\n * Notable options:\n * - `panel.useShadowDOM`: Whether to isolate styles in Shadow DOM (default: false).\n * Set to false to let custom cards inherit your app's CSS (Tailwind, etc.)\n */\n config?: Omit<PillarConfig, \"productKey\" | \"helpCenter\">;\n\n /**\n * Handler called when a task action is triggered from the chat.\n * Use this to handle AI-suggested actions like opening modals, navigating, etc.\n *\n * @example\n * ```tsx\n * <PillarProvider\n * productKey=\"my-product-key\"\n * onTask={(task) => {\n * switch (task.name) {\n * case 'invite_team_member':\n * openInviteModal(task.data);\n * break;\n * case 'open_settings':\n * router.push('/settings');\n * break;\n * }\n * }}\n * >\n * ```\n */\n onTask?: (task: TaskExecutePayload) => void;\n\n /**\n * Custom card components to render for inline_ui type actions.\n * Map card type names to React components that will render the inline UI.\n *\n * @example\n * ```tsx\n * import { InviteMembersCard } from './cards/InviteMembersCard';\n *\n * <PillarProvider\n * productKey=\"my-product-key\"\n * cards={{\n * invite_members: InviteMembersCard,\n * confirm_delete: ConfirmDeleteCard,\n * }}\n * >\n * ```\n */\n cards?: Record<string, CardComponent>;\n\n /**\n * Enable DOM scanning to send page context with messages.\n * @deprecated DOM scanning is currently disabled. This prop has no effect.\n */\n domScanning?: boolean;\n\n /**\n * Enable DOM scanning dev mode to preview the scanned page before sending.\n * Shows a modal with the AST tree visualization before each message is sent.\n * Useful for debugging what context will be sent to the LLM.\n /** Children components */\n children: ReactNode;\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst PillarContext = createContext<PillarContextValue | null>(null);\n\n// ============================================================================\n// Provider Component\n// ============================================================================\n\nexport function PillarProvider({\n productKey,\n helpCenter,\n config,\n onTask,\n cards,\n domScanning: _domScanning, // Deprecated - DOM scanning is disabled\n children,\n}: PillarProviderProps): React.ReactElement {\n const [pillar, setPillar] = useState<Pillar | null>(null);\n const [state, setState] = useState<PillarState>(\"uninitialized\");\n const [isPanelOpen, setIsPanelOpen] = useState(false);\n // DOM scanning is disabled - always false\n const isDOMScanningEnabled = false;\n\n // Support both productKey (new) and helpCenter (deprecated)\n const resolvedKey = productKey ?? helpCenter;\n\n // Keep a ref to the latest onTask callback to avoid re-subscribing\n const onTaskRef = useRef(onTask);\n onTaskRef.current = onTask;\n\n // Warn about deprecated helpCenter usage\n useEffect(() => {\n if (helpCenter && !productKey) {\n console.warn(\n '[Pillar React] \"helpCenter\" prop is deprecated. Use \"productKey\" instead.'\n );\n }\n }, []);\n\n // Keep a ref to cards to access latest versions\n const cardsRef = useRef(cards);\n cardsRef.current = cards;\n\n // Initialize SDK\n useEffect(() => {\n let mounted = true;\n\n const initPillar = async () => {\n try {\n // Pillar is a singleton - check if already initialized\n const existingInstance = Pillar.getInstance();\n if (existingInstance) {\n // Reuse existing instance (preserves chat history, panel state, etc.)\n if (mounted) {\n setPillar(existingInstance);\n setState(existingInstance.state);\n\n // Re-subscribe to events\n existingInstance.on(\"panel:open\", () => {\n setIsPanelOpen(true);\n });\n\n existingInstance.on(\"panel:close\", () => {\n setIsPanelOpen(false);\n });\n }\n return;\n }\n\n // Initialize new instance\n // Note: DOM scanning is disabled, config.domScanning is ignored\n const instance = await Pillar.init({\n productKey: resolvedKey,\n ...config,\n });\n\n if (mounted) {\n setPillar(instance);\n setState(instance.state);\n\n // Listen for panel open/close\n instance.on(\"panel:open\", () => {\n setIsPanelOpen(true);\n });\n\n instance.on(\"panel:close\", () => {\n setIsPanelOpen(false);\n });\n }\n } catch (error) {\n console.error(\"[Pillar React] Failed to initialize:\", error);\n if (mounted) {\n setState(\"error\");\n }\n }\n };\n\n initPillar();\n\n // Cleanup - DON'T destroy the singleton on unmount\n // This preserves conversation history and panel state across navigation\n // Pillar.destroy() should only be called explicitly when the app unmounts completely\n return () => {\n mounted = false;\n // Note: We intentionally don't call Pillar.destroy() here\n // The singleton persists to maintain state across route changes\n };\n }, [resolvedKey]); // Re-initialize if productKey changes\n\n // Update state when SDK state changes\n useEffect(() => {\n if (pillar) {\n const unsubscribe = pillar.on(\"ready\", () => {\n setState(\"ready\");\n });\n\n const unsubscribeError = pillar.on(\"error\", () => {\n setState(\"error\");\n });\n\n return () => {\n unsubscribe();\n unsubscribeError();\n };\n }\n }, [pillar]);\n\n // Register task handler\n useEffect(() => {\n if (pillar) {\n const unsubscribe = pillar.on(\"task:execute\", (task) => {\n onTaskRef.current?.(task);\n });\n\n return unsubscribe;\n }\n }, [pillar]);\n\n // DOM scanning is disabled - no sync needed\n\n // Register custom card renderers\n useEffect(() => {\n if (!pillar || !cards) return;\n\n const unsubscribers: Array<() => void> = [];\n const roots: Map<HTMLElement, Root> = new Map();\n\n // Register each card component as a vanilla renderer\n Object.entries(cards).forEach(([cardType, Component]) => {\n const unsubscribe = pillar.registerCard(\n cardType,\n (container, data, callbacks: CardCallbacks) => {\n // Create a React root for this container\n const root = createRoot(container);\n roots.set(container, root);\n\n // Render the React component\n root.render(\n <Component\n data={data}\n onConfirm={callbacks.onConfirm}\n onCancel={callbacks.onCancel}\n onStateChange={callbacks.onStateChange}\n />\n );\n\n // Return cleanup function\n return () => {\n const existingRoot = roots.get(container);\n if (existingRoot) {\n existingRoot.unmount();\n roots.delete(container);\n }\n };\n }\n );\n\n unsubscribers.push(unsubscribe);\n });\n\n return () => {\n // Cleanup all registrations\n unsubscribers.forEach((unsub) => unsub());\n // Unmount all React roots\n roots.forEach((root) => root.unmount());\n roots.clear();\n };\n }, [pillar, cards]);\n\n // Actions\n const open = useCallback(\n (options?: {\n view?: string;\n article?: string;\n search?: string;\n focusInput?: boolean;\n }) => {\n pillar?.open(options);\n },\n [pillar]\n );\n\n const close = useCallback(() => {\n pillar?.close();\n }, [pillar]);\n\n const toggle = useCallback(() => {\n pillar?.toggle();\n }, [pillar]);\n\n const openArticle = useCallback(\n (slug: string) => {\n pillar?.open({ article: slug });\n },\n [pillar]\n );\n\n const openCategory = useCallback(\n async (slug: string) => {\n pillar?.navigate(\"category\", { slug });\n },\n [pillar]\n );\n\n const search = useCallback(\n (query: string) => {\n pillar?.open({ search: query });\n },\n [pillar]\n );\n\n const navigate = useCallback(\n (view: string, params?: Record<string, string>) => {\n pillar?.navigate(view, params);\n },\n [pillar]\n );\n\n const setTheme = useCallback(\n (theme: Partial<ThemeConfig>) => {\n pillar?.setTheme(theme);\n },\n [pillar]\n );\n\n const setTextSelectionEnabled = useCallback(\n (enabled: boolean) => {\n pillar?.setTextSelectionEnabled(enabled);\n },\n [pillar]\n );\n\n // DOM scanning is disabled - this is a no-op\n const setDOMScanningEnabled = useCallback(\n (_enabled: boolean) => {\n // DOM scanning is disabled - this method has no effect\n },\n []\n );\n\n const scanPage = useCallback(\n (options?: ScanOptions): CompactScanResult | null => {\n if (!pillar) return null;\n return scanPageDirect(options);\n },\n [pillar]\n );\n\n const on = useCallback(\n <K extends keyof PillarEvents>(\n event: K,\n callback: (data: PillarEvents[K]) => void\n ) => {\n return pillar?.on(event, callback) ?? (() => {});\n },\n [pillar]\n );\n\n // Context value\n const value = useMemo<PillarContextValue>(\n () => ({\n pillar,\n state,\n isReady: state === \"ready\",\n isPanelOpen,\n open,\n close,\n toggle,\n openArticle,\n openCategory,\n search,\n navigate,\n setTheme,\n setTextSelectionEnabled,\n setDOMScanningEnabled,\n isDOMScanningEnabled,\n scanPage,\n on,\n }),\n [\n pillar,\n state,\n isPanelOpen,\n open,\n close,\n toggle,\n openArticle,\n openCategory,\n search,\n navigate,\n setTheme,\n setTextSelectionEnabled,\n setDOMScanningEnabled,\n isDOMScanningEnabled,\n scanPage,\n on,\n ]\n );\n\n return (\n <PillarContext.Provider value={value}>{children}</PillarContext.Provider>\n );\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function usePillarContext(): PillarContextValue {\n const context = useContext(PillarContext);\n\n if (!context) {\n throw new Error(\"usePillarContext must be used within a PillarProvider\");\n }\n\n return context;\n}\n","/**\n * PillarPanel Component\n * Renders the Pillar help panel at a custom location in the DOM\n */\n\nimport React, { useRef, useEffect, type CSSProperties, type HTMLAttributes } from 'react';\nimport { usePillarContext } from './PillarProvider';\n\nexport interface PillarPanelProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name for the container */\n className?: string;\n \n /** Custom inline styles for the container */\n style?: CSSProperties;\n}\n\n/**\n * Renders the Pillar help panel at a custom location in the DOM.\n * Use this when you want to control where the panel is rendered instead of\n * having it automatically appended to document.body.\n * \n * **Important**: When using this component, set `panel.container: 'manual'` in your\n * PillarProvider config to prevent automatic mounting.\n * \n * @example\n * ```tsx\n * <PillarProvider \n * productKey=\"my-product-key\"\n * config={{ panel: { container: 'manual' } }}\n * >\n * <div className=\"my-layout\">\n * <Sidebar />\n * <PillarPanel className=\"help-panel-container\" />\n * <MainContent />\n * </div>\n * </PillarProvider>\n * ```\n */\nexport function PillarPanel({ \n className, \n style,\n ...props \n}: PillarPanelProps): React.ReactElement {\n const containerRef = useRef<HTMLDivElement>(null);\n const { pillar, isReady } = usePillarContext();\n const hasMounted = useRef(false);\n\n useEffect(() => {\n // Only mount once when SDK is ready and we have a container\n if (!isReady || !pillar || !containerRef.current || hasMounted.current) {\n return;\n }\n\n // Mount the panel into our container\n pillar.mountPanelTo(containerRef.current);\n hasMounted.current = true;\n\n // Cleanup is handled by Pillar.destroy() in the provider\n }, [isReady, pillar]);\n\n return (\n <div \n ref={containerRef} \n className={className}\n style={style}\n data-pillar-panel-container=\"\"\n {...props}\n />\n );\n}\n\n","/**\n * useHelpPanel Hook\n * Panel-specific controls and state\n */\n\nimport { useCallback } from 'react';\nimport { usePillarContext } from '../PillarProvider';\n\nexport interface UseHelpPanelResult {\n /** Whether the panel is currently open */\n isOpen: boolean;\n \n /** Open the panel */\n open: (options?: { view?: string; article?: string; search?: string }) => void;\n \n /** Close the panel */\n close: () => void;\n \n /** Toggle the panel */\n toggle: () => void;\n \n /** Open a specific article in the panel */\n openArticle: (slug: string) => void;\n \n /** Open a specific category in the panel */\n openCategory: (slug: string) => Promise<void>;\n \n /** Open search with a query */\n openSearch: (query?: string) => void;\n \n /** Open the AI chat */\n openChat: () => void;\n}\n\n/**\n * Hook for panel-specific controls\n * \n * @example\n * ```tsx\n * function HelpButton() {\n * const { isOpen, toggle, openChat } = useHelpPanel();\n * \n * return (\n * <div>\n * <button onClick={toggle}>\n * {isOpen ? 'Close' : 'Help'}\n * </button>\n * <button onClick={openChat}>\n * Ask AI\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useHelpPanel(): UseHelpPanelResult {\n const { isPanelOpen, open, close, toggle, openArticle, openCategory, search, navigate } = usePillarContext();\n\n const openSearch = useCallback(\n (query?: string) => {\n if (query) {\n search(query);\n } else {\n open({ view: 'search' });\n }\n },\n [search, open]\n );\n\n const openChat = useCallback(() => {\n navigate('chat');\n }, [navigate]);\n\n return {\n isOpen: isPanelOpen,\n open,\n close,\n toggle,\n openArticle,\n openCategory,\n openSearch,\n openChat,\n };\n}\n\n","/**\n * usePillar Hook\n * Access Pillar SDK instance and state with optional type-safe onTask\n */\n\nimport type {\n SyncActionDefinitions,\n ActionDefinitions,\n ActionDataType,\n ActionNames,\n} from '@pillar-ai/sdk';\nimport { useCallback } from 'react';\nimport { usePillarContext, type PillarContextValue } from '../PillarProvider';\n\nexport type UsePillarResult = PillarContextValue;\n\n/**\n * Extended result with type-safe onTask method.\n *\n * @template TActions - The action definitions for type inference\n */\nexport interface TypedUsePillarResult<\n TActions extends SyncActionDefinitions | ActionDefinitions,\n> extends Omit<PillarContextValue, 'pillar'> {\n pillar: PillarContextValue['pillar'];\n /**\n * Type-safe task handler registration.\n *\n * @param taskName - The action name (autocompleted from your actions)\n * @param handler - Handler function with typed data parameter\n * @returns Unsubscribe function\n */\n onTask: <TName extends ActionNames<TActions>>(\n taskName: TName,\n handler: (data: ActionDataType<TActions, TName>) => void\n ) => () => void;\n}\n\n/**\n * Hook to access the Pillar SDK instance and state\n *\n * @example Basic usage (untyped)\n * ```tsx\n * function MyComponent() {\n * const { isReady, open, close, isPanelOpen } = usePillar();\n *\n * if (!isReady) return <div>Loading...</div>;\n *\n * return (\n * <button onClick={() => open()}>\n * {isPanelOpen ? 'Close Help' : 'Get Help'}\n * </button>\n * );\n * }\n * ```\n *\n * @example Type-safe onTask with action definitions\n * ```tsx\n * import { actions } from '@/lib/pillar/actions';\n *\n * function MyComponent() {\n * const { pillar, onTask } = usePillar<typeof actions>();\n *\n * useEffect(() => {\n * // TypeScript knows data has { type, url, name }\n * const unsub = onTask('add_new_source', (data) => {\n * console.log(data.url); // ✓ Typed!\n * });\n * return unsub;\n * }, [onTask]);\n * }\n * ```\n */\nexport function usePillar<\n TActions extends SyncActionDefinitions | ActionDefinitions = SyncActionDefinitions,\n>(): TypedUsePillarResult<TActions> {\n const context = usePillarContext();\n\n // Create a type-safe wrapper around pillar.onTask\n const onTask = useCallback(\n <TName extends ActionNames<TActions>>(\n taskName: TName,\n handler: (data: ActionDataType<TActions, TName>) => void\n ): (() => void) => {\n if (!context.pillar) {\n // Return no-op if pillar not ready\n return () => {};\n }\n // Cast handler to match the SDK's expected type\n // The runtime behavior is the same, this is just for type narrowing\n return context.pillar.onTask(\n taskName as string,\n handler as (data: Record<string, unknown>) => void\n );\n },\n [context.pillar]\n );\n\n return {\n ...context,\n onTask,\n };\n}\n\n","/**\n * usePillarTool Hook\n *\n * Register one or more tools with co-located metadata and handlers.\n * Tools are registered on mount and unregistered on unmount.\n *\n * @example Single tool\n * ```tsx\n * import { usePillarTool } from '@pillar-ai/react';\n *\n * function CartButton() {\n * usePillarTool({\n * name: 'add_to_cart',\n * description: 'Add a product to the shopping cart',\n * inputSchema: {\n * type: 'object',\n * properties: {\n * productId: { type: 'string', description: 'Product ID' },\n * quantity: { type: 'number', description: 'Quantity to add' },\n * },\n * required: ['productId', 'quantity'],\n * },\n * execute: async ({ productId, quantity }) => {\n * await cartApi.add(productId, quantity);\n * return { content: [{ type: 'text', text: 'Added to cart' }] };\n * },\n * });\n *\n * return <button>Cart</button>;\n * }\n * ```\n *\n * @example Multiple tools\n * ```tsx\n * import { usePillarTool } from '@pillar-ai/react';\n *\n * function BillingPage() {\n * usePillarTool([\n * {\n * name: 'get_current_plan',\n * description: 'Get the current billing plan',\n * execute: async () => ({ plan: 'pro', price: 29 }),\n * },\n * {\n * name: 'upgrade_plan',\n * description: 'Upgrade to a higher plan',\n * inputSchema: {\n * type: 'object',\n * properties: { planId: { type: 'string' } },\n * required: ['planId'],\n * },\n * execute: async ({ planId }) => {\n * await billingApi.upgrade(planId);\n * return { content: [{ type: 'text', text: 'Upgraded!' }] };\n * },\n * },\n * ]);\n *\n * return <div>Billing Content</div>;\n * }\n * ```\n */\n\nimport type { ToolSchema } from \"@pillar-ai/sdk\";\nimport { useEffect, useMemo, useRef } from \"react\";\nimport { usePillarContext } from \"../PillarProvider\";\n\n/**\n * Register one or more Pillar tools with co-located metadata and handlers.\n *\n * The tools are registered when the component mounts and automatically\n * unregistered when it unmounts. The `execute` functions always capture\n * the latest React state and props via refs, so you don't need to worry\n * about stale closures.\n *\n * @param schemaOrSchemas - Single tool schema or array of tool schemas\n */\nexport function usePillarTool(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schemaOrSchemas: ToolSchema<any> | ToolSchema<any>[]\n): void {\n const { pillar } = usePillarContext();\n\n // Normalize to array for consistent handling\n const schemas = useMemo(\n () =>\n Array.isArray(schemaOrSchemas) ? schemaOrSchemas : [schemaOrSchemas],\n [schemaOrSchemas]\n );\n\n // Keep refs to latest schemas so handlers capture current state/props\n const schemasRef = useRef(schemas);\n schemasRef.current = schemas;\n\n // Stable dependency key for the effect (tool names joined)\n const toolNamesKey = useMemo(\n () => schemas.map((s) => s.name).join(\",\"),\n [schemas]\n );\n\n useEffect(() => {\n if (!pillar) return;\n\n // Register all tools and collect unsubscribe functions\n const unsubscribes = schemasRef.current.map((schema, index) => {\n return pillar.defineTool({\n ...schema,\n // Wrap execute to always use the latest ref version\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n execute: (input: any) => schemasRef.current[index].execute(input),\n } as ToolSchema);\n });\n\n // Cleanup: unregister all tools\n return () => {\n unsubscribes.forEach((unsub) => unsub());\n };\n }, [pillar, toolNamesKey]);\n}\n\n/** @deprecated Use usePillarTool instead */\nexport const usePillarAction = usePillarTool;\n"],"names":["_jsx"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -456,15 +456,17 @@ function usePillar() {
|
|
|
456
456
|
*
|
|
457
457
|
* @param schemaOrSchemas - Single tool schema or array of tool schemas
|
|
458
458
|
*/
|
|
459
|
-
function usePillarTool(
|
|
459
|
+
function usePillarTool(
|
|
460
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
461
|
+
schemaOrSchemas) {
|
|
460
462
|
const { pillar } = usePillarContext();
|
|
461
463
|
// Normalize to array for consistent handling
|
|
462
|
-
const schemas = react.useMemo(() =>
|
|
464
|
+
const schemas = react.useMemo(() => Array.isArray(schemaOrSchemas) ? schemaOrSchemas : [schemaOrSchemas], [schemaOrSchemas]);
|
|
463
465
|
// Keep refs to latest schemas so handlers capture current state/props
|
|
464
466
|
const schemasRef = react.useRef(schemas);
|
|
465
467
|
schemasRef.current = schemas;
|
|
466
468
|
// Stable dependency key for the effect (tool names joined)
|
|
467
|
-
const toolNamesKey = react.useMemo(() => schemas.map((s) => s.name).join(
|
|
469
|
+
const toolNamesKey = react.useMemo(() => schemas.map((s) => s.name).join(","), [schemas]);
|
|
468
470
|
react.useEffect(() => {
|
|
469
471
|
if (!pillar)
|
|
470
472
|
return;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/PillarProvider.tsx","../src/PillarPanel.tsx","../src/hooks/useHelpPanel.ts","../src/hooks/usePillar.ts","../src/hooks/usePillarTool.ts"],"sourcesContent":["/**\n * PillarProvider\n * Context provider that initializes and manages the Pillar SDK\n */\n\nimport {\n Pillar,\n scanPageDirect,\n type CardCallbacks,\n type CompactScanResult,\n type PillarConfig,\n type PillarEvents,\n type PillarState,\n type ScanOptions,\n type TaskExecutePayload,\n type ThemeConfig,\n} from \"@pillar-ai/sdk\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentType,\n type ReactNode,\n} from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\n\n// ============================================================================\n// Card Types\n// ============================================================================\n\n/**\n * Props passed to custom card components.\n */\nexport interface CardComponentProps<T = Record<string, unknown>> {\n /** Data extracted by the AI for this action */\n data: T;\n /** Called when user confirms the action */\n onConfirm: (modifiedData?: Record<string, unknown>) => void;\n /** Called when user cancels the action */\n onCancel: () => void;\n /** Called to report state changes (loading, success, error) */\n onStateChange?: (\n state: \"loading\" | \"success\" | \"error\",\n message?: string\n ) => void;\n}\n\n/**\n * A React component that can be used as a custom card renderer.\n */\nexport type CardComponent<T = Record<string, unknown>> = ComponentType<\n CardComponentProps<T>\n>;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PillarContextValue {\n /** The Pillar SDK instance */\n pillar: Pillar | null;\n\n /** Current SDK state */\n state: PillarState;\n\n /** Whether the SDK is ready */\n isReady: boolean;\n\n /** Whether the panel is currently open */\n isPanelOpen: boolean;\n\n /** Open the help panel */\n open: (options?: {\n view?: string;\n article?: string;\n search?: string;\n focusInput?: boolean;\n }) => void;\n\n /** Close the help panel */\n close: () => void;\n\n /** Toggle the help panel */\n toggle: () => void;\n\n /** Open a specific article */\n openArticle: (slug: string) => void;\n\n /** Open a specific category */\n openCategory: (slug: string) => Promise<void>;\n\n /** Perform a search */\n search: (query: string) => void;\n\n /** Navigate to a specific view */\n navigate: (view: string, params?: Record<string, string>) => void;\n\n /** Update the panel theme at runtime */\n setTheme: (theme: Partial<ThemeConfig>) => void;\n\n /** Enable or disable the text selection \"Ask AI\" popover */\n setTextSelectionEnabled: (enabled: boolean) => void;\n\n /**\n * Enable or disable DOM scanning.\n * @deprecated DOM scanning is currently disabled and this method has no effect.\n */\n setDOMScanningEnabled: (enabled: boolean) => void;\n\n /**\n * Whether DOM scanning is enabled.\n * @deprecated Always returns false - DOM scanning is disabled.\n */\n isDOMScanningEnabled: boolean;\n\n /** Manually scan the page and get the compact result */\n scanPage: (options?: ScanOptions) => CompactScanResult | null;\n\n /** Subscribe to SDK events */\n on: <K extends keyof PillarEvents>(\n event: K,\n callback: (data: PillarEvents[K]) => void\n ) => () => void;\n}\n\nexport interface PillarProviderProps {\n /**\n * Your product key from the Pillar app.\n * Get it at app.trypillar.com\n */\n productKey?: string;\n\n /**\n * @deprecated Use `productKey` instead. Will be removed in v1.0.\n */\n helpCenter?: string;\n\n /**\n * Additional SDK configuration\n *\n * Notable options:\n * - `panel.useShadowDOM`: Whether to isolate styles in Shadow DOM (default: false).\n * Set to false to let custom cards inherit your app's CSS (Tailwind, etc.)\n */\n config?: Omit<PillarConfig, \"productKey\" | \"helpCenter\">;\n\n /**\n * Handler called when a task action is triggered from the chat.\n * Use this to handle AI-suggested actions like opening modals, navigating, etc.\n *\n * @example\n * ```tsx\n * <PillarProvider\n * productKey=\"my-product-key\"\n * onTask={(task) => {\n * switch (task.name) {\n * case 'invite_team_member':\n * openInviteModal(task.data);\n * break;\n * case 'open_settings':\n * router.push('/settings');\n * break;\n * }\n * }}\n * >\n * ```\n */\n onTask?: (task: TaskExecutePayload) => void;\n\n /**\n * Custom card components to render for inline_ui type actions.\n * Map card type names to React components that will render the inline UI.\n *\n * @example\n * ```tsx\n * import { InviteMembersCard } from './cards/InviteMembersCard';\n *\n * <PillarProvider\n * productKey=\"my-product-key\"\n * cards={{\n * invite_members: InviteMembersCard,\n * confirm_delete: ConfirmDeleteCard,\n * }}\n * >\n * ```\n */\n cards?: Record<string, CardComponent>;\n\n /**\n * Enable DOM scanning to send page context with messages.\n * @deprecated DOM scanning is currently disabled. This prop has no effect.\n */\n domScanning?: boolean;\n\n /**\n * Enable DOM scanning dev mode to preview the scanned page before sending.\n * Shows a modal with the AST tree visualization before each message is sent.\n * Useful for debugging what context will be sent to the LLM.\n /** Children components */\n children: ReactNode;\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst PillarContext = createContext<PillarContextValue | null>(null);\n\n// ============================================================================\n// Provider Component\n// ============================================================================\n\nexport function PillarProvider({\n productKey,\n helpCenter,\n config,\n onTask,\n cards,\n domScanning: _domScanning, // Deprecated - DOM scanning is disabled\n children,\n}: PillarProviderProps): React.ReactElement {\n const [pillar, setPillar] = useState<Pillar | null>(null);\n const [state, setState] = useState<PillarState>(\"uninitialized\");\n const [isPanelOpen, setIsPanelOpen] = useState(false);\n // DOM scanning is disabled - always false\n const isDOMScanningEnabled = false;\n\n // Support both productKey (new) and helpCenter (deprecated)\n const resolvedKey = productKey ?? helpCenter;\n\n // Keep a ref to the latest onTask callback to avoid re-subscribing\n const onTaskRef = useRef(onTask);\n onTaskRef.current = onTask;\n\n // Warn about deprecated helpCenter usage\n useEffect(() => {\n if (helpCenter && !productKey) {\n console.warn(\n '[Pillar React] \"helpCenter\" prop is deprecated. Use \"productKey\" instead.'\n );\n }\n }, []);\n\n // Keep a ref to cards to access latest versions\n const cardsRef = useRef(cards);\n cardsRef.current = cards;\n\n // Initialize SDK\n useEffect(() => {\n let mounted = true;\n\n const initPillar = async () => {\n try {\n // Pillar is a singleton - check if already initialized\n const existingInstance = Pillar.getInstance();\n if (existingInstance) {\n // Reuse existing instance (preserves chat history, panel state, etc.)\n if (mounted) {\n setPillar(existingInstance);\n setState(existingInstance.state);\n\n // Re-subscribe to events\n existingInstance.on(\"panel:open\", () => {\n setIsPanelOpen(true);\n });\n\n existingInstance.on(\"panel:close\", () => {\n setIsPanelOpen(false);\n });\n }\n return;\n }\n\n // Initialize new instance\n // Note: DOM scanning is disabled, config.domScanning is ignored\n const instance = await Pillar.init({\n productKey: resolvedKey,\n ...config,\n });\n\n if (mounted) {\n setPillar(instance);\n setState(instance.state);\n\n // Listen for panel open/close\n instance.on(\"panel:open\", () => {\n setIsPanelOpen(true);\n });\n\n instance.on(\"panel:close\", () => {\n setIsPanelOpen(false);\n });\n }\n } catch (error) {\n console.error(\"[Pillar React] Failed to initialize:\", error);\n if (mounted) {\n setState(\"error\");\n }\n }\n };\n\n initPillar();\n\n // Cleanup - DON'T destroy the singleton on unmount\n // This preserves conversation history and panel state across navigation\n // Pillar.destroy() should only be called explicitly when the app unmounts completely\n return () => {\n mounted = false;\n // Note: We intentionally don't call Pillar.destroy() here\n // The singleton persists to maintain state across route changes\n };\n }, [resolvedKey]); // Re-initialize if productKey changes\n\n // Update state when SDK state changes\n useEffect(() => {\n if (pillar) {\n const unsubscribe = pillar.on(\"ready\", () => {\n setState(\"ready\");\n });\n\n const unsubscribeError = pillar.on(\"error\", () => {\n setState(\"error\");\n });\n\n return () => {\n unsubscribe();\n unsubscribeError();\n };\n }\n }, [pillar]);\n\n // Register task handler\n useEffect(() => {\n if (pillar) {\n const unsubscribe = pillar.on(\"task:execute\", (task) => {\n onTaskRef.current?.(task);\n });\n\n return unsubscribe;\n }\n }, [pillar]);\n\n // DOM scanning is disabled - no sync needed\n\n // Register custom card renderers\n useEffect(() => {\n if (!pillar || !cards) return;\n\n const unsubscribers: Array<() => void> = [];\n const roots: Map<HTMLElement, Root> = new Map();\n\n // Register each card component as a vanilla renderer\n Object.entries(cards).forEach(([cardType, Component]) => {\n const unsubscribe = pillar.registerCard(\n cardType,\n (container, data, callbacks: CardCallbacks) => {\n // Create a React root for this container\n const root = createRoot(container);\n roots.set(container, root);\n\n // Render the React component\n root.render(\n <Component\n data={data}\n onConfirm={callbacks.onConfirm}\n onCancel={callbacks.onCancel}\n onStateChange={callbacks.onStateChange}\n />\n );\n\n // Return cleanup function\n return () => {\n const existingRoot = roots.get(container);\n if (existingRoot) {\n existingRoot.unmount();\n roots.delete(container);\n }\n };\n }\n );\n\n unsubscribers.push(unsubscribe);\n });\n\n return () => {\n // Cleanup all registrations\n unsubscribers.forEach((unsub) => unsub());\n // Unmount all React roots\n roots.forEach((root) => root.unmount());\n roots.clear();\n };\n }, [pillar, cards]);\n\n // Actions\n const open = useCallback(\n (options?: {\n view?: string;\n article?: string;\n search?: string;\n focusInput?: boolean;\n }) => {\n pillar?.open(options);\n },\n [pillar]\n );\n\n const close = useCallback(() => {\n pillar?.close();\n }, [pillar]);\n\n const toggle = useCallback(() => {\n pillar?.toggle();\n }, [pillar]);\n\n const openArticle = useCallback(\n (slug: string) => {\n pillar?.open({ article: slug });\n },\n [pillar]\n );\n\n const openCategory = useCallback(\n async (slug: string) => {\n pillar?.navigate(\"category\", { slug });\n },\n [pillar]\n );\n\n const search = useCallback(\n (query: string) => {\n pillar?.open({ search: query });\n },\n [pillar]\n );\n\n const navigate = useCallback(\n (view: string, params?: Record<string, string>) => {\n pillar?.navigate(view, params);\n },\n [pillar]\n );\n\n const setTheme = useCallback(\n (theme: Partial<ThemeConfig>) => {\n pillar?.setTheme(theme);\n },\n [pillar]\n );\n\n const setTextSelectionEnabled = useCallback(\n (enabled: boolean) => {\n pillar?.setTextSelectionEnabled(enabled);\n },\n [pillar]\n );\n\n // DOM scanning is disabled - this is a no-op\n const setDOMScanningEnabled = useCallback(\n (_enabled: boolean) => {\n // DOM scanning is disabled - this method has no effect\n },\n []\n );\n\n const scanPage = useCallback(\n (options?: ScanOptions): CompactScanResult | null => {\n if (!pillar) return null;\n return scanPageDirect(options);\n },\n [pillar]\n );\n\n const on = useCallback(\n <K extends keyof PillarEvents>(\n event: K,\n callback: (data: PillarEvents[K]) => void\n ) => {\n return pillar?.on(event, callback) ?? (() => {});\n },\n [pillar]\n );\n\n // Context value\n const value = useMemo<PillarContextValue>(\n () => ({\n pillar,\n state,\n isReady: state === \"ready\",\n isPanelOpen,\n open,\n close,\n toggle,\n openArticle,\n openCategory,\n search,\n navigate,\n setTheme,\n setTextSelectionEnabled,\n setDOMScanningEnabled,\n isDOMScanningEnabled,\n scanPage,\n on,\n }),\n [\n pillar,\n state,\n isPanelOpen,\n open,\n close,\n toggle,\n openArticle,\n openCategory,\n search,\n navigate,\n setTheme,\n setTextSelectionEnabled,\n setDOMScanningEnabled,\n isDOMScanningEnabled,\n scanPage,\n on,\n ]\n );\n\n return (\n <PillarContext.Provider value={value}>{children}</PillarContext.Provider>\n );\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function usePillarContext(): PillarContextValue {\n const context = useContext(PillarContext);\n\n if (!context) {\n throw new Error(\"usePillarContext must be used within a PillarProvider\");\n }\n\n return context;\n}\n","/**\n * PillarPanel Component\n * Renders the Pillar help panel at a custom location in the DOM\n */\n\nimport React, { useRef, useEffect, type CSSProperties, type HTMLAttributes } from 'react';\nimport { usePillarContext } from './PillarProvider';\n\nexport interface PillarPanelProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name for the container */\n className?: string;\n \n /** Custom inline styles for the container */\n style?: CSSProperties;\n}\n\n/**\n * Renders the Pillar help panel at a custom location in the DOM.\n * Use this when you want to control where the panel is rendered instead of\n * having it automatically appended to document.body.\n * \n * **Important**: When using this component, set `panel.container: 'manual'` in your\n * PillarProvider config to prevent automatic mounting.\n * \n * @example\n * ```tsx\n * <PillarProvider \n * productKey=\"my-product-key\"\n * config={{ panel: { container: 'manual' } }}\n * >\n * <div className=\"my-layout\">\n * <Sidebar />\n * <PillarPanel className=\"help-panel-container\" />\n * <MainContent />\n * </div>\n * </PillarProvider>\n * ```\n */\nexport function PillarPanel({ \n className, \n style,\n ...props \n}: PillarPanelProps): React.ReactElement {\n const containerRef = useRef<HTMLDivElement>(null);\n const { pillar, isReady } = usePillarContext();\n const hasMounted = useRef(false);\n\n useEffect(() => {\n // Only mount once when SDK is ready and we have a container\n if (!isReady || !pillar || !containerRef.current || hasMounted.current) {\n return;\n }\n\n // Mount the panel into our container\n pillar.mountPanelTo(containerRef.current);\n hasMounted.current = true;\n\n // Cleanup is handled by Pillar.destroy() in the provider\n }, [isReady, pillar]);\n\n return (\n <div \n ref={containerRef} \n className={className}\n style={style}\n data-pillar-panel-container=\"\"\n {...props}\n />\n );\n}\n\n","/**\n * useHelpPanel Hook\n * Panel-specific controls and state\n */\n\nimport { useCallback } from 'react';\nimport { usePillarContext } from '../PillarProvider';\n\nexport interface UseHelpPanelResult {\n /** Whether the panel is currently open */\n isOpen: boolean;\n \n /** Open the panel */\n open: (options?: { view?: string; article?: string; search?: string }) => void;\n \n /** Close the panel */\n close: () => void;\n \n /** Toggle the panel */\n toggle: () => void;\n \n /** Open a specific article in the panel */\n openArticle: (slug: string) => void;\n \n /** Open a specific category in the panel */\n openCategory: (slug: string) => Promise<void>;\n \n /** Open search with a query */\n openSearch: (query?: string) => void;\n \n /** Open the AI chat */\n openChat: () => void;\n}\n\n/**\n * Hook for panel-specific controls\n * \n * @example\n * ```tsx\n * function HelpButton() {\n * const { isOpen, toggle, openChat } = useHelpPanel();\n * \n * return (\n * <div>\n * <button onClick={toggle}>\n * {isOpen ? 'Close' : 'Help'}\n * </button>\n * <button onClick={openChat}>\n * Ask AI\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useHelpPanel(): UseHelpPanelResult {\n const { isPanelOpen, open, close, toggle, openArticle, openCategory, search, navigate } = usePillarContext();\n\n const openSearch = useCallback(\n (query?: string) => {\n if (query) {\n search(query);\n } else {\n open({ view: 'search' });\n }\n },\n [search, open]\n );\n\n const openChat = useCallback(() => {\n navigate('chat');\n }, [navigate]);\n\n return {\n isOpen: isPanelOpen,\n open,\n close,\n toggle,\n openArticle,\n openCategory,\n openSearch,\n openChat,\n };\n}\n\n","/**\n * usePillar Hook\n * Access Pillar SDK instance and state with optional type-safe onTask\n */\n\nimport type {\n SyncActionDefinitions,\n ActionDefinitions,\n ActionDataType,\n ActionNames,\n} from '@pillar-ai/sdk';\nimport { useCallback } from 'react';\nimport { usePillarContext, type PillarContextValue } from '../PillarProvider';\n\nexport type UsePillarResult = PillarContextValue;\n\n/**\n * Extended result with type-safe onTask method.\n *\n * @template TActions - The action definitions for type inference\n */\nexport interface TypedUsePillarResult<\n TActions extends SyncActionDefinitions | ActionDefinitions,\n> extends Omit<PillarContextValue, 'pillar'> {\n pillar: PillarContextValue['pillar'];\n /**\n * Type-safe task handler registration.\n *\n * @param taskName - The action name (autocompleted from your actions)\n * @param handler - Handler function with typed data parameter\n * @returns Unsubscribe function\n */\n onTask: <TName extends ActionNames<TActions>>(\n taskName: TName,\n handler: (data: ActionDataType<TActions, TName>) => void\n ) => () => void;\n}\n\n/**\n * Hook to access the Pillar SDK instance and state\n *\n * @example Basic usage (untyped)\n * ```tsx\n * function MyComponent() {\n * const { isReady, open, close, isPanelOpen } = usePillar();\n *\n * if (!isReady) return <div>Loading...</div>;\n *\n * return (\n * <button onClick={() => open()}>\n * {isPanelOpen ? 'Close Help' : 'Get Help'}\n * </button>\n * );\n * }\n * ```\n *\n * @example Type-safe onTask with action definitions\n * ```tsx\n * import { actions } from '@/lib/pillar/actions';\n *\n * function MyComponent() {\n * const { pillar, onTask } = usePillar<typeof actions>();\n *\n * useEffect(() => {\n * // TypeScript knows data has { type, url, name }\n * const unsub = onTask('add_new_source', (data) => {\n * console.log(data.url); // ✓ Typed!\n * });\n * return unsub;\n * }, [onTask]);\n * }\n * ```\n */\nexport function usePillar<\n TActions extends SyncActionDefinitions | ActionDefinitions = SyncActionDefinitions,\n>(): TypedUsePillarResult<TActions> {\n const context = usePillarContext();\n\n // Create a type-safe wrapper around pillar.onTask\n const onTask = useCallback(\n <TName extends ActionNames<TActions>>(\n taskName: TName,\n handler: (data: ActionDataType<TActions, TName>) => void\n ): (() => void) => {\n if (!context.pillar) {\n // Return no-op if pillar not ready\n return () => {};\n }\n // Cast handler to match the SDK's expected type\n // The runtime behavior is the same, this is just for type narrowing\n return context.pillar.onTask(\n taskName as string,\n handler as (data: Record<string, unknown>) => void\n );\n },\n [context.pillar]\n );\n\n return {\n ...context,\n onTask,\n };\n}\n\n","/**\n * usePillarTool Hook\n *\n * Register one or more tools with co-located metadata and handlers.\n * Tools are registered on mount and unregistered on unmount.\n *\n * @example Single tool\n * ```tsx\n * import { usePillarTool } from '@pillar-ai/react';\n *\n * function CartButton() {\n * usePillarTool({\n * name: 'add_to_cart',\n * description: 'Add a product to the shopping cart',\n * inputSchema: {\n * type: 'object',\n * properties: {\n * productId: { type: 'string', description: 'Product ID' },\n * quantity: { type: 'number', description: 'Quantity to add' },\n * },\n * required: ['productId', 'quantity'],\n * },\n * execute: async ({ productId, quantity }) => {\n * await cartApi.add(productId, quantity);\n * return { content: [{ type: 'text', text: 'Added to cart' }] };\n * },\n * });\n *\n * return <button>Cart</button>;\n * }\n * ```\n *\n * @example Multiple tools\n * ```tsx\n * import { usePillarTool } from '@pillar-ai/react';\n *\n * function BillingPage() {\n * usePillarTool([\n * {\n * name: 'get_current_plan',\n * description: 'Get the current billing plan',\n * execute: async () => ({ plan: 'pro', price: 29 }),\n * },\n * {\n * name: 'upgrade_plan',\n * description: 'Upgrade to a higher plan',\n * inputSchema: {\n * type: 'object',\n * properties: { planId: { type: 'string' } },\n * required: ['planId'],\n * },\n * execute: async ({ planId }) => {\n * await billingApi.upgrade(planId);\n * return { content: [{ type: 'text', text: 'Upgraded!' }] };\n * },\n * },\n * ]);\n *\n * return <div>Billing Content</div>;\n * }\n * ```\n */\n\nimport { useEffect, useRef, useMemo } from 'react';\nimport type { ToolSchema } from '@pillar-ai/sdk';\nimport { usePillarContext } from '../PillarProvider';\n\n/**\n * Register a single Pillar tool with co-located metadata and handler.\n */\nexport function usePillarTool<TInput = Record<string, unknown>>(\n schema: ToolSchema<TInput>\n): void;\n\n/**\n * Register multiple Pillar tools with co-located metadata and handlers.\n */\nexport function usePillarTool(schemas: ToolSchema[]): void;\n\n/**\n * Register one or more Pillar tools with co-located metadata and handlers.\n *\n * The tools are registered when the component mounts and automatically\n * unregistered when it unmounts. The `execute` functions always capture\n * the latest React state and props via refs, so you don't need to worry\n * about stale closures.\n *\n * @param schemaOrSchemas - Single tool schema or array of tool schemas\n */\nexport function usePillarTool<TInput = Record<string, unknown>>(\n schemaOrSchemas: ToolSchema<TInput> | ToolSchema[]\n): void {\n const { pillar } = usePillarContext();\n\n // Normalize to array for consistent handling\n const schemas = useMemo(\n () => (Array.isArray(schemaOrSchemas) ? schemaOrSchemas : [schemaOrSchemas]),\n [schemaOrSchemas]\n );\n\n // Keep refs to latest schemas so handlers capture current state/props\n const schemasRef = useRef(schemas);\n schemasRef.current = schemas;\n\n // Stable dependency key for the effect (tool names joined)\n const toolNamesKey = useMemo(\n () => schemas.map((s) => s.name).join(','),\n [schemas]\n );\n\n useEffect(() => {\n if (!pillar) return;\n\n // Register all tools and collect unsubscribe functions\n const unsubscribes = schemasRef.current.map((schema, index) => {\n return pillar.defineTool({\n ...schema,\n // Wrap execute to always use the latest ref version\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n execute: (input: any) => schemasRef.current[index].execute(input),\n } as ToolSchema);\n });\n\n // Cleanup: unregister all tools\n return () => {\n unsubscribes.forEach((unsub) => unsub());\n };\n }, [pillar, toolNamesKey]);\n}\n\n/** @deprecated Use usePillarTool instead */\nexport const usePillarAction = usePillarTool;\n"],"names":["createContext","useState","useRef","useEffect","Pillar","createRoot","_jsx","useCallback","scanPageDirect","useMemo","useContext"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/PillarProvider.tsx","../src/PillarPanel.tsx","../src/hooks/useHelpPanel.ts","../src/hooks/usePillar.ts","../src/hooks/usePillarTool.ts"],"sourcesContent":["/**\n * PillarProvider\n * Context provider that initializes and manages the Pillar SDK\n */\n\nimport {\n Pillar,\n scanPageDirect,\n type CardCallbacks,\n type CompactScanResult,\n type PillarConfig,\n type PillarEvents,\n type PillarState,\n type ScanOptions,\n type TaskExecutePayload,\n type ThemeConfig,\n} from \"@pillar-ai/sdk\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentType,\n type ReactNode,\n} from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\n\n// ============================================================================\n// Card Types\n// ============================================================================\n\n/**\n * Props passed to custom card components.\n */\nexport interface CardComponentProps<T = Record<string, unknown>> {\n /** Data extracted by the AI for this action */\n data: T;\n /** Called when user confirms the action */\n onConfirm: (modifiedData?: Record<string, unknown>) => void;\n /** Called when user cancels the action */\n onCancel: () => void;\n /** Called to report state changes (loading, success, error) */\n onStateChange?: (\n state: \"loading\" | \"success\" | \"error\",\n message?: string\n ) => void;\n}\n\n/**\n * A React component that can be used as a custom card renderer.\n */\nexport type CardComponent<T = Record<string, unknown>> = ComponentType<\n CardComponentProps<T>\n>;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PillarContextValue {\n /** The Pillar SDK instance */\n pillar: Pillar | null;\n\n /** Current SDK state */\n state: PillarState;\n\n /** Whether the SDK is ready */\n isReady: boolean;\n\n /** Whether the panel is currently open */\n isPanelOpen: boolean;\n\n /** Open the help panel */\n open: (options?: {\n view?: string;\n article?: string;\n search?: string;\n focusInput?: boolean;\n }) => void;\n\n /** Close the help panel */\n close: () => void;\n\n /** Toggle the help panel */\n toggle: () => void;\n\n /** Open a specific article */\n openArticle: (slug: string) => void;\n\n /** Open a specific category */\n openCategory: (slug: string) => Promise<void>;\n\n /** Perform a search */\n search: (query: string) => void;\n\n /** Navigate to a specific view */\n navigate: (view: string, params?: Record<string, string>) => void;\n\n /** Update the panel theme at runtime */\n setTheme: (theme: Partial<ThemeConfig>) => void;\n\n /** Enable or disable the text selection \"Ask AI\" popover */\n setTextSelectionEnabled: (enabled: boolean) => void;\n\n /**\n * Enable or disable DOM scanning.\n * @deprecated DOM scanning is currently disabled and this method has no effect.\n */\n setDOMScanningEnabled: (enabled: boolean) => void;\n\n /**\n * Whether DOM scanning is enabled.\n * @deprecated Always returns false - DOM scanning is disabled.\n */\n isDOMScanningEnabled: boolean;\n\n /** Manually scan the page and get the compact result */\n scanPage: (options?: ScanOptions) => CompactScanResult | null;\n\n /** Subscribe to SDK events */\n on: <K extends keyof PillarEvents>(\n event: K,\n callback: (data: PillarEvents[K]) => void\n ) => () => void;\n}\n\nexport interface PillarProviderProps {\n /**\n * Your product key from the Pillar app.\n * Get it at app.trypillar.com\n */\n productKey?: string;\n\n /**\n * @deprecated Use `productKey` instead. Will be removed in v1.0.\n */\n helpCenter?: string;\n\n /**\n * Additional SDK configuration\n *\n * Notable options:\n * - `panel.useShadowDOM`: Whether to isolate styles in Shadow DOM (default: false).\n * Set to false to let custom cards inherit your app's CSS (Tailwind, etc.)\n */\n config?: Omit<PillarConfig, \"productKey\" | \"helpCenter\">;\n\n /**\n * Handler called when a task action is triggered from the chat.\n * Use this to handle AI-suggested actions like opening modals, navigating, etc.\n *\n * @example\n * ```tsx\n * <PillarProvider\n * productKey=\"my-product-key\"\n * onTask={(task) => {\n * switch (task.name) {\n * case 'invite_team_member':\n * openInviteModal(task.data);\n * break;\n * case 'open_settings':\n * router.push('/settings');\n * break;\n * }\n * }}\n * >\n * ```\n */\n onTask?: (task: TaskExecutePayload) => void;\n\n /**\n * Custom card components to render for inline_ui type actions.\n * Map card type names to React components that will render the inline UI.\n *\n * @example\n * ```tsx\n * import { InviteMembersCard } from './cards/InviteMembersCard';\n *\n * <PillarProvider\n * productKey=\"my-product-key\"\n * cards={{\n * invite_members: InviteMembersCard,\n * confirm_delete: ConfirmDeleteCard,\n * }}\n * >\n * ```\n */\n cards?: Record<string, CardComponent>;\n\n /**\n * Enable DOM scanning to send page context with messages.\n * @deprecated DOM scanning is currently disabled. This prop has no effect.\n */\n domScanning?: boolean;\n\n /**\n * Enable DOM scanning dev mode to preview the scanned page before sending.\n * Shows a modal with the AST tree visualization before each message is sent.\n * Useful for debugging what context will be sent to the LLM.\n /** Children components */\n children: ReactNode;\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst PillarContext = createContext<PillarContextValue | null>(null);\n\n// ============================================================================\n// Provider Component\n// ============================================================================\n\nexport function PillarProvider({\n productKey,\n helpCenter,\n config,\n onTask,\n cards,\n domScanning: _domScanning, // Deprecated - DOM scanning is disabled\n children,\n}: PillarProviderProps): React.ReactElement {\n const [pillar, setPillar] = useState<Pillar | null>(null);\n const [state, setState] = useState<PillarState>(\"uninitialized\");\n const [isPanelOpen, setIsPanelOpen] = useState(false);\n // DOM scanning is disabled - always false\n const isDOMScanningEnabled = false;\n\n // Support both productKey (new) and helpCenter (deprecated)\n const resolvedKey = productKey ?? helpCenter;\n\n // Keep a ref to the latest onTask callback to avoid re-subscribing\n const onTaskRef = useRef(onTask);\n onTaskRef.current = onTask;\n\n // Warn about deprecated helpCenter usage\n useEffect(() => {\n if (helpCenter && !productKey) {\n console.warn(\n '[Pillar React] \"helpCenter\" prop is deprecated. Use \"productKey\" instead.'\n );\n }\n }, []);\n\n // Keep a ref to cards to access latest versions\n const cardsRef = useRef(cards);\n cardsRef.current = cards;\n\n // Initialize SDK\n useEffect(() => {\n let mounted = true;\n\n const initPillar = async () => {\n try {\n // Pillar is a singleton - check if already initialized\n const existingInstance = Pillar.getInstance();\n if (existingInstance) {\n // Reuse existing instance (preserves chat history, panel state, etc.)\n if (mounted) {\n setPillar(existingInstance);\n setState(existingInstance.state);\n\n // Re-subscribe to events\n existingInstance.on(\"panel:open\", () => {\n setIsPanelOpen(true);\n });\n\n existingInstance.on(\"panel:close\", () => {\n setIsPanelOpen(false);\n });\n }\n return;\n }\n\n // Initialize new instance\n // Note: DOM scanning is disabled, config.domScanning is ignored\n const instance = await Pillar.init({\n productKey: resolvedKey,\n ...config,\n });\n\n if (mounted) {\n setPillar(instance);\n setState(instance.state);\n\n // Listen for panel open/close\n instance.on(\"panel:open\", () => {\n setIsPanelOpen(true);\n });\n\n instance.on(\"panel:close\", () => {\n setIsPanelOpen(false);\n });\n }\n } catch (error) {\n console.error(\"[Pillar React] Failed to initialize:\", error);\n if (mounted) {\n setState(\"error\");\n }\n }\n };\n\n initPillar();\n\n // Cleanup - DON'T destroy the singleton on unmount\n // This preserves conversation history and panel state across navigation\n // Pillar.destroy() should only be called explicitly when the app unmounts completely\n return () => {\n mounted = false;\n // Note: We intentionally don't call Pillar.destroy() here\n // The singleton persists to maintain state across route changes\n };\n }, [resolvedKey]); // Re-initialize if productKey changes\n\n // Update state when SDK state changes\n useEffect(() => {\n if (pillar) {\n const unsubscribe = pillar.on(\"ready\", () => {\n setState(\"ready\");\n });\n\n const unsubscribeError = pillar.on(\"error\", () => {\n setState(\"error\");\n });\n\n return () => {\n unsubscribe();\n unsubscribeError();\n };\n }\n }, [pillar]);\n\n // Register task handler\n useEffect(() => {\n if (pillar) {\n const unsubscribe = pillar.on(\"task:execute\", (task) => {\n onTaskRef.current?.(task);\n });\n\n return unsubscribe;\n }\n }, [pillar]);\n\n // DOM scanning is disabled - no sync needed\n\n // Register custom card renderers\n useEffect(() => {\n if (!pillar || !cards) return;\n\n const unsubscribers: Array<() => void> = [];\n const roots: Map<HTMLElement, Root> = new Map();\n\n // Register each card component as a vanilla renderer\n Object.entries(cards).forEach(([cardType, Component]) => {\n const unsubscribe = pillar.registerCard(\n cardType,\n (container, data, callbacks: CardCallbacks) => {\n // Create a React root for this container\n const root = createRoot(container);\n roots.set(container, root);\n\n // Render the React component\n root.render(\n <Component\n data={data}\n onConfirm={callbacks.onConfirm}\n onCancel={callbacks.onCancel}\n onStateChange={callbacks.onStateChange}\n />\n );\n\n // Return cleanup function\n return () => {\n const existingRoot = roots.get(container);\n if (existingRoot) {\n existingRoot.unmount();\n roots.delete(container);\n }\n };\n }\n );\n\n unsubscribers.push(unsubscribe);\n });\n\n return () => {\n // Cleanup all registrations\n unsubscribers.forEach((unsub) => unsub());\n // Unmount all React roots\n roots.forEach((root) => root.unmount());\n roots.clear();\n };\n }, [pillar, cards]);\n\n // Actions\n const open = useCallback(\n (options?: {\n view?: string;\n article?: string;\n search?: string;\n focusInput?: boolean;\n }) => {\n pillar?.open(options);\n },\n [pillar]\n );\n\n const close = useCallback(() => {\n pillar?.close();\n }, [pillar]);\n\n const toggle = useCallback(() => {\n pillar?.toggle();\n }, [pillar]);\n\n const openArticle = useCallback(\n (slug: string) => {\n pillar?.open({ article: slug });\n },\n [pillar]\n );\n\n const openCategory = useCallback(\n async (slug: string) => {\n pillar?.navigate(\"category\", { slug });\n },\n [pillar]\n );\n\n const search = useCallback(\n (query: string) => {\n pillar?.open({ search: query });\n },\n [pillar]\n );\n\n const navigate = useCallback(\n (view: string, params?: Record<string, string>) => {\n pillar?.navigate(view, params);\n },\n [pillar]\n );\n\n const setTheme = useCallback(\n (theme: Partial<ThemeConfig>) => {\n pillar?.setTheme(theme);\n },\n [pillar]\n );\n\n const setTextSelectionEnabled = useCallback(\n (enabled: boolean) => {\n pillar?.setTextSelectionEnabled(enabled);\n },\n [pillar]\n );\n\n // DOM scanning is disabled - this is a no-op\n const setDOMScanningEnabled = useCallback(\n (_enabled: boolean) => {\n // DOM scanning is disabled - this method has no effect\n },\n []\n );\n\n const scanPage = useCallback(\n (options?: ScanOptions): CompactScanResult | null => {\n if (!pillar) return null;\n return scanPageDirect(options);\n },\n [pillar]\n );\n\n const on = useCallback(\n <K extends keyof PillarEvents>(\n event: K,\n callback: (data: PillarEvents[K]) => void\n ) => {\n return pillar?.on(event, callback) ?? (() => {});\n },\n [pillar]\n );\n\n // Context value\n const value = useMemo<PillarContextValue>(\n () => ({\n pillar,\n state,\n isReady: state === \"ready\",\n isPanelOpen,\n open,\n close,\n toggle,\n openArticle,\n openCategory,\n search,\n navigate,\n setTheme,\n setTextSelectionEnabled,\n setDOMScanningEnabled,\n isDOMScanningEnabled,\n scanPage,\n on,\n }),\n [\n pillar,\n state,\n isPanelOpen,\n open,\n close,\n toggle,\n openArticle,\n openCategory,\n search,\n navigate,\n setTheme,\n setTextSelectionEnabled,\n setDOMScanningEnabled,\n isDOMScanningEnabled,\n scanPage,\n on,\n ]\n );\n\n return (\n <PillarContext.Provider value={value}>{children}</PillarContext.Provider>\n );\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function usePillarContext(): PillarContextValue {\n const context = useContext(PillarContext);\n\n if (!context) {\n throw new Error(\"usePillarContext must be used within a PillarProvider\");\n }\n\n return context;\n}\n","/**\n * PillarPanel Component\n * Renders the Pillar help panel at a custom location in the DOM\n */\n\nimport React, { useRef, useEffect, type CSSProperties, type HTMLAttributes } from 'react';\nimport { usePillarContext } from './PillarProvider';\n\nexport interface PillarPanelProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name for the container */\n className?: string;\n \n /** Custom inline styles for the container */\n style?: CSSProperties;\n}\n\n/**\n * Renders the Pillar help panel at a custom location in the DOM.\n * Use this when you want to control where the panel is rendered instead of\n * having it automatically appended to document.body.\n * \n * **Important**: When using this component, set `panel.container: 'manual'` in your\n * PillarProvider config to prevent automatic mounting.\n * \n * @example\n * ```tsx\n * <PillarProvider \n * productKey=\"my-product-key\"\n * config={{ panel: { container: 'manual' } }}\n * >\n * <div className=\"my-layout\">\n * <Sidebar />\n * <PillarPanel className=\"help-panel-container\" />\n * <MainContent />\n * </div>\n * </PillarProvider>\n * ```\n */\nexport function PillarPanel({ \n className, \n style,\n ...props \n}: PillarPanelProps): React.ReactElement {\n const containerRef = useRef<HTMLDivElement>(null);\n const { pillar, isReady } = usePillarContext();\n const hasMounted = useRef(false);\n\n useEffect(() => {\n // Only mount once when SDK is ready and we have a container\n if (!isReady || !pillar || !containerRef.current || hasMounted.current) {\n return;\n }\n\n // Mount the panel into our container\n pillar.mountPanelTo(containerRef.current);\n hasMounted.current = true;\n\n // Cleanup is handled by Pillar.destroy() in the provider\n }, [isReady, pillar]);\n\n return (\n <div \n ref={containerRef} \n className={className}\n style={style}\n data-pillar-panel-container=\"\"\n {...props}\n />\n );\n}\n\n","/**\n * useHelpPanel Hook\n * Panel-specific controls and state\n */\n\nimport { useCallback } from 'react';\nimport { usePillarContext } from '../PillarProvider';\n\nexport interface UseHelpPanelResult {\n /** Whether the panel is currently open */\n isOpen: boolean;\n \n /** Open the panel */\n open: (options?: { view?: string; article?: string; search?: string }) => void;\n \n /** Close the panel */\n close: () => void;\n \n /** Toggle the panel */\n toggle: () => void;\n \n /** Open a specific article in the panel */\n openArticle: (slug: string) => void;\n \n /** Open a specific category in the panel */\n openCategory: (slug: string) => Promise<void>;\n \n /** Open search with a query */\n openSearch: (query?: string) => void;\n \n /** Open the AI chat */\n openChat: () => void;\n}\n\n/**\n * Hook for panel-specific controls\n * \n * @example\n * ```tsx\n * function HelpButton() {\n * const { isOpen, toggle, openChat } = useHelpPanel();\n * \n * return (\n * <div>\n * <button onClick={toggle}>\n * {isOpen ? 'Close' : 'Help'}\n * </button>\n * <button onClick={openChat}>\n * Ask AI\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useHelpPanel(): UseHelpPanelResult {\n const { isPanelOpen, open, close, toggle, openArticle, openCategory, search, navigate } = usePillarContext();\n\n const openSearch = useCallback(\n (query?: string) => {\n if (query) {\n search(query);\n } else {\n open({ view: 'search' });\n }\n },\n [search, open]\n );\n\n const openChat = useCallback(() => {\n navigate('chat');\n }, [navigate]);\n\n return {\n isOpen: isPanelOpen,\n open,\n close,\n toggle,\n openArticle,\n openCategory,\n openSearch,\n openChat,\n };\n}\n\n","/**\n * usePillar Hook\n * Access Pillar SDK instance and state with optional type-safe onTask\n */\n\nimport type {\n SyncActionDefinitions,\n ActionDefinitions,\n ActionDataType,\n ActionNames,\n} from '@pillar-ai/sdk';\nimport { useCallback } from 'react';\nimport { usePillarContext, type PillarContextValue } from '../PillarProvider';\n\nexport type UsePillarResult = PillarContextValue;\n\n/**\n * Extended result with type-safe onTask method.\n *\n * @template TActions - The action definitions for type inference\n */\nexport interface TypedUsePillarResult<\n TActions extends SyncActionDefinitions | ActionDefinitions,\n> extends Omit<PillarContextValue, 'pillar'> {\n pillar: PillarContextValue['pillar'];\n /**\n * Type-safe task handler registration.\n *\n * @param taskName - The action name (autocompleted from your actions)\n * @param handler - Handler function with typed data parameter\n * @returns Unsubscribe function\n */\n onTask: <TName extends ActionNames<TActions>>(\n taskName: TName,\n handler: (data: ActionDataType<TActions, TName>) => void\n ) => () => void;\n}\n\n/**\n * Hook to access the Pillar SDK instance and state\n *\n * @example Basic usage (untyped)\n * ```tsx\n * function MyComponent() {\n * const { isReady, open, close, isPanelOpen } = usePillar();\n *\n * if (!isReady) return <div>Loading...</div>;\n *\n * return (\n * <button onClick={() => open()}>\n * {isPanelOpen ? 'Close Help' : 'Get Help'}\n * </button>\n * );\n * }\n * ```\n *\n * @example Type-safe onTask with action definitions\n * ```tsx\n * import { actions } from '@/lib/pillar/actions';\n *\n * function MyComponent() {\n * const { pillar, onTask } = usePillar<typeof actions>();\n *\n * useEffect(() => {\n * // TypeScript knows data has { type, url, name }\n * const unsub = onTask('add_new_source', (data) => {\n * console.log(data.url); // ✓ Typed!\n * });\n * return unsub;\n * }, [onTask]);\n * }\n * ```\n */\nexport function usePillar<\n TActions extends SyncActionDefinitions | ActionDefinitions = SyncActionDefinitions,\n>(): TypedUsePillarResult<TActions> {\n const context = usePillarContext();\n\n // Create a type-safe wrapper around pillar.onTask\n const onTask = useCallback(\n <TName extends ActionNames<TActions>>(\n taskName: TName,\n handler: (data: ActionDataType<TActions, TName>) => void\n ): (() => void) => {\n if (!context.pillar) {\n // Return no-op if pillar not ready\n return () => {};\n }\n // Cast handler to match the SDK's expected type\n // The runtime behavior is the same, this is just for type narrowing\n return context.pillar.onTask(\n taskName as string,\n handler as (data: Record<string, unknown>) => void\n );\n },\n [context.pillar]\n );\n\n return {\n ...context,\n onTask,\n };\n}\n\n","/**\n * usePillarTool Hook\n *\n * Register one or more tools with co-located metadata and handlers.\n * Tools are registered on mount and unregistered on unmount.\n *\n * @example Single tool\n * ```tsx\n * import { usePillarTool } from '@pillar-ai/react';\n *\n * function CartButton() {\n * usePillarTool({\n * name: 'add_to_cart',\n * description: 'Add a product to the shopping cart',\n * inputSchema: {\n * type: 'object',\n * properties: {\n * productId: { type: 'string', description: 'Product ID' },\n * quantity: { type: 'number', description: 'Quantity to add' },\n * },\n * required: ['productId', 'quantity'],\n * },\n * execute: async ({ productId, quantity }) => {\n * await cartApi.add(productId, quantity);\n * return { content: [{ type: 'text', text: 'Added to cart' }] };\n * },\n * });\n *\n * return <button>Cart</button>;\n * }\n * ```\n *\n * @example Multiple tools\n * ```tsx\n * import { usePillarTool } from '@pillar-ai/react';\n *\n * function BillingPage() {\n * usePillarTool([\n * {\n * name: 'get_current_plan',\n * description: 'Get the current billing plan',\n * execute: async () => ({ plan: 'pro', price: 29 }),\n * },\n * {\n * name: 'upgrade_plan',\n * description: 'Upgrade to a higher plan',\n * inputSchema: {\n * type: 'object',\n * properties: { planId: { type: 'string' } },\n * required: ['planId'],\n * },\n * execute: async ({ planId }) => {\n * await billingApi.upgrade(planId);\n * return { content: [{ type: 'text', text: 'Upgraded!' }] };\n * },\n * },\n * ]);\n *\n * return <div>Billing Content</div>;\n * }\n * ```\n */\n\nimport type { ToolSchema } from \"@pillar-ai/sdk\";\nimport { useEffect, useMemo, useRef } from \"react\";\nimport { usePillarContext } from \"../PillarProvider\";\n\n/**\n * Register one or more Pillar tools with co-located metadata and handlers.\n *\n * The tools are registered when the component mounts and automatically\n * unregistered when it unmounts. The `execute` functions always capture\n * the latest React state and props via refs, so you don't need to worry\n * about stale closures.\n *\n * @param schemaOrSchemas - Single tool schema or array of tool schemas\n */\nexport function usePillarTool(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schemaOrSchemas: ToolSchema<any> | ToolSchema<any>[]\n): void {\n const { pillar } = usePillarContext();\n\n // Normalize to array for consistent handling\n const schemas = useMemo(\n () =>\n Array.isArray(schemaOrSchemas) ? schemaOrSchemas : [schemaOrSchemas],\n [schemaOrSchemas]\n );\n\n // Keep refs to latest schemas so handlers capture current state/props\n const schemasRef = useRef(schemas);\n schemasRef.current = schemas;\n\n // Stable dependency key for the effect (tool names joined)\n const toolNamesKey = useMemo(\n () => schemas.map((s) => s.name).join(\",\"),\n [schemas]\n );\n\n useEffect(() => {\n if (!pillar) return;\n\n // Register all tools and collect unsubscribe functions\n const unsubscribes = schemasRef.current.map((schema, index) => {\n return pillar.defineTool({\n ...schema,\n // Wrap execute to always use the latest ref version\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n execute: (input: any) => schemasRef.current[index].execute(input),\n } as ToolSchema);\n });\n\n // Cleanup: unregister all tools\n return () => {\n unsubscribes.forEach((unsub) => unsub());\n };\n }, [pillar, toolNamesKey]);\n}\n\n/** @deprecated Use usePillarTool instead */\nexport const usePillarAction = usePillarTool;\n"],"names":["createContext","useState","useRef","useEffect","Pillar","createRoot","_jsx","useCallback","scanPageDirect","useMemo","useContext"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pillar-ai/react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "React SDK for Pillar product copilot — AI assistant for SaaS and web apps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.esm.js",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"react-dom": ">=17.0.0 || >=19.0.0"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@pillar-ai/sdk": "^0.1.
|
|
58
|
+
"@pillar-ai/sdk": "^0.1.25"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@rollup/plugin-commonjs": "^25.0.7",
|