@hasna/contacts 0.6.22 → 0.6.27

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.
Files changed (185) hide show
  1. package/README.md +82 -6
  2. package/dist/cli/commands/advanced.d.ts.map +1 -1
  3. package/dist/cli/commands/audience.d.ts +18 -0
  4. package/dist/cli/commands/audience.d.ts.map +1 -0
  5. package/dist/cli/commands/core.d.ts.map +1 -1
  6. package/dist/cli/commands/crm.d.ts.map +1 -1
  7. package/dist/cli/index.js +9446 -5681
  8. package/dist/cli/storage.d.ts.map +1 -1
  9. package/dist/cloud/http-storage.d.ts +88 -0
  10. package/dist/cloud/http-storage.d.ts.map +1 -0
  11. package/dist/db/audiences.d.ts +51 -0
  12. package/dist/db/audiences.d.ts.map +1 -0
  13. package/dist/db/companies.d.ts.map +1 -1
  14. package/dist/db/contacts.d.ts.map +1 -1
  15. package/dist/db/database.d.ts +1 -2
  16. package/dist/db/database.d.ts.map +1 -1
  17. package/dist/db/paths.d.ts +3 -0
  18. package/dist/db/paths.d.ts.map +1 -0
  19. package/dist/db/pg-migrations.d.ts.map +1 -1
  20. package/dist/db/storage.d.ts +1 -1
  21. package/dist/db/storage.d.ts.map +1 -1
  22. package/dist/db/tags.d.ts.map +1 -1
  23. package/dist/db/tombstones.d.ts +19 -0
  24. package/dist/db/tombstones.d.ts.map +1 -0
  25. package/dist/generated/storage-kit/health.d.ts +20 -0
  26. package/dist/generated/storage-kit/health.d.ts.map +1 -0
  27. package/dist/generated/storage-kit/index.d.ts +8 -0
  28. package/dist/generated/storage-kit/index.d.ts.map +1 -0
  29. package/dist/generated/storage-kit/migrations.d.ts +48 -0
  30. package/dist/generated/storage-kit/migrations.d.ts.map +1 -0
  31. package/dist/generated/storage-kit/mode.d.ts +48 -0
  32. package/dist/generated/storage-kit/mode.d.ts.map +1 -0
  33. package/dist/generated/storage-kit/pool.d.ts +34 -0
  34. package/dist/generated/storage-kit/pool.d.ts.map +1 -0
  35. package/dist/generated/storage-kit/query.d.ts +36 -0
  36. package/dist/generated/storage-kit/query.d.ts.map +1 -0
  37. package/dist/generated/storage-kit/tls.d.ts +26 -0
  38. package/dist/generated/storage-kit/tls.d.ts.map +1 -0
  39. package/dist/index.d.ts +6 -76
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +3876 -2787
  42. package/dist/lib/audience-contract.d.ts +215 -0
  43. package/dist/lib/audience-contract.d.ts.map +1 -0
  44. package/dist/lib/mailery-sync.d.ts +46 -0
  45. package/dist/lib/mailery-sync.d.ts.map +1 -0
  46. package/dist/lib/package-version.d.ts +6 -0
  47. package/dist/lib/package-version.d.ts.map +1 -0
  48. package/dist/mcp/handlers/advanced.d.ts +5 -0
  49. package/dist/mcp/handlers/advanced.d.ts.map +1 -1
  50. package/dist/mcp/handlers/audience.d.ts +9 -0
  51. package/dist/mcp/handlers/audience.d.ts.map +1 -0
  52. package/dist/mcp/handlers/core.d.ts +4 -0
  53. package/dist/mcp/handlers/core.d.ts.map +1 -1
  54. package/dist/mcp/handlers/crm.d.ts +5 -0
  55. package/dist/mcp/handlers/crm.d.ts.map +1 -1
  56. package/dist/mcp/handlers/index.d.ts.map +1 -1
  57. package/dist/mcp/index.js +5843 -4045
  58. package/dist/mcp/storage-tools.d.ts.map +1 -1
  59. package/dist/mcp/tools.d.ts +252 -0
  60. package/dist/mcp/tools.d.ts.map +1 -1
  61. package/dist/sdk/index.d.ts +16 -0
  62. package/dist/sdk/index.d.ts.map +1 -0
  63. package/dist/sdk/index.js +173 -0
  64. package/dist/sdk/v1.generated.d.ts +189 -0
  65. package/dist/sdk/v1.generated.d.ts.map +1 -0
  66. package/dist/server/cloud.d.ts +51 -0
  67. package/dist/server/cloud.d.ts.map +1 -0
  68. package/dist/server/index.js +8791 -4916
  69. package/dist/server/openapi.d.ts +708 -0
  70. package/dist/server/openapi.d.ts.map +1 -0
  71. package/dist/server/pg-store.d.ts +57 -0
  72. package/dist/server/pg-store.d.ts.map +1 -0
  73. package/dist/server/security.d.ts +24 -0
  74. package/dist/server/security.d.ts.map +1 -0
  75. package/dist/server/serve.d.ts +8 -1
  76. package/dist/server/serve.d.ts.map +1 -1
  77. package/dist/server/v1.d.ts +6 -0
  78. package/dist/server/v1.d.ts.map +1 -0
  79. package/dist/store/index.d.ts +383 -0
  80. package/dist/store/index.d.ts.map +1 -0
  81. package/dist/types/index.d.ts +96 -0
  82. package/dist/types/index.d.ts.map +1 -1
  83. package/hasna.contract.json +32 -0
  84. package/migrations/0001_core_schema.sql +162 -0
  85. package/migrations/0002_contact_fields_groups.sql +22 -0
  86. package/migrations/0003_status_archiving.sql +17 -0
  87. package/migrations/0004_company_relationships.sql +16 -0
  88. package/migrations/0005_contact_projects.sql +19 -0
  89. package/migrations/0006_contact_notes.sql +14 -0
  90. package/migrations/0007_entities_vendor_tasks.sql +91 -0
  91. package/migrations/0008_deals_events.sql +36 -0
  92. package/migrations/0009_history_learnings_coordination.sql +122 -0
  93. package/migrations/0010_documents_health.sql +38 -0
  94. package/migrations/0011_feedback.sql +14 -0
  95. package/migrations/0012_audiences_consent_suppressions.sql +38 -0
  96. package/migrations/9001_api_keys.sql +18 -0
  97. package/package.json +19 -4
  98. package/dist/cli/storage-contract.test.d.ts +0 -2
  99. package/dist/cli/storage-contract.test.d.ts.map +0 -1
  100. package/dist/db/activity.test.d.ts +0 -2
  101. package/dist/db/activity.test.d.ts.map +0 -1
  102. package/dist/db/applications.test.d.ts +0 -2
  103. package/dist/db/applications.test.d.ts.map +0 -1
  104. package/dist/db/companies.test.d.ts +0 -2
  105. package/dist/db/companies.test.d.ts.map +0 -1
  106. package/dist/db/contact-tasks.test.d.ts +0 -2
  107. package/dist/db/contact-tasks.test.d.ts.map +0 -1
  108. package/dist/db/contacts.test.d.ts +0 -2
  109. package/dist/db/contacts.test.d.ts.map +0 -1
  110. package/dist/db/coordination.test.d.ts +0 -2
  111. package/dist/db/coordination.test.d.ts.map +0 -1
  112. package/dist/db/database.test.d.ts +0 -2
  113. package/dist/db/database.test.d.ts.map +0 -1
  114. package/dist/db/deals.test.d.ts +0 -2
  115. package/dist/db/deals.test.d.ts.map +0 -1
  116. package/dist/db/documents.test.d.ts +0 -2
  117. package/dist/db/documents.test.d.ts.map +0 -1
  118. package/dist/db/events.test.d.ts +0 -2
  119. package/dist/db/events.test.d.ts.map +0 -1
  120. package/dist/db/feedback.d.ts +0 -15
  121. package/dist/db/feedback.d.ts.map +0 -1
  122. package/dist/db/field-history.test.d.ts +0 -2
  123. package/dist/db/field-history.test.d.ts.map +0 -1
  124. package/dist/db/freshness.test.d.ts +0 -2
  125. package/dist/db/freshness.test.d.ts.map +0 -1
  126. package/dist/db/graph.test.d.ts +0 -2
  127. package/dist/db/graph.test.d.ts.map +0 -1
  128. package/dist/db/groups.test.d.ts +0 -2
  129. package/dist/db/groups.test.d.ts.map +0 -1
  130. package/dist/db/health.test.d.ts +0 -2
  131. package/dist/db/health.test.d.ts.map +0 -1
  132. package/dist/db/identity.test.d.ts +0 -2
  133. package/dist/db/identity.test.d.ts.map +0 -1
  134. package/dist/db/job-history.test.d.ts +0 -2
  135. package/dist/db/job-history.test.d.ts.map +0 -1
  136. package/dist/db/learnings.test.d.ts +0 -2
  137. package/dist/db/learnings.test.d.ts.map +0 -1
  138. package/dist/db/notes.test.d.ts +0 -2
  139. package/dist/db/notes.test.d.ts.map +0 -1
  140. package/dist/db/org-chart.test.d.ts +0 -2
  141. package/dist/db/org-chart.test.d.ts.map +0 -1
  142. package/dist/db/org-members.test.d.ts +0 -2
  143. package/dist/db/org-members.test.d.ts.map +0 -1
  144. package/dist/db/relationships.test.d.ts +0 -2
  145. package/dist/db/relationships.test.d.ts.map +0 -1
  146. package/dist/db/signals.test.d.ts +0 -2
  147. package/dist/db/signals.test.d.ts.map +0 -1
  148. package/dist/db/sqlite-adapter.test.d.ts +0 -2
  149. package/dist/db/sqlite-adapter.test.d.ts.map +0 -1
  150. package/dist/db/storage.test.d.ts +0 -2
  151. package/dist/db/storage.test.d.ts.map +0 -1
  152. package/dist/db/tags.test.d.ts +0 -2
  153. package/dist/db/tags.test.d.ts.map +0 -1
  154. package/dist/db/vendor-comms.test.d.ts +0 -2
  155. package/dist/db/vendor-comms.test.d.ts.map +0 -1
  156. package/dist/lib/audit.test.d.ts +0 -2
  157. package/dist/lib/audit.test.d.ts.map +0 -1
  158. package/dist/lib/brief.test.d.ts +0 -2
  159. package/dist/lib/brief.test.d.ts.map +0 -1
  160. package/dist/lib/config.test.d.ts +0 -2
  161. package/dist/lib/config.test.d.ts.map +0 -1
  162. package/dist/lib/dedup.test.d.ts +0 -2
  163. package/dist/lib/dedup.test.d.ts.map +0 -1
  164. package/dist/lib/export.test.d.ts +0 -2
  165. package/dist/lib/export.test.d.ts.map +0 -1
  166. package/dist/lib/gmail-import.test.d.ts +0 -2
  167. package/dist/lib/gmail-import.test.d.ts.map +0 -1
  168. package/dist/lib/google-contacts.test.d.ts +0 -2
  169. package/dist/lib/google-contacts.test.d.ts.map +0 -1
  170. package/dist/lib/import.test.d.ts +0 -2
  171. package/dist/lib/import.test.d.ts.map +0 -1
  172. package/dist/lib/signature-parser.test.d.ts +0 -2
  173. package/dist/lib/signature-parser.test.d.ts.map +0 -1
  174. package/dist/lib/stats.test.d.ts +0 -2
  175. package/dist/lib/stats.test.d.ts.map +0 -1
  176. package/dist/lib/timeline.test.d.ts +0 -2
  177. package/dist/lib/timeline.test.d.ts.map +0 -1
  178. package/dist/lib/upcoming.test.d.ts +0 -2
  179. package/dist/lib/upcoming.test.d.ts.map +0 -1
  180. package/dist/mcp/http.test.d.ts +0 -2
  181. package/dist/mcp/http.test.d.ts.map +0 -1
  182. package/dist/mcp/mcp.test.d.ts +0 -2
  183. package/dist/mcp/mcp.test.d.ts.map +0 -1
  184. package/dist/mcp/storage-contract.test.d.ts +0 -2
  185. package/dist/mcp/storage-contract.test.d.ts.map +0 -1
package/README.md CHANGED
@@ -17,6 +17,33 @@ npm install -g @hasna/contacts
17
17
  contacts --help
18
18
  ```
19
19
 
20
+ ## Audiences, consent, and suppression
21
+
22
+ Audience segments implement the `hasna.audience.v1` contract (distribution
23
+ apps plan): predicate definitions over contact tags, attributes (columns or
24
+ custom fields), and group membership, resolved to per-channel recipient lists
25
+ that honor consent and suppression.
26
+
27
+ ```bash
28
+ contacts audience create beta-testers \
29
+ --name "Beta testers" \
30
+ --predicates '[{"kind":"tag","value":"beta"}]' \
31
+ --policy opt_in
32
+ contacts audience list
33
+ contacts audience show beta-testers # hasna.audience.v1 document
34
+ contacts audience resolve beta-testers --channel email # email|telegram|sms
35
+ contacts consent set CONTACT_ID --channel email --status opt_in
36
+ contacts suppression add someone@example.com --channel email --reason unsubscribe
37
+ contacts suppression sync --dry-run # push unsubscribes to mailery
38
+ ```
39
+
40
+ Resolution always excludes archived and `do_not_contact` contacts and
41
+ suppressed addresses; the audience `--policy` (`opt_in`, `opt_out`,
42
+ `transactional`, `none`) controls how per-channel consent is applied.
43
+ `contacts suppression sync` pushes unsynced email suppressions to mailery via
44
+ `@hasna/mailery` when it is installed; any other backend can implement the
45
+ `SuppressionSyncAdapter` interface exported from the package.
46
+
20
47
  ## MCP Server
21
48
 
22
49
  ```bash
@@ -44,6 +71,18 @@ The REST server (`contacts-serve`) also exposes `/health` and `/mcp` when runnin
44
71
  contacts-serve
45
72
  ```
46
73
 
74
+ `contacts-serve` binds to `127.0.0.1` by default. Use `--host <host>` or
75
+ `CONTACTS_HOST=<host>` only when intentionally exposing it beyond loopback.
76
+ Shared binds still fail closed unless a valid contacts token is configured and
77
+ sent with the request. The unauthenticated local development fallback is disabled
78
+ by default and only activates when all of the following are true:
79
+
80
+ - no contacts API token environment variable is configured
81
+ - `CONTACTS_ALLOW_UNAUTHENTICATED_LOOPBACK=1`
82
+ - the server is explicitly bound to a loopback host
83
+
84
+ The fallback does not trust the HTTP `Host` header.
85
+
47
86
  ## Storage
48
87
 
49
88
  Contacts owns its local SQLite storage directly. It does not depend on shared
@@ -52,14 +91,51 @@ cloud runtime commands or MCP tools.
52
91
  ```bash
53
92
  contacts storage status
54
93
  contacts storage status --json
55
- contacts cloud status --json
94
+ contacts storage push --tables contacts,companies
95
+ contacts storage pull --tables contacts,companies
96
+ contacts storage sync
97
+ ```
98
+
99
+ Optional cross-machine sync uses contacts-owned PostgreSQL storage. Set one of:
100
+
101
+ ```bash
102
+ export HASNA_CONTACTS_POSTGRES_URL="postgres://..."
103
+ # or OPEN_CONTACTS_POSTGRES_URL / CONTACTS_POSTGRES_URL
56
104
  ```
57
105
 
58
- `contacts cloud status` remains as a compatibility alias that reports local
59
- storage and remote-sync availability. `contacts cloud push` and
60
- `contacts cloud pull` return a clear unsupported message until repo-native
61
- remote sync is configured inside this package. `contacts cloud feedback` saves
62
- feedback locally in the contacts database.
106
+ Remote PostgreSQL connections require verified TLS for non-local hosts. Local
107
+ PostgreSQL development URLs can disable TLS explicitly.
108
+
109
+ By default, remote sync covers contacts, companies, tags, and the other
110
+ non-sensitive relationship tables. `webhooks`, `contact_documents`, and
111
+ `contact_health` are excluded until explicitly requested with `--tables` and
112
+ `HASNA_CONTACTS_ALLOW_SENSITIVE_SYNC=1`. Sync inserts or updates rows with
113
+ timestamp conflict protection. Deletes for `contacts`, `companies`, and `tags`
114
+ write `_contacts_tombstones`; push/pull sync carries those tombstones and pull
115
+ applies them unless the local row has a newer `updated_at`.
116
+
117
+ Shared REST/dashboard deployments must set one of
118
+ `HASNA_CONTACTS_API_TOKENS`, `OPEN_CONTACTS_API_TOKENS`, or
119
+ `CONTACTS_API_TOKENS`. Values are comma-separated `token=scope scope` records.
120
+ Supported scopes include `contacts:read`, `contacts:write`,
121
+ `contacts:import`, `contacts:export`, `contacts:export:full`,
122
+ `documents:read`, `images:read`, `images:write`, `companies:*`, `tags:*`,
123
+ `stats:read`, `dashboard:read`, and `mcp:access`. Loopback-only development
124
+ without configured tokens remains allowed; shared hosts fail closed.
125
+
126
+ Server exports are redacted by default: email addresses, phone numbers,
127
+ addresses, notes, birthdays, social profiles, and custom fields are withheld.
128
+ Full exports require both `contacts:export` and `contacts:export:full`. Export,
129
+ import, document file read, image mutation, contact mutation, company mutation,
130
+ and tag mutation routes write audit entries. Document attachments are served
131
+ only from the managed contacts documents directory and use private `no-store`
132
+ cache headers.
133
+
134
+ `contacts cloud status`, `contacts cloud push`, `contacts cloud pull`, and
135
+ `contacts cloud sync` remain compatibility aliases for the contacts-owned
136
+ storage commands. They do not load or depend on the deprecated shared cloud
137
+ runtime. `contacts cloud feedback` saves feedback locally in the contacts
138
+ database.
63
139
 
64
140
  ## Data Directory
65
141
 
@@ -1 +1 @@
1
- {"version":3,"file":"advanced.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/advanced.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBzC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAg7B/D"}
1
+ {"version":3,"file":"advanced.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/advanced.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAo5B/D"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Audience / consent / suppression commands (distribution apps plan).
3
+ *
4
+ * contacts audience create <slug> --name <name> --predicates <json> [--match all|any] [--policy <policy>]
5
+ * contacts audience list
6
+ * contacts audience show <id>
7
+ * contacts audience delete <id>
8
+ * contacts audience resolve <id> --channel email|telegram|sms [--json]
9
+ * contacts consent set <contactId> --channel <channel> --status opt_in|opt_out|unknown [--source <source>]
10
+ * contacts consent show <contactId>
11
+ * contacts suppression add <address> --channel <channel> [--contact <id>] [--reason <reason>]
12
+ * contacts suppression remove <address> --channel <channel>
13
+ * contacts suppression list [--channel <channel>] [--unsynced]
14
+ * contacts suppression sync [--dry-run]
15
+ */
16
+ import type { Command } from "commander";
17
+ export declare function registerAudienceCommands(program: Command): void;
18
+ //# sourceMappingURL=audience.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audience.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/audience.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+BzC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6P/D"}
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/core.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6CzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAq3B3D"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/core.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAk5B3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"crm.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/crm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgDzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAs7B1D"}
1
+ {"version":3,"file":"crm.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/crm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAezC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAy6B1D"}