@pillar-ai/angular 0.1.11
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/LICENSE +21 -0
- package/README.md +357 -0
- package/dist/LICENSE +21 -0
- package/dist/README.md +357 -0
- package/dist/esm2022/lib/inject-help-panel.mjs +59 -0
- package/dist/esm2022/lib/inject-pillar-tool.mjs +111 -0
- package/dist/esm2022/lib/inject-pillar.mjs +79 -0
- package/dist/esm2022/lib/pillar-panel.component.mjs +80 -0
- package/dist/esm2022/lib/pillar.service.mjs +308 -0
- package/dist/esm2022/lib/types.mjs +5 -0
- package/dist/esm2022/pillar-ai-angular.mjs +5 -0
- package/dist/esm2022/public-api.mjs +67 -0
- package/dist/fesm2022/pillar-ai-angular.mjs +695 -0
- package/dist/fesm2022/pillar-ai-angular.mjs.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/lib/inject-help-panel.d.ts +34 -0
- package/dist/lib/inject-pillar-tool.d.ts +89 -0
- package/dist/lib/inject-pillar.d.ts +96 -0
- package/dist/lib/pillar-panel.component.d.ts +58 -0
- package/dist/lib/pillar.service.d.ts +126 -0
- package/dist/lib/types.d.ts +119 -0
- package/dist/public-api.d.ts +77 -0
- package/package.json +73 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pillar-ai-angular.mjs","sources":["../../src/lib/pillar.service.ts","../../src/lib/pillar-panel.component.ts","../../src/lib/inject-pillar.ts","../../src/lib/inject-help-panel.ts","../../src/lib/inject-pillar-tool.ts","../../src/public-api.ts","../../src/pillar-ai-angular.ts"],"sourcesContent":["/**\n * PillarService\n * Angular service that initializes and manages the Pillar SDK\n */\n\nimport {\n Injectable,\n NgZone,\n signal,\n computed,\n inject,\n createComponent,\n ApplicationRef,\n EnvironmentInjector,\n type Type,\n} from '@angular/core';\nimport {\n Pillar,\n type CardCallbacks,\n type PillarConfig,\n type PillarEvents,\n type PillarState,\n type TaskExecutePayload,\n type ThemeConfig,\n type ToolSchema,\n} from '@pillar-ai/sdk';\nimport type { CardComponent, PillarInitConfig } from './types';\n\n@Injectable({ providedIn: 'root' })\nexport class PillarService {\n private readonly ngZone = inject(NgZone);\n private readonly appRef = inject(ApplicationRef);\n private readonly environmentInjector = inject(EnvironmentInjector);\n\n // Internal state\n private readonly _pillar = signal<Pillar | null>(null);\n private readonly cleanupFns: Array<() => void> = [];\n private readonly cardRefs: Map<HTMLElement, any> = new Map();\n private onTaskCallback: ((task: TaskExecutePayload) => void) | null = null;\n private registeredCards: Record<string, CardComponent> | null = null;\n\n // Public signals\n readonly state = signal<PillarState>('uninitialized');\n readonly isReady = computed(() => this.state() === 'ready');\n readonly isPanelOpen = signal(false);\n\n /**\n * Get the Pillar SDK instance.\n */\n getInstance(): Pillar | null {\n return this._pillar();\n }\n\n /**\n * Initialize the Pillar SDK.\n * Call this in your app's initialization (e.g., APP_INITIALIZER).\n *\n * @param initConfig - Configuration options\n */\n async init(initConfig: PillarInitConfig): Promise<void> {\n const { productKey, helpCenter, config, onTask, cards } = initConfig;\n\n // Support both productKey (new) and helpCenter (deprecated)\n const resolvedKey = productKey ?? helpCenter;\n\n if (helpCenter && !productKey) {\n console.warn(\n '[Pillar Angular] \"helpCenter\" is deprecated. Use \"productKey\" instead.'\n );\n }\n\n // Store callbacks for later use\n this.onTaskCallback = onTask ?? null;\n this.registeredCards = cards ?? null;\n\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 this._pillar.set(existingInstance);\n this.state.set(existingInstance.state);\n this.subscribeToEvents(existingInstance);\n this.registerCards(existingInstance);\n return;\n }\n\n // Initialize new instance\n const instance = await Pillar.init({\n productKey: resolvedKey,\n ...config,\n });\n\n this.ngZone.run(() => {\n this._pillar.set(instance);\n this.state.set(instance.state);\n });\n\n this.subscribeToEvents(instance);\n this.registerCards(instance);\n } catch (error) {\n console.error('[Pillar Angular] Failed to initialize:', error);\n this.ngZone.run(() => {\n this.state.set('error');\n });\n throw error;\n }\n }\n\n /**\n * Subscribe to SDK events and sync to Angular signals.\n */\n private subscribeToEvents(instance: Pillar): void {\n // Panel open/close events\n const unsubOpen = instance.on('panel:open', () => {\n this.ngZone.run(() => {\n this.isPanelOpen.set(true);\n });\n });\n this.cleanupFns.push(unsubOpen);\n\n const unsubClose = instance.on('panel:close', () => {\n this.ngZone.run(() => {\n this.isPanelOpen.set(false);\n });\n });\n this.cleanupFns.push(unsubClose);\n\n // State change events\n const unsubReady = instance.on('ready', () => {\n this.ngZone.run(() => {\n this.state.set('ready');\n });\n });\n this.cleanupFns.push(unsubReady);\n\n const unsubError = instance.on('error', () => {\n this.ngZone.run(() => {\n this.state.set('error');\n });\n });\n this.cleanupFns.push(unsubError);\n\n // Task execution events\n if (this.onTaskCallback) {\n const callback = this.onTaskCallback;\n const unsubTask = instance.on('task:execute', (task) => {\n this.ngZone.run(() => {\n callback(task);\n });\n });\n this.cleanupFns.push(unsubTask);\n }\n }\n\n /**\n * Register custom card components.\n */\n private registerCards(instance: Pillar): void {\n if (!this.registeredCards) return;\n\n Object.entries(this.registeredCards).forEach(([cardType, CardComponent]) => {\n const unsubscribe = instance.registerCard(\n cardType,\n (container, data, callbacks: CardCallbacks) => {\n // Create an Angular component dynamically\n const componentRef = createComponent(CardComponent as Type<any>, {\n environmentInjector: this.environmentInjector,\n });\n\n // Set inputs\n componentRef.setInput('data', data);\n componentRef.setInput('onConfirm', callbacks.onConfirm);\n componentRef.setInput('onCancel', callbacks.onCancel);\n componentRef.setInput('onStateChange', callbacks.onStateChange);\n\n // Attach to the application\n this.appRef.attachView(componentRef.hostView);\n\n // Append to container\n container.appendChild(componentRef.location.nativeElement);\n this.cardRefs.set(container, componentRef);\n\n // Return cleanup function\n return () => {\n const ref = this.cardRefs.get(container);\n if (ref) {\n this.appRef.detachView(ref.hostView);\n ref.destroy();\n this.cardRefs.delete(container);\n }\n };\n }\n );\n\n this.cleanupFns.push(unsubscribe);\n });\n }\n\n /**\n * Open the help panel.\n */\n open(options?: {\n view?: string;\n article?: string;\n search?: string;\n focusInput?: boolean;\n }): void {\n this._pillar()?.open(options);\n }\n\n /**\n * Close the help panel.\n */\n close(): void {\n this._pillar()?.close();\n }\n\n /**\n * Toggle the help panel.\n */\n toggle(): void {\n this._pillar()?.toggle();\n }\n\n /**\n * Open a specific article.\n */\n openArticle(slug: string): void {\n this._pillar()?.open({ article: slug });\n }\n\n /**\n * Open a specific category.\n */\n async openCategory(slug: string): Promise<void> {\n this._pillar()?.navigate('category', { slug });\n }\n\n /**\n * Perform a search.\n */\n search(query: string): void {\n this._pillar()?.open({ search: query });\n }\n\n /**\n * Navigate to a specific view.\n */\n navigate(view: string, params?: Record<string, string>): void {\n this._pillar()?.navigate(view, params);\n }\n\n /**\n * Update the panel theme at runtime.\n */\n setTheme(theme: Partial<ThemeConfig>): void {\n this._pillar()?.setTheme(theme);\n }\n\n /**\n * Enable or disable the text selection \"Ask AI\" popover.\n */\n setTextSelectionEnabled(enabled: boolean): void {\n this._pillar()?.setTextSelectionEnabled(enabled);\n }\n\n /**\n * Subscribe to SDK events.\n */\n on<K extends keyof PillarEvents>(\n event: K,\n callback: (data: PillarEvents[K]) => void\n ): () => void {\n const pillar = this._pillar();\n if (!pillar) {\n return () => {};\n }\n\n // Wrap callback to run in Angular zone\n const wrappedCallback = (data: PillarEvents[K]) => {\n this.ngZone.run(() => callback(data));\n };\n\n return pillar.on(event, wrappedCallback);\n }\n\n /**\n * Register a task handler.\n */\n onTask(\n taskName: string,\n handler: (data: Record<string, unknown>) => void\n ): () => void {\n const pillar = this._pillar();\n if (!pillar) {\n return () => {};\n }\n\n // Wrap handler to run in Angular zone\n const wrappedHandler = (data: Record<string, unknown>) => {\n this.ngZone.run(() => handler(data));\n };\n\n return pillar.onTask(taskName, wrappedHandler);\n }\n\n /**\n * Define a tool with metadata and handler.\n * Returns an unsubscribe function to remove the tool.\n *\n * @example\n * ```typescript\n * const unsubscribe = pillarService.defineTool({\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' },\n * quantity: { type: 'number' },\n * },\n * required: ['productId', 'quantity'],\n * },\n * execute: async ({ productId, quantity }) => {\n * await this.cartService.add(productId, quantity);\n * return { content: [{ type: 'text', text: 'Added to cart' }] };\n * },\n * });\n *\n * // Later, to unregister:\n * unsubscribe();\n * ```\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n defineTool(schema: ToolSchema<any>): () => void {\n const pillar = this._pillar();\n if (!pillar) {\n console.warn('[Pillar Angular] Cannot define tool - SDK not initialized');\n return () => {};\n }\n\n // Wrap execute to run in Angular zone\n const wrappedSchema = {\n ...schema,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n execute: async (input: any) => {\n return this.ngZone.run(() => schema.execute(input));\n },\n };\n\n return pillar.defineTool(wrappedSchema);\n }\n\n /**\n * Mount the panel to a specific container element.\n * Used for manual panel placement with PillarPanelComponent.\n */\n mountPanelTo(container: HTMLElement): void {\n this._pillar()?.mountPanelTo(container);\n }\n\n /**\n * Cleanup resources.\n * Note: We intentionally don't call Pillar.destroy() here to preserve\n * conversation history across route changes. Call Pillar.destroy()\n * explicitly if you need to fully reset the SDK.\n */\n ngOnDestroy(): void {\n // Run all cleanup functions\n this.cleanupFns.forEach((cleanup) => cleanup());\n this.cleanupFns.length = 0;\n\n // Destroy all card component refs\n this.cardRefs.forEach((ref) => {\n this.appRef.detachView(ref.hostView);\n ref.destroy();\n });\n this.cardRefs.clear();\n }\n}\n","/**\n * PillarPanelComponent\n * Renders the Pillar help panel at a custom location in the DOM\n */\n\nimport {\n Component,\n ElementRef,\n ViewChild,\n AfterViewInit,\n OnDestroy,\n inject,\n effect,\n input,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport { PillarService } from './pillar.service';\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 * Pillar configuration to prevent automatic mounting.\n *\n * @example\n * ```typescript\n * // app.config.ts\n * function initPillar() {\n * const pillar = inject(PillarService);\n * return () => pillar.init({\n * productKey: 'your-product-key',\n * config: { panel: { container: 'manual' } }\n * });\n * }\n *\n * // layout.component.ts\n * @Component({\n * selector: 'app-layout',\n * standalone: true,\n * imports: [PillarPanelComponent],\n * template: `\n * <div class=\"layout\">\n * <app-sidebar />\n * <pillar-panel class=\"help-panel-container\" />\n * <main>\n * <router-outlet />\n * </main>\n * </div>\n * `,\n * })\n * export class LayoutComponent {}\n * ```\n */\n@Component({\n selector: 'pillar-panel',\n standalone: true,\n template: '<div #container data-pillar-panel-container></div>',\n styles: [\n `\n :host {\n display: block;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PillarPanelComponent implements AfterViewInit, OnDestroy {\n @ViewChild('container', { static: true })\n private containerRef!: ElementRef<HTMLDivElement>;\n\n private readonly pillarService = inject(PillarService);\n private hasMounted = false;\n private effectRef: ReturnType<typeof effect> | null = null;\n\n /**\n * Optional class to add to the container element.\n * Use host binding for styling instead if possible.\n */\n readonly containerClass = input<string>('');\n\n ngAfterViewInit(): void {\n // Use effect to react to isReady signal changes\n this.effectRef = effect(() => {\n const isReady = this.pillarService.isReady();\n\n if (isReady && !this.hasMounted && this.containerRef?.nativeElement) {\n this.pillarService.mountPanelTo(this.containerRef.nativeElement);\n this.hasMounted = true;\n }\n });\n }\n\n ngOnDestroy(): void {\n // Effect is automatically cleaned up when component is destroyed\n // Panel cleanup is handled by PillarService\n this.effectRef?.destroy();\n }\n}\n","/**\n * injectPillar Function\n * Angular-idiomatic injection helper for accessing Pillar SDK\n */\n\nimport { inject } from '@angular/core';\nimport type {\n SyncActionDefinitions,\n ActionDefinitions,\n ActionDataType,\n ActionNames,\n} from '@pillar-ai/sdk';\nimport { PillarService } from './pillar.service';\n\n/**\n * Result type for injectPillar with type-safe onTask.\n *\n * @template TActions - The action definitions for type inference\n */\nexport interface InjectPillarResult<\n TActions extends SyncActionDefinitions | ActionDefinitions = SyncActionDefinitions,\n> {\n /** Get the Pillar SDK instance */\n pillar: () => ReturnType<PillarService['getInstance']>;\n\n /** Current SDK state */\n state: PillarService['state'];\n\n /** Whether the SDK is ready */\n isReady: PillarService['isReady'];\n\n /** Whether the panel is currently open */\n isPanelOpen: PillarService['isPanelOpen'];\n\n /** Open the help panel */\n open: PillarService['open'];\n\n /** Close the help panel */\n close: PillarService['close'];\n\n /** Toggle the help panel */\n toggle: PillarService['toggle'];\n\n /** Open a specific article */\n openArticle: PillarService['openArticle'];\n\n /** Open a specific category */\n openCategory: PillarService['openCategory'];\n\n /** Perform a search */\n search: PillarService['search'];\n\n /** Navigate to a specific view */\n navigate: PillarService['navigate'];\n\n /** Update the panel theme at runtime */\n setTheme: PillarService['setTheme'];\n\n /** Enable or disable the text selection \"Ask AI\" popover */\n setTextSelectionEnabled: PillarService['setTextSelectionEnabled'];\n\n /** Subscribe to SDK events */\n on: PillarService['on'];\n\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 * Angular injection function to access the Pillar SDK.\n * Use this in components, directives, or services to interact with Pillar.\n *\n * Must be called within an injection context (constructor, field initializer, or inject()).\n *\n * @example Basic usage (untyped)\n * ```typescript\n * @Component({\n * selector: 'app-help-button',\n * standalone: true,\n * template: `\n * <button (click)=\"toggle()\">\n * {{ isPanelOpen() ? 'Close Help' : 'Get Help' }}\n * </button>\n * `,\n * })\n * export class HelpButtonComponent {\n * private pillar = injectPillar();\n * isPanelOpen = this.pillar.isPanelOpen;\n * toggle = this.pillar.toggle;\n * }\n * ```\n *\n * @example Type-safe onTask with action definitions\n * ```typescript\n * import { actions } from '@/lib/pillar/actions';\n *\n * @Component({...})\n * export class MyComponent implements OnInit, OnDestroy {\n * private pillar = injectPillar<typeof actions>();\n * private unsubscribe?: () => void;\n *\n * ngOnInit() {\n * // TypeScript knows data has the correct shape\n * this.unsubscribe = this.pillar.onTask('add_new_source', (data) => {\n * console.log(data.url); // ✓ Typed!\n * });\n * }\n *\n * ngOnDestroy() {\n * this.unsubscribe?.();\n * }\n * }\n * ```\n */\nexport function injectPillar<\n TActions extends SyncActionDefinitions | ActionDefinitions = SyncActionDefinitions,\n>(): InjectPillarResult<TActions> {\n const service = inject(PillarService);\n\n // Create a type-safe wrapper around pillar.onTask\n const onTask = <TName extends ActionNames<TActions>>(\n taskName: TName,\n handler: (data: ActionDataType<TActions, TName>) => void\n ): (() => void) => {\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 service.onTask(\n taskName as string,\n handler as (data: Record<string, unknown>) => void\n );\n };\n\n return {\n pillar: () => service.getInstance(),\n state: service.state,\n isReady: service.isReady,\n isPanelOpen: service.isPanelOpen,\n open: service.open.bind(service),\n close: service.close.bind(service),\n toggle: service.toggle.bind(service),\n openArticle: service.openArticle.bind(service),\n openCategory: service.openCategory.bind(service),\n search: service.search.bind(service),\n navigate: service.navigate.bind(service),\n setTheme: service.setTheme.bind(service),\n setTextSelectionEnabled: service.setTextSelectionEnabled.bind(service),\n on: service.on.bind(service),\n onTask,\n };\n}\n","/**\n * injectHelpPanel Function\n * Angular injection helper for panel-specific controls\n */\n\nimport { inject, computed } from '@angular/core';\nimport { PillarService } from './pillar.service';\nimport type { InjectHelpPanelResult } from './types';\n\n/**\n * Angular injection function for panel-specific controls.\n * Provides a simplified API focused on panel operations.\n *\n * Must be called within an injection context (constructor, field initializer, or inject()).\n *\n * @example\n * ```typescript\n * @Component({\n * selector: 'app-help-menu',\n * standalone: true,\n * template: `\n * <div>\n * <button (click)=\"toggle()\">\n * {{ isOpen() ? 'Close' : 'Help' }}\n * </button>\n * <button (click)=\"openChat()\">Ask AI</button>\n * </div>\n * `,\n * })\n * export class HelpMenuComponent {\n * private panel = injectHelpPanel();\n * isOpen = this.panel.isOpen;\n * toggle = this.panel.toggle;\n * openChat = this.panel.openChat;\n * }\n * ```\n */\nexport function injectHelpPanel(): InjectHelpPanelResult {\n const service = inject(PillarService);\n\n const openSearch = (query?: string): void => {\n if (query) {\n service.search(query);\n } else {\n service.open({ view: 'search' });\n }\n };\n\n const openChat = (): void => {\n service.navigate('chat');\n };\n\n return {\n isOpen: computed(() => service.isPanelOpen()),\n open: service.open.bind(service),\n close: service.close.bind(service),\n toggle: service.toggle.bind(service),\n openArticle: service.openArticle.bind(service),\n openCategory: service.openCategory.bind(service),\n openSearch,\n openChat,\n };\n}\n","/**\n * injectPillarTool Function\n * Angular-idiomatic injection helper for registering Pillar tools\n *\n * Register one or more tools with co-located metadata and handlers.\n * Tools are registered when called and automatically unregistered\n * when the component is destroyed.\n *\n * @example Single tool\n * ```typescript\n * import { Component } from '@angular/core';\n * import { injectPillarTool } from '@pillar-ai/angular';\n *\n * @Component({\n * selector: 'app-cart-button',\n * standalone: true,\n * template: `<button>Cart</button>`,\n * })\n * export class CartButtonComponent {\n * constructor() {\n * injectPillarTool({\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 * }\n * ```\n *\n * @example Multiple tools\n * ```typescript\n * import { Component } from '@angular/core';\n * import { injectPillarTool } from '@pillar-ai/angular';\n *\n * @Component({\n * selector: 'app-billing-page',\n * standalone: true,\n * template: `<div>Billing Content</div>`,\n * })\n * export class BillingPageComponent {\n * constructor() {\n * injectPillarTool([\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 * }\n * ```\n */\n\nimport { inject, DestroyRef } from '@angular/core';\nimport type { ToolSchema } from '@pillar-ai/sdk';\nimport { PillarService } from './pillar.service';\n\n/**\n * Register one or more Pillar tools with co-located metadata and handlers.\n *\n * The tools are registered when this function is called and automatically\n * unregistered when the component is destroyed. Must be called within\n * an injection context (constructor, field initializer, or inject()).\n *\n * @param schemaOrSchemas - Single tool schema or array of tool schemas\n */\nexport function injectPillarTool(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schemaOrSchemas: ToolSchema<any> | ToolSchema<any>[]\n): void {\n const service = inject(PillarService);\n const destroyRef = inject(DestroyRef);\n\n // Normalize to array for consistent handling\n const schemas = Array.isArray(schemaOrSchemas)\n ? schemaOrSchemas\n : [schemaOrSchemas];\n\n // Track unsubscribe functions\n const unsubscribes: Array<() => void> = [];\n\n // Register all tools\n schemas.forEach((schema) => {\n const unsub = service.defineTool(schema);\n unsubscribes.push(unsub);\n });\n\n // Cleanup on destroy\n destroyRef.onDestroy(() => {\n unsubscribes.forEach((unsub) => unsub());\n });\n}\n\n/** @deprecated Use injectPillarTool instead */\nexport const injectPillarAction = injectPillarTool;\n","/**\n * @pillar-ai/angular - Angular bindings for Pillar SDK\n *\n * @example\n * ```typescript\n * // app.config.ts\n * import { ApplicationConfig, APP_INITIALIZER, inject } from '@angular/core';\n * import { PillarService } from '@pillar-ai/angular';\n *\n * function initPillar() {\n * const pillar = inject(PillarService);\n * return () => pillar.init({ productKey: 'your-product-key' });\n * }\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * { provide: APP_INITIALIZER, useFactory: initPillar, multi: true },\n * ],\n * };\n *\n * // help-button.component.ts\n * import { Component } from '@angular/core';\n * import { injectPillar } from '@pillar-ai/angular';\n *\n * @Component({\n * selector: 'app-help-button',\n * standalone: true,\n * template: `\n * <button (click)=\"toggle()\">\n * {{ isPanelOpen() ? 'Close Help' : 'Get Help' }}\n * </button>\n * `,\n * })\n * export class HelpButtonComponent {\n * private pillar = injectPillar();\n * isPanelOpen = this.pillar.isPanelOpen;\n * toggle = this.pillar.toggle;\n * }\n *\n * // Custom panel placement example:\n * // layout.component.ts\n * import { Component } from '@angular/core';\n * import { PillarPanelComponent } from '@pillar-ai/angular';\n *\n * @Component({\n * selector: 'app-layout',\n * standalone: true,\n * imports: [PillarPanelComponent],\n * template: `\n * <div class=\"layout\">\n * <pillar-panel class=\"custom-panel\" />\n * <main>Your content</main>\n * </div>\n * `,\n * })\n * export class LayoutComponent {}\n * ```\n */\n\n// Service\nexport { PillarService } from './lib/pillar.service';\n\n// Components\nexport { PillarPanelComponent } from './lib/pillar-panel.component';\n\n// Inject functions\nexport { injectPillar, type InjectPillarResult } from './lib/inject-pillar';\nexport { injectHelpPanel } from './lib/inject-help-panel';\nexport { injectPillarTool, injectPillarAction } from './lib/inject-pillar-tool';\n\n// Types\nexport type {\n CardComponent,\n CardComponentProps,\n PillarContextValue,\n PillarInitConfig,\n PillarServiceActions,\n PillarServiceState,\n InjectHelpPanelResult,\n} from './lib/types';\n\n// Re-export types from core SDK for convenience\nexport type {\n // Configuration types\n EdgeTriggerConfig,\n MobileTriggerConfig,\n MobileTriggerPosition,\n MobileTriggerIcon,\n MobileTriggerSize,\n PanelConfig,\n PillarConfig,\n PillarEvents,\n PillarState,\n ResolvedConfig,\n ResolvedMobileTriggerConfig,\n ResolvedThemeConfig,\n TaskExecutePayload,\n TextSelectionConfig,\n ThemeColors,\n ThemeConfig,\n ThemeMode,\n CardCallbacks,\n CardRenderer,\n SidebarTabConfig,\n // Tool types for type-safe onTask and injectPillarTool\n ToolDefinitions,\n SyncToolDefinitions,\n ToolDataType,\n ToolNames,\n // Unified tool schema (new API)\n ToolExecuteResult,\n ToolSchema,\n ToolType,\n // Backwards compatibility aliases (deprecated)\n ActionDefinitions,\n SyncActionDefinitions,\n ActionDataType,\n ActionNames,\n ActionResult,\n ActionSchema,\n ActionType,\n // Chat context for escalation\n ChatContext,\n // DOM Scanning types (deprecated - feature is disabled)\n /** @deprecated DOM scanning is disabled */\n DOMScanningConfig,\n /** @deprecated DOM scanning is disabled */\n ResolvedDOMScanningConfig,\n /** @deprecated DOM scanning is disabled */\n ScanOptions,\n /** @deprecated DOM scanning is disabled */\n CompactScanResult,\n /** @deprecated DOM scanning is disabled */\n InteractionType,\n // DOM Scanner utilities (deprecated - feature is disabled)\n /** @deprecated DOM scanning is disabled */\n scanPageDirect,\n} from '@pillar-ai/sdk';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* injectHelpPanel Function
|
|
3
|
+
* Angular injection helper for panel-specific controls
|
|
4
|
+
*/
|
|
5
|
+
import type { InjectHelpPanelResult } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Angular injection function for panel-specific controls.
|
|
8
|
+
* Provides a simplified API focused on panel operations.
|
|
9
|
+
*
|
|
10
|
+
* Must be called within an injection context (constructor, field initializer, or inject()).
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* @Component({
|
|
15
|
+
* selector: 'app-help-menu',
|
|
16
|
+
* standalone: true,
|
|
17
|
+
* template: `
|
|
18
|
+
* <div>
|
|
19
|
+
* <button (click)="toggle()">
|
|
20
|
+
* {{ isOpen() ? 'Close' : 'Help' }}
|
|
21
|
+
* </button>
|
|
22
|
+
* <button (click)="openChat()">Ask AI</button>
|
|
23
|
+
* </div>
|
|
24
|
+
* `,
|
|
25
|
+
* })
|
|
26
|
+
* export class HelpMenuComponent {
|
|
27
|
+
* private panel = injectHelpPanel();
|
|
28
|
+
* isOpen = this.panel.isOpen;
|
|
29
|
+
* toggle = this.panel.toggle;
|
|
30
|
+
* openChat = this.panel.openChat;
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function injectHelpPanel(): InjectHelpPanelResult;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* injectPillarTool Function
|
|
3
|
+
* Angular-idiomatic injection helper for registering Pillar tools
|
|
4
|
+
*
|
|
5
|
+
* Register one or more tools with co-located metadata and handlers.
|
|
6
|
+
* Tools are registered when called and automatically unregistered
|
|
7
|
+
* when the component is destroyed.
|
|
8
|
+
*
|
|
9
|
+
* @example Single tool
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { Component } from '@angular/core';
|
|
12
|
+
* import { injectPillarTool } from '@pillar-ai/angular';
|
|
13
|
+
*
|
|
14
|
+
* @Component({
|
|
15
|
+
* selector: 'app-cart-button',
|
|
16
|
+
* standalone: true,
|
|
17
|
+
* template: `<button>Cart</button>`,
|
|
18
|
+
* })
|
|
19
|
+
* export class CartButtonComponent {
|
|
20
|
+
* constructor() {
|
|
21
|
+
* injectPillarTool({
|
|
22
|
+
* name: 'add_to_cart',
|
|
23
|
+
* description: 'Add a product to the shopping cart',
|
|
24
|
+
* inputSchema: {
|
|
25
|
+
* type: 'object',
|
|
26
|
+
* properties: {
|
|
27
|
+
* productId: { type: 'string', description: 'Product ID' },
|
|
28
|
+
* quantity: { type: 'number', description: 'Quantity to add' },
|
|
29
|
+
* },
|
|
30
|
+
* required: ['productId', 'quantity'],
|
|
31
|
+
* },
|
|
32
|
+
* execute: async ({ productId, quantity }) => {
|
|
33
|
+
* await cartApi.add(productId, quantity);
|
|
34
|
+
* return { content: [{ type: 'text', text: 'Added to cart' }] };
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
* }
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @example Multiple tools
|
|
42
|
+
* ```typescript
|
|
43
|
+
* import { Component } from '@angular/core';
|
|
44
|
+
* import { injectPillarTool } from '@pillar-ai/angular';
|
|
45
|
+
*
|
|
46
|
+
* @Component({
|
|
47
|
+
* selector: 'app-billing-page',
|
|
48
|
+
* standalone: true,
|
|
49
|
+
* template: `<div>Billing Content</div>`,
|
|
50
|
+
* })
|
|
51
|
+
* export class BillingPageComponent {
|
|
52
|
+
* constructor() {
|
|
53
|
+
* injectPillarTool([
|
|
54
|
+
* {
|
|
55
|
+
* name: 'get_current_plan',
|
|
56
|
+
* description: 'Get the current billing plan',
|
|
57
|
+
* execute: async () => ({ plan: 'pro', price: 29 }),
|
|
58
|
+
* },
|
|
59
|
+
* {
|
|
60
|
+
* name: 'upgrade_plan',
|
|
61
|
+
* description: 'Upgrade to a higher plan',
|
|
62
|
+
* inputSchema: {
|
|
63
|
+
* type: 'object',
|
|
64
|
+
* properties: { planId: { type: 'string' } },
|
|
65
|
+
* required: ['planId'],
|
|
66
|
+
* },
|
|
67
|
+
* execute: async ({ planId }) => {
|
|
68
|
+
* await billingApi.upgrade(planId);
|
|
69
|
+
* return { content: [{ type: 'text', text: 'Upgraded!' }] };
|
|
70
|
+
* },
|
|
71
|
+
* },
|
|
72
|
+
* ]);
|
|
73
|
+
* }
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
import type { ToolSchema } from '@pillar-ai/sdk';
|
|
78
|
+
/**
|
|
79
|
+
* Register one or more Pillar tools with co-located metadata and handlers.
|
|
80
|
+
*
|
|
81
|
+
* The tools are registered when this function is called and automatically
|
|
82
|
+
* unregistered when the component is destroyed. Must be called within
|
|
83
|
+
* an injection context (constructor, field initializer, or inject()).
|
|
84
|
+
*
|
|
85
|
+
* @param schemaOrSchemas - Single tool schema or array of tool schemas
|
|
86
|
+
*/
|
|
87
|
+
export declare function injectPillarTool(schemaOrSchemas: ToolSchema<any> | ToolSchema<any>[]): void;
|
|
88
|
+
/** @deprecated Use injectPillarTool instead */
|
|
89
|
+
export declare const injectPillarAction: typeof injectPillarTool;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* injectPillar Function
|
|
3
|
+
* Angular-idiomatic injection helper for accessing Pillar SDK
|
|
4
|
+
*/
|
|
5
|
+
import type { SyncActionDefinitions, ActionDefinitions, ActionDataType, ActionNames } from '@pillar-ai/sdk';
|
|
6
|
+
import { PillarService } from './pillar.service';
|
|
7
|
+
/**
|
|
8
|
+
* Result type for injectPillar with type-safe onTask.
|
|
9
|
+
*
|
|
10
|
+
* @template TActions - The action definitions for type inference
|
|
11
|
+
*/
|
|
12
|
+
export interface InjectPillarResult<TActions extends SyncActionDefinitions | ActionDefinitions = SyncActionDefinitions> {
|
|
13
|
+
/** Get the Pillar SDK instance */
|
|
14
|
+
pillar: () => ReturnType<PillarService['getInstance']>;
|
|
15
|
+
/** Current SDK state */
|
|
16
|
+
state: PillarService['state'];
|
|
17
|
+
/** Whether the SDK is ready */
|
|
18
|
+
isReady: PillarService['isReady'];
|
|
19
|
+
/** Whether the panel is currently open */
|
|
20
|
+
isPanelOpen: PillarService['isPanelOpen'];
|
|
21
|
+
/** Open the help panel */
|
|
22
|
+
open: PillarService['open'];
|
|
23
|
+
/** Close the help panel */
|
|
24
|
+
close: PillarService['close'];
|
|
25
|
+
/** Toggle the help panel */
|
|
26
|
+
toggle: PillarService['toggle'];
|
|
27
|
+
/** Open a specific article */
|
|
28
|
+
openArticle: PillarService['openArticle'];
|
|
29
|
+
/** Open a specific category */
|
|
30
|
+
openCategory: PillarService['openCategory'];
|
|
31
|
+
/** Perform a search */
|
|
32
|
+
search: PillarService['search'];
|
|
33
|
+
/** Navigate to a specific view */
|
|
34
|
+
navigate: PillarService['navigate'];
|
|
35
|
+
/** Update the panel theme at runtime */
|
|
36
|
+
setTheme: PillarService['setTheme'];
|
|
37
|
+
/** Enable or disable the text selection "Ask AI" popover */
|
|
38
|
+
setTextSelectionEnabled: PillarService['setTextSelectionEnabled'];
|
|
39
|
+
/** Subscribe to SDK events */
|
|
40
|
+
on: PillarService['on'];
|
|
41
|
+
/**
|
|
42
|
+
* Type-safe task handler registration.
|
|
43
|
+
*
|
|
44
|
+
* @param taskName - The action name (autocompleted from your actions)
|
|
45
|
+
* @param handler - Handler function with typed data parameter
|
|
46
|
+
* @returns Unsubscribe function
|
|
47
|
+
*/
|
|
48
|
+
onTask: <TName extends ActionNames<TActions>>(taskName: TName, handler: (data: ActionDataType<TActions, TName>) => void) => () => void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Angular injection function to access the Pillar SDK.
|
|
52
|
+
* Use this in components, directives, or services to interact with Pillar.
|
|
53
|
+
*
|
|
54
|
+
* Must be called within an injection context (constructor, field initializer, or inject()).
|
|
55
|
+
*
|
|
56
|
+
* @example Basic usage (untyped)
|
|
57
|
+
* ```typescript
|
|
58
|
+
* @Component({
|
|
59
|
+
* selector: 'app-help-button',
|
|
60
|
+
* standalone: true,
|
|
61
|
+
* template: `
|
|
62
|
+
* <button (click)="toggle()">
|
|
63
|
+
* {{ isPanelOpen() ? 'Close Help' : 'Get Help' }}
|
|
64
|
+
* </button>
|
|
65
|
+
* `,
|
|
66
|
+
* })
|
|
67
|
+
* export class HelpButtonComponent {
|
|
68
|
+
* private pillar = injectPillar();
|
|
69
|
+
* isPanelOpen = this.pillar.isPanelOpen;
|
|
70
|
+
* toggle = this.pillar.toggle;
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* @example Type-safe onTask with action definitions
|
|
75
|
+
* ```typescript
|
|
76
|
+
* import { actions } from '@/lib/pillar/actions';
|
|
77
|
+
*
|
|
78
|
+
* @Component({...})
|
|
79
|
+
* export class MyComponent implements OnInit, OnDestroy {
|
|
80
|
+
* private pillar = injectPillar<typeof actions>();
|
|
81
|
+
* private unsubscribe?: () => void;
|
|
82
|
+
*
|
|
83
|
+
* ngOnInit() {
|
|
84
|
+
* // TypeScript knows data has the correct shape
|
|
85
|
+
* this.unsubscribe = this.pillar.onTask('add_new_source', (data) => {
|
|
86
|
+
* console.log(data.url); // ✓ Typed!
|
|
87
|
+
* });
|
|
88
|
+
* }
|
|
89
|
+
*
|
|
90
|
+
* ngOnDestroy() {
|
|
91
|
+
* this.unsubscribe?.();
|
|
92
|
+
* }
|
|
93
|
+
* }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function injectPillar<TActions extends SyncActionDefinitions | ActionDefinitions = SyncActionDefinitions>(): InjectPillarResult<TActions>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PillarPanelComponent
|
|
3
|
+
* Renders the Pillar help panel at a custom location in the DOM
|
|
4
|
+
*/
|
|
5
|
+
import { AfterViewInit, OnDestroy } from '@angular/core';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
/**
|
|
8
|
+
* Renders the Pillar help panel at a custom location in the DOM.
|
|
9
|
+
* Use this when you want to control where the panel is rendered instead of
|
|
10
|
+
* having it automatically appended to document.body.
|
|
11
|
+
*
|
|
12
|
+
* **Important**: When using this component, set `panel.container: 'manual'` in your
|
|
13
|
+
* Pillar configuration to prevent automatic mounting.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // app.config.ts
|
|
18
|
+
* function initPillar() {
|
|
19
|
+
* const pillar = inject(PillarService);
|
|
20
|
+
* return () => pillar.init({
|
|
21
|
+
* productKey: 'your-product-key',
|
|
22
|
+
* config: { panel: { container: 'manual' } }
|
|
23
|
+
* });
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* // layout.component.ts
|
|
27
|
+
* @Component({
|
|
28
|
+
* selector: 'app-layout',
|
|
29
|
+
* standalone: true,
|
|
30
|
+
* imports: [PillarPanelComponent],
|
|
31
|
+
* template: `
|
|
32
|
+
* <div class="layout">
|
|
33
|
+
* <app-sidebar />
|
|
34
|
+
* <pillar-panel class="help-panel-container" />
|
|
35
|
+
* <main>
|
|
36
|
+
* <router-outlet />
|
|
37
|
+
* </main>
|
|
38
|
+
* </div>
|
|
39
|
+
* `,
|
|
40
|
+
* })
|
|
41
|
+
* export class LayoutComponent {}
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare class PillarPanelComponent implements AfterViewInit, OnDestroy {
|
|
45
|
+
private containerRef;
|
|
46
|
+
private readonly pillarService;
|
|
47
|
+
private hasMounted;
|
|
48
|
+
private effectRef;
|
|
49
|
+
/**
|
|
50
|
+
* Optional class to add to the container element.
|
|
51
|
+
* Use host binding for styling instead if possible.
|
|
52
|
+
*/
|
|
53
|
+
readonly containerClass: import("@angular/core").InputSignal<string>;
|
|
54
|
+
ngAfterViewInit(): void;
|
|
55
|
+
ngOnDestroy(): void;
|
|
56
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PillarPanelComponent, never>;
|
|
57
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PillarPanelComponent, "pillar-panel", never, { "containerClass": { "alias": "containerClass"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
58
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Pillar, type PillarEvents, type PillarState, type ThemeConfig, type ToolSchema } from '@pillar-ai/sdk';
|
|
2
|
+
import type { PillarInitConfig } from './types';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export declare class PillarService {
|
|
5
|
+
private readonly ngZone;
|
|
6
|
+
private readonly appRef;
|
|
7
|
+
private readonly environmentInjector;
|
|
8
|
+
private readonly _pillar;
|
|
9
|
+
private readonly cleanupFns;
|
|
10
|
+
private readonly cardRefs;
|
|
11
|
+
private onTaskCallback;
|
|
12
|
+
private registeredCards;
|
|
13
|
+
readonly state: import("@angular/core").WritableSignal<PillarState>;
|
|
14
|
+
readonly isReady: import("@angular/core").Signal<boolean>;
|
|
15
|
+
readonly isPanelOpen: import("@angular/core").WritableSignal<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Get the Pillar SDK instance.
|
|
18
|
+
*/
|
|
19
|
+
getInstance(): Pillar | null;
|
|
20
|
+
/**
|
|
21
|
+
* Initialize the Pillar SDK.
|
|
22
|
+
* Call this in your app's initialization (e.g., APP_INITIALIZER).
|
|
23
|
+
*
|
|
24
|
+
* @param initConfig - Configuration options
|
|
25
|
+
*/
|
|
26
|
+
init(initConfig: PillarInitConfig): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Subscribe to SDK events and sync to Angular signals.
|
|
29
|
+
*/
|
|
30
|
+
private subscribeToEvents;
|
|
31
|
+
/**
|
|
32
|
+
* Register custom card components.
|
|
33
|
+
*/
|
|
34
|
+
private registerCards;
|
|
35
|
+
/**
|
|
36
|
+
* Open the help panel.
|
|
37
|
+
*/
|
|
38
|
+
open(options?: {
|
|
39
|
+
view?: string;
|
|
40
|
+
article?: string;
|
|
41
|
+
search?: string;
|
|
42
|
+
focusInput?: boolean;
|
|
43
|
+
}): void;
|
|
44
|
+
/**
|
|
45
|
+
* Close the help panel.
|
|
46
|
+
*/
|
|
47
|
+
close(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Toggle the help panel.
|
|
50
|
+
*/
|
|
51
|
+
toggle(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Open a specific article.
|
|
54
|
+
*/
|
|
55
|
+
openArticle(slug: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Open a specific category.
|
|
58
|
+
*/
|
|
59
|
+
openCategory(slug: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Perform a search.
|
|
62
|
+
*/
|
|
63
|
+
search(query: string): void;
|
|
64
|
+
/**
|
|
65
|
+
* Navigate to a specific view.
|
|
66
|
+
*/
|
|
67
|
+
navigate(view: string, params?: Record<string, string>): void;
|
|
68
|
+
/**
|
|
69
|
+
* Update the panel theme at runtime.
|
|
70
|
+
*/
|
|
71
|
+
setTheme(theme: Partial<ThemeConfig>): void;
|
|
72
|
+
/**
|
|
73
|
+
* Enable or disable the text selection "Ask AI" popover.
|
|
74
|
+
*/
|
|
75
|
+
setTextSelectionEnabled(enabled: boolean): void;
|
|
76
|
+
/**
|
|
77
|
+
* Subscribe to SDK events.
|
|
78
|
+
*/
|
|
79
|
+
on<K extends keyof PillarEvents>(event: K, callback: (data: PillarEvents[K]) => void): () => void;
|
|
80
|
+
/**
|
|
81
|
+
* Register a task handler.
|
|
82
|
+
*/
|
|
83
|
+
onTask(taskName: string, handler: (data: Record<string, unknown>) => void): () => void;
|
|
84
|
+
/**
|
|
85
|
+
* Define a tool with metadata and handler.
|
|
86
|
+
* Returns an unsubscribe function to remove the tool.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const unsubscribe = pillarService.defineTool({
|
|
91
|
+
* name: 'add_to_cart',
|
|
92
|
+
* description: 'Add a product to the shopping cart',
|
|
93
|
+
* inputSchema: {
|
|
94
|
+
* type: 'object',
|
|
95
|
+
* properties: {
|
|
96
|
+
* productId: { type: 'string' },
|
|
97
|
+
* quantity: { type: 'number' },
|
|
98
|
+
* },
|
|
99
|
+
* required: ['productId', 'quantity'],
|
|
100
|
+
* },
|
|
101
|
+
* execute: async ({ productId, quantity }) => {
|
|
102
|
+
* await this.cartService.add(productId, quantity);
|
|
103
|
+
* return { content: [{ type: 'text', text: 'Added to cart' }] };
|
|
104
|
+
* },
|
|
105
|
+
* });
|
|
106
|
+
*
|
|
107
|
+
* // Later, to unregister:
|
|
108
|
+
* unsubscribe();
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
defineTool(schema: ToolSchema<any>): () => void;
|
|
112
|
+
/**
|
|
113
|
+
* Mount the panel to a specific container element.
|
|
114
|
+
* Used for manual panel placement with PillarPanelComponent.
|
|
115
|
+
*/
|
|
116
|
+
mountPanelTo(container: HTMLElement): void;
|
|
117
|
+
/**
|
|
118
|
+
* Cleanup resources.
|
|
119
|
+
* Note: We intentionally don't call Pillar.destroy() here to preserve
|
|
120
|
+
* conversation history across route changes. Call Pillar.destroy()
|
|
121
|
+
* explicitly if you need to fully reset the SDK.
|
|
122
|
+
*/
|
|
123
|
+
ngOnDestroy(): void;
|
|
124
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PillarService, never>;
|
|
125
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<PillarService>;
|
|
126
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for Pillar Angular SDK
|
|
3
|
+
*/
|
|
4
|
+
import type { Pillar, PillarConfig, PillarEvents, PillarState, TaskExecutePayload, ThemeConfig } from '@pillar-ai/sdk';
|
|
5
|
+
import type { Signal, WritableSignal, Type } from '@angular/core';
|
|
6
|
+
/**
|
|
7
|
+
* Props passed to custom card components.
|
|
8
|
+
*/
|
|
9
|
+
export interface CardComponentProps<T = Record<string, unknown>> {
|
|
10
|
+
/** Data extracted by the AI for this action */
|
|
11
|
+
data: T;
|
|
12
|
+
/** Called when user confirms the action */
|
|
13
|
+
onConfirm: (modifiedData?: Record<string, unknown>) => void;
|
|
14
|
+
/** Called when user cancels the action */
|
|
15
|
+
onCancel: () => void;
|
|
16
|
+
/** Called to report state changes (loading, success, error) */
|
|
17
|
+
onStateChange?: (state: 'loading' | 'success' | 'error', message?: string) => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* An Angular component that can be used as a custom card renderer.
|
|
21
|
+
* The component should accept CardComponentProps as inputs.
|
|
22
|
+
*/
|
|
23
|
+
export type CardComponent<T = Record<string, unknown>> = Type<CardComponentProps<T>>;
|
|
24
|
+
export interface PillarServiceState {
|
|
25
|
+
/** The Pillar SDK instance */
|
|
26
|
+
pillar: Signal<Pillar | null>;
|
|
27
|
+
/** Current SDK state */
|
|
28
|
+
state: WritableSignal<PillarState>;
|
|
29
|
+
/** Whether the SDK is ready */
|
|
30
|
+
isReady: Signal<boolean>;
|
|
31
|
+
/** Whether the panel is currently open */
|
|
32
|
+
isPanelOpen: WritableSignal<boolean>;
|
|
33
|
+
}
|
|
34
|
+
export interface PillarServiceActions {
|
|
35
|
+
/** Open the help panel */
|
|
36
|
+
open: (options?: {
|
|
37
|
+
view?: string;
|
|
38
|
+
article?: string;
|
|
39
|
+
search?: string;
|
|
40
|
+
focusInput?: boolean;
|
|
41
|
+
}) => void;
|
|
42
|
+
/** Close the help panel */
|
|
43
|
+
close: () => void;
|
|
44
|
+
/** Toggle the help panel */
|
|
45
|
+
toggle: () => void;
|
|
46
|
+
/** Open a specific article */
|
|
47
|
+
openArticle: (slug: string) => void;
|
|
48
|
+
/** Open a specific category */
|
|
49
|
+
openCategory: (slug: string) => Promise<void>;
|
|
50
|
+
/** Perform a search */
|
|
51
|
+
search: (query: string) => void;
|
|
52
|
+
/** Navigate to a specific view */
|
|
53
|
+
navigate: (view: string, params?: Record<string, string>) => void;
|
|
54
|
+
/** Update the panel theme at runtime */
|
|
55
|
+
setTheme: (theme: Partial<ThemeConfig>) => void;
|
|
56
|
+
/** Enable or disable the text selection "Ask AI" popover */
|
|
57
|
+
setTextSelectionEnabled: (enabled: boolean) => void;
|
|
58
|
+
/** Subscribe to SDK events */
|
|
59
|
+
on: <K extends keyof PillarEvents>(event: K, callback: (data: PillarEvents[K]) => void) => () => void;
|
|
60
|
+
/** Register a task handler */
|
|
61
|
+
onTask: (taskName: string, handler: (data: Record<string, unknown>) => void) => () => void;
|
|
62
|
+
/** Get the Pillar SDK instance */
|
|
63
|
+
getInstance: () => Pillar | null;
|
|
64
|
+
}
|
|
65
|
+
export interface PillarContextValue extends PillarServiceState, PillarServiceActions {
|
|
66
|
+
}
|
|
67
|
+
export interface PillarInitConfig {
|
|
68
|
+
/**
|
|
69
|
+
* Your product key from the Pillar app.
|
|
70
|
+
* Get it at app.trypillar.com
|
|
71
|
+
*/
|
|
72
|
+
productKey?: string;
|
|
73
|
+
/**
|
|
74
|
+
* @deprecated Use `productKey` instead. Will be removed in v1.0.
|
|
75
|
+
*/
|
|
76
|
+
helpCenter?: string;
|
|
77
|
+
/**
|
|
78
|
+
* Additional SDK configuration
|
|
79
|
+
*
|
|
80
|
+
* Notable options:
|
|
81
|
+
* - `panel.useShadowDOM`: Whether to isolate styles in Shadow DOM (default: false).
|
|
82
|
+
* Set to false to let custom cards inherit your app's CSS (Tailwind, etc.)
|
|
83
|
+
*/
|
|
84
|
+
config?: Omit<PillarConfig, 'productKey' | 'helpCenter'>;
|
|
85
|
+
/**
|
|
86
|
+
* Handler called when a task action is triggered from the chat.
|
|
87
|
+
* Use this to handle AI-suggested actions like opening modals, navigating, etc.
|
|
88
|
+
*/
|
|
89
|
+
onTask?: (task: TaskExecutePayload) => void;
|
|
90
|
+
/**
|
|
91
|
+
* Custom card components to render for inline_ui type actions.
|
|
92
|
+
* Map card type names to Angular components that will render the inline UI.
|
|
93
|
+
*/
|
|
94
|
+
cards?: Record<string, CardComponent>;
|
|
95
|
+
}
|
|
96
|
+
export interface InjectPillarResult extends PillarContextValue {
|
|
97
|
+
}
|
|
98
|
+
export interface InjectHelpPanelResult {
|
|
99
|
+
/** Whether the panel is currently open */
|
|
100
|
+
isOpen: Signal<boolean>;
|
|
101
|
+
/** Open the panel */
|
|
102
|
+
open: (options?: {
|
|
103
|
+
view?: string;
|
|
104
|
+
article?: string;
|
|
105
|
+
search?: string;
|
|
106
|
+
}) => void;
|
|
107
|
+
/** Close the panel */
|
|
108
|
+
close: () => void;
|
|
109
|
+
/** Toggle the panel */
|
|
110
|
+
toggle: () => void;
|
|
111
|
+
/** Open a specific article in the panel */
|
|
112
|
+
openArticle: (slug: string) => void;
|
|
113
|
+
/** Open a specific category in the panel */
|
|
114
|
+
openCategory: (slug: string) => Promise<void>;
|
|
115
|
+
/** Open search with a query */
|
|
116
|
+
openSearch: (query?: string) => void;
|
|
117
|
+
/** Open the AI chat */
|
|
118
|
+
openChat: () => void;
|
|
119
|
+
}
|