p2pme-ai-support
p2pme-ai-support
An embeddable p2p.me AI support chat widget — a zero-dependency, Shadow-DOM
web component backed by the commops agent API (@commops/server). Drop in one
<script> tag, or import createChatWidget in any bundler. Styles are isolated
in a Shadow Root so they never collide with the host page, and themable via CSS
custom properties.
This is the only published package in the monorepo (npm, public).
browser ──HTTP──► @commops/server ──► @commops/agent
▲
p2pme-ai-support (this package — talks to the server over fetch)
Install / embed
A. Plain <script> (IIFE auto-init) — fastest
<script
src="https://unpkg.com/p2pme-ai-support/dist/p2pme-ai-support.global.js"
data-commops-api="https://api.p2p.me"
data-commops-country="INR"
data-commops-title="p2p.me support"
data-commops-open="false"
></script>
It reads data-commops-* off its own tag, mounts a launcher + panel on
document.body, and also exposes window.CommopsWidget.create(opts) for manual
control. Supported attributes: api (required), country, title, greeting,
placeholder, footer, open, accent, accent-contrast, home
(false to skip the home screen), home-title, home-subtitle, faqs
(comma-separated), prompts, typewriter, sources, feedback.
B. ESM / bundler
npm i p2pme-ai-support # or: bun add p2pme-ai-support
import { createChatWidget } from 'p2pme-ai-support'
const widget = createChatWidget({
apiUrl: 'https://api.p2p.me', // base URL or full /chat URL
country: 'INR',
title: 'p2p.me support',
greeting: 'Hey! Ask me anything about p2p.me.',
theme: { accent: '#2563eb' },
// target: someElement, // defaults to document.body
})
widget.open() // open() / close() / toggle() / destroy()
API
| File | Export | Purpose |
|---|---|---|
src/widget.ts |
createChatWidget(opts) → WidgetHandle |
builds the Shadow-DOM UI, wires ChatClient + session, manages transcript/typing/escalate |
src/client.ts |
ChatClient, ChatApiError |
typed fetch wrapper for POST /chat |
src/session.ts |
getSessionId() |
stable anonymous id (localStorage-persisted, fallback in-memory) |
src/styles.ts |
styles |
the Shadow-Root CSS string (--cw-* custom properties) |
src/index.ts |
ESM public surface | re-exports the above |
src/embed.ts |
IIFE entry | auto-init from data-* + window.CommopsWidget |
WidgetOptions: apiUrl (req), country, title, greeting, placeholder,
footer, openOnLoad, theme, target, plus the home-screen + chat-feel
options: homeScreen (def true — a Relay/Mintlify-style landing with a hero,
search box, FAQ list and a "Chat with us" card), homeTitle, homeSubtitle,
faqs (questions listed on home; tapping one opens chat and asks it),
starterPrompts, typewriter, showSources, feedback. WidgetTheme:
accent, accentContrast, bg, fg, muted, botBg, border, radius,
font → mapped to --cw-* vars on the shadow host.
A turn calls POST /chat → { action, reply, escalated }. escalated shows the
reply + a "human teammate notified" system line; silent/empty shows a soft
"a teammate will follow up"; rate_limited shows a friendly slow-down message.
Build & publish
bun run --filter 'p2pme-ai-support' typecheck
bun run --filter 'p2pme-ai-support' build # esm + iife + .d.ts → dist/
build runs three steps: build:esm (dist/index.js), build:iife
(dist/p2pme-ai-support.global.js), build:types (tsc --emitDeclarationOnly).
prepublishOnly runs the full build, and files: ["dist", "README.md"] ships
only the artifacts. Publish with npm publish (publishConfig.access: public).
Testing in a real app
See TESTING-USER-APP.md for embedding + smoke-testing
the widget inside the user-app-client (Vite + React) app against a local or
staging @commops/server.