npm package: @solomei-ai/intent
Description: Lightweight browser SDK for intent events (client-only).
Latest version: 1.11.4

# Intent Integration

[![codecov](https://codecov.io/gh/solomei-ai/intent-sdk/branch/main/graph/badge.svg)](https://codecov.io/gh/solomei-ai/intent-sdk)

The **Intent** tracker collects consented client context and sends events to **Callimacus**.
It can be easily integrated into modern applications (React, Vite, Next.js, etc.) via npm or directly via a script tag.

---

## 📦 Installation

### Using npm (recommended)

Install the package from npm:

```bash
npm install @solomei-ai/intent
```

---

## ⚙️ Usage

Initialize **Intent** in your app entry point:

```ts
// app entry
import { initIntent } from '@solomei-ai/intent';

initIntent({
  clientId: 'cal-pk-...',                     // your Callimacus Client ID
  consent: true,                           // can be toggled later
  geo: true,                               // can be toggled later
});
```

### Advanced Configuration Options

The `initIntent` function accepts the following options:

```ts
initIntent({
  clientId: 'cal-pk-...',         // Required: Your Callimacus Client ID
  consent: true,                  // Optional: Enable/disable tracking (default: false)
  geo: false,                     // Optional: Enable/disable geolocation (default: false)
  baseUrl: 'https://...',         // Optional: Custom API endpoint (default: 'https://intent.callimacus.ai')
  ip: '192.0.2.1',                // Optional: Client IP address
  sidMaxAgeSeconds: 2592000,      // Optional: Session cookie max-age in seconds (default: 30 days = 2592000 seconds)
  debug: false,                   // Optional: Enable debug logging for timing information (default: false)
  debugPanel: false,              // Optional: Enable visual debug panel (default: false)
});
```

---

## 🌐 CDN Usage

If you prefer not to use npm, include the package via a `<script>` tag:

### Option 1: jsDelivr

```html
<script src="https://cdn.jsdelivr.net/npm/@solomei-ai/intent/dist/intent.umd.min.js"></script>
```

### Option 2: unpkg

```html
<script src="https://unpkg.com/@solomei-ai/intent/dist/intent.umd.min.js"></script>
```

Once loaded, access the module from the global `window.Intent` namespace:

```html
<script>
  const { initIntent } = window.Intent;

  initIntent({
    clientId: 'cal-pk-...',
    consent: true,
    geo: false,
  });
</script>
```

---

## 📘 More Information

* npm: [@solomei-ai/intent](https://www.npmjs.com/package/@solomei-ai/intent)
* jsDelivr: [https://www.jsdelivr.com/package/npm/@solomei-ai/intent](https://www.jsdelivr.com/package/npm/@solomei-ai/intent)
* unpkg: [https://unpkg.com/@solomei-ai/intent](https://unpkg.com/@solomei-ai/intent)

---


## Managing consent & geolocation flags

### Recommended: Type-Safe Functions (v1.10.0+)

Use the dedicated helper functions for better type safety and IDE support:

```ts
import {setConsent, setGeo, setDebug} from '@solomei-ai/intent';

// Grant or revoke consent
setConsent(true);  // granted
setConsent(false); // disabled

// Enable or disable device geolocation capture
setGeo(true);      // enabled
setGeo(false);     // disabled

// Enable or disable debug logging
setDebug(true);    // enabled
setDebug(false);   // disabled
```

**Benefits of type-safe functions:**
- Clear, self-documenting API
- Better IDE autocomplete and type checking
- Prevents typos in flag names
- Explicit boolean-only parameters

### Alternative: Generic setFlag Function (Deprecated)

The `setFlag` function remains available for backwards compatibility:

```ts
import {setFlag} from '@solomei-ai/intent';

// Grant or revoke consent
setFlag('intent:consent', true);  // granted
setFlag('intent:consent', false); // disabled

// Enable or disable device geolocation capture
setFlag('intent:geo', true);      // enabled
setFlag('intent:geo', false);     // disabled

// Enable or disable debug logging
setFlag('intent:debug', true);    // enabled
setFlag('intent:debug', false);   // disabled
```

> **⚠️ URGENT DEPRECATION WARNING:** The **entire `setFlag` function will be removed in v2.0.0 (February 2026 - approximately 1-2 months)**. All users must migrate to the type-safe functions (`setConsent`, `setGeo`, `setDebug`) before upgrading to v2.0.0. See the Migration Guide below for details.

---

**Behavior:**
- When consent is granted, the tracker maintains a first-party cookie `intent_sid`.
- If consent is revoked, the tracker clears `intent_sid` and stops sending events.

### Migration Guide

**Upgrading from v1.9.x and earlier:**

The new type-safe functions are recommended but optional. Your existing code using `setFlag` will continue to work without any changes:

```ts
// ✅ This still works (backwards compatible)
setFlag('intent:consent', true);

// ✅ Recommended: Migrate to type-safe functions for better DX
setConsent(true);
```

No breaking changes - all existing code remains functional.

**⚠️ URGENT: Deprecation Timeline**

- **v1.10.0 (Current - December 2025)**: `setFlag` function is deprecated but still supported
- **v2.0.0 (February 2026 - ~1-2 months)**: `setFlag` function will be **completely removed**

**⚠️ You have approximately 1-2 months to complete migration before v2.0.0**

**Migration Required Before v2.0.0:**

All code using `setFlag` must be migrated to the type-safe alternatives:

```ts
// ❌ Will NOT work in v2.0.0 - setFlag will be removed
setFlag('intent:consent', true);
setFlag('intent:consent', 'granted');
setFlag('intent:geo', false);
setFlag('intent:debug', true);

// ✅ REQUIRED migration for v2.0.0
setConsent(true);          // replaces setFlag('intent:consent', true)
setGeo(false);             // replaces setFlag('intent:geo', false)
setDebug(true);            // replaces setFlag('intent:debug', true)
```

**Migration Steps:**

1. Find all uses of `setFlag` in your codebase
2. Replace each call with the appropriate type-safe function:
   - `setFlag('intent:consent', ...)` → `setConsent(...)`
   - `setFlag('intent:geo', ...)` → `setGeo(...)`
   - `setFlag('intent:debug', ...)` → `setDebug(...)`
3. If you were using custom flag names, you'll need to find an alternative solution or open an issue to discuss your use case

**Search & Replace Examples:**

```bash
# Find all uses of setFlag
grep -r "setFlag" your-codebase/

# Example replacements:
setFlag('intent:consent', true)  → setConsent(true)
setFlag('intent:consent', false) → setConsent(false)
setFlag('intent:geo', true)      → setGeo(true)
setFlag('intent:geo', false)     → setGeo(false)
setFlag('intent:debug', true)    → setDebug(true)
setFlag('intent:debug', false)   → setDebug(false)
```

---

## Debug Logging & Debug Panel

### Debug Logging

By default, the SDK does not output any console logs to avoid spamming the browser console. However, you can enable debug logging to see timing information for performance analysis:

```ts
import {initIntent} from '@solomei-ai/intent';

// Enable debug logging during initialization
initIntent({
  clientId: 'cal-pk-...',
  debug: true,  // Enable debug logs
});
```

Or toggle debug logging at runtime:

```ts
import {setDebug} from '@solomei-ai/intent';

// Enable debug logging (recommended - type-safe)
setDebug(true);

// Disable debug logging
setDebug(false);

// Backwards compatible: using setFlag still works
import {setFlag} from '@solomei-ai/intent';
setFlag('intent:debug', true);
setFlag('intent:debug', false);
```

When debug logging is enabled, the SDK will output timing information to the console, including:
- **HTML serialization time**: Time taken to serialize the DOM into HTML
- **Screenshot capture time**: Time taken by html2canvas-pro to render the page
- **JPEG encoding time**: Time taken to encode the canvas to JPEG format
- **Total capture time**: Total time for the entire capture process

This is useful for:
- **Performance tuning**: Identify bottlenecks in the capture process
- **Development debugging**: Understand SDK behavior during development
- **Production troubleshooting**: Temporarily enable logs to diagnose issues

**Note:** Debug logging is disabled by default to prevent console spam in production. Only enable it when needed for debugging or performance analysis.

### Debug Panel (Visual Event Inspector)

> **⚠️ WARNING: The debug panel is intended for development and debugging only.**  
> **DO NOT enable in production environments.** It exposes internal SDK behavior including screenshots, event payloads, and HTML content that may reveal sensitive application structure.

The SDK provides separate build variants to ensure the debug panel code is not shipped to production:

#### Build Variants

**Production Build (Default)** - Debug panel excluded
```bash
npm install @solomei-ai/intent
```
```ts
import {initIntent} from '@solomei-ai/intent';  // Production build
```
```html
<script src="https://unpkg.com/@solomei-ai/intent/dist/intent.umd.min.js"></script>
```

**Debug Build** - Debug panel included (for development/testing only)
```ts
// ESM - use the /debug export
import {initIntent, setDebugPanel} from '@solomei-ai/intent/debug';
```
```html
<!-- UMD - use the .debug variant -->
<script src="https://unpkg.com/@solomei-ai/intent/dist/intent.debug.umd.min.js"></script>
```

#### Best Practice: Environment-Based Loading

Use your build system to load the appropriate variant:

```ts
// Vite / Webpack example
const Intent = import.meta.env.PROD 
  ? await import('@solomei-ai/intent')
  : await import('@solomei-ai/intent/debug');

Intent.initIntent({
  clientId: 'cal-pk-...',
  consent: true,
  debugPanel: !import.meta.env.PROD  // Only in development
});
```

**Recommended Use Cases:**
- **Local Development**: Debug event capture during integration
- **Testing Environments**: Verify SDK behavior in test/staging
- **Internal Demos**: Showcase SDK functionality to internal stakeholders
- **Troubleshooting**: Diagnose issues in non-production environments

**NOT Recommended:**
- ❌ Production websites or applications
- ❌ Public demos accessible to end users
- ❌ Any environment where exposing SDK internals is a concern

#### Usage

**Enable debug panel during initialization:**

```ts
import {initIntent} from '@solomei-ai/intent/debug';  // Use debug build

initIntent({
  clientId: 'cal-pk-...',
  consent: true,
  debugPanel: true,  // Enable visual debug panel
});
```

**Toggle debug panel at runtime:**

```ts
import {setDebugPanel} from '@solomei-ai/intent/debug';

// Show debug panel (development only)
setDebugPanel(true);

// Hide debug panel
setDebugPanel(false);
```

**Debug Panel Features:**
- 📸 **Screenshots**: View the actual JPEG screenshots captured by the SDK
- 🔍 **Event Details**: Expand each event to see properties, HTML, and bounding box data
- 🎯 **Event Types**: See what type of event was captured (click, pageview, scroll, etc.)
- 🕐 **Timestamps**: Track when each event occurred
- 🗑️ **Clear Events**: Clear the event log with a single button click
- 🎨 **Draggable**: Move the panel anywhere on the screen
- ➖ **Minimize**: Collapse the panel when not needed

The debug panel appears as a floating window in the top-right corner and can be dragged anywhere on the page. It displays up to 50 recent events (automatically removes oldest when limit is reached).

---

## 🎮 Test & Demo Page

A comprehensive test and demo page is included in the `demo/test-demo.html` file. This page showcases:

- ✅ All form input types (text, email, password, date, color, range, etc.)
- ✅ Interactive elements (buttons, links, clickable divs)
- ✅ Auto-redacted fields (email, password, phone, credit card, etc.)
- ✅ Custom redaction examples with `data-intent-redact`
- ✅ SDK initialization and consent controls
- ✅ Debug panel demonstration
- ✅ Complete documentation and usage instructions

**To use the test page:**

1. Build the SDK:
   ```bash
   npm run build
   ```

2. Start a local web server from the repository root:
   ```bash
   # Using Python 3
   python3 -m http.server 8080
   
   # Or using Node.js http-server
   npx http-server -p 8080
   ```

3. Open your browser and navigate to:
   ```
   http://localhost:8080/demo/test-demo.html
   ```

4. Follow the on-page instructions to:
   - Initialize the SDK
   - Enable the debug panel
   - Grant consent
   - Interact with elements to see captured events

The test page is perfect for demonstrating the SDK to stakeholders, testing new features, and understanding how the SDK captures and handles different types of data.

---

## Using `intent_sid`

Use these utilities to read or manage the session cookie from your app:
```ts
import {
   getIntentSessionId,
   clearIntentSessionId,
   ensureIntentSessionId,
   setIntentSessionMaxAge,
} from '@solomei-ai/intent';

const sid = getIntentSessionId();   // string | undefined, can be sent to backend
clearIntentSessionId();             // deletes cookie
ensureIntentSessionId();            // creates cookie if missing
setIntentSessionMaxAge(86400);      // updates cookie max-age (in seconds)
```

---

## 🔒 Data Collection & Privacy

### What Data is Collected

When consent is granted, the Intent SDK automatically collects the following data to help understand user behavior and improve experiences:

1. **Screenshots**: Visual captures of the page viewport, downscaled to JPEG format for efficient transmission
2. **HTML Content**: Serialized HTML of interacted elements (buttons, links, inputs, etc.)
3. **Interaction Events**: User actions including:
   - Clicks on buttons, links, and interactive elements
   - Form submissions (Enter key on input fields)
   - Page scroll events
   - Page focus/blur events
   - Pageview events
4. **Session Information**:
   - Session ID stored in first-party cookie `intent_sid` (created when consent is granted)
   - Session cookie max-age (default: 30 days, configurable via `sidMaxAgeSeconds`)
5. **Context Information**: Browser and device metadata:
   - **User agent**: Browser name, version, and platform
   - **Languages**: Preferred language(s) and accept-language settings
   - **Timezone**: Local timezone and UTC offset
   - **Local time**: Current date and time in user's timezone
   - **Screen**: Resolution, pixel ratio, available space, and color depth
   - **Viewport**: Window size and screen orientation
   - **Device capabilities**: CPU cores, touch support, pointer type (coarse/fine)
   - **Battery status**: Level and charging state (when available)
   - **Network connection**: Connection type, speed, RTT, and data saver mode (when available or inferred from performance timing)
   - **Performance timing**: Used to infer network characteristics
   - **Online/offline status**: Browser connectivity state
   - **Cookies enabled**: Whether the browser allows cookies
   - **Do Not Track (DNT)**: Browser DNT setting value
   - **Referrer**: HTTP referrer if present
   - **PWA status**: Service worker presence and display mode
   - **Device orientation/tilt**: Device physical orientation (when available)
   - **Geolocation**: Latitude and longitude (only when explicitly enabled via `geo: true`)
6. **Client Configuration** (stored in localStorage):
   - Client ID (`clientId`)
   - API endpoint (`baseUrl`)
   - Optional IP address (`ip`)
   - Consent status (`intent:consent`)
   - Geolocation preference (`intent:geo`)
   - Debug logging preference (`intent:debug`)
   - Session max-age setting

### Built-in Redaction

The SDK **automatically redacts** the following sensitive information:

- **Password fields** (`<input type="password">`)
- **Form fields with sensitive autocomplete attributes** (both `<input>` and `<textarea>` elements):
  - Names (`name`, `given-name`, `additional-name`, `family-name`, `nickname`, `username`)
  - Email addresses (`email`)
  - Phone numbers (`tel`)
  - Addresses:
    - Street addresses (`street-address`, `address-line1`, `address-line2`, `address-line3`)
    - Administrative levels (`address-level1`, `address-level2`, `address-level3`, `address-level4`)
    - Postal and country (`postal-code`, `country`, `country-name`)
  - Credit card details:
    - Card numbers and security (`cc-number`, `cc-exp`, `cc-exp-month`, `cc-exp-year`, `cc-csc`, `cc-type`)
    - Cardholder names (`cc-name`, `cc-given-name`, `cc-additional-name`, `cc-family-name`)
  - Birthday information (`bday`, `bday-day`, `bday-month`, `bday-year`)
  - Organization details (`organization`, `organization-title`)
  - Other sensitive fields (`sex`, `webauthn`)

**Exception:** Search fields (`<input type="search">` or elements with `role="searchbox"`) are NOT redacted, even if they have sensitive autocomplete attributes, to preserve search functionality in captured events.

Redacted fields are replaced with placeholder text like `<Password>`, `<Email>`, `<Credit card>`, `<Name>`, `<Phone>`, `<Address>`, etc., in both the HTML content and screenshots.

### Data Transmission & Storage

**How Data is Transmitted:**
- Events are sent to the Callimacus API endpoint (default: `https://intent.callimacus.ai/events`)
- Data is transmitted via HTTPS POST requests with JSON payloads
- The SDK uses `fetch()` with `keepalive` for reliability during page unload
- Credentials are not included in requests (`credentials: 'omit'`)
- The client ID is sent in the `x-sl-access-token` header
- The session ID is sent in the `x-intent-sid` header

**Local Storage:**
- The SDK stores configuration and preferences in browser `localStorage`
- Keys used: `intent:consent`, `intent:geo`, `intent:debug`, `intent:data-client-id`, `intent:data-base-url`, `intent:data-ip`, `intent:data-sid-max-age`
- localStorage data persists until explicitly cleared by the user or your application

**Cookies:**
- First-party cookie `intent_sid` stores the session identifier
- Cookie attributes: `SameSite=Lax`, `Secure` (HTTPS only)
- Default expiration: 30 days (configurable via `sidMaxAgeSeconds`)
- Cookie is created when consent is granted and deleted when consent is revoked

**Data Retention:**
- Data retention policies are managed by Callimacus, not by this client-side SDK
- For information about server-side data retention, consult your Callimacus account settings or contact Callimacus support

### Your Responsibility: Redacting Additional Fields

⚠️ **Important**: While the SDK provides automatic redaction for common sensitive fields, **you are responsible for identifying and redacting any additional sensitive or PII data specific to your application**.

The SDK cannot automatically detect all sensitive information. You must explicitly mark any custom fields, proprietary data, or application-specific sensitive content for redaction.

### How to Redact Custom Fields

Use the `data-intent-redact` attribute to mark elements for redaction:

#### Option 1: Redact with default label
```html
<!-- Element will be masked with a gray placeholder labeled "<Sensitive>" -->
<div data-intent-redact>Sensitive content here</div>
<input type="text" data-intent-redact />

<!-- Or explicitly use "mask" value for "<Redacted>" label -->
<div data-intent-redact="mask">Sensitive content</div>
```

#### Option 2: Redact with custom label
```html
<!-- Provide a descriptive label using data-intent-redact-label -->
<div data-intent-redact data-intent-redact-label="Account Balance">$1,234.56</div>
<input type="text" data-intent-redact data-intent-redact-label="Social Security Number" />
```

The custom label will appear as `<Account Balance>` or `<Social Security Number>` in the captured screenshots and HTML.

#### Option 3: Completely ignore elements
```html
<!-- Element will not appear in screenshots or HTML captures at all -->
<div data-intent-redact="ignore">This won't be captured</div>
```

### Redaction Examples

```html
<!-- Patient medical record number -->
<input 
  type="text" 
  data-intent-redact 
  data-intent-redact-label="Medical Record Number" 
  placeholder="Enter MRN" 
/>

<!-- Customer account balance -->
<div data-intent-redact data-intent-redact-label="Account Balance">
  Balance: $5,432.10
</div>

<!-- Internal employee ID -->
<span data-intent-redact data-intent-redact-label="Employee ID">
  EMP-123456
</span>

<!-- Proprietary business data -->
<section data-intent-redact data-intent-redact-label="Revenue Dashboard">
  <!-- Entire section will be redacted -->
  Q4 Revenue: $10M
</section>

<!-- Element to completely exclude from tracking -->
<div data-intent-redact="ignore">
  Internal debug information
</div>
```

### Best Practices

1. **Review Your Forms**: Audit all form fields and identify which ones contain sensitive or PII data beyond standard fields (name, email, phone, etc.)
2. **Mark Custom Sensitive Data**: Apply `data-intent-redact` to any elements displaying user-specific information, financial data, health information, or proprietary business data
3. **Use Descriptive Labels**: Provide meaningful labels with `data-intent-redact-label` to help you understand what was redacted when reviewing captured events
4. **Test Your Redaction**: Before going to production, test your pages to ensure all sensitive information is properly masked
5. **Regular Audits**: Periodically review your application for new sensitive fields that may need redaction as features evolve

### Compliance Note

Proper data redaction is critical for compliance with privacy regulations (GDPR, CCPA, HIPAA, etc.). While this SDK provides tools for redaction, **it is your responsibility as the integrator to ensure all applicable sensitive data is properly redacted** according to your legal and regulatory requirements.

---