clivly 0.2.1 → 0.2.2

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
@@ -4,8 +4,8 @@ Configure and integrate [Clivly](https://clivly.com) — the CRM that lives insi
4
4
  your app.
5
5
 
6
6
  For the full integration path, including when to use `start()` versus
7
- `runScheduled()` / `createClivlyHandler()`, see
8
- [`docs/guides/connecting-to-clivly-cloud.md`](../../docs/guides/connecting-to-clivly-cloud.md).
7
+ `runScheduled()` / `createClivlyHandler()`, see the
8
+ [connecting to Clivly Cloud guide](https://github.com/amani-joseph/clivly.com/blob/master/docs/guides/connecting-to-clivly-cloud.md).
9
9
 
10
10
  ## Usage
11
11
 
@@ -67,9 +67,11 @@ npx clivly doctor --config ./apps/web/clivly.config.ts
67
67
  ## More docs
68
68
 
69
69
  - Onboarding guide:
70
- [`docs/guides/connecting-to-clivly-cloud.md`](../../docs/guides/connecting-to-clivly-cloud.md)
71
- - SDK docs: [`../sdk/README.md`](../sdk/README.md)
72
- - Release notes: [`../../CHANGELOG.md`](../../CHANGELOG.md)
70
+ [connecting to Clivly Cloud](https://github.com/amani-joseph/clivly.com/blob/master/docs/guides/connecting-to-clivly-cloud.md)
71
+ - SDK docs:
72
+ [`@clivly/sdk` README](https://github.com/amani-joseph/clivly.com/blob/master/packages/sdk/README.md)
73
+ - Release notes:
74
+ [CHANGELOG](https://github.com/amani-joseph/clivly.com/blob/master/CHANGELOG.md)
73
75
 
74
76
  ## License
75
77
 
@@ -1,4 +1,4 @@
1
- import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, c as CreateCompanyInput, d as CreateTaskInput, g as RecordSource, i as Contact, l as CreateContactInput, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, w as UpdateTaskInput, y as TaskFilters } from "./types-LJTBhkcN.cjs";
1
+ import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, c as CreateCompanyInput, d as CreateTaskInput, g as RecordSource, i as Contact, l as CreateContactInput, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, w as UpdateTaskInput, y as TaskFilters } from "./types-_qbJXMt_.mjs";
2
2
 
3
3
  //#region ../core/src/adapter.d.ts
4
4
  /**
@@ -31,6 +31,12 @@ interface CRMAdapter {
31
31
  getTasks(orgId: string, filters?: TaskFilters): Promise<Task[]>;
32
32
  reopenTask(orgId: string, id: string): Promise<Task>;
33
33
  updateContact(orgId: string, id: string, data: UpdateContactInput): Promise<Contact>;
34
+ /**
35
+ * Move a deal to `stage` and reorder it directly after `afterId` (null = top
36
+ * of the column). The adapter computes the fractional `position` from the
37
+ * target column's current order; callers never pass a numeric position.
38
+ */
39
+ moveDeal(orgId: string, id: string, stage: Deal["stage"], afterId: string | null): Promise<Deal>;
34
40
  updateDeal(orgId: string, id: string, data: UpdateDealInput): Promise<Deal>;
35
41
  updateDealStage(orgId: string, id: string, stage: Deal["stage"]): Promise<Deal>;
36
42
  updateTask(orgId: string, id: string, data: UpdateTaskInput): Promise<Task>;
@@ -1,4 +1,4 @@
1
- import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, c as CreateCompanyInput, d as CreateTaskInput, g as RecordSource, i as Contact, l as CreateContactInput, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, w as UpdateTaskInput, y as TaskFilters } from "./types-C4POUcvk.mjs";
1
+ import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, c as CreateCompanyInput, d as CreateTaskInput, g as RecordSource, i as Contact, l as CreateContactInput, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, w as UpdateTaskInput, y as TaskFilters } from "./types-BpsKVccL.cjs";
2
2
 
3
3
  //#region ../core/src/adapter.d.ts
4
4
  /**
@@ -31,6 +31,12 @@ interface CRMAdapter {
31
31
  getTasks(orgId: string, filters?: TaskFilters): Promise<Task[]>;
32
32
  reopenTask(orgId: string, id: string): Promise<Task>;
33
33
  updateContact(orgId: string, id: string, data: UpdateContactInput): Promise<Contact>;
34
+ /**
35
+ * Move a deal to `stage` and reorder it directly after `afterId` (null = top
36
+ * of the column). The adapter computes the fractional `position` from the
37
+ * target column's current order; callers never pass a numeric position.
38
+ */
39
+ moveDeal(orgId: string, id: string, stage: Deal["stage"], afterId: string | null): Promise<Deal>;
34
40
  updateDeal(orgId: string, id: string, data: UpdateDealInput): Promise<Deal>;
35
41
  updateDealStage(orgId: string, id: string, stage: Deal["stage"]): Promise<Deal>;
36
42
  updateTask(orgId: string, id: string, data: UpdateTaskInput): Promise<Task>;
@@ -1,4 +1,4 @@
1
- import { f as CrmRole } from "./types-C4POUcvk.mjs";
1
+ import { f as CrmRole } from "./types-_qbJXMt_.mjs";
2
2
 
3
3
  //#region ../core/src/auth-adapter.d.ts
4
4
  interface ClivlyUser {
@@ -1,4 +1,4 @@
1
- import { f as CrmRole } from "./types-LJTBhkcN.cjs";
1
+ import { f as CrmRole } from "./types-BpsKVccL.cjs";
2
2
 
3
3
  //#region ../core/src/auth-adapter.d.ts
4
4
  interface ClivlyUser {
@@ -1,4 +1,4 @@
1
- import { n as ClivlyUser, t as ClivlyAuthAdapter } from "./auth-adapter-wvfGKsOJ.cjs";
1
+ import { n as ClivlyUser, t as ClivlyAuthAdapter } from "./auth-adapter-CdLODn2p.cjs";
2
2
 
3
3
  //#region ../auth-better-auth/src/map.d.ts
4
4
  interface BetterAuthLikeUser {
@@ -1,4 +1,4 @@
1
- import { n as ClivlyUser, t as ClivlyAuthAdapter } from "./auth-adapter-FEOR1nx-.mjs";
1
+ import { n as ClivlyUser, t as ClivlyAuthAdapter } from "./auth-adapter-CRBW4elj.mjs";
2
2
 
3
3
  //#region ../auth-better-auth/src/map.d.ts
4
4
  interface BetterAuthLikeUser {
package/auth-clerk.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as ClivlyUser, t as ClivlyAuthAdapter } from "./auth-adapter-wvfGKsOJ.cjs";
1
+ import { n as ClivlyUser, t as ClivlyAuthAdapter } from "./auth-adapter-CdLODn2p.cjs";
2
2
 
3
3
  //#region ../auth-clerk/src/map.d.ts
4
4
  interface ClerkLikeUser {
package/auth-clerk.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as ClivlyUser, t as ClivlyAuthAdapter } from "./auth-adapter-FEOR1nx-.mjs";
1
+ import { n as ClivlyUser, t as ClivlyAuthAdapter } from "./auth-adapter-CRBW4elj.mjs";
2
2
 
3
3
  //#region ../auth-clerk/src/map.d.ts
4
4
  interface ClerkLikeUser {
package/auth-workos.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as ClivlyUser, t as ClivlyAuthAdapter } from "./auth-adapter-wvfGKsOJ.cjs";
1
+ import { n as ClivlyUser, t as ClivlyAuthAdapter } from "./auth-adapter-CdLODn2p.cjs";
2
2
 
3
3
  //#region ../auth-workos/src/map.d.ts
4
4
  interface WorkOSLikeUser {
package/auth-workos.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as ClivlyUser, t as ClivlyAuthAdapter } from "./auth-adapter-FEOR1nx-.mjs";
1
+ import { n as ClivlyUser, t as ClivlyAuthAdapter } from "./auth-adapter-CRBW4elj.mjs";
2
2
 
3
3
  //#region ../auth-workos/src/map.d.ts
4
4
  interface WorkOSLikeUser {
@@ -1,2 +1,2 @@
1
- import { t as CRMAdapter } from "./adapter-nLfZpgIG.cjs";
1
+ import { t as CRMAdapter } from "./adapter-Cy4q2CLs.cjs";
2
2
  export { CRMAdapter };
@@ -1,2 +1,2 @@
1
- import { t as CRMAdapter } from "./adapter-xs04z0KX.mjs";
1
+ import { t as CRMAdapter } from "./adapter-Cd6D_3JD.mjs";
2
2
  export { CRMAdapter };
@@ -1,2 +1,2 @@
1
- import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-wvfGKsOJ.cjs";
1
+ import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-CdLODn2p.cjs";
2
2
  export { ClivlyAuthAdapter, ClivlyUser, CrmMembership, MembershipResolver, authCustom };
@@ -1,2 +1,2 @@
1
- import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-FEOR1nx-.mjs";
1
+ import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-CRBW4elj.mjs";
2
2
  export { ClivlyAuthAdapter, ClivlyUser, CrmMembership, MembershipResolver, authCustom };
package/core-types.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-LJTBhkcN.cjs";
1
+ import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-BpsKVccL.cjs";
2
2
  export { Activity, ActivityType, Company, Contact, ContactFilters, ContactStatus, CreateActivityInput, CreateCompanyInput, CreateContactInput, CreateDealInput, CreateTaskInput, CrmRole, Deal, DealStage, Note, RecordSource, Task, TaskEntityType, TaskFilters, TaskPriority, TaskStatus, UpdateContactInput, UpdateDealInput, UpdateTaskInput };
package/core-types.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-C4POUcvk.mjs";
1
+ import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-_qbJXMt_.mjs";
2
2
  export { Activity, ActivityType, Company, Contact, ContactFilters, ContactStatus, CreateActivityInput, CreateCompanyInput, CreateContactInput, CreateDealInput, CreateTaskInput, CrmRole, Deal, DealStage, Note, RecordSource, Task, TaskEntityType, TaskFilters, TaskPriority, TaskStatus, UpdateContactInput, UpdateDealInput, UpdateTaskInput };
package/core.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-LJTBhkcN.cjs";
2
- import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-wvfGKsOJ.cjs";
3
- import { t as CRMAdapter } from "./adapter-nLfZpgIG.cjs";
1
+ import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-BpsKVccL.cjs";
2
+ import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-CdLODn2p.cjs";
3
+ import { t as CRMAdapter } from "./adapter-Cy4q2CLs.cjs";
4
4
  import { C as validateEntitiesConfig, S as relationshipsSchema, _ as RelationshipsMap, a as ClivlyEntitiesConfig, b as filterSchema, c as ConfigValidationResult, d as FilterExpr, f as FilterValue, g as RelationshipVia, h as RelationshipSpec, i as ClivlyConfigError, l as CrmConcept, m as MaterializingConcept, n as CRM_CONCEPTS, o as ClivlyEntityConfig, p as MATERIALIZING_CONCEPTS, s as ConfigValidationError, t as CANONICAL_FIELDS, u as DiscoveredSchemaTable, v as defineClivlyConfig, x as relationshipSchema, y as entitiesConfigSchema } from "./entity-config-GczjD3y8.cjs";
5
5
  import { i as relationshipViaSignature, n as buildFilterFromDiscriminator, r as buildRelationships, t as RelationshipCandidate } from "./mapping-form-CUlFVfG8.cjs";
6
6
  import { n as mappingsToEntitiesConfig, t as EntityMappingRow } from "./mappings-config-DjRLCb2Q.cjs";
package/core.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-C4POUcvk.mjs";
2
- import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-FEOR1nx-.mjs";
3
- import { t as CRMAdapter } from "./adapter-xs04z0KX.mjs";
1
+ import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-_qbJXMt_.mjs";
2
+ import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-CRBW4elj.mjs";
3
+ import { t as CRMAdapter } from "./adapter-Cd6D_3JD.mjs";
4
4
  import { C as validateEntitiesConfig, S as relationshipsSchema, _ as RelationshipsMap, a as ClivlyEntitiesConfig, b as filterSchema, c as ConfigValidationResult, d as FilterExpr, f as FilterValue, g as RelationshipVia, h as RelationshipSpec, i as ClivlyConfigError, l as CrmConcept, m as MaterializingConcept, n as CRM_CONCEPTS, o as ClivlyEntityConfig, p as MATERIALIZING_CONCEPTS, s as ConfigValidationError, t as CANONICAL_FIELDS, u as DiscoveredSchemaTable, v as defineClivlyConfig, x as relationshipSchema, y as entitiesConfigSchema } from "./entity-config-D1DFyeUp.mjs";
5
5
  import { i as relationshipViaSignature, n as buildFilterFromDiscriminator, r as buildRelationships, t as RelationshipCandidate } from "./mapping-form-kjSiJaCX.mjs";
6
6
  import { n as mappingsToEntitiesConfig, t as EntityMappingRow } from "./mappings-config-GxiYsSBQ.mjs";
package/index.cjs CHANGED
@@ -5,6 +5,7 @@ const require_entity_config = require("./entity-config-Cvjo1cpv.cjs");
5
5
  require("./mapping-score-D9gfhtRu.cjs");
6
6
  const require_core_entity_heuristics = require("./core-entity-heuristics.cjs");
7
7
  let node_fs = require("node:fs");
8
+ let node_module = require("node:module");
8
9
  let node_path = require("node:path");
9
10
  let jiti = require("jiti");
10
11
  let node_url = require("node:url");
@@ -315,6 +316,16 @@ const defaultRun = (command, args, cwd) => new Promise((resolvePromise, reject)
315
316
  child.on("error", reject);
316
317
  child.on("close", (code) => resolvePromise(code ?? 0));
317
318
  });
319
+ const QUIET_FLAGS = {
320
+ npm: [
321
+ "--no-audit",
322
+ "--no-fund",
323
+ "--loglevel=error"
324
+ ],
325
+ pnpm: ["--reporter=silent"],
326
+ yarn: [],
327
+ bun: []
328
+ };
318
329
  /**
319
330
  * Best-effort install: run `<pm> add <packages>`. Never throws — returns
320
331
  * `{ ok, command }` so the caller can print the exact command on failure and
@@ -322,11 +333,12 @@ const defaultRun = (command, args, cwd) => new Promise((resolvePromise, reject)
322
333
  */
323
334
  async function installPackages(options) {
324
335
  const { command, args } = addCommand(options.pm, options.packages);
325
- const printable = `${command} ${args.join(" ")}`;
336
+ const fullArgs = [...args, ...QUIET_FLAGS[options.pm]];
337
+ const printable = `${command} ${fullArgs.join(" ")}`;
326
338
  const run = options.run ?? defaultRun;
327
339
  try {
328
340
  return {
329
- ok: await run(command, args, options.cwd) === 0,
341
+ ok: await run(command, fullArgs, options.cwd) === 0,
330
342
  command: printable
331
343
  };
332
344
  } catch {
@@ -545,29 +557,39 @@ function renderEntity(key, entity) {
545
557
  fields: ${renderFields(entity.fields)}${renderRelationships(entity)},
546
558
  }`;
547
559
  }
548
- function renderSource(role, entity) {
560
+ function renderSource(role, entity, dbExpr) {
549
561
  const opts = entity.idField === null ? `{ entity: "${entity.tableName}", cursorField: "${entity.cursorField}" }` : `{ entity: "${entity.tableName}", cursorField: "${entity.cursorField}", idField: "${entity.idField}" }`;
550
- return ` ${role}: fromDrizzle(db, ${entity.moduleKey}, ${opts})`;
551
- }
552
- function renderTableImport(plan) {
553
- const tableKeys = [plan.contact.moduleKey, plan.company?.moduleKey].filter(Boolean);
554
- if (plan.db) return `import { db, ${tableKeys.join(", ")} } from "${plan.importPath}";`;
555
- return `import { ${tableKeys.join(", ")} } from "${plan.importPath}";
556
- import { db } from "./db"; // TODO: point at your Drizzle instance`;
562
+ return ` ${role}: fromDrizzle(${dbExpr}, schema.${entity.moduleKey}, ${opts})`;
563
+ }
564
+ function fallbackDbImportPath(schemaImportPath) {
565
+ const slash = schemaImportPath.lastIndexOf("/");
566
+ return `${slash >= 0 ? schemaImportPath.slice(0, slash) : "."}/db`;
567
+ }
568
+ function renderDbExpr(plan) {
569
+ return plan.db ? `schema.${plan.db.moduleKey}` : "db";
570
+ }
571
+ function renderImports(plan) {
572
+ const lines = [
573
+ "import { createClivlySDK } from \"clivly/sdk\";",
574
+ "import { fromDrizzle } from \"clivly/drizzle\";",
575
+ "import { defineClivlyConfig } from \"clivly/core\";",
576
+ "import { discoverFromDrizzle } from \"clivly/core/drizzle\";",
577
+ `import * as schema from "${plan.importPath}";`
578
+ ];
579
+ if (!plan.db) lines.push(`import { db } from "${fallbackDbImportPath(plan.importPath)}"; // TODO: point at your Drizzle instance`);
580
+ return lines.join("\n");
557
581
  }
558
582
  function renderTodoHeader(todos) {
559
583
  if (todos.length === 0) return "";
560
584
  return `// TODO(clivly): review before running \`clivly doctor\`:\n${todos.map((t) => `// - ${t}`).join("\n")}\n\n`;
561
585
  }
562
586
  function renderInitConfig(plan) {
587
+ const dbExpr = renderDbExpr(plan);
563
588
  const entities = [renderEntity(plan.contact.moduleKey, plan.contact)];
564
589
  if (plan.company) entities.push(renderEntity(plan.company.moduleKey, plan.company));
565
- const sources = [renderSource("contacts", plan.contact)];
566
- if (plan.company) sources.push(renderSource("companies", plan.company));
567
- return `${renderTodoHeader(plan.todos)}import { createClivlySDK } from "@clivly/sdk";
568
- import { fromDrizzle } from "@clivly/sdk/drizzle";
569
- import { defineClivlyConfig } from "@clivly/core";
570
- ${renderTableImport(plan)}
590
+ const sources = [renderSource("contacts", plan.contact, dbExpr)];
591
+ if (plan.company) sources.push(renderSource("companies", plan.company, dbExpr));
592
+ return `${renderTodoHeader(plan.todos)}${renderImports(plan)}
571
593
 
572
594
  const entities = defineClivlyConfig({
573
595
  entities: {
@@ -578,6 +600,9 @@ ${entities.join(",\n")},
578
600
  export default createClivlySDK({
579
601
  apiKey: process.env.CLIVLY_API_KEY!,
580
602
  entities,
603
+ // Every table in your Drizzle schema, so the Clivly dashboard can offer them
604
+ // all when you add a mapping — not just the ones wired up as sources below.
605
+ schema: discoverFromDrizzle(schema),
581
606
  source: {
582
607
  ${sources.join(",\n")},
583
608
  },
@@ -753,6 +778,13 @@ function readDeps(cwd) {
753
778
  return {};
754
779
  }
755
780
  }
781
+ function readOwnVersion() {
782
+ const req = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
783
+ for (const rel of ["./package.json", "../package.json"]) try {
784
+ const pkg = req(rel);
785
+ if (pkg.name === "clivly" && pkg.version) return pkg.version;
786
+ } catch {}
787
+ }
756
788
  function defaultReadEnv(cwd) {
757
789
  const path = (0, node_path.join)(cwd, ".env");
758
790
  return (0, node_fs.existsSync)(path) ? (0, node_fs.readFileSync)(path, "utf8") : "";
@@ -780,6 +812,7 @@ function resolveInitDeps(options) {
780
812
  detectPackageManager: options.detectPackageManager ?? detectPackageManager,
781
813
  install: options.installPackages ?? installPackages,
782
814
  readEnv: options.readEnv ?? defaultReadEnv,
815
+ readOwnVersion: options.readOwnVersion ?? readOwnVersion,
783
816
  writeEnv: options.writeEnv ?? defaultWriteEnv,
784
817
  framework: "unknown"
785
818
  };
@@ -867,12 +900,14 @@ function printNextSteps(out) {
867
900
  async function scaffold(options, deps, plan) {
868
901
  const { out } = deps;
869
902
  const pm = deps.detectPackageManager(options.cwd);
903
+ const version = deps.readOwnVersion();
904
+ const spec = version ? `clivly@${version}` : "clivly";
870
905
  const result = await deps.install({
871
906
  cwd: options.cwd,
872
907
  pm,
873
- packages: ["@clivly/sdk", "@clivly/core"]
908
+ packages: [spec]
874
909
  });
875
- if (result.ok) out(`Installed @clivly/sdk @clivly/core (${pm})\n`);
910
+ if (result.ok) out(`Installed clivly (${pm})\n`);
876
911
  else out(`Could not install automatically — run:\n ${result.command}\n`);
877
912
  writeScaffoldFiles(options, deps, plan);
878
913
  writeEnvFile(options, deps);
package/index.d.cts CHANGED
@@ -46,6 +46,7 @@ interface RunInitOptions {
46
46
  out?: (line: string) => void;
47
47
  readDeps?: (cwd: string) => Record<string, string>;
48
48
  readEnv?: (cwd: string) => string;
49
+ readOwnVersion?: () => string | undefined;
49
50
  resolveSchemaPath?: (cwd: string) => string | null;
50
51
  schemaFlag?: string;
51
52
  writeConfig?: (path: string, contents: string) => void;
package/index.d.mts CHANGED
@@ -46,6 +46,7 @@ interface RunInitOptions {
46
46
  out?: (line: string) => void;
47
47
  readDeps?: (cwd: string) => Record<string, string>;
48
48
  readEnv?: (cwd: string) => string;
49
+ readOwnVersion?: () => string | undefined;
49
50
  resolveSchemaPath?: (cwd: string) => string | null;
50
51
  schemaFlag?: string;
51
52
  writeConfig?: (path: string, contents: string) => void;
package/index.mjs CHANGED
@@ -3,6 +3,7 @@ import { t as createClivlySDK } from "./sdk-BZUn6wzs.mjs";
3
3
  import { t as CANONICAL_FIELDS } from "./entity-config-DoR0khce.mjs";
4
4
  import "./mapping-score-BJNe0lFn.mjs";
5
5
  import { matchesConcept, requiredFieldsFor, scoreFieldMap, scoreRelationships, suggestCursorField, toFieldMap } from "./core-entity-heuristics.mjs";
6
+ import { createRequire } from "node:module";
6
7
  import { existsSync, mkdirSync, readFileSync, realpathSync, statSync, writeFileSync } from "node:fs";
7
8
  import { dirname, isAbsolute, join, relative, resolve } from "node:path";
8
9
  import { createJiti } from "jiti";
@@ -314,6 +315,16 @@ const defaultRun = (command, args, cwd) => new Promise((resolvePromise, reject)
314
315
  child.on("error", reject);
315
316
  child.on("close", (code) => resolvePromise(code ?? 0));
316
317
  });
318
+ const QUIET_FLAGS = {
319
+ npm: [
320
+ "--no-audit",
321
+ "--no-fund",
322
+ "--loglevel=error"
323
+ ],
324
+ pnpm: ["--reporter=silent"],
325
+ yarn: [],
326
+ bun: []
327
+ };
317
328
  /**
318
329
  * Best-effort install: run `<pm> add <packages>`. Never throws — returns
319
330
  * `{ ok, command }` so the caller can print the exact command on failure and
@@ -321,11 +332,12 @@ const defaultRun = (command, args, cwd) => new Promise((resolvePromise, reject)
321
332
  */
322
333
  async function installPackages(options) {
323
334
  const { command, args } = addCommand(options.pm, options.packages);
324
- const printable = `${command} ${args.join(" ")}`;
335
+ const fullArgs = [...args, ...QUIET_FLAGS[options.pm]];
336
+ const printable = `${command} ${fullArgs.join(" ")}`;
325
337
  const run = options.run ?? defaultRun;
326
338
  try {
327
339
  return {
328
- ok: await run(command, args, options.cwd) === 0,
340
+ ok: await run(command, fullArgs, options.cwd) === 0,
329
341
  command: printable
330
342
  };
331
343
  } catch {
@@ -544,29 +556,39 @@ function renderEntity(key, entity) {
544
556
  fields: ${renderFields(entity.fields)}${renderRelationships(entity)},
545
557
  }`;
546
558
  }
547
- function renderSource(role, entity) {
559
+ function renderSource(role, entity, dbExpr) {
548
560
  const opts = entity.idField === null ? `{ entity: "${entity.tableName}", cursorField: "${entity.cursorField}" }` : `{ entity: "${entity.tableName}", cursorField: "${entity.cursorField}", idField: "${entity.idField}" }`;
549
- return ` ${role}: fromDrizzle(db, ${entity.moduleKey}, ${opts})`;
550
- }
551
- function renderTableImport(plan) {
552
- const tableKeys = [plan.contact.moduleKey, plan.company?.moduleKey].filter(Boolean);
553
- if (plan.db) return `import { db, ${tableKeys.join(", ")} } from "${plan.importPath}";`;
554
- return `import { ${tableKeys.join(", ")} } from "${plan.importPath}";
555
- import { db } from "./db"; // TODO: point at your Drizzle instance`;
561
+ return ` ${role}: fromDrizzle(${dbExpr}, schema.${entity.moduleKey}, ${opts})`;
562
+ }
563
+ function fallbackDbImportPath(schemaImportPath) {
564
+ const slash = schemaImportPath.lastIndexOf("/");
565
+ return `${slash >= 0 ? schemaImportPath.slice(0, slash) : "."}/db`;
566
+ }
567
+ function renderDbExpr(plan) {
568
+ return plan.db ? `schema.${plan.db.moduleKey}` : "db";
569
+ }
570
+ function renderImports(plan) {
571
+ const lines = [
572
+ "import { createClivlySDK } from \"clivly/sdk\";",
573
+ "import { fromDrizzle } from \"clivly/drizzle\";",
574
+ "import { defineClivlyConfig } from \"clivly/core\";",
575
+ "import { discoverFromDrizzle } from \"clivly/core/drizzle\";",
576
+ `import * as schema from "${plan.importPath}";`
577
+ ];
578
+ if (!plan.db) lines.push(`import { db } from "${fallbackDbImportPath(plan.importPath)}"; // TODO: point at your Drizzle instance`);
579
+ return lines.join("\n");
556
580
  }
557
581
  function renderTodoHeader(todos) {
558
582
  if (todos.length === 0) return "";
559
583
  return `// TODO(clivly): review before running \`clivly doctor\`:\n${todos.map((t) => `// - ${t}`).join("\n")}\n\n`;
560
584
  }
561
585
  function renderInitConfig(plan) {
586
+ const dbExpr = renderDbExpr(plan);
562
587
  const entities = [renderEntity(plan.contact.moduleKey, plan.contact)];
563
588
  if (plan.company) entities.push(renderEntity(plan.company.moduleKey, plan.company));
564
- const sources = [renderSource("contacts", plan.contact)];
565
- if (plan.company) sources.push(renderSource("companies", plan.company));
566
- return `${renderTodoHeader(plan.todos)}import { createClivlySDK } from "@clivly/sdk";
567
- import { fromDrizzle } from "@clivly/sdk/drizzle";
568
- import { defineClivlyConfig } from "@clivly/core";
569
- ${renderTableImport(plan)}
589
+ const sources = [renderSource("contacts", plan.contact, dbExpr)];
590
+ if (plan.company) sources.push(renderSource("companies", plan.company, dbExpr));
591
+ return `${renderTodoHeader(plan.todos)}${renderImports(plan)}
570
592
 
571
593
  const entities = defineClivlyConfig({
572
594
  entities: {
@@ -577,6 +599,9 @@ ${entities.join(",\n")},
577
599
  export default createClivlySDK({
578
600
  apiKey: process.env.CLIVLY_API_KEY!,
579
601
  entities,
602
+ // Every table in your Drizzle schema, so the Clivly dashboard can offer them
603
+ // all when you add a mapping — not just the ones wired up as sources below.
604
+ schema: discoverFromDrizzle(schema),
580
605
  source: {
581
606
  ${sources.join(",\n")},
582
607
  },
@@ -752,6 +777,13 @@ function readDeps(cwd) {
752
777
  return {};
753
778
  }
754
779
  }
780
+ function readOwnVersion() {
781
+ const req = createRequire(import.meta.url);
782
+ for (const rel of ["./package.json", "../package.json"]) try {
783
+ const pkg = req(rel);
784
+ if (pkg.name === "clivly" && pkg.version) return pkg.version;
785
+ } catch {}
786
+ }
755
787
  function defaultReadEnv(cwd) {
756
788
  const path = join(cwd, ".env");
757
789
  return existsSync(path) ? readFileSync(path, "utf8") : "";
@@ -779,6 +811,7 @@ function resolveInitDeps(options) {
779
811
  detectPackageManager: options.detectPackageManager ?? detectPackageManager,
780
812
  install: options.installPackages ?? installPackages,
781
813
  readEnv: options.readEnv ?? defaultReadEnv,
814
+ readOwnVersion: options.readOwnVersion ?? readOwnVersion,
782
815
  writeEnv: options.writeEnv ?? defaultWriteEnv,
783
816
  framework: "unknown"
784
817
  };
@@ -866,12 +899,14 @@ function printNextSteps(out) {
866
899
  async function scaffold(options, deps, plan) {
867
900
  const { out } = deps;
868
901
  const pm = deps.detectPackageManager(options.cwd);
902
+ const version = deps.readOwnVersion();
903
+ const spec = version ? `clivly@${version}` : "clivly";
869
904
  const result = await deps.install({
870
905
  cwd: options.cwd,
871
906
  pm,
872
- packages: ["@clivly/sdk", "@clivly/core"]
907
+ packages: [spec]
873
908
  });
874
- if (result.ok) out(`Installed @clivly/sdk @clivly/core (${pm})\n`);
909
+ if (result.ok) out(`Installed clivly (${pm})\n`);
875
910
  else out(`Could not install automatically — run:\n ${result.command}\n`);
876
911
  writeScaffoldFiles(options, deps, plan);
877
912
  writeEnvFile(options, deps);
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "clivly",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Clivly CLI — scaffold a CRM into your app (clivly init).",
7
7
  "license": "MIT",
8
- "bin": "./index.mjs",
8
+ "bin": {
9
+ "clivly": "index.mjs"
10
+ },
9
11
  "main": "./index.cjs",
10
12
  "module": "./index.mjs",
11
13
  "types": "./index.d.mts",
@@ -232,5 +234,29 @@
232
234
  "vite": {
233
235
  "optional": true
234
236
  }
235
- }
236
- }
237
+ },
238
+ "author": "Joseph Amani",
239
+ "engines": {
240
+ "node": ">=18"
241
+ },
242
+ "repository": {
243
+ "type": "git",
244
+ "url": "git+https://github.com/amani-joseph/clivly.com.git",
245
+ "directory": "packages/cli"
246
+ },
247
+ "homepage": "https://clivly.com",
248
+ "bugs": {
249
+ "url": "https://github.com/amani-joseph/clivly.com/issues"
250
+ },
251
+ "keywords": [
252
+ "crm",
253
+ "cli",
254
+ "drizzle",
255
+ "typescript",
256
+ "tanstack-start",
257
+ "nextjs",
258
+ "self-hosted",
259
+ "embedded-crm",
260
+ "postgres"
261
+ ]
262
+ }
@@ -34,6 +34,7 @@ interface Deal {
34
34
  name: string;
35
35
  orgId: string;
36
36
  owner: string | null;
37
+ position: number | null;
37
38
  stage: DealStage;
38
39
  value: number;
39
40
  }
@@ -34,6 +34,7 @@ interface Deal {
34
34
  name: string;
35
35
  orgId: string;
36
36
  owner: string | null;
37
+ position: number | null;
37
38
  stage: DealStage;
38
39
  value: number;
39
40
  }