@pillar-ai/sdk 0.2.1 → 0.2.2
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 +6 -0
- package/dist/api/mcp-client.d.ts +7 -0
- package/dist/cli/sync.js +77 -14
- package/dist/core/Pillar.d.ts +21 -0
- package/dist/core/config.d.ts +7 -0
- package/dist/index.d.ts +1 -1
- package/dist/pillar.esm.js +1 -1
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/skill.d.ts +33 -0
- package/dist/tools/types.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -122,6 +122,9 @@ For production, define tools in code and sync them via the `pillar-sync` CLI dur
|
|
|
122
122
|
const pillar = await Pillar.init({
|
|
123
123
|
agentSlug: "your-agent-slug",
|
|
124
124
|
|
|
125
|
+
// Forward an existing auth token to API tool sources (optional)
|
|
126
|
+
// userApiToken: accessToken,
|
|
127
|
+
|
|
125
128
|
panel: {
|
|
126
129
|
position: "right", // 'left' | 'right'
|
|
127
130
|
mode: "push", // 'overlay' | 'push'
|
|
@@ -150,6 +153,9 @@ const pillar = await Pillar.init({
|
|
|
150
153
|
| `pillar.close()` | Close the co-pilot panel |
|
|
151
154
|
| `pillar.toggle()` | Toggle the co-pilot panel |
|
|
152
155
|
| `pillar.setContext(context)` | Update the user/product context |
|
|
156
|
+
| `pillar.identify(userId, profile?)` | Associate a user with the session. Profile: `name`, `email`, `apiToken` |
|
|
157
|
+
| `pillar.setUserApiToken(token)` | Forward a Bearer token to API tool sources |
|
|
158
|
+
| `pillar.logout(options?)` | Clear user identity and API token |
|
|
153
159
|
| `pillar.on(event, callback)` | Subscribe to SDK events |
|
|
154
160
|
|
|
155
161
|
> **Note:** `Pillar.init()` and `Pillar.getInstance()` are static methods on the class. All other methods (lowercase `pillar`) are instance methods - call them on the instance returned from `init()` or `getInstance()`.
|
package/dist/api/mcp-client.d.ts
CHANGED
|
@@ -148,12 +148,19 @@ export declare class MCPClient {
|
|
|
148
148
|
private config;
|
|
149
149
|
private requestId;
|
|
150
150
|
private _externalUserId;
|
|
151
|
+
private _userApiToken;
|
|
151
152
|
constructor(config: ResolvedConfig);
|
|
152
153
|
/**
|
|
153
154
|
* Set the external user ID for authenticated users.
|
|
154
155
|
* Enables cross-device conversation history.
|
|
155
156
|
*/
|
|
156
157
|
setExternalUserId(userId: string): void;
|
|
158
|
+
/**
|
|
159
|
+
* Set a user API token for passthrough to OpenAPI tool sources.
|
|
160
|
+
* When set, this token is forwarded as-is to customer APIs,
|
|
161
|
+
* bypassing the per-user OAuth linking flow.
|
|
162
|
+
*/
|
|
163
|
+
setUserApiToken(token: string): void;
|
|
157
164
|
/**
|
|
158
165
|
* Get or create a persistent visitor ID.
|
|
159
166
|
* Stored in localStorage to persist across sessions.
|
package/dist/cli/sync.js
CHANGED
|
@@ -241,7 +241,7 @@ async function scanTools(scanDir) {
|
|
|
241
241
|
}
|
|
242
242
|
const files = globFiles(absoluteDir, [".ts", ".tsx", ".js", ".jsx", ".mjs"]);
|
|
243
243
|
console.log(`[pillar-sync] Scanning ${files.length} files in ${scanDir}`);
|
|
244
|
-
const
|
|
244
|
+
const TOOL_PATTERNS = [
|
|
245
245
|
"defineTool",
|
|
246
246
|
"usePillarTool",
|
|
247
247
|
"injectPillarTool",
|
|
@@ -249,23 +249,55 @@ async function scanTools(scanDir) {
|
|
|
249
249
|
"usePillarAction",
|
|
250
250
|
"injectPillarAction"
|
|
251
251
|
];
|
|
252
|
+
const SKILL_PATTERN = "defineSkill";
|
|
253
|
+
const ALL_PATTERNS = [...TOOL_PATTERNS, SKILL_PATTERN];
|
|
252
254
|
const candidateFiles = files.filter((file) => {
|
|
253
255
|
const content = fs.readFileSync(file, "utf-8");
|
|
254
|
-
return
|
|
256
|
+
return ALL_PATTERNS.some((p) => content.includes(p));
|
|
255
257
|
});
|
|
256
|
-
console.log(`[pillar-sync] Found ${candidateFiles.length} files with tool definitions`);
|
|
258
|
+
console.log(`[pillar-sync] Found ${candidateFiles.length} files with tool/skill definitions`);
|
|
257
259
|
const tools = [];
|
|
260
|
+
const skills = [];
|
|
258
261
|
for (const filePath of candidateFiles) {
|
|
259
262
|
let visit2 = function(node) {
|
|
260
263
|
if (ts.isCallExpression(node)) {
|
|
261
264
|
const callee = node.expression;
|
|
262
|
-
let
|
|
265
|
+
let isToolCall = false;
|
|
266
|
+
let isSkillCall = false;
|
|
263
267
|
if (ts.isIdentifier(callee)) {
|
|
264
|
-
|
|
268
|
+
isToolCall = TOOL_PATTERNS.includes(callee.text);
|
|
269
|
+
isSkillCall = callee.text === SKILL_PATTERN;
|
|
265
270
|
} else if (ts.isPropertyAccessExpression(callee)) {
|
|
266
|
-
|
|
271
|
+
isToolCall = callee.name.text === "defineTool" || callee.name.text === "defineAction";
|
|
272
|
+
isSkillCall = callee.name.text === "defineSkill";
|
|
267
273
|
}
|
|
268
|
-
if (
|
|
274
|
+
if (isSkillCall && node.arguments.length > 0) {
|
|
275
|
+
const arg = node.arguments[0];
|
|
276
|
+
const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
|
|
277
|
+
const relativePath = path.relative(process.cwd(), filePath);
|
|
278
|
+
if (ts.isObjectLiteralExpression(arg)) {
|
|
279
|
+
const obj = evaluateNode(arg, ts, fileScope);
|
|
280
|
+
if (obj && typeof obj.name === "string" && typeof obj.description === "string" && typeof obj.content === "string") {
|
|
281
|
+
skills.push({
|
|
282
|
+
name: obj.name,
|
|
283
|
+
description: obj.description,
|
|
284
|
+
content: obj.content,
|
|
285
|
+
sourceFile: relativePath,
|
|
286
|
+
line: lineNumber
|
|
287
|
+
});
|
|
288
|
+
console.log(`[pillar-sync] skill: ${obj.name} (${relativePath}:${lineNumber})`);
|
|
289
|
+
} else if (obj) {
|
|
290
|
+
console.warn(
|
|
291
|
+
`[pillar-sync] \u26A0 Skipping skill at ${relativePath}:${lineNumber} \u2014 missing name, description, or content`
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
} else {
|
|
295
|
+
console.warn(
|
|
296
|
+
`[pillar-sync] \u26A0 Skipping skill at ${relativePath}:${lineNumber} \u2014 argument is not an inline object literal`
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (isToolCall && node.arguments.length > 0) {
|
|
269
301
|
const arg = node.arguments[0];
|
|
270
302
|
const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
|
|
271
303
|
const relativePath = path.relative(process.cwd(), filePath);
|
|
@@ -375,7 +407,27 @@ async function scanTools(scanDir) {
|
|
|
375
407
|
}
|
|
376
408
|
deduplicatedTools.push(instances[0]);
|
|
377
409
|
}
|
|
378
|
-
|
|
410
|
+
const skillsByName = /* @__PURE__ */ new Map();
|
|
411
|
+
for (const skill of skills) {
|
|
412
|
+
const existing = skillsByName.get(skill.name);
|
|
413
|
+
if (existing) {
|
|
414
|
+
existing.push(skill);
|
|
415
|
+
} else {
|
|
416
|
+
skillsByName.set(skill.name, [skill]);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
const deduplicatedSkills = [];
|
|
420
|
+
for (const [name, instances] of skillsByName) {
|
|
421
|
+
if (instances.length > 1) {
|
|
422
|
+
const locations = instances.map((s) => `${s.sourceFile}:${s.line}`).join(", ");
|
|
423
|
+
console.warn(
|
|
424
|
+
`[pillar-sync] \u26A0 Duplicate skill "${name}" found in ${instances.length} locations: ${locations}`
|
|
425
|
+
);
|
|
426
|
+
console.warn(`[pillar-sync] Using first definition from ${instances[0].sourceFile}:${instances[0].line}`);
|
|
427
|
+
}
|
|
428
|
+
deduplicatedSkills.push(instances[0]);
|
|
429
|
+
}
|
|
430
|
+
return { tools: deduplicatedTools, skills: deduplicatedSkills };
|
|
379
431
|
}
|
|
380
432
|
function findAgentGuidance(scanDir) {
|
|
381
433
|
const absoluteDir = path.resolve(process.cwd(), scanDir);
|
|
@@ -472,19 +524,23 @@ async function main() {
|
|
|
472
524
|
const platform = process.env.PILLAR_PLATFORM || "web";
|
|
473
525
|
const version = process.env.PILLAR_VERSION || getPackageVersion();
|
|
474
526
|
const gitSha = process.env.GIT_SHA || getGitSha();
|
|
475
|
-
console.log(`[pillar-sync] Scanning for tools in: ${scanDir}`);
|
|
527
|
+
console.log(`[pillar-sync] Scanning for tools and skills in: ${scanDir}`);
|
|
476
528
|
let scannedTools;
|
|
529
|
+
let scannedSkills;
|
|
477
530
|
try {
|
|
478
|
-
|
|
531
|
+
const scanResult = await scanTools(scanDir);
|
|
532
|
+
scannedTools = scanResult.tools;
|
|
533
|
+
scannedSkills = scanResult.skills;
|
|
479
534
|
} catch (error) {
|
|
480
|
-
console.error(`[pillar-sync] Failed to scan
|
|
535
|
+
console.error(`[pillar-sync] Failed to scan:`, error);
|
|
481
536
|
process.exit(1);
|
|
482
537
|
}
|
|
483
538
|
const toolCount = scannedTools.length;
|
|
484
|
-
|
|
539
|
+
const skillCount = scannedSkills.length;
|
|
540
|
+
console.log(`[pillar-sync] Found ${toolCount} tools and ${skillCount} skills`);
|
|
485
541
|
const agentGuidance = findAgentGuidance(scanDir);
|
|
486
|
-
if (toolCount === 0) {
|
|
487
|
-
console.warn("[pillar-sync] No tools found. Nothing to sync.");
|
|
542
|
+
if (toolCount === 0 && skillCount === 0) {
|
|
543
|
+
console.warn("[pillar-sync] No tools or skills found. Nothing to sync.");
|
|
488
544
|
process.exit(0);
|
|
489
545
|
}
|
|
490
546
|
const manifest = buildManifestFromScan(scannedTools, platform, version, gitSha, agentGuidance);
|
|
@@ -506,6 +562,13 @@ async function main() {
|
|
|
506
562
|
if (manifest.agentGuidance) {
|
|
507
563
|
requestBody.agent_guidance = manifest.agentGuidance;
|
|
508
564
|
}
|
|
565
|
+
if (scannedSkills.length > 0) {
|
|
566
|
+
requestBody.skills = scannedSkills.map((s) => ({
|
|
567
|
+
name: s.name,
|
|
568
|
+
description: s.description,
|
|
569
|
+
content: s.content
|
|
570
|
+
}));
|
|
571
|
+
}
|
|
509
572
|
const forceSync = args.force === true;
|
|
510
573
|
const syncUrl = `${apiUrl}/api/admin/configs/${slug}/actions/sync/?async=true${forceSync ? "&force=true" : ""}`;
|
|
511
574
|
console.log(`[pillar-sync] POST ${syncUrl}`);
|
package/dist/core/Pillar.d.ts
CHANGED
|
@@ -399,6 +399,8 @@ export declare class Pillar {
|
|
|
399
399
|
name?: string;
|
|
400
400
|
email?: string;
|
|
401
401
|
metadata?: Record<string, unknown>;
|
|
402
|
+
/** API token to forward as Bearer to OpenAPI tool sources, bypassing OAuth linking. */
|
|
403
|
+
apiToken?: string;
|
|
402
404
|
}, options?: {
|
|
403
405
|
preserveConversation?: boolean;
|
|
404
406
|
}): Promise<void>;
|
|
@@ -434,6 +436,25 @@ export declare class Pillar {
|
|
|
434
436
|
* Whether the current user is identified (logged in).
|
|
435
437
|
*/
|
|
436
438
|
get isIdentified(): boolean;
|
|
439
|
+
/**
|
|
440
|
+
* Pass the user's existing API token for direct forwarding to OpenAPI tool sources.
|
|
441
|
+
*
|
|
442
|
+
* When set, Pillar uses this token as a Bearer token for API calls made
|
|
443
|
+
* on behalf of the user, bypassing the per-user OAuth linking flow.
|
|
444
|
+
* Useful when the user is already authenticated in your app.
|
|
445
|
+
*
|
|
446
|
+
* @param token - The user's API/OAuth token, or empty string to clear
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* ```typescript
|
|
450
|
+
* // After user logs in to your app
|
|
451
|
+
* pillar.setUserApiToken(accessToken);
|
|
452
|
+
*
|
|
453
|
+
* // Clear on logout
|
|
454
|
+
* pillar.setUserApiToken('');
|
|
455
|
+
* ```
|
|
456
|
+
*/
|
|
457
|
+
setUserApiToken(token: string): void;
|
|
437
458
|
/**
|
|
438
459
|
* Report a user action for context building.
|
|
439
460
|
* Recent actions are tracked and sent with chat requests for better context.
|
package/dist/core/config.d.ts
CHANGED
|
@@ -435,6 +435,13 @@ export interface PillarConfig {
|
|
|
435
435
|
* @example ['/login', '/signup', '/onboarding']
|
|
436
436
|
*/
|
|
437
437
|
excludeRoutes?: string[];
|
|
438
|
+
/**
|
|
439
|
+
* User's API token for OpenAPI tool passthrough.
|
|
440
|
+
* When set, Pillar forwards this as a Bearer token to API tool sources,
|
|
441
|
+
* bypassing per-user OAuth linking. Useful when the user is already
|
|
442
|
+
* authenticated in your app.
|
|
443
|
+
*/
|
|
444
|
+
userApiToken?: string;
|
|
438
445
|
/** Called when the SDK is initialized and ready. */
|
|
439
446
|
onReady?: () => void;
|
|
440
447
|
/** Called when the SDK encounters an error. */
|
package/dist/index.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export { Pillar, getApiClient, type ChatContext, type PillarState, type ToolInfo
|
|
|
23
23
|
export { getPillarInstance } from "./core/instance";
|
|
24
24
|
export { DEFAULT_SIDEBAR_TABS, type DOMScanningConfig, type EdgeTriggerConfig, type InteractionHighlightConfig, type MobileTriggerConfig, type MobileTriggerIcon, type MobileTriggerPosition, type MobileTriggerSize, type PanelConfig, type PanelMode, type PanelPosition, type PillarConfig, type ResolvedConfig, type ResolvedDOMScanningConfig, type ResolvedInteractionHighlightConfig, type ResolvedMobileTriggerConfig, type ResolvedPanelConfig, type ResolvedSuggestionsConfig, type ResolvedThemeConfig, type SidebarTabConfig, type SuggestionsConfig, type TextSelectionConfig, type ThemeColors, type ThemeConfig, type ThemeMode, type UrlParamsConfig, type ZIndexConfig, } from "./core/config";
|
|
25
25
|
export { type AssistantContext, type Context, type Suggestion, type UserProfile, } from "./core/context";
|
|
26
|
-
export { clearRegistry, getToolCount, getToolDefinition, getToolNames, getClientInfo, getHandler, getManifest, hasTool, setClientInfo, type ToolDataSchema, type ToolDataSchemaProperty, type ToolDataType, type ToolDefinition, type ToolDefinitions, type ToolManifest, type ToolManifestEntry, type ToolNames, type ToolType, type ToolTypeDataMap, type ToolExecuteResult, type ToolSchemaBase, type InlineUIToolSchema, type ExecutableToolSchema, type ToolSchema, type ClientInfo, type CopyTextData, type ExternalLinkData, type InlineUIData, type NavigateToolData, type TriggerToolData, type QueryToolData, type Platform, type SyncToolDefinition, type SyncToolDefinitions, type TypedOnTask, type TypedPillarMethods, type TypedTaskHandler, getActionCount, getActionDefinition, getActionNames, hasAction, type ActionDataSchema, type ActionDataSchemaProperty, type ActionDataType, type ActionDefinition, type ActionDefinitions, type ActionManifest, type ActionManifestEntry, type ActionNames, type ActionType, type ActionTypeDataMap, type ActionResult, type ActionSchema, type NavigateActionData, type TriggerActionData, type QueryActionData, type SyncActionDefinition, type SyncActionDefinitions, } from "./tools";
|
|
26
|
+
export { clearRegistry, getToolCount, getToolDefinition, getToolNames, getClientInfo, getHandler, getManifest, hasTool, setClientInfo, type ToolDataSchema, type ToolDataSchemaProperty, type ToolDataType, type ToolDefinition, type ToolDefinitions, type ToolManifest, type ToolManifestEntry, type ToolNames, type ToolType, type ToolTypeDataMap, type ToolExecuteResult, type ToolSchemaBase, type InlineUIToolSchema, type ExecutableToolSchema, type ToolSchema, type ClientInfo, type CopyTextData, type ExternalLinkData, type InlineUIData, type NavigateToolData, type TriggerToolData, type QueryToolData, type Platform, type SyncToolDefinition, type SyncToolDefinitions, type TypedOnTask, type TypedPillarMethods, type TypedTaskHandler, defineSkill, type SkillDefinition, getActionCount, getActionDefinition, getActionNames, hasAction, type ActionDataSchema, type ActionDataSchemaProperty, type ActionDataType, type ActionDefinition, type ActionDefinitions, type ActionManifest, type ActionManifestEntry, type ActionNames, type ActionType, type ActionTypeDataMap, type ActionResult, type ActionSchema, type NavigateActionData, type TriggerActionData, type QueryActionData, type SyncActionDefinition, type SyncActionDefinitions, } from "./tools";
|
|
27
27
|
export { APIClient, type ArticleSummary, type ChatMessage, type ChatResponse, type ProgressEvent, } from "./api/client";
|
|
28
28
|
export { type ToolRequest, type ToolData, type ChatImage, type ImageUploadResponse, type TokenUsage, toolToTaskButton, type ActionRequest, type ActionData, actionToTaskButton, } from "./api/mcp-client";
|
|
29
29
|
export { normalizeToolResult } from "./utils/normalize-tool-result";
|