@clivly/sdk 0.4.0 → 0.7.0

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 CHANGED
@@ -18,15 +18,14 @@ npm install clivly
18
18
  Clivly's stable packages publish on npm's `latest` tag. Use `@next` only when
19
19
  you are intentionally validating a prerelease build.
20
20
 
21
- Add `drizzle-orm` when you use `clivly/drizzle` or `clivly/core/drizzle`, and
21
+ Add `drizzle-orm` when you use `clivly/drizzle`, and
22
22
  `vite` when you use the Vite/TanStack Start plugin.
23
23
 
24
24
  ## Usage
25
25
 
26
26
  ```ts
27
- import { createClivlySDK } from "clivly/sdk";
27
+ import { createClivlySDK, defineClivlyConfig } from "clivly/sdk";
28
28
  import { fromDrizzle } from "clivly/drizzle";
29
- import { defineClivlyConfig } from "clivly/core";
30
29
  import { db, participants, accounts } from "./db";
31
30
 
32
31
  // Declarative entity config — the non-deprecated source of truth. It maps your
@@ -48,7 +47,7 @@ const entities = defineClivlyConfig({
48
47
  });
49
48
 
50
49
  const clivly = createClivlySDK({
51
- apiKey: process.env.CLIVLY_API_KEY!, // sk_live_… from Settings → API keys
50
+ apiKey: process.env.CLIVLY_SECRET_KEY!, // sk_live_… from Settings → API keys
52
51
  entities,
53
52
  source: {
54
53
  contacts: fromDrizzle(db, participants, { entity: "participants", cursorField: "updatedAt" }),
@@ -63,7 +62,7 @@ await clivly.start(); // heartbeat + backfill + interval delta sync
63
62
 
64
63
  // Optional: let Clivly's dashboard start a sync in this app.
65
64
  const remote = createClivlySDK({
66
- apiKey: process.env.CLIVLY_API_KEY!,
65
+ apiKey: process.env.CLIVLY_SECRET_KEY!,
67
66
  entities,
68
67
  source: { /* … */ },
69
68
  syncTrigger: {
@@ -71,7 +70,6 @@ const remote = createClivlySDK({
71
70
  url: process.env.CLIVLY_SYNC_TRIGGER_URL,
72
71
  secret: process.env.CLIVLY_SYNC_TRIGGER_SECRET, // whsec_… from Integrations → Remote sync
73
72
  },
74
- verifyToken: process.env.CLIVLY_VERIFY_TOKEN,
75
73
  });
76
74
 
77
75
  export async function POST(request: Request) {
@@ -170,7 +168,7 @@ serverless cold start**, so a fresh isolate would re-page the whole entity. Pass
170
168
 
171
169
  ```ts
172
170
  const clivly = createClivlySDK({
173
- apiKey: process.env.CLIVLY_API_KEY!,
171
+ apiKey: process.env.CLIVLY_SECRET_KEY!,
174
172
  entities,
175
173
  source: { /* … */ },
176
174
  cursorStore: {
@@ -36,7 +36,7 @@ function originAllowed(origin, allowedOrigins) {
36
36
  if (!origin) return false;
37
37
  return allowedOrigins.includes(origin);
38
38
  }
39
- function createChatSessionHandler({ allowedOrigins, apiKey, apiUrl = DEFAULT_API_URL, fetchImpl = fetch }) {
39
+ function createChatSessionHandler({ allowedOrigins, apiKey, apiUrl = DEFAULT_API_URL, fetchImpl = fetch, resolveUser }) {
40
40
  const sessionUrl = `${normalizeApiUrl(apiUrl)}/clivly/widget/session`;
41
41
  return async (request) => {
42
42
  if (request.method !== "POST") return new Response(JSON.stringify({ error: "method_not_allowed" }), {
@@ -55,6 +55,12 @@ function createChatSessionHandler({ allowedOrigins, apiKey, apiUrl = DEFAULT_API
55
55
  return jsonResponse({ error: "invalid_json" }, 400);
56
56
  }
57
57
  if (!isChatSessionRequestBody(body)) return jsonResponse({ error: "invalid_request" }, 400);
58
+ let hostUser = null;
59
+ if (resolveUser) try {
60
+ hostUser = await resolveUser(request);
61
+ } catch {
62
+ console.warn("[clivly] resolveUser threw; continuing without host identity");
63
+ }
58
64
  try {
59
65
  const upstream = await fetchImpl(sessionUrl, {
60
66
  method: "POST",
@@ -67,7 +73,8 @@ function createChatSessionHandler({ allowedOrigins, apiKey, apiUrl = DEFAULT_API
67
73
  widgetId: body.widgetId,
68
74
  visitor: body.visitor,
69
75
  visitorToken: body.visitorToken,
70
- origin
76
+ origin,
77
+ ...hostUser ? { hostUser } : {}
71
78
  })
72
79
  });
73
80
  const responseBody = await upstream.text();
@@ -1,11 +1,5 @@
1
- import { c as CreateChatSessionHandlerOptions } from "./types-jMafEyTv.cjs";
2
-
1
+ import { c as CreateChatSessionHandlerOptions } from "./types-DTaz5mLi.cjs";
3
2
  //#region src/chat-session.d.ts
4
- declare function createChatSessionHandler({
5
- allowedOrigins,
6
- apiKey,
7
- apiUrl,
8
- fetchImpl
9
- }: CreateChatSessionHandlerOptions): (request: Request) => Promise<Response>;
3
+ declare function createChatSessionHandler({ allowedOrigins, apiKey, apiUrl, fetchImpl, resolveUser }: CreateChatSessionHandlerOptions): (request: Request) => Promise<Response>;
10
4
  //#endregion
11
5
  export { createChatSessionHandler };
@@ -1,11 +1,5 @@
1
- import { c as CreateChatSessionHandlerOptions } from "./types-B7wBCHRT.mjs";
2
-
1
+ import { c as CreateChatSessionHandlerOptions } from "./types-DTaz5mLi.mjs";
3
2
  //#region src/chat-session.d.ts
4
- declare function createChatSessionHandler({
5
- allowedOrigins,
6
- apiKey,
7
- apiUrl,
8
- fetchImpl
9
- }: CreateChatSessionHandlerOptions): (request: Request) => Promise<Response>;
3
+ declare function createChatSessionHandler({ allowedOrigins, apiKey, apiUrl, fetchImpl, resolveUser }: CreateChatSessionHandlerOptions): (request: Request) => Promise<Response>;
10
4
  //#endregion
11
5
  export { createChatSessionHandler };
@@ -35,7 +35,7 @@ function originAllowed(origin, allowedOrigins) {
35
35
  if (!origin) return false;
36
36
  return allowedOrigins.includes(origin);
37
37
  }
38
- function createChatSessionHandler({ allowedOrigins, apiKey, apiUrl = DEFAULT_API_URL, fetchImpl = fetch }) {
38
+ function createChatSessionHandler({ allowedOrigins, apiKey, apiUrl = DEFAULT_API_URL, fetchImpl = fetch, resolveUser }) {
39
39
  const sessionUrl = `${normalizeApiUrl(apiUrl)}/clivly/widget/session`;
40
40
  return async (request) => {
41
41
  if (request.method !== "POST") return new Response(JSON.stringify({ error: "method_not_allowed" }), {
@@ -54,6 +54,12 @@ function createChatSessionHandler({ allowedOrigins, apiKey, apiUrl = DEFAULT_API
54
54
  return jsonResponse({ error: "invalid_json" }, 400);
55
55
  }
56
56
  if (!isChatSessionRequestBody(body)) return jsonResponse({ error: "invalid_request" }, 400);
57
+ let hostUser = null;
58
+ if (resolveUser) try {
59
+ hostUser = await resolveUser(request);
60
+ } catch {
61
+ console.warn("[clivly] resolveUser threw; continuing without host identity");
62
+ }
57
63
  try {
58
64
  const upstream = await fetchImpl(sessionUrl, {
59
65
  method: "POST",
@@ -66,7 +72,8 @@ function createChatSessionHandler({ allowedOrigins, apiKey, apiUrl = DEFAULT_API
66
72
  widgetId: body.widgetId,
67
73
  visitor: body.visitor,
68
74
  visitorToken: body.visitorToken,
69
- origin
75
+ origin,
76
+ ...hostUser ? { hostUser } : {}
70
77
  })
71
78
  });
72
79
  const responseBody = await upstream.text();
package/dist/drizzle.cjs CHANGED
@@ -1,7 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_drizzle_meta = require("./drizzle-meta-iAu8w1hj.cjs");
2
+ const require_drizzle_meta = require("./drizzle-meta-CdCs30q3.cjs");
3
3
  let drizzle_orm = require("drizzle-orm");
4
4
  let drizzle_orm_pg_core = require("drizzle-orm/pg-core");
5
+ let _clivly_core_drizzle = require("@clivly/core/drizzle");
5
6
  //#region src/drizzle.ts
6
7
  function buildColumnsMeta(table) {
7
8
  const columns = (0, drizzle_orm.getTableColumns)(table);
@@ -103,5 +104,11 @@ function drizzleIntrospector(db) {
103
104
  };
104
105
  }
105
106
  //#endregion
107
+ Object.defineProperty(exports, "discoverFromDrizzle", {
108
+ enumerable: true,
109
+ get: function() {
110
+ return _clivly_core_drizzle.discoverFromDrizzle;
111
+ }
112
+ });
106
113
  exports.drizzleIntrospector = drizzleIntrospector;
107
114
  exports.fromDrizzle = fromDrizzle;
@@ -1,6 +1,6 @@
1
- import { m as NamespaceIntrospector, p as SyncSource } from "./types-jMafEyTv.cjs";
1
+ import { m as NamespaceIntrospector, p as SyncSource } from "./types-DTaz5mLi.cjs";
2
2
  import { Table } from "drizzle-orm";
3
-
3
+ import { discoverFromDrizzle } from "@clivly/core/drizzle";
4
4
  //#region src/drizzle.d.ts
5
5
  interface DrizzleDb {
6
6
  select: (...args: any[]) => any;
@@ -25,4 +25,4 @@ declare function fromDrizzle(db: DrizzleDb, table: Table, opts: {
25
25
  */
26
26
  declare function drizzleIntrospector(db: unknown): NamespaceIntrospector;
27
27
  //#endregion
28
- export { drizzleIntrospector, fromDrizzle };
28
+ export { discoverFromDrizzle, drizzleIntrospector, fromDrizzle };
@@ -1,6 +1,6 @@
1
- import { m as NamespaceIntrospector, p as SyncSource } from "./types-B7wBCHRT.mjs";
1
+ import { m as NamespaceIntrospector, p as SyncSource } from "./types-DTaz5mLi.mjs";
2
2
  import { Table } from "drizzle-orm";
3
-
3
+ import { discoverFromDrizzle } from "@clivly/core/drizzle";
4
4
  //#region src/drizzle.d.ts
5
5
  interface DrizzleDb {
6
6
  select: (...args: any[]) => any;
@@ -25,4 +25,4 @@ declare function fromDrizzle(db: DrizzleDb, table: Table, opts: {
25
25
  */
26
26
  declare function drizzleIntrospector(db: unknown): NamespaceIntrospector;
27
27
  //#endregion
28
- export { drizzleIntrospector, fromDrizzle };
28
+ export { discoverFromDrizzle, drizzleIntrospector, fromDrizzle };
package/dist/drizzle.mjs CHANGED
@@ -1,6 +1,7 @@
1
- import { t as DRIZZLE_META } from "./drizzle-meta-DMx_9nlj.mjs";
1
+ import { t as DRIZZLE_META } from "./drizzle-meta-DNqzkREf.mjs";
2
2
  import { asc, getTableColumns, getTableName, sql } from "drizzle-orm";
3
3
  import { getTableConfig } from "drizzle-orm/pg-core";
4
+ import { discoverFromDrizzle } from "@clivly/core/drizzle";
4
5
  //#region src/drizzle.ts
5
6
  function buildColumnsMeta(table) {
6
7
  const columns = getTableColumns(table);
@@ -102,4 +103,4 @@ function drizzleIntrospector(db) {
102
103
  };
103
104
  }
104
105
  //#endregion
105
- export { drizzleIntrospector, fromDrizzle };
106
+ export { discoverFromDrizzle, drizzleIntrospector, fromDrizzle };
package/dist/index.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_drizzle_meta = require("./drizzle-meta-iAu8w1hj.cjs");
2
+ const require_drizzle_meta = require("./drizzle-meta-CdCs30q3.cjs");
3
3
  const require_chat_session = require("./chat-session.cjs");
4
+ let _clivly_core_entity_config = require("@clivly/core/entity-config");
4
5
  //#region src/custom-slug.ts
5
6
  const NON_ALNUM = /[^a-z0-9]+/g;
6
7
  const EDGE_HYPHENS = /(^-|-$)/g;
@@ -395,9 +396,7 @@ function observedTriggerUrl(req) {
395
396
  const proto = forwardedProto || requestUrl.protocol.replace(":", "");
396
397
  try {
397
398
  return new URL(`${proto}://${host}${requestUrl.pathname}`).toString();
398
- } catch {
399
- return;
400
- }
399
+ } catch {}
401
400
  }
402
401
  /**
403
402
  * Decide which trigger URL to report, in precedence order:
@@ -595,9 +594,7 @@ function connectReason(status) {
595
594
  async function resolveOrg(response) {
596
595
  try {
597
596
  return (await response.json())?.org;
598
- } catch {
599
- return;
600
- }
597
+ } catch {}
601
598
  }
602
599
  function retryAfterMs(res) {
603
600
  const header = res.headers.get("retry-after");
@@ -620,7 +617,8 @@ function createFetcher(retry) {
620
617
  }
621
618
  if (!(res === null || isRetryableStatus(res.status)) || attempt >= maxAttempts) return res;
622
619
  const backoff = baseDelayMs * 2 ** (attempt - 1) + Math.random() * baseDelayMs;
623
- await sleep(res ? retryAfterMs(res) ?? backoff : backoff);
620
+ const wait = res ? retryAfterMs(res) ?? backoff : backoff;
621
+ await sleep(wait);
624
622
  }
625
623
  };
626
624
  }
@@ -677,7 +675,7 @@ async function handlePreviewRequest(config, preview) {
677
675
  if (!source) return jsonResponse({ error: `No configured source for table "${preview.sourceTable}"` }, 400);
678
676
  const idField = source.idField ?? "id";
679
677
  const filterColumns = preview.filter ? Object.keys(preview.filter).filter((k) => k !== "$raw") : [];
680
- const needed = new Set([
678
+ const needed = /* @__PURE__ */ new Set([
681
679
  idField,
682
680
  ...Object.values(preview.fieldMap),
683
681
  ...filterColumns
@@ -939,3 +937,9 @@ exports.ClivlyNetworkError = ClivlyNetworkError;
939
937
  exports.ClivlyRateLimitError = ClivlyRateLimitError;
940
938
  exports.createChatSessionHandler = require_chat_session.createChatSessionHandler;
941
939
  exports.createClivlySDK = createClivlySDK;
940
+ Object.defineProperty(exports, "defineClivlyConfig", {
941
+ enumerable: true,
942
+ get: function() {
943
+ return _clivly_core_entity_config.defineClivlyConfig;
944
+ }
945
+ });
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- import { a as ClivlySDK, c as CreateChatSessionHandlerOptions, d as DoctorCheck, f as DoctorReport, i as ClivlyConnectResult, l as CursorStore, n as ChatWidgetVisitor, o as ClivlySDKConfig, r as ClivlyConnectReason, s as ClivlyUser, t as ChatSessionRequestBody, u as DiscoveredTable } from "./types-jMafEyTv.cjs";
1
+ import { a as ClivlySDK, c as CreateChatSessionHandlerOptions, d as DoctorCheck, f as DoctorReport, i as ClivlyConnectResult, l as CursorStore, n as ChatWidgetVisitor, o as ClivlySDKConfig, r as ClivlyConnectReason, s as ClivlyUser, t as ChatSessionRequestBody, u as DiscoveredTable } from "./types-DTaz5mLi.cjs";
2
2
  import { createChatSessionHandler } from "./chat-session.cjs";
3
-
3
+ import { ClivlyEntitiesConfig, defineClivlyConfig } from "@clivly/core/entity-config";
4
4
  //#region src/errors.d.ts
5
5
  declare class ClivlyError extends Error {
6
6
  /** HTTP status, or null when the request never completed (network error). */
@@ -31,4 +31,4 @@ declare class ClivlyNetworkError extends ClivlyError {}
31
31
  */
32
32
  declare function createClivlySDK(config: ClivlySDKConfig): ClivlySDK;
33
33
  //#endregion
34
- export { type ChatSessionRequestBody, type ChatWidgetVisitor, ClivlyAuthError, type ClivlyConnectReason, type ClivlyConnectResult, ClivlyError, ClivlyNetworkError, ClivlyRateLimitError, type ClivlySDK, type ClivlySDKConfig, type ClivlyUser, type CreateChatSessionHandlerOptions, type CursorStore, type DiscoveredTable, type DoctorCheck, type DoctorReport, createChatSessionHandler, createClivlySDK };
34
+ export { type ChatSessionRequestBody, type ChatWidgetVisitor, ClivlyAuthError, type ClivlyConnectReason, type ClivlyConnectResult, type ClivlyEntitiesConfig, ClivlyError, ClivlyNetworkError, ClivlyRateLimitError, type ClivlySDK, type ClivlySDKConfig, type ClivlyUser, type CreateChatSessionHandlerOptions, type CursorStore, type DiscoveredTable, type DoctorCheck, type DoctorReport, createChatSessionHandler, createClivlySDK, defineClivlyConfig };
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { a as ClivlySDK, c as CreateChatSessionHandlerOptions, d as DoctorCheck, f as DoctorReport, i as ClivlyConnectResult, l as CursorStore, n as ChatWidgetVisitor, o as ClivlySDKConfig, r as ClivlyConnectReason, s as ClivlyUser, t as ChatSessionRequestBody, u as DiscoveredTable } from "./types-B7wBCHRT.mjs";
1
+ import { a as ClivlySDK, c as CreateChatSessionHandlerOptions, d as DoctorCheck, f as DoctorReport, i as ClivlyConnectResult, l as CursorStore, n as ChatWidgetVisitor, o as ClivlySDKConfig, r as ClivlyConnectReason, s as ClivlyUser, t as ChatSessionRequestBody, u as DiscoveredTable } from "./types-DTaz5mLi.mjs";
2
2
  import { createChatSessionHandler } from "./chat-session.mjs";
3
-
3
+ import { ClivlyEntitiesConfig, defineClivlyConfig } from "@clivly/core/entity-config";
4
4
  //#region src/errors.d.ts
5
5
  declare class ClivlyError extends Error {
6
6
  /** HTTP status, or null when the request never completed (network error). */
@@ -31,4 +31,4 @@ declare class ClivlyNetworkError extends ClivlyError {}
31
31
  */
32
32
  declare function createClivlySDK(config: ClivlySDKConfig): ClivlySDK;
33
33
  //#endregion
34
- export { type ChatSessionRequestBody, type ChatWidgetVisitor, ClivlyAuthError, type ClivlyConnectReason, type ClivlyConnectResult, ClivlyError, ClivlyNetworkError, ClivlyRateLimitError, type ClivlySDK, type ClivlySDKConfig, type ClivlyUser, type CreateChatSessionHandlerOptions, type CursorStore, type DiscoveredTable, type DoctorCheck, type DoctorReport, createChatSessionHandler, createClivlySDK };
34
+ export { type ChatSessionRequestBody, type ChatWidgetVisitor, ClivlyAuthError, type ClivlyConnectReason, type ClivlyConnectResult, type ClivlyEntitiesConfig, ClivlyError, ClivlyNetworkError, ClivlyRateLimitError, type ClivlySDK, type ClivlySDKConfig, type ClivlyUser, type CreateChatSessionHandlerOptions, type CursorStore, type DiscoveredTable, type DoctorCheck, type DoctorReport, createChatSessionHandler, createClivlySDK, defineClivlyConfig };
package/dist/index.mjs CHANGED
@@ -1,5 +1,6 @@
1
- import { t as DRIZZLE_META } from "./drizzle-meta-DMx_9nlj.mjs";
1
+ import { t as DRIZZLE_META } from "./drizzle-meta-DNqzkREf.mjs";
2
2
  import { createChatSessionHandler } from "./chat-session.mjs";
3
+ import { defineClivlyConfig } from "@clivly/core/entity-config";
3
4
  //#region src/custom-slug.ts
4
5
  const NON_ALNUM = /[^a-z0-9]+/g;
5
6
  const EDGE_HYPHENS = /(^-|-$)/g;
@@ -394,9 +395,7 @@ function observedTriggerUrl(req) {
394
395
  const proto = forwardedProto || requestUrl.protocol.replace(":", "");
395
396
  try {
396
397
  return new URL(`${proto}://${host}${requestUrl.pathname}`).toString();
397
- } catch {
398
- return;
399
- }
398
+ } catch {}
400
399
  }
401
400
  /**
402
401
  * Decide which trigger URL to report, in precedence order:
@@ -594,9 +593,7 @@ function connectReason(status) {
594
593
  async function resolveOrg(response) {
595
594
  try {
596
595
  return (await response.json())?.org;
597
- } catch {
598
- return;
599
- }
596
+ } catch {}
600
597
  }
601
598
  function retryAfterMs(res) {
602
599
  const header = res.headers.get("retry-after");
@@ -619,7 +616,8 @@ function createFetcher(retry) {
619
616
  }
620
617
  if (!(res === null || isRetryableStatus(res.status)) || attempt >= maxAttempts) return res;
621
618
  const backoff = baseDelayMs * 2 ** (attempt - 1) + Math.random() * baseDelayMs;
622
- await sleep(res ? retryAfterMs(res) ?? backoff : backoff);
619
+ const wait = res ? retryAfterMs(res) ?? backoff : backoff;
620
+ await sleep(wait);
623
621
  }
624
622
  };
625
623
  }
@@ -676,7 +674,7 @@ async function handlePreviewRequest(config, preview) {
676
674
  if (!source) return jsonResponse({ error: `No configured source for table "${preview.sourceTable}"` }, 400);
677
675
  const idField = source.idField ?? "id";
678
676
  const filterColumns = preview.filter ? Object.keys(preview.filter).filter((k) => k !== "$raw") : [];
679
- const needed = new Set([
677
+ const needed = /* @__PURE__ */ new Set([
680
678
  idField,
681
679
  ...Object.values(preview.fieldMap),
682
680
  ...filterColumns
@@ -932,4 +930,4 @@ function createClivlySDK(config) {
932
930
  };
933
931
  }
934
932
  //#endregion
935
- export { ClivlyAuthError, ClivlyError, ClivlyNetworkError, ClivlyRateLimitError, createChatSessionHandler, createClivlySDK };
933
+ export { ClivlyAuthError, ClivlyError, ClivlyNetworkError, ClivlyRateLimitError, createChatSessionHandler, createClivlySDK, defineClivlyConfig };
@@ -1,5 +1,4 @@
1
1
  import { ClivlyEntitiesConfig } from "@clivly/core";
2
-
3
2
  //#region src/drizzle-meta.d.ts
4
3
  declare const DRIZZLE_META: "__clivly_drizzle_source_meta__";
5
4
  interface DrizzleSourceMeta {
@@ -85,9 +84,12 @@ interface ClivlySDKConfig {
85
84
  * above is unambiguous; nothing here is part of the supported API.
86
85
  */
87
86
  experimental?: {
88
- /** Cloudflare Tunnel token — reserved for tunnel mode. Not wired up yet. */tunnelToken?: string; /** CRM write-back target — reserved. Not wired up yet. */
87
+ /** Cloudflare Tunnel token — reserved for tunnel mode. Not wired up yet. */
88
+ tunnelToken?: string;
89
+ /** CRM write-back target — reserved. Not wired up yet. */
89
90
  writeBack?: {
90
- enabled?: boolean; /** Only crm_* tables are ever accepted; this narrows further. */
91
+ enabled?: boolean;
92
+ /** Only crm_* tables are ever accepted; this narrows further. */
91
93
  tables?: string[];
92
94
  };
93
95
  };
@@ -116,7 +118,9 @@ interface ClivlySDKConfig {
116
118
  * responses (e.g. 4xx other than 429) are returned immediately, not retried.
117
119
  */
118
120
  retry?: {
119
- /** Total attempts including the first. Defaults to 3. Min 1. */maxAttempts?: number; /** Base backoff in ms (doubled each attempt). Defaults to 500. */
121
+ /** Total attempts including the first. Defaults to 3. Min 1. */
122
+ maxAttempts?: number;
123
+ /** Base backoff in ms (doubled each attempt). Defaults to 500. */
120
124
  baseDelayMs?: number;
121
125
  };
122
126
  /** Tables/columns to report for entity discovery + mapping. */
@@ -126,7 +130,8 @@ interface ClivlySDKConfig {
126
130
  source?: {
127
131
  contacts: SyncSource;
128
132
  companies?: SyncSource;
129
- deals?: SyncSource; /** Org-defined custom objects to mirror. Each carries its object-type slug. */
133
+ deals?: SyncSource;
134
+ /** Org-defined custom objects to mirror. Each carries its object-type slug. */
130
135
  custom?: Array<SyncSource & {
131
136
  objectType: string;
132
137
  }>;
@@ -178,7 +183,9 @@ interface ClivlySDKConfig {
178
183
  /**
179
184
  * Shared secret Clivly Cloud presents (as `Authorization: Bearer <token>`) when
180
185
  * calling the `/clivly/auth/verify` endpoint. Required for the verify handler to
181
- * authenticate the caller; without it the handler fails closed (HTTP 503).
186
+ * authenticate the caller; without it the handler fails closed (HTTP 503). No
187
+ * cloud consumer calls this endpoint yet — it is an inert primitive reserved for
188
+ * a future CRM/dashboard auth-passthrough.
182
189
  */
183
190
  verifyToken?: string;
184
191
  }
@@ -201,6 +208,13 @@ interface CreateChatSessionHandlerOptions {
201
208
  apiKey: string;
202
209
  apiUrl?: string;
203
210
  fetchImpl?: typeof fetch;
211
+ /**
212
+ * Optional host-auth hook. When provided, it runs on the incoming browser
213
+ * request (session cookies intact) and, on a non-null `ClivlyUser`, the host
214
+ * vouches for that verified identity to Clivly Cloud. Absent/null/throwing =
215
+ * the visitor stays self-reported. Never fails the session.
216
+ */
217
+ resolveUser?: (req: Request) => Promise<ClivlyUser | null> | ClivlyUser | null;
204
218
  }
205
219
  interface DoctorCheck {
206
220
  /** Human-readable outcome — what passed, or why it failed. */
@@ -1,5 +1,4 @@
1
1
  import { ClivlyEntitiesConfig } from "@clivly/core";
2
-
3
2
  //#region src/drizzle-meta.d.ts
4
3
  declare const DRIZZLE_META: "__clivly_drizzle_source_meta__";
5
4
  interface DrizzleSourceMeta {
@@ -85,9 +84,12 @@ interface ClivlySDKConfig {
85
84
  * above is unambiguous; nothing here is part of the supported API.
86
85
  */
87
86
  experimental?: {
88
- /** Cloudflare Tunnel token — reserved for tunnel mode. Not wired up yet. */tunnelToken?: string; /** CRM write-back target — reserved. Not wired up yet. */
87
+ /** Cloudflare Tunnel token — reserved for tunnel mode. Not wired up yet. */
88
+ tunnelToken?: string;
89
+ /** CRM write-back target — reserved. Not wired up yet. */
89
90
  writeBack?: {
90
- enabled?: boolean; /** Only crm_* tables are ever accepted; this narrows further. */
91
+ enabled?: boolean;
92
+ /** Only crm_* tables are ever accepted; this narrows further. */
91
93
  tables?: string[];
92
94
  };
93
95
  };
@@ -116,7 +118,9 @@ interface ClivlySDKConfig {
116
118
  * responses (e.g. 4xx other than 429) are returned immediately, not retried.
117
119
  */
118
120
  retry?: {
119
- /** Total attempts including the first. Defaults to 3. Min 1. */maxAttempts?: number; /** Base backoff in ms (doubled each attempt). Defaults to 500. */
121
+ /** Total attempts including the first. Defaults to 3. Min 1. */
122
+ maxAttempts?: number;
123
+ /** Base backoff in ms (doubled each attempt). Defaults to 500. */
120
124
  baseDelayMs?: number;
121
125
  };
122
126
  /** Tables/columns to report for entity discovery + mapping. */
@@ -126,7 +130,8 @@ interface ClivlySDKConfig {
126
130
  source?: {
127
131
  contacts: SyncSource;
128
132
  companies?: SyncSource;
129
- deals?: SyncSource; /** Org-defined custom objects to mirror. Each carries its object-type slug. */
133
+ deals?: SyncSource;
134
+ /** Org-defined custom objects to mirror. Each carries its object-type slug. */
130
135
  custom?: Array<SyncSource & {
131
136
  objectType: string;
132
137
  }>;
@@ -178,7 +183,9 @@ interface ClivlySDKConfig {
178
183
  /**
179
184
  * Shared secret Clivly Cloud presents (as `Authorization: Bearer <token>`) when
180
185
  * calling the `/clivly/auth/verify` endpoint. Required for the verify handler to
181
- * authenticate the caller; without it the handler fails closed (HTTP 503).
186
+ * authenticate the caller; without it the handler fails closed (HTTP 503). No
187
+ * cloud consumer calls this endpoint yet — it is an inert primitive reserved for
188
+ * a future CRM/dashboard auth-passthrough.
182
189
  */
183
190
  verifyToken?: string;
184
191
  }
@@ -201,6 +208,13 @@ interface CreateChatSessionHandlerOptions {
201
208
  apiKey: string;
202
209
  apiUrl?: string;
203
210
  fetchImpl?: typeof fetch;
211
+ /**
212
+ * Optional host-auth hook. When provided, it runs on the incoming browser
213
+ * request (session cookies intact) and, on a non-null `ClivlyUser`, the host
214
+ * vouches for that verified identity to Clivly Cloud. Absent/null/throwing =
215
+ * the visitor stays self-reported. Never fails the session.
216
+ */
217
+ resolveUser?: (req: Request) => Promise<ClivlyUser | null> | ClivlyUser | null;
204
218
  }
205
219
  interface DoctorCheck {
206
220
  /** Human-readable outcome — what passed, or why it failed. */
package/dist/vite.d.cts CHANGED
@@ -1,6 +1,5 @@
1
- import { a as ClivlySDK } from "./types-jMafEyTv.cjs";
1
+ import { a as ClivlySDK } from "./types-DTaz5mLi.cjs";
2
2
  import { Plugin } from "vite";
3
-
4
3
  //#region src/vite.d.ts
5
4
  interface ClivlyViteOptions {
6
5
  /** Log prefix for Clivly's boot lines. Defaults to "clivly". */
package/dist/vite.d.mts CHANGED
@@ -1,6 +1,5 @@
1
- import { a as ClivlySDK } from "./types-B7wBCHRT.mjs";
1
+ import { a as ClivlySDK } from "./types-DTaz5mLi.mjs";
2
2
  import { Plugin } from "vite";
3
-
4
3
  //#region src/vite.d.ts
5
4
  interface ClivlyViteOptions {
6
5
  /** Log prefix for Clivly's boot lines. Defaults to "clivly". */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clivly/sdk",
3
- "version": "0.4.0",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Clivly SDK — connect your app to Clivly Cloud (heartbeat, discovery, auth bridge).",
@@ -55,7 +55,7 @@
55
55
  "access": "public"
56
56
  },
57
57
  "dependencies": {
58
- "@clivly/core": "0.4.0"
58
+ "@clivly/core": "0.7.0"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "drizzle-orm": ">=0.30",
@@ -72,11 +72,14 @@
72
72
  "devDependencies": {
73
73
  "@electric-sql/pglite": "^0.5.4",
74
74
  "drizzle-orm": "^0.45.2",
75
- "tsdown": "^0.21.9",
75
+ "tsdown": "^0.22.14",
76
76
  "typescript": "^6",
77
77
  "vite": "^8.0.8",
78
78
  "vitest": "^3.2.0"
79
79
  },
80
+ "engines": {
81
+ "node": ">=22"
82
+ },
80
83
  "scripts": {
81
84
  "build": "tsdown",
82
85
  "check-types": "tsc --noEmit",