@pillar-ai/sdk 0.1.8 → 0.1.13

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/README.md CHANGED
@@ -1,20 +1,115 @@
1
1
  # @pillar-ai/sdk
2
2
 
3
- Pillar Embedded Help SDK - Add contextual help and AI chat to your application.
3
+ Cursor for your product Embed an AI co-pilot that executes tasks, not just answers questions.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@pillar-ai/sdk)](https://www.npmjs.com/package/@pillar-ai/sdk)
6
+ [![npm downloads](https://img.shields.io/npm/dm/@pillar-ai/sdk)](https://www.npmjs.com/package/@pillar-ai/sdk)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue)](https://www.typescriptlang.org/)
9
+
10
+ ## What is Pillar?
11
+
12
+ Pillar is an embedded AI co-pilot that helps users complete tasks, not just answer questions. Users say what they want, and Pillar uses your UI to make it happen — navigating pages, pre-filling forms, and calling your APIs.
13
+
14
+ **How it works:**
15
+
16
+ 1. User asks: *"Export this to CSV"* or *"Turn off email notifications"*
17
+ 2. Pillar understands intent and chains actions
18
+ 3. Your code executes with the user's session
19
+
20
+ ## Features
21
+
22
+ - **Task Execution** — Navigate pages, pre-fill forms, call APIs on behalf of users
23
+ - **Multi-Step Plans** — Chain actions into workflows for complex tasks
24
+ - **Context-Aware** — Knows current page, user state, and selected text
25
+ - **Knowledge Sync** — Trained on your docs, Zendesk, Intercom, and more
26
+ - **Custom Action Cards** — Render interactive UI for confirmations and data input
27
+ - **Framework Bindings** — First-class support for React, Vue, and Svelte
28
+
29
+ ## Why Pillar?
30
+
31
+ - **Runs client-side** with the user's session — no proxy servers, no token forwarding
32
+ - **One npm install**, define your actions, and you're live
33
+ - **Syncs with your docs** for grounded, accurate answers
34
+
35
+ ## Documentation
36
+
37
+ **[View Full Documentation](https://trypillar.com/docs)** | [Getting Started](https://trypillar.com/docs/getting-started/quick-start) | [API Reference](https://trypillar.com/docs/reference/core)
4
38
 
5
39
  ## Installation
6
40
 
7
41
  ```bash
8
42
  npm install @pillar-ai/sdk
43
+ # or
44
+ pnpm add @pillar-ai/sdk
45
+ # or
46
+ yarn add @pillar-ai/sdk
9
47
  ```
10
48
 
11
49
  ## Quick Start
12
50
 
51
+ ### 1. Get Your Product Key
52
+
53
+ First, register your product in the [Pillar app](https://app.trypillar.com):
54
+
55
+ 1. Sign up or log in at [app.trypillar.com](https://app.trypillar.com)
56
+ 2. Create a new product
57
+ 3. Copy your **Product Key** from the settings page
58
+
59
+ ### 2. Initialize the SDK
60
+
13
61
  ```javascript
14
62
  import { Pillar } from "@pillar-ai/sdk";
15
63
 
16
64
  await Pillar.init({
17
- helpCenter: "your-help-center",
65
+ productKey: "your-product-key", // From Pillar app
66
+ });
67
+ ```
68
+
69
+ ## Defining Actions
70
+
71
+ Define what your co-pilot can do. When users make requests, Pillar matches intent to actions and executes them:
72
+
73
+ ```javascript
74
+ Pillar.init({
75
+ productKey: "your-product-key",
76
+ actions: {
77
+ // Navigation actions
78
+ go_to_settings: {
79
+ type: "navigate",
80
+ label: "Open Settings",
81
+ description: "Navigate to the settings page",
82
+ path: "/settings",
83
+ },
84
+
85
+ // Trigger actions that execute code
86
+ export_to_csv: {
87
+ type: "trigger",
88
+ label: "Export to CSV",
89
+ description: "Export current data to a CSV file",
90
+ },
91
+
92
+ // Actions with data schemas
93
+ update_preferences: {
94
+ type: "trigger",
95
+ label: "Update Preferences",
96
+ description: "Update notification preferences",
97
+ dataSchema: {
98
+ emailAlerts: { type: "boolean" },
99
+ frequency: { type: "string", enum: ["daily", "weekly", "monthly"] },
100
+ },
101
+ },
102
+ },
103
+
104
+ onTask: (actionName, data) => {
105
+ // Your code executes here
106
+ if (actionName === "export_to_csv") {
107
+ downloadCSV();
108
+ }
109
+ if (actionName === "update_preferences") {
110
+ updateUserPreferences(data.emailAlerts, data.frequency);
111
+ }
112
+ },
18
113
  });
19
114
  ```
20
115
 
@@ -22,21 +117,17 @@ await Pillar.init({
22
117
 
23
118
  ```javascript
24
119
  Pillar.init({
25
- // Required
26
- helpCenter: "your-help-center",
120
+ productKey: "your-product-key",
27
121
 
28
- // Optional configuration
29
122
  panel: {
30
123
  position: "right", // 'left' | 'right'
31
124
  mode: "push", // 'overlay' | 'push'
32
125
  },
33
126
 
34
- // Edge trigger (sidebar tab that opens the panel)
35
127
  edgeTrigger: {
36
- enabled: true, // Set to false to use your own custom button
128
+ enabled: true, // Set to false to use your own button
37
129
  },
38
130
 
39
- // Theme
40
131
  theme: {
41
132
  mode: "auto", // 'light' | 'dark' | 'auto'
42
133
  colors: {
@@ -46,63 +137,28 @@ Pillar.init({
46
137
  });
47
138
  ```
48
139
 
49
- ## Custom Trigger Button
50
-
51
- To use your own button instead of the built-in edge trigger:
52
-
53
- ```javascript
54
- Pillar.init({
55
- helpCenter: "your-help-center",
56
- edgeTrigger: { enabled: false },
57
- });
58
-
59
- // Then control the panel programmatically
60
- document.getElementById("my-help-button").addEventListener("click", () => {
61
- Pillar.toggle();
62
- });
63
- ```
64
-
65
- ## Features
66
-
67
- - **AI Chat**: Embedded AI assistant that understands your product
68
- - **Edge Trigger**: Built-in sidebar tab to open the help panel (or use your own button)
69
- - **Contextual Help**: Show relevant help based on user context
70
- - **Text Selection**: Allow users to ask questions about selected text
71
- - **Customizable UI**: Full control over positioning, theming, and behavior
72
-
73
140
  ## API Reference
74
141
 
75
- ### Pillar.init(config)
76
-
77
- Initialize the SDK with your configuration.
78
-
79
- ### Pillar.open()
80
-
81
- Open the help panel.
82
-
83
- ### Pillar.close()
84
-
85
- Close the help panel.
86
-
87
- ### Pillar.toggle()
142
+ | Method | Description |
143
+ |--------|-------------|
144
+ | `Pillar.init(config)` | Initialize the SDK with your configuration |
145
+ | `Pillar.open()` | Open the co-pilot panel |
146
+ | `Pillar.close()` | Close the co-pilot panel |
147
+ | `Pillar.toggle()` | Toggle the co-pilot panel |
148
+ | `Pillar.setContext(context)` | Update the user/product context |
149
+ | `Pillar.on(event, callback)` | Subscribe to SDK events |
88
150
 
89
- Toggle the help panel open/closed.
151
+ For complete API documentation, see the [API Reference](https://trypillar.com/docs/reference/core).
90
152
 
91
- ### Pillar.setContext(context)
153
+ ## Framework Integrations
92
154
 
93
- Update the user/product context.
155
+ For idiomatic integration with your framework, use our framework-specific packages:
94
156
 
95
- ### Pillar.on(event, callback)
96
-
97
- Subscribe to SDK events.
98
-
99
- ## React Integration
100
-
101
- For React applications, use the `@pillar-ai/react` package for a more idiomatic integration with hooks and components.
102
-
103
- ```bash
104
- npm install @pillar-ai/react
105
- ```
157
+ | Framework | Package | Installation |
158
+ |-----------|---------|--------------|
159
+ | React | [@pillar-ai/react](https://github.com/pillarhq/sdk-react) | `npm install @pillar-ai/react` |
160
+ | Vue | [@pillar-ai/vue](https://github.com/pillarhq/sdk-vue) | `npm install @pillar-ai/vue` |
161
+ | Svelte | [@pillar-ai/svelte](https://github.com/pillarhq/sdk-svelte) | `npm install @pillar-ai/svelte` |
106
162
 
107
163
  ## License
108
164
 
@@ -30,4 +30,4 @@
30
30
  * @module actions
31
31
  */
32
32
  export type { ActionType, ActionDataSchema, ActionDefinition, ActionDefinitions, ActionManifest, ActionManifestEntry, ClientInfo, Platform, SyncActionDefinition, SyncActionDefinitions, ActionTypeDataMap, NavigateActionData, TriggerActionData, InlineUIData, ExternalLinkData, CopyTextData, ActionDataType, ActionNames, TypedTaskHandler, TypedOnTask, TypedPillarMethods, } from './types';
33
- export { defineActions, setClientInfo, getClientInfo, getHandler, getActionDefinition, hasAction, getActionNames, getManifest, clearRegistry, getActionCount, } from './registry';
33
+ export { setClientInfo, getClientInfo, getHandler, getActionDefinition, hasAction, getActionNames, getManifest, clearRegistry, getActionCount, } from './registry';
@@ -2,45 +2,33 @@
2
2
  * Action Registry - Manages code-defined action handlers.
3
3
  *
4
4
  * This module provides the registration and lookup mechanism for
5
- * actions defined in code. Actions are registered using `defineActions()`
6
- * and can be looked up by name using `getHandler()`.
5
+ * actions defined in code. Actions are registered at runtime via
6
+ * `pillar.onTask()` and can be looked up by name using `getHandler()`.
7
7
  *
8
- * The registry also generates the manifest that gets synced to the server
9
- * during CI/CD builds.
10
- */
11
- import type { ActionDefinition, ActionDefinitions, ActionManifest, ClientInfo, Platform } from './types';
12
- /**
13
- * Define and register actions with the SDK.
14
- *
15
- * Call this during app initialization to register your action handlers.
16
- * The metadata will be synced to the server during CI/CD builds.
8
+ * Action metadata is synced to the server during CI/CD builds using
9
+ * the `pillar-sync` CLI with a barrel file export pattern:
17
10
  *
18
11
  * @example
19
12
  * ```ts
20
- * import { defineActions } from '@pillar-ai/sdk/actions';
21
- * import { router } from './router';
13
+ * // lib/pillar/actions/index.ts
14
+ * import type { SyncActionDefinitions } from '@pillar-ai/sdk';
22
15
  *
23
- * export const actions = defineActions({
16
+ * export const actions = {
24
17
  * open_settings: {
25
18
  * description: 'Navigate to the settings page',
26
- * type: 'navigate',
19
+ * type: 'navigate' as const,
27
20
  * path: '/settings',
28
- * handler: () => router.push('/settings'),
29
- * },
30
- * open_billing: {
31
- * description: 'Navigate to billing and subscription management',
32
- * type: 'navigate',
33
- * path: '/settings/billing',
34
21
  * autoRun: true,
35
- * handler: (data) => router.push('/settings/billing', data),
36
22
  * },
37
- * });
38
- * ```
23
+ * } as const satisfies SyncActionDefinitions;
24
+ *
25
+ * export default actions;
39
26
  *
40
- * @param actions - Map of action name to definition
41
- * @returns The same actions object (for re-export convenience)
27
+ * // Sync via CI/CD:
28
+ * // npx pillar-sync --actions ./lib/pillar/actions/index.ts
29
+ * ```
42
30
  */
43
- export declare function defineActions<T extends ActionDefinitions>(actions: T): T;
31
+ import type { ActionDefinition, ActionManifest, ClientInfo, Platform } from './types';
44
32
  /**
45
33
  * Set client platform and version info.
46
34
  *
@@ -6,16 +6,22 @@
6
6
  *
7
7
  * @example
8
8
  * ```ts
9
- * import { defineActions } from '@pillar-ai/sdk/actions';
9
+ * // lib/pillar/actions/index.ts
10
+ * import type { SyncActionDefinitions } from '@pillar-ai/sdk';
10
11
  *
11
- * const actions = defineActions({
12
+ * export const actions = {
12
13
  * open_settings: {
13
14
  * description: 'Navigate to the settings page',
14
- * type: 'navigate',
15
+ * type: 'navigate' as const,
15
16
  * path: '/settings',
16
- * handler: () => router.push('/settings'),
17
+ * autoRun: true,
17
18
  * },
18
- * });
19
+ * } as const satisfies SyncActionDefinitions;
20
+ *
21
+ * export default actions;
22
+ *
23
+ * // Sync via CI/CD: npx pillar-sync --actions ./lib/pillar/actions/index.ts
24
+ * // Register handlers at runtime: pillar.onTask('open_settings', () => router.push('/settings'));
19
25
  * ```
20
26
  */
21
27
  /**
@@ -33,9 +33,20 @@ export interface ChatResponse {
33
33
  actions?: TaskButtonData[];
34
34
  }
35
35
  export interface ProgressEvent {
36
- kind: 'search' | 'search_complete' | 'generating' | 'thinking';
36
+ kind: 'processing' | 'search' | 'search_complete' | 'query' | 'query_complete' | 'query_failed' | 'generating';
37
37
  message?: string;
38
38
  progress_id?: string;
39
+ metadata?: {
40
+ sources?: Array<{
41
+ title: string;
42
+ url: string;
43
+ score?: number;
44
+ }>;
45
+ result_count?: number;
46
+ query?: string;
47
+ action_name?: string;
48
+ no_sources_used?: boolean;
49
+ };
39
50
  }
40
51
  /**
41
52
  * Server-side embed config response.
@@ -59,10 +59,22 @@ export interface StreamCallbacks {
59
59
  onError?: (error: string) => void;
60
60
  /** Called when stream is complete */
61
61
  onComplete?: (conversationId?: string, queryLogId?: string) => void;
62
- /** Called for progress updates */
62
+ /** Called for progress updates (search, query, generating, etc.) */
63
63
  onProgress?: (progress: {
64
64
  kind: string;
65
65
  message?: string;
66
+ progress_id?: string;
67
+ metadata?: {
68
+ sources?: Array<{
69
+ title: string;
70
+ url: string;
71
+ score?: number;
72
+ }>;
73
+ result_count?: number;
74
+ query?: string;
75
+ action_name?: string;
76
+ no_sources_used?: boolean;
77
+ };
66
78
  }) => void;
67
79
  }
68
80
  /** Image for chat requests (from upload-image endpoint) */
@@ -1,2 +1 @@
1
- #!/usr/bin/env node
2
1
  export {};
package/dist/cli/sync.js CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- #!/usr/bin/env node
3
2
 
4
3
  // src/cli/sync.ts
5
4
  import * as fs from "fs";
@@ -59,6 +58,43 @@ async function loadActions(actionsPath) {
59
58
  if (!fs.existsSync(absolutePath)) {
60
59
  throw new Error(`Actions file not found: ${absolutePath}`);
61
60
  }
61
+ const isTypeScript = absolutePath.endsWith(".ts") || absolutePath.endsWith(".tsx");
62
+ if (isTypeScript) {
63
+ try {
64
+ const tempDir = path.dirname(absolutePath);
65
+ const tempFile = path.join(tempDir, `.pillar-sync-temp-${Date.now()}.mjs`);
66
+ const importPath = absolutePath.replace(/\\/g, "/");
67
+ const extractScript = `import actions from '${importPath}';
68
+ const result = actions.default || actions;
69
+ console.log(JSON.stringify(result));`;
70
+ fs.writeFileSync(tempFile, extractScript, "utf-8");
71
+ try {
72
+ const result = execSync(`npx tsx "${tempFile}"`, {
73
+ encoding: "utf-8",
74
+ cwd: process.cwd(),
75
+ stdio: ["pipe", "pipe", "pipe"]
76
+ });
77
+ const actions = JSON.parse(result.trim());
78
+ if (!actions || typeof actions !== "object") {
79
+ throw new Error(
80
+ 'Actions file must export an actions object as default or named export "actions"'
81
+ );
82
+ }
83
+ return actions;
84
+ } finally {
85
+ if (fs.existsSync(tempFile)) {
86
+ fs.unlinkSync(tempFile);
87
+ }
88
+ }
89
+ } catch (error) {
90
+ if (error instanceof Error && error.message.includes("tsx")) {
91
+ console.error("[pillar-sync] TypeScript files require tsx.");
92
+ console.error("[pillar-sync] Make sure tsx is installed: npm install -D tsx");
93
+ console.error("[pillar-sync] Then run: npx pillar-sync --actions ./actions.ts");
94
+ }
95
+ throw error;
96
+ }
97
+ }
62
98
  const fileUrl = pathToFileURL(absolutePath).href;
63
99
  try {
64
100
  const module = await import(fileUrl);
@@ -70,11 +106,6 @@ async function loadActions(actionsPath) {
70
106
  }
71
107
  return actions;
72
108
  } catch (error) {
73
- if (error instanceof Error && error.message.includes("Unknown file extension")) {
74
- console.error("[pillar-sync] TypeScript files require tsx.");
75
- console.error("[pillar-sync] Make sure tsx is installed: npm install -D tsx");
76
- console.error("[pillar-sync] Then run: npx pillar-sync --actions ./actions.ts");
77
- }
78
109
  throw error;
79
110
  }
80
111
  }
@@ -38,6 +38,7 @@ export declare class Panel {
38
38
  */
39
39
  open(options?: {
40
40
  view?: string;
41
+ search?: string;
41
42
  focusInput?: boolean;
42
43
  }): void;
43
44
  /**