@arcyai/sdk
v0.4.0
Published
ARCY SDK — deploy an AI agent that your users can talk to, learn from, and put on autopilot
Downloads
1,498
Readme
@arcyai/sdk
An agentic layer for your SaaS. Your users can ask questions, follow guided flows, and let ARCY operate your product for them.
ARCY embeds directly into your app as a persistent widget. Users open it to get answers in Chat mode, walk through step-by-step tutorials in Copilot mode, or hand the wheel to Autopilot and watch it navigate, click, and fill forms on their behalf. You get a behavioral analytics layer that maps every signal back to your product strategy.
Before you start
Get your keys from app.arcyai.com > Settings > API Keys
ARCY uses two environments. Each app has a separate key pair for each:
| Environment | Publishable key | Behavior |
| ----------- | --------------- | --------------------------------------------------------------------- |
| Development | pk_test_... | Events are tracked but isolated from production data. |
| Production | pk_live_... | Full production tracking. |
Add the keys for each environment to the corresponding .env file:
# .env.local (development)
NEXT_PUBLIC_ARCY_PUBLISHABLE_KEY=pk_test_...
ARCY_SECRET_KEY=sk_test_...
# .env.production
NEXT_PUBLIC_ARCY_PUBLISHABLE_KEY=pk_live_...
ARCY_SECRET_KEY=sk_live_...NEXT_PUBLIC_ARCY_PUBLISHABLE_KEY is safe to expose in client code. ARCY_SECRET_KEY is server-side only and must never appear in the browser.
Setup
Option 1: Automated (recommended)
Install the CLI globally once:
npm install -g @arcyai/sdkRun init. It detects your framework and auth library locally, generates the .arcy/ knowledge graph, and wires up ARCYProvider automatically. Interactive elements are identified at runtime by a passive, multi-signal fingerprint captured from real usage, not a source-code attribute, so no JSX is ever touched. Everything runs on your machine; no source file is sent anywhere.
arcy initFully supported frameworks: Next.js App Router, Next.js Pages Router, Vite + React, Create React App. Fully supported auth libraries: Clerk, NextAuth, Auth0, Supabase, Firebase. Any other combination still runs the local analysis; init prints a manual wiring snippet instead of auto-wiring the provider.
Push your config and go live:
arcy pushConfirm everything is connected:
arcy status --wait--wait polls until the first real session is received, then prints confirmation and exits. No dashboard visit needed.
Reload your app. The ARCY panel appears in the bottom-right corner. Chat, Copilot, and Autopilot modes are live.
Option 2: Manual
If you prefer to wire things up yourself or want to understand what the CLI does:
1. Install the package
npm install @arcyai/sdk
# or
pnpm add @arcyai/sdk
# or
yarn add @arcyai/sdk2. Import the base styles
// In your root layout or global CSS entry point
import "@arcyai/sdk/styles"3. Wrap your app with ARCYProvider
Pick the snippet for your auth framework:
Next.js + Clerk
// components/arcy-wrapper.tsx
"use client"
import { useUser } from "@clerk/nextjs"
import { ARCYProvider } from "@arcyai/sdk/react"
export function ArcyWrapper({ children }: { children: React.ReactNode }) {
const { user, isLoaded } = useUser()
if (!isLoaded || !user) return <>{children}</>
return (
<ARCYProvider
publicKey={process.env.NEXT_PUBLIC_ARCY_PUBLISHABLE_KEY!}
userId={user.id}
userTraits={{
email: user.primaryEmailAddress?.emailAddress,
name: user.fullName ?? undefined,
plan: user.publicMetadata?.plan as string | undefined,
createdAt: user.createdAt ?? undefined,
}}
organizationId={user.organizationMemberships?.[0]?.organization?.id}
organizationTraits={{
name: user.organizationMemberships?.[0]?.organization?.name ?? undefined,
}}
>
{children}
</ARCYProvider>
)
}// app/layout.tsx
import { ArcyWrapper } from "@/components/arcy-wrapper"
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<ArcyWrapper>{children}</ArcyWrapper>
</body>
</html>
)
}Next.js + NextAuth
// components/arcy-wrapper.tsx
"use client"
import { useSession } from "next-auth/react"
import { ARCYProvider } from "@arcyai/sdk/react"
export function ArcyWrapper({ children }: { children: React.ReactNode }) {
const { data: session } = useSession()
if (!session?.user) return <>{children}</>
return (
<ARCYProvider
publicKey={process.env.NEXT_PUBLIC_ARCY_PUBLISHABLE_KEY!}
userId={session.user.id}
userTraits={{
email: session.user.email ?? undefined,
name: session.user.name ?? undefined,
}}
>
{children}
</ARCYProvider>
)
}Next.js + Supabase
// components/arcy-wrapper.tsx
"use client"
import { useUser } from "@supabase/auth-helpers-react"
import { ARCYProvider } from "@arcyai/sdk/react"
export function ArcyWrapper({ children }: { children: React.ReactNode }) {
const user = useUser()
if (!user) return <>{children}</>
return (
<ARCYProvider
publicKey={process.env.NEXT_PUBLIC_ARCY_PUBLISHABLE_KEY!}
userId={user.id}
userTraits={{
email: user.email,
createdAt: user.created_at,
...user.user_metadata,
}}
>
{children}
</ARCYProvider>
)
}React + Vite (custom auth)
// components/arcy-wrapper.tsx
import { ARCYProvider } from "@arcyai/sdk/react"
interface ArcyWrapperProps {
children: React.ReactNode
user: { id: string; email: string; name?: string; plan?: string } | null
}
export function ArcyWrapper({ children, user }: ArcyWrapperProps) {
if (!user) return <>{children}</>
return (
<ARCYProvider
publicKey={import.meta.env.VITE_ARCY_PUBLISHABLE_KEY}
userId={user.id}
userTraits={{
email: user.email,
name: user.name,
plan: user.plan,
}}
>
{children}
</ARCYProvider>
)
}4. No source markup required
ARCY identifies interactive elements at runtime through a passive, multi-signal fingerprint (element id, class, aria-label, text) captured from real user interaction. There is no attribute to add and no build step. If a specific guided-flow step needs a stable, hand-authored target, set anchorId directly in .arcy/flows/*.yaml.
5. Push config and go live
arcy push
arcy status --waitThe ARCY panel appears in the bottom-right corner of your app.
ARCYProvider props
| Prop | Type | Required | Description |
| -------------------- | ----------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| publicKey | string | Yes | Your ARCY publishable key (pk_test_... or pk_live_...). Safe to expose in client code. Throws immediately if a secret key (sk_...) is passed. |
| userId | string | No | Your user's ID from your auth provider. Enables per-user analytics and flow targeting. |
| userTraits | UserTraits | No | User metadata: email, name, plan, role, createdAt. Expansion signals: seatCount, featureDepth, integrationCount. More signals means better product intelligence. |
| organizationId | string | No | Organization ID for B2B products. Links users to accounts in the ARCY dashboard. |
| organizationTraits | OrganizationTraits | No | Org-level metadata: name, plan. ICP fields: companySize, industry. Expansion signals: seatCount, integrationCount. |
| navigationManifest | NavigationItem[] | No | Describes your app's pages so ARCY can answer "where is X?" questions and show redirect buttons in Chat mode. |
| metadata | Record<string, string \| number \| boolean \| null> | No | Arbitrary session metadata attached to every event. |
Expansion signal fields
Pass these via organizationTraits to unlock ICP segmentation and expansion scoring in your ARCY dashboard.
<ARCYProvider
publicKey="pk_..."
userId={userId}
organizationId={org.id}
organizationTraits={{
name: org.name,
plan: org.plan,
companySize: "51-200", // "1-10" | "11-50" | "51-200" | "201-500" | "500+"
industry: "FinTech",
seatCount: org.seatCount,
integrationCount: org.integrationCount,
}}
userTraits={{
email: user.email,
plan: user.plan,
seatCount: user.seatCount,
integrationCount: user.integrationCount,
}}
>
{children}
</ARCYProvider>companySize and industry are required for ICP segmentation. seatCount and integrationCount power expansion scoring. featureDepth tracks which product areas a user engages with.
CLI reference
ARCY CLI follows git naming conventions.
| Command | What it does |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| arcy init | First-time local setup: detect framework/auth, wire ARCYProvider, install the SDK, run arcy analyze once |
| arcy analyze | Local, zero-network extraction: refresh .arcy/ knowledge graph skeletons and entity/flow candidates. Incremental and CI-safe |
| arcy push | Push local .arcy/ knowledge graph to the ARCY backend |
| arcy pull | Pull latest flows and config from the ARCY backend |
| arcy status | Show connectivity and sync state |
| arcy status --wait | Poll until the first session is received, then confirm and exit |
| arcy log | Show push history |
| arcy validate | Validate .arcy/ YAML files against ARCY schemas. Runs automatically before arcy push. |
| arcy rm | Remove ARCY setup from your codebase |
Standard workflow after shipping new features:
arcy analyze # refresh the .arcy/ knowledge graph and entity/flow candidates, zero network calls
arcy push # push changes to ARCY backend
arcy status # confirm everything is liveTo pull flows edited in the ARCY dashboard:
arcy pullSecurity and privacy
What leaves your environment:
ARCYProviderat runtime sends session metadata (theuserId,userTraits, andorganizationIdyou pass), route paths, and a masked, multi-signal element fingerprint (id, class, aria-label, text) when users interact with elements. Input/hidden field values and anything matching a PII pattern are masked client-side before the payload is ever built. No full DOM content, no user-typed text outside the ARCY chat panel, no cookies.- When a user sends a message in the ARCY panel, the message text and session context are sent to the ARCY backend for the AI response.
arcy pushuploads your.arcy/knowledge graph YAML (routes, labels, anchor IDs) to the ARCY backend. Enrichment (authoring descriptions, personas, FAQ) sends that same structural map, never raw source, to a model for semantic authoring, and is tenant-gated.
What never leaves your environment:
ARCY_SECRET_KEY(sk_...) is server-side only.ARCYProviderthrows immediately if a secret key is detected in a browser context.- Source file content, under any CLI command.
arcy initandarcy analyzeare 100% local and deterministic; the only network call either makes is your own package manager installing the SDK. - Any field not explicitly passed as a prop to
ARCYProvider. - Cookie values or
localStoragecontents beyond the ARCY visitor ID and theme preference.
Storage used by the SDK:
localStorage: a persistent anonymous visitor ID (__arcy_vid) that links pre-signup behavior to identified users. Scoped to the host origin.localStorage: ARCY theme preference (arcy-theme). Not sent to the backend.sessionStorage: conversation state (chat messages, autopilot plan, copilot session). Cleared when the tab closes.
Content Security Policy:
Add the following directive to allow ARCY network calls:
Content-Security-Policy: connect-src https://api.arcyai.com;Staying current after code changes
When you ship new features or redesign existing screens:
arcy analyze # detects new/changed elements, refreshes the .arcy/ knowledge graph, zero network calls
arcy push # pushes changes to the ARCY backendarcy analyze is safe to run at any time, including on every commit in CI: it is incremental (only re-walks changed files) and idempotent.
What ARCY is not
- Not an analytics SDK. ARCY collects behavioral signals as a side effect of the AI layer, not as its primary purpose.
- Not a tooltip library. ARCY uses your existing UI to answer questions and execute actions in it.
- Not a chatbot. Autopilot mode navigates pages, clicks buttons, and fills forms on behalf of your user.
License
MIT
