Search documentation

Search documentation

Syncing Tools

The pillar-sync CLI scans your codebase for usePillarTool, injectPillarTool, and defineTool calls, then syncs them to Pillar's backend. This enables the AI to discover and suggest tools to users.

Prerequisites

Before syncing, you need:

  1. A Project Slug — Your unique identifier (e.g., acme-corp)
  2. A Secret Token — For authenticating sync requests

Get both from the Pillar admin dashboard: Tools → Configure Sync

Quick Start

examples/guides/tools-sync/basic-sync.sh
# Set your credentials
export PILLAR_SLUG="your-help-center-slug"
export PILLAR_SECRET="your-secret-token"
# Scan and sync your actions
npx pillar-sync --scan ./src

Installation

The CLI is included with the SDK:

examples/guides/tools-sync/install.sh
npm install @pillar-ai/sdk
# or
pnpm add @pillar-ai/sdk
# or
yarn add @pillar-ai/sdk

Defining Tools

Use usePillarTool / injectPillarTool (framework SDKs) or pillar.defineTool() (Vanilla JS) to define tools with co-located handlers:

examples/guides/tools-sync/hook-file.tsx
// src/hooks/usePillarTools.ts
import { usePillarTool } from "@pillar-ai/react";
import { useRouter } from "next/navigation";
export function usePillarTools() {
const router = useRouter();
usePillarTool({
name: "open_settings",
type: "navigate",
description: "Open the application settings page",
examples: ["go to settings", "open preferences", "change my settings"],
execute: () => {
router.push("/settings");
},
});
usePillarTool({
name: "search_products",
type: "query",
description: "Search for products in the catalog",
inputSchema: {
type: "object",
properties: {
query: { type: "string", description: "Search term" },
category: { type: "string", description: "Optional category filter" },
},
required: ["query"],
},
examples: ["find blue shirts", "search for laptops under $1000"],
execute: async ({ query, category }) => {
router.push(`/search?q=${query}${category ? `&cat=${category}` : ""}`);
},
});
}

The CLI scanner finds usePillarTool, injectPillarTool, and defineTool calls via AST parsing — no barrel file needed. See Setting Up Tools for the full API reference.

Multiple Tools

Register multiple related tools in a single call:

examples/guides/tools/use-pillar-tool-multiple.tsx
import { usePillarTool } from "@pillar-ai/react";
import { useRouter } from "next/navigation";
export function useNavigationTools() {
const router = useRouter();
// Register multiple related tools in a single call
usePillarTool([
{
name: "open_billing",
type: "navigate",
description: "Navigate to billing and subscription settings",
examples: ["go to billing", "view my subscription", "payment settings"],
execute: () => router.push("/settings/billing"),
},
{
name: "open_team",
type: "navigate",
description: "Navigate to team management page",
examples: ["manage team", "invite team members", "team settings"],
execute: () => router.push("/settings/team"),
},
{
name: "open_integrations",
type: "navigate",
description: "Navigate to integrations and connected apps",
examples: ["view integrations", "connect apps", "api settings"],
execute: () => router.push("/settings/integrations"),
},
]);
}

Environment Variables

Required

VariableDescription
PILLAR_SLUGYour project slug (e.g., acme-corp)
PILLAR_SECRETSecret token for authentication

Optional

VariableDefaultDescription
PILLAR_API_URLhttps://help-api.trypillar.comAPI URL (override for custom deployments)
PILLAR_PLATFORMwebPlatform: web, ios, android, desktop
PILLAR_VERSIONFrom package.jsonApp version (semver or git SHA)
GIT_SHAAuto-detectedGit commit SHA for traceability

CLI Arguments

ArgumentDescription
--scan <dir>Directory to scan for tools (required)
--localUse localhost:8003 as the API URL
--helpShow help message

Local Development

Use the --local flag to sync against a local Pillar backend:

examples/guides/tools-sync/local-sync.sh
# Sync against local Pillar backend (localhost:8003)
PILLAR_SLUG=my-app PILLAR_SECRET=dev-secret \
npx pillar-sync --scan ./src --local

CI/CD Integration

GitHub Actions

# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Sync Pillar actions
        env:
          PILLAR_SLUG: ${{ secrets.PILLAR_SLUG }}
          PILLAR_SECRET: ${{ secrets.PILLAR_SECRET }}
          GIT_SHA: ${{ github.sha }}
        run: npx pillar-sync --scan ./src

      - name: Deploy
        run: npm run deploy

Store PILLAR_SLUG and PILLAR_SECRET as GitHub repository secrets.

GitLab CI

# .gitlab-ci.yml
stages:
  - build
  - sync
  - deploy

build:
  stage: build
  script:
    - npm ci
    - npm run build

sync-pillar:
  stage: sync
  script:
    - npx pillar-sync --scan ./src
  variables:
    PILLAR_SLUG: $PILLAR_SLUG
    PILLAR_SECRET: $PILLAR_SECRET
    GIT_SHA: $CI_COMMIT_SHA

deploy:
  stage: deploy
  script:
    - npm run deploy

Generic CI

examples/guides/tools-sync/generic-ci.sh
#!/bin/bash
set -e
# Build your app
npm ci
npm run build
# Sync actions to Pillar
export PILLAR_SLUG="${PILLAR_SLUG}"
export PILLAR_SECRET="${PILLAR_SECRET}"
export GIT_SHA="${CI_COMMIT_SHA:-$(git rev-parse HEAD)}"
npx pillar-sync --scan ./src
# Deploy your app
npm run deploy

How Sync Works

  1. Scan — The CLI uses TypeScript's compiler API to find usePillarTool and defineTool calls
  2. Extract — Tool metadata (name, description, type, inputSchema, etc.) is extracted from the AST
  3. Build Manifest — Creates a versioned manifest with platform info
  4. Upload — Sends the manifest to Pillar's API
  5. Process — Backend processes tools asynchronously (creates, updates, deletes)
  6. Complete — CLI polls for completion and reports results

What Gets Synced

The scanner extracts these fields from your tool definitions:

  • name — Tool identifier
  • description — Used for AI matching
  • type — Tool type (navigate, trigger_tool, query, etc.)
  • inputSchema — For data extraction from user queries
  • examples — Example phrases that trigger the tool
  • autoRun — Whether to auto-execute without confirmation
  • autoComplete — Whether the tool completes immediately

The execute function stays in your code — only metadata is synced.

Response Statuses

StatusDescription
unchangedManifest matches existing deployment (no-op)
acceptedJob queued for processing
createdDeployment created (synchronous mode)

Debugging

Enable debug mode to write the manifest to disk:

examples/guides/tools-sync/debug-sync.sh
# Enable debug mode to write manifest to disk
PILLAR_DEBUG=1 PILLAR_SLUG=my-app PILLAR_SECRET=xxx \
npx pillar-sync --scan ./src
# Check the generated manifest
cat actions-manifest.json

This creates actions-manifest.json in your project root.

Version Tracking

Each sync creates a versioned deployment. The CLI tracks:

  • Version — From PILLAR_VERSION or package.json
  • Git SHA — From GIT_SHA or auto-detected from git
  • Platform — From PILLAR_PLATFORM
  • Timestamp — When the sync occurred

This enables rollback and audit tracking in the Pillar dashboard.

Best Practices

Sync on Deploy

Always sync tools as part of your deployment pipeline to keep tools in sync with your app:

examples/guides/tools-sync/deploy-script.sh
#!/bin/bash
# deploy.sh - Run as part of your deployment
# Build the app
npm run build
# Sync actions before deploying
npx pillar-sync --scan ./src
# Deploy (e.g., to Vercel, AWS, etc.)
vercel deploy --prod

Use Environment-Specific Slugs

For staging/production environments, use different project slugs:

examples/guides/tools-sync/env-specific.sh
# Staging environment
PILLAR_SLUG=myapp-staging PILLAR_SECRET=$STAGING_SECRET \
npx pillar-sync --scan ./src
# Production environment
PILLAR_SLUG=myapp-production PILLAR_SECRET=$PROD_SECRET \
npx pillar-sync --scan ./src

Organize Tools by Feature

Group related tools in dedicated files for better organization:

src/
  hooks/               # React / Vue composables
    usePillarTools.ts
    useNavigationTools.ts
    useAdminTools.ts
  tools/               # Angular components or Vanilla JS modules
    pillar-tools.component.ts
    navigation-tools.component.ts
    admin-tools.component.ts

Next Steps

  • Learn how to define tools with usePillarTool / injectPillarTool
  • Set up context to enable tool filtering
  • View sync history in the Pillar admin dashboard